#ifndef AST_TO_C_C #define AST_TO_C_C AST_TO_C_C #include #include void ast_to_c(char *output_name,struct AST *tree) { size_t output_name_length; char *hold_name; FILE *hold_out; if(output_name!=NULL) { output_name_length=strnlen(output_name,1000); hold_name=calloc(output_name_length+100,1); memcpy(hold_name,output_name,output_name_length); memcpy(hold_name+output_name_length,".h",sizeof(".h")); hold_out=fopen(hold_name,"w"); ast_translation_unit_to_c_print_header_part(hold_out,output_name,(struct AST_Translation_Unit*)tree); fclose(hold_out); memcpy(hold_name+output_name_length,".c",sizeof(".c")); hold_out=fopen(hold_name,"w"); ast_translation_unit_to_c_print_body_part(hold_out,output_name,(struct AST_Translation_Unit*)tree); fclose(hold_out); memcpy(hold_name+output_name_length,"_external.h",sizeof("_external.h")); hold_out=fopen(hold_name,"w"); ast_translation_unit_to_c_print_external_commands(hold_out,output_name,(struct AST_Translation_Unit*)tree); fclose(hold_out); free(hold_name); }else { ast_translation_unit_to_c_print_external_commands(stdout,NULL,(struct AST_Translation_Unit*)tree); ast_translation_unit_to_c_print_header_part(stdout,NULL,(struct AST_Translation_Unit*)tree); ast_translation_unit_to_c_print_body_part(stdout,NULL,(struct AST_Translation_Unit*)tree); } } void ast_translation_unit_to_c_print_base_name(FILE *out, char *base_name) { size_t i; for(i=0;i<1000 && base_name[i]!='\0';++i) fprintf(out,"%c",toupper(base_name[i])); } void ast_translation_unit_to_c_print_header_string(FILE *out,char *base_name,char *file_suffix) { fprintf(out,"#ifndef "); ast_translation_unit_to_c_print_base_name(out,base_name); fprintf(out,"%s\n#define ",file_suffix); ast_translation_unit_to_c_print_base_name(out,base_name); fprintf(out,"%s ",file_suffix); ast_translation_unit_to_c_print_base_name(out,base_name); fprintf(out,"%s\n",file_suffix); } void ast_translation_unit_to_c_print_footer_string(FILE *out,char *base_name,char *file_suffix) { fprintf(out,"\n#endif //#ifndef "); ast_translation_unit_to_c_print_base_name(out,base_name); fprintf(out,"%s",file_suffix); } void ast_translation_unit_to_c_print_header_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit) { size_t i; if(base_name) { ast_translation_unit_to_c_print_header_string(out,base_name,"_H"); fprintf(out,"#include\n\n"); } ast_to_c_print_internal_stuff_for_header(out,translation_unit); for(i=0;inumber_of_machines;++i) ast_machine_to_c_make_header_part(out,translation_unit->machines[i]); ast_machines_to_c_array(out,translation_unit); if(base_name) ast_translation_unit_to_c_print_footer_string(out,base_name,"_H"); } void ast_translation_unit_to_c_print_body_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit) { size_t i; if(base_name) { ast_translation_unit_to_c_print_header_string(out,base_name,"_C"); fprintf(out,"#include \"%s.h\"\n",base_name); fprintf(out,"#include \"%s_external.h\"\n\n",base_name); } for(i=0;inumber_of_machines;++i) ast_machine_to_c_make_body_part(out,translation_unit->machines[i]); ast_to_c_print_internal_stuff_for_body(out); if(base_name) ast_translation_unit_to_c_print_footer_string(out,base_name,"_C"); } void ast_translation_unit_to_c_print_external_commands(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit) { if(base_name) { ast_translation_unit_to_c_print_header_string(out,base_name,"_EXTERNAL_H"); fprintf(out,"#include \"%s.h\"\n\n",base_name); } Map_Map_Extended(translation_unit->used_commands_map,(void (*)(void*,void*))ast_command_to_c_extern_declaration,out); if(base_name) { ast_translation_unit_to_c_print_footer_string(out,base_name,"_EXTERNAL_H"); } } void ast_machine_to_c(FILE *out,struct AST_Machine *machine) { assert(out!=NULL && machine!=NULL && machine->type==AST_TYPE_MACHINE); ast_machine_to_c_make_header_part(out,machine); ast_machine_to_c_make_body_part(out,machine); } void ast_machine_to_c_make_body_part(FILE *out,struct AST_Machine *machine) { size_t i; struct State_And_Transitions **table; table=extract_transition_table(machine->states,machine->transitions); for(i=0;istates->number_of_states;++i) { ast_state_to_c_signature(out,machine,machine->states->states[i]); fprintf(out,"\n{\n"); ast_transitions_of_state_to_c(out,machine,table[i]); fprintf(out,"\n}\n"); } } void ast_machine_to_c_make_header_part(FILE *out,struct AST_Machine *machine) { ast_events_to_c(out,machine); ast_states_to_c(out,machine); } void ast_events_to_c(FILE *out,struct AST_Machine *machine) { size_t i; assert(out!=NULL && machine!=NULL && machine->type==AST_TYPE_MACHINE); fprintf(out,"enum "); ast_machine_enum_tag(out,machine); fprintf(out,"\n{\n"); for(i=0;ievents->number_of_events;++i) { fprintf(out,"\t"); ast_event_to_c_enum(out,machine,machine->events->events[i]); fprintf(out,",\n"); } fprintf(out,"};\n"); } void ast_states_to_c(FILE *out,struct AST_Machine *machine) { size_t i; assert(out!=NULL && machine!=NULL && machine->type==AST_TYPE_MACHINE); for(i=0;istates->number_of_states;++i) { fprintf(out,"extern "); ast_state_to_c_signature(out,machine,machine->states->states[i]); fprintf(out,";\n"); } } void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct State_And_Transitions *vector) { size_t i; //fprintf(out,"\tmachine_buffer_t *hold_buffer;\n\thold_buffer=input;\n\n"); if(vector->number_of_transitions>0) { fprintf(out,"\tswitch(event)\n\t{\n"); for(i=0;inumber_of_transitions;++i) { fprintf(out,"\t\tcase "); ast_event_to_c_enum(out,machine,vector->transitions[i]->event); fprintf(out,":\n"); ast_pipeline_to_c(out,3,vector->transitions[i]->pipeline); fprintf(out,"\t\t\tmachine_states["); ast_token_to_c(out,machine->id); fprintf(out,"]="); ast_state_to_c_function_name(out,machine,vector->transitions[i]->to); fprintf(out,";\n\t\t\tbreak;\n"); } fprintf(out,"\t}\n"); } fprintf(out,"\tdelete_machine_buffer(input);\n"); } /*prints the enum tag for the given machine*/ void ast_machine_enum_tag(FILE *out,struct AST_Machine *machine) { fprintf(out,"MACHINE_"); ast_token_to_c(out,machine->id); fprintf(out,"_EVENTS_ENUM"); } void ast_state_to_c_signature(FILE *out,struct AST_Machine *machine,struct AST_State *state) { fprintf(out,"void "); ast_state_to_c_function_name(out,machine,state); fprintf(out,"(int event,machine_buffer_t *input)"); } void ast_token_to_c(FILE *out,struct token *token) { size_t i; assert(out!=NULL && token!=NULL); for(i=0;isize;++i) fprintf(out,"%c",token->data[i]); } void ast_pipeline_to_c(FILE *out,size_t indentation,struct AST_Pipeline *pipeline) { size_t i; if(pipeline==NULL) return; for(i=0;isize;++i) { ast_to_c_print_tabs(out,indentation); fprintf(out,"input="); ast_command_to_c(out,pipeline->pipeline[i],"input"); fprintf(out,";\n"); } //ast_to_c_print_tabs(out,indentation); } void ast_command_to_c(FILE *out,struct AST_Command *command,char *hold_buffer) { ast_token_to_c(out,command->function_name); fprintf(out,"("); if(command->argument==NULL) fprintf(out,"NULL"); else ast_token_to_c(out,command->argument); fprintf(out,",%s)",hold_buffer); } void ast_command_to_c_extern_declaration(struct AST_Command *command,FILE *out) { fprintf(out,"extern machine_buffer_t* "); ast_token_to_c(out,command->function_name); fprintf(out,"(machine_buffer_t *arguments,machine_buffer_t *input);\n"); } void ast_to_c_print_tabs(FILE *out,size_t number_of_tabs) { size_t i; for(i=0;inumber_of_machines;++i) { ast_state_to_c_function_name(out,translation_unit->machines[i],translation_unit->machines[i]->starting_state); fprintf(out,","); } fprintf(out,"};\n"); } void ast_machines_to_c_enum(FILE *out,struct AST_Translation_Unit *translation_unit) { size_t i; fprintf(out,"enum MACHINES_ENUM\n{\n"); for(i=0;inumber_of_machines;++i) { fprintf(out,"\t"); ast_token_to_c(out,translation_unit->machines[i]->id); fprintf(out,",\n"); } fprintf(out,"\tMACHINES_ENUM_END\n};\n"); } void ast_state_to_c_function_name(FILE *out,struct AST_Machine *machine,struct AST_State *state) { fprintf(out,"machine_"); ast_token_to_c(out,machine->id); fprintf(out,"_state_"); ast_token_to_c(out,state->name); } void ast_event_to_c_enum(FILE *out,struct AST_Machine *machine,struct AST_Event *event) { ast_token_to_c(out,machine->id); fprintf(out,"_EVENT_"); ast_token_to_c(out,event->name); } void ast_to_c_print_internal_stuff_for_header(FILE *out,struct AST_Translation_Unit *translation_unit) { fprintf(out,"\n\n"); ast_machines_to_c_enum(out,translation_unit); fprintf(out,"\n\n"); ast_to_c_print_comment(out,"\tthis is the structure that facilitates data exchange"); fprintf(out,"typedef struct machine_buffer_t \n{" "\n\tsize_t size;\n\tunsigned char buffer[];\n} machine_buffer_t;\n\n"); ast_to_c_print_comment(out, "\tuse this function to pass an event to a machine\n" "\tthe input buffer is passed to the first executed function if any\n" "\tany remaining buffer after the pipeline has finished is passed\n" "\tto the delete_machine_buffer function\n" "\tinput can be NULL" ); fprintf(out,"void push_event_to_machine(enum MACHINES_ENUM machine,int event,machine_buffer_t *input);\n\n"); ast_to_c_print_comment(out, "\tthis function creates a buffer structure in the heap\n" "\tit COPIES the contents of content \n" "\tsize is in bytes" ); fprintf(out,"machine_buffer_t* get_machine_buffer(void *content,size_t size);\n\n"); ast_to_c_print_comment(out,"\tfrees the buffer from the heap"); fprintf(out,"void delete_machine_buffer(machine_buffer_t *buffer);\n\n"); } void ast_to_c_print_internal_stuff_for_body(FILE *out) { fprintf(out, "void push_event_to_machine(enum MACHINES_ENUM machine,int event,machine_buffer_t *input)\n" "{\n" "\tif(machinesize=size;\n" "\tfor(i=0;ibuffer[i]=((unsigned char*)content)[i];\n" "\treturn ret;\n" "}\n"); fprintf(out, "\nvoid delete_machine_buffer(machine_buffer_t *buffer)\n" "{\n" "\tif(buffer)\n" "\t{\n" "\t\tfree(buffer);\n" "\t}\n}" ); } void ast_to_c_print_comment(FILE *out,char *comment) { fprintf(out,"/*\n"); fprintf(out,"%s\n",comment); fprintf(out,"*/\n"); } #endif