aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/scat/prose.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/scat/prose.c')
-rw-r--r--src/cmd/scat/prose.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/cmd/scat/prose.c b/src/cmd/scat/prose.c
new file mode 100644
index 00000000..17a09750
--- /dev/null
+++ b/src/cmd/scat/prose.c
@@ -0,0 +1,168 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include "sky.h"
+
+extern Biobuf bout;
+
+char*
+append(char *p, char *s)
+{
+ while(*s)
+ *p++ = *s++;
+ return p;
+}
+
+int
+matchlen(char *a, char *b)
+{
+ int n;
+
+ for(n=0; *a==*b; a++, b++, n++)
+ if(*a == 0)
+ return n;
+ if(*a == 0)
+ return n;
+ return 0;
+}
+
+char*
+prose(char *s, char *desc[][2], short index[])
+{
+ static char buf[512];
+ char *p=buf;
+ int i, j, k, max;
+
+ j = 0;
+ while(*s){
+ if(p >= buf+sizeof buf)
+ abort();
+ if(*s == ' '){
+ if(p>buf && p[-1]!=' ')
+ *p++ = ' ';
+ s++;
+ continue;
+ }
+ if(*s == ','){
+ *p++ = ';', s++;
+ continue;
+ }
+ if(s[0]=='M' && '0'<=s[1] && s[1]<='9'){ /* Messier tag */
+ *p++ = *s++;
+ continue; /* below will copy the number */
+ }
+ if((i=index[(uchar)*s]) == -1){
+ Dup:
+ switch(*s){
+ default:
+ while(*s && *s!=',' && *s!=' ')
+ *p++=*s++;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ while('0'<=*s && *s<='9')
+ *p++ = *s++;
+ if(*s=='\'' || *s=='s')
+ *p++ = *s++;
+ break;
+
+ case '(': case ')':
+ case '\'': case '"':
+ case '&': case '-': case '+':
+ *p++ = *s++;
+ break;
+
+ case '*':
+ if('0'<=s[1] && s[1]<='9'){
+ int flag=0;
+ s++;
+ Pnumber:
+ while('0'<=*s && *s<='9')
+ *p++=*s++;
+ if(s[0] == '-'){
+ *p++ = *s++;
+ flag++;
+ goto Pnumber;
+ }
+ if(s[0]==',' && s[1]==' ' && '0'<=s[2] && s[2]<='9'){
+ *p++ = *s++;
+ s++; /* skip blank */
+ flag++;
+ goto Pnumber;
+ }
+ if(s[0] == '.'){
+ if(s[1]=='.' && s[2]=='.'){
+ *p++ = '-';
+ s += 3;
+ flag++;
+ goto Pnumber;
+ }
+ *p++ = *s++;
+ goto Pnumber;
+ }
+ p = append(p, "m star");
+ if(flag)
+ *p++ = 's';
+ *p++ = ' ';
+ break;
+ }
+ if(s[1] == '*'){
+ if(s[2] == '*'){
+ p = append(p, "triple star ");
+ s += 3;
+ }else{
+ p = append(p, "double star ");
+ s += 2;
+ }
+ break;
+ }
+ p = append(p, "star ");
+ s++;
+ break;
+ }
+ continue;
+ }
+ for(max=-1; desc[i][0] && desc[i][0][0]==*s; i++){
+ k = matchlen(desc[i][0], s);
+ if(k > max)
+ max = k, j = i;
+ }
+ if(max == 0)
+ goto Dup;
+ s += max;
+ for(k=0; desc[j][1][k]; k++)
+ *p++=desc[j][1][k];
+ if(*s == ' ')
+ *p++ = *s++;
+ else if(*s == ',')
+ *p++ = ';', s++;
+ else
+ *p++ = ' ';
+ }
+ *p = 0;
+ return buf;
+}
+
+void
+prdesc(char *s, char *desc[][2], short index[])
+{
+ int c, j;
+
+ if(index[0] == 0){
+ index[0] = 1;
+ for(c=1, j=0; c<128; c++)
+ if(desc[j][0]==0 || desc[j][0][0]>c)
+ index[c] = -1;
+ else if(desc[j][0][0] == c){
+ index[c] = j;
+ while(desc[j][0] && desc[j][0][0] == c)
+ j++;
+ if(j >= NINDEX){
+ fprint(2, "scat: internal error: too many prose entries\n");
+ exits("NINDEX");
+ }
+ }
+ }
+ Bprint(&bout, "\t%s [%s]\n", prose(s, desc, index), s);
+}