- Subject: [slang-users] A Nice demo of USing MMT types in C
- From: Ben Duncan <linux4ms@xxxxxxx>
- Date: Tue, 19 Jun 2007 12:28:05 -0500
Attached is a Demo of both a C program and the .sl program.
It is used a Active demo to teach about using MMT types,
and calling / accessing C functions / variables from inside
of the S-Lang environment.:
--
Ben Duncan - Business Network Solutions, Inc. 336 Elton Road Jackson MS,
39212
"Never attribute to malice, that which can be adequately explained by stupidity"
- Hanlon's Razor
/*
********************************************************************
* This is the program testmmt.c. It is a DEMO program that is an *
* attempt to document via a working MODEL, the S-lang C Api *
* using program variables, and the Memeory Managed types. *
* Memory Managed Types are where we wish to have a "item"/type *
* that we wish to use thru our C program, but be controlled by *
* The S-Lang environment. *
* *
* Written By Ben Duncan of Jackson, MS and released under the *
* GPL 2 license and higher. Copyrighted 2007 *
* Compile with the following statement: *
* gcc -shared -fPIC -I /usr/include -I ../include -W1,-R/usr/lib \ *
* -lm -o testmmt-module.so testmmt.c *
* then copy to the slang module root directory. *
********************************************************************
*/
#include <slang.h>
SLANG_MODULE(testmmt);
static char *Module_Version_String = "$Revision: 1.0 $";
static int TEST_Type_Id = 0;
int TEST_Initialized = 0;
/*
********************************************************************
* The following is our TEST structures we are going to use to *
* inside of the C program / S-Lang environment. Their intents' *
* are to modifiable, store some arbitrary type of data and be *
* passed around. It is ALSO the intent that multiple "NAMED" *
* instances of them can be created and be passed to / from the C *
* program for modification and access. I have CHOSEN NOT to make *
* make them ACCESABLE to the S-Lang interpreter, because I wish to *
* simulate something one would do when writing a DATABASE module *
* or other MODULE that may take ANY kind of structure. *
********************************************************************
*/
typedef struct Test_Item
{
int tli_lineid ;
char tli_displayname [32] ;
char tli_type [32] ;
char tli_program [32] ;
} testitem;
typedef struct Test_Set
{
char ts_heading [32] ;
int ts_count ;
char ts_status ;
testitem *ts_item ;
} testset;
/*
********************************************************************
* The VARIBALES where will place our C structure fields to MAKE *
* the data from the ABOVE structures avialable to the S-Lang *
* interpreter and environment. This is done with the function *
* status_struct. *
********************************************************************
*/
char Var_ts_heading [32] ;
static int Var_ts_count ;
char Var_ts_status ;
static int Var_tli_lineid ;
char Var_tli_displayname [32] ;
char Var_tli_type [32] ;
char Var_tli_program [32] ;
char *Var_heading_ptr = Var_ts_heading ;
char *Var_displayname_ptr = Var_tli_displayname ;
char *Var_type_ptr = Var_tli_type ;
char *Var_program_ptr= Var_tli_program ;
/*
********************************************************************
* This frees the internal C structure and all of the memeory *
* allocated for it. *
********************************************************************
*/
static void free_test_type (testset *ts_ptr)
{
if (ts_ptr->ts_item != NULL )
{
SLfree( (char *) ts_ptr->ts_item ) ;
}
SLfree ((char *) ts_ptr);
}
/*
********************************************************************
* Our DESTRUCTOR for the MMT. Called when the envrionment *
* gets shutdown. *
********************************************************************
*/
static void destroy_testset (SLtype type, VOID_STAR ptr)
{
testset *ts_ptr = (testset *) ptr;
(void) type;
free_test_type (ts_ptr ) ;
}
/*
********************************************************************
* This will create the C structures and initilize the memeory *
* required for it. IT IS ALSO where the Memory Managed Type (MMT) *
* will get created and then passed back to the S-Lang environment *
********************************************************************
*/
static SLang_MMT_Type *allocate_test_type ( void )
{
testitem *ti_ptr;
testset *ts_ptr;
SLang_MMT_Type *mmt;
/*
********************************************************************
* We are NOW going to MALLOC and initilize our 2 structures. *
********************************************************************
*/
ts_ptr = (testset *) SLmalloc (sizeof (testset));
if (ts_ptr == NULL)
{
return NULL;
}
memset ((char *) ts_ptr, 0, sizeof (testset));
ts_ptr->ts_item = NULL ;
ti_ptr = (testitem *) SLmalloc (sizeof (testitem));
if (ti_ptr == NULL)
{
free_test_type (ts_ptr) ;
return NULL;
}
memset ((char *) ti_ptr, 0, sizeof (testitem));
strcpy(ts_ptr->ts_heading, "ORIGNAL " ) ;
ts_ptr->ts_count = 0 ;
ts_ptr->ts_status = 'A' ;
ts_ptr->ts_item = ti_ptr ;
ti_ptr->tli_lineid = 1 ;
strcpy(ti_ptr->tli_displayname, "ORIGNAL " ) ;
strcpy(ti_ptr->tli_type, "ORIGNAL " ) ;
strcpy(ti_ptr->tli_program, "ORIGNAL " ) ;
/*
********************************************************************
* We are NOW going to ACTUALLY create our very OWN MMT at this *
* point. If we get a NULL return value, we are busted, so clear *
* out everthing we have done to this point .... *
********************************************************************
*/
if (NULL == (mmt = SLang_create_mmt (TEST_Type_Id, (VOID_STAR) ts_ptr)))
{
free_test_type (ts_ptr) ;
return NULL;
}
return mmt;
}
/*
********************************************************************
* This is OUR function we call from within the interpretor to *
* get our MMT created. Notice HOW we DO NOT return any VALUES on *
* any KIND of status. We are PUSHING the MMT onto the stack, if we *
* have sucesfully created it, otherwise we push a NULL onto the *
* stack. We will have to TEST inside of our S-Lang script, for the *
* NULL value and take the necesary action if a NULL gets returned. *
* We avoid using a RETURN of any value, because then we WILL have *
* to deal with the return CODES as well. This is a simplier way to *
* process the creation of a MMT item. *
********************************************************************
*/
static void create_struct ( void )
{
SLang_MMT_Type *mmt;
if (NULL == (mmt = allocate_test_type () ))
{
(void) SLang_push_null();
return ;
}
if (-1 == SLang_push_mmt (mmt))
{
SLang_free_mmt (mmt);
(void) SLang_push_null();
return ;
}
return ;
}
/*
********************************************************************
* The following is designed to update OUR test structures in a very*
* simplistic mode. The following are the meanings : *
* First parameter is WHAT we are going to change, the second is *
* The VALUE to be changed *
* 1 = ts_heading, String Value *
* 2 = ts)count, INTEGER value *
* 3 = ts_status, SIngle Characer *
* 4 = tli_lineid, INTEGER value *
* 5 = tli_displayname, STRING value *
* 6 = tli_type, STRING value *
* 7 = tli_program, STRING value *
* *
* TO KEEP THINGS simple, we are going to be PUSHING these on the *
* stack in REVERSE order from the interpreter. SO the FIRST *
* value is going to be second and the second first, like this: *
* () = update_struct("MY VALUE", 1 MMT ) ; *
* *
* Note that we are USING a "pointer" de-reference to get to the *
* TEST ITEMS from a pointer in the TEST SET. This is example of *
* One could build a simple structure head into a really complex *
* structure of a linked list. *
********************************************************************
*/
static int update_struct ( void )
{
SLang_MMT_Type *mmt ;
int changeid ;
int integervalue ;
char *MyString = NULL ;
testset *ts_ptr ;
testitem *ti_ptr ;
if (NULL == (mmt = SLang_pop_mmt (TEST_Type_Id)))
return -1 ;
ts_ptr = SLang_object_from_mmt (mmt);
if (ts_ptr->ts_item == NULL )
{
SLang_verror (SL_NOT_IMPLEMENTED,
"WE DO NOT HAVE A DETAIL LINE !!");
SLang_free_mmt (mmt);
return -1 ;
}
ti_ptr = ts_ptr->ts_item ;
if (SLang_Num_Function_Args != 3 )
{
SLang_verror (SL_INTRINSIC_ERROR,
"INVALID NUMBER OF ARGUMENTS PASSED !!!! " ) ;
return -1 ;
}
if (-1 == SLang_pop_integer(&changeid))
{
SLang_verror (SL_INTRINSIC_ERROR,
"INVALID INTEGER ARGUMENT PASSED !!!! " ) ;
return -1 ;
}
switch ( changeid )
{
case 1:
if (-1 == SLpop_string (&MyString))
{
SLang_verror (SL_INTRINSIC_ERROR,
"INVALID #1 STRING ARGUMENT PASSED !!!! " ) ;
return -1;
}
sprintf( ts_ptr->ts_heading , "%-30s", MyString ) ;
break ;
case 2:
if (-1 == SLang_pop_integer (&integervalue))
{
SLang_verror (SL_INTRINSIC_ERROR,
"INVALID #2 INTEGER ARGUMENT PASSED !!!! " ) ;
return -1;
}
ts_ptr->ts_count = integervalue ;
break ;
case 3:
if (-1 == SLang_pop_integer (&integervalue))
{
SLang_verror (SL_INTRINSIC_ERROR,
"INVALID #3 CHARACTER ARGUMENT PASSED !!!! " ) ;
return -1;
}
ts_ptr->ts_status = integervalue ;
break ;
case 4:
if (-1 == SLang_pop_integer (&integervalue))
{
SLang_verror (SL_INTRINSIC_ERROR,
"INVALID #4 INTEGERARGUMENT PASSED !!!! " ) ;
return -1;
}
ti_ptr->tli_lineid = integervalue ;
break ;
case 5:
if (-1 == SLpop_string (&MyString))
{
SLang_verror (SL_INTRINSIC_ERROR,
"INVALID #5 STRING ARGUMENT PASSED !!!! " ) ;
return -1;
}
sprintf( ti_ptr->tli_displayname , "%-30s", MyString ) ;
break ;
case 6:
if (-1 == SLpop_string (&MyString))
{
SLang_verror (SL_INTRINSIC_ERROR,
"INVALID #6 STRING ARGUMENT PASSED !!!! " ) ;
return -1;
}
sprintf( ti_ptr->tli_type , "%-30s", MyString ) ;
break ;
case 7:
if (-1 == SLpop_string (&MyString))
{
SLang_verror (SL_INTRINSIC_ERROR,
"INVALID #6 STRING ARGUMENT PASSED !!!! " ) ;
return -1;
}
sprintf( ti_ptr->tli_program , "%-30s", MyString ) ;
break ;
default:
SLang_verror (SL_INTRINSIC_ERROR,
"INVALID # ARGUMENT PASSED !!!! " ) ;
return -1;
}
if ( MyString != NULL )
{
SLfree ( MyString ) ;
}
SLang_free_mmt (mmt);
return 0 ;
}
/*
********************************************************************
* This clears out the structure we passed back to it. It simply *
* resets the values to some known values for our amusement. *
********************************************************************
*/
static void clear_struct ( void )
{
SLang_MMT_Type *mmt ;
testset *ts_ptr ;
testitem *ti_ptr ;
if (NULL == (mmt = SLang_pop_mmt (TEST_Type_Id)))
{
SLang_verror (SL_NOT_IMPLEMENTED,
"WE DO NOT HAVE A MMT TYPE !!");
return ;
}
ts_ptr = SLang_object_from_mmt (mmt);
if (ts_ptr->ts_item == NULL )
{
SLang_verror (SL_NOT_IMPLEMENTED,
"WE DO NOT HAVE A DETAIL LINE !!");
SLang_free_mmt (mmt);
return ;
}
ti_ptr = ts_ptr->ts_item ;
strcpy(ts_ptr->ts_heading, "RESET " ) ;
ts_ptr->ts_count = 0 ;
ts_ptr->ts_status = 'O' ;
ti_ptr->tli_lineid = 1 ;
strcpy(ti_ptr->tli_displayname, "RESET " ) ;
strcpy(ti_ptr->tli_type, "RESET " ) ;
strcpy(ti_ptr->tli_program, "RESET " ) ;
SLang_free_mmt (mmt);
}
/*
********************************************************************
* This Gets the VALUES stored on the MMT and puts them out on the *
* interpreter accessable variables. This is so we can have access *
* to whatever we have stored on our MMT structures *
********************************************************************
*/
static void status_struct ( void )
{
SLang_MMT_Type *mmt ;
testset *ts_ptr ;
testitem *ti_ptr ;
if (NULL == (mmt = SLang_pop_mmt (TEST_Type_Id)))
{
SLang_verror (SL_NOT_IMPLEMENTED,
"WE DO NOT HAVE A MMT TYPE !!");
return ;
}
ts_ptr = SLang_object_from_mmt (mmt);
if (ts_ptr->ts_item == NULL )
{
SLang_verror (SL_NOT_IMPLEMENTED,
"WE DO NOT HAVE A DETAIL LINE !!");
SLang_free_mmt (mmt);
return ;
}
ti_ptr = ts_ptr->ts_item ;
sprintf( Var_ts_heading, "%-30s", ts_ptr->ts_heading ) ;
Var_ts_count = ts_ptr->ts_count ;
Var_ts_status = ts_ptr->ts_status ;
Var_tli_lineid = ti_ptr->tli_lineid ;
sprintf( Var_tli_displayname, "%-30s", ti_ptr->tli_displayname ) ;
sprintf( Var_tli_type, "%-30s", ti_ptr->tli_type ) ;
sprintf( Var_tli_program, "%-30s", ti_ptr->tli_program ) ;
SLang_free_mmt (mmt);
}
/*
********************************************************************
* This closes out MMT structure, freeing all memeory that was *
* allocated to it. BE CAREFUL, the "NAMED" variable inside of your *
* S-Lang program will still be there, but the C structure will be *
* gone. *
* *
* As an alternative, you MIGHT wish to leave the "MASTER" *
* structure "alive" but have some sort of "status" flag during the *
* duration of the S-Lang script. *
********************************************************************
*/
static void close_struct ( void )
{
SLang_MMT_Type *mmt ;
testset *ts_ptr ;
testitem *ti_ptr ;
if (NULL == (mmt = SLang_pop_mmt (TEST_Type_Id)))
{
SLang_verror (SL_NOT_IMPLEMENTED,
"WE DO NOT HAVE A MMT TYPE !!");
return ;
}
ts_ptr = SLang_object_from_mmt (mmt);
if (ts_ptr->ts_item == NULL )
{
SLang_verror (SL_NOT_IMPLEMENTED,
"WE DO NOT HAVE A DETAIL LINE !!");
SLang_free_mmt (mmt);
return ;
}
ti_ptr = ts_ptr->ts_item ;
if (ti_ptr != NULL )
{
SLfree( (char *) ti_ptr ) ;
}
SLfree ((char *) ts_ptr);
SLang_free_mmt (mmt);
}
/*
********************************************************************
* The following is designed to create our Accessable Functions, *
* accessable named variable, accessable constants that are *
* AVAILBLE to and from the interpreter. Named variable's MAYBE *
* marked as read only, meaning ONLY the C program can MODIFY them *
* CONSTANTS are where we ill set up any type of NON MODIFIABLE *
* variables we wish to use from inside the interpreter *
********************************************************************
*/
#define I SLANG_INT_TYPE
#define S SLANG_STRING_TYPE
/*
********************************************************************
* See the cslang guide at 5.3.2 for more information on using *
* MAKE_INSTRINSIC macro. *
********************************************************************
*/
static SLang_Intrin_Fun_Type Module_Funs [] =
{
MAKE_INTRINSIC_0 ( "CreateStruct", create_struct, SLANG_VOID_TYPE ),
MAKE_INTRINSIC_0 ( "UpdateStruct", update_struct, SLANG_VOID_TYPE ),
MAKE_INTRINSIC_0 ( "ClearStruct", clear_struct, SLANG_VOID_TYPE ),
MAKE_INTRINSIC_0 ( "StatusStruct", status_struct, SLANG_VOID_TYPE ),
MAKE_INTRINSIC_0 ( "Close_Struct", close_struct, SLANG_VOID_TYPE ),
SLANG_END_INTRIN_FUN_TABLE
};
/*
********************************************************************
* See the cslang guide at 5.4.0 for more information on using *
* MAKE_VARIABLE macro. *
********************************************************************
*/
static SLang_Intrin_Var_Type Module_Variables [] = {
MAKE_VARIABLE("Var_Ts_Heading", &Var_heading_ptr, SLANG_STRING_TYPE, 1),
MAKE_VARIABLE("Var_Ts_Count", &Var_ts_count, SLANG_INT_TYPE, 0),
MAKE_VARIABLE("Var_Ts_Status", &Var_ts_status, SLANG_INT_TYPE, 0),
MAKE_VARIABLE("Var_Tli_Lineid", &Var_tli_lineid, SLANG_INT_TYPE, 0),
MAKE_VARIABLE("Var_Tli_displayname", &Var_displayname_ptr, SLANG_STRING_TYPE, 1),
MAKE_VARIABLE("Var_Tli_Type", &Var_type_ptr, SLANG_STRING_TYPE, 1),
MAKE_VARIABLE("Var_Tli_Program", &Var_program_ptr, SLANG_STRING_TYPE, 1),
SLANG_END_INTRIN_VAR_TABLE
};
/*
********************************************************************
* This is the MACRO to make CONSTANTS that are avialable to the *
* S-Lang environment. A Constant is a single Character or Integer *
* by defination. *
* It's usage is defined as :MAKE_ICONSTANT("VAR", <int|char>) *
* where "VAR is our S-lang constant named variable and the next *
* Parameter can be a integer or a SINGLE character type *
* We aslo have avialable the "MAKE_ICONSTANT_T(n,v,t)" to make a *
* constant variable named "n" of a single VALUE of "v" of the *
* type of "t" (I assume SLANG_INT_TYPE or SLANG_CHAR_TYPE ) *
********************************************************************
*/
static SLang_IConstant_Type Module_Constants [] = {
SLANG_END_ICONST_TABLE
};
#undef I
#undef S
/*
********************************************************************
* WHere we ACTUALLY do the registration of NEW class of data types *
* This is setting our S-Lang environment up to handle the "type" *
* we have created and are going to use throughout this program. *
* Of important notice, is that we are ONLY setting up the "testset"*
* and not the "testitem". This is BECAUSE testitem is NOT really *
* a NEW type (We could make it one) since it is a CHILD of the *
* testset type. As an idea, the testset could be the TYPE that *
* that gives you access into some sort of a linked list, but you *
* are not wanting the COMPLETE linked list to be of a *
* "type"/"class" *
********************************************************************
*/
static int register_test_type (void)
{
SLang_Class_Type *cl;
if (NULL == (cl = SLclass_allocate_class ("testset")))
return -1;
if (-1 == SLclass_set_destroy_function (cl, destroy_testset))
return -1;
/*
********************************************************************
* By registering as SLANG_VOID_TYPE, slang will dynamically *
* allocate a new type. *
********************************************************************
*/
if (-1 == SLclass_register_class (cl, SLANG_VOID_TYPE, sizeof (testset),
SLANG_CLASS_TYPE_MMT))
return -1;
/*
********************************************************************
* This SETS up our new type indicator *
********************************************************************
*/
TEST_Type_Id = SLclass_get_class_id (cl);
return 0;
}
/*
********************************************************************
* Here we are going the initilization routines. We are creating *
* a NAMED space with the "_ns" module then one that does not use *
* the named space. *
********************************************************************
*/
int init_testmmt_module_ns (char *ns_name)
{
SLang_NameSpace_Type *ns;
ns = SLns_create_namespace (ns_name);
if (ns == NULL)
return -1;
/*
********************************************************************
* WE must REGISTER any "NEW" types with S-Lang's interpreter via *
* SLclass_register_class. See the S-Lang library programmer's *
* guide for more information. *
********************************************************************
*/
if (-1 == register_test_type ())
return -1;
/*
********************************************************************
* Ok, we are going to pass to our SLang interperter all of our *
* things, such as the "functions" , named variables, constants *
* The named VARIABLES are defined variables FROM the C program *
* are directly accessable to the interpreter stack for reference *
********************************************************************
*/
if ( ( -1 == SLns_add_intrin_fun_table ( ns, Module_Funs, "__TESTMMT__" ) )
|| ( -1 == SLns_add_intrin_var_table ( ns, Module_Variables, NULL ) )
|| ( -1 == SLns_add_iconstant_table ( ns, Module_Constants, NULL ) ) )
return -1;
TEST_Initialized = 1;
return 0;
}
/*
********************************************************************
* This initilizer will do prettymuch the same thing as the above. *
* However, it does not MAP to any namespace so everthing is *
* GLOBAL as far as the interperter is converned. *
********************************************************************
*/
int init_testmmt_module ( void )
{
if (-1 == register_test_type ())
return -1;
if ( ( -1 == SLadd_intrin_fun_table ( Module_Funs, NULL ) )
|| ( -1 == SLadd_intrin_var_table ( Module_Variables, NULL ) )
|| ( -1 == SLadd_iconstant_table ( Module_Constants, NULL ) ) )
return -1;
TEST_Initialized = 1;
return 0;
}
/*
********************************************************************
* This function is designed to "shut" down the module safely. *
* You can put things in it such as, freeing MALLOC'd stuff, setting*
* variables to some sort of state, etc. It is optional *
********************************************************************
*/
void deinit_module ( void )
{
TEST_Initialized = 0;
}
************************** CUT HERE ********************************
% testmmt.sl
% Save this program as testmmt.sl
% run from the command line as >slsh testmmt.sl
%
% A TEst menu Case
% Add traceback Debug Flags
_debug_info = 1;
_traceback = 1;
import ("testmmt", "Global") ;
define print_structure ( StructIn )
{
StatusStruct ( StructIn ) ;
fprintf (stdout, "\nPrinting the STATUS data \n" ) ;
fprintf (stdout, "Var_Ts_Heading is |%-s| \n", Var_Ts_Heading ) ;
fprintf (stdout, "Var_Ts_Count is %d \n", Var_Ts_Count ) ;
fprintf (stdout, "Var_Ts_Status is %c \n", Var_Ts_Status ) ;
fprintf (stdout, "Var_Tli_Lineid is %d \n", Var_Tli_Lineid ) ;
fprintf (stdout, "Var_Tli_Displayname is |%-s| \n", Var_Tli_displayname ) ;
fprintf (stdout, "Var_Tli_type is |%-s| \n", Var_Tli_Type) ;
fprintf (stdout, "Var_Tli_program is |%-s| \n", Var_Tli_Program) ;
}
% MAKE_INTRINSIC_0 ( "CreateStruct", create_struct, SLANG_VOID_TYPE ),
% MAKE_INTRINSIC_0 ( "UpdateStruct", update_struct, SLANG_VOID_TYPE ),
% MAKE_INTRINSIC_0 ( "GetStruct", update_struct, SLANG_VOID_TYPE ),
% MAKE_INTRINSIC_0 ( "ClearStruct", clear_struct, SLANG_VOID_TYPE ),
% MAKE_INTRINSIC_0 ( "StatusStruct", status_struct, SLANG_VOID_TYPE ),
% MAKE_INTRINSIC_0 ( "Close_Struct", close_struct, SLANG_VOID_TYPE ),
% MAKE_VARIABLE("Var_Ts_Heading", &Var_ts_heading, SLANG_STRING_TYPE, 1),
% MAKE_VARIABLE("Var_Ts_Count", &Var_ts_count, SLANG_INT_TYPE, 1),
% MAKE_VARIABLE("Var_Tli_Lineid", &Var_tli_lineid, SLANG_INT_TYPE, 1),
% MAKE_VARIABLE("Var_Tli_displayname", &Var_tli_displayname, SLANG_STRING_TYPE, 1),
% MAKE_VARIABLE("Var_Tli_Type", &Var_tli_type, SLANG_STRING_TYPE, 1),
% MAKE_VARIABLE("Var_Tli_Program", &Var_tli_program, SLANG_STRING_TYPE, 1),
fprintf (stdout, "Creating the structures \n" ) ;
variable MyStruct = CreateStruct ( ) ;
if ( MyStruct == NULL )
{
fprintf (stdout, "WE DO NOT HAVE A STRUCTURE !!!! \n" ) ;
exit (-1) ;
}
variable SecondStruct = CreateStruct ( ) ;
if ( SecondStruct == NULL )
{
fprintf (stdout, "WE DO NOT HAVE A 2nd STRUCTURE !!!! \n" ) ;
exit (-1) ;
}
fprintf (stdout, "Getting the STATUS data \n" ) ;
StatusStruct ( MyStruct ) ;
print_structure ( MyStruct ) ;
variable C_VAL = 1 ;
UpdateStruct ( "NEW VALUE", C_VAL , MyStruct ) ;
print_structure ( MyStruct ) ;
fprintf (stdout, "\n GONNA TEST SECOND STRUCTURE !!! \n " ) ;
C_VAL = 1 ;
UpdateStruct ( "SECOND STRUCTURE ", C_VAL , SecondStruct ) ;
C_VAL = 3 ;
UpdateStruct ( 'Z' , C_VAL , SecondStruct ) ;
C_VAL = 5 ;
UpdateStruct ( "SECOND VALUE", C_VAL , SecondStruct ) ;
StatusStruct ( SecondStruct ) ;
print_structure ( SecondStruct ) ;
fprintf (stdout, "ALL DONE \n" ) ;
[2007 date index]
[2007 thread index]
[Thread Prev] [Thread Next]
[Date Prev] [Date Next]