# Copyright 2003-2005 Regents of the University of California # SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. # SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # You should have received a copy of the GNU General Public License along # with SETI_BOINC; see the file COPYING. If not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Copyright 2003-2005 Regents, University of California # All rights reserved # # $Id: schema_to_class.awk,v 1.57.2.5 2007/03/29 01:08:22 korpela Exp $ # BEGIN { print "processing BEGIN" # Work around gawk FILENAME bug. if ((FILENAME=="") || (FILENAME=="-")) { tmpfilename=ARGV[ARGC-1] headerfile=ARGV[ARGC-1]".h" sourcefile=ARGV[ARGC-1]".cpp" } else { tmpfilename=FILENAME headerfile=FILENAME".h" sourcefile=FILENAME".cpp" } print "// This file is automatically generated. Do not edit" > sourcefile print "// This file is automatically generated. Do not edit" > headerfile print "#include \"sah_config.h\"" > sourcefile print "" > sourcefile print "#include " > sourcefile print "#include " >sourcefile print "#include " >sourcefile print "#include " >sourcefile print "#include " >sourcefile print "#include " >sourcefile print "#include " > sourcefile print "" > sourcefile print "#include \"parse.h\"" > sourcefile print "#include \"xml_util.h\"" > sourcefile print "#include \"db_table.h\"" >sourcefile n=split(tmpfilename,a,"/") print "#include \""a[n]".h\"" >sourcefile print "\n#ifdef _WIN32" >sourcefile print "#pragma warning( disable : 4355 )" >sourcefile print "#endif\n" >sourcefile print "#ifndef _H_"a[n]"_H" >headerfile print "#define _H_"a[n]"_H" >headerfile print "#define found(x) ((x != std::string::npos))" >sourcefile print "" > sourcefile nrefs=1 nfields=1 ref_table[1]="" ref_row[1]="" ref_rtable[1]="" def_types[1]="no_types_defined" ndef_types=1 } /^begin_refs/,/^end_refs/ \ { print "processing refs" ref_table[nrefs]=$1 ref_row[nrefs]=$2 ref_rtable[nrefs++]=$3 } /synonym/,/;/ \ { print "processing synonym" if (index($5,";")) { split($5,a,";") tt=a[1] } else { tt=$5 } print "typedef "tt" "$3";" >headerfile next } /database/,/;/ \ { dbtype="" print "processing database" for (i=0;isourcefile print "using namespace "dbtype";" >sourcefile print "#endif\n\n" >sourcefile } if (index(db_name,";")) { split(db_name,a,";") db_name=a[1] } print "extern const char *db_name;" >headerfile print "const char *db_name=\""db_name"\";" >sourcefile print "extern int db_is_open;\n" >headerfile print "int db_is_open;\n" >sourcefile print "#ifndef CLIENT" >headerfile print "inline int db_open() { \n\t if (!db_is_open) db_is_open=sql_database(db_name);\n\t return db_is_open; }" >headerfile print "inline int db_close() { \n\t if (db_is_open) db_is_open=!sql_finish();\n\t return !db_is_open; }" >headerfile print "inline int db_change(const char *name) { \n\t if(strcmp(db_name, name) || !db_is_open) { \n\t\t db_close();\n\t\t db_name=name;\n\t\t db_open(); } return(db_is_open); }" >headerfile print "#else" >headerfile print "inline int db_open() { return (db_is_open=1); }" >headerfile print "inline int db_close() { return !(db_is_open=0); }" >headerfile print "inline int db_change() { return (db_is_open=1); }" >headerfile print "#endif\n" >headerfile next } /{/ { print "// "$0 > headerfile print "// "$0 > sourcefile while (!index($0,"}")) { getline print "// "$0 > headerfile print "// "$0 > sourcefile } print "\n" >headerfile print "\n" >sourcefile next } /deprecated/ { next } /alter/ { while (!index($0,";")) { getline } next } /revoke/ { while (!index($0,";")) { getline } next } /index/ { while (!index($0,";")) { getline } next } /create[ \t]/ { print "processing create" if ($2 == "table") { if (index($3,"\.")) { n=split($3,a,"\.") } else { n=1 a[n]=$3 } is_typedef=0 } else { if (index($4,"\.")) { n=split($4,a,"\.") } else { n=1 a[n]=$4 } is_typedef=1 } nfields=1 fields[1]="" type[1]="" nsf=1 sf[1]="" sfz[1]=0 table=a[n] if (is_typedef) { def_types[ndef_types++]=a[n] print "class ",a[n], \ " : public db_type<"a[n]"> {\n public:" \ > headerfile } else { print "class ",a[n], \ " : public db_table<"a[n]"> {\n public:" \ > headerfile } } /list\(/ { print "processing list" isref=0 islist=1 n=split($2,a,"(") type[nfields]="v "a[n] fields[nfields++]=$1 print "\tsqlblob<"a[n]"> ",$1,";" > headerfile next } /integer8|bigint|int8/ { print "processing integer8" isref=0 type[nfields]="ld" if (index($NF,"bitfield")) type[nfields]="lb" fields[nfields++]=$1 for (i=1;i "ref_row[i]";" >headerfile type[nfields-1]="r" } } if (!isref) print "\tsqlint8_t ",$1";" > headerfile if ($1=="id") { id_type[table]="sqlint8_t " id_name[table]=$1 } next } /[ \t]integer|[ \t]int/ { print "processing integer" isref=0 type[nfields]="d" fields[nfields++]=$1 for (i=1;i "ref_row[i]";" >headerfile type[nfields-1]="r" } } if (!isref) print "\tlong ",$1";" > headerfile if ($1=="id") { id_type[table]="long" id_name[table]=$1 } next } /[ \t]smallint|[ \t]mediumint/ { print "processing smallint" isref=0 type[nfields]="d" fields[nfields++]=$1 for (i=1;i "ref_row[i]";" >headerfile print ref_rtable[i],table"."ref_row[i] type[nfields-1]="r" } } if (!isref) print "\tlong ",$1";" > headerfile if ($1=="id") { id_type[table]="long" id_name[table]=$1 } next } /serial8|bigint*auto_increment/ { print "processing serial8" key=$1 type[nfields]="ld" id_type[table]="sqlint8_t" id_name[table]=$1 fields[nfields++]=$1 print "\tsqlint8_t ",$1";" > headerfile next } /serial|auto_increment/ { print "processing serial" key=$1 type[nfields]="d" id_type[table]="long" id_name[table]=$1 fields[nfields++]=$1 print "\tlong ",$1";" > headerfile next } /smallfloat/ { print "processing smallfloat" type[nfields]="f" fields[nfields++]=$1 print "\tdouble ",$1";" > headerfile next } /[ \t]float|[ \t]double/ { print "processing float" type[nfields]="f" fields[nfields++]=$1 print "\tdouble ",$1";" > headerfile next } /char[ \t\(]|[ \t]byte/ { print "processing char" type[nfields]="s" for (i=0;i headerfile } else { print "\tsqlblob ",$1";" >headerfile; } next } /,/ { print "processing ," for (i=1;iheaderfile next } } } /./ { print "processing ." for (i=1;iheaderfile next } } } /;/ { print "processing ; nfields=",nfields if (nfields!=1) { firstcomma=0 for (i=(nfields-1);i;i--) { if (firstcomma) { comma[i]="," } else { comma[i]="" } if (type[i]!="s") firstcomma=1 } print "\t"table"();" >headerfile print "\t"table"(const "table" &a);" >headerfile print "\t"table"(const SQL_ROW &a);" >headerfile print "\t"table"(const std::string &s,const char *tag=\""table"\");" >headerfile print "\t"table" &operator =(const "table" &a);" >headerfile print "\tstd::string update_format() const;" >headerfile print "\tstd::string insert_format() const;" >headerfile print "\tstd::string select_format() const;" >headerfile print "\tstd::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const;" >headerfile print "\tstd::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag=\""table"\") const;" >headerfile print "\tvoid parse(const SQL_ROW &s);" >headerfile print "\tvoid parse(const std::string &s);" >headerfile print "\tvoid parse_xml(const std::string &s,const char *tag=\""table"\");" >headerfile print " private:\n};\n\n" >headerfile if (is_typedef) { print "template <> const char * const db_type<"table">::type_name=\""table"\";" >sourcefile print "template <> const char * db_type<"table">::_search_tag=type_name;" >sourcefile print "template <> const int db_type<"table">::_nfields="nfields-1";" >sourcefile printf("template <> const char * const db_type<%s>::column_names[%d]={",table,nfields-1) >sourcefile } else { print "template <> const char * const db_table<"table">::table_name=\""table"\";" >sourcefile print "template <> const char * db_table<"table">::_search_tag=table_name;" >sourcefile print "template <> const int db_table<"table">::_nfields="nfields-1";" >sourcefile printf("template <> const char * const db_table<%s>::column_names[%d]={",table,nfields-1) >sourcefile } for (i=1;isourcefile print "};\n" >sourcefile print table"::"table"() : " >sourcefile if (is_typedef) { print "\tdb_type<"table">(*this)," > sourcefile } else { print "\tdb_table<"table">(*this,-1)," > sourcefile } for (i=1;isourcefile } else if ((type[i]=="r")||(type[i]=="t")) { printf("\t%s()%s\n",fields[i],comma[i]) >sourcefile } else if (type[i]=="b") { printf("\t%s((unsigned char *)0,%d,_x_csv)%s\n",fields[i],arrlen[i],comma[i]) >sourcefile } else if (index(type[i],"v")==1) { n=split(type[i],a," ") stype=a[n] n=split(stype,a,"(") stype=a[n] sis_deftype=0 for (n=1;nsourcefile } else { printf("\t%s((%s *)0,%d,_x_xml_values)%s\n",fields[i],stype,arrlen[i],comma[i]) >sourcefile } } } print "{\n\tdb_open();" >sourcefile for (i=1;isourcefile } print "}\n\n" >sourcefile print table"::"table"(const "table" &a) : " >sourcefile if (is_typedef) { print "\tdb_type<"table">(*this)," > sourcefile } else { print "\tdb_table<"table">(*this,-1)," > sourcefile } for (i=1;isourcefile } print "{\n\tdb_open();" >sourcefile for (i=1;isourcefile } print "}\n\n" >sourcefile print table"::"table"(const SQL_ROW &a) : " >sourcefile if (is_typedef) { print "\tdb_type<"table">(*this)" > sourcefile } else { print "\tdb_table<"table">(*this,-1)" > sourcefile } print "{\n\tdb_open();" >sourcefile print "\tparse(a);\n}\n\n" >sourcefile print table"::"table"(const std::string &s,const char *tag) : " >sourcefile #for (i=1;isourcefile # } else if ((type[i]=="r")||(type[i]=="t")) { # printf("\t%s(),\n",fields[i]) >sourcefile # } #} if (is_typedef) { print "\tdb_type<"table">(*this)" > sourcefile } else { print "\tdb_table<"table">(*this,-1)" > sourcefile } print "{\n\tdb_open();" >sourcefile print "\tif (xml_match_tag(s,tag)) {" >sourcefile print "\t parse_xml(s,tag);" >sourcefile print "\t} else {\n\t parse(s);\n\t}\n}\n\n" >sourcefile print table" &"table"::operator =(const "table" &a) {" >sourcefile print "\tif (&a != this) {" >sourcefile for (i=1;isourcefile } else { if (index(type[i],"v") == 1) { n=split(type[i],a," ") stype=a[n] n=split(stype,a,"(") stype=a[n] print "\t\t{" >sourcefile print "\t\t "fields[i]".clear();" > sourcefile print "\t\t std::vector<"stype">::const_iterator i(a."fields[i]".begin());" > sourcefile print "\t\t for (;i!=a."fields[i]".end();i++) {" >sourcefile print "\t\t "fields[i]".push_back(*i); " >sourcefile print "\t\t }\n\t\t}" >sourcefile } } } for (i=1;isourcefile } print "\t}\n\treturn (*this);\n}\n\n" >sourcefile print "std::string "table"::update_format() const" >sourcefile if (is_typedef) { print "{\tstd::ostringstream rv(\"\");\n" >sourcefile print "\trv << \"ROW(\";" >sourcefile i=1 } else { print "{\tstd::ostringstream rv(\"\");\n" >sourcefile i=2 } print "\tfor (int i="i";i<"nfields-1";i++) rv << \"?,\";" >sourcefile print "\trv << \"?\";" >sourcefile if (is_typedef) { print "rv << \")\";\n" >sourcefile } print "\treturn rv.str();\n}\n\n" >sourcefile print "std::string "table"::insert_format() const" >sourcefile if (is_typedef) { print "{\treturn update_format();\n}\n" >sourcefile } else { print "{\treturn std::string(\"?,\")+update_format();\n}\n" >sourcefile } print "std::string "table"::select_format() const" >sourcefile print "{\nstd::string rv(\"\");" >sourcefile print "for (int i=0; i<"nfields-2";i++) rv+=\"?,\";" >sourcefile print "rv+=\"?\";\nreturn rv;\n}\n" >sourcefile print "std::string "table"::print(int full_subtables, int show_ids, int no_refs) const" >sourcefile print "{\tstd::ostringstream rv(\"\");\n" >sourcefile print "\trv.precision(14);" >sourcefile if (is_typedef) { print "\trv << \"ROW(\";" >> sourcefile } for (i=1;isourcefile print "\t if (full_subtables) {" > sourcefile print "\t rv << "fields[i]".print(full_subtables,show_ids,no_refs);" > sourcefile print "\t} else {" > sourcefile print "\t rv << "fields[i]".id;" > sourcefile print "\t }\n\t}" > sourcefile } else if (type[i] == "t") { print "\trv << "fields[i]".print(full_subtables,show_ids,no_refs);" > sourcefile } else if (index(type[i],"v")==1) { n=split(type[i],a," ") stype=a[n] n=split(stype,a,"(") stype=a[n] print "\trv << \"LIST {\";" > sourcefile print "\t{\n\tstd::vector<"stype">::const_iterator p="fields[i]".begin();" > sourcefile print "\tfor (;p<"fields[i]".end();p++) {" > sourcefile sis_deftype=0 for (n=1;n sourcefile } else { print "\t rv << p->print();" >sourcefile } print "\t if (p != "fields[i]".end()-1) {" >sourcefile print "\t rv << ',';" >sourcefile print "\t } else {" >sourcefile print "\t rv << \"}\";" >sourcefile print "\t }" >sourcefile print "\t}\n\t}" >sourcefile } else if ((type[i]=="s")) { print "\trv << \"'\" << "fields[i]" << \"'\";" >sourcefile } else if ((type[i]=="b")) { if (dbtype == "ifx") { print "\trv << \"\" << "fields[i]".print_hex() ;" >sourcefile } else { print "\trv << \"\" << "fields[i]".print_raw() ;" >sourcefile } } else { printf("\t") > sourcefile if ((i==1) && (!is_typedef)) { printf("if (show_ids) ") > sourcefile } print "rv << "fields[i]";" > sourcefile } if (i!=(nfields-1)) print "\trv << ',';" >sourcefile } if (is_typedef) { print "\trv << \")\";" > sourcefile } print "\treturn rv.str();\n}\n\n" >sourcefile print "std::string "table"::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const " >sourcefile print "{\n\tstd::ostringstream rv(\"\");\n" >sourcefile print "\trv.precision(14);" >sourcefile print "\trv << xml_indent() << '<' << tag << \">\\n\";" >sourcefile print "\txml_indent(2);" >sourcefile for (i=1;isourcefile print "\t if (full_subtables) {" > sourcefile print "\t rv << "fields[i]".print_xml(full_subtables,show_ids,no_refs,\""fields[i]"\");" > sourcefile print "\t} else {" > sourcefile print "\t rv << xml_indent() << \"<"fields[i]">\" << "fields[i]".id << \"\\n\";" > sourcefile print "\t }\n\t}" > sourcefile } else if (type[i] == "t") { print "\trv << "fields[i]".print_xml(full_subtables,show_ids,no_refs,\""fields[i]"\");" > sourcefile } else if (index(type[i],"v")==1) { n=split(type[i],a," ") stype=a[n] n=split(stype,a,"(") stype=a[n] sis_deftype=0 for (n=1;nsourcefile print "\t rv << xml_indent() << \"<"fields[i]"\";" >sourcefile print "\t {\n\t std::string enc_string="fields[i]".print_xml();" >sourcefile if (!sis_deftype) { print "\t rv << \" length=\" << enc_string.size() << \" encoding=\\\"\" << xml_encoding_names["fields[i]".encoding] << \"\\\">\" ;" >sourcefile } else { print "\t rv << \">\\n\" ;" >sourcefile } print "\t rv << enc_string;" >sourcefile print "\t }\n}" >sourcefile if (sis_deftype) print "\trv << xml_indent(-2);" > sourcefile print "\trv << \"\\n\"; " >sourcefile } else if (type[i]=="s") { print "\t{\n\t std::string enc_field=xml_encode_string("fields[i]",std::min(strlen("fields[i]"),sizeof("fields[i]")));" > sourcefile print "\t rv << xml_indent() << \"<"fields[i]">\";" > sourcefile print "\t rv << enc_field << \"\\n\";" >sourcefile print "\t}" >> sourcefile } else if (type[i]=="b") { print "\tif ("fields[i]".size()) {\n\t std::string enc_field=xml_encode_string("fields[i]","fields[i]".encoding);" > sourcefile print "\t rv << xml_indent() << \"<"fields[i]" length=\" << enc_field.size() << \" encoding=\\\"\" << xml_encoding_names["fields[i]".encoding] << \"\\\">\"; "> sourcefile print "\t rv << enc_field << \"\\n\";" >sourcefile print "\t}" >> sourcefile } else { printf("\t") > sourcefile if ((i==1) && (!is_typedef)) { printf("if (show_ids) ") > sourcefile } print "rv << xml_indent() << \"<"fields[i]">\" << "fields[i]" << \"\\n\";" > sourcefile } } print "\txml_indent(-2);" >sourcefile print "\trv << xml_indent() << \"\\n\";" >sourcefile print "\treturn rv.str();\n}\n\n" >sourcefile print "\tvoid "table"::parse_xml(const std::string &s,const char *tag) {" >sourcefile print "\t std::string field,sub;" > sourcefile print "\t if (extract_xml_record(s,tag,field)) {" >sourcefile print "\t std::string::size_type pos=0;" >sourcefile for (i=1;i sourcefile print "\t "fields[i]".parse_xml(sub,\""fields[i]"\");" >sourcefile print "\t }" > sourcefile } else if (index(type[i],"v")==1) { n=split(type[i],a," ") stype=a[n] n=split(stype,a,"(") stype=a[n] sis_deftype=0 for (n=1;nsourcefile print "\t if (extract_xml_record(field,\""fields[i]"\",sub)) {" >sourcefile if (sis_deftype) { print "\t pos=0;" >sourcefile print "\t while ((pos=sub.find(\"<"stype"\",pos)) != std::string::npos) { " >sourcefile print "\t "fields[i]".push_back("stype"(std::string(sub.c_str()+pos))); " >sourcefile print "\t pos=sub.find(\"sourcefile print "\t pos=sub.find(\">\",pos);" >sourcefile print "\t }" > sourcefile } else { print "\t pos=sub.find(\">\");" >sourcefile print "\t do {" > sourcefile print "\t if (pos!=std::string::npos) {" >sourcefile print "\t do { pos++; } while ((sub[pos]=='\\n') || (sub[pos]==','));" >sourcefile print "\t std::istringstream in(std::string(sub.c_str()+pos)); " >sourcefile print "\t "stype" tmp;" >sourcefile print "\t in >> tmp;" >sourcefile print "\t "fields[i]".push_back(tmp);" >sourcefile print "\t }" >sourcefile print "\t } while ((pos=sub.find(\",\",pos)) != std::string::npos); " >sourcefile } print "\t }" > sourcefile } else { print "\t if (extract_xml_record(field,\""fields[i]"\",sub)) {" > sourcefile print "\t pos=sub.find(\">\");" >sourcefile print "\t do { pos++; } while(sub[pos]=='\\n');" >sourcefile if ((type[i] != "s") && (type[i] != "b")) { print "\t std::istringstream in(sub.c_str()+pos);" >sourcefile print "\t in >> "fields[i]";" > sourcefile } else if (type[i] == "b") { print "\t "fields[i]"=(xml_decode_field(sub,\""fields[i]"\"));" >sourcefile } else { print "\t std::string::size_type epos=sub.find(\"<\",pos);" >sourcefile print "\t if (epos==std::string::npos) epos=sub.find('\\n',pos);" > sourcefile print "\t if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos);" > sourcefile print "\t std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos));" >sourcefile print "\t strncpy("fields[i]",(const char *)&(in.front()),std::min(in.size(),(size_t)"arrlen[i]"));" >sourcefile print "\t "fields[i]"[std::min(in.size(),(size_t)"arrlen[i]-1")]=0;" > sourcefile } print "\t }" >sourcefile } } print "\t }" >sourcefile print "\t }\n" >sourcefile print "\tvoid "table"::parse(const SQL_ROW &s) {" >sourcefile for (i=1;isourcefile if (type[i]=="r" || type[i]=="t") { print "\t "fields[i]".parse(SQL_ROW(s["i-1"]->c_str(),0));" >sourcefile } else if (index(type[i],"v")==1) { n=split(type[i],a," ") stype=a[n] n=split(stype,a,"(") stype=a[n] sis_deftype=0 for (n=1;nsourcefile print "\t int i;" >sourcefile print "\t "fields[i]".clear();" >sourcefile print "\t SQL_ROW tmp((*s["i-1"]).c_str()); ">sourcefile if (sis_deftype) { print "\t for (i=0;isourcefile print "\t "fields[i]".push_back("stype"(SQL_ROW((*tmp[i]).c_str())));" >sourcefile } else { print "\t for (i=0;isourcefile print "\t std::istringstream in(*(tmp[i]));" >sourcefile print "\t "stype" tmp0;" >sourcefile print "\t in >> tmp0;" >sourcefile print "\t "fields[i]".push_back(tmp0);" >sourcefile } print "\t }" >sourcefile } else { if ((type[i] != "s") && (type[i] != "b")) { print "\t std::istringstream row(*(s["i-1"]));" >sourcefile print "\t row >> "fields[i]";" > sourcefile } else if (type[i] == "b") { print "\t "fields[i]"=sqlblob(*(s["i-1"]));" >sourcefile } else { print "\t strncpy("fields[i]",s["i-1"]->c_str(),"arrlen[i]");">sourcefile print "\t "fields[i]"["arrlen[i]-1"]=0;" > sourcefile } } print "\t }" >sourcefile } print "\t }\n" >sourcefile print "\tvoid "table"::parse(const std::string &s) {" >sourcefile print "\t SQL_ROW row(s.c_str(),"nfields-1");" >sourcefile print "\t parse(row);" >sourcefile print "\t }\n" >sourcefile nfields=1 } } END { print "processing END" print "#endif"> headerfile }