Files @ 2d956d549430
Branch filter:

Location: DistRen/src/common/csv.c - annotation

binki
Add simple CSV parser for normaldotcom.
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
2d956d549430
/*
 * Copyright 2010 Nathan Phillip Brink
 *
 * This file is a part of DistRen.
 *
 * DistRen is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * DistRen is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with DistRen.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "common/config.h"

#include "common/csv.h"

#include <list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**
 * \todo
 *   replace with a more generic function for rendering a CSV file
 */
static int csv_print_row(size_t *columns, char *row[])
{
  size_t c;

  for (c = 0; c < *columns; c ++)
    {
      printf("%s", row[c]);
      if (c < *columns - 1)
	printf(", ");
    }
  printf("\n");

  return TRUE;
}

csv_row_t csv_row_init(size_t columns)
{
  csv_row_t row;

  row = malloc(sizeof(struct csv_row));
  if (!row)
    return NULL;

  row->cols = malloc(sizeof(char *) * columns);
  if (!row->cols)
    {
      free(row);
      return NULL;
    }
  row->num_cols = columns;

  return row;
}

void csv_row_free(csv_row_t row)
{
  size_t c;

  for (c = 0; c < row->num_cols; c ++)
    free(row->cols[c]);
  free(row);
}

list_t csv_parse(const char *inbuf, size_t columns)
{
  list_t rows;
  size_t seek;
  const char newline = '\n';
  csv_row_t row;

  size_t cur_col;

  rows = list_init();
  while(*inbuf)
    {
      row = csv_row_init(columns);
      if (!row)
	{
	  list_free(rows, (list_dealloc_func_t)&csv_row_free);
	  return NULL;
	}

      for(cur_col = 0; cur_col < columns; cur_col ++)
	{
	  for(seek = 0; inbuf[seek]; seek ++)
	    if (inbuf[seek] == newline
		|| inbuf[seek] == ',')
	      break;
	  row->cols[cur_col] = malloc(seek + 1);
	  if (seek)
	    memcpy(row->cols[cur_col], inbuf, seek);
	  row->cols[cur_col][seek] = '\0';

	  /* get us to the ',' (or NULL or newline char, if things are bad) */
	  inbuf += seek;
	  /* skip a comma, but not a NULL char or newline */
	  if (*inbuf == ',')
	    inbuf ++;
	}

      list_insert_after(rows, row, 0);

      /* skip the newline char */
      while (*inbuf && *inbuf != newline)
	inbuf ++;
      if (*inbuf == newline)
	inbuf ++;
    }

  return rows;
}