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.

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

mercurial