prose.c 3.2 KB

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