home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 9 / CD_ASCQ_09_1193.iso / news / 4441 / mpegcode / src / param.c < prev    next >
C/C++ Source or Header  |  1993-09-27  |  20KB  |  730 lines

  1. /*===========================================================================*
  2.  * param.c                                     *
  3.  *                                         *
  4.  *    Procedures to read in parameter file                     *
  5.  *                                         *
  6.  * EXPORTED PROCEDURES:                                 *
  7.  *    ReadParamFile                                 *
  8.  *    GetNthInputFileName                             *
  9.  *                                         *
  10.  *===========================================================================*/
  11.  
  12. /*
  13.  * Copyright (c) 1993 The Regents of the University of California.
  14.  * All rights reserved.
  15.  *
  16.  * Permission to use, copy, modify, and distribute this software and its
  17.  * documentation for any purpose, without fee, and without written agreement is
  18.  * hereby granted, provided that the above copyright notice and the following
  19.  * two paragraphs appear in all copies of this software.
  20.  *
  21.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  22.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  23.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  24.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25.  *
  26.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  27.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  28.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  29.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  30.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  31.  */
  32.  
  33. /*  
  34.  *  $Header: /n/picasso/users/keving/encode/src/RCS/param.c,v 1.2 1993/07/22 22:23:43 keving Exp keving $
  35.  *  $Log: param.c,v $
  36.  * Revision 1.2  1993/07/22  22:23:43  keving
  37.  * nothing
  38.  *
  39.  * Revision 1.1  1993/06/30  20:06:09  keving
  40.  * nothing
  41.  *
  42.  */
  43.  
  44.  
  45. /*==============*
  46.  * HEADER FILES *
  47.  *==============*/
  48.  
  49. #include "all.h"
  50. #include "mtypes.h"
  51. #include "mpeg.h"
  52. #include "search.h"
  53. #include "prototypes.h"
  54. #include "parallel.h"
  55. #include "param.h"
  56. #include "readframe.h"
  57. #include "fsize.h"
  58.  
  59.  
  60. /*===========*
  61.  * CONSTANTS *
  62.  *===========*/
  63.  
  64. #define INPUT_ENTRY_BLOCK_SIZE   128
  65.  
  66. #define FIRST_OPTION 0
  67. #define OPTION_GOP  0
  68. #define OPTION_PATTERN 1
  69. #define OPTION_PIXEL 2
  70. #define OPTION_PQSCALE 3
  71. #define OPTION_OUTPUT 4
  72. #define OPTION_RANGE 5
  73. #define OPTION_PSEARCH_ALG 6
  74. #define OPTION_IQSCALE 7
  75. #define OPTION_INPUT_DIR 8
  76. #define OPTION_INPUT_CONVERT 9
  77. #define OPTION_INPUT 10
  78. #define OPTION_BQSCALE 11
  79. #define OPTION_BASE_FORMAT 12
  80. #define OPTION_SPF 13
  81. #define OPTION_BSEARCH_ALG 14
  82. #define OPTION_REF_FRAME    15
  83. #define LAST_OPTION 15
  84. /* YUV_SIZE not required, so put after LAST_OPTION */
  85. #define OPTION_IO_CONVERT   16
  86. #define OPTION_SLAVE_CONVERT    17
  87. #define OPTION_YUV_SIZE    18
  88.  
  89.  
  90. /*=======================*
  91.  * STRUCTURE DEFINITIONS *
  92.  *=======================*/
  93.  
  94. typedef struct InputFileEntryStruct {
  95.     char    left[256];
  96.     char    right[256];
  97.     boolean glob;        /* if FALSE, left is complete name */
  98.     int        startID;
  99.     int        endID;
  100.     int        skip;
  101.     int        numPadding;        /* -1 if there is none */
  102.     int        numFiles;
  103. } InputFileEntry;
  104.  
  105.  
  106. /*==================*
  107.  * STATIC VARIABLES *
  108.  *==================*/
  109.  
  110. static InputFileEntry **inputFileEntries;
  111. static int numInputFileEntries = 0;
  112. static int  maxInputFileEntries;
  113.  
  114.  
  115. /*==================*
  116.  * GLOBAL VARIABLES *
  117.  *==================*/
  118.  
  119. extern char currentPath[MAXPATHLEN];
  120. extern char currentGOPPath[MAXPATHLEN];
  121. extern char currentFramePath[MAXPATHLEN];
  122. char    outputFileName[256];
  123. int numInputFiles = 0;
  124. char inputConversion[1024];
  125. char ioConversion[1024];
  126. char slaveConversion[1024];
  127. boolean optionSeen[OPTION_YUV_SIZE+1];
  128. int numMachines;
  129. char    machineName[MAX_MACHINES][256];
  130. char    userName[MAX_MACHINES][256];
  131. char    executable[MAX_MACHINES][1024];
  132. char    remoteParamFile[MAX_MACHINES][1024];
  133. boolean    remote[MAX_MACHINES];
  134.  
  135.  
  136. /*===============================*
  137.  * INTERNAL PROCEDURE prototypes *
  138.  *===============================*/
  139.  
  140. static void    ReadInputFileNames _ANSI_ARGS_((FILE *fpointer,
  141.                         char *endInput));
  142. static char    *SkipSpacesTabs _ANSI_ARGS_((char *start));
  143. static void    ReadMachineNames _ANSI_ARGS_((FILE *fpointer));
  144.  
  145.  
  146. /*=====================*
  147.  * EXPORTED PROCEDURES *
  148.  *=====================*/
  149.  
  150.  
  151. /*===========================================================================*
  152.  *
  153.  * ReadParamFile
  154.  *
  155.  *    read the parameter file
  156.  *    function is ENCODE_FRAMES, COMBINE_GOPS, or COMBINE_FRAMES, and
  157.  *        will slightly modify the procedure's behavior as to what it
  158.  *        is looking for in the parameter file
  159.  *
  160.  * RETURNS:    TRUE if the parameter file was read correctly; FALSE if not
  161.  *
  162.  * SIDE EFFECTS:    sets parameters accordingly, as well as machine info for
  163.  *            parallel execution and input file names
  164.  *
  165.  *===========================================================================*/
  166. boolean
  167. ReadParamFile(fileName, function)
  168.     char *fileName;
  169.     int function;
  170. {
  171.     FILE *fpointer;
  172.     char    input[256];
  173.     char    *charPtr;
  174.     boolean yuvUsed = FALSE;
  175.     static char *optionText[LAST_OPTION+1] = { "GOP", "PATTERN", "PIXEL", "PQSCALE",
  176.     "OUTPUT", "RANGE", "PSEARCH_ALG", "IQSCALE", "INPUT_DIR",
  177.     "INPUT_CONVERT", "INPUT", "BQSCALE", "BASE_FILE_FORMAT",
  178.     "SLICES_PER_FRAME", "BSEARCH_ALG", "REFERENCE_FRAME" };
  179.     register int index;
  180.  
  181.     if ( (fpointer = fopen(fileName, "r")) == NULL ) {
  182.     fprintf(stderr, "Error:  Cannot open parameter file:  %s\n", fileName);
  183.     return FALSE;
  184.     }
  185.  
  186.     /* should set defaults */
  187.     numInputFiles = 0;
  188.     numMachines = 0;
  189.     sprintf(currentPath, ".");
  190.     sprintf(currentGOPPath, ".");
  191.     sprintf(currentFramePath, ".");
  192.     SetRemoteShell("rsh");
  193.  
  194.     switch(function) {
  195.     case ENCODE_FRAMES:
  196.         for ( index = FIRST_OPTION; index <= LAST_OPTION; index++ ) {
  197.         optionSeen[index] = FALSE;
  198.         }
  199.         optionSeen[OPTION_YUV_SIZE] = FALSE;
  200.         optionSeen[OPTION_IO_CONVERT] = FALSE;
  201.         optionSeen[OPTION_SLAVE_CONVERT] = FALSE;
  202.         break;
  203.     case COMBINE_GOPS:
  204.         for ( index = FIRST_OPTION; index <= LAST_OPTION; index++ ) {
  205.         optionSeen[index] = TRUE;
  206.         }
  207.  
  208.         optionSeen[OPTION_YUV_SIZE] = FALSE;
  209.         optionSeen[OPTION_OUTPUT] = FALSE;
  210.         break;
  211.     case COMBINE_FRAMES:
  212.         for ( index = FIRST_OPTION; index <= LAST_OPTION; index++ ) {
  213.         optionSeen[index] = TRUE;
  214.         }
  215.  
  216.         optionSeen[OPTION_GOP] = FALSE;
  217.         optionSeen[OPTION_OUTPUT] = FALSE;
  218.         optionSeen[OPTION_YUV_SIZE] = FALSE;
  219.         break;
  220.     }
  221.  
  222.     while ( fgets(input, 256, fpointer) != NULL ) {
  223.     if ( input[0] == '#' ) {        /* skip comments */
  224.         continue;
  225.     }
  226.  
  227.     input[strlen(input)-1] = '\0';    /* get rid of newline */
  228.  
  229.     switch(input[0]) {
  230.         case 'G':
  231.         if ( strncmp(input, "GOP_SIZE", 8) == 0 ) {
  232.             charPtr = SkipSpacesTabs(&input[8]);
  233.             SetGOPSize(atoi(charPtr));
  234.             optionSeen[OPTION_GOP] = TRUE;
  235.         } else if ( strncmp(input, "GOP_INPUT_DIR", 13) == 0 ) {
  236.             charPtr = SkipSpacesTabs(&input[13]);
  237.             strcpy(currentGOPPath, charPtr);
  238.         } else if ( strncmp(input, "GOP_INPUT", 9) == 0 ) {
  239.             if ( function == COMBINE_GOPS ) {
  240.             ReadInputFileNames(fpointer, "GOP_END_INPUT");
  241.             }
  242.         }
  243.         break;
  244.  
  245.         case 'F':
  246.         if ( strncmp(input, "FRAME_INPUT_DIR", 15) == 0 ) {
  247.             charPtr = SkipSpacesTabs(&input[15]);
  248.             strcpy(currentFramePath, charPtr);
  249.         } else if ( strncmp(input, "FRAME_INPUT", 11) == 0 ) {
  250.             if ( function == COMBINE_FRAMES ) {
  251.             ReadInputFileNames(fpointer, "FRAME_END_INPUT");
  252.             }
  253.         }
  254.         break;
  255.  
  256.         case 'P':
  257.         if ( strncmp(input, "PATTERN", 7) == 0 ) {
  258.             charPtr = SkipSpacesTabs(&input[7]);
  259.             SetFramePattern(charPtr);
  260.             optionSeen[OPTION_PATTERN] = TRUE;
  261.         } else if ( strncmp(input, "PIXEL", 5) == 0 ) {
  262.             charPtr = SkipSpacesTabs(&input[5]);
  263.             SetPixelSearch(charPtr);
  264.             optionSeen[OPTION_PIXEL] = TRUE;
  265.         } else if ( strncmp(input, "PQSCALE", 7) == 0 ) {
  266.             charPtr = SkipSpacesTabs(&input[7]);
  267.             SetPQScale(atoi(charPtr));
  268.             optionSeen[OPTION_PQSCALE] = TRUE;
  269.         } else if ( strncmp(input, "PSEARCH_ALG", 11) == 0 ) {
  270.             charPtr = SkipSpacesTabs(&input[11]);
  271.             SetPSearchAlg(charPtr);
  272.             optionSeen[OPTION_PSEARCH_ALG] = TRUE;
  273.         } else if ( strncmp(input, "PARALLEL_TEST_FRAMES", 20) == 0 ) {
  274.             charPtr = SkipSpacesTabs(&input[20]);
  275.             parallelTestFrames = atoi(charPtr);
  276.         } else if ( strncmp(input, "PARALLEL_TIME_CHUNKS", 20) == 0 ) {
  277.             charPtr = SkipSpacesTabs(&input[20]);
  278.             parallelTimeChunks = atoi(charPtr);
  279.         } else if ( strncmp(input, "PARALLEL", 8) == 0 ) {
  280.             ReadMachineNames(fpointer);
  281.         }
  282.         break;
  283.  
  284.         case 'O':
  285.         if ( strncmp(input, "OUTPUT", 6) == 0 ) {
  286.             charPtr = SkipSpacesTabs(&input[6]);
  287.             if ( whichGOP == -1 ) {
  288.             strcpy(outputFileName, charPtr);
  289.             } else {
  290.             sprintf(outputFileName, "%s.gop.%d",
  291.                 charPtr, whichGOP);
  292.             }
  293.  
  294.             optionSeen[OPTION_OUTPUT] = TRUE;
  295.         }
  296.         break;
  297.  
  298.         case 'R':
  299.         if ( strncmp(input, "RANGE", 5) == 0 ) {
  300.             charPtr = SkipSpacesTabs(&input[5]);
  301.             SetSearchRange(atoi(charPtr));
  302.             optionSeen[OPTION_RANGE] = TRUE;
  303.         } else if ( strncmp(input, "REFERENCE_FRAME", 15) == 0 ) {
  304.             charPtr = SkipSpacesTabs(&input[15]);
  305.             SetReferenceFrameType(charPtr);
  306.             optionSeen[OPTION_REF_FRAME] = TRUE;
  307.         } else if ( strncmp(input, "RSH", 3) == 0 ) {
  308.             charPtr = SkipSpacesTabs(&input[3]);
  309.             SetRemoteShell(charPtr);
  310.         }
  311.  
  312.         break;
  313.  
  314.         case 'S':
  315.         if ( strncmp(input, "SLICES_PER_FRAME", 16) == 0 ) {
  316.             charPtr = SkipSpacesTabs(&input[16]);
  317.             SetSlicesPerFrame(atoi(charPtr));
  318.             optionSeen[OPTION_SPF] = TRUE;
  319.         } else if ( strncmp(input, "SLAVE_CONVERT", 13) == 0 ) {
  320.             charPtr = SkipSpacesTabs(&input[13]);
  321.             strcpy(slaveConversion, charPtr);
  322.             optionSeen[OPTION_SLAVE_CONVERT] = TRUE;
  323.         }
  324.  
  325.         break;
  326.  
  327.         case 'I':
  328.         if ( strncmp(input, "IQSCALE", 7) == 0 ) {
  329.             charPtr = SkipSpacesTabs(&input[7]);
  330.             SetIQScale(atoi(charPtr));
  331.             optionSeen[OPTION_IQSCALE] = TRUE;
  332.         } else if ( strncmp(input, "INPUT_DIR", 9) == 0 ) {
  333.             charPtr = SkipSpacesTabs(&input[9]);
  334.             strcpy(currentPath, charPtr);
  335.             optionSeen[OPTION_INPUT_DIR] = TRUE;
  336.         } else if ( strncmp(input, "INPUT_CONVERT", 13) == 0 ) {
  337.             charPtr = SkipSpacesTabs(&input[13]);
  338.             strcpy(inputConversion, charPtr);
  339.             optionSeen[OPTION_INPUT_CONVERT] = TRUE;
  340.         } else if ( strcmp(input, "INPUT") == 0 ) {   /* yes, strcmp */
  341.             if ( function == ENCODE_FRAMES ) {
  342.             ReadInputFileNames(fpointer, "END_INPUT");
  343.             optionSeen[OPTION_INPUT] = TRUE;
  344.             }
  345.         } else if ( strncmp(input, "IO_SERVER_CONVERT", 17) == 0 ) {
  346.             charPtr = SkipSpacesTabs(&input[17]);
  347.             strcpy(ioConversion, charPtr);
  348.             optionSeen[OPTION_IO_CONVERT] = TRUE;
  349.         }
  350.  
  351.         break;
  352.  
  353.         case 'B':
  354.         if ( strncmp(input, "BQSCALE", 7) == 0 ) {
  355.             charPtr = SkipSpacesTabs(&input[7]);
  356.             SetBQScale(atoi(charPtr));
  357.             optionSeen[OPTION_BQSCALE] = TRUE;
  358.         } else if ( strncmp(input, "BASE_FILE_FORMAT", 16) == 0 ) {
  359.             charPtr = SkipSpacesTabs(&input[16]);
  360.             SetFileFormat(charPtr);
  361.             if ( strcmp(charPtr, "YUV") == 0 ) {
  362.                 yuvUsed = TRUE;
  363.             }
  364.             optionSeen[OPTION_BASE_FORMAT] = TRUE;
  365.         } else if ( strncmp(input, "BSEARCH_ALG", 11) == 0 ) {
  366.             charPtr = SkipSpacesTabs(&input[11]);
  367.             SetBSearchAlg(charPtr);
  368.             optionSeen[OPTION_BSEARCH_ALG] = TRUE;
  369.         }
  370.         break;
  371.  
  372.         case 'Y':
  373.         if ( strncmp(input, "YUV_SIZE", 8) == 0 ) {
  374.             charPtr = SkipSpacesTabs(&input[8]);
  375.             sscanf(charPtr, "%dx%d", &yuvWidth, &yuvHeight);
  376.             Fsize_Validate(&yuvWidth, &yuvHeight);
  377.             optionSeen[OPTION_YUV_SIZE] = TRUE;
  378.         }
  379.         break;
  380.         default:
  381.         break;
  382.     }
  383.     }
  384.  
  385.     fclose(fpointer);
  386.  
  387.     for ( index = FIRST_OPTION; index <= LAST_OPTION; index++ ) {
  388.     if ( ! optionSeen[index] ) {
  389.         fprintf(stdout, "ERROR:  Missing option '%s'\n", optionText[index]);
  390.         exit(1);
  391.     }
  392.     }
  393.  
  394.     /* error checking */
  395.     if ( yuvUsed && (! optionSeen[OPTION_YUV_SIZE]) ) {
  396.         fprintf(stderr, "ERROR:  YUV format used but YUV_SIZE not given\n");
  397.     exit(1);
  398.     }
  399.  
  400.     if ( optionSeen[OPTION_IO_CONVERT] != optionSeen[OPTION_SLAVE_CONVERT] ) {
  401.         fprintf(stderr, "ERROR:  must have either both IO_SERVER_CONVERT and SLAVE_CONVERT\n");
  402.         fprintf(stderr, "        or neither\n");
  403.     exit(1);
  404.     }
  405.  
  406.     SetIOConvert(optionSeen[OPTION_IO_CONVERT]);
  407.  
  408.     SetFCode();
  409.  
  410.     if ( psearchAlg == PSEARCH_TWOLEVEL )
  411.     SetPixelSearch("HALF");
  412.  
  413.     return TRUE;
  414. }
  415.  
  416.  
  417. /*===========================================================================*
  418.  *
  419.  * GetNthInputFileName
  420.  *
  421.  *    finds the nth input file name
  422.  *
  423.  * RETURNS:    name is placed in already allocated fileName string
  424.  *
  425.  * SIDE EFFECTS:    none
  426.  *
  427.  *===========================================================================*/
  428. void
  429. GetNthInputFileName(fileName, n)
  430.     char *fileName;
  431.     int n;
  432. {
  433.     static int    lastN = 0, lastMapN = 0, lastSoFar = 0;
  434.     int        mapN;
  435.     register int index;
  436.     int        soFar;
  437.     int        loop;
  438.     int        numPadding;
  439.     char    numBuffer[33];
  440.  
  441.     /* assumes n is within bounds 0...numInputFiles-1 */
  442.  
  443.     if ( n >= lastN ) {
  444.     soFar = lastSoFar;
  445.     index = lastMapN;
  446.     } else {
  447.     soFar = 0;
  448.     index = 0;
  449.     }
  450.  
  451.     while ( soFar + inputFileEntries[index]->numFiles <= n ) {
  452.     soFar +=  inputFileEntries[index]->numFiles;
  453.     index++;
  454.     }
  455.  
  456.     mapN = index;
  457.  
  458.     index = inputFileEntries[mapN]->startID +
  459.         inputFileEntries[mapN]->skip*(n-soFar);
  460.  
  461.     numPadding = inputFileEntries[mapN]->numPadding;
  462.  
  463.     if ( numPadding != -1 ) {
  464.     sprintf(numBuffer, "%32d", index);
  465.     for ( loop = 32-numPadding; loop < 32; loop++ ) {
  466.         if ( numBuffer[loop] != ' ' ) {
  467.         break;
  468.         } else {
  469.         numBuffer[loop] = '0';
  470.         }
  471.     }
  472.  
  473.     sprintf(fileName, "%s%s%s",
  474.         inputFileEntries[mapN]->left,
  475.         &numBuffer[32-numPadding],
  476.         inputFileEntries[mapN]->right);
  477.     } else {
  478.     sprintf(fileName, "%s%d%s",
  479.         inputFileEntries[mapN]->left,
  480.         index,
  481.         inputFileEntries[mapN]->right);
  482.     }
  483.  
  484.     lastN = n;
  485.     lastMapN = mapN;
  486.     lastSoFar = soFar;
  487. }
  488.  
  489.  
  490. /*=====================*
  491.  * INTERNAL PROCEDURES *
  492.  *=====================*/
  493.  
  494. /*===========================================================================*
  495.  *
  496.  * ReadMachineNames
  497.  *
  498.  *    read a list of machine names for parallel execution
  499.  *
  500.  * RETURNS:    nothing
  501.  *
  502.  * SIDE EFFECTS:    machine info updated
  503.  *
  504.  *===========================================================================*/
  505. static void
  506. ReadMachineNames(fpointer)
  507.     FILE *fpointer;
  508. {
  509.     char    input[256];
  510.     char    *charPtr;
  511.  
  512.     while ( (fgets(input, 256, fpointer) != NULL) &&
  513.         (strncmp(input, "END_PARALLEL", 12) != 0) ) {
  514.     if ( input[0] == '#' ) {
  515.         continue;
  516.     }
  517.  
  518.     if ( strncmp(input, "REMOTE", 6) == 0 ) {
  519.         charPtr = SkipSpacesTabs(&input[6]);
  520.         remote[numMachines] = TRUE;
  521.  
  522.         sscanf(charPtr, "%s %s %s %s", machineName[numMachines],
  523.            userName[numMachines], executable[numMachines],
  524.            remoteParamFile[numMachines]);
  525.     } else {
  526.         remote[numMachines] = FALSE;
  527.  
  528.         sscanf(input, "%s %s %s", machineName[numMachines],
  529.            userName[numMachines], executable[numMachines]);
  530.     }
  531.  
  532.     numMachines++;
  533.     }
  534. }
  535.  
  536.  
  537. /*===========================================================================*
  538.  *
  539.  * ReadInputFileNames
  540.  *
  541.  *    read a list of input file names
  542.  *
  543.  * RETURNS:    nothing
  544.  *
  545.  * SIDE EFFECTS:    info stored for retrieval using GetNthInputFileName
  546.  *
  547.  *===========================================================================*/
  548. static void
  549. ReadInputFileNames(fpointer, endInput)
  550.     FILE *fpointer;
  551.     char *endInput;
  552. {
  553.     char    input[256];
  554.     char left[256], right[256];
  555.     char *globPtr, *charPtr;
  556.     char leftNumText[256], rightNumText[256];
  557.     char    skipNumText[256];
  558.     int    leftNum, rightNum;
  559.     int        skipNum;
  560.     boolean padding;
  561.     int        numPadding = 0;
  562.     int        length;
  563.  
  564.     inputFileEntries = (InputFileEntry **) malloc(INPUT_ENTRY_BLOCK_SIZE*
  565.                           sizeof(InputFileEntry *));
  566.     maxInputFileEntries = INPUT_ENTRY_BLOCK_SIZE;
  567.  
  568.     length = strlen(endInput);
  569.  
  570.     /* read input files up until endInput */
  571.     while ( (fgets(input, 256, fpointer) != NULL) &&
  572.         (strncmp(input, endInput, length) != 0) ) {
  573.     if ( input[0] == '#' ) {
  574.         continue;
  575.     }
  576.  
  577.     input[strlen(input)-1] = '\0';    /* get rid of newline */
  578.  
  579.     if ( numInputFileEntries == maxInputFileEntries ) {    /* more space! */
  580.         maxInputFileEntries += INPUT_ENTRY_BLOCK_SIZE;
  581.         inputFileEntries = realloc(inputFileEntries,
  582.                        maxInputFileEntries*
  583.                        sizeof(InputFileEntry *));
  584.     }
  585.  
  586.     inputFileEntries[numInputFileEntries] = (InputFileEntry *)
  587.                         malloc(sizeof(InputFileEntry));
  588.  
  589.     if ( input[strlen(input)-1] == ']' ) {
  590.         inputFileEntries[numInputFileEntries]->glob = TRUE;
  591.  
  592.         /* star expand */
  593.  
  594.         globPtr = input;
  595.         charPtr = left;
  596.         /* copy left of '*' */
  597.         while ( (*globPtr != '\0') && (*globPtr != '*') ) {
  598.         *charPtr = *globPtr;
  599.         charPtr++;
  600.         globPtr++;
  601.         }
  602.         *charPtr = '\0';
  603.  
  604.         globPtr++;
  605.         charPtr = right;
  606.         /* copy right of '*' */
  607.         while ( (*globPtr != '\0') && (*globPtr != ' ') &&
  608.             (*globPtr != '\t') ) {
  609.         *charPtr = *globPtr;
  610.         charPtr++;
  611.         globPtr++;
  612.         }
  613.         *charPtr = '\0';
  614.  
  615.         globPtr = SkipSpacesTabs(globPtr);
  616.  
  617.         if ( *globPtr != '[' ) {
  618.         fprintf(stderr, "ERROR:  Invalid input file expansion expression (no '[')\n");
  619.         exit(1);
  620.         }
  621.  
  622.         globPtr++;
  623.         charPtr = leftNumText;
  624.         /* copy left number */
  625.         while ( isdigit(*globPtr) ) {
  626.         *charPtr = *globPtr;
  627.         charPtr++;
  628.         globPtr++;
  629.         }
  630.         *charPtr = '\0';
  631.  
  632.         if ( *globPtr != '-' ) {
  633.         fprintf(stderr, "ERROR:  Invalid input file expansion expression (no '-')\n");
  634.         exit(1);
  635.         }
  636.  
  637.         globPtr++;
  638.         charPtr = rightNumText;
  639.         /* copy right number */
  640.         while ( isdigit(*globPtr) ) {
  641.         *charPtr = *globPtr;
  642.         charPtr++;
  643.         globPtr++;
  644.         }
  645.         *charPtr = '\0';
  646.  
  647.  
  648.         if ( *globPtr != ']' ) {
  649.         if ( *globPtr != '+' ) {
  650.             fprintf(stderr, "ERROR:  Invalid input file expansion expression (no ']')\n");
  651.             exit(1);
  652.         }
  653.  
  654.         globPtr++;
  655.         charPtr = skipNumText;
  656.         /* copy skip number */
  657.         while ( isdigit(*globPtr) ) {
  658.             *charPtr = *globPtr;
  659.             charPtr++;
  660.             globPtr++;
  661.         }
  662.         *charPtr = '\0';
  663.  
  664.         if ( *globPtr != ']' ) {
  665.             fprintf(stderr, "ERROR:  Invalid input file expansion expression (no ']')\n");
  666.             exit(1);
  667.         }
  668.  
  669.         skipNum = atoi(skipNumText);
  670.         } else {
  671.         skipNum = 1;
  672.         }
  673.  
  674.         leftNum = atoi(leftNumText);
  675.         rightNum = atoi(rightNumText);
  676.  
  677.         if ( (leftNumText[0] == '0') && (leftNumText[1] != '\0') ) {
  678.         padding = TRUE;
  679.         numPadding = strlen(leftNumText);
  680.         } else {
  681.         padding = FALSE;
  682.         }
  683.  
  684.         inputFileEntries[numInputFileEntries]->startID = leftNum;
  685.         inputFileEntries[numInputFileEntries]->endID = rightNum;
  686.         inputFileEntries[numInputFileEntries]->skip = skipNum;
  687.         inputFileEntries[numInputFileEntries]->numFiles = (rightNum-leftNum+1)/skipNum;
  688.         strcpy(inputFileEntries[numInputFileEntries]->left, left);
  689.         strcpy(inputFileEntries[numInputFileEntries]->right, right);
  690.         if ( padding ) {
  691.         inputFileEntries[numInputFileEntries]->numPadding = numPadding;
  692.         } else {
  693.         inputFileEntries[numInputFileEntries]->numPadding = -1;
  694.         }
  695.     } else {
  696.         strcpy(inputFileEntries[numInputFileEntries]->left, input);
  697.         inputFileEntries[numInputFileEntries]->glob = FALSE;
  698.         inputFileEntries[numInputFileEntries]->numFiles = 1;
  699.     }
  700.  
  701.     numInputFiles += inputFileEntries[numInputFileEntries]->numFiles;
  702.     numInputFileEntries++;
  703.     }
  704. }
  705.  
  706.  
  707. /*===========================================================================*
  708.  *
  709.  * SkipSpacesTabs
  710.  *
  711.  *    skip all spaces and tabs
  712.  *
  713.  * RETURNS:    point to next character not a space or tab
  714.  *
  715.  * SIDE EFFECTS:    none
  716.  *
  717.  *===========================================================================*/
  718. static char *
  719. SkipSpacesTabs(start)
  720.     char *start;
  721. {
  722.     while ( (*start == ' ') || (*start == '\t') ) {
  723.     start++;
  724.     }
  725.  
  726.     return start;
  727. }
  728.  
  729.  
  730.