Back to index

lightning-sunbird  0.9+nobinonly
xpt_dump.c
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /*
00039  * A utility for dumping the contents of a typelib file (.xpt) to screen 
00040  */ 
00041 
00042 #include "xpt_xdr.h"
00043 #include <stdio.h>
00044 #ifdef XP_MAC
00045 #include <stat.h>
00046 #include <StandardFile.h>
00047 #include "FullPath.h"
00048 #else
00049 #ifdef XP_OS2_EMX
00050 #include <sys/types.h>
00051 #endif
00052 #include <sys/stat.h>
00053 #endif
00054 #include <stdlib.h>
00055 #include <string.h>
00056 #include "prprf.h"
00057 
00058 #define BASE_INDENT 3
00059 
00060 static char *type_array[32] = 
00061             {"int8",        "int16",       "int32",       "int64",
00062              "uint8",       "uint16",      "uint32",      "uint64",
00063              "float",       "double",      "boolean",     "char",
00064              "wchar_t",     "void",        "reserved",    "reserved",
00065              "reserved",    "reserved",    "reserved",    "reserved",
00066              "reserved",    "reserved",    "reserved",    "reserved",
00067              "reserved",    "reserved",    "reserved",    "reserved",
00068              "reserved",    "reserved",    "reserved",    "reserved"};
00069 
00070 static char *ptype_array[32] = 
00071             {"int8 *",      "int16 *",     "int32 *",     "int64 *",
00072              "uint8 *",     "uint16 *",    "uint32 *",    "uint64 *",
00073              "float *",     "double *",    "boolean *",   "char *",
00074              "wchar_t *",   "void *",      "nsIID *",     "DOMString *",
00075              "string",      "wstring",     "Interface *", "InterfaceIs *",
00076              "array",       "string_s",    "wstring_s",   "UTF8String *",
00077              "CString *",   "AString *",    "reserved",    "reserved",
00078              "reserved",    "reserved",    "reserved",    "reserved"};
00079 
00080 static char *rtype_array[32] = 
00081             {"int8 &",      "int16 &",     "int32 &",     "int64 &",
00082              "uint8 &",     "uint16 &",    "uint32 &",    "uint64 &",
00083              "float &",     "double &",    "boolean &",   "char &",
00084              "wchar_t &",   "void &",      "nsIID &",     "DOMString &",
00085              "string &",    "wstring &",   "Interface &", "InterfaceIs &",
00086              "array &",     "string_s &",  "wstring_s &", "UTF8String &",
00087              "CString &",   "AString &",    "reserved",    "reserved",
00088              "reserved",    "reserved",    "reserved",    "reserved"};
00089 
00090 PRBool param_problems = PR_FALSE;
00091 
00092 PRBool
00093 XPT_DumpHeader(XPTCursor *cursor, XPTHeader *header, 
00094                const int indent, PRBool verbose_mode);
00095 
00096 PRBool
00097 XPT_DumpAnnotations(XPTAnnotation *ann, const int indent, PRBool verbose_mode);
00098 
00099 PRBool
00100 XPT_DumpInterfaceDirectoryEntry(XPTCursor *cursor,
00101                                 XPTInterfaceDirectoryEntry *ide, 
00102                                 XPTHeader *header, const int indent,
00103                                 PRBool verbose_mode);
00104 
00105 PRBool
00106 XPT_DumpInterfaceDescriptor(XPTCursor *cursor, XPTInterfaceDescriptor *id, 
00107                             XPTHeader *header, const int indent,
00108                             PRBool verbose_mode);
00109 
00110 PRBool
00111 XPT_DumpMethodDescriptor(XPTHeader *header, XPTMethodDescriptor *md,
00112                          XPTInterfaceDescriptor *id,
00113                          const int indent, PRBool verbose_mode);
00114 PRBool
00115 XPT_GetStringForType(XPTHeader *header, XPTTypeDescriptor *td,
00116                      XPTInterfaceDescriptor *id,
00117                      char **type_string);
00118 
00119 PRBool
00120 XPT_DumpXPTString(XPTString *str);
00121 
00122 PRBool
00123 XPT_DumpParamDescriptor(XPTHeader *header, XPTParamDescriptor *pd,
00124                         XPTInterfaceDescriptor *id,
00125                         const int indent, PRBool verbose_mode,
00126                         PRBool is_result);
00127 
00128 PRBool
00129 XPT_DumpTypeDescriptor(XPTTypeDescriptor *td, 
00130                        XPTInterfaceDescriptor *id,
00131                        int indent, PRBool verbose_mode);
00132 
00133 PRBool
00134 XPT_DumpConstDescriptor(XPTHeader *header, XPTConstDescriptor *cd,
00135                         XPTInterfaceDescriptor *id,
00136                         const int indent, PRBool verbose_mode);
00137 
00138 static void
00139 xpt_dump_usage(char *argv[]) {
00140     fprintf(stdout, "Usage: %s [-v] <filename.xpt>\n"
00141             "       -v verbose mode\n", argv[0]);
00142 }
00143 
00144 #if defined(XP_MAC) && defined(XPIDL_PLUGIN)
00145 
00146 #define main xptdump_main
00147 int xptdump_main(int argc, char *argv[]);
00148 
00149 #define get_file_length mac_get_file_length
00150 extern size_t mac_get_file_length(const char* filename);
00151 
00152 #else /* !(XP_MAC && XPIDL_PLUGIN) */
00153 
00154 static size_t get_file_length(const char* filename)
00155 {
00156     struct stat file_stat;
00157     if (stat(filename, &file_stat) != 0) {
00158         perror("FAILED: get_file_length");
00159         exit(1);
00160     }
00161     return file_stat.st_size;
00162 }
00163 
00164 #endif /* !(XP_MAC && XPIDL_PLUGIN) */
00165 
00166 int 
00167 main(int argc, char **argv)
00168 {
00169     PRBool verbose_mode = PR_FALSE;
00170     XPTArena *arena;
00171     XPTState *state;
00172     XPTCursor curs, *cursor = &curs;
00173     XPTHeader *header;
00174     size_t flen;
00175     char *name;
00176     char *whole;
00177     FILE *in;
00178     int result = 1;
00179 
00180     switch (argc) {
00181     case 2:
00182         if (argv[1][0] == '-') {
00183             xpt_dump_usage(argv);
00184             return 1;
00185         }
00186         name = argv[1];
00187         flen = get_file_length(name);
00188         in = fopen(name, "rb");
00189         break;
00190     case 3:
00191         verbose_mode = PR_TRUE;
00192         if (argv[1][0] != '-' || argv[1][1] != 'v') {
00193             xpt_dump_usage(argv);
00194             return 1;
00195         }
00196         name = argv[2];
00197         flen = get_file_length(name);
00198         in = fopen(name, "rb");
00199         break;
00200     default:
00201         xpt_dump_usage(argv);
00202         return 1;
00203     }
00204 
00205     if (!in) {
00206         perror("FAILED: fopen");
00207         return 1;
00208     }
00209 
00210     arena = XPT_NewArena(1024, sizeof(double), "main xpt_dump arena");
00211     if (!arena) {
00212         perror("XPT_NewArena failed");
00213         return 1;
00214     }
00215 
00216     /* after arena creation all exits via 'goto out' */
00217 
00218     whole = XPT_MALLOC(arena, flen);
00219     if (!whole) {
00220         perror("FAILED: XPT_MALLOC for whole");
00221         goto out;
00222     }
00223 
00224     if (flen > 0) {
00225         size_t rv = fread(whole, 1, flen, in);
00226         if (rv < flen) {
00227             fprintf(stderr, "short read (%d vs %d)! ouch!\n", rv, flen);
00228             goto out;
00229         }
00230         if (ferror(in) != 0 || fclose(in) != 0)
00231             perror("FAILED: Unable to read typelib file.\n");
00232 
00233         state = XPT_NewXDRState(XPT_DECODE, whole, flen);
00234         if (!XPT_MakeCursor(state, XPT_HEADER, 0, cursor)) {
00235             fprintf(stdout, "XPT_MakeCursor failed for %s\n", name);
00236             goto out;
00237         }
00238         if (!XPT_DoHeader(arena, cursor, &header)) {
00239             fprintf(stdout,
00240                     "DoHeader failed for %s.  Is %s a valid .xpt file?\n",
00241                     name, name);
00242             goto out;
00243         }
00244 
00245         if (!XPT_DumpHeader(cursor, header, BASE_INDENT, verbose_mode)) {
00246             perror("FAILED: XPT_DumpHeader");
00247             goto out;
00248         }
00249    
00250         if (param_problems) {
00251             fprintf(stdout, "\nWARNING: ParamDescriptors are present with "
00252                     "bad in/out/retval flag information.\n"
00253                     "These have been marked with 'XXX'.\n"
00254                     "Remember, retval params should always be marked as out!\n");
00255         }
00256 
00257         XPT_DestroyXDRState(state);
00258         XPT_FREE(arena, whole);
00259 
00260     } else {
00261         fclose(in);
00262         perror("FAILED: file length <= 0");
00263         goto out;
00264     }
00265 
00266     result = 0;
00267 
00268 out:
00269     XPT_DestroyArena(arena);
00270     return result;
00271 }
00272 
00273 PRBool
00274 XPT_DumpHeader(XPTCursor *cursor, XPTHeader *header, 
00275                const int indent, PRBool verbose_mode) 
00276 {
00277     int i;
00278     
00279     fprintf(stdout, "Header:\n");
00280 
00281     if (verbose_mode) {
00282         fprintf(stdout, "%*sMagic beans:           ", indent, " ");
00283         for (i=0; i<16; i++) {
00284             fprintf(stdout, "%02x", header->magic[i]);
00285         }
00286         fprintf(stdout, "\n");
00287         if (strncmp((const char*)header->magic, XPT_MAGIC, 16) == 0)
00288             fprintf(stdout, "%*s                       PASSED\n", indent, " ");
00289         else
00290             fprintf(stdout, "%*s                       FAILED\n", indent, " ");
00291     }
00292     fprintf(stdout, "%*sMajor version:         %d\n", indent, " ",
00293             header->major_version);
00294     fprintf(stdout, "%*sMinor version:         %d\n", indent, " ",
00295             header->minor_version);    
00296     fprintf(stdout, "%*sNumber of interfaces:  %d\n", indent, " ",
00297             header->num_interfaces);
00298 
00299     if (verbose_mode) {
00300         fprintf(stdout, "%*sFile length:           %d\n", indent, " ",
00301                 header->file_length);
00302         fprintf(stdout, "%*sData pool offset:      %d\n\n", indent, " ",
00303                 header->data_pool);
00304     }
00305     
00306     fprintf(stdout, "%*sAnnotations:\n", indent, " ");
00307     if (!XPT_DumpAnnotations(header->annotations, indent*2, verbose_mode))
00308         return PR_FALSE;
00309 
00310     fprintf(stdout, "\nInterface Directory:\n");
00311     for (i=0; i<header->num_interfaces; i++) {
00312         if (verbose_mode) {
00313             fprintf(stdout, "%*sInterface #%d:\n", indent, " ", i);
00314             if (!XPT_DumpInterfaceDirectoryEntry(cursor,
00315                                                  &header->interface_directory[i],
00316                                                  header, indent*2,
00317                                                  verbose_mode)) {
00318                 return PR_FALSE;
00319             }
00320         } else {
00321             if (!XPT_DumpInterfaceDirectoryEntry(cursor,
00322                                                  &header->interface_directory[i],
00323                                                  header, indent,
00324                                                  verbose_mode)) {
00325                 return PR_FALSE;
00326             }
00327         }
00328     }
00329 
00330     return PR_TRUE;
00331 }    
00332 
00333 PRBool
00334 XPT_DumpAnnotations(XPTAnnotation *ann, const int indent, PRBool verbose_mode) 
00335 {
00336     int i = -1;
00337     XPTAnnotation *last;
00338     int new_indent = indent + BASE_INDENT;
00339 
00340     do {
00341         i++;
00342         if (XPT_ANN_IS_PRIVATE(ann->flags)) {
00343             if (verbose_mode) {
00344                 fprintf(stdout, "%*sAnnotation #%d is private.\n", 
00345                         indent, " ", i);
00346             } else {
00347                 fprintf(stdout, "%*sAnnotation #%d:\n", 
00348                         indent, " ", i);
00349             }                
00350             fprintf(stdout, "%*sCreator:      ", new_indent, " ");
00351             if (!XPT_DumpXPTString(ann->creator))
00352                 return PR_FALSE;
00353             fprintf(stdout, "\n");
00354             fprintf(stdout, "%*sPrivate Data: ", new_indent, " ");            
00355             if (!XPT_DumpXPTString(ann->private_data))
00356                 return PR_FALSE;
00357             fprintf(stdout, "\n");
00358         } else {
00359             fprintf(stdout, "%*sAnnotation #%d is empty.\n", 
00360                     indent, " ", i);
00361         }
00362         last = ann;
00363         ann = ann->next;
00364     } while (!XPT_ANN_IS_LAST(last->flags));
00365         
00366     if (verbose_mode) {
00367         fprintf(stdout, "%*sAnnotation #%d is the last annotation.\n", 
00368                 indent, " ", i);
00369     }
00370 
00371     return PR_TRUE;
00372 }
00373 
00374 static void
00375 print_IID(struct nsID *iid, FILE *file)
00376 {
00377     fprintf(file, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
00378             (PRUint32) iid->m0, (PRUint32) iid->m1,(PRUint32) iid->m2,
00379             (PRUint32) iid->m3[0], (PRUint32) iid->m3[1],
00380             (PRUint32) iid->m3[2], (PRUint32) iid->m3[3],
00381             (PRUint32) iid->m3[4], (PRUint32) iid->m3[5],
00382             (PRUint32) iid->m3[6], (PRUint32) iid->m3[7]);
00383             
00384 }
00385 
00386 PRBool
00387 XPT_DumpInterfaceDirectoryEntry(XPTCursor *cursor, 
00388                                 XPTInterfaceDirectoryEntry *ide, 
00389                                 XPTHeader *header, const int indent,
00390                                 PRBool verbose_mode)
00391 {
00392     int new_indent = indent + BASE_INDENT;
00393 
00394     if (verbose_mode) {
00395         fprintf(stdout, "%*sIID:                             ", indent, " ");
00396         print_IID(&ide->iid, stdout);
00397         fprintf(stdout, "\n");
00398         
00399         fprintf(stdout, "%*sName:                            %s\n", 
00400                 indent, " ", ide->name);
00401         fprintf(stdout, "%*sNamespace:                       %s\n", 
00402                 indent, " ", ide->name_space ? ide->name_space : "none");
00403         fprintf(stdout, "%*sAddress of interface descriptor: %p\n", 
00404                 indent, " ", ide->interface_descriptor);
00405 
00406         fprintf(stdout, "%*sDescriptor:\n", indent, " ");
00407     
00408         if (!XPT_DumpInterfaceDescriptor(cursor, ide->interface_descriptor, 
00409                                          header, new_indent, verbose_mode)) {
00410             return PR_FALSE;
00411         }
00412     } else {
00413         fprintf(stdout, "%*s- %s::%s (", indent, " ", 
00414                 ide->name_space ? ide->name_space : "", ide->name);
00415         print_IID(&ide->iid, stdout);
00416         fprintf(stdout, "):\n");
00417         if (!XPT_DumpInterfaceDescriptor(cursor, ide->interface_descriptor, 
00418                                          header, new_indent, verbose_mode)) {
00419             return PR_FALSE;
00420         }
00421     }
00422 
00423     return PR_TRUE;
00424 }    
00425 
00426 PRBool
00427 XPT_DumpInterfaceDescriptor(XPTCursor *cursor, XPTInterfaceDescriptor *id,
00428                             XPTHeader *header, const int indent,
00429                             PRBool verbose_mode)
00430 {
00431     XPTInterfaceDirectoryEntry *parent_ide;
00432     int i;
00433     int new_indent = indent + BASE_INDENT;
00434     int more_indent = new_indent + BASE_INDENT;
00435 
00436     if (!id) {
00437         fprintf(stdout, "%*s[Unresolved]\n", indent, " ");
00438         return PR_TRUE;
00439     }
00440 
00441     if (id->parent_interface) {
00442 
00443         parent_ide = &header->interface_directory[id->parent_interface - 1];
00444 
00445         fprintf(stdout, "%*sParent: %s::%s\n", indent, " ", 
00446                 parent_ide->name_space ? 
00447                 parent_ide->name_space : "", 
00448                 parent_ide->name);
00449     }
00450 
00451     fprintf(stdout, "%*sFlags:\n", indent, " ");
00452 
00453     fprintf(stdout, "%*sScriptable: %s\n", new_indent, " ", 
00454             XPT_ID_IS_SCRIPTABLE(id->flags) ? "TRUE" : "FALSE");
00455 
00456     fprintf(stdout, "%*sFunction: %s\n", new_indent, " ", 
00457             XPT_ID_IS_FUNCTION(id->flags) ? "TRUE" : "FALSE");
00458 
00459     if (verbose_mode) {
00460         if (id->parent_interface) {
00461             fprintf(stdout, 
00462                     "%*sIndex of parent interface (in data pool): %d\n", 
00463                     indent, " ", id->parent_interface);
00464             
00465         }
00466     } else {
00467     }   
00468 
00469     if (id->num_methods > 0) {
00470         if (verbose_mode) {
00471             fprintf(stdout, 
00472                     "%*s# of Method Descriptors:                   %d\n", 
00473                     indent, " ", id->num_methods);
00474         } else {
00475             fprintf(stdout, "%*sMethods:\n", indent, " ");
00476         }
00477 
00478         for (i=0; i<id->num_methods; i++) {
00479             if (verbose_mode) {
00480                 fprintf(stdout, "%*sMethod #%d:\n", new_indent, " ", i);
00481                 if (!XPT_DumpMethodDescriptor(header,
00482                                               &id->method_descriptors[i], id,
00483                                               more_indent, verbose_mode)) {
00484                     return PR_FALSE;
00485                 } 
00486             } else { 
00487                 if (!XPT_DumpMethodDescriptor(header,
00488                                               &id->method_descriptors[i], id,
00489                                               new_indent, verbose_mode)) {
00490                     return PR_FALSE;
00491                 } 
00492             }
00493         }        
00494     } else {
00495         fprintf(stdout, "%*sMethods:\n", indent, " ");
00496         fprintf(stdout, "%*sNo Methods\n", new_indent, " ");
00497     }
00498     
00499     if (id->num_constants > 0) {
00500         if (verbose_mode) {
00501             fprintf(stdout, 
00502                     "%*s# of Constant Descriptors:                  %d\n", 
00503                     indent, " ", id->num_constants);
00504         } else {
00505             fprintf(stdout, "%*sConstants:\n", indent, " ");
00506         }
00507         
00508         for (i=0; i<id->num_constants; i++) {
00509             if (verbose_mode) {
00510                 fprintf(stdout, "%*sConstant #%d:\n", new_indent, " ", i);
00511                 if (!XPT_DumpConstDescriptor(header, 
00512                                              &id->const_descriptors[i], id,
00513                                              more_indent, verbose_mode))
00514                 return PR_FALSE;
00515             } else {
00516                 if (!XPT_DumpConstDescriptor(header, 
00517                                              &id->const_descriptors[i], id,
00518                                              new_indent, verbose_mode)) {
00519                     return PR_FALSE;
00520                 }
00521             }
00522         }
00523     } else { 
00524         fprintf(stdout, "%*sConstants:\n", indent, " ");
00525         fprintf(stdout, "%*sNo Constants\n", new_indent, " ");
00526     }
00527 
00528     return PR_TRUE;
00529 }
00530 
00531 PRBool
00532 XPT_DumpMethodDescriptor(XPTHeader *header, XPTMethodDescriptor *md,
00533                          XPTInterfaceDescriptor *id,
00534                          const int indent, PRBool verbose_mode)
00535 {
00536     int i;
00537     int new_indent = indent + BASE_INDENT;
00538     int more_indent = new_indent + BASE_INDENT;
00539 
00540     if (verbose_mode) {
00541         fprintf(stdout, "%*sName:             %s\n", indent, " ", md->name);
00542         fprintf(stdout, "%*sIs Getter?        ", indent, " ");
00543         if (XPT_MD_IS_GETTER(md->flags))
00544             fprintf(stdout, "TRUE\n");
00545         else 
00546             fprintf(stdout, "FALSE\n");
00547         
00548         fprintf(stdout, "%*sIs Setter?        ", indent, " ");
00549         if (XPT_MD_IS_SETTER(md->flags))
00550             fprintf(stdout, "TRUE\n");
00551         else 
00552             fprintf(stdout, "FALSE\n");
00553         
00554         fprintf(stdout, "%*sIs NotXPCOM?      ", indent, " ");
00555         if (XPT_MD_IS_NOTXPCOM(md->flags))
00556             fprintf(stdout, "TRUE\n");
00557         else 
00558             fprintf(stdout, "FALSE\n");
00559         
00560         fprintf(stdout, "%*sIs Constructor?   ", indent, " ");
00561         if (XPT_MD_IS_CTOR(md->flags))
00562             fprintf(stdout, "TRUE\n");
00563         else 
00564             fprintf(stdout, "FALSE\n");
00565         
00566         fprintf(stdout, "%*sIs Hidden?        ", indent, " ");
00567         if (XPT_MD_IS_HIDDEN(md->flags))
00568             fprintf(stdout, "TRUE\n");
00569         else 
00570             fprintf(stdout, "FALSE\n");
00571         
00572         fprintf(stdout, "%*s# of arguments:   %d\n", indent, " ", md->num_args);
00573         fprintf(stdout, "%*sParameter Descriptors:\n", indent, " ");
00574         
00575         for (i=0; i<md->num_args; i++) {
00576             fprintf(stdout, "%*sParameter #%d:\n", new_indent, " ", i);
00577             
00578             if (!XPT_DumpParamDescriptor(header, &md->params[i], id, 
00579                                          more_indent, verbose_mode, PR_FALSE))
00580                 return PR_FALSE;
00581         }
00582    
00583         fprintf(stdout, "%*sResult:\n", indent, " ");
00584         if (!XPT_DumpParamDescriptor(header, md->result, id, new_indent,
00585                                      verbose_mode, PR_TRUE)) {
00586             return PR_FALSE;
00587         }
00588     } else {
00589         char *param_type;
00590         XPTParamDescriptor *pd;
00591 
00592         if (!XPT_GetStringForType(header, &md->result->type, id, &param_type)) {
00593             return PR_FALSE;
00594         }
00595         fprintf(stdout, "%*s%c%c%c%c%c %s %s(", indent - 6, " ",
00596                 XPT_MD_IS_GETTER(md->flags) ? 'G' : ' ',
00597                 XPT_MD_IS_SETTER(md->flags) ? 'S' : ' ',
00598                 XPT_MD_IS_HIDDEN(md->flags) ? 'H' : ' ',
00599                 XPT_MD_IS_NOTXPCOM(md->flags) ? 'N' : ' ',
00600                 XPT_MD_IS_CTOR(md->flags) ? 'C' : ' ',
00601                 param_type, md->name);
00602         for (i=0; i<md->num_args; i++) {
00603             if (i!=0) {
00604                 fprintf(stdout, ", ");
00605             }
00606             pd = &md->params[i];
00607             if (XPT_PD_IS_IN(pd->flags)) {
00608                 fprintf(stdout, "in");
00609                 if (XPT_PD_IS_OUT(pd->flags)) {
00610                     fprintf(stdout, "out ");
00611                     if (XPT_PD_IS_RETVAL(pd->flags)) {
00612                         fprintf(stdout, "retval ");
00613                     }
00614                     if (XPT_PD_IS_SHARED(pd->flags)) {
00615                         fprintf(stdout, "shared ");
00616                     }
00617                 } else {
00618                     fprintf(stdout, " ");
00619                     if (XPT_PD_IS_DIPPER(pd->flags)) {
00620                         fprintf(stdout, "dipper ");
00621                     }
00622                     if (XPT_PD_IS_RETVAL(pd->flags)) {
00623                         fprintf(stdout, "retval ");
00624                     }
00625                 }
00626             } else {
00627                 if (XPT_PD_IS_OUT(pd->flags)) {
00628                     fprintf(stdout, "out ");
00629                     if (XPT_PD_IS_RETVAL(pd->flags)) {
00630                         fprintf(stdout, "retval ");
00631                     }
00632                     if (XPT_PD_IS_SHARED(pd->flags)) {
00633                         fprintf(stdout, "shared ");
00634                     }
00635                 } else {
00636                     param_problems = PR_TRUE;
00637                     fprintf(stdout, "XXX ");
00638                 }
00639             }
00640             if (!XPT_GetStringForType(header, &pd->type, id, &param_type)) {
00641                 return PR_FALSE;
00642             }
00643             fprintf(stdout, "%s", param_type);
00644         }
00645         fprintf(stdout, ");\n");   
00646     }
00647     return PR_TRUE;
00648 }
00649     
00650 PRBool
00651 XPT_GetStringForType(XPTHeader *header, XPTTypeDescriptor *td,
00652                      XPTInterfaceDescriptor *id,
00653                      char **type_string)
00654 {
00655     static char buf[128]; /* ugly non-reentrant use of static buffer! */
00656     PRBool isArray = PR_FALSE;
00657 
00658     int tag = XPT_TDP_TAG(td->prefix);
00659     
00660     if (tag == TD_ARRAY) {
00661         isArray = PR_TRUE;
00662         td = &id->additional_types[td->type.additional_type];
00663         tag = XPT_TDP_TAG(td->prefix);
00664     }
00665     
00666     if (tag == TD_INTERFACE_TYPE) {
00667         int idx = td->type.iface;
00668         if (!idx || idx > header->num_interfaces)
00669             *type_string = "UNKNOWN_INTERFACE";
00670         else
00671             *type_string = header->interface_directory[idx-1].name;
00672     } else if (XPT_TDP_IS_POINTER(td->prefix.flags)) {
00673         if (XPT_TDP_IS_REFERENCE(td->prefix.flags))
00674             *type_string = rtype_array[tag];
00675         else
00676             *type_string = ptype_array[tag];
00677     } else {
00678         *type_string = type_array[tag];
00679     }
00680 
00681     if(isArray) {
00682         sprintf(buf, "%s []", *type_string);
00683         *type_string = buf;
00684     }
00685 
00686     return PR_TRUE;
00687 }
00688 
00689 PRBool
00690 XPT_DumpXPTString(XPTString *str)
00691 {
00692     int i;
00693     for (i=0; i<str->length; i++) {
00694         fprintf(stdout, "%c", str->bytes[i]);
00695     }
00696     return PR_TRUE;
00697 }
00698 
00699 PRBool
00700 XPT_DumpParamDescriptor(XPTHeader *header, XPTParamDescriptor *pd,
00701                         XPTInterfaceDescriptor *id,
00702                         const int indent, PRBool verbose_mode, 
00703                         PRBool is_result)
00704 {
00705     int new_indent = indent + BASE_INDENT;
00706     
00707     if (!XPT_PD_IS_IN(pd->flags) && 
00708         !XPT_PD_IS_OUT(pd->flags) &&
00709         (XPT_PD_IS_RETVAL(pd->flags) ||
00710          XPT_PD_IS_SHARED(pd->flags))) {
00711         param_problems = PR_TRUE;
00712         fprintf(stdout, "XXX\n");
00713     } else {
00714         if (!XPT_PD_IS_IN(pd->flags) && !XPT_PD_IS_OUT(pd->flags)) {
00715             if (is_result) {
00716                 if (XPT_TDP_TAG(pd->type.prefix) != TD_UINT32 &&
00717                     XPT_TDP_TAG(pd->type.prefix) != TD_VOID) {
00718                     param_problems = PR_TRUE;
00719                     fprintf(stdout, "XXX\n");   
00720                 }
00721             } else {
00722                 param_problems = PR_TRUE;
00723                 fprintf(stdout, "XXX\n");
00724             }
00725         }
00726     }
00727 
00728     fprintf(stdout, "%*sIn Param?   ", indent, " ");
00729     if (XPT_PD_IS_IN(pd->flags))
00730         fprintf(stdout, "TRUE\n");
00731     else 
00732         fprintf(stdout, "FALSE\n");
00733     
00734     fprintf(stdout, "%*sOut Param?  ", indent, " ");
00735     if (XPT_PD_IS_OUT(pd->flags))
00736         fprintf(stdout, "TRUE\n");
00737     else 
00738         fprintf(stdout, "FALSE\n");
00739     
00740     fprintf(stdout, "%*sRetval?     ", indent, " ");
00741     if (XPT_PD_IS_RETVAL(pd->flags))
00742         fprintf(stdout, "TRUE\n");
00743     else 
00744         fprintf(stdout, "FALSE\n");
00745 
00746     fprintf(stdout, "%*sShared?     ", indent, " ");
00747     if (XPT_PD_IS_SHARED(pd->flags))
00748         fprintf(stdout, "TRUE\n");
00749     else 
00750         fprintf(stdout, "FALSE\n");
00751 
00752     fprintf(stdout, "%*sDipper?     ", indent, " ");
00753     if (XPT_PD_IS_DIPPER(pd->flags))
00754         fprintf(stdout, "TRUE\n");
00755     else 
00756         fprintf(stdout, "FALSE\n");
00757 
00758 
00759     fprintf(stdout, "%*sType Descriptor:\n", indent, " ");
00760     if (!XPT_DumpTypeDescriptor(&pd->type, id, new_indent, verbose_mode))
00761         return PR_FALSE;
00762     
00763     return PR_TRUE;
00764 }
00765 
00766 PRBool
00767 XPT_DumpTypeDescriptor(XPTTypeDescriptor *td, 
00768                        XPTInterfaceDescriptor *id,
00769                        int indent, PRBool verbose_mode)
00770 {
00771     int new_indent;
00772 
00773     if (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
00774         fprintf(stdout, "%*sArray (size in arg %d and length in arg %d) of...\n", 
00775             indent, " ", td->argnum, td->argnum2);
00776         td = &id->additional_types[td->type.additional_type];
00777         indent += BASE_INDENT;
00778     }
00779 
00780     new_indent = indent + BASE_INDENT;
00781 
00782     fprintf(stdout, "%*sIs Pointer?        ", indent, " ");
00783     if (XPT_TDP_IS_POINTER(td->prefix.flags))
00784         fprintf(stdout, "TRUE\n");
00785     else 
00786         fprintf(stdout, "FALSE\n");
00787 
00788     fprintf(stdout, "%*sIs Unique Pointer? ", indent, " ");
00789     if (XPT_TDP_IS_UNIQUE_POINTER(td->prefix.flags))
00790         fprintf(stdout, "TRUE\n");
00791     else 
00792         fprintf(stdout, "FALSE\n");
00793 
00794     fprintf(stdout, "%*sIs Reference?      ", indent, " ");
00795     if (XPT_TDP_IS_REFERENCE(td->prefix.flags))
00796         fprintf(stdout, "TRUE\n");
00797     else 
00798         fprintf(stdout, "FALSE\n");
00799 
00800     fprintf(stdout, "%*sTag:               %d\n", indent, " ", 
00801             XPT_TDP_TAG(td->prefix));
00802     
00803     if (XPT_TDP_TAG(td->prefix) == TD_PSTRING_SIZE_IS ||
00804         XPT_TDP_TAG(td->prefix) == TD_PWSTRING_SIZE_IS) {
00805         fprintf(stdout, "%*s - size in arg %d and length in arg %d\n", 
00806             indent, " ", td->argnum, td->argnum2);
00807     }
00808 
00809     if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
00810         fprintf(stdout, "%*sInterfaceTypeDescriptor:\n", indent, " "); 
00811         fprintf(stdout, "%*sIndex of IDE:             %d\n", new_indent, " ", 
00812                 td->type.iface);
00813     }
00814 
00815     if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE) {
00816         fprintf(stdout, "%*sInterfaceTypeDescriptor:\n", indent, " "); 
00817         fprintf(stdout, "%*sIndex of Method Argument: %d\n", new_indent, " ", 
00818                 td->argnum);        
00819     }
00820 
00821     return PR_TRUE;
00822 }
00823 
00824 PRBool
00825 XPT_DumpConstDescriptor(XPTHeader *header, XPTConstDescriptor *cd,
00826                         XPTInterfaceDescriptor *id,
00827                         const int indent, PRBool verbose_mode)
00828 {
00829     int new_indent = indent + BASE_INDENT;
00830     char *const_type;
00831 /*      char *out; */
00832     PRUint32 uintout;
00833     PRInt32 intout;
00834 
00835     if (verbose_mode) {
00836         fprintf(stdout, "%*sName:   %s\n", indent, " ", cd->name);
00837         fprintf(stdout, "%*sType Descriptor: \n", indent, " ");
00838         if (!XPT_DumpTypeDescriptor(&cd->type, id, new_indent, verbose_mode))
00839             return PR_FALSE;
00840         fprintf(stdout, "%*sValue:  ", indent, " ");
00841     } else {
00842         if (!XPT_GetStringForType(header, &cd->type, id, &const_type)) {
00843             return PR_FALSE;
00844         }
00845         fprintf(stdout, "%*s%s %s = ", indent, " ", const_type, cd->name);
00846     }        
00847 
00848     switch(XPT_TDP_TAG(cd->type.prefix)) {
00849     case TD_INT8:
00850         fprintf(stdout, "%d", cd->value.i8);
00851         break;
00852     case TD_INT16:
00853         fprintf(stdout, "%d", cd->value.i16);
00854         break;
00855     case TD_INT64:
00856         /* XXX punt for now to remove NSPR linkage...
00857          * borrow from mozilla/nsprpub/pr/src/io/prprf.c::cvt_ll? */
00858 
00859 /*          out = PR_smprintf("%lld", cd->value.i64); */
00860 /*          fputs(out, stdout); */
00861 /*          PR_smprintf_free(out); */
00862         LL_L2I(intout, cd->value.i64);
00863         fprintf(stdout, "%d", intout);
00864         break;
00865     case TD_INT32:
00866         fprintf(stdout, "%d", cd->value.i32);
00867         break;
00868     case TD_UINT8:
00869         fprintf(stdout, "%u", cd->value.ui8);
00870         break;
00871     case TD_UINT16:
00872         fprintf(stdout, "%u", cd->value.ui16);
00873         break;
00874     case TD_UINT64:
00875 /*          out = PR_smprintf("%lld", cd->value.ui64); */
00876 /*          fputs(out, stdout); */
00877 /*          PR_smprintf_free(out); */
00878         /* XXX punt for now to remove NSPR linkage. */
00879         LL_L2UI(uintout, cd->value.ui64);
00880         fprintf(stdout, "%u", uintout);
00881         break;
00882     case TD_UINT32:
00883         fprintf(stdout, "%u", cd->value.ui32);
00884         break;
00885     case TD_FLOAT:
00886         fprintf(stdout, "%f", cd->value.flt);
00887         break;
00888     case TD_DOUBLE:
00889         fprintf(stdout, "%g", cd->value.dbl);
00890         break;
00891     case TD_BOOL:
00892         if (cd->value.bul)
00893             fprintf(stdout, "TRUE");
00894         else 
00895             fprintf(stdout, "FALSE");
00896             break;
00897     case TD_CHAR:
00898         fprintf(stdout, "%c", cd->value.ch);
00899         break;
00900     case TD_WCHAR:
00901         fprintf(stdout, "%c", cd->value.wch & 0xff);
00902         break;
00903     case TD_VOID:
00904         fprintf(stdout, "VOID");
00905         break;
00906     case TD_PNSIID:
00907         if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) {
00908             print_IID(cd->value.iid, stdout);
00909         } else 
00910             return PR_FALSE;
00911         break;
00912     case TD_PSTRING:
00913         if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) {
00914             fprintf(stdout, "%s", cd->value.str);
00915         } else 
00916             return PR_FALSE;
00917         break;
00918     case TD_PWSTRING:
00919         if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) {
00920             PRUint16 *ch = cd->value.wstr;
00921             while (*ch) {
00922                 fprintf(stdout, "%c", *ch & 0xff);
00923                 ch++;
00924             }
00925         } else 
00926             return PR_FALSE;
00927         break;
00928     default:
00929         perror("Unrecognized type");
00930         return PR_FALSE;
00931         break;   
00932     }
00933     
00934     if (verbose_mode) {
00935         fprintf(stdout, "\n");
00936     } else {
00937         fprintf(stdout, ";\n");
00938     }
00939 
00940     return PR_TRUE;
00941 }