| /* This is an auto-generated file -- do not edit directly. */ |
| |
| /* Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/Defines.h" |
| /* Charmonizer/Core/Defines.h -- Universal definitions. |
| */ |
| #ifndef H_CHAZ_DEFINES |
| #define H_CHAZ_DEFINES 1 |
| |
| #ifndef true |
| #define true 1 |
| #define false 0 |
| #endif |
| |
| #define CHAZ_QUOTE(x) #x "\n" |
| |
| #endif /* H_CHAZ_DEFINES */ |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/Library.h" |
| /* Charmonizer/Core/Library.h |
| */ |
| |
| #ifndef H_CHAZ_LIB |
| #define H_CHAZ_LIB |
| |
| typedef struct chaz_Lib chaz_Lib; |
| |
| typedef enum { |
| chaz_Lib_SHARED = 1, |
| chaz_Lib_STATIC = 2 |
| } chaz_LibType; |
| |
| chaz_Lib* |
| chaz_Lib_new(const char *name, chaz_LibType type, const char *version, |
| const char *major_version); |
| |
| void |
| chaz_Lib_destroy(chaz_Lib *flags); |
| |
| const char* |
| chaz_Lib_get_name(chaz_Lib *lib); |
| |
| const char* |
| chaz_Lib_get_version(chaz_Lib *lib); |
| |
| const char* |
| chaz_Lib_get_major_version(chaz_Lib *lib); |
| |
| int |
| chaz_Lib_is_shared(chaz_Lib *lib); |
| |
| int |
| chaz_Lib_is_static(chaz_Lib *lib); |
| |
| char* |
| chaz_Lib_filename(chaz_Lib *lib); |
| |
| char* |
| chaz_Lib_major_version_filename(chaz_Lib *lib); |
| |
| char* |
| chaz_Lib_no_version_filename(chaz_Lib *lib); |
| |
| char* |
| chaz_Lib_implib_filename(chaz_Lib *lib); |
| |
| char* |
| chaz_Lib_export_filename(chaz_Lib *lib); |
| |
| #endif /* H_CHAZ_LIB */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/CFlags.h" |
| /* Charmonizer/Core/CFlags.h |
| */ |
| |
| #ifndef H_CHAZ_CFLAGS |
| #define H_CHAZ_CFLAGS |
| |
| /* #include "Charmonizer/Core/Library.h" */ |
| |
| #define CHAZ_CFLAGS_STYLE_POSIX 1 |
| #define CHAZ_CFLAGS_STYLE_GNU 2 |
| #define CHAZ_CFLAGS_STYLE_MSVC 3 |
| #define CHAZ_CFLAGS_STYLE_SUN_C 4 |
| |
| typedef struct chaz_CFlags chaz_CFlags; |
| |
| chaz_CFlags* |
| chaz_CFlags_new(int style); |
| |
| void |
| chaz_CFlags_destroy(chaz_CFlags *flags); |
| |
| const char* |
| chaz_CFlags_get_string(chaz_CFlags *flags); |
| |
| void |
| chaz_CFlags_append(chaz_CFlags *flags, const char *string); |
| |
| void |
| chaz_CFlags_clear(chaz_CFlags *flags); |
| |
| void |
| chaz_CFlags_set_output_obj(chaz_CFlags *flags, const char *filename); |
| |
| void |
| chaz_CFlags_set_output_exe(chaz_CFlags *flags, const char *filename); |
| |
| void |
| chaz_CFlags_add_define(chaz_CFlags *flags, const char *name, |
| const char *value); |
| |
| void |
| chaz_CFlags_add_include_dir(chaz_CFlags *flags, const char *dir); |
| |
| void |
| chaz_CFlags_enable_optimization(chaz_CFlags *flags); |
| |
| void |
| chaz_CFlags_disable_strict_aliasing(chaz_CFlags *flags); |
| |
| void |
| chaz_CFlags_set_warnings_as_errors(chaz_CFlags *flags); |
| |
| void |
| chaz_CFlags_compile_shared_library(chaz_CFlags *flags); |
| |
| void |
| chaz_CFlags_hide_symbols(chaz_CFlags *flags); |
| |
| void |
| chaz_CFlags_link_shared_library(chaz_CFlags *flags); |
| |
| void |
| chaz_CFlags_set_shared_library_version(chaz_CFlags *flags, chaz_Lib *lib); |
| |
| void |
| chaz_CFlags_set_link_output(chaz_CFlags *flags, const char *filename); |
| |
| void |
| chaz_CFlags_add_library_path(chaz_CFlags *flags, const char *directory); |
| |
| void |
| chaz_CFlags_add_library(chaz_CFlags *flags, chaz_Lib *lib); |
| |
| void |
| chaz_CFlags_add_external_library(chaz_CFlags *flags, const char *library); |
| |
| void |
| chaz_CFlags_enable_code_coverage(chaz_CFlags *flags); |
| |
| #endif /* H_CHAZ_CFLAGS */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/CLI.h" |
| #ifndef H_CHAZ_CLI |
| #define H_CHAZ_CLI 1 |
| |
| #define CHAZ_CLI_NO_ARG 0 |
| #define CHAZ_CLI_ARG_REQUIRED (1 << 0) |
| #define CHAZ_CLI_ARG_OPTIONAL (1 << 1) |
| |
| /* The CLI module provides argument parsing for a command line interface. |
| */ |
| |
| typedef struct chaz_CLI chaz_CLI; |
| |
| /* Constructor. |
| * |
| * @param name The name of the application. |
| * @param description A description of the application. |
| */ |
| chaz_CLI* |
| chaz_CLI_new(const char *name, const char *description); |
| |
| /* Destructor. |
| */ |
| void |
| chaz_CLI_destroy(chaz_CLI *self); |
| |
| /* Return a string combining usage header with documentation of options. |
| */ |
| const char* |
| chaz_CLI_help(chaz_CLI *self); |
| |
| /* Override the generated usage header. |
| */ |
| void |
| chaz_CLI_set_usage(chaz_CLI *self, const char *usage); |
| |
| /* Register an option. Updates the "help" string, invalidating previous |
| * values. Returns true on success, or reports an error and returns false if |
| * the option was already registered. |
| */ |
| int |
| chaz_CLI_register(chaz_CLI *self, const char *name, const char *help, |
| int flags); |
| |
| /* Set an option. The specified option must have been registered previously. |
| * The supplied `value` is optional and will be copied. |
| * |
| * Returns true on success. Reports an error and returns false on failure. |
| */ |
| int |
| chaz_CLI_set(chaz_CLI *self, const char *name, const char *value); |
| |
| /* Returns true if the option has been set, false otherwise. |
| */ |
| int |
| chaz_CLI_defined(chaz_CLI *self, const char *name); |
| |
| /* Return the value of a given option converted to a long int. Defaults to 0. |
| * Reports an error if the named option has not been registered. |
| */ |
| long |
| chaz_CLI_longval(chaz_CLI *self, const char *name); |
| |
| /* Return the value of an option as a C string. Defaults to NULL. Reports an |
| * error if the named option has not been registered. |
| */ |
| const char* |
| chaz_CLI_strval(chaz_CLI *self, const char *name); |
| |
| /* Unset an option, making subsequent calls to `get` return false and making |
| * it possible to call `set` again. |
| * |
| * Returns true if the option exists and was able to be unset. |
| */ |
| int |
| chaz_CLI_unset(chaz_CLI *self, const char *name); |
| |
| /* Parse `argc` and `argv`, setting options as appropriate. Returns true on |
| * success. Reports an error and returns false if either an unexpected option |
| * was encountered or an option which requires an argument was supplied |
| * without one. |
| */ |
| int |
| chaz_CLI_parse(chaz_CLI *self, int argc, const char *argv[]); |
| |
| #endif /* H_CHAZ_CLI */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/Compiler.h" |
| /* Charmonizer/Core/Compiler.h |
| */ |
| |
| #ifndef H_CHAZ_COMPILER |
| #define H_CHAZ_COMPILER |
| |
| #include <stddef.h> |
| /* #include "Charmonizer/Core/Defines.h" */ |
| /* #include "Charmonizer/Core/CFlags.h" */ |
| |
| /* Attempt to compile and link an executable. Return true if the executable |
| * file exists after the attempt. |
| */ |
| int |
| chaz_CC_compile_exe(const char *source_path, const char *exe_path, |
| const char *code); |
| |
| /* Attempt to compile an object file. Return true if the object file |
| * exists after the attempt. |
| */ |
| int |
| chaz_CC_compile_obj(const char *source_path, const char *obj_path, |
| const char *code); |
| |
| /* Attempt to compile the supplied source code and return true if the |
| * effort succeeds. |
| */ |
| int |
| chaz_CC_test_compile(const char *source); |
| |
| /* Attempt to compile the supplied source code. If successful, capture the |
| * output of the program and return a pointer to a newly allocated buffer. |
| * If the compilation fails, return NULL. The length of the captured |
| * output will be placed into the integer pointed to by [output_len]. |
| */ |
| char* |
| chaz_CC_capture_output(const char *source, size_t *output_len); |
| |
| /** Initialize the compiler environment. |
| */ |
| void |
| chaz_CC_init(const char *cc_command, const char *cflags); |
| |
| /* Clean up the environment. |
| */ |
| void |
| chaz_CC_clean_up(void); |
| |
| /* Accessor for the compiler executable's string representation. |
| */ |
| const char* |
| chaz_CC_get_cc(void); |
| |
| /* Accessor for `cflags`. |
| */ |
| const char* |
| chaz_CC_get_cflags(void); |
| |
| /* Accessor for `extra_cflags`. |
| */ |
| chaz_CFlags* |
| chaz_CC_get_extra_cflags(void); |
| |
| /* Accessor for `temp_cflags`. |
| */ |
| chaz_CFlags* |
| chaz_CC_get_temp_cflags(void); |
| |
| /* Return a new CFlags object. |
| */ |
| chaz_CFlags* |
| chaz_CC_new_cflags(void); |
| |
| /* Return the extension for a compiled object. |
| */ |
| const char* |
| chaz_CC_obj_ext(void); |
| |
| int |
| chaz_CC_gcc_version_num(void); |
| |
| const char* |
| chaz_CC_gcc_version(void); |
| |
| int |
| chaz_CC_msvc_version_num(void); |
| |
| int |
| chaz_CC_sun_c_version_num(void); |
| |
| const char* |
| chaz_CC_link_command(void); |
| |
| /* Create a command for building a static library. |
| * |
| * @param target The target library filename. |
| * @param objects The list of object files to be archived in the library. |
| */ |
| char* |
| chaz_CC_format_archiver_command(const char *target, const char *objects); |
| |
| /* Returns a "ranlib" command if valid. |
| * |
| * @param target The library filename. |
| */ |
| char* |
| chaz_CC_format_ranlib_command(const char *target); |
| |
| #endif /* H_CHAZ_COMPILER */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/ConfWriter.h" |
| /* Charmonizer/Core/ConfWriter.h -- Write to a config file. |
| */ |
| |
| #ifndef H_CHAZ_CONFWRITER |
| #define H_CHAZ_CONFWRITER 1 |
| |
| #include <stddef.h> |
| #include <stdarg.h> |
| /* #include "Charmonizer/Core/Defines.h" */ |
| |
| struct chaz_ConfWriter; |
| |
| /* Initialize elements needed by ConfWriter. Must be called before anything |
| * else, but after os and compiler are initialized. |
| */ |
| void |
| chaz_ConfWriter_init(void); |
| |
| /* Close the include guard on charmony.h, then close the file. Delete temp |
| * files and perform any other needed cleanup. |
| */ |
| void |
| chaz_ConfWriter_clean_up(void); |
| |
| /* Print output to charmony.h. |
| */ |
| void |
| chaz_ConfWriter_append_conf(const char *fmt, ...); |
| |
| /* Add a pound-define. |
| */ |
| void |
| chaz_ConfWriter_add_def(const char *sym, const char *value); |
| |
| /* Add a globally scoped pound-define. |
| */ |
| void |
| chaz_ConfWriter_add_global_def(const char *sym, const char *value); |
| |
| /* Add a typedef. |
| */ |
| void |
| chaz_ConfWriter_add_typedef(const char *type, const char *alias); |
| |
| /* Add a globally scoped typedef. |
| */ |
| void |
| chaz_ConfWriter_add_global_typedef(const char *type, const char *alias); |
| |
| /* Pound-include a system header (within angle brackets). |
| */ |
| void |
| chaz_ConfWriter_add_sys_include(const char *header); |
| |
| /* Pound-include a locally created header (within quotes). |
| */ |
| void |
| chaz_ConfWriter_add_local_include(const char *header); |
| |
| /* Print a "chapter heading" comment in the conf file when starting a module. |
| */ |
| void |
| chaz_ConfWriter_start_module(const char *module_name); |
| |
| /* Leave a little whitespace at the end of each module. |
| */ |
| void |
| chaz_ConfWriter_end_module(void); |
| |
| void |
| chaz_ConfWriter_add_writer(struct chaz_ConfWriter *writer); |
| |
| typedef void |
| (*chaz_ConfWriter_clean_up_t)(void); |
| typedef void |
| (*chaz_ConfWriter_vappend_conf_t)(const char *fmt, va_list args); |
| typedef void |
| (*chaz_ConfWriter_add_def_t)(const char *sym, const char *value); |
| typedef void |
| (*chaz_ConfWriter_add_global_def_t)(const char *sym, const char *value); |
| typedef void |
| (*chaz_ConfWriter_add_typedef_t)(const char *type, const char *alias); |
| typedef void |
| (*chaz_ConfWriter_add_global_typedef_t)(const char *type, const char *alias); |
| typedef void |
| (*chaz_ConfWriter_add_sys_include_t)(const char *header); |
| typedef void |
| (*chaz_ConfWriter_add_local_include_t)(const char *header); |
| typedef void |
| (*chaz_ConfWriter_start_module_t)(const char *module_name); |
| typedef void |
| (*chaz_ConfWriter_end_module_t)(void); |
| typedef struct chaz_ConfWriter { |
| chaz_ConfWriter_clean_up_t clean_up; |
| chaz_ConfWriter_vappend_conf_t vappend_conf; |
| chaz_ConfWriter_add_def_t add_def; |
| chaz_ConfWriter_add_global_def_t add_global_def; |
| chaz_ConfWriter_add_typedef_t add_typedef; |
| chaz_ConfWriter_add_global_typedef_t add_global_typedef; |
| chaz_ConfWriter_add_sys_include_t add_sys_include; |
| chaz_ConfWriter_add_local_include_t add_local_include; |
| chaz_ConfWriter_start_module_t start_module; |
| chaz_ConfWriter_end_module_t end_module; |
| } chaz_ConfWriter; |
| |
| #endif /* H_CHAZ_CONFWRITER */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/ConfWriterC.h" |
| /* Charmonizer/Core/ConfWriterC.h -- Write to a C header file. |
| */ |
| |
| #ifndef H_CHAZ_CONFWRITERC |
| #define H_CHAZ_CONFWRITERC 1 |
| |
| /* Enable writing config to a C header file. |
| */ |
| void |
| chaz_ConfWriterC_enable(void); |
| |
| #endif /* H_CHAZ_CONFWRITERC */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/ConfWriterPerl.h" |
| /* Charmonizer/Core/ConfWriterPerl.h -- Write to a Perl module file. |
| */ |
| |
| #ifndef H_CHAZ_CONFWRITERPERL |
| #define H_CHAZ_CONFWRITERPERL 1 |
| |
| /* Enable writing config to a Perl module file. |
| */ |
| void |
| chaz_ConfWriterPerl_enable(void); |
| |
| #endif /* H_CHAZ_CONFWRITERPERL */ |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/ConfWriterPython.h" |
| /* Charmonizer/Core/ConfWriterPython.h -- Write to a Python module file. |
| */ |
| |
| #ifndef H_CHAZ_CONFWRITERPYTHON |
| #define H_CHAZ_CONFWRITERPYTHON 1 |
| |
| /* Enable writing config to a Python module file. |
| */ |
| void |
| chaz_ConfWriterPython_enable(void); |
| |
| #endif /* H_CHAZ_CONFWRITERPYTHON */ |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/ConfWriterRuby.h" |
| /* Charmonizer/Core/ConfWriterRuby.h -- Write to a Ruby module file. |
| */ |
| |
| #ifndef H_CHAZ_CONFWRITERRUBY |
| #define H_CHAZ_CONFWRITERRUBY 1 |
| |
| /* Enable writing config to a Ruby module file. |
| */ |
| void |
| chaz_ConfWriterRuby_enable(void); |
| |
| #endif /* H_CHAZ_CONFWRITERRUBY */ |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/HeaderChecker.h" |
| /* Charmonizer/Probe/HeaderChecker.h |
| */ |
| |
| #ifndef H_CHAZ_HEAD_CHECK |
| #define H_CHAZ_HEAD_CHECK |
| |
| /* #include "Charmonizer/Core/Defines.h" */ |
| |
| /* Bootstrap the HeadCheck. Call this before anything else. |
| */ |
| void |
| chaz_HeadCheck_init(void); |
| |
| /* Check for a particular header and return true if it's available. The |
| * test-compile is only run the first time a given request is made. |
| */ |
| int |
| chaz_HeadCheck_check_header(const char *header_name); |
| |
| /* Attempt to compile a file which pulls in all the headers specified by name |
| * in a null-terminated array. If the compile succeeds, add them all to the |
| * internal register and return true. |
| */ |
| int |
| chaz_HeadCheck_check_many_headers(const char **header_names); |
| |
| /* Return true if the member is present in the struct. */ |
| int |
| chaz_HeadCheck_contains_member(const char *struct_name, const char *member, |
| const char *includes); |
| |
| #endif /* H_CHAZ_HEAD_CHECK */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/Make.h" |
| /* Charmonizer/Core/Make.h |
| */ |
| |
| #ifndef H_CHAZ_MAKE |
| #define H_CHAZ_MAKE |
| |
| /* #include "Charmonizer/Core/CFlags.h" */ |
| /* #include "Charmonizer/Core/Library.h" */ |
| |
| typedef struct chaz_MakeFile chaz_MakeFile; |
| typedef struct chaz_MakeVar chaz_MakeVar; |
| typedef struct chaz_MakeRule chaz_MakeRule; |
| |
| typedef void (*chaz_Make_list_files_callback_t)(const char *dir, char *file, |
| void *context); |
| |
| /** Initialize the environment. |
| */ |
| void |
| chaz_Make_init(void); |
| |
| /** Clean up the environment. |
| */ |
| void |
| chaz_Make_clean_up(void); |
| |
| /** Return the name of the detected 'make' executable. |
| */ |
| const char* |
| chaz_Make_get_make(void); |
| |
| /** Return the type of shell used by the detected 'make' executable. |
| */ |
| int |
| chaz_Make_shell_type(void); |
| |
| /** Recursively list files in a directory. For every file a callback is called |
| * with the filename and a context variable. |
| * |
| * @param dir Directory to search in. |
| * @param ext File extension to search for. |
| * @param callback Callback to call for every matching file. |
| * @param context Context variable to pass to callback. |
| */ |
| void |
| chaz_Make_list_files(const char *dir, const char *ext, |
| chaz_Make_list_files_callback_t callback, void *context); |
| |
| /** MakeFile constructor. |
| */ |
| chaz_MakeFile* |
| chaz_MakeFile_new(); |
| |
| /** MakeFile destructor. |
| */ |
| void |
| chaz_MakeFile_destroy(chaz_MakeFile *makefile); |
| |
| /** Add a variable to a makefile. |
| * |
| * @param makefile The makefile. |
| * @param name Name of the variable. |
| * @param value Value of the variable. Can be NULL if you want add content |
| * later. |
| * @return a MakeVar. |
| */ |
| chaz_MakeVar* |
| chaz_MakeFile_add_var(chaz_MakeFile *makefile, const char *name, |
| const char *value); |
| |
| /** Add a rule to a makefile. |
| * |
| * @param makefile The makefile. |
| * @param target The first target of the rule. Can be NULL if you want to add |
| * targets later. |
| * @param prereq The first prerequisite of the rule. Can be NULL if you want to |
| * add prerequisites later. |
| * @return a MakeRule. |
| */ |
| chaz_MakeRule* |
| chaz_MakeFile_add_rule(chaz_MakeFile *makefile, const char *target, |
| const char *prereq); |
| |
| /** Return the rule for the 'clean' target. |
| * |
| * @param makefile The makefile. |
| */ |
| chaz_MakeRule* |
| chaz_MakeFile_clean_rule(chaz_MakeFile *makefile); |
| |
| /** Return the rule for the 'distclean' target. |
| * |
| * @param makefile The makefile. |
| */ |
| chaz_MakeRule* |
| chaz_MakeFile_distclean_rule(chaz_MakeFile *makefile); |
| |
| /** Add a rule to link an executable. The executable will also be added to the |
| * list of files to clean. |
| * |
| * @param makefile The makefile. |
| * @param exe The name of the executable. |
| * @param sources The list of source files. |
| * @param link_flags Additional link flags. |
| */ |
| chaz_MakeRule* |
| chaz_MakeFile_add_exe(chaz_MakeFile *makefile, const char *exe, |
| const char *sources, chaz_CFlags *link_flags); |
| |
| /** Add a rule to compile and link an executable. The executable will also be |
| * added to the list of files to clean. |
| * |
| * @param makefile The makefile. |
| * @param exe The name of the executable. |
| * @param sources The list of source files. |
| * @param cflags Additional compiler flags. |
| */ |
| chaz_MakeRule* |
| chaz_MakeFile_add_compiled_exe(chaz_MakeFile *makefile, const char *exe, |
| const char *sources, chaz_CFlags *cflags); |
| |
| /** Add a rule to link a shared library. The shared library will also be added |
| * to the list of files to clean. |
| * |
| * @param makefile The makefile. |
| * @param lib The shared library. |
| * @param sources The list of source files. |
| * @param link_flags Additional link flags. |
| */ |
| chaz_MakeRule* |
| chaz_MakeFile_add_shared_lib(chaz_MakeFile *makefile, chaz_Lib *lib, |
| const char *sources, chaz_CFlags *link_flags); |
| |
| /** Add a rule to create a static library. The static library will also be added |
| * to the list of files to clean. |
| * |
| * @param makefile The makefile. |
| * @param lib The static library. |
| * @param objects The list of object files to be archived. |
| */ |
| chaz_MakeRule* |
| chaz_MakeFile_add_static_lib(chaz_MakeFile *makefile, chaz_Lib *lib, |
| const char *objects); |
| |
| /** Add a rule to build the lemon parser generator. |
| * |
| * @param makefile The makefile. |
| * @param dir The lemon directory. |
| */ |
| chaz_MakeRule* |
| chaz_MakeFile_add_lemon_exe(chaz_MakeFile *makefile, const char *dir); |
| |
| /** Add a rule for a lemon grammar. |
| * |
| * @param makefile The makefile. |
| * @param base_name The filename of the grammar without extension. |
| */ |
| chaz_MakeRule* |
| chaz_MakeFile_add_lemon_grammar(chaz_MakeFile *makefile, |
| const char *base_name); |
| |
| /** Write the makefile to a file named 'Makefile' in the current directory. |
| * |
| * @param makefile The makefile. |
| */ |
| void |
| chaz_MakeFile_write(chaz_MakeFile *makefile); |
| |
| /** Append content to a makefile variable. The new content will be separated |
| * from the existing content with whitespace. |
| * |
| * @param var The variable. |
| * @param element The additional content. |
| */ |
| void |
| chaz_MakeVar_append(chaz_MakeVar *var, const char *element); |
| |
| /** Add another target to a makefile rule. |
| * |
| * @param rule The rule. |
| * @param target The additional rule. |
| */ |
| void |
| chaz_MakeRule_add_target(chaz_MakeRule *rule, const char *target); |
| |
| /** Add another prerequisite to a makefile rule. |
| * |
| * @param rule The rule. |
| * @param prereq The additional prerequisite. |
| */ |
| void |
| chaz_MakeRule_add_prereq(chaz_MakeRule *rule, const char *prereq); |
| |
| /** Add a command to a rule. |
| * |
| * @param rule The rule. |
| * @param command The additional command. |
| */ |
| void |
| chaz_MakeRule_add_command(chaz_MakeRule *rule, const char *command); |
| |
| /** Add a command to remove one or more files. |
| * |
| * @param rule The rule. |
| * @param files The list of files. |
| */ |
| void |
| chaz_MakeRule_add_rm_command(chaz_MakeRule *rule, const char *files); |
| |
| /** Add a command to remove one or more directories. |
| * |
| * @param rule The rule. |
| * @param dirs The list of directories. |
| */ |
| void |
| chaz_MakeRule_add_recursive_rm_command(chaz_MakeRule *rule, const char *dirs); |
| |
| /** Add one or more commands to call another makefile recursively. |
| * |
| * @param rule The rule. |
| * @param dir The directory in which to call the makefile. |
| * @param target The target to call. Pass NULL for the default target. |
| */ |
| void |
| chaz_MakeRule_add_make_command(chaz_MakeRule *rule, const char *dir, |
| const char *target); |
| |
| #endif /* H_CHAZ_MAKE */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/OperatingSystem.h" |
| /* Charmonizer/Core/OperatingSystem.h - abstract an operating system down to a few |
| * variables. |
| */ |
| |
| #ifndef H_CHAZ_OPER_SYS |
| #define H_CHAZ_OPER_SYS |
| |
| #define CHAZ_OS_POSIX 1 |
| #define CHAZ_OS_CMD_EXE 2 |
| |
| /* Safely remove a file named [name]. Needed because of Windows quirks. |
| * Returns true on success, false on failure. |
| */ |
| int |
| chaz_OS_remove(const char *name); |
| |
| /* Invoke a command and attempt to suppress output from both stdout and stderr |
| * (as if they had been sent to /dev/null). If it's not possible to run the |
| * command quietly, run it anyway. |
| */ |
| int |
| chaz_OS_run_quietly(const char *command); |
| |
| /* Capture both stdout and stderr for a command to the supplied filepath. |
| */ |
| int |
| chaz_OS_run_redirected(const char *command, const char *path); |
| |
| /* Run a command beginning with the name of an executable in the current |
| * working directory and capture both stdout and stderr to the supplied |
| * filepath. |
| */ |
| int |
| chaz_OS_run_local_redirected(const char *command, const char *path); |
| |
| /* Run a command and return the output from stdout. |
| */ |
| char* |
| chaz_OS_run_and_capture(const char *command, size_t *output_len); |
| |
| /* Attempt to create a directory. |
| */ |
| void |
| chaz_OS_mkdir(const char *filepath); |
| |
| /* Attempt to remove a directory, which must be empty. |
| */ |
| void |
| chaz_OS_rmdir(const char *filepath); |
| |
| /* Return the operating system name. |
| */ |
| const char* |
| chaz_OS_name(void); |
| |
| int |
| chaz_OS_is_darwin(void); |
| |
| int |
| chaz_OS_is_cygwin(void); |
| |
| /* Return the extension for an executable on this system. |
| */ |
| const char* |
| chaz_OS_exe_ext(void); |
| |
| /* Return the extension for a shared object on this system. |
| */ |
| const char* |
| chaz_OS_shared_lib_ext(void); |
| |
| /* Return the extension for a static library on this system. |
| */ |
| const char* |
| chaz_OS_static_lib_ext(void); |
| |
| /* Return the equivalent of /dev/null on this system. |
| */ |
| const char* |
| chaz_OS_dev_null(void); |
| |
| /* Return the directory separator on this system. |
| */ |
| const char* |
| chaz_OS_dir_sep(void); |
| |
| /* Return the shell type of this system. |
| */ |
| int |
| chaz_OS_shell_type(void); |
| |
| /* Initialize the Charmonizer/Core/OperatingSystem module. |
| */ |
| void |
| chaz_OS_init(void); |
| |
| #endif /* H_CHAZ_COMPILER */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Core/Util.h" |
| /* Chaz/Core/Util.h -- miscellaneous utilities. |
| */ |
| |
| #ifndef H_CHAZ_UTIL |
| #define H_CHAZ_UTIL 1 |
| |
| #include <stdio.h> |
| #include <stddef.h> |
| #include <stdarg.h> |
| |
| extern int chaz_Util_verbosity; |
| |
| /* Open a file (truncating if necessary) and write [content] to it. Util_die() if |
| * an error occurs. |
| */ |
| void |
| chaz_Util_write_file(const char *filename, const char *content); |
| |
| /* Read an entire file into memory. |
| */ |
| char* |
| chaz_Util_slurp_file(const char *file_path, size_t *len_ptr); |
| |
| /* Return a newly allocated copy of a NULL-terminated string. |
| */ |
| char* |
| chaz_Util_strdup(const char *string); |
| |
| /* Join a NULL-terminated list of strings using a separator. |
| */ |
| char* |
| chaz_Util_join(const char *sep, ...); |
| |
| /* Get the length of a file (may overshoot on text files under DOS). |
| */ |
| long |
| chaz_Util_flength(void *file); |
| |
| /* Print an error message to stderr and exit. |
| */ |
| void |
| chaz_Util_die(const char *format, ...); |
| |
| /* Print an error message to stderr. |
| */ |
| void |
| chaz_Util_warn(const char *format, ...); |
| |
| /* Attept to delete a file. Return true if the file is gone, whether or not |
| * it was there to begin with. Issue a warning and return false if the file |
| * still exists. |
| */ |
| int |
| chaz_Util_remove_and_verify(const char *file_path); |
| |
| /* Attempt to open a file for reading, then close it immediately. |
| */ |
| int |
| chaz_Util_can_open_file(const char *file_path); |
| |
| #endif /* H_CHAZ_UTIL */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe.h" |
| #ifndef H_CHAZ |
| #define H_CHAZ 1 |
| |
| #include <stddef.h> |
| #include <stdio.h> |
| |
| struct chaz_CLI; |
| |
| /* Parse command line arguments, initializing and filling in the supplied |
| * `args` struct. |
| * |
| * APP_NAME --cc=CC_COMMAND |
| * [--enable-c] |
| * [--enable-perl] |
| * [--enable-python] |
| * [--enable-ruby] |
| * [-- [CFLAGS]] |
| * |
| * @return true if argument parsing proceeds without incident, false if |
| * unexpected arguments are encountered or values are missing or invalid. |
| */ |
| int |
| chaz_Probe_parse_cli_args(int argc, const char *argv[], |
| struct chaz_CLI *cli); |
| |
| /* Exit after printing usage instructions to stderr. |
| */ |
| void |
| chaz_Probe_die_usage(void); |
| |
| /* Set up the Charmonizer environment. |
| * |
| * If the environment variable CHARM_VERBOSITY has been set, it will be |
| * processed at this time: |
| * |
| * 0 - silent |
| * 1 - normal |
| * 2 - debugging |
| */ |
| void |
| chaz_Probe_init(struct chaz_CLI *cli); |
| |
| /* Clean up the Charmonizer environment -- deleting tempfiles, etc. This |
| * should be called only after everything else finishes. |
| */ |
| void |
| chaz_Probe_clean_up(void); |
| |
| /* Return an integer version of the GCC version number which is |
| * (10000 * __GNU_C__ + 100 * __GNUC_MINOR__ + __GNUC_PATCHLEVEL__). |
| */ |
| int |
| chaz_Probe_gcc_version_num(void); |
| |
| /* If the compiler is GCC (or claims compatibility), return an X.Y.Z string |
| * version of the GCC version; otherwise, return NULL. |
| */ |
| const char* |
| chaz_Probe_gcc_version(void); |
| |
| /* Return the integer version of MSVC defined by _MSC_VER |
| */ |
| int |
| chaz_Probe_msvc_version_num(void); |
| |
| #endif /* Include guard. */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/AtomicOps.h" |
| /* Charmonizer/Probe/AtomicOps.h |
| */ |
| |
| #ifndef H_CHAZ_ATOMICOPS |
| #define H_CHAZ_ATOMICOPS |
| |
| #include <stdio.h> |
| |
| /* Run the AtomicOps module. |
| * |
| * These following symbols will be defined if the associated headers are |
| * available: |
| * |
| * HAS_LIBKERN_OSATOMIC_H <libkern/OSAtomic.h> (Mac OS X) |
| * HAS_SYS_ATOMIC_H <sys/atomic.h> (Solaris) |
| * HAS_INTRIN_H <intrin.h> (Windows) |
| * |
| * This symbol is defined if OSAtomicCompareAndSwapPtr is available: |
| * |
| * HAS_OSATOMIC_CAS_PTR |
| */ |
| void chaz_AtomicOps_run(void); |
| |
| #endif /* H_CHAZ_ATOMICOPS */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/Booleans.h" |
| /* Charmonizer/Probe/Booleans.h -- bool type. |
| * |
| * If stdbool.h is is available, it will be pound-included in the configuration |
| * header. If it is not, the following typedef will be defined: |
| * |
| * bool |
| * |
| * These symbols will be defined if they are not already: |
| * |
| * true |
| * false |
| */ |
| |
| #ifndef H_CHAZ_BOOLEANS |
| #define H_CHAZ_BOOLEANS |
| |
| #include <stdio.h> |
| |
| /* Run the Booleans module. |
| */ |
| void chaz_Booleans_run(void); |
| |
| #endif /* H_CHAZ_BOOLEANS */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/BuildEnv.h" |
| /* Charmonizer/Probe/BuildEnv.h -- Build environment. |
| * |
| * Capture various information about the build environment, including the C |
| * compiler's interface, the shell, the operating system, etc. |
| * |
| * The following symbols will be defined: |
| * |
| * CC - String representation of the C compiler executable. |
| * CFLAGS - C compiler flags. |
| * EXTRA_CFLAGS - Extra C compiler flags. |
| */ |
| |
| #ifndef H_CHAZ_BUILDENV |
| #define H_CHAZ_BUILDENV |
| |
| #include <stdio.h> |
| |
| /* Run the BuildEnv module. |
| */ |
| void chaz_BuildEnv_run(void); |
| |
| #endif /* H_CHAZ_BUILDENV */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/DirManip.h" |
| /* Charmonizer/Probe/DirManip.h |
| */ |
| |
| #ifndef H_CHAZ_DIRMANIP |
| #define H_CHAZ_DIRMANIP |
| |
| /* The DirManip module exports or aliases symbols related to directory and file |
| * manipulation. |
| * |
| * Defined if the header files dirent.h and direct.h are available, respectively: |
| * |
| * HAS_DIRENT_H |
| * HAS_DIRECT_H |
| * |
| * Defined if struct dirent has these members. |
| * |
| * HAS_DIRENT_D_NAMLEN |
| * HAS_DIRENT_D_TYPE |
| * |
| * The "makedir" macro will be aliased to the POSIX-specified two-argument |
| * "mkdir" interface: |
| * |
| * makedir |
| * |
| * On some systems, the second argument to makedir will be ignored, in which |
| * case this symbol will be true; otherwise, it will be false: (TODO: This |
| * isn't verified and may sometimes be incorrect.) |
| * |
| * MAKEDIR_MODE_IGNORED |
| * |
| * String representing the system's directory separator: |
| * |
| * DIR_SEP |
| * |
| * True if the remove() function removes directories, false otherwise: |
| * |
| * REMOVE_ZAPS_DIRS |
| */ |
| void chaz_DirManip_run(void); |
| |
| #endif /* H_CHAZ_DIR_SEP */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/Floats.h" |
| /* Charmonizer/Probe/Floats.h -- floating point types. |
| * |
| * The following symbols will be created if the platform supports IEEE 754 |
| * floating point types: |
| * |
| * F32_NAN |
| * F32_INF |
| * F32_NEGINF |
| * F64_NAN |
| * F64_INF |
| * F64_NEGINF |
| * |
| * TODO: Actually test to see whether IEEE 754 is supported, rather than just |
| * lying about it. |
| */ |
| |
| #ifndef H_CHAZ_FLOATS |
| #define H_CHAZ_FLOATS |
| |
| /* Run the Floats module. |
| */ |
| void |
| chaz_Floats_run(void); |
| |
| /* Return the name of the math library to link against or NULL. |
| */ |
| const char* |
| chaz_Floats_math_library(void); |
| |
| #endif /* H_CHAZ_FLOATS */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/FuncMacro.h" |
| /* Charmonizer/Probe/FuncMacro.h |
| */ |
| |
| #ifndef H_CHAZ_FUNC_MACRO |
| #define H_CHAZ_FUNC_MACRO |
| |
| #include <stdio.h> |
| |
| /* Run the FuncMacro module. |
| * |
| * If __func__ successfully resolves, this will be defined: |
| * |
| * HAS_ISO_FUNC_MACRO |
| * |
| * If __FUNCTION__ successfully resolves, this will be defined: |
| * |
| * HAS_GNUC_FUNC_MACRO |
| * |
| * If one or the other succeeds, these will be defined: |
| * |
| * HAS_FUNC_MACRO |
| * FUNC_MACRO |
| * |
| * The "inline" keyword will also be probed for. If it is available, the |
| * following macro will be defined to "inline", otherwise it will be defined |
| * to nothing. |
| * |
| * INLINE |
| */ |
| void chaz_FuncMacro_run(void); |
| |
| #endif /* H_CHAZ_FUNC_MACRO */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 20 "src/Charmonizer/Probe/Headers.h" |
| /* Charmonizer/Probe/Headers.h |
| */ |
| |
| #ifndef H_CHAZ_HEADERS |
| #define H_CHAZ_HEADERS |
| |
| #include <stdio.h> |
| /* #include "Charmonizer/Core/Defines.h" */ |
| |
| /* Check whether a particular header file is available. The test-compile is |
| * only run the first time a given request is made. |
| */ |
| int |
| chaz_Headers_check(const char *header_name); |
| |
| /* Run the Headers module. |
| * |
| * Exported symbols: |
| * |
| * If HAS_C89 is declared, this system has all the header files described in |
| * Ansi C 1989. HAS_C90 is a synonym. (It would be surprising if they are |
| * not defined, because Charmonizer itself assumes C89.) |
| * |
| * HAS_C89 |
| * HAS_C90 |
| * |
| * One symbol is exported for each C89 header file: |
| * |
| * HAS_ASSERT_H |
| * HAS_CTYPE_H |
| * HAS_ERRNO_H |
| * HAS_FLOAT_H |
| * HAS_LIMITS_H |
| * HAS_LOCALE_H |
| * HAS_MATH_H |
| * HAS_SETJMP_H |
| * HAS_SIGNAL_H |
| * HAS_STDARG_H |
| * HAS_STDDEF_H |
| * HAS_STDIO_H |
| * HAS_STDLIB_H |
| * HAS_STRING_H |
| * HAS_TIME_H |
| * |
| * One symbol is exported for every POSIX header present, and HAS_POSIX is |
| * exported if they're all there. |
| * |
| * HAS_POSIX |
| * |
| * HAS_CPIO_H |
| * HAS_DIRENT_H |
| * HAS_FCNTL_H |
| * HAS_GRP_H |
| * HAS_PWD_H |
| * HAS_SYS_STAT_H |
| * HAS_SYS_TIMES_H |
| * HAS_SYS_TYPES_H |
| * HAS_SYS_UTSNAME_H |
| * HAS_WAIT_H |
| * HAS_TAR_H |
| * HAS_TERMIOS_H |
| * HAS_UNISTD_H |
| * HAS_UTIME_H |
| * |
| * If pthread.h is available, this will be exported: |
| * |
| * HAS_PTHREAD_H |
| */ |
| void |
| chaz_Headers_run(void); |
| |
| #endif /* H_CHAZ_HEADERS */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/Integers.h" |
| /* Charmonizer/Probe/Integers.h -- info about integer types and sizes. |
| * |
| * One or the other of these will be defined, depending on whether the |
| * processor is big-endian or little-endian. |
| * |
| * BIG_END |
| * LITTLE_END |
| * |
| * These will always be defined: |
| * |
| * SIZEOF_CHAR |
| * SIZEOF_SHORT |
| * SIZEOF_INT |
| * SIZEOF_LONG |
| * SIZEOF_PTR |
| * |
| * If long longs are available these symbols will be defined: |
| * |
| * HAS_LONG_LONG |
| * SIZEOF_LONG_LONG |
| * |
| * Similarly, with the __int64 type (the sizeof is included for completeness): |
| * |
| * HAS___INT64 |
| * SIZEOF___INT64 |
| * |
| * If the inttypes.h or stdint.h header files are available, these may be |
| * defined: |
| * |
| * HAS_INTTYPES_H |
| * HAS_STDINT_H |
| * |
| * If stdint.h is is available, it will be pound-included in the configuration |
| * header. If it is not, the following typedefs and macros will be defined if |
| * possible: |
| * |
| * int8_t |
| * int16_t |
| * int32_t |
| * int64_t |
| * uint8_t |
| * uint16_t |
| * uint32_t |
| * uint64_t |
| * INT8_MAX |
| * INT16_MAX |
| * INT32_MAX |
| * INT64_MAX |
| * INT8_MIN |
| * INT16_MIN |
| * INT32_MIN |
| * INT64_MIN |
| * UINT8_MAX |
| * UINT16_MAX |
| * UINT32_MAX |
| * UINT64_MAX |
| * SIZE_MAX |
| * INT32_C |
| * INT64_C |
| * UINT32_C |
| * UINT64_C |
| * |
| * If inttypes.h is is available, it will be pound-included in the |
| * configuration header. If it is not, the following macros will be defined if |
| * possible: |
| * |
| * PRId64 |
| * PRIu64 |
| * |
| * Availability of integer types is indicated by which of these are defined: |
| * |
| * HAS_INT8_T |
| * HAS_INT16_T |
| * HAS_INT32_T |
| * HAS_INT64_T |
| * |
| * If 64-bit integers are available, this macro will promote pointers to i64_t |
| * safely. |
| * |
| * PTR_TO_I64(ptr) |
| */ |
| |
| #ifndef H_CHAZ_INTEGERS |
| #define H_CHAZ_INTEGERS |
| |
| #include <stdio.h> |
| |
| /* Run the Integers module. |
| */ |
| void chaz_Integers_run(void); |
| |
| #endif /* H_CHAZ_INTEGERS */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/LargeFiles.h" |
| /* Charmonizer/Probe/LargeFiles.h |
| */ |
| |
| #ifndef H_CHAZ_LARGE_FILES |
| #define H_CHAZ_LARGE_FILES |
| |
| #include <stdio.h> |
| |
| /* The LargeFiles module attempts to detect these symbols or alias them to |
| * synonyms: |
| * |
| * off64_t |
| * fopen64 |
| * ftello64 |
| * fseeko64 |
| * lseek64 |
| * pread64 |
| * |
| * If off64_t or its equivalent is available, this will be defined: |
| * |
| * HAS_64BIT_OFFSET_TYPE |
| * |
| * If 64-bit variants of fopen, ftell, and fseek are available, this will be |
| * defined: |
| * |
| * HAS_64BIT_STDIO |
| * |
| * If 64-bit variants of pread and lseek are available, then corresponding |
| * symbols will be defined: |
| * |
| * HAS_64BIT_PREAD |
| * HAS_64BIT_LSEEK |
| * |
| * Use of the off64_t symbol may require sys/types.h. |
| */ |
| void chaz_LargeFiles_run(void); |
| |
| #endif /* H_CHAZ_LARGE_FILES */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/Memory.h" |
| /* Charmonizer/Probe/Memory.h |
| */ |
| |
| #ifndef H_CHAZ_MEMORY |
| #define H_CHAZ_MEMORY |
| |
| /* The Memory module attempts to detect these symbols or alias them to |
| * synonyms: |
| * |
| * alloca |
| * |
| * These following symbols will be defined if the associated headers are |
| * available: |
| * |
| * HAS_SYS_MMAN_H <sys/mman.h> |
| * HAS_ALLOCA_H <alloca.h> |
| * HAS_MALLOC_H <malloc.h> |
| * |
| * Defined if alloca() is available via stdlib.h: |
| * |
| * ALLOCA_IN_STDLIB_H |
| */ |
| void chaz_Memory_run(void); |
| |
| #endif /* H_CHAZ_MEMORY */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/RegularExpressions.h" |
| /* Charmonizer/Probe/RegularExpressions.h -- regular expressions. |
| */ |
| |
| #ifndef H_CHAZ_REGULAREXPRESSIONS |
| #define H_CHAZ_REGULAREXPRESSIONS |
| |
| /* Run the RegularExpressions module. |
| */ |
| void chaz_RegularExpressions_run(void); |
| |
| #endif /* H_CHAZ_REGULAREXPRESSIONS */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/Strings.h" |
| /* Charmonizer/Probe/Strings.h |
| */ |
| |
| #ifndef H_CHAZ_STRINGS |
| #define H_CHAZ_STRINGS |
| |
| /* The Strings module attempts to detect whether snprintf works as specified |
| * by the C99 standard. It also looks for system-specific functions which can |
| * be used to emulate snprintf. |
| */ |
| void chaz_Strings_run(void); |
| |
| #endif /* H_CHAZ_STRINGS */ |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/SymbolVisibility.h" |
| /* Charmonizer/Probe/SymbolVisibility.h |
| */ |
| |
| #ifndef H_CHAZ_SYMBOLVISIBILITY |
| #define H_CHAZ_SYMBOLVISIBILITY |
| |
| void chaz_SymbolVisibility_run(void); |
| |
| #endif /* H_CHAZ_SYMBOLVISIBILITY */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/UnusedVars.h" |
| /* Charmonizer/Probe/UnusedVars.h |
| */ |
| |
| #ifndef H_CHAZ_UNUSED_VARS |
| #define H_CHAZ_UNUSED_VARS |
| |
| #include <stdio.h> |
| |
| /* Run the UnusedVars module. |
| * |
| * These symbols are exported: |
| * |
| * UNUSED_VAR(var) |
| * UNREACHABLE_RETURN(type) |
| * |
| */ |
| void chaz_UnusedVars_run(void); |
| |
| #endif /* H_CHAZ_UNUSED_VARS */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 21 "src/Charmonizer/Probe/VariadicMacros.h" |
| /* Charmonizer/Probe/VariadicMacros.h |
| */ |
| |
| #ifndef H_CHAZ_VARIADIC_MACROS |
| #define H_CHAZ_VARIADIC_MACROS |
| |
| #include <stdio.h> |
| |
| /* Run the VariadicMacros module. |
| * |
| * If your compiler supports ISO-style variadic macros, this will be defined: |
| * |
| * HAS_ISO_VARIADIC_MACROS |
| * |
| * If your compiler supports GNU-style variadic macros, this will be defined: |
| * |
| * HAS_GNUC_VARIADIC_MACROS |
| * |
| * If you have at least one of the above, this will be defined: |
| * |
| * HAS_VARIADIC_MACROS |
| */ |
| void chaz_VariadicMacros_run(void); |
| |
| #endif /* H_CHAZ_VARIADIC_MACROS */ |
| |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 17 "src/Charmonizer/Core/Library.c" |
| #include <string.h> |
| #include <stdlib.h> |
| /* #include "Charmonizer/Core/Library.h" */ |
| /* #include "Charmonizer/Core/Compiler.h" */ |
| /* #include "Charmonizer/Core/Util.h" */ |
| /* #include "Charmonizer/Core/OperatingSystem.h" */ |
| |
| struct chaz_Lib { |
| char *name; |
| char *version; |
| char *major_version; |
| int is_static; |
| int is_shared; |
| chaz_LibType lib_type; |
| }; |
| |
| static char* |
| S_build_filename(chaz_Lib *lib, const char *version, const char *ext); |
| |
| static const char* |
| S_get_prefix(void); |
| |
| chaz_Lib* |
| chaz_Lib_new(const char *name, chaz_LibType lib_type, const char *version, |
| const char *major_version) { |
| chaz_Lib *lib = (chaz_Lib*)malloc(sizeof(chaz_Lib)); |
| lib->name = chaz_Util_strdup(name); |
| lib->version = chaz_Util_strdup(version); |
| lib->major_version = chaz_Util_strdup(major_version); |
| lib->lib_type = lib_type; |
| if (lib_type == chaz_Lib_SHARED) { |
| lib->is_shared = 1; |
| lib->is_static = 0; |
| } |
| else if (lib_type == chaz_Lib_STATIC) { |
| lib->is_shared = 0; |
| lib->is_static = 1; |
| } |
| else { |
| chaz_Util_die("Invalid value for lib_type: %d", lib_type); |
| } |
| return lib; |
| } |
| |
| void |
| chaz_Lib_destroy(chaz_Lib *lib) { |
| free(lib->name); |
| free(lib->version); |
| free(lib->major_version); |
| free(lib); |
| } |
| |
| const char* |
| chaz_Lib_get_name(chaz_Lib *lib) { |
| return lib->name; |
| } |
| |
| const char* |
| chaz_Lib_get_version(chaz_Lib *lib) { |
| return lib->version; |
| } |
| |
| const char* |
| chaz_Lib_get_major_version(chaz_Lib *lib) { |
| return lib->major_version; |
| } |
| |
| int |
| chaz_Lib_is_shared (chaz_Lib *lib) { |
| return lib->is_shared; |
| } |
| |
| int |
| chaz_Lib_is_static (chaz_Lib *lib) { |
| return lib->is_static; |
| } |
| |
| char* |
| chaz_Lib_filename(chaz_Lib *lib) { |
| const char *ext = lib->is_shared |
| ? chaz_OS_shared_lib_ext() |
| : chaz_OS_static_lib_ext(); |
| |
| if ((strcmp(ext, ".dll") == 0) || strcmp(ext, ".lib") == 0) { |
| return S_build_filename(lib, lib->major_version, ext); |
| } |
| else { |
| return S_build_filename(lib, lib->version, ext); |
| } |
| } |
| |
| char* |
| chaz_Lib_major_version_filename(chaz_Lib *lib) { |
| const char *ext = lib->is_shared |
| ? chaz_OS_shared_lib_ext() |
| : chaz_OS_static_lib_ext(); |
| return S_build_filename(lib, lib->major_version, ext); |
| } |
| |
| char* |
| chaz_Lib_no_version_filename(chaz_Lib *lib) { |
| const char *prefix = S_get_prefix(); |
| const char *ext = lib->is_shared |
| ? chaz_OS_shared_lib_ext() |
| : chaz_OS_static_lib_ext(); |
| return chaz_Util_join("", prefix, lib->name, ext, NULL); |
| } |
| |
| char* |
| chaz_Lib_implib_filename(chaz_Lib *lib) { |
| return S_build_filename(lib, lib->major_version, ".lib"); |
| } |
| |
| char* |
| chaz_Lib_export_filename(chaz_Lib *lib) { |
| return S_build_filename(lib, lib->major_version, ".exp"); |
| } |
| |
| static char* |
| S_build_filename(chaz_Lib *lib, const char *version, const char *ext) { |
| const char *prefix = S_get_prefix(); |
| const char *shlib_ext = chaz_OS_shared_lib_ext(); |
| |
| /* Use `shlib_ext` as a proxy for OS to determine behavior, but append |
| * the supplied `ext`. */ |
| if (strcmp(shlib_ext, ".dll") == 0) { |
| return chaz_Util_join("", prefix, lib->name, "-", version, ext, NULL); |
| } |
| else if (strcmp(shlib_ext, ".dylib") == 0) { |
| return chaz_Util_join("", prefix, lib->name, ".", version, ext, NULL); |
| } |
| else { |
| return chaz_Util_join("", prefix, lib->name, ext, ".", version, NULL); |
| } |
| } |
| |
| static const char* |
| S_get_prefix() { |
| if (chaz_CC_msvc_version_num()) { |
| return ""; |
| } |
| else if (chaz_OS_is_cygwin()) { |
| return "cyg"; |
| } |
| else { |
| return "lib"; |
| } |
| } |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 17 "src/Charmonizer/Core/CFlags.c" |
| #include <string.h> |
| #include <stdlib.h> |
| /* #include "Charmonizer/Core/CFlags.h" */ |
| /* #include "Charmonizer/Core/Compiler.h" */ |
| /* #include "Charmonizer/Core/Util.h" */ |
| /* #include "Charmonizer/Core/OperatingSystem.h" */ |
| /* #include "Charmonizer/Core/Library.h" */ |
| |
| struct chaz_CFlags { |
| int style; |
| char *string; |
| }; |
| |
| chaz_CFlags* |
| chaz_CFlags_new(int style) { |
| chaz_CFlags *flags = (chaz_CFlags*)malloc(sizeof(chaz_CFlags)); |
| flags->style = style; |
| flags->string = chaz_Util_strdup(""); |
| return flags; |
| } |
| |
| void |
| chaz_CFlags_destroy(chaz_CFlags *flags) { |
| free(flags->string); |
| free(flags); |
| } |
| |
| const char* |
| chaz_CFlags_get_string(chaz_CFlags *flags) { |
| return flags->string; |
| } |
| |
| void |
| chaz_CFlags_append(chaz_CFlags *flags, const char *string) { |
| char *new_string; |
| if (flags->string[0] == '\0') { |
| new_string = chaz_Util_strdup(string); |
| } |
| else { |
| new_string = chaz_Util_join(" ", flags->string, string, NULL); |
| } |
| free(flags->string); |
| flags->string = new_string; |
| } |
| |
| void |
| chaz_CFlags_clear(chaz_CFlags *flags) { |
| if (flags->string[0] != '\0') { |
| free(flags->string); |
| flags->string = chaz_Util_strdup(""); |
| } |
| } |
| |
| void |
| chaz_CFlags_set_output_obj(chaz_CFlags *flags, const char *filename) { |
| const char *output; |
| char *string; |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| output = "/c /Fo"; |
| } |
| else { |
| /* POSIX */ |
| output = "-c -o "; |
| } |
| string = chaz_Util_join("", output, filename, NULL); |
| chaz_CFlags_append(flags, string); |
| free(string); |
| } |
| |
| void |
| chaz_CFlags_set_output_exe(chaz_CFlags *flags, const char *filename) { |
| const char *output; |
| char *string; |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| output = "/Fe"; |
| } |
| else { |
| /* POSIX */ |
| output = "-o "; |
| } |
| string = chaz_Util_join("", output, filename, NULL); |
| chaz_CFlags_append(flags, string); |
| free(string); |
| } |
| |
| void |
| chaz_CFlags_add_define(chaz_CFlags *flags, const char *name, |
| const char *value) { |
| const char *define; |
| char *string; |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| define = "/D"; |
| } |
| else { |
| /* POSIX */ |
| define = "-D "; |
| } |
| if (value) { |
| string = chaz_Util_join("", define, name, "=", value, NULL); |
| } |
| else { |
| string = chaz_Util_join("", define, name, NULL); |
| } |
| chaz_CFlags_append(flags, string); |
| free(string); |
| } |
| |
| void |
| chaz_CFlags_add_include_dir(chaz_CFlags *flags, const char *dir) { |
| const char *include; |
| char *string; |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| include = "/I "; |
| } |
| else { |
| /* POSIX */ |
| include = "-I "; |
| } |
| string = chaz_Util_join("", include, dir, NULL); |
| chaz_CFlags_append(flags, string); |
| free(string); |
| } |
| |
| void |
| chaz_CFlags_enable_optimization(chaz_CFlags *flags) { |
| const char *string; |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| string = "/O2"; |
| } |
| else if (flags->style == CHAZ_CFLAGS_STYLE_GNU) { |
| string = "-O2"; |
| } |
| else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) { |
| string = "-xO4"; |
| } |
| else { |
| /* POSIX */ |
| string = "-O 1"; |
| } |
| chaz_CFlags_append(flags, string); |
| } |
| |
| void |
| chaz_CFlags_enable_debugging(chaz_CFlags *flags) { |
| if (flags->style == CHAZ_CFLAGS_STYLE_GNU |
| || flags->style == CHAZ_CFLAGS_STYLE_SUN_C) { |
| chaz_CFlags_append(flags, "-g"); |
| } |
| } |
| |
| void |
| chaz_CFlags_disable_strict_aliasing(chaz_CFlags *flags) { |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| return; |
| } |
| else if (flags->style == CHAZ_CFLAGS_STYLE_GNU) { |
| chaz_CFlags_append(flags, "-fno-strict-aliasing"); |
| } |
| else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) { |
| chaz_CFlags_append(flags, "-xalias_level=any"); |
| } |
| else { |
| chaz_Util_die("Don't know how to disable strict aliasing with '%s'", |
| chaz_CC_get_cc()); |
| } |
| } |
| |
| void |
| chaz_CFlags_set_warnings_as_errors(chaz_CFlags *flags) { |
| const char *string; |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| string = "/WX"; |
| } |
| else if (flags->style == CHAZ_CFLAGS_STYLE_GNU) { |
| string = "-Werror"; |
| } |
| else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) { |
| string = "-errwarn=%all"; |
| } |
| else { |
| chaz_Util_die("Don't know how to set warnings as errors with '%s'", |
| chaz_CC_get_cc()); |
| } |
| chaz_CFlags_append(flags, string); |
| } |
| |
| void |
| chaz_CFlags_compile_shared_library(chaz_CFlags *flags) { |
| const char *string; |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| string = "/MD"; |
| } |
| else if (flags->style == CHAZ_CFLAGS_STYLE_GNU) { |
| const char *shlib_ext = chaz_OS_shared_lib_ext(); |
| if (strcmp(shlib_ext, ".dylib") == 0) { |
| string = "-fno-common"; |
| } |
| else if (strcmp(shlib_ext, ".so") == 0) { |
| string = "-fPIC"; |
| } |
| else if (strcmp(shlib_ext, ".dll") == 0) { |
| /* MinGW */ |
| return; |
| } |
| else { |
| /* unknown */ |
| return; |
| } |
| } |
| else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) { |
| string = "-KPIC"; |
| } |
| else { |
| return; |
| } |
| chaz_CFlags_append(flags, string); |
| } |
| |
| void |
| chaz_CFlags_hide_symbols(chaz_CFlags *flags) { |
| if (flags->style == CHAZ_CFLAGS_STYLE_GNU) { |
| if (strcmp(chaz_OS_shared_lib_ext(), ".dll") != 0) { |
| chaz_CFlags_append(flags, "-fvisibility=hidden"); |
| } |
| } |
| else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) { |
| if (chaz_CC_sun_c_version_num() >= 0x550) { |
| /* Sun Studio 8. */ |
| chaz_CFlags_append(flags, "-xldscope=hidden"); |
| } |
| } |
| } |
| |
| void |
| chaz_CFlags_link_shared_library(chaz_CFlags *flags) { |
| const char *string; |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| string = "/DLL"; |
| } |
| else if (flags->style == CHAZ_CFLAGS_STYLE_GNU) { |
| if (strcmp(chaz_OS_shared_lib_ext(), ".dylib") == 0) { |
| string = "-dynamiclib"; |
| } |
| else { |
| string = "-shared"; |
| } |
| } |
| else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) { |
| string = "-G"; |
| } |
| else { |
| chaz_Util_die("Don't know how to link a shared library with '%s'", |
| chaz_CC_get_cc()); |
| } |
| chaz_CFlags_append(flags, string); |
| } |
| |
| void |
| chaz_CFlags_set_shared_library_version(chaz_CFlags *flags, chaz_Lib *lib) { |
| if (flags->style == CHAZ_CFLAGS_STYLE_GNU) { |
| const char *shlib_ext = chaz_OS_shared_lib_ext(); |
| |
| if (strcmp(shlib_ext, ".dylib") == 0) { |
| const char *version = chaz_Lib_get_version(lib); |
| char *string |
| = chaz_Util_join(" ", "-current_version", version, NULL); |
| chaz_CFlags_append(flags, string); |
| free(string); |
| } |
| else if (strcmp(shlib_ext, ".so") == 0) { |
| char *soname = chaz_Lib_major_version_filename(lib); |
| char *string = chaz_Util_join("", "-Wl,-soname,", soname, NULL); |
| chaz_CFlags_append(flags, string); |
| free(string); |
| free(soname); |
| } |
| } |
| else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) { |
| char *soname = chaz_Lib_major_version_filename(lib); |
| char *string = chaz_Util_join(" ", "-h", soname, NULL); |
| chaz_CFlags_append(flags, string); |
| free(string); |
| free(soname); |
| } |
| } |
| |
| void |
| chaz_CFlags_set_link_output(chaz_CFlags *flags, const char *filename) { |
| const char *output; |
| char *string; |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| output = "/OUT:"; |
| } |
| else { |
| output = "-o "; |
| } |
| string = chaz_Util_join("", output, filename, NULL); |
| chaz_CFlags_append(flags, string); |
| free(string); |
| } |
| |
| void |
| chaz_CFlags_add_library_path(chaz_CFlags *flags, const char *directory) { |
| const char *lib_path; |
| char *string; |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| if (strcmp(directory, ".") == 0) { |
| /* The MS linker searches the current directory by default. */ |
| return; |
| } |
| else { |
| lib_path = "/LIBPATH:"; |
| } |
| } |
| else { |
| lib_path = "-L "; |
| } |
| string = chaz_Util_join("", lib_path, directory, NULL); |
| chaz_CFlags_append(flags, string); |
| free(string); |
| } |
| |
| void |
| chaz_CFlags_add_library(chaz_CFlags *flags, chaz_Lib *lib) { |
| char *filename; |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| filename = chaz_Lib_implib_filename(lib); |
| } |
| else { |
| filename = chaz_Lib_filename(lib); |
| } |
| chaz_CFlags_append(flags, filename); |
| free(filename); |
| } |
| |
| void |
| chaz_CFlags_add_external_library(chaz_CFlags *flags, const char *library) { |
| char *string; |
| if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) { |
| string = chaz_Util_join("", library, ".lib", NULL); |
| } |
| else { |
| string = chaz_Util_join(" ", "-l", library, NULL); |
| } |
| chaz_CFlags_append(flags, string); |
| free(string); |
| } |
| |
| void |
| chaz_CFlags_enable_code_coverage(chaz_CFlags *flags) { |
| if (flags->style == CHAZ_CFLAGS_STYLE_GNU) { |
| chaz_CFlags_append(flags, "--coverage"); |
| } |
| else { |
| chaz_Util_die("Don't know how to enable code coverage with '%s'", |
| chaz_CC_get_cc()); |
| } |
| } |
| |
| |
| |
| /***************************************************************************/ |
| |
| #line 17 "src/Charmonizer/Core/CLI.c" |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <stdarg.h> |
| #include <string.h> |
| #include <ctype.h> |
| /* #include "Charmonizer/Core/CLI.h" */ |
| /* #include "Charmonizer/Core/Util.h" */ |
| |
| typedef struct chaz_CLIOption { |
| char *name; |
| char *help; |
| char *value; |
| int defined; |
| int flags; |
| } chaz_CLIOption; |
| |
| struct chaz_CLI { |
| char *name; |
| char *desc; |
| char *usage; |
| char *help; |
| chaz_CLIOption *opts; |
| int num_opts; |
| }; |
| |
| static void |
| S_chaz_CLI_error(chaz_CLI *self, const char *pattern, ...) { |
| va_list ap; |
| if (chaz_Util_verbosity > 0) { |
| va_start(ap, pattern); |
| vfprintf(stderr, pattern, ap); |
| va_end(ap); |
| fprintf(stderr, "\n"); |
| } |
| } |
| |
| static void |
| S_chaz_CLI_rebuild_help(chaz_CLI *self) { |
| int i; |
| size_t amount = 200; // Length of section headers. |
| |
| // Allocate space. |
| if (self->usage) { |
| amount += strlen(self->usage); |
| } |
| else { |
| amount += strlen(self->name); |
| } |
| if (self->desc) { |
| amount += strlen(self->desc); |
| } |
| for (i = 0; i < self->num_opts; i++) { |
| chaz_CLIOption *opt = &self->opts[i]; |
| amount += 24 + 2 * strlen(opt->name); |
| if (opt->flags) { |
| amount += strlen(opt->name); |
| } |
| if (opt->help) { |
| amount += strlen(opt->help); |
| } |
| } |
| free(self->help); |
| self->help = (char*)malloc(amount); |
| self->help[0] = '\0'; |
| |
| // Accumulate "help" string. |
| if (self->usage) { |
| strcat(self->help, self->usage); |
| } |
| else { |
| strcat(self->help, "Usage: "); |
| strcat(self->help, self->name); |
| if (self->num_opts) { |
| strcat(self->help, " [OPTIONS]"); |
| } |
| } |
| if (self->desc) { |
| strcat(self->help, "\n\n"); |
| strcat(self->help, self->desc); |
| } |
| strcat(self->help, "\n"); |
| if (self->num_opts) { |
| strcat(self->help, "\nOptional arguments:\n"); |
| for (i = 0; i < self->num_opts; i++) { |
| chaz_CLIOption *opt = &self->opts[i]; |
| size_t line_start = strlen(self->help); |
| size_t current_len; |
| |
| strcat(self->help, " --"); |
| strcat(self->help, opt->name); |
| current_len = strlen(self->help); |
| if (opt->flags) { |
| int j; |
| if (opt->flags & CHAZ_CLI_ARG_OPTIONAL) { |
| self->help[current_len++] = '['; |
| } |
| self->help[current_len++] = '='; |
| for (j = 0; opt->name[j]; j++) { |
| self->help[current_len++] = toupper(opt->name[j]); |
| } |
| if (opt->flags & CHAZ_CLI_ARG_OPTIONAL) { |
| strcat(self->help, "]"); |
| } |
| self->help[current_len] = '\0'; |
| } |
| if (opt->help) { |
| self->help[current_len++] = ' '; |
| while (current_len - line_start < 25) { |
| self->help[current_len++] = ' '; |
| } |
| self->help[current_len] = '\0'; |
| strcpy(self->help + current_len, opt->help); |
| } |
| strcat(self->help, "\n"); |
| } |
| } |
| strcat(self->help, "\n"); |
| } |
| |
| chaz_CLI* |
| chaz_CLI_new(const char *name, const char *description) { |
| chaz_CLI *self = calloc(1, sizeof(chaz_CLI)); |
| self->name = chaz_Util_strdup(name ? name : "PROGRAM"); |
| self->desc = description ? chaz_Util_strdup(description) : NULL; |
| self->help = NULL; |
| self->opts = NULL; |
| self->num_opts = 0; |
| S_chaz_CLI_rebuild_help(self); |
| return self; |
| } |
| |
| void |
| chaz_CLI_destroy(chaz_CLI *self) { |
| int i; |
| for (i = 0; i < self->num_opts; i++) { |
| chaz_CLIOption *opt = &self->opts[i]; |
| free(opt->name); |
| free(opt->help); |
| free(opt->value); |
| } |
| free(self->name); |
| free(self->desc); |
| free(self->opts); |
| free(self->usage); |
| free(self->help); |
| } |
| |
| void |
| chaz_CLI_set_usage(chaz_CLI *self, const char *usage) { |
| free(self->usage); |
| self->usage = chaz_Util_strdup(usage); |
| } |
| |
| const char* |
| chaz_CLI_help(chaz_CLI *self) { |
| return self->help; |
| } |
| |
| int |
| chaz_CLI_register(chaz_CLI *self, const char *name, const char *help, |
| int flags) { |
| int rank; |
| int i; |
| int arg_required = !!(flags & CHAZ_CLI_ARG_REQUIRED); |
| int arg_optional = !!(flags & CHAZ_CLI_ARG_OPTIONAL); |
| |
| // Validate flags |
| if (arg_required && arg_optional) { |
| S_chaz_CLI_error(self, "Conflicting flags: value both optional " |
| "and required"); |
| return 0; |
| } |
| |
| // Insert new option. Keep options sorted by name. |
| for (rank = self->num_opts; rank > 0; rank--) { |
| int comparison = strcmp(name, self->opts[rank - 1].name); |
| if (comparison == 0) { |
| S_chaz_CLI_error(self, "Option '%s' already registered", name); |
| return 0; |
| } |
| else if (comparison > 0) { |
| break; |
| } |
| } |
| self->num_opts += 1; |
| self->opts = realloc(self->opts, self->num_opts * sizeof(chaz_CLIOption)); |
| for (i = self->num_opts - 1; i > rank; i--) { |
| self->opts[i] = self->opts[i - 1]; |
| } |
| self->opts[rank].name = chaz_Util_strdup(name); |
| self->opts[rank].help = help ? chaz_Util_strdup(help) : NULL; |
| self->opts[rank].flags = flags; |
| self->opts[rank].defined = 0; |
| self->opts[rank].value = NULL; |
| |
| // Update `help` with new option. |
| S_chaz_CLI_rebuild_help(self); |
| |
| return 1; |
| } |
| |
| int |
| chaz_CLI_set(chaz_CLI *self, const char *name, const char *value) { |
| int i; |
| for (i = 0; i < self->num_opts; i++) { |
| chaz_CLIOption *opt = &self->opts[i]; |
| if (strcmp(opt->name, name) == 0) { |
| if (opt->defined) { |
| S_chaz_CLI_error(self, "'%s' specified multiple times", name); |
| return 0; |
| } |
| opt->defined = 1; |
| if (value != NULL) { |
| opt->value = chaz_Util_strdup(value); |
| } |
| return 1; |
| } |
| } |
| S_chaz_CLI_error(self, "Attempt to set unknown option: '%s'", name); |
| return 0; |
| } |
| |
| int |
| chaz_CLI_unset(chaz_CLI *self, const char *name) { |
| int i; |
| for (i = 0; i < self->num_opts; i++) { |
| chaz_CLIOption *opt = &self->opts[i]; |
| if (strcmp(opt->name, name) == 0) { |
| free(opt->value); |
| opt->value = NULL; |
| opt->defined = 0; |
| return 1; |
| } |
| } |
| S_chaz_CLI_error(self, "Attempt to unset unknown option: '%s'", name); |
| return 0; |
| } |
| |
| int |
| chaz_CLI_defined(chaz_CLI *self, const char *name) { |
| int i; |
| for (i = 0; i < self->num_opts; i++) { |
| chaz_CLIOption *opt = &self->opts[i]; |
| if (strcmp(opt->name, name) == 0) { |
| return opt->defined; |
| } |
| } |
| S_chaz_CLI_error(self, "Inquiry for unknown option: '%s'", name); |
| return 0; |
| } |
| |
| long |
| chaz_CLI_longval(chaz_CLI *self, const char *name) { |
| int i; |
| for (i = 0; i < self->num_opts; i++) { |
| chaz_CLIOption *opt = &self->opts[i]; |
| if (strcmp(opt->name, name) == 0) { |
| if (!opt->defined || !opt->value) { |
| return 0; |
| } |
| return strtol(opt->value, NULL, 10); |
| } |
| } |
| S_chaz_CLI_error(self, "Longval request for unknown option: '%s'", name); |
| return 0; |
| } |
| |
| const char* |
| chaz_CLI_strval(chaz_CLI *self, const char *name) { |
| int i; |
| for (i = 0; i < self->num_opts; i++) { |
| chaz_CLIOption *opt = &self->opts[i]; |
| if (strcmp(opt->name, name) == 0) { |
| return opt->value; |
| } |
| } |
| S_chaz_CLI_error(self, "Strval request for unknown option: '%s'", name); |
| return 0; |
| } |
| |
| int |
| chaz_CLI_parse(chaz_CLI *self, int argc, const char *argv[]) { |
| int i; |
| char *name = NULL; |
| size_t name_cap = 0; |
| |
| /* Parse most args. */ |
| for (i = 1; i < argc; i++) { |
| const char *arg = argv[i]; |
| size_t name_len = 0; |
| int has_equals = 0; |
| const char *value = NULL; |
| |
| /* Stop processing if we see `-` or `--`. */ |
| if (strcmp(arg, "--") == 0 || strcmp(arg, "-") == 0) { |
| break; |
| } |
| |
| if (strncmp(arg, "--", 2) != 0) { |
| S_chaz_CLI_error(self, "Unexpected argument: '%s'", arg); |
| free(name); |
| return 0; |
| } |
| |
| /* Extract the name of the argument, look for a potential value. */ |
| while (1) { |
| char c = arg[name_len + 2]; |
| if (isalnum(c) || c == '-' || c == '_') { |
| name_len++; |
| } |
| else if (c == '\0') { |
| break; |
| } |
| else if (c == '=') { |
| /* The rest of the arg is the value. */ |
| value = arg + 2 + name_len + 1; |
| break; |
| } |
| else { |
| free(name); |
| S_chaz_CLI_error(self, "Malformed argument: '%s'", arg); |
| return 0; |
| } |
| } |
| if (name_len + 1 > name_cap) { |
| name_cap = name_len + 1; |
| name = (char*)realloc(name, name_cap); |
| } |
| memcpy(name, arg + 2, name_len); |
| name[name_len] = '\0'; |
| |
| /* Attempt to set the option. */ |
| if (!chaz_CLI_set(self, name, value)) { |
| free(name); |
| return 0; |
| } |
| } |
| |
| return 1; |
| } |
| |
| |
| /***************************************************************************/ |
| |
| #line 17 "src/Charmonizer/Core/Compiler.c" |
| #include <string.h> |
| #include <stdlib.h> |
| /* #include "Charmonizer/Core/Util.h" */ |
| /* #include "Charmonizer/Core/Compiler.h" */ |
| /* #include "Charmonizer/Core/ConfWriter.h" */ |
| /* #include "Charmonizer/Core/OperatingSystem.h" */ |
| |
| /* Detect macros which may help to identify some compilers. |
| */ |
| static void |
| chaz_CC_detect_known_compilers(void); |
| |
| /* Temporary files. */ |
| #define CHAZ_CC_TRY_SOURCE_PATH "_charmonizer_try.c" |
| #define CHAZ_CC_TRY_BASENAME "_charmonizer_try" |
| #define CHAZ_CC_TARGET_PATH "_charmonizer_target" |
| |
| /* Static vars. */ |
| static struct { |
| char *cc_command; |
| char *cflags; |
| char *try_exe_name; |
| char obj_ext[10]; |
| char gcc_version_str[30]; |
| int cflags_style; |
| int intval___GNUC__; |
| int intval___GNUC_MINOR__; |
| int intval___GNUC_PATCHLEVEL__; |
| int intval__MSC_VER; |
| int intval___clang__; |
| int intval___SUNPRO_C; |
| chaz_CFlags *extra_cflags; |
| chaz_CFlags *temp_cflags; |
| } chaz_CC = { |
| NULL, NULL, NULL, |
| "", "", |
| 0, 0, 0, 0, 0, 0, 0, |
| NULL, NULL |
| }; |
| |
| void |
| chaz_CC_init(const char *compiler_command, const char *compiler_flags) { |
| const char *code = "int main() { return 0; }\n"; |
| int compile_succeeded = 0; |
| |
| if (chaz_Util_verbosity) { printf("Creating compiler object...\n"); } |
| |
| /* Assign, init. */ |
| chaz_CC.cc_command = chaz_Util_strdup(compiler_command); |
| chaz_CC.cflags = chaz_Util_strdup(compiler_flags); |
| chaz_CC.extra_cflags = NULL; |
| chaz_CC.temp_cflags = NULL; |
| |
| /* Set names for the targets which we "try" to compile. */ |
| chaz_CC.try_exe_name |
| = chaz_Util_join("", CHAZ_CC_TRY_BASENAME, chaz_OS_exe_ext(), NULL); |
| |
| /* If we can't compile anything, game over. */ |
| if (chaz_Util_verbosity) { |
| printf("Trying to compile a small test file...\n"); |
| } |
| /* Try MSVC argument style. */ |
| strcpy(chaz_CC.obj_ext, ".obj"); |
| chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_MSVC; |
| compile_succeeded = chaz_CC_test_compile(code); |
| if (!compile_succeeded) { |
| /* Try POSIX argument style. */ |
| strcpy(chaz_CC.obj_ext, ".o"); |
| chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_POSIX; |
| compile_succeeded = chaz_CC_test_compile(code); |
| } |
| if (!compile_succeeded) { |
| chaz_Util_die("Failed to compile a small test file"); |
| } |
| |
| chaz_CC_detect_known_compilers(); |
| |
| if (chaz_CC.intval___GNUC__) { |
| chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_GNU; |
| } |
| else if (chaz_CC.intval__MSC_VER) { |
| chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_MSVC; |
| } |
| else if (chaz_CC.intval___SUNPRO_C) { |
| chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_SUN_C; |
| } |
| else { |
| chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_POSIX; |
| } |
| chaz_CC.extra_cflags = chaz_CFlags_new(chaz_CC.cflags_style); |
| chaz_CC.temp_cflags = chaz_CFlags_new(chaz_CC.cflags_style); |
| } |
| |
| static const char chaz_CC_detect_macro_code[] = |
| CHAZ_QUOTE( #include <stdio.h> ) |
| CHAZ_QUOTE( int main() { ) |
| CHAZ_QUOTE( #ifndef %s ) |
| CHAZ_QUOTE( #error "nope" ) |
| CHAZ_QUOTE( #endif ) |
| CHAZ_QUOTE( printf("%%d", %s); ) |
| CHAZ_QUOTE( return 0; ) |
| CHAZ_QUOTE( } ); |
| |
| static int |
| chaz_CC_detect_macro(const char *macro) { |
| size_t size = sizeof(chaz_CC_detect_macro_code) |
| + (strlen(macro) * 2) |
| + 20; |
| char *code = (char*)malloc(size); |
| int retval = 0; |
| char *output; |
| size_t len; |
| sprintf(code, chaz_CC_detect_macro_code, macro, macro); |
| output = chaz_CC_capture_output(code, &len); |
| if (output) { |
| retval = atoi(output); |
| free(output); |
| } |
| free(code); |
| return retval; |
| } |
| |
| static void |
| chaz_CC_detect_known_compilers(void) { |
| chaz_CC.intval___GNUC__ = chaz_CC_detect_macro("__GNUC__"); |
| if (chaz_CC.intval___GNUC__) { |
| chaz_CC.intval___GNUC_MINOR__ |
| = chaz_CC_detect_macro("__GNUC_MINOR__"); |
| chaz_CC.intval___GNUC_PATCHLEVEL__ |
| = chaz_CC_detect_macro("__GNUC_PATCHLEVEL__"); |
| sprintf(chaz_CC.gcc_version_str, "%d.%d.%d", chaz_CC.intval___GNUC__, |
| chaz_CC.intval___GNUC_MINOR__, |
| chaz_CC.intval___GNUC_PATCHLEVEL__); |
| } |
| chaz_CC.intval__MSC_VER = chaz_CC_detect_macro("_MSC_VER"); |
| chaz_CC.intval___clang__ = chaz_CC_detect_macro("__clang__"); |
| chaz_CC.intval___SUNPRO_C = chaz_CC_detect_macro("__SUNPRO_C"); |
| } |
| |
| void |
| chaz_CC_clean_up(void) { |
| free(chaz_CC.cc_command); |
| free(chaz_CC.cflags); |
| free(chaz_CC.try_exe_name); |
| chaz_CFlags_destroy(chaz_CC.extra_cflags); |
| chaz_CFlags_destroy(chaz_CC.temp_cflags); |
| } |
| |
| int |
| chaz_CC_compile_exe(const char *source_path, const char *exe_name, |
| const char *code) { |
| chaz_CFlags *local_cflags = chaz_CFlags_new(chaz_CC.cflags_style); |
| const char *extra_cflags_string = ""; |
| const char *temp_cflags_string = ""; |
| const char *local_cflags_string; |
| char *exe_file = chaz_Util_join("", exe_name, chaz_OS_exe_ext(), NULL); |
| char *command; |
| int result; |
| |
| /* Write the source file. */ |
| chaz_Util_write_file(source_path, code); |
| |
| /* Prepare and run the compiler command. */ |
| if (chaz_CC.extra_cflags) { |
| extra_cflags_string = chaz_CFlags_get_string(chaz_CC.extra_cflags); |
| } |
| if (chaz_CC.temp_cflags) { |
| temp_cflags_string = chaz_CFlags_get_string(chaz_CC.temp_cflags); |
| } |
| chaz_CFlags_set_output_exe(local_cflags, exe_file); |
| local_cflags_string = chaz_CFlags_get_string(local_cflags); |
| command = chaz_Util_join(" ", chaz_CC.cc_command, chaz_CC.cflags, |
| source_path, extra_cflags_string, |
| temp_cflags_string, local_cflags_string, NULL); |
| if (chaz_Util_verbosity < 2) { |
| chaz_OS_run_quietly(command); |
| } |
| else { |
| system(command); |
| } |
| |
| if (chaz_CC.intval__MSC_VER) { |
| /* Zap MSVC junk. */ |
| size_t junk_buf_size = strlen(exe_file) + 4; |
| char *junk = (char*)malloc(junk_buf_size); |
| sprintf(junk, "%s.obj", exe_name); |
| chaz_Util_remove_and_verify(junk); |
| sprintf(junk, "%s.ilk", exe_name); |
| chaz_Util_remove_and_verify(junk); |
| sprintf(junk, "%s.pdb", exe_name); |
| chaz_Util_remove_and_verify(junk); |
| free(junk); |
| } |
| |
| /* See if compilation was successful. Remove the source file. */ |
| result = chaz_Util_can_open_file(exe_file); |
| if (!chaz_Util_remove_and_verify(source_path)) { |
| chaz_Util_die("Failed to remove '%s'", source_path); |
| } |
| |
| chaz_CFlags_destroy(local_cflags); |
| free(command); |
| free(exe_file); |
| return result; |
| } |
| |
| int |
| chaz_CC_compile_obj(const char *source_path, const char *obj_name, |
| const char *code) { |
| chaz_CFlags *local_cflags = chaz_CFlags_new(chaz_CC.cflags_style); |
| const char *extra_cflags_string = ""; |
| const char *temp_cflags_string = ""; |
| const char *local_cflags_string; |
| char *obj_file = chaz_Util_join("", obj_name, chaz_CC.obj_ext, NULL); |
| char *command; |
| int result; |
| |
| /* Write the source file. */ |
| chaz_Util_write_file(source_path, code); |
| |
| /* Prepare and run the compiler command. */ |
| if (chaz_CC.extra_cflags) { |
| extra_cflags_string = chaz_CFlags_get_string(chaz_CC.extra_cflags); |
| } |
| if (chaz_CC.temp_cflags) { |
| temp_cflags_string = chaz_CFlags_get_string(chaz_CC.temp_cflags); |
| } |
| chaz_CFlags_set_output_obj(local_cflags, obj_file); |
| local_cflags_string = chaz_CFlags_get_string(local_cflags); |
| command = chaz_Util_join(" ", chaz_CC.cc_command, chaz_CC.cflags, |
| source_path, extra_cflags_string, |
| temp_cflags_string, local_cflags_string, NULL); |
| if (chaz_Util_verbosity < 2) { |
| chaz_OS_run_quietly(command); |
| } |
| else { |
| system(command); |
| } |
| |
| /* See if compilation was successful. Remove the source file. */ |
| result = chaz_Util_can_open_file(obj_file); |
| if (!chaz_Util_remove_and_verify(source_path)) { |
| chaz_Util_die("Failed to remove '%s'", source_path); |
| } |
| |
| chaz_CFlags_destroy(local_cflags); |
| free(command); |
| free(obj_file); |
| return result; |
| } |
| |
| int |
| chaz_CC_test_compile(const char *source) { |
| int compile_succeeded; |
| char *try_obj_name |
| = chaz_Util_join("", CHAZ_CC_TRY_BASENAME, chaz_CC.obj_ext, NULL); |
| if (!chaz_Util_remove_and_verify(try_obj_name)) { |
| chaz_Util_die("Failed to delete file '%s'", try_obj_name); |
| } |
| compile_succeeded = chaz_CC_compile_obj(CHAZ_CC_TRY_SOURCE_PATH, |
| CHAZ_CC_TRY_BASENAME, source); |
| chaz_Util_remove_and_verify(try_obj_name); |
| free(try_obj_name); |
| return compile_succeeded; |
| } |
| |
| char* |
| chaz_CC_capture_output(const char *source, size_t *output_len) { |
| char *captured_output = NULL; |
| int compile_succeeded; |
| |
| /* Clear out previous versions and test to make sure removal worked. */ |
| if (!chaz_Util_remove_and_verify(chaz_CC.try_exe_name)) { |
| chaz_Util_die("Failed to delete file '%s'", chaz_CC.try_exe_name); |
| } |
| if (!chaz_Util_remove_and_verify(CHAZ_CC_TARGET_PATH)) { |
| chaz_Util_die("Failed to delete file '%s'", CHAZ_CC_TARGET_PATH); |
| } |
| |
| /* Attempt compilation; if successful, run app and slurp output. */ |
| compile_succeeded = chaz_CC_compile_exe(CHAZ_CC_TRY_SOURCE_PATH, |
| CHAZ_CC_TRY_BASENAME, source); |
| if (compile_succeeded) { |
| chaz_OS_run_local_redirected(chaz_CC.try_exe_name, |
| CHAZ_CC_TARGET_PATH); |
| captured_output = chaz_Util_slurp_file(CHAZ_CC_TARGET_PATH, |
| output_len); |
| } |
| else { |
| *output_len = 0; |
| } |
| |
| /* Remove all the files we just created. */ |
| chaz_Util_remove_and_verify(CHAZ_CC_TRY_SOURCE_PATH); |
| chaz_Util_remove_and_verify(chaz_CC.try_exe_name); |
| chaz_Util_remove_and_verify(CHAZ_CC_TARGET_PATH); |
| |
| return captured_output; |
| } |
| |
| const char* |
| chaz_CC_get_cc(void) { |
| return chaz_CC.cc_command; |
| } |
| |
| const char* |
| chaz_CC_get_cflags(void) { |
| return chaz_CC.cflags; |
| } |
| |
| chaz_CFlags* |
| chaz_CC_get_extra_cflags(void) { |
| return chaz_CC.extra_cflags; |
| } |
| |
| chaz_CFlags* |
| chaz_CC_get_temp_cflags(void) { |
| return chaz_CC.temp_cflags; |
| } |
| |
| chaz_CFlags* |
| chaz_CC_new_cflags(void) { |
| return chaz_CFlags_new(chaz_CC.cflags_style); |
| } |
| |
| const char* |
| chaz_CC_obj_ext(void) { |
| return chaz_CC.obj_ext; |
| } |
| |
| int |
| chaz_CC_gcc_version_num(void) { |
| return 10000 * chaz_CC.intval___GNUC__ |
| + 100 * chaz_CC.intval___GNUC_MINOR__ |
| + chaz_CC.intval___GNUC_PATCHLEVEL__; |
| } |
| |
| const char* |
| chaz_CC_gcc_version(void) { |
| return chaz_CC.intval___GNUC__ ? chaz_CC.gcc_version_str : NULL; |
| } |
| |
| int |
| chaz_CC_msvc_version_num(void) { |
| return chaz_CC.intval__MSC_VER; |
| } |
| |
| int |
| chaz_CC_sun_c_version_num(void) { |
| return chaz_CC.intval___SUNPRO_C; |
| } |
| |
| const char* |
| chaz_CC_link_command() { |
| if (chaz_CC.intval__MSC_VER) { |
| return "link"; |
| } |
| else { |
| return chaz_CC.cc_command; |
| } |
| } |
| |
| char* |
| chaz_CC_format_archiver_command(const char *target, const char *objects) { |
| if (chaz_CC.intval__MSC_VER) { |
| /* TODO: Write `objects` to a temporary file in order to avoid |
| * exceeding line length limits. */ |
| char *out = chaz_Util_join("", "/OUT:", target, NULL); |
| char *command = chaz_Util_join(" ", "lib", "/NOLOGO", out, NULL); |
| free(out); |
| return command; |
| } |
| else { |
| return chaz_Util_join(" ", "ar", "rcs", target, objects, NULL); |
| } |
| } |
| |
| char* |
| chaz_CC_format_ranlib_command(const char *target) { |
| if (chaz_CC.intval__MSC_VER) { |
| return NULL; |
| } |
| return chaz_Util_join(" ", "ranlib", target, NULL); |
| } |
| |
| |
| /***************************************************************************/ |
| |
| #line 17 "src/Charmonizer/Core/ConfWriter.c" |
| /* #include "Charmonizer/Core/Util.h" */ |
| /* #include "Charmonizer/Core/ConfWriter.h" */ |
| #include <stdarg.h> |
| #include <stdio.h> |
| |
| #define CW_MAX_WRITERS 10 |
| static struct { |
| chaz_ConfWriter *writers[CW_MAX_WRITERS]; |
| size_t num_writers; |
| } chaz_CW; |
| |
| void |
| chaz_ConfWriter_init(void) { |
| chaz_CW.num_writers = 0; |
| return; |
| } |
| |
| void |
| chaz_ConfWriter_clean_up(void) { |
| size_t i; |
| for (i = 0; i < chaz_CW.num_writers; i++) { |
| chaz_CW.writers[i]->clean_up(); |
| } |
| } |
| |
| void |
| chaz_ConfWriter_append_conf(const char *fmt, ...) { |
| va_list args; |
| size_t i; |
| |
| for (i = 0; i < chaz_CW.num_writers; i++) { |
| va_start(args, fmt); |
| chaz_CW.writers[i]->vappend_conf(fmt, args); |
| va_end(args); |
| } |
| } |
| |
| void |
| chaz_ConfWriter_add_def(const char *sym, const char *value) { |
| size_t i; |
| for (i = 0; i < chaz_CW.num_writers; i++) { |
| chaz_CW.writers[i]->add_def(sym, value); |
| } |
| } |
| |
| void |
| chaz_ConfWriter_add_global_def(const char *sym, const char *value) { |
| size_t i; |
| for (i = 0; i < chaz_CW.num_writers; i++) { |
| chaz_CW.writers[i]->add_global_def(sym, value); |
| } |
| } |
| |
| void |
| chaz_ConfWriter_add_typedef(const char *type, const char *alias) { |
| size_t i; |
| for (i = 0; i < chaz_CW.num_writers; i++) { |
| chaz_CW.writers[i]->add_typedef(type, alias); |
| } |
| } |
| |
| void |
| chaz_ConfWriter_add_global_typedef(const char *type, const char *alias) { |
| size_t i; |
| for (i = 0; i < chaz_CW.num_writers; i++) { |
| chaz_CW.writers[i]->add_global_typedef(type, alias); |
| } |
| } |
| |
| void |
| chaz_ConfWriter_add_sys_include(const char *header) { |
| size_t i; |
| for (i = 0; i < chaz_CW.num_writers; i++) { |
| chaz_CW.writers[i]->add_sys_include(header); |
| } |
| } |
| |
| void |
| chaz_ConfWriter_add_local_include(const char *header) { |
| size_t i; |
| for (i = 0; i < chaz_CW.num_writers; i++) { |
| chaz_CW.writers[i]->add_local_include(header); |
| } |
| } |
| |
| void |
| chaz_ConfWriter_start_module(const char *module_name) { |
| size_t i; |
| if (chaz_Util_verbosity > 0) { |
| printf("Running %s module...\n", module_name); |
| } |
| for (i = 0; i < chaz_CW.num_writers; i++) { |
| chaz_CW.writers[i]->start_module(module_name); |
| } |
| } |
| |
| void |
| chaz_ConfWriter_end_module(void) { |
| size_t i; |
| for (i = 0; i < chaz_CW.num_writers; i++) { |
| chaz_CW.writers[i]->end_module(); |
| } |
| } |
| |
| void |
| chaz_ConfWriter_add_writer(chaz_ConfWriter *writer) { |
| chaz_CW.writers[chaz_CW.num_writers] = writer; |
| chaz_CW.num_writers++; |
| } |
| |
| |
| /***************************************************************************/ |
| |
| #line 17 "src/Charmonizer/Core/ConfWriterC.c" |
| /* #include "Charmonizer/Core/Util.h" */ |
| /* #include "Charmonizer/Core/ConfWriter.h" */ |
| /* #include "Charmonizer/Core/ConfWriterC.h" */ |
| /* #include "Charmonizer/Core/OperatingSystem.h" */ |
| /* #include "Charmonizer/Core/Compiler.h" */ |
| #include <ctype.h> |
| #include <errno.h> |
| #include <stdarg.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| typedef enum chaz_ConfElemType { |
| CHAZ_CONFELEM_DEF, |
| CHAZ_CONFELEM_GLOBAL_DEF, |
| CHAZ_CONFELEM_TYPEDEF, |
| CHAZ_CONFELEM_GLOBAL_TYPEDEF, |
| CHAZ_CONFELEM_SYS_INCLUDE, |
| CHAZ_CONFELEM_LOCAL_INCLUDE |
| } chaz_ConfElemType; |
| |
| typedef struct chaz_ConfElem { |
| char *str1; |
| char *str2; |
| chaz_ConfElemType type; |
| } chaz_ConfElem; |
| |
| /* Static vars. */ |
| static struct { |
| FILE *fh; |
| char *MODULE_NAME; |
| chaz_ConfElem *defs; |
| size_t def_cap; |
| size_t def_count; |
| } chaz_ConfWriterC = { NULL, NULL, 0, 0 }; |
| static chaz_ConfWriter CWC_conf_writer; |
| |
| /* Open the charmony.h file handle. Print supplied text to it, if non-null. |
| * Print an explanatory comment and open the include guard. |
| */ |
| static void |
| chaz_ConfWriterC_open_charmony_h(const char *charmony_start); |
| |
| /* Push a new elem onto the def list. */ |
| static void |
| chaz_ConfWriterC_push_def_list_item(const char *str1, const char *str2, |
| chaz_ConfElemType type); |
| |
| /* Free the def list. */ |
| static void |
| chaz_ConfWriterC_clear_def_list(void); |
| |
| static void |
| chaz_ConfWriterC_clean_up(void); |
| static void |
| chaz_ConfWriterC_vappend_conf(const char *fmt, va_list args); |
| static void |
| chaz_ConfWriterC_add_def(const char *sym, const char *value); |
| static void |
| chaz_ConfWriterC_add_global_def(const char *sym, const char *value); |
| static void |
| chaz_ConfWriterC_add_typedef(const char *type, const char *alias); |
| static void |
| chaz_ConfWriterC_add_global_typedef(const char *type, const char *alias); |
| static void |
| chaz_ConfWriterC_add_sys_include(const char *header); |
| static void |
| chaz_ConfWriterC_add_local_include(const char *header); |
| static void |
| chaz_ConfWriterC_start_module(const char *module_name); |
| static void |
| chaz_ConfWriterC_end_module(void); |
| |
| void |
| chaz_ConfWriterC_enable(void) { |
| CWC_conf_writer.clean_up = chaz_ConfWriterC_clean_up; |
| CWC_conf_writer.vappend_conf = chaz_ConfWriterC_vappend_conf; |
| CWC_conf_writer.add_def = chaz_ConfWriterC_add_def; |
| CWC_conf_writer.add_global_def = chaz_ConfWriterC_add_global_def; |
| CWC_conf_writer.add_typedef = chaz_ConfWriterC_add_typedef; |
| CWC_conf_writer.add_global_typedef = chaz_ConfWriterC_add_global_typedef; |
| CWC_conf_writer.add_sys_include = chaz_ConfWriterC_add_sys_include; |
| CWC_conf_writer.add_local_include = chaz_ConfWriterC_add_local_include; |
| CWC_conf_writer.start_module = chaz_ConfWriterC_start_module; |
| CWC_conf_writer.end_module = chaz_ConfWriterC_end_module; |
| chaz_ConfWriterC_open_charmony_h(NULL); |
| chaz_ConfWriter_add_writer(&CWC_conf_writer); |
| return; |
| } |
| |
| static void |
| chaz_ConfWriterC_open_charmony_h(const char *charmony_start) { |
| /* Open the filehandle. */ |
| chaz_ConfWriterC.fh = fopen("charmony.h", "w+"); |
| if (chaz_ConfWriterC.fh == NULL) { |
| chaz_Util_die("Can't open 'charmony.h': %s", strerror(errno)); |
| } |
| |
| /* Print supplied text (if any) along with warning, open include guard. */ |
| if (charmony_start != NULL) { |
| fwrite(charmony_start, sizeof(char), strlen(charmony_start), |
| chaz_ConfWriterC.fh); |
| } |
| fprintf(chaz_ConfWriterC.fh, |
| "/* Header file auto-generated by Charmonizer. \n" |
| " * DO NOT EDIT THIS FILE!!\n" |
| " */\n\n" |
| "#ifndef H_CHARMONY\n" |
| "#define H_CHARMONY 1\n\n" |
| ); |
| } |
| |
| static void |
| chaz_ConfWriterC_clean_up(void) { |
| /* Write the last bit of charmony.h and close. */ |
| fprintf(chaz_ConfWriterC.fh, "#endif /* H_CHARMONY */\n\n"); |
| if (fclose(chaz_ConfWriterC.fh)) { |
| chaz_Util_die("Couldn't close 'charmony.h': %s", strerror(errno)); |
| } |
| } |
| |
| static void |
| chaz_ConfWriterC_vappend_conf(const char *fmt, va_list args) { |
| vfprintf(chaz_ConfWriterC.fh, fmt, args); |
| } |
| |
| static int |
| chaz_ConfWriterC_sym_is_uppercase(const char *sym) { |
| return isupper(sym[0]); |
| } |
| |
| static char* |
| chaz_ConfWriterC_uppercase_string(const char *src) { |
| char *retval = chaz_Util_strdup(src); |
| size_t i; |
| for (i = 0; retval[i]; ++i) { |
| retval[i] = toupper(retval[i]); |
| } |
| return retval; |
| } |
| |
| static void |
| chaz_ConfWriterC_add_def(const char *sym, const char *value) { |
| chaz_ConfWriterC_push_def_list_item(sym, value, CHAZ_CONFELEM_DEF); |
| } |
| |
| static void |
| chaz_ConfWriterC_append_def_to_conf(const char *sym, const char *value) { |
| if (value) { |
| if (chaz_ConfWriterC_sym_is_uppercase(sym)) { |
| fprintf(chaz_ConfWriterC.fh, "#define CHY_%s %s\n", sym, value); |
| } |
| else { |
| fprintf(chaz_ConfWriterC.fh, "#define chy_%s %s\n", sym, value); |
| } |
| } |
| else { |
| if (chaz_ConfWriterC_sym_is_uppercase(sym)) { |
| fprintf(chaz_ConfWriterC.fh, "#define CHY_%s\n", sym); |
| } |
| else { |
| fprintf(chaz_ConfWriterC.fh, "#define chy_%s\n", sym); |
| } |
| } |
| } |
| |
| static void |
| chaz_ConfWriterC_add_global_def(const char *sym, const char *value) { |
| chaz_ConfWriterC_push_def_list_item(sym, value, CHAZ_CONFELEM_GLOBAL_DEF); |
| } |
| |
| static void |
| chaz_ConfWriterC_append_global_def_to_conf(const char *sym, |
| const char *value) { |
| char *name_end = strchr(sym, '('); |
| if (name_end == NULL) { |
| if (strcmp(sym, value) == 0) { return; } |
| fprintf(chaz_ConfWriterC.fh, "#ifndef %s\n", sym); |
| } |
| else { |
| size_t name_len = (size_t)(name_end - sym); |
| char *name = chaz_Util_strdup(sym); |
| name[name_len] = '\0'; |
| fprintf(chaz_ConfWriterC.fh, "#ifndef %s\n", name); |
| free(name); |
| } |
| if (value) { |
| fprintf(chaz_ConfWriterC.fh, " #define %s %s\n", sym, value); |
| } |
| else { |
| fprintf(chaz_ConfWriterC.fh, " #define %s\n", sym); |
| } |
| fprintf(chaz_ConfWriterC.fh, "#endif\n"); |
| } |
| |
| static void |
| chaz_ConfWriterC_add_typedef(const char *type, const char *alias) { |
| chaz_ConfWriterC_push_def_list_item(alias, type, CHAZ_CONFELEM_TYPEDEF); |
| } |
| |
| static void |
| chaz_ConfWriterC_append_typedef_to_conf(const char *type, const char *alias) { |
| if (chaz_ConfWriterC_sym_is_uppercase(alias)) { |
| fprintf(chaz_ConfWriterC.fh, "typedef %s CHY_%s;\n", type, alias); |
| } |
| else { |
| fprintf(chaz_ConfWriterC.fh, "typedef %s chy_%s;\n", type, alias); |
| } |
| } |
| |
| static void |
| chaz_ConfWriterC_add_global_typedef(const char *type, const char *alias) { |
| chaz_ConfWriterC_push_def_list_item(alias, type, |
| CHAZ_CONFELEM_GLOBAL_TYPEDEF); |
| } |
| |
| static void |
| chaz_ConfWriterC_append_global_typedef_to_conf(const char *type, |
| const char *alias) { |
| if (strcmp(type, alias) == 0) { return; } |
| fprintf(chaz_ConfWriterC.fh, "typedef %s %s;\n", type, alias); |
| } |
| |
| static void |
| chaz_ConfWriterC_add_sys_include(const char *header) { |
| chaz_ConfWriterC_push_def_list_item(header, NULL, |
| CHAZ_CONFELEM_SYS_INCLUDE); |
| } |
| |
| static void |
| chaz_ConfWriterC_append_sys_include_to_conf(const char *header) { |
| fprintf(chaz_ConfWriterC.fh, "#include <%s>\n", header); |
| } |
| |
| static void |
| chaz_ConfWriterC_add_local_include(const char *header) { |
| chaz_ConfWriterC_push_def_list_item(header, NULL, |
| CHAZ_CONFELEM_LOCAL_INCLUDE); |
| } |
| |
| static void |
| chaz_ConfWriterC_append_local_include_to_conf(const char *header) { |
| fprintf(chaz_ConfWriterC.fh, "#include \"%s\"\n", header); |
| } |
| |
| static void |
| chaz_ConfWriterC_start_module(const char *module_name) { |
| fprintf(chaz_ConfWriterC.fh, "\n/* %s */\n", module_name); |
| chaz_ConfWriterC.MODULE_NAME |
| = chaz_ConfWriterC_uppercase_string(module_name); |
| } |
| |
| static void |
| chaz_ConfWriterC_end_module(void) { |
| size_t num_globals = 0; |
| size_t i; |
| chaz_ConfElem *defs = chaz_ConfWriterC.defs; |
| for (i = 0; i < chaz_ConfWriterC.def_count; i++) { |
| switch (defs[i].type) { |
| case CHAZ_CONFELEM_GLOBAL_DEF: |
| ++num_globals; |
| /* fall through */ |
| case CHAZ_CONFELEM_DEF: |
| chaz_ConfWriterC_append_def_to_conf(defs[i].str1, |
| defs[i].str2); |
| break; |
| case CHAZ_CONFELEM_GLOBAL_TYPEDEF: { |
| char *sym = chaz_ConfWriterC_uppercase_string(defs[i].str1); |
| chaz_ConfWriterC_append_def_to_conf(sym, defs[i].str2); |
| free(sym); |
| ++num_globals; |
| } |
| /* fall through */ |
| case CHAZ_CONFELEM_TYPEDEF: |
| chaz_ConfWriterC_append_typedef_to_conf(defs[i].str2, |
| defs[i].str1); |
| break; |
| case CHAZ_CONFELEM_SYS_INCLUDE: |
| ++num_globals; |
| break; |
| case CHAZ_CONFELEM_LOCAL_INCLUDE: |
| chaz_ConfWriterC_append_local_include_to_conf(defs[i].str1); |
| break; |
| default: |
| chaz_Util_die("Internal error: bad element type %d", |
| (int)defs[i].type); |
| } |
| } |
| |
| /* Write out short names. */ |
| fprintf(chaz_ConfWriterC.fh, |
| "\n#if defined(CHY_USE_SHORT_NAMES) " |
| "|| defined(CHAZ_USE_SHORT_NAMES)\n" |
| ); |
| for (i = 0; i < chaz_ConfWriterC.def_count; i++) { |
| switch (defs[i].type) { |
| case CHAZ_CONFELEM_DEF: |
| case CHAZ_CONFELEM_TYPEDEF: |
| { |
| const char *sym = defs[i].str1; |
| const char *value = defs[i].str2; |
| if (!value || strcmp(sym, value) != 0) { |
| const char *prefix |
| = chaz_ConfWriterC_sym_is_uppercase(sym) |
| ? "CHY_" : "chy_"; |
| fprintf(chaz_ConfWriterC.fh, " #define %s %s%s\n", |
| sym, prefix, sym); |
| } |
| } |
| break; |
| case CHAZ_CONFELEM_GLOBAL_DEF: |
| case CHAZ_CONFELEM_GLOBAL_TYPEDEF: |
| case CHAZ_CONFELEM_SYS_INCLUDE: |
| case CHAZ_CONFELEM_LOCAL_INCLUDE: |
| /* no-op */ |
| break; |
| default: |
| chaz_Util_die("Internal error: bad element type %d", |
| (int)defs[i].type); |
| } |
| } |
| |
| fprintf(chaz_ConfWriterC.fh, "#endif /* USE_SHORT_NAMES */\n"); |
| |
| /* Write out global definitions and system includes. */ |
| if (num_globals) { |
| fprintf(chaz_ConfWriterC.fh, "\n#ifdef CHY_EMPLOY_%s\n\n", |
| chaz_ConfWriterC.MODULE_NAME); |
| for (i = 0; i < chaz_ConfWriterC.def_count; i++) { |
| switch (defs[i].type) { |
| case CHAZ_CONFELEM_GLOBAL_DEF: |
| chaz_ConfWriterC_append_global_def_to_conf(defs[i].str1, |
| defs[i].str2); |
| break; |
| case CHAZ_CONFELEM_GLOBAL_TYPEDEF: |
| chaz_ConfWriterC_append_global_typedef_to_conf( |
| defs[i].str2, defs[i].str1); |
| break; |
| case CHAZ_CONFELEM_SYS_INCLUDE: |
| chaz_ConfWriterC_append_sys_include_to_conf(defs[i].str1); |
| break; |
| case CHAZ_CONFELEM_DEF: |
| case CHAZ_CONFELEM_TYPEDEF: |
| case CHAZ_CONFELEM_LOCAL_INCLUDE: |
| /* no-op */ |
| break; |
| default: |
| chaz_Util_die("Internal error: bad element type %d", |
| (int)defs[i].type); |
| } |
| } |
| fprintf(chaz_ConfWriterC.fh, "\n#endif /* EMPLOY_%s */\n", |
| chaz_ConfWriterC.MODULE_NAME); |
| } |
| |
| fprintf(chaz_ConfWriterC.fh, "\n"); |
| |
|