home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / OS2 / CPOSTSRC.ZIP / CPOSTUTL.C < prev    next >
C/C++ Source or Header  |  1994-02-13  |  39KB  |  1,306 lines

  1. /*------------------------------------------------------------------
  2.  * cpostutl.c : utilities for cPost
  3.  *------------------------------------------------------------------
  4.  * 11-23-91 originally by Patrick J. Mueller
  5.  * 12-03-92 converted from cBook to cPost
  6.  *------------------------------------------------------------------*/
  7.  
  8. #if defined(OPSYS_OS2) || defined(OPSYS_OS2V2)
  9.    #define INCL_BASE
  10.    #include <os2.h>
  11. #endif
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <ctype.h>
  17. #include <stdarg.h>
  18. #include <time.h>
  19.  
  20. #include "ctok.h"
  21. #include "cpost.h"
  22. #include "tokfile.h"
  23.  
  24. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  25. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  26.  
  27. /*------------------------------------------------------------------
  28.  * compare two file names
  29.  *------------------------------------------------------------------*/
  30. int FileNameCompare(
  31.    File *file1,
  32.    File *file2
  33.    )
  34.    {
  35.    int   scmp;
  36.    int   i;
  37.    char *name1;
  38.    char *name2;
  39.  
  40.    /*---------------------------------------------------------------
  41.     * get the base file names
  42.     *---------------------------------------------------------------*/
  43.    name1 = malloc(1+strlen(file1->name));
  44.    name2 = malloc(1+strlen(file2->name));
  45.  
  46.    if (!name1 || !name2)
  47.       cPostError(1,"out of memory!!!");
  48.  
  49.    strcpy(name1,file1->name);
  50.    strcpy(name2,file2->name);
  51.  
  52.    if (strchr(name1,'.')) *strchr(name1,'.') = 0;
  53.    if (strchr(name2,'.')) *strchr(name2,'.') = 0;
  54.  
  55.    /*---------------------------------------------------------------
  56.     * sort each category
  57.     *---------------------------------------------------------------*/
  58.    for (i=0; i<(int)strlen(info.oSort); i++)
  59.       {
  60.       /*------------------------------------------------------------
  61.        * sort by type
  62.        *------------------------------------------------------------*/
  63.       if ('T' == info.oSort[i])
  64.          {
  65.          if (file1->type < file2->type)
  66.             {
  67.             free(name1);
  68.             free(name2);
  69.             return -1;
  70.             }
  71.          if (file1->type > file2->type)
  72.             {
  73.             free(name1);
  74.             free(name2);
  75.             return  1;
  76.             }
  77.  
  78.          scmp = Stricmp(file1->ext,file2->ext);
  79.          if (scmp)
  80.             {
  81.             free(name1);
  82.             free(name2);
  83.             return  scmp;
  84.             }
  85.          }
  86.  
  87.       /*------------------------------------------------------------
  88.        * sort by name
  89.        *------------------------------------------------------------*/
  90.       else if ('N' == info.oSort[i])
  91.          {
  92.          /*---------------------------------------------------------
  93.           * sort by name
  94.           *---------------------------------------------------------*/
  95.          scmp = Stricmp(file1->name,file2->name);
  96.          if (scmp)
  97.             {
  98.             free(name1);
  99.             free(name2);
  100.             return  scmp;
  101.             }
  102.          }
  103.       }
  104.  
  105.    free(name1);
  106.    free(name2);
  107.  
  108.    return 0;
  109.    }
  110.  
  111. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  112. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  113.  
  114. /*------------------------------------------------------------------
  115.  * compare two strings indirectly
  116.  *------------------------------------------------------------------*/
  117. int IdentCompare(
  118.    char **str1,
  119.    char **str2
  120.    )
  121.    {
  122.    return strcmp(*str1,*str2);
  123.    }
  124.  
  125. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  126. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  127.  
  128. /*------------------------------------------------------------------
  129.  * compare two function names
  130.  *------------------------------------------------------------------*/
  131. int FunctionNameCompare(
  132.    Function *func1,
  133.    Function *func2
  134.    )
  135.    {
  136.    int cmp;
  137.  
  138.    cmp = Stricmp(func1->name,func2->name);
  139.    if (cmp) return cmp;
  140.  
  141.    cmp = strcmp(func1->name,func2->name);
  142.    if (cmp) return cmp;
  143.  
  144.    return 0;
  145.    }
  146.  
  147. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  148. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  149.  
  150. /*------------------------------------------------------------------
  151.  * compare two function names (via indirection)
  152.  *------------------------------------------------------------------*/
  153. int FunctionNamePtrCompare(
  154.    Function **func1,
  155.    Function **func2
  156.    )
  157.    {
  158.    return FunctionNameCompare(*func1,*func2);
  159.    }
  160.  
  161. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  162. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  163.  
  164. /*------------------------------------------------------------------
  165.  * hash an identifier
  166.  *------------------------------------------------------------------*/
  167. int IdentHash(
  168.    char     **str,
  169.    int        hashSize
  170.    )
  171.    {
  172.    int   hash;
  173.    char *c;
  174.  
  175.    for (hash=0, c=*str; *c; c++)
  176.       hash +=*c;
  177.  
  178.    return hash % hashSize;
  179.    }
  180.  
  181. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  182. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  183.  
  184. /*------------------------------------------------------------------
  185.  * add a file to the list of files
  186.  *------------------------------------------------------------------*/
  187. void FileAdd(
  188.    Info      *info,
  189.    List      *fileList,
  190.    char      *name,
  191.    char      *pathName,
  192.    char      *fDate,
  193.    char      *fTime
  194.    )
  195.    {
  196.    File  file;
  197.    char *type;
  198.    char *test;
  199.    char *ext;
  200.  
  201.    /*---------------------------------------------------------------
  202.     * copy the name in
  203.     *---------------------------------------------------------------*/
  204.    file.name = malloc(1+strlen(name));
  205.    if (NULL == file.name)
  206.       cPostError(1,"out of memory!!!");
  207.  
  208.    strcpy(file.name,name);
  209.  
  210.    file.pathName = malloc(1+strlen(name)+strlen(pathName));
  211.    if (NULL == file.pathName)
  212.       cPostError(1,"out of memory!!!");
  213.  
  214.    strcpy(file.pathName,pathName);
  215.    strcat(file.pathName,name);
  216.  
  217.    strcpy(file.date,fDate);
  218.    strcpy(file.time,fTime);
  219.  
  220.    /*---------------------------------------------------------------
  221.     * get the extension
  222.     *---------------------------------------------------------------*/
  223.    ext = strchr(file.name,'.');
  224.    if (!ext)
  225.       file.ext = "";
  226.    else
  227.       {
  228.       ext++;
  229.       file.ext = malloc(1+strlen(ext));
  230.       if (!file.ext)
  231.          cPostError(1,"out of memory!!!");
  232.  
  233.       strcpy(file.ext,ext);
  234.  
  235.       /*------------------------------------------------------------
  236.        * remove . and anything following it
  237.        *------------------------------------------------------------*/
  238.       if (strchr(file.ext,'.'))
  239.          *strchr(file.ext,'.') = '\0';
  240.       }
  241.  
  242.    /*---------------------------------------------------------------
  243.     * default the type to 'other'
  244.     *---------------------------------------------------------------*/
  245.    file.type = 2;
  246.  
  247.    /*---------------------------------------------------------------
  248.     * see if it's an 'H' file
  249.     *---------------------------------------------------------------*/
  250.    type = malloc(1+strlen(info->oHtype));
  251.    if (!type)
  252.       cPostError(1,"out of memory!!!");
  253.  
  254.    strcpy(type,info->oHtype);
  255.    test = strtok(type,", ");
  256.    while (test)
  257.       {
  258.       if (!Stricmp(file.ext,test))
  259.          file.type = 0;
  260.  
  261.       test = strtok(NULL,", ");
  262.       }
  263.  
  264.    free(type);
  265.  
  266.    /*---------------------------------------------------------------
  267.     * see if it's a 'C' file
  268.     *---------------------------------------------------------------*/
  269.    type = malloc(1+strlen(info->oCtype));
  270.    if (!type)
  271.       cPostError(1,"out of memory!!!");
  272.  
  273.    strcpy(type,info->oCtype);
  274.    test = strtok(type,", ");
  275.    while (test)
  276.       {
  277.       if (!Stricmp(file.ext,test))
  278.          file.type = 1;
  279.  
  280.       test = strtok(NULL,", ");
  281.       }
  282.  
  283.    free(type);
  284.  
  285.    /*---------------------------------------------------------------
  286.     * set rest of stuff
  287.     *---------------------------------------------------------------*/
  288.    file.line      = NULL;
  289.    file.lines     = 0L;
  290.    file.cline     = 0L;
  291.    file.tempName  = NULL;
  292.    file.breakList = NULL;
  293.  
  294.    file.funcDefList = ListCreate(sizeof(Function *),
  295.                                  (ListCompareFunc *)FunctionNamePtrCompare,
  296.                                  cPostNoMem);
  297.    if (!file.funcDefList)
  298.       cPostError(1,"error creating function definition list");
  299.  
  300.    file.funcProList = ListCreate(sizeof(Function *),
  301.                                  (ListCompareFunc *)FunctionNamePtrCompare,
  302.                                  cPostNoMem);
  303.    if (!file.funcProList)
  304.       cPostError(1,"error creating function prototype list");
  305.  
  306.    /*---------------------------------------------------------------
  307.     * now add it to the list
  308.     *---------------------------------------------------------------*/
  309.    if (ListFind(fileList,&file))
  310.       return;
  311.  
  312.    if (ListAdd(fileList,&file))
  313.       return;
  314.  
  315.    /*---------------------------------------------------------------
  316.     * otherwise, error adding it
  317.     *---------------------------------------------------------------*/
  318.    cPostError(1,"error adding file %s to file list",name);
  319.    }
  320.  
  321. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  322. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  323.  
  324. #if defined(OPSYS_OS2) || defined(OPSYS_OS2V2)
  325. /*------------------------------------------------------------------
  326.  * OS/2 version - add all the files in a file spec to the list
  327.  *------------------------------------------------------------------*/
  328. void FileSpecAddOS2(
  329.    Info      *info,
  330.    List      *fileList,
  331.    char      *fileSpec
  332.    )
  333.    {
  334.    USHORT       rc;
  335.    HDIR         hDir;
  336. #if defined(OPSYS_OS2V2)
  337.    FILEFINDBUF3 ffbuf;
  338.    ULONG        attr;
  339.    ULONG        cnt;
  340. #else
  341.    FILEFINDBUF  ffbuf;
  342.    USHORT       attr;
  343.    USHORT       cnt;
  344. #endif
  345.    int               files;
  346.    static UCHAR      pathName[261];
  347.    char              szTime[9];
  348.    char              szDate[9];
  349.  
  350.    /*---------------------------------------------------------------
  351.     * get path name of spec
  352.     *---------------------------------------------------------------*/
  353. #if defined(OPSYS_OS2V2)
  354.    rc = DosQueryPathInfo(fileSpec,5,pathName,sizeof(pathName));
  355. #else
  356.    rc = DosQPathInfo(fileSpec,5,pathName,sizeof(pathName),0);
  357. #endif
  358.    if (rc)
  359.       cPostError(1,"error getting path for %s",fileSpec);
  360.  
  361.    /*---------------------------------------------------------------
  362.     * convert slashes to back slashes
  363.     *---------------------------------------------------------------*/
  364.    while (strchr(pathName,'/'))
  365.       *strchr(pathName,'/') = '\\';
  366.  
  367.    *(strrchr(pathName,'\\') + 1) = '\0';
  368.  
  369.    /*---------------------------------------------------------------
  370.     * get the first file
  371.     *---------------------------------------------------------------*/
  372.    hDir = 0xFFFF;
  373.    attr = 0;
  374.    cnt  = 1;
  375.  
  376. #if defined(OPSYS_OS2V2)
  377.    rc = DosFindFirst(fileSpec,&hDir,attr,&ffbuf,sizeof(ffbuf), &cnt,1);
  378. #else
  379.    rc = DosFindFirst(fileSpec,&hDir,attr,&ffbuf,sizeof(ffbuf), &cnt,0);
  380. #endif
  381.  
  382.    /*---------------------------------------------------------------
  383.     * continue while we keep getting files
  384.     *---------------------------------------------------------------*/
  385.    for (files=0; 0 == rc; files++)
  386.       {
  387.       sprintf(szDate,"%2.2d/%2.2d/%2.2d",
  388.               (int) ffbuf.fdateLastWrite.month,
  389.               (int) ffbuf.fdateLastWrite.day,
  390.               (int) ffbuf.fdateLastWrite.year+80);
  391.  
  392.       sprintf(szTime,"%2.2d:%2.2d:%2.2d",
  393.               (int) ffbuf.ftimeLastWrite.hours,
  394.               (int) ffbuf.ftimeLastWrite.minutes,
  395.               (int) ffbuf.ftimeLastWrite.twosecs * 2);
  396.  
  397.       if (!IsTempFileName(ffbuf.achName))
  398.          FileAdd(info,fileList,ffbuf.achName,pathName,szDate,szTime);
  399.  
  400.       /*------------------------------------------------------------
  401.        * get next file
  402.        *------------------------------------------------------------*/
  403.       rc = DosFindNext(hDir,&ffbuf,sizeof(ffbuf),&cnt);
  404.       }
  405.  
  406.    rc = DosFindClose(hDir);
  407.    }
  408.  
  409. #elif defined(OPSYS_CMS)
  410. /*------------------------------------------------------------------
  411.  * cms version - add all the files in a file spec to the list
  412.  *------------------------------------------------------------------*/
  413. void FileSpecAddCMS(
  414.    Info      *info,
  415.    List      *fileList,
  416.    char      *fileSpec
  417.    )
  418.    {
  419.    int    rc;
  420.    FILE  *stack;
  421.    int    num;
  422.    char  *copy;
  423.    char  *buffer;
  424.    char   fileName[21];
  425.    char  *fileDate;
  426.    char  *fileTime;
  427.    int    i;
  428.  
  429. #define BUFFER_LEN 1000
  430.  
  431.    /*---------------------------------------------------------------
  432.     * make copy of spec, and translate '.' to ' '
  433.     *---------------------------------------------------------------*/
  434.    copy = malloc(1+strlen(fileSpec));
  435.    if (!copy)
  436.       cPostError(1,"out of memory!!!");
  437.  
  438.    strcpy(copy,fileSpec);
  439.    fileSpec = copy;
  440.  
  441.    /*---------------------------------------------------------------
  442.     * translate '.' to ' '
  443.     *---------------------------------------------------------------*/
  444.    while (strchr(fileSpec,'.'))
  445.       *strchr(fileSpec,'.') = ' ';
  446.  
  447.    /*---------------------------------------------------------------
  448.     * build command string
  449.     *---------------------------------------------------------------*/
  450.    buffer = malloc(BUFFER_LEN);
  451.    if (!buffer)
  452.       cPostError(1,"out of memory!!!");
  453.  
  454.    strcpy(buffer,"LISTFILE ");
  455.    strcat(buffer,fileSpec);
  456.    strcat(buffer," ( NOH STACK DATE");
  457.  
  458.    /*---------------------------------------------------------------
  459.     * set high water mark
  460.     *---------------------------------------------------------------*/
  461.    system("MAKEBUF");
  462.  
  463.    /*---------------------------------------------------------------
  464.     * run command
  465.     *---------------------------------------------------------------*/
  466.    rc = system(buffer);
  467.    if (rc)
  468.       {
  469.       cPostError(rc,"return code %d from '%s'",rc,buffer);
  470.       exit(rc);
  471.       }
  472.  
  473.    /*---------------------------------------------------------------
  474.     * see how many stacked
  475.     *---------------------------------------------------------------*/
  476.    num = system("SENTRIES");
  477.  
  478.    /*---------------------------------------------------------------
  479.     * open the stack
  480.     *---------------------------------------------------------------*/
  481.    stack = fopen("*","r");
  482.    if (!stack)
  483.       {
  484.       cPostError(1,"error opening stack for reading");
  485.       exit(1);
  486.       }
  487.  
  488.    /*---------------------------------------------------------------
  489.     * read the stack, add files
  490.     *---------------------------------------------------------------*/
  491.    while (num--)
  492.       {
  493.       fgets(buffer,BUFFER_LEN,stack);
  494.       if ('\n' == buffer[strlen(buffer)-1])
  495.          buffer[strlen(buffer)-1] = '\0';
  496.  
  497.       /*------------------------------------------------------------
  498.        * get the file name
  499.        *------------------------------------------------------------*/
  500.       copy = strtok(buffer," ");
  501.       strcpy(fileName,copy);
  502.       strcat(fileName,".");
  503.  
  504.       copy = strtok(NULL," ");
  505.       strcat(fileName,copy);
  506.       strcat(fileName,".");
  507.  
  508.       copy = strtok(NULL," ");
  509.       strcat(fileName,copy);
  510.  
  511.       /*------------------------------------------------------------
  512.        * get the date and time
  513.        *------------------------------------------------------------*/
  514.       for (i=0; i<4; i++)
  515.          strtok(NULL," ");
  516.  
  517.       fileDate = strtok(NULL," ");
  518.       fileTime = strtok(NULL," ");
  519.  
  520.       /*------------------------------------------------------------
  521.        * add file
  522.        *------------------------------------------------------------*/
  523.       FileAdd(info,fileList,fileName,"",fileDate,fileTime);
  524.       }
  525.  
  526.    /*---------------------------------------------------------------
  527.     * close stack, free memory, leave
  528.     *---------------------------------------------------------------*/
  529.    fclose(stack);
  530.    free(fileSpec);
  531.    free(buffer);
  532.  
  533.    }
  534.  
  535. /*------------------------------------------------------------------
  536.  * other operating systems (AIX, DOS, ???)
  537.  *------------------------------------------------------------------*/
  538. #else
  539.  
  540. #include <sys/types.h>
  541. #include <sys/stat.h>
  542.  
  543. /*------------------------------------------------------------------
  544.  * get file date and time
  545.  *------------------------------------------------------------------*/
  546. void getFileDateTime(
  547.    char *fileName,
  548.    char *fileDate,
  549.    char *fileTime
  550.    )
  551.    {
  552.    struct stat  s;
  553.    struct tm   *t;
  554.  
  555.    *fileDate = 0;
  556.    *fileTime = 0;
  557.  
  558.    if (stat(fileName,&s))
  559.       return;
  560.  
  561.    t = localtime(&(s.st_mtime));
  562.  
  563.    sprintf(fileDate,"%2.2d/%2.2d/%2.2d",
  564.            (int) t->tm_mon + 1,
  565.            (int) t->tm_mday,
  566.            (int) t->tm_year % 100);
  567.  
  568.    sprintf(fileTime,"%2.2d:%2.2d:%2.2d",
  569.            (int) t->tm_hour,
  570.            (int) t->tm_min,
  571.            (int) t->tm_sec);
  572.    }
  573.  
  574. /*------------------------------------------------------------------
  575.  * generic version - add all the files in a file spec to the list
  576.  *   this will work for AIX
  577.  *------------------------------------------------------------------*/
  578. void FileSpecAddGeneric(
  579.    Info      *info,
  580.    List      *fileList,
  581.    char      *fileSpec
  582.    )
  583.    {
  584.    char        *pathName;
  585.    char        *fileName;
  586.    struct stat  statBuff;
  587.    char         dateBuff[9];
  588.    char         timeBuff[9];
  589.  
  590.    /*---------------------------------------------------------------
  591.     * get area for path name
  592.     *---------------------------------------------------------------*/
  593.    if (!strchr(fileSpec,'/'))
  594.       {
  595.       pathName = "";
  596.       fileName = fileSpec;
  597.       }
  598.  
  599.    else
  600.       {
  601.       /*------------------------------------------------------------
  602.        * convert back slashes to slashes
  603.        *------------------------------------------------------------*/
  604.       while (strchr(fileSpec,'\\'))
  605.          *strchr(fileSpec,'\\') = '/';
  606.  
  607.       /*------------------------------------------------------------
  608.        * get path part of file spec
  609.        *------------------------------------------------------------*/
  610.       pathName = malloc(1+strlen(fileSpec));
  611.       if (!pathName)
  612.          cPostError(1,"out of memory!!!");
  613.  
  614.       strcpy(pathName,fileSpec);
  615.  
  616.       *(strrchr(pathName,'/') + 1) = '\0';
  617.  
  618.       /*------------------------------------------------------------
  619.        * get filename part of file spec
  620.        *------------------------------------------------------------*/
  621.       fileName = malloc(1+strlen(fileSpec));
  622.       if (!fileName)
  623.          cPostError(1,"out of memory!!!");
  624.  
  625.       strcpy(fileName,fileSpec);
  626.       fileName = strrchr(fileName,'/') + 1;
  627.       }
  628.  
  629.    /*------------------------------------------------------------
  630.     * get file date and time
  631.     *------------------------------------------------------------*/
  632.    getFileDateTime(fileSpec,dateBuff,timeBuff);
  633.  
  634.    /*---------------------------------------------------------------
  635.     * add file
  636.     *---------------------------------------------------------------*/
  637.    FileAdd(info,fileList,fileName,pathName,dateBuff,timeBuff);
  638.    }
  639.  
  640. #endif
  641.  
  642. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  643. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  644.  
  645. /*------------------------------------------------------------------
  646.  * the router for FileSpecAdd
  647.  *------------------------------------------------------------------*/
  648. void FileSpecAdd(
  649.    Info      *info,
  650.    List      *fileList,
  651.    char      *fileSpec
  652.    )
  653.    {
  654.    TokFileInfo tfi;
  655.  
  656.  
  657.    /*---------------------------------------------------------------
  658.     * check for @ files
  659.     *---------------------------------------------------------------*/
  660.    if (('@' == fileSpec[0]) && (1 != strlen(fileSpec)))
  661.       {
  662.       fileSpec++;
  663.       tfi = TokFileOpen(fileSpec);
  664.       if (!tfi)
  665.          {
  666.          cPostError(0,"error opening file '%s' for reading",fileSpec);
  667.          return;
  668.          }
  669.  
  670.       /*------------------------------------------------------------
  671.        * add filenames from file
  672.        *------------------------------------------------------------*/
  673.       while (NULL != (fileSpec = TokFileNext(tfi)))
  674.          FileSpecAdd(info,fileList,fileSpec);
  675.  
  676.       return;
  677.       }
  678.  
  679.    /*---------------------------------------------------------------
  680.     * call the op/sys dependant function
  681.     *---------------------------------------------------------------*/
  682.  
  683. #if defined(OPSYS_OS2) || defined(OPSYS_OS2V2)
  684.  
  685.    FileSpecAddOS2(info,fileList,fileSpec);
  686.  
  687. #elif defined(OPSYS_CMS)
  688.  
  689.    FileSpecAddCMS(info,fileList,fileSpec);
  690.  
  691. #else
  692.  
  693.    FileSpecAddGeneric(info,fileList,fileSpec);
  694.  
  695. #endif
  696.    }
  697.  
  698. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  699. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  700.  
  701. /*------------------------------------------------------------------
  702.  * count occurances of a character in a string
  703.  *------------------------------------------------------------------*/
  704. static int strcnt(
  705.    char  c,
  706.    char *string
  707.    )
  708.    {
  709.    int   cnt;
  710.  
  711.    cnt    = 0;
  712.    string = strchr(string,c);
  713.  
  714.    while (string)
  715.       {
  716.       cnt++;
  717.       string++;
  718.       string = strchr(string,c);
  719.       }
  720.  
  721.    return cnt;
  722.    }
  723.  
  724. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  725. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  726.  
  727. /*------------------------------------------------------------------
  728.  * expand tabs
  729.  *------------------------------------------------------------------*/
  730. static char *ExpandTabs(
  731.    char *line,
  732.    int   expand
  733.    )
  734.    {
  735.    int   tabs;
  736.    char *newLine;
  737.    int   lineLen;
  738.    int   col;
  739.    char *c1;
  740.    char *c2;
  741.  
  742.    /*---------------------------------------------------------------
  743.     * get # of tabs - if no tabs, return line intact
  744.     *---------------------------------------------------------------*/
  745.    tabs = strcnt('\t',line);
  746.    if (!tabs)
  747.       return line;
  748.  
  749.    /*---------------------------------------------------------------
  750.     * otherwise, allocate space for new line
  751.     *---------------------------------------------------------------*/
  752.    lineLen = strlen(line);
  753.    newLine = malloc(lineLen + 1 + expand * tabs);
  754.    if (!newLine)
  755.       cPostError(1,"out of memory!!!");
  756.  
  757.    memset(newLine,0,lineLen + 1 + expand * tabs);
  758.  
  759.    /*---------------------------------------------------------------
  760.     * copy old string to new string, expanding tabs as you go
  761.     *---------------------------------------------------------------*/
  762.    col = 1;
  763.    c1  = line;
  764.    c2  = newLine;
  765.    while (*c1)
  766.       {
  767.       /*------------------------------------------------------------
  768.        * copy non-tab chars into new string
  769.        *------------------------------------------------------------*/
  770.       if ('\t' != *c1)
  771.          {
  772.          *c2++ = *c1++;
  773.          col++;
  774.          }
  775.  
  776.       else
  777.          {
  778.          c1++;
  779. /*------------------------------------------------------------------
  780.  * art roberts identified this bug in the code and also supplied a
  781.  * fix (below).
  782.  *------------------------------------------------------------------*/
  783. #if 0
  784.          for (i = col%expand; i < (expand+1); i++)
  785.             {
  786.             *c2++ = ' ';
  787.             col++;
  788.             }
  789. #else
  790.          do
  791.             {
  792.             *c2++ = ' ';
  793.             }
  794.          while ((col++ % expand) != 0);
  795. #endif
  796.          }
  797.       }
  798.  
  799.    /*---------------------------------------------------------------
  800.     * free original line, return new line
  801.     *---------------------------------------------------------------*/
  802.    free(line);
  803.    return newLine;
  804.    }
  805.  
  806. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  807. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  808.  
  809. /*------------------------------------------------------------------
  810.  * read file into array of lines
  811.  *------------------------------------------------------------------*/
  812. File *FileReadLines(
  813.    Info *info,
  814.    File *file
  815.    )
  816.    {
  817.    static char    buffer [MAX_LINE_LEN];
  818.    FILE          *hFile;
  819.    unsigned long  lines;
  820.    char          *line;
  821.  
  822.    /*---------------------------------------------------------------
  823.     * initialize
  824.     *---------------------------------------------------------------*/
  825.    file->line       = NULL;
  826.    file->lines      = 0;
  827.    file->cline      = 0L;
  828.    file->maxLineLen = 0;
  829.    memset(buffer,'\0',sizeof(buffer));
  830.  
  831.    /*---------------------------------------------------------------
  832.     * open file
  833.     *---------------------------------------------------------------*/
  834.    if (file->tempName)
  835.       {
  836.       hFile = fopen(file->tempName,"r");
  837.       if (NULL == hFile)
  838.          cPostError(1,"error opening file %s for reading",file->tempName);
  839.       }
  840.  
  841.    else
  842.       {
  843.       hFile = fopen(file->pathName,"r");
  844.       if (NULL == hFile)
  845.          cPostError(1,"error opening file %s for reading",file->pathName);
  846.       }
  847.  
  848.    /*---------------------------------------------------------------
  849.     * buffer input
  850.     *---------------------------------------------------------------*/
  851. /* setvbuf(hFile,NULL,_IOFBF,32000); */
  852.  
  853.    /*---------------------------------------------------------------
  854.     * allocate area for lines
  855.     *---------------------------------------------------------------*/
  856.    lines = FILE_LINES;
  857.    file->line = malloc(((int)lines)*sizeof(char *));
  858.    if (NULL == file->line)
  859.       cPostError(1,"out of memory!!!");
  860.  
  861.    /*---------------------------------------------------------------
  862.     * loop for each line in the file
  863.     *---------------------------------------------------------------*/
  864.    for (file->lines=0;;file->lines++)
  865.       {
  866.       /*------------------------------------------------------------
  867.        * reallocate buffer if we need to
  868.        *------------------------------------------------------------*/
  869.       if (file->lines >= lines)
  870.          {
  871.          lines += FILE_LINES;
  872.          file->line   = realloc(file->line,((int)lines)*sizeof(char *));
  873.          if (NULL == file->line)
  874.             cPostError(1,"out of memory!!!");
  875.          }
  876.  
  877.       /*------------------------------------------------------------
  878.        * read a line
  879.        *------------------------------------------------------------*/
  880. #if defined(DO_IT_NO_MORE)
  881.       if (info->indent1)
  882.          {
  883.          buffer[0] = ' ';
  884.          if (!fgets(&(buffer[1]),MAX_LINE_LEN-1,hFile))
  885.             break;
  886.          }
  887.  
  888.       else
  889. #endif
  890.          {
  891.          if (!fgets(buffer,MAX_LINE_LEN,hFile))
  892.             break;
  893.          }
  894.  
  895.  
  896.       /*------------------------------------------------------------
  897.        * malloc space for new line
  898.        *------------------------------------------------------------*/
  899.       line = malloc(1+strlen(buffer));
  900.       if (!line)
  901.          cPostError(1,"out of memory!!!");
  902.  
  903.       /*------------------------------------------------------------
  904.        * copy line we just got into new line
  905.        *------------------------------------------------------------*/
  906.       strcpy(line,buffer);
  907.  
  908.       /*---------------------------------------------------------------
  909.        * expand tabs
  910.        *---------------------------------------------------------------*/
  911.       line = ExpandTabs(line,info->oTabs);
  912.  
  913.       /*------------------------------------------------------------
  914.        * set vars
  915.        *------------------------------------------------------------*/
  916.       file->line[file->lines] = line;
  917.       file->maxLineLen = max(file->maxLineLen,(int)strlen(line));
  918.       }
  919.  
  920.    /*---------------------------------------------------------------
  921.     * close the file
  922.     *---------------------------------------------------------------*/
  923.    fclose(hFile);
  924.  
  925.    return file;
  926.    }
  927.  
  928. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  929. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  930.  
  931. /*------------------------------------------------------------------
  932.  * return bytes from the file, conveniently a line at a time
  933.  *------------------------------------------------------------------*/
  934. unsigned long GetBlockOfFile(
  935.    void  *readInfo,
  936.    char **buffer
  937.    )
  938.    {
  939.    File *file;
  940.    file = readInfo;
  941.  
  942.    if (file->cline >= file->lines)
  943.       return 0L;
  944.  
  945.    *buffer = file->line[file->cline++];
  946.    return (unsigned long) strlen(*buffer);
  947.    }
  948.  
  949. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  950. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  951.  
  952. /*------------------------------------------------------------------
  953.  * get function (add if needed) from global function table
  954.  *------------------------------------------------------------------*/
  955. Function *GetFunction(
  956.    Info          *info,
  957.    char          *name
  958.    )
  959.    {
  960.    Function  func;
  961.    Function *found;
  962.  
  963.    func.name = name;
  964.  
  965.    /*---------------------------------------------------------------
  966.     * look for function
  967.     *---------------------------------------------------------------*/
  968.    found = ListFind(info->funcTree,&func);
  969.    if (found)
  970.       return found;
  971.  
  972.    /*---------------------------------------------------------------
  973.     * fill in fields if not found
  974.     *---------------------------------------------------------------*/
  975.    func.id           = 0;
  976.    func.spotted      = 0;
  977.    func.callsList    = ListCreate(sizeof(Function *),
  978.                                   (ListCompareFunc *)FunctionNamePtrCompare,
  979.                                   cPostNoMem);
  980.    if (!func.callsList)
  981.       cPostError(1,"error creating function calls list");
  982.  
  983.    func.calledByList = ListCreate(sizeof(Function *),
  984.                                   (ListCompareFunc *)FunctionNamePtrCompare,
  985.                                   cPostNoMem);
  986.    if (!func.calledByList)
  987.       cPostError(1,"error creating function called by list");
  988.  
  989.    func.name         = malloc(1+strlen(name));
  990.    if (!func.name)
  991.       cPostError(1,"out of memory!!!");
  992.  
  993.    strcpy(func.name,name);
  994.  
  995.    func.lineNo       = 0;
  996.    func.fileName     = "";
  997.  
  998.    /*---------------------------------------------------------------
  999.     * add it, return pointer
  1000.     *---------------------------------------------------------------*/
  1001.    if (!ListAdd(info->funcTree,&func))
  1002.       cPostError(1,"error adding function to function list");
  1003.  
  1004.    found = ListFind(info->funcTree,&func);
  1005.    if (!found)
  1006.       cPostError(1,"error retrieving function from function list");
  1007.  
  1008.    return found;
  1009.    }
  1010.  
  1011. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  1012. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  1013.  
  1014. /*------------------------------------------------------------------
  1015.  * prinf function table entry
  1016.  *------------------------------------------------------------------*/
  1017. static int PrintFunctionTableEntry(
  1018.    Function **func,
  1019.    Info      *info
  1020.    )
  1021.    {
  1022.    fprintf(info->oFile,":hp2.%s:ehp2.",(*func)->name);
  1023.  
  1024.    if ('\0' != *((*func)->fileName))
  1025.       {
  1026.       fprintf(info->oFile," (%s, page :spotref refid=sp%4.4d.)\n",
  1027.                      (*func)->fileName,(*func)->id);
  1028.       }
  1029.  
  1030.    else
  1031.       fprintf(info->oFile,"\n");
  1032.  
  1033.    info->count1++;
  1034.    return 0;
  1035.    }
  1036.  
  1037. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  1038. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  1039.  
  1040. /*------------------------------------------------------------------
  1041.  * print function pointer information
  1042.  *------------------------------------------------------------------*/
  1043. int PrintFunctionPtrInfo(
  1044.    Function **func,
  1045.    Info      *info
  1046.    )
  1047.    {
  1048.    return PrintFunctionInfo(*func,info);
  1049.    }
  1050.  
  1051. /*------------------------------------------------------------------
  1052.  * print function information
  1053.  *------------------------------------------------------------------*/
  1054. int PrintFunctionInfo(
  1055.    Function  *func,
  1056.    Info      *info
  1057.    )
  1058.    {
  1059.  
  1060.    /*---------------------------------------------------------------
  1061.     * print table definition
  1062.     *---------------------------------------------------------------*/
  1063.    fprintf(info->oFile,":table refid=reftbl.\n");
  1064.  
  1065.    /*---------------------------------------------------------------
  1066.     * print function name
  1067.     *---------------------------------------------------------------*/
  1068.    fprintf(info->oFile,":row.:c 5.&fn%4.4d.",func->id);
  1069.  
  1070.    if ('\0' != *(func->fileName))
  1071.       {
  1072.       fprintf(info->oFile," (%s, page :spotref refid=sp%4.4d.)\n",
  1073.                      func->fileName,func->id);
  1074.       }
  1075.  
  1076.    else
  1077.       fprintf(info->oFile,"\n");
  1078.  
  1079.    /*---------------------------------------------------------------
  1080.     * print calls list
  1081.     *---------------------------------------------------------------*/
  1082.    if (ListCount(func->callsList))
  1083.       {
  1084.       fprintf(info->oFile,":c 1.calls\n:c 2.");
  1085.  
  1086.       info->count1 = 1;
  1087.       info->count2 = ListCount(func->callsList);
  1088.  
  1089.       ListIterate(func->callsList,
  1090.                   (ListIterateFunc *)PrintFunctionTableEntry,
  1091.                   info);
  1092.       }
  1093.  
  1094.    /*---------------------------------------------------------------
  1095.     * print called by list
  1096.     *---------------------------------------------------------------*/
  1097.    if (ListCount(func->calledByList))
  1098.       {
  1099.       fprintf(info->oFile,":c 3.called\nby\n:c 4.");
  1100.  
  1101.       info->count1 = 1;
  1102.       info->count2 = ListCount(func->calledByList);
  1103.  
  1104.       ListIterate(func->calledByList,
  1105.                   (ListIterateFunc *)PrintFunctionTableEntry,
  1106.                   info);
  1107.       }
  1108.  
  1109.    fprintf(info->oFile,":etable.\n");
  1110.  
  1111.    return 0;
  1112.    }
  1113.  
  1114. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  1115. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  1116.  
  1117. /*------------------------------------------------------------------
  1118.  * generate a temporary file name
  1119.  *------------------------------------------------------------------*/
  1120. char *TempFileName(
  1121.    FILE **file,
  1122.    Info  *info
  1123.    )
  1124.    {
  1125.    char       *name;
  1126.    static int  counter = 0;
  1127.  
  1128.    name = malloc(13 + 1 + strlen(info->oTemp));
  1129.    if (!name)
  1130.       cPostError(1,"out of memory!!!");
  1131.  
  1132.    for(;;)
  1133.       {
  1134.  
  1135. #if defined(OPSYS_CMS)
  1136.       if (*(info->oTemp))
  1137.          sprintf(name,"cps%.5d.tmp.%c",counter++,*(info->oTemp));
  1138.       else
  1139.          sprintf(name,"cps%.5d.tmp",counter++);
  1140. #else
  1141.       sprintf(name,"%scps%.5d.tmp",info->oTemp,counter++);
  1142. #endif
  1143.  
  1144.       /*---------------------------------------------------------------
  1145.        * open temp file
  1146.        *---------------------------------------------------------------*/
  1147.       *file = fopen(name,"r");
  1148.       if (NULL == *file)
  1149.          {
  1150.          *file = fopen(name,"w");
  1151.          if (NULL != *file)
  1152.             return name;
  1153.          else
  1154.             {
  1155.             cPostError(0,"error opening temp file '%s' for writing",name);
  1156.             cPostError(1,"check -y value for writable temporary path");
  1157.             }
  1158.          }
  1159.  
  1160.       fclose(*file);
  1161.       }
  1162.  
  1163.    /*---------------------------------------------------------------
  1164.     * can't really get here anymore
  1165.     *---------------------------------------------------------------*/
  1166.    cPostError(1,"can't create temp file");
  1167.    return NULL;
  1168.    }
  1169.  
  1170. /*------------------------------------------------------------------
  1171.  * see if a file is one of our temporary files
  1172.  *------------------------------------------------------------------*/
  1173. int IsTempFileName(
  1174.    char *name
  1175.    )
  1176.    {
  1177.    if (Memicmp(name,"cps",3))
  1178.       return 0;
  1179.  
  1180.    if (Memicmp(name+8,".tmp",4))
  1181.       return 0;
  1182.  
  1183.    return 1;
  1184.    }
  1185.  
  1186. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  1187. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  1188.  
  1189. /*------------------------------------------------------------------
  1190.  * compare strings case insensitively
  1191.  *------------------------------------------------------------------*/
  1192. int Stricmp(
  1193.    char *str1,
  1194.    char *str2
  1195.    )
  1196.    {
  1197.    char c1;
  1198.    char c2;
  1199.  
  1200.    while (*str1 && *str2)
  1201.       {
  1202.       c1 = (char) toupper(*str1);
  1203.       c2 = (char) toupper(*str2);
  1204.  
  1205.       if (c1 < c2)
  1206.          return -1;
  1207.       else if (c1 > c2)
  1208.          return  1;
  1209.  
  1210.       str1++; str2++;
  1211.       }
  1212.  
  1213.    if (!*str1 && !*str2)
  1214.       return 0;
  1215.  
  1216.    if (*str1)
  1217.       return  1;
  1218.    else
  1219.       return -1;
  1220.    }
  1221.  
  1222. /*------------------------------------------------------------------
  1223.  * compare strings case insensitively
  1224.  *------------------------------------------------------------------*/
  1225. int Memicmp(
  1226.    char *str1,
  1227.    char *str2,
  1228.    int   len
  1229.    )
  1230.    {
  1231.    char c1;
  1232.    char c2;
  1233.    int  i;
  1234.  
  1235.    for (i=0; i<len; i++)
  1236.       {
  1237.       c1 = (char) toupper(*str1);
  1238.       c2 = (char) toupper(*str2);
  1239.  
  1240.       if (c1 < c2)
  1241.          return -1;
  1242.       else if (c1 > c2)
  1243.          return  1;
  1244.  
  1245.       str1++; str2++;
  1246.       }
  1247.  
  1248.    return 0;
  1249.    }
  1250.  
  1251. /*------------------------------------------------------------------
  1252.  * upper case a string
  1253.  *------------------------------------------------------------------*/
  1254. char *Strupr(
  1255.    char *str
  1256.    )
  1257.    {
  1258.    char *orig;
  1259.  
  1260.    orig = str;
  1261.    while (*str)
  1262.       {
  1263.       *str = (char) toupper(*str);
  1264.       str++;
  1265.       }
  1266.  
  1267.    return orig;
  1268.    }
  1269.  
  1270. #if 0
  1271. /*------------------------------------------------------------------
  1272.  * reverse a string
  1273.  *------------------------------------------------------------------*/
  1274. char *Strrev(
  1275.    char *str
  1276.    )
  1277.    {
  1278.    int   len;
  1279.    char  temp;
  1280.    int   i;
  1281.  
  1282.    len = strlen(str);
  1283.  
  1284.    for (i=0; i<(len+1)/2-1; i++)
  1285.       {
  1286.       temp         = str[i];
  1287.       str[i]       = str[len-1-i];
  1288.       str[len-i-1] = temp;
  1289.       }
  1290.  
  1291.    return str;
  1292.    }
  1293. #endif
  1294.  
  1295. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  1296. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  1297.  
  1298. /*------------------------------------------------------------------
  1299.  * called when out of memory
  1300.  *------------------------------------------------------------------*/
  1301. void cPostNoMem(void)
  1302.    {
  1303.    cPostError(1,"out of memory!!!");
  1304.    }
  1305.  
  1306.