| 
									
										
										
										
											2014-08-13 19:20:17 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * QAPI util functions | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Authors: | 
					
						
							|  |  |  |  *  Hu Tao       <hutao@cn.fujitsu.com> | 
					
						
							|  |  |  |  *  Peter Lieven <pl@kamp.de> | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. | 
					
						
							|  |  |  |  * See the COPYING.LIB file in the top-level directory. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-29 17:49:57 +00:00
										 |  |  | #include "qemu/osdep.h"
 | 
					
						
							| 
									
										
										
										
											2021-10-28 12:25:19 +02:00
										 |  |  | #include "qapi/compat-policy.h"
 | 
					
						
							| 
									
										
											  
											
												include/qemu/osdep.h: Don't include qapi/error.h
Commit 57cb38b included qapi/error.h into qemu/osdep.h to get the
Error typedef.  Since then, we've moved to include qemu/osdep.h
everywhere.  Its file comment explains: "To avoid getting into
possible circular include dependencies, this file should not include
any other QEMU headers, with the exceptions of config-host.h,
compiler.h, os-posix.h and os-win32.h, all of which are doing a
similar job to this file and are under similar constraints."
qapi/error.h doesn't do a similar job, and it doesn't adhere to
similar constraints: it includes qapi-types.h.  That's in excess of
100KiB of crap most .c files don't actually need.
Add the typedef to qemu/typedefs.h, and include that instead of
qapi/error.h.  Include qapi/error.h in .c files that need it and don't
get it now.  Include qapi-types.h in qom/object.h for uint16List.
Update scripts/clean-includes accordingly.  Update it further to match
reality: replace config.h by config-target.h, add sysemu/os-posix.h,
sysemu/os-win32.h.  Update the list of includes in the qemu/osdep.h
comment quoted above similarly.
This reduces the number of objects depending on qapi/error.h from "all
of them" to less than a third.  Unfortunately, the number depending on
qapi-types.h shrinks only a little.  More work is needed for that one.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
[Fix compilation without the spice devel packages. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
											
										 
											2016-03-14 09:01:28 +01:00
										 |  |  | #include "qapi/error.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-23 16:35:06 +02:00
										 |  |  | #include "qemu/ctype.h"
 | 
					
						
							| 
									
										
										
										
											2020-11-03 11:13:39 -05:00
										 |  |  | #include "qapi/qmp/qerror.h"
 | 
					
						
							| 
									
										
										
										
											2017-08-24 10:46:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-28 12:25:19 +02:00
										 |  |  | CompatPolicy compat_policy; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bool compat_policy_input_ok1(const char *adjective, | 
					
						
							|  |  |  |                                     CompatPolicyInput policy, | 
					
						
							|  |  |  |                                     ErrorClass error_class, | 
					
						
							|  |  |  |                                     const char *kind, const char *name, | 
					
						
							|  |  |  |                                     Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     switch (policy) { | 
					
						
							|  |  |  |     case COMPAT_POLICY_INPUT_ACCEPT: | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     case COMPAT_POLICY_INPUT_REJECT: | 
					
						
							|  |  |  |         error_set(errp, error_class, "%s %s %s disabled by policy", | 
					
						
							|  |  |  |                   adjective, kind, name); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     case COMPAT_POLICY_INPUT_CRASH: | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         abort(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool compat_policy_input_ok(unsigned special_features, | 
					
						
							|  |  |  |                             const CompatPolicy *policy, | 
					
						
							|  |  |  |                             ErrorClass error_class, | 
					
						
							|  |  |  |                             const char *kind, const char *name, | 
					
						
							|  |  |  |                             Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if ((special_features & 1u << QAPI_DEPRECATED) | 
					
						
							|  |  |  |         && !compat_policy_input_ok1("Deprecated", | 
					
						
							|  |  |  |                                     policy->deprecated_input, | 
					
						
							|  |  |  |                                     error_class, kind, name, errp)) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-10-28 12:25:20 +02:00
										 |  |  |     if ((special_features & (1u << QAPI_UNSTABLE)) | 
					
						
							|  |  |  |         && !compat_policy_input_ok1("Unstable", | 
					
						
							|  |  |  |                                     policy->unstable_input, | 
					
						
							|  |  |  |                                     error_class, kind, name, errp)) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-10-28 12:25:19 +02:00
										 |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 10:46:10 +02:00
										 |  |  | const char *qapi_enum_lookup(const QEnumLookup *lookup, int val) | 
					
						
							| 
									
										
										
										
											2017-08-24 10:46:07 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-08-24 10:46:10 +02:00
										 |  |  |     assert(val >= 0 && val < lookup->size); | 
					
						
							| 
									
										
										
										
											2017-08-24 10:46:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 10:46:10 +02:00
										 |  |  |     return lookup->array[val]; | 
					
						
							| 
									
										
										
										
											2017-08-24 10:46:07 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-08-13 19:20:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 10:46:10 +02:00
										 |  |  | int qapi_enum_parse(const QEnumLookup *lookup, const char *buf, | 
					
						
							| 
									
										
										
										
											2017-08-24 10:45:57 +02:00
										 |  |  |                     int def, Error **errp) | 
					
						
							| 
									
										
										
										
											2014-08-13 19:20:17 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!buf) { | 
					
						
							|  |  |  |         return def; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 10:46:10 +02:00
										 |  |  |     for (i = 0; i < lookup->size; i++) { | 
					
						
							|  |  |  |         if (!strcmp(buf, lookup->array[i])) { | 
					
						
							| 
									
										
										
										
											2014-08-13 19:20:17 +02:00
										 |  |  |             return i; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     error_setg(errp, "invalid parameter value: %s", buf); | 
					
						
							|  |  |  |     return def; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-02-28 22:27:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-03 11:13:39 -05:00
										 |  |  | bool qapi_bool_parse(const char *name, const char *value, bool *obj, Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (g_str_equal(value, "on") || | 
					
						
							|  |  |  |         g_str_equal(value, "yes") || | 
					
						
							|  |  |  |         g_str_equal(value, "true") || | 
					
						
							|  |  |  |         g_str_equal(value, "y")) { | 
					
						
							|  |  |  |         *obj = true; | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (g_str_equal(value, "off") || | 
					
						
							|  |  |  |         g_str_equal(value, "no") || | 
					
						
							|  |  |  |         g_str_equal(value, "false") || | 
					
						
							|  |  |  |         g_str_equal(value, "n")) { | 
					
						
							|  |  |  |         *obj = false; | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, | 
					
						
							|  |  |  |                "'on' or 'off'"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-28 22:27:04 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Parse a valid QAPI name from @str. | 
					
						
							|  |  |  |  * A valid name consists of letters, digits, hyphen and underscore. | 
					
						
							|  |  |  |  * It may be prefixed by __RFQDN_ (downstream extension), where RFQDN | 
					
						
							|  |  |  |  * may contain only letters, digits, hyphen and period. | 
					
						
							|  |  |  |  * The special exception for enumeration names is not implemented. | 
					
						
							| 
									
										
										
										
											2017-07-28 19:46:03 -03:00
										 |  |  |  * See docs/devel/qapi-code-gen.txt for more on QAPI naming rules. | 
					
						
							| 
									
										
										
										
											2022-02-18 15:55:51 +01:00
										 |  |  |  * Keep this consistent with scripts/qapi-gen.py! | 
					
						
							| 
									
										
										
										
											2017-02-28 22:27:04 +01:00
										 |  |  |  * If @complete, the parse fails unless it consumes @str completely. | 
					
						
							|  |  |  |  * Return its length on success, -1 on failure. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int parse_qapi_name(const char *str, bool complete) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *p = str; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (*p == '_') {            /* Downstream __RFQDN_ */ | 
					
						
							|  |  |  |         p++; | 
					
						
							|  |  |  |         if (*p != '_') { | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         while (*++p) { | 
					
						
							|  |  |  |             if (!qemu_isalnum(*p) && *p != '-' && *p != '.') { | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (*p != '_') { | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         p++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!qemu_isalpha(*p)) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     while (*++p) { | 
					
						
							|  |  |  |         if (!qemu_isalnum(*p) && *p != '-' && *p != '_') { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (complete && *p) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return p - str; | 
					
						
							|  |  |  | } |