ModuleFunctionList * parse_function_section(FILE * input,DYNFILE * dfp,FailureType * ft,boolean addnumbers) { ModuleFunctionList * out; boolean outoffunction=TRUE; char * name; boolean next_line_alloc = FALSE; boolean next_line_free = FALSE; char buffer[MAXLINE]; char * tempb; ModuleFunction * mf; FuncInfo * fi = NULL; out = ModuleFunctionList_alloc_std(); while( get_watched_line(buffer,MAXLINE,input) != NULL) { chop_newline(buffer); if( strstartcmp(buffer,"%}") == 0) break; if( strstartcmp(buffer,"%func") == 0 ) { /* fprintf(stderr,"Getting info line!\n"); */ fi = read_FuncInfo_line(buffer,input); fi->is_hand_written = TRUE; if( fi == NULL ) { warn("Unable to read function info line at %s. Probably going to give a parse error",buffer); } else add_DYNFILE(dfp,fi); continue; } if( outoffunction == TRUE ) { if( buffer[0] == '{' ) { outoffunction = FALSE; fputs_func_DYNFILE(buffer,dfp); continue; } /* fprintf(stderr,"Got here [%s]\n",buffer); */ if( buffer[0] == '\0' || isspace(buffer[0]) || strstartcmp(buffer,"static") == 0 || buffer[0] == '#' || buffer[0] == '/' || buffer[0] == '*' ) { next_line_alloc = next_line_free = FALSE; fputs_func_DYNFILE(buffer,dfp); continue; } /*** if the line starts with a ! we want to interpret it ***/ /*** as a dynamite specific tag ***/ if( strstartcmp(buffer,"!constructor") == 0 ) { next_line_alloc = TRUE; continue; } if( strstartcmp(buffer,"!deconstructor") == 0 ) { next_line_free = TRUE; continue; } if ( buffer[0] == '!' ) { next_line_alloc = next_line_free = FALSE; continue; } /*fprintf(stderr,"Got here again [%s]\n",buffer);*/ /*** ok this should be a function! ****/ if( next_line_alloc == TRUE || next_line_free == TRUE ) { tempb = stringalloc(buffer); name = parse_and_get_module_name_from_func(tempb,next_line_alloc); if(name == NULL) { warn("Function [%s] specified as cons/decons, but no module name parsed...",buffer); } else { if( (mf=get_ModuleFunction_from_name(out,name)) == NULL ) mf = new_ModuleFunction(out,name); if( next_line_alloc == TRUE ) { if( mf->has_cons == TRUE ) warn("Module %s already has a constructor... double overload!",name); else mf->has_cons = TRUE; } else { if( mf->has_decons == TRUE ) warn("Module %s already has a deconstructor... double overload",name); else mf->has_decons = TRUE; } ckfree(name); } ckfree(tempb); } /*** end of if cons/decons ***/ next_line_alloc = next_line_free = FALSE; /*** reconcile with fi if any ***/ if( fi != NULL ) { reconcile_FuncInfo_with_funcstr(fi,buffer); dfp->funcpos += show_eddystyle_FuncInfo(fi,dfp->func); /** already added to DYNFILE **/ } else { /* fprintf(stderr,"Using [%s] as an unknown function\n",buffer); */ fi = unknown_user_FuncInfo(buffer); /* fprintf(stderr,"Unknown function %s...\n",fi->name);*/ add_DYNFILE(dfp,fi); } /*** put #line compiler information ***/ /*** using global parsed file which is also used for errors... sort of yukky. ***/ if( addnumbers == TRUE) { fprintf(dfp->func,"# line %d \"%s\"\n",get_watched_linecount(),parsed_file); dfp->funcpos++; } /*** put line ***/ fi->line_in_c = dfp->funcpos; fi = NULL; fputs_func_DYNFILE(buffer,dfp); /*** put away function now ***/ /*** header information will be put away in dfp call ***/ } else { /*** actually inside a function ***/ if( buffer[0] == '}' ) outoffunction = TRUE; fputs_func_DYNFILE(buffer,dfp); } } return out; }
boolean do_a_file(char * sourcename,MethodTypeSet * mts,boolean write_html_now,int c_protection_level,boolean should_hard_link,boolean should_warn_undocs,boolean addnumbers,char * package,APIpara * api_para,FailureType * ft) { FILE * ifp = NULL; DYNFILE * dfp = NULL; char * outputname = NULL; char * runner; char * rt; char c; char buffer[MAXLINE]; Dynamite * dyn; ModuleFunctionList * mfl = NULL; boolean end_of_file; ParseError pfail; int no; int i; #ifdef COMPUGEN OneModel * om; #endif /* Read first block */ /* read_plain_scan_and_replace("test.kar"); */ /*** open source ***/ ifp = openfile(sourcename,"r"); if( ifp == NULL ){ warn("Could not open [%s] as Dynamite source",sourcename); return FALSE; } open_watch_file(ifp); parsed_file = stringalloc(sourcename); push_errormsg_stack_call(parse_line_error); /*** open DYNFILE ***/ runner = strrchr(sourcename,'.'); if( runner == NULL ) { warn("Source %s has no . character. Not critical, but worrying...",sourcename); runner = sourcename + strlen(sourcename); } /*** hard coding debug for the moment ***/ c = *runner; *runner = '\0'; if( (dfp = open_std_no_html_dynfile(sourcename)) == NULL) { warn("Could not open DYNFILE system for output %s\n",outputname); goto error; } dfp->code_debug_level = c_protection_level; dfp->should_hard_link = should_hard_link; if( package != NULL ) { dfp->package_name = stringalloc(package); } *runner = c; /* Skip to %{ */ while( (rt=get_watched_line(buffer,MAXLINE,ifp)) != NULL) { if(strstartcmp(buffer,"%{") == 0) break; } if( rt == NULL) { log_full_error(WARNING,0,"Exhausted dynamite source [%s] without reading any blocks - consult man/help pages!",sourcename); goto error; } /* * Header region * Dump until next block %} * */ while( (rt=get_watched_line(buffer,MAXLINE,ifp)) != NULL) { if(strstartcmp(buffer,"%}") == 0) break; fputs(buffer,dfp->head); } if( rt == NULL) { warn("had only header information in dynamite file, no close header %}"); goto error; } /* Load in Dynamite */ dyn = read_Dynamite(ifp,"%{",&end_of_file,mts); if( dyn == NULL ) { log_full_error(WARNING,0,"Unable to read Dynamite models. Parse error."); goto error; } /* probably should check it now! */ pop_errormsg_stack(); pfail = (PERR_ARG_MISTYPE | PERR_ARG_NUM_MIS | PERR_SYNTAX); if( prepare_Dynamite(dyn,mts,dpi->dycw,pfail) == FALSE ) { log_full_error(FATAL,0,"A Dynamite blueprint fails semantic checks. Please refer to previous errors for the precise problem"); goto error; } if( tele_file != NULL ) { for(i=0;i<dyn->len;i++) { if( dyn->list[i]->type == DYNAMITETYPEGENERICMATRIX ) { write_Telegraph_grammar((GenericMatrix*)dyn->list[i]->data,tele_file); } } } /*** writes out user functions ***/ if( end_of_file == FALSE) { push_errormsg_stack_call(parse_line_error); mfl = parse_function_section(ifp,dfp,ft,addnumbers); pop_errormsg_stack(); } else { write_Dynamite_minimal_func(dfp); mfl = NULL; } /*** write out the header ***/ write_Dynamite_header(dyn,dpi,dfp); /*** writes out dynamite functions ***/ /*** should write line number now ***/ fprintf(dfp->func,"# line %d \"%s.c\"\n",dfp->funcpos,dfp->sourceroot); dfp->funcpos++; write_Dynamite_func(dyn,mfl,dpi,dfp); #ifdef COMPUGEN if( dyn->len > 0 && dyn->list[0]->type == DYNAMITETYPEGENERICMATRIX && dpi->doone == TRUE) { om = OneModel_from_GenericMatrix((GenericMatrix *) dyn->list[0]->data); if( om == NULL ) { warn("Cannot built Compugen port!"); } else { write_cugen_funcs(om,mts,dfp); } } #endif positionify_DYNFILE(dfp); /* check errors... could fail here */ if( have_got_unknown_func_DYNFILE(dfp,&no,should_warn_undocs) == TRUE) { *ft = (*ft | FailureType_dyc_UF); warn("You have %d undocumented functions",no); } if( should_make_API(api_para) == TRUE ) make_API(dfp,dyn,api_para); place_declarations_DYNFILE(dfp,FO_CUI_POSITION); /*** close Dynfile ***/ if(dyn != NULL) free_Dynamite(dyn); if( mfl != NULL ) free_ModuleFunctionList(mfl); close_dynfile(dfp); close_watch_file(); fclose(ifp); return TRUE; error : if( ifp != NULL) { fclose(ifp); close_watch_file(); } if( dfp != NULL) close_dynfile(dfp); return FALSE; }
FuncInfo * read_FuncInfo_line(char * line,FILE * ifp) { FuncInfo * out; ArgInfo * ari; char buffer[MAXLINE]; char * runner; if( strstartcmp(line,"%func") != 0 ) { warn("Attempting to read in-line function help with line starting [%30s] not %func",line); return NULL; } out = FuncInfo_alloc_std(); out->functype = FI_CALLABLE; out->ft = read_Ftext(buffer,MAXLINE,ifp,"%",get_watched_line); if( strstartcmp(buffer,"%%") == 0 ) return out; /*** could be in any order ***/ for(;;) { /* fprintf(stderr,"Looking at [%s]\n",buffer); */ if( feof(ifp) || ferror(ifp) ) { warn("End of file or file read error while in FuncInfo read. Not good!"); break; } else if ( strstartcmp(buffer,"%%") == 0 ) { break; } else if ( strstartcmp(buffer,"%simple") == 0 ) { if( (runner=strtok(buffer+7,spacestr)) == NULL ) { warn("Got a simple name specification, but no name!"); } else { out->simple = stringalloc(runner); } get_watched_line(buffer,MAXLINE,ifp); } else if( strstartcmp(buffer,"%arg") == 0) { while( get_watched_line(buffer,MAXLINE,ifp) != NULL ) { if( buffer[0] == '%' ) break; ari = read_ArgInfo_line(buffer); if( strcmp(ari->name,"return") == 0 ) { out->ret = ari; } else if( ari != NULL ) { add_FuncInfo(out,ari); } } } else if ( strstartcmp(buffer,"%short") == 0 ) { for(runner=buffer;*runner && !isspace(*runner);runner++) ; for(;*runner && isspace(*runner);runner++) ; out->sdesc=stringalloc(runner); get_watched_line(buffer,MAXLINE,ifp); } else if ( strstartcmp(buffer,"%type") == 0 ) { if( strstr(buffer,"call") != NULL ) { out->functype = FI_CALLABLE; } else if ( strstr(buffer,"int") != NULL ) { out->functype = FI_INTERNAL; } get_watched_line(buffer,MAXLINE,ifp); } else { warn("Cannot understand %% tag %20s\n",buffer); while( get_watched_line(buffer,MAXLINE,ifp) != NULL ) { if( buffer[0] == '%' ) break; } } if( buffer[0] == '%') continue; /*** back to for(;;) ***/ /* else */ warn("In funcinfo line, could not understand [%s], going to skip to next %% tag",buffer); while( get_watched_line(buffer,MAXLINE,ifp) != NULL ) { chop_newline(buffer); if( buffer[0] == '%' ) break; else { warn("Did not interpret line [%s]\n",buffer); } } } return out; }