Revision 337 (by dpavlin, 2004/06/10 19:22:40) new trunk for webpac v2
/*
	openisis - an open implementation of the CDS/ISIS database
	Version 0.8.x (patchlevel see file Version)
	Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 2.1 of the License, or (at your option) any later version.

	This library 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
	Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with this library; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

	see README for more information
EOH */

/*
	$Id: lrectest.c,v 1.12 2003/05/01 10:05:41 mawag Exp $
	tests for lrec methods.
*/

#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "openisis.h"
#include "loi.h"
#include "lfdt.h"
#include "luti.h"

#ifdef WIN32
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#endif

static const char* _TheSummary = "Meeting on the Implementation of the Recommendations of the Third Regional Conference of Ministers of Education and Ministers Responsible for Economic Planning in the Arab States";
#define SUMLEN (strlen (_TheSummary))

static Fd _TheFds[] = {
	{ 20, 0, FTX, 0, 0, 32, "author", "", 0, 0, 0, 0 },
	{ 21, 0, FTX, 1, 0, 32, "names", "", 0, 0, 0, 0 },
	{ 22, 0, FTX, 1, 0, 32, "year", "", 0, 0, 0, 0 },
	{ 42, 0, FTX, 1, 0, 32, "title", "", 0, 0, 0, 0 },
	{ 49, 0, FTX, 1, 0, 32, "summary", "", 0, 0, 0, 0 },
	{ 70, 0, FTX, 1, 0, 32, "country", "", 0, 0, 0, 0 },
	{ 80, 0, FTX, 1, 0, 32, "conference", "", 0, 0, 0, 0 },
	{ 81, 0, FTE, 0, 0, 32, "format", "", 0, 0, 0, 0 },
	{ 81, 0, FTV, 0, 0, 1, "autoformat", "", 0, 0, 0, 0 },
	{ 81, 0, FTV, 0, 0, 2, "naligned", "", 0, 0, 0, 0 },
	{ 81, 0, FTV, 0, 0, 73, "aligned", "", 0, 0, 0, 0 },
	{ 82, 0, FTB, 0, 0, 10, "soldout", "", 0, 0, 0, 0 }
};

static Fdt _TheFdt = {
	sizeof(_TheFds) / sizeof(_TheFds[0]),
	_TheFds,
	0
};

static void check (
	char *msg, Rec *rec, int *tag, const char **val, int len, int used
) {
	Field *F;
	int idx, vlen, ok;
	if (0 == rec) {
		fprintf (stderr, "ERR %s: 0 == rec\n", msg);
		exit (1);
	}
	if (! OPENISIS_RECOK (rec)) {
		fprintf (stderr, "ERR %s: ! RECOK: b %d u %d/%d f %d/%d\n",
			msg, rec->base, rec->used, rec->bytes, rec->len, rec->fields);
		exit (1);
	}
	if (len != rec->len) {
		fprintf (stderr, "ERR %s: len %d != %d\n", msg, rec->len, len);
		log_rec (LOG_ERROR, rec, 0, 0);
		exit (1);
	}
	if (0 <= used && used != rec->used - rec->base) {
		fprintf (stderr, "ERR %s: used %d (%d-%d) != %d\n",
			msg, (rec->used - rec->base), rec->used, rec->base, used);
		log_rec (LOG_ERROR, rec, 0, 0);
		exit (1);
	}
	ok = !0;
	for (idx = 0; len > idx; ++idx) {
		vlen = strlen (val[idx]);
		F = rec->field + idx;
		if (F->tag != tag[idx]) {
			fprintf (stderr, "ERR %s: fld[%d] tag %d != %d\n",
				msg, idx, F->tag, tag[idx]);
			ok = 0;
		}
		if (F->len != vlen ||
			strncmp (F->val, val[idx], vlen)) {
			fprintf (stderr, "ERR %s: fld[%d] val <%.*s> != <%s>\n",
				msg, idx, (int)F->len, F->val, val[idx]);
			ok = 0;
		}
	}
	if (! ok) {
		exit (1);
	}
}

int main (int argc, char **argv) {
	const char *args[32];
	const char *vals[32];
	int   tags[32];
	Rec  *rec  =  0;

	/* call lio_init to prepare stderr on windows */
	openIsisCOpen (0);

	if (1 < argc) {
#define EXPFLD (1332 + (1000 - 888))
		int bytes = 0, used = 0, num = atoi (argv[1]);
		printf ("entering loops (%d) ...\n", num);
		while (num) {
			int j;
			rec = 0;
			for (j = 1000; 1 <= --j;  ) {
				RADD (rec, j, _TheSummary, SUMLEN, !0);
			}
			for (j = 888; 666 <= --j;  ) {
				rec = rSet (rec, RDEL | RNOC, j, 0);
			}
			for (j = 666; 444 <= --j;  ) {
				rec = rSet (rec, RDEL, j, 0);
			}
			for (j = 444; 222 <= --j;  ) {
				rec = rSet (rec, RDEL | RNOC, j, 0);
			}
			for (j = 1333; 222 <= --j;  ) {
				RADD (rec, j, _TheSummary, SUMLEN, !0);
			}
			if (EXPFLD != rec->len) {
				printf ("%d: ERR: #len = %d, expected %d\n",
					num, rec->len, EXPFLD);
				exit (1);
			}
			if (0 == bytes) {
				bytes = rec->bytes;
				used  = rec->used;
				printf ("mem %d use %d ...\n",
					rec->bytes, rec->used);
			}
			else {
				if (bytes != rec->bytes || used != rec->used) {
					printf ("%d: ERR: mem = %d use = %d\n",
						num, rec->bytes, rec->used);
					exit (1);
				}
				if (0 == (num % 100)) {
					printf ("%d ...\n", num);
				}
			}
			mFree (rec);
			--num;
		}
		printf ("ok.\n");
		exit (0);
	}

	args[0] = "20";
	args[1] = "Mary";
	rec = rSet (rec, RARGV | 2, args);
	tags[0] = 20;
	vals[0] = args[1];
	check ("A", rec, tags, vals, 1, 4);

	args[0] = "22";
	args[1] = "1953";
	args[2] = "70";
	args[3] = "Italy";
	args[4] = "98";
	args[5] = "illegal";
	args[6] = "20";
	args[7] = "John";
	rec = rSet (rec, RARGV | RFDT | 8, &_TheFdt, args);
	tags[0] = 20;
	vals[0] = "Mary";
	tags[1] = 22;
	vals[1] = "1953";
	tags[2] = 70;
	vals[2] = "Italy";
	tags[3] = 20;
	vals[3] = "John";
	check ("B", rec, tags, vals, 3, 13);

	args[0] = "98";
	args[1] = "illegal";
	args[2] = "20";
	args[3] = "John";
	rec = rSet (rec, RARGV | RFDT | RIGN | 4, &_TheFdt, args);
	check ("C", rec, tags, vals, 4, 17);

	rec = rSet (rec, RDEL, 20, 0);
	tags[0] = 22;
	vals[0] = "1953";
	tags[1] = 70;
	vals[1] = "Italy";
	check ("D", rec, tags, vals, 2, 9);

	rec = rSet (rec, RDFLT | RFDT, &_TheFdt,
		81, "naligned", 22, "already there", 0);
	tags[2] = 81;
	vals[2] = "2";
	check ("D1", rec, tags, vals, 3, 10);

	tags[3] = 234;
	vals[3] = "foo";
	rec = rSet (rec, RDFLT, 234, "foo", 0);
	check ("D2", rec, tags, vals, 4, 13);

	rec = rSet (rec, RDEL, 234, 81, 0);
	check ("D3", rec, tags, vals, 2, 13);

	rec = rSet (rec, 0, 20, "Mary", 20, "James", 90, "Alabama", 0);
	tags[2] = 20;
	vals[2] = "Mary";
	tags[3] = 20;
	vals[3] = "James";
	tags[4] = 90;
	vals[4] = "Alabama";
	check ("E", rec, tags, vals, 5, 29);

	rec = rSet (rec, RFDT | RCHG, &_TheFdt,
		20, "Lary", 70, "Greece", 70, "Cuba", 42, "Folklore from Africa",
		81, "invalid", 0);
	tags[0] = 22;
	vals[0] = "1953";
	tags[1] = 70;
	vals[1] = "Greece";
	tags[2] = 20;
	vals[2] = "Lary";
	tags[3] = 90;
	vals[3] = "Alabama";
	tags[4] = 70;
	vals[4] = "Cuba";
	tags[5] = 42;
	vals[5] = "Folklore from Africa";
	check ("F", rec, tags, vals, 6, 45);

	rec = rSet (rec, 0, 20, "Peter", 20, "Gary", 70, "Egypt", 0);
	tags[6] = 20;
	vals[6] = "Peter";
	tags[7] = 20;
	vals[7] = "Gary";
	tags[8] = 70;
	vals[8] = "Egypt";
	check ("G", rec, tags, vals, 9, 59);

	args[0] = "author[1]";
	args[1] = "81";
	args[2] = "70";
	rec = rSet (rec, RFDT | RARGV | RDEL | 3, &_TheFdt, args);
	tags[0] = 22;
	vals[0] = "1953";
	tags[1] = 20;
	vals[1] = "Lary";
	tags[2] = 90;
	vals[2] = "Alabama";
	tags[3] = 42;
	vals[3] = "Folklore from Africa";
	tags[4] = 20;
	vals[4] = "Gary";
	check ("H", rec, tags, vals, 5, 39);

	args[0] = "author[0]";
	args[1] = "May";
	args[2] = "summary";
	args[3] = _TheSummary;
	args[4] = "soldout";
	args[5] = "format";
	args[6] = "aligned";
	rec = rSet (rec, RFDT | RARGV | RCHG | RNOC | 7, &_TheFdt, args);
	vals[1] = "May";
	tags[5] = 49;
	vals[5] = _TheSummary;
	tags[6] = 82;
	vals[6] = "1";
	tags[7] = 81;
	vals[7] = "73";
	check ("I", rec, tags, vals, 8, 42 + SUMLEN);

	args[0] = "20[0]";
	args[1] = "Marilyn";
	args[2] = "49[1]";
	args[3] = _TheSummary;
	rec = rSet (rec, RARGV | RCHG | 4, args);
	vals[1] = "Marilyn";
	tags[8] = 49;
	vals[8] = _TheSummary;
	check ("J", rec, tags, vals, 9, 45 + 2 * SUMLEN);

	rec = rSet (rec, RDEL | 2, 82, 22, 0);
	tags[0] = 20;
	vals[0] = "Marilyn";
	tags[1] = 90;
	vals[1] = "Alabama";
	tags[2] = 42;
	vals[2] = "Folklore from Africa";
	tags[3] = 20;
	vals[3] = "Gary";
	tags[4] = 49;
	vals[4] = _TheSummary;
	tags[5] = 81;
	vals[5] = "73";
	tags[6] = 49;
	vals[6] = _TheSummary;
	check ("K", rec, tags, vals, 7, 40 + 2 * SUMLEN);

	rec = rSet (rec, RFDT | RCHG, &_TheFdt,
		82, "false", 81, "2", 49, "overview", 0);
	vals[4] = "overview";
	vals[5] = "2";
	tags[6] = 82;
	vals[6] = "0";
	check ("L", rec, tags, vals, 7, 48);

	mFree (rec);

	printf ("ok.\n");
	return 0;
}