1998-12-03 09:33:59 +03:00
|
|
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
1998-11-28 19:52:24 +03:00
|
|
|
/*
|
|
|
|
* 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 XPCOM headers from XPIDL.
|
|
|
|
*/
|
|
|
|
|
1998-11-24 00:02:31 +03:00
|
|
|
#include "xpidl.h"
|
1999-02-08 20:47:44 +03:00
|
|
|
#include <ctype.h>
|
1998-11-24 00:02:31 +03:00
|
|
|
|
1998-11-28 19:52:24 +03:00
|
|
|
/* is this node from an aggregate type (interface)? */
|
1999-02-08 20:47:44 +03:00
|
|
|
#define UP_IS_AGGREGATE(node) \
|
|
|
|
(IDL_NODE_UP(node) && \
|
1998-11-28 19:52:24 +03:00
|
|
|
IDL_NODE_TYPE(IDL_NODE_UP(node)) == IDLN_INTERFACE)
|
|
|
|
|
1999-02-08 20:47:44 +03:00
|
|
|
#define UP_IS_NATIVE(node) \
|
|
|
|
(IDL_NODE_UP(node) && \
|
|
|
|
IDL_NODE_TYPE(IDL_NODE_UP(node)) == IDLN_NATIVE)
|
|
|
|
|
1998-11-27 00:03:03 +03:00
|
|
|
/* is this type output in the form "<foo> *"? */
|
1999-02-08 20:47:44 +03:00
|
|
|
#define STARRED_TYPE(node) (IDL_NODE_TYPE(node) == IDLN_TYPE_STRING || \
|
|
|
|
IDL_NODE_TYPE(node) == IDLN_TYPE_WIDE_STRING || \
|
|
|
|
(IDL_NODE_TYPE(node) == IDLN_IDENT && \
|
1998-11-28 19:52:24 +03:00
|
|
|
UP_IS_AGGREGATE(node)) )
|
1998-11-27 00:03:03 +03:00
|
|
|
|
1999-02-08 20:47:44 +03:00
|
|
|
#define IDL_OUTPUT_FLAGS (IDLF_OUTPUT_NO_NEWLINES | \
|
|
|
|
IDLF_OUTPUT_NO_QUALIFY_IDENTS | \
|
|
|
|
IDLF_OUTPUT_PROPERTIES)
|
|
|
|
|
1999-01-11 19:56:45 +03:00
|
|
|
static void
|
|
|
|
dump_IDL(TreeState *state)
|
|
|
|
{
|
1999-02-08 20:47:44 +03:00
|
|
|
IDL_tree_to_IDL(state->tree, state->ns, state->file, IDL_OUTPUT_FLAGS);
|
1999-01-11 19:56:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#define DUMP_IDL_COMMENT(state) \
|
|
|
|
fputs("\n /* ", state->file); \
|
|
|
|
dump_IDL(state); \
|
|
|
|
fputs(" */\n", state->file);
|
|
|
|
|
1998-11-27 00:03:03 +03:00
|
|
|
static void
|
|
|
|
write_header(gpointer key, gpointer value, gpointer user_data)
|
|
|
|
{
|
1998-12-06 21:41:44 +03:00
|
|
|
char *ident = (char *)value;
|
1998-11-27 00:03:03 +03:00
|
|
|
TreeState *state = (TreeState *)user_data;
|
|
|
|
fprintf(state->file, "#include \"%s.h\" /* interface %s */\n",
|
1998-12-03 09:33:59 +03:00
|
|
|
ident, ident);
|
1998-11-27 00:03:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
pass_1(TreeState *state)
|
|
|
|
{
|
1998-12-06 21:41:44 +03:00
|
|
|
if (state->tree) {
|
1999-02-09 18:30:31 +03:00
|
|
|
char *define = g_basename(state->basename);
|
1998-12-06 21:41:44 +03:00
|
|
|
fprintf(state->file, "/*\n * DO NOT EDIT. THIS FILE IS GENERATED FROM"
|
|
|
|
" %s.idl\n */\n", state->basename);
|
1999-01-11 19:56:45 +03:00
|
|
|
fprintf(state->file, "\n#ifndef __gen_%s_h__\n"
|
|
|
|
"#define __gen_%s_h__\n\n",
|
1999-02-09 18:30:31 +03:00
|
|
|
define, define);
|
1998-12-06 22:52:21 +03:00
|
|
|
if (g_hash_table_size(state->includes)) {
|
|
|
|
g_hash_table_foreach(state->includes, write_header, state);
|
|
|
|
fputc('\n', state->file);
|
|
|
|
}
|
1998-12-06 21:41:44 +03:00
|
|
|
} else {
|
1999-01-11 19:56:45 +03:00
|
|
|
fprintf(state->file, "\n#endif /* __gen_%s_h__ */\n", state->basename);
|
1998-12-06 21:41:44 +03:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
output_classname_iid_define(FILE *file, const char *className)
|
|
|
|
{
|
|
|
|
const char *iidName;
|
|
|
|
if (className[0] == 'n' && className[1] == 's') {
|
|
|
|
/* backcompat naming styles */
|
|
|
|
fputs("NS_", file);
|
|
|
|
iidName = className + 2;
|
|
|
|
} else {
|
|
|
|
iidName = className;
|
|
|
|
}
|
|
|
|
while (*iidName)
|
|
|
|
fputc(toupper(*iidName++), file);
|
|
|
|
fputs("_IID", file);
|
1998-11-27 00:03:03 +03:00
|
|
|
return TRUE;
|
|
|
|
}
|
1998-11-24 00:02:31 +03:00
|
|
|
|
|
|
|
static gboolean
|
|
|
|
interface(TreeState *state)
|
|
|
|
{
|
1998-11-27 00:03:03 +03:00
|
|
|
IDL_tree iface = state->tree, iter;
|
1998-12-03 09:33:59 +03:00
|
|
|
char *className = IDL_IDENT(IDL_INTERFACE(iface).ident).str;
|
|
|
|
const char *iid;
|
1998-11-27 00:03:03 +03:00
|
|
|
|
1999-01-11 19:56:45 +03:00
|
|
|
fprintf(state->file, "\n/* starting interface %s */\n",
|
1998-12-03 09:33:59 +03:00
|
|
|
className);
|
1998-12-09 16:08:29 +03:00
|
|
|
iid = IDL_tree_property_get(iface, "uuid");
|
1998-12-03 09:33:59 +03:00
|
|
|
if (iid) {
|
|
|
|
/* XXX use nsID parsing routines to validate? */
|
|
|
|
if (strlen(iid) != 36)
|
|
|
|
/* XXX report error */
|
|
|
|
return FALSE;
|
1998-12-14 21:47:39 +03:00
|
|
|
fprintf(state->file, "\n/* {%s} */\n#define ", iid);
|
1998-12-06 21:41:44 +03:00
|
|
|
if (!output_classname_iid_define(state->file, className))
|
|
|
|
return FALSE;
|
1998-12-14 21:47:39 +03:00
|
|
|
fprintf(state->file, "_STR \"%s\"\n#define ", iid);
|
1998-12-06 21:41:44 +03:00
|
|
|
if (!output_classname_iid_define(state->file, className))
|
|
|
|
return FALSE;
|
1998-12-03 09:33:59 +03:00
|
|
|
/* This is such a gross hack... */
|
1998-12-06 21:41:44 +03:00
|
|
|
fprintf(state->file, " \\\n {0x%.8s, 0x%.4s, 0x%.4s, \\\n "
|
1998-12-03 09:33:59 +03:00
|
|
|
"{ 0x%.2s, 0x%.2s, 0x%.2s, 0x%.2s, "
|
|
|
|
"0x%.2s, 0x%.2s, 0x%.2s, 0x%.2s }}\n\n",
|
|
|
|
iid, iid + 9, iid + 14, iid + 19, iid + 21, iid + 24,
|
|
|
|
iid + 26, iid + 28, iid + 30, iid + 32, iid + 34);
|
|
|
|
}
|
|
|
|
fprintf(state->file, "class %s", className);
|
1998-11-27 00:03:03 +03:00
|
|
|
if ((iter = IDL_INTERFACE(iface).inheritance_spec)) {
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs(" : ", state->file);
|
|
|
|
for (; iter; iter = IDL_LIST(iter).next) {
|
1999-01-11 19:56:45 +03:00
|
|
|
fprintf(state->file, "public %s",
|
|
|
|
IDL_IDENT(IDL_LIST(iter).data).str);
|
1998-12-03 09:33:59 +03:00
|
|
|
if (IDL_LIST(iter).next)
|
|
|
|
fputs(", ", state->file);
|
|
|
|
}
|
1998-11-27 00:03:03 +03:00
|
|
|
}
|
1998-12-14 21:47:39 +03:00
|
|
|
fputs(" {\n"
|
|
|
|
" public: \n"
|
|
|
|
" static const nsIID& IID() {\n"
|
|
|
|
" static nsIID iid = ",
|
|
|
|
state->file);
|
|
|
|
if (!output_classname_iid_define(state->file, className))
|
|
|
|
return FALSE;
|
|
|
|
fputs(";\n return iid;\n }\n", state->file);
|
|
|
|
|
1998-11-27 00:03:03 +03:00
|
|
|
state->tree = IDL_INTERFACE(iface).body;
|
1998-11-25 02:16:49 +03:00
|
|
|
|
1999-02-16 08:10:40 +03:00
|
|
|
if (state->tree && !xpidl_process_node(state))
|
1998-12-03 09:33:59 +03:00
|
|
|
return FALSE;
|
1998-11-25 02:16:49 +03:00
|
|
|
|
1998-12-14 21:47:39 +03:00
|
|
|
fputs("};\n", state->file);
|
1998-11-25 02:16:49 +03:00
|
|
|
|
|
|
|
return TRUE;
|
1998-11-24 00:02:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
list(TreeState *state)
|
|
|
|
{
|
|
|
|
IDL_tree iter;
|
|
|
|
for (iter = state->tree; iter; iter = IDL_LIST(iter).next) {
|
1998-12-03 09:33:59 +03:00
|
|
|
state->tree = IDL_LIST(iter).data;
|
1999-02-16 08:10:40 +03:00
|
|
|
if (!xpidl_process_node(state))
|
1998-12-03 09:33:59 +03:00
|
|
|
return FALSE;
|
1998-11-24 00:02:31 +03:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
1998-11-25 02:16:49 +03:00
|
|
|
static gboolean
|
|
|
|
xpcom_type(TreeState *state)
|
|
|
|
{
|
|
|
|
if (!state->tree) {
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("void", state->file);
|
|
|
|
return TRUE;
|
1998-11-25 02:16:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
switch(IDL_NODE_TYPE(state->tree)) {
|
|
|
|
case IDLN_TYPE_INTEGER: {
|
1998-12-03 09:33:59 +03:00
|
|
|
gboolean sign = IDL_TYPE_INTEGER(state->tree).f_signed;
|
|
|
|
switch (IDL_TYPE_INTEGER(state->tree).f_type) {
|
|
|
|
case IDL_INTEGER_TYPE_SHORT:
|
|
|
|
fputs(sign ? "PRInt16" : "PRUint16", state->file);
|
|
|
|
break;
|
|
|
|
case IDL_INTEGER_TYPE_LONG:
|
|
|
|
fputs(sign ? "PRInt32" : "PRUint32", state->file);
|
|
|
|
break;
|
|
|
|
case IDL_INTEGER_TYPE_LONGLONG:
|
|
|
|
fputs(sign ? "PRInt64" : "PRUint64", state->file);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_error("Unknown integer type %d\n",
|
|
|
|
IDL_TYPE_INTEGER(state->tree).f_type);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
break;
|
1998-11-25 02:16:49 +03:00
|
|
|
}
|
1998-11-25 22:12:50 +03:00
|
|
|
case IDLN_TYPE_CHAR:
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("char", state->file);
|
|
|
|
break;
|
1998-11-25 22:12:50 +03:00
|
|
|
case IDLN_TYPE_WIDE_CHAR:
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("PRUint16", state->file); /* wchar_t? */
|
|
|
|
break;
|
1998-11-25 22:12:50 +03:00
|
|
|
case IDLN_TYPE_WIDE_STRING:
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("PRUnichar *", state->file);
|
|
|
|
break;
|
1998-11-25 02:16:49 +03:00
|
|
|
case IDLN_TYPE_STRING:
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("char *", state->file);
|
|
|
|
break;
|
1998-11-25 02:16:49 +03:00
|
|
|
case IDLN_TYPE_BOOLEAN:
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("PRBool", state->file);
|
|
|
|
break;
|
1998-11-25 02:16:49 +03:00
|
|
|
case IDLN_IDENT:
|
1999-02-08 20:47:44 +03:00
|
|
|
if (UP_IS_NATIVE(state->tree)) {
|
|
|
|
fputs(IDL_NATIVE(IDL_NODE_UP(state->tree)).user_type, state->file);
|
|
|
|
} else {
|
|
|
|
fputs(IDL_IDENT(state->tree).str, state->file);
|
|
|
|
}
|
1998-12-03 09:33:59 +03:00
|
|
|
if (UP_IS_AGGREGATE(state->tree))
|
|
|
|
fputs(" *", state->file);
|
|
|
|
break;
|
1998-11-25 02:16:49 +03:00
|
|
|
default:
|
1998-12-03 09:33:59 +03:00
|
|
|
fprintf(state->file, "unknown_type_%d", IDL_NODE_TYPE(state->tree));
|
|
|
|
break;
|
1998-11-25 02:16:49 +03:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
1998-11-24 00:02:31 +03:00
|
|
|
static gboolean
|
|
|
|
type_integer(TreeState *state)
|
|
|
|
{
|
|
|
|
IDL_tree p = state->tree;
|
|
|
|
|
|
|
|
if (!IDL_TYPE_INTEGER(p).f_signed)
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("unsigned ", state->file);
|
1998-11-24 00:02:31 +03:00
|
|
|
|
|
|
|
switch(IDL_TYPE_INTEGER(p).f_type) {
|
|
|
|
case IDL_INTEGER_TYPE_SHORT:
|
1998-12-03 09:33:59 +03:00
|
|
|
printf("short");
|
|
|
|
break;
|
1998-11-24 00:02:31 +03:00
|
|
|
case IDL_INTEGER_TYPE_LONG:
|
1998-12-03 09:33:59 +03:00
|
|
|
printf("long");
|
|
|
|
break;
|
1998-11-24 00:02:31 +03:00
|
|
|
case IDL_INTEGER_TYPE_LONGLONG:
|
1998-12-03 09:33:59 +03:00
|
|
|
printf("long long");
|
|
|
|
break;
|
1998-11-24 00:02:31 +03:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
type(TreeState *state)
|
|
|
|
{
|
|
|
|
if (!state->tree) {
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("void", state->file);
|
|
|
|
return TRUE;
|
1998-11-24 00:02:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
switch(IDL_NODE_TYPE(state->tree)) {
|
|
|
|
case IDLN_TYPE_INTEGER:
|
1998-12-03 09:33:59 +03:00
|
|
|
return type_integer(state);
|
1998-11-24 00:02:31 +03:00
|
|
|
case IDLN_TYPE_STRING:
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("string", state->file);
|
|
|
|
return TRUE;
|
1998-11-25 22:12:50 +03:00
|
|
|
case IDLN_TYPE_WIDE_STRING:
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("wstring", state->file);
|
|
|
|
return TRUE;
|
1998-11-25 22:12:50 +03:00
|
|
|
case IDLN_TYPE_CHAR:
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("char", state->file);
|
|
|
|
return TRUE;
|
1998-11-25 22:12:50 +03:00
|
|
|
case IDLN_TYPE_WIDE_CHAR:
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("wchar", state->file);
|
|
|
|
return TRUE;
|
1998-11-25 02:16:49 +03:00
|
|
|
case IDLN_TYPE_BOOLEAN:
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs("boolean", state->file);
|
|
|
|
return TRUE;
|
1998-11-28 19:52:24 +03:00
|
|
|
case IDLN_IDENT:
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs(IDL_IDENT(state->tree).str, state->file);
|
|
|
|
break;
|
1998-11-24 00:02:31 +03:00
|
|
|
default:
|
1998-12-03 09:33:59 +03:00
|
|
|
fprintf(state->file, "unknown_type_%d", IDL_NODE_TYPE(state->tree));
|
|
|
|
return TRUE;
|
1998-11-24 00:02:31 +03:00
|
|
|
}
|
1999-02-08 20:47:44 +03:00
|
|
|
|
|
|
|
return TRUE;
|
1998-11-24 00:02:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
param_dcls(TreeState *state)
|
|
|
|
{
|
|
|
|
IDL_tree iter;
|
1998-11-25 07:19:59 +03:00
|
|
|
fputs("(", state->file);
|
1998-11-24 00:02:31 +03:00
|
|
|
for (iter = state->tree; iter; iter = IDL_LIST(iter).next) {
|
1998-12-03 09:33:59 +03:00
|
|
|
struct _IDL_PARAM_DCL decl = IDL_PARAM_DCL(IDL_LIST(iter).data);
|
|
|
|
switch(decl.attr) {
|
|
|
|
case IDL_PARAM_IN:
|
|
|
|
fputs("in ", state->file);
|
|
|
|
break;
|
|
|
|
case IDL_PARAM_OUT:
|
|
|
|
fputs("out ", state->file);
|
|
|
|
break;
|
|
|
|
case IDL_PARAM_INOUT:
|
|
|
|
fputs("inout ", state->file);
|
|
|
|
break;
|
|
|
|
default:;
|
|
|
|
}
|
|
|
|
state->tree = (IDL_tree)decl.param_type_spec;
|
|
|
|
if (!type(state))
|
|
|
|
return FALSE;
|
|
|
|
fputs(" ", state->file);
|
|
|
|
state->tree = (IDL_tree)decl.simple_declarator;
|
1999-02-16 08:10:40 +03:00
|
|
|
if (!xpidl_process_node(state))
|
1998-12-03 09:33:59 +03:00
|
|
|
return FALSE;
|
|
|
|
if (IDL_LIST(iter).next)
|
|
|
|
fputs(", ", state->file);
|
1998-11-25 02:16:49 +03:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* An attribute declaration looks like:
|
|
|
|
*
|
|
|
|
* [ IDL_ATTR_DCL]
|
|
|
|
* - param_type_spec [IDL_TYPE_* or NULL for void]
|
|
|
|
* - simple_declarations [IDL_LIST]
|
|
|
|
* - data [IDL_IDENT]
|
|
|
|
* - next [IDL_LIST or NULL if no more idents]
|
|
|
|
* - data [IDL_IDENT]
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ATTR_IDENT(tree) (IDL_IDENT(IDL_LIST(IDL_ATTR_DCL(tree).simple_declarations).data))
|
|
|
|
#define ATTR_TYPE_DECL(tree) (IDL_ATTR_DCL(tree).param_type_spec)
|
|
|
|
#define ATTR_TYPE(tree) (IDL_NODE_TYPE(ATTR_TYPE_DECL(tree)))
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
attr_accessor(TreeState *state, gboolean getter)
|
|
|
|
{
|
|
|
|
char *attrname = ATTR_IDENT(state->tree).str;
|
1998-12-03 09:33:59 +03:00
|
|
|
IDL_tree orig = state->tree;
|
|
|
|
fprintf(state->file, " NS_IMETHOD %cet%c%s(",
|
|
|
|
getter ? 'G' : 'S',
|
|
|
|
toupper(attrname[0]), attrname + 1);
|
|
|
|
state->tree = ATTR_TYPE_DECL(state->tree);
|
|
|
|
if (!xpcom_type(state))
|
|
|
|
return FALSE;
|
|
|
|
state->tree = orig;
|
1998-12-03 20:38:55 +03:00
|
|
|
fprintf(state->file, "%s%sa%c%s) = 0;\n",
|
1998-12-03 09:33:59 +03:00
|
|
|
(STARRED_TYPE(orig) ? "" : " "),
|
|
|
|
getter ? "*" : "",
|
|
|
|
toupper(attrname[0]), attrname + 1);
|
1998-11-24 00:02:31 +03:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
attr_dcl(TreeState *state)
|
|
|
|
{
|
1998-11-25 02:16:49 +03:00
|
|
|
gboolean ro = IDL_ATTR_DCL(state->tree).f_readonly;
|
1999-01-11 19:56:45 +03:00
|
|
|
DUMP_IDL_COMMENT(state);
|
1998-11-25 02:16:49 +03:00
|
|
|
return attr_accessor(state, TRUE) && (ro || attr_accessor(state, FALSE));
|
1998-11-24 00:02:31 +03:00
|
|
|
}
|
|
|
|
|
1998-11-28 19:52:24 +03:00
|
|
|
static gboolean
|
|
|
|
do_enum(TreeState *state)
|
|
|
|
{
|
|
|
|
IDL_tree enumb = state->tree, iter;
|
1999-02-16 08:10:40 +03:00
|
|
|
|
1998-12-06 22:52:21 +03:00
|
|
|
fprintf(state->file, "enum %s {\n",
|
1998-12-03 09:33:59 +03:00
|
|
|
IDL_IDENT(IDL_TYPE_ENUM(enumb).ident).str);
|
1998-11-28 19:52:24 +03:00
|
|
|
|
|
|
|
for (iter = IDL_TYPE_ENUM(enumb).enumerator_list;
|
1998-12-03 09:33:59 +03:00
|
|
|
iter; iter = IDL_LIST(iter).next)
|
|
|
|
fprintf(state->file, " %s%s\n", IDL_IDENT(IDL_LIST(iter).data).str,
|
|
|
|
IDL_LIST(iter).next ? ",": "");
|
1998-11-28 19:52:24 +03:00
|
|
|
|
1998-12-06 22:52:21 +03:00
|
|
|
fputs("};\n\n", state->file);
|
1998-11-28 19:52:24 +03:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
1999-01-11 19:56:45 +03:00
|
|
|
static gboolean
|
|
|
|
do_typedef(TreeState *state)
|
|
|
|
{
|
|
|
|
IDL_tree type = IDL_TYPE_DCL(state->tree).type_spec,
|
|
|
|
dcls = IDL_TYPE_DCL(state->tree).dcls,
|
|
|
|
complex;
|
|
|
|
fputs("typedef ", state->file);
|
|
|
|
fputs(" ", state->file);
|
|
|
|
|
|
|
|
if (IDL_NODE_TYPE(type) == IDLN_TYPE_SEQUENCE) {
|
|
|
|
fprintf(stderr, "SEQUENCE!\n");
|
|
|
|
} else {
|
|
|
|
state->tree = type;
|
|
|
|
if (!xpcom_type(state))
|
|
|
|
return FALSE;
|
|
|
|
if (IDL_NODE_TYPE(complex = IDL_LIST(dcls).data) == IDLN_TYPE_ARRAY) {
|
1999-02-08 20:47:44 +03:00
|
|
|
fprintf(state->file, "%s[%ld]",
|
1999-01-11 19:56:45 +03:00
|
|
|
IDL_IDENT(IDL_TYPE_ARRAY(complex).ident).str,
|
1999-02-08 20:47:44 +03:00
|
|
|
(long)IDL_INTEGER(IDL_LIST(IDL_TYPE_ARRAY(complex).size_list).
|
1999-01-11 19:56:45 +03:00
|
|
|
data).value);
|
|
|
|
} else {
|
|
|
|
fputs(IDL_IDENT(IDL_LIST(dcls).data).str, state->file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fputs(";\n", state->file);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
1998-11-25 07:19:59 +03:00
|
|
|
/*
|
|
|
|
* param generation:
|
1998-12-03 09:33:59 +03:00
|
|
|
* in string foo --> nsString *foo
|
|
|
|
* out string foo --> nsString **foo;
|
|
|
|
* inout string foo --> nsString **foo;
|
1998-11-25 07:19:59 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
xpcom_param(TreeState *state)
|
|
|
|
{
|
|
|
|
IDL_tree param = state->tree;
|
|
|
|
state->tree = IDL_PARAM_DCL(param).param_type_spec;
|
1998-11-27 00:03:03 +03:00
|
|
|
|
1998-11-25 07:19:59 +03:00
|
|
|
if (!xpcom_type(state))
|
1998-12-03 09:33:59 +03:00
|
|
|
return FALSE;
|
1998-11-25 22:12:50 +03:00
|
|
|
fprintf(state->file, "%s%s",
|
1998-12-03 09:33:59 +03:00
|
|
|
STARRED_TYPE(state->tree) ? "" : " ",
|
|
|
|
IDL_PARAM_DCL(param).attr == IDL_PARAM_IN ? "" : "*");
|
1998-11-25 07:19:59 +03:00
|
|
|
fprintf(state->file, "%s",
|
1998-12-03 09:33:59 +03:00
|
|
|
IDL_IDENT(IDL_PARAM_DCL(param).simple_declarator).str);
|
1998-11-25 07:19:59 +03:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
1998-11-24 00:02:31 +03:00
|
|
|
/*
|
|
|
|
* A method is an `operation', therefore a method decl is an `op dcl'.
|
|
|
|
* I blame Elliot.
|
|
|
|
*/
|
|
|
|
static gboolean
|
|
|
|
op_dcl(TreeState *state)
|
|
|
|
{
|
|
|
|
struct _IDL_OP_DCL op = IDL_OP_DCL(state->tree);
|
1998-11-25 07:19:59 +03:00
|
|
|
IDL_tree iter;
|
1999-01-11 19:56:45 +03:00
|
|
|
|
|
|
|
DUMP_IDL_COMMENT(state);
|
1998-11-25 07:19:59 +03:00
|
|
|
|
|
|
|
fprintf(state->file, " NS_IMETHOD %s(", IDL_IDENT(op.ident).str);
|
|
|
|
for (iter = op.parameter_dcls; iter; iter = IDL_LIST(iter).next) {
|
1998-12-03 09:33:59 +03:00
|
|
|
state->tree = IDL_LIST(iter).data;
|
|
|
|
if (!xpcom_param(state))
|
|
|
|
return FALSE;
|
1998-12-06 22:52:21 +03:00
|
|
|
if (IDL_LIST(iter).next || op.op_type_spec || op.f_varargs)
|
1998-12-03 09:33:59 +03:00
|
|
|
fputs(", ", state->file);
|
1998-11-25 07:19:59 +03:00
|
|
|
}
|
1998-12-06 22:52:21 +03:00
|
|
|
|
|
|
|
/* make IDL return value into trailing out argument */
|
|
|
|
if (op.op_type_spec) {
|
|
|
|
IDL_tree fake_param = IDL_param_dcl_new(IDL_PARAM_OUT,
|
|
|
|
op.op_type_spec,
|
|
|
|
IDL_ident_new("_retval"));
|
|
|
|
if (!fake_param)
|
|
|
|
return FALSE;
|
|
|
|
state->tree = fake_param;
|
|
|
|
if (!xpcom_param(state))
|
|
|
|
return FALSE;
|
|
|
|
if (op.f_varargs)
|
|
|
|
fputs(", ", state->file);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* varargs go last */
|
|
|
|
if (op.f_varargs) {
|
1999-01-11 19:56:45 +03:00
|
|
|
fputs("nsVarArgs *_varargs", state->file);
|
1998-12-06 22:52:21 +03:00
|
|
|
}
|
1998-11-25 22:12:50 +03:00
|
|
|
fputs(") = 0;\n", state->file);
|
1998-11-24 00:02:31 +03:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
1998-12-14 21:47:39 +03:00
|
|
|
static void
|
|
|
|
dump_codefrag_line(gpointer data, gpointer user_data)
|
|
|
|
{
|
|
|
|
TreeState *state = (TreeState *)user_data;
|
|
|
|
char *line = (char *)data;
|
|
|
|
fputs(line, state->file);
|
|
|
|
fputc('\n', state->file);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
codefrag(TreeState *state)
|
|
|
|
{
|
|
|
|
if (strcmp(IDL_CODEFRAG(state->tree).desc, "C++"))
|
|
|
|
return TRUE;
|
|
|
|
g_slist_foreach(IDL_CODEFRAG(state->tree).lines, dump_codefrag_line,
|
|
|
|
(gpointer)state);
|
|
|
|
fputc('\n', state->file);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
1999-02-16 08:10:40 +03:00
|
|
|
nodeHandler *xpidl_header_dispatch()
|
1998-12-02 22:53:27 +03:00
|
|
|
{
|
1998-12-03 09:33:59 +03:00
|
|
|
static nodeHandler table[IDLN_LAST];
|
|
|
|
static gboolean initialized = FALSE;
|
|
|
|
|
|
|
|
if (!initialized) {
|
|
|
|
table[IDLN_NONE] = pass_1;
|
|
|
|
table[IDLN_LIST] = list;
|
|
|
|
table[IDLN_ATTR_DCL] = attr_dcl;
|
|
|
|
table[IDLN_OP_DCL] = op_dcl;
|
|
|
|
table[IDLN_PARAM_DCL] = param_dcls;
|
|
|
|
table[IDLN_TYPE_ENUM] = do_enum;
|
|
|
|
table[IDLN_INTERFACE] = interface;
|
1998-12-14 21:47:39 +03:00
|
|
|
table[IDLN_CODEFRAG] = codefrag;
|
1999-01-11 19:56:45 +03:00
|
|
|
table[IDLN_TYPE_DCL] = do_typedef;
|
1998-12-03 09:33:59 +03:00
|
|
|
initialized = TRUE;
|
|
|
|
}
|
1999-02-16 08:10:40 +03:00
|
|
|
|
|
|
|
return table;
|
1998-12-02 22:53:27 +03:00
|
|
|
}
|