
#ifndef _XTEND_DSV_H_
#define _XTEND_DSV_H_

#define DSV_DATA_OK             0
#define DSV_DATA_INVALID        -1      // Catch-all for non-specific error
#define DSV_DATA_OUT_OF_RANGE   -2

#define DSV_INIT                { 0, 0, NULL, NULL }
#define DSV_FIELD_MAX_CHARS     32767

#define DSV_FIELD(line,col)     ((line)->fields[col-1]) // 1-based column

typedef struct
{
    size_t      array_size,
		num_fields;
    char        **fields,
		*delims;
}   dsv_line_t;

/*
 *  Generated by /home/bacon/scripts/gen-get-set
 *
 *  Accessor macros.  Use these to access structure members from functions
 *  outside the dsv_line_t class.
 *
 *  These generated macros are not expected to be perfect.  Check and edit
 *  as needed before adding to your code.
 */

#define DSV_LINE_ARRAY_SIZE(ptr)        ((ptr)->array_size)
#define DSV_LINE_NUM_FIELDS(ptr)        ((ptr)->num_fields)
#define DSV_LINE_FIELDS(ptr)            ((ptr)->fields)
#define DSV_LINE_FIELDS_AE(ptr,c)       ((ptr)->fields[c])
#define DSV_LINE_DELIMS(ptr)            ((ptr)->delims)
#define DSV_LINE_DELIMS_AE(ptr,c)       ((ptr)->delims[c])

/*
 *  Generated by /home/bacon/scripts/gen-get-set
 *
 *  Mutator macros for setting with no sanity checking.  Use these to
 *  set structure members from functions outside the dsv_line_t
 *  class.  These macros perform no data validation.  Hence, they achieve
 *  maximum performance where data are guaranteed correct by other means.
 *  Use the mutator functions (same name as the macro, but lower case)
 *  for more robust code with a small performance penalty.
 *
 *  These generated macros are not expected to be perfect.  Check and edit
 *  as needed before adding to your code.
 */

#define DSV_LINE_SET_ARRAY_SIZE(ptr,val)        ((ptr)->array_size = (val))
#define DSV_LINE_SET_NUM_FIELDS(ptr,val)        ((ptr)->num_fields = (val))
#define DSV_LINE_SET_FIELDS(ptr,val)            ((ptr)->fields = (val))
#define DSV_LINE_SET_FIELDS_CPY(ptr,val,array_size) \
    for (size_t c = 0; c < (array_size); ++c) (ptr)->fields[c] = val[c];
#define DSV_LINE_SET_FIELDS_AE(ptr,c,val)       ((ptr)->fields[c] = (val))
#define DSV_LINE_SET_DELIMS(ptr,val)            ((ptr)->delims = (val))
#define DSV_LINE_SET_DELIMS_CPY(ptr,val,array_size) strlcpy((ptr)->delims,val,array_size)
#define DSV_LINE_SET_DELIMS_AE(ptr,c,val)       ((ptr)->delims[c] = (val))

/* dsv.c */                                                                     
int dsv_read_field(FILE *stream, char buff[], size_t buff_size, const char *delims, size_t *len);                                                               
int dsv_read_field_malloc(FILE *stream, char **buff, size_t *buff_size, const char *delims, size_t *len);                                                       
int dsv_skip_field(FILE *stream, const char *delims);                           
int dsv_skip_rest_of_line(FILE *stream);                                        
int dsv_read_line(FILE *stream, dsv_line_t *dsv_line, const char *delims);      
void dsv_write_line(FILE *stream, dsv_line_t *dsv_line);                        
void dsv_copy_line(dsv_line_t *dest, dsv_line_t *src);                          
void dsv_free_line(dsv_line_t *dsv_line);                                       
int tsv_read_field(FILE *stream, char buff[], size_t buff_size, size_t *len);   
int tsv_read_field_malloc(FILE *stream, char **buff, size_t *buff_size, size_t *len);                                                                           
int tsv_skip_field(FILE *stream);                                               
int tsv_skip_rest_of_line(FILE *stream);                                        
int csv_read_field(FILE *stream, char buff[], size_t buff_size, size_t *len);   
int csv_read_field_malloc(FILE *stream, char **buff, size_t *buff_size, size_t *len);                                                                           
int csv_skip_field(FILE *stream);                                               
int csv_skip_rest_of_line(FILE *stream);                                        
#endif  // _XTEND_DSV_H_/*
