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