Dict.m 8.2 KB

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