Back to index

lightning-sunbird  0.9+nobinonly
xpidl.c
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; 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 the GNU General Public License Version 2 or later (the "GPL"), or
00026  * 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  * Main xpidl program entry point.
00040  */
00041 
00042 #include "xpidl.h"
00043 
00044 static ModeData modes[] = {
00045     {"header",  "Generate C++ header",         "h",    xpidl_header_dispatch},
00046     {"typelib", "Generate XPConnect typelib",  "xpt",  xpidl_typelib_dispatch},
00047     {"doc",     "Generate HTML documentation", "html", xpidl_doc_dispatch},
00048     {"java",    "Generate Java interface",     "java", xpidl_java_dispatch},
00049     {0,         0,                             0,      0}
00050 };
00051 
00052 static ModeData *
00053 FindMode(char *mode)
00054 {
00055     int i;
00056     for (i = 0; modes[i].mode; i++) {
00057         if (!strcmp(modes[i].mode, mode))
00058             return &modes[i];
00059     }
00060     return NULL;
00061 }
00062 
00063 gboolean enable_debug               = FALSE;
00064 gboolean enable_warnings            = FALSE;
00065 gboolean verbose_mode               = FALSE;
00066 gboolean emit_typelib_annotations   = FALSE;
00067 gboolean explicit_output_filename   = FALSE;
00068 
00069 /* The following globals are explained in xpt_struct.h */
00070 PRUint8  major_version              = XPT_MAJOR_VERSION;
00071 PRUint8  minor_version              = XPT_MINOR_VERSION;
00072 
00073 static char xpidl_usage_str[] =
00074 "Usage: %s -m mode [-w] [-v] [-t version number]\n"
00075 "          [-I path] [-o basename | -e filename.ext] filename.idl\n"
00076 "       -a emit annotations to typelib\n"
00077 "       -w turn on warnings (recommended)\n"
00078 "       -v verbose mode (NYI)\n"
00079 "       -t create a typelib of a specific version number\n"
00080 "       -I add entry to start of include path for ``#include \"nsIThing.idl\"''\n"
00081 "       -o use basename (e.g. ``/tmp/nsIThing'') for output\n"
00082 "       -e use explicit output filename\n"
00083 "       -m specify output mode:\n";
00084 
00085 static void
00086 xpidl_usage(int argc, char *argv[])
00087 {
00088     int i;
00089     fprintf(stderr, xpidl_usage_str, argv[0]);
00090     for (i = 0; modes[i].mode; i++) {
00091         fprintf(stderr, "          %-12s  %-30s (.%s)\n", modes[i].mode,
00092                 modes[i].modeInfo, modes[i].suffix);
00093     }
00094 }
00095 
00096 #if defined(XP_MAC) && defined(XPIDL_PLUGIN)
00097 #define main xpidl_main
00098 int xpidl_main(int argc, char *argv[]);
00099 #endif
00100 
00101 int main(int argc, char *argv[])
00102 {
00103     int i;
00104     IncludePathEntry *inc, *inc_head, **inc_tail;
00105     char *file_basename = NULL;
00106     ModeData *mode = NULL;
00107     gboolean create_old_typelib = FALSE;
00108 
00109     /* turn this on for extra checking of our code */
00110 /*    IDL_check_cast_enable(TRUE); */
00111 
00112     inc_head = xpidl_malloc(sizeof *inc);
00113 #ifndef XP_MAC
00114     inc_head->directory = ".";
00115 #else
00116     inc_head->directory = "";
00117 #endif
00118     inc_head->next = NULL;
00119     inc_tail = &inc_head->next;
00120 
00121     for (i = 1; i < argc; i++) {
00122         if (argv[i][0] != '-')
00123             break;
00124         switch (argv[i][1]) {
00125           case '-':
00126             argc++;             /* pretend we didn't see this */
00127             /* fall through */
00128           case 0:               /* - is a legal input filename (stdin)  */
00129             goto done_options;
00130           case 'a':
00131             emit_typelib_annotations = TRUE;
00132             break;
00133           case 'w':
00134             enable_warnings = TRUE;
00135             break;
00136           case 'v':
00137             verbose_mode = TRUE;
00138             break;
00139           case 't':
00140           {
00141             /* Parse for "-t version number" and store it into global boolean
00142              * and string variables.
00143              */
00144             const gchar* typelib_version_string = NULL;
00145 
00146             /* 
00147              * If -t is the last argument on the command line, we have a problem
00148              */
00149 
00150             if (i + 1 == argc) {
00151                 fprintf(stderr, "ERROR: missing version number after -t\n");
00152                 xpidl_usage(argc, argv);
00153                 return 1;
00154             }
00155 
00156             /* Do not allow more than one "-t" definition */
00157             if (create_old_typelib) {
00158                 fprintf(stderr,
00159                         "ERROR: -t argument used twice. "
00160                         "Cannot specify more than one version\n");
00161                 xpidl_usage(argc, argv);
00162                 return 1;
00163             }
00164 
00165             /*
00166              * Assume that the argument after "-t" is the version number string
00167              * and search for it in our internal list of acceptable version
00168              * numbers.
00169              */
00170             switch (XPT_ParseVersionString(argv[++i], &major_version, 
00171                                            &minor_version)) {
00172               case XPT_VERSION_CURRENT:
00173                 break; 
00174               case XPT_VERSION_OLD: 
00175                 create_old_typelib = TRUE;
00176                 break; 
00177               case XPT_VERSION_UNSUPPORTED: 
00178                 fprintf(stderr, "ERROR: version \"%s\" not supported.\n", 
00179                         argv[i]);
00180                 xpidl_usage(argc, argv);
00181                 return 1;          
00182               case XPT_VERSION_UNKNOWN: 
00183               default:
00184                 fprintf(stderr, "ERROR: version \"%s\" not recognised.\n", 
00185                         argv[i]);
00186                 xpidl_usage(argc, argv);
00187                 return 1;          
00188             }
00189             break;
00190           }
00191           case 'I':
00192             if (argv[i][2] == '\0' && i == argc) {
00193                 fputs("ERROR: missing path after -I\n", stderr);
00194                 xpidl_usage(argc, argv);
00195                 return 1;
00196             }
00197             inc = xpidl_malloc(sizeof *inc);
00198             if (argv[i][2] == '\0') {
00199                 /* is it the -I foo form? */
00200                 inc->directory = argv[++i];
00201             } else {
00202                 /* must be the -Ifoo form.  Don't preincrement i. */
00203                 inc->directory = argv[i] + 2;
00204             }
00205 #ifdef DEBUG_shaver_includes
00206             fprintf(stderr, "adding %s to include path\n", inc->directory);
00207 #endif
00208             inc->next = NULL;
00209             *inc_tail = inc;
00210             inc_tail = &inc->next;
00211             break;
00212           case 'o':
00213             if (i == argc) {
00214                 fprintf(stderr, "ERROR: missing basename after -o\n");
00215                 xpidl_usage(argc, argv);
00216                 return 1;
00217             }
00218             file_basename = argv[++i];
00219             explicit_output_filename = FALSE;
00220             break;
00221           case 'e':
00222             if (i == argc) {
00223                 fprintf(stderr, "ERROR: missing basename after -e\n");
00224                 xpidl_usage(argc, argv);
00225                 return 1;
00226             }
00227             file_basename = argv[++i];
00228             explicit_output_filename = TRUE;
00229             break;
00230           case 'm':
00231             if (i + 1 == argc) {
00232                 fprintf(stderr, "ERROR: missing modename after -m\n");
00233                 xpidl_usage(argc, argv);
00234                 return 1;
00235             }
00236             if (mode) {
00237                 fprintf(stderr,
00238                         "ERROR: must specify exactly one mode "
00239                         "(first \"%s\", now \"%s\")\n", mode->mode,
00240                         argv[i + 1]);
00241                 xpidl_usage(argc, argv);
00242                 return 1;
00243             }
00244             mode = FindMode(argv[++i]);
00245             if (!mode) {
00246                 fprintf(stderr, "ERROR: unknown mode \"%s\"\n", argv[i]);
00247                 xpidl_usage(argc, argv);
00248                 return 1;
00249             }
00250             break;                 
00251           default:
00252             fprintf(stderr, "unknown option %s\n", argv[i]);
00253             xpidl_usage(argc, argv);
00254             return 1;
00255         }
00256     }
00257  done_options:
00258     if (!mode) {
00259         fprintf(stderr, "ERROR: must specify output mode\n");
00260         xpidl_usage(argc, argv);
00261         return 1;
00262     }
00263     if (argc != i + 1) {
00264         fprintf(stderr, "ERROR: extra arguments after input file\n");
00265     }
00266 
00267     /*
00268      * Don't try to process multiple files, given that we don't handle -o
00269      * multiply.
00270      */
00271     if (xpidl_process_idl(argv[i], inc_head, file_basename, mode))
00272         return 0;
00273 
00274     return 1;
00275 }