Logo Search packages:      
Sourcecode: xulrunner-1.9 version File versions  Download package

mantomak.c

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is mozilla.org code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define DEFAULT_MANIFEST_EXT ".mn"
#define DEFAULT_MAKEFILE_EXT ".win"

typedef struct char_list_struct {
    char *m_pString;
    struct char_list_struct *m_pNext;
} char_list;

typedef struct macro_list_struct   {
    char *m_pMacro;
    char_list *m_pValue;
    struct macro_list_struct *m_pNext;
} macro_list;

void help(void);
char *input_filename(const char *);
char *output_filename(const char *, const char *);
int input_to_output(FILE *, FILE *);
int output_rules(FILE *);
int output_end(FILE *);
int buffer_to_output(char *, FILE *);
macro_list *extract_macros(char *);
char *find_macro(char *, char **);
void add_macro(char *, macro_list **);
int macro_length(char *);
int value_length(char *);
void add_values(char *, char_list **);
char *skip_white(char *);
int write_macros(macro_list *, FILE *);
int write_values(char_list *, FILE *, int);
void free_macro_list(macro_list *);
void free_char_list(char_list *);
void morph_macro(macro_list **, char *, char *, char *);
void slash_convert(macro_list *, char *);
int explicit_rules(macro_list *, char *, FILE *);
void create_classroot(macro_list **ppList );

int main(int argc, char *argv[])
{
      int iOS = 0;
      char *pInputFile = NULL;
      char *pOutputFile = NULL;

      /*      Figure out arguments.
       *      [REQUIRED] First argument is input file.
       *      [OPTIONAL] Second argument is output file.
       */
      if(argc > 1)    {
            FILE *pInputStream = NULL;
            FILE *pOutputStream = NULL;

            /*      Form respective filenames.
             */
            pInputFile = input_filename(argv[1]);
            pOutputFile = output_filename(pInputFile, argc > 2 ? argv[2] : NULL);

            if(pInputFile == NULL)  {
                  fprintf(stderr, "MANTOMAK:  Unable to form input filename\n");
                  iOS = 1;
            }
            else    {
                  pInputStream = fopen(pInputFile, "rb");
                  if(pInputStream == NULL)        {
                        fprintf(stderr, "MANTOMAK:  Unable to open input file %s\n", pInputFile);
                        iOS = 1;
                  }
            }
            if(pOutputFile == NULL) {
                  fprintf(stderr, "MANTOMAK:  Unable to form output filename\n");
                  iOS = 1;
            }
            else if(pInputStream != NULL)   {
                  pOutputStream = fopen(pOutputFile, "wt");
                  if(pOutputStream == NULL)       {
                        fprintf(stderr, "MANTOMAK:  Unable to open output file %s\n", pOutputFile);
                        iOS = 1;
                  }
            }

            /*      Only do the real processing if our error code is not
             *              already set.
             */
            if(iOS == 0)    {
                  iOS = input_to_output(pInputStream, pOutputStream);
            }

            if(pInputStream != NULL)        {
                  fclose(pInputStream);
                  pInputStream = NULL;
            }
            if(pOutputStream != NULL)       {
                  fclose(pOutputStream);
                  pOutputStream = NULL;
            }
      }
      else    {
            help();
            iOS = 1;
      }

      if(pInputFile)  {
            free(pInputFile);
            pInputFile = NULL;
      }
      if(pOutputFile) {
            free(pOutputFile);
            pOutputFile = NULL;
      }

      return(iOS);
}

void help(void)
{
      fprintf(stderr, "USAGE:\tmantomak.exe InputFile [OutputFile]\n\n");
      fprintf(stderr, "InputFile:\tManifest file.  If without extension, \"%s\" assumed.\n", DEFAULT_MANIFEST_EXT);
      fprintf(stderr, "OutputFile:\tNMake file.  If not present, \"InputFile%s\" assumed.\n", DEFAULT_MAKEFILE_EXT);
}

char *input_filename(const char *pInputFile)
{
      char aResult[_MAX_PATH];
      char aDrive[_MAX_DRIVE];
      char aDir[_MAX_DIR];
      char aName[_MAX_FNAME];
      char aExt[_MAX_EXT];

      if(pInputFile == NULL)  {
            return(NULL);
      }

      _splitpath(pInputFile, aDrive, aDir, aName, aExt);

      if(aExt[0] == '\0')     {
            /*      No extension provided.
             *      Use the default.
             */
            strcpy(aExt, DEFAULT_MANIFEST_EXT);
      }

      aResult[0] = '\0';
      _makepath(aResult, aDrive, aDir, aName, aExt);

      if(aResult[0] == '\0')  {
            return(NULL);
      }
      else    {
            return(strdup(aResult));
      }
}

char *output_filename(const char *pInputFile, const char *pOutputFile)
{
      char aResult[_MAX_PATH];
      char aDrive[_MAX_DRIVE];
      char aDir[_MAX_DIR];
      char aName[_MAX_FNAME];
      char aExt[_MAX_EXT];

      if(pOutputFile != NULL) {
            return(strdup(pOutputFile));
      }

      /*      From here on out, we have to create our own filename,
       *              implied from the input file name.
       */

      if(pInputFile == NULL)  {
            return(NULL);
      }

      _splitpath(pInputFile, aDrive, aDir, aName, aExt);
      strcpy(aExt, DEFAULT_MAKEFILE_EXT);

      aResult[0] = '\0';
      _makepath(aResult, aDrive, aDir, aName, aExt);

      if(aResult[0] == '\0')  {
            return(NULL);
      }
      else    {
            return(strdup(aResult));
      }
}

int input_to_output(FILE *pInput, FILE *pOutput)
{
      char *pHog = NULL;
      long lSize = 0;
      int iRetval = 0;

      /*      Read the entire file into memory.
       */
      fseek(pInput, 0, SEEK_END);
      lSize = ftell(pInput);
      fseek(pInput, 0, SEEK_SET);

      pHog = (char *)malloc(lSize + 1);
      if(pHog)        {
            *(pHog + lSize) = '\0';
            fread(pHog, lSize, 1, pInput);

            iRetval = buffer_to_output(pHog, pOutput);

            free(pHog);
            pHog = NULL;
      }
      else    {
            fprintf(stderr, "MANTOMAK:  Out of Memory....\n");
            iRetval = 1;
      }

      return(iRetval);
}

int output_rules(FILE *pOutput)
{
      int iRetval = 0;

      if(EOF ==
      fputs("\n"
            "!if \"$(MANIFEST_LEVEL)\"==\"RULES\""
            "\n",
          pOutput))
    {
            fprintf(stderr, "MANTOMAK:  Error writing to file....\n");
            iRetval = 1;
      }
      return(iRetval);
}

int output_end(FILE *pOutput)
{
      int iRetval = 0;

      if(EOF ==
      fputs("\n"
            "!endif"
            "\n",
          pOutput))
    {
            fprintf(stderr, "MANTOMAK:  Error writing to file....\n");
            iRetval = 1;
      }
      return(iRetval);
}


int buffer_to_output(char *pBuffer, FILE *pOutput)
{
    int iRetval = 0;
    macro_list *pMacros = NULL;

    /*  Tokenize the macros and their corresponding values.
     */
    pMacros = extract_macros(pBuffer);
    if(pMacros != NULL) {
      /*  Perform forward to backslash conversion on those macros known to be
       *      path information only.
       */
      slash_convert(pMacros, "JBOOTDIRS");
      slash_convert(pMacros, "JDIRS");
      slash_convert(pMacros, "DEPTH");
      slash_convert(pMacros, "NS_DEPTH");
      slash_convert(pMacros, "PACKAGE");
      slash_convert(pMacros, "JMC_GEN_DIR");
      slash_convert(pMacros, "DIST_PUBLIC");

      /*  Process some of the macros, and convert them
       *      into different macros with different data.
       */
      morph_macro(&pMacros, "JMC_GEN", "JMC_HEADERS", "$(JMC_GEN_DIR)\\%s.h");
      morph_macro(&pMacros, "JMC_GEN", "JMC_STUBS", "$(JMC_GEN_DIR)\\%s.c");
      morph_macro(&pMacros, "JMC_GEN", "JMC_OBJS", ".\\$(OBJDIR)\\%s.obj");
      morph_macro(&pMacros, "CSRCS", "C_OBJS", ".\\$(OBJDIR)\\%s.obj");
      morph_macro(&pMacros, "CPPSRCS", "CPP_OBJS", ".\\$(OBJDIR)\\%s.obj");
      morph_macro(&pMacros, "REQUIRES", "LINCS", "-I$(XPDIST)\\public\\%s");

      create_classroot( &pMacros );

      /*  Output the Macros and the corresponding values.
       */
      iRetval = write_macros(pMacros, pOutput);

      /*  Output rule file inclusion
       */
      if(iRetval == 0)    {
          iRetval = output_rules(pOutput);
      }

      /*  Output explicit build rules/dependencies for JMC_GEN.
       */
      if(iRetval == 0)    {
          iRetval = explicit_rules(pMacros, "JMC_GEN", pOutput);
      }

      if(iRetval == 0)    {
          iRetval = output_end(pOutput);
      }
      /*  Free off the macro list.
       */
      free_macro_list(pMacros);
      pMacros = NULL;
    }

    return(iRetval);
}

int explicit_rules(macro_list *pList, char *pMacro, FILE *pOutput)
{
    int iRetval = 0;
    macro_list *pEntry = NULL;

    if(pList == NULL || pMacro == NULL || pOutput == NULL) {
      return(0);
    }

    /*  Find macro of said name.
     *  Case insensitive.
     */
    pEntry = pList;
    while(pEntry)    {
      if(stricmp(pEntry->m_pMacro, pMacro) == 0)  {
          break;
      }

      pEntry = pEntry->m_pNext;
    }

    if(pEntry)  {
      /*  Decide style of rule depending on macro name.
       */
      if(stricmp(pEntry->m_pMacro, "JMC_GEN") == 0)    {
          char_list *pNames = NULL;
          char *pModuleName = NULL;
          char *pClassName = NULL;

          pNames = pEntry->m_pValue;
          while(pNames)   {
            pModuleName = pNames->m_pString;
            pClassName = pModuleName + 1;

            fprintf(pOutput, "$(JMC_GEN_DIR)\\%s.h", pModuleName);
            fprintf(pOutput, ": ");
            fprintf(pOutput, "$(JMCSRCDIR)\\%s.class", pClassName);
            fprintf(pOutput, "\n    ");
            fprintf(pOutput, "$(JMC) -d $(JMC_GEN_DIR) -interface $(JMC_GEN_FLAGS) $(?F:.class=)");
            fprintf(pOutput, "\n");

            fprintf(pOutput, "$(JMC_GEN_DIR)\\%s.c", pModuleName);
            fprintf(pOutput, ": ");
            fprintf(pOutput, "$(JMCSRCDIR)\\%s.class", pClassName);
            fprintf(pOutput, "\n    ");
            fprintf(pOutput, "$(JMC) -d $(JMC_GEN_DIR) -module $(JMC_GEN_FLAGS) $(?F:.class=)");
            fprintf(pOutput, "\n");

            pNames = pNames->m_pNext;
          }
      }
      else    {
          /*  Don't know how to format macro.
           */
          iRetval = 69;
      }
    }

    return(iRetval);
}

void slash_convert(macro_list *pList, char *pMacro)
{
    macro_list *pEntry = NULL;

    if(pList == NULL || pMacro == NULL) {
      return;
    }

    /*  Find macro of said name.
     *  Case insensitive.
     */
    pEntry = pList;
    while(pEntry)    {
      if(stricmp(pEntry->m_pMacro, pMacro) == 0)  {
          break;
      }

      pEntry = pEntry->m_pNext;
    }

    if(pEntry)  {
      char *pConvert = NULL;
      char_list *pValue = pEntry->m_pValue;

      while(pValue)   {
          pConvert = pValue->m_pString;
          while(pConvert && *pConvert)    {
            if(*pConvert == '/')    {
                *pConvert = '\\';
            }
            pConvert++;
          }
          pValue = pValue->m_pNext;
      }
    }
}

void morph_macro(macro_list **ppList, char *pMacro, char *pMorph, char *pPrintf)
{
    macro_list *pEntry = NULL;

    if(ppList == NULL || pMacro == NULL || pMorph == NULL || pPrintf == NULL) {
      return;
    }

    /*  Find macro of said name.
     *  Case insensitive.
     */
    pEntry = *ppList;
    while(pEntry)    {
      if(stricmp(pEntry->m_pMacro, pMacro) == 0)  {
          break;
      }

      pEntry = pEntry->m_pNext;
    }

    if(pEntry)  {
      char_list *pFilename = NULL;
      char aPath[_MAX_PATH];
      char aDrive[_MAX_DRIVE];
      char aDir[_MAX_DIR];
      char aFName[_MAX_FNAME];
      char aExt[_MAX_EXT];
      char *pBuffer = NULL;

      /*  Start with buffer size needed.
       *  We expand this as we go along if needed.
       */
      pBuffer = (char *)malloc(strlen(pMorph) + 2);
      strcpy(pBuffer, pMorph);
      strcat(pBuffer, "=");

      /*  Go through each value, converting over to new macro.
       */
      pFilename = pEntry->m_pValue;
      while(pFilename) {
          _splitpath(pFilename->m_pString, aDrive, aDir, aFName, aExt);

          /*  Expand buffer by required amount.
           */
          sprintf(aPath, pPrintf, aFName);
          strcat(aPath, " ");
          pBuffer = (char *)realloc(pBuffer, _msize(pBuffer) + strlen(aPath));
          strcat(pBuffer, aPath);

          pFilename = pFilename->m_pNext;
      }

      /*  Add the macro.
       */
      add_macro(pBuffer, ppList);

      free(pBuffer);
      pBuffer = NULL;
    }
}

void create_classroot(macro_list **ppList )
{
    char cwd[512];
    int i, i2;
    macro_list *pEntry = NULL;
    macro_list *pE;

    /*  Find macro of said name.
     *  Case insensitive.
     */
    pEntry = *ppList;
    while(pEntry)    {
      if(stricmp(pEntry->m_pMacro, "PACKAGE") == 0)  {
          break;
      }

      pEntry = pEntry->m_pNext;
    }

    if(pEntry == 0 || pEntry->m_pValue == 0 || pEntry->m_pValue->m_pString == 0)  {
      return;
    }

    _getcwd( cwd, 512 );

    i = strlen( pEntry->m_pValue->m_pString );
    i2 = strlen( cwd );

    cwd[i2-i-1] = 0;

    pE = NULL;
    pE = (macro_list *)calloc(sizeof(macro_list),1);
    pE->m_pMacro = strdup("CLASSROOT");
    pE->m_pValue = (char_list *)calloc(sizeof(char_list),1);
    pE->m_pValue->m_pString = strdup(cwd);

    while(*ppList)  {
      ppList = &((*ppList)->m_pNext);
    }
    *ppList = pE;
}


int write_macros(macro_list *pList, FILE *pOutput)
{
    int iRetval = 0;
    int iLineLength = 0;

    if(pList == NULL || pOutput == NULL)    {
      return(0);
    }

      if(EOF ==
      fputs("\n"
            "!if \"$(MANIFEST_LEVEL)\"==\"MACROS\""
            "\n",
          pOutput))
    {
            fprintf(stderr, "MANTOMAK:  Error writing to file....\n");
            return(1);
      }

    while(pList)    {
        int bIgnoreForWin16 = 0;

        /* The following macros should not be emitted for Win16 */
        if (0 == strcmp(pList->m_pMacro, "LINCS")) {
            bIgnoreForWin16 = 1;
        }


        if (bIgnoreForWin16) {
            if(0 > fprintf(pOutput, "!if \"$(MOZ_BITS)\" != \"16\"\n"))  {
                fprintf(stderr, "MANTOMAK:  Error writing to file....\n");
                iRetval = 1;
                break;
            }
        }

      if(0 > fprintf(pOutput, "%s=", pList->m_pMacro))  {
            fprintf(stderr, "MANTOMAK:  Error writing to file....\n");
          iRetval = 1;
          break;
      }
      iLineLength += strlen(pList->m_pMacro) + 1;

      iRetval = write_values(pList->m_pValue, pOutput, iLineLength);
      if(iRetval) {
          break;
      }

      if(EOF == fputc('\n', pOutput))    {
            fprintf(stderr, "MANTOMAK:  Error writing to file....\n");
          iRetval = 1;
          break;
      }
      iLineLength = 0;

      pList = pList->m_pNext;

        if (bIgnoreForWin16) {
            if(0 > fprintf(pOutput, "!endif\n"))  {
                fprintf(stderr, "MANTOMAK:  Error writing to file....\n");
                iRetval = 1;
                break;
            }
            bIgnoreForWin16 = 0;
        }
    }

      if(EOF ==
      fputs("\n"
            "!endif"
            "\n",
          pOutput))
    {
            fprintf(stderr, "MANTOMAK:  Error writing to file....\n");
            return(1);
      }
    return(iRetval);
}

int write_values(char_list *pList, FILE *pOutput, int iLineLength)
{
    int iRetval = 0;
    
    if(pList == NULL || pOutput == NULL)    {
      return(0);
    }

    while(pList)    {
      if(iLineLength == 0)    {
          if(EOF == fputs("    ", pOutput))  {
                fprintf(stderr, "MANTOMAK:  Error writing to file....\n");
            iRetval = 1;
            break;
          }
          iLineLength += 4;

          if(0 > fprintf(pOutput, "%s ", pList->m_pString))   {
                fprintf(stderr, "MANTOMAK:  Error writing to file....\n");
            iRetval = 1;
            break;
          }
          iLineLength += strlen(pList->m_pString) + 1;
      }
      else if(iLineLength + strlen(pList->m_pString) > 72)    {
          if(EOF == fputs("\\\n", pOutput)) {
                fprintf(stderr, "MANTOMAK:  Error writing to file....\n");
            iRetval = 1;
            break;
          }
          iLineLength = 0;
          continue;
      }
      else    {
          if(0 > fprintf(pOutput, "%s ", pList->m_pString))   {
                fprintf(stderr, "MANTOMAK:  Error writing to file....\n");
            iRetval = 1;
            break;
          }
          iLineLength += strlen(pList->m_pString) + 1;
      }

      pList = pList->m_pNext;
    }

    return(iRetval);
}

macro_list *extract_macros(char *pBuffer)
{
    macro_list *pRetval = NULL;
    char *pTraverse = NULL;
    char *pMacro = NULL;

    pTraverse = pBuffer;
    while(pTraverse)    {
      pMacro = NULL;
      pTraverse = find_macro(pTraverse, &pMacro);
      if(pMacro)  {
          add_macro(pMacro, &pRetval);
      }
    }

    return(pRetval);
}

void add_macro(char *pString, macro_list **ppList)
{
    macro_list *pEntry = NULL;
    int iLength = 0;

    if(pString == NULL || *pString == '\0' || ppList == NULL) {
      return;
    }

    /*  Allocate a new list entry for the macro.
     */
    pEntry = (macro_list *)calloc(1, sizeof(macro_list));

    /*  Very first part of the string is the macro name.
     *  How long is it?
     */
    iLength = macro_length(pString);
    pEntry->m_pMacro = (char *)calloc(iLength + 1, 1);
    strncpy(pEntry->m_pMacro, pString, iLength);

    /*  Skip to the values.
     *  These are always on the right side of an '='
     */
    pString = strchr(pString, '=');
    if(pString) {
      pString++;
    }
    add_values(pString, &(pEntry->m_pValue));

    /*  Add the macro to the end of the macro list.
     */
    while(*ppList)  {
      ppList = &((*ppList)->m_pNext);
    }
    *ppList = pEntry;
}

void add_values(char *pString, char_list **ppList)
{
    char_list **ppTraverse = NULL;
    char_list *pEntry = NULL;
    int iLength = 0;
    int iBackslash = 0;

    if(pString == NULL || *pString == '\0' || ppList == NULL)   {
      return;
    }

    while(pString)  {
      /*  Find start of value.
       */
      iBackslash = 0;
      while(*pString) {
          if(*pString == '\\')    {
            iBackslash++;
          }
          else if(*pString == '\n')   {
            if(iBackslash == 0)  {
                /*  End of values.
                 *  Setting to NULL gets out of all loops.
                 */
                pString = NULL;
                break;
            }
            iBackslash = 0;
          }
          else if(!isspace(*pString))  {
            /*  Backslashes part of string.
             *  This screws up if a backslash is in the middle of the string.
             */
            pString -= iBackslash;
            break;
          }

          pString++;
      }
      if(pString == NULL || *pString == '\0') {
          break;
      }

      /*  Do not honor anything beginning with a #
       */
      if(*pString == '#') {
          /*  End of line.
           */
          while(*pString && *pString != '\n') {
            pString++;
          }
          continue;
      }

      /*  Very first part of the string is value name.
       *  How long is it?
       */
      iLength = value_length(pString);

      /*  Do not honor $(NULL)
       */
      if(_strnicmp(pString, "$(NULL)", 7) == 0)    {
          pString += iLength;
          continue;
      }

      /*  Allocate a new list entry for the next value.
       */
      pEntry = (char_list *)calloc(1, sizeof(char_list));

      pEntry->m_pString = (char *)calloc(iLength + 1, 1);
      strncpy(pEntry->m_pString, pString, iLength);

      /*  Add new value entry to the end of the list.
       */
      ppTraverse = ppList;
      while(*ppTraverse)  {
          ppTraverse = &((*ppTraverse)->m_pNext);
      }
      *ppTraverse = pEntry;

      /*  Go on to next value.
       */
      pString += iLength;
    }
}

char *find_macro(char *pBuffer, char **ppMacro)
{
    char *pRetval = NULL;
    int iBackslash = 0;

    if(pBuffer == NULL || ppMacro == NULL) {
      return(NULL);
    }

    /*  Skip any whitespace in the buffer.
     *  If comments need to be skipped also, this is the place.
     */
    while(1)    {
      while(*pBuffer && isspace(*pBuffer))    {
          pBuffer++;
      }
      if(*pBuffer == '#') {
          /*  Go to the end of the line, it's a comment.
           */
          while(*pBuffer && *pBuffer != '\n') {
            pBuffer++;
          }

          continue;
      }
      break;
    }

    if(*pBuffer)    {
      /*  Should be at the start of a macro.
       */
      *ppMacro = pBuffer;
    }

    /*  Find the end of the macro for the return value.
     *  This is the end of a line which does not contain a backslash at the end.
     */
    while(*pBuffer) {
      if(*pBuffer == '\\')    {
          iBackslash++;
      }
      else if(*pBuffer == '\n')   {
          if(iBackslash == 0)  {
            pRetval = pBuffer + 1;
            break;
          }
          iBackslash = 0;
      }
      else if(!isspace(*pBuffer))  {
          iBackslash = 0;
      }

      pBuffer++;
    }

    return(pRetval);
}

int macro_length(char *pMacro)
{
    int iRetval = 0;

    if(pMacro == NULL)  {
      return(0);
    }

    /*  Length is no big deal.
     *  Problem is finding the end:
     *      whitespace
     *      '='
     */
    while(*pMacro)  {
      if(*pMacro == '=')  {
          break;
      }
      else if(isspace(*pMacro))   {
          break;
      }
      
      pMacro++;
      iRetval++;
    }

    return(iRetval);
}

int value_length(char *pValue)
{
    int iRetval = 0;

    if(pValue == NULL)  {
      return(0);
    }

    /*  Length is no big deal.
     *  Problem is finding the end:
     *      whitespace
     *      '\\'whitespace
     */
    while(*pValue)  {
      if(*pValue == '\\')  {
          char *pFindNewline = pValue + 1;
          /*  If whitespace to end of line, break here.
           */
          while(isspace(*pFindNewline))   {
            if(*pFindNewline == '\n')   {
                break;
            }
            pFindNewline++;
          }
          if(*pFindNewline == '\n')   {
            break;
          }
      }
      else if(isspace(*pValue))   {
          break;
      }
      
      pValue++;
      iRetval++;
    }

    return(iRetval);
}

char *skip_white(char *pString)
{
    if(pString == NULL) {
      return(NULL);
    }

    while(*pString && isspace(*pString)) {
      pString++;
    }

    return(pString);
}

void free_macro_list(macro_list *pList)
{
    macro_list *pFree = NULL;

    if(pList == NULL)   {
      return;
    }

    while(pList)    {
      pFree = pList;
      pList = pList->m_pNext;

      pFree->m_pNext = NULL;

      free_char_list(pFree->m_pValue);
      pFree->m_pValue = NULL;

      free(pFree->m_pMacro);
      pFree->m_pMacro = NULL;

      free(pFree);
      pFree = NULL;
    }
}

void free_char_list(char_list *pList)
{
    char_list *pFree = NULL;

    if(pList == NULL)   {
      return;
    }

    while(pList)    {
      pFree = pList;
      pList = pList->m_pNext;

      pFree->m_pNext = NULL;

      free(pFree->m_pString);
      pFree->m_pString = NULL;

      free(pFree);
      pFree = NULL;
    }
}

Generated by  Doxygen 1.6.0   Back to index