home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / source / dict.m < prev    next >
Encoding:
Text File  |  1996-08-08  |  8.2 KB  |  584 lines

  1.  
  2. #import "qedefs.h"
  3.  
  4. @implementation Dict
  5.  
  6. - init
  7. {
  8.     [super    initCount:0
  9.         elementSize:sizeof(dict_t)
  10.         description:NULL];
  11.     return self;    
  12. }
  13.  
  14. - print
  15. {
  16.     int    i;
  17.     dict_t    *d;
  18.     
  19.     for (i=0 ; i<numElements ; i++)
  20.     {
  21.         d = [self elementAt: i];
  22.         printf ("%s : %s\n",d->key, d->value);
  23.     }
  24.     return self;
  25. }
  26.  
  27. /*
  28. ===========
  29. copyFromZone
  30.  
  31. JDC
  32. ===========
  33. */
  34. - copyFromZone:(NXZone *)zone
  35. {
  36.     id    new;
  37.     int    i;
  38.     dict_t    *d;
  39.     char    *old;
  40.     
  41.     new = [super copyFromZone: zone];
  42.     for (i=0 ; i<numElements ; i++)
  43.     {
  44.         d = [self elementAt: i];
  45.         old = d->key;
  46.         d->key = malloc(strlen(old)+1);    
  47.         strcpy (d->key, old);
  48.         
  49.         old = d->value;
  50.         d->value = malloc(strlen(old)+1);    
  51.         strcpy (d->value, old);
  52.     }
  53.     
  54.     return new;
  55. }
  56.  
  57. - initFromFile:(FILE *)fp
  58. {
  59.     [self init];
  60.     return [self parseBraceBlock:fp];
  61. }
  62.  
  63. //===============================================
  64. //
  65. //    Dictionary pair functions
  66. //
  67. //===============================================
  68.  
  69. //
  70. //    Write a { } block out to a FILE*
  71. //
  72. - writeBlockTo:(FILE *)fp
  73. {
  74.     int        max;
  75.     int        i;
  76.     dict_t    *d;
  77.     
  78.     fprintf(fp,"{\n");
  79.     max = [super count];
  80.     for (i = 0;i < max;i++)
  81.     {
  82.         d = [super elementAt:i];
  83.         fprintf(fp,"\t{\"%s\"\t\"%s\"}\n",d->key,d->value);
  84.     }
  85.     fprintf(fp,"}\n");
  86.     
  87.     return self;
  88. }
  89.  
  90. //
  91. //    Write a single { } block out
  92. //
  93. - writeFile:(char *)path
  94. {
  95.     FILE    *fp;
  96.     
  97.     fp = fopen(path,"w+t");
  98.     if (fp != NULL)
  99.     {
  100.         printf("Writing dictionary file %s.\n",path);
  101.         fprintf(fp,"// QE_Project file %s\n",path);
  102.         [self writeBlockTo:fp];
  103.         fclose(fp);
  104.     }
  105.     else
  106.     {
  107.         printf("Error writing %s!\n",path);
  108.         return NULL;
  109.     }
  110.  
  111.     return self;
  112. }
  113.  
  114. //===============================================
  115. //
  116. //    Utility methods
  117. //
  118. //===============================================
  119.  
  120. //
  121. //    Find a keyword in storage
  122. //    Returns * to dict_t, otherwise NULL
  123. //
  124. - (dict_t *) findKeyword:(char *)key
  125. {    
  126.     int        max;
  127.     int        i;
  128.     dict_t    *d;
  129.     
  130.     max = [super count];
  131.     for (i = 0;i < max;i++)
  132.     {
  133.         d = [super elementAt:i];
  134.         if (!strcmp(d->key,key))
  135.             return d;
  136.     }
  137.     
  138.     return NULL;
  139. }
  140.  
  141. //
  142. //    Change a keyword's string
  143. //
  144. - changeStringFor:(char *)key to:(char *)value
  145. {
  146.     dict_t    *d;
  147.     dict_t    newd;
  148.     
  149.     d = [self findKeyword:key];
  150.     if (d != NULL)
  151.     {
  152.         free(d->value);
  153.         d->value = malloc(strlen(value)+1);
  154.         strcpy(d->value,value);
  155.     }
  156.     else
  157.     {
  158.         newd.key = malloc(strlen(key)+1);
  159.         strcpy(newd.key,key);
  160.         newd.value = malloc(strlen(value)+1);
  161.         strcpy(newd.value,value);
  162.         [self addElement:&newd];
  163.     }
  164.     return self;
  165. }
  166.  
  167. //
  168. //    Search for keyword, return the string *
  169. //
  170. - (char *)getStringFor:(char *)name
  171. {
  172.     dict_t    *d;
  173.     
  174.     d = [self findKeyword:name];
  175.     if (d != NULL)
  176.         return d->value;
  177.     
  178.     return "";
  179. }
  180.  
  181. //
  182. //    Search for keyword, return the value
  183. //
  184. - (unsigned int)getValueFor:(char *)name
  185. {
  186.     dict_t    *d;
  187.     
  188.     d = [self findKeyword:name];
  189.     if (d != NULL)
  190.         return atol(d->value);
  191.     
  192.     return 0;
  193. }
  194.  
  195. //
  196. //    Return # of units in keyword's value
  197. //
  198. - (int) getValueUnits:(char *)key
  199. {
  200.     id        temp;
  201.     int        count;
  202.     
  203.     temp = [self parseMultipleFrom:key];
  204.     count = [temp count];
  205.     [temp free];
  206.     
  207.     return count;
  208. }
  209.  
  210. //
  211. //    Convert List to string
  212. //
  213. - (char *)convertListToString:(id)list
  214. {
  215.     int        i;
  216.     int        max;
  217.     char    tempstr[4096];
  218.     char    *s;
  219.     char    *newstr;
  220.     
  221.     max = [list count];
  222.     tempstr[0] = 0;
  223.     for (i = 0;i < max;i++)
  224.     {
  225.         s = [list elementAt:i];
  226.         strcat(tempstr,s);
  227.         strcat(tempstr,"  ");
  228.     }
  229.     newstr = malloc(strlen(tempstr)+1);
  230.     strcpy(newstr,tempstr);
  231.     
  232.     return newstr;
  233. }
  234.  
  235. //
  236. // JDC: I wrote this to simplify removing vectors
  237. //
  238. - removeKeyword:(char *)key
  239. {
  240.     dict_t    *d;
  241.  
  242.     d = [self findKeyword:key];
  243.     if (d == NULL)
  244.         return self;
  245.     [self removeElementAt:d - (dict_t*)dataPtr];
  246.     return self;
  247. }
  248.  
  249. //
  250. //    Delete string from keyword's value
  251. //
  252. - delString:(char *)string fromValue:(char *)key
  253. {
  254.     id        temp;
  255.     int        count;
  256.     int        i;
  257.     char    *s;
  258.     dict_t    *d;
  259.     
  260.     d = [self findKeyword:key];
  261.     if (d == NULL)
  262.         return NULL;
  263.     temp = [self parseMultipleFrom:key];
  264.     count = [temp count];
  265.     for (i = 0;i < count;i++)
  266.     {
  267.         s = [temp elementAt:i];
  268.         if (!strcmp(s,string))
  269.         {
  270.             [temp removeElementAt:i];
  271.             free(d->value);
  272.             d->value = [self convertListToString:temp];
  273.             [temp free];
  274.             
  275.             break;
  276.         }
  277.     }
  278.     return self;
  279. }
  280.  
  281. //
  282. //    Add string to keyword's value
  283. //
  284. - addString:(char *)string toValue:(char *)key
  285. {
  286.     char    *newstr;
  287.     char    spacing[] = "\t";
  288.     dict_t    *d;
  289.     
  290.     d = [self findKeyword:key];
  291.     if (d == NULL)
  292.         return NULL;
  293.     newstr = malloc(strlen(string) + strlen(d->value) + strlen(spacing) + 1);
  294.     strcpy(newstr,d->value);
  295.     strcat(newstr,spacing);
  296.     strcat(newstr,string);
  297.     free(d->value);
  298.     d->value = newstr;
  299.     
  300.     return self;
  301. }
  302.  
  303. //===============================================
  304. //
  305. //    Use these for multiple parameters in a keyword value
  306. //
  307. //===============================================
  308. char    *searchStr;
  309. char    item[4096];
  310.  
  311. - setupMultiple:(char *)value
  312. {
  313.     searchStr = value;
  314.     return self;
  315. }
  316.  
  317. - (char *)getNextParameter
  318. {
  319.     char    *s;
  320.     
  321.     if (!searchStr)
  322.         return NULL;
  323.     strcpy(item,searchStr);
  324.     s = FindWhitespcInBuffer(item);    
  325.     if (!*s)
  326.         searchStr = NULL;
  327.     else
  328.     {
  329.         *s = 0;
  330.         searchStr = FindNonwhitespcInBuffer(s+1);
  331.     }
  332.     return item;
  333. }
  334.  
  335. //
  336. //    Parses a keyvalue string & returns a Storage full of those items
  337. //
  338. - (id) parseMultipleFrom:(char *)key
  339. {
  340.     #define    ITEMSIZE    128
  341.     id        stuff;
  342.     char    string[ITEMSIZE];
  343.     char    *s;
  344.     
  345.     s = [self getStringFor:key];
  346.     if (s == NULL)
  347.         return NULL;
  348.         
  349.     stuff = [[Storage alloc]
  350.             initCount:0
  351.             elementSize:ITEMSIZE
  352.             description:NULL];
  353.             
  354.     [self setupMultiple:s];
  355.     while((s = [self getNextParameter]))
  356.     {
  357.         bzero(string,ITEMSIZE);
  358.         strcpy(string,s);
  359.         [stuff addElement:string];
  360.     }
  361.     
  362.     return stuff;
  363. }
  364.  
  365. //===============================================
  366. //
  367. //    Dictionary pair parsing
  368. //
  369. //===============================================
  370.  
  371. //
  372. //    parse all keyword/value pairs within { } 's
  373. //
  374. - (id) parseBraceBlock:(FILE *)fp
  375. {
  376.     int        c;
  377.     dict_t    pair;
  378.     char    string[1024];
  379.     
  380.     c = FindBrace(fp);
  381.     if (c == -1)
  382.         return NULL;
  383.         
  384.     while((c = FindBrace(fp)) != '}')
  385.     {
  386.         if (c == -1)
  387.             return NULL;
  388. //        c = FindNonwhitespc(fp);
  389. //        if (c == -1)
  390. //            return NULL;
  391. //        CopyUntilWhitespc(fp,string);
  392.  
  393. // JDC: fixed to allow quoted keys
  394.         c = FindNonwhitespc(fp);
  395.         if (c == -1)
  396.             return NULL;
  397.         c = fgetc(fp);
  398.         if ( c == '\"')        
  399.             CopyUntilQuote(fp,string);
  400.         else
  401.         {
  402.             ungetc (c,fp);
  403.             CopyUntilWhitespc(fp,string);
  404.         }
  405.  
  406.         pair.key = malloc(strlen(string)+1);
  407.         strcpy(pair.key,string);
  408.         
  409.         c = FindQuote(fp);
  410.         CopyUntilQuote(fp,string);
  411.         pair.value = malloc(strlen(string)+1);
  412.         strcpy(pair.value,string);
  413.         
  414.         [super addElement:&pair];
  415.         c = FindBrace(fp);
  416.     }
  417.     
  418.     return self;
  419. }
  420.  
  421. @end
  422.  
  423. //===============================================
  424. //
  425. //    C routines for string parsing
  426. //
  427. //===============================================
  428. int    GetNextChar(FILE *fp)
  429. {
  430.     int        c;
  431.     int        c2;
  432.     
  433.     c = getc(fp);
  434.     if (c == EOF)
  435.         return -1;
  436.     if (c == '/')        // parse comments
  437.     {
  438.         c2 = getc(fp);
  439.         if (c2 == '/')
  440.         {
  441.             while((c2 = getc(fp)) != '\n');
  442.             c = getc(fp);
  443.         }
  444.         else
  445.             ungetc(c2,fp);
  446.     }
  447.     return c;
  448. }
  449.  
  450. void CopyUntilWhitespc(FILE *fp,char *buffer)
  451. {
  452.     int    count = 800;
  453.     int    c;
  454.     
  455.     while(count--)
  456.     {
  457.         c = GetNextChar(fp);
  458.         if (c == EOF)
  459.             return;
  460.         if (c <= ' ')
  461.         {
  462.             *buffer = 0;
  463.             return;
  464.         }
  465.         *buffer++ = c;
  466.     }
  467. }
  468.  
  469. void CopyUntilQuote(FILE *fp,char *buffer)
  470. {
  471.     int    count = 800;
  472.     int    c;
  473.     
  474.     while(count--)
  475.     {
  476.         c = GetNextChar(fp);
  477.         if (c == EOF)
  478.             return;
  479.         if (c == '\"')
  480.         {
  481.             *buffer = 0;
  482.             return;
  483.         }
  484.         *buffer++ = c;
  485.     }
  486. }
  487.  
  488. int FindBrace(FILE *fp)
  489. {
  490.     int    count = 800;
  491.     int    c;
  492.     
  493.     while(count--)
  494.     {
  495.         c = GetNextChar(fp);
  496.         if (c == EOF)
  497.             return -1;
  498.         if (c == '{' ||
  499.             c == '}')
  500.             return c;
  501.     }
  502.     return -1;
  503. }
  504.  
  505. int FindQuote(FILE *fp)
  506. {
  507.     int    count = 800;
  508.     int    c;
  509.     
  510.     while(count--)
  511.     {
  512.         c = GetNextChar(fp);
  513.         if (c == EOF)
  514.             return -1;
  515.         if (c == '\"')
  516.             return c;
  517.     }
  518.     return -1;
  519. }
  520.  
  521. int FindWhitespc(FILE *fp)
  522. {
  523.     int    count = 800;
  524.     int    c;
  525.         
  526.     while(count--)
  527.     {
  528.         c = GetNextChar(fp);
  529.         if (c == EOF)
  530.             return -1;
  531.         if (c <= ' ')
  532.         {
  533.             ungetc(c,fp);
  534.             return c;
  535.         }
  536.     }
  537.     return -1;        
  538. }
  539.  
  540. int FindNonwhitespc(FILE *fp)
  541. {
  542.     int    count = 800;
  543.     int    c;
  544.         
  545.     while(count--)
  546.     {
  547.         c = GetNextChar(fp);
  548.         if (c == EOF)
  549.             return -1;
  550.         if (c > ' ')
  551.         {
  552.             ungetc(c,fp);
  553.             return c;
  554.         }
  555.     }
  556.     return -1;
  557. }
  558.  
  559. char *FindWhitespcInBuffer(char *buffer)
  560. {
  561.     int    count = 1000;
  562.     char    *b = buffer;
  563.     
  564.     while(count--)
  565.         if (*b <= ' ')
  566.             return b;
  567.         else
  568.             b++;
  569.     return NULL;        
  570. }
  571.  
  572. char *FindNonwhitespcInBuffer(char *buffer)
  573. {
  574.     int    count = 1000;
  575.     char    *b = buffer;
  576.     
  577.     while(count--)
  578.         if (*b > ' ')
  579.             return b;
  580.         else
  581.             b++;
  582.     return NULL;
  583. }
  584.