Modified Files:

Makefile.am
Added Files:
	cmpp/Makefile cmpp/cmpp.h cmpp/ifs_lex.l cmpp/ifs_yacc.h
    cmpp/ifs_yacc.y cmpp/main.c cmpp/mod_lex.l cmpp/mod_yacc.h
    cmpp/mod_yacc.y cmpp/pp_ifs.c cmpp/pp_lst.c cmpp/pp_mod.c
    cmpp/read_ifs.c cmpp/util.c cmpp/writ_ifs.c

Version of cmpp from xspice, still needs some work to make it compatable
with SpiceOpus and tclspice, but compiles.
This commit is contained in:
stefanjones 2003-06-26 10:05:39 +00:00
parent fcae1791c5
commit ad5e06720a
16 changed files with 5229 additions and 1 deletions

View File

@ -9,7 +9,7 @@ EXTRA_DIST = README
## libs. It is currently compiled manually, last.
##SUBDIRS = mif cm enh evt ipc idn icm
SUBDIRS = mif cm enh evt ipc idn
SUBDIRS = mif cm enh evt ipc idn cmpp
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)

36
src/xspice/cmpp/Makefile Executable file
View File

@ -0,0 +1,36 @@
cmpp_OBJS=main.o pp_ifs.o pp_lst.o pp_mod.o read_ifs.o util.o writ_ifs.o \
ifs_yacc.o ifs_lex.o mod_yacc.o mod_lex.o
cmpp_GEN=ifs_yacc.c ifs_tok.h \
ifs_lex.c ifs_lex.h \
mod_lex.c mod_lex.h \
mod_yacc.c mod_tok.h
YACC=bison -d --yacc
#YACC=yacc -d
CC=gcc -O2 -g
LEX=flex -t
all: cmpp
cmpp: $(cmpp_OBJS)
$(CC) -o cmpp $(cmpp_OBJS)
%.c : %.y
$(YACC) -p $(*:yacc=)yy $<
mv -f y.tab.c $*.c
mv -f y.tab.h $(*:yacc=)tok.h
%.c : %.l
$(LEX) -P$(*:lex=)yy $< > $@
ifs_lex.c : ifs_lex.l
$(LEX) -i -P$(*:lex=)yy $< > $@
clean:
rm -f $(cmpp_OBJS) $(cmpp_GEN) cmpp

285
src/xspice/cmpp/cmpp.h Executable file
View File

@ -0,0 +1,285 @@
/*============================================================================
FILE cmpp.h
MEMBER OF process cmpp
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains shared constants, type definitions,
and function prototypes used in the cmpp process.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#include <stdio.h>
#define IFSPEC_FILENAME "ifspec.ifs"
#define UDNFUNC_FILENAME "udnfunc.c"
#define MODPATH_FILENAME "modpath.lst"
#define UDNPATH_FILENAME "udnpath.lst"
/* *********************************************************************** */
typedef enum {
OK, /* Returned with no error */
ERROR, /* Returned with error */
} Status_t;
#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 */
/* ******************************************************************** */
/* Structures used by parser to check for valid connections/parameters */
/* ******************************************************************** */
/*
* The boolean type
*/
typedef enum {
FALSE,
TRUE,
} Boolean_t;
/*
* The direction of a connector
*/
typedef enum {
IN,
OUT,
INOUT,
} Dir_t;
/*
* The type of a port
*/
typedef enum {
VOLTAGE, /* v - Single-ended voltage */
DIFF_VOLTAGE, /* vd - Differential voltage */
CURRENT, /* i - Single-ended current */
DIFF_CURRENT, /* id - Differential current */
VSOURCE_CURRENT, /* vnam - Vsource name for input current */
CONDUCTANCE, /* g - Single-ended VCIS */
DIFF_CONDUCTANCE, /* gd - Differential VCIS */
RESISTANCE, /* h - Single-ended ICVS */
DIFF_RESISTANCE, /* hd - Differential ICVS */
DIGITAL, /* d - Digital */
USER_DEFINED, /* <identifier> - Any user defined type */
} Port_Type_t;
/*
* The type of a parameter or Static_Var
*/
typedef enum {
BOOLEAN,
INTEGER,
REAL,
COMPLEX,
STRING,
POINTER, /* NOTE: POINTER should not be used for Parameters - only
* Static_Vars - this is enforced by the cmpp.
*/
} Data_Type_t;
/*
* The complex type
*/
typedef struct {
double real;
double imag;
} Complex_t;
/*
* Values of different types.
*
* Note that a struct is used instead of a union for conformity
* with the use of the Mif_Value_t type in the simulator where
* the type must be statically initialized. ANSI C does not
* support useful initialization of unions.
*
*/
typedef struct {
Boolean_t bvalue; /* For BOOLEAN parameters */
int ivalue; /* For INTEGER parameters */
double rvalue; /* For REAL parameters */
Complex_t cvalue; /* For COMPLEX parameters */
char *svalue; /* For STRING parameters */
} Value_t;
/*
* Information about the model as a whole
*/
typedef struct {
char *c_fcn_name; /* Name used in the C function */
char *model_name; /* Name used in a spice deck */
char *description; /* Description of the model */
} Name_Info_t;
/*
* Information about a connection
*/
typedef struct {
char *name; /* Name of this connection */
char *description; /* Description of this connection */
Dir_t direction; /* IN, OUT, or INOUT */
Port_Type_t default_port_type; /* The default port type */
char *default_type; /* The default type in string form */
int num_allowed_types; /* The size of the allowed type arrays */
Port_Type_t *allowed_port_type; /* Array of allowed types */
char **allowed_type; /* Array of allowed types in string form */
Boolean_t is_array; /* True if connection is an array */
Boolean_t has_conn_ref; /* True if there is associated with an array conn */
int conn_ref; /* Subscript of the associated array conn */
Boolean_t has_lower_bound; /* True if there is an array size lower bound */
int lower_bound; /* Array size lower bound */
Boolean_t has_upper_bound; /* True if there is an array size upper bound */
int upper_bound; /* Array size upper bound */
Boolean_t null_allowed; /* True if null is allowed for this connection */
} Conn_Info_t;
/*
* Information about a parameter
*/
typedef struct {
char *name; /* Name of this parameter */
char *description; /* Description of this parameter */
Data_Type_t type; /* Data type, e.g. REAL, INTEGER, ... */
Boolean_t has_default; /* True if there is a default value */
Value_t default_value; /* The default value */
Boolean_t has_lower_limit; /* True if there is a lower limit */
Value_t lower_limit; /* The lower limit for this parameter */
Boolean_t has_upper_limit; /* True if there is a upper limit */
Value_t upper_limit; /* The upper limit for this parameter */
Boolean_t is_array; /* True if parameter is an array */
Boolean_t has_conn_ref; /* True if there is associated with an array conn */
int conn_ref; /* Subscript of the associated array conn */
Boolean_t has_lower_bound; /* True if there is an array size lower bound */
int lower_bound; /* Array size lower bound */
Boolean_t has_upper_bound; /* True if there is an array size upper bound */
int upper_bound; /* Array size upper bound */
Boolean_t null_allowed; /* True if null is allowed for this parameter */
} Param_Info_t;
/*
* Information about an instance variable
*/
typedef struct {
char *name; /* Name of this parameter */
char *description; /* Description of this parameter */
Data_Type_t type; /* Data type, e.g. REAL, INTEGER, ... */
Boolean_t is_array; /* True if parameter is an array */
} Inst_Var_Info_t;
/*
* The all encompassing structure for the ifs table information
*/
typedef struct {
Name_Info_t name; /* The name table entries */
int num_conn; /* Number of entries in the connection table(s) */
Conn_Info_t *conn; /* Array of connection info structs */
int num_param; /* Number of entries in the parameter table(s) */
Param_Info_t *param; /* Array of parameter info structs */
int num_inst_var; /* Number of entries in the instance var table(s) */
Inst_Var_Info_t *inst_var; /* Array of instance variable info structs */
} Ifs_Table_t;
/* *********************************************************************** */
void preprocess_ifs_file(void);
void preprocess_lst_files(void);
void preprocess_mod_file(char *filename);
void print_error(char *message);
Status_t read_ifs_file(char *filename, int mode, Ifs_Table_t *ifs_table);
Status_t write_ifs_c_file(char *filename, Ifs_Table_t *ifs_table);

176
src/xspice/cmpp/ifs_lex.l Executable file
View File

@ -0,0 +1,176 @@
%option yylineno
%option noyywrap
%{ /* $Id$ */
/*============================================================================
FILE ifs_lex.l
MEMBER OF process cmpp
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Steve Tynor
MODIFICATIONS
12/31/91 Bill Kuhn Change "array" to "vector" and "array_bounds"
to "vector_bounds".
SUMMARY
This file defines tokens applicable to parsing the ifspec.ifs
file, and actions to be taken on encountering those tokens.
INTERFACES
None.
REFERENCED FILES
ifs_yacc.y
NON-STANDARD FEATURES
None.
============================================================================*/
#include "ifs_yacc.h"
#include "ifs_tok.h"
int yyival;
double yydval;
extern int atoi();
extern double atof();
/*
* IFS specs are case insensitive:
*/
/* saj - use -i flex command line option
#undef input
#define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:isupper(yytchar)?tolower(yytchar):yytchar)
*/
/*---------------------------------------------------------------------------*/
%}
%start BOOL CTYPE DIR DTYPE
%x comment stringl
%p 5000
W [ \t\n]
A [_a-z]
D [0-9]
I [a-z_]
Z [0-9a-z_]
E [eE][+-]?{D}+
%%
"/*" { BEGIN(comment); }
<comment>[^*\n]* /* eat anything that's not a '*' */
<comment>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
<comment>\n /* new line */
<comment><<EOF>> {ifs_yyerror ("Unterminated comment"); yyterminate(); }
<comment>"*"+"/" { BEGIN(INITIAL); }
"\"" { BEGIN(stringl); }
<stringl>[^\"]* { return TOK_STRING_LITERAL; }
<stringl>"\"" { BEGIN(INITIAL); }
<stringl><<EOF>> {ifs_yyerror ("Unterminated string literal");
yyterminate(); }
allowed_types{W}*: {BEGIN CTYPE; return TOK_ALLOWED_TYPES;}
vector{W}*: {BEGIN BOOL; return TOK_ARRAY;}
vector_bounds{W}*: {return TOK_ARRAY_BOUNDS;}
c_function_name{W}*: {return TOK_C_FUNCTION_NAME;}
port_name{W}*: {return TOK_PORT_NAME;}
port_table{W}*: {return TOK_PORT_TABLE;}
data_type{W}*: {BEGIN DTYPE; return TOK_DATA_TYPE;}
default_type{W}*: {BEGIN CTYPE; return TOK_DEFAULT_TYPE;}
default_value{W}*: {return TOK_DEFAULT_VALUE;}
description{W}*: {return TOK_DESCRIPTION;}
direction{W}*: {BEGIN DIR; return TOK_DIRECTION;}
static_var_name{W}*: {return TOK_STATIC_VAR_NAME;}
static_var_table{W}*: {return TOK_STATIC_VAR_TABLE;}
limits{W}*: {return TOK_LIMITS;}
name_table{W}*: {return TOK_NAME_TABLE;}
null_allowed{W}*: {BEGIN BOOL; return TOK_NULL_ALLOWED;}
parameter_name{W}*: {return TOK_PARAMETER_NAME;}
parameter_table{W}*: {return TOK_PARAMETER_TABLE;}
spice_model_name{W}*: {return TOK_SPICE_MODEL_NAME;}
<BOOL>yes {return TOK_BOOL_YES;}
<BOOL>no {return TOK_BOOL_NO;}
true {return TOK_BOOL_YES;}
false {return TOK_BOOL_NO;}
<CTYPE>v {return TOK_CTYPE_V;}
<CTYPE>vd {return TOK_CTYPE_VD;}
<CTYPE>vnam {return TOK_CTYPE_VNAM;}
<CTYPE>i {return TOK_CTYPE_I;}
<CTYPE>id {return TOK_CTYPE_ID;}
<CTYPE>g {return TOK_CTYPE_G;}
<CTYPE>gd {return TOK_CTYPE_GD;}
<CTYPE>h {return TOK_CTYPE_H;}
<CTYPE>hd {return TOK_CTYPE_HD;}
<CTYPE>d {return TOK_CTYPE_D;}
<DIR>in {return TOK_DIR_IN;}
<DIR>out {return TOK_DIR_OUT;}
<DIR>inout {return TOK_DIR_INOUT;}
<DTYPE>real {return TOK_DTYPE_REAL;}
<DTYPE>int {return TOK_DTYPE_INT;}
<DTYPE>boolean {return TOK_DTYPE_BOOLEAN;}
<DTYPE>complex {return TOK_DTYPE_COMPLEX;}
<DTYPE>string {return TOK_DTYPE_STRING;}
<DTYPE>pointer {return TOK_DTYPE_POINTER;}
"<" {return TOK_LANGLE;}
">" {return TOK_RANGLE;}
"[" {return TOK_LBRACKET;}
"]" {return TOK_RBRACKET;}
"," {return TOK_COMMA;}
"-" {return TOK_DASH;}
{I}+{Z}* {return TOK_IDENTIFIER;}
[+-]?{D}+ {yyival = atoi (yytext);
return TOK_INT_LITERAL;}
[+-]?{D}+"."{D}*({E})? |
[+-]?{D}*"."{D}+({E})? |
[+-]?{D}+({E})? {yydval = atof (yytext);
return TOK_REAL_LITERAL;}
. ; /* ignore anything else */
\n ; /* ignore anything else */
%%
/*--------------------------------------------------------------------------*/
void reset_lex_context ()
{
BEGIN 0;
}

81
src/xspice/cmpp/ifs_yacc.h Executable file
View File

@ -0,0 +1,81 @@
/* $Id$ */
/*============================================================================
FILE ifs_yacc.h
MEMBER OF process cmpp
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Steve Tynor
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
Typedefs needed by the YYSTYPE union (%union operator) in the yacc
file. These are only used in the yacc file, but must be defined here since
the generated token.h file includes a definition of the union YYSTYPE.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#include "cmpp.h"
typedef struct {
Boolean_t has_value;
Data_Type_t kind;
union {
Boolean_t bvalue;
int ivalue;
double rvalue;
Complex_t cvalue;
char *svalue;
} u;
} My_Value_t;
typedef struct {
Boolean_t has_bound;
My_Value_t bound;
} Bound_t;
typedef struct {
Boolean_t is_named;
union {
char *name;
struct {
Bound_t upper;
Bound_t lower;
} bounds;
} u;
} Range_t;
typedef struct {
Port_Type_t kind;
char *id; /* undefined unless kind == USER_DEFINED */
} My_Port_Type_t;
typedef struct ctype_list_s {
My_Port_Type_t ctype;
struct ctype_list_s *next;
} Ctype_List_t;

901
src/xspice/cmpp/ifs_yacc.y Executable file
View File

@ -0,0 +1,901 @@
%{ /* $Id$ */
/*============================================================================
FILE ifs_yacc.y
MEMBER OF process cmpp
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Steve Tynor
MODIFICATIONS
12/31/91 Bill Kuhn Fix bug in usage of strcmp in check_default_type()
SUMMARY
This file contains the BNF specification of the language used in
the ifspec.ifs file together with various support functions,
and parses the ifspec.ifs file to get the information from it
and place this information into a data structure
of type Ifs_Table_t.
INTERFACES
yyparse() - Generated automatically by UNIX 'yacc' utility.
REFERENCED FILES
ifs_lex.l
NON-STANDARD FEATURES
None.
============================================================================*/
#include <assert.h>
#include "ifs_yacc.h"
extern int yylineno;
extern int yyival;
extern double yydval;
extern char *ifs_yytext;
extern char *strdup();
Boolean_t parser_just_names;
static Boolean_t saw_model_name;
static Boolean_t saw_function_name;
static char *dtype_to_str[] = {
"BOOLEAN", "INTEGER", "REAL", "COMPLEX", "STRING", "POINTER"
};
static Boolean_t did_default_type;
static Boolean_t did_allowed_types;
static int num_items;
static int item;
static int item_offset;
static Boolean_t num_items_fixed;
Ifs_Table_t *parser_ifs_table;
#define TBL parser_ifs_table
static int alloced_size [4];
/*
* !!!!! Make sure these are large enough so that they never get realloced
* !!!!! since that will cause garbage uninitialized data...
* !!!!! (FIX THIS!)
*/
#define DEFAULT_SIZE_CONN 100
#define DEFAULT_SIZE_PARAM 100
#define DEFAULT_SIZE_INST_VAR 100
#define GROW_SIZE 10
typedef enum {
TBL_NAME,
TBL_PORT,
TBL_PARAMETER,
TBL_STATIC_VAR,
} Table_t;
typedef struct {
Table_t table;
int record;
} Context_t;
Context_t context;
#define ITEM_BUFFER_SIZE 20 /* number of items that can be put in a table
* before requiring a new xxx_TABLE: keyword
*/
#define FOR_ITEM(i) for (i = item_offset; i < num_items; i++)
#define ITEM_BUF(i) item_buffer[i-item_offset]
#define ASSIGN_BOUNDS(struct_name, i) \
if (ITEM_BUF(i).range.is_named) {\
TBL->struct_name[i].has_conn_ref = TRUE;\
TBL->struct_name[i].conn_ref = find_conn_ref (ITEM_BUF(i).range.u.name);\
} else {\
TBL->struct_name[i].has_conn_ref = FALSE;\
TBL->struct_name[i].has_lower_bound =\
ITEM_BUF(i).range.u.bounds.lower.has_bound;\
TBL->struct_name[i].has_upper_bound =\
ITEM_BUF(i).range.u.bounds.upper.has_bound;\
if (TBL->struct_name[i].has_lower_bound) {\
assert (ITEM_BUF(i).range.u.bounds.lower.bound.kind == INTEGER);\
TBL->struct_name[i].lower_bound =\
ITEM_BUF(i).range.u.bounds.lower.bound.u.ivalue;\
}\
if (TBL->struct_name[i].has_upper_bound) {\
assert (ITEM_BUF(i).range.u.bounds.upper.bound.kind == INTEGER);\
TBL->struct_name[i].upper_bound =\
ITEM_BUF(i).range.u.bounds.upper.bound.u.ivalue;\
}\
}
/*---------------------------------------------------------------------------*/
static void fatal (char *str)
{
yyerror (str);
exit(1);
}
/*---------------------------------------------------------------------------*/
static int find_conn_ref (name)
char *name;
{
int i;
char str[130];
for (i = 0; i < TBL->num_conn; i++) {
if (strcmp (name, TBL->conn[i].name) == 0) {
return i;
}
}
sprintf (str, "Port `%s' not found", name);
yyerror (str);
}
typedef enum {C_DOUBLE, C_BOOLEAN, C_POINTER, C_UNDEF} Ctype_Class_t;
/*---------------------------------------------------------------------------*/
static Ctype_Class_t get_ctype_class (Port_Type_t type)
{
switch (type) {
case USER_DEFINED:
return C_POINTER;
break;
case DIGITAL:
return C_BOOLEAN;
break;
default:
return C_DOUBLE;
break;
}
}
/*---------------------------------------------------------------------------*/
static void check_port_type_direction (Dir_t dir, Port_Type_t port_type)
{
switch (port_type) {
case VOLTAGE:
case DIFF_VOLTAGE:
case CURRENT:
case DIFF_CURRENT:
case DIGITAL:
case USER_DEFINED:
/*
* anything goes
*/
break;
case VSOURCE_CURRENT:
if (dir != IN) {
yyerror ("Port type `vnam' is only valid for `in' ports");
}
break;
case CONDUCTANCE:
case DIFF_CONDUCTANCE:
case RESISTANCE:
case DIFF_RESISTANCE:
if (dir != INOUT) {
yyerror ("Port types `g', `gd', `h', `hd' are only valid for `inout' ports");
}
break;
default:
assert (0);
}
}
/*---------------------------------------------------------------------------*/
static void check_dtype_not_pointer (Data_Type_t dtype)
{
if (dtype == POINTER) {
yyerror("Invalid parameter type - POINTER type valid only for STATIC_VARs");
}
}
/*---------------------------------------------------------------------------*/
static void check_default_type (Conn_Info_t conn)
{
int i;
for (i = 0; i < conn.num_allowed_types; i++) {
if (conn.default_port_type == conn.allowed_port_type[i]) {
if ((conn.default_port_type != USER_DEFINED) ||
(strcmp (conn.default_type, conn.allowed_type[i]) == 0)) {
return;
}
}
}
yyerror ("Port default type is not an allowed type");
}
/*---------------------------------------------------------------------------*/
static void assign_ctype_list (conn, ctype_list)
Conn_Info_t *conn;
Ctype_List_t *ctype_list;
{
int i;
Ctype_List_t *p;
Ctype_Class_t class = C_UNDEF;
conn->num_allowed_types = 0;
for (p = ctype_list; p; p = p->next) {
conn->num_allowed_types++;
}
conn->allowed_type = (char**) calloc (conn->num_allowed_types,
sizeof (char*));
conn->allowed_port_type = (Port_Type_t*) calloc (conn->num_allowed_types,
sizeof (Port_Type_t));
if (! (conn->allowed_type && conn->allowed_port_type)) {
fatal ("Could not allocate memory");
}
for (i = conn->num_allowed_types-1, p = ctype_list; p; i--, p = p->next) {
if (class == C_UNDEF) {
class = get_ctype_class (p->ctype.kind);
}
if (class != get_ctype_class (p->ctype.kind)) {
yyerror ("Incompatible port types in `allowed_types' clause");
}
check_port_type_direction (conn->direction, p->ctype.kind);
conn->allowed_port_type[i] = p->ctype.kind;
conn->allowed_type[i] = p->ctype.id;
}
}
/*---------------------------------------------------------------------------*/
static void assign_value (type, dest_value, src_value)
Data_Type_t type;
Value_t *dest_value;
My_Value_t src_value;
{
char str[200];
if ((type == REAL) && (src_value.kind == INTEGER)) {
dest_value->rvalue = src_value.u.ivalue;
return;
} else if (type != src_value.kind) {
sprintf (str, "Invalid parameter type (saw %s - expected %s)",
dtype_to_str[src_value.kind],
dtype_to_str[type] );
yyerror (str);
}
switch (type) {
case BOOLEAN:
dest_value->bvalue = src_value.u.bvalue;
break;
case INTEGER:
dest_value->ivalue = src_value.u.ivalue;
break;
case REAL:
dest_value->rvalue = src_value.u.rvalue;
break;
case COMPLEX:
dest_value->cvalue = src_value.u.cvalue;
break;
case STRING:
dest_value->svalue = src_value.u.svalue;
break;
default:
yyerror ("INTERNAL ERROR - unexpected data type in `assign_value'");
}
}
/*---------------------------------------------------------------------------*/
static void assign_limits (type, param, range)
Data_Type_t type;
Param_Info_t *param;
Range_t range;
{
if (range.is_named) {
yyerror ("Named range not allowed for limits");
}
param->has_lower_limit = range.u.bounds.lower.has_bound;
if (param->has_lower_limit) {
assign_value (type, &param->lower_limit, range.u.bounds.lower.bound);
}
param->has_upper_limit = range.u.bounds.upper.has_bound;
if (param->has_upper_limit) {
assign_value (type, &param->upper_limit, range.u.bounds.upper.bound);
}
}
/*---------------------------------------------------------------------------*/
static void check_item_num ()
{
if (item-item_offset >= ITEM_BUFFER_SIZE) {
fatal ("Too many items in table - split into sub-tables");
}
if (item > alloced_size [context.table] ) {
switch (context.table) {
case TBL_NAME:
break;
case TBL_PORT:
alloced_size[context.table] += GROW_SIZE;
TBL->conn = (Conn_Info_t*)
realloc (TBL->conn,
alloced_size [context.table] * sizeof (Conn_Info_t));
if (! TBL->conn) {
fatal ("Error allocating memory for port definition");
}
break;
case TBL_PARAMETER:
alloced_size [context.table] += GROW_SIZE;
TBL->param = (Param_Info_t*)
realloc (TBL->param,
alloced_size [context.table] * sizeof (Param_Info_t));
if (! TBL->param) {
fatal ("Error allocating memory for parameter definition");
}
break;
case TBL_STATIC_VAR:
alloced_size [context.table] += GROW_SIZE;
TBL->inst_var = (Inst_Var_Info_t*)
realloc (TBL->inst_var,
alloced_size [context.table] * sizeof (Inst_Var_Info_t));
if (! TBL->inst_var) {
fatal ("Error allocating memory for static variable definition");
}
break;
}
}
item++;
}
/*---------------------------------------------------------------------------*/
static void check_end_item_num ()
{
if (num_items_fixed) {
if (item != num_items) {
char buf[200];
sprintf
(buf,
"Wrong number of elements in sub-table (saw %d - expected %d)",
item - item_offset,
num_items - item_offset);
fatal (buf);
}
} else {
num_items = item;
num_items_fixed = TRUE;
switch (context.table) {
case TBL_NAME:
break;
case TBL_PORT:
TBL->num_conn = num_items;
break;
case TBL_PARAMETER:
TBL->num_param = num_items;
break;
case TBL_STATIC_VAR:
TBL->num_inst_var = num_items;
break;
}
}
item = item_offset;
}
#define INIT(n) item = (n); item_offset = (n); num_items = (n); num_items_fixed = FALSE
#define ITEM check_item_num()
#define END check_end_item_num()
%}
%token TOK_ALLOWED_TYPES
%token TOK_ARRAY
%token TOK_ARRAY_BOUNDS
%token TOK_BOOL_NO
%token TOK_BOOL_YES
%token TOK_COMMA
%token TOK_PORT_NAME
%token TOK_PORT_TABLE
%token TOK_CTYPE_D
%token TOK_CTYPE_G
%token TOK_CTYPE_GD
%token TOK_CTYPE_H
%token TOK_CTYPE_HD
%token TOK_CTYPE_I
%token TOK_CTYPE_ID
%token TOK_CTYPE_V
%token TOK_CTYPE_VD
%token TOK_CTYPE_VNAM
%token TOK_C_FUNCTION_NAME
%token TOK_DASH
%token TOK_DATA_TYPE
%token TOK_DEFAULT_TYPE
%token TOK_DEFAULT_VALUE
%token TOK_DESCRIPTION
%token TOK_DIRECTION
%token TOK_DIR_IN
%token TOK_DIR_INOUT
%token TOK_DIR_OUT
%token TOK_DTYPE_BOOLEAN
%token TOK_DTYPE_COMPLEX
%token TOK_DTYPE_INT
%token TOK_DTYPE_POINTER
%token TOK_DTYPE_REAL
%token TOK_DTYPE_STRING
%token TOK_IDENTIFIER
%token TOK_STATIC_VAR_NAME
%token TOK_STATIC_VAR_TABLE
%token TOK_INT_LITERAL
%token TOK_LANGLE
%token TOK_LBRACKET
%token TOK_LIMITS
%token TOK_NAME_TABLE
%token TOK_NULL_ALLOWED
%token TOK_PARAMETER_NAME
%token TOK_PARAMETER_TABLE
%token TOK_RANGLE
%token TOK_RBRACKET
%token TOK_REAL_LITERAL
%token TOK_SPICE_MODEL_NAME
%token TOK_STRING_LITERAL
%union {
Ctype_List_t *ctype_list;
Dir_t dir;
Boolean_t bool;
Range_t range;
Data_Type_t dtype;
My_Port_Type_t ctype;
My_Value_t value;
char *str;
Bound_t bound;
int ival;
double rval;
Complex_t cval;
}
%type <ctype_list> ctype_list delimited_ctype_list
%type <dir> direction
%type <ctype> ctype
%type <dtype> dtype
%type <range> range int_range
%type <value> value number integer_value value_or_dash
%type <str> identifier string
%type <bool> bool
%type <bound> int_or_dash number_or_dash
%type <ival> integer
%type <rval> real
%type <cval> complex
%start ifs_file
%{
/*
* resuse the Yacc union for our buffer:
*/
YYSTYPE item_buffer [ITEM_BUFFER_SIZE];
/*
* Shorthand for refering to the current element of the item buffer:
*/
#define BUF ITEM_BUF(item-1)
%}
%%
ifs_file : {TBL->num_conn = 0;
TBL->num_param = 0;
TBL->num_inst_var = 0;
saw_function_name = FALSE;
saw_model_name = FALSE;
alloced_size [TBL_PORT] = DEFAULT_SIZE_CONN;
alloced_size [TBL_PARAMETER] = DEFAULT_SIZE_PARAM;
alloced_size [TBL_STATIC_VAR] =
DEFAULT_SIZE_INST_VAR;
TBL->conn = (Conn_Info_t*)
calloc (DEFAULT_SIZE_CONN,
sizeof (Conn_Info_t));
TBL->param = (Param_Info_t*)
calloc (DEFAULT_SIZE_PARAM,
sizeof (Param_Info_t));
TBL->inst_var = (Inst_Var_Info_t*)
calloc (DEFAULT_SIZE_INST_VAR,
sizeof (Inst_Var_Info_t));
if (! (TBL->conn && TBL->param &&
TBL->inst_var) ) {
fatal ("Could not allocate enough memory");
}
}
list_of_tables
;
list_of_tables : table
| list_of_tables table
;
table : TOK_NAME_TABLE
{context.table = TBL_NAME;}
name_table
| TOK_PORT_TABLE
{context.table = TBL_PORT;
did_default_type = FALSE;
did_allowed_types = FALSE;
INIT (TBL->num_conn);}
port_table
{TBL->num_conn = num_items;}
| TOK_PARAMETER_TABLE
{context.table = TBL_PARAMETER;
INIT (TBL->num_param);}
parameter_table
{TBL->num_param = num_items;}
| TOK_STATIC_VAR_TABLE
{context.table = TBL_STATIC_VAR;
INIT (TBL->num_inst_var);}
static_var_table
{TBL->num_inst_var = num_items;}
;
name_table : /* empty */
| name_table name_table_item
;
name_table_item : TOK_C_FUNCTION_NAME identifier
{TBL->name.c_fcn_name =strdup (ifs_yytext);
saw_function_name = TRUE;
if (parser_just_names && saw_model_name) return 0;}
| TOK_SPICE_MODEL_NAME identifier
{TBL->name.model_name = strdup (ifs_yytext);
saw_model_name = TRUE;
if (parser_just_names && saw_function_name) return 0;}
| TOK_DESCRIPTION string
{TBL->name.description = strdup (ifs_yytext);}
;
port_table : /* empty */
| port_table port_table_item
;
port_table_item : TOK_PORT_NAME list_of_ids
{int i;
END;
FOR_ITEM (i) {
TBL->conn[i].name = ITEM_BUF(i).str;
}}
| TOK_DESCRIPTION list_of_strings
{int i;
END;
FOR_ITEM (i) {
TBL->conn[i].description = ITEM_BUF(i).str;
}}
| TOK_DIRECTION list_of_directions
{int i;
END;
FOR_ITEM (i) {
TBL->conn[i].direction = ITEM_BUF(i).dir;
}}
| TOK_DEFAULT_TYPE list_of_ctypes
{int i;
END;
did_default_type = TRUE;
FOR_ITEM (i) {
TBL->conn[i].default_port_type =
ITEM_BUF(i).ctype.kind;
TBL->conn[i].default_type = ITEM_BUF(i).ctype.id;
if (did_allowed_types) {
check_default_type (TBL->conn[i]);
}
}}
| TOK_ALLOWED_TYPES list_of_ctype_lists
{int i;
END;
did_allowed_types = TRUE;
FOR_ITEM (i) {
assign_ctype_list (&TBL->conn[i],
ITEM_BUF(i).ctype_list);
if (did_default_type) {
check_default_type (TBL->conn[i]);
}
}}
| TOK_ARRAY list_of_bool
{int i;
END;
FOR_ITEM (i) {
TBL->conn[i].is_array = ITEM_BUF(i).bool;
}}
| TOK_ARRAY_BOUNDS list_of_array_bounds
{int i;
END;
FOR_ITEM (i) {
ASSIGN_BOUNDS (conn, i);
assert (!TBL->conn[i].has_conn_ref);
}}
| TOK_NULL_ALLOWED list_of_bool
{int i;
END;
FOR_ITEM (i) {
TBL->conn[i].null_allowed = ITEM_BUF(i).bool;
}}
;
parameter_table : /* empty */
| parameter_table parameter_table_item
;
parameter_table_item : TOK_PARAMETER_NAME list_of_ids
{int i;
END;
FOR_ITEM (i) {
TBL->param[i].name = ITEM_BUF(i).str;
}}
| TOK_DESCRIPTION list_of_strings
{int i;
END;
FOR_ITEM (i) {
TBL->param[i].description = ITEM_BUF(i).str;
}}
| TOK_DATA_TYPE list_of_dtypes
{int i;
END;
FOR_ITEM (i) {
check_dtype_not_pointer (ITEM_BUF(i).dtype);
TBL->param[i].type = ITEM_BUF(i).dtype;
}}
| TOK_DEFAULT_VALUE list_of_values
{int i;
END;
FOR_ITEM (i) {
TBL->param[i].has_default =
ITEM_BUF(i).value.has_value;
if (TBL->param[i].has_default) {
assign_value (TBL->param[i].type,
&TBL->param[i].default_value,
ITEM_BUF(i).value);
}
}}
| TOK_LIMITS list_of_ranges
{int i;
END;
FOR_ITEM (i) {
assign_limits (TBL->param[i].type,
&TBL->param[i],
ITEM_BUF(i).range);
}}
| TOK_ARRAY list_of_bool
{int i;
END;
FOR_ITEM (i) {
TBL->param[i].is_array = ITEM_BUF(i).bool;
}}
| TOK_ARRAY_BOUNDS list_of_array_bounds
{int i;
END;
FOR_ITEM (i) {
ASSIGN_BOUNDS (param, i);
}}
| TOK_NULL_ALLOWED list_of_bool
{int i;
END;
FOR_ITEM (i) {
TBL->param[i].null_allowed = ITEM_BUF(i).bool;
}}
;
static_var_table : /* empty */
| static_var_table static_var_table_item
;
static_var_table_item : TOK_STATIC_VAR_NAME list_of_ids
{int i;
END;
FOR_ITEM (i) {
TBL->inst_var[i].name = ITEM_BUF(i).str;
}}
| TOK_DESCRIPTION list_of_strings
{int i;
END;
FOR_ITEM (i) {
TBL->inst_var[i].description = ITEM_BUF(i).str;
}}
| TOK_DATA_TYPE list_of_dtypes
{int i;
END;
FOR_ITEM (i) {
TBL->inst_var[i].type = ITEM_BUF(i).dtype;
}}
| TOK_ARRAY list_of_bool
{int i;
END;
FOR_ITEM (i) {
TBL->inst_var[i].is_array = ITEM_BUF(i).bool;
}}
;
list_of_ids : /* empty */
| list_of_ids identifier {ITEM; BUF.str = $2;}
;
list_of_array_bounds : /* empty */
| list_of_array_bounds int_range
{ITEM;
BUF.range = $2;}
| list_of_array_bounds identifier
{ITEM;
BUF.range.is_named = TRUE;
BUF.range.u.name = $2;}
;
list_of_strings : /* empty */
| list_of_strings string {ITEM; BUF.str = $2;}
;
list_of_directions : /* empty */
| list_of_directions direction {ITEM; BUF.dir = $2;}
;
direction : TOK_DIR_IN {$$ = IN;}
| TOK_DIR_OUT {$$ = OUT;}
| TOK_DIR_INOUT {$$ = INOUT;}
;
list_of_bool : /* empty */
| list_of_bool bool {ITEM; BUF.bool = $2;}
;
list_of_ctypes : /* empty */
| list_of_ctypes ctype {ITEM; BUF.ctype = $2;}
;
ctype : TOK_CTYPE_V {$$.kind = VOLTAGE;}
| TOK_CTYPE_VD {$$.kind = DIFF_VOLTAGE;}
| TOK_CTYPE_VNAM {$$.kind = VSOURCE_CURRENT;}
| TOK_CTYPE_I {$$.kind = CURRENT;}
| TOK_CTYPE_ID {$$.kind = DIFF_CURRENT;}
| TOK_CTYPE_G {$$.kind = CONDUCTANCE;}
| TOK_CTYPE_GD {$$.kind = DIFF_CONDUCTANCE;}
| TOK_CTYPE_H {$$.kind = RESISTANCE;}
| TOK_CTYPE_HD {$$.kind = DIFF_RESISTANCE;}
| TOK_CTYPE_D {$$.kind = DIGITAL;}
| identifier {$$.kind = USER_DEFINED;
$$.id = $1;}
;
list_of_dtypes : /* empty */
| list_of_dtypes dtype {ITEM; BUF.dtype = $2;}
;
dtype : TOK_DTYPE_REAL {$$ = REAL;}
| TOK_DTYPE_INT {$$ = INTEGER;}
| TOK_DTYPE_BOOLEAN {$$ = BOOLEAN;}
| TOK_DTYPE_COMPLEX {$$ = COMPLEX;}
| TOK_DTYPE_STRING {$$ = STRING;}
| TOK_DTYPE_POINTER {$$ = POINTER;}
;
list_of_ranges : /* empty */
| list_of_ranges range {ITEM; BUF.range = $2;}
;
int_range : TOK_DASH {$$.is_named = FALSE;
$$.u.bounds.lower.has_bound = FALSE;
$$.u.bounds.upper.has_bound = FALSE;}
| TOK_LBRACKET int_or_dash maybe_comma int_or_dash
TOK_RBRACKET
{$$.is_named = FALSE;
$$.u.bounds.lower = $2;
$$.u.bounds.upper = $4;}
;
maybe_comma : /* empty */
| TOK_COMMA
;
int_or_dash : TOK_DASH {$$.has_bound = FALSE;}
| integer_value {$$.has_bound = TRUE;
$$.bound = $1;}
;
range : TOK_DASH {$$.is_named = FALSE;
$$.u.bounds.lower.has_bound = FALSE;
$$.u.bounds.upper.has_bound = FALSE;}
| TOK_LBRACKET number_or_dash maybe_comma
number_or_dash TOK_RBRACKET
{$$.is_named = FALSE;
$$.u.bounds.lower = $2;
$$.u.bounds.upper = $4;}
;
number_or_dash : TOK_DASH {$$.has_bound = FALSE;}
| number {$$.has_bound = TRUE;
$$.bound = $1;}
;
list_of_values : /* empty */
| list_of_values value_or_dash {ITEM; BUF.value = $2;}
;
value_or_dash : TOK_DASH {$$.has_value = FALSE;}
| value
;
value : string {$$.has_value = TRUE;
$$.kind = STRING;
$$.u.svalue = $1;}
| bool {$$.has_value = TRUE;
$$.kind = BOOLEAN;
$$.u.bvalue = $1;}
| complex {$$.has_value = TRUE;
$$.kind = COMPLEX;
$$.u.cvalue = $1;}
| number
;
complex : TOK_LANGLE real maybe_comma real TOK_RANGLE
{$$.real = $2;
$$.imag = $4;}
;
list_of_ctype_lists : /* empty */
| list_of_ctype_lists delimited_ctype_list
{ITEM; BUF.ctype_list = $2;}
;
delimited_ctype_list : TOK_LBRACKET ctype_list TOK_RBRACKET {$$ = $2;}
;
ctype_list : ctype
{$$ = (Ctype_List_t*)calloc (1,
sizeof (Ctype_List_t));
if (!$$) {
fatal ("Error allocating memory");
}
$$->ctype = $1;
$$->next = (Ctype_List_t*)0;}
| ctype_list maybe_comma ctype
{$$ = (Ctype_List_t*)calloc (1,
sizeof (Ctype_List_t));
if (!$$) {
fatal ("Error allocating memory");
}
$$->ctype = $3;
$$->next = $1;
/*$$->next = (Ctype_List_t*)0;
assert ($1);
$1->next = $$;*/}
;
bool : TOK_BOOL_YES {$$ = TRUE;}
| TOK_BOOL_NO {$$ = FALSE;}
;
string : TOK_STRING_LITERAL {$$ = strdup(ifs_yytext);}
;
identifier : TOK_IDENTIFIER {$$ = strdup(ifs_yytext);}
;
number : real {$$.has_value = TRUE;
$$.kind = REAL;
$$.u.rvalue = $1;}
| integer_value
;
integer_value : integer {$$.has_value = TRUE;
$$.kind = INTEGER;
$$.u.ivalue = $1;}
;
real : TOK_REAL_LITERAL {$$ = yydval;}
;
integer : TOK_INT_LITERAL {$$ = yyival;}
;
%%

125
src/xspice/cmpp/main.c Executable file
View File

@ -0,0 +1,125 @@
/*============================================================================
FILE main.c
MEMBER OF process cmpp
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains the top-level function for the Code Model
PreProcessor (cmpp). It handles reading the command-line
arguments, and then vectors to an appropriate function.
INTERFACES
main()
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#include <stdio.h>
#include "cmpp.h"
#define USAGE_MSG "Usage: cmpp [-ifs] [-mod [<filename>]] [-lst]"
#define TOO_FEW_ARGS "ERROR - Too few arguments"
#define TOO_MANY_ARGS "ERROR - Too many arguments"
#define UNRECOGNIZED_ARGS "ERROR - Unrecognized argument"
/* *********************************************************************** */
/*
main
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.
depending on the argument.
*/
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 */
if(argc < 2) {
print_error(TOO_FEW_ARGS);
print_error(USAGE_MSG);
exit(1);
}
if(strcmp(argv[1],"-ifs") == 0) {
if(argc == 2) {
preprocess_ifs_file();
}
else {
print_error(TOO_MANY_ARGS);
print_error(USAGE_MSG);
exit(1);
}
}
else if(strcmp(argv[1],"-lst") == 0) {
if(argc == 2) {
preprocess_lst_files();
}
else {
print_error(TOO_MANY_ARGS);
print_error(USAGE_MSG);
exit(1);
}
}
else if(strcmp(argv[1],"-mod") == 0) {
if(argc == 2) {
preprocess_mod_file("cfunc.mod");
}
else if(argc == 3) {
preprocess_mod_file(argv[2]);
}
else {
print_error(TOO_MANY_ARGS);
print_error(USAGE_MSG);
exit(1);
}
}
else {
print_error(UNRECOGNIZED_ARGS);
print_error(USAGE_MSG);
exit(1);
}
exit(0);
}

108
src/xspice/cmpp/mod_lex.l Executable file
View File

@ -0,0 +1,108 @@
%option yylineno
%option noyywrap
%array
%{ /* $Id$ */
/*============================================================================
FILE mod_lex.l
MEMBER OF process cmpp
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Steve Tynor
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file defines tokens applicable to parsing the cfunc.mod
file, and actions to be taken on encountering those tokens.
INTERFACES
None.
REFERENCED FILES
mod_yacc.y
NON-STANDARD FEATURES
None.
============================================================================*/
#include "mod_yacc.h"
#include "mod_tok.h"
%}
I [A-Za-z_]
Z [0-9A-Za-z_]
%%
"/*" {char ch, last_ch;
ECHO; /* a comment - repeat it */
ch = '\0';
do {
last_ch = ch;
ch = input();
fputc(ch,mod_yyout);
} while (ch && !((last_ch == '*') && (ch == '/')));
if (!ch) {mod_yyerror ("Unterminated comment");}}
ARGS {return TOK_ARGS;}
INIT {return TOK_INIT;}
ANALYSIS {return TOK_ANALYSIS;}
NEW_TIMEPOINT {return TOK_NEW_TIMEPOINT;}
CALL_TYPE {return TOK_CALL_TYPE;}
TIME {return TOK_TIME;}
RAD_FREQ {return TOK_RAD_FREQ;}
TEMPERATURE {return TOK_TEMPERATURE;}
T {return TOK_T;}
LOAD {return TOK_LOAD;}
TOTAL_LOAD {return TOK_TOTAL_LOAD;}
MESSAGE {return TOK_MESSAGE;}
PARAM {return TOK_PARAM;}
PARAM_SIZE {return TOK_PARAM_SIZE;}
PARAM_NULL {return TOK_PARAM_NULL;}
PORT_SIZE {return TOK_PORT_SIZE;}
PORT_NULL {return TOK_PORT_NULL;}
PARTIAL {return TOK_PARTIAL;}
AC_GAIN {return TOK_AC_GAIN;}
OUTPUT_DELAY {return TOK_OUTPUT_DELAY;}
STATIC_VAR {return TOK_STATIC_VAR;}
STATIC_VAR_SIZE {return TOK_STATIC_VAR_SIZE;}
INPUT {return TOK_INPUT;}
INPUT_STATE {return TOK_INPUT_STATE;}
INPUT_TYPE {return TOK_INPUT_TYPE;}
INPUT_STRENGTH {return TOK_INPUT_STRENGTH;}
OUTPUT {return TOK_OUTPUT;}
OUTPUT_STATE {return TOK_OUTPUT_STATE;}
OUTPUT_STRENGTH {return TOK_OUTPUT_STRENGTH;}
OUTPUT_TYPE {return TOK_OUTPUT_TYPE;}
OUTPUT_CHANGED {return TOK_OUTPUT_CHANGED;}
"(" {return TOK_LPAREN;}
")" {return TOK_RPAREN;}
"[" {return TOK_LBRACKET;}
"]" {return TOK_RBRACKET;}
"," {return TOK_COMMA;}
{I}+{Z}* {return TOK_IDENTIFIER;}
[ \t] ECHO; /* just eat non-newline whitespace */
\n ECHO; /* echo newlines */
. {return TOK_MISC_C;}
%%

49
src/xspice/cmpp/mod_yacc.h Executable file
View File

@ -0,0 +1,49 @@
/* $Id$ */
/*============================================================================
FILE mod_yacc.h
MEMBER OF process cmpp
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Steve Tynor
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
Typedefs needed by the YYSTYPE union (%union operator) in the yacc
file. These are only used in the yacc file, but must be defined here since
the generated token.h file includes a definition of the union YYSTYPE.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#include "cmpp.h"
typedef struct {
char *id;
Boolean_t has_subscript;
char *subscript;
} Sub_Id_t;

566
src/xspice/cmpp/mod_yacc.y Executable file
View File

@ -0,0 +1,566 @@
%{ /* $Id$ */
/*============================================================================
FILE mod_yacc.y
MEMBER OF process cmpp
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Steve Tynor
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains a BNF specification of the translation of
cfunc.mod files to cfunc.c files, together with various support
functions.
INTERFACES
mod_yyparse() - Function 'yyparse()' is generated automatically
by UNIX 'yacc' utility and then converted to
'mod_yyparse()' by UNIX 'sed' utility under
direction of Makefile.
REFERENCED FILES
mod_lex.l
NON-STANDARD FEATURES
Names of functions generated by 'yacc' are translated by 'sed'
under direction of the Makefile to prevent collisions with
functions generated from ifs_yacc.y.
============================================================================*/
#include <assert.h>
#include <stdio.h>
#include "mod_yacc.h"
Ifs_Table_t *mod_ifs_table;
extern char mod_yytext[];
extern FILE* mod_yyout;
/* saj - use standard includes */
#include <string.h>
#include <ctype.h>
/*
extern char *strdup(char*);
extern int strlen(char*);
extern char *strcat(char*, char*);
*/
int mod_num_errors;
#define BUFFER_SIZE 3000
static char buffer [BUFFER_SIZE];
static int buf_len;
typedef enum {CONN, PARAM, STATIC_VAR} Id_Kind_t;
/*--------------------------------------------------------------------------*/
static char *subscript (Sub_Id_t sub_id)
{
if (sub_id.has_subscript) {
return sub_id.subscript;
} else {
return "0";
}
}
/*--------------------------------------------------------------------------*/
int strcmpi(s, t)
char *s;
char *t;
/* string compare - case insensitive */
{
for (; *s && t && tolower(*s) == tolower(*t); s++, t++);
if (*s && !*t) {
return 1;
}
if (!*s && *t) {
return -1;
}
if (! (*s || *t)) {
return 0;
}
return (tolower(*s) - tolower(*t));
}
/*---------------------------------------------------------------------------*/
static void put_type (FILE *fp, Data_Type_t type)
{
char ch;
switch (type) {
case INTEGER:
ch = 'i';
break;
case REAL:
ch = 'r';
break;
case COMPLEX:
ch = 'c';
break;
case BOOLEAN:
ch = 'b';
break;
case STRING:
ch = 's';
break;
case POINTER:
ch = 'p';
break;
}
fprintf (fp, ".%cvalue", ch);
}
/*---------------------------------------------------------------------------*/
static void put_conn_type (FILE *fp, Port_Type_t type)
{
char ch;
switch (type) {
case USER_DEFINED:
ch = 'p';
break;
case DIGITAL:
ch = 'p';
break;
default:
ch = 'r';
break;
}
fprintf (fp, ".%cvalue", ch);
}
/*---------------------------------------------------------------------------*/
static void check_dir (int conn_number, Dir_t dir, char *context)
{
Dir_t conn_dir;
if (conn_number >= 0) {
/*
* If negative, this is an invalid port ID and we've already issued
* an error.
*/
conn_dir = mod_ifs_table->conn[conn_number].direction;
if ((conn_dir != dir) && (conn_dir != INOUT)) {
char error_str[200];
sprintf (error_str,
"Direction of port `%s' in %s() is not %s or INOUT",
mod_ifs_table->conn[conn_number].name, context,
(dir == IN) ? "IN" : "OUT");
yyerror (error_str);
mod_num_errors++;
}
}
}
/*---------------------------------------------------------------------------*/
static void check_subscript (Boolean_t formal, Boolean_t actual,
Boolean_t missing_actual_ok,
char *context, char *id)
{
char error_str[200];
if ((formal && !actual) && !missing_actual_ok) {
sprintf (error_str,
"%s `%s' is an array - subscript required",
context, id);
yyerror (error_str);
mod_num_errors++;
return;
} else if (!formal && actual) {
sprintf (error_str,
"%s `%s' is not an array - subscript prohibited",
context, id);
yyerror (error_str);
mod_num_errors++;
return;
}
}
/*---------------------------------------------------------------------------*/
static int check_id (Sub_Id_t sub_id, Id_Kind_t kind, Boolean_t do_subscript)
{
int i;
char error_str[200];
switch (kind) {
case CONN:
for (i = 0; i < mod_ifs_table->num_conn; i++) {
if (0 == strcmpi (sub_id.id, mod_ifs_table->conn[i].name)) {
if (do_subscript) {
check_subscript (mod_ifs_table->conn[i].is_array,
sub_id.has_subscript, FALSE, "Port",
sub_id.id);
}
return i;
}
}
break;
case PARAM:
for (i = 0; i < mod_ifs_table->num_param; i++) {
if (0 == strcmpi (sub_id.id, mod_ifs_table->param[i].name)) {
if (do_subscript) {
check_subscript (mod_ifs_table->param[i].is_array,
sub_id.has_subscript, FALSE, "Parameter",
sub_id.id);
}
return i;
}
}
break;
case STATIC_VAR:
for (i = 0; i < mod_ifs_table->num_inst_var; i++) {
if (0 == strcmpi (sub_id.id, mod_ifs_table->inst_var[i].name)) {
if (do_subscript) {
check_subscript (mod_ifs_table->inst_var[i].is_array,
sub_id.has_subscript, TRUE,
"Static Variable",
sub_id.id);
}
return i;
}
}
break;
}
sprintf (error_str, "No %s named '%s'",
((kind==CONN)
? "port"
: ((kind==PARAM)
? "parameter"
:"static variable")),
sub_id.id);
yyerror (error_str);
mod_num_errors++;
abort();
return -1;
}
/*---------------------------------------------------------------------------*/
static int valid_id (Sub_Id_t sub_id, Id_Kind_t kind)
{
return check_id (sub_id, kind, FALSE);
}
/*---------------------------------------------------------------------------*/
static int valid_subid (Sub_Id_t sub_id, Id_Kind_t kind)
{
return check_id (sub_id, kind, TRUE);
}
/*---------------------------------------------------------------------------*/
static init_buffer ()
{
buf_len = 0;
buffer[0] = '\0';
}
/*---------------------------------------------------------------------------*/
static append (char *str)
{
int len = strlen (str);
if (len + buf_len > BUFFER_SIZE) {
yyerror ("Buffer overflow - try reducing the complexity of CM-macro array subscripts");
exit (1);
}
(void)strcat (buffer,str);
}
%}
%union {
char *str;
Sub_Id_t sub_id;
}
%type <str> buffered_c_code
%type <sub_id> subscriptable_id id
%token TOK_ARGS
%token TOK_INIT
%token TOK_ANALYSIS
%token TOK_NEW_TIMEPOINT
%token TOK_TIME
%token TOK_RAD_FREQ
%token TOK_TEMPERATURE
%token TOK_T
%token TOK_PARAM
%token TOK_PARAM_SIZE
%token TOK_PARAM_NULL
%token TOK_PORT_SIZE
%token TOK_PORT_NULL
%token TOK_PARTIAL
%token TOK_AC_GAIN
%token TOK_CHANGED
%token TOK_OUTPUT_DELAY
%token TOK_STATIC_VAR
%token TOK_STATIC_VAR_SIZE
%token TOK_INPUT
%token TOK_INPUT_STRENGTH
%token TOK_INPUT_STATE
%token TOK_INPUT_TYPE
%token TOK_OUTPUT
%token TOK_OUTPUT_CHANGED
%token TOK_OUTPUT_STRENGTH
%token TOK_OUTPUT_STATE
%token TOK_OUTPUT_TYPE
%token TOK_COMMA
%token TOK_LPAREN
%token TOK_RPAREN
%token TOK_LBRACKET
%token TOK_RBRACKET
%token TOK_MISC_C
%token TOK_IDENTIFIER
%token TOK_LOAD
%token TOK_TOTAL_LOAD
%token TOK_MESSAGE
%token TOK_CALL_TYPE
%start mod_file
%%
mod_file : /* empty */
| mod_file c_code
;
c_code : /* empty */
| c_code c_char
| c_code macro
/*| TOK_RPAREN {yyerror ("Unmatched )"); YYERROR;}
| TOK_RBRACKET {yyerror ("Unmatched ]"); YYERROR;}*/
;
buffered_c_code : {init_buffer();} buffered_c_code2
{$$ = strdup (buffer);}
;
buffered_c_code2 : /* empty */
| buffered_c_code2 buffered_c_char
;
buffered_c_char : TOK_IDENTIFIER {append (mod_yytext);}
| TOK_MISC_C {append (mod_yytext);}
| TOK_COMMA {append (mod_yytext);}
| TOK_LBRACKET
{append("[");}
buffered_c_code2 TOK_RBRACKET
{append("]");}
| TOK_LPAREN
{append("(");}
buffered_c_code2 TOK_RPAREN
{append(")");}
;
c_char : TOK_IDENTIFIER {fputs (mod_yytext, mod_yyout);}
| TOK_MISC_C {fputs (mod_yytext, mod_yyout);}
| TOK_COMMA {fputs (mod_yytext, mod_yyout);}
| TOK_LBRACKET
{putc ('[', mod_yyout);}
c_code TOK_RBRACKET
{putc (']', mod_yyout);}
| TOK_LPAREN
{putc ('(', mod_yyout);}
c_code TOK_RPAREN
{putc (')', mod_yyout);}
;
macro : TOK_INIT
{fprintf (mod_yyout, "private->circuit.init");}
| TOK_ARGS
{fprintf (mod_yyout, "Mif_Private_t *private");}
| TOK_ANALYSIS
{fprintf (mod_yyout, "private->circuit.anal_type");}
| TOK_NEW_TIMEPOINT
{fprintf (mod_yyout, "private->circuit.anal_init");}
| TOK_CALL_TYPE
{fprintf (mod_yyout, "private->circuit.call_type");}
| TOK_TIME
{fprintf (mod_yyout, "private->circuit.time");}
| TOK_RAD_FREQ
{fprintf (mod_yyout, "private->circuit.frequency");}
| TOK_TEMPERATURE
{fprintf (mod_yyout, "private->circuit.temperature");}
| TOK_T TOK_LPAREN buffered_c_code TOK_RPAREN
{fprintf (mod_yyout, "private->circuit.t[%s]", $3);}
| TOK_PARAM TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, PARAM);
fprintf (mod_yyout, "private->param[%d]->element[%s]",
i, subscript ($3));
put_type (mod_yyout, mod_ifs_table->param[i].type);
}
| TOK_PARAM_SIZE TOK_LPAREN id TOK_RPAREN
{int i = valid_id ($3, PARAM);
fprintf (mod_yyout, "private->param[%d]->size", i);}
| TOK_PARAM_NULL TOK_LPAREN id TOK_RPAREN
{int i = valid_id ($3, PARAM);
fprintf (mod_yyout, "private->param[%d]->is_null", i);}
| TOK_PORT_SIZE TOK_LPAREN id TOK_RPAREN
{int i = valid_id ($3, CONN);
fprintf (mod_yyout, "private->conn[%d]->size", i);}
| TOK_PORT_NULL TOK_LPAREN id TOK_RPAREN
{int i = valid_id ($3, CONN);
fprintf (mod_yyout, "private->conn[%d]->is_null", i);}
| TOK_PARTIAL TOK_LPAREN subscriptable_id TOK_COMMA
subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
int j = valid_subid ($5, CONN);
check_dir (i, OUT, "PARTIAL");
check_dir (j, IN, "PARTIAL");
fprintf (mod_yyout, "private->conn[%d]->port[%s]->partial[%d].port[%s]",
i, subscript($3), j, subscript($5));}
| TOK_AC_GAIN TOK_LPAREN subscriptable_id TOK_COMMA
subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
int j = valid_subid ($5, CONN);
check_dir (i, OUT, "AC_GAIN");
check_dir (j, IN, "AC_GAIN");
fprintf (mod_yyout,
"private->conn[%d]->port[%s]->ac_gain[%d].port[%s]",
i, subscript($3), j, subscript($5));}
| TOK_STATIC_VAR TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, STATIC_VAR);
fprintf (mod_yyout,
"private->inst_var[%d]->element[%s]",
i, subscript($3));
if (mod_ifs_table->inst_var[i].is_array
&& !($3.has_subscript)) {
/* null - eg. for malloc lvalue */
} else {
put_type (mod_yyout,
mod_ifs_table->inst_var[i].type);
} }
| TOK_STATIC_VAR_SIZE TOK_LPAREN id TOK_RPAREN
{int i = valid_subid ($3, STATIC_VAR);
fprintf (mod_yyout, "private->inst_var[%d]->size",
i, subscript($3));}
| TOK_OUTPUT_DELAY TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
check_dir (i, OUT, "OUTPUT_DELAY");
fprintf (mod_yyout,
"private->conn[%d]->port[%s]->delay", i,
subscript($3));}
| TOK_CHANGED TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
check_dir (i, OUT, "CHANGED");
fprintf (mod_yyout,
"private->conn[%d]->port[%s]->changed", i,
subscript($3));}
| TOK_INPUT TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
check_dir (i, IN, "INPUT");
fprintf (mod_yyout,
"private->conn[%d]->port[%s]->input",
i, subscript($3));
put_conn_type (mod_yyout,
mod_ifs_table->conn[i].allowed_port_type[0]);}
| TOK_INPUT_TYPE TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
check_dir (i, IN, "INPUT_TYPE");
fprintf (mod_yyout,
"private->conn[%d]->port[%s]->type_str",
i, subscript($3)); }
| TOK_OUTPUT_TYPE TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
check_dir (i, OUT, "OUTPUT_TYPE");
fprintf (mod_yyout,
"private->conn[%d]->port[%s]->type_str",
i, subscript($3)); }
| TOK_INPUT_STRENGTH TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
check_dir (i, IN, "INPUT_STRENGTH");
fprintf (mod_yyout,
"((Digital_t*)(private->conn[%d]->port[%s]->input",
i, subscript($3));
put_conn_type (mod_yyout,
mod_ifs_table->conn[i].allowed_port_type[0]);
fprintf (mod_yyout, "))->strength");}
| TOK_INPUT_STATE TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
check_dir (i, IN, "INPUT_STATE");
fprintf (mod_yyout,
"((Digital_t*)(private->conn[%d]->port[%s]->input",
i, subscript($3));
put_conn_type (mod_yyout,
mod_ifs_table->conn[i].allowed_port_type[0]);
fprintf (mod_yyout, "))->state");}
| TOK_OUTPUT TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
check_dir (i, OUT, "OUTPUT");
fprintf (mod_yyout,
"private->conn[%d]->port[%s]->output",
i, subscript($3));
put_conn_type (mod_yyout,
mod_ifs_table->conn[i].allowed_port_type[0]);}
| TOK_OUTPUT_STRENGTH TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
check_dir (i, OUT, "OUTPUT_STRENGTH");
fprintf (mod_yyout,
"((Digital_t*)(private->conn[%d]->port[%s]->output",
i, subscript($3));
put_conn_type (mod_yyout,
mod_ifs_table->conn[i].allowed_port_type[0]);
fprintf (mod_yyout, "))->strength");}
| TOK_OUTPUT_STATE TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
check_dir (i, OUT, "OUTPUT_STATE");
fprintf (mod_yyout,
"((Digital_t*)(private->conn[%d]->port[%s]->output",
i, subscript($3));
put_conn_type (mod_yyout,
mod_ifs_table->conn[i].allowed_port_type[0]);
fprintf (mod_yyout, "))->state");}
| TOK_OUTPUT_CHANGED TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
fprintf (mod_yyout,
"private->conn[%d]->port[%s]->changed", i,
subscript($3));}
| TOK_LOAD TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
fprintf (mod_yyout,
"private->conn[%d]->port[%s]->load", i,
subscript($3));}
| TOK_TOTAL_LOAD TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
fprintf (mod_yyout,
"private->conn[%d]->port[%s]->total_load", i,
subscript($3));}
| TOK_MESSAGE TOK_LPAREN subscriptable_id TOK_RPAREN
{int i = valid_subid ($3, CONN);
fprintf (mod_yyout,
"private->conn[%d]->port[%s]->msg", i,
subscript($3));}
;
subscriptable_id : id
| id TOK_LBRACKET buffered_c_code TOK_RBRACKET
{$$ = $1;
$$.has_subscript = TRUE;
$$.subscript = $3;}
;
id : TOK_IDENTIFIER
{$$.has_subscript = FALSE;
$$.id = strdup (mod_yytext);}
;
%%

88
src/xspice/cmpp/pp_ifs.c Executable file
View File

@ -0,0 +1,88 @@
/*============================================================================
FILE pp_ifs.c
MEMBER OF process cmpp
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains the main function for processing an Interface Spec
File (ifspec.ifs).
INTERFACES
preprocess_ifs_file()
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#include "cmpp.h"
/* *********************************************************************** */
/*
preprocess_ifs_file
Function preprocess_ifs_file is the top-level driver function for
preprocessing an Interface Specification file (ifspec.ifs). This
function calls read_ifs_file() requesting it to read and parse
the Interface Specification file and place the information
contained in it into an internal data structure. Then
write_ifs_c_file() is called to write the information out in a C
file that will be compiled and linked with the simulator.
*/
void preprocess_ifs_file(void)
{
Ifs_Table_t ifs_table; /* Repository for info read from ifspec.ifs file */
Status_t status; /* Return status */
/* Read the entire ifspec.ifs file and load the data into ifs_table */
status = read_ifs_file(IFSPEC_FILENAME,GET_IFS_TABLE,&ifs_table);
if(status != OK) {
exit(1);
}
/* Write the ifspec.c file required by the spice simulator */
status = write_ifs_c_file("ifspec.c",&ifs_table);
if(status != OK) {
exit(1);
}
}

1082
src/xspice/cmpp/pp_lst.c Executable file

File diff suppressed because it is too large Load Diff

180
src/xspice/cmpp/pp_mod.c Executable file
View File

@ -0,0 +1,180 @@
/*============================================================================
FILE pp_mod.c
MEMBER OF process cmpp
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Steve Tynor
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains the top-level driver function for preprocessing the
"cfunc.mod" file. First, the "ifspec.ifs" file is opened and parsed to
get the data that will be needed in the .mod to .c translation (See
read_ifs.c). Then the .mod file is translated. Most of the work of the
translation is handled by the UNIX 'lex' and 'yacc' utilities. This
translation is begun at the call to mod_yyparse() below. See also files:
mod_lex.l
mod_yacc.y
Note that to allow lex/yacc to be used twice (once for the ifspec.ifs
file, and then again for the cfunc.mod file), the functions created by
lex/yacc for the latter are translated using the UNIX text editor 'sed'
under the direction of the Makefile and the following 'sed scripts':
mod_lex.sed
mod_yacc.sed
Hence the call to 'mod_yyparse()' rather than 'yyparse()' below.
INTERFACES
preprocess_mod_file()
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#include "cmpp.h"
/*---------------------------------------------------------------------------*/
static void change_extension (char *filename, char *ext, char *new_filename)
{
int i = strlen (filename);
strcpy (new_filename, filename);
for (; i >= 0; i--) {
if (new_filename[i] == '.') {
new_filename[i+1] = '\0';
break;
}
}
strcat (new_filename, ext);
}
/*---------------------------------------------------------------------------*/
/*
preprocess_mod_file
Function preprocess_mod_file is the top-level driver function for
preprocessing a code model file (cfunc.mod). This function calls
read_ifs_file() requesting it to read and parse the Interface
Specification file (ifspec.ifs) and place the information
contained in it into an internal data structure. It then calls
mod_yyparse() to read the cfunc.mod file and translate it
according to the Interface Specification information. Function
mod_yyparse() is automatically generated by UNIX lex/yacc
utilities.
*/
void preprocess_mod_file (
char *filename) /* The file to read */
{
extern FILE *mod_yyin;
extern FILE *mod_yyout;
extern char *current_filename;
extern int mod_yylineno;
extern int mod_num_errors;
extern Ifs_Table_t *mod_ifs_table;
Ifs_Table_t ifs_table; /* info read from ifspec.ifs file */
Status_t status; /* Return status */
char error_str[200];
char output_filename[200];
/*
* Read the entire ifspec.ifs file and load the data into ifs_table
*/
status = read_ifs_file (IFSPEC_FILENAME, GET_IFS_TABLE, &ifs_table);
if (status != OK) {
exit(1);
}
mod_yyin = fopen (filename, "r");
if (mod_yyin == NULL) {
sprintf(error_str, "ERROR - Could not open input .mod file: %s",
filename);
print_error(error_str);
return;
}
current_filename = filename;
change_extension (filename, "c", output_filename);
mod_yyout = fopen (output_filename, "w");
if (mod_yyout == NULL) {
sprintf(error_str, "ERROR - Could not open output .c: %s",
output_filename);
print_error(error_str);
return;
}
mod_ifs_table = &ifs_table;
mod_num_errors = 0;
fprintf (mod_yyout, "#line 1 \"%s\"\n", filename);
fprintf (mod_yyout, "#include \"cm.h\"\n");
fprintf (mod_yyout, "#line 1 \"%s\"\n", filename);
mod_yylineno = 1;
if (!mod_yyin) {
sprintf (error_str, "Could not open .mod file: \"%s\"", filename);
print_error (error_str);
unlink (output_filename);
exit(1);
}
if (!mod_yyout) {
sprintf (error_str, "Could not create .c file: \"%s\"",
output_filename);
print_error (error_str);
unlink (output_filename);
exit(1);
}
if (mod_yyparse() || (mod_num_errors > 0)) {
sprintf (error_str, "Error parsing .mod file: \"%s\"", filename);
print_error (error_str);
unlink (output_filename);
exit (1);
}
fclose (mod_yyout);
}
/*---------------------------------------------------------------------------*/
int mod_yyerror (str)
char *str;
{
extern int mod_yylineno;
extern char mod_yytext[];
extern char *current_filename;
extern char *prog_name;
fprintf (stderr, "%s: Error: \"%s\": line %d (near \'%s\'):\n\t%s.\n",
prog_name, current_filename, mod_yylineno, mod_yytext, str);
}

173
src/xspice/cmpp/read_ifs.c Executable file
View File

@ -0,0 +1,173 @@
/*============================================================================
FILE read_ifs.c
MEMBER OF process cmpp
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn and Steve Tynor
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains top-level functions used in reading information
from the ifspec.ifs file and building an internal data structure that
holds the information. Most of the work in parsing of the
ifspec.ifs file and in building the structure is handled by
the UNIX 'lex' and 'yacc' utilities. This processing is begun
at the call to yyparse() in read_ifs_table() below. See also files:
ifs_lex.l
ifs_yacc.y
INTERFACES
read_ifs_file()
yywrap()
yyerror()
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#include <assert.h>
#include "cmpp.h"
extern char *prog_name;
void *malloc(unsigned size);
static Status_t read_ifs_table(FILE *fp, int mode, Ifs_Table_t *ifs_table);
char *current_filename;
/* *********************************************************************** */
/*
NOTE
The following function may be called either by cmpp -ifs or cmpp -lst with
mode set to GET_IFS_TABLE or GET_IFS_NAME respectively.
*/
/*
read_ifs_file
Function read_ifs_file() opens the Interface Specification file
(ifspec.ifs) for read access and calls read_ifs_table() with the
assigned file pointer to read and parse the file. Upon return
from read_ifs_table(), the file is closed.
*/
Status_t read_ifs_file(
char *filename, /* File to read */
int mode, /* Get names only or get everything? */
Ifs_Table_t *ifs_table) /* Table to put info in */
{
FILE *fp; /* Ifs file pointer */
char msg[MAX_PATH_LEN+257]; /* space for an error message */
Status_t status; /* returned status from function */
/* Open the ifs file for read access */
fp = fopen(filename, "r");
if(fp == NULL) {
perror (prog_name);
sprintf(msg, "ERROR - File not found: %s", filename);
print_error(msg);
return(ERROR);
}
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);
}
/* *********************************************************************** */
/*
read_ifs_table
Function read_ifs_table() calls yyparse() to read and parse the
Interface Specification file contents and place the information
into an internal data structure. Function yyparse() is
automatically generated by UNIX lex/yacc.
*/
static Status_t read_ifs_table(
FILE *fp, /* File to read from */
int mode, /* Get names only or get everything? */
Ifs_Table_t *ifs_table) /* Table to put info in */
{
extern FILE *ifs_yyin;
extern Ifs_Table_t *parser_ifs_table;
extern Boolean_t parser_just_names;
extern int ifs_yylineno;
assert (ifs_table);
assert (fp);
ifs_yylineno = 1;
ifs_yyin = fp;
parser_just_names = (mode == GET_IFS_NAME);
parser_ifs_table = ifs_table;
if (ifs_yyparse()) {
print_error ("Error parsing interface specification file");
return ERROR;
}
return OK;
}
/*---------------------------------------------------------------------------*/
int ifs_yyerror (str)
char *str;
{
extern int ifs_yylineno;
extern char ifs_yytext[];
fprintf (stderr, "%s: Error: \"%s\": line %d (near \'%s\'):\n\t%s.\n",
prog_name, current_filename, ifs_yylineno, ifs_yytext, str);
}

87
src/xspice/cmpp/util.c Executable file
View File

@ -0,0 +1,87 @@
/*============================================================================
FILE util.c
MEMBER OF process cmpp
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn and Steve Tynor
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains miscellaneous utility functions used in cmpp.
INTERFACES
init_error()
print_error()
str_to_lower()
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#include "cmpp.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
/* *********************************************************************** */
char *prog_name;
/* Initialize print_error() with the name of the program */
void init_error (char *program_name)
{
prog_name = program_name;
}
/* Print an error message to stderr */
void print_error(
char *msg) /* The message to write */
{
fprintf(stderr, "%s: %s\n", prog_name, msg);
}
/* Convert a string to all lower case */
str_to_lower(s)
char *s; /* The string to convert */
{
int i;
char c;
for(i = 0; (c = s[i]) != '\0'; i++)
if(isalpha(c))
if(isupper(c))
s[i] = tolower(c);
}

1291
src/xspice/cmpp/writ_ifs.c Executable file

File diff suppressed because it is too large Load Diff