diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 4cd98bb2af..e9bfb1f712 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -78,7 +78,7 @@ int import_stack_ptr = 0; static void pop_import(void); -static UUID* parse_uuid(const char*u) +UUID *parse_uuid(const char *u) { UUID* uuid = xmalloc(sizeof(UUID)); char b[3]; diff --git a/tools/widl/parser.y b/tools/widl/parser.y index ae7f8f199d..8399b400b4 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -265,6 +265,7 @@ static void check_all_user_types(ifref_list_t *ifaces); %type coclass coclasshdr coclassdef %type pointer_type version %type libraryhdr +%type uuid_string %left ',' %right '?' ':' @@ -498,7 +499,7 @@ attribute: { $$ = NULL; } | tSWITCHIS '(' expr ')' { $$ = make_attrp(ATTR_SWITCHIS, $3); } | tSWITCHTYPE '(' type ')' { $$ = make_attrp(ATTR_SWITCHTYPE, $3); } | tTRANSMITAS '(' type ')' { $$ = make_attrp(ATTR_TRANSMITAS, $3); } - | tUUID '(' aUUID ')' { $$ = make_attrp(ATTR_UUID, $3); } + | tUUID '(' uuid_string ')' { $$ = make_attrp(ATTR_UUID, $3); } | tV1ENUM { $$ = make_attr(ATTR_V1ENUM); } | tVARARG { $$ = make_attr(ATTR_VARARG); } | tVERSION '(' version ')' { $$ = make_attrv(ATTR_VERSION, $3); } @@ -506,6 +507,12 @@ attribute: { $$ = NULL; } | pointer_type { $$ = make_attrv(ATTR_POINTERTYPE, $1); } ; +uuid_string: + aUUID + | aSTRING { if (!is_valid_uuid($1)) + yyerror("invalid UUID: %s", $1); + $$ = parse_uuid($1); } + callconv: | tSTDCALL ; @@ -2037,3 +2044,20 @@ static void check_all_user_types(ifref_list_t *ifrefs) check_for_user_types_and_context_handles(f->args); } } + +int is_valid_uuid(const char *s) +{ + int i; + + for (i = 0; i < 36; ++i) + if (i == 8 || i == 13 || i == 18 || i == 23) + { + if (s[i] != '-') + return FALSE; + } + else + if (!isxdigit(s[i])) + return FALSE; + + return s[i] == '\0'; +} diff --git a/tools/widl/utils.h b/tools/widl/utils.h index 3641aaecae..aa1d6b4817 100644 --- a/tools/widl/utils.h +++ b/tools/widl/utils.h @@ -42,4 +42,7 @@ void chat(const char *s, ...) __attribute__((format (printf, 1, 2))); char *dup_basename(const char *name, const char *ext); +UUID *parse_uuid(const char *u); +int is_valid_uuid(const char *s); + #endif