New back-end switching for whiter teeth and fresher breath.

De-const-ipate in params.  (Maybe strings should still be const?  I await the
outcome of The Great String Debate.)
This commit is contained in:
shaver%netscape.com 1999-02-03 23:55:33 +00:00
parent 81d2fdf2cb
commit 0abc9fdeb8
8 changed files with 228 additions and 238 deletions

View File

@ -22,30 +22,45 @@
#include "xpidl.h"
static ModeData modes[] = {
{"header", "Generate C++ header", "h", NULL },
{"typelib", "Generate XPConnect typelib", "xpt", NULL },
{"doc", "Generate HTML documentation", "html", NULL },
{0}
};
static ModeData *
FindMode(char *mode)
{
int i;
for (i = 0; modes[i].mode && strcmp(modes[i].mode, mode); i++)
;
if (modes[i].mode)
return &modes[i];
return NULL;
}
gboolean enable_debug = FALSE;
gboolean enable_warnings = FALSE;
gboolean verbose_mode = FALSE;
gboolean generate_docs = FALSE;
gboolean generate_typelib = FALSE;
gboolean generate_headers = FALSE;
gboolean generate_nothing = FALSE;
static char xpidl_usage_str[] =
"Usage: %s [-t] [-d] [-h] [-w] [-v] [-I path] [-n] [-o basename] filename.idl\n"
" -t generate typelib data (filename.xpt) (NYI)\n"
" -d generate HTML documentation (filename.html) (NYI)\n"
" -h generate C++ headers (filename.h)\n"
"Usage: %s [-m mode] [-w] [-v] [-I path] [-n] [-o basename] filename.idl\n"
" -w turn on warnings (recommended)\n"
" -v verbose mode (NYI)\n"
" -I add entry to start of include path for ``#include \"nsIThing.idl\"''\n"
" -n do not generate output files, just test IDL (NYI)\n"
" -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";
static void
xpidl_usage(int argc, char *argv[])
{
/* XXX Mac! */
int i;
fprintf(stderr, xpidl_usage_str, argv[0]);
for (i = 0; modes[i].mode; i++) {
fprintf(stderr, " %-12s %-30s (.%s)\n", modes[i].mode,
modes[i].modeInfo, modes[i].suffix);
}
}
int
@ -54,6 +69,7 @@ main(int argc, char *argv[])
int i, idlfiles;
IncludePathEntry *inc, *inc_head = NULL;
char *basename = NULL;
ModeData *mode = NULL;
inc_head = malloc(sizeof *inc);
if (!inc_head)
@ -61,28 +77,21 @@ main(int argc, char *argv[])
inc_head->directory = ".";
inc_head->next = NULL;
/* initialize mode factories */
modes[0].factory = headerDispatch;
modes[1].factory = typelibDispatch;
modes[2].factory = docDispatch;
for (i = 1; i < argc; i++) {
if (argv[i][0] != '-')
break;
switch (argv[i][1]) {
case 'd':
generate_docs = TRUE;
break;
case 't':
generate_typelib = TRUE;
break;
case 'h':
generate_headers = TRUE;
break;
case 'w':
enable_warnings = TRUE;
break;
case 'v':
verbose_mode = TRUE;
break;
case 'n':
generate_nothing = TRUE;
break;
case 'I':
if (i == argc) {
fputs("ERROR: missing path after -I\n", stderr);
@ -102,13 +111,42 @@ main(int argc, char *argv[])
break;
case 'o':
if (i == argc) {
fprintf(stderr, "ERROR: missing basename after -o\n", stderr);
fprintf(stderr, "ERROR: missing basename after -o\n");
xpidl_usage(argc, argv);
return 1;
}
basename = argv[i + 1];
i++;
break;
case 'h': /* legacy stuff, already! */
mode = FindMode("header");
if (!mode) {
xpidl_usage(argc, argv);
return 1;
}
break;
case 'm':
if (i == argc) {
fprintf(stderr, "ERROR: missing modename after -m\n");
xpidl_usage(argc, argv);
return 1;
}
if (mode) {
fprintf(stderr,
"ERROR: can only specify one mode "
"(first \"%s\", now \"%s\")\n", mode->mode,
argv[i + 1]);
xpidl_usage(argc, argv);
return 1;
}
mode = FindMode(argv[++i]);
if (!mode) {
fprintf(stderr, "ERROR: unknown mode \"%s\"\n", argv[i]);
xpidl_usage(argc, argv);
return 1;
}
break;
default:
fprintf(stderr, "unknown option %s\n", argv[i]);
xpidl_usage(argc, argv);
@ -116,15 +154,15 @@ main(int argc, char *argv[])
}
}
if (!(generate_docs || generate_typelib || generate_headers)) {
fprintf(stderr, "ERROR: must specify one of -t, -d, -h\n");
if (!mode) {
fprintf(stderr, "ERROR: must specify output mode\n");
xpidl_usage(argc, argv);
return 1;
}
for (idlfiles = 0; i < argc; i++) {
if (argv[i][0] && argv[i][0] != '-')
idlfiles += xpidl_process_idl(argv[i], inc_head, basename);
idlfiles += xpidl_process_idl(argv[i], inc_head, basename, mode);
}
if (!idlfiles)

View File

@ -38,40 +38,16 @@
extern gboolean enable_debug;
extern gboolean enable_warnings;
extern gboolean verbose_mode;
extern gboolean generate_docs;
extern gboolean generate_typelib;
extern gboolean generate_headers;
extern gboolean generate_nothing;
typedef struct IncludePathEntry {
char *directory;
struct IncludePathEntry *next;
} IncludePathEntry;
typedef struct TreeState TreeState;
typedef struct {
FILE *file;
char *basename;
IDL_ns ns;
IDL_tree tree;
int mode;
GHashTable *includes;
IncludePathEntry *include_path;
} TreeState;
#define TREESTATE_HEADER 0
#define TREESTATE_TYPELIB 1
#define TREESTATE_DOC 2
#define TREESTATE_NUM 3
/*
* A function to handle an IDL_tree type.
*/
typedef gboolean (*nodeHandler)(TreeState *);
/*
* An array of vectors of nodeHandlers, for handling each kind of node.
*/
extern nodeHandler *nodeDispatch[TREESTATE_NUM];
/* Function that produces a table of nodeHandlers for a given mode */
typedef nodeHandler *(*nodeHandlerFactory)();
extern nodeHandler *headerDispatch();
extern nodeHandler *typelibDispatch();
@ -82,13 +58,35 @@ extern nodeHandler *docDispatch();
*/
gboolean node_is_error(TreeState *state);
typedef struct ModeData {
char *mode;
char *modeInfo;
char *suffix;
nodeHandlerFactory factory;
} ModeData;
typedef struct IncludePathEntry {
char *directory;
struct IncludePathEntry *next;
} IncludePathEntry;
struct TreeState {
FILE *file;
char *basename;
IDL_ns ns;
IDL_tree tree;
GHashTable *includes;
IncludePathEntry *include_path;
nodeHandler *dispatch;
};
/*
* Process an IDL file, generating InterfaceInfo, documentation and headers as
* appropriate.
*/
int
xpidl_process_idl(char *filename, IncludePathEntry *include_path,
char *basename);
char *basename, ModeData *mode);
/*
* Iterate over an IDLN_LIST -- why is this not part of libIDL?
@ -106,5 +104,4 @@ void XPIDL_cleanup_on_error();
gboolean process_node(TreeState *state);
#endif /* __xpidl_h */

View File

@ -410,11 +410,6 @@ xpcom_param(TreeState *state)
IDL_tree param = state->tree;
state->tree = IDL_PARAM_DCL(param).param_type_spec;
/* in params that are pointers should be const */
if (STARRED_TYPE(state->tree) &&
IDL_PARAM_DCL(param).attr == IDL_PARAM_IN)
fputs("const ", state->file);
if (!xpcom_type(state))
return FALSE;
fprintf(state->file, "%s%s",

View File

@ -22,12 +22,6 @@
#include "xpidl.h"
FILE *typelib_file = NULL;
FILE *doc_file = NULL;
FILE *header_file = NULL;
nodeHandler *nodeDispatch[TREESTATE_NUM] = { NULL };
/*
* Pass 1 generates #includes for headers and the like.
*/
@ -36,7 +30,7 @@ process_tree_pass1(TreeState *state)
{
nodeHandler handler;
if ((handler = nodeDispatch[state->mode][0]))
if ((handler = state->dispatch[0]))
return handler(state);
return TRUE;
}
@ -66,7 +60,7 @@ gboolean
process_node(TreeState *state)
{
char *name = NULL;
nodeHandler *handlerp = nodeDispatch[state->mode], handler;
nodeHandler *handlerp = state->dispatch, handler;
gint type;
assert(state->tree);
@ -436,7 +430,7 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
int
xpidl_process_idl(char *filename, IncludePathEntry *include_path,
char *basename)
char *basename, ModeData *mode)
{
char *tmp, *outname, *mode_outname;
IDL_tree top;
@ -477,57 +471,28 @@ xpidl_process_idl(char *filename, IncludePathEntry *include_path,
state.includes = stack.includes;
state.include_path = include_path;
nodeDispatch[TREESTATE_HEADER] = headerDispatch();
nodeDispatch[TREESTATE_TYPELIB] = typelibDispatch();
nodeDispatch[TREESTATE_DOC] = docDispatch();
if (generate_headers) {
if (strcmp(outname, "-")) {
mode_outname = g_strdup_printf("%s.h", outname);
state.file = fopen(mode_outname, "w");
if (!state.file) {
perror("error opening output file");
free(mode_outname);
return 0;
}
free(mode_outname);
} else {
state.file = stdout;
state.dispatch = mode->factory();
if (!state.dispatch) {
/* XXX error */
return 0;
}
if (strcmp(outname, "-")) {
mode_outname = g_strdup_printf("%s.%s", outname, mode->suffix);
state.file = fopen(mode_outname, "w");
free(mode_outname);
if (!state.file) {
perror("error opening output file");
return 0;
}
state.mode = TREESTATE_HEADER;
state.tree = top;
ok = process_tree(&state);
if (state.file != stdout)
fclose(state.file);
if (!ok)
return 0;
}
if (generate_typelib) {
if (strcmp(basename, "-")) {
outname = g_strdup_printf("%s.xpt", basename);
state.file = fopen(outname, "wb");
if (!state.file) {
perror("error opening output file");
free(outname);
return 0;
}
} else {
state.file = stdout;
}
state.mode = TREESTATE_TYPELIB;
state.tree = top;
ok = process_tree(&state);
free(outname);
if (state.file != stdout)
fclose(state.file);
if (!ok)
return 0;
}
if (generate_docs) {
state.mode = TREESTATE_DOC;
state.tree = top;
if (!process_tree(&state))
return 0;
} else {
state.file = stdout;
}
state.tree = top;
ok = process_tree(&state);
if (state.file != stdout)
fclose(state.file);
if (!ok)
return 0;
free(state.basename);
free(outname);
/* g_hash_table_foreach(state.includes, free_name, NULL);

View File

@ -22,30 +22,45 @@
#include "xpidl.h"
static ModeData modes[] = {
{"header", "Generate C++ header", "h", NULL },
{"typelib", "Generate XPConnect typelib", "xpt", NULL },
{"doc", "Generate HTML documentation", "html", NULL },
{0}
};
static ModeData *
FindMode(char *mode)
{
int i;
for (i = 0; modes[i].mode && strcmp(modes[i].mode, mode); i++)
;
if (modes[i].mode)
return &modes[i];
return NULL;
}
gboolean enable_debug = FALSE;
gboolean enable_warnings = FALSE;
gboolean verbose_mode = FALSE;
gboolean generate_docs = FALSE;
gboolean generate_typelib = FALSE;
gboolean generate_headers = FALSE;
gboolean generate_nothing = FALSE;
static char xpidl_usage_str[] =
"Usage: %s [-t] [-d] [-h] [-w] [-v] [-I path] [-n] [-o basename] filename.idl\n"
" -t generate typelib data (filename.xpt) (NYI)\n"
" -d generate HTML documentation (filename.html) (NYI)\n"
" -h generate C++ headers (filename.h)\n"
"Usage: %s [-m mode] [-w] [-v] [-I path] [-n] [-o basename] filename.idl\n"
" -w turn on warnings (recommended)\n"
" -v verbose mode (NYI)\n"
" -I add entry to start of include path for ``#include \"nsIThing.idl\"''\n"
" -n do not generate output files, just test IDL (NYI)\n"
" -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";
static void
xpidl_usage(int argc, char *argv[])
{
/* XXX Mac! */
int i;
fprintf(stderr, xpidl_usage_str, argv[0]);
for (i = 0; modes[i].mode; i++) {
fprintf(stderr, " %-12s %-30s (.%s)\n", modes[i].mode,
modes[i].modeInfo, modes[i].suffix);
}
}
int
@ -54,6 +69,7 @@ main(int argc, char *argv[])
int i, idlfiles;
IncludePathEntry *inc, *inc_head = NULL;
char *basename = NULL;
ModeData *mode = NULL;
inc_head = malloc(sizeof *inc);
if (!inc_head)
@ -61,28 +77,21 @@ main(int argc, char *argv[])
inc_head->directory = ".";
inc_head->next = NULL;
/* initialize mode factories */
modes[0].factory = headerDispatch;
modes[1].factory = typelibDispatch;
modes[2].factory = docDispatch;
for (i = 1; i < argc; i++) {
if (argv[i][0] != '-')
break;
switch (argv[i][1]) {
case 'd':
generate_docs = TRUE;
break;
case 't':
generate_typelib = TRUE;
break;
case 'h':
generate_headers = TRUE;
break;
case 'w':
enable_warnings = TRUE;
break;
case 'v':
verbose_mode = TRUE;
break;
case 'n':
generate_nothing = TRUE;
break;
case 'I':
if (i == argc) {
fputs("ERROR: missing path after -I\n", stderr);
@ -102,13 +111,42 @@ main(int argc, char *argv[])
break;
case 'o':
if (i == argc) {
fprintf(stderr, "ERROR: missing basename after -o\n", stderr);
fprintf(stderr, "ERROR: missing basename after -o\n");
xpidl_usage(argc, argv);
return 1;
}
basename = argv[i + 1];
i++;
break;
case 'h': /* legacy stuff, already! */
mode = FindMode("header");
if (!mode) {
xpidl_usage(argc, argv);
return 1;
}
break;
case 'm':
if (i == argc) {
fprintf(stderr, "ERROR: missing modename after -m\n");
xpidl_usage(argc, argv);
return 1;
}
if (mode) {
fprintf(stderr,
"ERROR: can only specify one mode "
"(first \"%s\", now \"%s\")\n", mode->mode,
argv[i + 1]);
xpidl_usage(argc, argv);
return 1;
}
mode = FindMode(argv[++i]);
if (!mode) {
fprintf(stderr, "ERROR: unknown mode \"%s\"\n", argv[i]);
xpidl_usage(argc, argv);
return 1;
}
break;
default:
fprintf(stderr, "unknown option %s\n", argv[i]);
xpidl_usage(argc, argv);
@ -116,15 +154,15 @@ main(int argc, char *argv[])
}
}
if (!(generate_docs || generate_typelib || generate_headers)) {
fprintf(stderr, "ERROR: must specify one of -t, -d, -h\n");
if (!mode) {
fprintf(stderr, "ERROR: must specify output mode\n");
xpidl_usage(argc, argv);
return 1;
}
for (idlfiles = 0; i < argc; i++) {
if (argv[i][0] && argv[i][0] != '-')
idlfiles += xpidl_process_idl(argv[i], inc_head, basename);
idlfiles += xpidl_process_idl(argv[i], inc_head, basename, mode);
}
if (!idlfiles)

View File

@ -38,40 +38,16 @@
extern gboolean enable_debug;
extern gboolean enable_warnings;
extern gboolean verbose_mode;
extern gboolean generate_docs;
extern gboolean generate_typelib;
extern gboolean generate_headers;
extern gboolean generate_nothing;
typedef struct IncludePathEntry {
char *directory;
struct IncludePathEntry *next;
} IncludePathEntry;
typedef struct TreeState TreeState;
typedef struct {
FILE *file;
char *basename;
IDL_ns ns;
IDL_tree tree;
int mode;
GHashTable *includes;
IncludePathEntry *include_path;
} TreeState;
#define TREESTATE_HEADER 0
#define TREESTATE_TYPELIB 1
#define TREESTATE_DOC 2
#define TREESTATE_NUM 3
/*
* A function to handle an IDL_tree type.
*/
typedef gboolean (*nodeHandler)(TreeState *);
/*
* An array of vectors of nodeHandlers, for handling each kind of node.
*/
extern nodeHandler *nodeDispatch[TREESTATE_NUM];
/* Function that produces a table of nodeHandlers for a given mode */
typedef nodeHandler *(*nodeHandlerFactory)();
extern nodeHandler *headerDispatch();
extern nodeHandler *typelibDispatch();
@ -82,13 +58,35 @@ extern nodeHandler *docDispatch();
*/
gboolean node_is_error(TreeState *state);
typedef struct ModeData {
char *mode;
char *modeInfo;
char *suffix;
nodeHandlerFactory factory;
} ModeData;
typedef struct IncludePathEntry {
char *directory;
struct IncludePathEntry *next;
} IncludePathEntry;
struct TreeState {
FILE *file;
char *basename;
IDL_ns ns;
IDL_tree tree;
GHashTable *includes;
IncludePathEntry *include_path;
nodeHandler *dispatch;
};
/*
* Process an IDL file, generating InterfaceInfo, documentation and headers as
* appropriate.
*/
int
xpidl_process_idl(char *filename, IncludePathEntry *include_path,
char *basename);
char *basename, ModeData *mode);
/*
* Iterate over an IDLN_LIST -- why is this not part of libIDL?
@ -106,5 +104,4 @@ void XPIDL_cleanup_on_error();
gboolean process_node(TreeState *state);
#endif /* __xpidl_h */

View File

@ -410,11 +410,6 @@ xpcom_param(TreeState *state)
IDL_tree param = state->tree;
state->tree = IDL_PARAM_DCL(param).param_type_spec;
/* in params that are pointers should be const */
if (STARRED_TYPE(state->tree) &&
IDL_PARAM_DCL(param).attr == IDL_PARAM_IN)
fputs("const ", state->file);
if (!xpcom_type(state))
return FALSE;
fprintf(state->file, "%s%s",

View File

@ -22,12 +22,6 @@
#include "xpidl.h"
FILE *typelib_file = NULL;
FILE *doc_file = NULL;
FILE *header_file = NULL;
nodeHandler *nodeDispatch[TREESTATE_NUM] = { NULL };
/*
* Pass 1 generates #includes for headers and the like.
*/
@ -36,7 +30,7 @@ process_tree_pass1(TreeState *state)
{
nodeHandler handler;
if ((handler = nodeDispatch[state->mode][0]))
if ((handler = state->dispatch[0]))
return handler(state);
return TRUE;
}
@ -66,7 +60,7 @@ gboolean
process_node(TreeState *state)
{
char *name = NULL;
nodeHandler *handlerp = nodeDispatch[state->mode], handler;
nodeHandler *handlerp = state->dispatch, handler;
gint type;
assert(state->tree);
@ -436,7 +430,7 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
int
xpidl_process_idl(char *filename, IncludePathEntry *include_path,
char *basename)
char *basename, ModeData *mode)
{
char *tmp, *outname, *mode_outname;
IDL_tree top;
@ -477,57 +471,28 @@ xpidl_process_idl(char *filename, IncludePathEntry *include_path,
state.includes = stack.includes;
state.include_path = include_path;
nodeDispatch[TREESTATE_HEADER] = headerDispatch();
nodeDispatch[TREESTATE_TYPELIB] = typelibDispatch();
nodeDispatch[TREESTATE_DOC] = docDispatch();
if (generate_headers) {
if (strcmp(outname, "-")) {
mode_outname = g_strdup_printf("%s.h", outname);
state.file = fopen(mode_outname, "w");
if (!state.file) {
perror("error opening output file");
free(mode_outname);
return 0;
}
free(mode_outname);
} else {
state.file = stdout;
state.dispatch = mode->factory();
if (!state.dispatch) {
/* XXX error */
return 0;
}
if (strcmp(outname, "-")) {
mode_outname = g_strdup_printf("%s.%s", outname, mode->suffix);
state.file = fopen(mode_outname, "w");
free(mode_outname);
if (!state.file) {
perror("error opening output file");
return 0;
}
state.mode = TREESTATE_HEADER;
state.tree = top;
ok = process_tree(&state);
if (state.file != stdout)
fclose(state.file);
if (!ok)
return 0;
}
if (generate_typelib) {
if (strcmp(basename, "-")) {
outname = g_strdup_printf("%s.xpt", basename);
state.file = fopen(outname, "wb");
if (!state.file) {
perror("error opening output file");
free(outname);
return 0;
}
} else {
state.file = stdout;
}
state.mode = TREESTATE_TYPELIB;
state.tree = top;
ok = process_tree(&state);
free(outname);
if (state.file != stdout)
fclose(state.file);
if (!ok)
return 0;
}
if (generate_docs) {
state.mode = TREESTATE_DOC;
state.tree = top;
if (!process_tree(&state))
return 0;
} else {
state.file = stdout;
}
state.tree = top;
ok = process_tree(&state);
if (state.file != stdout)
fclose(state.file);
if (!ok)
return 0;
free(state.basename);
free(outname);
/* g_hash_table_foreach(state.includes, free_name, NULL);