allow main methods without parameters and main methods returning void,
authorJürg Billeter <j@bitron.ch>
Thu, 23 Nov 2006 20:48:25 +0000 (20:48 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Thu, 23 Nov 2006 20:48:25 +0000 (20:48 +0000)
2006-11-23  Jürg Billeter  <j@bitron.ch>

* vala/valacodegenerator.vala: allow main methods without parameters and
  main methods returning void, check complete signature of main method

svn path=/trunk/; revision=181

vala/ChangeLog
vala/vala/valacodegenerator.vala

index b28b3ed..c077545 100644 (file)
@@ -1,3 +1,8 @@
+2006-11-23  Jürg Billeter  <j@bitron.ch>
+
+       * vala/valacodegenerator.vala: allow main methods without parameters and
+         main methods returning void, check complete signature of main method
+
 2006-11-22  Jürg Billeter  <j@bitron.ch>
 
        * vala/parser.y, vala/valacodegenerator.vala: support enum members with
index 57bd298..4e7bfae 100644 (file)
@@ -1322,21 +1322,86 @@ public class Vala.CodeGenerator : CodeVisitor {
                        function.block.add_statement (creturn);
                }
                
-               if (m.name != null && m.name == "main") {
+               bool return_value = true;
+               bool args_parameter = true;
+               if (is_possible_entry_point (m, ref return_value, ref args_parameter)) {
+                       // m is possible entry point, add appropriate startup code
                        var cmain = new CCodeFunction ("main", "int");
                        cmain.add_parameter (new CCodeFormalParameter ("argc", "int"));
                        cmain.add_parameter (new CCodeFormalParameter ("argv", "char **"));
                        var main_block = new CCodeBlock ();
                        main_block.add_statement (new CCodeExpressionStatement (new CCodeFunctionCall (new CCodeIdentifier ("g_type_init"))));
                        var main_call = new CCodeFunctionCall (new CCodeIdentifier (function.name));
-                       main_call.add_argument (new CCodeIdentifier ("argc"));
-                       main_call.add_argument (new CCodeIdentifier ("argv"));
-                       main_block.add_statement (new CCodeReturnStatement (main_call));
+                       if (args_parameter) {
+                               main_call.add_argument (new CCodeIdentifier ("argc"));
+                               main_call.add_argument (new CCodeIdentifier ("argv"));
+                       }
+                       if (return_value) {
+                               main_block.add_statement (new CCodeReturnStatement (main_call));
+                       } else {
+                               // method returns void, always use 0 as exit code
+                               main_block.add_statement (new CCodeExpressionStatement (main_call));
+                               main_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("0")));
+                       }
                        cmain.block = main_block;
                        source_type_member_definition.append (cmain);
                }
        }
        
+       private bool is_possible_entry_point (Method! m, ref bool return_value, ref bool args_parameter) {
+               if (m.name == null || m.name != "main") {
+                       // method must be called "main"
+                       return false;
+               }
+               
+               if (m.instance) {
+                       // method must be static
+                       return false;
+               }
+               
+               if (m.return_type.data_type == null) {
+                       return_value = false;
+               } else if (m.return_type.data_type == int_type.data_type) {
+                       return_value = true;
+               } else {
+                       // return type must be void or int
+                       return false;
+               }
+               
+               var params = m.get_parameters ();
+               if (params.length () == 0) {
+                       // method may have no parameters
+                       args_parameter = false;
+                       return true;
+               }
+               
+               if (params.length () > 1) {
+                       // method must not have more than one parameter
+                       return false;
+               }
+               
+               var param = (FormalParameter) params.data;
+
+               if (param.type_reference.is_out) {
+                       // parameter must not be an out parameter
+                       return false;
+               }
+               
+               if (!(param.type_reference.data_type is Array)) {
+                       // parameter must be an array
+                       return false;
+               }
+               
+               var array_type = (Array) param.type_reference.data_type;
+               if (array_type.element_type != string_type.data_type) {
+                       // parameter must be an array of strings
+                       return false;
+               }
+               
+               args_parameter = true;
+               return true;
+       }
+       
        public override void visit_formal_parameter (FormalParameter! p) {
                if (!p.ellipsis) {
                        p.ccodenode = new CCodeFormalParameter (p.name, p.type_reference.get_cname ());