2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $XConsortium: parser.c /main/8 1996/03/25 09:14:08 rswiston $ */
24 /***************************************************************************/
28 /***************************************************************************/
41 /***************************************************************************
43 * Local procedure declarations
45 ***************************************************************************/
48 char ** GetKeywordValuePairs(char *, int *, int);
49 FiletypeData ** GetFiletypeData(FILE *, char *, short *);
50 char ** ProcessExecString(char *);
51 int ProcessContents(FiletypeData *);
52 Boolean IsLastSingle(char *);
55 /***************************************************************************
57 * Extern variable declarations
59 ***************************************************************************/
62 /***************************************************************************
64 * Global variable declarations
66 ***************************************************************************/
68 /* Action Keyword Table */
69 char keywordDB[][30] = { "ACTION" ,
80 /* Max Number of fields in Action Keyword Table */
81 #define MAX_NUM_ACTION_FIELDS 8
83 /* Filetype Keyword Table */
84 char FiletypekeywordDB[][30] = { "DATA_ATTRIBUTES" ,
93 "DATA_ATTRIBUTES_NAME" ,
104 /* Max Number of fields in Filetype Keyword Table */
105 #define MAX_NUM_FILETYPE_FIELDS 17
108 char *args[3],*fline;
110 static int state = 0;
113 /*****************************************************************
115 ** GetActionData(FILE *fp, ActionData *) **
117 ** Description: Parses the action file and fills the data in the**
118 ** pointer pointing to the ActionData structure **
119 ** passed as input. **
121 ** Input : Filepointer that points to the ActionFile and, **
122 ** a pointer to the ActionData structure. **
124 ** Output : 0 (No error). **
127 ** references : dtcreate.h, parser.h, and dtcreate spec. **
129 ******************************************************************/
133 GetActionData(FILE *fp, ActionData *ActionDataptr)
135 int rc,manflds=0,len,first=TRUE,lastfld=0,fldid=-1;
136 char linebuf[1024],**wordPairs,**execstr;
139 /* reset the read pointer to zero byte for fp */
141 /* Initialize the ActionData structure passed */
143 memset((ActionData *)ActionDataptr,
144 NULL,sizeof(ActionData));
147 printf("ActionDataptr is NULL\n");
152 /* initialize the linebuf with NULL's */
153 bzero(linebuf,sizeof(linebuf));
154 while (fgets (linebuf, sizeof (linebuf)-1, fp))
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] == '}')
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
168 if( (wordPairs = GetKeywordValuePairs(linebuf,&fldid,ACTION_TABLE)) != NULL)
170 if( first && strcmp(wordPairs[0],"ACTION") )
173 printf("first && strcmp(wordPairs[0],ACTION)\n");
179 /* Update the mandatory fields counter */
180 if( !strcmp(wordPairs[0],"TYPE") ||
181 !strcmp(wordPairs[0],"EXEC_STRING") ||
182 !strcmp(wordPairs[0],"WINDOW_TYPE") )
184 if( !strcmp(wordPairs[0],"WINDOW_TYPE") )
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;
193 if( !strcmp(wordPairs[0],"ARG_TYPE") )
194 ActionDataptr->fsFlags |= CA_DF_ONLYFTFILES;
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.
200 if( wordPairs && wordPairs[0] && !wordPairs[1])
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
209 case 7: /* next line for action_name */
210 ActionDataptr->pszName=wordPairs[0];
213 case 1: /* next line for action_icon_name */
214 ActionDataptr->pszIcon=wordPairs[0];
217 case 2 : /* next line for exec_string */
218 ActionDataptr->pszCmd=wordPairs[0];
221 case 3: /* next line for action_help_text */
222 ActionDataptr->pszHelp=wordPairs[0];
228 else if(wordPairs && wordPairs[1])
230 if(fldid >= 0 && fldid <=2)
232 /* for fldid see the comments above */
235 case 7: /* first line for action_name */
236 ActionDataptr->pszName=wordPairs[1];
239 case 1: /* first line for action_icon_name */
240 ActionDataptr->pszIcon=wordPairs[1];
243 case 2 : /* first line for exec_string */
244 ActionDataptr->pszCmd=wordPairs[1];
247 case 3: /* first line for action_help_text */
249 ActionDataptr->pszHelp=wordPairs[1];
252 default: state=0;break;
256 /* reset the linebuf to NULL's */
257 bzero(linebuf,sizeof(linebuf));
262 /* Done with retrieving Action Data */
263 /* Check if we got all the mandatory fields data */
266 printf("if(manflds != 3)\n");
271 /* Everything looks right so process the exec_string */
272 if( !(execstr = ProcessExecString(ActionDataptr->pszCmd)) )
274 ActionDataptr->pszCmd = NULL;
275 ActionDataptr->pszPrompt = 0;
279 ActionDataptr->pszCmd = execstr[0];
280 ActionDataptr->pszPrompt = execstr[1];
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) {
288 printf("!ActionDataptr->papFiletypes && ActionDataptr->cFiletypes > 0)\n");
290 return(1); /* return 1 if error */
292 return(0); /* return 0 if no error */
298 /*****************************************************************
300 ** GetFiletypeData(FILE *fp, char *pszOpenCmd) **
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). **
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. **
311 ** Output : Pointer to an array of FiletypeData structures **
312 ** containing data for all the Filetypes,and,no of **
315 ** references : dtcreate.h, parser.h, and dtcreate spec. **
317 ******************************************************************/
320 GetFiletypeData(FILE *fp, char *pszOpenCmd, short *nftypes)
322 int manflds=0,len,nfiletypes,previous=0,lastfld=0,fldid;
323 char linebuf[1024],**wordPairs,**execstr;
324 FiletypeData **ppFiletypeData,**ppnewFiletypeData;
330 /* Initialize the linebuf */
331 bzero(linebuf,sizeof(linebuf));
332 while (fgets (linebuf, sizeof (linebuf)-1, fp))
334 /* If begin of a stanza skip and continue */
335 if(linebuf[0] == '{')
340 /* skip the rest of the line if a comment found */
341 if(linebuf[0] == '#') continue;
343 /* If end of a stanza check if all the mandatory fields are there */
344 if( linebuf[0] == '}' )
346 /* Check for atleast one field in DATA_ATTRIBUTES stanza */
347 if( previous == DATA_ATTRIBUTES && manflds != 1 )
349 printf("Error in DATA_ATTR stanza of the FiletypeData\n");
352 /* Check for atleast one field in DATA_CRITERIA stanza */
353 else if( previous == DATA_CRITERIA && manflds != 1 )
355 printf("Error in DATA_CRITERIA stanza of the FiletypeData\n");
358 /* Check for atleast two fields in ACTION_OPEN or ACTION_PRINT stanza */
359 else if( (previous == ACTION_OPEN || previous == ACTION_PRINT) )
363 printf("Error in ACTION_OPEN/PRINT stanza of the FiletypeData\n");
367 /* Check for atleast three fields in ACTION_PRINT_FTYPE stanza */
368 else if( previous == ACTION_PRINT_FTYPE && manflds != 3 )
370 printf("Error in ACTION_PRINT_FTYPE stanza of the FiletypeData\n");
375 len = strlen (linebuf);
376 if (linebuf[len-1] == '\n')
377 linebuf[len-1] = '\0';
379 if( (wordPairs = GetKeywordValuePairs(linebuf,&fldid,FILETYPE_TABLE)) != NULL)
381 if( !strcmp(wordPairs[0],"DATA_ATTRIBUTES") )
386 /* Allocate a filetypedata pointer to an array of filetypedata records */
389 if( (ppFiletypeData = (FiletypeData **)calloc(1,sizeof(FiletypeData *)))
392 printf("\n Cannot allocate memory\n");
395 /* Allocate a filetypedata record */
398 if( (ppFiletypeData[nfiletypes] =
399 (FiletypeData *)calloc(1,sizeof(FiletypeData)) )
402 printf("\n Cannot allocate memory\n");
408 ppFiletypeData[nfiletypes]->pszOpenCmd = pszOpenCmd;
409 previous = DATA_ATTRIBUTES;
412 else if(previous == ACTION_OPEN || previous == ACTION_PRINT)
414 /* New filetypedata started so allocate a new filetypedata ptr */
415 if( (ppnewFiletypeData =
416 (FiletypeData **)realloc((FiletypeData *)ppFiletypeData,
417 nfiletypes+2 * sizeof(FiletypeData *)))
420 printf("\n Cannot allocate memory\n");
423 else if(ppFiletypeData)
425 ppFiletypeData=ppnewFiletypeData;
426 /* Process the contents field if any */
427 if(ProcessContents((FiletypeData *)ppFiletypeData[nfiletypes]) < 0 )
429 printf("\n Error in Contents Data\n");
432 /* Everything looks right so process the exec_string */
433 if( !(execstr = ProcessExecString((char *)ppFiletypeData[nfiletypes]->pszPrintCmd)) )
434 ppFiletypeData[nfiletypes]->pszPrintCmd=NULL;
436 ppFiletypeData[nfiletypes]->pszPrintCmd=execstr[0];
438 /* Allocate a new filetypedata record */
439 if( (ppFiletypeData[nfiletypes] =
440 (FiletypeData *)calloc(1,sizeof(FiletypeData)) )
443 printf("\n Cannot allocate memory\n");
446 ppFiletypeData[nfiletypes]->pszOpenCmd = pszOpenCmd;
447 previous = DATA_ATTRIBUTES;
454 printf("Error in filetypedata \n");
458 else if( !strcmp(wordPairs[0],"DATA_CRITERIA") )
460 if( previous == DATA_ATTRIBUTES )
462 previous = DATA_CRITERIA;
467 printf("Error in filetypedata \n");
471 else if( !strcmp(wordPairs[0],"ACTION") && !strcmp(wordPairs[1],"Open") )
473 if( previous == DATA_CRITERIA )
475 previous = ACTION_OPEN;
480 printf("Error in filetypedata \n");
484 else if( !strcmp(wordPairs[0],"ACTION") && strcmp(wordPairs[1],"Open") &&
485 strcmp(wordPairs[1], "Print") )
487 if( previous == ACTION_OPEN )
489 previous = ACTION_PRINT_FTYPE;
494 printf("Error in filetypedata \n");
498 else if( !strcmp(wordPairs[0],"ACTION") && !strcmp(wordPairs[1],"Print") )
500 if( previous == ACTION_PRINT_FTYPE )
502 previous = ACTION_PRINT;
507 printf("Error in filetypedata \n");
513 /* update mandatory fields counter */
514 if( previous == DATA_ATTRIBUTES && strcmp(wordPairs[0],"DATA_ATTRIBUTES") )
516 if( !strcmp(wordPairs[0],"ACTIONS") )
519 else if( previous == DATA_CRITERIA )
521 if( !strcmp(wordPairs[0],"DATA_ATTRIBUTES_NAME") )
524 else if( previous == ACTION_OPEN || previous == ACTION_PRINT )
526 if( !strcmp(wordPairs[0],"ARG_TYPE") ||
527 !strcmp(wordPairs[0],"TYPE") ||
528 !strcmp(wordPairs[0],"MAP_ACTION") ||
529 !strcmp(wordPairs[0],"LABEL") )
532 else if( previous == ACTION_PRINT_FTYPE )
534 if( !strcmp(wordPairs[0],"TYPE") ||
535 !strcmp(wordPairs[0],"WINDOW_TYPE") )
543 if( wordPairs && !wordPairs[1] && wordPairs[0])
547 case 0: /* next line for filetype_name */
548 ppFiletypeData[nfiletypes]->pszName=wordPairs[0];
551 case 1: /* next line for icon_name */
552 ppFiletypeData[nfiletypes]->pszIcon=wordPairs[0];
555 case 2 : /* next line for help_text */
556 ppFiletypeData[nfiletypes]->pszHelp=wordPairs[0];
559 case 3: /* next line for print_cmd */
560 ppFiletypeData[nfiletypes]->pszPrintCmd=wordPairs[0];
563 case 4: /* next line for name_pattern or path_pattern */
564 ppFiletypeData[nfiletypes]->pszPattern=wordPairs[0];
566 case 5: /* next line for name_pattern or path_pattern */
567 ppFiletypeData[nfiletypes]->pszPattern=wordPairs[0];
569 case 6: /* next line for mode */
570 ppFiletypeData[nfiletypes]->pszPermissions=wordPairs[0];
572 case 7: /* next line for contents */
573 ppFiletypeData[nfiletypes]->pszContents=wordPairs[0];
579 else if(wordPairs && wordPairs[1])
583 case 0: /* first line for filetype_name */
584 ppFiletypeData[nfiletypes]->pszName = wordPairs[1];
587 case 1: /* first line for icon_name */
588 ppFiletypeData[nfiletypes]->pszIcon=wordPairs[1];
591 case 2 : /* first line for help_text */
592 ppFiletypeData[nfiletypes]->pszHelp=wordPairs[1];
595 case 3: /* first line for print_cmd */
596 ppFiletypeData[nfiletypes]->pszPrintCmd=wordPairs[1];
600 case 4: /* first line for name_pattern or path_pattern */
601 ppFiletypeData[nfiletypes]->pszPattern=wordPairs[1];
604 case 5: /* first line for name_pattern or path_pattern */
605 ppFiletypeData[nfiletypes]->pszPattern=wordPairs[1];
608 case 6: /* first line for mode */
609 ppFiletypeData[nfiletypes]->pszPermissions=wordPairs[1];
612 case 7: /* first line for contents */
613 ppFiletypeData[nfiletypes]->pszContents=wordPairs[1];
621 bzero(linebuf,sizeof(linebuf));
622 } /* end of while fgets */
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) )
629 else if(ppFiletypeData)
631 /* Process Contents for the last file filetype if any */
632 if(ProcessContents((FiletypeData *)ppFiletypeData[nfiletypes]) < 0)
634 printf("\n Error in Contents Data\n");
637 /* Everything looks right so process the exec_string */
639 ProcessExecString((char *)ppFiletypeData[nfiletypes]->pszPrintCmd)) )
640 ppFiletypeData[nfiletypes]->pszPrintCmd=NULL;
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;
655 /*****************************************************************
657 ** GetKeywordValuePairs(char *s, int *id, int table) **
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. **
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 **
670 ** Output : pointer to two pointers pointing to text strings**
671 ** fieldid in the id parameter. **
673 ** references : dtcreate.h, parser.h, and dtcreate spec. **
675 ******************************************************************/
678 GetKeywordValuePairs(char *s, int *id, int table)
684 args[0] = args[1] = args[2] = NULL;
685 /* Skip all leading spaces */
686 while (*s && isspace (*s))
688 /* Skip the complete line if a '#' character is found (comments) */
689 if (!*s || *s == '#')
692 while (*s && *s != '#' && !isspace (*s))
696 args[0] = (char *)malloc (s - wordStart + 1);
699 memset(args[0],0,sizeof(args[0]));
701 strncpy (args[0], wordStart, s - wordStart);
702 args[0][s-wordStart] = '\0';
706 args[1] = (char *)malloc (strlen(s)+1);
713 memset(args[1],0,sizeof(args[1]));
715 /* Skip all leading spaces */
716 while (*s && isspace (*s))
720 /* Check for whether args[0] is a keyword or not */
722 if( table == ACTION_TABLE )
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)
729 else if( table == FILETYPE_TABLE )
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)
736 /* If no keyword found then keep the complete string
739 if( (idx == MAX_NUM_ACTION_FIELDS && table == ACTION_TABLE) ||
740 (idx == MAX_NUM_FILETYPE_FIELDS && table == FILETYPE_TABLE) )
744 if( (temp4 = (char *)realloc(args[0],strlen(args[0])+strlen(args[1])+2) ) == NULL )
746 printf("Cannot Allocate memory\n");
751 strcat(args[0],args[1]);
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)
762 printf("Cannot Allocate memory\n");
765 strcat(temp4,args[0]);
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';
774 args[0][strlen(args[0])] = '\0';
776 args[1][strlen(args[1])] = '\0';
777 if(args[0] && args[1])
780 flinesize=strlen(fline);
782 if(!args[1] && args[0])
785 flinesize=strlen(fline);
791 /*****************************************************************
793 ** ProcessExecString(char *) **
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 **
803 ** Input : A character pointer that points to the complete **
804 ** text string comprising the command and arguments**
805 ** and prompt (if any). **
807 ** Limitation : Supports only ONE prompt. **
809 ** Output : returns 0 (No error). **
810 ** returns >0 (Error). **
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. **
817 ** references : dtcreate.h, parser.h, and dtcreate spec. **
819 ******************************************************************/
822 ProcessExecString(char *cmd)
825 char *s1, *s2,*s3,*s4,*argbuf,*exec_args[3];
826 int done=FALSE, argfound=FALSE,promptfound=FALSE;
829 return((char **)NULL);
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 */
841 s4 = strstr(s1,"%Arg");
846 strncat(exec_args[0],s1,(s4-s1));
847 exec_args[0][strlen(exec_args[0])] = '\0';
850 s2 = strchr(s1+1,'%'); /* at this point we got s1 to s2
851 covers the complete string
854 if(argbuf) { free(argbuf); argbuf = NULL; }
857 argbuf = (char *)calloc(1,(s2-s1)+2);
858 strncpy(argbuf,s1,(s2-s1)+1);
862 strcat(exec_args[0],s1);
866 argbuf[strlen(argbuf)]='\0';
867 if( strncmp(argbuf,"%Arg_",5) &&
868 strncmp(argbuf,"%Args%",6) &&
869 strncmp(argbuf,"%Args\"",6) )
871 strncat(exec_args[0],argbuf,strlen(argbuf)-1);
872 exec_args[0][strlen(exec_args[0])] = '\0';
879 strcat(exec_args[0],s1);
880 if(argbuf) { free(argbuf); argbuf = NULL; }
890 /* move s1 until a '_' or 's' */
891 tmp = strchr(argbuf,'_');
893 tmp= strchr(argbuf,'s');
894 strcat(exec_args[0],"$");
896 /* start of Arg processing */
897 while (*tmp != '%' && *tmp != '"' )
901 strcat(exec_args[0],"*");
904 if( *tmp > '0' && *tmp <= '9')
906 strncat(exec_args[0],tmp,1);
907 exec_args[0][strlen(exec_args[0])] = '\0';
911 /* end of Arg processing */
913 /* Get Prompt string if any */
914 s3 = strchr(argbuf,'"');
915 if(s3 && *(s3+1) != '"')
920 if( (tmp = strchr(s3,'"')) )
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';
930 /* see if there is some stuff between the last '%'
931 and the next first '%' of another Arg
937 if(argbuf) { free(argbuf); argbuf = NULL; }
941 /*****************************************************************
943 ** ProcessContents(FiletypeData *) **
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**
950 ** Input : A pointer of type FiletypeData defined in **
953 ** Output : Fills the sStart, fsFlags and pszContents fields**
954 ** of the FiletypeData pointer and returns 0 (No **
955 ** error or >0 (error) values. **
957 ** Assumptions: Fields are separated by atleast one blank **
960 ** references : dtcreate.h, parser.h, and dtcreate spec. **
962 ******************************************************************/
965 ProcessContents(FiletypeData *pFtD)
968 char *s1,*tmp,*s2,buf[10],*cts;
971 bzero(buf,sizeof(buf));
972 /* simply return if there is no data in contents field */
973 if(!pFtD->pszContents)
975 cts = (char *)calloc(1,strlen(pFtD->pszContents)+1);
976 strcpy(cts,pFtD->pszContents);
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 */
984 if( (s1 = strchr(cts,' ')) )
986 while( *s1 && !isspace(*s1) && *s1 != '\n') s1++;
989 strncpy(buf,cts,(s1-cts));
991 pFtD->sStart=atoi(buf);
993 while( *s1 && isspace(*s1) ) s1++;
995 /* Get the fsFlags value if any */
997 bzero(buf,sizeof(buf));
999 if ( (tmp = strchr(s1,' ')) )
1001 while( *tmp && !isspace(*tmp) && *tmp != '\n') tmp++;
1004 strncpy(buf,s1,(tmp-s1));
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;
1017 while( *tmp && isspace(*tmp) ) tmp++;
1019 /* Get the contents if any */
1022 pFtD->pszContents = (char *)calloc(1,strlen(s2)+1);
1023 strcpy(pFtD->pszContents,s2);
1032 /*****************************************************************
1034 ** IsLastSingle(char *str) **
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. **
1040 ******************************************************************/
1043 IsLastSingle(char *str)
1051 n = mblen(str, MB_CUR_MAX);