parser.c 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: parser.c /main/8 1996/03/25 09:14:08 rswiston $ */
  24. /***************************************************************************/
  25. /* */
  26. /* parser.c */
  27. /* */
  28. /***************************************************************************/
  29. #ifdef _AIX
  30. #define _ILS_MACRO
  31. #endif /* _AIX */
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <sys/stat.h>
  36. #include "dtcreate.h"
  37. #include "parser.h"
  38. #include <ctype.h>
  39. /***************************************************************************
  40. *
  41. * Local procedure declarations
  42. *
  43. ***************************************************************************/
  44. char ** GetKeywordValuePairs(char *, int *, int);
  45. FiletypeData ** GetFiletypeData(FILE *, char *, short *);
  46. char ** ProcessExecString(char *);
  47. int ProcessContents(FiletypeData *);
  48. Boolean IsLastSingle(char *);
  49. /***************************************************************************
  50. *
  51. * Extern variable declarations
  52. *
  53. ***************************************************************************/
  54. /***************************************************************************
  55. *
  56. * Global variable declarations
  57. *
  58. ***************************************************************************/
  59. /* Action Keyword Table */
  60. char keywordDB[][30] = { "ACTION" ,
  61. "ICON" ,
  62. "EXEC_STRING" ,
  63. "DESCRIPTION" ,
  64. "TYPE" ,
  65. "WINDOW_TYPE" ,
  66. "ARG_TYPE" ,
  67. "LABEL" ,
  68. '\0' ,
  69. };
  70. /* Max Number of fields in Action Keyword Table */
  71. #define MAX_NUM_ACTION_FIELDS 8
  72. /* Filetype Keyword Table */
  73. char FiletypekeywordDB[][30] = { "DATA_ATTRIBUTES" ,
  74. "ICON" ,
  75. "DESCRIPTION" ,
  76. "EXEC_STRING" ,
  77. "NAME_PATTERN" ,
  78. "PATH_PATTERN" ,
  79. "MODE" ,
  80. "CONTENT" ,
  81. "ACTIONS" ,
  82. "DATA_ATTRIBUTES_NAME" ,
  83. "DATA_CRITERIA" ,
  84. "WINDOW_TYPE" ,
  85. "ACTION" ,
  86. "ARG_TYPE" ,
  87. "MAP_ACTION" ,
  88. "TYPE" ,
  89. "LABEL" ,
  90. '\0' ,
  91. };
  92. /* Max Number of fields in Filetype Keyword Table */
  93. #define MAX_NUM_FILETYPE_FIELDS 17
  94. char *args[3],*fline;
  95. int flinesize=0;
  96. static int state = 0;
  97. /*****************************************************************
  98. ** **
  99. ** GetActionData(FILE *fp, ActionData *) **
  100. ** **
  101. ** Description: Parses the action file and fills the data in the**
  102. ** pointer pointing to the ActionData structure **
  103. ** passed as input. **
  104. ** **
  105. ** Input : Filepointer that points to the ActionFile and, **
  106. ** a pointer to the ActionData structure. **
  107. ** **
  108. ** Output : 0 (No error). **
  109. ** 1 (error). **
  110. ** **
  111. ** references : dtcreate.h, parser.h, and dtcreate spec. **
  112. ** **
  113. ******************************************************************/
  114. int
  115. GetActionData(FILE *fp, ActionData *ActionDataptr)
  116. {
  117. int rc,manflds=0,len,first=TRUE,lastfld=0,fldid=-1;
  118. char linebuf[1024],**wordPairs,**execstr;
  119. /* reset the read pointer to zero byte for fp */
  120. rewind(fp);
  121. /* Initialize the ActionData structure passed */
  122. if(ActionDataptr)
  123. memset(ActionDataptr,
  124. 0,sizeof(ActionData));
  125. else {
  126. #ifdef DEBUG
  127. printf("ActionDataptr is NULL\n");
  128. #endif
  129. return 1;
  130. }
  131. /* initialize the linebuf with NULL's */
  132. bzero(linebuf,sizeof(linebuf));
  133. while (fgets (linebuf, sizeof (linebuf)-1, fp))
  134. {
  135. /* skip the complete line if it starts with a '{' or a comment ('#') */
  136. if(linebuf[0] == '{' || linebuf[0] == '#') continue;
  137. /* If the first character is '}' reached the end of Action Stanza so quit */
  138. if(linebuf[0] == '}')
  139. break;
  140. len = strlen (linebuf);
  141. if (linebuf[len-1] == '\n')
  142. linebuf[len-1] = '\0';
  143. /* Get the keyword and value pair from the string linebuf */
  144. /* On return, wordPairs[0] = keyword like ICON
  145. and wordPairs[1] = value for the keyword
  146. */
  147. if( (wordPairs = GetKeywordValuePairs(linebuf,&fldid,ACTION_TABLE)) != NULL)
  148. {
  149. if( first && strcmp(wordPairs[0],"ACTION") )
  150. {
  151. #ifdef DEBUG
  152. printf("first && strcmp(wordPairs[0],ACTION)\n");
  153. #endif
  154. return 1;
  155. }
  156. else
  157. first = FALSE;
  158. /* Update the mandatory fields counter */
  159. if( !strcmp(wordPairs[0],"TYPE") ||
  160. !strcmp(wordPairs[0],"EXEC_STRING") ||
  161. !strcmp(wordPairs[0],"WINDOW_TYPE") )
  162. manflds++;
  163. if( !strcmp(wordPairs[0],"WINDOW_TYPE") )
  164. {
  165. if( !strcmp(wordPairs[1],"PERM_TERMINAL") )
  166. ActionDataptr->fsFlags |= CA_WT_PERMTERM;
  167. if( !strcmp(wordPairs[1],"TERMINAL") )
  168. ActionDataptr->fsFlags |= CA_WT_TERM;
  169. if( !strcmp(wordPairs[1],"NO_STDIO") )
  170. ActionDataptr->fsFlags |= CA_WT_XWINDOWS;
  171. }
  172. if( !strcmp(wordPairs[0],"ARG_TYPE") )
  173. ActionDataptr->fsFlags |= CA_DF_ONLYFTFILES;
  174. /* if linebuf does not contain the keyword then everything
  175. in wordPairs[0],else, wordPairs[0] contains the keyword
  176. and wordpairs[1] contains the value.
  177. */
  178. if( wordPairs && wordPairs[0] && !wordPairs[1])
  179. {
  180. /* fldid is returned by the GetKeywordValuePairs function.
  181. This id determines which field of the ActionDataptr will
  182. have the value. Please see KeywordDB array in parser.h
  183. for more details.
  184. */
  185. switch(fldid)
  186. {
  187. case 7: /* next line for action_name */
  188. ActionDataptr->pszName=wordPairs[0];
  189. break;
  190. case 1: /* next line for action_icon_name */
  191. ActionDataptr->pszIcon=wordPairs[0];
  192. break;
  193. case 2 : /* next line for exec_string */
  194. ActionDataptr->pszCmd=wordPairs[0];
  195. break;
  196. case 3: /* next line for action_help_text */
  197. ActionDataptr->pszHelp=wordPairs[0];
  198. break;
  199. default: break;
  200. }
  201. }
  202. else if(wordPairs && wordPairs[1])
  203. {
  204. if(fldid >= 0 && fldid <=2)
  205. state = 0;
  206. /* for fldid see the comments above */
  207. switch(fldid)
  208. {
  209. case 7: /* first line for action_name */
  210. ActionDataptr->pszName=wordPairs[1];
  211. break;
  212. case 1: /* first line for action_icon_name */
  213. ActionDataptr->pszIcon=wordPairs[1];
  214. break;
  215. case 2 : /* first line for exec_string */
  216. ActionDataptr->pszCmd=wordPairs[1];
  217. break;
  218. case 3: /* first line for action_help_text */
  219. state = HELP_TEXT;
  220. ActionDataptr->pszHelp=wordPairs[1];
  221. break;
  222. default: state=0;break;
  223. }
  224. }
  225. /* reset the linebuf to NULL's */
  226. bzero(linebuf,sizeof(linebuf));
  227. }
  228. }
  229. state=0;
  230. /* Done with retrieving Action Data */
  231. /* Check if we got all the mandatory fields data */
  232. if(manflds != 3) {
  233. #ifdef DEBUG
  234. printf("if(manflds != 3)\n");
  235. #endif
  236. return 1;
  237. } else
  238. {
  239. /* Everything looks right so process the exec_string */
  240. if( !(execstr = ProcessExecString(ActionDataptr->pszCmd)) )
  241. {
  242. ActionDataptr->pszCmd = NULL;
  243. ActionDataptr->pszPrompt = 0;
  244. }
  245. else
  246. {
  247. ActionDataptr->pszCmd = execstr[0];
  248. ActionDataptr->pszPrompt = execstr[1];
  249. free(execstr);
  250. }
  251. /* Got the ActionData,so, go get the FiletypeData */
  252. ActionDataptr->papFiletypes =
  253. (FiletypeData **) GetFiletypeData(fp,(char *)(ActionDataptr->pszCmd),
  254. (short *)&(ActionDataptr->cFiletypes) );
  255. if( !ActionDataptr->papFiletypes && ActionDataptr->cFiletypes > 0) {
  256. #ifdef DEBUG
  257. printf("!ActionDataptr->papFiletypes && ActionDataptr->cFiletypes > 0)\n");
  258. #endif
  259. return(1); /* return 1 if error */
  260. } else
  261. return(0); /* return 0 if no error */
  262. }
  263. }
  264. /*****************************************************************
  265. ** **
  266. ** GetFiletypeData(FILE *fp, char *pszOpenCmd) **
  267. ** **
  268. ** Description: Parses the action file and returns a pointer **
  269. ** that points to the data in the form of **
  270. ** FiletypeData structure (defined in dtcreate.h). **
  271. ** **
  272. ** Input : Filepointer that points to the ActionFile, and, **
  273. ** a char pointer to the exec_string of the **
  274. ** ActionData structure as obtained in the GetAc- **
  275. ** -tionData function call. **
  276. ** **
  277. ** Output : Pointer to an array of FiletypeData structures **
  278. ** containing data for all the Filetypes,and,no of **
  279. ** file types. **
  280. ** **
  281. ** references : dtcreate.h, parser.h, and dtcreate spec. **
  282. ** **
  283. ******************************************************************/
  284. FiletypeData **
  285. GetFiletypeData(FILE *fp, char *pszOpenCmd, short *nftypes)
  286. {
  287. int manflds=0,len,nfiletypes,previous=0,lastfld=0,fldid;
  288. char linebuf[1024],**wordPairs,**execstr;
  289. FiletypeData **ppFiletypeData,**ppnewFiletypeData;
  290. wordPairs=0;
  291. ppFiletypeData=0;
  292. nfiletypes=0;
  293. /* Initialize the linebuf */
  294. bzero(linebuf,sizeof(linebuf));
  295. while (fgets (linebuf, sizeof (linebuf)-1, fp))
  296. {
  297. /* If begin of a stanza skip and continue */
  298. if(linebuf[0] == '{')
  299. {
  300. continue;
  301. }
  302. /* skip the rest of the line if a comment found */
  303. if(linebuf[0] == '#') continue;
  304. /* If end of a stanza check if all the mandatory fields are there */
  305. if( linebuf[0] == '}' )
  306. {
  307. /* Check for atleast one field in DATA_ATTRIBUTES stanza */
  308. if( previous == DATA_ATTRIBUTES && manflds != 1 )
  309. {
  310. printf("Error in DATA_ATTR stanza of the FiletypeData\n");
  311. return NULL;
  312. }
  313. /* Check for atleast one field in DATA_CRITERIA stanza */
  314. else if( previous == DATA_CRITERIA && manflds != 1 )
  315. {
  316. printf("Error in DATA_CRITERIA stanza of the FiletypeData\n");
  317. return NULL;
  318. }
  319. /* Check for atleast two fields in ACTION_OPEN or ACTION_PRINT stanza */
  320. else if( (previous == ACTION_OPEN || previous == ACTION_PRINT) )
  321. {
  322. if( manflds != 4)
  323. {
  324. printf("Error in ACTION_OPEN/PRINT stanza of the FiletypeData\n");
  325. return NULL;
  326. }
  327. }
  328. /* Check for atleast three fields in ACTION_PRINT_FTYPE stanza */
  329. else if( previous == ACTION_PRINT_FTYPE && manflds != 3 )
  330. {
  331. printf("Error in ACTION_PRINT_FTYPE stanza of the FiletypeData\n");
  332. return NULL;
  333. }
  334. continue;
  335. }
  336. len = strlen (linebuf);
  337. if (linebuf[len-1] == '\n')
  338. linebuf[len-1] = '\0';
  339. if( (wordPairs = GetKeywordValuePairs(linebuf,&fldid,FILETYPE_TABLE)) != NULL)
  340. {
  341. if( !strcmp(wordPairs[0],"DATA_ATTRIBUTES") )
  342. {
  343. /* first filetype */
  344. if( previous == 0 )
  345. {
  346. /* Allocate a filetypedata pointer to an array of filetypedata records */
  347. if( !ppFiletypeData)
  348. {
  349. if( (ppFiletypeData = (FiletypeData **)calloc(1,sizeof(FiletypeData *)))
  350. == NULL )
  351. {
  352. printf("\n Cannot allocate memory\n");
  353. return NULL;
  354. }
  355. /* Allocate a filetypedata record */
  356. else
  357. {
  358. if( (ppFiletypeData[nfiletypes] =
  359. (FiletypeData *)calloc(1,sizeof(FiletypeData)) )
  360. == NULL )
  361. {
  362. printf("\n Cannot allocate memory\n");
  363. return NULL;
  364. }
  365. }
  366. }
  367. ppFiletypeData[nfiletypes]->pszOpenCmd = pszOpenCmd;
  368. previous = DATA_ATTRIBUTES;
  369. manflds=0;
  370. }
  371. else if(previous == ACTION_OPEN || previous == ACTION_PRINT)
  372. {
  373. /* New filetypedata started so allocate a new filetypedata ptr */
  374. if( (ppnewFiletypeData =
  375. (FiletypeData **)realloc((FiletypeData *)ppFiletypeData,
  376. nfiletypes+2 * sizeof(FiletypeData *)))
  377. == NULL )
  378. {
  379. printf("\n Cannot allocate memory\n");
  380. return NULL;
  381. }
  382. else if(ppFiletypeData)
  383. {
  384. ppFiletypeData=ppnewFiletypeData;
  385. /* Process the contents field if any */
  386. if(ProcessContents((FiletypeData *)ppFiletypeData[nfiletypes]) < 0 )
  387. {
  388. printf("\n Error in Contents Data\n");
  389. return NULL;
  390. }
  391. /* Everything looks right so process the exec_string */
  392. if( !(execstr = ProcessExecString((char *)ppFiletypeData[nfiletypes]->pszPrintCmd)) )
  393. ppFiletypeData[nfiletypes]->pszPrintCmd=NULL;
  394. else {
  395. ppFiletypeData[nfiletypes]->pszPrintCmd=execstr[0];
  396. free(execstr);
  397. }
  398. nfiletypes++;
  399. /* Allocate a new filetypedata record */
  400. if( (ppFiletypeData[nfiletypes] =
  401. (FiletypeData *)calloc(1,sizeof(FiletypeData)) )
  402. == NULL )
  403. {
  404. printf("\n Cannot allocate memory\n");
  405. return NULL;
  406. }
  407. ppFiletypeData[nfiletypes]->pszOpenCmd = pszOpenCmd;
  408. previous = DATA_ATTRIBUTES;
  409. manflds=0;
  410. }
  411. }
  412. else
  413. {
  414. printf("Error in filetypedata \n");
  415. return NULL;
  416. }
  417. }
  418. else if( !strcmp(wordPairs[0],"DATA_CRITERIA") )
  419. {
  420. if( previous == DATA_ATTRIBUTES )
  421. {
  422. previous = DATA_CRITERIA;
  423. manflds=0;
  424. }
  425. else
  426. {
  427. printf("Error in filetypedata \n");
  428. return NULL;
  429. }
  430. }
  431. else if( !strcmp(wordPairs[0],"ACTION") && !strcmp(wordPairs[1],"Open") )
  432. {
  433. if( previous == DATA_CRITERIA )
  434. {
  435. previous = ACTION_OPEN;
  436. manflds=0;
  437. }
  438. else
  439. {
  440. printf("Error in filetypedata \n");
  441. return NULL;
  442. }
  443. }
  444. else if( !strcmp(wordPairs[0],"ACTION") && strcmp(wordPairs[1],"Open") &&
  445. strcmp(wordPairs[1], "Print") )
  446. {
  447. if( previous == ACTION_OPEN )
  448. {
  449. previous = ACTION_PRINT_FTYPE;
  450. manflds=0;
  451. }
  452. else
  453. {
  454. printf("Error in filetypedata \n");
  455. return NULL;
  456. }
  457. }
  458. else if( !strcmp(wordPairs[0],"ACTION") && !strcmp(wordPairs[1],"Print") )
  459. {
  460. if( previous == ACTION_PRINT_FTYPE )
  461. {
  462. previous = ACTION_PRINT;
  463. manflds=0;
  464. }
  465. else
  466. {
  467. printf("Error in filetypedata \n");
  468. return NULL;
  469. }
  470. }
  471. /* update mandatory fields counter */
  472. if( previous == DATA_ATTRIBUTES && strcmp(wordPairs[0],"DATA_ATTRIBUTES") )
  473. {
  474. if( !strcmp(wordPairs[0],"ACTIONS") )
  475. manflds++;
  476. }
  477. else if( previous == DATA_CRITERIA )
  478. {
  479. if( !strcmp(wordPairs[0],"DATA_ATTRIBUTES_NAME") )
  480. manflds++;
  481. }
  482. else if( previous == ACTION_OPEN || previous == ACTION_PRINT )
  483. {
  484. if( !strcmp(wordPairs[0],"ARG_TYPE") ||
  485. !strcmp(wordPairs[0],"TYPE") ||
  486. !strcmp(wordPairs[0],"MAP_ACTION") ||
  487. !strcmp(wordPairs[0],"LABEL") )
  488. manflds++;
  489. }
  490. else if( previous == ACTION_PRINT_FTYPE )
  491. {
  492. if( !strcmp(wordPairs[0],"TYPE") ||
  493. !strcmp(wordPairs[0],"WINDOW_TYPE") )
  494. manflds++;
  495. }
  496. }
  497. if( wordPairs && !wordPairs[1] && wordPairs[0])
  498. {
  499. switch(fldid)
  500. {
  501. case 0: /* next line for filetype_name */
  502. ppFiletypeData[nfiletypes]->pszName=wordPairs[0];
  503. break;
  504. case 1: /* next line for icon_name */
  505. ppFiletypeData[nfiletypes]->pszIcon=wordPairs[0];
  506. break;
  507. case 2 : /* next line for help_text */
  508. ppFiletypeData[nfiletypes]->pszHelp=wordPairs[0];
  509. break;
  510. case 3: /* next line for print_cmd */
  511. ppFiletypeData[nfiletypes]->pszPrintCmd=wordPairs[0];
  512. manflds++;
  513. break;
  514. case 4: /* next line for name_pattern or path_pattern */
  515. ppFiletypeData[nfiletypes]->pszPattern=wordPairs[0];
  516. break;
  517. case 5: /* next line for name_pattern or path_pattern */
  518. ppFiletypeData[nfiletypes]->pszPattern=wordPairs[0];
  519. break;
  520. case 6: /* next line for mode */
  521. ppFiletypeData[nfiletypes]->pszPermissions=wordPairs[0];
  522. break;
  523. case 7: /* next line for contents */
  524. ppFiletypeData[nfiletypes]->pszContents=wordPairs[0];
  525. break;
  526. default: break;
  527. }
  528. }
  529. else if(wordPairs && wordPairs[1])
  530. {
  531. switch(fldid)
  532. {
  533. case 0: /* first line for filetype_name */
  534. ppFiletypeData[nfiletypes]->pszName = wordPairs[1];
  535. break;
  536. case 1: /* first line for icon_name */
  537. ppFiletypeData[nfiletypes]->pszIcon=wordPairs[1];
  538. break;
  539. case 2 : /* first line for help_text */
  540. ppFiletypeData[nfiletypes]->pszHelp=wordPairs[1];
  541. break;
  542. case 3: /* first line for print_cmd */
  543. ppFiletypeData[nfiletypes]->pszPrintCmd=wordPairs[1];
  544. manflds++;
  545. break;
  546. case 4: /* first line for name_pattern or path_pattern */
  547. ppFiletypeData[nfiletypes]->pszPattern=wordPairs[1];
  548. break;
  549. case 5: /* first line for name_pattern or path_pattern */
  550. ppFiletypeData[nfiletypes]->pszPattern=wordPairs[1];
  551. break;
  552. case 6: /* first line for mode */
  553. ppFiletypeData[nfiletypes]->pszPermissions=wordPairs[1];
  554. break;
  555. case 7: /* first line for contents */
  556. ppFiletypeData[nfiletypes]->pszContents=wordPairs[1];
  557. break;
  558. default: break;
  559. }
  560. }
  561. bzero(linebuf,sizeof(linebuf));
  562. } /* end of while fgets */
  563. /* Done with retrieving FiletypeData */
  564. /* Check if we got all the mandatory fields data */
  565. if( (previous == ACTION_OPEN && manflds != 4) ||
  566. (previous == ACTION_PRINT && manflds != 4) )
  567. return NULL;
  568. else if(ppFiletypeData)
  569. {
  570. /* Process Contents for the last file filetype if any */
  571. if(ProcessContents((FiletypeData *)ppFiletypeData[nfiletypes]) < 0)
  572. {
  573. printf("\n Error in Contents Data\n");
  574. return NULL;
  575. }
  576. /* Everything looks right so process the exec_string */
  577. if(!(execstr =
  578. ProcessExecString((char *)ppFiletypeData[nfiletypes]->pszPrintCmd)) )
  579. ppFiletypeData[nfiletypes]->pszPrintCmd=NULL;
  580. else
  581. ppFiletypeData[nfiletypes]->pszPrintCmd=execstr[0];
  582. if( !ppFiletypeData[nfiletypes])
  583. ppFiletypeData[nfiletypes] = 0;
  584. /* return number of filetypes */
  585. *nftypes = nfiletypes+1;
  586. free(execstr);
  587. return ppFiletypeData;
  588. }
  589. else
  590. return NULL;
  591. }
  592. /*****************************************************************
  593. ** **
  594. ** GetKeywordValuePairs(char *s, int *id, int table) **
  595. ** **
  596. ** Description: Parses the text string in *s and returns a **
  597. ** pointer to two strings that are Keyword and **
  598. ** values.However, it returns the complete string **
  599. ** in the first pointer if keyword not found. **
  600. ** **
  601. ** Input : A character pointer pointing to text string. **
  602. ** An integer pointer to return the field id. **
  603. ** An integer value that determines which table to **
  604. ** use (either ACTION_TABLE of FILETYPE_TABLE). **
  605. ** see definitions in parser.h **
  606. ** **
  607. ** Output : pointer to two pointers pointing to text strings**
  608. ** fieldid in the id parameter. **
  609. ** **
  610. ** references : dtcreate.h, parser.h, and dtcreate spec. **
  611. ** **
  612. ******************************************************************/
  613. char **
  614. GetKeywordValuePairs(char *s, int *id, int table)
  615. {
  616. char *wordStart;
  617. static int fldid=-1;
  618. int idx;
  619. args[0] = args[1] = args[2] = NULL;
  620. /* Skip all leading spaces */
  621. while (*s && isspace (*s))
  622. ++s;
  623. /* Skip the complete line if a '#' character is found (comments) */
  624. if (!*s || *s == '#')
  625. return NULL;
  626. wordStart = s;
  627. while (*s && *s != '#' && !isspace (*s))
  628. ++s;
  629. if (!args[0])
  630. {
  631. int szArgs0 = s - wordStart + 1;
  632. args[0] = (char *)malloc (szArgs0);
  633. if (!args[0])
  634. return NULL;
  635. memset(args[0],0,szArgs0);
  636. }
  637. strncpy (args[0], wordStart, s - wordStart);
  638. args[0][s-wordStart] = '\0';
  639. if (!args[1])
  640. {
  641. int szArgs1 = strlen(s) + 1;
  642. args[1] = (char *)malloc (szArgs1);
  643. if (!args[1])
  644. {
  645. if(args[0])
  646. free(args[0]);
  647. return NULL;
  648. }
  649. memset(args[1],0,szArgs1);
  650. }
  651. /* Skip all leading spaces */
  652. while (*s && isspace (*s))
  653. ++s;
  654. strcpy (args[1], s);
  655. args[2]=NULL;
  656. /* Check for whether args[0] is a keyword or not */
  657. idx=0;
  658. if( table == ACTION_TABLE )
  659. {
  660. /* Check for keyword in keywordDB defined in parser.h */
  661. while((strcmp(keywordDB[idx],"")) && (strcmp(args[0],keywordDB[idx])) ) idx++;
  662. if(idx >= 0 && idx < MAX_NUM_ACTION_FIELDS)
  663. fldid = idx;
  664. }
  665. else if( table == FILETYPE_TABLE )
  666. {
  667. /* Check for keyword in FiletypekeywordDB defined in parser.h */
  668. while((strcmp(FiletypekeywordDB[idx],"")) && (strcmp(args[0],FiletypekeywordDB[idx])) ) idx++;
  669. if(idx >= 0 && idx < MAX_NUM_FILETYPE_FIELDS)
  670. fldid = idx;
  671. }
  672. /* If no keyword found then keep the complete string
  673. in the first array
  674. */
  675. if( (idx == MAX_NUM_ACTION_FIELDS && table == ACTION_TABLE) ||
  676. (idx == MAX_NUM_FILETYPE_FIELDS && table == FILETYPE_TABLE) )
  677. {
  678. char *temp4;
  679. if( (temp4 = (char *)realloc(args[0],strlen(args[0])+strlen(args[1])+2) ) == NULL )
  680. {
  681. printf("Cannot Allocate memory\n");
  682. return NULL;
  683. }
  684. args[0] = temp4;
  685. strcat(args[0]," ");
  686. strcat(args[0],args[1]);
  687. if(args[1])
  688. {
  689. free(args[1]);
  690. args[1]=NULL;
  691. }
  692. if( IsLastSingle(args[0]) && args[0][strlen(args[0])-1] == '\\' )
  693. args[0][strlen(args[0])-1] = '\0';
  694. if( (temp4 = (char *)realloc(fline,flinesize+strlen(args[0])+1)) == NULL)
  695. {
  696. printf("Cannot Allocate memory\n");
  697. return NULL;
  698. }
  699. strcat(temp4,args[0]);
  700. free(args[0]);
  701. args[0]=temp4;
  702. }
  703. *id = fldid; /* return field id */
  704. if(args[1] && IsLastSingle(args[1]) && args[1][strlen(args[1])-1] == '\\')
  705. args[1][strlen(args[1])-1] = '\0';
  706. if(args[0])
  707. args[0][strlen(args[0])] = '\0';
  708. if(args[1])
  709. args[1][strlen(args[1])] = '\0';
  710. if(args[0] && args[1])
  711. {
  712. fline = args[1];
  713. flinesize=strlen(fline);
  714. }
  715. if(!args[1] && args[0])
  716. {
  717. fline = args[0];
  718. flinesize=strlen(fline);
  719. }
  720. return args;
  721. }
  722. /*****************************************************************
  723. ** **
  724. ** ProcessExecString(char *) **
  725. ** **
  726. ** Description: Parses the text string and returns two pointers,**
  727. ** the first pointing to cmd part (if any) **
  728. ** the second pointing to prompt part (if any) **
  729. ** of either the ActionData structure type or **
  730. ** FiletypeData structure type. Please see **
  731. ** dtcreate.h for the above mentioned datastructure**
  732. ** definitions and for the cmd and prompt fields **
  733. ** **
  734. ** Input : A character pointer that points to the complete **
  735. ** text string comprising the command and arguments**
  736. ** and prompt (if any). **
  737. ** **
  738. ** Limitation : Supports only ONE prompt. **
  739. ** **
  740. ** Output : Pointer to 3-element result array from malloc, **
  741. ** or NULL on error **
  742. ** **
  743. ** Assumptions: a) Arg fields start with a '%' character. **
  744. ** b) Prompt string start and end with '"' chara- **
  745. ** cter. Also, the prompt string comes after **
  746. ** the Arg strings if any. **
  747. ** **
  748. ** references : dtcreate.h, parser.h, and dtcreate spec. **
  749. ** **
  750. ******************************************************************/
  751. char **
  752. ProcessExecString(char *cmd)
  753. {
  754. char *s1, *s2,*s3,*s4,*argbuf,**exec_args;
  755. int done=FALSE, argfound=FALSE,promptfound=FALSE;
  756. if (!cmd) {
  757. return((char **)NULL);
  758. }
  759. s1=s2=s3=s4=argbuf=NULL;
  760. exec_args = calloc(3, sizeof(char*));
  761. if (!exec_args) return NULL;
  762. /* Allocate buffer for the cmd string */
  763. exec_args[0] = (char *)calloc(1,strlen(cmd)+1);
  764. exec_args[1] = exec_args[2] = NULL;
  765. /* check if any Args present */
  766. s1=cmd;
  767. while( !done )
  768. {
  769. char *tmp;
  770. tmp=NULL;
  771. s4 = strstr(s1,"%Arg");
  772. if(s4)
  773. {
  774. if ( (s4-s1) > 0 )
  775. {
  776. strncat(exec_args[0],s1,(s4-s1));
  777. exec_args[0][strlen(exec_args[0])] = '\0';
  778. }
  779. s1 = s4;
  780. s2 = strchr(s1+1,'%'); /* at this point we got s1 to s2
  781. covers the complete string
  782. between %'s
  783. */
  784. if(argbuf) { free(argbuf); argbuf = NULL; }
  785. if(s2)
  786. {
  787. argbuf = (char *)calloc(1,(s2-s1)+2);
  788. strncpy(argbuf,s1,(s2-s1)+1);
  789. }
  790. else
  791. {
  792. strcat(exec_args[0],s1);
  793. done=TRUE;
  794. continue;
  795. }
  796. argbuf[strlen(argbuf)]='\0';
  797. if( strncmp(argbuf,"%Arg_",5) &&
  798. strncmp(argbuf,"%Args%",6) &&
  799. strncmp(argbuf,"%Args\"",6) )
  800. {
  801. strncat(exec_args[0],argbuf,strlen(argbuf)-1);
  802. exec_args[0][strlen(exec_args[0])] = '\0';
  803. s1=s2;
  804. continue;
  805. }
  806. }
  807. else if (*s1)
  808. {
  809. strcat(exec_args[0],s1);
  810. if(argbuf) { free(argbuf); argbuf = NULL; }
  811. done = TRUE;
  812. continue;
  813. }
  814. else
  815. {
  816. done = TRUE;
  817. continue;
  818. }
  819. /* move s1 until a '_' or 's' */
  820. tmp = strchr(argbuf,'_');
  821. if(!tmp)
  822. tmp= strchr(argbuf,'s');
  823. strcat(exec_args[0],"$");
  824. argfound=TRUE;
  825. /* start of Arg processing */
  826. while (*tmp != '%' && *tmp != '"' )
  827. {
  828. if(*tmp == 's')
  829. {
  830. strcat(exec_args[0],"*");
  831. break;
  832. }
  833. if( *tmp > '0' && *tmp <= '9')
  834. {
  835. strncat(exec_args[0],tmp,1);
  836. exec_args[0][strlen(exec_args[0])] = '\0';
  837. }
  838. tmp++;
  839. }
  840. /* end of Arg processing */
  841. /* Get Prompt string if any */
  842. s3 = strchr(argbuf,'"');
  843. if(s3 && *(s3+1) != '"')
  844. {
  845. s3++;
  846. if(!promptfound)
  847. {
  848. if( (tmp = strchr(s3,'"')) )
  849. {
  850. promptfound=TRUE;
  851. exec_args[1] = (char *)calloc(1,(tmp-s3)+1);
  852. strncpy(exec_args[1],s3,(tmp-s3));
  853. exec_args[1][strlen(exec_args[1])] = '\0';
  854. }
  855. }
  856. }
  857. /* see if there is some stuff between the last '%'
  858. and the next first '%' of another Arg
  859. */
  860. if( argfound) s2++;
  861. argfound = FALSE;
  862. s1=s2;
  863. }
  864. if(argbuf) { free(argbuf); argbuf = NULL; }
  865. return exec_args;
  866. }
  867. /*****************************************************************
  868. ** **
  869. ** ProcessContents(FiletypeData *) **
  870. ** **
  871. ** Description: Parses the text string in pszContents field and **
  872. ** fills the sStart,fsFlags and pszContents fields **
  873. ** of the filetypeData datastructure that is passed**
  874. ** as input. **
  875. ** **
  876. ** Input : A pointer of type FiletypeData defined in **
  877. ** dtcreate.h **
  878. ** **
  879. ** Output : Fills the sStart, fsFlags and pszContents fields**
  880. ** of the FiletypeData pointer and returns 0 (No **
  881. ** error or >0 (error) values. **
  882. ** **
  883. ** Assumptions: Fields are separated by atleast one blank **
  884. ** character. **
  885. ** **
  886. ** references : dtcreate.h, parser.h, and dtcreate spec. **
  887. ** **
  888. ******************************************************************/
  889. int
  890. ProcessContents(FiletypeData *pFtD)
  891. {
  892. char *s1,*tmp,*s2,buf[10],*cts;
  893. s1=s2=tmp=cts=NULL;
  894. bzero(buf,sizeof(buf));
  895. /* simply return if there is no data in contents field */
  896. if(!pFtD->pszContents)
  897. return (0);
  898. cts = (char *)calloc(1,strlen(pFtD->pszContents)+1);
  899. strcpy(cts,pFtD->pszContents);
  900. s1=cts;
  901. free(pFtD->pszContents);
  902. pFtD->pszContents=NULL;
  903. /* Skip all leading spaces */
  904. while( *s1 && isspace(*s1) ) s1++;
  905. /* Get the sStart value if any */
  906. /*
  907. if( (s1 = strchr(cts,' ')) )
  908. */
  909. while( *s1 && !isspace(*s1) && *s1 != '\n') s1++;
  910. if((s1-cts) > 0)
  911. {
  912. strncpy(buf,cts,(s1-cts));
  913. buf[s1-cts]='\0';
  914. pFtD->sStart=atoi(buf);
  915. }
  916. while( *s1 && isspace(*s1) ) s1++;
  917. /* Get the fsFlags value if any */
  918. tmp=s1;
  919. bzero(buf,sizeof(buf));
  920. /*
  921. if ( (tmp = strchr(s1,' ')) )
  922. */
  923. while( *tmp && !isspace(*tmp) && *tmp != '\n') tmp++;
  924. if((tmp-s1) > 0)
  925. {
  926. strncpy(buf,s1,(tmp-s1));
  927. buf[tmp-s1]='\0';
  928. if ( !strcmp(buf,"byte") )
  929. pFtD->fsFlags|=CA_FT_CNTBYTE;
  930. else if ( !strcmp(buf,"string") )
  931. pFtD->fsFlags|=CA_FT_CNTSTRING;
  932. else if ( !strcmp(buf,"long") )
  933. pFtD->fsFlags|=CA_FT_CNTLONG;
  934. else if ( !strcmp(buf,"short") )
  935. pFtD->fsFlags|=CA_FT_CNTSHORT;
  936. else {
  937. free(cts);
  938. return (-1);
  939. }
  940. }
  941. while( *tmp && isspace(*tmp) ) tmp++;
  942. s2=tmp;
  943. /* Get the contents if any */
  944. if (*s2)
  945. {
  946. pFtD->pszContents = (char *)calloc(1,strlen(s2)+1);
  947. strcpy(pFtD->pszContents,s2);
  948. free(cts);
  949. }
  950. return 0;
  951. }
  952. /*****************************************************************
  953. ** **
  954. ** IsLastSingle(char *str) **
  955. ** **
  956. ** Description: returns TRUE if the last character of the **
  957. ** string str is a single-byte character, returns **
  958. ** FALSE if it is a multi-byte character. **
  959. ** **
  960. ******************************************************************/
  961. Boolean
  962. IsLastSingle(char *str)
  963. {
  964. int n;
  965. if(MB_CUR_MAX == 1)
  966. return(TRUE);
  967. while(*str) {
  968. n = mblen(str, MB_CUR_MAX);
  969. str += n;
  970. }
  971. if(n > 1)
  972. return(FALSE);
  973. else
  974. return(TRUE);
  975. }