6e35192005-08-20Martin Nilsson // Output one file per class as C, more or less. inherit "util"; string head = "", sfhead="", dir, sdir; string debug = ""; object parent;
beb21d2008-06-28Martin Nilsson protected string filename( Class c )
6e35192005-08-20Martin Nilsson { if( sizeof( c->c_name() ) ) return "p"+c->c_name()+".c"; return "pgtk_globals.c"; } array files = ({});
beb21d2008-06-28Martin Nilsson protected void output_class( Class cls, int lvl )
6e35192005-08-20Martin Nilsson { string current_data = ""; if( !cls->functions["_sprintf"] ) cls->create_default_sprintf();
9f73e32005-12-18Marcus Comstedt  cls->create_init_exit();
6e35192005-08-20Martin Nilsson  /* Start output */ current_data += "#define EXTPRG extern\n"+sfhead;
4ca9822006-01-02Marcus Comstedt  if(cls->mixin_for) current_data += "#define CLASS_TYPE MIXIN\n";
6e35192005-08-20Martin Nilsson  if( sizeof( cls->pre ) ) current_data += COMPOSE( cls->pre ); void output_thing( object thing ) {
08a19f2005-10-06Henrik Grubbström (Grubba)  if( mixed err=catch( current_data += thing->c_definition() ) )
6e35192005-08-20Martin Nilsson  werror(thing->file+":"+thing->line+": Error: "+ (stringp(err)?err:describe_backtrace(err))+"\n" ); }; foreach( sort( indices( cls->functions ) ), string fun ) output_thing( cls->functions[ fun ] ); foreach( sort( indices( cls->members ) ), string mem ) output_thing( cls->members[ mem ] ); // Processing done. Actually write the file. write_file( dir + filename( cls ), current_data ); files += ({ filename( cls ) }); } string protos = "";
beb21d2008-06-28Martin Nilsson protected void build_protos( Class cls, int lvl )
6e35192005-08-20Martin Nilsson { if( cls->name != "global" )
ba9e802006-02-27Martin Stjernholm  protos+=(" "*lvl)+"EXTPRG struct program *"+glue_c_name(cls->c_name())+"_program;\n";
6e35192005-08-20Martin Nilsson  foreach( sort( indices( cls->functions ) ), string f ) protos += (" "*lvl)+ " extern "+cls->functions[ f ]->c_prototype(); foreach( sort( indices( cls->members ) ), string f ) protos += (" "*lvl)+ " extern "+cls->members[ f ]->c_prototype(); } int init_n; string initfun = "", exitfun="", type_switch="", toplevel ="";
beb21d2008-06-28Martin Nilsson protected void build_pike_fadds( Class cls, int lvl )
6e35192005-08-20Martin Nilsson { string res = ""; init_n++; if( mixed e = catch { void output_thing( mixed thing ) { if( mixed err=catch( res += thing->pike_add() ) ) werror(thing->file+":"+thing->line+": Error: "+ (stringp(err)?err:describe_backtrace(err))+"\n" ); }; if( cls->name != "_global" ) {
ba9e802006-02-27Martin Stjernholm  exitfun += " free_program( "+glue_c_name(cls->c_name())+"_program );\n";
4ca9822006-01-02Marcus Comstedt  if( !cls->mixin_for ) type_switch = "#ifdef "+cls->c_type_define()+"\n" " if(PGTK_CHECK_TYPE(widget, "+cls->c_type_define()+"))\n"
ba9e802006-02-27Martin Stjernholm  " return "+glue_c_name(cls->c_name())+"_program;\n"
4ca9822006-01-02Marcus Comstedt  "#endif\n"+type_switch;
6e35192005-08-20Martin Nilsson  } res = "static void _"+init_n+"()\n{\n"; if( cls->name != "_global" ) { res +=
b28b982016-06-23Henrik Grubbström (Grubba)  " start_new_program(); /* "+cls->name+" */\n" + " Pike_compiler->new_program->id = " + cls->class_id() + ";\n";
4ca9822006-01-02Marcus Comstedt  if( sizeof(cls->inherits) ) foreach( cls->inherits, Class c )
ba9e802006-02-27Martin Stjernholm  res += " low_inherit( "+glue_c_name(c->c_name())+
4ca9822006-01-02Marcus Comstedt  "_program,0,0,0,0,0);\n";
6e35192005-08-20Martin Nilsson  else {
4ca9822006-01-02Marcus Comstedt  res += " ADD_STORAGE(struct "+ (cls->mixin_for? "mixin_wrapper":"object_wrapper")+ ");\n";
6e35192005-08-20Martin Nilsson  } } foreach( sort( indices( cls->functions ) ), string f ) output_thing( cls->functions[ f ] ); foreach( sort( indices( cls->members ) ), string f ) output_thing( cls->members[ f ] ); if( cls->name != "_global" ) {
b28b982016-06-23Henrik Grubbström (Grubba)  res += (" "+glue_c_name(cls->c_name())+"_program = end_program();\n");
6e35192005-08-20Martin Nilsson  res += (" add_program_constant("+S(cls->pike_name(),1,0,26)+",\n"
414b7d2008-07-13Marcus Comstedt  " "+glue_c_name(cls->c_name())+"_program, ID_FINAL);\n");
6e35192005-08-20Martin Nilsson // predef::write("pike_name==%s\n",cls->pike_name()); /* string str=S(cls->pike_name(),1,0,26); predef::write("pike_name==%s\n",str); array aaa=str/"\n"; string str1; sscanf(aaa[1],"%*[ \t](%s)",str1); predef::write("PSTR==%s\n",str1); */ } res += "}\n\n"; toplevel += res;
9f73e32005-12-18Marcus Comstedt  if( cls->name == "_global" ) { if(sizeof(cls->init))
ba9e802006-02-27Martin Stjernholm  initfun += " pgtk2__init();\n";
9f73e32005-12-18Marcus Comstedt  if(sizeof(cls->exit))
ba9e802006-02-27Martin Stjernholm  exitfun += " pgtk2__exit();\n";
9f73e32005-12-18Marcus Comstedt  }
6e35192005-08-20Martin Nilsson  } ) werror(cls->file+":"+cls->line+": Error: "+ (stringp(e)?e:describe_backtrace(e))+"\n" ); } string make_initfun() { string res = ""; string line = ""; for( int i = 1; i<=init_n; i++ ) { line += "_"+i+"(); "; if( sizeof( line ) > 70 ) { res += " "+line+"\n"; line = ""; } } if( sizeof(line) ) res += " "+line+"\n"; return res; } void post_class_build() { } array(string) output( mapping(string:Class) classes, mapping(string:Constant) constants,
2d49322006-01-07Martin Nilsson  array(Node) global_code,
d1bf152006-01-14Martin Nilsson  mapping(string:int) strings)
6e35192005-08-20Martin Nilsson { head = Stdio.read_bytes( combine_path( sdir, "../pgtk.c.head" ) ); if(!head) error("Failed to load ../pgtk.c.head\n"); sfhead = replace( head, "PROTOTYPES", "#include \"prototypes.h\"" ); traverse_class_tree( classes, output_class ); post_class_build(); traverse_class_tree( classes, build_protos ); write_file( dir + "prototypes.h", protos ); write_file( dir + "time_stamp", (string)time() ); string pre = "#define EXTPRG\n"+sfhead+"\n", res = ""; pre += Parser.Pike.simple_reconstitute( global_code ); // This code is here to optimize the global string data. // Basically, make sure that the constants/classes/functions etc. // is added in reverse length order. foreach( sort(indices(constants)), string c ) if( mixed e = catch( initfun += constants[c]->pike_add()) ) werror(constants[c]->file+":"+constants[c]->line+": Error: "+ (stringp(e)?e:describe_backtrace(e))+"\n" ); array q = ({}); foreach( classes;; object c ) q |= indices(c->functions) | indices(c->members); q = Array.uniq2( sort(q) ); sort(map(q,sizeof),q); foreach( reverse(q), string w ) S(w); traverse_class_tree( classes, build_pike_fadds ); mapping done = ([]); foreach( classes;; object c ) foreach( c->signals; string n; object s ) if( !done[n] ) done[n] = s; q = sort(indices( done )); sort(map(q,sizeof),q); foreach( reverse(q), string w ) S("s_"+w,1); foreach( sort(indices( done )), string w ) initfun += done[w]->pike_add();
2d49322006-01-07Martin Nilsson 
d1bf152006-01-14Martin Nilsson  if(sizeof(strings))
2d49322006-01-07Martin Nilsson  {
ba9e802006-02-27Martin Stjernholm  pre += "struct pike_string * pgtk2_pstr_vector["+sizeof(strings)+"];\n\n";
d1bf152006-01-14Martin Nilsson  foreach( strings; string str; int idx ) { initfun += sprintf("\n /* %O */\n", str);
5e9fc02015-08-18Per Hedbor  initfun += " pgtk2_pstr_vector[" + idx + "] = make_shared_static_string(" +
9a9e1e2015-08-24Chris Angelico  S(str,1,2) + "," + sizeof(str) + ",0);\n";
d1bf152006-01-14Martin Nilsson  } exitfun += #" { int i;
ba9e802006-02-27Martin Stjernholm  for( i=0; i<NELEM(pgtk2_pstr_vector); i++ ) free_string( pgtk2_pstr_vector[i] );
d1bf152006-01-14Martin Nilsson  } ";
2d49322006-01-07Martin Nilsson  }
6e35192005-08-20Martin Nilsson  pre += get_string_data()+"\n\n"; files = ({ "pgtk.c" }) + files; write_file( dir+"pgtk.c", pre + toplevel + "PIKE_MODULE_INIT {\n"+make_initfun()+initfun+"}\n\n" "PIKE_MODULE_EXIT {\n"+exitfun+"}\n\n"
ba9e802006-02-27Martin Stjernholm  "struct program *pgtk2_type_to_program(GObject *widget)\n"
6e35192005-08-20Martin Nilsson  "{\n"
f4aff32008-01-23Henrik Grubbström (Grubba)  " if (!widget) return pg2_object_program;\n"
6e35192005-08-20Martin Nilsson  +type_switch+
ba9e802006-02-27Martin Stjernholm  " return pg2_object_program;\n}\n\n" );
6e35192005-08-20Martin Nilsson  return files; } int up_to_date( ) { int last_time = (int)Stdio.read_bytes( dir+"time_stamp" ); if(!last_time ) return 0; foreach( map(get_dir( sdir ), lambda(string s){return sdir+s;})|
350a492006-01-03Marcus Comstedt  ({ __FILE__, combine_path( __FILE__, "../../build_pgtk.pike" )}),
6e35192005-08-20Martin Nilsson  string f ) { Stdio.Stat s;
985fe22005-08-24Martin Nilsson  if( !(s = file_stat( f ) ) ) {
6e35192005-08-20Martin Nilsson  werror("Failed to stat "+f+"\n");
985fe22005-08-24Martin Nilsson  return 0; }
6e35192005-08-20Martin Nilsson  if( s->mtime > last_time ) return 0; } return 1; } void create( string _s, string _d, object p ) { sdir = _s; dir = _d; parent = p; }