]> begriffs open source - sa-parse/blob - src/csv_driver.c
WIP: implement API on top of CSV parser
[sa-parse] / src / csv_driver.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "csv_parser.h"
5
6 static void print_document(const csv_document_t *doc);
7 static void print_usage(const char *program_name);
8
9 int main(int argc, char *argv[])
10 {
11         csv_parser_t *parser = csv_parser_create();
12         if (!parser) {
13                 fprintf(stderr, "Error: Failed to create CSV parser\n");
14                 return 1;
15         }
16         
17         csv_document_t *document = NULL;
18         csv_error_t result;
19         bool has_header = false;
20         char *filename = NULL;
21         
22         /* Parse command line arguments */
23         for (int i = 1; i < argc; i++) {
24                 if (strcmp(argv[i], "--header") == 0 || strcmp(argv[i], "-h") == 0) {
25                         has_header = true;
26                 } else if (strcmp(argv[i], "--help") == 0) {
27                         print_usage(argv[0]);
28                         csv_parser_destroy(parser);
29                         return 0;
30                 } else if (argv[i][0] != '-') {
31                         filename = argv[i];
32                 } else {
33                         fprintf(stderr, "Error: Unknown option '%s'\n", argv[i]);
34                         print_usage(argv[0]);
35                         csv_parser_destroy(parser);
36                         return 1;
37                 }
38         }
39         
40         if (filename) {
41                 /* Parse file argument */
42                 FILE *file = fopen(filename, "r");
43                 if (!file) {
44                         fprintf(stderr, "Error: Cannot open file '%s'\n", filename);
45                         csv_parser_destroy(parser);
46                         return 1;
47                 }
48                 
49                 printf("Parsing CSV file: %s\n", filename);
50                 result = csv_parser_parse_file(parser, file, &document);
51                 fclose(file);
52         } else {
53                 /* Parse from stdin */
54                 printf("CSV Parser - Enter CSV data (Ctrl+D to end):\n");
55                 result = csv_parser_parse_file(parser, stdin, &document);
56         }
57         
58         if (result == CSV_SUCCESS) {
59                 /* If user specified header option, treat first record as header */
60                 if (has_header && document && document->records) {
61                         csv_error_t header_result = csv_document_set_first_record_as_header(document);
62                         if (header_result != CSV_SUCCESS) {
63                                 printf("Warning: Failed to set header: %s\n", csv_error_string(header_result));
64                         }
65                 }
66                 
67                 printf("Parsing completed successfully.\n");
68                 print_document(document);
69                 csv_document_free(document);
70         } else {
71                 printf("Parsing failed: %s\n", csv_error_string(result));
72                 printf("Error details: %s\n", csv_parser_get_error(parser));
73         }
74         
75         csv_parser_destroy(parser);
76         return result == CSV_SUCCESS ? 0 : 1;
77 }
78
79 static void print_document(const csv_document_t *doc)
80 {
81         if (!doc) {
82                 printf("Document is NULL\n");
83                 return;
84         }
85         
86         printf("\nDocument summary:\n");
87         printf("- Records: %zu\n", doc->record_count);
88         printf("- Has header: %s\n", csv_document_has_header(doc) ? "yes" : "no");
89         
90         /* Print header if present */
91         if (csv_document_has_header(doc)) {
92                 printf("\nHeader:\n");
93                 csv_field_t *field = csv_record_get_first_field(doc->header);
94                 int field_num = 1;
95                 while (field) {
96                         printf("  Field %d: '%s'\n", field_num++, csv_field_get_content(field));
97                         field = csv_field_get_next(field);
98                 }
99         }
100         
101         /* Print data records */
102         printf("\nData records:\n");
103         csv_record_t *record = csv_document_get_first_record(doc);
104         int record_num = 1;
105         
106         while (record) {
107                 printf("Record %d (%zu fields):\n", record_num++, record->field_count);
108                 
109                 csv_field_t *field = csv_record_get_first_field(record);
110                 int field_num = 1;
111                 while (field) {
112                         const char *content = csv_field_get_content(field);
113                         printf("  Field %d: '%s'\n", field_num++, content ? content : "");
114                         field = csv_field_get_next(field);
115                 }
116                 
117                 record = csv_record_get_next(record);
118         }
119 }
120
121 static void print_usage(const char *program_name)
122 {
123         printf("Usage: %s [options] [filename]\n", program_name);
124         printf("Options:\n");
125         printf("  -h, --header    Treat the first record as a header\n");
126         printf("  --help          Show this help message\n");
127         printf("\n");
128         printf("  If filename is provided, parse that file\n");
129         printf("  Otherwise, read from standard input\n");
130 }