[comp.databases] Informix schema => C structures

riddle@woton.UUCP (06/19/87)

#  sh archive - cd to a suitable directory and run this through sh
#
#  built on Thu Jun 18 16:30:20 CDT 1987 by woton!riddle
#
echo README
cat > README <<"%RoNnIe%RaYgUn%"

  The following are two awk scripts which might be of interest to some of
  you.  They convert an Informix schema into the C structures needed for
  interfacing with ALL-II routines.  The Makefile formalizing the
  relationship would look something like this:
  
  	test.c:	test.sch
  		awk -f $(BINDIR)/dbrec.awk test.sch > test.c
  	
  	test.h:	test.sch
  		awk -f $(BINDIR)/dbview.awk test.sch > test.h
  	
  	prog:	prog.c test.c test.h
  		cc -f -g -O prog.c -ldb -lm -o prog
  
  The program "prog.c" contains "#include" lines for "test.h" and "test.c".
  See the awk scripts themselves for sample input and output. 
  
  Caveats: these scripts aren't extremely smart, and in particular they
  can be confused by comments (I get around this by beginning each
  comment line between the "{" and "}" with a "#").  If someone would
  like to take this idea and turn it into an idiot-proof C program, I
  would be delighted. 
  
  --- Prentiss Riddle ("Aprendiz de todo, maestro de nada.")
  --- Opinions expressed are not necessarily those of Shriners Burns Institute.
  --- riddle@woton.UUCP  {ihnp4,harvard,seismo}!ut-sally!im4u!woton!riddle

%RoNnIe%RaYgUn%
#
echo dbrec.awk
cat > dbrec.awk <<"%RoNnIe%RaYgUn%"
#! /bin/awk
#
#	dbrec.awk -- awk script to convert an Informix schema into
#			a C record structure
#
#  Usage:  awk -f dbrec.awk foo.sch > foo.c
#
#  Diagnostics are produced as comments within the C output.
#
#  NOTE: schema keywords must be in lower case.
#
#  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
#  Author:	Prentiss Riddle
#		Shriners Burns Institute
#		610 Texas Ave.
#		Galveston, TX 77550 USA
#		(409)-761-4701
#		UUCP address: ihnp4!ut-sally!im4u!woton!riddle
#  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
#
#  History:
#  86.11.26  riddle	Original version.
#  86.12.11  riddle	Modified to ignore composite variables.
#  86.12.12  riddle	Added section to handle end of file even
#			  without "end" or "permissions" statement.
#  87.02.05  riddle	Added "edate" and "ydate" field types.
#  87.02.06  riddle	Added "FILE_struct" definition.
#
#====================================================================
#  Sample input:
#
#	database dummy
#	
#	file test
#	
#	field f1	type character length 3		index
#	field f2	type char 3
#	field f3	type date
#	field f4	type double
#	field f5	type float
#	field f6	type int
#	field f7	type integer
#	field f8	type long
#	field f9	type money
#	field f10	type serial
#	
#	permissions
#	
#	file	user riddle	access all
#	file	public		access read
#	
#	end
#
#  Sample output:
#
#	/* c record structure based on Informix schema
#	 * automagically produced using dbrec.awk
#	 */
#	/* Informix database: dummy  */
#	/* Informix file:     test  */
#	struct test_struct
#	{
#	char   f1 [ 4 ];
#	char   f2 [ 4 ];
#	long   f3 ;		/* Informix type "date" */
#	double f4 ;
#	float  f5 ;
#	int    f6 ;
#	int    f7 ;
#	long   f8 ;
#	double f9 ;		/* Informix type "money" */
#	long   f10 ;		/* Informix type "serial" */
#	};
#	struct test_struct test_rec;
#	#ifdef NF_test
#	#if NF_test != 10
#		fprintf(stderr, "compile problem in test_rec: NF_test != 10\n");
#		exit(-1);
#	#endif
#	#endif
#
#====================================================================


BEGIN	{ print "/* c record structure based on Informix schema"
	  print " * automagically produced using dbrec.awk"
	  print " */"
	  NFIELDS = 0
	}

/^[ 	]*database[ 	]/	{
	  if (DATABASE != "") {
	 	print "/* ERROR - database redefinition:"
		print " *     ", $0
		print " */"
		exit
	  }
	  DATABASE = $2
	  print "/* Informix database:", DATABASE, " */"
	}

/^[ 	]*file[ 	]/	{
	  if (FILE != "") {
	 	print "/* ERROR - file redefinition:"
		print " *     ", $0
		print " */"
		exit
	  }
	  FILE = $2
	  print "/* Informix file:    ", FILE, " */"
	  printf "struct %s_struct\n", FILE
	  print "{"
	}

/^[ 	]*field[	 ]/	{
	  NFIELDS++;
	  if ($4 == "char" || $4 == "character") {
		if ($5 == "len" || $5 == "length") {
			LEN = $6 + 1
		} else {
#			## "length" keyword omitted
			LEN = $5 + 1
		}
		print "char  ", $2, "[", LEN, "];"
	  } else if ($4 == "composite") {
		print "/* Composite field ignored:"
		print " *	", $0
		print " */"
		NFIELDS--;
	  } else if ($4 == "date") {
		print "long  ", $2, ";		/* Informix type \"date\" */"
	  } else if ($4 == "double") {
		print "double", $2, ";"
	  } else if ($4 == "edate") {
		print "long  ", $2, ";		/* Informix type \"edate\" */"
	  } else if ($4 == "float") {
		print "float ", $2, ";"
	  } else if ($4 == "int" || $4 == "integer") {
		print "int   ", $2, ";"
	  } else if ($4 == "long") {
		print "long  ", $2, ";"
	  } else if ($4 == "money") {
		print "double", $2, ";		/* Informix type \"money\" */"
	  } else if ($4 == "serial") {
		print "long  ", $2, ";		/* Informix type \"serial\" */"
	  } else if ($4 == "ydate") {
		print "long  ", $2, ";		/* Informix type \"ydate\" */"
	  } else {
		print "/* Unrecognized field statement:"
		print " *      ", $0
		print " */"
		NFIELDS--;
	  }
	}

/^[ 	]*end[ 	]/ || /^[ 	]*permissions[ 	]*$/ {
	  exit
	}

END	{
	  printf "};\n"
	  printf "struct %s_struct %s_rec;\n", FILE, FILE
#	  # The following generates c pre-processor code to check that the
#	  # number of fields processed by dbrec.awk and dbview.awk are
#	  # in agreement.
	  printf "#ifdef NF_%s\n", FILE
	  printf "#if NF_%s != %d\n", FILE, NFIELDS
	  printf "\tfprintf(stderr, \"compile problem in %s_rec: NF_%s != %d\\n\");\n", FILE, FILE, NFIELDS
	  printf "\texit(-1);\n"
	  printf "#endif\n"
	  printf "#endif\n"
	}
%RoNnIe%RaYgUn%
#
echo dbview.awk
cat > dbview.awk <<"%RoNnIe%RaYgUn%"
#! /bin/awk
#
#	dbview.awk -- awk script to convert an Informix schema into
#			a C "dbview" structure
#
#  Usage:  awk -f dbview.awk foo.sch > foo.h
#
#  Diagnostics are produced as comments within the C output.
#
#  NOTE: schema keywords must be in lower case.
#
#  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
#  Author:	Prentiss Riddle
#		Shriners Burns Institute
#		610 Texas Ave.
#		Galveston, TX 77550 USA
#		(409)-761-4701
#		UUCP address: ihnp4!ut-sally!im4u!woton!riddle
#  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
#
#  History:
#  86.11.26  riddle	Original version.
#  86.12.11  riddle	Modified to ignore composite keys.
#  86.12.12  riddle	Modified to keep track of whether or not a comma is
#			  needed between fields (this is to avoid getting a
#			  spurious extra comma before the final "};").
#			Added section to handle end of file even in case
#			  of missing "end" or "permissions" statement.
#			Added NFIELDS definition.
#
#============================================================================
#  Sample input:
#
#	database dummy
#	
#	file test
#	
#	field f1	type character length 3		index
#	field f2	type char 3
#	field f3	type date
#	field f4	type double
#	field f5	type float
#	field f6	type int
#	field f7	type integer
#	field f8	type long
#	field f9	type money
#	field f10	type serial
#	
#	permissions
#	
#	file	user riddle	access all
#	file	public		access read
#	
#	end
#
#  Sample output:
#
#	/* c "dbview" structure based on Informix schema
#	 * automagically produced using dbview.awk
#	 */
#	/* Informix database: dummy  */
#	/* Informix file:     test  */
#	struct dbview test_list[]=
#	{
#	{"f1"},
#	{"f2"},
#	{"f3"},
#	{"f4"},
#	{"f5"},
#	{"f6"},
#	{"f7"},
#	{"f8"},
#	{"f9"},
#	{"f10"}
#	};
#	#define NF_test	10	/* no. of fields in test_list */
#
#====================================================================


BEGIN	{ print "/* c \"dbview\" structure based on Informix schema"
	  print " * automagically produced using dbview.awk"
	  print " */"
	  NEEDCOMMA = 0
	  NFIELDS = 0
	}

/^[ 	]*database[ 	]/	{
	  if (DATABASE != "") {
	 	print "/* ERROR - database redefinition:"
		print " *     ", $0
		print " */"
		exit
	  }
	  DATABASE = $2
	  print "/* Informix database:", DATABASE, " */"
	}

/^[ 	]*file[ 	]/	{
	  if (FILE != "") {
	 	print "/* ERROR - file redefinition:"
		print " *     ", $0
		print " */"
		exit
	  }
	  FILE = $2
	  print "/* Informix file:    ", FILE, " */"
	  printf "struct dbview %s_list[]=\n", FILE
	  print "{"
	}

/^[ 	]*field[	 ]/	{
	  if (NEEDCOMMA == 1) {
#		# print comma separator between fields
		printf ",\n"
	  }
	  if ($4 != "composite") {
		printf "{\"%s\"}", $2
		NEEDCOMMA = 1
		NFIELDS++
	  } else {
		print "/* Composite field ignored:"
		print " *	", $0
		print " */"
		NEEDCOMMA = 0
	  }
	}

/^[ 	]*end[ 	]/ || /^[ 	]*permissions[ 	]*$/	{
	  exit
	}

END	{
	  printf "\n};\n"
	  printf "#define NF_%s\t%d\t/* no. of fields in %s_list */\n", FILE, NFIELDS, FILE
	}

%RoNnIe%RaYgUn%
#
wc  README dbrec.awk dbview.awk
echo total should be: 337 1544 8528 total
# end of sh archive