intl/icu/source/tools/toolutil/flagparser.c

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /******************************************************************************
     2  *   Copyright (C) 2009-2012, International Business Machines
     3  *   Corporation and others.  All Rights Reserved.
     4  *******************************************************************************
     5  */
     7 #include "flagparser.h"
     8 #include "filestrm.h"
     9 #include "cstring.h"
    10 #include "cmemory.h"
    12 #define DEFAULT_BUFFER_SIZE 512
    14 static int32_t currentBufferSize = DEFAULT_BUFFER_SIZE;
    16 static int32_t extractFlag(char* buffer, int32_t bufferSize, char* flag, int32_t flagSize, const char ** flagNames, int32_t numOfFlags, UErrorCode *status);
    17 static int32_t getFlagOffset(const char *buffer, int32_t bufferSize);
    19 /*
    20  * Opens the given fileName and reads in the information storing the data in flagBuffer.
    21  */
    22 U_CAPI int32_t U_EXPORT2
    23 parseFlagsFile(const char *fileName, char **flagBuffer, int32_t flagBufferSize, const char ** flagNames, int32_t numOfFlags, UErrorCode *status) {
    24     char* buffer = uprv_malloc(sizeof(char) * currentBufferSize);
    25     char* tmpFlagBuffer = uprv_malloc(sizeof(char) * flagBufferSize);
    26     UBool allocateMoreSpace = FALSE;
    27     int32_t idx, i;
    28     int32_t result = 0;
    30     FileStream *f = T_FileStream_open(fileName, "r");
    31     if (f == NULL) {
    32         *status = U_FILE_ACCESS_ERROR;
    33         return -1;
    34     }
    36     if (buffer == NULL) {
    37         *status = U_MEMORY_ALLOCATION_ERROR;
    38         return -1;
    39     }
    41     do {
    42         if (allocateMoreSpace) {
    43             allocateMoreSpace = FALSE;
    44             currentBufferSize *= 2;
    45             uprv_free(buffer);
    46             buffer = uprv_malloc(sizeof(char) * currentBufferSize);
    47             if (buffer == NULL) {
    48                 uprv_free(tmpFlagBuffer);
    49                 *status = U_MEMORY_ALLOCATION_ERROR;
    50                 return -1;
    51             }
    52         }
    53         for (i = 0; i < numOfFlags;) {
    54             if (T_FileStream_readLine(f, buffer, currentBufferSize) == NULL) {
    55                 /* End of file reached. */
    56                 break;
    57             }
    58             if (buffer[0] == '#') {
    59                 continue;
    60             }
    62             if (uprv_strlen(buffer) == (currentBufferSize - 1) && buffer[currentBufferSize-2] != '\n') {
    63                 /* Allocate more space for buffer if it didnot read the entrire line */
    64                 allocateMoreSpace = TRUE;
    65                 T_FileStream_rewind(f);
    66                 break;
    67             } else {
    68                 idx = extractFlag(buffer, currentBufferSize, tmpFlagBuffer, flagBufferSize, flagNames, numOfFlags, status);
    69                 if (U_FAILURE(*status)) {
    70                     if (*status == U_BUFFER_OVERFLOW_ERROR) {
    71                         result = currentBufferSize;
    72                     } else {
    73                         result = -1;
    74                     }
    75                     break;
    76                 } else {
    77                     if (flagNames != NULL) {
    78                         if (idx >= 0) {
    79                             uprv_strcpy(flagBuffer[idx], tmpFlagBuffer);
    80                         } else {
    81                             /* No match found.  Skip it. */
    82                             continue;
    83                         }
    84                     } else {
    85                         uprv_strcpy(flagBuffer[i++], tmpFlagBuffer);
    86                     }
    87                 }
    88             }
    89         }
    90     } while (allocateMoreSpace && U_SUCCESS(*status));
    92     uprv_free(tmpFlagBuffer);
    93     uprv_free(buffer);
    95     T_FileStream_close(f);
    97     if (U_SUCCESS(*status) && result == 0) {
    98         currentBufferSize = DEFAULT_BUFFER_SIZE;
    99     }
   101     return result;
   102 }
   105 /*
   106  * Extract the setting after the '=' and store it in flag excluding the newline character.
   107  */
   108 static int32_t extractFlag(char* buffer, int32_t bufferSize, char* flag, int32_t flagSize, const char **flagNames, int32_t numOfFlags, UErrorCode *status) {
   109     int32_t i, idx = -1;
   110     char *pBuffer;
   111     int32_t offset=0;
   112     UBool bufferWritten = FALSE;
   114     if (buffer[0] != 0) {
   115         /* Get the offset (i.e. position after the '=') */
   116         offset = getFlagOffset(buffer, bufferSize);
   117         pBuffer = buffer+offset;
   118         for(i = 0;;i++) {
   119             if (i >= flagSize) {
   120                 *status = U_BUFFER_OVERFLOW_ERROR;
   121                 return -1;
   122             }
   123             if (pBuffer[i+1] == 0) {
   124                 /* Indicates a new line character. End here. */
   125                 flag[i] = 0;
   126                 break;
   127             }
   129             flag[i] = pBuffer[i];
   130             if (i == 0) {
   131                 bufferWritten = TRUE;
   132             }
   133         }
   134     }
   136     if (!bufferWritten) {
   137         flag[0] = 0;
   138     }
   140     if (flagNames != NULL && offset>0) {
   141         offset--;  /* Move offset back 1 because of '='*/
   142         for (i = 0; i < numOfFlags; i++) {
   143             if (uprv_strncmp(buffer, flagNames[i], offset) == 0) {
   144                 idx = i;
   145                 break;
   146             }
   147         }
   148     }
   150     return idx;
   151 }
   153 /*
   154  * Get the position after the '=' character.
   155  */
   156 static int32_t getFlagOffset(const char *buffer, int32_t bufferSize) {
   157     int32_t offset = 0;
   159     for (offset = 0; offset < bufferSize;offset++) {
   160         if (buffer[offset] == '=') {
   161             offset++;
   162             break;
   163         }
   164     }
   166     if (offset == bufferSize || (offset - 1) == bufferSize) {
   167         offset = 0;
   168     }
   170     return offset;
   171 }

mercurial