www.pudn.com > bayes.rar > io.c
/*----------------------------------------------------------------------
File : io.c
Contents: input/output utility functions for attribute sets and tables
Authors : Christian Borgelt
History : 17.04.1999 file created
14.07.2001 adapted to new function as_err
15.07.2001 function io_asin removed
23.07.2001 function msg removed
16.08.2003 slight changes in error message output
----------------------------------------------------------------------*/
#include
#include
#include
#include
#include
#include "io.h"
#ifdef STORAGE
#include "storage.h"
#endif
/*----------------------------------------------------------------------
Preprocessor Definitions
----------------------------------------------------------------------*/
/* --- error codes --- */
#define OK 0 /* no error */
#define E_NONE 0 /* no error */
#define E_NOMEM (-1) /* not enough memory */
#define E_FOPEN (-2) /* cannot open file */
#define E_FREAD (-3) /* read error on file */
#define E_FWRITE (-4) /* write error on file */
#define E_STDIN (-5) /* double assignment of stdin */
/* codes -6 to -15 not used */
/* codes -16 to -20 defined in attset.h */
#define E_UNKNOWN (-21) /* unknown error */
#define SEC_SINCE(t) ((clock()-(t)) /(double)CLOCKS_PER_SEC)
/*----------------------------------------------------------------------
Constants
----------------------------------------------------------------------*/
static const char *errmsgs[] = { /* error messages */
/* E_NONE 0 */ "no error\n",
/* E_NOMEM -1 */ "not enough memory\n",
/* E_FOPEN -2 */ "cannot open file %s\n",
/* E_FREAD -3 */ "read error on file %s\n",
/* E_FWRITE -4 */ "write error on file %s\n",
/* E_STDIN -5 */ "double assignment of standard input\n",
/* -6 to -15 */ NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
/* E_VALUE -16 */ "file %s, record %d: "
"illegal value %s in field %d\n",
/* E_FLDCNT -17 */ "file %s, record %d: "
"%s%d field(s) instead of %d\n",
/* E_EMPFLD -18 */ "file %s, record %d: "
"empty name%s in field %d\n",
/* E_DUPFLD -19 */ "file %s, record %d: "
"duplicate field name %s in field %d\n",
/* E_MISFLD -20 */ "file %s, record %d: "
"missing field %s\n",
/* E_UNKNOWN -21 */ "unknown error\n"
};
/*----------------------------------------------------------------------
Auxiliary Functions
----------------------------------------------------------------------*/
int io_error (int code, ...)
{ /* --- print an error message */
va_list args; /* list of variable arguments */
const char *msg; /* error message */
if ((code > 0) || (code < E_UNKNOWN))
code = E_UNKNOWN; /* check the error code and */
msg = errmsgs[-code]; /* get the error message */
if (!msg) msg = errmsgs[-E_UNKNOWN];
if (prgname) fprintf(stderr, "\n%s: ", prgname);
else fprintf(stderr, "\n");
va_start(args, code); /* get variable arguments */
vfprintf(stderr, msg, args); /* print the error message */
va_end(args); /* end argument evaluation */
return code; /* return the error code */
} /* io_error() */
/*----------------------------------------------------------------------
Attribute Set Functions
----------------------------------------------------------------------*/
FILE* io_hdr (ATTSET *attset, const char *fn_hdr,
const char *fn_tab, int flags, int verbose)
{ /* --- read a table header */
FILE *in; /* input file to read */
TFSERR *err; /* error information */
int r; /* buffer for result of as_read */
assert(attset); /* check the function arguments */
if (flags & AS_ATT) { /* if to use a table header file */
if (fn_hdr && *fn_hdr) /* if a proper file name is given, */
in = fopen(fn_hdr, "rb"); /* open header file for reading */
else if (fn_tab && *fn_tab){/* if a proper table name is given, */
in = stdin; fn_hdr = ""; } /* read from stdin */
else { io_error(E_STDIN); return NULL; }
if (verbose) fprintf(stderr, "reading %s ... ", fn_hdr);
if (!in) { io_error(E_FOPEN, fn_hdr); return NULL; }
r = as_read(attset, in, flags & ~AS_DFLT);
if (in != stdin) fclose(in);/* read the table header */
if (r != 0) { /* if an error occurred, */
err = as_err(attset); /* get the error information */
io_error(r, fn_hdr, 1, err->s, err->fld, err->exp);
return NULL; /* print an error message */
} /* and abort the function */
if (verbose) fprintf(stderr, "[%d attribute(s)] done.\n",
as_attcnt(attset));
} /* print a success message */
if (fn_tab && *fn_tab) /* if a table file name is given, */
in = fopen(fn_tab, "rb"); /* open table file for input */
else { /* if no table file is given, */
in = stdin; fn_tab = ""; } /* read from stdin */
if (verbose) fprintf(stderr, "reading %s ... ", fn_tab);
if (!in) { io_error(E_FOPEN, fn_tab); return NULL; }
if (!(flags & AS_ATT) /* if not to use a table header file */
&& (as_read(attset, in, flags|AS_ATT) != 0)) {
err = as_err(attset); /* get the error information */
io_error(err->code, fn_tab, 1, err->s, err->fld, err->exp);
if (in != stdin) fclose(in); return NULL;
} /* read att. names from table file */
return in; /* return the file to read table from */
} /* io_hdr() */
/*--------------------------------------------------------------------*/
int io_body (ATTSET *attset, FILE *in, const char *fn_tab,
int flags, int verbose)
{ /* --- traverse a table body */
int cnt = 0; /* number of tuples */
double wgt = 0; /* weight of tuples */
TFSERR *err; /* error information */
int f; /* flags for reading records */
int r; /* buffer for result of as_read */
clock_t t; /* timer for measurement */
assert(attset && in); /* check the function arguments */
t = clock(); /* start the timer */
if (!fn_tab || !*fn_tab) fn_tab = "";
f = AS_INST | (flags & ~(AS_ATT|AS_DFLT));
r = ((flags & AS_DFLT) && !(flags & AS_ATT))
? 0 : as_read(attset, in, f);
while (r == 0) { /* record read loop */
cnt++; /* increment the tuple counter */
wgt += as_getwgt(attset); /* and sum the tuple weight */
r = as_read(attset, in, f); /* try to read the next tuple */
} /* from the table file */
if (in != stdin) fclose(in); /* close the input file */
if (r < 0) { /* if an error occurred, */
err = as_err(attset); /* get the error information */
cnt += (flags & (AS_ATT|AS_DFLT)) ? 1 : 2;
return io_error(r, fn_tab, cnt, err->s, err->fld, err->exp);
} /* print an error message */
if (verbose) { /* if verbose output requested */
fprintf(stderr, "[%d/%g tuple(s)] done", cnt, wgt);
fprintf(stderr, " [%.2fs]", SEC_SINCE(t));
fputs(".\n", stderr); /* print a log message */
}
return 0; /* return 'ok' */
} /* io_body() */
/*--------------------------------------------------------------------*/
int io_tab (ATTSET *attset, const char *fn_hdr,
const char *fn_tab, int flags, int verbose)
{ /* --- traverse a table */
FILE *in; /* input file to read */
assert(attset); /* check the function arguments */
in = io_hdr(attset, fn_hdr, fn_tab, flags, verbose);
if (!in) return E_FREAD; /* read the table header */
return io_body(attset, in, fn_tab, flags, verbose);
} /* io_tab() */ /* and the table body */
/*----------------------------------------------------------------------
Table Functions
----------------------------------------------------------------------*/
#ifdef TAB_RDWR
TABLE* io_bodyin (ATTSET *attset, FILE *in, const char *fn_tab,
int flags, const char *tabname, int verbose)
{ /* --- read a table body */
TABLE *table; /* created table */
int cnt = 0; /* number of tuples */
double wgt = 0; /* weight of tuples */
TFSERR *err; /* error information */
int f; /* flags for reading records */
int r; /* buffer for result of as_read */
clock_t t; /* timer for measurement */
assert(attset && in); /* check the function arguments */
t = clock(); /* start the timer */
if (!fn_tab || !*fn_tab) fn_tab = "";
table = tab_create(tabname, attset, tpl_delete);
if (!table) { /* create a table */
if (in != stdin) fclose(in);
io_error(E_NOMEM); return NULL;
}
f = AS_INST | (flags & ~(AS_ATT|AS_DFLT));
r = ((flags & AS_DFLT) && !(flags & AS_ATT))
? 0 : as_read(attset, in, f);
while (r == 0) { /* record read loop */
if (tab_tpladd(table, NULL) != 0) {
r = E_NOMEM; break; } /* store the current tuple */
cnt++; /* count the tuple read */
wgt += as_getwgt(attset); /* and sum the tuple weight */
r = as_read(attset, in, f); /* try to read the next tuple */
} /* from the table file */
if (in != stdin) fclose(in); /* close the input file */
if (r < 0) { /* if an error occurred, */
err = as_err(attset); /* get the error information */
cnt += (flags & (AS_ATT|AS_DFLT)) ? 1 : 2;
io_error(r, fn_tab, cnt, err->s, err->fld, err->exp);
tab_delete(table, 0); return NULL;
} /* print an error message */
if (verbose) { /* if verbose output requested */
fprintf(stderr, "[%d/%g tuple(s)] done", cnt, wgt);
if (verbose > 1) fprintf(stderr, " [%.2fs]", SEC_SINCE(t));
fputs(".\n", stderr); /* print a log message */
}
return table; /* return the table read */
} /* io_bodyin() */
/*--------------------------------------------------------------------*/
TABLE* io_tabin (ATTSET *attset, const char *fn_hdr,
const char *fn_tab, int flags,
const char *tabname, int verbose)
{ /* --- read a table from a file */
FILE *in; /* input file to read */
assert(attset && tabname); /* check the function arguments */
in = io_hdr(attset, fn_hdr, fn_tab, flags, verbose);
if (!in) return NULL; /* read the table header */
return io_bodyin(attset, in, fn_tab, flags, tabname, verbose);
} /* io_tabin() */ /* read the table body */
/*--------------------------------------------------------------------*/
int io_tabout (TABLE *table, const char *fname, int flags, int verbose)
{ /* --- write a table to a file */
int i, k; /* loop variable, buffer */
int cnt; /* number of tuples */
ATTSET *attset; /* attribute set of table */
FILE *out; /* output file to write */
double wgt = 0; /* weight of tuples */
clock_t t; /* timer for measurement */
assert(table); /* check the function argument */
t = clock(); /* start the timer */
attset = tab_attset(table); /* get the table's attribute set */
if (fname && *fname) /* if a output file name is given, */
out = fopen(fname, "w"); /* open output file for writing */
else { /* if no output file name is given, */
out = stdout; fname = ""; } /* write to standard output */
if (verbose) fprintf(stderr, "writing %s ... ", fname);
if (!out) return io_error(E_FOPEN, fname);
if (flags & AS_ATT) { /* if to write a table header */
if (flags & AS_ALIGN) /* if to align the fields, */
flags |= AS_ALNHDR; /* align them to the header */
if (as_write(attset, out, flags) != 0) {
if (out != stdout) fclose(out);
return io_error(E_FWRITE, fname);
} /* write the attribute names */
} /* to the output file */
flags = AS_INST | (flags & ~(AS_ATT|AS_INST));
wgt = 0; /* clear weight sum */
cnt = tab_tplcnt(table); /* get the number of tuples */
for (i = 0; i < cnt; i++) { /* and traverse the tuples */
tpl_toas(tab_tpl(table,i)); /* copy tuple to its attribute set */
if (as_write(attset, out, flags) != 0) {
i = -1; break; } /* write the tuple */
wgt += as_getwgt(attset); /* to the output file */
} /* and sum its weight */
k = (out != stdout) /* if not written to stdout, */
? fclose(out) : 0; /* close the output file */
if ((i < 0) || (k != 0)) return io_error(E_FWRITE, fname);
if (verbose) { /* if verbose output requested */
fprintf(stderr, "[%d/%g tuple(s)] done", cnt, wgt);
if (verbose > 1) fprintf(stderr, " [%.2fs]", SEC_SINCE(t));
fputs(".\n", stderr); /* print a log message */
}
return 0; /* return 'ok' */
} /* io_tabout() */
#endif