inpcom.c, rewrite .lib processing

This commit is contained in:
rlar 2013-05-18 09:47:06 +02:00
parent 54be463685
commit afeb7e4b59
1 changed files with 90 additions and 216 deletions

View File

@ -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)
{ {