URI:
       tconform.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
       ---
       tconform.c (2450B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <bio.h>
            4 #include <libsec.h>
            5 #include <ctype.h>
            6 #include "iso9660.h"
            7 
            8 /*
            9  * We keep an array sorted by bad atom pointer.
           10  * The theory is that since we don't free memory very often,
           11  * the array will be mostly sorted already and insertions will
           12  * usually be near the end, so we won't spend much time
           13  * keeping it sorted.
           14  */
           15 
           16 /*
           17  * Binary search a Tx list.
           18  * If no entry is found, return a pointer to
           19  * where a new such entry would go.
           20  */
           21 static Tx*
           22 txsearch(char *atom, Tx *t, int n)
           23 {
           24         while(n > 0) {
           25                 if(atom < t[n/2].bad)
           26                         n = n/2;
           27                 else if(atom > t[n/2].bad) {
           28                         t += n/2+1;
           29                         n -= (n/2+1);
           30                 } else
           31                         return &t[n/2];
           32         }
           33         return t;
           34 }
           35 
           36 void
           37 addtx(char *b, char *g)
           38 {
           39         Tx *t;
           40         Conform *c;
           41 
           42         if(map == nil)
           43                 map = emalloc(sizeof(*map));
           44         c = map;
           45 
           46         if(c->nt%32 == 0)
           47                 c->t = erealloc(c->t, (c->nt+32)*sizeof(c->t[0]));
           48         t = txsearch(b, c->t, c->nt);
           49         if(t < c->t+c->nt && t->bad == b) {
           50                 fprint(2, "warning: duplicate entry for %s in _conform.map\n", b);
           51                 return;
           52         }
           53 
           54         if(t != c->t+c->nt)
           55                 memmove(t+1, t, (c->t+c->nt - t)*sizeof(Tx));
           56         t->bad = b;
           57         t->good = g;
           58         c->nt++;
           59 }
           60 
           61 char*
           62 conform(char *s, int isdir)
           63 {
           64         Tx *t;
           65         char buf[10], *g;
           66         Conform *c;
           67 
           68         c = map;
           69         s = atom(s);
           70         if(c){
           71                 t = txsearch(s, c->t, c->nt);
           72                 if(t < c->t+c->nt && t->bad == s)
           73                         return t->good;
           74         }
           75 
           76         sprint(buf, "%c%.6d", isdir ? 'D' : 'F', c ? c->nt : 0);
           77         g = atom(buf);
           78         addtx(s, g);
           79         return g;
           80 }
           81 
           82 #ifdef NOTUSED
           83 static int
           84 isalldigit(char *s)
           85 {
           86         while(*s)
           87                 if(!isdigit(*s++))
           88                         return 0;
           89         return 1;
           90 }
           91 #endif
           92 
           93 static int
           94 goodcmp(const void *va, const void *vb)
           95 {
           96         Tx *a, *b;
           97 
           98         a = (Tx*)va;
           99         b = (Tx*)vb;
          100         return strcmp(a->good, b->good);
          101 }
          102 
          103 static int
          104 badatomcmp(const void *va, const void *vb)
          105 {
          106         Tx *a, *b;
          107 
          108         a = (Tx*)va;
          109         b = (Tx*)vb;
          110         if(a->good < b->good)
          111                 return -1;
          112         if(a->good > b->good)
          113                 return 1;
          114         return 0;
          115 }
          116 
          117 void
          118 wrconform(Cdimg *cd, int n, ulong *pblock, ulong *plength)
          119 {
          120         char buf[1024];
          121         int i;
          122         Conform *c;
          123 
          124         c = map;
          125         *pblock = cd->nextblock;
          126         if(c==nil || n==c->nt){
          127                 *plength = 0;
          128                 return;
          129         }
          130 
          131         Cwseek(cd, cd->nextblock*Blocksize);
          132         qsort(c->t, c->nt, sizeof(c->t[0]), goodcmp);
          133         for(i=n; i<c->nt; i++) {
          134                 snprint(buf, sizeof buf, "%s %s\n", c->t[i].good, c->t[i].bad);
          135                 Cwrite(cd, buf, strlen(buf));
          136         }
          137         qsort(c->t, c->nt, sizeof(c->t[0]), badatomcmp);
          138         *plength = Cwoffset(cd) - *pblock*Blocksize;
          139         chat("write _conform.map at %lud+%lud\n", *pblock, *plength);
          140         Cpadblock(cd);
          141 }