/*
* Copyright (c) 1995, 1996, 1997, 1999 The University of Utah and
* the Computer Systems Laboratory at the University of Utah (CSL).
*
* This file is part of Flick, the Flexible IDL Compiler Kit.
*
* Flick is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Flick is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Flick; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place #330, Boston, MA 02111, USA.
*/
/* aoid.cc - aoid, the AOI file ASCII-output pretty printer */
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h> // POSIX string funcs
#include <ctype.h> // External functions
#include <assert.h>
#include <mom/libmeta.h>
#include <mom/compiler.h>
#include <mom/libaoi.h>
aoi the_aoi;
char *progname;
FILE *output_file;
/* The following is for printing the AOI tree
* ------------------------------------------
* (moved from mom/fe/corba/be_produce.cc to mom/util/aoid)
*/
static int indent;
const int ISPC = 2;
static void print_node(aoi_type node);
static void i_printf(const char *format, ...)
{
int i;
va_list vl;
va_start(vl, format);
for (i=0; i<indent; i++)
fprintf(output_file, " ");
fflush(output_file);
vfprintf(output_file, format, vl);
va_end(vl);
fflush(output_file);
}
static const char *aoi_kind_str(aoi_kind kind)
{
switch (kind) {
case AOI_INDIRECT:
return "AOI_INDIRECT";
case AOI_INTEGER:
return "AOI_INTEGER";
case AOI_SCALAR:
return "AOI_SCALAR";
case AOI_FLOAT:
return "AOI_FLOAT";
case AOI_CHAR:
return "AOI_CHAR";
case AOI_ARRAY:
return "AOI_ARRAY";
case AOI_STRUCT:
return "AOI_STRUCT";
case AOI_UNION:
return "AOI_UNION";
case AOI_INTERFACE:
return "AOI_INTERFACE";
case AOI_EXCEPTION:
return "AOI_EXCEPTION";
case AOI_ENUM:
return "AOI_ENUM";
case AOI_VOID:
return "AOI_VOID";
case AOI_CONST:
return "AOI_CONST";
case AOI_NAMESPACE:
return "AOI_NAMESPACE";
case AOI_OPTIONAL:
return "AOI_OPTIONAL";
case AOI_FWD_INTRFC:
return "AOI_FWD_INTRFC";
case AOI_ANY:
return "AOI_ANY";
case AOI_TYPE_TAG:
return "AOI_TYPE_TAG";
case AOI_TYPED:
return "AOI_TYPED";
case AOI_ERROR:
return "AOI_ERROR";
default:
return "(invalid AOI type)";
}
}
static void print_op_flags(aoi_op_flags op_flags)
{
int old_indent = indent;
/*
* Output the proper indentation; we subtract 1 because we always
* output a leading space.
*/
indent += ISPC - 1;
i_printf("");
/* Disable indentation for the rest of our output. */
indent = 0;
/* One `if' for each possible flag. */
if (op_flags & AOI_OP_FLAG_ONEWAY)
i_printf(" oneway");
if (op_flags & AOI_OP_FLAG_IDEMPOTENT)
i_printf(" idempotent");
/* If there are no flags, say so. */
if (op_flags == AOI_OP_FLAG_NONE)
i_printf(" none");
i_printf("\n");
indent = old_indent;
}
static void print_const(aoi_const con, int doindent);
static void print_attrib(aoi_attribute *att)
{
indent += ISPC;
i_printf("name = \"%s\" (%s)\n",
att->name,
att->readonly ? "readonly" : "readwrite");
i_printf("type:\n");
print_node(att->type);
i_printf("read request:\n");
print_const(att->read_request_code, 1);
i_printf("read reply:\n");
print_const(att->read_reply_code, 1);
if (!att->readonly) {
i_printf("write request:\n");
print_const(att->write_request_code, 1);
i_printf("write reply:\n");
print_const(att->write_reply_code, 1);
}
indent -= ISPC;
}
static void print_parameter(aoi_parameter *param)
{
indent += ISPC;
i_printf("name = \"%s\"\n", param->name);
i_printf("direction = %s%s\n",
(param->direction & 0x1)? "IN" : "",
(param->direction & 0x2)? "OUT" : "");
i_printf("type = \n");
print_node(param->type);
indent -= ISPC;
}
static void print_operation(aoi_operation *op)
{
u_int i;
indent += ISPC;
i_printf("operation name: \"%s\"\n", op->name);
i_printf("flags:\n");
print_op_flags(op->flags);
i_printf("params:\n");
for (i = 0; i < op->params.params_len; i++) {
i_printf("#%d - ",i);
print_parameter(&op->params.params_val[i]);
}
i_printf("return type:\n");
print_node(op->return_type);
i_printf("exceptions:\n");
for (i = 0; i < op->exceps.exceps_len; i++)
print_node(op->exceps.exceps_val[i]);
i_printf("request code:\n");
print_const(op->request_code, 1);
i_printf("reply code:\n");
print_const(op->reply_code, 1);
indent -= ISPC;
}
static void print_field(aoi_field *field)
{
indent += ISPC;
i_printf("name = \"%s\", type:\n", field->name);
print_node(field->type);
indent -= ISPC;
}
static void print_const(aoi_const con, int doindent)
{
u_int i;
if (doindent)
indent += ISPC;
switch (con->kind) {
case AOI_CONST_INT:
i_printf("<%d>\n", con->aoi_const_u_u.const_int);
break;
case AOI_CONST_CHAR:
i_printf(((con->aoi_const_u_u.const_char == '\'') ? "'\\%c'\n" :
(con->aoi_const_u_u.const_char == '\\') ? "'\\%c'\n" :
isprint(con->aoi_const_u_u.const_char) ? "'%c'\n" :
/* Otherwise, print in octal notation. */
"'\\%03d'\n"),
con->aoi_const_u_u.const_char);
break;
case AOI_CONST_FLOAT:
i_printf("[%lf]\n", con->aoi_const_u_u.const_float);
break;
case AOI_CONST_STRUCT:
i_printf("CONST_STRUCT:\n");
for (i = 0;
i < con->aoi_const_u_u.const_struct.aoi_const_struct_len;
i++) {
i_printf("#%d - ", i);
print_const((con->aoi_const_u_u.const_struct.
aoi_const_struct_val[i]),
0);
}
break;
case AOI_CONST_ARRAY:
i_printf("CONST_ARRAY:\n");
for (i = 0;
i < con->aoi_const_u_u.const_array.aoi_const_array_len;
i++) {
i_printf("#%d - ", i);
print_const((con->aoi_const_u_u.const_array.
aoi_const_array_val[i]),
0);
}
break;
default:
panic("unknown const kind");
}
if (doindent)
indent -= ISPC;
}
static void print_item(aoi_def *n, int slot); /* declaration, for reference in print_node() */
static void print_node(aoi_type node)
{
u_int i;
indent += ISPC;
i_printf("kind = %s\n", aoi_kind_str(node->kind));
switch (node->kind) {
case AOI_INDIRECT: {
aoi_ref ref = node->aoi_type_u_u.indirect_ref;
i_printf("reference to slot #%d - \"%s\"\n", ref,
the_aoi.defs.defs_val[ref].name);
break;
}
case AOI_INTEGER:
i_printf("integer %d-%u\n",
node->aoi_type_u_u.integer_def.min,
(u_int) node->aoi_type_u_u.integer_def.min +
(u_int) node->aoi_type_u_u.integer_def.range);
break;
case AOI_SCALAR:
i_printf("%s%d bit scalar\n",
((node->aoi_type_u_u.scalar_def.flags ==
AOI_SCALAR_FLAG_NONE) ? "" :
(node->aoi_type_u_u.scalar_def.flags ==
AOI_SCALAR_FLAG_SIGNED) ? "signed " :
(node->aoi_type_u_u.scalar_def.flags ==
AOI_SCALAR_FLAG_UNSIGNED) ? "unsigned " :
"incorrectly-flagged "),
node->aoi_type_u_u.scalar_def.bits);
break;
case AOI_FLOAT:
i_printf("%d bit float\n",
node->aoi_type_u_u.float_def.bits);
break;
case AOI_CHAR:
i_printf("%s%d bit char\n",
((node->aoi_type_u_u.char_def.flags ==
AOI_CHAR_FLAG_NONE) ? "" :
(node->aoi_type_u_u.char_def.flags ==
AOI_CHAR_FLAG_SIGNED) ? "signed " :
(node->aoi_type_u_u.char_def.flags ==
AOI_CHAR_FLAG_UNSIGNED) ? "unsigned " :
"incorrectly-flagged "),
node->aoi_type_u_u.char_def.bits);
break;
case AOI_ARRAY:
i_printf("array with length_type:\n");
print_node(node->aoi_type_u_u.array_def.length_type);
i_printf("of:\n");
print_node(node->aoi_type_u_u.array_def.element_type);
i_printf("flags:\n");
if (node->aoi_type_u_u.array_def.flgs == AOI_ARRAY_FLAG_NONE)
i_printf("AOI_ARRAY_FLAG_NONE\n");
if (node->aoi_type_u_u.array_def.flgs &
AOI_ARRAY_FLAG_NULL_TERMINATED_STRING)
i_printf("AOI_ARRAY_FLAG_NULL_TERMINATED_STRING\n");
if (node->aoi_type_u_u.array_def.flgs & AOI_ARRAY_FLAG_OPAQUE)
i_printf("AOI_ARRAY_FLAG_OPAQUE\n");
break;
case AOI_STRUCT:
i_printf("slots:\n");
for (i = 0;
i < node->aoi_type_u_u.struct_def.slots.slots_len;
i++) {
i_printf("#%d name = \"%s\", type: \n",
i,
(node->aoi_type_u_u.struct_def.slots.
slots_val[i].name));
print_node(node->aoi_type_u_u.struct_def.slots.
slots_val[i].type);
}
break;
case AOI_UNION:
i_printf("discriminator:\n");
print_field(&node->aoi_type_u_u.union_def.discriminator);
i_printf("union name: '%s'\n",
node->aoi_type_u_u.union_def.union_label);
for (i = 0; i < node->aoi_type_u_u.union_def.cases.cases_len;
i++) {
i_printf("#%d value: ", i);
print_const((node->aoi_type_u_u.union_def.cases.
cases_val[i].val),
0);
i_printf("#%d var: ", i);
print_field(&(node->aoi_type_u_u.union_def.cases.
cases_val[i].var));
}
if (node->aoi_type_u_u.union_def.dfault) {
i_printf("default var = \n");
print_field(node->aoi_type_u_u.union_def.dfault);
}
break;
case AOI_INTERFACE:
i_printf("code:\n");
print_const(node->aoi_type_u_u.interface_def.code, 1);
i_printf("parents:\n");
for (i = 0;
i < node->aoi_type_u_u.interface_def.parents.parents_len;
i++)
print_node(node->aoi_type_u_u.interface_def.parents.
parents_val[i]);
i_printf("operations:\n");
for (i = 0;
i < node->aoi_type_u_u.interface_def.ops.ops_len;
i++)
print_operation(&(node->aoi_type_u_u.interface_def.ops.
ops_val[i]));
i_printf("attributes:\n");
for (i = 0;
i < node->aoi_type_u_u.interface_def.attribs.attribs_len;
i++)
print_attrib(&(node->aoi_type_u_u.interface_def.
attribs.attribs_val[i]));
i_printf("exceptions:\n");
for (i = 0;
i < node->aoi_type_u_u.interface_def.excepts.excepts_len;
i++)
print_node(node->aoi_type_u_u.interface_def.
excepts.excepts_val[i]);
break;
case AOI_EXCEPTION:
i_printf("slots:\n");
for (i = 0;
i < node->aoi_type_u_u.exception_def.slots.slots_len;
i++) {
i_printf("name = \"%s\", type: \n",
node->aoi_type_u_u.exception_def.slots.
slots_val[i].name);
print_node(node->aoi_type_u_u.exception_def.slots.
slots_val[i].type);
}
break;
case AOI_CONST:
i_printf("type:\n");
print_node(node->aoi_type_u_u.const_def.type);
i_printf("value:\n");
print_const(node->aoi_type_u_u.const_def.value, 1);
break;
case AOI_ENUM:
i_printf("enum name: '%s'\n",
node->aoi_type_u_u.enum_def.enum_label);
i_printf("values:\n");
indent += ISPC;
for (i = 0; i < node->aoi_type_u_u.enum_def.defs.defs_len;
i++) {
i_printf("Slot #%d\n", i);
print_field(&(node->aoi_type_u_u.enum_def.defs.
defs_val[i]));
}
indent -= ISPC;
break;
case AOI_VOID:
break;
case AOI_NAMESPACE:
break;
case AOI_OPTIONAL:
i_printf("type:\n");
print_node(node->aoi_type_u_u.optional_def.type);
break;
case AOI_FWD_INTRFC:
break;
case AOI_ANY:
break;
case AOI_TYPE_TAG:
break;
case AOI_TYPED:
i_printf("tag:\n");
print_node(node->aoi_type_u_u.typed_def.tag);
i_printf("type:\n");
print_node(node->aoi_type_u_u.typed_def.type);
break;
case AOI_ERROR:
i_printf("!!! AOI_ERROR nodes should not appear in `.aoi' "
"files !!!\n");
break;
default:
panic("Type %d is not yet implemented.", node->kind);
break;
}
indent -= ISPC;
}
static void print_item(aoi_def *n, int slot)
{
indent = 0;
i_printf("Slot #%d\nScope #%d\nName \"%s\"\nIDL File #%d\n",
slot,
n->scope,
n->name,
n->idl_file);
print_node(n->binding);
i_printf("\n");
}
static void print_all()
{
u_int i;
for (i = 0; i < the_aoi.defs.defs_len; i++)
print_item(&(the_aoi.defs.defs_val[i]), i);
}
void usage(void)
{
fprintf(stderr,
("Usage: %s [<options>] [<infile>]\n"
"<infile>: AOI input file; defaults to stdin.\n"
"<options>:\n"
"-?, -h, --help "
"Print this usage message.\n"
"-v, -V, --version "
"Print the program version number.\n"
"-o<file>, -o <file>, "
"Write output to <file>.\n"
" --output <file> "
"Default is <infileroot>%s, or stdout.\n"),
progname,
AOID_SUFFIX);
exit(1);
}
void version()
{
fprintf(stderr,
"AOI Dump Utility program, version "
FLICK_VERSION"\n");
exit(0);
}
int main(int argc, char **argv)
{
FILE *input_file;
char *outname = 0;
progname = argv[0];
argv++; argc--;
/* Parse arguments. */
while ((argc > 0) && (argv[0][0] == '-')) {
switch (argv[0][1]) {
case '?':
case 'h':
usage();
case 'o':
if (argv[0][2] == 0) {
if (argc < 2)
panic("filename required after -o");
outname = argv[1];
argv++;
argc--;
} else
outname = argv[0]+2;
break;
case 'v':
case 'V':
version();
default:
if (!strcmp(argv[0], "--help"))
usage();
if (!strcmp(argv[0], "--version"))
version();
if (!strcmp(argv[0], "--output")) {
if (argc < 2)
panic("filename required after `%s'",
argv[0]);
outname = argv[1];
argv++;
argc--;
break;
}
fprintf(stderr,
"unknown command-line option `%s'\n",
argv[0]);
usage();
}
argv++;
argc--;
}
/* Handle the remaining input and output file setting. */
if (argc > 1)
usage();
if (argc == 1) {
char *inname=argv[0];
input_file = fopen(inname, "rb");
if (!input_file)
panic("can't open input file `%s'", inname);
if (outname == 0)
outname = resuffix(inname, AOID_SUFFIX);
} else
input_file = stdin;
if (outname != 0) {
output_file = fopen(outname, "w");
if (!output_file)
panic("can't open output file `%s'", outname);
} else
output_file = stdout;
/* End of argument processing. */
/* Read in AOI binary from standard input. */
aoi_readfh(&the_aoi, input_file);
print_meta(&the_aoi.meta_data, output_file, 0);
/* Output an ASCII translation to standard output. */
print_all();
exit(0);
}
/* End of file. */
syntax highlighted by Code2HTML, v. 0.9.1