diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2017-05-08 13:46:22 +0200 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2018-05-08 08:25:18 +0200 |
commit | 489895fbd7a550e661f9f6ea19d3dcd25d0cc790 (patch) | |
tree | cbbf9a2ef40e0f5b7bee098798f0006ba3ed11cb | |
parent | f7e70338aee8717f4b2050f442d9a6fc41b50d5d (diff) | |
download | vala-489895fbd7a550e661f9f6ea19d3dcd25d0cc790.tar.gz |
Reintroduce POSIX profile
This reverts commit ca020bf04a09fe16e5583eea5a3a341e7796bff5.
33 files changed, 786 insertions, 220 deletions
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala index 39a98e45f..cd9377512 100644 --- a/codegen/valaccodearraymodule.vala +++ b/codegen/valaccodearraymodule.vala @@ -57,8 +57,14 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule { return; } - var gnew = new CCodeFunctionCall (new CCodeIdentifier ("g_new0")); - gnew.add_argument (new CCodeIdentifier (get_ccode_name (expr.element_type))); + CCodeFunctionCall gnew; + if (context.profile == Profile.POSIX) { + cfile.add_include ("stdlib.h"); + gnew = new CCodeFunctionCall (new CCodeIdentifier ("calloc")); + } else { + gnew = new CCodeFunctionCall (new CCodeIdentifier ("g_new0")); + gnew.add_argument (new CCodeIdentifier (get_ccode_name (expr.element_type))); + } bool first = true; CCodeExpression cexpr = null; @@ -83,6 +89,12 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule { gnew.add_argument (cexpr); + if (context.profile == Profile.POSIX) { + var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); + csizeof.add_argument (new CCodeIdentifier (get_ccode_name (expr.element_type))); + gnew.add_argument (csizeof); + } + var temp_var = get_temp_variable (expr.value_type, true, expr); var name_cnode = get_variable_cexpression (temp_var.name); int i = 0; diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala index eb47fc134..9d7bc1783 100644 --- a/codegen/valaccodeattribute.vala +++ b/codegen/valaccodeattribute.vala @@ -713,14 +713,30 @@ public class Vala.CCodeAttribute : AttributeCache { } else if (node is GenericType) { var type = (GenericType) node; if (type.value_owned) { - return "gpointer"; + if (CodeContext.get ().profile == Profile.GOBJECT) { + return "gpointer"; + } else { + return "void *"; + } } else { - return "gconstpointer"; + if (CodeContext.get ().profile == Profile.GOBJECT) { + return "gconstpointer"; + } else { + return "const void *"; + } } } else if (node is MethodType) { - return "gpointer"; + if (CodeContext.get ().profile == Profile.GOBJECT) { + return "gpointer"; + } else { + return "void *"; + } } else if (node is NullType) { - return "gpointer"; + if (CodeContext.get ().profile == Profile.GOBJECT) { + return "gpointer"; + } else { + return "void *"; + } } else if (node is PointerType) { var type = (PointerType) node; if (type.base_type.data_type != null && type.base_type.data_type.is_reference_type ()) { diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 540a014af..fe1b31218 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -454,53 +454,53 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { unichar_type = new IntegerType (unichar_struct); } - var glib_ns = root_symbol.scope.lookup ("GLib"); - - gtype_type = (TypeSymbol) glib_ns.scope.lookup ("Type"); - gobject_type = (TypeSymbol) glib_ns.scope.lookup ("Object"); - gerror_type = new ErrorType (null, null); - glist_type = (Class) glib_ns.scope.lookup ("List"); - gslist_type = (Class) glib_ns.scope.lookup ("SList"); - gnode_type = (Class) glib_ns.scope.lookup ("Node"); - gqueue_type = (Class) glib_ns.scope.lookup ("Queue"); - gvaluearray_type = (Class) glib_ns.scope.lookup ("ValueArray"); - gstringbuilder_type = (TypeSymbol) glib_ns.scope.lookup ("StringBuilder"); - garray_type = (TypeSymbol) glib_ns.scope.lookup ("Array"); - gbytearray_type = (TypeSymbol) glib_ns.scope.lookup ("ByteArray"); - gptrarray_type = (TypeSymbol) glib_ns.scope.lookup ("PtrArray"); - gthreadpool_type = (TypeSymbol) glib_ns.scope.lookup ("ThreadPool"); - gdestroynotify_type = new DelegateType ((Delegate) glib_ns.scope.lookup ("DestroyNotify")); - - gquark_type = new IntegerType ((Struct) glib_ns.scope.lookup ("Quark")); - gvalue_type = (Struct) glib_ns.scope.lookup ("Value"); - gvariant_type = (Class) glib_ns.scope.lookup ("Variant"); - gsource_type = (Class) glib_ns.scope.lookup ("Source"); - - gmutex_type = (Struct) glib_ns.scope.lookup ("Mutex"); - grecmutex_type = (Struct) glib_ns.scope.lookup ("RecMutex"); - grwlock_type = (Struct) glib_ns.scope.lookup ("RWLock"); - gcond_type = (Struct) glib_ns.scope.lookup ("Cond"); - - mutex_type = grecmutex_type; - - type_module_type = (TypeSymbol) glib_ns.scope.lookup ("TypeModule"); - - regex_type = new ObjectType ((Class) root_symbol.scope.lookup ("GLib").scope.lookup ("Regex")); - - if (context.module_init_method != null) { - foreach (Parameter parameter in context.module_init_method.get_parameters ()) { - if (parameter.variable_type.data_type == type_module_type) { - in_plugin = true; - module_init_param_name = parameter.name; - break; + if (context.profile == Profile.GOBJECT) { + var glib_ns = root_symbol.scope.lookup ("GLib"); + + gtype_type = (TypeSymbol) glib_ns.scope.lookup ("Type"); + gobject_type = (TypeSymbol) glib_ns.scope.lookup ("Object"); + gerror_type = new ErrorType (null, null); + glist_type = (Class) glib_ns.scope.lookup ("List"); + gslist_type = (Class) glib_ns.scope.lookup ("SList"); + gnode_type = (Class) glib_ns.scope.lookup ("Node"); + gqueue_type = (Class) glib_ns.scope.lookup ("Queue"); + gvaluearray_type = (Class) glib_ns.scope.lookup ("ValueArray"); + gstringbuilder_type = (TypeSymbol) glib_ns.scope.lookup ("StringBuilder"); + garray_type = (TypeSymbol) glib_ns.scope.lookup ("Array"); + gbytearray_type = (TypeSymbol) glib_ns.scope.lookup ("ByteArray"); + gptrarray_type = (TypeSymbol) glib_ns.scope.lookup ("PtrArray"); + gthreadpool_type = (TypeSymbol) glib_ns.scope.lookup ("ThreadPool"); + gdestroynotify_type = new DelegateType ((Delegate) glib_ns.scope.lookup ("DestroyNotify")); + + gquark_type = new IntegerType ((Struct) glib_ns.scope.lookup ("Quark")); + gvalue_type = (Struct) glib_ns.scope.lookup ("Value"); + gvariant_type = (Class) glib_ns.scope.lookup ("Variant"); + gsource_type = (Class) glib_ns.scope.lookup ("Source"); + + gmutex_type = (Struct) glib_ns.scope.lookup ("Mutex"); + grecmutex_type = (Struct) glib_ns.scope.lookup ("RecMutex"); + grwlock_type = (Struct) glib_ns.scope.lookup ("RWLock"); + gcond_type = (Struct) glib_ns.scope.lookup ("Cond"); + + mutex_type = grecmutex_type; + + type_module_type = (TypeSymbol) glib_ns.scope.lookup ("TypeModule"); + + regex_type = new ObjectType ((Class) root_symbol.scope.lookup ("GLib").scope.lookup ("Regex")); + + if (context.module_init_method != null) { + foreach (Parameter parameter in context.module_init_method.get_parameters ()) { + if (parameter.variable_type.data_type == type_module_type) { + in_plugin = true; + module_init_param_name = parameter.name; + break; + + } } } - if (!in_plugin) { - Report.error (context.module_init_method.source_reference, "[ModuleInit] requires a parameter of type `GLib.TypeModule'"); - } - } - dbus_proxy_type = (TypeSymbol) glib_ns.scope.lookup ("DBusProxy"); + dbus_proxy_type = (TypeSymbol) glib_ns.scope.lookup ("DBusProxy"); + } var gtk_ns = root_symbol.scope.lookup ("Gtk"); if (gtk_ns != null) { @@ -540,7 +540,12 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { // generate C header file for public API if (context.header_filename != null) { - bool ret = header_file.store (context.header_filename, null, context.version_header, false, "G_BEGIN_DECLS", "G_END_DECLS"); + bool ret; + if (context.profile == Profile.GOBJECT) { + ret = header_file.store (context.header_filename, null, context.version_header, false, "G_BEGIN_DECLS", "G_END_DECLS"); + } else { + ret = header_file.store (context.header_filename, null, context.version_header, false); + } if (!ret) { Report.error (null, "unable to open `%s' for writing".printf (context.header_filename)); } @@ -548,7 +553,12 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { // generate C header file for internal API if (context.internal_header_filename != null) { - bool ret = internal_header_file.store (context.internal_header_filename, null, context.version_header, false, "G_BEGIN_DECLS", "G_END_DECLS"); + bool ret; + if (context.profile == Profile.GOBJECT) { + ret = internal_header_file.store (context.internal_header_filename, null, context.version_header, false, "G_BEGIN_DECLS", "G_END_DECLS"); + } else { + ret = internal_header_file.store (context.internal_header_filename, null, context.version_header, false); + } if (!ret) { Report.error (null, "unable to open `%s' for writing".printf (context.internal_header_filename)); } @@ -736,10 +746,12 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { wrappers = new HashSet<string> (str_hash, str_equal); generated_external_symbols = new HashSet<Symbol> (); - header_file.add_include ("glib.h"); - internal_header_file.add_include ("glib.h"); - cfile.add_include ("glib.h"); - cfile.add_include ("glib-object.h"); + if (context.profile == Profile.GOBJECT) { + header_file.add_include ("glib.h"); + internal_header_file.add_include ("glib.h"); + cfile.add_include ("glib.h"); + cfile.add_include ("glib-object.h"); + } source_file.accept_children (this); @@ -3129,7 +3141,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } public CCodeExpression? get_destroy_func_expression (DataType type, bool is_chainup = false) { - if (type.data_type == glist_type || type.data_type == gslist_type || type.data_type == gnode_type || type.data_type == gqueue_type) { + if (context.profile == Profile.GOBJECT && (type.data_type == glist_type || type.data_type == gslist_type || type.data_type == gnode_type || type.data_type == gqueue_type)) { // create wrapper function to free list elements if necessary bool elements_require_free = false; @@ -3233,9 +3245,17 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { return get_variable_cexpression (func_name); } } else if (type is ArrayType) { - return new CCodeIdentifier ("g_free"); + if (context.profile == Profile.POSIX) { + return new CCodeIdentifier ("free"); + } else { + return new CCodeIdentifier ("g_free"); + } } else if (type is PointerType) { - return new CCodeIdentifier ("g_free"); + if (context.profile == Profile.POSIX) { + return new CCodeIdentifier ("free"); + } else { + return new CCodeIdentifier ("g_free"); + } } else { return new CCodeConstant ("NULL"); } @@ -3476,40 +3496,42 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { /* set freed references to NULL to prevent further use */ var ccomma = new CCodeCommaExpression (); - if (type.data_type != null && !is_reference_counting (type.data_type) && - (type.data_type.is_subtype_of (gstringbuilder_type) - || type.data_type.is_subtype_of (garray_type) - || type.data_type.is_subtype_of (gbytearray_type) - || type.data_type.is_subtype_of (gptrarray_type))) { - ccall.add_argument (new CCodeConstant ("TRUE")); - } else if (type.data_type == gthreadpool_type) { - ccall.add_argument (new CCodeConstant ("FALSE")); - ccall.add_argument (new CCodeConstant ("TRUE")); - } else if (type is ArrayType) { - var array_type = (ArrayType) type; - if (requires_destroy (array_type.element_type)) { - CCodeExpression csizeexpr = null; - if (((GLibValue) value).array_length_cvalues != null) { - csizeexpr = get_array_length_cvalue (value); - } else if (get_array_null_terminated (value)) { - requires_array_length = true; - var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length")); - len_call.add_argument (cvar); - csizeexpr = len_call; - } else { - csizeexpr = get_array_length_cexpr (value); - } - - if (csizeexpr != null) { - var st = array_type.element_type.data_type as Struct; - if (st != null && !array_type.element_type.nullable) { - ccall.call = new CCodeIdentifier (append_struct_array_free (st)); - ccall.add_argument (csizeexpr); + if (context.profile == Profile.GOBJECT) { + if (type.data_type != null && !is_reference_counting (type.data_type) && + (type.data_type.is_subtype_of (gstringbuilder_type) + || type.data_type.is_subtype_of (garray_type) + || type.data_type.is_subtype_of (gbytearray_type) + || type.data_type.is_subtype_of (gptrarray_type))) { + ccall.add_argument (new CCodeConstant ("TRUE")); + } else if (type.data_type == gthreadpool_type) { + ccall.add_argument (new CCodeConstant ("FALSE")); + ccall.add_argument (new CCodeConstant ("TRUE")); + } else if (type is ArrayType) { + var array_type = (ArrayType) type; + if (requires_destroy (array_type.element_type)) { + CCodeExpression csizeexpr = null; + if (((GLibValue) value).array_length_cvalues != null) { + csizeexpr = get_array_length_cvalue (value); + } else if (get_array_null_terminated (value)) { + requires_array_length = true; + var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length")); + len_call.add_argument (cvar); + csizeexpr = len_call; } else { - requires_array_free = true; - ccall.call = new CCodeIdentifier ("_vala_array_free"); - ccall.add_argument (csizeexpr); - ccall.add_argument (new CCodeCastExpression (get_destroy_func_expression (array_type.element_type), "GDestroyNotify")); + csizeexpr = get_array_length_cexpr (value); + } + + if (csizeexpr != null) { + var st = array_type.element_type.data_type as Struct; + if (st != null && !array_type.element_type.nullable) { + ccall.call = new CCodeIdentifier (append_struct_array_free (st)); + ccall.add_argument (csizeexpr); + } else { + requires_array_free = true; + ccall.call = new CCodeIdentifier ("_vala_array_free"); + ccall.add_argument (csizeexpr); + ccall.add_argument (new CCodeCastExpression (get_destroy_func_expression (array_type.element_type), "GDestroyNotify")); + } } } } @@ -3961,7 +3983,12 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } public override void visit_boolean_literal (BooleanLiteral expr) { - set_cvalue (expr, new CCodeConstant (expr.value ? "TRUE" : "FALSE")); + if (context.profile == Profile.GOBJECT) { + set_cvalue (expr, new CCodeConstant (expr.value ? "TRUE" : "FALSE")); + } else { + cfile.add_include ("stdbool.h"); + set_cvalue (expr, new CCodeConstant (expr.value ? "true" : "false")); + } } public override void visit_character_literal (CharacterLiteral expr) { @@ -4074,6 +4101,9 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } public override void visit_null_literal (NullLiteral expr) { + if (context.profile != Profile.GOBJECT) { + cfile.add_include ("stddef.h"); + } set_cvalue (expr, new CCodeConstant ("NULL")); var array_type = expr.target_type as ArrayType; @@ -4333,6 +4363,9 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { dup0_func = dupid.name; } else if (add_wrapper (dup0_func)) { string pointer_cname = "gpointer"; + if (context.profile == Profile.POSIX) { + pointer_cname = "void *"; + } var dup0_fun = new CCodeFunction (dup0_func, pointer_cname); dup0_fun.add_parameter (new CCodeParameter ("self", pointer_cname)); dup0_fun.modifiers = CCodeModifiers.STATIC; @@ -5213,7 +5246,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { var cl = expr.type_reference.data_type as Class; var iface = expr.type_reference.data_type as Interface; - if (iface != null || (cl != null && !cl.is_compact)) { + if (context.profile == Profile.GOBJECT && (iface != null || (cl != null && !cl.is_compact))) { // checked cast for strict subtypes of GTypeInstance if (expr.is_silent_cast) { TargetValue to_cast = expr.inner.target_value; @@ -5514,13 +5547,35 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { set_cvalue (expr, new CCodeConstant ("%s %s".printf (left, right))); return; } else { - // convert to g_strconcat (a, b, NULL) var temp_value = create_temp_value (expr.value_type, false, expr); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_strconcat")); - ccall.add_argument (cleft); - ccall.add_argument (cright); - ccall.add_argument (new CCodeConstant("NULL")); + CCodeFunctionCall ccall; + + if (context.profile == Profile.POSIX) { + // convert to strcat (strcpy (malloc (1 + strlen (a) + strlen (b)), a), b) + ccall = new CCodeFunctionCall (new CCodeIdentifier ("strcat")); + var strcpy = new CCodeFunctionCall (new CCodeIdentifier ("strcpy")); + var malloc = new CCodeFunctionCall (new CCodeIdentifier ("malloc")); + + var strlen_a = new CCodeFunctionCall (new CCodeIdentifier ("strlen")); + strlen_a.add_argument (cleft); + var strlen_b = new CCodeFunctionCall (new CCodeIdentifier ("strlen")); + strlen_b.add_argument (cright); + var newlength = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("1"), + new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, strlen_a, strlen_b)); + malloc.add_argument (newlength); + + strcpy.add_argument (malloc); + strcpy.add_argument (cleft); + + ccall.add_argument (strcpy); + ccall.add_argument (cright); + } else { + // convert to g_strconcat (a, b, NULL) + ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_strconcat")); + ccall.add_argument (cleft); + ccall.add_argument (cright); + ccall.add_argument (new CCodeConstant("NULL")); + } ccode.add_assignment (get_cvalue_ (temp_value), ccall); expr.target_value = temp_value; @@ -5753,11 +5808,13 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { bool unboxing = (type is ValueType && type.nullable && target_type is ValueType && !target_type.nullable); - bool gvalue_boxing = (target_type != null + bool gvalue_boxing = (context.profile == Profile.GOBJECT + && target_type != null && target_type.data_type == gvalue_type && !(type is NullType) && get_ccode_type_id (type) != "G_TYPE_VALUE"); - bool gvariant_boxing = (target_type != null + bool gvariant_boxing = (context.profile == Profile.GOBJECT + && target_type != null && target_type.data_type == gvariant_type && !(type is NullType) && type.data_type != gvariant_type); diff --git a/codegen/valaccodecompiler.vala b/codegen/valaccodecompiler.vala index 05a71636d..76549c94c 100644 --- a/codegen/valaccodecompiler.vala +++ b/codegen/valaccodecompiler.vala @@ -36,15 +36,23 @@ public class Vala.CCodeCompiler { * @param context a code context */ public void compile (CodeContext context, string? cc_command, string[] cc_options) { - string pc = " gobject-2.0"; + string pc = ""; + if (context.profile == Profile.GOBJECT) { + pc += " gobject-2.0"; + } foreach (string pkg in context.get_packages ()) { if (context.pkg_config_exists (pkg)) { pc += " " + pkg; } } - string? pkgflags = context.pkg_config_compile_flags (pc); - if (pkgflags == null) { - return; + string? pkgflags; + if (pc.length > 0) { + pkgflags = context.pkg_config_compile_flags (pc); + if (pkgflags == null) { + return; + } + } else { + pkgflags = ""; } // TODO compile the C code files in parallel diff --git a/codegen/valaccodecontrolflowmodule.vala b/codegen/valaccodecontrolflowmodule.vala index 6b5505b12..1936d512d 100644 --- a/codegen/valaccodecontrolflowmodule.vala +++ b/codegen/valaccodecontrolflowmodule.vala @@ -206,7 +206,12 @@ public abstract class Vala.CCodeControlFlowModule : CCodeMethodModule { } public override void visit_loop (Loop stmt) { - ccode.open_while (new CCodeConstant ("TRUE")); + if (context.profile == Profile.GOBJECT) { + ccode.open_while (new CCodeConstant ("TRUE")); + } else { + cfile.add_include ("stdbool.h"); + ccode.open_while (new CCodeConstant ("true")); + } stmt.body.emit (this); diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala index 65b455fa5..fb78e5985 100644 --- a/codegen/valaccodemethodcallmodule.vala +++ b/codegen/valaccodemethodcallmodule.vala @@ -53,6 +53,8 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { // Enum.VALUE.to_string() var en = (Enum) ma.inner.value_type.data_type; ccall.call = new CCodeIdentifier (generate_enum_tostring_function (en)); + } else if (context.profile == Profile.POSIX && ma.inner != null && ma.inner.value_type != null && ma.inner.value_type.data_type == string_type.data_type && ma.member_name == "printf") { + ccall.call = new CCodeIdentifier (generate_string_printf_function ()); } else if (expr.is_constructv_chainup) { ccall.call = new CCodeIdentifier (get_ccode_constructv_name ((CreationMethod) m)); } @@ -132,8 +134,12 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { } if (m is CreationMethod && m.parent_symbol is Class) { - if (!((Class) m.parent_symbol).is_compact) { - ccall.add_argument (get_variable_cexpression ("object_type")); + if (context.profile == Profile.GOBJECT) { + if (!((Class) m.parent_symbol).is_compact) { + ccall.add_argument (get_variable_cexpression ("object_type")); + } + } else { + ccall.add_argument (get_this_cexpression ()); } if (!current_class.is_compact) { @@ -311,7 +317,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { param.accept (this); } generate_dynamic_method_wrapper ((DynamicMethod) m); - } else if (m is CreationMethod && m.parent_symbol is Class) { + } else if (m is CreationMethod && context.profile == Profile.GOBJECT && m.parent_symbol is Class) { ccode.add_assignment (get_this_cexpression (), new CCodeCastExpression (ccall, get_ccode_name (current_class) + "*")); if (current_method.body.captured) { @@ -920,5 +926,80 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { } return false; } + + string generate_string_printf_function () { + if (!add_wrapper ("string_printf")) { + // wrapper already defined + return "string_printf"; + } + + // declaration + var function = new CCodeFunction ("string_printf", "char*"); + function.add_parameter (new CCodeParameter ("format", "const char*")); + function.add_parameter (new CCodeParameter.with_ellipsis ()); + function.modifiers = CCodeModifiers.STATIC; + + // definition + push_context (new EmitContext ()); + push_function (function); + + ccode.add_declaration ("int", new CCodeVariableDeclarator ("length")); + ccode.add_declaration ("va_list", new CCodeVariableDeclarator ("ap")); + ccode.add_declaration ("char*", new CCodeVariableDeclarator ("result")); + + var va_start = new CCodeFunctionCall (new CCodeIdentifier ("va_start")); + va_start.add_argument (new CCodeIdentifier ("ap")); + va_start.add_argument (new CCodeIdentifier ("format")); + + ccode.add_expression (va_start); + + var vsnprintf = new CCodeFunctionCall (new CCodeIdentifier ("vsnprintf")); + vsnprintf.add_argument (new CCodeConstant ("NULL")); + vsnprintf.add_argument (new CCodeConstant ("0")); + vsnprintf.add_argument (new CCodeIdentifier ("format")); + vsnprintf.add_argument (new CCodeIdentifier ("ap")); + + ccode.add_assignment (new CCodeIdentifier ("length"), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, vsnprintf, new CCodeConstant ("1"))); + + var va_end = new CCodeFunctionCall (new CCodeIdentifier ("va_end")); + va_end.add_argument (new CCodeIdentifier ("ap")); + + ccode.add_expression (va_end); + + var malloc = new CCodeFunctionCall (new CCodeIdentifier ("malloc")); + malloc.add_argument (new CCodeIdentifier ("length")); + + ccode.add_assignment (new CCodeIdentifier ("result"), malloc); + + va_start = new CCodeFunctionCall (new CCodeIdentifier ("va_start")); + va_start.add_argument (new CCodeIdentifier ("ap")); + va_start.add_argument (new CCodeIdentifier ("format")); + + ccode.add_expression (va_start); + + vsnprintf = new CCodeFunctionCall (new CCodeIdentifier ("vsnprintf")); + vsnprintf.add_argument (new CCodeIdentifier ("result")); + vsnprintf.add_argument (new CCodeIdentifier ("length")); + vsnprintf.add_argument (new CCodeIdentifier ("format")); + vsnprintf.add_argument (new CCodeIdentifier ("ap")); + + ccode.add_expression (vsnprintf); + + va_end = new CCodeFunctionCall (new CCodeIdentifier ("va_end")); + va_end.add_argument (new CCodeIdentifier ("ap")); + + ccode.add_expression (va_end); + + ccode.add_return (new CCodeIdentifier ("result")); + + // append to file + cfile.add_include ("stdarg.h"); + cfile.add_function_declaration (function); + cfile.add_function (function); + + pop_context (); + + return "string_printf"; + } } diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index 8caaef347..66e3ad1a7 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -858,11 +858,13 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { cmain.add_parameter (new CCodeParameter ("argv", "char **")); push_function (cmain); - if (context.mem_profiler) { - var mem_profiler_init_call = new CCodeFunctionCall (new CCodeIdentifier ("g_mem_set_vtable")); - mem_profiler_init_call.line = cmain.line; - mem_profiler_init_call.add_argument (new CCodeConstant ("glib_mem_profiler_table")); - ccode.add_expression (mem_profiler_init_call); + if (context.profile == Profile.GOBJECT) { + if (context.mem_profiler) { + var mem_profiler_init_call = new CCodeFunctionCall (new CCodeIdentifier ("g_mem_set_vtable")); + mem_profiler_init_call.line = cmain.line; + mem_profiler_init_call.add_argument (new CCodeConstant ("glib_mem_profiler_table")); + ccode.add_expression (mem_profiler_init_call); + } } var main_call = new CCodeFunctionCall (new CCodeIdentifier (function.name)); diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala index 0ce9dae17..7b20f504a 100644 --- a/codegen/valaccodestructmodule.vala +++ b/codegen/valaccodestructmodule.vala @@ -53,15 +53,17 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule { return; } - if (get_ccode_has_type_id (st)) { - decl_space.add_include ("glib-object.h"); - decl_space.add_type_declaration (new CCodeNewline ()); - var macro = "(%s_get_type ())".printf (get_ccode_lower_case_name (st, null)); - decl_space.add_type_declaration (new CCodeMacroReplacement (get_ccode_type_id (st), macro)); - - var type_fun = new StructRegisterFunction (st); - type_fun.init_from_type (context, false, true); - decl_space.add_type_member_declaration (type_fun.get_declaration ()); + if (context.profile == Profile.GOBJECT) { + if (get_ccode_has_type_id (st)) { + decl_space.add_include ("glib-object.h"); + decl_space.add_type_declaration (new CCodeNewline ()); + var macro = "(%s_get_type ())".printf (get_ccode_lower_case_name (st, null)); + decl_space.add_type_declaration (new CCodeMacroReplacement (get_ccode_type_id (st), macro)); + + var type_fun = new StructRegisterFunction (st); + type_fun.init_from_type (context, false, true); + decl_space.add_type_member_declaration (type_fun.get_declaration ()); + } } var instance_struct = new CCodeStruct ("_%s".printf (get_ccode_name (st))); @@ -212,10 +214,17 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule { ccode.add_declaration (get_ccode_name (st) + "*", new CCodeVariableDeclarator ("dup")); - var creation_call = new CCodeFunctionCall (new CCodeIdentifier ("g_new0")); - creation_call.add_argument (new CCodeConstant (get_ccode_name (st))); - creation_call.add_argument (new CCodeConstant ("1")); - ccode.add_assignment (new CCodeIdentifier ("dup"), creation_call); + if (context.profile == Profile.GOBJECT) { + var creation_call = new CCodeFunctionCall (new CCodeIdentifier ("g_new0")); + creation_call.add_argument (new CCodeConstant (get_ccode_name (st))); + creation_call.add_argument (new CCodeConstant ("1")); + ccode.add_assignment (new CCodeIdentifier ("dup"), creation_call); + } else if (context.profile == Profile.POSIX) { + var creation_call = new CCodeFunctionCall (new CCodeIdentifier ("calloc")); + creation_call.add_argument (new CCodeConstant ("1")); + creation_call.add_argument (new CCodeIdentifier ("sizeof (%s*)".printf (get_ccode_name (st)))); + ccode.add_assignment (new CCodeIdentifier ("dup"), creation_call); + } if (st.is_disposable ()) { var copy_call = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_copy_function (st))); @@ -260,9 +269,15 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule { ccode.add_expression (destroy_call); } - var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free")); - free_call.add_argument (new CCodeIdentifier ("self")); - ccode.add_expression (free_call); + if (context.profile == Profile.GOBJECT) { + var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free")); + free_call.add_argument (new CCodeIdentifier ("self")); + ccode.add_expression (free_call); + } else if (context.profile == Profile.POSIX) { + var free_call = new CCodeFunctionCall (new CCodeIdentifier ("free")); + free_call.add_argument (new CCodeIdentifier ("self")); + ccode.add_expression (free_call); + } pop_function (); diff --git a/compiler/valacompiler.vala b/compiler/valacompiler.vala index 31dd06ad5..733db4526 100644 --- a/compiler/valacompiler.vala +++ b/compiler/valacompiler.vala @@ -272,7 +272,10 @@ class Vala.Compiler { if (ccode_only && save_temps) { Report.warning (null, "--save-temps has no effect when -C or --ccode is set"); } - if (profile == "gobject-2.0" || profile == "gobject" || profile == null) { + if (profile == "posix") { + context.profile = Profile.POSIX; + context.add_define ("POSIX"); + } else if (profile == "gobject-2.0" || profile == "gobject" || profile == null) { // default profile context.profile = Profile.GOBJECT; context.add_define ("GOBJECT"); @@ -301,26 +304,33 @@ class Vala.Compiler { context.add_define ("VALA_0_%d".printf (i)); } - int glib_major = 2; - int glib_minor = 40; - if (target_glib != null && target_glib.scanf ("%d.%d", out glib_major, out glib_minor) != 2) { - Report.error (null, "Invalid format for --target-glib"); - } + if (context.profile == Profile.POSIX) { + if (!nostdpkg) { + /* default package */ + context.add_external_package ("posix"); + } + } else if (context.profile == Profile.GOBJECT) { + int glib_major = 2; + int glib_minor = 40; + if (target_glib != null && target_glib.scanf ("%d.%d", out glib_major, out glib_minor) != 2) { + Report.error (null, "Invalid format for --target-glib"); + } - context.target_glib_major = glib_major; - context.target_glib_minor = glib_minor; - if (context.target_glib_major != 2) { - Report.error (null, "This version of valac only supports GLib 2"); - } + context.target_glib_major = glib_major; + context.target_glib_minor = glib_minor; + if (context.target_glib_major != 2) { + Report.error (null, "This version of valac only supports GLib 2"); + } - for (int i = 16; i <= glib_minor; i += 2) { - context.add_define ("GLIB_2_%d".printf (i)); - } + for (int i = 16; i <= glib_minor; i += 2) { + context.add_define ("GLIB_2_%d".printf (i)); + } - if (!nostdpkg) { - /* default packages */ - context.add_external_package ("glib-2.0"); - context.add_external_package ("gobject-2.0"); + if (!nostdpkg) { + /* default packages */ + context.add_external_package ("glib-2.0"); + context.add_external_package ("gobject-2.0"); + } } if (packages != null) { @@ -346,7 +356,11 @@ class Vala.Compiler { return quit (); } - context.codegen = new GDBusServerModule (); + if (context.profile == Profile.GOBJECT) { + context.codegen = new GDBusServerModule (); + } else { + context.codegen = new CCodeDelegateModule (); + } bool has_c_files = false; bool has_h_files = false; @@ -423,28 +437,30 @@ class Vala.Compiler { if (library != null) { if (gir != null) { - string gir_base = Path.get_basename(gir); - long gir_len = gir_base.length; - int last_hyphen = gir_base.last_index_of_char ('-'); - - if (last_hyphen == -1 || !gir_base.has_suffix (".gir")) { - Report.error (null, "GIR file name `%s' is not well-formed, expected NAME-VERSION.gir".printf (gir)); - } else { - string gir_namespace = gir_base.substring (0, last_hyphen); - string gir_version = gir_base.substring (last_hyphen + 1, gir_len - last_hyphen - 5); - gir_version.canon ("0123456789.", '?'); - if (gir_namespace == "" || gir_version == "" || !gir_version[0].isdigit () || gir_version.contains ("?")) { + if (context.profile == Profile.GOBJECT) { + string gir_base = Path.get_basename (gir); + long gir_len = gir_base.length; + int last_hyphen = gir_base.last_index_of_char ('-'); + + if (last_hyphen == -1 || !gir_base.has_suffix (".gir")) { Report.error (null, "GIR file name `%s' is not well-formed, expected NAME-VERSION.gir".printf (gir)); } else { - var gir_writer = new GIRWriter (); - - // put .gir file in current directory unless -d has been explicitly specified - string gir_directory = "."; - if (directory != null) { - gir_directory = context.directory; + string gir_namespace = gir_base.substring (0, last_hyphen); + string gir_version = gir_base.substring (last_hyphen + 1, gir_len - last_hyphen - 5); + gir_version.canon ("0123456789.", '?'); + if (gir_namespace == "" || gir_version == "" || !gir_version[0].isdigit () || gir_version.contains ("?")) { + Report.error (null, "GIR file name `%s' is not well-formed, expected NAME-VERSION.gir".printf (gir)); + } else { + var gir_writer = new GIRWriter (); + + // put .gir file in current directory unless -d has been explicitly specified + string gir_directory = "."; + if (directory != null) { + gir_directory = context.directory; + } + + gir_writer.write_file (context, gir_directory, gir, gir_namespace, gir_version, library, shared_library); } - - gir_writer.write_file (context, gir_directory, gir, gir_namespace, gir_version, library, shared_library); } } diff --git a/vala/valaarraytype.vala b/vala/valaarraytype.vala index 10be086d8..626c60c89 100644 --- a/vala/valaarraytype.vala +++ b/vala/valaarraytype.vala @@ -194,7 +194,7 @@ public class Vala.ArrayType : ReferenceType { } public override bool compatible (DataType target_type) { - if (target_type.data_type != null) { + if (CodeContext.get ().profile == Profile.GOBJECT && target_type.data_type != null) { if (target_type.data_type.is_subtype_of (CodeContext.get ().analyzer.gvalue_type.data_type) && element_type.data_type == CodeContext.get ().root.scope.lookup ("string")) { // allow implicit conversion from string[] to GValue return true; diff --git a/vala/valacatchclause.vala b/vala/valacatchclause.vala index 93996a910..bb8d73cb2 100644 --- a/vala/valacatchclause.vala +++ b/vala/valacatchclause.vala @@ -116,6 +116,12 @@ public class Vala.CatchClause : CodeNode { checked = true; + if (context.profile == Profile.POSIX) { + Report.error (source_reference, "`catch' is not supported in POSIX profile"); + error = true; + return false; + } + if (error_type != null) { if (!(error_type is ErrorType)) { Report.error (source_reference, "clause must catch a valid error type, found `%s' instead".printf (error_type.to_string ())); diff --git a/vala/valacodecontext.vala b/vala/valacodecontext.vala index 17b35c9fd..65a5e2ab9 100644 --- a/vala/valacodecontext.vala +++ b/vala/valacodecontext.vala @@ -437,10 +437,17 @@ public class Vala.CodeContext { var source_file = new SourceFile (this, SourceFileType.SOURCE, rpath, null, cmdline); source_file.relative_filename = filename; - // import the GLib namespace by default (namespace of backend-specific standard library) - var ns_ref = new UsingDirective (new UnresolvedSymbol (null, "GLib", null)); - source_file.add_using_directive (ns_ref); - root.add_using_directive (ns_ref); + if (profile == Profile.POSIX) { + // import the Posix namespace by default (namespace of backend-specific standard library) + var ns_ref = new UsingDirective (new UnresolvedSymbol (null, "Posix", null)); + source_file.add_using_directive (ns_ref); + root.add_using_directive (ns_ref); + } else if (profile == Profile.GOBJECT) { + // import the GLib namespace by default (namespace of backend-specific standard library) + var ns_ref = new UsingDirective (new UnresolvedSymbol (null, "GLib", null)); + source_file.add_using_directive (ns_ref); + root.add_using_directive (ns_ref); + } add_source_file (source_file); } else if (filename.has_suffix (".vapi") || filename.has_suffix (".gir")) { diff --git a/vala/valacreationmethod.vala b/vala/valacreationmethod.vala index 4d905348f..198f031c1 100644 --- a/vala/valacreationmethod.vala +++ b/vala/valacreationmethod.vala @@ -128,7 +128,8 @@ public class Vala.CreationMethod : Method { // ensure we chain up to base constructor if (!chain_up && cl != null && cl.base_class != null) { - if (cl.base_class.default_construction_method != null + if (context.profile == Profile.GOBJECT + && cl.base_class.default_construction_method != null && !cl.base_class.default_construction_method.has_construct_function) { // directly chain up to Object var old_insert_block = context.analyzer.insert_block; diff --git a/vala/valadatatype.vala b/vala/valadatatype.vala index e25e5a417..6d4876344 100644 --- a/vala/valadatatype.vala +++ b/vala/valadatatype.vala @@ -268,7 +268,7 @@ public abstract class Vala.DataType : CodeNode { return false; } - if (target_type.data_type != null) { + if (CodeContext.get ().profile == Profile.GOBJECT && target_type.data_type != null) { if (target_type.data_type.is_subtype_of (CodeContext.get ().analyzer.gvalue_type.data_type)) { // allow implicit conversion to GValue return true; diff --git a/vala/valaelementaccess.vala b/vala/valaelementaccess.vala index 993f9c1f5..755eaf6ee 100644 --- a/vala/valaelementaccess.vala +++ b/vala/valaelementaccess.vala @@ -151,7 +151,7 @@ public class Vala.ElementAccess : Expression { value_type.value_owned = false; } else { var ma = container as MemberAccess; - if (ma != null && ma.symbol_reference is ArrayLengthField) { + if (context.profile == Profile.GOBJECT && ma != null && ma.symbol_reference is ArrayLengthField) { // propagate lvalue for gobject length access ma.inner.lvalue = true; ((MemberAccess) ma.inner).check_lvalue_access (); diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala index ff7c03edc..8b436f5f0 100644 --- a/vala/valaflowanalyzer.vala +++ b/vala/valaflowanalyzer.vala @@ -872,6 +872,7 @@ public class Vala.FlowAnalyzer : CodeVisitor { // exceptional control flow foreach (DataType error_data_type in node.get_error_types()) { var error_type = error_data_type as ErrorType; + var error_class = error_data_type.data_type as Class; current_block = last_block; unreachable_reported = true; @@ -882,19 +883,32 @@ public class Vala.FlowAnalyzer : CodeVisitor { mark_unreachable (); break; } else if (jump_target.is_error_target) { - if (jump_target.error_domain == null - || (jump_target.error_domain == error_type.error_domain - && (jump_target.error_code == null - || jump_target.error_code == error_type.error_code))) { + if (context.profile == Profile.GOBJECT) { + if (jump_target.error_domain == null + || (jump_target.error_domain == error_type.error_domain + && (jump_target.error_code == null + || jump_target.error_code == error_type.error_code))) { + // error can always be caught by this catch clause + // following catch clauses cannot be reached by this error + current_block.connect (jump_target.basic_block); + mark_unreachable (); + break; + } else if (error_type.error_domain == null + || (error_type.error_domain == jump_target.error_domain + && (error_type.error_code == null + || error_type.error_code == jump_target.error_code))) { + // error might be caught by this catch clause + // unknown at compile time + // following catch clauses might still be reached by this error + current_block.connect (jump_target.basic_block); + } + } else if (jump_target.error_class == null || jump_target.error_class == error_class) { // error can always be caught by this catch clause // following catch clauses cannot be reached by this error current_block.connect (jump_target.basic_block); mark_unreachable (); break; - } else if (error_type.error_domain == null - || (error_type.error_domain == jump_target.error_domain - && (error_type.error_code == null - || error_type.error_code == jump_target.error_code))) { + } else if (jump_target.error_class.is_subtype_of (error_class)) { // error might be caught by this catch clause // unknown at compile time // following catch clauses might still be reached by this error @@ -975,8 +989,13 @@ public class Vala.FlowAnalyzer : CodeVisitor { all_basic_blocks.add (error_block); if (catch_clause.error_type != null) { - var error_type = (ErrorType) catch_clause.error_type; - jump_stack.add (new JumpTarget.error_target (error_block, catch_clause, catch_clause.error_type.data_type as ErrorDomain, error_type.error_code, null)); + if (context.profile == Profile.GOBJECT) { + var error_type = (ErrorType) catch_clause.error_type; + jump_stack.add (new JumpTarget.error_target (error_block, catch_clause, catch_clause.error_type.data_type as ErrorDomain, error_type.error_code, null)); + } else { + var error_class = catch_clause.error_type.data_type as Class; + jump_stack.add (new JumpTarget.error_target (error_block, catch_clause, null, null, error_class)); + } } else { jump_stack.add (new JumpTarget.error_target (error_block, catch_clause, null, null, null)); } @@ -1008,8 +1027,14 @@ public class Vala.FlowAnalyzer : CodeVisitor { break; } - if (prev_target.error_domain == jump_target.error_domain && - prev_target.error_code == jump_target.error_code) { + if (context.profile == Profile.GOBJECT) { + if (prev_target.error_domain == jump_target.error_domain && + prev_target.error_code == jump_target.error_code) { + Report.error (stmt.source_reference, "double catch clause of same error detected"); + stmt.error = true; + return; + } + } else if (prev_target.error_class == jump_target.error_class) { Report.error (stmt.source_reference, "double catch clause of same error detected"); stmt.error = true; return; diff --git a/vala/valaforeachstatement.vala b/vala/valaforeachstatement.vala index 4d928429f..416fb55d2 100644 --- a/vala/valaforeachstatement.vala +++ b/vala/valaforeachstatement.vala @@ -175,7 +175,7 @@ public class Vala.ForeachStatement : Block { array_type.inline_allocated = false; return check_without_iterator (context, collection_type, array_type.element_type); - } else if (collection_type.compatible (context.analyzer.glist_type) || collection_type.compatible (context.analyzer.gslist_type)) { + } else if (context.profile == Profile.GOBJECT && (collection_type.compatible (context.analyzer.glist_type) || collection_type.compatible (context.analyzer.gslist_type))) { if (collection_type.get_type_arguments ().size != 1) { error = true; Report.error (collection.source_reference, "missing type argument for collection"); @@ -183,7 +183,7 @@ public class Vala.ForeachStatement : Block { } return check_without_iterator (context, collection_type, collection_type.get_type_arguments ().get (0)); - } else if (collection_type.compatible (context.analyzer.gvaluearray_type)) { + } else if (context.profile == Profile.GOBJECT && collection_type.compatible (context.analyzer.gvaluearray_type)) { return check_without_iterator (context, collection_type, context.analyzer.gvalue_type); } else { return check_with_iterator (context, collection_type); diff --git a/vala/valagenieparser.vala b/vala/valagenieparser.vala index b925babbc..57f041a5e 100644 --- a/vala/valagenieparser.vala +++ b/vala/valagenieparser.vala @@ -2425,8 +2425,11 @@ public class Vala.Genie.Parser : CodeVisitor { if (is_root) { return parse_main_method_declaration (attrs); } - rollback (begin); - return parse_constructor_declaration (attrs); + if (context.profile == Profile.GOBJECT) { + rollback (begin); + return parse_constructor_declaration (attrs); + } + break; case TokenType.DELEGATE: return parse_delegate_declaration (attrs); case TokenType.DEF: @@ -3160,8 +3163,8 @@ public class Vala.Genie.Parser : CodeVisitor { if (readonly) { throw new ParseError.SYNTAX ("set block not allowed for a read only property"); } - _construct = accept (TokenType.CONSTRUCT); - } else if (accept (TokenType.CONSTRUCT)) { + _construct = (context.profile == Profile.GOBJECT) && accept (TokenType.CONSTRUCT); + } else if (context.profile == Profile.GOBJECT && accept (TokenType.CONSTRUCT)) { _construct = true; } else if (!accept (TokenType.EOL)) { throw new ParseError.SYNTAX ("expected get, set, or construct"); diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala index a5e056f46..64263ba3e 100644 --- a/vala/valamemberaccess.vala +++ b/vala/valamemberaccess.vala @@ -885,7 +885,7 @@ public class Vala.MemberAccess : Expression { } var this_access = inner.symbol_reference is Parameter && inner.symbol_reference.name == "this"; - var struct_or_array = (inner.value_type is StructValueType && !inner.value_type.nullable) || inner.value_type is ArrayType; + var struct_or_array = (inner.value_type is StructValueType && !inner.value_type.nullable) || (CodeContext.get ().profile == Profile.GOBJECT && inner.value_type is ArrayType); var ma = inner as MemberAccess; if (ma == null && struct_or_array && inner is PointerIndirection) { diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala index 41063ba3e..8f68dc4bd 100644 --- a/vala/valamethodcall.vala +++ b/vala/valamethodcall.vala @@ -211,7 +211,7 @@ public class Vala.MethodCall : Expression { } var mtype = call.value_type; - var gobject_chainup = call.symbol_reference == context.analyzer.object_type; + var gobject_chainup = (context.profile == Profile.GOBJECT && call.symbol_reference == context.analyzer.object_type); is_chainup = gobject_chainup; if (!gobject_chainup) { diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala index 08a37dfad..fa419fd22 100644 --- a/vala/valaobjectcreationexpression.vala +++ b/vala/valaobjectcreationexpression.vala @@ -322,7 +322,7 @@ public class Vala.ObjectCreationExpression : Expression { symbol_reference = st.default_construction_method; } - if (st.is_simple_type () && symbol_reference == null && object_initializer.size == 0) { + if (context.profile == Profile.GOBJECT && st.is_simple_type () && symbol_reference == null && object_initializer.size == 0) { error = true; Report.error (source_reference, "`%s' does not have a default constructor".printf (st.get_full_name ())); return false; diff --git a/vala/valaparser.vala b/vala/valaparser.vala index eca5565cf..9a26015c1 100644 --- a/vala/valaparser.vala +++ b/vala/valaparser.vala @@ -2261,9 +2261,12 @@ public class Vala.Parser : CodeVisitor { switch (current ()) { case TokenType.CONSTRUCT: - rollback (begin); - parse_constructor_declaration (parent, attrs); - return; + if (context.profile == Profile.GOBJECT) { + rollback (begin); + parse_constructor_declaration (parent, attrs); + return; + } + break; case TokenType.TILDE: rollback (begin); parse_destructor_declaration (parent, attrs); @@ -2879,8 +2882,8 @@ public class Vala.Parser : CodeVisitor { bool writable, _construct; if (accept (TokenType.SET)) { writable = true; - _construct = accept (TokenType.CONSTRUCT); - } else if (accept (TokenType.CONSTRUCT)) { + _construct = (context.profile == Profile.GOBJECT) && accept (TokenType.CONSTRUCT); + } else if (context.profile == Profile.GOBJECT && accept (TokenType.CONSTRUCT)) { _construct = true; writable = accept (TokenType.SET); } else { diff --git a/vala/valapointertype.vala b/vala/valapointertype.vala index 9cfe6ea42..6e0d799cf 100644 --- a/vala/valapointertype.vala +++ b/vala/valapointertype.vala @@ -83,7 +83,7 @@ public class Vala.PointerType : DataType { return base_type.compatible (target_type); } - if (target_type.data_type != null && target_type.data_type.is_subtype_of (CodeContext.get ().analyzer.gvalue_type.data_type)) { + if (CodeContext.get ().profile == Profile.GOBJECT && target_type.data_type != null && target_type.data_type.is_subtype_of (CodeContext.get ().analyzer.gvalue_type.data_type)) { // allow implicit conversion to GValue return true; } diff --git a/vala/valaprofile.vala b/vala/valaprofile.vala index 802496572..1ef0bd516 100644 --- a/vala/valaprofile.vala +++ b/vala/valaprofile.vala @@ -21,5 +21,6 @@ */ public enum Vala.Profile { - GOBJECT + GOBJECT, + POSIX } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 8f4335bd2..c0c075f9a 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -200,22 +200,24 @@ public class Vala.SemanticAnalyzer : CodeVisitor { unichar_type = new IntegerType (unichar_struct); } - var glib_ns = root_symbol.scope.lookup ("GLib"); + if (context.profile == Profile.GOBJECT) { + var glib_ns = root_symbol.scope.lookup ("GLib"); - object_type = (Class) glib_ns.scope.lookup ("Object"); - type_type = new IntegerType ((Struct) glib_ns.scope.lookup ("Type")); - gvalue_type = new StructValueType ((Struct) glib_ns.scope.lookup ("Value")); - gvariant_type = new ObjectType ((Class) glib_ns.scope.lookup ("Variant")); + object_type = (Class) glib_ns.scope.lookup ("Object"); + type_type = new IntegerType ((Struct) glib_ns.scope.lookup ("Type")); + gvalue_type = new StructValueType ((Struct) glib_ns.scope.lookup ("Value")); + gvariant_type = new ObjectType ((Class) glib_ns.scope.lookup ("Variant")); - glist_type = new ObjectType ((Class) glib_ns.scope.lookup ("List")); - gslist_type = new ObjectType ((Class) glib_ns.scope.lookup ("SList")); - garray_type = new ObjectType ((Class) glib_ns.scope.lookup ("Array")); - gvaluearray_type = new ObjectType ((Class) glib_ns.scope.lookup ("ValueArray")); + glist_type = new ObjectType ((Class) glib_ns.scope.lookup ("List")); + gslist_type = new ObjectType ((Class) glib_ns.scope.lookup ("SList")); + garray_type = new ObjectType ((Class) glib_ns.scope.lookup ("Array")); + gvaluearray_type = new ObjectType ((Class) glib_ns.scope.lookup ("ValueArray")); - gerror_type = (Class) glib_ns.scope.lookup ("Error"); - regex_type = new ObjectType ((Class) root_symbol.scope.lookup ("GLib").scope.lookup ("Regex")); + gerror_type = (Class) glib_ns.scope.lookup ("Error"); + regex_type = new ObjectType ((Class) root_symbol.scope.lookup ("GLib").scope.lookup ("Regex")); - gsource_type = (Class) glib_ns.scope.lookup ("Source"); + gsource_type = (Class) glib_ns.scope.lookup ("Source"); + } current_symbol = root_symbol; context.root.check (context); diff --git a/vala/valathrowstatement.vala b/vala/valathrowstatement.vala index 0c30d3357..d4cade7a2 100644 --- a/vala/valathrowstatement.vala +++ b/vala/valathrowstatement.vala @@ -79,6 +79,12 @@ public class Vala.ThrowStatement : CodeNode, Statement { checked = true; + if (context.profile == Profile.POSIX) { + Report.error (source_reference, "`throws' is not supported in POSIX profile"); + error = true; + return false; + } + error_expression.target_type = new ErrorType (null, null, source_reference); error_expression.target_type.value_owned = true; @@ -94,7 +100,7 @@ public class Vala.ThrowStatement : CodeNode, Statement { return false; } - if (!(error_expression.value_type is ErrorType)) { + if (context.profile == Profile.GOBJECT && !(error_expression.value_type is ErrorType)) { Report.error (error_expression.source_reference, "`%s' is not an error type".printf (error_expression.value_type.to_string ())); error = true; return false; diff --git a/vala/valatrystatement.vala b/vala/valatrystatement.vala index 38000f516..7e82228a5 100644 --- a/vala/valatrystatement.vala +++ b/vala/valatrystatement.vala @@ -111,6 +111,12 @@ public class Vala.TryStatement : CodeNode, Statement { checked = true; + if (context.profile == Profile.POSIX) { + Report.error (source_reference, "`try' is not supported in POSIX profile"); + error = true; + return false; + } + body.check (context); var error_types = new ArrayList<DataType> (); diff --git a/vala/valatypecheck.vala b/vala/valatypecheck.vala index b02cd9405..5b22d75d4 100644 --- a/vala/valatypecheck.vala +++ b/vala/valatypecheck.vala @@ -116,7 +116,7 @@ public class Vala.TypeCheck : Expression { return false; } - if (type_reference.get_type_arguments ().size > 0) { + if (context.profile == Profile.GOBJECT && type_reference.get_type_arguments ().size > 0) { Report.warning (_data_type.source_reference, "Type argument list has no effect"); } diff --git a/vala/valatypeofexpression.vala b/vala/valatypeofexpression.vala index 936c7d44a..9b0506ba1 100644 --- a/vala/valatypeofexpression.vala +++ b/vala/valatypeofexpression.vala @@ -82,7 +82,7 @@ public class Vala.TypeofExpression : Expression { value_type = context.analyzer.type_type; - if (type_reference.get_type_arguments ().size > 0) { + if (context.profile == Profile.GOBJECT && type_reference.get_type_arguments ().size > 0) { Report.warning (_data_type.source_reference, "Type argument list without effect"); } diff --git a/vapi/libarchive.vapi b/vapi/libarchive.vapi index 72a0048e0..967a81861 100644 --- a/vapi/libarchive.vapi +++ b/vapi/libarchive.vapi @@ -208,7 +208,11 @@ namespace Archive { public Result open_filename (string filename, size_t block_size); public Result open_memory ([CCode (array_length_type = "size_t")] uint8[] buffer); public Result open_fd (int fd, size_t block_size); +#if POSIX + public Result open_FILE (Posix.FILE file); +#else public Result open_FILE (GLib.FileStream file); +#endif public Result next_header (out unowned Entry entry); public int64_t header_position (); @@ -311,7 +315,11 @@ namespace Archive { ); public Result open_fd (int fd); public Result open_filename (string filename); +#if POSIX + public Result open_FILE (Posix.FILE file); +#else public Result open_FILE (GLib.FileStream file); +#endif public Result open_memory ([CCode (array_length_type = "size_t")] uint8[] buffer, out size_t used); [CCode (cname="archive_write_header")] diff --git a/vapi/libdaemon.vapi b/vapi/libdaemon.vapi index 7f80fb5dc..a18a42b6b 100644 --- a/vapi/libdaemon.vapi +++ b/vapi/libdaemon.vapi @@ -83,7 +83,11 @@ namespace Daemon { public int exec (string dir, out int ret, string prog, ...); +#if POSIX + public Posix.pid_t fork (); +#else public GLib.Pid fork (); +#endif public int retval_init (); public void retval_done (); public int retval_wait (int timeout); @@ -111,7 +115,11 @@ namespace Daemon { public unowned string pid_file_proc_default (); public int pid_file_create (); public int pid_file_remove (); +#if POSIX + public Posix.pid_t pid_file_is_running (); +#else public GLib.Pid pid_file_is_running (); +#endif public int pid_file_kill (Sig s); public int pid_file_kill_wait (Sig s, int m); diff --git a/vapi/libxml-2.0.vapi b/vapi/libxml-2.0.vapi index 1ac8a19b5..e192dc2ff 100644 --- a/vapi/libxml-2.0.vapi +++ b/vapi/libxml-2.0.vapi @@ -407,7 +407,11 @@ namespace Xml { public Dtd* create_int_subset ([CCode (type = "xmlChar*")] string name, [CCode (type = "xmlChar*")] string external_id, [CCode (type = "xmlChar*")] string system_id); [CCode (cname = "xmlDocDump", instance_pos = -1)] +#if POSIX + public int dump (Posix.FILE f); +#else public int dump (GLib.FileStream f); +#endif [CCode (cname = "xmlDocDumpFormatMemory")] public void dump_memory_format ([CCode (type = "xmlChar*")] out string mem, out int len = null, bool format = true); @@ -422,7 +426,11 @@ namespace Xml { public void dump_memory_enc ([CCode (type = "xmlChar**")] out string mem, out int len = null, string enc = "UTF-8"); [CCode (cname = "xmlDocFormatDump", instance_pos = 1.1)] +#if POSIX + public int dump_format (Posix.FILE f, bool format = true); +#else public int dump_format (GLib.FileStream f, bool format = true); +#endif [CCode (cname = "xmlDocGetRootElement")] public Node* get_root_element(); @@ -431,7 +439,11 @@ namespace Xml { public Node* set_root_element(Node* root); [CCode (cname = "xmlElemDump", instance_pos = 1.1)] +#if POSIX + public void elem_dump (Posix.FILE f, Node* cur); +#else public void elem_dump (GLib.FileStream f, Node* cur); +#endif [CCode (cname = "xmlGetDocCompressMode")] public int get_compress_mode (); @@ -1001,7 +1013,11 @@ namespace Xml { public static string path_to_uri ([CCode (type = "xmlChar*")] string path); [CCode (cname = "xmlPrintURI", instance_pos = -1)] +#if POSIX + public void print (Posix.FILE stream); +#else public void print (GLib.FileStream stream); +#endif [CCode (cname = "xmlSaveUri", type = "xmlChar*")] public string save (); @@ -1952,16 +1968,28 @@ namespace Html { public void dump_memory_format ([CCode (type = "xmlChar**")] out string mem, out int len = null, bool format = true); [CCode (cname = "htmlDocDump", instance_pos = -1)] +#if POSIX + public int dump (Posix.FILE f); +#else public int dump (GLib.FileStream f); +#endif [CCode (cname = "htmlSaveFile", instance_pos = -1)] public int save_file (string filename); [CCode (cname = "htmlNodeDumpFile", instance_pos = 1.1)] +#if POSIX + public int node_dump_file (Posix.FILE file, Xml.Node* node); +#else public int node_dump_file (GLib.FileStream file, Xml.Node* node); +#endif [CCode (cname = "htmlNodeDumpFileFormat", instance_pos = 1.1)] +#if POSIX + public int node_dump_file_format (Posix.FILE file, string enc = "UTF-8", bool format = true); +#else public int node_dump_file_format (GLib.FileStream file, string enc = "UTF-8", bool format = true); +#endif [CCode (cname = "htmlSaveFileEnc", instance_pos = 1.1)] public int save_file_enc (string filename, string enc = "UTF-8"); diff --git a/vapi/posix.vapi b/vapi/posix.vapi index c6d6c6a8f..916ead5ff 100644 --- a/vapi/posix.vapi +++ b/vapi/posix.vapi @@ -24,6 +24,256 @@ * Nikolay Orliuk <virkony@gmail.com> */ +#if POSIX +[CCode (cname = "bool", cheader_filename = "stdbool.h", default_value = "false")] +[BooleanType] +public struct bool { + public inline unowned string to_string () { + if (this) { + return "true"; + } else { + return "false"; + } + } + + public static inline bool parse (string str) { + if (str == "true") { + return true; + } else { + return false; + } + } +} + +[CCode (cname = "char", default_value = "\'\\0\'")] +[IntegerType (rank = 2, min = 0, max = 127)] +public struct char { + public inline string to_string () { + return "%c".printf (this); + } +} + +[CCode (cname = "unsigned char", default_value = "\'\\0\'")] +[IntegerType (rank = 3, min = 0, max = 255)] +public struct uchar { + public inline string to_string () { + return "%hhu".printf (this); + } +} + +[CCode (cname = "int", default_value = "0")] +[IntegerType (rank = 6)] +public struct int { + public inline string to_string () { + return "%d".printf (this); + } + + [CCode (cname = "atoi", cheader_filename = "stdlib.h")] + public static int parse (string str); +} + +[CCode (cname = "unsigned int", default_value = "0U")] +[IntegerType (rank = 7)] +public struct uint { + public inline string to_string () { + return "%u".printf (this); + } +} + +[CCode (cname = "short", default_value = "0")] +[IntegerType (rank = 4, min = -32768, max = 32767)] +public struct short { + public inline string to_string () { + return "%hi".printf (this); + } +} + +[CCode (cname = "unsigned short", default_value = "0U")] +[IntegerType (rank = 5, min = 0, max = 65535)] +public struct ushort { + public inline string to_string () { + return "%hu".printf (this); + } +} + +[CCode (cname = "long", default_value = "0L")] +[IntegerType (rank = 8)] +public struct long { + public inline string to_string () { + return "%li".printf (this); + } + + [CCode (cname = "atol", cheader_filename = "stdlib.h")] + public static long parse (string str); +} + +[CCode (cname = "unsigned long", default_value = "0UL")] +[IntegerType (rank = 9)] +public struct ulong { + public inline string to_string () { + return "%lu".printf (this); + } +} + +[CCode (cname = "size_t", cheader_filename = "sys/types.h", default_value = "0UL")] +[IntegerType (rank = 9)] +public struct size_t { + public inline string to_string () { + return "%zu".printf (this); + } +} + +[CCode (cname = "ssize_t", cheader_filename = "sys/types.h", default_value = "0L")] +[IntegerType (rank = 8)] +public struct ssize_t { + public inline string to_string () { + return "%zi".printf (this); + } +} + +[CCode (cname = "int8_t", cheader_filename = "stdint.h", default_value = "0")] +[IntegerType (rank = 1, min = -128, max = 127)] +public struct int8 { + [CCode (cname = "PRIi8", cheader_filename = "inttypes.h")] + public const string FORMAT; + + public inline string to_string () { + return ("%" + FORMAT).printf (this); + } +} + +[CCode (cname = "uint8_t", cheader_filename = "stdint.h", default_value = "0U")] +[IntegerType (rank = 3, min = 0, max = 255)] +public struct uint8 { + [CCode (cname = "PRIu8", cheader_filename = "inttypes.h")] + public const string FORMAT; + + public inline string to_string () { + return ("%" + FORMAT).printf (this); + } +} + +[CCode (cname = "int16_t", cheader_filename = "stdint.h", default_value = "0")] +[IntegerType (rank = 4, min = -32768, max = 32767)] +public struct int16 { + [CCode (cname = "PRIi16", cheader_filename = "inttypes.h")] + public const string FORMAT; + + public inline string to_string () { + return ("%" + FORMAT).printf (this); + } +} + +[CCode (cname = "uint16_t", cheader_filename = "stdint.h", default_value = "0U")] +[IntegerType (rank = 5, min = 0, max = 65535)] +public struct uint16 { + [CCode (cname = "PRIu16", cheader_filename = "inttypes.h")] + public const string FORMAT; + + public inline string to_string () { + return ("%" + FORMAT).printf (this); + } +} + +[CCode (cname = "int32_t", cheader_filename = "stdint.h", default_value = "0")] +[IntegerType (rank = 6)] +public struct int32 { + [CCode (cname = "PRIi32", cheader_filename = "inttypes.h")] + public const string FORMAT; + + public inline string to_string () { + return ("%" + FORMAT).printf (this); + } +} + +[CCode (cname = "uint32_t", cheader_filename = "stdint.h", default_value = "0U")] +[IntegerType (rank = 7)] +public struct uint32 { + [CCode (cname = "PRIu32", cheader_filename = "inttypes.h")] + public const string FORMAT; + + public inline string to_string () { + return ("%" + FORMAT).printf (this); + } +} + +[CCode (cname = "int64_t", cheader_filename = "stdint.h", default_value = "0LL")] +[IntegerType (rank = 10)] +public struct int64 { + [CCode (cname = "PRIi64", cheader_filename = "inttypes.h")] + public const string FORMAT; + + public inline string to_string () { + return ("%" + FORMAT).printf (this); + } + + [CCode (cname = "strtoll", cheader_filename = "stdlib.h")] + public static int64 parse (string str, out unowned string? end = null, int base = 10); +} + +[CCode (cname = "uint64_t", cheader_filename = "stdint.h", default_value = "0ULL")] +[IntegerType (rank = 11)] +public struct uint64 { + [CCode (cname = "PRIu64", cheader_filename = "inttypes.h")] + public const string FORMAT; + + public inline string to_string () { + return ("%" + FORMAT).printf (this); + } + + [CCode (cname = "strtoull", cheader_filename = "stdlib.h")] + public static uint64 parse (string str, out unowned string? end = null, int base = 10); +} + +[CCode (cname = "float", default_value = "0.0F")] +[FloatingType (rank = 1)] +public struct float { + public inline string to_string () { + return "%.8g".printf (this); + } +} + +[CCode (cname = "double", default_value = "0.0")] +[FloatingType (rank = 2)] +public struct double { + public inline string to_string () { + return "%.17g".printf (this); + } + + [CCode (cname = "strtod", cheader_filename = "stdlib.h")] + public static double parse (string str, out unowned string? end = null); +} + +[CCode (cheader_filename = "time.h")] +[IntegerType (rank = 8)] +public struct time_t { + [CCode (cname = "time")] + public time_t (); +} + +[Compact] +[Immutable] +[CCode (cname = "char", const_cname = "const char", copy_function = "strdup", free_function = "free", cheader_filename = "stdlib.h,string.h")] +public class string { + [PrintfFormat] + public string printf (...); + + public inline unowned string to_string () { + return this; + } + + public int length { + [CCode (cname = "strlen")] + get; + } +} + +[CCode (cname="printf", cheader_filename = "stdio.h")] +[PrintfFormat] +public void print (string format,...); + +#endif + [CCode (cprefix = "", lower_case_cprefix = "")] namespace Posix { [CCode (cheader_filename = "assert.h")] |