xref: /plan9/sys/src/cmd/scat/prose.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
43e12c5d1SDavid du Colombier #include "sky.h"
53e12c5d1SDavid du Colombier 
63e12c5d1SDavid du Colombier extern	Biobuf	bout;
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier char*
append(char * p,char * s)93e12c5d1SDavid du Colombier append(char *p, char *s)
103e12c5d1SDavid du Colombier {
113e12c5d1SDavid du Colombier 	while(*s)
123e12c5d1SDavid du Colombier 		*p++ = *s++;
133e12c5d1SDavid du Colombier 	return p;
143e12c5d1SDavid du Colombier }
153e12c5d1SDavid du Colombier 
163e12c5d1SDavid du Colombier int
matchlen(char * a,char * b)173e12c5d1SDavid du Colombier matchlen(char *a, char *b)
183e12c5d1SDavid du Colombier {
193e12c5d1SDavid du Colombier 	int n;
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier 	for(n=0; *a==*b; a++, b++, n++)
223e12c5d1SDavid du Colombier 		if(*a == 0)
233e12c5d1SDavid du Colombier 			return n;
243e12c5d1SDavid du Colombier 	if(*a == 0)
253e12c5d1SDavid du Colombier 		return n;
263e12c5d1SDavid du Colombier 	return 0;
273e12c5d1SDavid du Colombier }
283e12c5d1SDavid du Colombier 
293e12c5d1SDavid du Colombier char*
prose(char * s,char * desc[][2],short index[])303e12c5d1SDavid du Colombier prose(char *s, char *desc[][2], short index[])
313e12c5d1SDavid du Colombier {
323e12c5d1SDavid du Colombier 	static char buf[512];
333e12c5d1SDavid du Colombier 	char *p=buf;
343e12c5d1SDavid du Colombier 	int i, j, k, max;
353e12c5d1SDavid du Colombier 
363e12c5d1SDavid du Colombier 	j = 0;
373e12c5d1SDavid du Colombier 	while(*s){
38*219b2ee8SDavid du Colombier 		if(p >= buf+sizeof buf)
39*219b2ee8SDavid du Colombier 			abort();
403e12c5d1SDavid du Colombier 		if(*s == ' '){
41*219b2ee8SDavid du Colombier 			if(p>buf && p[-1]!=' ')
42*219b2ee8SDavid du Colombier 				*p++ = ' ';
43*219b2ee8SDavid du Colombier 			s++;
443e12c5d1SDavid du Colombier 			continue;
453e12c5d1SDavid du Colombier 		}
463e12c5d1SDavid du Colombier 		if(*s == ','){
473e12c5d1SDavid du Colombier 			*p++ = ';', s++;
483e12c5d1SDavid du Colombier 			continue;
493e12c5d1SDavid du Colombier 		}
503e12c5d1SDavid du Colombier 		if(s[0]=='M' && '0'<=s[1] && s[1]<='9'){	/* Messier tag */
513e12c5d1SDavid du Colombier 			*p++ = *s++;
523e12c5d1SDavid du Colombier 			continue;	/* below will copy the number */
533e12c5d1SDavid du Colombier 		}
543e12c5d1SDavid du Colombier 		if((i=index[*s]) == -1){
553e12c5d1SDavid du Colombier 	Dup:
563e12c5d1SDavid du Colombier 			switch(*s){
573e12c5d1SDavid du Colombier 			default:
583e12c5d1SDavid du Colombier 				while(*s && *s!=',' && *s!=' ')
593e12c5d1SDavid du Colombier 					*p++=*s++;
603e12c5d1SDavid du Colombier 				break;
613e12c5d1SDavid du Colombier 
623e12c5d1SDavid du Colombier 			case '0': case '1': case '2': case '3': case '4':
633e12c5d1SDavid du Colombier 			case '5': case '6': case '7': case '8': case '9':
643e12c5d1SDavid du Colombier 				while('0'<=*s && *s<='9')
653e12c5d1SDavid du Colombier 					*p++ = *s++;
66*219b2ee8SDavid du Colombier 				if(*s=='\'' || *s=='s')
67*219b2ee8SDavid du Colombier 					*p++ = *s++;
683e12c5d1SDavid du Colombier 				break;
693e12c5d1SDavid du Colombier 
703e12c5d1SDavid du Colombier 			case '(': case ')':
713e12c5d1SDavid du Colombier 			case '\'': case '"':
723e12c5d1SDavid du Colombier 			case '&': case '-': case '+':
733e12c5d1SDavid du Colombier 				*p++ = *s++;
743e12c5d1SDavid du Colombier 				break;
753e12c5d1SDavid du Colombier 
763e12c5d1SDavid du Colombier 			case '*':
773e12c5d1SDavid du Colombier 				if('0'<=s[1] && s[1]<='9'){
783e12c5d1SDavid du Colombier 					int flag=0;
793e12c5d1SDavid du Colombier 					s++;
803e12c5d1SDavid du Colombier 				Pnumber:
813e12c5d1SDavid du Colombier 					while('0'<=*s && *s<='9')
823e12c5d1SDavid du Colombier 						*p++=*s++;
833e12c5d1SDavid du Colombier 					if(s[0] == '-'){
843e12c5d1SDavid du Colombier 						*p++ = *s++;
853e12c5d1SDavid du Colombier 						flag++;
863e12c5d1SDavid du Colombier 						goto Pnumber;
873e12c5d1SDavid du Colombier 					}
88*219b2ee8SDavid du Colombier 					if(s[0]==',' && s[1]==' ' && '0'<=s[2] && s[2]<='9'){
89*219b2ee8SDavid du Colombier 						*p++ = *s++;
90*219b2ee8SDavid du Colombier 						s++;	/* skip blank */
91*219b2ee8SDavid du Colombier 						flag++;
92*219b2ee8SDavid du Colombier 						goto Pnumber;
93*219b2ee8SDavid du Colombier 					}
943e12c5d1SDavid du Colombier 					if(s[0] == '.'){
953e12c5d1SDavid du Colombier 						if(s[1]=='.' && s[2]=='.'){
963e12c5d1SDavid du Colombier 							*p++ = '-';
973e12c5d1SDavid du Colombier 							s += 3;
983e12c5d1SDavid du Colombier 							flag++;
993e12c5d1SDavid du Colombier 							goto Pnumber;
1003e12c5d1SDavid du Colombier 						}
1013e12c5d1SDavid du Colombier 						*p++ = *s++;
1023e12c5d1SDavid du Colombier 						goto Pnumber;
1033e12c5d1SDavid du Colombier 					}
1043e12c5d1SDavid du Colombier 					p = append(p, "m star");
1053e12c5d1SDavid du Colombier 					if(flag)
1063e12c5d1SDavid du Colombier 						*p++ = 's';
1073e12c5d1SDavid du Colombier 					*p++ = ' ';
1083e12c5d1SDavid du Colombier 					break;
1093e12c5d1SDavid du Colombier 				}
1103e12c5d1SDavid du Colombier 				if(s[1] == '*'){
1113e12c5d1SDavid du Colombier 					if(s[2] == '*'){
1123e12c5d1SDavid du Colombier 						p = append(p, "triple star ");
1133e12c5d1SDavid du Colombier 						s += 3;
1143e12c5d1SDavid du Colombier 					}else{
1153e12c5d1SDavid du Colombier 						p = append(p, "double star ");
1163e12c5d1SDavid du Colombier 						s += 2;
1173e12c5d1SDavid du Colombier 					}
1183e12c5d1SDavid du Colombier 					break;
1193e12c5d1SDavid du Colombier 				}
1203e12c5d1SDavid du Colombier 				p = append(p, "star ");
1213e12c5d1SDavid du Colombier 				s++;
1223e12c5d1SDavid du Colombier 				break;
1233e12c5d1SDavid du Colombier 			}
1243e12c5d1SDavid du Colombier 			continue;
1253e12c5d1SDavid du Colombier 		}
1263e12c5d1SDavid du Colombier 		for(max=-1; desc[i][0] && desc[i][0][0]==*s; i++){
1273e12c5d1SDavid du Colombier 			k = matchlen(desc[i][0], s);
1283e12c5d1SDavid du Colombier 			if(k > max)
1293e12c5d1SDavid du Colombier 				max = k, j = i;
1303e12c5d1SDavid du Colombier 		}
1313e12c5d1SDavid du Colombier 		if(max == 0)
1323e12c5d1SDavid du Colombier 			goto Dup;
1333e12c5d1SDavid du Colombier 		s += max;
1343e12c5d1SDavid du Colombier 		for(k=0; desc[j][1][k]; k++)
1353e12c5d1SDavid du Colombier 			*p++=desc[j][1][k];
1363e12c5d1SDavid du Colombier 		if(*s == ' ')
1373e12c5d1SDavid du Colombier 			*p++ = *s++;
1383e12c5d1SDavid du Colombier 		else if(*s == ',')
1393e12c5d1SDavid du Colombier 			*p++ = ';', s++;
1403e12c5d1SDavid du Colombier 		else
1413e12c5d1SDavid du Colombier 			*p++ = ' ';
1423e12c5d1SDavid du Colombier 	}
1433e12c5d1SDavid du Colombier 	*p = 0;
1443e12c5d1SDavid du Colombier 	return buf;
1453e12c5d1SDavid du Colombier }
1463e12c5d1SDavid du Colombier 
1473e12c5d1SDavid du Colombier void
prdesc(char * s,char * desc[][2],short index[])1483e12c5d1SDavid du Colombier prdesc(char *s, char *desc[][2], short index[])
1493e12c5d1SDavid du Colombier {
1503e12c5d1SDavid du Colombier 	int c, j;
1513e12c5d1SDavid du Colombier 
1523e12c5d1SDavid du Colombier 	if(index[0] == 0){
1533e12c5d1SDavid du Colombier 		index[0] = 1;
1543e12c5d1SDavid du Colombier 		for(c=1, j=0; c<128; c++)
1553e12c5d1SDavid du Colombier 			if(desc[j][0]==0 || desc[j][0][0]>c)
1563e12c5d1SDavid du Colombier 				index[c] = -1;
1573e12c5d1SDavid du Colombier 			else if(desc[j][0][0] == c){
1583e12c5d1SDavid du Colombier 				index[c] = j;
1593e12c5d1SDavid du Colombier 				while(desc[j][0] && desc[j][0][0] == c)
1603e12c5d1SDavid du Colombier 					j++;
1613e12c5d1SDavid du Colombier 				if(j >= NINDEX){
1623e12c5d1SDavid du Colombier 					fprint(2, "scat: internal error: too many prose entries\n");
1633e12c5d1SDavid du Colombier 					exits("NINDEX");
1643e12c5d1SDavid du Colombier 				}
1653e12c5d1SDavid du Colombier 			}
1663e12c5d1SDavid du Colombier 	}
1673e12c5d1SDavid du Colombier 	Bprint(&bout, "\t%s [%s]\n", prose(s, desc, index), s);
1683e12c5d1SDavid du Colombier }
169