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