diff options
| author | Thomas Schmucker <ts@its1.de> | 2020-07-05 11:54:28 +0200 |
|---|---|---|
| committer | Thomas Schmucker <ts@its1.de> | 2020-07-05 11:54:28 +0200 |
| commit | db6807fd6644b1e129008ff9622384cef4e48654 (patch) | |
| tree | 1e7869a413caedcea433e051987df80bbb445403 | |
| parent | 12b36ad95dc633648b6c93d7626e17a0016b4547 (diff) | |
| download | libcsv-db6807fd6644b1e129008ff9622384cef4e48654.tar.gz libcsv-db6807fd6644b1e129008ff9622384cef4e48654.tar.bz2 libcsv-db6807fd6644b1e129008ff9622384cef4e48654.zip | |
Formatiere den Quellcode mit clang-format
| -rw-r--r-- | .clang-format | 45 | ||||
| -rw-r--r-- | csv-test.c | 496 | ||||
| -rw-r--r-- | csv.c | 108 | ||||
| -rw-r--r-- | csv.h | 26 |
4 files changed, 363 insertions, 312 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..b32bad6 --- /dev/null +++ b/.clang-format | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | --- | ||
| 2 | AccessModifierOffset: -4 | ||
| 3 | AlignConsecutiveAssignments: 'true' | ||
| 4 | AlignConsecutiveDeclarations: 'true' | ||
| 5 | AlignEscapedNewlines: Left | ||
| 6 | AlignTrailingComments: 'true' | ||
| 7 | AlwaysBreakAfterReturnType: TopLevelDefinitions | ||
| 8 | BreakBeforeBraces: Stroustrup | ||
| 9 | BreakConstructorInitializers: BeforeComma | ||
| 10 | BreakInheritanceList: BeforeComma | ||
| 11 | ColumnLimit: '0' | ||
| 12 | CompactNamespaces: 'false' | ||
| 13 | Cpp11BracedListStyle: 'false' | ||
| 14 | FixNamespaceComments: 'true' | ||
| 15 | IncludeBlocks: Regroup | ||
| 16 | IncludeCategories: | ||
| 17 | - Regex: '^.*(precomp|pch|stdafx)' | ||
| 18 | Priority: -1 | ||
| 19 | - Regex: '^<.*>' | ||
| 20 | Priority: 1 | ||
| 21 | - Regex: '^".*"' | ||
| 22 | Priority: 2 | ||
| 23 | - Regex: '.*' | ||
| 24 | Priority: 3 | ||
| 25 | IndentCaseLabels: 'false' | ||
| 26 | IndentPPDirectives: AfterHash | ||
| 27 | IndentWidth: '4' | ||
| 28 | IndentWrappedFunctionNames: 'false' | ||
| 29 | KeepEmptyLinesAtTheStartOfBlocks: 'false' | ||
| 30 | PointerAlignment: Right | ||
| 31 | SortIncludes: 'true' | ||
| 32 | SpaceAfterCStyleCast: 'true' | ||
| 33 | SpaceAfterTemplateKeyword: 'false' | ||
| 34 | SpaceBeforeAssignmentOperators: 'true' | ||
| 35 | SpaceBeforeParens: ControlStatements | ||
| 36 | SpaceBeforeRangeBasedForLoopColon: 'false' | ||
| 37 | SpaceInEmptyParentheses: 'false' | ||
| 38 | SpacesInAngles: 'false' | ||
| 39 | SpacesInCStyleCastParentheses: 'false' | ||
| 40 | SpacesInConditionalStatement: 'true' | ||
| 41 | SpacesInParentheses: 'false' | ||
| 42 | Standard: Auto | ||
| 43 | TabWidth: '4' | ||
| 44 | UseTab: ForIndentation | ||
| 45 | ... | ||
| @@ -1,19 +1,19 @@ | |||
| 1 | #undef NDEBUG | 1 | #undef NDEBUG |
| 2 | 2 | ||
| 3 | #include <assert.h> | ||
| 4 | #include <setjmp.h> | ||
| 3 | #include <stdio.h> | 5 | #include <stdio.h> |
| 4 | #include <stdlib.h> | 6 | #include <stdlib.h> |
| 5 | #include <string.h> | 7 | #include <string.h> |
| 6 | #include <assert.h> | ||
| 7 | #include <setjmp.h> | ||
| 8 | 8 | ||
| 9 | #include "csv.h" | 9 | #include "csv.h" |
| 10 | 10 | ||
| 11 | #define FMEMOPEN(f, data) \ | 11 | #define FMEMOPEN(f, data) \ |
| 12 | f = fmemopen(data, sizeof(data)-1, "r"); \ | 12 | f = fmemopen(data, sizeof(data) - 1, "r"); \ |
| 13 | assert(f != NULL) | 13 | assert(f != NULL) |
| 14 | 14 | ||
| 15 | #define FMEMCLOSE(f) \ | 15 | #define FMEMCLOSE(f) \ |
| 16 | fclose(f); \ | 16 | fclose(f); \ |
| 17 | f = NULL | 17 | f = NULL |
| 18 | 18 | ||
| 19 | void | 19 | void |
| @@ -21,13 +21,13 @@ test_empty_object(void) | |||
| 21 | { | 21 | { |
| 22 | { | 22 | { |
| 23 | csv_t csv = { 0 }; | 23 | csv_t csv = { 0 }; |
| 24 | assert( csv_nfields(&csv) == 0 ); | 24 | assert(csv_nfields(&csv) == 0); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | { | 27 | { |
| 28 | csv_t csv; | 28 | csv_t csv; |
| 29 | csv_init(&csv); | 29 | csv_init(&csv); |
| 30 | assert( csv_nfields(&csv) == 0 ); | 30 | assert(csv_nfields(&csv) == 0); |
| 31 | } | 31 | } |
| 32 | } | 32 | } |
| 33 | 33 | ||
| @@ -42,19 +42,19 @@ test_line_endings1(void) | |||
| 42 | 42 | ||
| 43 | FMEMOPEN(f, data); | 43 | FMEMOPEN(f, data); |
| 44 | 44 | ||
| 45 | assert( csv_read(&csv, f) == 3 ); | 45 | assert(csv_read(&csv, f) == 3); |
| 46 | assert( csv_nfields(&csv) == 3 ), | 46 | assert(csv_nfields(&csv) == 3); |
| 47 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 47 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 48 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 48 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 49 | assert( strcmp(csv_field(&csv, 2), "C") == 0 ); | 49 | assert(strcmp(csv_field(&csv, 2), "C") == 0); |
| 50 | 50 | ||
| 51 | assert( csv_read(&csv, f) == 3 ); | 51 | assert(csv_read(&csv, f) == 3); |
| 52 | assert( csv_nfields(&csv) == 3 ), | 52 | assert(csv_nfields(&csv) == 3); |
| 53 | assert( strcmp(csv_field(&csv, 0), "D") == 0 ); | 53 | assert(strcmp(csv_field(&csv, 0), "D") == 0); |
| 54 | assert( strcmp(csv_field(&csv, 1), "E") == 0 ); | 54 | assert(strcmp(csv_field(&csv, 1), "E") == 0); |
| 55 | assert( strcmp(csv_field(&csv, 2), "F") == 0 ); | 55 | assert(strcmp(csv_field(&csv, 2), "F") == 0); |
| 56 | 56 | ||
| 57 | assert( csv_read(&csv, f) == EOF ); | 57 | assert(csv_read(&csv, f) == EOF); |
| 58 | 58 | ||
| 59 | FMEMCLOSE(f); | 59 | FMEMCLOSE(f); |
| 60 | } | 60 | } |
| @@ -70,19 +70,19 @@ test_line_endings2(void) | |||
| 70 | 70 | ||
| 71 | FMEMOPEN(f, data); | 71 | FMEMOPEN(f, data); |
| 72 | 72 | ||
| 73 | assert( csv_read(&csv, f) == 3 ); | 73 | assert(csv_read(&csv, f) == 3); |
| 74 | assert( csv_nfields(&csv) == 3 ), | 74 | assert(csv_nfields(&csv) == 3); |
| 75 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 75 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 76 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 76 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 77 | assert( strcmp(csv_field(&csv, 2), "C") == 0 ); | 77 | assert(strcmp(csv_field(&csv, 2), "C") == 0); |
| 78 | 78 | ||
| 79 | assert( csv_read(&csv, f) == 3 ); | 79 | assert(csv_read(&csv, f) == 3); |
| 80 | assert( csv_nfields(&csv) == 3 ), | 80 | assert(csv_nfields(&csv) == 3); |
| 81 | assert( strcmp(csv_field(&csv, 0), "D") == 0 ); | 81 | assert(strcmp(csv_field(&csv, 0), "D") == 0); |
| 82 | assert( strcmp(csv_field(&csv, 1), "E") == 0 ); | 82 | assert(strcmp(csv_field(&csv, 1), "E") == 0); |
| 83 | assert( strcmp(csv_field(&csv, 2), "F") == 0 ); | 83 | assert(strcmp(csv_field(&csv, 2), "F") == 0); |
| 84 | 84 | ||
| 85 | assert( csv_read(&csv, f) == EOF ); | 85 | assert(csv_read(&csv, f) == EOF); |
| 86 | 86 | ||
| 87 | FMEMCLOSE(f); | 87 | FMEMCLOSE(f); |
| 88 | } | 88 | } |
| @@ -95,143 +95,143 @@ test_empty_fields(void) | |||
| 95 | 95 | ||
| 96 | char data[] = "\n" | 96 | char data[] = "\n" |
| 97 | "\r" | 97 | "\r" |
| 98 | "\r\n" | 98 | "\r\n" |
| 99 | "\"\"\n" | 99 | "\"\"\n" |
| 100 | "\"\"\r" | 100 | "\"\"\r" |
| 101 | "\"\"\r\n" | 101 | "\"\"\r\n" |
| 102 | ",\n" | 102 | ",\n" |
| 103 | ",\r" | 103 | ",\r" |
| 104 | ",\r\n" | 104 | ",\r\n" |
| 105 | "\"\",\"\"\n" | 105 | "\"\",\"\"\n" |
| 106 | "\"\",\"\"\r" | 106 | "\"\",\"\"\r" |
| 107 | "\"\",\"\"\r\n" | 107 | "\"\",\"\"\r\n" |
| 108 | ",,\n" | 108 | ",,\n" |
| 109 | ",,\r" | 109 | ",,\r" |
| 110 | ",,\r\n" | 110 | ",,\r\n" |
| 111 | "\"\",\"\",\n" | 111 | "\"\",\"\",\n" |
| 112 | "\"\",\"\",\r" | 112 | "\"\",\"\",\r" |
| 113 | "\"\",\"\",\r\n" | 113 | "\"\",\"\",\r\n" |
| 114 | ",,"; | 114 | ",,"; |
| 115 | 115 | ||
| 116 | FMEMOPEN(f, data); | 116 | FMEMOPEN(f, data); |
| 117 | 117 | ||
| 118 | // Line 1 | 118 | // Line 1 |
| 119 | assert( csv_read(&csv, f) == 1 ); | 119 | assert(csv_read(&csv, f) == 1); |
| 120 | assert( csv_nfields(&csv) == 1 ); | 120 | assert(csv_nfields(&csv) == 1); |
| 121 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 121 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 122 | 122 | ||
| 123 | // Line 2 | 123 | // Line 2 |
| 124 | assert( csv_read(&csv, f) == 1 ); | 124 | assert(csv_read(&csv, f) == 1); |
| 125 | assert( csv_nfields(&csv) == 1 ); | 125 | assert(csv_nfields(&csv) == 1); |
| 126 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 126 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 127 | 127 | ||
| 128 | // Line 3 | 128 | // Line 3 |
| 129 | assert( csv_read(&csv, f) == 1 ); | 129 | assert(csv_read(&csv, f) == 1); |
| 130 | assert( csv_nfields(&csv) == 1 ); | 130 | assert(csv_nfields(&csv) == 1); |
| 131 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 131 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 132 | 132 | ||
| 133 | // Line 4 | 133 | // Line 4 |
| 134 | assert( csv_read(&csv, f) == 1 ); | 134 | assert(csv_read(&csv, f) == 1); |
| 135 | assert( csv_nfields(&csv) == 1 ); | 135 | assert(csv_nfields(&csv) == 1); |
| 136 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 136 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 137 | 137 | ||
| 138 | // Line 5 | 138 | // Line 5 |
| 139 | assert( csv_read(&csv, f) == 1 ); | 139 | assert(csv_read(&csv, f) == 1); |
| 140 | assert( csv_nfields(&csv) == 1 ); | 140 | assert(csv_nfields(&csv) == 1); |
| 141 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 141 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 142 | 142 | ||
| 143 | // Line 6 | 143 | // Line 6 |
| 144 | assert( csv_read(&csv, f) == 1 ); | 144 | assert(csv_read(&csv, f) == 1); |
| 145 | assert( csv_nfields(&csv) == 1 ); | 145 | assert(csv_nfields(&csv) == 1); |
| 146 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 146 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 147 | 147 | ||
| 148 | // Line 7 | 148 | // Line 7 |
| 149 | assert( csv_read(&csv, f) == 2 ); | 149 | assert(csv_read(&csv, f) == 2); |
| 150 | assert( csv_nfields(&csv) == 2 ); | 150 | assert(csv_nfields(&csv) == 2); |
| 151 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 151 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 152 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 152 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 153 | 153 | ||
| 154 | // Line 8 | 154 | // Line 8 |
| 155 | assert( csv_read(&csv, f) == 2 ); | 155 | assert(csv_read(&csv, f) == 2); |
| 156 | assert( csv_nfields(&csv) == 2 ); | 156 | assert(csv_nfields(&csv) == 2); |
| 157 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 157 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 158 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 158 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 159 | 159 | ||
| 160 | // Line 9 | 160 | // Line 9 |
| 161 | assert( csv_read(&csv, f) == 2 ); | 161 | assert(csv_read(&csv, f) == 2); |
| 162 | assert( csv_nfields(&csv) == 2 ); | 162 | assert(csv_nfields(&csv) == 2); |
| 163 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 163 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 164 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 164 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 165 | 165 | ||
| 166 | // Line 10 | 166 | // Line 10 |
| 167 | assert( csv_read(&csv, f) == 2 ); | 167 | assert(csv_read(&csv, f) == 2); |
| 168 | assert( csv_nfields(&csv) == 2 ); | 168 | assert(csv_nfields(&csv) == 2); |
| 169 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 169 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 170 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 170 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 171 | 171 | ||
| 172 | // Line 11 | 172 | // Line 11 |
| 173 | assert( csv_read(&csv, f) == 2 ); | 173 | assert(csv_read(&csv, f) == 2); |
| 174 | assert( csv_nfields(&csv) == 2 ); | 174 | assert(csv_nfields(&csv) == 2); |
| 175 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 175 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 176 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 176 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 177 | 177 | ||
| 178 | // Line 12 | 178 | // Line 12 |
| 179 | assert( csv_read(&csv, f) == 2 ); | 179 | assert(csv_read(&csv, f) == 2); |
| 180 | assert( csv_nfields(&csv) == 2 ); | 180 | assert(csv_nfields(&csv) == 2); |
| 181 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 181 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 182 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 182 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 183 | 183 | ||
| 184 | // Line 13 | 184 | // Line 13 |
| 185 | assert( csv_read(&csv, f) == 3 ); | 185 | assert(csv_read(&csv, f) == 3); |
| 186 | assert( csv_nfields(&csv) == 3 ); | 186 | assert(csv_nfields(&csv) == 3); |
| 187 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 187 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 188 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 188 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 189 | assert( strcmp(csv_field(&csv, 2), "") == 0 ); | 189 | assert(strcmp(csv_field(&csv, 2), "") == 0); |
| 190 | 190 | ||
| 191 | // Line 14 | 191 | // Line 14 |
| 192 | assert( csv_read(&csv, f) == 3 ); | 192 | assert(csv_read(&csv, f) == 3); |
| 193 | assert( csv_nfields(&csv) == 3 ); | 193 | assert(csv_nfields(&csv) == 3); |
| 194 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 194 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 195 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 195 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 196 | assert( strcmp(csv_field(&csv, 2), "") == 0 ); | 196 | assert(strcmp(csv_field(&csv, 2), "") == 0); |
| 197 | 197 | ||
| 198 | // Line 15 | 198 | // Line 15 |
| 199 | assert( csv_read(&csv, f) == 3 ); | 199 | assert(csv_read(&csv, f) == 3); |
| 200 | assert( csv_nfields(&csv) == 3 ); | 200 | assert(csv_nfields(&csv) == 3); |
| 201 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 201 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 202 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 202 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 203 | assert( strcmp(csv_field(&csv, 2), "") == 0 ); | 203 | assert(strcmp(csv_field(&csv, 2), "") == 0); |
| 204 | 204 | ||
| 205 | // Line 16 | 205 | // Line 16 |
| 206 | assert( csv_read(&csv, f) == 3 ); | 206 | assert(csv_read(&csv, f) == 3); |
| 207 | assert( csv_nfields(&csv) == 3 ); | 207 | assert(csv_nfields(&csv) == 3); |
| 208 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 208 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 209 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 209 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 210 | assert( strcmp(csv_field(&csv, 2), "") == 0 ); | 210 | assert(strcmp(csv_field(&csv, 2), "") == 0); |
| 211 | 211 | ||
| 212 | // Line 17 | 212 | // Line 17 |
| 213 | assert( csv_read(&csv, f) == 3 ); | 213 | assert(csv_read(&csv, f) == 3); |
| 214 | assert( csv_nfields(&csv) == 3 ); | 214 | assert(csv_nfields(&csv) == 3); |
| 215 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 215 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 216 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 216 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 217 | assert( strcmp(csv_field(&csv, 2), "") == 0 ); | 217 | assert(strcmp(csv_field(&csv, 2), "") == 0); |
| 218 | 218 | ||
| 219 | // Line 18 | 219 | // Line 18 |
| 220 | assert( csv_read(&csv, f) == 3 ); | 220 | assert(csv_read(&csv, f) == 3); |
| 221 | assert( csv_nfields(&csv) == 3 ); | 221 | assert(csv_nfields(&csv) == 3); |
| 222 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 222 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 223 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 223 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 224 | assert( strcmp(csv_field(&csv, 2), "") == 0 ); | 224 | assert(strcmp(csv_field(&csv, 2), "") == 0); |
| 225 | 225 | ||
| 226 | // Line 19 | 226 | // Line 19 |
| 227 | assert( csv_read(&csv, f) == 3 ); | 227 | assert(csv_read(&csv, f) == 3); |
| 228 | assert( csv_nfields(&csv) == 3 ); | 228 | assert(csv_nfields(&csv) == 3); |
| 229 | assert( strcmp(csv_field(&csv, 0), "") == 0 ); | 229 | assert(strcmp(csv_field(&csv, 0), "") == 0); |
| 230 | assert( strcmp(csv_field(&csv, 1), "") == 0 ); | 230 | assert(strcmp(csv_field(&csv, 1), "") == 0); |
| 231 | assert( strcmp(csv_field(&csv, 2), "") == 0 ); | 231 | assert(strcmp(csv_field(&csv, 2), "") == 0); |
| 232 | 232 | ||
| 233 | // EOF | 233 | // EOF |
| 234 | assert( csv_read(&csv, f) == EOF ); | 234 | assert(csv_read(&csv, f) == EOF); |
| 235 | 235 | ||
| 236 | FMEMCLOSE(f); | 236 | FMEMCLOSE(f); |
| 237 | } | 237 | } |
| @@ -244,143 +244,143 @@ test_simple_fields(void) | |||
| 244 | 244 | ||
| 245 | char data[] = "A\n" | 245 | char data[] = "A\n" |
| 246 | "A\r" | 246 | "A\r" |
| 247 | "A\r\n" | 247 | "A\r\n" |
| 248 | "\"A\"\n" | 248 | "\"A\"\n" |
| 249 | "\"A\"\r" | 249 | "\"A\"\r" |
| 250 | "\"A\"\r\n" | 250 | "\"A\"\r\n" |
| 251 | "A,B\n" | 251 | "A,B\n" |
| 252 | "A,B\r" | 252 | "A,B\r" |
| 253 | "A,B\r\n" | 253 | "A,B\r\n" |
| 254 | "\"A\",\"B\"\n" | 254 | "\"A\",\"B\"\n" |
| 255 | "\"A\",\"B\"\r" | 255 | "\"A\",\"B\"\r" |
| 256 | "\"A\",\"B\"\r\n" | 256 | "\"A\",\"B\"\r\n" |
| 257 | "A,B,C\n" | 257 | "A,B,C\n" |
| 258 | "A,B,C\r" | 258 | "A,B,C\r" |
| 259 | "A,B,C\r\n" | 259 | "A,B,C\r\n" |
| 260 | "\"A\",\"B\",C\n" | 260 | "\"A\",\"B\",C\n" |
| 261 | "\"A\",\"B\",C\r" | 261 | "\"A\",\"B\",C\r" |
| 262 | "\"A\",\"B\",C\r\n" | 262 | "\"A\",\"B\",C\r\n" |
| 263 | "A,B,C"; | 263 | "A,B,C"; |
| 264 | 264 | ||
| 265 | FMEMOPEN(f, data); | 265 | FMEMOPEN(f, data); |
| 266 | 266 | ||
| 267 | // Line 1 | 267 | // Line 1 |
| 268 | assert( csv_read(&csv, f) == 1 ); | 268 | assert(csv_read(&csv, f) == 1); |
| 269 | assert( csv_nfields(&csv) == 1 ); | 269 | assert(csv_nfields(&csv) == 1); |
| 270 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 270 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 271 | 271 | ||
| 272 | // Line 2 | 272 | // Line 2 |
| 273 | assert( csv_read(&csv, f) == 1 ); | 273 | assert(csv_read(&csv, f) == 1); |
| 274 | assert( csv_nfields(&csv) == 1 ); | 274 | assert(csv_nfields(&csv) == 1); |
| 275 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 275 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 276 | 276 | ||
| 277 | // Line 3 | 277 | // Line 3 |
| 278 | assert( csv_read(&csv, f) == 1 ); | 278 | assert(csv_read(&csv, f) == 1); |
| 279 | assert( csv_nfields(&csv) == 1 ); | 279 | assert(csv_nfields(&csv) == 1); |
| 280 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 280 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 281 | 281 | ||
| 282 | // Line 4 | 282 | // Line 4 |
| 283 | assert( csv_read(&csv, f) == 1 ); | 283 | assert(csv_read(&csv, f) == 1); |
| 284 | assert( csv_nfields(&csv) == 1 ); | 284 | assert(csv_nfields(&csv) == 1); |
| 285 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 285 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 286 | 286 | ||
| 287 | // Line 5 | 287 | // Line 5 |
| 288 | assert( csv_read(&csv, f) == 1 ); | 288 | assert(csv_read(&csv, f) == 1); |
| 289 | assert( csv_nfields(&csv) == 1 ); | 289 | assert(csv_nfields(&csv) == 1); |
| 290 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 290 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 291 | 291 | ||
| 292 | // Line 6 | 292 | // Line 6 |
| 293 | assert( csv_read(&csv, f) == 1 ); | 293 | assert(csv_read(&csv, f) == 1); |
| 294 | assert( csv_nfields(&csv) == 1 ); | 294 | assert(csv_nfields(&csv) == 1); |
| 295 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 295 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 296 | 296 | ||
| 297 | // Line 7 | 297 | // Line 7 |
| 298 | assert( csv_read(&csv, f) == 2 ); | 298 | assert(csv_read(&csv, f) == 2); |
| 299 | assert( csv_nfields(&csv) == 2 ); | 299 | assert(csv_nfields(&csv) == 2); |
| 300 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 300 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 301 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 301 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 302 | 302 | ||
| 303 | // Line 8 | 303 | // Line 8 |
| 304 | assert( csv_read(&csv, f) == 2 ); | 304 | assert(csv_read(&csv, f) == 2); |
| 305 | assert( csv_nfields(&csv) == 2 ); | 305 | assert(csv_nfields(&csv) == 2); |
| 306 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 306 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 307 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 307 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 308 | 308 | ||
| 309 | // Line 9 | 309 | // Line 9 |
| 310 | assert( csv_read(&csv, f) == 2 ); | 310 | assert(csv_read(&csv, f) == 2); |
| 311 | assert( csv_nfields(&csv) == 2 ); | 311 | assert(csv_nfields(&csv) == 2); |
| 312 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 312 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 313 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 313 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 314 | 314 | ||
| 315 | // Line 10 | 315 | // Line 10 |
| 316 | assert( csv_read(&csv, f) == 2 ); | 316 | assert(csv_read(&csv, f) == 2); |
| 317 | assert( csv_nfields(&csv) == 2 ); | 317 | assert(csv_nfields(&csv) == 2); |
| 318 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 318 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 319 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 319 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 320 | 320 | ||
| 321 | // Line 11 | 321 | // Line 11 |
| 322 | assert( csv_read(&csv, f) == 2 ); | 322 | assert(csv_read(&csv, f) == 2); |
| 323 | assert( csv_nfields(&csv) == 2 ); | 323 | assert(csv_nfields(&csv) == 2); |
| 324 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 324 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 325 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 325 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 326 | 326 | ||
| 327 | // Line 12 | 327 | // Line 12 |
| 328 | assert( csv_read(&csv, f) == 2 ); | 328 | assert(csv_read(&csv, f) == 2); |
| 329 | assert( csv_nfields(&csv) == 2 ); | 329 | assert(csv_nfields(&csv) == 2); |
| 330 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 330 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 331 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 331 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 332 | 332 | ||
| 333 | // Line 13 | 333 | // Line 13 |
| 334 | assert( csv_read(&csv, f) == 3 ); | 334 | assert(csv_read(&csv, f) == 3); |
| 335 | assert( csv_nfields(&csv) == 3 ); | 335 | assert(csv_nfields(&csv) == 3); |
| 336 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 336 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 337 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 337 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 338 | assert( strcmp(csv_field(&csv, 2), "C") == 0 ); | 338 | assert(strcmp(csv_field(&csv, 2), "C") == 0); |
| 339 | 339 | ||
| 340 | // Line 14 | 340 | // Line 14 |
| 341 | assert( csv_read(&csv, f) == 3 ); | 341 | assert(csv_read(&csv, f) == 3); |
| 342 | assert( csv_nfields(&csv) == 3 ); | 342 | assert(csv_nfields(&csv) == 3); |
| 343 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 343 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 344 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 344 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 345 | assert( strcmp(csv_field(&csv, 2), "C") == 0 ); | 345 | assert(strcmp(csv_field(&csv, 2), "C") == 0); |
| 346 | 346 | ||
| 347 | // Line 15 | 347 | // Line 15 |
| 348 | assert( csv_read(&csv, f) == 3 ); | 348 | assert(csv_read(&csv, f) == 3); |
| 349 | assert( csv_nfields(&csv) == 3 ); | 349 | assert(csv_nfields(&csv) == 3); |
| 350 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 350 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 351 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 351 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 352 | assert( strcmp(csv_field(&csv, 2), "C") == 0 ); | 352 | assert(strcmp(csv_field(&csv, 2), "C") == 0); |
| 353 | 353 | ||
| 354 | // Line 16 | 354 | // Line 16 |
| 355 | assert( csv_read(&csv, f) == 3 ); | 355 | assert(csv_read(&csv, f) == 3); |
| 356 | assert( csv_nfields(&csv) == 3 ); | 356 | assert(csv_nfields(&csv) == 3); |
| 357 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 357 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 358 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 358 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 359 | assert( strcmp(csv_field(&csv, 2), "C") == 0 ); | 359 | assert(strcmp(csv_field(&csv, 2), "C") == 0); |
| 360 | 360 | ||
| 361 | // Line 17 | 361 | // Line 17 |
| 362 | assert( csv_read(&csv, f) == 3 ); | 362 | assert(csv_read(&csv, f) == 3); |
| 363 | assert( csv_nfields(&csv) == 3 ); | 363 | assert(csv_nfields(&csv) == 3); |
| 364 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 364 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 365 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 365 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 366 | assert( strcmp(csv_field(&csv, 2), "C") == 0 ); | 366 | assert(strcmp(csv_field(&csv, 2), "C") == 0); |
| 367 | 367 | ||
| 368 | // Line 18 | 368 | // Line 18 |
| 369 | assert( csv_read(&csv, f) == 3 ); | 369 | assert(csv_read(&csv, f) == 3); |
| 370 | assert( csv_nfields(&csv) == 3 ); | 370 | assert(csv_nfields(&csv) == 3); |
| 371 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 371 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 372 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 372 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 373 | assert( strcmp(csv_field(&csv, 2), "C") == 0 ); | 373 | assert(strcmp(csv_field(&csv, 2), "C") == 0); |
| 374 | 374 | ||
| 375 | // Line 19 | 375 | // Line 19 |
| 376 | assert( csv_read(&csv, f) == 3 ); | 376 | assert(csv_read(&csv, f) == 3); |
| 377 | assert( csv_nfields(&csv) == 3 ); | 377 | assert(csv_nfields(&csv) == 3); |
| 378 | assert( strcmp(csv_field(&csv, 0), "A") == 0 ); | 378 | assert(strcmp(csv_field(&csv, 0), "A") == 0); |
| 379 | assert( strcmp(csv_field(&csv, 1), "B") == 0 ); | 379 | assert(strcmp(csv_field(&csv, 1), "B") == 0); |
| 380 | assert( strcmp(csv_field(&csv, 2), "C") == 0 ); | 380 | assert(strcmp(csv_field(&csv, 2), "C") == 0); |
| 381 | 381 | ||
| 382 | // EOF | 382 | // EOF |
| 383 | assert( csv_read(&csv, f) == EOF ); | 383 | assert(csv_read(&csv, f) == EOF); |
| 384 | 384 | ||
| 385 | FMEMCLOSE(f); | 385 | FMEMCLOSE(f); |
| 386 | } | 386 | } |
| @@ -395,15 +395,15 @@ test_quoted_fields(void) | |||
| 395 | 395 | ||
| 396 | FMEMOPEN(f, data); | 396 | FMEMOPEN(f, data); |
| 397 | 397 | ||
| 398 | assert( csv_read(&csv, f) == 5 ); | 398 | assert(csv_read(&csv, f) == 5); |
| 399 | assert( csv_nfields(&csv) == 5 ), | 399 | assert(csv_nfields(&csv) == 5); |
| 400 | assert( strcmp(csv_field(&csv, 0), "foo \"baz\" bar") == 0 ); | 400 | assert(strcmp(csv_field(&csv, 0), "foo \"baz\" bar") == 0); |
| 401 | assert( strcmp(csv_field(&csv, 1), "foo \"\"baz\"\" bar") == 0 ); | 401 | assert(strcmp(csv_field(&csv, 1), "foo \"\"baz\"\" bar") == 0); |
| 402 | assert( strcmp(csv_field(&csv, 2), "foo \"baz\" bar") == 0 ); | 402 | assert(strcmp(csv_field(&csv, 2), "foo \"baz\" bar") == 0); |
| 403 | assert( strcmp(csv_field(&csv, 3), "foo \"baz\" bar") == 0 ); | 403 | assert(strcmp(csv_field(&csv, 3), "foo \"baz\" bar") == 0); |
| 404 | assert( strcmp(csv_field(&csv, 4), "foo \"baz\", bar") == 0 ); | 404 | assert(strcmp(csv_field(&csv, 4), "foo \"baz\", bar") == 0); |
| 405 | 405 | ||
| 406 | assert( csv_read(&csv, f) == EOF ); | 406 | assert(csv_read(&csv, f) == EOF); |
| 407 | 407 | ||
| 408 | FMEMCLOSE(f); | 408 | FMEMCLOSE(f); |
| 409 | } | 409 | } |
| @@ -418,11 +418,11 @@ test_wrong_quoted_field(void) | |||
| 418 | 418 | ||
| 419 | FMEMOPEN(f, data); | 419 | FMEMOPEN(f, data); |
| 420 | 420 | ||
| 421 | assert( csv_read(&csv, f) == 1 ); | 421 | assert(csv_read(&csv, f) == 1); |
| 422 | assert( csv_nfields(&csv) == 1 ), | 422 | assert(csv_nfields(&csv) == 1); |
| 423 | assert( strcmp(csv_field(&csv, 0), "foo") == 0 ); | 423 | assert(strcmp(csv_field(&csv, 0), "foo") == 0); |
| 424 | 424 | ||
| 425 | assert( csv_read(&csv, f) == EOF ); | 425 | assert(csv_read(&csv, f) == EOF); |
| 426 | 426 | ||
| 427 | FMEMCLOSE(f); | 427 | FMEMCLOSE(f); |
| 428 | } | 428 | } |
| @@ -436,26 +436,26 @@ cb_error(csv_err_t err, void *cb_arg) | |||
| 436 | void | 436 | void |
| 437 | test_out_of_range_error(void) | 437 | test_out_of_range_error(void) |
| 438 | { | 438 | { |
| 439 | jmp_buf env; | 439 | jmp_buf env; |
| 440 | csv_options_t csv_options = csv_default_options; | 440 | csv_options_t csv_options = csv_default_options; |
| 441 | csv_options.cb_error = cb_error; | 441 | csv_options.cb_error = cb_error; |
| 442 | csv_options.cb_error_arg = &env; | 442 | csv_options.cb_error_arg = &env; |
| 443 | 443 | ||
| 444 | csv_t csv; | 444 | csv_t csv; |
| 445 | csv_init_opt(&csv, &csv_options); | 445 | csv_init_opt(&csv, &csv_options); |
| 446 | 446 | ||
| 447 | FILE *f; | 447 | FILE *f; |
| 448 | char data[] = ","; | 448 | char data[] = ","; |
| 449 | 449 | ||
| 450 | FMEMOPEN(f, data); | 450 | FMEMOPEN(f, data); |
| 451 | 451 | ||
| 452 | switch ( setjmp(env) ) { | 452 | switch ( setjmp(env) ) { |
| 453 | case CSV_ERR_OK: | 453 | case CSV_ERR_OK: |
| 454 | assert( csv_read(&csv, f) == 2 ); | 454 | assert(csv_read(&csv, f) == 2); |
| 455 | assert( csv_nfields(&csv) == 2 ); | 455 | assert(csv_nfields(&csv) == 2); |
| 456 | 456 | ||
| 457 | // force an "out of range"-Exception! | 457 | // force an "out of range"-Exception! |
| 458 | assert( strcmp(csv_field(&csv, 2), "will fail") == 0 ); | 458 | assert(strcmp(csv_field(&csv, 2), "will fail") == 0); |
| 459 | break; | 459 | break; |
| 460 | 460 | ||
| 461 | case CSV_ERR_OUT_OF_RANGE: | 461 | case CSV_ERR_OUT_OF_RANGE: |
| @@ -472,21 +472,21 @@ test_out_of_range_error(void) | |||
| 472 | void | 472 | void |
| 473 | test_read_error(void) | 473 | test_read_error(void) |
| 474 | { | 474 | { |
| 475 | jmp_buf env; | 475 | jmp_buf env; |
| 476 | csv_options_t csv_options = csv_default_options; | 476 | csv_options_t csv_options = csv_default_options; |
| 477 | csv_options.cb_error = cb_error; | 477 | csv_options.cb_error = cb_error; |
| 478 | csv_options.cb_error_arg = &env; | 478 | csv_options.cb_error_arg = &env; |
| 479 | 479 | ||
| 480 | csv_t csv; | 480 | csv_t csv; |
| 481 | csv_init_opt(&csv, &csv_options); | 481 | csv_init_opt(&csv, &csv_options); |
| 482 | 482 | ||
| 483 | FILE *f = fopen("/dev/null", "r"); | 483 | FILE *f = fopen("/dev/null", "r"); |
| 484 | assert(f != NULL); | 484 | assert(f != NULL); |
| 485 | fputc('T', f); // Set Error-Flag! | 485 | fputc('T', f); // Set Error-Flag! |
| 486 | 486 | ||
| 487 | switch ( setjmp(env) ) { | 487 | switch ( setjmp(env) ) { |
| 488 | case CSV_ERR_OK: | 488 | case CSV_ERR_OK: |
| 489 | assert( csv_read(&csv, f) == EOF ); | 489 | assert(csv_read(&csv, f) == EOF); |
| 490 | break; | 490 | break; |
| 491 | 491 | ||
| 492 | case CSV_ERR_IO_READ: | 492 | case CSV_ERR_IO_READ: |
| @@ -546,11 +546,11 @@ test_allocation_error1(void) | |||
| 546 | jmp_buf env; | 546 | jmp_buf env; |
| 547 | 547 | ||
| 548 | csv_options_t csv_options = csv_default_options; | 548 | csv_options_t csv_options = csv_default_options; |
| 549 | csv_options.cb_error = cb_error; | 549 | csv_options.cb_error = cb_error; |
| 550 | csv_options.cb_error_arg = &env; | 550 | csv_options.cb_error_arg = &env; |
| 551 | csv_options.cb_allocate = my_allocate; | 551 | csv_options.cb_allocate = my_allocate; |
| 552 | csv_options.cb_reallocate = my_reallocate; | 552 | csv_options.cb_reallocate = my_reallocate; |
| 553 | csv_options.cb_free = my_free; | 553 | csv_options.cb_free = my_free; |
| 554 | 554 | ||
| 555 | csv_t csv; | 555 | csv_t csv; |
| 556 | csv_init_opt(&csv, &csv_options); | 556 | csv_init_opt(&csv, &csv_options); |
| @@ -563,7 +563,7 @@ test_allocation_error1(void) | |||
| 563 | 563 | ||
| 564 | switch ( setjmp(env) ) { | 564 | switch ( setjmp(env) ) { |
| 565 | case CSV_ERR_OK: | 565 | case CSV_ERR_OK: |
| 566 | assert( csv_read(&csv, f) == 20 ); | 566 | assert(csv_read(&csv, f) == 20); |
| 567 | assert(!"this should not be happen!"); | 567 | assert(!"this should not be happen!"); |
| 568 | break; | 568 | break; |
| 569 | 569 | ||
| @@ -1,29 +1,30 @@ | |||
| 1 | #include "csv.h" | ||
| 2 | |||
| 3 | #include <assert.h> | ||
| 1 | #include <stdio.h> | 4 | #include <stdio.h> |
| 2 | #include <stdlib.h> | 5 | #include <stdlib.h> |
| 3 | #include <assert.h> | ||
| 4 | #include <string.h> | 6 | #include <string.h> |
| 5 | #include "csv.h" | ||
| 6 | 7 | ||
| 7 | #ifndef CSV_DEFAULT_DELIMITER | 8 | #ifndef CSV_DEFAULT_DELIMITER |
| 8 | #define CSV_DEFAULT_DELIMITER '"' | 9 | # define CSV_DEFAULT_DELIMITER '"' |
| 9 | #endif | 10 | #endif |
| 10 | 11 | ||
| 11 | #ifndef CSV_DEFAULT_SEPARATOR | 12 | #ifndef CSV_DEFAULT_SEPARATOR |
| 12 | #define CSV_DEFAULT_SEPARATOR ',' | 13 | # define CSV_DEFAULT_SEPARATOR ',' |
| 13 | #endif | 14 | #endif |
| 14 | 15 | ||
| 15 | #if defined(__GNUC__) || defined(__clang__) | 16 | #if defined(__GNUC__) || defined(__clang__) |
| 16 | #define mul_overflow __builtin_mul_overflow | 17 | # define mul_overflow __builtin_mul_overflow |
| 17 | #else | 18 | #else |
| 18 | static inline int | 19 | static inline int |
| 19 | mul_overflow(size_t a, size_t b, size_t *out) | 20 | mul_overflow(size_t a, size_t b, size_t *out) |
| 20 | { | 21 | { |
| 21 | *out = a * b; | 22 | *out = a * b; |
| 22 | return ( a != 0 && (*out / a) != b ); | 23 | return (a != 0 && (*out / a) != b); |
| 23 | } | 24 | } |
| 24 | #endif | 25 | #endif |
| 25 | 26 | ||
| 26 | #define UNUSED(x) (void)(sizeof((x), 0)) | 27 | #define UNUSED(x) (void) (sizeof((x), 0)) |
| 27 | 28 | ||
| 28 | // === CSV-MEMORY Interface === | 29 | // === CSV-MEMORY Interface === |
| 29 | 30 | ||
| @@ -66,16 +67,16 @@ csv_mem_free(void *ptr, size_t n, size_t sz, void *cb_arg) | |||
| 66 | const csv_options_t csv_default_options = { | 67 | const csv_options_t csv_default_options = { |
| 67 | .field_delimiter = CSV_DEFAULT_DELIMITER, | 68 | .field_delimiter = CSV_DEFAULT_DELIMITER, |
| 68 | .field_separator = CSV_DEFAULT_SEPARATOR, | 69 | .field_separator = CSV_DEFAULT_SEPARATOR, |
| 69 | .cb_error = NULL, | 70 | .cb_error = NULL, |
| 70 | .cb_allocate = csv_mem_allocate, | 71 | .cb_allocate = csv_mem_allocate, |
| 71 | .cb_reallocate = csv_mem_reallocate, | 72 | .cb_reallocate = csv_mem_reallocate, |
| 72 | .cb_free = csv_mem_free | 73 | .cb_free = csv_mem_free |
| 73 | }; | 74 | }; |
| 74 | 75 | ||
| 75 | // === CSV-ERROR Interface === | 76 | // === CSV-ERROR Interface === |
| 76 | 77 | ||
| 77 | static void | 78 | static void |
| 78 | csv_fatal_error(csv_err_t csv_err, const csv_options_t * const csv_options) | 79 | csv_fatal_error(csv_err_t csv_err, const csv_options_t *const csv_options) |
| 79 | { | 80 | { |
| 80 | if ( csv_options->cb_error != NULL ) { | 81 | if ( csv_options->cb_error != NULL ) { |
| 81 | (*csv_options->cb_error)(csv_err, csv_options->cb_error_arg); | 82 | (*csv_options->cb_error)(csv_err, csv_options->cb_error_arg); |
| @@ -109,27 +110,27 @@ csv_string_empty(csv_string_t *csv_string) | |||
| 109 | { | 110 | { |
| 110 | assert(csv_string != NULL); | 111 | assert(csv_string != NULL); |
| 111 | 112 | ||
| 112 | return ( csv_string->pos == 0 ) ? 1 : 0; | 113 | return (csv_string->pos == 0) ? 1 : 0; |
| 113 | } | 114 | } |
| 114 | 115 | ||
| 115 | static inline void | 116 | static inline void |
| 116 | csv_string_append(csv_string_t *csv_string, char ch, const csv_options_t * const csv_options) | 117 | csv_string_append(csv_string_t *csv_string, char ch, const csv_options_t *const csv_options) |
| 117 | { | 118 | { |
| 118 | assert(csv_string != NULL); | 119 | assert(csv_string != NULL); |
| 119 | assert(csv_options != NULL); | 120 | assert(csv_options != NULL); |
| 120 | 121 | ||
| 121 | static const int INITIAL_CAP = 16; | 122 | static const int INITIAL_CAP = 16; |
| 122 | 123 | ||
| 123 | if ( csv_string->pos == csv_string->cap ) { // grow if needed | 124 | if ( csv_string->pos == csv_string->cap ) { // grow if needed |
| 124 | if ( csv_string->str == NULL ) { // first call? | 125 | if ( csv_string->str == NULL ) { // first call? |
| 125 | if ( (csv_string->str = csv_options->cb_allocate(INITIAL_CAP, 1, csv_options->cb_memory_arg)) == NULL ) { | 126 | if ( (csv_string->str = csv_options->cb_allocate(INITIAL_CAP, 1, csv_options->cb_memory_arg)) == NULL ) { |
| 126 | csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); | 127 | csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); |
| 127 | return; | 128 | return; |
| 128 | } | 129 | } |
| 129 | csv_string->cap = INITIAL_CAP; | 130 | csv_string->cap = INITIAL_CAP; |
| 130 | } | 131 | } |
| 131 | else { // subsequent call | 132 | else { // subsequent call |
| 132 | int cap = (csv_string->cap * 3) / 2; // *= 1.5 | 133 | int cap = (csv_string->cap * 3) / 2; // *= 1.5 |
| 133 | char *str = csv_options->cb_reallocate(csv_string->str, cap, 1, csv_options->cb_memory_arg); | 134 | char *str = csv_options->cb_reallocate(csv_string->str, cap, 1, csv_options->cb_memory_arg); |
| 134 | if ( str == NULL ) { | 135 | if ( str == NULL ) { |
| 135 | csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); | 136 | csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); |
| @@ -140,11 +141,11 @@ csv_string_append(csv_string_t *csv_string, char ch, const csv_options_t * const | |||
| 140 | } | 141 | } |
| 141 | } | 142 | } |
| 142 | 143 | ||
| 143 | csv_string->str[csv_string->pos++] = ch; // append char | 144 | csv_string->str[csv_string->pos++] = ch; // append char |
| 144 | } | 145 | } |
| 145 | 146 | ||
| 146 | static inline void | 147 | static inline void |
| 147 | csv_string_free(csv_string_t *csv_string, const csv_options_t * const csv_options) | 148 | csv_string_free(csv_string_t *csv_string, const csv_options_t *const csv_options) |
| 148 | { | 149 | { |
| 149 | assert(csv_string != NULL); | 150 | assert(csv_string != NULL); |
| 150 | assert(csv_options != NULL); | 151 | assert(csv_options != NULL); |
| @@ -163,8 +164,8 @@ csv_field_init(csv_field_t *csv_field) | |||
| 163 | assert(csv_field != NULL); | 164 | assert(csv_field != NULL); |
| 164 | 165 | ||
| 165 | csv_field->fields = NULL; | 166 | csv_field->fields = NULL; |
| 166 | csv_field->cap = 0; | 167 | csv_field->cap = 0; |
| 167 | csv_field->pos = 0; | 168 | csv_field->pos = 0; |
| 168 | } | 169 | } |
| 169 | 170 | ||
| 170 | static inline void | 171 | static inline void |
| @@ -176,30 +177,30 @@ csv_field_reset(csv_field_t *csv_field) | |||
| 176 | } | 177 | } |
| 177 | 178 | ||
| 178 | static inline void | 179 | static inline void |
| 179 | csv_field_append(csv_field_t *csv_field, int idx, const csv_options_t * const csv_options) | 180 | csv_field_append(csv_field_t *csv_field, int idx, const csv_options_t *const csv_options) |
| 180 | { | 181 | { |
| 181 | assert(csv_field != NULL); | 182 | assert(csv_field != NULL); |
| 182 | assert(csv_options != NULL); | 183 | assert(csv_options != NULL); |
| 183 | 184 | ||
| 184 | static const size_t INITIAL_CAP = 16; | 185 | static const size_t INITIAL_CAP = 16; |
| 185 | 186 | ||
| 186 | if ( csv_field->pos == csv_field->cap ) { // grow if needed | 187 | if ( csv_field->pos == csv_field->cap ) { // grow if needed |
| 187 | if ( csv_field->fields == NULL ) { // first call | 188 | if ( csv_field->fields == NULL ) { // first call |
| 188 | if ( (csv_field->fields = csv_options->cb_allocate(INITIAL_CAP, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg)) == NULL ) { | 189 | if ( (csv_field->fields = csv_options->cb_allocate(INITIAL_CAP, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg)) == NULL ) { |
| 189 | csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); | 190 | csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); |
| 190 | return; | 191 | return; |
| 191 | } | 192 | } |
| 192 | csv_field->cap = INITIAL_CAP; | 193 | csv_field->cap = INITIAL_CAP; |
| 193 | } | 194 | } |
| 194 | else { // subsequent call | 195 | else { // subsequent call |
| 195 | int cap = (csv_field->cap * 3) / 2; // *= 1.5 | 196 | int cap = (csv_field->cap * 3) / 2; // *= 1.5 |
| 196 | int *fields = csv_options->cb_reallocate(csv_field->fields, cap, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg); | 197 | int *fields = csv_options->cb_reallocate(csv_field->fields, cap, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg); |
| 197 | if ( fields == NULL ) { | 198 | if ( fields == NULL ) { |
| 198 | csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); | 199 | csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); |
| 199 | return; | 200 | return; |
| 200 | } | 201 | } |
| 201 | csv_field->fields = fields; | 202 | csv_field->fields = fields; |
| 202 | csv_field->cap = cap; | 203 | csv_field->cap = cap; |
| 203 | } | 204 | } |
| 204 | } | 205 | } |
| 205 | 206 | ||
| @@ -207,7 +208,7 @@ csv_field_append(csv_field_t *csv_field, int idx, const csv_options_t * const cs | |||
| 207 | } | 208 | } |
| 208 | 209 | ||
| 209 | static inline void | 210 | static inline void |
| 210 | csv_field_free(csv_field_t *csv_field, const csv_options_t * const csv_options) | 211 | csv_field_free(csv_field_t *csv_field, const csv_options_t *const csv_options) |
| 211 | { | 212 | { |
| 212 | assert(csv_field != NULL); | 213 | assert(csv_field != NULL); |
| 213 | assert(csv_options != NULL); | 214 | assert(csv_options != NULL); |
| @@ -228,7 +229,7 @@ csv_init(csv_t *csv) | |||
| 228 | } | 229 | } |
| 229 | 230 | ||
| 230 | void | 231 | void |
| 231 | csv_init_opt(csv_t *csv, const csv_options_t * const csv_options) | 232 | csv_init_opt(csv_t *csv, const csv_options_t *const csv_options) |
| 232 | { | 233 | { |
| 233 | assert(csv != NULL); | 234 | assert(csv != NULL); |
| 234 | 235 | ||
| @@ -255,7 +256,7 @@ csv_cleanup(csv_t *csv) | |||
| 255 | } | 256 | } |
| 256 | 257 | ||
| 257 | int | 258 | int |
| 258 | csv_nfields(const csv_t * const csv) | 259 | csv_nfields(const csv_t *const csv) |
| 259 | { | 260 | { |
| 260 | assert(csv != NULL); | 261 | assert(csv != NULL); |
| 261 | 262 | ||
| @@ -266,7 +267,7 @@ csv_nfields(const csv_t * const csv) | |||
| 266 | } | 267 | } |
| 267 | 268 | ||
| 268 | const char * | 269 | const char * |
| 269 | csv_field(const csv_t * const csv, int idx) | 270 | csv_field(const csv_t *const csv, int idx) |
| 270 | { | 271 | { |
| 271 | assert(csv != NULL); | 272 | assert(csv != NULL); |
| 272 | assert(idx >= 0 && idx < csv->csv_field.pos); | 273 | assert(idx >= 0 && idx < csv->csv_field.pos); |
| @@ -310,12 +311,12 @@ csv_read(csv_t *csv, FILE *in) | |||
| 310 | }; | 311 | }; |
| 311 | 312 | ||
| 312 | register const int DELIM = csv->csv_options->field_delimiter; | 313 | register const int DELIM = csv->csv_options->field_delimiter; |
| 313 | register const int SEP = csv->csv_options->field_separator; | 314 | register const int SEP = csv->csv_options->field_separator; |
| 314 | 315 | ||
| 315 | csv_string_reset(&csv->csv_string); | 316 | csv_string_reset(&csv->csv_string); |
| 316 | csv_field_reset(&csv->csv_field); | 317 | csv_field_reset(&csv->csv_field); |
| 317 | 318 | ||
| 318 | for ( int state = STATE_START_FIELD; ; ) { | 319 | for ( int state = STATE_START_FIELD;; ) { |
| 319 | int ch; | 320 | int ch; |
| 320 | 321 | ||
| 321 | switch ( state ) { | 322 | switch ( state ) { |
| @@ -326,9 +327,9 @@ csv_read(csv_t *csv, FILE *in) | |||
| 326 | if ( ch == EOF ) { | 327 | if ( ch == EOF ) { |
| 327 | state = STATE_END_FILE; | 328 | state = STATE_END_FILE; |
| 328 | } | 329 | } |
| 329 | else if ( ch == '\r' ) { // test for CR.. | 330 | else if ( ch == '\r' ) { // test for CR.. |
| 330 | ch = getc(in); | 331 | ch = getc(in); |
| 331 | if ( ch != '\n' ) { // ..LF | 332 | if ( ch != '\n' ) { // ..LF |
| 332 | ungetc(ch, in); | 333 | ungetc(ch, in); |
| 333 | } | 334 | } |
| 334 | state = STATE_END_LINE; | 335 | state = STATE_END_LINE; |
| @@ -379,7 +380,7 @@ csv_read(csv_t *csv, FILE *in) | |||
| 379 | } | 380 | } |
| 380 | else { | 381 | else { |
| 381 | csv_string_append(&csv->csv_string, DELIM, csv->csv_options); | 382 | csv_string_append(&csv->csv_string, DELIM, csv->csv_options); |
| 382 | ungetc(ch, in); // we have read too far... Put the character back! | 383 | ungetc(ch, in); // we have read too far... Put the character back! |
| 383 | } | 384 | } |
| 384 | } | 385 | } |
| 385 | else { | 386 | else { |
| @@ -434,7 +435,7 @@ csv_read(csv_t *csv, FILE *in) | |||
| 434 | 435 | ||
| 435 | if ( csv_string_empty(&csv->csv_string) ) { | 436 | if ( csv_string_empty(&csv->csv_string) ) { |
| 436 | csv_cleanup(csv); | 437 | csv_cleanup(csv); |
| 437 | return EOF; // EOF reached | 438 | return EOF; // EOF reached |
| 438 | } | 439 | } |
| 439 | 440 | ||
| 440 | /* | 441 | /* |
| @@ -458,18 +459,24 @@ const char * | |||
| 458 | csv_err_str(csv_err_t csv_err) | 459 | csv_err_str(csv_err_t csv_err) |
| 459 | { | 460 | { |
| 460 | switch ( csv_err ) { | 461 | switch ( csv_err ) { |
| 461 | case CSV_ERR_OK: return "no error"; | 462 | case CSV_ERR_OK: |
| 462 | case CSV_ERR_OUT_OF_MEMORY: return "out of memory"; | 463 | return "no error"; |
| 463 | case CSV_ERR_OUT_OF_RANGE: return "index out of range"; | 464 | case CSV_ERR_OUT_OF_MEMORY: |
| 464 | case CSV_ERR_IO_READ: return "read error"; | 465 | return "out of memory"; |
| 465 | case CSV_ERR_IO_WRITE: return "write error"; | 466 | case CSV_ERR_OUT_OF_RANGE: |
| 466 | default: return "unknown error"; | 467 | return "index out of range"; |
| 468 | case CSV_ERR_IO_READ: | ||
| 469 | return "read error"; | ||
| 470 | case CSV_ERR_IO_WRITE: | ||
| 471 | return "write error"; | ||
| 472 | default: | ||
| 473 | return "unknown error"; | ||
| 467 | } | 474 | } |
| 468 | // NOT REACHED | 475 | // NOT REACHED |
| 469 | } | 476 | } |
| 470 | 477 | ||
| 471 | static void | 478 | static void |
| 472 | csv_write_field(FILE *out, const char *field, const csv_options_t * const csv_options) | 479 | csv_write_field(FILE *out, const char *field, const csv_options_t *const csv_options) |
| 473 | { | 480 | { |
| 474 | assert(csv_options != NULL); | 481 | assert(csv_options != NULL); |
| 475 | assert(field != NULL); | 482 | assert(field != NULL); |
| @@ -499,7 +506,7 @@ csv_write_field(FILE *out, const char *field, const csv_options_t * const csv_op | |||
| 499 | } | 506 | } |
| 500 | 507 | ||
| 501 | void | 508 | void |
| 502 | csv_write(FILE *out, const csv_t * const csv) | 509 | csv_write(FILE *out, const csv_t *const csv) |
| 503 | { | 510 | { |
| 504 | assert(out != NULL); | 511 | assert(out != NULL); |
| 505 | assert(csv != NULL); | 512 | assert(csv != NULL); |
| @@ -510,8 +517,8 @@ csv_write(FILE *out, const csv_t * const csv) | |||
| 510 | register const int SEP = csv->csv_options->field_separator; | 517 | register const int SEP = csv->csv_options->field_separator; |
| 511 | 518 | ||
| 512 | if ( 0 < csv->csv_field.pos ) { | 519 | if ( 0 < csv->csv_field.pos ) { |
| 513 | const char *str = csv->csv_string.str; | 520 | const char *str = csv->csv_string.str; |
| 514 | const int *field = csv->csv_field.fields; | 521 | const int * field = csv->csv_field.fields; |
| 515 | 522 | ||
| 516 | csv_write_field(out, &str[*field++], csv->csv_options); | 523 | csv_write_field(out, &str[*field++], csv->csv_options); |
| 517 | 524 | ||
| @@ -529,7 +536,7 @@ csv_write(FILE *out, const csv_t * const csv) | |||
| 529 | } | 536 | } |
| 530 | 537 | ||
| 531 | void | 538 | void |
| 532 | csv_write_ex(FILE *out, int n, const char *fields[], const csv_options_t * csv_options) | 539 | csv_write_ex(FILE *out, int n, const char *fields[], const csv_options_t *csv_options) |
| 533 | { | 540 | { |
| 534 | assert(out != NULL); | 541 | assert(out != NULL); |
| 535 | assert(fields != NULL); | 542 | assert(fields != NULL); |
| @@ -558,4 +565,3 @@ csv_write_ex(FILE *out, int n, const char *fields[], const csv_options_t * csv_o | |||
| 558 | csv_fatal_error(CSV_ERR_IO_WRITE, csv_options); | 565 | csv_fatal_error(CSV_ERR_IO_WRITE, csv_options); |
| 559 | } | 566 | } |
| 560 | } | 567 | } |
| 561 | |||
| @@ -1,14 +1,14 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include <stdio.h> /* FILE */ | 3 | #include <stddef.h> /* size_t */ |
| 4 | #include <stddef.h> /* size_t */ | 4 | #include <stdio.h> /* FILE */ |
| 5 | 5 | ||
| 6 | #ifdef __cplusplus | 6 | #ifdef __cplusplus |
| 7 | extern "C" { | 7 | extern "C" { |
| 8 | #endif | 8 | #endif |
| 9 | 9 | ||
| 10 | typedef enum { | 10 | typedef enum { |
| 11 | CSV_ERR_OK = 0, | 11 | CSV_ERR_OK = 0, |
| 12 | CSV_ERR_OUT_OF_MEMORY = -1, | 12 | CSV_ERR_OUT_OF_MEMORY = -1, |
| 13 | CSV_ERR_OUT_OF_RANGE = -2, | 13 | CSV_ERR_OUT_OF_RANGE = -2, |
| 14 | CSV_ERR_IO_READ = -3, | 14 | CSV_ERR_IO_READ = -3, |
| @@ -32,23 +32,23 @@ extern const csv_options_t csv_default_options; | |||
| 32 | 32 | ||
| 33 | typedef struct { | 33 | typedef struct { |
| 34 | char *str; | 34 | char *str; |
| 35 | int cap, pos; | 35 | int cap, pos; |
| 36 | } csv_string_t; | 36 | } csv_string_t; |
| 37 | 37 | ||
| 38 | typedef struct { | 38 | typedef struct { |
| 39 | int *fields; | 39 | int *fields; |
| 40 | int cap, pos; | 40 | int cap, pos; |
| 41 | } csv_field_t; | 41 | } csv_field_t; |
| 42 | 42 | ||
| 43 | typedef struct { | 43 | typedef struct { |
| 44 | const csv_options_t *csv_options; | 44 | const csv_options_t *csv_options; |
| 45 | csv_string_t csv_string; | 45 | csv_string_t csv_string; |
| 46 | csv_field_t csv_field; | 46 | csv_field_t csv_field; |
| 47 | } csv_t; | 47 | } csv_t; |
| 48 | 48 | ||
| 49 | /* initialization */ | 49 | /* initialization */ |
| 50 | void csv_init(csv_t *csv); | 50 | void csv_init(csv_t *csv); |
| 51 | void csv_init_opt(csv_t *csv, const csv_options_t * const csv_options); | 51 | void csv_init_opt(csv_t *csv, const csv_options_t *const csv_options); |
| 52 | 52 | ||
| 53 | /* cleanup after error */ | 53 | /* cleanup after error */ |
| 54 | void csv_cleanup(csv_t *csv); | 54 | void csv_cleanup(csv_t *csv); |
| @@ -57,15 +57,15 @@ void csv_cleanup(csv_t *csv); | |||
| 57 | int csv_read(csv_t *csv, FILE *in); | 57 | int csv_read(csv_t *csv, FILE *in); |
| 58 | 58 | ||
| 59 | /* field access */ | 59 | /* field access */ |
| 60 | int csv_nfields(const csv_t * const csv); | 60 | int csv_nfields(const csv_t *const csv); |
| 61 | const char * csv_field(const csv_t * const csv, int idx); | 61 | const char *csv_field(const csv_t *const csv, int idx); |
| 62 | 62 | ||
| 63 | /* write */ | 63 | /* write */ |
| 64 | void csv_write(FILE *out, const csv_t * const csv); | 64 | void csv_write(FILE *out, const csv_t *const csv); |
| 65 | void csv_write_ex(FILE *out, int n, const char *fields[], const csv_options_t * const csv_options); | 65 | void csv_write_ex(FILE *out, int n, const char *fields[], const csv_options_t *const csv_options); |
| 66 | 66 | ||
| 67 | /* error handling */ | 67 | /* error handling */ |
| 68 | const char * csv_err_str(csv_err_t csv_err); | 68 | const char *csv_err_str(csv_err_t csv_err); |
| 69 | 69 | ||
| 70 | #ifdef __cplusplus | 70 | #ifdef __cplusplus |
| 71 | } | 71 | } |
