home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cidsam.zip / HLRFIO.C < prev    next >
C/C++ Source or Header  |  1993-06-28  |  20KB  |  478 lines

  1.                   /*********************************/
  2.                   /*              NOTE             */
  3.                   /*                               */
  4.                   /* This sample code has been     */
  5.                   /* provided by IBM.  It is not   */
  6.                   /* warranted for any particular  */
  7.                   /* use or purpose.               */
  8.                   /*                               */
  9.                   /* IBM releases this code into   */
  10.                   /* the public domain.  You may   */
  11.                   /* use it, modify it, or         */
  12.                   /* incorporate it into other     */
  13.                   /* products without restriction. */
  14.                   /*********************************/
  15.  /*********************************************************************/
  16.  /*                                                                   */
  17.  /* MODULE  NAME:    hlrfio.c                                         */
  18.  /*                                                                   */
  19.  /* DESCRIPTIVE NAME: Higher level (than rfio.c) routines for         */
  20.  /*                   Response File I/O                               */
  21.  /*                                                                   */
  22.  /* LINKAGE:   These are linkable subroutines. They require           */
  23.  /*            CID_findfile() and CID_log()  be linked in also.       */
  24.  /*                                                                   */
  25.  /*********************************************************************/
  26. #pragma page (1)
  27. /*
  28.  
  29.      A higher-level interface to the rfio package.  For those who are
  30.      satisfied with the error handling and logging implemented here,
  31.      and who
  32.             a) Use Include (NOT case sensitive) as a keyword to
  33.                indicate include files.
  34.             b) Are happy with sequential processing of includes
  35.      the response file interface can be reduced to four calls:
  36.  
  37.  
  38.      UINT RFOpen(char *pszFilename)
  39.  
  40.          which opens the file named filename as a response file.
  41.          It returns 0 for success, 1 for failure.
  42.  
  43.      UINT RFGetNextKeyword(char **ppszKeyword, char **ppszValue,
  44.                            UINT *puiType)
  45.  
  46.          which stores pointers to the next keyword and value, and stores
  47.          an indicator of the type of value (string or list) (RFLIST and
  48.          RFSTRING respectively).
  49.  
  50.          Do not issue a free() against *ppxzKeyword or *ppszValue.
  51.          If you need a copy of the keyword and/or value, make one.
  52.          The values will be erased and the space they take up will be
  53.          freed on the next call to RFGetNextKeyword().
  54.  
  55.          This function returns RF0 as long as everything is OK,
  56.          RFEOF when the last keyword and value have already been returned,
  57.          or RFERR when a fatal error has occured.
  58.  
  59.      UINT RFGetNextKwdInList(char **ppszStart, char **ppszKeyword,
  60.                              char **ppszValue, UINT *puiType)
  61.  
  62.          which works just like RF_Get_Next_Kwd_In_List();
  63.          Like RFGetNextKeyword, it returns RF0 as long as everything is
  64.          OK, RFEOF when the last keyword and value have already been
  65.          returned, or RFERR when a fatal error has occured.
  66.  
  67.      UINT RFClose(void)
  68.  
  69.          which closes a response file.  RFClose is not required unless the
  70.          caller wants to free resources (memory and file handles) in use
  71.          by rfio.  A call to RFOpen automatically closes down any previously
  72.          open Response File, so there is no need to call RFClose() between
  73.          Response Files.  This function always returns 0.
  74.  
  75.      char *RFCopyString(char *string)
  76.  
  77.          which makes a *persistent* copy of a string value
  78.  
  79.      VOID *RFCopyList(void *from)
  80.  
  81.          which makes a *persistant* copy of a list.
  82.  
  83.      VOID *RFMergeLists(void *list1, void *list2)
  84.  
  85.          which merges the values in two lists.  The algorithm is to examine
  86.          each keyword in list1.  If there is a corresponding keyword in list2,
  87.          then the _value_ from list2 is assigned to the keyword in the
  88.          merged list.  Any unmatched keywords in either list appear in the
  89.          merged list.  If list1 and list2 have a keyword to which imbedded
  90.          lists are assigned, then the imbedded lists are *not* merged; the
  91.          list2 imbedded list is assigned to the keyword.
  92.  
  93.      char *RFCopyString(char *string)
  94.  
  95.          which makes a persistent copy of a string value
  96.  
  97.      UINT RFSizeOfList(void *list)
  98.  
  99.          which returns the size in bytes of the list whose address is passed.
  100.          The entire length, including terminating null, in included in the
  101.          value returned.  
  102.  
  103. */
  104. #pragma page (1)
  105.  
  106.  
  107. #include <stdlib.h>
  108. #include <stdio.h>
  109. #include <stdarg.h>
  110. #include <string.h>
  111. #define INCL_BASE
  112. #include <os2.h>
  113. #include "rfioe.h"
  114. #include "hlrfio.h"
  115.  
  116. /****************************************************************************/
  117. /*                   G L O B A L   V A R I A B L E S                        */
  118. /****************************************************************************/
  119. RFISP rfisp = (RFISP)NULL;        /* pointer to the imbed file chain */
  120. RFHANDLE rfh;
  121. char *pszRFtempkw = NULL;
  122. char *pszRFtempval = NULL;
  123. char *pszRFLtempkw = NULL;
  124. char *pszRFLtempval = NULL;
  125.  
  126. /****************************************************************************/
  127. /*              F U N C T I O N    D E C L A R A T I O N                    */
  128. /****************************************************************************/
  129. extern void CID_Log(UINT uiMsgno, ...);
  130. #pragma page (1)
  131.  
  132.  
  133. /****************************************************************************/
  134. /*                            R F O p e n                                   */
  135. /****************************************************************************/
  136. UINT RFOpen(char *pszFilename)
  137. {
  138.     int rc;
  139.  
  140.     if (rfisp)                 /* If there is an open file already */
  141.       RFClose();                  /* Close it out */
  142.  
  143.     if ( (rfisp = RF_Create_Root_ISE()) == (RFISP)NULL)
  144.       {
  145.          CID_Log(HRF_OOS_ERROR, NULL);
  146.          return(RFHERR);
  147.       }
  148.     else
  149.       if ( (rfh = RF_Open_File(pszFilename, rfisp, &rc)) == NULL )
  150.         {
  151.           CID_Log(HRF_OPEN_MAIN_FILE_ERROR, pszFilename, NULL);
  152.           free(rfisp);
  153.           rfisp = (RFISP)NULL;
  154.           return(RFHERR);
  155.         }
  156.       else
  157.         {
  158.           pszRFtempkw = NULL;
  159.           pszRFtempval = NULL;
  160.           return(RFH0);
  161.         }
  162. }
  163. #pragma page (1)
  164.  
  165.  
  166. /****************************************************************************/
  167. /*                      R F G e t N e x t K e y w o r d                     */
  168. /****************************************************************************/
  169. UINT RFGetNextKeyword(char **ppszKw, char **ppszVal, UINT *puiType)
  170. {
  171.     int rc;
  172.     char caNumbuf[17];
  173.     int  iRFtemptype;
  174.  
  175.     if (pszRFtempkw)        /* free up memory from last call */
  176.       {                                                        /* @U1a */
  177.         free(pszRFtempkw);
  178.         pszRFtempkw = NULL;                                    /* @U1a */
  179.       }                                                        /* @U1a */
  180.     if (pszRFtempval)
  181.       {                                                        /* @U1a */
  182.         free(pszRFtempval);
  183.         pszRFtempval = NULL;                                   /* @U1a */
  184.       }                                                        /* @U1a */
  185.  
  186.     while(1)
  187.     {
  188.       rc = RF_Get_Next_Kwd_In_File(rfh, &pszRFtempkw, &pszRFtempval,
  189.                                    &iRFtemptype);
  190.       switch(rc)
  191.          {
  192.             case RFSYNTAX:     CID_Log(HRF_SYNTAX_ERROR,
  193.                                      itoa(iRFtemptype, caNumbuf, 10),
  194.                                      RF_Get_Current_Filename(rfisp),
  195.                                      pszRFtempval, NULL);
  196.                                return(RFHERR);
  197.                                break;
  198.  
  199.             case RFOOS:        CID_Log(HRF_OOS_ERROR, NULL);
  200.                                return(RFHERR);
  201.                                break;
  202.  
  203.             case RFERR:        CID_Log(HRF_DOSIO_ERROR,
  204.                                      RF_Get_Current_Filename(rfisp),
  205.                                      iRFtemptype, NULL);
  206.                                return(RFHERR);
  207.                                break;
  208.  
  209.             case RFEOF:        if ( (rfh = RF_Close_File(rfh, rfisp)) == NULL)
  210.                                  return(RFHEOF);
  211.                                break;
  212.  
  213.             case RF0:          if (stricmp(pszRFtempkw, "include") == 0)
  214.                                  {
  215.                                    rfh = RF_Open_File(pszRFtempval, rfisp, &rc);
  216.                                    if (!rfh)
  217.                                      {
  218.                                        CID_Log(HRF_OPEN_IMBED_FILE_ERROR,
  219.                                              pszRFtempval, NULL);
  220.                                        return(RFHERR);
  221.                                      }
  222.                                  }
  223.                                else
  224.                                  {
  225.                                     *ppszKw = pszRFtempkw;
  226.                                     *ppszVal = pszRFtempval;
  227.                                     *puiType = iRFtemptype;
  228.                                     return(RFH0);
  229.                                  }
  230.                                break;
  231.  
  232.               default:         CID_Log(HRF_BAD_GETNEXT_RC,
  233.                                      itoa(rc, caNumbuf, 10), NULL);
  234.                                return(RFHERR);
  235.                                break;
  236.          }  /* End SWITCH on rc */
  237.     }
  238. }
  239. #pragma page (1)
  240.  
  241.  
  242. /****************************************************************************/
  243. /*               R F G e t N e x t K e y w o r d I n L i s t                */
  244. /****************************************************************************/
  245. UINT RFGetNextKwdInList(char **ppszStart, char **ppszKeyword,
  246.                         char **ppszValue, UINT *puiType)
  247. {
  248.  
  249.    char *p;
  250.     char caNumbuf[17];
  251.    int  rc;
  252.    int  iRFLtemptype;
  253.  
  254.    if (pszRFLtempkw)        /* free up memory from last call */
  255.      {                                                         /* @U1a */
  256.        free(pszRFLtempkw);                                     /* @U1c */
  257.        pszRFLtempkw = NULL;                                    /* @U1a */
  258.      }                                                         /* @U1a */
  259.    if (pszRFLtempval)
  260.      {                                                         /* @U1a */
  261.        free(pszRFLtempval);                                    /* @U1c */
  262.        pszRFLtempval = NULL;                                   /* @U1a */
  263.      }                                                         /* @U1a */
  264.  
  265.    p = *ppszStart;
  266.    rc = RF_Get_Next_Kwd_In_List(&p, &pszRFLtempkw, &pszRFLtempval,
  267.                                 &iRFLtemptype);
  268.    switch (rc)
  269.    {
  270.           case RFSYNTAX:     CID_Log(HRF_LIST_SYNTAX_ERROR,
  271.                                    itoa(iRFLtemptype, caNumbuf, 10),
  272.                                    RF_Get_Current_Filename(rfisp),
  273.                                    pszRFLtempval, NULL);
  274.                              return(RFHERR);
  275.                              break;
  276.  
  277.           case RFOOS:        CID_Log(HRF_LIST_OOS_ERROR, NULL);
  278.                              return(RFHERR);
  279.                              break;
  280.  
  281.           case RFERR:        CID_Log(HRF_LIST_DOSIO_ERROR,
  282.                                    RF_Get_Current_Filename(rfisp),
  283.                                    iRFLtemptype, NULL);
  284.                              return(RFHERR);
  285.                              break;
  286.  
  287.           case RFEOF:        return(RFHEOF);
  288.                              break;
  289.  
  290.           case RF0:          *ppszStart = p;
  291.                              *ppszKeyword = pszRFLtempkw;
  292.                              *ppszValue   = pszRFLtempval;
  293.                              *puiType     = iRFLtemptype;
  294.                              return(RFH0);
  295.                              break;
  296.  
  297.           default:           CID_Log(HRF_BAD_GETNEXT_RC,
  298.                                    itoa(rc, caNumbuf, 10), NULL);
  299.                              return(RFHERR);
  300.                              break;
  301.  
  302.    }
  303. }
  304. #pragma page (1)
  305.  
  306.  
  307. /****************************************************************************/
  308. /*                             R F C l o s e                                */
  309. /****************************************************************************/
  310. UINT RFClose()
  311. {                           /* Close it out */
  312.    if (pszRFLtempkw)        /* free up memory from last call */
  313.      {                                                        /* @C1a */
  314.        free(pszRFLtempkw);                                    /* @C1c */
  315.        pszRFLtempkw = NULL;                                   /* @C1a */
  316.      }                                                        /* @C1a */
  317.    if (pszRFLtempval)                                         /* @C1a */
  318.      {                                                        /* @C1a */
  319.        free(pszRFLtempval);                                   /* @C1c */
  320.        pszRFLtempval = NULL;                                  /* @C1a */
  321.      }                                                        /* @C1a */
  322.    if (pszRFtempkw)                                           /* @C1a */
  323.      {                                                        /* @C1a */
  324.        free(pszRFtempkw);                                     /* @C1a */
  325.        pszRFtempkw = NULL;                                    /* @C1a */
  326.      }                                                        /* @C1a */
  327.    if (pszRFtempval)                                          /* @C1a */
  328.      {                                                        /* @C1a */
  329.        free(pszRFtempval);                                    /* @C1a */
  330.        pszRFtempval = NULL;                                   /* @C1a */
  331.      }                                                        /* @C1a */
  332.   while (RF_Close_File(rfh, rfisp));
  333.   free(rfisp);
  334.   rfisp = (RFISP)NULL;
  335.   return(RFH0);
  336. }
  337. #pragma page (1)
  338.  
  339. /****************************************************************************/
  340. /*                        R F C o p y S t r i n g                           */
  341. /****************************************************************************/
  342. /****************************************************************************/
  343. /* This routine makes a permanent copy of the string that is passed to it   */
  344. /* and returns the address of the string.                                   */
  345. /****************************************************************************/
  346. char *RFCopyString(char *model)
  347. {
  348.    char *p;
  349.                  
  350.                                           /* Allocate memory for the     */
  351.    p = (char *)malloc(strlen(model) + 1); /* permanent copy              */
  352.    if (p)                                 /* If memory was allocated     */
  353.      strcpy(p, model);                    /* make the copy.              */
  354.    return(p);
  355. }
  356.  
  357. /****************************************************************************/
  358. /*                          R F C o p y L i s t                             */
  359. /****************************************************************************/
  360. void * RFCopyList(void *from)
  361. {
  362.    unsigned int listsize;
  363.    char *p;
  364.    char lastchar;
  365.  
  366.    if (!from)             /* get out if a bad value was passed */
  367.      return(NULL);
  368.  
  369.    lastchar = ' ';
  370.                           /* malloc enough space for the list, and copy   @C1a*/
  371.                           /* the list into the malloced space.            @C1a*/
  372.    listsize = RFSizeOfList(from);
  373.    p = malloc(listsize);
  374.    if (p)
  375.      memcpy((void *)p, from, listsize);
  376.    else
  377.      CID_Log(HRF_OOS_ERROR, NULL);
  378.    return(p);
  379. }
  380.  
  381. /****************************************************************************/
  382. /*                        R F M e r g e L i s t s                           */
  383. /****************************************************************************/
  384. /* We don't bother to sort.  Lists will seldom be long enough to make it    */
  385. /* worth while.                                                             */
  386. /****************************************************************************/
  387. void *RFMergeLists(void *list1, void *list2)
  388. {
  389.    char *start1, *start2, *startm;
  390.    char *keyword1, *keyword2, *keywordm;
  391.    char *value1, *value2, *valuem;
  392.    void *mergedList;
  393.    UINT type1, type2, typem;
  394.    UINT merged_size, found;
  395.    char lastchar;
  396.                           /* Get worst-case size of combined lists          */
  397.    merged_size = RFSizeOfList(list1) + RFSizeOfList(list2);
  398.                           /* Allocate enough memory for the worst case.     */
  399.    mergedList = (void *)malloc(merged_size);
  400.    if (!mergedList)       /* Bail out if no memory is available.            */
  401.      return(NULL);
  402.    startm = mergedList;   /* This pointer will increase as we fill the      */
  403.                           /* merged list.                                   */
  404.    lastchar = ' ';        /* First, copy in all of list2.                   */
  405.    for (start2 = list2; *start2 || lastchar; *startm++ = *start2++)
  406.       lastchar = *start2;
  407.    start2 -= 3;          /* back up over )00                                */
  408.    start1 = list1;       /* Now, pick up anything unmatched from list1      */
  409.    while (RFGetNextKwdInList(&start1, &keyword1, &value1, &type1) == RFH0)
  410.       {
  411.          keywordm = RFCopyString(keyword1);
  412.         if (type1 == RFHLIST)
  413.           {
  414.              typem = RFHLIST;
  415.              valuem = RFCopyList(value1);
  416.           }
  417.         else
  418.           {
  419.              typem = RFHSTRING;
  420.              valuem = RFCopyString(value1);
  421.           }
  422.         start2 = list2;        /* Try to match w/ a kwd in list 2           */
  423.         found  = 0;
  424.         while (RFGetNextKwdInList(&start2,&keyword2,&value2,&type2) == RFH0)
  425.           {
  426.              if (stricmp(keywordm, keyword2) == 0)   /* match found         */
  427.                {
  428.                   found = 1;
  429.                   break;
  430.                }
  431.           }
  432.          if (!found)
  433.            {
  434.               strcpy(startm, keywordm);
  435.               strcat(startm,"=");
  436.               startm += (strlen(keywordm) + 1);
  437.               if (typem == RFHSTRING)
  438.                 {
  439.                   strcpy(startm, valuem);
  440.                   startm += (strlen(valuem) + 1);
  441.                 }
  442.               else
  443.                 {
  444.                    lastchar = ' ';
  445.                    for (start2 = valuem; *start2 || lastchar; *startm++ = *start2)
  446.                      lastchar = *start2++;
  447.                 }
  448.             }
  449.           free(keywordm);
  450.           free(valuem);
  451.       }
  452.     *startm = '\0';               /* Put in the terminating (double) null.   */
  453.                                   /* Make a copy of the list with the correct*/
  454.                                   /* size (we had assumed worst-case before) */
  455.     startm = RFCopyList(mergedList);
  456.     free(mergedList);             /* Free the worst-case space.              */
  457.     return(startm);               /* Return pointer to merged list.          */
  458. }
  459.  
  460. /****************************************************************************/
  461. /*                        R F S i z e O f L i s t                           */
  462. /****************************************************************************/
  463. UINT RFSizeOfList(void *list)
  464. {
  465.    UINT size = 0;
  466.    char *p, c;
  467.  
  468.    c = 0;
  469.    p = (char *)list;
  470.    while (1)              /* Look for two consecutive null bytes.           */
  471.       {                   /* Everything up to and including that is part of */
  472.          size++;          /* the list.                                      */
  473.          if (!*p && !c)
  474.            return(size);
  475.          c = *p++;
  476.       }
  477. }
  478.