diff --git a/xpcom/typelib/xpidl/xpidl.h b/xpcom/typelib/xpidl/xpidl.h index ea77f25db2a0..b2048b96dc7f 100644 --- a/xpcom/typelib/xpidl/xpidl.h +++ b/xpcom/typelib/xpidl/xpidl.h @@ -43,17 +43,18 @@ * ## idiom, which allows us to pass through varargs calls. */ #if !(LIBIDL_MAJOR_VERSION == 0 && LIBIDL_MINOR_VERSION == 6 && \ - LIBIDL_MICRO_VERSION == 5) + LIBIDL_MICRO_VERSION == 5) && !defined(DEBUG_shaver) /* - * This turns a varargs call to XPIDL_WARNING directly into a varargs call to - * IDL_tree_warning. The only tricky bit is that you must call XPIDL_WARNING - * with extra parens, e.g. XPIDL_WARNING((foo, bar, "sil")) + * This turns a varargs call to XPIDL_WARNING directly into a varargs + * call to IDL_tree_warning or xpidl_tree_warning as appropriate. The + * only tricky bit is that you must call XPIDL_WARNING with extra + * parens, e.g. XPIDL_WARNING((foo, bar, "sil")) * - * Probably best removed when we leave 6.5. -*/ + * Probably best removed when we leave 6.5. */ #define XPIDL_WARNING(x) IDL_tree_warning##x #else -#define XPIDL_WARNING(x) do { } while (0) +extern void xpidl_tree_warning(IDL_tree p, int level, const char *fmt, ...); +#define XPIDL_WARNING(x) xpidl_tree_warning##x #endif /* @@ -196,4 +197,11 @@ xpidl_parse_iid(nsID *id, const char *str); gboolean verify_method_declaration(IDL_tree method_tree); +/* + * Verify that a native declaration has an associated C++ expression, i.e. that + * it's of the form native () + */ +gboolean +check_native(TreeState *state); + #endif /* __xpidl_h */ diff --git a/xpcom/typelib/xpidl/xpidl_header.c b/xpcom/typelib/xpidl/xpidl_header.c index 12a798065354..9b13616ff3d8 100644 --- a/xpcom/typelib/xpidl/xpidl_header.c +++ b/xpcom/typelib/xpidl/xpidl_header.c @@ -487,26 +487,9 @@ attr_dcl(TreeState *state) static gboolean do_enum(TreeState *state) { - XPIDL_WARNING((state->tree, IDL_WARNING1, - "enums not supported, enum \'%s\' ignored", - IDL_IDENT(IDL_TYPE_ENUM(state->tree).ident).str)); - return TRUE; -#if 0 - IDL_tree enumb = state->tree, iter; - - fprintf(state->file, "enum %s {\n", - IDL_IDENT(IDL_TYPE_ENUM(enumb).ident).str); - - for (iter = IDL_TYPE_ENUM(enumb).enumerator_list; - iter; - iter = IDL_LIST(iter).next) { - fprintf(state->file, " %s%s\n", IDL_IDENT(IDL_LIST(iter).data).str, - IDL_LIST(iter).next ? ",": ""); - } - - fputs("};\n\n", state->file); - return TRUE; -#endif + IDL_tree_error(state->tree, "enums not supported, " + "see http://bugzilla.mozilla.org/show_bug.cgi?id=8781"); + return FALSE; } static gboolean @@ -542,8 +525,9 @@ do_const_dcl(TreeState *state) name, (int) IDL_INTEGER(dcl->const_exp).value); } else { IDL_tree_error(state->tree, - "const decl \'%s\' must be of type short or long", + "const declaration \'%s\' must be of type short or long", name); + return FALSE; } return TRUE; } @@ -769,10 +753,11 @@ static gboolean codefrag(TreeState *state) { const char *desc = IDL_CODEFRAG(state->tree).desc; - if (strcmp(desc, "C++")) { + + if (strcmp(desc, "C++") && /* libIDL bug? */ strcmp(desc, "C++\r")) { XPIDL_WARNING((state->tree, IDL_WARNING1, "ignoring '%%{%s' escape. " - "(Use '%%{C++' to escape verbatim code.)", desc)); + "(Use '%%{C++' to escape verbatim C++ code.)", desc)); return TRUE; } @@ -785,8 +770,9 @@ nodeHandler * xpidl_header_dispatch(void) { static nodeHandler table[IDLN_LAST]; + static gboolean initialized = FALSE; - if (!table[IDLN_NONE]) { + if (!initialized) { table[IDLN_NONE] = pass_1; table[IDLN_LIST] = list; table[IDLN_ATTR_DCL] = attr_dcl; @@ -797,6 +783,8 @@ xpidl_header_dispatch(void) table[IDLN_CODEFRAG] = codefrag; table[IDLN_TYPE_DCL] = do_typedef; table[IDLN_CONST_DCL] = do_const_dcl; + table[IDLN_NATIVE] = check_native; + initialized = TRUE; } return table; diff --git a/xpcom/typelib/xpidl/xpidl_idl.c b/xpcom/typelib/xpidl/xpidl_idl.c index 70c14fdbf0db..dd7db88e2f29 100644 --- a/xpcom/typelib/xpidl/xpidl_idl.c +++ b/xpcom/typelib/xpidl/xpidl_idl.c @@ -104,14 +104,19 @@ static int msg_callback(int level, int num, int line, const char *file, const char *message) { + char *warning_message; + + if (!file) + file = ""; + warning_message = g_strdup_printf("%s:%d: %s\n", file, line, message); + #ifdef XP_MAC - static char warning_message[1024]; - sprintf(warning_message, "%s:%d: %s\n", file, line, message); mac_warning(warning_message); #else - /* XXX Mac */ - fprintf(stderr, "%s:%d: %s\n", file, line, message); + fputs(warning_message, stderr); #endif + + free(warning_message); return 1; } @@ -888,3 +893,50 @@ verify_method_declaration(IDL_tree method_tree) } return TRUE; } + +/* + * Verify that a native declaration has an associated C++ expression, i.e. that + * it's of the form native () + */ +gboolean +check_native(TreeState *state) +{ + char *native_name; + /* require that native declarations give a native type */ + if (IDL_NATIVE(state->tree).user_type) + return TRUE; + native_name = IDL_IDENT(IDL_NATIVE(state->tree).ident).str; + IDL_tree_error(state->tree, + "``native %s;'' needs C++ type: ``native %s();''", + native_name, native_name); + return FALSE; +} + +/* + * Our own version of IDL_tree_warning, which we use when IDL_tree_warning + * would crash on us. + */ +void +xpidl_tree_warning(IDL_tree p, int level, const char *fmt, ...) +{ + va_list ap; + char *msg, *file; + int lineno; + + /* XXX need to check against __IDL_max_msg_level, no accessor */ + va_start(ap, fmt); + msg = g_strdup_vprintf(fmt, ap); + + if (p) { + file = p->_file; + lineno = p->_line; + } else { + file = NULL; + lineno = 0; + } + + /* call our message callback, like IDL_tree_warning would */ + msg_callback(level, 0 /* unused in callee */, lineno, file, msg); + + va_end(ap); +} diff --git a/xpcom/typelib/xpidl/xpidl_typelib.c b/xpcom/typelib/xpidl/xpidl_typelib.c index 2bb6c14bcea8..7cd76107fb2f 100644 --- a/xpcom/typelib/xpidl/xpidl_typelib.c +++ b/xpcom/typelib/xpidl/xpidl_typelib.c @@ -463,12 +463,7 @@ pass_1(TreeState *state) destroy_header: /* XXX XPT_DestroyHeader(HEADER(state)) */ -#ifdef DEBUG_shaver - fprintf(stderr, "writing typelib was %ssuccessful\n", - ok ? "" : "not "); -#else ; /* msvc would like a statement here */ -#endif } return ok; @@ -853,18 +848,10 @@ handle_iid_is: } } if (isID) { -#ifdef DEBUG_shaver - fprintf(stderr, "doing nsID for %s\n", - IDL_IDENT(type).str); -#endif td->prefix.flags = TD_PNSIID | XPT_TDP_POINTER; if(IDL_tree_property_get(type, "ref")) td->prefix.flags |= XPT_TDP_REFERENCE; } else { -#ifdef DEBUG_shaver - fprintf(stderr, "not doing nsID for %s\n", - IDL_IDENT(type).str); -#endif td->prefix.flags = TD_VOID | XPT_TDP_POINTER; } break; @@ -894,11 +881,12 @@ handle_iid_is: } IDL_tree_error(type, "can't handle %s ident in param list\n", #ifdef DEBUG_shaver - IDL_NODE_TYPE_NAME(IDL_NODE_UP(type)) + /* XXX is this safe to use on Win now? */ + IDL_NODE_TYPE_NAME(IDL_NODE_UP(type)) #else - "that type of" + "that type of" #endif - ); + ); #ifdef DEBUG_shaver XPT_ASSERT(0); #endif @@ -908,7 +896,8 @@ handle_iid_is: default: IDL_tree_error(type, "can't handle %s in param list\n", #ifdef DEBUG_shaver - IDL_NODE_TYPE_NAME(IDL_NODE_UP(type)) + /* XXX is this safe to use on Win now? */ + IDL_NODE_TYPE_NAME(IDL_NODE_UP(type)) #else "that type" #endif @@ -1035,6 +1024,7 @@ typelib_op_dcl(TreeState *state) IDL_tree iter; uint16 num_args = 0; uint8 op_flags = 0; + gboolean saw_retval = FALSE; gboolean op_notxpcom = (IDL_tree_property_get(op->ident, "notxpcom") != NULL); gboolean op_noscript = (IDL_tree_property_get(op->ident, "noscript") @@ -1070,9 +1060,22 @@ typelib_op_dcl(TreeState *state) for (num_args = 0, iter = op->parameter_dcls; iter; iter = IDL_LIST(iter).next, num_args++) { - if (!fill_pd_from_param(state, &meth->params[num_args], - IDL_LIST(iter).data)) + XPTParamDescriptor *pd = &meth->params[num_args]; + if (!fill_pd_from_param(state, pd, IDL_LIST(iter).data)) return FALSE; + if (pd->flags & XPT_PD_RETVAL) { + if (op->op_type_spec) { + IDL_tree_error(state->tree, + "can't have [retval] with non-void return type"); + return FALSE; + } + if (saw_retval) { + IDL_tree_error(state->tree, + "can't have more than one [retval] parameter"); + return FALSE; + } + saw_retval = TRUE; + } } /* XXX unless [notxpcom] */ @@ -1286,6 +1289,7 @@ xpidl_typelib_dispatch(void) table[IDLN_INTERFACE] = typelib_interface; table[IDLN_CONST_DCL] = typelib_const_dcl; table[IDLN_TYPE_ENUM] = typelib_enum; + table[IDLN_NATIVE] = check_native; initialized = TRUE; }