/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2005,2007 Oracle. All rights reserved. * * $Id: util.c,v 1.21 2007/05/17 15:15:13 bostic Exp $ */ #include "csv.h" #include "csv_local.h" #include "csv_extern.h" /* * entry_print -- * Display the primary database's data item. */ int entry_print(void *data, size_t len, u_int32_t field_count) { u_int32_t a, *offset; u_int i; char *raw; memcpy(&a, data, sizeof(u_int32_t)); printf("\tversion: %lu\n", (u_long)a); offset = (u_int32_t *)data + 1; if (field_count == 0) { memcpy(&a, offset++, sizeof(u_int32_t)); printf("\tcolumn map: %lu fields: {%.*s}\n", (u_long)a, (int)(len - 2 * sizeof(u_int32_t)), (u_int8_t *)data + 2 * sizeof(u_int32_t)); } else { raw = (char *)(offset + (field_count + 1)); for (i = 0; i < field_count; ++i) { memcpy(&a, &offset[i], sizeof(u_int32_t)); len = OFFSET_LEN(offset, i); printf("\toffset %4lu: len %4lu: {%.*s}\n", (u_long)offset[i], (u_long)len, (int)len, raw + a); } } return (0); } /* * strtod_err -- * strtod(3) with error checking. */ int strtod_err(char *input, double *valp) { double val; char *end; /* * strtoul requires setting errno to detect errors. */ errno = 0; val = strtod(input, &end); if (errno == ERANGE) { dbenv->err(dbenv, ERANGE, "%s", input); return (1); } if (input[0] == '\0' || (end[0] != '\0' && end[0] != '\n' && !isspace(end[0]))) { dbenv->errx(dbenv, "%s: invalid floating point argument", input); return (1); } *valp = val; return (0); } /* * strtoul_err -- * strtoul(3) with error checking. */ int strtoul_err(char *input, u_long *valp) { u_long val; char *end; /* * strtoul requires setting errno to detect errors. */ errno = 0; val = strtoul(input, &end, 10); if (errno == ERANGE) { dbenv->err(dbenv, ERANGE, "%s", input); return (1); } if (input[0] == '\0' || (end[0] != '\0' && end[0] != '\n' && !isspace(end[0]))) { dbenv->errx(dbenv, "%s: invalid unsigned long argument", input); return (1); } *valp = val; return (0); } int secondary_callback(DB *db_arg, const DBT *key, const DBT *data, DBT *result) { DbField *f; DbRecord record; void *faddr, *addr; /* Populate the field. */ if (DbRecord_init(key, data, &record) != 0) return (-1); f = db_arg->app_private; faddr = (u_int8_t *)&record + f->offset; /* * If necessary, copy the field into separate memory. * Set up the result DBT. */ switch (f->type) { case STRING: result->data = *(char **)faddr; result->size = strlen(*(char **)faddr) + 1; break; case DOUBLE: if ((addr = malloc(sizeof(double))) == NULL) return (-1); result->data = addr; result->size = sizeof(double); result->flags = DB_DBT_APPMALLOC; memcpy(addr, faddr, sizeof(double)); break; case ULONG: if ((addr = malloc(sizeof(u_long))) == NULL) return (-1); result->data = addr; result->size = sizeof(u_long); result->flags = DB_DBT_APPMALLOC; memcpy(addr, faddr, sizeof(u_long)); break; default: case NOTSET: abort(); /* NOTREACHED */ } return (0); } /* * compare_double -- * Compare two keys. */ int compare_double(DB *db_arg, const DBT *a_arg, const DBT *b_arg) { double a, b; db_arg = db_arg; /* Quiet compiler. */ memcpy(&a, a_arg->data, sizeof(double)); memcpy(&b, b_arg->data, sizeof(double)); return (a > b ? 1 : ((a < b) ? -1 : 0)); } /* * compare_ulong -- * Compare two keys. */ int compare_ulong(DB *db_arg, const DBT *a_arg, const DBT *b_arg) { u_long a, b; db_arg = db_arg; /* Quiet compiler. */ memcpy(&a, a_arg->data, sizeof(u_long)); memcpy(&b, b_arg->data, sizeof(u_long)); return (a > b ? 1 : ((a < b) ? -1 : 0)); } /* * field_cmp_double -- * Compare two double. */ int field_cmp_double(void *a, void *b, OPERATOR op) { switch (op) { case GT: return (*(double *)a > *(double *)b); case GTEQ: return (*(double *)a >= *(double *)b); case LT: return (*(double *)a < *(double *)b); case LTEQ: return (*(double *)a <= *(double *)b); case NEQ: return (*(double *)a != *(double *)b); case EQ: return (*(double *)a == *(double *)b); case WC: case NWC: break; } abort(); /* NOTREACHED */ } /* * field_cmp_re -- * Compare against regular expression. */ int field_cmp_re(void *a, void *b, OPERATOR op) { op = op; /* Quiet compiler. */ switch (op) { #ifdef HAVE_WILDCARD_SUPPORT case WC: return (regexec(b, *(char **)a, 0, NULL, 0) == 0); case NWC: return (regexec(b, *(char **)a, 0, NULL, 0) != 0); #else case WC: case NWC: a = a; b = b; /* Quiet compiler. */ /* FALLTHROUGH */ #endif case GT: case GTEQ: case LT: case LTEQ: case NEQ: case EQ: break; } abort(); /* NOTREACHED */ } /* * field_cmp_string -- * Compare two strings. */ int field_cmp_string(void *a, void *b, OPERATOR op) { int v; v = strcasecmp(*(char **)a, b); switch (op) { case GT: return (v > 0 ? 1 : 0); case GTEQ: return (v >= 0 ? 1 : 0); case LT: return (v < 0 ? 1 : 0); case LTEQ: return (v <= 0 ? 1 : 0); case NEQ: return (v ? 1 : 0); case EQ: return (v ? 0 : 1); case WC: case NWC: break; } abort(); /* NOTREACHED */ } /* * field_cmp_ulong -- * Compare two ulongs. */ int field_cmp_ulong(void *a, void *b, OPERATOR op) { switch (op) { case GT: return (*(u_long *)a > *(u_long *)b); case GTEQ: return (*(u_long *)a >= *(u_long *)b); case LT: return (*(u_long *)a < *(u_long *)b); case LTEQ: return (*(u_long *)a <= *(u_long *)b); case NEQ: return (*(u_long *)a != *(u_long *)b); case EQ: return (*(u_long *)a == *(u_long *)b); case WC: case NWC: break; } abort(); /* NOTREACHED */ }