Mstdlib-1.24.0

Typedefs

typedef struct M_csv M_csv_t
 
typedef M_bool(* M_csv_row_filter_cb) (const M_csv_t *csv, size_t row, void *thunk)
 
typedef M_bool(* M_csv_cell_writer_cb) (M_buf_t *buf, const char *cell, const char *header, void *thunk)
 

Enumerations

enum  M_CSV_FLAGS {
  M_CSV_FLAG_NONE = 0 ,
  M_CSV_FLAG_TRIM_WHITESPACE = 1 << 0
}
 

Functions

M_csv_tM_csv_parse (const char *data, size_t len, char delim, char quote, M_uint32 flags) M_MALLOC
 
M_csv_tM_csv_parse_add_headers (const char *data, size_t len, char delim, char quote, M_uint32 flags, M_list_str_t *headers)
 
M_csv_tM_csv_parse_inplace (char *data, size_t len, char delim, char quote, M_uint32 flags) M_MALLOC_ALIASED
 
void M_csv_destroy (M_csv_t *csv) M_FREE(1)
 
size_t M_csv_raw_num_rows (const M_csv_t *csv)
 
size_t M_csv_raw_num_cols (const M_csv_t *csv)
 
const char * M_csv_raw_cell (const M_csv_t *csv, size_t row, size_t col)
 
size_t M_csv_get_numrows (const M_csv_t *csv)
 
size_t M_csv_get_numcols (const M_csv_t *csv)
 
const char * M_csv_get_cellbynum (const M_csv_t *csv, size_t row, size_t col)
 
const char * M_csv_get_header (const M_csv_t *csv, size_t col)
 
const char * M_csv_get_cell (const M_csv_t *csv, size_t row, const char *colname)
 
ssize_t M_csv_get_cell_num (const M_csv_t *csv, const char *colname)
 
void M_csv_output_set_control_chars (M_csv_t *csv, char delim, char quote)
 
void M_csv_output_headers_buf (M_buf_t *buf, const M_csv_t *csv, M_list_str_t *headers)
 
void M_csv_output_rows_buf (M_buf_t *buf, const M_csv_t *csv, M_list_str_t *headers, M_csv_row_filter_cb filter_cb, void *filter_thunk, M_csv_cell_writer_cb writer_cb, void *writer_thunk)
 

Detailed Description

CSV Parser.

RFC 4180 compliant CSV parser.

The first row in the CSV is assumed to be the header. If there is no header the raw functions should be used to reterive data. If there is a header the non-raw functions should be used. These functions take into account the header when indexing rows automatically. The first row after the header is index 0.

Example:

const char *data = "header1,header1\ncell1,cell2"
M_csv_t *csv;
const char *const_temp;
csv = M_csv_parse(data, M_str_len(data), ',', '"', M_CSV_FLAG_NONE);
const_temp = M_csv_get_header(csv, 0);
M_printf("header='%s'\n", const_temp);
const_temp = M_csv_get_cellbynum(csv, 0, 1);
M_printf("cell='%s'\n", const_temp);
const char * M_csv_get_header(const M_csv_t *csv, size_t col)
void M_csv_destroy(M_csv_t *csv) M_FREE(1)
M_csv_t * M_csv_parse(const char *data, size_t len, char delim, char quote, M_uint32 flags) M_MALLOC
const char * M_csv_get_cellbynum(const M_csv_t *csv, size_t row, size_t col)
struct M_csv M_csv_t
Definition: m_csv.h:78
@ M_CSV_FLAG_NONE
Definition: m_csv.h:82
ssize_t M_printf(const char *fmt,...)
size_t M_str_len(const char *s) M_WARN_UNUSED_RESULT

Example output:

header='header1'
cell='cell2'

Typedef Documentation

◆ M_csv_t

typedef struct M_csv M_csv_t

◆ M_csv_row_filter_cb

typedef M_bool(* M_csv_row_filter_cb) (const M_csv_t *csv, size_t row, void *thunk)

Callback that can be used to filter rows from data returned by M_csv_output_rows_buf().

Parameters
[in]csvthe csv being output.
[in]rowthe idx of the current row being considered (NOT raw - 0 is the first row after the header).
[in]thunkpointer to thunk object passed into M_csv_output_rows_buf() by caller.
Returns
M_TRUE, if the row should be included in output. M_FALSE otherwise.

◆ M_csv_cell_writer_cb

typedef M_bool(* M_csv_cell_writer_cb) (M_buf_t *buf, const char *cell, const char *header, void *thunk)

Callback that can be used to edit data from certain columns as it's written out.

Parameters
[in]bufbuffer to write new version of cell data to.
[in]celloriginal cell data (may be empty/NULL, if cell was empty)
[in]headerheader of column this cell came from
[in]thunkpointer to thunk object passed into M_csv_output_rows_buf() by caller.
Returns
M_TRUE if we added a modified value to buf. M_FALSE if value was OK as-is.

Enumeration Type Documentation

◆ M_CSV_FLAGS

Flags controlling parse behavior

Enumerator
M_CSV_FLAG_NONE 

No Flags

M_CSV_FLAG_TRIM_WHITESPACE 

If a cell is not quoted, trim leading and trailing whitespace

Function Documentation

◆ M_csv_parse()

M_csv_t * M_csv_parse ( const char *  data,
size_t  len,
char  delim,
char  quote,
M_uint32  flags 
)

Parse a string into a CSV object.

Parameters
[in]dataThe data to parse.
[in]lenThe length of the data to parse.
[in]delimCSV delimiter character. Typically comma (",").
[in]quoteCSV quote character. Typically double quote (""").
[in]flagsFlags controlling parse behavior.
Returns
CSV object.
See also
M_csv_destroy

◆ M_csv_parse_add_headers()

M_csv_t * M_csv_parse_add_headers ( const char *  data,
size_t  len,
char  delim,
char  quote,
M_uint32  flags,
M_list_str_t headers 
)

Parse a string into a CSV object, using given column headers.

Same as M_csv_parse, but add the given headers as the first row before parsing the data into the table.

Parameters
[in]dataThe data to parse.
[in]lenThe length of data to parse.
[in]delimCSV delimiter character. Typically comma (',').
[in]quoteCSV quote character. Typically double quote ('"').
[in]flagsFlags controlling parse behavior.
[in]headersList of headers to add as first row of table.
Returns
CSV object

◆ M_csv_parse_inplace()

M_csv_t * M_csv_parse_inplace ( char *  data,
size_t  len,
char  delim,
char  quote,
M_uint32  flags 
)

Parse a string into a CSV object.

This will take ownership of the data passed in. The data must be valid for the life of the returned CSV object and will be destroyed by the CSV object when the CSV object is destroyed.

Parameters
[in]dataThe string to parse.
[in]lenThe length of the data to parse.
[in]delimCSV delimiter character. Typically comma (",").
[in]quoteCSV quote character. Typically double quote (""").
[in]flagsFlags controlling parse behavior.
Returns
CSV object.
See also
M_csv_destroy

◆ M_csv_destroy()

void M_csv_destroy ( M_csv_t csv)

Destory a CSV object.

Parameters
[in]csvThe csv.

◆ M_csv_raw_num_rows()

size_t M_csv_raw_num_rows ( const M_csv_t csv)

Get the raw number of csv rows.

This should be used when the CSV data does not contain a header. This count will include the header as a row in the count.

Parameters
[in]csvThe csv.
Returns
The number of rows including the header as a row.
See also
M_csv_get_numrows

◆ M_csv_raw_num_cols()

size_t M_csv_raw_num_cols ( const M_csv_t csv)

Get the raw number of csv columns.

This should be used when the CSV data does not contain a header.

Parameters
[in]csvThe csv.
Returns
The number of columns.
See also
M_csv_get_numcols

◆ M_csv_raw_cell()

const char * M_csv_raw_cell ( const M_csv_t csv,
size_t  row,
size_t  col 
)

Get the cell at the given position.

This should be used when the CSV data does not contain a header. This assumes that the first row is data (not the header).

Parameters
[in]csvThe csv.
[in]rowThe row. Indexed from 0 where 0 is the header (if there is a header).
[in]colThe column. Indexed from 0.
Returns
The csv data at the position or NULL if the position if invalid.
See also
M_csv_get_cellbynum

◆ M_csv_get_numrows()

size_t M_csv_get_numrows ( const M_csv_t csv)

Get the number of csv rows.

This should be used when the CSV data contains a header. This count will not include the header as a row in the count.

Parameters
[in]csvThe csv.
Returns
The number of rows excluding the header as a row.
See also
M_csv_raw_num_rows

◆ M_csv_get_numcols()

size_t M_csv_get_numcols ( const M_csv_t csv)

Get the raw number of csv columns.

This should be used when the CSV data contains a header.

Parameters
[in]csvThe csv.
Returns
The number of columns.
See also
M_csv_raw_num_cols

◆ M_csv_get_cellbynum()

const char * M_csv_get_cellbynum ( const M_csv_t csv,
size_t  row,
size_t  col 
)

Get the cell at the given position.

This should be used when the CSV data contains a header. This assumes that the first row is a header (not data).

Parameters
[in]csvThe csv.
[in]rowThe row. Indexed from 0 where 0 is the first row after the header.
[in]colThe column. Indexed from 0.
Returns
The csv data at the position or NULL if the position if invalid.
See also
M_csv_raw_cell

◆ M_csv_get_header()

const char * M_csv_get_header ( const M_csv_t csv,
size_t  col 
)

Get the header for a given column

This should be used when the CSV data contains a header. This assumes that the first row is a header (not data).

Parameters
[in]csvThe csv.
[in]colThe column. Indexed from 0.
Returns
The header for the given column.

◆ M_csv_get_cell()

const char * M_csv_get_cell ( const M_csv_t csv,
size_t  row,
const char *  colname 
)

Get the cell at the for the given header.

This should be used when the CSV data contains a header. This assumes that the first row is a header (not data).

Parameters
[in]csvThe csv.
[in]rowThe row. Indexed from 0 where 0 is the first row after the header.
[in]colnameThe column name to get the data from.
Returns
The csv data at the position or NULL if the position if invalid.

◆ M_csv_get_cell_num()

ssize_t M_csv_get_cell_num ( const M_csv_t csv,
const char *  colname 
)

Get the column number for a given column (header) name.

This should be used when the CSV data contains a header. This assumes that the first row is a header (not data).

Parameters
[in]csvThe csv.
[in]colnameThe column name to get the data from.
Returns
Column number for the given name on success. Otherwise -1.

◆ M_csv_output_set_control_chars()

void M_csv_output_set_control_chars ( M_csv_t csv,
char  delim,
char  quote 
)

Use different delim and quote characters for output than for parsing.

By default, M_csv_output_headers_buf() and M_csv_output_rows_buf() will use the same delimiter and quote characters that were used when parsing the data.

However, if you need to use a different delimiter and/or quote character in your output, call this function first to change them.

Parameters
csvThe csv.
delimdelimiter char to use in subsequent write operations
quotequote char to use in subsequent write operations

◆ M_csv_output_headers_buf()

void M_csv_output_headers_buf ( M_buf_t buf,
const M_csv_t csv,
M_list_str_t headers 
)

Write the header row, in CSV format.

When outputting CSV data, this should be called first, with the exact same list of headers that you'll be using later with M_csv_output_rows_buf().

If headers is NULL, all headers defined in the CSV data will be output, in the same order they were originally stored in.

See also
M_csv_output_rows_buf()
Parameters
[out]bufbuffer to place output in.
[in]csvthe CSV data to output.
[in]headersnames of columns to include in header row (will be written in this exact order).

◆ M_csv_output_rows_buf()

void M_csv_output_rows_buf ( M_buf_t buf,
const M_csv_t csv,
M_list_str_t headers,
M_csv_row_filter_cb  filter_cb,
void *  filter_thunk,
M_csv_cell_writer_cb  writer_cb,
void *  writer_thunk 
)

Write the parsed data to the given buffer, in CSV format.

If headers is not NULL, only the columns whose names match will be output, in the same order that the column headers are listed in headers. If there are names in headers which aren't present in the parsed CSV file, an empty value will be added for that column in every row.

A filter callback may be used to omit certain rows from the output. If no filter callback is provided, all rows will be output.

See also
M_csv_output_headers_buf()
Parameters
[out]bufbuffer to place output in
[in]csvthe CSV data to output.
[in]headersnames of columns to include in output (also controls column order).
[in]filter_cbcallback to control which rows are output (may be NULL).
[in]filter_thunkpointer to pass to filter_cb (may be NULL).
[in]writer_cbcallback to allow editing cell values (may be NULL).
[in]writer_thunkpointer to pass to writer_cb (may be NULL).