URI:
       trobert.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       trobert.c (7131B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <bio.h>
            4 #include "dict.h"
            5 
            6 /*
            7  * Robert Électronique.
            8  */
            9 
           10 enum
           11 {
           12         CIT = MULTIE+1,        /* citation ptr followed by long int and ascii label */
           13         BROM,                /* bold roman */
           14         ITON,                /* start italic */
           15         ROM,                /* roman */
           16         SYM,                /* symbol font? */
           17         HEL,                /* helvetica */
           18         BHEL,                /* helvetica bold */
           19         SMALL,                /* smaller? */
           20         ITOFF,                /* end italic */
           21         SUP,                /* following character is superscript */
           22         SUB                /* following character is subscript */
           23 };
           24 
           25 static Rune intab[256] = {
           26         /*0*/        /*1*/        /*2*/        /*3*/        /*4*/        /*5*/        /*6*/        /*7*/
           27 /*00*/        NONE,        0x263a,        0x263b,        0x2665,        0x2666,        0x2663,        0x2660,        0x2022,
           28         0x25d8,        0x298,'\n',        0x2642,        0x2640,        0x266a,        0x266b,        0x203b,
           29 /*10*/        0x21e8,        0x21e6,        0x2195,        0x203c,        0xb6,        0xa7,        0x2043,        0x21a8,
           30         0x2191,        0x2193,        0x2192,        0x2190,        0x2319,        0x2194,        0x25b4,        0x25be,
           31 /*20*/        0x20,        0x21,        0x22,        0x23,        0x24,        0x25,        0x26,'\'',
           32         0x28,        0x29,        0x2a,        0x2b,        0x2c,        0x2d,        0x2e,        0x2f,
           33 /*30*/        0x30,        0x31,        0x32,        0x33,        0x34,        0x35,        0x36,        0x37,
           34         0x38,        0x39,        0x3a,        0x3b,        0x3c,        0x3d,        0x3e,        0x3f,
           35 /*40*/        0x40,        0x41,        0x42,        0x43,        0x44,        0x45,        0x46,        0x47,
           36         0x48,        0x49,        0x4a,        0x4b,'L',        0x4d,        0x4e,        0x4f,
           37 /*50*/        0x50,        0x51,        0x52,        0x53,        0x54,        0x55,        0x56,        0x57,
           38         0x58,        0x59,        0x5a,        0x5b,'\\',        0x5d,        0x5e,        0x5f,
           39 /*60*/        0x60,        0x61,        0x62,        0x63,        0x64,        0x65,        0x66,        0x67,
           40         0x68,        0x69,        0x6a,        0x6b,        0x6c,        0x6d,        0x6e,        0x6f,
           41 /*70*/        0x70,        0x71,        0x72,        0x73,        0x74,        0x75,        0x76,        0x77,
           42         0x78,        0x79,        0x7a,        0x7b,        0x7c,        0x7d,        0x7e,        0x7f,
           43 /*80*/        0xc7,        0xfc,        0xe9,        0xe2,        0xe4,        0xe0,        0xe5,        0xe7,
           44         0xea,        0xeb,        0xe8,        0xef,        0xee,        0xec,        0xc4,        0xc5,
           45 /*90*/        0xc9,        0xe6,        0xc6,        0xf4,        0xf6,        0xf2,        0xfb,        0xf9,
           46         0xff,        0xd6,        0xdc,        0xa2,        0xa3,        0xa5,        0x20a7,        0x283,
           47 /*a0*/        0xe1,        0xed,        0xf3,        0xfa,        0xf1,        0xd1,        0xaa,        0xba,
           48         0xbf,        0x2310,        0xac,        0xbd,        0xbc,        0xa1,        0xab,        0xbb,
           49 /*b0*/        NONE,        NONE,        NONE,        NONE,        NONE,        NONE,        NONE,        NONE,
           50         NONE,        NONE,        NONE,        NONE,        NONE,        NONE,        NONE,        NONE,
           51 /*c0*/        NONE,        NONE,        NONE,        NONE,        NONE,        NONE,        NONE,        NONE,
           52         CIT,        BROM,        NONE,        ITON,        ROM,        SYM,        HEL,        BHEL,
           53 /*d0*/        NONE,        SMALL,        ITOFF,        SUP,        SUB,        NONE,        NONE,        NONE,
           54         NONE,        NONE,        NONE,        NONE,        NONE,        NONE,        NONE,        NONE,
           55 /*e0*/        0x3b1,        0xdf,        0x3b3,        0x3c0,        0x3a3,        0x3c3,        0xb5,        0x3c4,
           56         0x3a6,        0x398,        0x3a9,        0x3b4,        0x221e,        0xd8,        0x3b5,        0x2229,
           57 /*f0*/        0x2261,        0xb1,        0x2265,        0x2264,        0x2320,        0x2321,        0xf7,        0x2248,
           58         0xb0,        0x2219,        0xb7,        0x221a,        0x207f,        0xb2,        0x220e,        0xa0
           59 };
           60 
           61 static Rune suptab[256];
           62 
           63 static void
           64 initsuptab(void)
           65 {
           66         suptab['0']= 0x2070;        suptab['1']= 0x2071;        suptab['2']= 0x2072;        suptab['3']= 0x2073;
           67         suptab['4']= 0x2074;        suptab['5']= 0x2075;        suptab['6']= 0x2076;        suptab['7']= 0x2077;
           68         suptab['8']= 0x2078;        suptab['9']= 0x2079;        suptab['+']= 0x207a;        suptab['-']= 0x207b;
           69         suptab['=']= 0x207c;        suptab['(']= 0x207d;        suptab[')']= 0x207e;        suptab['a']= 0xaa;
           70         suptab['n']= 0x207f;        suptab['o']= 0xba;
           71 }
           72 
           73 static Rune subtab[256];
           74 
           75 static void
           76 initsubtab(void)
           77 {
           78         subtab['0']= 0x2080;        subtab['1']= 0x2081;        subtab['2']= 0x2082;        subtab['3']= 0x2083;
           79         subtab['4']= 0x2084;        subtab['5']= 0x2085;        subtab['6']= 0x2086;        subtab['7']= 0x2087;
           80         subtab['8']= 0x2088;        subtab['9']= 0x2089;        subtab['+']= 0x208a;        subtab['-']= 0x208b;
           81         subtab['=']= 0x208c;        subtab['(']= 0x208d;        subtab[')']= 0x208e;
           82 }
           83 
           84 #define        GSHORT(p)        (((p)[0]<<8) | (p)[1])
           85 #define        GLONG(p)        (((p)[0]<<24) | ((p)[1]<<16) | ((p)[2]<<8) | (p)[3])
           86 
           87 static char        cfile[] = "robert/cits.rob";
           88 static char        dfile[] = "robert/defs.rob";
           89 static char        efile[] = "robert/etym.rob";
           90 static char        kfile[] = "robert/_phon";
           91 
           92 static Biobuf *        cb;
           93 static Biobuf *        db;
           94 static Biobuf *        eb;
           95 
           96 static Biobuf *        Bouvrir(char*);
           97 static void        citation(int, int);
           98 static void        robertprintentry(Entry*, Entry*, int);
           99 
          100 void
          101 robertindexentry(Entry e, int cmd)
          102 {
          103         uchar *p = (uchar *)e.start;
          104         long ea, el, da, dl, fa;
          105         Entry def, etym;
          106 
          107         ea = GLONG(&p[0]);
          108         el = GSHORT(&p[4]);
          109         da = GLONG(&p[6]);
          110         dl = GSHORT(&p[10]);
          111         fa = GLONG(&p[12]);
          112         USED(fa);
          113 
          114         if(db == 0)
          115                 db = Bouvrir(dfile);
          116         def.start = malloc(dl+1);
          117         def.end = def.start + dl;
          118         def.doff = da;
          119         Bseek(db, da, 0);
          120         Bread(db, def.start, dl);
          121         *def.end = 0;
          122         if(cmd == 'h'){
          123                 robertprintentry(&def, 0, cmd);
          124         }else{
          125                 if(eb == 0)
          126                         eb = Bouvrir(efile);
          127                 etym.start = malloc(el+1);
          128                 etym.end = etym.start + el;
          129                 etym.doff = ea;
          130                 Bseek(eb, ea, 0);
          131                 Bread(eb, etym.start, el);
          132                 *etym.end = 0;
          133                 robertprintentry(&def, &etym, cmd);
          134                 free(etym.start);
          135         }
          136         free(def.start);
          137 }
          138 
          139 static void
          140 robertprintentry(Entry *def, Entry *etym, int cmd)
          141 {
          142         uchar *p, *pe;
          143         Rune r; int c, n;
          144         int baseline = 0;
          145         int lineno = 0;
          146         int cit = 0;
          147 
          148         if(suptab['0'] == 0)
          149                 initsuptab();
          150         if(subtab['0'] == 0)
          151                 initsubtab();
          152 
          153         p = (uchar *)def->start;
          154         pe = (uchar *)def->end;
          155         while(p < pe){
          156                 if(cmd == 'r'){
          157                         outchar(*p++);
          158                         continue;
          159                 }
          160                 c = *p++;
          161                 switch(r = intab[c]){        /* assign = */
          162                 case BROM:
          163                 case ITON:
          164                 case ROM:
          165                 case SYM:
          166                 case HEL:
          167                 case BHEL:
          168                 case SMALL:
          169                 case ITOFF:
          170                 case NONE:
          171                         if(debug)
          172                                 outprint("\\%.2ux", c);
          173                         baseline = 0;
          174                         break;
          175 
          176                 case SUP:
          177                         baseline = 1;
          178                         break;
          179 
          180                 case SUB:
          181                         baseline = -1;
          182                         break;
          183 
          184                 case CIT:
          185                         n = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
          186                         p += 4;
          187                         if(debug)
          188                                 outprint("[%d]", n);
          189                         while(*p == ' ' || ('0'<=*p && *p<='9') || *p == '.'){
          190                                 if(debug)
          191                                         outchar(*p);
          192                                 ++p;
          193                         }
          194                         ++cit;
          195                         outnl(2);
          196                         citation(n, cmd);
          197                         baseline = 0;
          198                         break;
          199 
          200                 case '\n':
          201                         outnl(0);
          202                         baseline = 0;
          203                         ++lineno;
          204                         break;
          205 
          206                 default:
          207                         if(baseline > 0 && r < nelem(suptab))
          208                                 r = suptab[r];
          209                         else if(baseline < 0 && r < nelem(subtab))
          210                                 r = subtab[r];
          211                         if(cit){
          212                                 outchar('\n');
          213                                 cit = 0;
          214                         }
          215                         outrune(r);
          216                         baseline = 0;
          217                         break;
          218                 }
          219                 if(r == '\n'){
          220                         if(cmd == 'h')
          221                                 break;
          222                         if(lineno == 1 && etym)
          223                                 robertprintentry(etym, 0, cmd);
          224                 }
          225         }
          226         outnl(0);
          227 }
          228 
          229 static void
          230 citation(int addr, int cmd)
          231 {
          232         Entry cit;
          233 
          234         if(cb == 0)
          235                 cb = Bouvrir(cfile);
          236         Bseek(cb, addr, 0);
          237         cit.start = Brdline(cb, 0xc8);
          238         cit.end = cit.start + Blinelen(cb) - 1;
          239         cit.doff = addr;
          240         *cit.end = 0;
          241         robertprintentry(&cit, 0, cmd);
          242 }
          243 
          244 long
          245 robertnextoff(long fromoff)
          246 {
          247         return (fromoff & ~15) + 16;
          248 }
          249 
          250 void
          251 robertprintkey(void)
          252 {
          253         Biobuf *db;
          254         char *l;
          255 
          256         db = Bouvrir(kfile);
          257         while(l = Brdline(db, '\n'))        /* assign = */
          258                 Bwrite(bout, l, Blinelen(db));
          259         Bterm(db);
          260 }
          261 
          262 void
          263 robertflexentry(Entry e, int cmd)
          264 {
          265         uchar *p, *pe;
          266         Rune r; int c;
          267         int lineno = 1;
          268 
          269         p = (uchar *)e.start;
          270         pe = (uchar *)e.end;
          271         while(p < pe){
          272                 if(cmd == 'r'){
          273                         Bputc(bout, *p++);
          274                         continue;
          275                 }
          276                 c = *p++;
          277                 r = intab[c];
          278                 if(r == '$')
          279                         r = '\n';
          280                 if(r == '\n'){
          281                         ++lineno;
          282                         if(cmd == 'h' && lineno > 2)
          283                                 break;
          284                 }
          285                 if(cmd == 'h' && lineno < 2)
          286                         continue;
          287                 if(r > MULTIE){
          288                         if(debug)
          289                                 Bprint(bout, "\\%.2ux", c);
          290                         continue;
          291                 }
          292                 if(r < Runeself)
          293                         Bputc(bout, r);
          294                 else
          295                         Bputrune(bout, r);
          296         }
          297         outnl(0);
          298 }
          299 
          300 long
          301 robertnextflex(long fromoff)
          302 {
          303         int c;
          304 
          305         if(Bseek(bdict, fromoff, 0) < 0)
          306                 return -1;
          307         while((c = Bgetc(bdict)) >= 0){
          308                 if(c == '$')
          309                         return Boffset(bdict);
          310         }
          311         return -1;
          312 }
          313 
          314 static Biobuf *
          315 Bouvrir(char *fichier)
          316 {
          317         Biobuf *db;
          318 
          319         fichier = dictfile(fichier);
          320         db = Bopen(fichier, OREAD);
          321         if(db == 0){
          322                 fprint(2, "%s: impossible d'ouvrir %s: %r\n", argv0, fichier);
          323                 exits("ouvrir");
          324         }
          325         return db;
          326 }