Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#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[*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);
}