prose.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include "sky.h"
  5. extern Biobuf bout;
  6. char*
  7. append(char *p, char *s)
  8. {
  9. while(*s)
  10. *p++ = *s++;
  11. return p;
  12. }
  13. int
  14. matchlen(char *a, char *b)
  15. {
  16. int n;
  17. for(n=0; *a==*b; a++, b++, n++)
  18. if(*a == 0)
  19. return n;
  20. if(*a == 0)
  21. return n;
  22. return 0;
  23. }
  24. char*
  25. prose(char *s, char *desc[][2], short index[])
  26. {
  27. static char buf[512];
  28. char *p=buf;
  29. int i, j, k, max;
  30. j = 0;
  31. while(*s){
  32. if(p >= buf+sizeof buf)
  33. abort();
  34. if(*s == ' '){
  35. if(p>buf && p[-1]!=' ')
  36. *p++ = ' ';
  37. s++;
  38. continue;
  39. }
  40. if(*s == ','){
  41. *p++ = ';', s++;
  42. continue;
  43. }
  44. if(s[0]=='M' && '0'<=s[1] && s[1]<='9'){ /* Messier tag */
  45. *p++ = *s++;
  46. continue; /* below will copy the number */
  47. }
  48. if((i=index[*s]) == -1){
  49. Dup:
  50. switch(*s){
  51. default:
  52. while(*s && *s!=',' && *s!=' ')
  53. *p++=*s++;
  54. break;
  55. case '0': case '1': case '2': case '3': case '4':
  56. case '5': case '6': case '7': case '8': case '9':
  57. while('0'<=*s && *s<='9')
  58. *p++ = *s++;
  59. if(*s=='\'' || *s=='s')
  60. *p++ = *s++;
  61. break;
  62. case '(': case ')':
  63. case '\'': case '"':
  64. case '&': case '-': case '+':
  65. *p++ = *s++;
  66. break;
  67. case '*':
  68. if('0'<=s[1] && s[1]<='9'){
  69. int flag=0;
  70. s++;
  71. Pnumber:
  72. while('0'<=*s && *s<='9')
  73. *p++=*s++;
  74. if(s[0] == '-'){
  75. *p++ = *s++;
  76. flag++;
  77. goto Pnumber;
  78. }
  79. if(s[0]==',' && s[1]==' ' && '0'<=s[2] && s[2]<='9'){
  80. *p++ = *s++;
  81. s++; /* skip blank */
  82. flag++;
  83. goto Pnumber;
  84. }
  85. if(s[0] == '.'){
  86. if(s[1]=='.' && s[2]=='.'){
  87. *p++ = '-';
  88. s += 3;
  89. flag++;
  90. goto Pnumber;
  91. }
  92. *p++ = *s++;
  93. goto Pnumber;
  94. }
  95. p = append(p, "m star");
  96. if(flag)
  97. *p++ = 's';
  98. *p++ = ' ';
  99. break;
  100. }
  101. if(s[1] == '*'){
  102. if(s[2] == '*'){
  103. p = append(p, "triple star ");
  104. s += 3;
  105. }else{
  106. p = append(p, "double star ");
  107. s += 2;
  108. }
  109. break;
  110. }
  111. p = append(p, "star ");
  112. s++;
  113. break;
  114. }
  115. continue;
  116. }
  117. for(max=-1; desc[i][0] && desc[i][0][0]==*s; i++){
  118. k = matchlen(desc[i][0], s);
  119. if(k > max)
  120. max = k, j = i;
  121. }
  122. if(max == 0)
  123. goto Dup;
  124. s += max;
  125. for(k=0; desc[j][1][k]; k++)
  126. *p++=desc[j][1][k];
  127. if(*s == ' ')
  128. *p++ = *s++;
  129. else if(*s == ',')
  130. *p++ = ';', s++;
  131. else
  132. *p++ = ' ';
  133. }
  134. *p = 0;
  135. return buf;
  136. }
  137. void
  138. prdesc(char *s, char *desc[][2], short index[])
  139. {
  140. int c, j;
  141. if(index[0] == 0){
  142. index[0] = 1;
  143. for(c=1, j=0; c<128; c++)
  144. if(desc[j][0]==0 || desc[j][0][0]>c)
  145. index[c] = -1;
  146. else if(desc[j][0][0] == c){
  147. index[c] = j;
  148. while(desc[j][0] && desc[j][0][0] == c)
  149. j++;
  150. if(j >= NINDEX){
  151. fprint(2, "scat: internal error: too many prose entries\n");
  152. exits("NINDEX");
  153. }
  154. }
  155. }
  156. Bprint(&bout, "\t%s [%s]\n", prose(s, desc, index), s);
  157. }