Jim Monte's update to cmpp

This commit is contained in:
Jim Monte 2020-01-29 02:24:42 -05:00 committed by Holger Vogt
parent 375a92d788
commit 955dda749d
9 changed files with 1854 additions and 1066 deletions

View File

@ -11,7 +11,7 @@ bin_PROGRAMS = cmpp
AM_CPPFLAGS = -I. -I$(srcdir)
AM_YFLAGS = -d
cmpp_SOURCES = main.c cmpp.h \
cmpp_SOURCES = main.c cmpp.h file_buffer.c file_buffer.h\
pp_ifs.c pp_lst.c pp_mod.c read_ifs.c writ_ifs.c util.c \
ifs_lex.l ifs_yacc.y ifs_yacc_y.h \
mod_lex.l mod_yacc.y mod_yacc_y.h
@ -42,7 +42,7 @@ if CROSS_COMPILING
BUILT_SOURCES += build/cmpp$(BUILD_EXEEXT)
CLEANFILES = build/cmpp$(BUILD_EXEEXT)
BUILD_CMPP_FILES = main.c \
BUILD_CMPP_FILES = main.c file_buffer.c \
pp_ifs.c pp_lst.c pp_mod.c read_ifs.c writ_ifs.c util.c \
ifs_lex.c ifs_yacc.c \
mod_lex.c mod_yacc.c

View File

@ -38,6 +38,7 @@ NON-STANDARD FEATURES
============================================================================*/
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
@ -49,20 +50,25 @@ NON-STANDARD FEATURES
#ifdef _MSC_VER
#include <io.h>
#include <string.h>
/* If CRT debugging is being used so that crtdbg.h is included, strdup will
* be defined to a debug version. In this case, strdup should not be
* redefined to the standard version. */
#ifndef strdup
#define strdup _strdup
#endif
#define unlink _unlink
#define isatty _isatty
#define fileno _fileno
#endif
#endif /* _MSC_VER */
/* *********************************************************************** */
#define GET_IFS_TABLE 0 /* Read the entire ifs table */
#define GET_IFS_NAME 1 /* Get the C function name out of the table only */
#define MAX_PATH_LEN 1024 /* Maximum pathname length */
#define MAX_NAME_LEN 1024 /* Maximum SPICE name length */
#define MAX_FN_LEN 31 /* Maximum filename length */
/* ******************************************************************** */
@ -262,7 +268,9 @@ void preprocess_ifs_file(void);
void preprocess_lst_files(void);
void preprocess_mod_file(char *filename);
void preprocess_mod_file(const char *filename);
int output_paths_from_lst_file(const char *filename);
void init_error (char *program_name);
@ -272,6 +280,7 @@ void print_error(const char *fmt, ...) __attribute__ ((format (__printf__, 1, 2)
#else
void print_error(const char *fmt, ...);
#endif
void vprint_error(const char *fmt, va_list p);
void str_to_lower(char *s);
@ -281,7 +290,7 @@ int read_ifs_file(const char *filename, int mode, Ifs_Table_t *ifs_table);
int write_ifs_c_file(const char *filename, Ifs_Table_t *ifs_table);
FILE *fopen_cmpp(const char **path_p, const char *mode);
char *gen_filename(const char *filename, const char *mode);
void rem_ifs_table(Ifs_Table_t *ifs_table);

View File

@ -35,25 +35,37 @@ REFERENCED FILES
NON-STANDARD FEATURES
None.
============================================================================*/
#ifdef DEBUG_CMPP
#ifdef _WIN32
#include <Windows.h>
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cmpp.h"
#define USAGE_MSG "Usage: cmpp [-ifs] [-mod [<filename>]] [-lst]"
#define USAGE_MSG \
"Usage: cmpp [-ifs] | [-mod [<filename>]] | [-lst] | [-p fn.lst]"
#define TOO_FEW_ARGS "ERROR - Too few arguments"
#define TOO_MANY_ARGS "ERROR - Too many arguments"
#define UNRECOGNIZED_ARGS "ERROR - Unrecognized argument"
#ifdef DEBUG_CMPP
#define PRINT_CMPP_INFO(argc, argv) print_cmpp_info(argc, argv);
static void print_cmpp_info(int argc, char **argv);
#else
#define PRINT_CMPP_INFO(argc, argv)
#endif
/* *********************************************************************** */
/*
main
@ -61,9 +73,11 @@ Function main checks the validity of the command-line arguments
supplied when the program is invoked and calls one of the three
major functions as appropriate:
preprocess_ifs_file Process Interface Specification File.
preprocess_mod_file Process Model Definition File.
preprocess_lst_file Process Pathname List Files.
preprocess_ifs_file Process Interface Specification File.
preprocess_mod_file Process Model Definition File.
preprocess_lst_file Process Pathname List Files.
output_paths_from_lst_file Write paths from a list file to stdout
to facilite building the code models
depending on the argument.
*/
@ -72,11 +86,11 @@ int main(
int argc, /* Number of command line arguments */
char *argv[]) /* Command line argument text */
{
init_error (argv[0]);
/* Process command line arguments and vector to appropriate function */
PRINT_CMPP_INFO(argc, argv)
/* Process command line arguments and vector to appropriate function */
if(argc < 2) {
print_error(TOO_FEW_ARGS);
print_error(USAGE_MSG);
@ -115,6 +129,26 @@ int main(
print_error(USAGE_MSG);
exit(1);
}
}
else if (strcmp(argv[1],"-p") == 0) { /* Output paths from a list file */
if (argc == 3) {
const int n_item = output_paths_from_lst_file(argv[2]);
if (n_item < 0) {
print_error("Unable to print paths to stdout");
exit(-1);
}
exit(n_item);
}
else { /* Wrong number of arguments */
if (argc < 3) {
print_error(TOO_FEW_ARGS);
}
else {
print_error(TOO_MANY_ARGS);
}
print_error(USAGE_MSG);
exit(1);
}
}
else {
print_error(UNRECOGNIZED_ARGS);
@ -123,5 +157,67 @@ int main(
}
exit(0);
}
} /* end of function main */
#ifdef DEBUG_CMPP
/* Print some debugging information for cmpp
*
* With the use of environment variables to locate files, it is helpful
* to know some information about the program when debugging. If the
* build of a code model fails due to cmpp, the macro can be enabled to
* find the information needed to separately debug cmpp */
static void print_cmpp_info(int argc, char **argv)
{
/* Print the program and its arguments */
{
int i;
for (i = 0; i < argc; ++i) {
(void) fprintf(stdout, "%s ", argv[i]);
}
(void) fprintf(stdout, "\n");
}
#ifdef _WIN32
/* Print the current directory */
{
const DWORD n_char = GetCurrentDirectoryA(0, (char *) NULL);
if (n_char > 0) {
char *p_buf = (char *) malloc(n_char);
if (p_buf != (char *) NULL) {
if (GetCurrentDirectoryA(n_char, p_buf) != 0) {
(void) fprintf(stdout, "Current Directory: \"%s\".\n",
p_buf);
}
free(p_buf);
}
}
}
#endif
/* Print the CMPP_IDIR environment variable if defined */
{
const char * const ev = getenv("CMPP_IDIR");
if (ev) {
(void) fprintf(stdout, "CMPP_IDIR = \"%s\"\n", ev);
}
else {
(void) fprintf(stdout, "CMPP_IDIR is not defined\n");
}
}
/* Print the CMPP_ODIR environment variable if defined */
{
const char * const ev = getenv("CMPP_ODIR");
if (ev) {
(void) fprintf(stdout, "CMPP_ODIR = \"%s\"\n", ev);
}
else {
(void) fprintf(stdout, "CMPP_ODIR is not defined\n");
}
}
} /* end of function print_cmpp_info */
#endif /* #ifdef DEBUG_CMPP */

View File

@ -42,14 +42,6 @@ NON-STANDARD FEATURES
/* *********************************************************************** */
static void txfree(void *ptr)
{
if(ptr)
free(ptr);
};
/*
preprocess_ifs_file
@ -91,30 +83,51 @@ void preprocess_ifs_file(void)
void rem_ifs_table(Ifs_Table_t *ifs_table)
{
int i;
/* Remove the ifs_table */
txfree(ifs_table->name.c_fcn_name);
txfree(ifs_table->name.description);
txfree(ifs_table->name.model_name);
free(ifs_table->name.c_fcn_name);
free(ifs_table->name.description);
free(ifs_table->name.model_name);
for(i = 0; i < ifs_table->num_conn; i++) {
txfree(ifs_table->conn[i].name);
txfree(ifs_table->conn[i].description);
txfree(ifs_table->conn[i].default_type);
{
Conn_Info_t * const p_conn = ifs_table->conn;
const int num_conn = ifs_table->num_conn;
int i;
for (i = 0; i < num_conn; ++i) {
Conn_Info_t *p_conn_cur = p_conn + i;
free(p_conn_cur->name);
free(p_conn_cur->description);
free(p_conn_cur->default_type);
}
}
for(i = 0; i < ifs_table->num_param; i++) {
txfree(ifs_table->param[i].name);
txfree(ifs_table->param[i].description);
{
Param_Info_t * const p_param = ifs_table->param;
const int num_param = ifs_table->num_param;
int i;
for (i = 0; i < num_param; ++i) {
Param_Info_t *p_param_cur = p_param + i;
free(p_param_cur->name);
free(p_param_cur->description);
}
}
for(i = 0; i < ifs_table->num_inst_var; i++) {
txfree(ifs_table->inst_var[i].name);
txfree(ifs_table->inst_var[i].description);
{
Inst_Var_Info_t * const p_inst_var = ifs_table->inst_var;
const int num_inst_var = ifs_table->num_inst_var;
int i;
for(i = 0; i < num_inst_var; ++i) {
Inst_Var_Info_t *p_inst_var_cur = p_inst_var + i;
free(p_inst_var_cur->name);
free(p_inst_var_cur->description);
}
}
txfree(ifs_table->conn);
txfree(ifs_table->param);
txfree(ifs_table->inst_var);
}
free(ifs_table->conn);
free(ifs_table->param);
free(ifs_table->inst_var);
} /* end of function rem_ifs_table */

File diff suppressed because it is too large Load Diff

View File

@ -54,6 +54,7 @@ NON-STANDARD FEATURES
============================================================================*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -74,21 +75,33 @@ extern int mod_num_errors;
extern Ifs_Table_t *mod_ifs_table;
extern const char *current_filename;
extern char *current_filename;
extern char *prog_name;
/*---------------------------------------------------------------------------*/
static char *change_extension (char *filename, char *ext)
/* Allocate and build a file name from the input filename by changing its
* extension (text after the last '.') in filename to ext or append .ext if
* the filename has no extension */
static char *change_extension(const char *filename, const char *ext)
{
char *p = strrchr(filename, '.');
size_t prefix_len = p ? (size_t) (p-filename+1) : strlen(filename);
char *new_filename = malloc(prefix_len + strlen(ext) + 1);
const char * const p = strrchr(filename, '.');
const size_t prefix_len = p ? (size_t) (p - filename) : strlen(filename);
const size_t ext_len = strlen(ext);
char * const new_filename = malloc(prefix_len + ext_len + 2);
/* +1 for '.' +1 for '\0' */
if (new_filename == (char *) NULL) {
return (char *) NULL;
}
strncpy(new_filename, filename, prefix_len);
strcpy(new_filename+prefix_len, ext);
{
char *p_cur = (char *) memcpy(new_filename, filename, prefix_len) +
prefix_len;
*p_cur++ = '.';
(void) memcpy(p_cur, ext, ext_len + 1);
}
return new_filename;
}
} /* end of function change_extension */
/*---------------------------------------------------------------------------*/
@ -108,14 +121,12 @@ utilities.
void preprocess_mod_file (
char *filename) /* The file to read */
const char *filename) /* The file to read */
{
Ifs_Table_t ifs_table; /* info read from ifspec.ifs file */
int status; /* Return status */
const char *output_filename;
Ifs_Table_t ifs_table; /* info read from ifspec.ifs file */
int status; /* Return status */
char *output_filename = (char *) NULL; /* .mod file being written */
/*
* Read the entire ifspec.ifs file and load the data into ifs_table
*/
@ -125,45 +136,80 @@ void preprocess_mod_file (
if (status != 0) {
exit(1);
}
current_filename = filename;
mod_yyin = fopen_cmpp (&current_filename, "r");
if (mod_yyin == NULL) {
print_error("ERROR - Could not open input .mod file: %s", current_filename);
exit(1);
}
output_filename = change_extension (filename, "c");
mod_yyout = fopen_cmpp (&output_filename, "w");
/* Open the cfunc.mod file defining the code model function */
if ((current_filename = gen_filename(filename, "r")) == (char *) NULL) {
print_error("ERROR - Unable to build mod file name");
exit(1);
}
if ((mod_yyin = fopen(current_filename, "r")) == (FILE *) NULL) {
print_error("ERROR - Unable to open mod file \"%s\": %s",
current_filename, strerror(errno));
exit(1);
}
{
char *output_filename_base = (char *) NULL;
if ((output_filename_base = change_extension(
filename, "c")) == (char *) NULL) {
print_error("ERROR - Could not change extension of "
"\"%s\".", filename);
exit(1);
}
if ((output_filename = gen_filename(
output_filename_base, "w")) == (char *) NULL) {
print_error("ERROR - Unable to build output file name");
exit(1);
}
free(output_filename_base);
}
if ((mod_yyout = fopen(output_filename, "w")) == (FILE *) NULL) {
/* .c file could not be opened */
print_error("ERROR - Could not open output .c file\"%s\": %s",
output_filename, strerror(errno));
exit(1);
}
if (mod_yyout == NULL) {
print_error("ERROR - Could not open output .c file: %s", output_filename);
exit(1);
}
mod_ifs_table = &ifs_table;
mod_num_errors = 0;
/* Define DEBUG_WITH_MOD_FILE to have the compiler use the cfunc.mod file for
* deugging instead of the cfunc.c file. */
#ifdef DEBUG_WITH_MOD_FILE
fprintf (mod_yyout, "#line 1 \"%s\"\n", current_filename);
#endif
fprintf (mod_yyout, "#include \"ngspice/cm.h\"\n");
fprintf (mod_yyout, "extern void %s(Mif_Private_t *);\n",
ifs_table.name.c_fcn_name);
ifs_table.name.c_fcn_name);
#ifdef DEBUG_WITH_MOD_FILE
fprintf (mod_yyout, "#line 1 \"%s\"\n", current_filename);
#endif
mod_yylineno = 1;
if (mod_yyparse() || (mod_num_errors > 0)) {
print_error("Error parsing .mod file: \"%s\"", current_filename);
unlink (output_filename);
exit (1);
}
fclose (mod_yyout);
if(output_filename)
free((char*)output_filename);
if (mod_yyparse() || (mod_num_errors > 0)) {
print_error("Error parsing .mod file: \"%s\"", current_filename);
unlink(output_filename);
exit(1);
}
if (fclose(mod_yyout) != 0) {
print_error("Error closing output file \"%s\": %s",
current_filename, strerror(errno));
unlink(output_filename);
exit(1);
}
rem_ifs_table(&ifs_table);
mod_yyrestart(NULL);
}
free(output_filename);
free(current_filename);
} /* end of function preprocess_mod_file */
/*---------------------------------------------------------------------------*/
void

View File

@ -47,7 +47,11 @@ NON-STANDARD FEATURES
============================================================================*/
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ifs_yacc_y.h"
extern char *prog_name;
@ -65,7 +69,7 @@ extern int ifs_num_errors;
static int read_ifs_table(FILE *fp, int mode, Ifs_Table_t *ifs_table);
const char *current_filename;
char *current_filename;
/* *********************************************************************** */
@ -94,35 +98,42 @@ int read_ifs_file(
int mode, /* Get names only or get everything? */
Ifs_Table_t *ifs_table) /* Table to put info in */
{
FILE *fp; /* Ifs file pointer */
int status; /* returned status from function */
FILE *fp = (FILE *) NULL; /* Ifs file pointer */
int status = 0; /* returned status from function */
/* Open the ifs file for read access */
fp = fopen_cmpp(&filename, "r");
if(fp == NULL) {
perror (prog_name);
print_error("ERROR - File not found: %s", filename);
return -1;
/* Open the model pathname file */
if ((current_filename = gen_filename(filename, "r")) == (char *) NULL) {
print_error("ERROR - Unable to build full file name");
return -1;
}
if ((fp = fopen(current_filename, "r")) == (FILE *) NULL) {
print_error("ERROR - Unable to open \"%s\": %s",
current_filename, strerror(errno));
status = -1;
goto EXITPOINT;
}
/* Get the stuff from the file into the ifs_table struct. Here mode
* defines the data that will be added to the structure */
status = read_ifs_table(fp, mode, ifs_table);
EXITPOINT:
/* Close file and return */
if (fp != (FILE *) NULL) {
if (fclose(fp) != 0) {
print_error("ERROR - Unable to close \"%s\": %s",
current_filename, strerror(errno));
status = -1;
}
}
current_filename = filename;
/* Get the stuff from the file into the ifs_table struct */
status = read_ifs_table(fp, mode, ifs_table);
/* Close file and return */
fclose(fp);
return(status);
}
free(current_filename);
current_filename = (char *) NULL;
return status;
} /* end of function read_ifs_file */
@ -146,7 +157,6 @@ static int read_ifs_table(
int mode, /* Get names only or get everything? */
Ifs_Table_t *ifs_table) /* Table to put info in */
{
assert (ifs_table);
assert (fp);

View File

@ -84,16 +84,21 @@ void print_error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "%s: ", prog_name);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
vprint_error(fmt, ap);
va_end(ap);
} /* end of function print_error */
void vprint_error(const char *fmt, va_list p_arg)
{
fprintf(stderr, "%s: ", prog_name);
vfprintf(stderr, fmt, p_arg);
fprintf(stderr, "\n");
} /* end of function vprint_error */
/* Convert a string to all lower case */
void str_to_lower(char *s)
{
@ -110,24 +115,22 @@ void str_to_lower(char *s)
/* If *path_p is relative, prefix with the value of the CMPP output or
* input environment variable. Open the file and return the path that
* was used to open it. */
FILE *fopen_cmpp(const char **path_p, const char *mode)
char *gen_filename(const char *filename, const char *mode)
{
const char *path = *path_p;
char *buf = (char *) NULL;
/* If absoulte path, prefix with CMPP_ODIR/CMPP_IDIR env value */
if (!is_absolute_pathname(path)) { /* relative path */
if (!is_absolute_pathname(filename)) { /* relative path */
const char *e = getenv((*mode == 'w' || *mode == 'a') ?
"CMPP_ODIR" : "CMPP_IDIR");
if (e) { /* have env var */
const size_t len_prefix = strlen(e);
const size_t len_path = strlen(path);
const size_t n_char = len_prefix + len_path + 1;
const size_t len_filename = strlen(filename);
const size_t n_char = len_prefix + len_filename + 1;
/* Allocate buffer to build full file name */
if ((buf = (char *) malloc(n_char + 1)) == (char *) NULL) {
*path_p = (char *) NULL;
return (FILE *) NULL;
return (char *) NULL;
}
/* Build the full file name */
@ -136,24 +139,21 @@ FILE *fopen_cmpp(const char **path_p, const char *mode)
(void) memcpy(p_cur, e, len_prefix);
p_cur += len_prefix;
*p_cur++ = DIR_TERM_UNIX;
(void) memcpy(p_cur, path, len_path + 1);
(void) memcpy(p_cur, filename, len_filename + 1);
}
} /* end of case that env variable found */
} /* end of case that path is absolute */
/* If did not build full file name yet, copy the original
* name of the file */
/* If did not build full file name yet, make the original
* name of the file the full file name */
if (buf == (char *) NULL) {
if ((buf = strdup(path)) == (char *) NULL) { /* failed */
*path_p = (char *) NULL;
return (FILE *) NULL;
if ((buf = strdup(filename)) == (char *) NULL) { /* failed */
return (char *) NULL;
}
}
/* Return copy of file name and opened file */
*path_p = buf;
return fopen(buf, mode);
} /* end of function fopen_cmpp */
return buf;
} /* end of function gen_filename */

File diff suppressed because it is too large Load Diff