prep for -m stub; misc code cleanups.

This commit is contained in:
brendan%netscape.com 1999-02-16 05:10:40 +00:00
Родитель f63bfa5bf7
Коммит e53469bc76
18 изменённых файлов: 270 добавлений и 170 удалений

Просмотреть файл

@ -28,6 +28,7 @@ CSRCS = \
xpidl.c \ xpidl.c \
xpidl_idl.c \ xpidl_idl.c \
xpidl_header.c \ xpidl_header.c \
xpidl_stub.c \
xpidl_typelib.c \ xpidl_typelib.c \
xpidl_doc.c \ xpidl_doc.c \
$(NULL) $(NULL)

Просмотреть файл

@ -25,6 +25,7 @@ OBJS = \
.\$(OBJDIR)\xpidl.obj \ .\$(OBJDIR)\xpidl.obj \
.\$(OBJDIR)\xpidl_idl.obj \ .\$(OBJDIR)\xpidl_idl.obj \
.\$(OBJDIR)\xpidl_header.obj \ .\$(OBJDIR)\xpidl_header.obj \
.\$(OBJDIR)\xpidl_stub.obj \
.\$(OBJDIR)\xpidl_typelib.obj \ .\$(OBJDIR)\xpidl_typelib.obj \
.\$(OBJDIR)\xpidl_doc.obj \ .\$(OBJDIR)\xpidl_doc.obj \
$(NULL) $(NULL)

Просмотреть файл

@ -23,9 +23,10 @@
#include "xpidl.h" #include "xpidl.h"
static ModeData modes[] = { static ModeData modes[] = {
{"header", "Generate C++ header", "h", NULL }, {"header", "Generate C++ header", "h", xpidl_header_dispatch},
{"typelib", "Generate XPConnect typelib", "xpt", NULL }, {"stub", "Generate C++ JS API stubs", "cpp", xpidl_stub_dispatch},
{"doc", "Generate HTML documentation", "html", NULL }, {"typelib", "Generate XPConnect typelib", "xpt", xpidl_typelib_dispatch},
{"doc", "Generate HTML documentation", "html", xpidl_doc_dispatch},
{0} {0}
}; };
@ -33,18 +34,18 @@ static ModeData *
FindMode(char *mode) FindMode(char *mode)
{ {
int i; int i;
for (i = 0; modes[i].mode && strcmp(modes[i].mode, mode); i++) for (i = 0; modes[i].mode; i++) {
; if (!strcmp(modes[i].mode, mode))
if (modes[i].mode) return &modes[i];
return &modes[i]; }
return NULL; return NULL;
} }
gboolean enable_debug = FALSE; gboolean enable_debug = FALSE;
gboolean enable_warnings = FALSE; gboolean enable_warnings = FALSE;
gboolean verbose_mode = FALSE; gboolean verbose_mode = FALSE;
static char xpidl_usage_str[] = static char xpidl_usage_str[] =
"Usage: %s [-m mode] [-w] [-v] [-I path] [-n] [-o basename] filename.idl\n" "Usage: %s [-m mode] [-w] [-v] [-I path] [-n] [-o basename] filename.idl\n"
" -w turn on warnings (recommended)\n" " -w turn on warnings (recommended)\n"
" -v verbose mode (NYI)\n" " -v verbose mode (NYI)\n"
@ -52,7 +53,7 @@ static char xpidl_usage_str[] =
" -o use basename (e.g. ``/tmp/nsIThing'') for output\n" " -o use basename (e.g. ``/tmp/nsIThing'') for output\n"
" -m specify output mode:\n"; " -m specify output mode:\n";
static void static void
xpidl_usage(int argc, char *argv[]) xpidl_usage(int argc, char *argv[])
{ {
int i; int i;
@ -63,25 +64,50 @@ xpidl_usage(int argc, char *argv[])
} }
} }
static char OOM[] = "ERROR: out of memory\n";
void *
xpidl_malloc(size_t nbytes)
{
void *p = malloc(nbytes);
if (!p) {
fputs(OOM, stderr);
exit(1);
}
return p;
}
char *
xpidl_strdup(const char *s)
{
char *ns = strdup(s);
if (!ns) {
fputs(OOM, stderr);
exit(1);
}
return ns;
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int i, idlfiles; int i, idlfiles;
IncludePathEntry *inc, *inc_head = NULL; IncludePathEntry *inc, *inc_head, **inc_tail;
char *basename = NULL; char *basename = NULL;
ModeData *mode = NULL; ModeData *mode = NULL;
inc_head = malloc(sizeof *inc); inc_head = xpidl_malloc(sizeof *inc);
if (!inc_head)
return 1;
inc_head->directory = "."; inc_head->directory = ".";
inc_head->next = NULL; inc_head->next = NULL;
inc_tail = &inc_head->next;
#if 0
/* initialize mode factories */ /* initialize mode factories */
modes[0].factory = headerDispatch; modes[0].factory = headerDispatch;
modes[1].factory = typelibDispatch; modes[1].factory = typelibDispatch;
modes[2].factory = docDispatch; modes[2].factory = docDispatch;
#endif
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
if (argv[i][0] != '-') if (argv[i][0] != '-')
break; break;
@ -103,15 +129,14 @@ main(int argc, char *argv[])
xpidl_usage(argc, argv); xpidl_usage(argc, argv);
return 1; return 1;
} }
inc = malloc(sizeof *inc); inc = xpidl_malloc(sizeof *inc);
if (!inc)
return 1;
inc->directory = argv[i + 1]; inc->directory = argv[i + 1];
#ifdef DEBUG_shaver_includes #ifdef DEBUG_shaver_includes
fprintf(stderr, "adding %s to include path\n", inc->directory); fprintf(stderr, "adding %s to include path\n", inc->directory);
#endif #endif
inc->next = inc_head; inc->next = NULL;
inc_head = inc; *inc_tail = inc;
inc_tail = &inc->next;
i++; i++;
break; break;
case 'o': case 'o':
@ -169,7 +194,7 @@ main(int argc, char *argv[])
if (argv[i][0]) if (argv[i][0])
idlfiles += xpidl_process_idl(argv[i], inc_head, basename, mode); idlfiles += xpidl_process_idl(argv[i], inc_head, basename, mode);
} }
if (!idlfiles) if (!idlfiles)
return 1; return 1;

Просмотреть файл

@ -49,9 +49,10 @@ typedef gboolean (*nodeHandler)(TreeState *);
/* Function that produces a table of nodeHandlers for a given mode */ /* Function that produces a table of nodeHandlers for a given mode */
typedef nodeHandler *(*nodeHandlerFactory)(); typedef nodeHandler *(*nodeHandlerFactory)();
extern nodeHandler *headerDispatch(); extern nodeHandler *xpidl_header_dispatch();
extern nodeHandler *typelibDispatch(); extern nodeHandler *xpidl_stub_dispatch();
extern nodeHandler *docDispatch(); extern nodeHandler *xpidl_typelib_dispatch();
extern nodeHandler *xpidl_doc_dispatch();
/* /*
* nodeHandler that reports an error. * nodeHandler that reports an error.
@ -96,17 +97,18 @@ void
xpidl_list_foreach(IDL_tree p, IDL_tree_func foreach, gpointer user_data); xpidl_list_foreach(IDL_tree p, IDL_tree_func foreach, gpointer user_data);
/* /*
* Add an output file to an internal list. Used to clean up temporary files * Wrapper whines to stderr then exits after null return from malloc or strdup.
* in case of fatal error.
*/ */
void *
xpidl_malloc(size_t nbytes);
void char *
XPIDL_add_output_file(char *fn); xpidl_strdup(const char *s);
void
XPIDL_cleanup_on_error();
/*
* Process an XPIDL node and its kids, if any.
*/
gboolean gboolean
process_node(TreeState *state); xpidl_process_node(TreeState *state);
#endif /* __xpidl_h */ #endif /* __xpidl_h */

Просмотреть файл

@ -22,7 +22,7 @@
* Generates documentation from javadoc-style comments in XPIDL files. * Generates documentation from javadoc-style comments in XPIDL files.
*/ */
nodeHandler *docDispatch() nodeHandler *xpidl_doc_dispatch()
{ {
static nodeHandler table[IDLN_LAST]; static nodeHandler table[IDLN_LAST];
static gboolean initialized = FALSE; static gboolean initialized = FALSE;

Просмотреть файл

@ -148,7 +148,7 @@ interface(TreeState *state)
state->tree = IDL_INTERFACE(iface).body; state->tree = IDL_INTERFACE(iface).body;
if (state->tree && !process_node(state)) if (state->tree && !xpidl_process_node(state))
return FALSE; return FALSE;
fputs("};\n", state->file); fputs("};\n", state->file);
@ -162,7 +162,7 @@ list(TreeState *state)
IDL_tree iter; IDL_tree iter;
for (iter = state->tree; iter; iter = IDL_LIST(iter).next) { for (iter = state->tree; iter; iter = IDL_LIST(iter).next) {
state->tree = IDL_LIST(iter).data; state->tree = IDL_LIST(iter).data;
if (!process_node(state)) if (!xpidl_process_node(state))
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@ -310,7 +310,7 @@ param_dcls(TreeState *state)
return FALSE; return FALSE;
fputs(" ", state->file); fputs(" ", state->file);
state->tree = (IDL_tree)decl.simple_declarator; state->tree = (IDL_tree)decl.simple_declarator;
if (!process_node(state)) if (!xpidl_process_node(state))
return FALSE; return FALSE;
if (IDL_LIST(iter).next) if (IDL_LIST(iter).next)
fputs(", ", state->file); fputs(", ", state->file);
@ -364,7 +364,7 @@ static gboolean
do_enum(TreeState *state) do_enum(TreeState *state)
{ {
IDL_tree enumb = state->tree, iter; IDL_tree enumb = state->tree, iter;
fprintf(state->file, "enum %s {\n", fprintf(state->file, "enum %s {\n",
IDL_IDENT(IDL_TYPE_ENUM(enumb).ident).str); IDL_IDENT(IDL_TYPE_ENUM(enumb).ident).str);
@ -491,7 +491,7 @@ codefrag(TreeState *state)
return TRUE; return TRUE;
} }
nodeHandler *headerDispatch() nodeHandler *xpidl_header_dispatch()
{ {
static nodeHandler table[IDLN_LAST]; static nodeHandler table[IDLN_LAST];
static gboolean initialized = FALSE; static gboolean initialized = FALSE;
@ -508,6 +508,6 @@ nodeHandler *headerDispatch()
table[IDLN_TYPE_DCL] = do_typedef; table[IDLN_TYPE_DCL] = do_typedef;
initialized = TRUE; initialized = TRUE;
} }
return table; return table;
} }

Просмотреть файл

@ -46,18 +46,19 @@ node_is_error(TreeState *state)
void void
xpidl_list_foreach(IDL_tree p, IDL_tree_func foreach, gpointer user_data) xpidl_list_foreach(IDL_tree p, IDL_tree_func foreach, gpointer user_data)
{ {
IDL_tree iter = p; IDL_tree iter;
for (; iter; iter = IDL_LIST(iter).next) for (iter = p; iter; iter = IDL_LIST(iter).next) {
if (!foreach(IDL_LIST(iter).data, if (!foreach(IDL_LIST(iter).data,
IDL_tree_get_scope(IDL_LIST(iter).data), user_data)) IDL_tree_get_scope(IDL_LIST(iter).data), user_data))
return; return;
}
} }
/* /*
* The bulk of the generation happens here. * The bulk of the generation happens here.
*/ */
gboolean gboolean
process_node(TreeState *state) xpidl_process_node(TreeState *state)
{ {
nodeHandler *handlerp = state->dispatch, handler; nodeHandler *handlerp = state->dispatch, handler;
gint type; gint type;
@ -86,7 +87,7 @@ process_tree(TreeState *state)
if (!process_tree_pass1(state)) if (!process_tree_pass1(state))
return FALSE; return FALSE;
state->tree = top; /* pass1 might mutate state */ state->tree = top; /* pass1 might mutate state */
if (!process_node(state)) if (!xpidl_process_node(state))
return FALSE; return FALSE;
state->tree = NULL; state->tree = NULL;
if (!process_tree_pass1(state)) if (!process_tree_pass1(state))
@ -143,7 +144,7 @@ fopen_from_includes(const char *filename, const char *mode,
return stdin; return stdin;
for (; include_path && !file; include_path = include_path->next) { for (; include_path && !file; include_path = include_path->next) {
filebuf = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", filebuf = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
include_path->directory, filename); include_path->directory, filename);
if (!filebuf) if (!filebuf)
return NULL; return NULL;
@ -161,28 +162,16 @@ fopen_from_includes(const char *filename, const char *mode,
static struct input_callback_data * static struct input_callback_data *
new_input_callback_data(const char *filename, IncludePathEntry *include_path) new_input_callback_data(const char *filename, IncludePathEntry *include_path)
{ {
struct input_callback_data *new_data = calloc(1, sizeof *new_data); struct input_callback_data *new_data = xpidl_malloc(sizeof *new_data);
if (!new_data) memset(new_data, 0, sizeof *new_data);
return NULL;
new_data->input = fopen_from_includes(filename, "r", include_path); new_data->input = fopen_from_includes(filename, "r", include_path);
if (!new_data->input) if (!new_data->input)
return NULL; return NULL;
new_data->buf = malloc(INPUT_BUF_CHUNK + 1); /* trailing NUL */ new_data->buf = xpidl_malloc(INPUT_BUF_CHUNK + 1); /* trailing NUL */
if (!new_data->buf) {
fclose(new_data->input);
return NULL;
}
new_data->len = 0;
new_data->point = new_data->buf; new_data->point = new_data->buf;
new_data->max = INPUT_BUF_CHUNK; new_data->max = INPUT_BUF_CHUNK;
new_data->filename = strdup(filename); new_data->filename = xpidl_strdup(filename);
if (!new_data->filename) {
free(new_data->buf);
fclose(new_data->input);
return NULL;
}
new_data->lineno = 1; new_data->lineno = 1;
new_data->next = NULL;
return new_data; return new_data;
} }
@ -194,7 +183,7 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
struct input_callback_data *data = stack->top, *new_data = NULL; struct input_callback_data *data = stack->top, *new_data = NULL;
int avail, copy; int avail, copy;
char *check_point, *ptr, *end_copy, *raw_start, *comment_start, char *check_point, *ptr, *end_copy, *raw_start, *comment_start,
*include_start; *include_start;
switch(reason) { switch(reason) {
case IDL_INPUT_REASON_INIT: case IDL_INPUT_REASON_INIT:
@ -206,7 +195,7 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
IDL_file_set(new_data->filename, new_data->lineno); IDL_file_set(new_data->filename, new_data->lineno);
stack->top = new_data; stack->top = new_data;
return 0; return 0;
case IDL_INPUT_REASON_FILL: case IDL_INPUT_REASON_FILL:
fill_start: fill_start:
avail = data->buf + data->len - data->point; avail = data->buf + data->len - data->point;
@ -273,7 +262,7 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
#endif #endif
end_copy = comment_start; end_copy = comment_start;
} }
/* include */ /* include */
if ((include_start = strstr(check_point, "#include")) && if ((include_start = strstr(check_point, "#include")) &&
(!raw_start || include_start < raw_start) && (!raw_start || include_start < raw_start) &&
@ -295,11 +284,11 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
#endif #endif
} else { } else {
#ifdef DEBUG_shaver_bufmgmt #ifdef DEBUG_shaver_bufmgmt
fprintf(stderr, "already have special %d/%d/%d\n", fprintf(stderr, "already have special %d/%d/%d\n",
data->f_raw, data->f_comment, data->f_include); data->f_raw, data->f_comment, data->f_include);
#endif #endif
} }
if ((end_copy == data->point || /* just found one at the start */ if ((end_copy == data->point || /* just found one at the start */
end_copy == data->buf + data->len /* left over */) && end_copy == data->buf + data->len /* left over */) &&
(data->f_raw || data->f_comment || data->f_include)) { (data->f_raw || data->f_comment || data->f_include)) {
@ -349,7 +338,7 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
return -1; return -1;
} }
data->point = ptr+1; data->point = ptr+1;
*ptr = 0; *ptr = 0;
ptr = strrchr(filename, '.'); ptr = strrchr(filename, '.');
@ -359,11 +348,11 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
assert(stack->includes); assert(stack->includes);
if (!g_hash_table_lookup(stack->includes, filename)) { if (!g_hash_table_lookup(stack->includes, filename)) {
char *basename = filename; char *basename = filename;
filename = strdup(filename); filename = xpidl_strdup(filename);
ptr = strrchr(basename, '.'); ptr = strrchr(basename, '.');
if (ptr) if (ptr)
*ptr = 0; *ptr = 0;
basename = strdup(basename); basename = xpidl_strdup(basename);
g_hash_table_insert(stack->includes, filename, basename); g_hash_table_insert(stack->includes, filename, basename);
new_data = new_input_callback_data(filename, new_data = new_input_callback_data(filename,
stack->include_path); stack->include_path);
@ -381,22 +370,21 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
#endif #endif
/* now continue getting data from new file */ /* now continue getting data from new file */
goto fill_start; goto fill_start;
} else {
/*
* if we started with a #include, but we've already
* processed that file, we need to continue scanning
* for special sequences.
*/
data->f_include = INPUT_IN_NONE;
goto scan_for_special;
} }
/*
* if we started with a #include, but we've already
* processed that file, we need to continue scanning
* for special sequences.
*/
data->f_include = INPUT_IN_NONE;
goto scan_for_special;
} }
} else { } else {
#ifdef DEBUG_shaver_bufmgmt #ifdef DEBUG_shaver_bufmgmt
fprintf(stderr, "no specials\n"); fprintf(stderr, "no specials\n");
#endif #endif
} }
avail = MIN(data->buf + data->len, end_copy) - data->point; avail = MIN(data->buf + data->len, end_copy) - data->point;
#ifdef DEBUG_shaver_bufmgmt #ifdef DEBUG_shaver_bufmgmt
fprintf(stderr, fprintf(stderr,
@ -413,7 +401,7 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
memcpy(cb_data->fill.buffer, data->point, copy); memcpy(cb_data->fill.buffer, data->point, copy);
data->point += copy; data->point += copy;
return copy; return copy;
case IDL_INPUT_REASON_ABORT: case IDL_INPUT_REASON_ABORT:
case IDL_INPUT_REASON_FINISH: case IDL_INPUT_REASON_FINISH:
if (data->input != stdin) if (data->input != stdin)
@ -447,15 +435,15 @@ xpidl_process_idl(char *filename, IncludePathEntry *include_path,
return 0; return 0;
} }
state.basename = strdup(filename); state.basename = xpidl_strdup(filename);
tmp = strrchr(state.basename, '.'); tmp = strrchr(state.basename, '.');
if (tmp) if (tmp)
*tmp = '\0'; *tmp = '\0';
if (!basename) if (!basename)
outname = strdup(state.basename); outname = xpidl_strdup(state.basename);
else else
outname = strdup(basename); outname = xpidl_strdup(basename);
/* so we don't include it again! */ /* so we don't include it again! */
g_hash_table_insert(stack.includes, filename, state.basename); g_hash_table_insert(stack.includes, filename, state.basename);
@ -475,6 +463,11 @@ xpidl_process_idl(char *filename, IncludePathEntry *include_path,
return 0; return 0;
} }
state.basename = xpidl_strdup(filename);
tmp = strrchr(state.basename, '.');
if (tmp)
*tmp = '\0';
/* so we don't make a #include for it */ /* so we don't make a #include for it */
g_hash_table_remove(stack.includes, filename); g_hash_table_remove(stack.includes, filename);
@ -509,6 +502,6 @@ xpidl_process_idl(char *filename, IncludePathEntry *include_path,
*/ */
IDL_ns_free(state.ns); IDL_ns_free(state.ns);
IDL_tree_free(top); IDL_tree_free(top);
return 1; return 1;
} }

Просмотреть файл

@ -0,0 +1,28 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* Generate JS API class stub functions from XPIDL.
*/
#include "xpidl.h"
nodeHandler *xpidl_stub_dispatch()
{
return NULL;
}

Просмотреть файл

@ -23,7 +23,7 @@
#include "xpidl.h" #include "xpidl.h"
nodeHandler *typelibDispatch() nodeHandler *xpidl_typelib_dispatch()
{ {
static nodeHandler table[IDLN_LAST]; static nodeHandler table[IDLN_LAST];
static gboolean initialized = FALSE; static gboolean initialized = FALSE;

Просмотреть файл

@ -28,6 +28,7 @@ CSRCS = \
xpidl.c \ xpidl.c \
xpidl_idl.c \ xpidl_idl.c \
xpidl_header.c \ xpidl_header.c \
xpidl_stub.c \
xpidl_typelib.c \ xpidl_typelib.c \
xpidl_doc.c \ xpidl_doc.c \
$(NULL) $(NULL)

Просмотреть файл

@ -25,6 +25,7 @@ OBJS = \
.\$(OBJDIR)\xpidl.obj \ .\$(OBJDIR)\xpidl.obj \
.\$(OBJDIR)\xpidl_idl.obj \ .\$(OBJDIR)\xpidl_idl.obj \
.\$(OBJDIR)\xpidl_header.obj \ .\$(OBJDIR)\xpidl_header.obj \
.\$(OBJDIR)\xpidl_stub.obj \
.\$(OBJDIR)\xpidl_typelib.obj \ .\$(OBJDIR)\xpidl_typelib.obj \
.\$(OBJDIR)\xpidl_doc.obj \ .\$(OBJDIR)\xpidl_doc.obj \
$(NULL) $(NULL)

Просмотреть файл

@ -23,9 +23,10 @@
#include "xpidl.h" #include "xpidl.h"
static ModeData modes[] = { static ModeData modes[] = {
{"header", "Generate C++ header", "h", NULL }, {"header", "Generate C++ header", "h", xpidl_header_dispatch},
{"typelib", "Generate XPConnect typelib", "xpt", NULL }, {"stub", "Generate C++ JS API stubs", "cpp", xpidl_stub_dispatch},
{"doc", "Generate HTML documentation", "html", NULL }, {"typelib", "Generate XPConnect typelib", "xpt", xpidl_typelib_dispatch},
{"doc", "Generate HTML documentation", "html", xpidl_doc_dispatch},
{0} {0}
}; };
@ -33,18 +34,18 @@ static ModeData *
FindMode(char *mode) FindMode(char *mode)
{ {
int i; int i;
for (i = 0; modes[i].mode && strcmp(modes[i].mode, mode); i++) for (i = 0; modes[i].mode; i++) {
; if (!strcmp(modes[i].mode, mode))
if (modes[i].mode) return &modes[i];
return &modes[i]; }
return NULL; return NULL;
} }
gboolean enable_debug = FALSE; gboolean enable_debug = FALSE;
gboolean enable_warnings = FALSE; gboolean enable_warnings = FALSE;
gboolean verbose_mode = FALSE; gboolean verbose_mode = FALSE;
static char xpidl_usage_str[] = static char xpidl_usage_str[] =
"Usage: %s [-m mode] [-w] [-v] [-I path] [-n] [-o basename] filename.idl\n" "Usage: %s [-m mode] [-w] [-v] [-I path] [-n] [-o basename] filename.idl\n"
" -w turn on warnings (recommended)\n" " -w turn on warnings (recommended)\n"
" -v verbose mode (NYI)\n" " -v verbose mode (NYI)\n"
@ -52,7 +53,7 @@ static char xpidl_usage_str[] =
" -o use basename (e.g. ``/tmp/nsIThing'') for output\n" " -o use basename (e.g. ``/tmp/nsIThing'') for output\n"
" -m specify output mode:\n"; " -m specify output mode:\n";
static void static void
xpidl_usage(int argc, char *argv[]) xpidl_usage(int argc, char *argv[])
{ {
int i; int i;
@ -63,25 +64,50 @@ xpidl_usage(int argc, char *argv[])
} }
} }
static char OOM[] = "ERROR: out of memory\n";
void *
xpidl_malloc(size_t nbytes)
{
void *p = malloc(nbytes);
if (!p) {
fputs(OOM, stderr);
exit(1);
}
return p;
}
char *
xpidl_strdup(const char *s)
{
char *ns = strdup(s);
if (!ns) {
fputs(OOM, stderr);
exit(1);
}
return ns;
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int i, idlfiles; int i, idlfiles;
IncludePathEntry *inc, *inc_head = NULL; IncludePathEntry *inc, *inc_head, **inc_tail;
char *basename = NULL; char *basename = NULL;
ModeData *mode = NULL; ModeData *mode = NULL;
inc_head = malloc(sizeof *inc); inc_head = xpidl_malloc(sizeof *inc);
if (!inc_head)
return 1;
inc_head->directory = "."; inc_head->directory = ".";
inc_head->next = NULL; inc_head->next = NULL;
inc_tail = &inc_head->next;
#if 0
/* initialize mode factories */ /* initialize mode factories */
modes[0].factory = headerDispatch; modes[0].factory = headerDispatch;
modes[1].factory = typelibDispatch; modes[1].factory = typelibDispatch;
modes[2].factory = docDispatch; modes[2].factory = docDispatch;
#endif
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
if (argv[i][0] != '-') if (argv[i][0] != '-')
break; break;
@ -103,15 +129,14 @@ main(int argc, char *argv[])
xpidl_usage(argc, argv); xpidl_usage(argc, argv);
return 1; return 1;
} }
inc = malloc(sizeof *inc); inc = xpidl_malloc(sizeof *inc);
if (!inc)
return 1;
inc->directory = argv[i + 1]; inc->directory = argv[i + 1];
#ifdef DEBUG_shaver_includes #ifdef DEBUG_shaver_includes
fprintf(stderr, "adding %s to include path\n", inc->directory); fprintf(stderr, "adding %s to include path\n", inc->directory);
#endif #endif
inc->next = inc_head; inc->next = NULL;
inc_head = inc; *inc_tail = inc;
inc_tail = &inc->next;
i++; i++;
break; break;
case 'o': case 'o':
@ -169,7 +194,7 @@ main(int argc, char *argv[])
if (argv[i][0]) if (argv[i][0])
idlfiles += xpidl_process_idl(argv[i], inc_head, basename, mode); idlfiles += xpidl_process_idl(argv[i], inc_head, basename, mode);
} }
if (!idlfiles) if (!idlfiles)
return 1; return 1;

Просмотреть файл

@ -49,9 +49,10 @@ typedef gboolean (*nodeHandler)(TreeState *);
/* Function that produces a table of nodeHandlers for a given mode */ /* Function that produces a table of nodeHandlers for a given mode */
typedef nodeHandler *(*nodeHandlerFactory)(); typedef nodeHandler *(*nodeHandlerFactory)();
extern nodeHandler *headerDispatch(); extern nodeHandler *xpidl_header_dispatch();
extern nodeHandler *typelibDispatch(); extern nodeHandler *xpidl_stub_dispatch();
extern nodeHandler *docDispatch(); extern nodeHandler *xpidl_typelib_dispatch();
extern nodeHandler *xpidl_doc_dispatch();
/* /*
* nodeHandler that reports an error. * nodeHandler that reports an error.
@ -96,17 +97,18 @@ void
xpidl_list_foreach(IDL_tree p, IDL_tree_func foreach, gpointer user_data); xpidl_list_foreach(IDL_tree p, IDL_tree_func foreach, gpointer user_data);
/* /*
* Add an output file to an internal list. Used to clean up temporary files * Wrapper whines to stderr then exits after null return from malloc or strdup.
* in case of fatal error.
*/ */
void *
xpidl_malloc(size_t nbytes);
void char *
XPIDL_add_output_file(char *fn); xpidl_strdup(const char *s);
void
XPIDL_cleanup_on_error();
/*
* Process an XPIDL node and its kids, if any.
*/
gboolean gboolean
process_node(TreeState *state); xpidl_process_node(TreeState *state);
#endif /* __xpidl_h */ #endif /* __xpidl_h */

Просмотреть файл

@ -22,7 +22,7 @@
* Generates documentation from javadoc-style comments in XPIDL files. * Generates documentation from javadoc-style comments in XPIDL files.
*/ */
nodeHandler *docDispatch() nodeHandler *xpidl_doc_dispatch()
{ {
static nodeHandler table[IDLN_LAST]; static nodeHandler table[IDLN_LAST];
static gboolean initialized = FALSE; static gboolean initialized = FALSE;

Просмотреть файл

@ -148,7 +148,7 @@ interface(TreeState *state)
state->tree = IDL_INTERFACE(iface).body; state->tree = IDL_INTERFACE(iface).body;
if (state->tree && !process_node(state)) if (state->tree && !xpidl_process_node(state))
return FALSE; return FALSE;
fputs("};\n", state->file); fputs("};\n", state->file);
@ -162,7 +162,7 @@ list(TreeState *state)
IDL_tree iter; IDL_tree iter;
for (iter = state->tree; iter; iter = IDL_LIST(iter).next) { for (iter = state->tree; iter; iter = IDL_LIST(iter).next) {
state->tree = IDL_LIST(iter).data; state->tree = IDL_LIST(iter).data;
if (!process_node(state)) if (!xpidl_process_node(state))
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@ -310,7 +310,7 @@ param_dcls(TreeState *state)
return FALSE; return FALSE;
fputs(" ", state->file); fputs(" ", state->file);
state->tree = (IDL_tree)decl.simple_declarator; state->tree = (IDL_tree)decl.simple_declarator;
if (!process_node(state)) if (!xpidl_process_node(state))
return FALSE; return FALSE;
if (IDL_LIST(iter).next) if (IDL_LIST(iter).next)
fputs(", ", state->file); fputs(", ", state->file);
@ -364,7 +364,7 @@ static gboolean
do_enum(TreeState *state) do_enum(TreeState *state)
{ {
IDL_tree enumb = state->tree, iter; IDL_tree enumb = state->tree, iter;
fprintf(state->file, "enum %s {\n", fprintf(state->file, "enum %s {\n",
IDL_IDENT(IDL_TYPE_ENUM(enumb).ident).str); IDL_IDENT(IDL_TYPE_ENUM(enumb).ident).str);
@ -491,7 +491,7 @@ codefrag(TreeState *state)
return TRUE; return TRUE;
} }
nodeHandler *headerDispatch() nodeHandler *xpidl_header_dispatch()
{ {
static nodeHandler table[IDLN_LAST]; static nodeHandler table[IDLN_LAST];
static gboolean initialized = FALSE; static gboolean initialized = FALSE;
@ -508,6 +508,6 @@ nodeHandler *headerDispatch()
table[IDLN_TYPE_DCL] = do_typedef; table[IDLN_TYPE_DCL] = do_typedef;
initialized = TRUE; initialized = TRUE;
} }
return table; return table;
} }

Просмотреть файл

@ -46,18 +46,19 @@ node_is_error(TreeState *state)
void void
xpidl_list_foreach(IDL_tree p, IDL_tree_func foreach, gpointer user_data) xpidl_list_foreach(IDL_tree p, IDL_tree_func foreach, gpointer user_data)
{ {
IDL_tree iter = p; IDL_tree iter;
for (; iter; iter = IDL_LIST(iter).next) for (iter = p; iter; iter = IDL_LIST(iter).next) {
if (!foreach(IDL_LIST(iter).data, if (!foreach(IDL_LIST(iter).data,
IDL_tree_get_scope(IDL_LIST(iter).data), user_data)) IDL_tree_get_scope(IDL_LIST(iter).data), user_data))
return; return;
}
} }
/* /*
* The bulk of the generation happens here. * The bulk of the generation happens here.
*/ */
gboolean gboolean
process_node(TreeState *state) xpidl_process_node(TreeState *state)
{ {
nodeHandler *handlerp = state->dispatch, handler; nodeHandler *handlerp = state->dispatch, handler;
gint type; gint type;
@ -86,7 +87,7 @@ process_tree(TreeState *state)
if (!process_tree_pass1(state)) if (!process_tree_pass1(state))
return FALSE; return FALSE;
state->tree = top; /* pass1 might mutate state */ state->tree = top; /* pass1 might mutate state */
if (!process_node(state)) if (!xpidl_process_node(state))
return FALSE; return FALSE;
state->tree = NULL; state->tree = NULL;
if (!process_tree_pass1(state)) if (!process_tree_pass1(state))
@ -143,7 +144,7 @@ fopen_from_includes(const char *filename, const char *mode,
return stdin; return stdin;
for (; include_path && !file; include_path = include_path->next) { for (; include_path && !file; include_path = include_path->next) {
filebuf = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", filebuf = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
include_path->directory, filename); include_path->directory, filename);
if (!filebuf) if (!filebuf)
return NULL; return NULL;
@ -161,28 +162,16 @@ fopen_from_includes(const char *filename, const char *mode,
static struct input_callback_data * static struct input_callback_data *
new_input_callback_data(const char *filename, IncludePathEntry *include_path) new_input_callback_data(const char *filename, IncludePathEntry *include_path)
{ {
struct input_callback_data *new_data = calloc(1, sizeof *new_data); struct input_callback_data *new_data = xpidl_malloc(sizeof *new_data);
if (!new_data) memset(new_data, 0, sizeof *new_data);
return NULL;
new_data->input = fopen_from_includes(filename, "r", include_path); new_data->input = fopen_from_includes(filename, "r", include_path);
if (!new_data->input) if (!new_data->input)
return NULL; return NULL;
new_data->buf = malloc(INPUT_BUF_CHUNK + 1); /* trailing NUL */ new_data->buf = xpidl_malloc(INPUT_BUF_CHUNK + 1); /* trailing NUL */
if (!new_data->buf) {
fclose(new_data->input);
return NULL;
}
new_data->len = 0;
new_data->point = new_data->buf; new_data->point = new_data->buf;
new_data->max = INPUT_BUF_CHUNK; new_data->max = INPUT_BUF_CHUNK;
new_data->filename = strdup(filename); new_data->filename = xpidl_strdup(filename);
if (!new_data->filename) {
free(new_data->buf);
fclose(new_data->input);
return NULL;
}
new_data->lineno = 1; new_data->lineno = 1;
new_data->next = NULL;
return new_data; return new_data;
} }
@ -194,7 +183,7 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
struct input_callback_data *data = stack->top, *new_data = NULL; struct input_callback_data *data = stack->top, *new_data = NULL;
int avail, copy; int avail, copy;
char *check_point, *ptr, *end_copy, *raw_start, *comment_start, char *check_point, *ptr, *end_copy, *raw_start, *comment_start,
*include_start; *include_start;
switch(reason) { switch(reason) {
case IDL_INPUT_REASON_INIT: case IDL_INPUT_REASON_INIT:
@ -206,7 +195,7 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
IDL_file_set(new_data->filename, new_data->lineno); IDL_file_set(new_data->filename, new_data->lineno);
stack->top = new_data; stack->top = new_data;
return 0; return 0;
case IDL_INPUT_REASON_FILL: case IDL_INPUT_REASON_FILL:
fill_start: fill_start:
avail = data->buf + data->len - data->point; avail = data->buf + data->len - data->point;
@ -273,7 +262,7 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
#endif #endif
end_copy = comment_start; end_copy = comment_start;
} }
/* include */ /* include */
if ((include_start = strstr(check_point, "#include")) && if ((include_start = strstr(check_point, "#include")) &&
(!raw_start || include_start < raw_start) && (!raw_start || include_start < raw_start) &&
@ -295,11 +284,11 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
#endif #endif
} else { } else {
#ifdef DEBUG_shaver_bufmgmt #ifdef DEBUG_shaver_bufmgmt
fprintf(stderr, "already have special %d/%d/%d\n", fprintf(stderr, "already have special %d/%d/%d\n",
data->f_raw, data->f_comment, data->f_include); data->f_raw, data->f_comment, data->f_include);
#endif #endif
} }
if ((end_copy == data->point || /* just found one at the start */ if ((end_copy == data->point || /* just found one at the start */
end_copy == data->buf + data->len /* left over */) && end_copy == data->buf + data->len /* left over */) &&
(data->f_raw || data->f_comment || data->f_include)) { (data->f_raw || data->f_comment || data->f_include)) {
@ -349,7 +338,7 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
return -1; return -1;
} }
data->point = ptr+1; data->point = ptr+1;
*ptr = 0; *ptr = 0;
ptr = strrchr(filename, '.'); ptr = strrchr(filename, '.');
@ -359,11 +348,11 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
assert(stack->includes); assert(stack->includes);
if (!g_hash_table_lookup(stack->includes, filename)) { if (!g_hash_table_lookup(stack->includes, filename)) {
char *basename = filename; char *basename = filename;
filename = strdup(filename); filename = xpidl_strdup(filename);
ptr = strrchr(basename, '.'); ptr = strrchr(basename, '.');
if (ptr) if (ptr)
*ptr = 0; *ptr = 0;
basename = strdup(basename); basename = xpidl_strdup(basename);
g_hash_table_insert(stack->includes, filename, basename); g_hash_table_insert(stack->includes, filename, basename);
new_data = new_input_callback_data(filename, new_data = new_input_callback_data(filename,
stack->include_path); stack->include_path);
@ -381,22 +370,21 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
#endif #endif
/* now continue getting data from new file */ /* now continue getting data from new file */
goto fill_start; goto fill_start;
} else {
/*
* if we started with a #include, but we've already
* processed that file, we need to continue scanning
* for special sequences.
*/
data->f_include = INPUT_IN_NONE;
goto scan_for_special;
} }
/*
* if we started with a #include, but we've already
* processed that file, we need to continue scanning
* for special sequences.
*/
data->f_include = INPUT_IN_NONE;
goto scan_for_special;
} }
} else { } else {
#ifdef DEBUG_shaver_bufmgmt #ifdef DEBUG_shaver_bufmgmt
fprintf(stderr, "no specials\n"); fprintf(stderr, "no specials\n");
#endif #endif
} }
avail = MIN(data->buf + data->len, end_copy) - data->point; avail = MIN(data->buf + data->len, end_copy) - data->point;
#ifdef DEBUG_shaver_bufmgmt #ifdef DEBUG_shaver_bufmgmt
fprintf(stderr, fprintf(stderr,
@ -413,7 +401,7 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
memcpy(cb_data->fill.buffer, data->point, copy); memcpy(cb_data->fill.buffer, data->point, copy);
data->point += copy; data->point += copy;
return copy; return copy;
case IDL_INPUT_REASON_ABORT: case IDL_INPUT_REASON_ABORT:
case IDL_INPUT_REASON_FINISH: case IDL_INPUT_REASON_FINISH:
if (data->input != stdin) if (data->input != stdin)
@ -447,15 +435,15 @@ xpidl_process_idl(char *filename, IncludePathEntry *include_path,
return 0; return 0;
} }
state.basename = strdup(filename); state.basename = xpidl_strdup(filename);
tmp = strrchr(state.basename, '.'); tmp = strrchr(state.basename, '.');
if (tmp) if (tmp)
*tmp = '\0'; *tmp = '\0';
if (!basename) if (!basename)
outname = strdup(state.basename); outname = xpidl_strdup(state.basename);
else else
outname = strdup(basename); outname = xpidl_strdup(basename);
/* so we don't include it again! */ /* so we don't include it again! */
g_hash_table_insert(stack.includes, filename, state.basename); g_hash_table_insert(stack.includes, filename, state.basename);
@ -475,6 +463,11 @@ xpidl_process_idl(char *filename, IncludePathEntry *include_path,
return 0; return 0;
} }
state.basename = xpidl_strdup(filename);
tmp = strrchr(state.basename, '.');
if (tmp)
*tmp = '\0';
/* so we don't make a #include for it */ /* so we don't make a #include for it */
g_hash_table_remove(stack.includes, filename); g_hash_table_remove(stack.includes, filename);
@ -509,6 +502,6 @@ xpidl_process_idl(char *filename, IncludePathEntry *include_path,
*/ */
IDL_ns_free(state.ns); IDL_ns_free(state.ns);
IDL_tree_free(top); IDL_tree_free(top);
return 1; return 1;
} }

Просмотреть файл

@ -0,0 +1,28 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* Generate JS API class stub functions from XPIDL.
*/
#include "xpidl.h"
nodeHandler *xpidl_stub_dispatch()
{
return NULL;
}

Просмотреть файл

@ -23,7 +23,7 @@
#include "xpidl.h" #include "xpidl.h"
nodeHandler *typelibDispatch() nodeHandler *xpidl_typelib_dispatch()
{ {
static nodeHandler table[IDLN_LAST]; static nodeHandler table[IDLN_LAST];
static gboolean initialized = FALSE; static gboolean initialized = FALSE;