[vala/staging] Add G_GNUC_PRINTF/SCANF attribute for Printf/ScanfFormat functions



commit 843f01e2e068b3a65a513e51c59dcff40e76a7af
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Tue Nov 8 16:37:31 2016 +0100

    Add G_GNUC_PRINTF/SCANF attribute for Printf/ScanfFormat functions
    
    https://bugzilla.gnome.org/show_bug.cgi?id=710862

 ccode/valaccodefunction.vala           |   12 ++++++++-
 ccode/valaccodefunctiondeclarator.vala |   12 ++++++++-
 ccode/valaccodemodifiers.vala          |    2 +
 codegen/valaccodemethodmodule.vala     |    6 ++++
 tests/Makefile.am                      |    1 +
 tests/methods/bug710862.vala           |   40 ++++++++++++++++++++++++++++++++
 vapi/glib-2.0.vapi                     |    2 +-
 7 files changed, 72 insertions(+), 3 deletions(-)
---
diff --git a/ccode/valaccodefunction.vala b/ccode/valaccodefunction.vala
index cd3e385..2d21e76 100644
--- a/ccode/valaccodefunction.vala
+++ b/ccode/valaccodefunction.vala
@@ -120,6 +120,7 @@ public class Vala.CCodeFunction : CCodeNode {
                
                int i = 0;
                int format_arg_index = -1;
+               int ellipsis_arg_index = -1;
                foreach (CCodeParameter param in parameters) {
                        if (i > 0) {
                                writer.write_string (", ");
@@ -128,6 +129,9 @@ public class Vala.CCodeFunction : CCodeNode {
                        if (CCodeModifiers.FORMAT_ARG in param.modifiers) {
                                format_arg_index = i;
                        }
+                       if (param.ellipsis) {
+                               ellipsis_arg_index = i;
+                       }
                        i++;
                }
                if (i == 0) {
@@ -141,7 +145,13 @@ public class Vala.CCodeFunction : CCodeNode {
                }
 
                if (is_declaration) {
-                       if (format_arg_index >= 0) {
+                       if (CCodeModifiers.PRINTF in modifiers) {
+                               format_arg_index = (format_arg_index >= 0 ? format_arg_index + 1 : 
ellipsis_arg_index);
+                               writer.write_string (" G_GNUC_PRINTF(%d,%d)".printf (format_arg_index, 
ellipsis_arg_index + 1));
+                       } else if (CCodeModifiers.SCANF in modifiers) {
+                               format_arg_index = (format_arg_index >= 0 ? format_arg_index + 1 : 
ellipsis_arg_index);
+                               writer.write_string (" G_GNUC_SCANF(%d,%d)".printf (format_arg_index, 
ellipsis_arg_index + 1));
+                       } else if (format_arg_index >= 0) {
                                writer.write_string (" G_GNUC_FORMAT(%d)".printf (format_arg_index + 1));
                        }
 
diff --git a/ccode/valaccodefunctiondeclarator.vala b/ccode/valaccodefunctiondeclarator.vala
index 1378662..1ad0bf9 100644
--- a/ccode/valaccodefunctiondeclarator.vala
+++ b/ccode/valaccodefunctiondeclarator.vala
@@ -57,6 +57,7 @@ public class Vala.CCodeFunctionDeclarator : CCodeDeclarator {
                
                int i = 0;
                int format_arg_index = -1;
+               int ellipsis_arg_index = -1;
                foreach (CCodeParameter param in parameters) {
                        if (i > 0) {
                                writer.write_string (", ");
@@ -65,12 +66,21 @@ public class Vala.CCodeFunctionDeclarator : CCodeDeclarator {
                        if (CCodeModifiers.FORMAT_ARG in param.modifiers) {
                                format_arg_index = i;
                        }
+                       if (param.ellipsis) {
+                               ellipsis_arg_index = i;
+                       }
                        i++;
                }
                
                writer.write_string (")");
 
-               if (format_arg_index >= 0) {
+               if (CCodeModifiers.PRINTF in modifiers) {
+                       format_arg_index = (format_arg_index >= 0 ? format_arg_index + 1 : 
ellipsis_arg_index);
+                       writer.write_string (" G_GNUC_PRINTF(%d,%d)".printf (format_arg_index, 
ellipsis_arg_index));
+               } else if (CCodeModifiers.SCANF in modifiers) {
+                       format_arg_index = (format_arg_index >= 0 ? format_arg_index + 1 : ellipsis_arg_index 
+ 1);
+                       writer.write_string (" G_GNUC_SCANF(%d,%d)".printf (format_arg_index, 
ellipsis_arg_index + 1));
+               } else if (format_arg_index >= 0) {
                        writer.write_string (" G_GNUC_FORMAT(%d)".printf (format_arg_index + 1));
                }
        }
diff --git a/ccode/valaccodemodifiers.vala b/ccode/valaccodemodifiers.vala
index 75c5a99..330e926 100644
--- a/ccode/valaccodemodifiers.vala
+++ b/ccode/valaccodemodifiers.vala
@@ -40,4 +40,6 @@ public enum Vala.CCodeModifiers {
        CONSTRUCTOR = 1 << 10,
        DESTRUCTOR = 1 << 11,
        FORMAT_ARG = 1 << 12
+       PRINTF = 1 << 13,
+       SCANF = 1 << 14
 }
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index ce127f5..69af597 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -1022,6 +1022,12 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                        }
                        last_pos = min_pos;
                }
+
+               if (m.printf_format) {
+                       func.modifiers |= CCodeModifiers.PRINTF;
+               } else if (m.scanf_format) {
+                       func.modifiers |= CCodeModifiers.SCANF;
+               }
        }
 
        public void generate_vfunc (Method m, DataType return_type, Map<int,CCodeParameter> cparam_map, 
Map<int,CCodeExpression> carg_map, string suffix = "", int direction = 3) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d3c709a..abd60f0 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -69,6 +69,7 @@ TESTS = \
        methods/bug653391.vala \
        methods/bug653908.vala \
        methods/bug663210.vala \
+       methods/bug710862.vala \
        methods/bug723009.vala \
        methods/bug723195.vala \
        methods/bug726347.vala \
diff --git a/tests/methods/bug710862.vala b/tests/methods/bug710862.vala
new file mode 100644
index 0000000..2b4a6b7
--- /dev/null
+++ b/tests/methods/bug710862.vala
@@ -0,0 +1,40 @@
+class Foo : Object {
+       [PrintfFormat]
+       public void print (string format, ...) {
+       }
+
+       [NoWrapper]
+       [PrintfFormat]
+       public void print_vfunc (string format, ...) {
+       }
+
+       [ScanfFormat]
+       public void scan (string input, string format, ...) {
+       }
+
+       [NoWrapper]
+       [ScanfFormat]
+       public void scan_vfunc (string input, string format, ...) {
+       }
+}
+
+[PrintfFormat]
+void print_something (string format, ...) {
+}
+
+[ScanfFormat]
+void scan_something (string input, string format, ...) {
+}
+
+void main () {
+       int i;
+
+       print_something ("%d", 42);
+       scan_something ("42", "%d", out i);
+
+       var foo = new Foo ();
+       foo.print ("%d", 42);
+       foo.print_vfunc ("%d", 42);
+       foo.scan ("42", "%d", out i);
+       foo.scan_vfunc ("42", "%d", out i);
+}
diff --git a/vapi/glib-2.0.vapi b/vapi/glib-2.0.vapi
index 3e50146..db96e28 100644
--- a/vapi/glib-2.0.vapi
+++ b/vapi/glib-2.0.vapi
@@ -1051,7 +1051,7 @@ public class string {
        [CCode (cname = "g_strdup_vprintf")]
        public string vprintf (va_list args);
        [CCode (cname = "sscanf", cheader_filename = "stdio.h"), ScanfFormat]
-       public int scanf (...);
+       public int scanf (string format, ...);
        [CCode (cname = "g_strconcat")]
        public string concat (string string2, ...);
        [CCode (cname = "g_strescape")]


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]