stage4/generate_c/generate_c.cc
changeset 908 9e8e1ba5ca46
parent 907 c3edb882a4b2
child 913 1c74da17cb61
equal deleted inserted replaced
907:c3edb882a4b2 908:9e8e1ba5ca46
   170 /***********************************************************************/
   170 /***********************************************************************/
   171 /***********************************************************************/
   171 /***********************************************************************/
   172 
   172 
   173 
   173 
   174 static int generate_line_directives__ = 0;
   174 static int generate_line_directives__ = 0;
       
   175 static int generate_pou_filepairs__   = 0;
   175 
   176 
   176 #ifdef __unix__
   177 #ifdef __unix__
   177 /* Parse command line options passed from main.c !! */
   178 /* Parse command line options passed from main.c !! */
   178 #include <stdlib.h> // for getsybopt()
   179 #include <stdlib.h> // for getsybopt()
   179 int  stage4_parse_options(char *options) {
   180 int  stage4_parse_options(char *options) {
   180   enum {                    LINE_OPT = 0             /*, SOME_OTHER_OPT, YET_ANOTHER_OPT */};
   181   enum {                    LINE_OPT = 0            ,  SEPTFILE_OPT              /*, SOME_OTHER_OPT, YET_ANOTHER_OPT */};
   181   char *const token[] = { /*[LINE_OPT]=*/(char *)"l" /*, SOME_OTHER_OPT, ...             */, NULL };
   182   char *const token[] = { /*[LINE_OPT]=*/(char *)"l",/*SEPTFILE_OPT*/(char *)"p" /*, SOME_OTHER_OPT, ...             */, NULL };
   182   /* unfortunately, the above commented out syntax for array initialization is valid in C, but not in C++ */
   183   /* unfortunately, the above commented out syntax for array initialization is valid in C, but not in C++ */
   183   
   184   
   184   char *subopts = options;
   185   char *subopts = options;
   185   char *value;
   186   char *value;
   186   int opt;
   187   int opt;
   187 
   188 
   188   while (*subopts != '\0') {
   189   while (*subopts != '\0') {
   189     switch (getsubopt(&subopts, token, &value)) {
   190     switch (getsubopt(&subopts, token, &value)) {
   190       case LINE_OPT: generate_line_directives__  = 1; break;
   191       case     LINE_OPT: generate_line_directives__  = 1; break;
   191       default      : fprintf(stderr, "Unrecognized option: -O %s\n", value); return -1; break;
   192       case SEPTFILE_OPT: generate_pou_filepairs__    = 1; break;
       
   193       default          : fprintf(stderr, "Unrecognized option: -O %s\n", value); return -1; break;
   192      }
   194      }
   193   }     
   195   }     
   194   return 0;
   196   return 0;
   195 }
   197 }
   196 
   198 
   197 
   199 
   198 void stage4_print_options(void) {
   200 void stage4_print_options(void) {
   199   printf("          (options must be separated by commas. Example: 'l,w,x')\n"); 
   201   printf("          (options must be separated by commas. Example: 'l,w,x')\n"); 
   200   printf("      l : insert '#line' directives in generated C code.\n"); 
   202   printf("      l : insert '#line' directives in generated C code.\n"); 
       
   203   printf("      p : place each POU in a separate pair of files (<pou_name>.c, <pou_name>.h).\n"); 
   201 }
   204 }
   202 #else /* not __unix__ */
   205 #else /* not __unix__ */
   203 /* getsubopt isn't supported with mingw, 
   206 /* getsubopt isn't supported with mingw, 
   204  *  then stage4 options aren't available on windows*/
   207  *  then stage4 options aren't available on windows*/
   205 void stage4_print_options(void) {}
   208 void stage4_print_options(void) {}
   768     generate_c_datatypes_c(stage4out_c *s4o_incl_ptr)
   771     generate_c_datatypes_c(stage4out_c *s4o_incl_ptr)
   769       : generate_c_typedecl_c(s4o_incl_ptr) {
   772       : generate_c_typedecl_c(s4o_incl_ptr) {
   770       current_mode = none_im;
   773       current_mode = none_im;
   771     };
   774     };
   772     virtual ~generate_c_datatypes_c(void) {
   775     virtual ~generate_c_datatypes_c(void) {
   773       while (!inline_array_defined.empty()) {
   776       inline_array_defined.clear(); // Not really necessary...
   774         inline_array_defined.erase(inline_array_defined.begin());
       
   775       }
       
   776     }
   777     }
   777 
   778 
   778     /*************************/
   779     /*************************/
   779     /* B.1 - Common elements */
   780     /* B.1 - Common elements */
   780     /*************************/
   781     /*************************/
   995               symbol->non_generic_type_name->accept(*this);
   996               symbol->non_generic_type_name->accept(*this);
   996               s4o_incl.print(",");
   997               s4o_incl.print(",");
   997               symbol->array_subrange_list->accept(*this);
   998               symbol->array_subrange_list->accept(*this);
   998               s4o_incl.print(")\n\n");
   999               s4o_incl.print(")\n\n");
   999 
  1000 
  1000               inline_array_defined[current_array_name] = 0;
  1001               inline_array_defined[current_array_name] = 0; // insert an element, indicating this array type has been defined!
  1001             }
  1002             }
  1002           }
  1003           }
  1003           break;
  1004           break;
  1004         case arrayname_im:
  1005         case arrayname_im:
  1005           {
  1006           {
  2495     symbol_c *current_configuration;
  2496     symbol_c *current_configuration;
  2496 
  2497 
  2497     const char *current_name;
  2498     const char *current_name;
  2498     const char *current_builddir;
  2499     const char *current_builddir;
  2499 
  2500 
       
  2501     bool        allow_output;
       
  2502     
  2500     unsigned long long common_ticktime;
  2503     unsigned long long common_ticktime;
  2501 
  2504 
  2502   public:
  2505   public:
  2503     generate_c_c(stage4out_c *s4o_ptr, const char *builddir): 
  2506     generate_c_c(stage4out_c *s4o_ptr, const char *builddir): 
  2504             s4o(*s4o_ptr),
  2507             s4o(*s4o_ptr),
  2508             variables_s4o(builddir, "VARIABLES","csv"),
  2511             variables_s4o(builddir, "VARIABLES","csv"),
  2509             generate_c_datatypes(&pous_incl_s4o)
  2512             generate_c_datatypes(&pous_incl_s4o)
  2510     {
  2513     {
  2511       current_builddir = builddir;
  2514       current_builddir = builddir;
  2512       current_configuration = NULL;
  2515       current_configuration = NULL;
       
  2516       allow_output = true;
  2513     }
  2517     }
  2514             
  2518             
  2515     ~generate_c_c(void) {}
  2519     ~generate_c_c(void) {}
  2516 
  2520 
  2517 
  2521 
  2523       s4o                  .enable_output();  
  2527       s4o                  .enable_output();  
  2524       pous_s4o             .enable_output();  
  2528       pous_s4o             .enable_output();  
  2525       pous_incl_s4o        .enable_output();  
  2529       pous_incl_s4o        .enable_output();  
  2526       located_variables_s4o.enable_output();  
  2530       located_variables_s4o.enable_output();  
  2527       variables_s4o        .enable_output();  
  2531       variables_s4o        .enable_output();  
       
  2532       allow_output = true;      
  2528       return NULL;
  2533       return NULL;
  2529     }
  2534     }
  2530     
  2535     
  2531     void *visit(disable_code_generation_pragma_c * symbol)  {
  2536     void *visit(disable_code_generation_pragma_c * symbol)  {
  2532       s4o                  .disable_output();  
  2537       s4o                  .disable_output();  
  2533       pous_s4o             .disable_output();  
  2538       pous_s4o             .disable_output();  
  2534       pous_incl_s4o        .disable_output();  
  2539       pous_incl_s4o        .disable_output();  
  2535       located_variables_s4o.disable_output();  
  2540       located_variables_s4o.disable_output();  
  2536       variables_s4o        .disable_output();  
  2541       variables_s4o        .disable_output();  
       
  2542       allow_output = false;      
  2537       return NULL;
  2543       return NULL;
  2538     } 
  2544     } 
  2539 
  2545 
  2540 
  2546 
  2541 /***************************/
  2547 /***************************/
  2583     }
  2589     }
  2584 
  2590 
  2585 /**************************************/
  2591 /**************************************/
  2586 /* B.1.5 - Program organization units */
  2592 /* B.1.5 - Program organization units */
  2587 /**************************************/
  2593 /**************************************/
       
  2594 #define handle_pou(fname,pname,var_decl_list) \
       
  2595       if (!allow_output) return NULL;\
       
  2596       var_decl_list->accept(generate_c_datatypes);\
       
  2597       if (generate_pou_filepairs__) {\
       
  2598         stage4out_c s4o_c(current_builddir, get_datatype_info_c::get_id_str(pname), "c");\
       
  2599         stage4out_c s4o_h(current_builddir, get_datatype_info_c::get_id_str(pname), "h");\
       
  2600         /* generate_c_datatypes_c generate_c_datatypes_(&s4o_h);*/\
       
  2601         /* var_decl_list->accept(generate_c_datatypes_);*/\
       
  2602         generate_c_pous_c::fname(symbol, s4o_h, true); /* generate the <pou_name>.h file */\
       
  2603         generate_c_pous_c::fname(symbol, s4o_c, false);/* generate the <pou_name>.c file */\
       
  2604         /* add #include directives to the POUS.h and POUS.c files... */\
       
  2605         pous_incl_s4o.print("#include \"");\
       
  2606         pous_s4o.     print("#include \"");\
       
  2607         pous_incl_s4o.print(get_datatype_info_c::get_id_str(pname));\
       
  2608         pous_s4o.     print(get_datatype_info_c::get_id_str(pname));\
       
  2609         pous_incl_s4o.print(".h\"\n");\
       
  2610         pous_s4o.     print(".c\"\n");\
       
  2611       } else {\
       
  2612         generate_c_pous_c::fname(symbol, pous_incl_s4o, true);\
       
  2613         generate_c_pous_c::fname(symbol, pous_s4o,      false);\
       
  2614       }
       
  2615 
  2588 /***********************/
  2616 /***********************/
  2589 /* B 1.5.1 - Functions */
  2617 /* B 1.5.1 - Functions */
  2590 /***********************/
  2618 /***********************/      
  2591     void *visit(function_declaration_c *symbol) {
  2619     void *visit(function_declaration_c *symbol) {
  2592       symbol->var_declarations_list->accept(generate_c_datatypes);
  2620       handle_pou(handle_function,symbol->derived_function_name, symbol->var_declarations_list)
  2593       generate_c_pous_c::handle_function(symbol, pous_incl_s4o, true);
       
  2594       generate_c_pous_c::handle_function(symbol, pous_s4o,      false);
       
  2595       return NULL;
  2621       return NULL;
  2596     }
  2622     }
  2597     
  2623     
  2598 /*****************************/
  2624 /*****************************/
  2599 /* B 1.5.2 - Function Blocks */
  2625 /* B 1.5.2 - Function Blocks */
  2600 /*****************************/
  2626 /*****************************/
  2601     void *visit(function_block_declaration_c *symbol) {
  2627     void *visit(function_block_declaration_c *symbol) {
  2602       symbol->var_declarations->accept(generate_c_datatypes);
  2628       handle_pou(handle_function_block,symbol->fblock_name, symbol->var_declarations)
  2603       generate_c_pous_c::handle_function_block(symbol, pous_incl_s4o, true);
       
  2604       generate_c_pous_c::handle_function_block(symbol, pous_s4o,      false);
       
  2605       return NULL;
  2629       return NULL;
  2606     }
  2630     }
  2607     
  2631     
  2608 /**********************/
  2632 /**********************/
  2609 /* B 1.5.3 - Programs */
  2633 /* B 1.5.3 - Programs */
  2610 /**********************/    
  2634 /**********************/    
  2611     void *visit(program_declaration_c *symbol) {
  2635     void *visit(program_declaration_c *symbol) {
  2612       symbol->var_declarations->accept(generate_c_datatypes);
  2636       handle_pou(handle_program,symbol->program_type_name, symbol->var_declarations)
  2613       generate_c_pous_c::handle_program(symbol, pous_incl_s4o, true);
       
  2614       generate_c_pous_c::handle_program(symbol, pous_s4o,      false);
       
  2615       return NULL;
  2637       return NULL;
  2616     }
  2638     }
  2617     
  2639     
  2618 
  2640 
  2619 /********************************/
  2641 /********************************/