diff options
Diffstat (limited to 'lib/csv.c')
| -rw-r--r-- | lib/csv.c | 1155 | 
1 files changed, 565 insertions, 590 deletions
@@ -30,690 +30,665 @@  #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_verbose(fmt, ...) \ -  do { if (DEBUG_V) 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)  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 (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); -      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 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); +	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"); -        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; +	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, *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"); -    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; +	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); +	free(curr);  out_rec: -  free(rec); -  return NULL; +	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)); -    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"); -  } +	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 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()));  }  #endif  | 
