"Fossies" - the Fresh Open Source Software Archive

Member "cpostutl.c" (9 May 1995, 37633 Bytes) of package /linux/misc/old/cpost.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cpostutl.c" see the Fossies "Dox" file reference documentation.

    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    orig = str;
 1260    
 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