/* Objective Modula-2 Compiler (objm2c) * * @file objm2c.c * main program (driver) * * Get command line arguments, open source file(s) and feed parser * * Author: Benjamin Kowarsch * * Copyright (C) 2009 The Objective Modula-2 Project. All rights reserved. * * License: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met * * 1) This file, or any part thereof, may NOT be hosted on websites which * contain advertising, unless specific prior written permission has been * obtained. The licensor will grant such permission upon request at its * sole discretion to websites the licensor does NOT consider abusive in * their use of advertising. Small notices in the footer of a website * naming corporate rights holders, infrastructure providers or sponsors * are not considered advertising in the context of this license. * * 2) Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 3) Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and other materials provided with the distribution. * * 4) Neither the author's name nor the names of any contributors may be used * to endorse or promote products derived from this software without * specific prior written permission. * * 5) Where this list of conditions or the following disclaimer, in part or * as a whole is overruled or nullified by applicable law, no permission * is granted to use the software. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. * */ #include #include "ASCII.h" #include "objm2_build_params.h" #include "objm2_errmsg.h" #include "objm2_filename.h" // -------------------------------------------------------------------------- // Application info // -------------------------------------------------------------------------- #define APP_NAME "Objective Modula-2 Compiler (objm2c)" #define APP_VERSION "Version 2.0" " " BUILD_VERSION #define APP_COPYRIGHT "(C) 2009 The Objective Modula-2 Project" // -------------------------------------------------------------------------- // Exit codes // -------------------------------------------------------------------------- #ifndef EXIT_SUCCESS #define EXIT_SUCCESS 0 #endif #ifndef EXIT_FAILURE #define EXIT_FAILURE 1 #endif // -------------------------------------------------------------------------- // Option macros // -------------------------------------------------------------------------- #define OPT_ENDMARKER -1 #define OPT_DUMPAST 'a' #define OPT_DUMPSYMTAB 's' #define OPT_SYNTAXCHECK 't' #define OPT_VERSION 'V' #define OPT_USAGE 'h' #define OPT_LIST "ahstV" // -------------------------------------------------------------------------- // function: show_usage() // -------------------------------------------------------------------------- // // Prints usage info to stdout. static void show_usage() { printf("Usage\n\n" " objm2c [ debug-option ] sourcefile\n\n" "Obtaining information:\n" " objm2c usage-info-option | version-info-option\n\n" "Debug options:\n" " -a, --dumpast : build and print AST only\n" " -s, --dumpsymtab : build and print symbol table only\n" " -t, --syntaxcheck : syntax check only\n\n" "Info options:\n" " -h, --help : print usage info\n" " -V, --version : print software version and copyright notice\n" "\n"); } // end show_usage // -------------------------------------------------------------------------- // function: show_version() // -------------------------------------------------------------------------- // // Prints software version and copyright notice to stdout. static void show_version() { printf("%s %s\n%s\n\n", APP_NAME, APP_VERSION, APP_COPYRIGHT); } // end show_version // -------------------------------------------------------------------------- // function: show_error( error ) // -------------------------------------------------------------------------- // // Prints error message for to stdout. static void show_error(objm2_err_t error) { printf(error_message(error)); printf("\n\n"); } // end show_error // -------------------------------------------------------------------------- // function: main() // -------------------------------------------------------------------------- // // Gets command line arguments, opens source file and feeds parser. int main (int argc, const char * argv[]) { int opt; bool syntax_check_only = false; objm2_file_type_t outfile_type; objm2_target_t target = OBJM2_TARGET_OBJC; objm2_filename_t source_filename, output_filename; int fn_status, fio_status, p_status, cg_status; objm2_parser_t parser; objm2_ast_node_t ast; objm2_codegen_t cgen; // get command line options and arguments opt = getopt_long(argc, (char **) argv, OPT_LIST, lopts_all, &index); switch (opt) { case OPT_DUMPAST : show_error(ERR_OPT_NOT_IMPLEMENTED); return EXIT_FAILURE; case OPT_DUMPSYMTAB : show_error(ERR_OPT_NOT_IMPLEMENTED); return EXIT_FAILURE; case OPT_SYNTAXCHECK : syntax_check_only = true; break; case OPT_USAGE : show_usage(); return EXIT_SUCCESS; case OPT_VERSION : show_version(); return EXIT_SUCCESS; case OPT_ENDMARKER : if (argc > 0) break; show_version(); show_usage(); return EXIT_SUCCESS; default : show_error(ERR_OPT_INVALID); show_usage(); return EXIT_FAILURE; } // end switch if (argc == 0) { show_error(); // missing sourcefile argument return EXIT_FAILURE; } else if (argc > 1) { show_error(); // extra arguments ingored } // end if // get source path argument source_path = (char *) argv[1]; // get source filename descriptor from source path source_filename = objm2_new_filename_from_path(source_path, DEFAULT_FILENAMING, &fn_status); if (fn_status != OBJM2_FILENAME_STATUS_SUCCESS) { show_error(fn_status); return EXIT_FAILURE; } // end if // get matching outfile type for target and source file type outfile_type = objm2_outfile_type_for(target, objm2_file_type(source_filename)); if (outfile_type == FILE_TYPE_UNKNOWN) { show_error(); // no outfile associated with with source for target return EXIT_FAILURE; } // end if // open source file sourcefile = objm2_open_sourcefile(source_filename, &fio_status); if (fio_status != OBJM2_FILEIO_STATUS_SUCCESS) { show_error(fio_status); return EXIT_FAILURE; } // end if // init parser parser = objm2_new_parser(sourcefile, &p_status); if (p_status != OBJM2_PARSER_STATUS_SUCCESS) { show_error(p_status); return EXIT_FAILURE; } // end if // create new AST root ast = objm2_ast_new_root(); if (ast == NULL) { show_error(OBJM2_AST_STATUS_ALLOCATION_FAILED); return EXIT_FAILURE; } // end if // invoke parser objm2_parser(parser, ast, &p_status); if (p_status != OBJM2_PARSER_STATUS_SUCCESS) { show_error(p_status); return EXIT_FAILURE; } // end if // get output filename descriptor from source file components output_filename = objm2_new_filename(objm2_directory_string(source_filename), objm2_filename_string(source_filename), outfile_type, DEFAULT_FILENAMING, &fn_status); if (fn_status != OBJM2_FILENAME_STATUS_SUCCESS) { show_error(fn_status); return EXIT_FAILURE; } // end if // create and open output file outfile = objm2_new_outfile(output_filename, &fio_status); if (fio_status != OBJM2_FILEIO_STATUS_SUCCESS) { show_error(fio_status); return EXIT_FAILURE; } // end if // invoke code generator cgen = objm2_new_codegen(outfile, ast, &cg_status); if (cg_status != OBJM2_CODEGEN_STATUS_SUCCESS) { show_error(cg_status); return EXIT_FAILURE; } // end if // clean up objm2_close_file(sourcefile, NULL); objm2_dispose_parser(parser); objm2_close_file(outfile, NULL); objm2_dispose_codegen(cgen); objm2_dispose_filename(sourcefile); objm2_dispose_filename(outfile); return EXIT_SUCCESS; } // main // END OF FILE