/**************************************************************************
* PROJECT: DEMETER Version 4.0
* MODULE: GENERATION
* FILE: gen_user_calls.c
* SYSTEM: C++ AT&T version 2.0 on sun, UNIX 4.3 BSD
*--------------------------------------------------------------------------
* COPYRIGHT (c) 1990 Northeastern University
* Prof. Karl J. Lieberherr
*--------------------------------------------------------------------------
* AUTHOR: Walter Hursch
*
* DATE: December 6, 1990
* REVISED: January 10, 1991
* no pp() implemented yet
* August 20, 1993
* change to u-main.C
*--------------------------------------------------------------------------
* DESCRIPTION:
* Generates the file user-calls.i in the directory path from class
* dictionary in intermediate notation. User-calls.i is not generated
* if it already exists in the given directory.
*
**************************************************************************/
/*
* $Log: gen_user_calls.C,v $
* Revision 5.4.1.1 1994/02/28 16:35:35 huersch
* *** empty log message ***
*
* Revision 5.4 1994/02/28 16:35:34 huersch
* *** empty log message ***
*
* Revision 5.3.1.1 1994/01/26 19:06:03 huersch
* No changes.
*
* Revision 5.3 1994/01/26 19:06:02 huersch
* *** empty log message ***
*
* Revision 5.2.1.1 1994/01/24 16:16:25 huersch
* No changes.
*
* Revision 5.2 1994/01/24 16:16:24 huersch
* *** empty log message ***
*
* Revision 5.1.1.1 1993/11/15 15:18:00 demeter
* *** empty log message ***
*
* Revision 5.0.1.6 1993/10/13 14:29:40 huersch
* Give better error message in main.C.sample; bug fix.
*
* Revision 5.0.1.5 1993/10/12 18:50:58 huersch
* Nop.
*
* Revision 5.0.1.4 1993/10/12 17:48:03 huersch
* Routed demeter-output to notmod/tmp.
*
*/
/**************************************************************************
Class dictionary used (intermediate notation):
;;; produced by extract-cd '(I-P1|O-P1)'
;;; produced by extract-cd 'O-P1'
; : O-P1: intermediate notation
;;; O-P1=I-P2
Demeter_in = Input.
Input :
Cd_graph
*common*.
Cd_graph = < adjacencies > Nlist(Adjacency)
["*terminal_sets*" Comma_list(Vertex) "."].
Adjacency =
< source > Vertex
< ns > Neighbors
["*inherits_from*" Comma_list(Term)]
"." .
Neighbors :
Intermediate_ns
*common*.
Intermediate_ns :
Repetit |
Non_repetit *common*.
Non_repetit : Instantiable | Abstract *common*
List(Int_part).
Instantiable = "instantiable=".
Repetit = "repetition=" Term
[ Non_empty].
Non_empty = "*non_empty*".
Abstract = "abstract=".
Int_part : Required_int_part | Optional_int_part
*common* Labeled.
Required_int_part = "*required*".
Optional_int_part = "*optional*".
Vertex = < vertex_name > Ident .
Opt_labeled_term :
Labeled
*common* Term.
Labeled = "<" < label_name > Ident ">" .
Term :
Normal
*common* Vertex .
Normal = .
; parameterized classes
List(S) ~ {S}.
Nlist(S) ~ S {S}.
Comma_list(S) ~ S {"," S}.
**************************************************************************/
#include "generate.h"
#include
#include
#include
/*
* demeter_in = < input > input .
*/
void Demeter_in::gen_user_calls( char* dest_path, char* top, char* TOP )
{
const int MAXPATH = 256;
fstream outFile;
char user_calls_filename[MAXPATH];
char first_classname[MAXPATH];
strcpy( user_calls_filename, dest_path );
strcat( user_calls_filename, "/main.C.sample" );
strcpy( first_classname, this -> get_first_classname() );
// create main.C.sample
outFile.open( user_calls_filename, ios::out );
if ( !outFile ) {
cerr << "Generate: cannot open " << user_calls_filename
<< " for output.\n";
exit( -1 );
}
// u-main.C.sample
outFile << "//-----------------------------------------------------------------\n"
<< "// main.C.sample \n"
<< "// This file is an example for a main.C Demeter main file.\n"
<< "// It provides sample code fragments showing how to use some of the \n"
<< "// Demeter runtime libraries. To have a quick test of your environment \n"
<< "// rename this file to main.C and compile the environment. \n"
<< "//-----------------------------------------------------------------\n"
<< endl;
outFile << "#include \"" << top << ".h\"\n\n\n";
outFile << "void out_of_store()\n{\n"
<< " cerr << \"" << top
<< ": operator new failed, out of store\\n\";\n"
<< " exit( 1 );\n}\n" << endl;
outFile << "#ifndef __GNUC__\n"
<< "extern PF set_new_handler( PF );\n"
<< "#else\n"
<< "extern \"C\" PF set_new_handler( PF );\n"
<< "#endif\n" << endl;
outFile << "/*\n"
<< " * GEN_DIR is a global variable containing the path of the generation\n"
<< " * environment. This path is used to find the cd-print and cd-parse\n"
<< " * class dictionaries.\n"
<< " * Do NOT delete the following statement.\n"
<< " */\n\n"
<< "char* GEN_DIR = getenv( \"GEN_DIR\" );\n" << endl;
outFile << "int main( int argc, char* argv[], char* envp[] )\n"
<< "{" << endl;
outFile << " // set new handler to catch out of memory exception\n"
<< " set_new_handler( &out_of_store );\n" << endl;
outFile << " //----------------------------------------\n"
<< " // Parsing an object \n"
<< " //----------------------------------------\n"
<< " // specify file to parse in \n"
<< " const int MAXPATH = 256;\n"
<< " char Dem_input[MAXPATH];\n\n"
<< " // Input file is first argument\n"
<< " if( argc >= 2 )\n"
<< " strcpy( Dem_input, argv[1] );\n"
<< " else {\n"
<< " strcpy( Dem_input, \"demeter-input\" ); // default input \n"
<< " }\n" << endl;
outFile << " // parse it in \n"
<< " cout << \"Parsing in object in: \" << Dem_input << \".\" << endl;\n"
<< " " << first_classname << "* i" << first_classname
<< " = new " << first_classname << "();\n"
<< " if ( ";
if ( MIFLAG ) {
outFile << first_classname << "::castdown( i" << first_classname
<< " -> g_parse(Dem_input) ) == NULL )\n";
}
else {
outFile << "( " << first_classname << "* ) i"
<< first_classname << " -> g_parse( Dem_input ) == NULL )\n";
}
outFile << " {\n"
<< " cerr << \"Parser error.\" << endl;\n"
<< " exit(1);\n"
<< " }\n"
<< " cout << endl;\n" << endl;
outFile << " //----------------------------------------\n"
<< " // Drawing an object \n"
<< " //----------------------------------------\n"
<< " cout << \"Drawing the parsed object:\" << endl;\n"
<< " i" << first_classname << " -> g_draw();\n"
<< " cout << \"\\nEnd of drawing.\\n\" << endl;\n" << endl;
outFile << " //----------------------------------------\n"
<< " // Copying an object \n"
<< " //----------------------------------------\n"
<< " cout << \"Copying the object.\" << endl;\n"
<< " " << first_classname << "* n" << first_classname << " = ";
if ( MIFLAG ) {
outFile << first_classname << "::castdown( i" << first_classname
<< " -> g_copy() );\n";
}
else {
outFile << "( " << first_classname << "* ) i" << first_classname
<< " -> g_copy();\n";
}
outFile << " cout << endl;\n" << endl;
outFile << " //----------------------------------------\n"
<< " // Displaying the copied object as a tree\n"
<< " //----------------------------------------\n"
<< " cout << \"Displaying the copied object as a tree:\" << endl;\n"
<< " n" << first_classname << " -> g_displayAsTree();\n"
<< " cout << \"\\nEnd of display.\\n\" << endl;\n" << endl;
outFile << " //----------------------------------------\n"
<< " // Comparing two objects \n"
<< " //----------------------------------------\n"
<< " cout << \"Comparing the two objects:\" << endl;\n"
<< " if ( i" << first_classname << " -> g_equal( n"
<< first_classname << " ) == 1 )\n"
<< " cout << \"copied and original object are equal\\n\" << endl;\n"
<< " else\n"
<< " cout << \"copied and original object are NOT equal\\n\" << endl;\n"
<< endl;
outFile << " //----------------------------------------\n"
<< " // Printing an object \n"
<< " //----------------------------------------\n"
<< " cout << \"Pretty printing the parsed object:\" << endl;\n"
<< " char* tmp_filename = \"notmod/tmp/demeter-output\";\n"
<< " ofstream outFile( tmp_filename );\n"
<< " if ( !outFile ) {\n"
<< " cerr << \"" << top
<< " error: unable to open \" << tmp_filename\n"
<< " << \" for output\" << endl;\n"
<< " exit( 1 );\n"
<< " }\n"
<< " cout << i" << first_classname << " << endl;\n"
<< " i" << first_classname << " -> g_print( outFile );\n"
<< " outFile.close();\n"
<< " cout << \"\\nEnd of printing.\\n\" << endl;\n" << endl;
outFile << " //----------------------------------------\n"
<< " // Selftest of generic parser/printer \n"
<< " //----------------------------------------\n"
<< " cout << \"Selftest of generic parser/printer:\" << endl;\n"
<< " " << first_classname << "* i" << first_classname
<< "_printed = new " << first_classname << "();\n"
<< " i" << first_classname << "_printed = ";
if ( MIFLAG ) {
outFile << first_classname << "::castdown( i" << first_classname
<< "_printed->g_parse( tmp_filename ) );\n";
}
else {
outFile << "(" << first_classname << "*)i" << first_classname
<< "_printed->g_parse( tmp_filename );\n";
}
outFile << " if( i" << first_classname << "->g_equal( i"
<< first_classname << "_printed ) == 1 ) {\n"
<< " cout << \"g_parse and g_parse( g_print( g_parse ) )"
<< " are equal.\\n\"\n"
<< " << \"Selftest passed.\\n\";\n"
<< " } else {\n"
<< " cout << \"g_parse and g_parse( g_print( g_parse ) )"
<< " are NOT equal.\\n\"\n"
<< " << \"Selftest failed.\\n\";\n"
<< " }\n"
<< " cout << endl;\n" << endl;
outFile << " //----------------------------------------\n"
<< " // Your own code follows after this \n"
<< " //----------------------------------------\n" << endl;
outFile << " cout << \"\\n*** FINISHED ***\" << endl;\n" << endl;
outFile << " return ( 0 );\n}" << endl;
outFile.close();
}