/* ------------------------------------------------ Copyright 2014 AT&T Intellectual Property Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ------------------------------------------- */ // This file contains functions used by more than one // code generation system. #include"generate_utils.h" #include"lapp.h" using namespace std; static char tmpstr[1000]; // Replace dots in node name with underscore to prevent generating variable // and structure names with dots inside string normalize_name(string name) { string ret = name; int pos = ret.find('.'); while (pos >=0) { ret = ret.replace(pos, 1, "_"); pos = ret.find('.', pos + 1); } pos = ret.find('/'); while (pos >=0) { ret = ret.replace(pos, 1, "_XX_"); pos = ret.find('/', pos + 1); } return ret; } // name of tuple struct string generate_tuple_name(string node_name){ string ret = normalize_name(node_name); if(ret == ""){ ret = "default"; } ret.append("_tuple"); return(ret); } // LFTA allocation function name. string generate_alloc_name(string node_name){ string ret = normalize_name(node_name); if(ret == ""){ ret = "default"; } ret.append("_fta_alloc"); return(ret); } // The name of the schema definition string. string generate_schema_string_name(string node_name){ string ret = normalize_name(node_name); if(ret == ""){ ret = "default"; } ret += "_schema_definition"; return(ret); } // Generate representations of a tuple. // LFTA and HFTA use slightly different names. string generate_tuple_struct(string node_name, vector sl_list){ string ret = "struct "+generate_tuple_name(normalize_name(node_name))+"{\n"; int s; for(s=0;sget_data_type()->make_tuple_cvar(tmpstr)+";\n"; } ret.append("\tgs_int8_t tuple_type;\n"); ret.append("} __attribute__ ((__packed__));\n\n"); return(ret); } // generate_host_tuple_struct uses numbered fields, // while generate_host_name_tuple_struct uses the filed names themselves. // TODO: change over from generate_host_tuple_struct // to generate_host_name_tuple_struct string generate_host_name_tuple_struct(table_def *td){ string ret = "struct "+generate_tuple_name(normalize_name(td->get_tbl_name()))+"{\n"; vector flds = td->get_fields(); int f; for(f=0;fget_type()); //fprintf(stderr,"tbl=%s, fld=%s, type=%s, dt.type=%d, dt.schema_type=%s\n",td->get_tbl_name().c_str(), flds[f]->get_name().c_str(),flds[f]->get_fcn().c_str(), dt.get_type(),dt.get_type_str().c_str()); ret+="\t"+dt.make_host_cvar(flds[f]->get_name())+";\n"; } ret.append("\tgs_int8_t tuple_type;\n"); ret.append("} __attribute__ ((__packed__));\n\n"); return(ret); } string generate_host_tuple_struct(table_def *td){ string ret = "struct "+generate_tuple_name(normalize_name(td->get_tbl_name()))+"{\n"; vector flds = td->get_fields(); int f; for(f=0;fget_type()); //fprintf(stderr,"tbl=%s, fld=%s, type=%s, dt.type=%d, dt.schema_type=%s out=%s\n",td->get_tbl_name().c_str(), flds[f]->get_name().c_str(),flds[f]->get_type().c_str(), dt.get_type(),dt.get_type_str().c_str(),dt.make_host_cvar(tmpstr).c_str()); sprintf(tmpstr,"tuple_var%d",f); ret+="\t"+dt.make_host_tuple_cvar(tmpstr)+";\n"; } ret.append("} __attribute__ ((__packed__));\n\n"); return(ret); } // convert internal tuple format to exteral tuple format. // mostly, perform htonl conversions. string generate_hfta_finalize_tuple(table_def *td){ string ret = "void finalize_tuple(host_tuple &tup){\n"; ret += "\tstruct "+generate_tuple_name(normalize_name(td->get_tbl_name()))+" *tuple = ("+ generate_tuple_name(td->get_tbl_name())+" *)(tup.data);\n"; vector flds = td->get_fields(); /* int f; for(f=0;fget_type()); if(dt.get_type() == v_str_t){ sprintf(tmpstr,"\ttuple->tuple_var%d.offset = htonl(tuple->tuple_var%d.offset);\n",f,f); ret += tmpstr; sprintf(tmpstr,"\ttuple->tuple_var%d.length = htonl(tuple->tuple_var%d.length);\n",f,f); ret += tmpstr; sprintf(tmpstr,"\ttuple->tuple_var%d.reserved = htonl(tuple->tuple_var%d.reserved);\n",f,f); ret += tmpstr; }else{ if(dt.needs_hn_translation()){ sprintf(tmpstr,"\ttuple->tuple_var%d = %s(tuple->tuple_var%d);\n", f, dt.hton_translation().c_str(), f); ret += tmpstr; } } } */ ret.append("};\n\n"); return(ret); } // make code translation so that it embeds // as a C-string -- escape the escape characters. string make_C_embedded_string(string &instr){ string outstr = "\""; int i; for(i=0;iget_tbl_name())+"_tuple(host_tuple *tup, char *buf, int len, struct "+generate_tuple_name(normalize_name(td->get_tbl_name()))+" *s, gs_int8_t tuple_type){\n"; ret += "\tstruct "+generate_tuple_name(td->get_tbl_name())+" *d;\n"; vector flds = td->get_fields(); ret+="\tif (tuple_type == TEMPORAL_TUPLE) {\n"; ret+="\t\td=(struct "+generate_tuple_name(td->get_tbl_name())+" *)buf;\n"; ret+="\t\ttup->data = (char *)d;\n"; ret+="\t\ttup->heap_resident=false;\n"; for(f=0;fget_type(),flds[f]->get_modifier_list()); if (dt.is_temporal()) { string fldnm = flds[f]->get_name(); // if(dt.needs_hn_translation()) // ret+="\t\td->"+fldnm+"="+dt.hton_translation()+"(s->"+fldnm+");\n"; // else ret+="\t\td->"+fldnm+"=s->"+fldnm+";\n"; } } ret += "\t\td->tuple_type = TEMPORAL_TUPLE;\n"; ret += "\t\ttup->tuple_size=sizeof(struct "+generate_tuple_name(td->get_tbl_name())+");\n"; ret += "\t\treturn 0;\n}\n"; bool uses_buffer_type = false; for(f=0;fget_type()); if(dt.is_buffer_type()) uses_buffer_type = true; } if(!uses_buffer_type){ ret+="\td=s;\n"; ret+="\ttup->data = (char *)d;\n"; ret+="\ttup->heap_resident=false;\n"; for(f=0;fget_type()); string fldnm = flds[f]->get_name(); // if(dt.needs_hn_translation()) // ret+="\td->"+fldnm+"="+dt.hton_translation()+"(s->"+fldnm+");\n"; // else ret+="\td->"+fldnm+"=s->"+fldnm+";\n"; } ret+= "\ttup->tuple_size=sizeof(struct "+generate_tuple_name(td->get_tbl_name())+");\n"; }else{ ret+="\tint pos=sizeof(struct "+generate_tuple_name(td->get_tbl_name())+");\n"; ret+="\td=(struct "+generate_tuple_name(td->get_tbl_name())+" *)buf;\n"; ret+="\ttup->data = (char *)d;\n"; ret+="\ttup->heap_resident=false;\n"; for(f=0;fget_type()); string fldnm = flds[f]->get_name(); if(dt.is_buffer_type()){ ret+="\tif(pos+"+dt.get_hfta_buffer_size()+"(&(s->"+fldnm+"))>len) return 1;\n"; ret+="\t"+dt.get_hfta_buffer_tuple_copy()+"(&(d->"+fldnm+"),&(s->"+fldnm+"), buf+pos, pos);\n"; ret+="\tpos+="+dt.get_hfta_buffer_size()+"(&(s->"+fldnm+"));\n"; // ret+="\td->"+fldnm+".length = htonl(d->"+fldnm+".length);\n"; // ret+="\td->"+fldnm+".offset = htonl(d->"+fldnm+".offset);\n"; // ret+="\td->"+fldnm+".reserved = htonl(d->"+fldnm+".reserved);\n"; }else{ // if(dt.needs_hn_translation()) // ret+="\td->"+fldnm+"="+dt.hton_translation()+"(s->"+fldnm+");\n"; // else ret+="\td->"+fldnm+"=s->"+fldnm+";\n"; } } ret+="\ttup->tuple_size=pos;\n"; } ret+= "\td->tuple_type = REGULAR_TUPLE;\n"; ret += "\treturn 0;\n"; ret+="}\n\n"; return(ret); } string generate_host_tuple_unpack(table_def *td){ int f; string ret = "struct "+generate_tuple_name(normalize_name(td->get_tbl_name())) +" *unpack_"+normalize_name(td->get_tbl_name())+"_tuple(host_tuple *tup){\n"; ret += "\tstruct "+generate_tuple_name(normalize_name(td->get_tbl_name()))+" *d;\n"; ret+="\td=(struct "+generate_tuple_name(normalize_name(td->get_tbl_name()))+" *)(tup->data);\n"; ret+="\tif(tup->tuple_sizeget_tbl_name())) +")) return NULL;\n"; vector flds = td->get_fields(); for(f=0;fget_type()); string fldnm = flds[f]->get_name(); if(dt.is_buffer_type()){ // ret+="\td->"+fldnm+".length = ntohl(d->"+fldnm+".length);\n"; // ret+="\td->"+fldnm+".offset = ntohl(d->"+fldnm+".offset);\n"; ret+="\td->"+fldnm+".reserved = SHALLOW_COPY;\n"; ret+="\tif(d->"+fldnm+".offset+d->"+fldnm+".length>tup->tuple_size) return NULL;\n"; ret+="\td->"+fldnm+".offset+=(unsigned int)(tup->data);\n"; }else{ // if(dt.needs_hn_translation()) // ret+="\td->"+fldnm+"="+dt.ntoh_translation()+"(d->"+fldnm+");\n"; } } ret += "\treturn d;\n"; ret+="}\n\n"; return(ret); } // Functions related to parsing. int split_string(char *instr,char sep, char **words,int max_words){ char *loc; char *str; int nwords = 0; str = instr; words[nwords++] = str; while( (loc = strchr(str,sep)) != NULL){ *loc = '\0'; str = loc+1; if(nwords >= max_words){ fprintf(stderr,"Error in split_string, too many words discovered (max is %d)\n",max_words); nwords = max_words-1; } words[nwords++] = str; } return(nwords); } std::vector split_string(const string &str, char sep){ char *instr = strdup(str.c_str()); char *words[1000]; int nwords = split_string(instr, sep, words, 1000); vector ret; for(int i=0;i