1 /******************************************************************************
2 * Copyright (C) 2009-2012, International Business Machines
3 * Corporation and others. All Rights Reserved.
4 *******************************************************************************
7 #include "flagparser.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
);
20 * Opens the given fileName and reads in the information storing the data in flagBuffer.
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
;
30 FileStream
*f
= T_FileStream_open(fileName
, "r");
32 *status
= U_FILE_ACCESS_ERROR
;
37 *status
= U_MEMORY_ALLOCATION_ERROR
;
42 if (allocateMoreSpace
) {
43 allocateMoreSpace
= FALSE
;
44 currentBufferSize
*= 2;
46 buffer
= uprv_malloc(sizeof(char) * currentBufferSize
);
48 uprv_free(tmpFlagBuffer
);
49 *status
= U_MEMORY_ALLOCATION_ERROR
;
53 for (i
= 0; i
< numOfFlags
;) {
54 if (T_FileStream_readLine(f
, buffer
, currentBufferSize
) == NULL
) {
55 /* End of file reached. */
58 if (buffer
[0] == '#') {
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
);
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
;
77 if (flagNames
!= NULL
) {
79 uprv_strcpy(flagBuffer
[idx
], tmpFlagBuffer
);
81 /* No match found. Skip it. */
85 uprv_strcpy(flagBuffer
[i
++], tmpFlagBuffer
);
90 } while (allocateMoreSpace
&& U_SUCCESS(*status
));
92 uprv_free(tmpFlagBuffer
);
95 T_FileStream_close(f
);
97 if (U_SUCCESS(*status
) && result
== 0) {
98 currentBufferSize
= DEFAULT_BUFFER_SIZE
;
106 * Extract the setting after the '=' and store it in flag excluding the newline character.
108 static int32_t extractFlag(char* buffer
, int32_t bufferSize
, char* flag
, int32_t flagSize
, const char **flagNames
, int32_t numOfFlags
, UErrorCode
*status
) {
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
;
120 *status
= U_BUFFER_OVERFLOW_ERROR
;
123 if (pBuffer
[i
+1] == 0) {
124 /* Indicates a new line character. End here. */
129 flag
[i
] = pBuffer
[i
];
131 bufferWritten
= TRUE
;
136 if (!bufferWritten
) {
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) {
154 * Get the position after the '=' character.
156 static int32_t getFlagOffset(const char *buffer
, int32_t bufferSize
) {
159 for (offset
= 0; offset
< bufferSize
;offset
++) {
160 if (buffer
[offset
] == '=') {
166 if (offset
== bufferSize
|| (offset
- 1) == bufferSize
) {