english
version "1.0"
identify "%Z%%M% %I% %E%"

#: Copyright (c) 1995-2005 by Wayne C. Gramlich.
#, All rights reserved.

module c_import

#: This module implements functionality that allows the importing of
#, C code into STIPPLE program.  If the C code is well written and
#, this module is used properly, the result is safe and proper STIPPLE
#, code; otherwise, you can get some extremely strange behavior using
#, this module.

define c_bind				#: C/STIPPLE name binding
    record
	c_name string			#: The C name
	stipple_comment string		#: The STIPPLE comment
	stipple_name string		#: The STIPPLE type name
    generate allocate, erase, print

define c_define				#: C #define
    record
	c_name string			#: Name of #define
	value string			#: Value of #define
    generate allocate, erase, print

define c_enumeration			#: C/STIPPLE enumeration
    record
	c_name string			#: C name of type
	exact_match logical		#: ({true}=>exact;{false}=>loose) match
	kind c_kind			#: Kind of C enumeration
	items vector[c_bind]		#: List of item names
	stipple_co_type string		#: STIPPLE type name for C enum values
	stipple_comment string		#: STIPPLE comment string
	stipple_name string		#: STIPPLE type name for STIPPLE values
    generate allocate, erase, print

define c_field				#: One field of a record/struct
    record
	c_name string			#: The C name for the field
	stipple_comment string		#: The STIPPLE comment for the field
	stipple_name string		#: The STIPPLE name for the field
	type c_sub_type			#: The type of the field
	generate_get logical		#: {true} generate a get routine
	generate_set logical		#: {true} generate a set routine
    generate allocate, erase, print

define c_kind				#: Kind of C structure definition
    enumeration
	defines				#: enum is a bunch of #define's
	enum				#: enum name {...};
	struct				#: struct name {...};
	typedef_enum			#: typedef enum {...} name;
	typedef_struct			#: typedef struct {...} name;
	typedef_struct_pointer		#: typedef struct {...} *name;
    generate print

define c_import				#: Top-level C import object
    record
	defines vector[c_define]	#: List of #define directives
	enumerations vector[c_enumeration] #: List of enumeration types
	import_logical logical		#: {true}=>import logical module
	import_out_stream logical	#: {true}=>import out_stream module
	import_string logical		#: {true}=>import string module
	import_system logical		#: {true}=>import system module
	import_table logical		#: {true}=>import table module
	imports vector[string]		#: List of imported modules
	includes vector[string]		#: Included strings
	include_paths vector[string]	#: Include directory paths
	module_name string		#: STIPPLE module name
	records vector[c_record]	#: All defined records
	type_character c_sub_type	#: Character type
	type_logical c_sub_type		#: Logical type
	type_integer c_sub_type		#: Integer type
	type_short_integer c_sub_type	#: Short integer type
	type_short_unsigned c_sub_type	#: Short unsigned integer type
	type_string c_sub_type		#: C string type
	type_unsigned c_sub_type	#: Unsigned type
    generate allocate, erase, print

define c_options			#: Options used
    record
	includes vector[string]		#: -I <include_file>
	output_file_name string		#: -o <output_file_name>
	c_generate logical		#: -c (generate C file)
	stipple_generate logical	#: -s (generate STIPPLE file)
    generate allocate, erase, print	

define c_record				#: C/STIPPLE struct/record
    record
	c_name string			#: The C name of the struct
	external logical		#: {true}=>emit an extern record
	fields vector[c_field]		#: The fields of the struct/record
	generate_print logical		#: {true}=>generate print procedure
	generate_new logical		#: {true}=>generate new procedure
	kind c_kind			#: Kind of C struct/typedef
	records vector[c_record]	#: Records defined
	stipple_comment string		#: The STIPPLE comment for the record
	stipple_name string		#: The STIPPLE name of the record
    generate allocate, erase, print

define c_sub_type			#: C/STIPPLE type
    variant kind c_type_kind
	character null			#: 8-bit unsigned character
	integer null			#: Signed integer
	logical null			#: Logical/bool type
	opaque c_bind			#: Type is opque
	pointer c_bind			#: Type is a pointer
	short_integer null		#: Short integer
	short_unsigned null		#: Unsigend short
	string null			#: Type is a C string
	unsigned null			#: Unsigned integer
    generate allocate, erase, print



#: {c_enumeration} routines:

procedure c_initial_generate@c_enumeration
    takes
	enumeration c_enumeration
	c_stream out_stream
    returns_nothing

    #: This procedure will generate the initial object declaration
    #, for the C type associated with {enumeration}.


procedure c_initialize_generate@c_enumeration
    takes
	enumeration c_enumeration
	c_stream out_stream
    returns_nothing

    #: This procedure will generate the initialization routine for
    #: the C type associated with {enumeration}.


procedure c_unsigned_convert_generate@c_enumeration
    takes
	enumeration c_enumeration
	c_stream out_stream
    returns_nothing

    #: This procedure will generate the unsigned converstion routine
    #, for the C type associated with {enumeration}.


procedure c_value_get_generate@c_enumeration
    takes
	enumeration c_enumeration
	c_stream out_stream
    returns_nothing

    #: This procedure will generate the c_value_get routine for {enumeration}
    #, to {c_stream}.


procedure format@c_enumeration
    takes
	enumeration c_enumeration
	out_stream out_stream
	format string
	offset unsigned
    returns_nothing

    #: This procedure will output {enumeration} to {out_stream}.


procedure item_append@c_enumeration
    takes
	enumeration c_enumeration
	c_name string
	stipple_name string
	stipple_comment string
    returns_nothing

    #: This procedure will add the enumeration item binding of {c_name}
    #, {stipple_name} to {enumeration}.  {stipple_comment} will appear
    #, in the generated STIPPLE code next to the item name.


procedure stipple_convert_generate@c_enumeration
    takes
	enumeration c_enumeration
	stipple_stream out_stream
    returns_nothing

    #: This procedure will output a procedure for convert the C enumeration
    #, co-type into the STIPPLE co-type.


procedure stipple_define_generate@c_enumeration
    takes
	enumeration c_enumeration
	stipple_stream out_stream
    returns_nothing

    #: This procedure will output a declaration for {enumeration} to
    #, {stipple_stream).


procedure stipple_equal_generate@c_enumeration
    takes
	enumeration c_enumeration
	stipple_stream out_stream
    returns_nothing

    #: This procedure will output the equal procedure for the C enumeration
    #, co-type associated with {enumeration} to {stipple_stream}.


procedure stipple_hash_generate@c_enumeration
    takes
	enumeration c_enumeration
	stipple_stream out_stream
    returns_nothing

    #: This procedure will output the hash procedure for the C enumeration
    #, co-type associated with {enumeration} to {stipple_stream}.


procedure stipple_print_generate@c_enumeration
    takes
	enumeration c_enumeration
	stipple_stream out_stream
    returns_nothing

    #: This procedure will output a procedure for printing the C enumeration
    #, co-type associated with {enumeration} to {stipple_stream}.


procedure stipple_unsigned_convert_generate@c_enumeration
    takes
	enumeration c_enumeration
	stipple_stream out_stream
    returns_nothing

    #: This procedure will output the {unsigned_convert} declaration for
    #, the C enumeration co-type associated with {enumeration} to
    #, {stipple_stream}.


#: {c_field} routines:

procedure stipple_get_generate@c_field
    takes
	field c_field
	record c_record
	stipple_stream out_stream
    returns_nothing

    #: This procedure will output the STIPPLE procedure declaration for
    #, the for {field}_get procedure.


procedure stipple_set_generate@c_field
    takes
	field c_field
	record c_record
	stipple_stream out_stream
    returns_nothing

    #: This procedure will output the STIPPLE procedure declaration for
    #, the for {field}_set procedure.


#: {c_import} routines:

procedure c_generate@c_import
    takes
	c_import c_import
	c_stream out_stream
    returns_nothing

    #: This procedure will output the C code associated with {c_import}
    #, to {c_stream}.


procedure create@c_import
    takes
	module_name string
    returns c_import

    #: This procedure will create and return a {c_import} object
    #, with a module name of {module_name}.


procedure define_append@c_import
    takes
	c_import c_import
	c_name string
	value string
    returns_nothing

    #: This procedure will append a #define directive the the #define
    #, directive list in {c_import}.  THe #define will have a name of
    #, {c_name} and a value of {value}.


procedure import_append@c_import
    takes
	c_import c_import
	import_name string
    returns_nothing

    #: This procedure will add {import_name} to the imports list in {c_import}.
	

procedure import_standard@c_import
    takes
	c_import c_import
    returns_nothing

    #: This procedure will append a bunch of standard modules to imports list
    #, {c_import}.


procedure include_append@c_import
    takes
	c_import c_import
	include_name string
    returns_nothing

    #: This procedure will append {include_name} to the inlcude list in
    #, {c_import}.  In ANSI-C, there are two syntaxes for include statements --
    #, file names enclosed in double quotes and file names enclosed in
    #, angle brackets.  An angle bracket include file is specified by
    #, making the first and last character of {include_name} be "<" and
    #, ">", respectively; otherwise the include name will be enclosed
    #, in double quotes.  It is incorrect to add double quotes to
    #, {include_name}.


procedure include_path_append@c_import
    takes
	c_import c_import
	include_path string
    returns_nothing

    #: This procedure will append {include_path} to the include directory
    #, path list in {c_import}.


procedure procedure0_append@c_import
    takes
	c_import c_import
	c_name string
	stipple_name string
	stipple_type string
	return_type c_sub_type
	comment string
    returns_nothing

    #: This procedure will ...


procedure procedure1_append@c_import
    takes
	c_import c_import
	c_name string
	stipple_name string
	stipple_type string
	return_type c_sub_type
	argument1_name string
	argument1_type c_sub_type
	comment string
    returns_nothing

    #: This procedure will ...


procedure procedure2_append@c_import
    takes
	c_import c_import
	c_name string
	stipple_name string
	stipple_type string
	return_type c_sub_type
	argument1_name string
	argument1_type c_sub_type
	argument2_name string
	argument2_type c_sub_type
	comment string
    returns_nothing

    #: This procedure will ...


procedure process@c_import
    takes
	c_import c_import
	program_name string
	system system
    returns logical

    #: This procedure will process any command line options in {system} and
    #, output any files requested by the options using {c_import}.  {true}
    #, is returned if there are any errors; otherwise, {false} is returned.


procedure stipple_generate@c_import
    takes
	c_import c_import
	stipple_stream out_stream
    returns_nothing

    #: This procedure will output the C code associated with {c_import}
    #, to {stipple_stream}.


#: {c_record} routines:

procedure c_get_set_generate@c_record
    takes
	record c_record
	c_stream out_stream
    returns_nothing

    #: This procedure will generate the C get/set procedure declarations
    #, for each field in {record} and output them to {c_stream}.


procedure c_allocate_generate@c_record
    takes
	record c_record
	c_stream out_stream
    returns_nothing

    #: This procedure will generate the C allocation routine for {record}
    #, and output it to {c_stream}.


procedure c_offset_verify_generate@c_record
    takes
	record c_record
	c_stream out_stream
    returns_nothing

    #: This procedure will output verification code to {c_stream} that will
    #, verify that each field in the C version of {record} has the exact
    #, same offset as the the STIPPLE version of {record}.


procedure c_print_generate@c_record
    takes
	record c_record
	c_stream out_stream
    returns_nothing

    #: This procedure will generate the C print routine for {record}
    #, and output it to {c_stream}.


procedure c_struct_generate@c_record
    takes
	record c_record
	c_stream out_stream
    returns_nothing

    #: This procedure will output the C structure for {record} to {c_stream}.


procedure enumeration_create@c_import
    takes
	c_import c_import
	kind c_kind
	c_name string
	stipple_name string
	stipple_comment string
	stipple_co_type string
    returns c_enumeration

    #: This procedure will create and return a {c_enumeration} object
    #, allocated from {c_import}.  The C type name will be {c_name}
    #, and be of {kind} {enum}, {typedef_eum}, or {defines}.  There will
    #, be either one or two STIPPLE types depending upon whether there
    #, is an exact match between the STIPPLE item values and the C item
    #, values.  If there is an exact match of item values, the C enum type
    #, is indistinguishable from the STIPPLE enumeration type and only
    #, one STIPPLE type is needed.  The one type case is specified by
    #, having {stipple_co_type} be the empty string.  Conversely, if the
    #, item values do not exactly match, two STIPPLE types are needed.
    #, One type represents the C enum values ({stipple_co_type}) and the
    #, other type represents the the enumeration value after it has been
    #, converted to the {stipple_name} type.


procedure format@c_record
    takes
	record c_record
	out_stream out_stream
	format string
	offset unsigned
    returns_nothing

    #: This procedure will output {record} to {out_stream}.


procedure record_create@c_import
    takes
	c_import c_import
	kind c_kind
	c_name string
	stipple_name string
	stipple_comment string
	external logical
	generate_print logical
	generate_new logical
    returns c_record

    #: This procedure will create and return a {c_record} object allocated
    #, from {c_import} of type {kind}.  The struct name in the ANSI-C code
    #, will be {c_name} and the record name in STIPPLE will be
    #, {stipple}.  If {stipple_comment} is not empty and starts with
    #, a "#" character, {stipple_comment} will be appended as a comment
    #, to the end of {define} clause.  If {external} is {true}, all
    #, accesses to the C structure are done through get and set procedures;
    #, otherwise, if {external} is {false}, both the order and size
    #, of the field names in the C struct exactly match corresponding
    #, field names in the STIPPLE record.  If {generate_print} is {true}
    #, a print procedure is generated.  If {generate_new} is {true} an
    #, allocation procedure is generated.


procedure field_append@c_record
    takes
	record c_record
	c_name string
	c_sub_type c_sub_type
	stipple_name string
	stipple_comment string
	generate_get logical
	generate_set logical
    returns_nothing

    #: This procedure will add a field to {record} with a ANSI-C name
    #, of {c_name} and an ANSI-C type extracted from {c_sub_type}.  The
    #, corresponding field name in the STIPPLE code will be {stipple_name}.
    #, If {stipple_name} is empty, {c_name} is used in its stead.
    #, If the first character in {stipple_comment} is a "#", {stipple_comment}
    #, will be output immediately after the field name in the STIPPLE code.
    #, If {generate_get} is {true}, a get routine will be generated.
    #, If {generate_set} is {true}, a set routine will be generated.


procedure stipple_define_generate@c_record
    takes
	record c_record
	stipple_stream out_stream
    returns_nothing

    #: This procedure will output the {define} declaration for {record}
    #, to {stipple_stream}.


#: {c_sub_type} routines:

procedure pointer_create@c_sub_type
    takes
	c_name string
	stipple_name string
    returns c_sub_type

    #: This procedure will create and return a {c_sub_type} containing
    #, the {c_name} to {stipple_name} binding.


procedure format@c_sub_type
    takes
	c_sub_type c_sub_type
	out_stream out_stream
	format string
	offset unsigned
    returns_nothing

    #: This procedure will output {c_sub_type} to {out_stream}.