/*
* Copyright (c) 1997, 1998, 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.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mom/compiler.h>
#include <mom/c/pfe.hh>
#include "private.hh"
/*
* `PG_FLAGS' is the number of flags ``hardcoded'' in this file --- yuck!
* These flags include:
*
* `-c' / `--client'
* to generate the client-side presentation
* `-s' / `--server'
* to generate the server-side presentation
* `-a' / `--async_stubs'
* to generate async. send/receive stubs and separate m/u stubs
* `--with_sids'
* to add client and server SIDs to the presentation
* `--client_stubs_for_inherited_operations'
* to control the creation of client stubs for inherited ops
* `--server_funcs_for_inherited_operations'
* to control the creation of server funcs for inherited ops
*/
#define PG_FLAGS (6)
/*
* `name_fmt_options' and `name_lit_options' are defined in `p_calc_name.cc'.
*/
extern name_fmt_option_struct name_fmt_options[];
extern name_lit_option_struct name_lit_options[];
pg_flags pg_state::args(int argc, char **argv, char *info)
{
flags_in *in;
int count = build_flags(&in);
flags_out out;
pg_flags res;
out = parse_args(argc, argv, count, in);
// print_args_flags(out, count, in);
std_handler(out, count, in, "<optional input filename>", info);
res = handler(out, in, info, count);
return res;
}
pg_flags pg_state::handler(flags_out out, flags_in *in, char *info, int count)
{
pg_flags res;
int out_index;
int name_options_index;
/* Get our program name. */
progname = out.progname;
/* Decide whether we are generating client or server. */
if (out.flag_seqs[STD_FLAGS].values[0].flag
&& out.flag_seqs[STD_FLAGS + 1].values[0].flag)
panic("Can't build both the client stubs and the server "
"skeleton.");
res.client = !out.flag_seqs[STD_FLAGS + 1].values[0].flag;
/* Get the name of our output file. */
res.output = out.flag_seqs[OUTPUT_FILE_FLAG].values[0].string;
/* Get the name of our input file. */
if (out.other_count == 1)
res.input = *out.other;
else if (out.other_count) {
for (int i = 0; i < out.other_count; i++)
fprintf(stderr,
"Arg #%d - '%s'\n",
i + 1, out.other[i]);
print_args_usage(out.progname,
count,
in,
"<optional input filename>",
info);
exit(1);
} else
res.input = 0;
/* Decide if we should implement the decomposed stub presentation. */
res.async_stubs = out.flag_seqs[STD_FLAGS + 2].values[0].flag;
/* Decide if we should include SIDs in the presentation. */
res.use_sids = out.flag_seqs[STD_FLAGS + 3].values[0].flag;
/*
* Decide if we should create client stubs and/or server functions for
* inherited operations.
*/
res.client_stubs_for_inherited_operations
= out.flag_seqs[STD_FLAGS + 4].values[0].flag;
res.server_funcs_for_inherited_operations
= out.flag_seqs[STD_FLAGS + 5].values[0].flag;
/* Process any name-mangling options that were specified. */
for (out_index = STD_FLAGS + PG_FLAGS, name_options_index = 0;
name_fmt_options[name_options_index].name != 0;
++out_index, ++name_options_index) {
if (out.flag_seqs[out_index].values[0].string)
/*
* The user specified a format string. Set the right
* `names.formats' to be that string.
*/
names.formats[name_fmt_options[name_options_index].
index]
= out.flag_seqs[out_index].values[0].string;
}
/* `out_index' is now pointing to the first literal option. */
for (name_options_index = 0;
name_lit_options[name_options_index].name != 0;
++out_index, ++name_options_index) {
if (out.flag_seqs[out_index].values[0].string) {
/*
* The user specified a literal string. Set the right
* `names.literals' to be that string.
*/
names.literals[name_lit_options[name_options_index].
index].str
= out.flag_seqs[out_index].values[0].string;
names.literals[name_lit_options[name_options_index].
index].len
= strlen(out.flag_seqs[out_index].values[0].
string);
}
}
return res;
}
int pg_state::build_flags(flags_in **in)
{
int flags_count;
int flags_index;
int name_flags_count;
int i;
/* Count the number of options that we will have. */
name_flags_count = 0;
for (i = 0; name_fmt_options[i].name; ++i)
++name_flags_count;
for (i = 0; name_lit_options[i].name; ++i)
++name_flags_count;
flags_count = STD_FLAGS
+ PG_FLAGS /* `-c', `-s', ... */
+ name_flags_count /* the name-mangling options */
;
*in = (flags_in *) mustmalloc(sizeof(flags_in) * flags_count);
set_def_flags(*in);
flags_index = STD_FLAGS;
/* Flags to generate client or server presentation. */
(*in)[flags_index].sng = 'c';
(*in)[flags_index].dbl = "client";
(*in)[flags_index].kind = fk_FLAG;
(*in)[flags_index].max_occur = FLAG_UNLIMITED_USE_LAST;
(*in)[flags_index].dfault.flag = 0;
(*in)[flags_index].explain =
"Build the client-side presentation (default)";
++flags_index;
(*in)[flags_index].sng = 's';
(*in)[flags_index].dbl = "server";
(*in)[flags_index].kind = fk_FLAG;
(*in)[flags_index].max_occur = FLAG_UNLIMITED_USE_LAST;
(*in)[flags_index].dfault.flag = 0;
(*in)[flags_index].explain =
"Build the server-side presentation";
++flags_index;
/* Flags to change the presentation style. */
(*in)[flags_index].sng = 'a';
(*in)[flags_index].dbl = "async_stubs";
(*in)[flags_index].kind = fk_FLAG;
(*in)[flags_index].max_occur = FLAG_UNLIMITED_USE_LAST;
(*in)[flags_index].dfault.flag = async_stubs;
(*in)[flags_index].explain =
("Produce asynchronous send/recv stubs, separate "
"marshal/unmarshal stubs");
++flags_index;
/* Flags to add SIDs to the presentation. */
(*in)[flags_index].sng = 0;
(*in)[flags_index].dbl = "with_sids";
(*in)[flags_index].kind = fk_FLAG;
(*in)[flags_index].max_occur = FLAG_UNLIMITED_USE_LAST;
(*in)[flags_index].dfault.flag = 0;
(*in)[flags_index].explain =
("Include client and server SIDs (security IDs) in "
"parameter lists");
++flags_index;
/*
* Flags to control the creation of certain client stubs and server
* work functions.
*/
(*in)[flags_index].sng = 0;
(*in)[flags_index].dbl = "client_stubs_for_inherited_operations";
(*in)[flags_index].kind = fk_FLAG;
(*in)[flags_index].max_occur = FLAG_UNLIMITED_USE_LAST;
(*in)[flags_index].dfault.flag = client_stubs_for_inherited_operations;
(*in)[flags_index].explain =
"Produce client stubs for inherited operations";
++flags_index;
(*in)[flags_index].sng = 0;
(*in)[flags_index].dbl = "server_funcs_for_inherited_operations";
(*in)[flags_index].kind = fk_FLAG;
(*in)[flags_index].max_occur = FLAG_UNLIMITED_USE_LAST;
(*in)[flags_index].dfault.flag = server_funcs_for_inherited_operations;
(*in)[flags_index].explain =
"Produce server functions for inherited operations";
++flags_index;
assert(flags_index == (STD_FLAGS + PG_FLAGS));
/*
* Flags to change the name-generating format strings. It is important
* that we create the flags in the same order as they appear in
* `name_fmt_options' --- this order is assumed by `pg_state::handler'
* above.
*/
for (i = 0; name_fmt_options[i].name; ++i, ++flags_index){
(*in)[flags_index].sng = 0;
(*in)[flags_index].dbl = name_fmt_options[i].name;
(*in)[flags_index].kind = fk_STRING;
(*in)[flags_index].max_occur = 1;
/*
* Perhaps `name.formats[name_fmt_options[i].index]' should be
* the default value? Currently, we use null to indicate that
* no value was specified by the user.
*/
(*in)[flags_index].dfault.string = 0;
(*in)[flags_index].explain = name_fmt_options[i].explain;
}
/*
* Flags to change the name-generating literal strings. Again, it is
* important that we create the flags in the same order as they appear
* in `name_lit_options' --- this order is assumed by the function
* `pg_state::handler' above.
*
* `pg_state::handler' also assumes that the literal string options
* immediately follow the format string options.
*/
for (i = 0; name_lit_options[i].name; ++i, ++flags_index){
(*in)[flags_index].sng = 0;
(*in)[flags_index].dbl = name_lit_options[i].name;
(*in)[flags_index].kind = fk_STRING;
(*in)[flags_index].max_occur = 1;
/*
* Perhaps `name.literals[name_lit_options[i].index]' should be
* the default value? Currently, we use null to indicate that
* no value was specified by the user.
*/
(*in)[flags_index].dfault.string = 0;
(*in)[flags_index].explain = name_lit_options[i].explain;
}
return flags_count;
}
/* End of file. */
syntax highlighted by Code2HTML, v. 0.9.1