aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2025-04-13 22:43:46 +0200
committerThomas Schmucker <ts@its1.de>2025-04-13 22:43:46 +0200
commit7d956c533e9fd7d3bbb9a4a8b7f89f0fe54d4bc3 (patch)
treeea1c5bc19dfe6bacad2d377378c460ee5284e74e
parent85fe3b67a67825dfc5e43959f001b2a7159dc23f (diff)
downloadlibcsv-7d956c533e9fd7d3bbb9a4a8b7f89f0fe54d4bc3.tar.gz
libcsv-7d956c533e9fd7d3bbb9a4a8b7f89f0fe54d4bc3.tar.bz2
libcsv-7d956c533e9fd7d3bbb9a4a8b7f89f0fe54d4bc3.zip
first draft
-rw-r--r--.gitignore2
-rw-r--r--config.mk3
-rwxr-xr-xcontrib/csv-parser.py (renamed from csv-parser.py)0
-rwxr-xr-xcontrib/csv-parser.rb (renamed from csv-parser.rb)0
-rw-r--r--contrib/csv-perf.c (renamed from csv-perf.c)0
-rw-r--r--contrib/csv-tutorial.c (renamed from csv-tutorial.c)0
-rw-r--r--contrib/seq-read.c (renamed from seq-read.c)0
-rw-r--r--lib/.clang-format (renamed from .clang-format)0
-rw-r--r--lib/.clang-tidy (renamed from .clang-tidy)0
-rw-r--r--lib/compile_flags.txt8
-rw-r--r--lib/config.mk4
-rw-r--r--lib/makefile20
-rw-r--r--lib/src/csv.c74
-rw-r--r--makefile32
-rw-r--r--tests/.clang-format45
-rw-r--r--tests/.clang-tidy19
-rw-r--r--tests/compile_flags.txt8
-rw-r--r--tests/config.mk3
-rw-r--r--tests/makefile24
19 files changed, 180 insertions, 62 deletions
diff --git a/.gitignore b/.gitignore
index 287f41c..98d5016 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
1*.o 1*.o
2*.a
2*.csv 3*.csv
4build/
3 5
4csv-test 6csv-test
5csv-perf 7csv-perf
diff --git a/config.mk b/config.mk
deleted file mode 100644
index 3c8fd05..0000000
--- a/config.mk
+++ /dev/null
@@ -1,3 +0,0 @@
1CC=cc
2CFLAGS=-Wall -Wextra -Wsign-compare -Wsign-conversion -pedantic -std=c99 -O2
3CFLAGS-TEST=$(CFLAGS) -fsanitize=address -ggdb -fprofile-instr-generate -fcoverage-mapping
diff --git a/csv-parser.py b/contrib/csv-parser.py
index 9029321..9029321 100755
--- a/csv-parser.py
+++ b/contrib/csv-parser.py
diff --git a/csv-parser.rb b/contrib/csv-parser.rb
index aaac877..aaac877 100755
--- a/csv-parser.rb
+++ b/contrib/csv-parser.rb
diff --git a/csv-perf.c b/contrib/csv-perf.c
index 1c0f7a3..1c0f7a3 100644
--- a/csv-perf.c
+++ b/contrib/csv-perf.c
diff --git a/csv-tutorial.c b/contrib/csv-tutorial.c
index 9bdb7e6..9bdb7e6 100644
--- a/csv-tutorial.c
+++ b/contrib/csv-tutorial.c
diff --git a/seq-read.c b/contrib/seq-read.c
index 90d201f..90d201f 100644
--- a/seq-read.c
+++ b/contrib/seq-read.c
diff --git a/.clang-format b/lib/.clang-format
index b32bad6..b32bad6 100644
--- a/.clang-format
+++ b/lib/.clang-format
diff --git a/.clang-tidy b/lib/.clang-tidy
index 0bceb5b..0bceb5b 100644
--- a/.clang-tidy
+++ b/lib/.clang-tidy
diff --git a/lib/compile_flags.txt b/lib/compile_flags.txt
new file mode 100644
index 0000000..8b85c07
--- /dev/null
+++ b/lib/compile_flags.txt
@@ -0,0 +1,8 @@
1-Wall
2-Wextra
3-Wsign-compare
4-Wsign-conversion
5-pedantic
6-std=c99
7-O2
8-Iinclude
diff --git a/lib/config.mk b/lib/config.mk
new file mode 100644
index 0000000..6b4ff86
--- /dev/null
+++ b/lib/config.mk
@@ -0,0 +1,4 @@
1BUILD_DIR=../build
2ARFLAGS=rcs
3CFLAGS=-Wall -Wextra -Wsign-compare -Wsign-conversion -pedantic -std=c99 -O2 -Iinclude -DNDEBUG
4
diff --git a/lib/makefile b/lib/makefile
index e69de29..5c832ba 100644
--- a/lib/makefile
+++ b/lib/makefile
@@ -0,0 +1,20 @@
1include config.mk
2
3LIBRARY=$(BUILD_DIR)/libcsv.a
4OBJS=$(BUILD_DIR)/csv.o
5
6$(LIBRARY): $(OBJS)
7 ar $(ARFLAGS) $@ $(OBJS)
8
9$(BUILD_DIR)/%.o: src/%.c | $(BUILD_DIR)
10 cc $(CFLAGS) -c $< -o $@
11
12$(BUILD_DIR):
13 mkdir -p $@
14
15compile_flags.txt:
16 echo "$(CFLAGS)" | tr ' ' '\n' > $@
17
18.PHONY: clean
19clean:
20 rm -f $(LIBRARY) $(OBJS)
diff --git a/lib/src/csv.c b/lib/src/csv.c
index e9c7464..ba78dbd 100644
--- a/lib/src/csv.c
+++ b/lib/src/csv.c
@@ -305,35 +305,35 @@ csv_read(csv_t *csv, FILE *in)
305 csv_field_reset(&csv->csv_field); 305 csv_field_reset(&csv->csv_field);
306 306
307 for ( int state = STATE_START_FIELD;; ) { 307 for ( int state = STATE_START_FIELD;; ) {
308 int ch; 308 int chr;
309 309
310 switch ( state ) { 310 switch ( state ) {
311 case STATE_START_FIELD: 311 case STATE_START_FIELD:
312 csv_field_append(&csv->csv_field, csv->csv_string.pos, csv->csv_options); 312 csv_field_append(&csv->csv_field, csv->csv_string.pos, csv->csv_options);
313 313
314 ch = getc(in); 314 chr = getc(in);
315 if ( ch == EOF ) { 315 if ( chr == EOF ) {
316 state = STATE_END_FILE; 316 state = STATE_END_FILE;
317 } 317 }
318 else if ( ch == '\r' ) { // test for CR.. 318 else if ( chr == '\r' ) { // test for CR..
319 ch = getc(in); 319 chr = getc(in);
320 if ( ch != '\n' ) { // ..LF 320 if ( chr != '\n' ) { // ..LF
321 (void) ungetc(ch, in); 321 (void) ungetc(chr, in);
322 } 322 }
323 state = STATE_END_LINE; 323 state = STATE_END_LINE;
324 } 324 }
325 else if ( ch == '\n' ) { 325 else if ( chr == '\n' ) {
326 state = STATE_END_LINE; 326 state = STATE_END_LINE;
327 } 327 }
328 else if ( ch == SEP ) { 328 else if ( chr == SEP ) {
329 state = STATE_END_FIELD; 329 state = STATE_END_FIELD;
330 } 330 }
331 else if ( ch == DELIM ) { 331 else if ( chr == DELIM ) {
332 state = STATE_QUOTED_FIELD; 332 state = STATE_QUOTED_FIELD;
333 } 333 }
334 else { 334 else {
335 if ( ch != '\0' ) { 335 if ( chr != '\0' ) {
336 csv_string_append(&csv->csv_string, ch, csv->csv_options); 336 csv_string_append(&csv->csv_string, chr, csv->csv_options);
337 } 337 }
338 state = STATE_SIMPLE_FIELD; 338 state = STATE_SIMPLE_FIELD;
339 } 339 }
@@ -341,39 +341,39 @@ csv_read(csv_t *csv, FILE *in)
341 341
342 case STATE_QUOTED_FIELD: 342 case STATE_QUOTED_FIELD:
343 do { 343 do {
344 ch = getc(in); 344 chr = getc(in);
345 if ( ch == EOF ) { 345 if ( chr == EOF ) {
346 state = STATE_END_FILE; 346 state = STATE_END_FILE;
347 } 347 }
348 else if ( ch == DELIM ) { 348 else if ( chr == DELIM ) {
349 ch = getc(in); 349 chr = getc(in);
350 if ( ch == EOF ) { 350 if ( chr == EOF ) {
351 state = STATE_END_FILE; 351 state = STATE_END_FILE;
352 } 352 }
353 else if ( ch == DELIM ) { 353 else if ( chr == DELIM ) {
354 csv_string_append(&csv->csv_string, DELIM, csv->csv_options); 354 csv_string_append(&csv->csv_string, DELIM, csv->csv_options);
355 } 355 }
356 else if ( ch == SEP ) { 356 else if ( chr == SEP ) {
357 state = STATE_END_FIELD; 357 state = STATE_END_FIELD;
358 } 358 }
359 else if ( ch == '\r' ) { 359 else if ( chr == '\r' ) {
360 ch = getc(in); 360 chr = getc(in);
361 if ( ch != '\n' ) { 361 if ( chr != '\n' ) {
362 (void) ungetc(ch, in); 362 (void) ungetc(chr, in);
363 } 363 }
364 state = STATE_END_LINE; 364 state = STATE_END_LINE;
365 } 365 }
366 else if ( ch == '\n' ) { 366 else if ( chr == '\n' ) {
367 state = STATE_END_LINE; 367 state = STATE_END_LINE;
368 } 368 }
369 else { 369 else {
370 csv_string_append(&csv->csv_string, DELIM, csv->csv_options); 370 csv_string_append(&csv->csv_string, DELIM, csv->csv_options);
371 (void) ungetc(ch, in); // we have read too far... Put the character back! 371 (void) ungetc(chr, in); // we have read too far... Put the character back!
372 } 372 }
373 } 373 }
374 else { 374 else {
375 if ( ch != '\0' ) { 375 if ( chr != '\0' ) {
376 csv_string_append(&csv->csv_string, ch, csv->csv_options); 376 csv_string_append(&csv->csv_string, chr, csv->csv_options);
377 } 377 }
378 } 378 }
379 } while ( state == STATE_QUOTED_FIELD ); 379 } while ( state == STATE_QUOTED_FIELD );
@@ -381,26 +381,26 @@ csv_read(csv_t *csv, FILE *in)
381 381
382 case STATE_SIMPLE_FIELD: 382 case STATE_SIMPLE_FIELD:
383 do { 383 do {
384 ch = getc(in); 384 chr = getc(in);
385 if ( ch == EOF ) { 385 if ( chr == EOF ) {
386 state = STATE_END_FILE; 386 state = STATE_END_FILE;
387 } 387 }
388 else if ( ch == SEP ) { 388 else if ( chr == SEP ) {
389 state = STATE_END_FIELD; 389 state = STATE_END_FIELD;
390 } 390 }
391 else if ( ch == '\r' ) { 391 else if ( chr == '\r' ) {
392 ch = getc(in); 392 chr = getc(in);
393 if ( ch != '\n' ) { 393 if ( chr != '\n' ) {
394 (void) ungetc(ch, in); 394 (void) ungetc(chr, in);
395 } 395 }
396 state = STATE_END_LINE; 396 state = STATE_END_LINE;
397 } 397 }
398 else if ( ch == '\n' ) { 398 else if ( chr == '\n' ) {
399 state = STATE_END_LINE; 399 state = STATE_END_LINE;
400 } 400 }
401 else { 401 else {
402 if ( ch != '\0' ) { 402 if ( chr != '\0' ) {
403 csv_string_append(&csv->csv_string, ch, csv->csv_options); 403 csv_string_append(&csv->csv_string, chr, csv->csv_options);
404 } 404 }
405 } 405 }
406 } while ( state == STATE_SIMPLE_FIELD ); 406 } while ( state == STATE_SIMPLE_FIELD );
diff --git a/makefile b/makefile
index 5b850c7..db36c5c 100644
--- a/makefile
+++ b/makefile
@@ -1,28 +1,16 @@
1include config.mk 1.PHONY: all lib test tests clean
2 2
3all: csv-test csv-perf seq-read csv-tutorial 3all: lib
4 4
5csv-test: csv-test.c csv.c csv.h 5lib tests:
6 $(CC) $(CFLAGS-TEST) -DNDEBUG -o $@ csv-test.c csv.c 6 $(MAKE) -C $@
7 ./$@
8 7
9coverage: csv-test 8test: tests
10 llvm-profdata merge -sparse default.profraw -o csv-test.profdata 9 build/tester
11 llvm-cov show ./csv-test -instr-profile=csv-test.profdata
12
13csv-perf: csv-perf.c csv.o csv.h
14 $(CC) $(CFLAGS) -o $@ csv-perf.c csv.o
15
16seq-read: seq-read.c
17 $(CC) $(CFLAGS) -o $@ $<
18
19csv-tutorial: csv-tutorial.c csv.o csv.h
20 $(CC) $(CFLAGS) -o $@ csv-tutorial.c csv.o
21
22csv.o: csv.c csv.h
23 $(CC) $(CFLAGS) -DNDEBUG -o $@ -c $<
24 10
25clean: 11clean:
26 rm -f csv-test csv-perf seq-read csv.o csv-tutorial 12 $(MAKE) -C lib clean
13 $(MAKE) -C tests clean
14 rm -rf build
27 15
28.PHONY: all clean coverage 16# Testdaten: https://excelbianalytics.com/wp/downloads-18-sample-csv-files-data-sets-for-testing-sales/
diff --git a/tests/.clang-format b/tests/.clang-format
new file mode 100644
index 0000000..b32bad6
--- /dev/null
+++ b/tests/.clang-format
@@ -0,0 +1,45 @@
1---
2AccessModifierOffset: -4
3AlignConsecutiveAssignments: 'true'
4AlignConsecutiveDeclarations: 'true'
5AlignEscapedNewlines: Left
6AlignTrailingComments: 'true'
7AlwaysBreakAfterReturnType: TopLevelDefinitions
8BreakBeforeBraces: Stroustrup
9BreakConstructorInitializers: BeforeComma
10BreakInheritanceList: BeforeComma
11ColumnLimit: '0'
12CompactNamespaces: 'false'
13Cpp11BracedListStyle: 'false'
14FixNamespaceComments: 'true'
15IncludeBlocks: Regroup
16IncludeCategories:
17 - Regex: '^.*(precomp|pch|stdafx)'
18 Priority: -1
19 - Regex: '^<.*>'
20 Priority: 1
21 - Regex: '^".*"'
22 Priority: 2
23 - Regex: '.*'
24 Priority: 3
25IndentCaseLabels: 'false'
26IndentPPDirectives: AfterHash
27IndentWidth: '4'
28IndentWrappedFunctionNames: 'false'
29KeepEmptyLinesAtTheStartOfBlocks: 'false'
30PointerAlignment: Right
31SortIncludes: 'true'
32SpaceAfterCStyleCast: 'true'
33SpaceAfterTemplateKeyword: 'false'
34SpaceBeforeAssignmentOperators: 'true'
35SpaceBeforeParens: ControlStatements
36SpaceBeforeRangeBasedForLoopColon: 'false'
37SpaceInEmptyParentheses: 'false'
38SpacesInAngles: 'false'
39SpacesInCStyleCastParentheses: 'false'
40SpacesInConditionalStatement: 'true'
41SpacesInParentheses: 'false'
42Standard: Auto
43TabWidth: '4'
44UseTab: ForIndentation
45...
diff --git a/tests/.clang-tidy b/tests/.clang-tidy
new file mode 100644
index 0000000..0bceb5b
--- /dev/null
+++ b/tests/.clang-tidy
@@ -0,0 +1,19 @@
1---
2Checks: "*,
3 -abseil-*,
4 -altera-*,
5 -android-*,
6 -fuchsia-*,
7 -google-*,
8 -llvm*,
9 -modernize-use-trailing-return-type,
10 -zircon-*,
11 -readability-else-after-return,
12 -readability-static-accessed-through-instance,
13 -readability-avoid-const-params-in-decls,
14 -cppcoreguidelines-non-private-member-variables-in-classes,
15 -misc-non-private-member-variables-in-classes,
16"
17WarningsAsErrors: ''
18HeaderFilterRegex: ''
19FormatStyle: none
diff --git a/tests/compile_flags.txt b/tests/compile_flags.txt
new file mode 100644
index 0000000..9352ecc
--- /dev/null
+++ b/tests/compile_flags.txt
@@ -0,0 +1,8 @@
1-Wall
2-Wextra
3-Wsign-compare
4-Wsign-conversion
5-pedantic
6-std=c99
7-O2
8-I../lib/include
diff --git a/tests/config.mk b/tests/config.mk
new file mode 100644
index 0000000..4b51d37
--- /dev/null
+++ b/tests/config.mk
@@ -0,0 +1,3 @@
1BUILD_DIR=../build
2CFLAGS=-Wall -Wextra -Wsign-compare -Wsign-conversion -pedantic -std=c99 -O2 -I../lib/include
3LDFLAGS=-L$(BUILD_DIR) -lcsv
diff --git a/tests/makefile b/tests/makefile
index e69de29..2300a19 100644
--- a/tests/makefile
+++ b/tests/makefile
@@ -0,0 +1,24 @@
1include config.mk
2
3TEST_RUNNER=$(BUILD_DIR)/tester
4OBJS=$(BUILD_DIR)/csv-test.o
5
6$(TEST_RUNNER): $(OBJS) | libcsv
7 cc -o $@ $(LDFLAGS) $(OBJS)
8
9$(BUILD_DIR)/%.o: src/%.c | $(BUILD_DIR)
10 cc $(CFLAGS) -c $< -o $@
11
12$(BUILD_DIR):
13 mkdir -p $@
14
15.PHONY: libcsv
16libcsv:
17 $(MAKE) -C ../lib
18
19compile_flags.txt:
20 echo "$(CFLAGS)" | tr ' ' '\n' > $@
21
22.PHONY: clean
23clean:
24 rm -f $(TEST_RUNNER) $(OBJS)