cmdline.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:22k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /**********************************************************************
  2. MPEG-4 Audio VM
  3. Command line module
  4. This software module was originally developed by
  5. Charalampos Ferkidis (University of Hannover / ACTS-MoMuSys)
  6. Heiko Purnhagen (University of Hannover / ACTS-MoMuSys)
  7. partially based on a concept by FhG IIS, Erlangen
  8. and edited by
  9. in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard
  10. ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an
  11. implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools
  12. as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives
  13. users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this
  14. software module or modifications thereof for use in hardware or
  15. software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio
  16. standards. Those intending to use this software module in hardware or
  17. software products are advised that this use may infringe existing
  18. patents. The original developer of this software module and his/her
  19. company, the subsequent editors and their companies, and ISO/IEC have
  20. no liability for use of this software module or modifications thereof
  21. in an implementation. Copyright is not released for non MPEG-2
  22. NBC/MPEG-4 Audio conforming products. The original developer retains
  23. full right to use the code for his/her own purpose, assign or donate
  24. the code to a third party and to inhibit third party from using the
  25. code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This
  26. copyright notice must be included in all copies or derivative works.
  27. Copyright (c) 1996.
  28. Source file: cmdline.c
  29. $Id: cmdline.c,v 1.2 2002/05/13 15:48:41 mvillari Exp $
  30. Required modules:
  31. common.o common module
  32. Authors:
  33.       partially based on a concept by FHG <iis.fhg.de>
  34. CF    Charalampos Ferekidis, Uni Hannover <ferekidi@tnt.uni-hannover.de>
  35. HP    Heiko Purnhagen, Uni Hannover <purnhage@tnt.uni-hannover.de>
  36. Changes:
  37. 28-may-96   CF    added functions for parsing of init files and strings
  38. 05-jun-96   HP    minor changes
  39.                   moved ErrorMsg() to seperat module
  40. 06-jun-96   HP    setDefault added to CmdLineEval()
  41. 07-jun-96   HP    use CommonProgName(), CommonWarning(), CommonExit()
  42. 10-jun-96   HP    ...
  43. 13-jun-96   HP    changed ComposeFileName()
  44. 14-jun-96   HP    fixed bug in ComposeFileName()
  45. 19-jun-96   HP    changed ComposeFileName()
  46.                   fixed bug in CmdLineParseString()
  47. 20-jun-96   HP    added NOTE re CmdLineParseString()
  48. 08-aug-96   HP    changed string handling in CmdLineParseString()
  49.                   changed handling of variable length argument list
  50.                   added CmdLineEvalFree(), CmdLineParseFree()
  51. 09-aug-96   HP    ...
  52. 14-aug-96   HP    fixed minor bug in CmdLineHelp(), added debug code
  53. 26-aug-96   HP    CVS
  54. 27-aug-96   HP    fixed bug in CmdLineEvalFree()
  55. 10-dec-96   HP    changed dflt. extension concat in ComposeFileName()
  56. 07-apr-97   HP    "-" support in CmdLineEval() and ComposeFileName()
  57. 04-may-98   HP/BT unsigned in ComposeFileName()
  58. **********************************************************************/
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62. #include "cmdline.h" /* command line module */
  63. #include "common_m4a.h" /* common module */
  64. /* ---------- declarations ---------- */
  65. #define MAX_HELP_SIZE 4096 /* max length of parameter/switch help */
  66. #define MAX_TOKEN_NUM 4096 /* max num of tokens generated by parser */
  67. #define MAX_LINE_SIZE 1024 /* max length of line in parsed init file */
  68. #define MAX_FILE_SIZE 65536 /* max length of parsed init file */
  69. /* ---------- variables ---------- */
  70. static int CLdebugLevel = 0; /* debug level */
  71. /* ---------- internal functions ---------- */
  72. /* StripPath() */
  73. /* Strip path from file name. */
  74. static char *StripPath (
  75.   char *fileName) /* in: file name */
  76. /* returns: file name without path */
  77. {
  78.   char *tmpName;
  79.   do {
  80.     tmpName = strchr(fileName,':');
  81.     if (tmpName==NULL)
  82.       tmpName=strchr(fileName,'\');
  83.     if (tmpName==NULL)
  84.       tmpName=strchr(fileName,'/');
  85.     if (tmpName!=NULL)
  86.       fileName = tmpName+1;
  87.   } while (tmpName!=NULL);
  88.   return fileName;
  89. }
  90. /* ---------- functions ---------- */
  91. /* CmdLineInit() */
  92. /* Init command line module. */
  93. void CmdLineInit (
  94.   int debugLevel) /* in: debug level */
  95. /*     0=off  1=basic  2=full */
  96. {
  97.   CLdebugLevel = debugLevel;
  98.   if (CLdebugLevel >= 1)
  99.     printf("CmdLineInit: debugLevel=%dn",CLdebugLevel);
  100. }
  101. /* CmdLineEval() */
  102. /* Evaluate parameters and switches in argv[]. */
  103. /* Command line mode (progNamePtr!=NULL): */
  104. /*   Evaluate command line in argv[] from main() and extract program name */
  105. /*   from argv[0]. Switches are identified by preceding '-' in the */
  106. /*   command line. */
  107. /* Token list mode (progNamePtr==NULL): */
  108. /*   Evaluate token list in argv[] (as generated by CmdLineParseString() or */
  109. /*   CmdLineParseFile()). Switches are identified by preceding '-' if */
  110. /*   paraList!=NULL. Switches don't have a preceding '-' if paraList==NULL. */
  111. int CmdLineEval (
  112.   int argc, /* in: num command line args */
  113.   char *argv[], /* in: command line args */
  114.   CmdLinePara *paraList, /* in: parameter info list */
  115. /*     or NULL */
  116.   CmdLineSwitch *switchList, /* in: switch info list */
  117. /*     or NULL */
  118.   int setDefault, /* in: 0 = leave switch used flags and args */
  119. /*         unchanged */
  120. /*     1 = init switch used flags and args */
  121. /*         with defaultValue */
  122.   char **progNamePtr) /* out: program name */
  123. /*      or NULL */
  124. /* returns: */
  125. /*  0=OK  1=help switch  2=error */
  126. {
  127.   char *progName;
  128.   char *tmpProgName;
  129.   int i;
  130.   int minusFlag;
  131.   char *minusChar;
  132.   CmdLinePara *paraPtr;
  133.   CmdLineSwitch *switchPtr;
  134.   int tmpVarArgIdx[MAX_TOKEN_NUM];
  135.   int count;  
  136.   int *varArgIdx;
  137.   /* extract program name from argv[0] if command line mode */
  138.   if (progNamePtr != NULL) {
  139.     progName = StripPath(argv[0]);
  140.     if ((tmpProgName=strchr(progName,'.'))!=NULL)
  141.       *tmpProgName = '';
  142.     *progNamePtr = progName;
  143.     CommonProgName(progName);
  144.   }
  145.   else /* progNamePtr==NULL */
  146.     progName = NULL;
  147.   /* set minusFlag if switches are preceded by '-' */
  148.   minusFlag = (progNamePtr!=NULL || paraList!=NULL);
  149.   minusChar = (minusFlag) ? "-" : "";
  150.     
  151.   if (CLdebugLevel >= 1)
  152.     printf("CmdLineEval: argc=%d  mode=%s  minusChar="%s"n",
  153.    argc,(progNamePtr!=NULL)?"cmd line":"token list",minusChar);
  154.   if (setDefault) {
  155.     /* reset switch used flags and evaluate default values */
  156.     switchPtr = switchList;
  157.     while (switchPtr != NULL && switchPtr->switchName != NULL) {
  158.       if (switchPtr->argument != NULL) {
  159. if (switchPtr->usedFlag != NULL)
  160.   *((int*)switchPtr->usedFlag) = 0;
  161. if (switchPtr->format == NULL)
  162.   *((int*)switchPtr->argument) = 0;
  163. else
  164.   if (switchPtr->defaultValue != NULL) {
  165.     if (strcmp(switchPtr->format,"%s") == 0)
  166.       *((char**)switchPtr->argument) = switchPtr->defaultValue;
  167.     else
  168.       if (sscanf(switchPtr->defaultValue,switchPtr->format,
  169.  switchPtr->argument) != 1) {
  170. CommonWarning("CmdLineEval: "
  171.       "switch %s%s default argument format error",
  172.       minusChar,switchPtr->switchName);
  173. return 2;
  174.       }
  175.   }
  176.       }
  177.       switchPtr++;
  178.     }
  179.   }
  180.   /* scan arguments  */
  181.   i = (progNamePtr==NULL) ? 0 : 1; /* skip program name */
  182. /* if command line mode */
  183.   paraPtr = paraList;
  184.   count = 0;
  185.   while (i < argc) {
  186.     if ((*argv[i] == '-' && *(argv[i]+1) != '') ||
  187. (minusFlag == 0 && *argv[i] != '')) {
  188.       /* evaluate cmdline switch */
  189.       switchPtr = switchList;
  190.       while (switchPtr != NULL && switchPtr->switchName != NULL) {
  191. if (strcmp(argv[i]+minusFlag,switchPtr->switchName) == 0) {
  192.   /* switchList entry found */
  193.   if (switchPtr->argument == NULL) {
  194.     /* help switch found */
  195.     return 1;
  196.   }
  197.   if (switchPtr->format != NULL) {
  198.     /* read switch argument */
  199.     if (++i >= argc) {
  200.       CommonWarning("CmdLineEval: switch %s%s has no argument",
  201.     minusChar,switchPtr->switchName);
  202.       return 2;
  203.     }
  204.     else
  205.       if (strcmp(switchPtr->format,"%s") == 0)
  206. *((char**)switchPtr->argument) = argv[i];
  207.       else
  208. if (sscanf(argv[i],switchPtr->format,switchPtr->argument)
  209.     != 1) {
  210.   CommonWarning("CmdLineEval: "
  211. "switch %s%s argument format error",
  212. minusChar,switchPtr->switchName);
  213.   return 2;
  214. }
  215.   }
  216.   else
  217.     /* switch without argument */
  218.     *((int*)switchPtr->argument) = 1;
  219.   /* set switch used flag */
  220.   if (switchPtr->usedFlag != NULL)
  221.     *((int*)switchPtr->usedFlag) = 1;
  222.   break; /* while (switchPtr ...) */
  223. }
  224. switchPtr++;
  225.       } /* while (switchPtr ...) */
  226.       if (switchPtr == NULL || switchPtr->switchName == NULL) {
  227. CommonWarning("CmdLineEval: switch %s unknown",argv[i]);
  228. return 2;
  229.       }
  230.     }
  231.     else { /* if (*argv[i] == '-' && ...) */
  232.       /* evaluate cmdline argument */
  233.       if (paraPtr == NULL || paraPtr->argument == NULL) {
  234. CommonWarning("CmdLineEval: too many arguments",argv[i]);
  235. return 2;
  236.       }
  237.       if (paraPtr->format == NULL) {
  238. /* variable length argument list */
  239. if (count+1 >= MAX_TOKEN_NUM) {
  240.   CommonWarning("CmdLineEval: argument list %s too long",
  241. paraPtr->help);
  242.   return 2;
  243. }
  244. tmpVarArgIdx[count++] = i;
  245.       }
  246.       else {
  247. if (strcmp(paraPtr->format,"%s") == 0)
  248.   *((char**)paraPtr->argument) = argv[i];
  249. else
  250.   if (sscanf(argv[i],paraPtr->format,paraPtr->argument) != 1) {
  251.     CommonWarning("CmdLineEval: argument %s format error",
  252.   paraPtr->help);
  253.     return 2;
  254.   }
  255. paraPtr++;
  256.       }
  257.     }
  258.     
  259.     i++;
  260.   } /* while (i < argc) */
  261.     
  262.   if (paraPtr != NULL && paraPtr->argument != NULL &&
  263.       paraPtr->format == NULL) {
  264.     /* variable length argument list */
  265.     if ((varArgIdx = (int*)malloc((count+1)*sizeof(int))) == NULL)
  266.       CommonExit(1,"CmdLineEval: memory allocation error (varArgIdx)");
  267.     for (i=0; i<count; i++)
  268.       varArgIdx[i] = tmpVarArgIdx[i];
  269.     varArgIdx[count] = -1;
  270.     *((int**)paraPtr->argument) = varArgIdx;
  271.     paraPtr++;
  272.   }
  273.   if (paraPtr != NULL && paraPtr->argument != NULL) {
  274.     CommonWarning("CmdLineEval: argument %s is missing",
  275.   paraPtr->help);
  276.     return 2;
  277.   }
  278.   return 0;
  279. }
  280. /* CmdLineEvalFree() */
  281. /* Free memory allocated by CmdLineEval() for variable length */
  282. /* argument list. */
  283. void CmdLineEvalFree (
  284.   CmdLinePara *paraList) /* in: parameter info list */
  285. /*     or NULL */
  286. {
  287.   CmdLinePara *paraPtr;
  288.   paraPtr = paraList;
  289.   while (paraPtr != NULL && paraPtr->argument != NULL)
  290.     if (paraPtr->format == NULL) {
  291.       free(*((void**)paraPtr->argument));
  292.       paraPtr = NULL;
  293.     }
  294.     else
  295.       paraPtr++;
  296.   if (CLdebugLevel >= 1)
  297.     printf("CmdLineEvalFree: %sn",
  298.    (paraList && !paraPtr) ? "free varArgIdx" : "no varArgIdx");
  299. }
  300. /* CmdLineHelp() */
  301. /* Print help text about program usage including description of */
  302. /* command line parameters and switches. */
  303. void CmdLineHelp (
  304.   char *progName, /* in: program name */
  305. /*     or NULL */
  306.   CmdLinePara *paraList, /* in: parameter info list */
  307. /*     or NULL */
  308.   CmdLineSwitch *switchList, /* in: switch info list */
  309. /*     or NULL */
  310.   FILE *outStream) /* in: output stream */
  311. /*     (e.g. stdout) */
  312. {
  313.   int minusFlag;
  314.   char *minusChar;
  315.   char help[MAX_HELP_SIZE]; /* copy of help for strtok() */
  316.   char *token;
  317.   int maxSwitchLen,tmp;
  318.   CmdLinePara *paraPtr;
  319.   CmdLineSwitch *switchPtr;
  320.   /* set minusFlag if switches are preceded by '-' */
  321.   minusFlag = (progName!=NULL || paraList!=NULL);
  322.   minusChar = (minusFlag) ? "-" : "";
  323.     
  324.   fprintf(outStream,"n");
  325.   maxSwitchLen = 0;
  326.   switchPtr = switchList;
  327.   while (switchPtr != NULL && switchPtr->switchName != NULL) {
  328.     if ((tmp=strlen(switchPtr->switchName)+
  329.  ((switchPtr->argument!=NULL && switchPtr->format!=NULL)?4:0))
  330. > maxSwitchLen)
  331.       maxSwitchLen = tmp;
  332.     switchPtr++;
  333.   }
  334.   
  335.   if (progName != NULL)
  336.     fprintf(outStream,"usage: %s",progName);
  337.   else
  338.     fprintf(outStream,"token list format:");
  339.   fprintf(outStream," %sswitches",minusChar);
  340.   paraPtr = paraList;
  341.   while (paraPtr != NULL && paraPtr->argument != NULL) {
  342.     fprintf(outStream," %s",paraPtr->help);
  343.     if (paraPtr->format==NULL)
  344.       /* remaining args are not processed !!! */
  345.       break; /* while (paraPtr ...) */
  346.     paraPtr++;
  347.   }
  348.   fprintf(outStream,"n");
  349.   
  350.   /* display help for every switch  */
  351.   switchPtr=switchList;
  352.   while (switchPtr != NULL && switchPtr->switchName != NULL) {
  353.     fprintf(outStream,"%9s %s%s%-*s   ",
  354.     (switchPtr==switchList)?"switches:":"",
  355.     minusChar,switchPtr->switchName,
  356.     maxSwitchLen-strlen(switchPtr->switchName),
  357.     (switchPtr->format==NULL)?"":" <x>");
  358.     if (strchr(switchPtr->help,'n')==NULL)
  359.       fprintf(outStream,"%s",switchPtr->help);
  360.     else {
  361.       /* multiple lines separated by 'n' */
  362.       strncpy(help,switchPtr->help,MAX_HELP_SIZE-1);
  363.       help[MAX_HELP_SIZE-1] = '';
  364.       token = strtok(help,"n");
  365.       fprintf(outStream,"%s",token);
  366.       while (token!=NULL) {
  367. token = strtok(NULL,"n");
  368. if (token!=NULL) {
  369.   fprintf(outStream,"n");
  370.   if (strcmp(token,"b")==0)
  371.     fprintf(outStream,"%9s %*s  ",
  372.     "",maxSwitchLen+minusFlag,"");
  373.   else
  374.     fprintf(outStream,"%9s %*s   %s",
  375.     "",maxSwitchLen+minusFlag,"",token);
  376. }
  377.       }
  378.     }
  379.     if (switchPtr->argument!=NULL && switchPtr->defaultValue!=NULL)
  380.       fprintf(outStream," (dflt: %s)",switchPtr->defaultValue);
  381.     fprintf(outStream,"n");
  382.     switchPtr++;
  383.   }
  384.   fprintf(outStream,"n");
  385. }
  386. /* CmdLineParseString() */
  387. /* Parse a copy of string into tokens separated by sepaChar. */
  388. /* Resulting token list can be evaluated by CmdLineEval(). */
  389. char **CmdLineParseString (
  390.   char *string, /* in: string to be parsed */
  391. /*     NOTE: string is not modified */
  392.   char *sepaChar, /* in: token separator characters */
  393.   int *count) /* out: number of tokens generated by parser */
  394. /*      (corresponds to argc) */
  395. /* returns: */
  396. /*  list of tokens generated by parser */
  397. /*  (corresponds to argv[]) */
  398. {
  399.   char *tmpTokenList[MAX_TOKEN_NUM];
  400.   char *firstChar;
  401.   char *stringBuf;
  402.   char **tokenList;
  403.   int  i,size;
  404.   if (CLdebugLevel >= 1)
  405.     printf("CmdLineParseString: sepa="%s"n",sepaChar);
  406.   if (string == NULL)
  407.     stringBuf = NULL;
  408.   else {
  409.     /* find first non-sepaChar */
  410.     firstChar = string;
  411.     while (*firstChar!='' && strchr(sepaChar,*firstChar)!=NULL)
  412.       firstChar++;
  413.     size = strlen(firstChar);
  414.     
  415.     /* copy string content */ 
  416.     if ((stringBuf = (char*)malloc((size+1)*sizeof(char))) == NULL)
  417.       CommonExit(1,"CmdLineParseString: memory allocation error (stringBuf)");
  418.     strcpy(stringBuf,firstChar);
  419.   }
  420.   /* parse string */
  421.   i = 0;
  422.   tmpTokenList[i] = (stringBuf==NULL)?(char*)NULL:strtok(stringBuf,sepaChar);
  423.   if (tmpTokenList[0]!=NULL && tmpTokenList[0]!=stringBuf)
  424.     CommonExit(1,"CmdLineParseString: internal error");
  425.   while (tmpTokenList[i]!=NULL) {
  426.     if (CLdebugLevel >= 2)
  427.       printf("%4d: "%s"n",i,tmpTokenList[i]);
  428.     if (++i >= MAX_TOKEN_NUM)
  429.       CommonExit(1,"CmdLineParseString: too many tokens");
  430.     tmpTokenList[i] = strtok(NULL,sepaChar);
  431.   }
  432.   *count = i;
  433.   /* copy token list */
  434.   if ((tokenList = (char**)malloc((*count+1)*sizeof(char*))) == NULL)
  435.     CommonExit(1,"CmdLineParseString: memory allocation error (tokenList)");
  436.   for (i=0; i<*count; i++)
  437.     tokenList[i] = tmpTokenList[i];
  438.   tokenList[*count] = NULL;
  439.   
  440.   if (CLdebugLevel >= 1)
  441.     printf("CmdLineParseString: tokenCount=%dn",*count);
  442.   return tokenList;
  443. }
  444. /* CmdLineParseFile() */
  445. /* Parse init file into tokens separated by sepaChar. */
  446. /* Comments preceded by a commentSepaChar are ingnored. */
  447. /* Resulting token list can be evaluated by CmdLineEval(). */
  448. char **CmdLineParseFile (
  449.   char *fileName, /* in: file name of init file */
  450.   char *sepaChar, /* in: token separator characters */
  451.   char *commentSepaChar, /* in: comment separator characters */
  452.   int *count) /* out: number of tokens generated by parser */
  453. /*      (corresponds to argc) */
  454. /* returns: */
  455. /*  list of tokens generated by parser */
  456. /*  (corresponds to argv[]) */
  457. /*  or NULL if file error */
  458. {
  459.   FILE *initFile;
  460.   char lineBuf[MAX_LINE_SIZE];
  461.   char *comment;
  462.   char tmpFileBuf[MAX_FILE_SIZE];
  463.   char *firstChar;
  464.   char *fileBuf;
  465.   char *tmpTokenList[MAX_TOKEN_NUM];
  466.   char **tokenList;
  467.   int  i,size,line;
  468.   if (CLdebugLevel >= 1)
  469.     printf("CmdLineParseFile: file="%s"  sepa="%s"  com="%s"n",
  470.    fileName,sepaChar,commentSepaChar);
  471.   /* open init file */
  472.   if ((initFile = fopen(fileName,"r")) == NULL) {
  473.     CommonWarning("CmdLineParseFile: error opening init file %s",fileName);
  474.     return NULL;
  475.   }
  476.   
  477.   /* read init file */
  478.   line = 0;
  479.   size = 0;
  480.   tmpFileBuf[0] = '';
  481.   while (fgets(lineBuf,MAX_LINE_SIZE,initFile) != NULL) {
  482.     line++;
  483.     comment = strpbrk(lineBuf,commentSepaChar);
  484.     if (comment != NULL)
  485.       i = comment-lineBuf;
  486.     else {
  487.       i = strlen(lineBuf)-1;
  488.       if (lineBuf[i] != 'n')
  489. CommonExit(1,"CmdLineParseFile: line %d too long",line);
  490.     }
  491.     if (size+i+1 >= MAX_FILE_SIZE)
  492.       CommonExit(1,"CmdLineParseFile: file too long");
  493.     strncat(tmpFileBuf+size,lineBuf,i);
  494.     strncat(tmpFileBuf+size+i,sepaChar,1);
  495.     size += i+1;
  496.   }
  497.   
  498.   /* close init file */
  499.   if (fclose(initFile)) {
  500.     CommonWarning("CmdLineParseFile: error closing init file");
  501.     return NULL;
  502.   }
  503.   
  504.   if (CLdebugLevel >= 1)
  505.     printf("CmdLineParseFile: initFileLineNum=%dn",line);
  506.   /* find first non-sepaChar */
  507.   firstChar = tmpFileBuf;
  508.   while (*firstChar!='' && strchr(sepaChar,*firstChar)!=NULL)
  509.     firstChar++;
  510.   size -= firstChar-tmpFileBuf;
  511.   /* copy file content */ 
  512.   if ((fileBuf = (char*)malloc((size+1)*sizeof(char))) == NULL)
  513.     CommonExit(1,"CmdLineParseFile: memory allocation error (fileBuf)");
  514.   strcpy(fileBuf,firstChar);
  515.   /* parse string */
  516.   i = 0;
  517.   tmpTokenList[i] = strtok(fileBuf,sepaChar);
  518.   if (tmpTokenList[0]!=NULL && tmpTokenList[0]!=fileBuf)
  519.     CommonExit(1,"CmdLineParseFile: internal error");
  520.   while (tmpTokenList[i]!=NULL) {
  521.     if (CLdebugLevel >= 2)
  522.       printf("%4d: "%s"n",i,tmpTokenList[i]);
  523.     if (++i >= MAX_TOKEN_NUM)
  524.       CommonExit(1,"CmdLineParseFile: too many tokens");
  525.     tmpTokenList[i] = strtok(NULL,sepaChar);
  526.   }
  527.   *count = i;
  528.   /* copy token list */
  529.   if ((tokenList = (char**)malloc((*count+1)*sizeof(char*))) == NULL)
  530.     CommonExit(1,"CmdLineParseFile: memory allocation error (tokenList)");
  531.   for (i=0; i<*count; i++)
  532.     tokenList[i] = tmpTokenList[i];
  533.   tokenList[*count] = NULL;
  534.   
  535.   if (CLdebugLevel >= 1)
  536.     printf("CmdLineParseFile: tokenCount=%dn",*count);
  537.   return tokenList;
  538. }
  539. /* CmdLineParseFree() */
  540. /* Free memory allocated by CmdLineParseString() or CmdLineParseFile(). */
  541. void CmdLineParseFree (
  542.   char **tokenList) /* in: token list returned by */
  543. /*     CmdLineParseString() or */
  544. /*     CmdLineParseFile() */
  545. {
  546.   if (tokenList != NULL) {
  547.     if (*tokenList != NULL)
  548.       free(*tokenList);
  549.     free(tokenList);
  550.   }
  551.   if (CLdebugLevel >= 1)
  552.     printf("CmdLineParseFree: %sn",
  553.    (tokenList) ? "free tokenList" : "no tokenList");
  554. }
  555. /* ComposeFileName() */
  556. /* Compose filename using default path and extension if required. */
  557. /* Handles Unix & DOS paths. "-" is passed through directly. */
  558. int ComposeFileName (
  559.   char *inName, /* in: input filename */
  560.   int forceDefault, /* in: 0=keep input path and/or extension if */
  561. /*       available, otherwise use default(s) */
  562. /*     1=force usage of default */
  563. /*       path and extension */
  564.   char *defaultPath, /* in: default path */
  565. /*     or NULL */
  566.   char *defaultExt, /* in: default extension */
  567. /*     or NULL */
  568.   char *fileName, /* out: composed filename */
  569.   unsigned int fileNameMaxLen) /* in: fileName max length */
  570. /* returns: */
  571. /*  0=OK  1=result too long */
  572. {
  573.   char *name,*dot,*tmp;
  574.   char pathChar;
  575.   if (CLdebugLevel >= 1)
  576.     printf("ComposeFileName: in="%s"  forceDef=%d  path="%s"  ext="%s""
  577.    "  len=%dn",
  578.    inName,forceDefault,
  579.    (defaultPath!=NULL)?defaultPath:"(NULL)",
  580.    (defaultExt!=NULL)?defaultExt:"(NULL)",
  581.    fileNameMaxLen);
  582.   if (strcmp(inName,"-")==0) {
  583.     if (fileNameMaxLen<2)
  584.       return 1;
  585.     strcpy(fileName,inName);
  586.     return 0;
  587.   }
  588.   /* compose path */
  589.   name = StripPath(inName);
  590.   if (name==inName || forceDefault) {
  591.     /* use default path */
  592.     if (defaultPath==NULL || *defaultPath=='')
  593.       *fileName = '';
  594.     else
  595.       if (strlen(defaultPath)+1 >= fileNameMaxLen)
  596. return 1;
  597.       else {
  598. strcpy(fileName,defaultPath);
  599. tmp = fileName+strlen(fileName)-1;
  600. if (strchr(fileName,'/')!=NULL || strchr(inName,'/')!=NULL)
  601.   pathChar = '/';
  602. else
  603.   if (strchr(fileName,'\')!=NULL || strchr(inName,'\')!=NULL)
  604.     pathChar = '\';
  605.   else
  606.     pathChar = '/';
  607. if (*tmp!=pathChar) {
  608.   /* append pathChar to default path */
  609.   *(++tmp) = pathChar;
  610.   *(++tmp) = '';
  611. }
  612.       }
  613.     if (strlen(fileName)+strlen(name) >= fileNameMaxLen)
  614.       return 1;
  615.     else
  616.       strcat(fileName,name);
  617.   }
  618.   else {
  619.     /* use input path */
  620.     if (strlen(inName) >= fileNameMaxLen)
  621.       return 1;
  622.     else
  623.       strcpy(fileName,inName);
  624.   }
  625.   /* compose extension */
  626.   dot = strchr(StripPath(fileName),'.');
  627.   if (dot!=NULL && forceDefault) {
  628.     /* remove input extension */
  629.     *dot = '';
  630.     dot = NULL;
  631.   }
  632.   if (dot==NULL && defaultExt!=NULL && *defaultExt!='') {
  633.     /* use default extension */
  634.     if (strlen(fileName)+strlen(defaultExt)+1 >= fileNameMaxLen)
  635.       return 1;
  636.     else {
  637.       if (strchr(defaultExt,'.') == NULL)
  638. /* insert '.' before extension */
  639. strcat(fileName,".");
  640.       strcat(fileName,defaultExt);
  641.     }
  642.   }
  643.   
  644.   if (CLdebugLevel >= 1)
  645.     printf("ComposeFileName: fileName="%s"n",fileName);
  646.   return 0;
  647. }
  648. /* end of cmdline.c */