]> begriffs open source - sa-parse/blob - src/csv_parser.h
WIP: way more csv tests
[sa-parse] / src / csv_parser.h
1 #ifndef CSV_PARSER_H
2 #define CSV_PARSER_H
3
4 #include <stddef.h>
5 #include <stdio.h>
6 #include <stdbool.h>
7
8 /* Forward declarations */
9 typedef struct csv_parser csv_parser_t;
10 typedef struct csv_field csv_field_t;
11 typedef struct csv_record csv_record_t;
12 typedef struct csv_document csv_document_t;
13
14 /* Error codes */
15 typedef enum {
16     CSV_SUCCESS = 0,
17     CSV_ERROR_MEMORY = -1,
18     CSV_ERROR_PARSE = -2,
19     CSV_ERROR_INVALID_PARAM = -3,
20     CSV_ERROR_IO = -4
21 } csv_error_t;
22
23 /* Error information structure */
24 typedef struct {
25     const char *message;        /* Error message (valid until next parse operation) */
26     int line;                   /* Line number where error occurred (1-based, 0 if unknown) */
27     int column;                 /* Column number where error occurred (1-based, 0 if unknown) */
28     bool has_location;          /* Whether line/column information is available */
29 } csv_error_info_t;
30
31 /* CSV field structure */
32 struct csv_field {
33     char *content;              /* Field content (null-terminated) */
34     struct csv_field *next;     /* Next field in the record */
35 };
36
37 /* CSV record structure */
38 struct csv_record {
39     csv_field_t *fields;        /* Linked list of fields */
40     size_t field_count;         /* Number of fields in this record */
41     struct csv_record *next;    /* Next record in the document */
42 };
43
44 /* CSV document structure */
45 struct csv_document {
46     csv_record_t *records;      /* Linked list of records (excluding header) */
47     size_t record_count;        /* Number of data records (excluding header) */
48     csv_record_t *header;       /* Optional header record (can be NULL) */
49 };
50
51 /* Parser context (opaque) */
52 struct csv_parser;
53
54 /**
55  * Create a new CSV parser instance
56  * @return Parser instance or NULL on error
57  */
58 csv_parser_t *csv_parser_create(void);
59
60 /**
61  * Destroy a CSV parser instance and free all associated memory
62  * @param parser Parser instance to destroy (NULL is safe to pass)
63  */
64 void csv_parser_destroy(csv_parser_t *parser);
65
66 /**
67  * Parse CSV data from a string
68  * @param parser Parser instance (must not be NULL)
69  * @param input Input CSV string (null-terminated, must not be NULL)
70  * @param document Pointer to store the parsed document (must not be NULL)
71  * @return CSV_SUCCESS on success, error code on failure
72  * @note The parser will set *document to NULL on failure
73  */
74 csv_error_t csv_parser_parse_string(csv_parser_t *parser, const char *input, csv_document_t **document);
75
76 /**
77  * Parse CSV data from a file pointer
78  * @param parser Parser instance (must not be NULL)
79  * @param file Open file pointer (must not be NULL and readable)
80  * @param document Pointer to store the parsed document (must not be NULL)
81  * @return CSV_SUCCESS on success, error code on failure
82  * @note The parser will set *document to NULL on failure
83  * @note File position will be advanced to end of parsed content
84  */
85 csv_error_t csv_parser_parse_file(csv_parser_t *parser, FILE *file, csv_document_t **document);
86
87 /**
88  * Get detailed error information from the parser
89  * @param parser Parser instance (must not be NULL)
90  * @return Error information structure
91  * @note The returned message pointer is valid until the next parse operation
92  */
93 csv_error_info_t csv_parser_get_error_info(csv_parser_t *parser);
94
95 /**
96  * Free a CSV document and all associated memory
97  * @param document Document to free (NULL is safe to pass)
98  */
99 void csv_document_free(csv_document_t *document);
100
101 /**
102  * Convert error code to human-readable string
103  * @param error Error code
104  * @return Error description string
105  */
106 const char *csv_error_string(csv_error_t error);
107
108 /* Data access helper functions */
109
110 /**
111  * Check if document has a header record
112  * @param document CSV document (must not be NULL)
113  * @return true if header exists, false if not
114  */
115 bool csv_document_has_header(const csv_document_t *document);
116
117 /**
118  * Get the first record from document (skipping header if present)
119  * @param document CSV document (must not be NULL)
120  * @return First data record or NULL if empty
121  */
122 csv_record_t *csv_document_get_first_record(const csv_document_t *document);
123
124 /**
125  * Get the next record in sequence
126  * @param record Current record (must not be NULL)
127  * @return Next record or NULL if at end
128  */
129 csv_record_t *csv_record_get_next(const csv_record_t *record);
130
131 /**
132  * Get the first field from a record
133  * @param record CSV record (must not be NULL)
134  * @return First field or NULL if record is empty
135  */
136 csv_field_t *csv_record_get_first_field(const csv_record_t *record);
137
138 /**
139  * Get the next field in sequence
140  * @param field Current field (must not be NULL)
141  * @return Next field or NULL if at end
142  */
143 csv_field_t *csv_field_get_next(const csv_field_t *field);
144
145 /**
146  * Get field content as string
147  * @param field CSV field (must not be NULL)
148  * @return Field content string or NULL on error
149  */
150 const char *csv_field_get_content(const csv_field_t *field);
151
152 /**
153  * Set the first record as the header (moves it from records to header)
154  * @param document CSV document (must not be NULL and have at least one record)
155  * @return CSV_SUCCESS on success, error code on failure
156  */
157 csv_error_t csv_document_set_first_record_as_header(csv_document_t *document);
158
159 #endif /* CSV_PARSER_H */