inpcom.c, rewrite .lib processing
This commit is contained in:
parent
54be463685
commit
afeb7e4b59
|
|
@ -20,6 +20,7 @@ Author: 1985 Wayne A. Christopher
|
||||||
|
|
||||||
#include "inpcom.h"
|
#include "inpcom.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
|
#include "subckt.h"
|
||||||
#include "../misc/util.h" /* ngdirname() */
|
#include "../misc/util.h" /* ngdirname() */
|
||||||
#include "ngspice/stringutil.h"
|
#include "ngspice/stringutil.h"
|
||||||
#include "ngspice/wordlist.h"
|
#include "ngspice/wordlist.h"
|
||||||
|
|
@ -42,11 +43,8 @@ Author: 1985 Wayne A. Christopher
|
||||||
#define N_SUBCKT_W_PARAMS 4000
|
#define N_SUBCKT_W_PARAMS 4000
|
||||||
|
|
||||||
static char *library_name[N_LIBRARY];
|
static char *library_name[N_LIBRARY];
|
||||||
static char *section_name[N_LIBRARY][N_SECTIONS];
|
|
||||||
static struct line *section_ref[N_LIBRARY][N_SECTIONS];
|
|
||||||
static struct line *library_deck[N_LIBRARY];
|
static struct line *library_deck[N_LIBRARY];
|
||||||
static int num_libraries;
|
static int num_libraries;
|
||||||
static int num_sections[N_LIBRARY];
|
|
||||||
static char *global;
|
static char *global;
|
||||||
static char *subckt_w_params[N_SUBCKT_W_PARAMS];
|
static char *subckt_w_params[N_SUBCKT_W_PARAMS];
|
||||||
static int num_subckt_w_params;
|
static int num_subckt_w_params;
|
||||||
|
|
@ -72,8 +70,7 @@ static void inp_stripcomments_deck(struct line *deck);
|
||||||
static void inp_stripcomments_line(char *s);
|
static void inp_stripcomments_line(char *s);
|
||||||
static void inp_fix_for_numparam(struct line *deck);
|
static void inp_fix_for_numparam(struct line *deck);
|
||||||
static void inp_remove_excess_ws(struct line *deck);
|
static void inp_remove_excess_ws(struct line *deck);
|
||||||
static void collect_section_references(struct line *deck, char *section_name_);
|
static void expand_section_references(struct line *deck, int call_depth, char *dir_name);
|
||||||
static void inp_init_lib_data(void);
|
|
||||||
static void inp_grab_func(struct line *deck);
|
static void inp_grab_func(struct line *deck);
|
||||||
static void inp_fix_inst_calls_for_numparam(struct line *deck);
|
static void inp_fix_inst_calls_for_numparam(struct line *deck);
|
||||||
static void inp_expand_macros_in_func(void);
|
static void inp_expand_macros_in_func(void);
|
||||||
|
|
@ -121,25 +118,41 @@ find_lib(char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static struct line *
|
||||||
find_section(int lib_idx, char *section_name_) {
|
find_section_definition(struct line *deck, char *name)
|
||||||
int j;
|
{
|
||||||
for (j = 0; j < num_sections[lib_idx]; j++)
|
struct line *c;
|
||||||
if (strcmp(section_name[lib_idx][j], section_name_) == 0)
|
|
||||||
return j;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (c = deck; c; c = c->li_next) {
|
||||||
|
char *line = c->li_line;
|
||||||
|
if (ciprefix(".lib", line)) {
|
||||||
|
char *s, *t, *y;
|
||||||
|
s = skip_non_ws(line);
|
||||||
|
while (isspace(*s) || isquote(*s))
|
||||||
|
s++;
|
||||||
|
for (t = s; *t && !isspace(*t) && !isquote(*t); t++)
|
||||||
|
;
|
||||||
|
y = t;
|
||||||
|
while (isspace(*y) || isquote(*y))
|
||||||
|
y++;
|
||||||
|
|
||||||
static void
|
if (!*y) {
|
||||||
remember_section_ref(int lib_idx, char *section_name_, struct line *deck) {
|
/* library section definition: `.lib <section-name>' .. `.endl' */
|
||||||
int section_idx = num_sections[lib_idx]++;
|
|
||||||
if (section_idx >= N_SECTIONS) {
|
char keep_char = *t;
|
||||||
fprintf(stderr, "ERROR, N_SECTIONS overflow\n");
|
*t = '\0';
|
||||||
controlled_exit(EXIT_FAILURE);
|
|
||||||
|
if (strcasecmp(name, s) == 0) {
|
||||||
|
*t = keep_char;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
*t = keep_char;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
section_ref[lib_idx][section_idx] = deck;
|
|
||||||
section_name[lib_idx][section_idx] = strdup(section_name_);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -203,116 +216,6 @@ read_a_lib(char *y, int call_depth, char *dir_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
expand_section_references(int line_number)
|
|
||||||
{
|
|
||||||
struct line *tmp_ptr = NULL, *next;
|
|
||||||
int lib_idx;
|
|
||||||
|
|
||||||
for (lib_idx = 0; lib_idx < num_libraries; lib_idx++) {
|
|
||||||
bool found_section = FALSE;
|
|
||||||
struct line *working = library_deck[lib_idx];
|
|
||||||
while (working) {
|
|
||||||
char *buffer = working->li_line;
|
|
||||||
|
|
||||||
if (found_section && ciprefix(".endl", buffer)) {
|
|
||||||
|
|
||||||
struct line *next = working->li_next;
|
|
||||||
|
|
||||||
/* Make the .endl a comment */
|
|
||||||
*buffer = '*';
|
|
||||||
found_section = FALSE;
|
|
||||||
|
|
||||||
/* append the line following the library section reference */
|
|
||||||
working->li_next = tmp_ptr;
|
|
||||||
|
|
||||||
/* and continue with the line following */
|
|
||||||
/* the .endl of this section definition */
|
|
||||||
working = next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ciprefix(".lib", buffer)) {
|
|
||||||
|
|
||||||
/* here we expect a libray section definition */
|
|
||||||
/* library section definition: `.lib <section-name>' .. `.endl' */
|
|
||||||
|
|
||||||
char keep_char;
|
|
||||||
int section_idx;
|
|
||||||
char *s, *t;
|
|
||||||
|
|
||||||
if (found_section) {
|
|
||||||
fprintf(stderr, "ERROR: .lib is missing .endl!\n");
|
|
||||||
controlled_exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
s = skip_non_ws(buffer); /* skip over .lib */
|
|
||||||
while (isspace(*s) || isquote(*s))
|
|
||||||
s++; /* advance past space chars */
|
|
||||||
for (t = s; *t && !isspace(*t) && !isquote(*t); t++)
|
|
||||||
; /* skip to end of word */
|
|
||||||
keep_char = *t;
|
|
||||||
*t = '\0';
|
|
||||||
|
|
||||||
/* check if we remember this section having been referenced somewhere */
|
|
||||||
section_idx = find_section(lib_idx, s);
|
|
||||||
|
|
||||||
*t = keep_char;
|
|
||||||
|
|
||||||
found_section = (section_idx >= 0);
|
|
||||||
|
|
||||||
if (found_section) {
|
|
||||||
|
|
||||||
struct line *c;
|
|
||||||
int line_number_lib;
|
|
||||||
|
|
||||||
/* make the .lib of this library section definition a comment */
|
|
||||||
*buffer = '*';
|
|
||||||
|
|
||||||
/* tmp_ptr is the line following the library section reference */
|
|
||||||
tmp_ptr = section_ref[lib_idx][section_idx]->li_next;
|
|
||||||
|
|
||||||
/* insert the section definition here, */
|
|
||||||
/* just behind the remembered section reference */
|
|
||||||
section_ref[lib_idx][section_idx]->li_next = working;
|
|
||||||
|
|
||||||
/* renumber lines */
|
|
||||||
line_number_lib = 1;
|
|
||||||
for (c = working; !ciprefix(".endl", c->li_line); c = c->li_next) {
|
|
||||||
c->li_linenum = line_number++;
|
|
||||||
c->li_linenum_orig = line_number_lib++;
|
|
||||||
}
|
|
||||||
c->li_linenum = line_number++; // renumber endl line
|
|
||||||
c->li_linenum_orig = line_number_lib++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
next = working->li_next;
|
|
||||||
|
|
||||||
/* drop this line in the current library file, if
|
|
||||||
* it is outside a library section definition
|
|
||||||
* or
|
|
||||||
* it is part of an unused library section definition
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!found_section) {
|
|
||||||
tfree(working->li_line);
|
|
||||||
tfree(working);
|
|
||||||
}
|
|
||||||
|
|
||||||
working = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_section) {
|
|
||||||
fprintf(stderr, "ERROR: .lib is missing .endl!\n");
|
|
||||||
controlled_exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return line_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
Read the entire input file and return a pointer to the first line of
|
Read the entire input file and return a pointer to the first line of
|
||||||
the linked list of 'card' records in data. The pointer is stored in
|
the linked list of 'card' records in data. The pointer is stored in
|
||||||
|
|
@ -478,50 +381,13 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile, bool intfile
|
||||||
|
|
||||||
/* now handle .lib statements */
|
/* now handle .lib statements */
|
||||||
if (ciprefix(".lib", buffer)) {
|
if (ciprefix(".lib", buffer)) {
|
||||||
|
if (inp_compat_mode == COMPATMODE_PS) {
|
||||||
char *y = NULL; /* filename */
|
|
||||||
char *z = NULL; /* libname */
|
|
||||||
char *s, *t;
|
|
||||||
|
|
||||||
inp_stripcomments_line(buffer);
|
|
||||||
s = skip_non_ws(buffer); /* skip over .lib */
|
|
||||||
|
|
||||||
s = strdup(s);
|
|
||||||
|
|
||||||
t = get_quoted_token(s, &y);
|
|
||||||
|
|
||||||
if (!y) {
|
|
||||||
fprintf(cp_err, "Error: .lib filename missing\n");
|
|
||||||
tfree(buffer); /* was allocated by readline() */
|
|
||||||
controlled_exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
t = get_quoted_token(t, &z);
|
|
||||||
|
|
||||||
if (z && (inp_compat_mode == COMPATMODE_ALL ||
|
|
||||||
inp_compat_mode == COMPATMODE_HS ||
|
|
||||||
inp_compat_mode == COMPATMODE_NATIVE))
|
|
||||||
{
|
|
||||||
/* here we have a */
|
|
||||||
/* library section reference: `.lib <library-file> <section-name>' */
|
|
||||||
|
|
||||||
if(!read_a_lib(y, call_depth, dir_name)) {
|
|
||||||
tfree(s);
|
|
||||||
tfree(buffer);
|
|
||||||
controlled_exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
tfree(s);
|
|
||||||
|
|
||||||
/* Make the .lib a comment */
|
|
||||||
*buffer = '*';
|
|
||||||
} else if (inp_compat_mode == COMPATMODE_PS) {
|
|
||||||
/* compatibility mode,
|
/* compatibility mode,
|
||||||
* this is neither a libray section definition nor a reference
|
* this is neither a libray section definition nor a reference
|
||||||
* interpret as old style
|
* interpret as old style
|
||||||
* .lib <file name> (no lib name given)
|
* .lib <file name> (no lib name given)
|
||||||
*/
|
*/
|
||||||
fprintf(cp_err, "Warning: library name missing in line\n %s", buffer);
|
char *s = skip_non_ws(buffer); /* skip over .lib */
|
||||||
fprintf(cp_err, " File included as: .inc %s\n", s);
|
fprintf(cp_err, " File included as: .inc %s\n", s);
|
||||||
memcpy(buffer, ".inc", 4);
|
memcpy(buffer, ".inc", 4);
|
||||||
}
|
}
|
||||||
|
|
@ -635,6 +501,7 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile, bool intfile
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
if ( !ciprefix("write", buffer) &&
|
if ( !ciprefix("write", buffer) &&
|
||||||
|
!ciprefix(".lib", buffer) &&
|
||||||
!ciprefix("codemodel", buffer) &&
|
!ciprefix("codemodel", buffer) &&
|
||||||
!ciprefix("use", buffer) &&
|
!ciprefix("use", buffer) &&
|
||||||
!ciprefix("load", buffer)
|
!ciprefix("load", buffer)
|
||||||
|
|
@ -712,16 +579,13 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile, bool intfile
|
||||||
cc->li_next = global_card;
|
cc->li_next = global_card;
|
||||||
global_card->li_next = prev;
|
global_card->li_next = prev;
|
||||||
|
|
||||||
inp_init_lib_data();
|
if (inp_compat_mode == COMPATMODE_ALL ||
|
||||||
collect_section_references(cc, NULL);
|
inp_compat_mode == COMPATMODE_HS ||
|
||||||
}
|
inp_compat_mode == COMPATMODE_NATIVE)
|
||||||
|
{
|
||||||
/*
|
/* process all library section references */
|
||||||
add libraries
|
expand_section_references(cc, call_depth, dir_name);
|
||||||
*/
|
}
|
||||||
|
|
||||||
if (call_depth == 0) {
|
|
||||||
line_number = expand_section_references(line_number);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2338,7 +2202,7 @@ inp_fix_for_numparam(struct line *deck)
|
||||||
char *str_ptr;
|
char *str_ptr;
|
||||||
|
|
||||||
while (c != NULL) {
|
while (c != NULL) {
|
||||||
if (ciprefix("*lib", c->li_line) || ciprefix("*inc", c->li_line)) {
|
if (ciprefix(".lib", c->li_line) || ciprefix("*lib", c->li_line) || ciprefix("*inc", c->li_line)) {
|
||||||
c = c->li_next;
|
c = c->li_next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -2398,7 +2262,7 @@ inp_remove_excess_ws(struct line *deck)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* recursively collect library section references,
|
* recursively expand library section references,
|
||||||
* either
|
* either
|
||||||
* every library section reference (when the given section_name_ === NULL)
|
* every library section reference (when the given section_name_ === NULL)
|
||||||
* or
|
* or
|
||||||
|
|
@ -2406,20 +2270,15 @@ inp_remove_excess_ws(struct line *deck)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
collect_section_references(struct line *deck, char *section_name_)
|
expand_section_references(struct line *deck, int call_depth, char *dir_name)
|
||||||
{
|
{
|
||||||
bool read_line = (section_name_ == NULL);
|
|
||||||
|
|
||||||
struct line *c;
|
struct line *c;
|
||||||
|
|
||||||
for (c = deck; c; c = c->li_next) {
|
for (c = deck; c; c = c->li_next) {
|
||||||
|
|
||||||
char *line = c->li_line;
|
char *line = c->li_line;
|
||||||
|
|
||||||
if (ciprefix(".endl", line) && section_name_ != NULL)
|
if (ciprefix(".lib", line)) {
|
||||||
read_line = FALSE;
|
|
||||||
|
|
||||||
if (ciprefix("*lib", line) || ciprefix(".lib", line)) {
|
|
||||||
|
|
||||||
char *s, *t, *y;
|
char *s, *t, *y;
|
||||||
|
|
||||||
|
|
@ -2432,19 +2291,10 @@ collect_section_references(struct line *deck, char *section_name_)
|
||||||
while (isspace(*y) || isquote(*y))
|
while (isspace(*y) || isquote(*y))
|
||||||
y++;
|
y++;
|
||||||
|
|
||||||
if (!*y) {
|
if (*y) {
|
||||||
/* library section definition: `.lib <section-name>' .. `.endl' */
|
|
||||||
|
|
||||||
char keep_char = *t;
|
|
||||||
*t = '\0';
|
|
||||||
|
|
||||||
if (section_name_ != NULL && strcmp(section_name_, s) == 0)
|
|
||||||
read_line = TRUE;
|
|
||||||
*t = keep_char;
|
|
||||||
}
|
|
||||||
else if (read_line == TRUE) {
|
|
||||||
/* library section reference: `.lib <library-file> <section-name>' */
|
/* library section reference: `.lib <library-file> <section-name>' */
|
||||||
|
|
||||||
|
struct line *section_def;
|
||||||
char keep_char1, keep_char2;
|
char keep_char1, keep_char2;
|
||||||
char *z, *copys = NULL;
|
char *z, *copys = NULL;
|
||||||
int lib_idx;
|
int lib_idx;
|
||||||
|
|
@ -2461,14 +2311,48 @@ collect_section_references(struct line *deck, char *section_name_)
|
||||||
if (copys)
|
if (copys)
|
||||||
s = copys;
|
s = copys;
|
||||||
}
|
}
|
||||||
|
|
||||||
lib_idx = find_lib(s);
|
lib_idx = find_lib(s);
|
||||||
if (lib_idx >= 0)
|
|
||||||
if (find_section(lib_idx, y) < 0) {
|
if (lib_idx < 0) {
|
||||||
/* remember this section having been referenced */
|
|
||||||
remember_section_ref(lib_idx, y, c);
|
if(!read_a_lib(s, call_depth, dir_name))
|
||||||
/* recursively check for nested section references */
|
controlled_exit(EXIT_FAILURE);
|
||||||
collect_section_references(library_deck[lib_idx], y);
|
|
||||||
|
lib_idx = find_lib(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lib_idx < 0) {
|
||||||
|
fprintf(stderr, "ERROR, library file %s not found\n", s);
|
||||||
|
controlled_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
section_def = find_section_definition(library_deck[lib_idx], y);
|
||||||
|
|
||||||
|
if (!section_def) {
|
||||||
|
fprintf(stderr, "ERROR, library file %s, section definition %s not found\n", s, y);
|
||||||
|
controlled_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* insert the library section definition into `c' */
|
||||||
|
{
|
||||||
|
struct line *t = inp_deckcopy(section_def);
|
||||||
|
struct line *rest = c->li_next;
|
||||||
|
c->li_next = t;
|
||||||
|
t->li_line[0] = '*';
|
||||||
|
t->li_line[1] = '<';
|
||||||
|
for (; t; t=t->li_next)
|
||||||
|
if(ciprefix(".endl", t->li_line))
|
||||||
|
break;
|
||||||
|
if (!t) {
|
||||||
|
fprintf(stderr, "ERROR, .endl not found\n");
|
||||||
|
controlled_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
t->li_line[0] = '*';
|
||||||
|
t->li_line[1] = '>';
|
||||||
|
t->li_next = rest;
|
||||||
|
}
|
||||||
|
|
||||||
*line = '*'; /* comment out .lib line */
|
*line = '*'; /* comment out .lib line */
|
||||||
*t = keep_char1;
|
*t = keep_char1;
|
||||||
*z = keep_char2;
|
*z = keep_char2;
|
||||||
|
|
@ -2480,16 +2364,6 @@ collect_section_references(struct line *deck, char *section_name_)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
inp_init_lib_data(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < num_libraries; i++)
|
|
||||||
num_sections[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
inp_get_subckt_name(char *s)
|
inp_get_subckt_name(char *s)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue