/* * 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/tld/builder.c,v 1.13 2005/10/18 15:31:05 stefanf Exp $ */ /**** builder.c --- Front end to library construction mode of TDF linker. * ** Author: Steve Folkes * **** Commentary: * * This file provides the front end to the library construction mode of the * TDF linker. * **** Change Log:*/ /****************************************************************************/ #include "builder.h" #include "capsule.h" #include "debug.h" #include "msgcat.h" #include "library.h" #include "shape-table.h" #include "tenapp.h" #include "unit-table.h" #include "solve-cycles.h" /*--------------------------------------------------------------------------*/ static LibraryP * builder_read_libraries(ArgDataP arg_data, unsigned *num_libs_ref, unsigned *num_capsules_ref) { unsigned num_lib_files = arg_data_num_library_files (arg_data); char **lib_files = arg_data_library_files (arg_data); LibraryP *libraries = ALLOCATE_VECTOR (LibraryP, num_lib_files); unsigned num_capsules = 0; unsigned i; for (i = 0; i < num_lib_files; i ++) { LibraryP library = library_create_stream_input (lib_files [i]); if (library != NIL (LibraryP)) { ShapeTableP lib_shapes = shape_table_create (); library_read (library, lib_shapes); library_close (library); libraries [i] = library; num_capsules += library_num_capsules (library); shape_table_deallocate (lib_shapes); } else { libraries [i] = NIL (LibraryP); MSG_cant_open_input_file (lib_files [i]); } } *num_libs_ref = num_lib_files; *num_capsules_ref = num_capsules; return (libraries); } static void builder_read_capsule(CapsuleP capsule, CapsuleP *capsules, unsigned capsule_index, UnitTableP units, ShapeTableP shapes) { char *name = capsule_name (capsule); unsigned i; for (i = 0; i < capsule_index; i ++) { if (cstring_equal (name, capsule_name (capsules [i]))) { MSG_duplicate_capsule_name (name); } } capsule_set_index (capsule, capsule_index); capsule_read (capsule, units, shapes); capsule_store_contents (capsule); capsule_close (capsule); capsules [capsule_index] = capsule; } static CapsuleP * builder_read_capsules(ArgDataP arg_data, UnitTableP units, ShapeTableP shapes, unsigned *num_capsules_ref) { unsigned num_input_files = arg_data_get_num_files (arg_data); char **input_files = arg_data_get_files (arg_data); unsigned capsule_index = 0; unsigned num_libraries; LibraryP *libraries; unsigned num_capsules; CapsuleP *capsules; unsigned i; libraries = builder_read_libraries (arg_data, &num_libraries, &num_capsules); num_capsules += num_input_files; capsules = ALLOCATE_VECTOR (CapsuleP, num_capsules); for (i = 0; i < num_libraries; i ++) { LibraryP library = libraries [i]; if (library != NIL (LibraryP)) { unsigned num_lib_capsules = library_num_capsules (library); unsigned j; for (j = 0; j < num_lib_capsules; j ++) { LibCapsuleP lib_capsule = library_get_capsule (library, j); char *name = lib_capsule_name (lib_capsule); NStringP contents = lib_capsule_contents (lib_capsule); CapsuleP capsule; capsule = capsule_create_string_input (name, contents); builder_read_capsule (capsule, capsules, capsule_index, units, shapes); capsule_index ++; } } } DEALLOCATE (libraries); for (i = 0; i < num_input_files; i ++) { CapsuleP capsule; if ((capsule = capsule_create_stream_input (input_files [i])) != NIL (CapsuleP)) { builder_read_capsule (capsule, capsules, capsule_index, units, shapes); capsule_index ++; } else { MSG_cant_open_input_file (input_files [i]); } } tenapp_checkerrors(MSG_SEV_ERROR); *num_capsules_ref = num_capsules; return (capsules); } static void builder_check_multi_defs(ShapeTableP shapes) { shape_table_iter (shapes, shape_entry_check_multi_defs, NULL); tenapp_checkerrors(MSG_SEV_ERROR); } static void builder_suppress_1(NStringP shape, BoolT all, NameKeyListP names, void *gclosure) { ShapeTableP lib_shapes = (ShapeTableP) gclosure; ShapeEntryP entry = shape_table_get (lib_shapes, shape); if (entry) { NameTableP table = shape_entry_name_table (entry); NameKeyListEntryP name = name_key_list_head (names); if (all) { name_table_iter (table, name_entry_builder_suppress, (void *) shape); } for (; name; name = name_key_list_entry_next (name)) { NameKeyP key = name_key_list_entry_key (name); NameEntryP name_entry = name_table_get (table, key); if (name_entry) { debug_info_l_suppress (shape, key); name_entry_set_definition (name_entry, NIL (CapsuleP)); } } } } static void builder_suppress(ArgDataP arg_data, ShapeTableP lib_shapes) { if (arg_data_get_suppress_mult (arg_data)) { shape_table_iter (lib_shapes, shape_entry_suppress_mult, NULL); } shape_control_iter (arg_data_get_suppresses (arg_data), builder_suppress_1, (void *) lib_shapes); tenapp_checkerrors(MSG_SEV_ERROR); } static void builder_write_library(ArgDataP arg_data, ShapeTableP shapes, unsigned num_capsules, CapsuleP *capsules) { char *output_file = arg_data_get_output_file (arg_data); LibraryP library; if ((library = library_create_stream_output (output_file)) != NIL (LibraryP)) { library_write (library, shapes, num_capsules, capsules); library_close (library); } else { MSG_cant_open_output_file (output_file); UNREACHED; } tenapp_checkerrors(MSG_SEV_ERROR); } /*--------------------------------------------------------------------------*/ void builder_main(ArgDataP arg_data) { UnitTableP units = unit_table_create (); ShapeTableP shapes = shape_table_create (); unsigned num_capsules; CapsuleP *capsules; capsules = builder_read_capsules (arg_data, units, shapes, &num_capsules); builder_check_multi_defs (shapes); builder_suppress (arg_data, shapes); builder_write_library (arg_data, shapes, num_capsules, capsules); }