[vala/staging: 3/3] Add G_GNUC_PRINTF/SCANF attribute for Printf/ScanfFormat functions
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/staging: 3/3] Add G_GNUC_PRINTF/SCANF attribute for Printf/ScanfFormat functions
- Date: Tue, 8 Nov 2016 17:45:49 +0000 (UTC)
commit ea412b5145e4980efd83418fcb7c56827f8ea69d
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 | 15 +++++++-
ccode/valaccodefunctiondeclarator.vala | 15 +++++++-
ccode/valaccodemodifiers.vala | 4 ++-
codegen/valaccodemethodmodule.vala | 6 +++
tests/Makefile.am | 1 +
tests/methods/bug710862.vala | 59 ++++++++++++++++++++++++++++++++
vapi/glib-2.0.vapi | 2 +-
7 files changed, 98 insertions(+), 4 deletions(-)
---
diff --git a/ccode/valaccodefunction.vala b/ccode/valaccodefunction.vala
index cd3e385..394fdac 100644
--- a/ccode/valaccodefunction.vala
+++ b/ccode/valaccodefunction.vala
@@ -118,8 +118,10 @@ public class Vala.CCodeFunction : CCodeNode {
writer.write_string (name);
writer.write_string (" (");
+ bool has_args = (CCodeModifiers.PRINTF in modifiers || CCodeModifiers.SCANF in modifiers);
int i = 0;
int format_arg_index = -1;
+ int args_index = -1;
foreach (CCodeParameter param in parameters) {
if (i > 0) {
writer.write_string (", ");
@@ -128,6 +130,11 @@ public class Vala.CCodeFunction : CCodeNode {
if (CCodeModifiers.FORMAT_ARG in param.modifiers) {
format_arg_index = i;
}
+ if (has_args && param.ellipsis) {
+ args_index = i;
+ } else if (has_args && param.type_name == "va_list" && format_arg_index < 0) {
+ format_arg_index = i - 1;
+ }
i++;
}
if (i == 0) {
@@ -141,7 +148,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 :
args_index);
+ writer.write_string (" G_GNUC_PRINTF(%d,%d)".printf (format_arg_index,
args_index + 1));
+ } else if (CCodeModifiers.SCANF in modifiers) {
+ format_arg_index = (format_arg_index >= 0 ? format_arg_index + 1 :
args_index);
+ writer.write_string (" G_GNUC_SCANF(%d,%d)".printf (format_arg_index,
args_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..b195f5a 100644
--- a/ccode/valaccodefunctiondeclarator.vala
+++ b/ccode/valaccodefunctiondeclarator.vala
@@ -55,8 +55,10 @@ public class Vala.CCodeFunctionDeclarator : CCodeDeclarator {
writer.write_string (name);
writer.write_string (") (");
+ bool has_args = (CCodeModifiers.PRINTF in modifiers || CCodeModifiers.SCANF in modifiers);
int i = 0;
int format_arg_index = -1;
+ int args_index = -1;
foreach (CCodeParameter param in parameters) {
if (i > 0) {
writer.write_string (", ");
@@ -65,12 +67,23 @@ public class Vala.CCodeFunctionDeclarator : CCodeDeclarator {
if (CCodeModifiers.FORMAT_ARG in param.modifiers) {
format_arg_index = i;
}
+ if (has_args && param.ellipsis) {
+ args_index = i;
+ } else if (has_args && param.type_name == "va_list" && format_arg_index < 0) {
+ format_arg_index = i - 1;
+ }
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 : args_index);
+ writer.write_string (" G_GNUC_PRINTF(%d,%d)".printf (format_arg_index, args_index +
1));
+ } else if (CCodeModifiers.SCANF in modifiers) {
+ format_arg_index = (format_arg_index >= 0 ? format_arg_index + 1 : args_index);
+ writer.write_string (" G_GNUC_SCANF(%d,%d)".printf (format_arg_index, args_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..2574230 100644
--- a/ccode/valaccodemodifiers.vala
+++ b/ccode/valaccodemodifiers.vala
@@ -39,5 +39,7 @@ public enum Vala.CCodeModifiers {
UNUSED = 1 << 9,
CONSTRUCTOR = 1 << 10,
DESTRUCTOR = 1 << 11,
- FORMAT_ARG = 1 << 12
+ 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..f881847
--- /dev/null
+++ b/tests/methods/bug710862.vala
@@ -0,0 +1,59 @@
+class Foo : Object {
+ [PrintfFormat]
+ public void print (string format, ...) {
+ var vargs = va_list ();
+ print_vargs (format, vargs);
+ }
+
+ [PrintfFormat]
+ public void print_vargs (string format, va_list vargs) {
+ }
+
+ [NoWrapper]
+ [PrintfFormat]
+ public void print_vfunc (string format, ...) {
+ var vargs = va_list ();
+ print_vfunc_vargs (format, vargs);
+ }
+
+ [NoWrapper]
+ [PrintfFormat]
+ public void print_vfunc_vargs (string format, va_list vargs) {
+ }
+
+ [ScanfFormat]
+ public void scan (string input, string format, ...) {
+ }
+
+ [NoWrapper]
+ [ScanfFormat]
+ public void scan_vfunc (string input, string format, ...) {
+ }
+}
+
+[PrintfFormat]
+void print_something (string format, ...) {
+ var vargs = va_list ();
+ print_something_vargs (format, vargs);
+}
+
+[PrintfFormat]
+void print_something_vargs (string format, va_list vargs) {
+}
+
+[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]