11 enum fmt_types { AT_STRING, AT_FLOAT, AT_DOUBLE, AT_COMPLEX,
12 AT_SHORTSHORT, AT_SHORT, AT_INT, AT_LONG, AT_LONGLONG,
13 AT_USHORTSHORT, AT_USHORT, AT_UINT, AT_ULONG, AT_ULONGLONG };
22 int count_complex_formats(
const char* fmt_str) {
23 const char * fmt_regex =
"%([[:digit:]]+\\$)?[+-]?([ 0]|\'.{1})?-?[[:digit:]]*(\\.[[:digit:]]+)?[lhjztL]*[eEfFgG]" 24 "%([[:digit:]]+\\$)?[+-]([ 0]|\'.{1})?-?[[:digit:]]*(\\.[[:digit:]]+)?[lhjztL]*[eEfFgG]j";
25 int ret = count_matches(fmt_regex, fmt_str);
39 int count_formats(
const char* fmt_str) {
40 const char * fmt_regex =
"%([[:digit:]]+\\$)?[+-]?([ 0]|\'.{1})?-?[[:digit:]]*(\\.[[:digit:]]+)?[lhjztL]*(64)?[bcdeEufFgGosxX]";
41 int ret = count_matches(fmt_regex, fmt_str);
55 int simplify_formats(
char *fmt_str,
const size_t fmt_len) {
56 const char * fmt_regex1 =
"%([[:digit:]]+\\$)?[+-]?([ 0]|\'.{1})?-?[[:digit:]]*(\\.[[:digit:]]+)?([lhjztL]*)([eEfFgG])";
59 int ret = regex_replace_sub(fmt_str, fmt_len, fmt_regex1,
62 const char * fmt_regex2 =
"%[lhjztL]*([fF])";
63 ret = regex_replace_sub(fmt_str, fmt_len, fmt_regex2,
94 return af_open(&((*t).f));
117 int at_readline_full_realloc(
const asciiTable_t t,
char **buf,
118 const size_t len_buf,
const int allow_realloc) {
120 int ret = 0, com = 1;
121 size_t nread = LINE_SIZE_MAX;
122 char *line = (
char*)malloc(nread);
124 cislog_error(
"at_readline_full_realloc: Failed to malloc line.");
127 while ((ret >= 0) && (com == 1)) {
128 ret = af_readline_full(t.
f, &line, &nread);
133 com = af_is_comment(t.
f, line);
135 if (ret > (
int)len_buf) {
137 cislog_debug(
"at_readline_full_realloc: reallocating buffer from %d to %d bytes.",
138 (
int)len_buf, ret + 1);
139 char *temp_buf = (
char*)realloc(*buf, ret + 1);
140 if (temp_buf == NULL) {
141 cislog_error(
"at_readline_full_realloc: Failed to realloc buffer.");
148 cislog_error(
"at_readline_full_realloc: line (%d bytes) is larger than destination buffer (%d bytes)",
169 int at_readline_full(
const asciiTable_t t,
char *buf,
const size_t len_buf) {
171 return at_readline_full_realloc(t, &buf, len_buf, 0);
181 int at_writeline_full(
const asciiTable_t t,
const char* line) {
183 ret = af_writeline_full(t.
f, line);
196 int at_vbytes_to_row(
const asciiTable_t t,
const char* line, va_list ap) {
198 char fmt[LINE_SIZE_MAX];
200 int sret = simplify_formats(fmt, LINE_SIZE_MAX);
202 cislog_debug(
"at_vbytes_to_row: simplify_formats returned %d", sret);
206 int ret = vsscanf(line, fmt, ap);
207 if (ret != t.
ncols) {
208 cislog_error(
"at_vbytes_to_row: %d arguments filled, but %d were expected",
226 int at_vrow_to_bytes(
const asciiTable_t t,
char *buf,
const size_t buf_siz, va_list ap) {
227 int ret = vsnprintf(buf, buf_siz, t.
format_str, ap);
242 size_t nread = LINE_SIZE_MAX;
243 char *line = (
char*)malloc(nread);
245 cislog_error(
"at_vreadline: Failed to malloc line.");
248 ret = at_readline_full(t, line, nread);
254 int sret = at_vbytes_to_row(t, line, ap);
285 int ret = at_vreadline(t, ap);
301 int ret = at_vwriteline(t, ap);
314 if (af_is_open(t.
f) == 1) {
331 int ret = at_open(t);
334 size_t nread = LINE_SIZE_MAX;
335 char *line = (
char*)malloc(nread);
337 cislog_error(
"at_discover_format_str: Failed to malloc line.");
341 while (getline(&line, &nread, (*t).f.fd) >= 0) {
342 if (af_is_comment((*t).f, line) == 1) {
343 if (count_formats(line) > 0) {
344 strcpy((*t).format_str, line + strlen((*t).f.comment));
364 count = count_formats((*t).format_str);
380 for (i = 0; i < (*t).ncols; i++) {
381 typ = (*t).format_typ[i];
382 siz = (*t).format_siz[i];
383 if (typ == AT_STRING) siz = (*t).format_siz[i];
384 else if (typ == AT_FLOAT) siz =
sizeof(float);
385 else if (typ == AT_DOUBLE) siz =
sizeof(double);
386 else if (typ == AT_COMPLEX) siz = 2*
sizeof(double);
387 else if (typ == AT_SHORTSHORT) siz =
sizeof(char);
388 else if (typ == AT_SHORT) siz =
sizeof(short);
389 else if (typ == AT_LONGLONG) siz =
sizeof(
long long);
390 else if (typ == AT_LONG) siz =
sizeof(long);
391 else if (typ == AT_INT) siz =
sizeof(int);
392 else if (typ == AT_USHORTSHORT) siz =
sizeof(
unsigned char);
393 else if (typ == AT_USHORT) siz =
sizeof(
unsigned short);
394 else if (typ == AT_ULONGLONG) siz =
sizeof(
unsigned long long);
395 else if (typ == AT_ULONG) siz =
sizeof(
unsigned long);
396 else if (typ == AT_UINT) siz =
sizeof(
unsigned int);
399 cislog_error(
"at_set_format_siz: Could not set size for column %d with type %d", i, typ);
402 (*t).format_siz[i] = siz;
418 (*t).format_typ = (
int*)malloc((*t).ncols*
sizeof(
int));
419 (*t).format_siz = (
int*)malloc((*t).ncols*
sizeof(
int));
420 if (((*t).format_typ == NULL) || ((*t).format_siz == NULL)) {
421 cislog_error(
"at_set_format_typ: Failed to alloc format_typ/format_siz");
428 for (icol = 0; icol < (*t).ncols; icol++) {
429 (*t).format_typ[icol] = -1;
430 (*t).format_siz[icol] = -1;
436 char re_fmt[FMT_LEN];
437 sprintf(re_fmt,
"%%[^%s%s]+[%s%s]",
438 (*t).column, (*t).f.newline, (*t).column, (*t).f.newline);
439 while (beg < strlen((*t).format_str)) {
440 mres = find_match(re_fmt, (*t).format_str + beg, &sind, &eind);
442 cislog_error(
"at_set_format_typ: find_match returned %d", mres);
444 }
else if (mres == 0) {
449 end = beg + (eind - sind);
450 strncpy(ifmt, &((*t).format_str)[beg], end-beg);
451 ifmt[end-beg] =
'\0';
452 if (find_match(
"%.*s", ifmt, &sind, &eind)) {
453 (*t).format_typ[icol] = AT_STRING;
454 mres = regex_replace_sub(ifmt, FMT_LEN,
455 "%(\\.)?([[:digit:]]*)s(.*)",
"$2", 0);
456 (*t).format_siz[icol] = atoi(ifmt);
458 }
else if (find_match(
"(%.*[fFeEgG]){2}j", ifmt, &sind, &eind)) {
460 }
else if (find_match(
"(\%.*[fFeEgG]){2}j", ifmt, &sind, &eind)) {
463 (*t).format_typ[icol] = AT_DOUBLE;
465 (*t).format_typ[icol] = AT_DOUBLE;
466 }
else if (find_match(
"%.*[fFeEgG]", ifmt, &sind, &eind)) {
467 (*t).format_typ[icol] = AT_DOUBLE;
472 }
else if (find_match(
"%.*hh[id]", ifmt, &sind, &eind)) {
473 (*t).format_typ[icol] = AT_SHORTSHORT;
474 }
else if (find_match(
"%.*h[id]", ifmt, &sind, &eind)) {
475 (*t).format_typ[icol] = AT_SHORT;
476 }
else if (find_match(
"%.*ll[id]", ifmt, &sind, &eind)) {
477 (*t).format_typ[icol] = AT_LONGLONG;
478 }
else if (find_match(
"%.*l64[id]", ifmt, &sind, &eind)) {
479 (*t).format_typ[icol] = AT_LONGLONG;
480 }
else if (find_match(
"%.*l[id]", ifmt, &sind, &eind)) {
481 (*t).format_typ[icol] = AT_LONG;
482 }
else if (find_match(
"%.*[id]", ifmt, &sind, &eind)) {
483 (*t).format_typ[icol] = AT_INT;
484 }
else if (find_match(
"%.*hh[uoxX]", ifmt, &sind, &eind)) {
485 (*t).format_typ[icol] = AT_USHORTSHORT;
486 }
else if (find_match(
"%.*h[uoxX]", ifmt, &sind, &eind)) {
487 (*t).format_typ[icol] = AT_USHORT;
488 }
else if (find_match(
"%.*ll[uoxX]", ifmt, &sind, &eind)) {
489 (*t).format_typ[icol] = AT_ULONGLONG;
490 }
else if (find_match(
"%.*l64[uoxX]", ifmt, &sind, &eind)) {
491 (*t).format_typ[icol] = AT_ULONGLONG;
492 }
else if (find_match(
"%.*l[uoxX]", ifmt, &sind, &eind)) {
493 (*t).format_typ[icol] = AT_ULONG;
494 }
else if (find_match(
"%.*[uoxX]", ifmt, &sind, &eind)) {
495 (*t).format_typ[icol] = AT_UINT;
497 cislog_error(
"at_set_format_typ: Could not parse format string: %s", ifmt);
503 return at_set_format_siz(t);
517 int at_vbytes_to_array(
const asciiTable_t t,
const char *data,
518 const size_t data_siz, va_list ap) {
521 if ((data_siz % t.
row_siz) != 0) {
522 cislog_error(
"at_vbytes_to_array: Data: %s", data);
523 cislog_error(
"at_vbytes_to_array: Data size (%d) not an even number of rows (row size is %d)",
528 int nrows = (int)data_siz / t.
row_siz;
529 int cur_pos = 0, col_siz;
531 for (i = 0; i < t.
ncols; i++) {
534 temp = va_arg(ap,
char**);
536 t2 = (
char*)realloc(*temp, col_siz);
538 cislog_error(
"at_vbytes_to_array: Failed to realloc temp var.");
549 memcpy(*temp, data+cur_pos, col_siz);
570 int at_varray_to_bytes(
const asciiTable_t t,
char *data,
const size_t data_siz, va_list ap) {
571 int nrows = va_arg(ap,
int);
573 if (msg_siz > (
int)data_siz) {
574 cislog_debug(
"at_varray_to_bytes: Message size (%d bytes) will exceed allocated buffer (%d bytes).",
575 msg_siz, (
int)data_siz);
579 int cur_pos = 0, col_siz;
582 for (i = 0; i < t.
ncols; i++) {
584 temp = va_arg(ap,
char*);
585 memcpy(data+cur_pos, temp, col_siz);
602 int at_bytes_to_array(
const asciiTable_t t,
char *data,
size_t data_siz, ...) {
604 va_start(ap, data_siz);
605 int ret = at_vbytes_to_array(t, data, data_siz, ap);
622 int at_array_to_bytes(
const asciiTable_t t,
char *data,
const size_t data_siz, ...) {
624 va_start(ap, data_siz);
625 int ret = at_varray_to_bytes(t, data, data_siz, ap);
637 free((*t).format_typ);
639 free((*t).format_siz);
640 (*t).format_typ = NULL;
641 (*t).format_siz = NULL;
652 int at_update(
asciiTable_t *t,
const char *filepath,
const char *io_mode) {
654 flag = af_update(&(t->
f), filepath, io_mode);
656 if ((strlen(t->
format_str) == 0) && (strcmp(io_mode,
"r") == 0)) {
657 flag = at_discover_format_str(t);
659 flag = at_set_ncols(t);
661 flag = at_set_format_typ(t);
685 asciiTable_t asciiTable(
const char *filepath,
const char *io_mode,
686 const char *format_str,
const char *comment,
687 const char *column,
const char *newline) {
695 t.
f = asciiFile(filepath, io_mode, comment, newline);
702 if (format_str == NULL) {
703 if (strcmp(io_mode,
"r") == 0) {
704 t.
status = at_discover_format_str(&t);
713 t.
status = at_set_ncols(&t);
715 t.
status = at_set_format_typ(&t);
int row_siz
Size of an entire row in bytes.
Definition: AsciiTable.h:83
int * format_typ
Array of ncols integers specifying column types.
Definition: AsciiTable.h:81
char comment[64]
Character(s) indicating a comment.
Definition: AsciiFile.h:14
char format_str[LINE_SIZE_MAX]
Format string for rows.
Definition: AsciiTable.h:78
asciiFile_t f
ASCII file structure.
Definition: AsciiTable.h:77
int * format_siz
Array of ncols sizes for elements in each column.
Definition: AsciiTable.h:82
char column[64]
Character(s) used to seperate columns.
Definition: AsciiTable.h:79
int ncols
Number of columns in the table.
Definition: AsciiTable.h:80
Structure containing information about an ASCII text file.
Definition: AsciiFile.h:11
FILE * fd
File identifier for ASCII file when open.
Definition: AsciiFile.h:16
Structure containing information about an ASCII table.
Definition: AsciiTable.h:76
int status
Negative if format_str has not been set yet.
Definition: AsciiTable.h:84