Changeset 108305 in vbox
- Timestamp:
- Feb 20, 2025 8:09:36 AM (2 months ago)
- svn:sync-xref-src-repo-rev:
- 167649
- Location:
- trunk/src/libs/xpcom18a4/xpcom/typelib/xpidl-new
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/xpcom/typelib/xpidl-new/xpidl.h
r108304 r108305 79 79 /** Node for the list of inputs. */ 80 80 RTLISTNODE NdInput; 81 /** Node for the list of include. */ 82 RTLISTNODE NdInclude; 81 83 /** The list of includes this input generated. */ 82 84 RTLISTANCHOR LstIncludes; … … 109 111 kXpidlNdType_Attribute, 110 112 kXpidlNdType_Method, 111 kXpidlNdType_Parameter 113 kXpidlNdType_Parameter, 114 kXpidlNdType_Const 112 115 } XPIDLNDTYPE; 113 116 … … 119 122 { 120 123 kXpidlType_Invalid = 0, 124 kXpidlType_Void, 121 125 kXpidlType_Boolean, 122 126 kXpidlType_Octet, … … 227 231 XPIDLDIRECTION enmDir; 228 232 } Param; 233 struct 234 { 235 PCXPIDLNODE pNdTypeSpec; 236 const char *pszName; 237 uint64_t u64Const; /* Only allowing numbers for now. */ 238 } Const; 229 239 } u; 230 240 /** Number of entries in the attribute array. */ … … 269 279 extern PRUint8 minor_version; 270 280 271 typedef struct TreeState TreeState; 272 273 /* 274 * A function to handle an IDL_tree type. 275 */ 276 typedef bool (*nodeHandler)(TreeState *); 277 278 /* 279 * Struct containing functions to define the behavior of a given output mode. 280 */ 281 typedef struct backend { 282 nodeHandler *dispatch_table; /* nodeHandlers table, indexed by node type. */ 283 nodeHandler emit_prolog; /* called at beginning of output generation. */ 284 nodeHandler emit_epilog; /* called at end. */ 285 } backend; 286 287 /* Function that produces a struct of output-generation functions */ 288 typedef backend *(*backendFactory)(); 289 290 extern backend *xpidl_header_dispatch(void); 291 extern backend *xpidl_typelib_dispatch(void); 281 282 /** 283 * Dispatch callback. 284 * 285 * @returns IPRT status code. 286 * @param pFile The file to output to. 287 * @param pInput The original input file to generate for. 288 * @param pParse The parsing state. 289 */ 290 typedef DECLCALLBACKTYPE(int, FNXPIDLDISPATCH,(FILE *pFile, PCXPIDLINPUT pInput, PCXPIDLPARSE pParse)); 291 /** Pointer to a dispatch callback. */ 292 typedef FNXPIDLDISPATCH *PFNXPIDLDISPATCH; 293 294 295 DECL_HIDDEN_CALLBACK(int) xpidl_header_dispatch(FILE *pFile, PCXPIDLINPUT pInput, PCXPIDLPARSE pParse); 296 DECL_HIDDEN_CALLBACK(int) xpidl_typelib_dispatch(FILE *pFile, PCXPIDLINPUT pInput, PCXPIDLPARSE pParse); 292 297 293 298 typedef struct ModeData { … … 295 300 char *modeInfo; 296 301 char *suffix; 297 backendFactory factory;302 PFNXPIDLDISPATCH dispatch; 298 303 } ModeData; 299 304 300 301 struct TreeState {302 FILE *file;303 /* Maybe supplied by -o. Not related to (g_)basename from string.h or glib */304 char *basename;305 RTLISTANCHOR *base_includes;306 nodeHandler *dispatch;307 void *priv; /* mode-private data */308 };309 305 310 306 /* … … 332 328 xpidl_basename(const char * path); 333 329 334 /*335 * Process an XPIDL node and its kids, if any.336 */337 bool338 xpidl_process_node(TreeState *state);339 340 /*341 * Write a newline folllowed by an indented, one-line comment containing IDL342 * source decompiled from state->tree.343 */344 void345 xpidl_write_comment(TreeState *state, int indent);346 347 348 330 349 331 /* … … 371 353 372 354 355 DECLHIDDEN(PCXPIDLATTR) xpidlNodeAttrFind(PCXPIDLNODE pNd, const char *pszAttr); 356 357 358 /* Try to common a little node-handling stuff. */ 359 360 361 DECLINLINE(bool) xpidlNdIsStringType(PCXPIDLNODE pNd) 362 { 363 return pNd->enmType == kXpidlNdType_BaseType 364 && ( pNd->u.enmBaseType == kXpidlType_String 365 || pNd->u.enmBaseType == kXpidlType_Wide_String); 366 } 367 368 369 /* is this node from an aggregate type (interface)? */ 370 #define UP_IS_AGGREGATE(a_pNd) \ 371 ( a_pNd->pParent \ 372 && ( a_pNd->pParent->enmType == kXpidlNdType_Interface_Forward_Decl \ 373 || a_pNd->pParent->enmType == kXpidlNdType_Interface_Def)) 374 375 #define UP_IS_NATIVE(a_pNd) \ 376 ( a_pNd->pParent \ 377 && a_pNd->pParent->enmType == kXpidlNdType_Native) 378 379 /* is this type output in the form "<foo> *"? */ 380 #define STARRED_TYPE(a_pNd) (xpidlNdIsStringType(a_pNd) || \ 381 (a_pNd->enmType == kXpidlNdType_Identifier && \ 382 UP_IS_AGGREGATE(a_pNd))) 383 384 #define DIPPER_TYPE(a_pNd) \ 385 (xpidlNodeAttrFind(a_pNd, "domstring") || \ 386 xpidlNodeAttrFind(a_pNd, "utf8string") || \ 387 xpidlNodeAttrFind(a_pNd, "cstring") || \ 388 xpidlNodeAttrFind(a_pNd, "astring")) 389 390 391 /* 392 * Verifies the interface declaration 393 */ 394 DECLHIDDEN(bool) verify_interface_declaration(PCXPIDLNODE pNd); 395 373 396 #if 0 374 /* Try to common a little node-handling stuff. */375 376 /* is this node from an aggregate type (interface)? */377 #define UP_IS_AGGREGATE(node) \378 (IDL_NODE_UP(node) && \379 (IDL_NODE_TYPE(IDL_NODE_UP(node)) == IDLN_INTERFACE || \380 IDL_NODE_TYPE(IDL_NODE_UP(node)) == IDLN_FORWARD_DCL))381 382 #define UP_IS_NATIVE(node) \383 (IDL_NODE_UP(node) && \384 IDL_NODE_TYPE(IDL_NODE_UP(node)) == IDLN_NATIVE)385 386 /* is this type output in the form "<foo> *"? */387 #define STARRED_TYPE(node) (IDL_NODE_TYPE(node) == IDLN_TYPE_STRING || \388 IDL_NODE_TYPE(node) == IDLN_TYPE_WIDE_STRING || \389 (IDL_NODE_TYPE(node) == IDLN_IDENT && \390 UP_IS_AGGREGATE(node)))391 392 #define DIPPER_TYPE(node) \393 (NULL != IDL_tree_property_get(node, "domstring") || \394 NULL != IDL_tree_property_get(node, "utf8string") || \395 NULL != IDL_tree_property_get(node, "cstring") || \396 NULL != IDL_tree_property_get(node, "astring"))397 398 397 /* 399 398 * Find the underlying type of an identifier typedef. Returns NULL … … 421 420 gboolean 422 421 verify_method_declaration(IDL_tree method_tree); 423 424 /*425 * Verifies the interface declaration426 */427 gboolean428 verify_interface_declaration(IDL_tree method_tree);429 422 430 423 /* -
trunk/src/libs/xpcom18a4/xpcom/typelib/xpidl-new/xpidl_header.c
r108284 r108305 39 39 * Generate XPCOM headers from XPIDL. 40 40 */ 41 #include <iprt/assert.h> 42 #include <iprt/path.h> 41 43 42 44 #include "xpidl.h" 43 45 #include <ctype.h> 44 46 45 #define AS_DECL 0 46 #define AS_CALL 1 47 #define AS_IMPL 2 48 49 #if 0 50 static bool write_method_signature(IDL_tree method_tree, FILE *outfile, 51 int mode, const char *className); 52 static bool write_attr_accessor(IDL_tree attr_tree, FILE * outfile, 53 bool getter, 54 int mode, const char *className); 55 56 static void 57 write_indent(FILE *outfile) { 47 static void write_indent(FILE *outfile) 48 { 58 49 fputs(" ", outfile); 59 50 } 60 51 61 static bool62 header_prolog(TreeState *state)63 {64 char *define = xpidl_basename(state->basename);65 fprintf(state->file, "/*\n * DO NOT EDIT. THIS FILE IS GENERATED FROM"66 " %s.idl\n */\n", state->basename);67 fprintf(state->file,68 "\n#ifndef __gen_%s_h__\n"69 "#define __gen_%s_h__\n",70 define, define);71 g_free(define);72 if (state->base_includes != NULL) {73 guint len = g_slist_length(state->base_includes);74 guint i;75 76 fputc('\n', state->file);77 for (i = 0; i < len; i++) {78 char *ident, *dot;79 80 ident = (char *)g_slist_nth_data(state->base_includes, i);81 82 /* suppress any trailing .extension */83 84 /* XXX use g_basename instead ? ? */85 86 dot = strrchr(ident, '.');87 if (dot != NULL)88 *dot = '\0';89 90 91 /* begin include guard */92 fprintf(state->file,93 "\n#ifndef __gen_%s_h__\n",94 ident);95 96 fprintf(state->file, "#include \"%s.h\"\n",97 (char *)g_slist_nth_data(state->base_includes, i));98 99 fprintf(state->file, "#endif\n");100 101 }102 if (i > 0)103 fputc('\n', state->file);104 }105 /*106 * Support IDL files that don't include a root IDL file that defines107 * NS_NO_VTABLE.108 */109 fprintf(state->file,110 "/* For IDL files that don't want to include root IDL files. */\n"111 "#ifndef NS_NO_VTABLE\n"112 "#define NS_NO_VTABLE\n"113 "#endif\n");114 115 return TRUE;116 }117 118 static bool119 header_epilog(TreeState *state)120 {121 char *define = xpidl_basename(state->basename);122 fprintf(state->file, "\n#endif /* __gen_%s_h__ */\n", define);123 g_free(define);124 return TRUE;125 }126 52 127 53 static void … … 141 67 } 142 68 143 static bool 144 interface(TreeState *state) 145 { 146 IDL_tree iface = state->tree, iter, orig; 147 char *className = IDL_IDENT(IDL_INTERFACE(iface).ident).str; 69 70 static int xpidlHdrWriteIdlType(PCXPIDLNODE pNd, FILE *pFile) 71 { 72 if (pNd->enmType == kXpidlNdType_BaseType) 73 { 74 switch (pNd->u.enmBaseType) 75 { 76 case kXpidlType_Void: 77 fputs("void", pFile); 78 break; 79 case kXpidlType_Boolean: 80 fputs("boolean", pFile); 81 break; 82 case kXpidlType_Octet: 83 fputs("octet", pFile); 84 break; 85 case kXpidlType_Char: 86 fputs("char", pFile); 87 break; 88 case kXpidlType_Wide_Char: 89 fputs("wchar", pFile); /* wchar_t? */ 90 break; 91 case kXpidlType_Short: 92 fputs("short", pFile); 93 break; 94 case kXpidlType_Long: 95 fputs("long", pFile); 96 break; 97 case kXpidlType_Long_Long: 98 fputs("long long", pFile); 99 break; 100 case kXpidlType_Unsigned_Short: 101 fputs("unsigned short", pFile); 102 break; 103 case kXpidlType_Unsigned_Long: 104 fputs("unsigned long", pFile); 105 break; 106 case kXpidlType_Unsigned_Long_Long: 107 fputs("unsigned long long", pFile); 108 break; 109 case kXpidlType_String: 110 fputs("string", pFile); 111 break; 112 case kXpidlType_Wide_String: 113 fputs("wstring", pFile); 114 break; 115 case kXpidlType_Double: 116 fputs("double", pFile); 117 break; 118 case kXpidlType_Float: 119 fputs("float", pFile); 120 break; 121 default: 122 AssertReleaseFailed(); 123 } 124 } 125 else 126 { 127 Assert(pNd->enmType == kXpidlNdType_Identifier); 128 fputs(pNd->u.pszIde, pFile); 129 } 130 131 return VINF_SUCCESS; 132 } 133 134 static int xpidlHdrWriteType(PCXPIDLNODE pNd, FILE *outfile) 135 { 136 if (pNd->enmType == kXpidlNdType_BaseType) 137 { 138 switch (pNd->u.enmBaseType) 139 { 140 case kXpidlType_Void: 141 fputs("void", outfile); 142 break; 143 case kXpidlType_Boolean: 144 fputs("PRBool", outfile); 145 break; 146 case kXpidlType_Octet: 147 fputs("PRUint8", outfile); 148 break; 149 case kXpidlType_Char: 150 fputs("char", outfile); 151 break; 152 case kXpidlType_Wide_Char: 153 fputs("PRUnichar", outfile); /* wchar_t? */ 154 break; 155 case kXpidlType_Short: 156 fputs("PRInt16", outfile); 157 break; 158 case kXpidlType_Long: 159 fputs("PRInt32", outfile); 160 break; 161 case kXpidlType_Long_Long: 162 fputs("PRInt64", outfile); 163 break; 164 case kXpidlType_Unsigned_Short: 165 fputs("PRUInt16", outfile); 166 break; 167 case kXpidlType_Unsigned_Long: 168 fputs("PRUInt32", outfile); 169 break; 170 case kXpidlType_Unsigned_Long_Long: 171 fputs("PRUInt64", outfile); 172 break; 173 case kXpidlType_String: 174 fputs("char *", outfile); 175 break; 176 case kXpidlType_Wide_String: 177 fputs("PRUnichar *", outfile); 178 break; 179 case kXpidlType_Double: 180 fputs("double", outfile); 181 break; 182 case kXpidlType_Float: 183 fputs("float", outfile); 184 break; 185 default: 186 AssertReleaseFailed(); 187 } 188 } 189 else 190 { 191 Assert(pNd->enmType == kXpidlNdType_Identifier); 192 if (UP_IS_NATIVE(pNd)) 193 { 194 if ( xpidlNodeAttrFind(pNd, "domstring") 195 || xpidlNodeAttrFind(pNd, "astring")) 196 fputs("nsAString", outfile); 197 else if (xpidlNodeAttrFind(pNd, "utf8string")) 198 fputs("nsACString", outfile); 199 else if (xpidlNodeAttrFind(pNd, "cstring")) 200 fputs("nsACString", outfile); 201 else 202 fputs(pNd->u.Native.pszNative, outfile); 203 204 if (xpidlNodeAttrFind(pNd, "ptr")) 205 fputs(" *", outfile); 206 else if (xpidlNodeAttrFind(pNd, "ref")) 207 fputs(" &", outfile); 208 } 209 else 210 fputs(pNd->u.pszIde, outfile); 211 212 if (UP_IS_AGGREGATE(pNd)) 213 fputs(" *", outfile); 214 } 215 216 return VINF_SUCCESS; 217 } 218 219 220 /* 221 * param generation: 222 * in string foo --> nsString *foo 223 * out string foo --> nsString **foo; 224 * inout string foo --> nsString **foo; 225 */ 226 227 /* If notype is true, just write the param name. */ 228 static int write_param(PCXPIDLNODE pNd, FILE *pFile) 229 { 230 PCXPIDLNODE pNdTypeSpec = pNd->u.Param.pNdTypeSpec; 231 bool is_in = pNd->u.Param.enmDir == kXpidlDirection_In; 232 /* in string, wstring, nsid, domstring, utf8string, cstring and 233 * astring any explicitly marked [const] are const 234 */ 235 236 if (is_in && 237 (xpidlNdIsStringType(pNdTypeSpec) || 238 // IDL_tree_property_get(IDL_PARAM_DCL(param_tree).simple_declarator, 239 // "const") || 240 xpidlNodeAttrFind(pNdTypeSpec, "nsid") || 241 xpidlNodeAttrFind(pNdTypeSpec, "domstring") || 242 xpidlNodeAttrFind(pNdTypeSpec, "utf8string") || 243 xpidlNodeAttrFind(pNdTypeSpec, "cstring") || 244 xpidlNodeAttrFind(pNdTypeSpec, "astring"))) { 245 fputs("const ", pFile); 246 } 247 else if ( pNd->u.Param.enmDir == kXpidlDirection_Out 248 && xpidlNodeAttrFind(pNd, "shared")) { 249 fputs("const ", pFile); 250 } 251 252 int rc = xpidlHdrWriteType(pNdTypeSpec, pFile); 253 if (RT_FAILURE(rc)) 254 return rc; 255 256 /* unless the type ended in a *, add a space */ 257 if (!STARRED_TYPE(pNdTypeSpec)) 258 fputc(' ', pFile); 259 260 /* out and inout params get a bonus '*' (unless this is type that has a 261 * 'dipper' class that is passed in to receive 'out' data) 262 */ 263 if ( !is_in 264 && !DIPPER_TYPE(pNdTypeSpec)) 265 fputc('*', pFile); 266 267 /* arrays get a bonus * too */ 268 /* XXX Should this be a leading '*' or a trailing "[]" ?*/ 269 if (xpidlNodeAttrFind(pNd, "array")) 270 fputc('*', pFile); 271 272 fputs(pNd->u.Param.pszName, pFile); 273 return VINF_SUCCESS; 274 } 275 276 277 /* 278 * Shared between the interface class declaration and the NS_DECL_IFOO macro 279 * provided to aid declaration of implementation classes. 280 */ 281 static int write_method_signature(PCXPIDLNODE pNd, FILE *pFile, const char *className) 282 { 283 bool no_generated_args = true; 284 bool op_notxpcom = (xpidlNodeAttrFind(pNd, "notxpcom") != NULL); 285 286 if (op_notxpcom) { 287 fputs("NS_IMETHOD_(", pFile); 288 int rc = xpidlHdrWriteType(pNd->u.Method.pNdTypeSpecRet, pFile); 289 if (RT_FAILURE(rc)) 290 return rc; 291 fputc(')', pFile); 292 } else { 293 fputs("NS_IMETHOD", pFile); 294 } 295 fputc(' ', pFile); 296 297 const char *pszName = pNd->u.Method.pszName; 298 fprintf(pFile, "%c%s(", toupper(*pszName), pszName + 1); 299 300 PCXPIDLNODE pIt; 301 RTListForEach(&pNd->u.Method.LstParams, pIt, XPIDLNODE, NdLst) 302 { 303 int rc = write_param(pIt, pFile); 304 if (RT_FAILURE(rc)) 305 return rc; 306 307 if (!RTListNodeIsLast(&pNd->u.Method.LstParams, &pIt->NdLst)) 308 fputs(", ", pFile); 309 no_generated_args = false; 310 } 311 312 #if 0 313 /* make IDL return value into trailing out argument */ 314 if (op->op_type_spec && !op_notxpcom) { 315 IDL_tree fake_param = IDL_param_dcl_new(IDL_PARAM_OUT, 316 op->op_type_spec, 317 IDL_ident_new("_retval")); 318 if (!fake_param) 319 return FALSE; 320 if (!write_param(fake_param, pFile)) 321 return FALSE; 322 323 #if 0 324 if (op->f_varargs) 325 fputs(", ", pFile); 326 #endif 327 no_generated_args = false; 328 } 329 #endif 330 331 #if 0 /** @todo No varargs allowed. */ 332 /* varargs go last */ 333 if (op->f_varargs) { 334 if (mode == AS_DECL || mode == AS_IMPL) { 335 fputs("nsVarArgs *", pFile); 336 } 337 fputs("_varargs", pFile); 338 no_generated_args = FALSE; 339 } 340 #endif 341 342 /* 343 * If generated method has no arguments, output 'void' to avoid C legacy 344 * behavior of disabling type checking. 345 */ 346 if (no_generated_args) 347 fputs("void", pFile); 348 349 fputc(')', pFile); 350 return VINF_SUCCESS; 351 } 352 353 354 static int xpidlHdrWriteMethod(PCXPIDLNODE pNd, FILE *pFile) 355 { 356 #if 0 /** @todo */ 357 /* 358 * Verify that e.g. non-scriptable methods in [scriptable] interfaces 359 * are declared so. Do this in a separate verification pass? 360 */ 361 if (!verify_method_declaration(state->tree)) 362 return FALSE; 363 #endif 364 365 write_indent(pFile); 366 int rc = write_method_signature(pNd, pFile, NULL); 367 if (RT_FAILURE(rc)) 368 return rc; 369 fputs(" = 0;\n\n", pFile); 370 371 return VINF_SUCCESS; 372 } 373 374 375 static int xpidlHdrWriteAttrAccessor(PCXPIDLNODE pNd, FILE *pFile, bool getter) 376 { 377 const char *pszName = pNd->u.Attribute.pszName; 378 379 fputs("NS_IMETHOD ", pFile); 380 fprintf(pFile, "%cet%c%s(", 381 getter ? 'G' : 'S', 382 toupper(*pszName), pszName + 1); 383 /* Setters for string, wstring, nsid, domstring, utf8string, 384 * cstring and astring get const. 385 */ 386 if (!getter && 387 (xpidlNdIsStringType(pNd->u.Attribute.pNdTypeSpec) || 388 xpidlNodeAttrFind(pNd, "nsid") || 389 xpidlNodeAttrFind(pNd, "domstring") || 390 xpidlNodeAttrFind(pNd, "utf8string") || 391 xpidlNodeAttrFind(pNd, "cstring") || 392 xpidlNodeAttrFind(pNd, "astring"))) 393 fputs("const ", pFile); 394 395 int rc = xpidlHdrWriteType(pNd->u.Attribute.pNdTypeSpec, pFile); 396 if (RT_FAILURE(rc)) 397 return rc; 398 fprintf(pFile, "%s%s", 399 (STARRED_TYPE(pNd->u.Attribute.pNdTypeSpec) ? "" : " "), 400 (getter && !DIPPER_TYPE(pNd->u.Attribute.pNdTypeSpec) ? "*" : "")); 401 fprintf(pFile, "a%c%s)", toupper(pszName[0]), pszName + 1); 402 return VINF_SUCCESS; 403 } 404 405 static int xpidlHdrWriteAttribute(PCXPIDLNODE pNd, FILE *pFile) 406 { 407 #if 0 /** @todo */ 408 if (!verify_attribute_declaration(state->tree)) 409 return FALSE; 410 #endif 411 412 /* Write the attribute as a comment. */ 413 write_indent(pFile); 414 if (pNd->u.Attribute.fReadonly) 415 fputs("/* readonly attribute ", pFile); 416 else 417 fputs("/* attribute ", pFile); 418 xpidlHdrWriteIdlType(pNd->u.Attribute.pNdTypeSpec, pFile); 419 fprintf(pFile, " %s; */\n", pNd->u.Attribute.pszName); 420 421 write_indent(pFile); 422 int rc = xpidlHdrWriteAttrAccessor(pNd, pFile, true); 423 if (RT_FAILURE(rc)) 424 return rc; 425 fputs(" = 0;\n", pFile); 426 427 if (!pNd->u.Attribute.fReadonly) { 428 write_indent(pFile); 429 rc = xpidlHdrWriteAttrAccessor(pNd, pFile, false); 430 if (RT_FAILURE(rc)) 431 return rc; 432 fputs(" = 0;\n", pFile); 433 } 434 fputc('\n', pFile); 435 436 return VINF_SUCCESS; 437 } 438 439 440 static int xpidlHdrWriteConst(PCXPIDLNODE pNd, FILE *pFile) 441 { 442 #if 0 /** @todo We only allow unsigned numbers for now. */ 443 if (!verify_const_declaration(pNd)) 444 return FALSE; 445 #endif 446 447 write_indent(pFile); 448 fprintf(pFile, "enum { %s = ", pNd->u.Const.pszName); 449 fprintf(pFile, "%lluU", pNd->u.Const.u64Const); 450 fprintf(pFile, " };\n\n"); 451 452 return VINF_SUCCESS; 453 } 454 455 456 static int xpidlHdrWriteInterface(PCXPIDLNODE pNd, FILE *pFile) 457 { 148 458 char *classNameUpper = NULL; 149 459 char *cp; 150 bool ok = TRUE;151 bool keepvtable;152 const char *iid;153 const char *name_space;154 460 struct nsID id; 155 461 char iid_parsed[UUID_LENGTH]; 156 GSList *doc_comments = IDL_IDENT(IDL_INTERFACE(iface).ident).comments; 157 158 if (!verify_interface_declaration(iface)) 159 return FALSE; 160 161 #define FAIL do {ok = FALSE; goto out;} while(0) 162 163 fprintf(state->file, "\n/* starting interface: %s */\n", 164 className); 165 166 name_space = IDL_tree_property_get(IDL_INTERFACE(iface).ident, "namespace"); 167 if (name_space) { 168 fprintf(state->file, "/* namespace: %s */\n", 169 name_space); 170 fprintf(state->file, "/* fully qualified name: %s.%s */\n", 171 name_space,className); 172 } 173 174 iid = IDL_tree_property_get(IDL_INTERFACE(iface).ident, "uuid"); 175 if (iid) { 462 int rc = VINF_SUCCESS; 463 464 if (!verify_interface_declaration(pNd)) 465 return VERR_INVALID_PARAMETER; 466 467 #define FAIL do {rc = VERR_INVALID_PARAMETER; goto out;} while(0) 468 469 fprintf(pFile, "\n/* starting interface: %s */\n", pNd->u.If.pszIfName); 470 471 AssertRelease(!xpidlNodeAttrFind(pNd, "namespace")); /* Not supported right now. */ 472 473 PCXPIDLATTR pAttrIid = xpidlNodeAttrFind(pNd, "uuid"); 474 if (pAttrIid) 475 { 476 AssertPtr(pAttrIid->pszVal); 477 176 478 /* Redundant, but a better error than 'cannot parse.' */ 177 if (strlen( iid) != 36) {178 IDL_tree_error(state->tree, "IID %s is the wrong length\n", iid);479 if (strlen(pAttrIid->pszVal) != 36) { 480 //IDL_tree_error(state->tree, "IID %s is the wrong length\n", iid); 179 481 FAIL; 180 482 } … … 184 486 * uuid and normalize resulting .h files. 185 487 */ 186 if (!xpidl_parse_iid(&id, iid)) {187 IDL_tree_error(state->tree, "cannot parse IID %s\n", iid);488 if (!xpidl_parse_iid(&id, pAttrIid->pszVal)) { 489 //IDL_tree_error(state->tree, "cannot parse IID %s\n", iid); 188 490 FAIL; 189 491 } 190 492 if (!xpidl_sprint_iid(&id, iid_parsed)) { 191 IDL_tree_error(state->tree, "error formatting IID %s\n", iid);493 //IDL_tree_error(state->tree, "error formatting IID %s\n", iid); 192 494 FAIL; 193 495 } 194 496 195 497 /* #define NS_ISUPPORTS_IID_STR "00000000-0000-0000-c000-000000000046" */ 196 fputs("#define ", state->file);197 write_classname_iid_define( state->file, className);198 fprintf( state->file, "_STR \"%s\"\n", iid_parsed);199 fputc('\n', state->file);498 fputs("#define ", pFile); 499 write_classname_iid_define(pFile, pNd->u.If.pszIfName); 500 fprintf(pFile, "_STR \"%s\"\n", iid_parsed); 501 fputc('\n', pFile); 200 502 201 503 /* #define NS_ISUPPORTS_IID { {0x00000000 .... 0x46 }} */ 202 fprintf( state->file, "#define ");203 write_classname_iid_define( state->file, className);204 fprintf( state->file, " \\\n"504 fprintf(pFile, "#define "); 505 write_classname_iid_define(pFile, pNd->u.If.pszIfName); 506 fprintf(pFile, " \\\n" 205 507 " {0x%.8x, 0x%.4x, 0x%.4x, \\\n" 206 508 " { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, " … … 209 511 id.m3[0], id.m3[1], id.m3[2], id.m3[3], 210 512 id.m3[4], id.m3[5], id.m3[6], id.m3[7]); 211 fputc('\n', state->file);513 fputc('\n', pFile); 212 514 } else { 213 IDL_tree_error(state->tree, "interface %s lacks a uuid attribute\n",214 className);515 //IDL_tree_error(state->tree, "interface %s lacks a uuid attribute\n", 516 // className); 215 517 FAIL; 216 518 } 217 218 if (doc_comments != NULL)219 printlist(state->file, doc_comments);220 519 221 520 /* … … 227 526 * the optimization. 228 527 */ 229 keepvtable = FALSE; 528 bool keepvtable = false; 529 #if 0 /* We don't allow code fragments in interface definitions. */ 230 530 for (iter = IDL_INTERFACE(state->tree).body; 231 531 iter != NULL; … … 236 536 keepvtable = TRUE; 237 537 } 538 #endif 539 540 /* The interface declaration itself. */ 541 fprintf(pFile, 542 "class %s%s", 543 (keepvtable ? "" : "NS_NO_VTABLE "), pNd->u.If.pszIfName); 238 544 239 /* The interface declaration itself. */ 240 fprintf(state->file, 241 "class %s%s", 242 (keepvtable ? "" : "NS_NO_VTABLE "), className); 243 244 if ((iter = IDL_INTERFACE(iface).inheritance_spec)) { 245 fputs(" : ", state->file); 246 if (IDL_LIST(iter).next != NULL) { 247 IDL_tree_error(iter, 248 "multiple inheritance is not supported by xpidl"); 249 FAIL; 250 } 251 fprintf(state->file, "public %s", IDL_IDENT(IDL_LIST(iter).data).str); 545 if (pNd->u.If.pszIfInherit) { 546 fputs(" : ", pFile); 547 fprintf(pFile, "public %s", pNd->u.If.pszIfInherit); 252 548 } 253 549 fputs(" {\n" 254 " public: \n\n", state->file); 255 256 fputs(" NS_DEFINE_STATIC_IID_ACCESSOR(", state->file); 257 write_classname_iid_define(state->file, className); 258 fputs(")\n\n", state->file); 259 260 orig = state->tree; /* It would be nice to remove this state-twiddling. */ 261 262 state->tree = IDL_INTERFACE(iface).body; 263 264 if (state->tree && !xpidl_process_node(state)) 265 FAIL; 266 267 fputs("};\n", state->file); 268 fputc('\n', state->file); 269 550 " public: \n\n", pFile); 551 552 fputs(" NS_DEFINE_STATIC_IID_ACCESSOR(", pFile); 553 write_classname_iid_define(pFile, pNd->u.If.pszIfName); 554 fputs(")\n\n", pFile); 555 556 PCXPIDLNODE pIt; 557 RTListForEach(&pNd->u.If.LstBody, pIt, XPIDLNODE, NdLst) 558 { 559 switch (pIt->enmType) 560 { 561 case kXpidlNdType_Const: 562 rc = xpidlHdrWriteConst(pIt, pFile); 563 if (RT_FAILURE(rc)) 564 return rc; 565 break; 566 case kXpidlNdType_Attribute: 567 rc = xpidlHdrWriteAttribute(pIt, pFile); 568 if (RT_FAILURE(rc)) 569 return rc; 570 break; 571 case kXpidlNdType_Method: 572 rc = xpidlHdrWriteMethod(pIt, pFile); 573 if (RT_FAILURE(rc)) 574 return rc; 575 break; 576 default: 577 FAIL; 578 } 579 } 580 581 fputs("};\n", pFile); 582 fputc('\n', pFile); 583 584 #if 0 270 585 /* 271 586 * #define NS_DECL_NSIFOO - create method prototypes that can be used in … … 479 794 } 480 795 } 481 fputc('\n', state->file); 796 #endif 797 fputc('\n', pFile); 482 798 483 799 #undef FAIL … … 486 802 if (classNameUpper) 487 803 free(classNameUpper); 488 return ok; 489 } 490 491 static bool 492 list(TreeState *state) 493 { 494 IDL_tree iter; 495 for (iter = state->tree; iter; iter = IDL_LIST(iter).next) { 496 state->tree = IDL_LIST(iter).data; 497 if (!xpidl_process_node(state)) 498 return FALSE; 499 } 500 return TRUE; 501 } 502 503 static bool 504 write_type(IDL_tree type_tree, bool is_out, FILE *outfile) 505 { 506 if (!type_tree) { 507 fputs("void", outfile); 508 return TRUE; 509 } 510 511 switch (IDL_NODE_TYPE(type_tree)) { 512 case IDLN_TYPE_INTEGER: { 513 bool sign = IDL_TYPE_INTEGER(type_tree).f_signed; 514 switch (IDL_TYPE_INTEGER(type_tree).f_type) { 515 case IDL_INTEGER_TYPE_SHORT: 516 fputs(sign ? "PRInt16" : "PRUint16", outfile); 517 break; 518 case IDL_INTEGER_TYPE_LONG: 519 fputs(sign ? "PRInt32" : "PRUint32", outfile); 520 break; 521 case IDL_INTEGER_TYPE_LONGLONG: 522 fputs(sign ? "PRInt64" : "PRUint64", outfile); 523 break; 524 default: 525 g_error("Unknown integer type %d\n", 526 IDL_TYPE_INTEGER(type_tree).f_type); 527 return FALSE; 528 } 529 break; 530 } 531 case IDLN_TYPE_CHAR: 532 fputs("char", outfile); 533 break; 534 case IDLN_TYPE_WIDE_CHAR: 535 fputs("PRUnichar", outfile); /* wchar_t? */ 536 break; 537 case IDLN_TYPE_WIDE_STRING: 538 fputs("PRUnichar *", outfile); 539 break; 540 case IDLN_TYPE_STRING: 541 fputs("char *", outfile); 542 break; 543 case IDLN_TYPE_BOOLEAN: 544 fputs("PRBool", outfile); 545 break; 546 case IDLN_TYPE_OCTET: 547 fputs("PRUint8", outfile); 548 break; 549 case IDLN_TYPE_FLOAT: 550 switch (IDL_TYPE_FLOAT(type_tree).f_type) { 551 case IDL_FLOAT_TYPE_FLOAT: 552 fputs("float", outfile); 553 break; 554 case IDL_FLOAT_TYPE_DOUBLE: 555 fputs("double", outfile); 556 break; 557 /* XXX 'long double' just ignored, or what? */ 558 default: 559 fprintf(outfile, "unknown_type_%d", IDL_NODE_TYPE(type_tree)); 560 break; 561 } 562 break; 563 case IDLN_IDENT: 564 if (UP_IS_NATIVE(type_tree)) { 565 if (IDL_tree_property_get(type_tree, "domstring") || 566 IDL_tree_property_get(type_tree, "astring")) { 567 fputs("nsAString", outfile); 568 } else if (IDL_tree_property_get(type_tree, "utf8string")) { 569 fputs("nsACString", outfile); 570 } else if (IDL_tree_property_get(type_tree, "cstring")) { 571 fputs("nsACString", outfile); 572 } else { 573 fputs(IDL_NATIVE(IDL_NODE_UP(type_tree)).user_type, outfile); 804 return rc; 805 } 806 807 808 DECL_HIDDEN_CALLBACK(int) xpidl_header_dispatch(FILE *pFile, PCXPIDLINPUT pInput, PCXPIDLPARSE pParse) 809 { 810 char *define = RTPathFilename(pInput->pszBasename); 811 fprintf(pFile, "/*\n * DO NOT EDIT. THIS FILE IS GENERATED FROM" 812 " %s.idl\n */\n", pInput->pszBasename); 813 fprintf(pFile, 814 "\n#ifndef __gen_%s_h__\n" 815 "#define __gen_%s_h__\n", 816 define, define); 817 818 if (!RTListIsEmpty(&pInput->LstIncludes)) 819 { 820 fputc('\n', pFile); 821 PCXPIDLINPUT pIt; 822 RTListForEach(&pInput->LstIncludes, pIt, XPIDLINPUT, NdInclude) 823 { 824 char *dot = strrchr(pIt->pszBasename, '.'); 825 if (dot != NULL) 826 *dot = '\0'; 827 828 829 /* begin include guard */ 830 fprintf(pFile, 831 "\n#ifndef __gen_%s_h__\n", 832 pIt->pszBasename); 833 834 fprintf(pFile, "#include \"%s.h\"\n", pIt->pszBasename); 835 836 fprintf(pFile, "#endif\n"); 837 } 838 839 fputc('\n', pFile); 840 } 841 /* 842 * Support IDL files that don't include a root IDL file that defines 843 * NS_NO_VTABLE. 844 */ 845 fprintf(pFile, 846 "/* For IDL files that don't want to include root IDL files. */\n" 847 "#ifndef NS_NO_VTABLE\n" 848 "#define NS_NO_VTABLE\n" 849 "#endif\n"); 850 851 PCXPIDLNODE pNd; 852 RTListForEach(&pParse->LstNodes, pNd, XPIDLNODE, NdLst) 853 { 854 /* Only output nodes from the first level input and not for any includes. */ 855 if (pNd->pInput != pInput) 856 continue; 857 858 int rc = VINF_SUCCESS; 859 switch (pNd->enmType) 860 { 861 case kXpidlNdType_RawBlock: 862 { 863 fprintf(pFile, "%.*s", (int)pNd->u.RawBlock.cchRaw, pNd->u.RawBlock.pszRaw); 864 break; 574 865 } 575 if (IDL_tree_property_get(type_tree, "ptr")) {576 fputs(" *", outfile);577 } else if (IDL_tree_property_get(type_tree, "ref")) {578 fputs(" &", outfile);866 case kXpidlNdType_Interface_Forward_Decl: 867 { 868 fprintf(pFile, "class %s; /* forward declaration */\n\n", pNd->u.pszIfFwdName); 869 break; 579 870 } 580 } else { 581 fputs(IDL_IDENT(type_tree).str, outfile); 582 } 583 if (UP_IS_AGGREGATE(type_tree)) 584 fputs(" *", outfile); 585 break; 586 default: 587 fprintf(outfile, "unknown_type_%d", IDL_NODE_TYPE(type_tree)); 588 break; 589 } 590 return TRUE; 591 } 592 593 /* 594 * An attribute declaration looks like: 595 * 596 * [ IDL_ATTR_DCL] 597 * - param_type_spec [IDL_TYPE_* or NULL for void] 598 * - simple_declarations [IDL_LIST] 599 * - data [IDL_IDENT] 600 * - next [IDL_LIST or NULL if no more idents] 601 * - data [IDL_IDENT] 602 */ 603 604 #define ATTR_IDENT(tree) (IDL_IDENT(IDL_LIST(IDL_ATTR_DCL(tree).simple_declarations).data)) 605 #define ATTR_TYPE_DECL(tree) (IDL_ATTR_DCL(tree).param_type_spec) 606 #define ATTR_TYPE(tree) (IDL_NODE_TYPE(ATTR_TYPE_DECL(tree))) 607 608 /* 609 * AS_DECL writes 'NS_IMETHOD foo(string bar, long sil)' 610 * AS_IMPL writes 'NS_IMETHODIMP className::foo(string bar, long sil)' 611 * AS_CALL writes 'foo(bar, sil)' 612 */ 613 static bool 614 write_attr_accessor(IDL_tree attr_tree, FILE * outfile, 615 bool getter, int mode, const char *className) 616 { 617 char *attrname = ATTR_IDENT(attr_tree).str; 618 619 if (mode == AS_DECL) { 620 fputs("NS_IMETHOD ", outfile); 621 } else if (mode == AS_IMPL) { 622 fprintf(outfile, "NS_IMETHODIMP %s::", className); 623 } 624 fprintf(outfile, "%cet%c%s(", 625 getter ? 'G' : 'S', 626 toupper(*attrname), attrname + 1); 627 if (mode == AS_DECL || mode == AS_IMPL) { 628 /* Setters for string, wstring, nsid, domstring, utf8string, 629 * cstring and astring get const. 630 */ 631 if (!getter && 632 (IDL_NODE_TYPE(ATTR_TYPE_DECL(attr_tree)) == IDLN_TYPE_STRING || 633 IDL_NODE_TYPE(ATTR_TYPE_DECL(attr_tree)) == IDLN_TYPE_WIDE_STRING || 634 IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "nsid") || 635 IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "domstring") || 636 IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "utf8string") || 637 IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "cstring") || 638 IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "astring"))) 639 { 640 fputs("const ", outfile); 641 } 642 643 if (!write_type(ATTR_TYPE_DECL(attr_tree), getter, outfile)) 644 return FALSE; 645 fprintf(outfile, "%s%s", 646 (STARRED_TYPE(attr_tree) ? "" : " "), 647 (getter && !DIPPER_TYPE(ATTR_TYPE_DECL(attr_tree)))? "*" : ""); 648 } 649 fprintf(outfile, "a%c%s)", toupper(attrname[0]), attrname + 1); 650 return TRUE; 651 } 652 653 static bool 654 attr_dcl(TreeState *state) 655 { 656 GSList *doc_comments; 657 658 if (!verify_attribute_declaration(state->tree)) 659 return FALSE; 660 661 doc_comments = 662 IDL_IDENT(IDL_LIST(IDL_ATTR_DCL 663 (state->tree).simple_declarations).data).comments; 664 665 if (doc_comments != NULL) { 666 write_indent(state->file); 667 printlist(state->file, doc_comments); 668 } 669 670 /* 671 * XXX lists of attributes with the same type, e.g. 672 * attribute string foo, bar sil; 673 * are legal IDL... but we don't do anything with 'em. 674 */ 675 if (IDL_LIST(IDL_ATTR_DCL(state->tree).simple_declarations).next != NULL) { 676 XPIDL_WARNING((state->tree, IDL_WARNING1, 677 "multiple attributes in a single declaration aren't " 678 "currently supported by xpidl")); 679 } 680 681 xpidl_write_comment(state, 2); 682 683 write_indent(state->file); 684 if (!write_attr_accessor(state->tree, state->file, TRUE, AS_DECL, NULL)) 685 return FALSE; 686 fputs(" = 0;\n", state->file); 687 688 if (!IDL_ATTR_DCL(state->tree).f_readonly) { 689 write_indent(state->file); 690 if (!write_attr_accessor(state->tree, state->file, FALSE, AS_DECL, NULL)) 691 return FALSE; 692 fputs(" = 0;\n", state->file); 693 } 694 fputc('\n', state->file); 695 696 return TRUE; 697 } 698 699 static bool 700 do_enum(TreeState *state) 701 { 702 IDL_tree_error(state->tree, "enums not supported, " 703 "see http://bugzilla.mozilla.org/show_bug.cgi?id=8781"); 704 return FALSE; 705 } 706 707 static bool 708 do_const_dcl(TreeState *state) 709 { 710 struct _IDL_CONST_DCL *dcl = &IDL_CONST_DCL(state->tree); 711 const char *name = IDL_IDENT(dcl->ident).str; 712 bool is_signed; 713 GSList *doc_comments = IDL_IDENT(dcl->ident).comments; 714 IDL_tree real_type; 715 const char *const_format; 716 717 if (!verify_const_declaration(state->tree)) 718 return FALSE; 719 720 if (doc_comments != NULL) { 721 write_indent(state->file); 722 printlist(state->file, doc_comments); 723 } 724 725 /* Could be a typedef; try to map it to the real type. */ 726 real_type = find_underlying_type(dcl->const_type); 727 real_type = real_type ? real_type : dcl->const_type; 728 is_signed = IDL_TYPE_INTEGER(real_type).f_signed; 729 730 const_format = is_signed ? "%" IDL_LL "d" : "%" IDL_LL "uU"; 731 write_indent(state->file); 732 fprintf(state->file, "enum { %s = ", name); 733 fprintf(state->file, const_format, IDL_INTEGER(dcl->const_exp).value); 734 fprintf(state->file, " };\n\n"); 735 736 return TRUE; 737 } 738 739 static bool 740 do_typedef(TreeState *state) 741 { 742 IDL_tree type = IDL_TYPE_DCL(state->tree).type_spec; 743 IDL_tree dcls = IDL_TYPE_DCL(state->tree).dcls; 744 IDL_tree complex; 745 GSList *doc_comments; 746 747 if (IDL_NODE_TYPE(type) == IDLN_TYPE_SEQUENCE) { 748 XPIDL_WARNING((state->tree, IDL_WARNING1, 749 "sequences not supported, ignored")); 750 } else { 751 if (IDL_NODE_TYPE(complex = IDL_LIST(dcls).data) == IDLN_TYPE_ARRAY) { 752 IDL_tree dim = IDL_TYPE_ARRAY(complex).size_list; 753 doc_comments = IDL_IDENT(IDL_TYPE_ARRAY(complex).ident).comments; 754 755 if (doc_comments != NULL) 756 printlist(state->file, doc_comments); 757 758 fputs("typedef ", state->file); 759 if (!write_type(type, FALSE, state->file)) 760 return FALSE; 761 fputs(" ", state->file); 762 763 fprintf(state->file, "%s", 764 IDL_IDENT(IDL_TYPE_ARRAY(complex).ident).str); 765 do { 766 fputc('[', state->file); 767 if (IDL_LIST(dim).data) { 768 fprintf(state->file, "%ld", 769 (long)IDL_INTEGER(IDL_LIST(dim).data).value); 770 } 771 fputc(']', state->file); 772 } while ((dim = IDL_LIST(dim).next) != NULL); 773 } else { 774 doc_comments = IDL_IDENT(IDL_LIST(dcls).data).comments; 775 776 if (doc_comments != NULL) 777 printlist(state->file, doc_comments); 778 779 fputs("typedef ", state->file); 780 if (!write_type(type, FALSE, state->file)) 781 return FALSE; 782 fputs(" ", state->file); 783 fputs(IDL_IDENT(IDL_LIST(dcls).data).str, state->file); 784 } 785 fputs(";\n\n", state->file); 786 } 787 return TRUE; 788 } 789 790 /* 791 * param generation: 792 * in string foo --> nsString *foo 793 * out string foo --> nsString **foo; 794 * inout string foo --> nsString **foo; 795 */ 796 797 /* If notype is true, just write the param name. */ 798 static bool 799 write_param(IDL_tree param_tree, FILE *outfile) 800 { 801 IDL_tree param_type_spec = IDL_PARAM_DCL(param_tree).param_type_spec; 802 bool is_in = IDL_PARAM_DCL(param_tree).attr == IDL_PARAM_IN; 803 /* in string, wstring, nsid, domstring, utf8string, cstring and 804 * astring any explicitly marked [const] are const 805 */ 806 807 if (is_in && 808 (IDL_NODE_TYPE(param_type_spec) == IDLN_TYPE_STRING || 809 IDL_NODE_TYPE(param_type_spec) == IDLN_TYPE_WIDE_STRING || 810 IDL_tree_property_get(IDL_PARAM_DCL(param_tree).simple_declarator, 811 "const") || 812 IDL_tree_property_get(param_type_spec, "nsid") || 813 IDL_tree_property_get(param_type_spec, "domstring") || 814 IDL_tree_property_get(param_type_spec, "utf8string") || 815 IDL_tree_property_get(param_type_spec, "cstring") || 816 IDL_tree_property_get(param_type_spec, "astring"))) { 817 fputs("const ", outfile); 818 } 819 else if (IDL_PARAM_DCL(param_tree).attr == IDL_PARAM_OUT && 820 IDL_tree_property_get(IDL_PARAM_DCL(param_tree).simple_declarator, 821 "shared")) { 822 fputs("const ", outfile); 823 } 824 825 if (!write_type(param_type_spec, !is_in, outfile)) 826 return FALSE; 827 828 /* unless the type ended in a *, add a space */ 829 if (!STARRED_TYPE(param_type_spec)) 830 fputc(' ', outfile); 831 832 /* out and inout params get a bonus '*' (unless this is type that has a 833 * 'dipper' class that is passed in to receive 'out' data) 834 */ 835 if (IDL_PARAM_DCL(param_tree).attr != IDL_PARAM_IN && 836 !DIPPER_TYPE(param_type_spec)) { 837 fputc('*', outfile); 838 } 839 /* arrays get a bonus * too */ 840 /* XXX Should this be a leading '*' or a trailing "[]" ?*/ 841 if (IDL_tree_property_get(IDL_PARAM_DCL(param_tree).simple_declarator, 842 "array")) 843 fputc('*', outfile); 844 845 fputs(IDL_IDENT(IDL_PARAM_DCL(param_tree).simple_declarator).str, outfile); 846 847 return TRUE; 848 } 849 850 /* 851 * A forward declaration, usually an interface. 852 */ 853 static bool 854 forward_dcl(TreeState *state) 855 { 856 IDL_tree iface = state->tree; 857 const char *className = IDL_IDENT(IDL_FORWARD_DCL(iface).ident).str; 858 859 if (!className) 860 return FALSE; 861 862 fprintf(state->file, "class %s; /* forward declaration */\n\n", className); 863 return TRUE; 864 } 865 866 /* 867 * Shared between the interface class declaration and the NS_DECL_IFOO macro 868 * provided to aid declaration of implementation classes. 869 * mode... 870 * AS_DECL writes 'NS_IMETHOD foo(string bar, long sil)' 871 * AS_IMPL writes 'NS_IMETHODIMP className::foo(string bar, long sil)' 872 * AS_CALL writes 'foo(bar, sil)' 873 */ 874 static bool 875 write_method_signature(IDL_tree method_tree, FILE *outfile, int mode, 876 const char *className) 877 { 878 struct _IDL_OP_DCL *op = &IDL_OP_DCL(method_tree); 879 bool no_generated_args = TRUE; 880 bool op_notxpcom = 881 (IDL_tree_property_get(op->ident, "notxpcom") != NULL); 882 const char *name; 883 IDL_tree iter; 884 885 if (mode == AS_DECL) { 886 if (op_notxpcom) { 887 fputs("NS_IMETHOD_(", outfile); 888 if (!write_type(op->op_type_spec, FALSE, outfile)) 889 return FALSE; 890 fputc(')', outfile); 891 } else { 892 fputs("NS_IMETHOD", outfile); 893 } 894 fputc(' ', outfile); 895 } 896 else if (mode == AS_IMPL) { 897 if (op_notxpcom) { 898 fputs("NS_IMETHODIMP_(", outfile); 899 if (!write_type(op->op_type_spec, FALSE, outfile)) 900 return FALSE; 901 fputc(')', outfile); 902 } else { 903 fputs("NS_IMETHODIMP", outfile); 904 } 905 fputc(' ', outfile); 906 } 907 name = IDL_IDENT(op->ident).str; 908 if (mode == AS_IMPL) { 909 fprintf(outfile, "%s::%c%s(", className, toupper(*name), name + 1); 910 } else { 911 fprintf(outfile, "%c%s(", toupper(*name), name + 1); 912 } 913 for (iter = op->parameter_dcls; iter; iter = IDL_LIST(iter).next) { 914 if (mode == AS_DECL || mode == AS_IMPL) { 915 if (!write_param(IDL_LIST(iter).data, outfile)) 916 return FALSE; 917 } else { 918 fputs(IDL_IDENT(IDL_PARAM_DCL(IDL_LIST(iter).data) 919 .simple_declarator).str, 920 outfile); 921 } 922 if ((IDL_LIST(iter).next || 923 (!op_notxpcom && op->op_type_spec) || op->f_varargs)) 924 fputs(", ", outfile); 925 no_generated_args = FALSE; 926 } 927 928 /* make IDL return value into trailing out argument */ 929 if (op->op_type_spec && !op_notxpcom) { 930 IDL_tree fake_param = IDL_param_dcl_new(IDL_PARAM_OUT, 931 op->op_type_spec, 932 IDL_ident_new("_retval")); 933 if (!fake_param) 934 return FALSE; 935 if (mode == AS_DECL || mode == AS_IMPL) { 936 if (!write_param(fake_param, outfile)) 937 return FALSE; 938 } else { 939 fputs("_retval", outfile); 940 } 941 if (op->f_varargs) 942 fputs(", ", outfile); 943 no_generated_args = FALSE; 944 } 945 946 /* varargs go last */ 947 if (op->f_varargs) { 948 if (mode == AS_DECL || mode == AS_IMPL) { 949 fputs("nsVarArgs *", outfile); 950 } 951 fputs("_varargs", outfile); 952 no_generated_args = FALSE; 953 } 954 955 /* 956 * If generated method has no arguments, output 'void' to avoid C legacy 957 * behavior of disabling type checking. 958 */ 959 if (no_generated_args && mode == AS_DECL) { 960 fputs("void", outfile); 961 } 962 963 fputc(')', outfile); 964 965 return TRUE; 966 } 967 968 /* 969 * A method is an `operation', therefore a method decl is an `op dcl'. 970 * I blame Elliot. 971 */ 972 static bool 973 op_dcl(TreeState *state) 974 { 975 GSList *doc_comments = IDL_IDENT(IDL_OP_DCL(state->tree).ident).comments; 976 977 /* 978 * Verify that e.g. non-scriptable methods in [scriptable] interfaces 979 * are declared so. Do this in a separate verification pass? 980 */ 981 if (!verify_method_declaration(state->tree)) 982 return FALSE; 983 984 if (doc_comments != NULL) { 985 write_indent(state->file); 986 printlist(state->file, doc_comments); 987 } 988 xpidl_write_comment(state, 2); 989 990 write_indent(state->file); 991 if (!write_method_signature(state->tree, state->file, AS_DECL, NULL)) 992 return FALSE; 993 fputs(" = 0;\n\n", state->file); 994 995 return TRUE; 996 } 997 998 static void 999 write_codefrag_line(gpointer data, gpointer user_data) 1000 { 1001 TreeState *state = (TreeState *)user_data; 1002 const char *line = (const char *)data; 1003 fputs(line, state->file); 1004 fputc('\n', state->file); 1005 } 1006 1007 static bool 1008 codefrag(TreeState *state) 1009 { 1010 const char *desc = IDL_CODEFRAG(state->tree).desc; 1011 GSList *lines = IDL_CODEFRAG(state->tree).lines; 1012 1013 if (strcmp(desc, "C++") && /* libIDL bug? */ strcmp(desc, "C++\r")) { 1014 XPIDL_WARNING((state->tree, IDL_WARNING1, 1015 "ignoring '%%{%s' escape. " 1016 "(Use '%%{C++' to escape verbatim C++ code.)", desc)); 1017 1018 return TRUE; 1019 } 1020 1021 /* 1022 * Emit #file directive to point debuggers back to the original .idl file 1023 * for the duration of the code fragment. We look at internal IDL node 1024 * properties _file, _line to do this; hopefully they won't change. 1025 * 1026 * _line seems to refer to the line immediately after the closing %}, so 1027 * we backtrack to get the proper line for the beginning of the block. 1028 */ 1029 g_slist_foreach(lines, write_codefrag_line, (gpointer)state); 1030 1031 return TRUE; 1032 } 1033 #endif 1034 1035 backend * 1036 xpidl_header_dispatch(void) 1037 { 1038 static backend result; 1039 static nodeHandler table[10 /*IDLN_LAST*/]; 1040 static bool initialized = false; 1041 1042 result.emit_prolog = NULL; //header_prolog; 1043 result.emit_epilog = NULL; //header_epilog; 1044 1045 #if 0 1046 if (!initialized) { 1047 table[IDLN_LIST] = NULL; //list; 1048 table[IDLN_ATTR_DCL] = NULL; //attr_dcl; 1049 table[IDLN_OP_DCL] = NULL; //op_dcl; 1050 table[IDLN_FORWARD_DCL] = NULL; //forward_dcl; 1051 table[IDLN_TYPE_ENUM] = NULL; //do_enum; 1052 table[IDLN_INTERFACE] = NULL; //interface; 1053 table[IDLN_CODEFRAG] = NULL; //codefrag; 1054 table[IDLN_TYPE_DCL] = NULL; //do_typedef; 1055 table[IDLN_CONST_DCL] = NULL; //do_const_dcl; 1056 table[IDLN_NATIVE] = NULL; //check_native; 1057 initialized = true; 1058 } 1059 #endif 1060 1061 result.dispatch_table = table; 1062 return &result; 1063 } 871 case kXpidlNdType_Interface_Def: 872 { 873 rc = xpidlHdrWriteInterface(pNd, pFile); 874 break; 875 } 876 case kXpidlNdType_Typedef: 877 { 878 fprintf(pFile, "typedef "); 879 rc = xpidlHdrWriteType(pNd->u.Typedef.pNodeTypeSpec, pFile); 880 if (RT_SUCCESS(rc)) 881 fprintf(pFile, " %s;\n\n", pNd->u.Typedef.pszName); 882 break; 883 } 884 default: /* Ignore */ 885 break; 886 } 887 if (RT_FAILURE(rc)) 888 return rc; 889 } 890 891 fprintf(pFile, "\n#endif /* __gen_%s_h__ */\n", define); 892 return VINF_SUCCESS; 893 } -
trunk/src/libs/xpcom18a4/xpcom/typelib/xpidl-new/xpidl_idl.c
r108304 r108305 41 41 kXpidlKeyword_Include, 42 42 kXpidlKeyword_Typedef, 43 kXpidlKeyword_Void, 43 44 kXpidlKeyword_Char, 44 45 kXpidlKeyword_Wide_Char, … … 59 60 kXpidlKeyword_Out, 60 61 kXpidlKeyword_InOut, 62 kXpidlKeyword_Const, 61 63 kXpidlKeyword_32Bit_Hack = 0x7fffffff 62 64 } XPIDLKEYWORD; … … 94 96 { RT_STR_TUPLE("#include"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kXpidlKeyword_Include }, 95 97 98 { RT_STR_TUPLE("void"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kXpidlKeyword_Void }, 96 99 { RT_STR_TUPLE("char"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kXpidlKeyword_Char }, 97 100 { RT_STR_TUPLE("long"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kXpidlKeyword_Long }, … … 114 117 { RT_STR_TUPLE("inout"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kXpidlKeyword_InOut }, 115 118 { RT_STR_TUPLE("out"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kXpidlKeyword_Out }, 116 117 { RT_STR_TUPLE("const"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, 0 }, 119 { RT_STR_TUPLE("const"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kXpidlKeyword_Const }, 118 120 119 121 { RT_STR_TUPLE(","), RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, ',' }, … … 244 246 245 247 248 static int xpidlParseSkipComments(PXPIDLPARSE pThis, PXPIDLINPUT pInput) 249 { 250 for (;;) 251 { 252 PCRTSCRIPTLEXTOKEN pTok; 253 int rc = RTScriptLexQueryToken(pInput->hIdlLex, &pTok); 254 if (RT_FAILURE(rc)) 255 return xpidlParseError(pThis, pInput, pTok, rc, "Lexer: Failed to query string literal token with %Rrc", rc); 256 257 if ( pTok->enmType != RTSCRIPTLEXTOKTYPE_COMMENT_SINGLE_LINE 258 && pTok->enmType != RTSCRIPTLEXTOKTYPE_COMMENT_MULTI_LINE) 259 return VINF_SUCCESS; 260 261 /* Make sure we don't miss any %{C++ %} blocks. */ 262 if (!strncmp(pTok->Type.Comment.pszComment, RT_STR_TUPLE("%{C++"))) 263 return xpidlParseError(pThis, pInput, pTok, VERR_INVALID_PARAMETER, "Parser: Encountered unexpected raw code block comment"); 264 265 RTScriptLexConsumeToken(pInput->hIdlLex); 266 } 267 268 return VINF_SUCCESS; 269 } 270 271 246 272 static int xpidlLexerConsumeIfStringLit(PXPIDLPARSE pThis, PXPIDLINPUT pInput, const char **ppszStrLit) 247 273 { … … 372 398 373 399 400 static int xpidlLexerConsumeIfNatural(PXPIDLPARSE pThis, PXPIDLINPUT pInput, uint64_t *pu64, bool *pfConsumed) 401 { 402 PCRTSCRIPTLEXTOKEN pTok; 403 int rc = RTScriptLexQueryToken(pInput->hIdlLex, &pTok); 404 if (RT_FAILURE(rc)) 405 return xpidlParseError(pThis, pInput, NULL, rc, "Lexer: Failed to query punctuator token with %Rrc", rc); 406 407 if ( pTok->enmType == RTSCRIPTLEXTOKTYPE_NUMBER 408 && pTok->Type.Number.enmType == RTSCRIPTLEXTOKNUMTYPE_NATURAL) 409 { 410 *pfConsumed = true; 411 *pu64 = pTok->Type.Number.Type.u64; 412 RTScriptLexConsumeToken(pInput->hIdlLex); 413 return VINF_SUCCESS; 414 } 415 416 *pfConsumed = false; 417 return VINF_SUCCESS; 418 } 419 420 /* Some parser helper macros. */ 374 421 #define XPIDL_PARSE_STRING_LIT(a_pszStrLit) \ 375 422 const char *a_pszStrLit = NULL; \ … … 383 430 384 431 385 /* Some parser helper macros. */ 432 #define XPIDL_PARSE_KEYWORD(a_enmKeyword, a_pszKeyword) \ 433 do { \ 434 bool fConsumed2 = false; \ 435 int rc2 = xpidlLexerConsumeIfKeyword(pThis, pInput, a_enmKeyword, &fConsumed2); \ 436 if (RT_FAILURE(rc2)) \ 437 return rc2; \ 438 if (!fConsumed2) \ 439 return xpidlParseError(pThis, pInput, NULL, VERR_INVALID_PARAMETER, "Parser: Expected keyword '%s'", a_pszKeyword); \ 440 } while(0) 441 442 386 443 #define XPIDL_PARSE_OPTIONAL_KEYWORD(a_fConsumed, a_enmKeyword) \ 387 444 bool a_fConsumed = false; \ … … 466 523 467 524 525 #define XPIDL_PARSE_NATURAL(a_u64) \ 526 uint64_t a_u64 = 0; \ 527 do { \ 528 bool fConsumed2 = false; \ 529 int rc2 = xpidlLexerConsumeIfNatural(pThis, pInput, &a_u64, &fConsumed2); \ 530 if (RT_FAILURE(rc2)) \ 531 return rc2; \ 532 if (!fConsumed2) \ 533 return xpidlParseError(pThis, pInput, NULL, VERR_INVALID_PARAMETER, "Parser: Expected a natural number"); \ 534 } while(0) 535 536 468 537 static PXPIDLINPUT xpidlInputCreate(const char *pszFilename, PRTLISTANCHOR pLstIncludePaths) 469 538 { … … 483 552 pInput->hIdlLex = hIdlLex; 484 553 pInput->pszFilename = xpidl_strdup(pszFilename); 554 pInput->pszBasename = RTPathFilename(pInput->pszFilename); 485 555 return pInput; 486 556 } … … 496 566 pNode->pInput = pInput; 497 567 pNode->enmType = enmType; 568 pNode->cAttrs = cAttrs; 498 569 switch (enmType) 499 570 { … … 555 626 break; 556 627 } 628 *pcAttrs = cAttrs; 557 629 g_fParsingAttributes = false; 558 630 … … 567 639 static const XPIDLKEYWORD g_aenmTypeKeywordsStart[] = 568 640 { 641 kXpidlKeyword_Void, 569 642 kXpidlKeyword_Char, 570 643 kXpidlKeyword_Wide_Char, … … 590 663 switch (enmType) 591 664 { 665 case kXpidlKeyword_Void: 666 enmBaseType = kXpidlType_Void; 667 break; 592 668 case kXpidlKeyword_Char: 593 669 enmBaseType = kXpidlType_Char; … … 694 770 695 771 772 static int xpidlParseConst(PXPIDLPARSE pThis, PXPIDLINPUT pInput, PXPIDLNODE pNdIf) 773 { 774 int rc; 775 PXPIDLNODE pNdConst = xpidlNodeCreate(pThis, pNdIf, pInput, kXpidlNdType_Const); 776 if (pNdConst) 777 { 778 RTListAppend(&pNdIf->u.If.LstBody, &pNdConst->NdLst); 779 780 PXPIDLNODE pNdTypeSpec = NULL; 781 int rc = xpidlParseTypeSpec(pThis, pInput, &pNdTypeSpec); 782 if (RT_FAILURE(rc)) 783 return rc; 784 pNdConst->u.Const.pNdTypeSpec = pNdTypeSpec; 785 786 XPIDL_PARSE_IDENTIFIER(pszName); /* The parameter name is always required. */ 787 pNdConst->u.Const.pszName = pszName; 788 789 XPIDL_PARSE_PUNCTUATOR('='); 790 XPIDL_PARSE_NATURAL(u64); 791 pNdConst->u.Const.u64Const = u64; 792 } 793 else 794 rc = VERR_NO_MEMORY; 795 796 return rc; 797 } 798 799 800 static int xpidlParseAttribute(PXPIDLPARSE pThis, PXPIDLINPUT pInput, PXPIDLNODE pNdIf, bool fReadonly) 801 { 802 int rc; 803 PXPIDLNODE pNdConst = xpidlNodeCreate(pThis, pNdIf, pInput, kXpidlNdType_Attribute); 804 if (pNdConst) 805 { 806 RTListAppend(&pNdIf->u.If.LstBody, &pNdConst->NdLst); 807 808 PXPIDLNODE pNdTypeSpec = NULL; 809 int rc = xpidlParseTypeSpec(pThis, pInput, &pNdTypeSpec); 810 if (RT_FAILURE(rc)) 811 return rc; 812 pNdConst->u.Attribute.pNdTypeSpec = pNdTypeSpec; 813 814 XPIDL_PARSE_IDENTIFIER(pszName); /* The parameter name is always required. */ 815 pNdConst->u.Attribute.pszName = pszName; 816 pNdConst->u.Attribute.fReadonly = fReadonly; 817 } 818 else 819 rc = VERR_NO_MEMORY; 820 821 return rc; 822 } 823 824 696 825 static int xpidlParseMethodParameters(PXPIDLPARSE pThis, PXPIDLINPUT pInput, PXPIDLNODE pNdMethod) 697 826 { … … 768 897 for (;;) 769 898 { 899 int rc = xpidlParseSkipComments(pThis, pInput); 900 if (RT_FAILURE(rc)) 901 return rc; 902 770 903 /* A closing '}' means we reached the end of the interface body. */ 771 904 bool fConsumed = false; … … 778 911 * readonly attribute <type spec> <name>; 779 912 * attribute <type spec> <name>; 913 * const <type spec> <name> = <value>; 780 914 * <type spec> <name> (...); 781 915 */ 782 static const XPIDLKEYWORD g_aenm AttributesKeywords[] =916 static const XPIDLKEYWORD g_aenmBodyKeywords[] = 783 917 { 784 918 kXpidlKeyword_Readonly, 785 919 kXpidlKeyword_Attribute, 920 kXpidlKeyword_Const, 786 921 kXpidlKeyword_Invalid 787 922 }; 788 923 789 XPIDL_PARSE_OPTIONAL_KEYWORD_LIST(enmAttr, g_aenmAttributesKeywords, kXpidlKeyword_Invalid); 790 if (enmAttr != kXpidlKeyword_Invalid) 791 { 792 AssertFailed(); 924 XPIDL_PARSE_OPTIONAL_KEYWORD_LIST(enmStart, g_aenmBodyKeywords, kXpidlKeyword_Invalid); 925 if (enmStart != kXpidlKeyword_Invalid) 926 { 927 if (enmStart == kXpidlKeyword_Const) 928 rc = xpidlParseConst(pThis, pInput, pNdIf); 929 else if (enmStart == kXpidlKeyword_Readonly) 930 { 931 XPIDL_PARSE_KEYWORD(kXpidlKeyword_Attribute, "attribute"); 932 rc = xpidlParseAttribute(pThis, pInput, pNdIf, true /*fReadonly*/); 933 } 934 else 935 { 936 Assert(enmStart == kXpidlKeyword_Attribute); 937 rc = xpidlParseAttribute(pThis, pInput, pNdIf, false /*fReadonly*/); 938 } 793 939 } 794 940 else 795 941 { 796 942 /* We need to parse a type spec. */ 797 int rc = VINF_SUCCESS;798 943 PXPIDLNODE pNdRetType = NULL; 799 944 XPIDLATTR aAttrs[32]; … … 836 981 return VERR_NO_MEMORY; 837 982 } 983 if (RT_FAILURE(rc)) 984 return rc; 838 985 839 986 XPIDL_PARSE_PUNCTUATOR(';'); … … 860 1007 { 861 1008 const char *pszIfInherit = NULL; 862 863 1009 XPIDL_PARSE_OPTIONAL_PUNCTUATOR(fConsumed, ':'); 864 1010 if (fConsumed) … … 866 1012 XPIDL_PARSE_PUNCTUATOR('{'); 867 1013 /* Now for the fun part, parsing the body of the interface. */ 868 PXPIDLNODE pNode = xpidlNodeCreate(pThis, pParent, pInput, kXpidlNdType_Interface_Def); 1014 PXPIDLNODE pNode = xpidlNodeCreateWithAttrs(pThis, pParent, pInput, kXpidlNdType_Interface_Def, 1015 &pThis->aAttrs[0], pThis->cAttrs); 869 1016 if (pNode) 870 1017 { 1018 pThis->cAttrs = 0; 1019 871 1020 pNode->u.If.pszIfName = pszName; 872 1021 pNode->u.If.pszIfInherit = pszIfInherit; … … 906 1055 { 907 1056 XPIDL_PARSE_STRING_LIT(pszFilename); 908 PXPIDLINPUT pInput = xpidlInputCreate(pszFilename, pLstIncludePaths);909 if (!pInput )1057 PXPIDLINPUT pInputNew = xpidlInputCreate(pszFilename, pLstIncludePaths); 1058 if (!pInputNew) 910 1059 return xpidlParseError(pThis, pInput, NULL, VERR_INVALID_PARAMETER, "Failed opening include file '%s'", 911 1060 pszFilename); 912 1061 913 RTListAppend(&pThis->LstInputs, &pInput->NdInput); 914 rc = xpidlParseIdl(pThis, pInput, pLstIncludePaths); 1062 RTListAppend(&pInput->LstIncludes, &pInputNew->NdInclude); 1063 RTListAppend(&pThis->LstInputs, &pInputNew->NdInput); 1064 rc = xpidlParseIdl(pThis, pInputNew, pLstIncludePaths); 915 1065 break; 916 1066 } … … 1070 1220 if (RT_SUCCESS(rc)) 1071 1221 { 1072 /** @todo Output. */ 1222 char *tmp, *outname, *real_outname = NULL; 1223 1224 pInput->pszBasename = xpidl_strdup(filename); 1225 1226 /* if basename has an .extension, truncate it. */ 1227 tmp = strrchr(pInput->pszBasename, '.'); 1228 if (tmp) 1229 *tmp = '\0'; 1230 1231 if (!file_basename) 1232 outname = xpidl_strdup(pInput->pszBasename); 1233 else 1234 outname = xpidl_strdup(file_basename); 1235 1236 FILE *pFile = NULL; 1237 if (strcmp(outname, "-")) 1238 { 1239 const char *fopen_mode; 1240 char *out_basename; 1241 1242 /* explicit_output_filename can't be true without a filename */ 1243 if (explicit_output_filename) { 1244 real_outname = xpidl_strdup(outname); 1245 } else { 1246 1247 if (!file_basename) { 1248 out_basename = RTPathFilename(outname); 1249 } else { 1250 out_basename = outname; 1251 } 1252 1253 rc = RTStrAPrintf(&real_outname, "%s.%s", out_basename, mode->suffix); 1254 if (RT_FAILURE(rc)) 1255 return rc; 1256 1257 if (out_basename != outname) 1258 free(out_basename); 1259 } 1260 1261 /* Use binary write for typelib mode */ 1262 fopen_mode = (strcmp(mode->mode, "typelib")) ? "w" : "wb"; 1263 pFile = fopen(real_outname, fopen_mode); 1264 if (!pFile) { 1265 perror("error opening output file"); 1266 free(outname); 1267 return VERR_INVALID_PARAMETER; 1268 } 1269 } 1270 else 1271 pFile = stdout; 1272 1273 rc = mode->dispatch(pFile, pInput, &ParseState); 1274 1275 if (pFile != stdout) 1276 fclose(pFile); 1277 free(outname); 1073 1278 } 1074 1279 else -
trunk/src/libs/xpcom18a4/xpcom/typelib/xpidl-new/xpidl_util.c
r108284 r108305 772 772 return FALSE; 773 773 } 774 775 /* 776 * Print a GSList as char strings to a file. 777 */ 778 void 779 printlist(FILE *outfile, GSList *slist) 780 { 781 guint i; 782 guint len = g_slist_length(slist); 783 784 for(i = 0; i < len; i++) { 785 fprintf(outfile, 786 "%s\n", (char *)g_slist_nth_data(slist, i)); 787 } 788 } 789 790 void 791 xpidl_list_foreach(IDL_tree p, IDL_tree_func foreach, gpointer user_data) 792 { 793 IDL_tree_func_data tfd; 794 795 while (p) { 796 struct _IDL_LIST *list = &IDL_LIST(p); 797 tfd.tree = list->data; 798 if (!foreach(&tfd, user_data)) 799 return; 800 p = list->next; 801 } 802 } 774 #endif 803 775 804 776 /* 805 777 * Verify that the interface declaration is correct 806 778 */ 807 gboolean 808 verify_interface_declaration(IDL_tree interface_tree) 809 { 810 IDL_tree iter; 779 DECLHIDDEN(bool) verify_interface_declaration(PCXPIDLNODE pNd) 780 { 811 781 /* 812 782 * If we have the scriptable attribute then make sure all of our direct … … 814 784 * NOTE: We don't recurse since all interfaces will fall through here 815 785 */ 816 if (IDL_tree_property_get(IDL_INTERFACE(interface_tree).ident, 817 "scriptable")) { 786 if (xpidlNodeAttrFind(pNd, "scriptable")) 787 { 788 #if 0 818 789 for (iter = IDL_INTERFACE(interface_tree).inheritance_spec; iter; 819 790 iter = IDL_LIST(iter).next) { … … 826 797 } 827 798 } 828 }829 return TRUE;830 }831 832 /*833 * Return a pointer to the start of the base filename of path834 */835 char *836 xpidl_basename(const char * path)837 {838 char * result = g_path_get_basename(path);839 /*840 *If this is windows then we'll handle either / or \ as a separator841 * g_basename only handles \ for windows842 */843 #if defined(XP_WIN32)844 # error adapt regarding g_basename() vs. g_path_get_basename()!845 const char * slash = strrchr(path, '/');846 /* If we found a slash and its after the current default OS separator */847 if (slash != NULL && (slash > result))848 result = slash + 1;849 799 #endif 850 return result; 851 } 852 #endif 800 } 801 return true; 802 } 803 804 805 DECLHIDDEN(PCXPIDLATTR) xpidlNodeAttrFind(PCXPIDLNODE pNd, const char *pszAttr) 806 { 807 for (uint32_t i = 0; i < pNd->cAttrs; i++) 808 { 809 if (!strcmp(pNd->aAttrs[i].pszName, pszAttr)) 810 return &pNd->aAttrs[i]; 811 } 812 813 return NULL; 814 }
Note:
See TracChangeset
for help on using the changeset viewer.