/* * Copyright (c) 2002, The Tendra Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * Crown Copyright (c) 1997 * * This TenDRA(r) Computer Program is subject to Copyright * owned by the United Kingdom Secretary of State for Defence * acting through the Defence Evaluation and Research Agency * (DERA). It is made available to Recipients with a * royalty-free licence for its use, reproduction, transfer * to other parties and amendment for any purpose not excluding * product development provided that any such use et cetera * shall be deemed to be acceptance of the following conditions:- * * (1) Its Recipients shall ensure that this Notice is * reproduced upon any copies or amended versions of it; * * (2) Any amended version of it shall be clearly marked to * show both the nature of and the organisation responsible * for the relevant amendment or amendments; * * (3) Its onward transfer from a recipient to another * party shall be deemed to be that party's acceptance of * these conditions; * * (4) DERA gives no warranty or assurance as to its * quality or suitability for any purpose and DERA accepts * no liability whatsoever in relation to any use to which * it may be put. * * $TenDRA: tendra/src/tools/tnc/main.c,v 1.12 2005/10/18 16:06:53 stefanf Exp $ */ #include "config.h" #include "argparse.h" #include "catstdn.h" #include "msgcat.h" #include "ostream.h" #include "tdf_types.h" #include "tdf_stream.h" #include "tenapp.h" #include "release.h" #include "types.h" #include "read_types.h" #include "analyser.h" #include "check.h" #include "de_types.h" #include "de_capsule.h" #include "de_unit.h" #include "enc_cap.h" #include "eval.h" #include "file.h" #include "help.h" #include "node.h" #include "read_cap.h" #include "shape.h" #include "tdf.h" #include "table.h" #include "utility.h" #include "write.h" static BoolT do_not_process = 0; static BoolT expand = 0; static BoolT evaluate = 0; static BoolT lib_input = 0; static char *out_file = NULL; static void (*input_fn)(void); static void (*output_fn)(void); /* * PROCESS AN OUTPUT OPTION * * The show option corresponding to arg is set to t. */ static boolean output_option(char *arg, boolean t) { boolean *p = null; if (streq (arg, "tokdecs")) { p = &show_tokdecs; } else if (streq (arg, "tokdefs")) { p = &show_tokdefs; } else if (streq (arg, "aldecs")) { p = &show_aldecs; } else if (streq (arg, "aldefs")) { p = &show_aldefs; } else if (streq (arg, "tagdecs")) { p = &show_tagdecs; } else if (streq (arg, "tagdefs")) { p = &show_tagdefs; } if (p == null) return (0); if (t) { show_tokdecs = 0; show_tokdefs = 0; show_aldefs = 0; show_tagdecs = 0; show_tagdefs = 0; } *p = t; return (1); } static void opt_check(char *option, void *closure) { UNUSED(option); UNUSED(closure); /* Switch on shape checking */ init_shapes (); do_check = 1; } static void opt_cv(char *option, void *closure) { UNUSED(option); UNUSED(closure); init_shapes (); do_check = 1; print_shapes = 1; } static void opt_decode(char *option, void *closure) { UNUSED(option); UNUSED(closure); input_fn = de_capsule; text_input = 0; } static void opt_encode(char *option, void *closure) { UNUSED(option); UNUSED(closure); output_fn = enc_capsule; text_output = 0; } static void opt_func(char *option, void *closure) { UNUSED(option); UNUSED(closure); func_input = 1; func_output = 1; } static void opt_print(char *option, void *closure) { UNUSED(option); UNUSED(closure); /* Pretty printer mode */ input_fn = de_capsule; output_fn = print_capsule; text_input = 0; text_output = 1; } static void opt_read(char *option, void *closure) { UNUSED(option); UNUSED(closure); input_fn = read_capsule; text_input = 1; } static void opt_write(char *option, void *closure) { UNUSED(option); UNUSED(closure); output_fn = print_capsule; text_output = 1; } static void opt_tsimp(char *option, void *closure) { UNUSED(option); UNUSED(closure); evaluate = 1; expand = 1; } static void opt_subject(char *option, void *closure, char *value) { UNUSED(option); UNUSED(closure); help (value); do_not_process = TRUE; } static void opt_include(char *option, void *closure, char *value) { UNUSED(option); UNUSED(closure); add_directory (value); } static void opt_lprefix(char *option, void *closure, char *value) { UNUSED(option); UNUSED(closure); local_prefix = value; } static void opt_outfile(char *option, void *closure, char *value) { UNUSED(option); UNUSED(closure); out_file = value; } static void opt_version(char *option, void *closure) { UNUSED(option); UNUSED(closure); tenapp_report_version (); MSG_TDF_version(VERSION_major, VERSION_minor); } static void opt_no(char *option, void *closure, char *value) { UNUSED(option); UNUSED(closure); if (!output_option (value, 0)) MSG_getopt_unknown_option (value); } static void opt_only(char *option, void *closure, char *value) { UNUSED(option); UNUSED(closure); if (!output_option (value, 1)) MSG_getopt_unknown_option (value); } static void opt_help(char *option, void *closure); static ArgListT cmdl_opts[] = { AP_OPT_EITHER (include, 'I', NULL, opt_include), AP_OPT_EITHER (lprefix, 'L', NULL, opt_lprefix), AP_OPT_EITHER (subject, 'S', NULL, opt_subject), AP_OPT_EMPTY (version, 'V', "verbose", opt_version), AP_OPT_EMPTY (check, 'c', "check", opt_check), AP_OPT_EMPTY (cv, '\0', "cv", opt_cv), AP_OPT_EMPTY (decode, 'd', "decode", opt_decode), AP_OPT_EMPTY (encode, 'e', "encode", opt_encode), AP_OPT_SET (eval, '\0', "eval", &evaluate), AP_OPT_SET (expand, '\0', "expand", &expand), AP_OPT_SET (funcin, '\0', "funcin", &func_input), AP_OPT_SET (funcout, '\0', "funcout", &func_output), AP_OPT_EMPTY (func, 'f', "func", opt_func), AP_OPT_EMPTY (help, 'h', "help", opt_help), AP_OPT_SET (lib, 'l', "lib", &lib_input), AP_OPT_FOLLOWING(no, '\0', "no", opt_no), AP_OPT_FOLLOWING(only, '\0', "only", opt_only), AP_OPT_EITHER (outfile, 'o', NULL, opt_outfile), AP_OPT_EMPTY (print, 'p', "print", opt_print), AP_OPT_SET (dont_check, 'q', NULL, &dont_check), AP_OPT_EMPTY (read, 'r', "read", opt_read), AP_OPT_EMPTY (tsimp, 't', "tsimp", opt_tsimp), AP_OPT_RESET (unsorted, 'u', "unsorted", &order_names), AP_OPT_SET (verbose, 'v', NULL, &verbose), AP_OPT_EMPTY (write, 'w', "write", opt_write), AP_OPT_EOL }; static void opt_help(char *option, void *closure) { UNUSED(option); UNUSED(closure); MSG_usage (); arg_print_usage (cmdl_opts); msg_append_newline (); } static void msg_uh_where(char ch, void *pp) { UNUSED(ch); UNUSED(pp); if (input_file) { write_fmt (msg_stream, ", %s", input_file); if (text_input) { write_fmt (msg_stream, ", line %ld", line_no); } else { tdf_pos b = tdf_stream_tell (tdfr); if (capname) write_fmt(msg_stream, ", capsule %s", capname); switch (decode_status) { case 0: write_fmt (msg_stream, " (at outermost level)"); break; case 1: write_fmt (msg_stream, " (in linking information)"); break; case 2 : write_fmt (msg_stream, " (in unit body)"); break; } write_fmt (msg_stream, ", byte %ld, bit %ld", b / 8, b % 8); if (decode_status == 0) write_fmt (msg_stream, " (Illegal TDF capsule?)"); if (decode_status >= 1 && !have_version) write_fmt (msg_stream, " (TDF version error?)"); } } } /* * MAIN ROUTINE * * This is the main routine. It processes the command line arguments * and calls the appropriate input and output routines. */ int main(int argc, char **argv) { int optcnt; tenapp_init(argc, argv, "TDF notation compiler", "1.9"); msg_uh_add(MSG_GLOB_where, msg_uh_where); /* Default action : read text, encode TDF capsule */ input_fn = read_capsule; output_fn = enc_capsule; text_input = 1; text_output = 0; /* Initialize internal tables */ init_tables (); init_constructs (); optcnt = arg_parse_arguments (cmdl_opts, --argc, ++argv); if (do_not_process) return (exit_status); argc -= optcnt; argv += optcnt; if (argc < 1) MSG_getopt_not_enough_arguments (); open_input (*argv++, 0); if (argc == 2) { if (out_file) MSG_getopt_too_many_arguments (); else open_output (*argv); } else output = stdout; /* Check on library input */ if (lib_input && input_fn == de_capsule) input_fn = de_library; /* Perform the appropriate actions */ (*input_fn) (); if (exit_status == EXIT_SUCCESS || text_output) { if (expand) expand_all (); if (evaluate) eval_all (); sort_all (); (*output_fn) (); } return (exit_status); }