X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=lib%2Fcsv.c;h=e6a5eae2e2bba4306026e6de5c9f33643cb57943;hb=386dab78bce12d747375f9987aadb6d2bdf9ef38;hp=95e3e97768a8a7b5cc8f7925da3c9893e23e2efa;hpb=c0fee6efb6e3cff01f666b7bd06a479c9adb06ff;p=mirror_frr.git diff --git a/lib/csv.c b/lib/csv.c index 95e3e9776..e6a5eae2e 100644 --- a/lib/csv.c +++ b/lib/csv.c @@ -13,10 +13,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with Quagga; see the file COPYING. If not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -31,681 +30,667 @@ #define DEBUG_E 1 #define DEBUG_V 1 -#define log_error(fmt, ...) \ - do { if (DEBUG_E) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ - __LINE__, __func__, ##__VA_ARGS__); } while (0) +#define log_error(fmt, ...) \ + do { \ + if (DEBUG_E) \ + fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, ##__VA_ARGS__); \ + } while (0) -#define log_verbose(fmt, ...) \ - do { if (DEBUG_V) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ - __LINE__, __func__, __VA_ARGS__); } while (0) +#define log_verbose(fmt, ...) \ + do { \ + if (DEBUG_V) \ + fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); \ + } while (0) struct _csv_field_t_ { - TAILQ_ENTRY(_csv_field_t_) next_field; - char *field; - int field_len; + TAILQ_ENTRY(_csv_field_t_) next_field; + char *field; + int field_len; }; struct _csv_record_t_ { - TAILQ_HEAD(, _csv_field_t_) fields; - TAILQ_ENTRY(_csv_record_t_) next_record; - char *record; - int rec_len; + TAILQ_HEAD(, _csv_field_t_) fields; + TAILQ_ENTRY(_csv_record_t_) next_record; + char *record; + int rec_len; }; struct _csv_t_ { - TAILQ_HEAD(, _csv_record_t_) records; - char *buf; - int buflen; - int csv_len; - int pointer; - int num_recs; + TAILQ_HEAD(, _csv_record_t_) records; + char *buf; + int buflen; + int csv_len; + int pointer; + int num_recs; }; -int -csvlen (csv_t *csv) +int csvlen(csv_t *csv) { - return (csv->csv_len); + return (csv->csv_len); } -csv_t * -csv_init (csv_t *csv, - char *buf, - int buflen) +csv_t *csv_init(csv_t *csv, char *buf, int buflen) { - if (csv == NULL) { - csv = malloc(sizeof(csv_t)); - if (csv == NULL) { - log_error("CSV Malloc failed\n"); - return (NULL); - } - } - memset(csv, 0, sizeof(csv_t)); - - csv->buf = buf; - csv->buflen = buflen; - TAILQ_INIT(&(csv->records)); - return (csv); + if (csv == NULL) { + csv = malloc(sizeof(csv_t)); + if (csv == NULL) { + log_error("CSV Malloc failed\n"); + return (NULL); + } + } + memset(csv, 0, sizeof(csv_t)); + + csv->buf = buf; + csv->buflen = buflen; + TAILQ_INIT(&(csv->records)); + return (csv); } -void -csv_clean (csv_t *csv) +void csv_clean(csv_t *csv) { - csv_record_t *rec; - csv_record_t *rec_n; - - rec = TAILQ_FIRST(&(csv->records)); - while (rec != NULL) { - rec_n = TAILQ_NEXT(rec, next_record); - csv_remove_record(csv, rec); - rec = rec_n; - } + csv_record_t *rec; + csv_record_t *rec_n; + + rec = TAILQ_FIRST(&(csv->records)); + while (rec != NULL) { + rec_n = TAILQ_NEXT(rec, next_record); + csv_remove_record(csv, rec); + rec = rec_n; + } } -void -csv_free (csv_t *csv) +void csv_free(csv_t *csv) { - if (csv != NULL) { - free(csv); - } + if (csv != NULL) { + free(csv); + } } -static void -csv_init_record (csv_record_t *record) +static void csv_init_record(csv_record_t *record) { - TAILQ_INIT(&(record->fields)); - record->rec_len = 0; + TAILQ_INIT(&(record->fields)); + record->rec_len = 0; } -csv_record_t * -csv_record_iter (csv_t *csv) +csv_record_t *csv_record_iter(csv_t *csv) { - return(TAILQ_FIRST(&(csv->records))); + return (TAILQ_FIRST(&(csv->records))); } -csv_record_t * -csv_record_iter_next (csv_record_t *rec) +csv_record_t *csv_record_iter_next(csv_record_t *rec) { - if(!rec) return NULL; - return(TAILQ_NEXT(rec, next_record)); + if (!rec) + return NULL; + return (TAILQ_NEXT(rec, next_record)); } -char * -csv_field_iter (csv_record_t *rec, - csv_field_t **fld) +char *csv_field_iter(csv_record_t *rec, csv_field_t **fld) { - if(!rec) return NULL; - *fld = TAILQ_FIRST(&(rec->fields)); - return ((*fld)->field); + if (!rec) + return NULL; + *fld = TAILQ_FIRST(&(rec->fields)); + return ((*fld)->field); } -char * -csv_field_iter_next (csv_field_t **fld) +char *csv_field_iter_next(csv_field_t **fld) { - *fld = TAILQ_NEXT(*fld, next_field); - if ((*fld) == NULL) { - return (NULL); - } - return ((*fld)->field); + *fld = TAILQ_NEXT(*fld, next_field); + if ((*fld) == NULL) { + return (NULL); + } + return ((*fld)->field); } -int -csv_field_len(csv_field_t *fld) +int csv_field_len(csv_field_t *fld) { - if (fld) { - return fld->field_len; - } - return 0; + if (fld) { + return fld->field_len; + } + return 0; } -static void -csv_decode_record(csv_record_t *rec) +static void csv_decode_record(csv_record_t *rec) { - char *curr = rec->record; - char *field; - csv_field_t *fld; - - field = strpbrk(curr, ","); - while (field != NULL) { - fld = malloc(sizeof(csv_field_t)); - if (fld) { - TAILQ_INSERT_TAIL(&(rec->fields), fld, next_field); - fld->field = curr; - fld->field_len = field-curr; - } - curr = field + 1; - field = strpbrk(curr, ","); - } - field = strstr(curr, "\n"); - if (!field) { - return; - } - fld = malloc(sizeof(csv_field_t)); - if (field && fld) { - fld->field = curr; - fld->field_len = field-curr; - TAILQ_INSERT_TAIL(&(rec->fields), fld, next_field); - } + char *curr = rec->record; + char *field; + csv_field_t *fld; + + field = strpbrk(curr, ","); + while (field != NULL) { + fld = malloc(sizeof(csv_field_t)); + if (fld) { + TAILQ_INSERT_TAIL(&(rec->fields), fld, next_field); + fld->field = curr; + fld->field_len = field - curr; + } + curr = field + 1; + field = strpbrk(curr, ","); + } + field = strstr(curr, "\n"); + if (!field) + return; + + fld = malloc(sizeof(csv_field_t)); + if (fld) { + fld->field = curr; + fld->field_len = field - curr; + TAILQ_INSERT_TAIL(&(rec->fields), fld, next_field); + } } -static csv_field_t * -csv_add_field_to_record(csv_t *csv, - csv_record_t *rec, - char *col) +static csv_field_t *csv_add_field_to_record(csv_t *csv, csv_record_t *rec, + char *col) { - csv_field_t *fld; - char *str = rec->record; - int rlen = rec->rec_len; - int blen = csv->buflen; - - fld = malloc(sizeof(csv_field_t)); - if (!fld) { - log_error("field malloc failed\n"); - /* more cleanup needed */ - return (NULL); - } - TAILQ_INSERT_TAIL(&(rec->fields), fld, next_field); - fld->field = str+rlen; - fld->field_len = snprintf((str+rlen), (blen - rlen), "%s", col); - rlen += fld->field_len; - rec->rec_len = rlen; - return fld; + csv_field_t *fld; + char *str = rec->record; + int rlen = rec->rec_len; + int blen = csv->buflen; + + fld = malloc(sizeof(csv_field_t)); + if (!fld) { + log_error("field malloc failed\n"); + /* more cleanup needed */ + return (NULL); + } + TAILQ_INSERT_TAIL(&(rec->fields), fld, next_field); + fld->field = str + rlen; + fld->field_len = snprintf((str + rlen), (blen - rlen), "%s", col); + rlen += fld->field_len; + rec->rec_len = rlen; + return fld; } -csv_record_t * -csv_encode (csv_t *csv, - int count, - ...) +csv_record_t *csv_encode(csv_t *csv, int count, ...) { - int tempc; - va_list list; - char *buf = csv->buf; - int len = csv->buflen; - int pointer = csv->pointer; - char *str = NULL; - char *col; - csv_record_t *rec; - csv_field_t *fld; - - if (buf) { - str = buf + pointer; - } else { - /* allocate sufficient buffer */ - str = (char *)malloc(csv->buflen); - if (!str) { - log_error("field str malloc failed\n"); - return (NULL); - } - } - - va_start(list, count); - rec = malloc(sizeof(csv_record_t)); - if (!rec) { - log_error("record malloc failed\n"); - if (!buf) { - free(str); - } - va_end(list); - return (NULL); - } - csv_init_record(rec); - rec->record = str; - TAILQ_INSERT_TAIL(&(csv->records), rec, next_record); - csv->num_recs++; - - /** - * Iterate through the fields passed as a variable list and add them - */ - for (tempc = 0; tempc < count; tempc++) { - col = va_arg(list, char *); - fld = csv_add_field_to_record(csv, rec, col); - if (!fld) { - log_error("fld malloc failed\n"); - csv_remove_record(csv, rec); - return (NULL); - } - if (tempc < (count - 1)) { - rec->rec_len += snprintf((str+rec->rec_len), (len - rec->rec_len), ","); - } - } - rec->rec_len += snprintf((str+rec->rec_len), (len - rec->rec_len), "\n"); - va_end(list); - csv->csv_len += rec->rec_len; - csv->pointer += rec->rec_len; - return (rec); + int tempc; + va_list list; + char *buf = csv->buf; + int len = csv->buflen; + int pointer = csv->pointer; + char *str = NULL; + char *col; + csv_record_t *rec; + csv_field_t *fld; + + if (buf) { + str = buf + pointer; + } else { + /* allocate sufficient buffer */ + str = (char *)malloc(csv->buflen); + if (!str) { + log_error("field str malloc failed\n"); + return (NULL); + } + } + + va_start(list, count); + rec = malloc(sizeof(csv_record_t)); + if (!rec) { + log_error("record malloc failed\n"); + if (!buf) + free(str); + va_end(list); + return (NULL); + } + csv_init_record(rec); + rec->record = str; + TAILQ_INSERT_TAIL(&(csv->records), rec, next_record); + csv->num_recs++; + + /** + * Iterate through the fields passed as a variable list and add them + */ + for (tempc = 0; tempc < count; tempc++) { + col = va_arg(list, char *); + fld = csv_add_field_to_record(csv, rec, col); + if (!fld) { + log_error("fld malloc failed\n"); + csv_remove_record(csv, rec); + va_end(list); + return (NULL); + } + if (tempc < (count - 1)) { + rec->rec_len += snprintf((str + rec->rec_len), + (len - rec->rec_len), ","); + } + } + rec->rec_len += + snprintf((str + rec->rec_len), (len - rec->rec_len), "\n"); + va_end(list); + csv->csv_len += rec->rec_len; + csv->pointer += rec->rec_len; + return (rec); } -int -csv_num_records (csv_t *csv) +int csv_num_records(csv_t *csv) { - if (csv) { - return csv->num_recs; - } - return 0; + if (csv) { + return csv->num_recs; + } + return 0; } -csv_record_t * -csv_encode_record (csv_t *csv, - csv_record_t *rec, - int count, - ...) +csv_record_t *csv_encode_record(csv_t *csv, csv_record_t *rec, int count, ...) { - int tempc; - va_list list; - char *str; - char *col; - csv_field_t *fld = NULL; - int i; - - va_start(list, count); - str = csv_field_iter(rec, &fld); - for (tempc = 0; tempc < count; tempc++) { - col = va_arg(list, char *); - for (i = 0; i < fld->field_len; i++) { - str[i] = col[i]; - } - str = csv_field_iter_next(&fld); - } - va_end(list); - return (rec); + int tempc; + va_list list; + char *str; + char *col; + csv_field_t *fld = NULL; + int i; + + va_start(list, count); + str = csv_field_iter(rec, &fld); + if (!fld) { + va_end(list); + return NULL; + } + + for (tempc = 0; tempc < count; tempc++) { + col = va_arg(list, char *); + for (i = 0; i < fld->field_len; i++) { + str[i] = col[i]; + } + str = csv_field_iter_next(&fld); + } + va_end(list); + return (rec); } -csv_record_t * -csv_append_record (csv_t *csv, - csv_record_t *rec, - int count, - ...) +csv_record_t *csv_append_record(csv_t *csv, csv_record_t *rec, int count, ...) { - int tempc; - va_list list; - int len = csv->buflen, tlen; - char *str; - csv_field_t *fld; - char *col; - - if (csv->buf) { - /* not only works with discrete bufs */ - return NULL; - } - - if (!rec) { - /* create a new rec */ - rec = calloc(1, sizeof(csv_record_t)); - if (!rec) { - log_error("record malloc failed\n"); - return NULL; - } - csv_init_record(rec); - rec->record = calloc(1, csv->buflen); - if (!rec->record) { - log_error("field str malloc failed\n"); - free(rec); - return NULL; - } - csv_insert_record(csv, rec); - } - - str = rec->record; - - va_start(list, count); - - if (rec->rec_len && (str[rec->rec_len-1] == '\n')) - str[rec->rec_len-1] = ','; - - /** - * Iterate through the fields passed as a variable list and add them - */ - tlen = rec->rec_len; - for (tempc = 0; tempc < count; tempc++) { - col = va_arg(list, char *); - fld = csv_add_field_to_record(csv, rec, col); - if (!fld) { - log_error("fld malloc failed\n"); - break; - } - if (tempc < (count - 1)) { - rec->rec_len += snprintf((str+rec->rec_len), - (len - rec->rec_len), ","); - } - } - rec->rec_len += snprintf((str+rec->rec_len), - (len - rec->rec_len), "\n"); - va_end(list); - csv->csv_len += (rec->rec_len - tlen); - csv->pointer += (rec->rec_len - tlen); - return (rec); + int tempc; + va_list list; + int len = csv->buflen, tlen; + char *str; + csv_field_t *fld; + char *col; + + if (csv->buf) { + /* not only works with discrete bufs */ + return NULL; + } + + if (!rec) { + /* create a new rec */ + rec = calloc(1, sizeof(csv_record_t)); + if (!rec) { + log_error("record malloc failed\n"); + return NULL; + } + csv_init_record(rec); + rec->record = calloc(1, csv->buflen); + if (!rec->record) { + log_error("field str malloc failed\n"); + free(rec); + return NULL; + } + csv_insert_record(csv, rec); + } + + str = rec->record; + + va_start(list, count); + + if (rec->rec_len && (str[rec->rec_len - 1] == '\n')) + str[rec->rec_len - 1] = ','; + + /** + * Iterate through the fields passed as a variable list and add them + */ + tlen = rec->rec_len; + for (tempc = 0; tempc < count; tempc++) { + col = va_arg(list, char *); + fld = csv_add_field_to_record(csv, rec, col); + if (!fld) { + log_error("fld malloc failed\n"); + break; + } + if (tempc < (count - 1)) { + rec->rec_len += snprintf((str + rec->rec_len), + (len - rec->rec_len), ","); + } + } + rec->rec_len += + snprintf((str + rec->rec_len), (len - rec->rec_len), "\n"); + va_end(list); + csv->csv_len += (rec->rec_len - tlen); + csv->pointer += (rec->rec_len - tlen); + return (rec); } -int -csv_serialize(csv_t *csv, char *msgbuf, int msglen) +int csv_serialize(csv_t *csv, char *msgbuf, int msglen) { - csv_record_t *rec; - int offset = 0; + csv_record_t *rec; + int offset = 0; - if (!csv || !msgbuf) return -1; + if (!csv || !msgbuf) + return -1; - rec = csv_record_iter(csv); - while (rec != NULL) { - if ((offset + rec->rec_len) >= msglen) - return -1; - offset += sprintf(&msgbuf[offset], "%s", rec->record); - rec = csv_record_iter_next(rec); - } + rec = csv_record_iter(csv); + while (rec != NULL) { + if ((offset + rec->rec_len) >= msglen) + return -1; + offset += sprintf(&msgbuf[offset], "%s", rec->record); + rec = csv_record_iter_next(rec); + } - return 0; + return 0; } -void -csv_clone_record (csv_t *csv, csv_record_t *in_rec, csv_record_t **out_rec) +void csv_clone_record(csv_t *csv, csv_record_t *in_rec, csv_record_t **out_rec) { - char *curr; - csv_record_t *rec; - - /* first check if rec belongs to this csv */ - if(!csv_is_record_valid(csv, in_rec)){ - log_error("rec not in this csv\n"); - return; - } - - /* only works with csv with discrete bufs */ - if (csv->buf) { - log_error("un-supported for this csv type - single buf detected\n"); - return; - } - - /* create a new rec */ - rec = calloc(1, sizeof(csv_record_t)); - if (!rec) { - log_error("record malloc failed\n"); - return; - } - csv_init_record(rec); - curr = calloc(1, csv->buflen); - if (!curr) { - log_error("field str malloc failed\n"); - return; - } - rec->record = curr; - rec->rec_len = in_rec->rec_len; - strcpy(rec->record, in_rec->record); - - /* decode record into fields */ - csv_decode_record(rec); - - *out_rec = rec; + char *curr; + csv_record_t *rec; + + /* first check if rec belongs to this csv */ + if (!csv_is_record_valid(csv, in_rec)) { + log_error("rec not in this csv\n"); + return; + } + + /* only works with csv with discrete bufs */ + if (csv->buf) { + log_error( + "un-supported for this csv type - single buf detected\n"); + return; + } + + /* create a new rec */ + rec = calloc(1, sizeof(csv_record_t)); + if (!rec) { + log_error("record malloc failed\n"); + return; + } + csv_init_record(rec); + curr = calloc(1, csv->buflen); + if (!curr) { + log_error("field str malloc failed\n"); + free(rec); + return; + } + rec->record = curr; + rec->rec_len = in_rec->rec_len; + strcpy(rec->record, in_rec->record); + + /* decode record into fields */ + csv_decode_record(rec); + + *out_rec = rec; } -void -csv_remove_record (csv_t *csv, csv_record_t *rec) +void csv_remove_record(csv_t *csv, csv_record_t *rec) { - csv_field_t *fld, *p_fld; - - /* first check if rec belongs to this csv */ - if(!csv_is_record_valid(csv, rec)){ - log_error("rec not in this csv\n"); - return; - } - - /* remove fields */ - csv_field_iter(rec, &fld); - while(fld) { - p_fld = fld; - csv_field_iter_next(&fld); - TAILQ_REMOVE(&(rec->fields), p_fld, next_field); - free(p_fld); - } - - TAILQ_REMOVE(&(csv->records), rec, next_record); - - csv->num_recs--; - csv->csv_len -= rec->rec_len; - csv->pointer -= rec->rec_len; - if (!csv->buf) - free(rec->record); - free(rec); + csv_field_t *fld = NULL, *p_fld; + + /* first check if rec belongs to this csv */ + if (!csv_is_record_valid(csv, rec)) { + log_error("rec not in this csv\n"); + return; + } + + /* remove fields */ + csv_field_iter(rec, &fld); + while (fld) { + p_fld = fld; + csv_field_iter_next(&fld); + TAILQ_REMOVE(&(rec->fields), p_fld, next_field); + free(p_fld); + } + + TAILQ_REMOVE(&(csv->records), rec, next_record); + + csv->num_recs--; + csv->csv_len -= rec->rec_len; + csv->pointer -= rec->rec_len; + if (!csv->buf) + free(rec->record); + free(rec); } -void -csv_insert_record (csv_t *csv, csv_record_t *rec) +void csv_insert_record(csv_t *csv, csv_record_t *rec) { - /* first check if rec already in csv */ - if(csv_is_record_valid(csv, rec)){ - log_error("rec already in this csv\n"); - return; - } - - /* we can only insert records if no buf was supplied during csv init */ - if (csv->buf) { - log_error("un-supported for this csv type - single buf detected\n"); - return; - } - - /* do we go beyond the max buf set for this csv ?*/ - if ((csv->csv_len + rec->rec_len) > csv->buflen ) { - log_error("cannot insert - exceeded buf size\n"); - return; - } - - TAILQ_INSERT_TAIL(&(csv->records), rec, next_record); - csv->num_recs++; - csv->csv_len += rec->rec_len; - csv->pointer += rec->rec_len; + /* first check if rec already in csv */ + if (csv_is_record_valid(csv, rec)) { + log_error("rec already in this csv\n"); + return; + } + + /* we can only insert records if no buf was supplied during csv init */ + if (csv->buf) { + log_error( + "un-supported for this csv type - single buf detected\n"); + return; + } + + /* do we go beyond the max buf set for this csv ?*/ + if ((csv->csv_len + rec->rec_len) > csv->buflen) { + log_error("cannot insert - exceeded buf size\n"); + return; + } + + TAILQ_INSERT_TAIL(&(csv->records), rec, next_record); + csv->num_recs++; + csv->csv_len += rec->rec_len; + csv->pointer += rec->rec_len; } -csv_record_t * -csv_concat_record (csv_t *csv, - csv_record_t *rec1, - csv_record_t *rec2) +csv_record_t *csv_concat_record(csv_t *csv, csv_record_t *rec1, + csv_record_t *rec2) { - char *curr; - char *ret; - csv_record_t *rec; - - /* first check if rec1 and rec2 belong to this csv */ - if(!csv_is_record_valid(csv, rec1) || - !csv_is_record_valid(csv, rec2)) { - log_error("rec1 and/or rec2 invalid\n"); - return (NULL); - } - - /* we can only concat records if no buf was supplied during csv init */ - if (csv->buf) { - log_error("un-supported for this csv type - single buf detected\n"); - return (NULL); - } - - /* create a new rec */ - rec = calloc(1, sizeof(csv_record_t)); - if (!rec) { - log_error("record malloc failed\n"); - return (NULL); - } - csv_init_record(rec); - - curr = (char *)calloc(1, csv->buflen); - if (!curr) { - log_error("field str malloc failed\n"); - return (NULL); - } - rec->record = curr; - - /* concat the record string */ - ret = strstr(rec1->record, "\n"); - if (!ret) { - log_error("rec1 str not properly formatted\n"); - return (NULL); - } - - snprintf(curr, (int)(ret - rec1->record + 1), "%s", rec1->record); - strcat(curr, ","); - - ret = strstr(rec2->record, "\n"); - if (!ret) { - log_error("rec2 str not properly formatted\n"); - return (NULL); - } - - snprintf((curr+strlen(curr)), (int)(ret - rec2->record + 1), "%s", - rec2->record); - strcat(curr, "\n"); - rec->rec_len = strlen(curr); - - /* paranoia */ - assert(csv->buflen > - (csv->csv_len - rec1->rec_len - rec2->rec_len + rec->rec_len)); - - /* decode record into fields */ - csv_decode_record(rec); - - /* now remove rec1 and rec2 and insert rec into this csv */ - csv_remove_record(csv, rec1); - csv_remove_record(csv, rec2); - csv_insert_record(csv, rec); - - return rec; + char *curr; + char *ret; + csv_record_t *rec; + + /* first check if rec1 and rec2 belong to this csv */ + if (!csv_is_record_valid(csv, rec1) + || !csv_is_record_valid(csv, rec2)) { + log_error("rec1 and/or rec2 invalid\n"); + return (NULL); + } + + /* we can only concat records if no buf was supplied during csv init */ + if (csv->buf) { + log_error( + "un-supported for this csv type - single buf detected\n"); + return (NULL); + } + + /* create a new rec */ + rec = calloc(1, sizeof(csv_record_t)); + if (!rec) { + log_error("record malloc failed\n"); + return (NULL); + } + csv_init_record(rec); + + curr = (char *)calloc(1, csv->buflen); + if (!curr) { + log_error("field str malloc failed\n"); + goto out_rec; + } + rec->record = curr; + + /* concat the record string */ + ret = strstr(rec1->record, "\n"); + if (!ret) { + log_error("rec1 str not properly formatted\n"); + goto out_curr; + } + + snprintf(curr, (int)(ret - rec1->record + 1), "%s", rec1->record); + strcat(curr, ","); + + ret = strstr(rec2->record, "\n"); + if (!ret) { + log_error("rec2 str not properly formatted\n"); + goto out_curr; + } + + snprintf((curr + strlen(curr)), (int)(ret - rec2->record + 1), "%s", + rec2->record); + strcat(curr, "\n"); + rec->rec_len = strlen(curr); + + /* paranoia */ + assert(csv->buflen + > (csv->csv_len - rec1->rec_len - rec2->rec_len + rec->rec_len)); + + /* decode record into fields */ + csv_decode_record(rec); + + /* now remove rec1 and rec2 and insert rec into this csv */ + csv_remove_record(csv, rec1); + csv_remove_record(csv, rec2); + csv_insert_record(csv, rec); + + return rec; + +out_curr: + free(curr); +out_rec: + free(rec); + return NULL; } -void -csv_decode (csv_t *csv, char *inbuf) +void csv_decode(csv_t *csv, char *inbuf) { - char *buf; - char *pos; - csv_record_t *rec; - - buf = (inbuf)? inbuf:csv->buf; - pos = strpbrk(buf, "\n"); - while (pos != NULL) { - rec = calloc(1, sizeof(csv_record_t)); - csv_init_record(rec); - TAILQ_INSERT_TAIL(&(csv->records), rec, next_record); - csv->num_recs++; - if (csv->buf) - rec->record = buf; - else { - rec->record = calloc(1, csv->buflen); - if (!rec->record) { - log_error("field str malloc failed\n"); - return; - } - strncpy(rec->record, buf, pos-buf+1); - } - rec->rec_len = pos-buf+1; - /* decode record into fields */ - csv_decode_record(rec); - buf = pos+1; - pos = strpbrk(buf, "\n"); - } + char *buf; + char *pos; + csv_record_t *rec; + + buf = (inbuf) ? inbuf : csv->buf; + pos = strpbrk(buf, "\n"); + while (pos != NULL) { + rec = calloc(1, sizeof(csv_record_t)); + if (!rec) + return; + csv_init_record(rec); + TAILQ_INSERT_TAIL(&(csv->records), rec, next_record); + csv->num_recs++; + if (csv->buf) + rec->record = buf; + else { + rec->record = calloc(1, csv->buflen); + if (!rec->record) { + log_error("field str malloc failed\n"); + return; + } + strncpy(rec->record, buf, pos - buf + 1); + } + rec->rec_len = pos - buf + 1; + /* decode record into fields */ + csv_decode_record(rec); + buf = pos + 1; + pos = strpbrk(buf, "\n"); + } } -int -csv_is_record_valid(csv_t *csv, csv_record_t *in_rec) +int csv_is_record_valid(csv_t *csv, csv_record_t *in_rec) { - csv_record_t *rec; - int valid = 0; - - rec = csv_record_iter(csv); - while (rec) { - if(rec == in_rec) { - valid = 1; - break; - } - rec = csv_record_iter_next(rec); - } - - return valid; + csv_record_t *rec; + int valid = 0; + + rec = csv_record_iter(csv); + while (rec) { + if (rec == in_rec) { + valid = 1; + break; + } + rec = csv_record_iter_next(rec); + } + + return valid; } -void -csv_dump (csv_t *csv) +void csv_dump(csv_t *csv) { - csv_record_t *rec; - csv_field_t *fld; - char *str; - - rec = csv_record_iter(csv); - while (rec != NULL) { - str = csv_field_iter(rec, &fld); - while (str != NULL) { - fprintf(stderr, "%s\n", str); - str = csv_field_iter_next(&fld); - } - rec = csv_record_iter_next(rec); - } + csv_record_t *rec; + csv_field_t *fld; + char *str; + + rec = csv_record_iter(csv); + while (rec != NULL) { + str = csv_field_iter(rec, &fld); + while (str != NULL) { + fprintf(stderr, "%s\n", str); + str = csv_field_iter_next(&fld); + } + rec = csv_record_iter_next(rec); + } } #ifdef TEST_CSV -static int -get_memory_usage (pid_t pid) +static int get_memory_usage(pid_t pid) { - int fd, data, stack; - char buf[4096], status_child[BUFSIZ]; - char *vm; - - sprintf(status_child, "/proc/%d/status", pid); - if ((fd = open(status_child, O_RDONLY)) < 0) - return -1; - - read(fd, buf, 4095); - buf[4095] = '\0'; - close(fd); - - data = stack = 0; - - vm = strstr(buf, "VmData:"); - if (vm) { - sscanf(vm, "%*s %d", &data); - } - vm = strstr(buf, "VmStk:"); - if (vm) { - sscanf(vm, "%*s %d", &stack); - } - - return data + stack; + int fd, data, stack; + char buf[4096], status_child[BUFSIZ]; + char *vm; + + sprintf(status_child, "/proc/%d/status", pid); + if ((fd = open(status_child, O_RDONLY)) < 0) + return -1; + + read(fd, buf, 4095); + buf[4095] = '\0'; + close(fd); + + data = stack = 0; + + vm = strstr(buf, "VmData:"); + if (vm) { + sscanf(vm, "%*s %d", &data); + } + vm = strstr(buf, "VmStk:"); + if (vm) { + sscanf(vm, "%*s %d", &stack); + } + + return data + stack; } -int main () +int main() { - char buf[10000]; - csv_t csv; - int p; - int i, j; - csv_record_t *rec; - csv_field_t *fld; - char *str; - char hdr1[32], hdr2[32]; - - log_verbose("Mem: %ld\n", get_memory_usage(getpid())); - csv_init(&csv, buf, 256); - sprintf(hdr1, "%4u", 0); - sprintf(hdr2, "%4u", 1); - log_verbose("(%d/%d/%d/%d)\n", strlen(hdr1), - strlen(hdr2), atoi(hdr1), atoi(hdr2)); - rec = csv_encode(&csv, 2, hdr1, hdr2); - csv_encode(&csv, 4, "name", "age", "sex", "hei"); - csv_encode(&csv, 3, NULL, "0", NULL); - csv_encode(&csv, 2, "p", "35"); - for (i=0; i < 50; i++) { - csv_encode(&csv, 2, "p", "10"); - } - csv_encode(&csv, 2, "pdfadfadfadsadsaddfdfdsfdsd", - "35444554545454545"); - log_verbose("%s\n", buf); - sprintf(hdr1, "%4u", csv.csv_len); - sprintf(hdr2, "%4u", 1); - log_verbose("(%d/%d/%d/%d)\n", strlen(hdr1), - strlen(hdr2), atoi(hdr1), atoi(hdr2)); - rec = csv_encode_record(&csv, rec, 2, hdr1, hdr2); - log_verbose("(%d/%d)\n%s\n", rec->rec_len, csv.csv_len, buf); - - log_verbose("Mem: %ld\n", get_memory_usage(getpid())); - csv_clean(&csv); - log_verbose("Mem: %ld\n", get_memory_usage(getpid())); - csv_init(&csv, buf, 256); - csv_decode(&csv, NULL); - log_verbose("AFTER DECODE\n"); - csv_dump(&csv); - csv_clean(&csv); - log_verbose("Mem: %ld\n", get_memory_usage(getpid())); + char buf[10000]; + csv_t csv; + int i; + csv_record_t *rec; + char hdr1[32], hdr2[32]; + + log_verbose("Mem: %d\n", get_memory_usage(getpid())); + csv_init(&csv, buf, 256); + sprintf(hdr1, "%4u", 0); + sprintf(hdr2, "%4u", 1); + log_verbose("(%zu/%zu/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1), + atoi(hdr2)); + rec = csv_encode(&csv, 2, hdr1, hdr2); + csv_encode(&csv, 4, "name", "age", "sex", "hei"); + csv_encode(&csv, 3, NULL, "0", NULL); + csv_encode(&csv, 2, "p", "35"); + for (i = 0; i < 50; i++) { + csv_encode(&csv, 2, "p", "10"); + } + csv_encode(&csv, 2, "pdfadfadfadsadsaddfdfdsfdsd", "35444554545454545"); + log_verbose("%s\n", buf); + sprintf(hdr1, "%4u", csv.csv_len); + sprintf(hdr2, "%4u", 1); + log_verbose("(%zu/%zu/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1), + atoi(hdr2)); + rec = csv_encode_record(&csv, rec, 2, hdr1, hdr2); + log_verbose("(%d/%d)\n%s\n", rec->rec_len, csv.csv_len, buf); + + log_verbose("Mem: %d\n", get_memory_usage(getpid())); + csv_clean(&csv); + log_verbose("Mem: %d\n", get_memory_usage(getpid())); + csv_init(&csv, buf, 256); + csv_decode(&csv, NULL); + log_verbose("%s", "AFTER DECODE\n"); + csv_dump(&csv); + csv_clean(&csv); + log_verbose("Mem: %d\n", get_memory_usage(getpid())); } #endif