2000-04-27 22:03:57 +02:00
|
|
|
/**********
|
|
|
|
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
|
|
|
|
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
|
2000-09-03 11:00:08 +02:00
|
|
|
Modified: 2000 AlansFixes
|
2000-04-27 22:03:57 +02:00
|
|
|
**********/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Routines to query and alter devices.
|
|
|
|
|
*/
|
|
|
|
|
|
2011-12-11 19:05:00 +01:00
|
|
|
#include "ngspice/ngspice.h"
|
|
|
|
|
#include "ngspice/gendefs.h"
|
|
|
|
|
#include "ngspice/cktdefs.h"
|
|
|
|
|
#include "ngspice/cpdefs.h"
|
|
|
|
|
#include "ngspice/ftedefs.h"
|
|
|
|
|
#include "ngspice/dgen.h"
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2000-06-27 18:09:02 +02:00
|
|
|
#include "circuits.h"
|
|
|
|
|
#include "device.h"
|
|
|
|
|
#include "variable.h"
|
2010-10-16 19:09:46 +02:00
|
|
|
#include "com_commands.h"
|
2011-09-18 11:03:55 +02:00
|
|
|
#include "../misc/util.h" /* ngdirname() */
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2004-08-16 11:10:40 +02:00
|
|
|
#include "gens.h" /* wl_forall */
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
static wordlist *devexpand(char *name);
|
|
|
|
|
static void all_show(wordlist *wl, int mode);
|
2007-10-09 23:27:25 +02:00
|
|
|
static void all_show_old(wordlist *wl, int mode);
|
2011-09-18 11:03:55 +02:00
|
|
|
static void com_alter_mod(wordlist *wl);
|
2012-08-05 12:11:16 +02:00
|
|
|
static void if_set_binned_model(CKTcircuit *, char *, char *, struct dvec *);
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2011-08-09 20:41:36 +02:00
|
|
|
/*
|
|
|
|
|
* devhelp: lists available devices and information on parameters
|
|
|
|
|
* devhelp : shows all available devices
|
|
|
|
|
* devhelp devname : shows all parameters of that model/instance
|
|
|
|
|
* devhelp devname parname : shows parameter meaning
|
|
|
|
|
* Options: -csv (comma separated value for generating docs)
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void com_devhelp(wordlist *wl)
|
|
|
|
|
{
|
|
|
|
|
/* Just a simple driver now */
|
|
|
|
|
devhelp(wl);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2011-08-09 20:41:36 +02:00
|
|
|
void devhelp(wordlist *wl)
|
|
|
|
|
{
|
|
|
|
|
int i, k = 0;
|
|
|
|
|
int devindex = -1, devInstParNo = 0 , devModParNo = 0;
|
|
|
|
|
bool found = FALSE;
|
|
|
|
|
bool csv = FALSE;
|
|
|
|
|
wordlist *wlist;
|
|
|
|
|
IFparm *plist;
|
|
|
|
|
|
|
|
|
|
/*First copy the base pointer */
|
|
|
|
|
wlist = wl;
|
|
|
|
|
|
|
|
|
|
/* If there are no arguments output the list of available devices */
|
|
|
|
|
if (!wlist) {
|
|
|
|
|
out_init();
|
|
|
|
|
out_printf("\nDevices available in the simulator\n\n");
|
2012-09-20 20:30:53 +02:00
|
|
|
for (k = 0; k < ft_sim->numDevices; k++)
|
2011-08-09 20:41:36 +02:00
|
|
|
if (ft_sim->devices[k])
|
|
|
|
|
out_printf("%-*s:\t%s\n",
|
|
|
|
|
DEV_WIDTH, ft_sim->devices[k]->name,
|
|
|
|
|
ft_sim->devices[k]->description);
|
|
|
|
|
out_send("\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The first argument must be the csv option or a device name */
|
|
|
|
|
if (wlist && wlist->wl_word && eq(wlist->wl_word, "-csv")) {
|
|
|
|
|
csv = TRUE;
|
|
|
|
|
if (wlist->wl_next)
|
|
|
|
|
wlist = wlist->wl_next;
|
|
|
|
|
else
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This argument, if exists, must be the device name */
|
|
|
|
|
if (wlist && wlist->wl_word) {
|
|
|
|
|
while (k < ft_sim->numDevices && !found) {
|
|
|
|
|
if (ft_sim->devices[k])
|
|
|
|
|
if (strcasecmp(ft_sim->devices[k]->name, wlist->wl_word) == 0) {
|
|
|
|
|
devindex = k;
|
|
|
|
|
if (ft_sim->devices[devindex]->numInstanceParms)
|
|
|
|
|
devInstParNo = *(ft_sim->devices[devindex]->numInstanceParms);
|
|
|
|
|
else
|
|
|
|
|
devInstParNo = 0;
|
|
|
|
|
|
|
|
|
|
if (ft_sim->devices[devindex]->numModelParms)
|
|
|
|
|
devModParNo = *(ft_sim->devices[devindex]->numModelParms);
|
|
|
|
|
else
|
|
|
|
|
devModParNo = 0;
|
|
|
|
|
|
|
|
|
|
wlist = wlist->wl_next;
|
|
|
|
|
found = TRUE;
|
|
|
|
|
}
|
|
|
|
|
k++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!found) {
|
|
|
|
|
fprintf(cp_out, "Error: Device %s not found\n", wlist->wl_word);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
/* At this point, found is TRUE and we have found the device.
|
|
|
|
|
* Now we have to scan the model and instance parameters to print
|
|
|
|
|
* the string
|
|
|
|
|
*/
|
2011-08-09 20:41:36 +02:00
|
|
|
found = FALSE;
|
|
|
|
|
if (wlist && wlist->wl_word) {
|
|
|
|
|
plist = ft_sim->devices[devindex]->modelParms;
|
|
|
|
|
for (i = 0; i < devModParNo; i++) { /* Scan model parameters first */
|
|
|
|
|
if (strcasecmp(plist[i].keyword, wlist->wl_word) == 0) {
|
|
|
|
|
found = TRUE;
|
|
|
|
|
out_init();
|
2011-08-14 09:28:44 +02:00
|
|
|
out_printf("Model Parameters\n");
|
|
|
|
|
if (csv)
|
|
|
|
|
out_printf("id#, Name, Dir, Description\n");
|
2012-09-20 20:30:53 +02:00
|
|
|
else
|
|
|
|
|
out_printf("%5s\t %-10s\t Dir\t Description\n", "id#", "Name");
|
2011-08-09 20:41:36 +02:00
|
|
|
printdesc(plist[i], csv);
|
|
|
|
|
out_send("\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!found) {
|
|
|
|
|
plist = ft_sim->devices[devindex]->instanceParms;
|
|
|
|
|
for (i = 0; i < devInstParNo; i++) { /* Scan instance parameters then */
|
|
|
|
|
if (strcasecmp(plist[i].keyword, wlist->wl_word) == 0) {
|
|
|
|
|
found = TRUE;
|
|
|
|
|
out_init();
|
2011-08-14 09:28:44 +02:00
|
|
|
out_printf("Instance Parameters\n");
|
|
|
|
|
if (csv)
|
|
|
|
|
out_printf("id#, Name, Dir, Description\n");
|
2012-09-20 20:30:53 +02:00
|
|
|
else
|
|
|
|
|
out_printf("%5s\t %-10s\t Dir\t Description\n", "id#", "Name");
|
2011-08-09 20:41:36 +02:00
|
|
|
printdesc(plist[i], csv);
|
|
|
|
|
out_send("\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!found)
|
|
|
|
|
fprintf(cp_out, "Error: Parameter %s not found\n", wlist->wl_word);
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
/* No arguments - we want all the parameters*/
|
2011-08-09 20:41:36 +02:00
|
|
|
out_init();
|
|
|
|
|
out_printf("%s - %s\n\n", ft_sim->devices[devindex]->name, ft_sim->devices[devindex]->description);
|
|
|
|
|
out_printf("Model Parameters\n");
|
|
|
|
|
if (csv)
|
|
|
|
|
out_printf("id#, Name, Dir, Description\n");
|
|
|
|
|
else
|
|
|
|
|
out_printf("%5s\t %-10s\t Dir\t Description\n", "id#", "Name");
|
|
|
|
|
|
|
|
|
|
plist = ft_sim->devices[devindex]->modelParms;
|
|
|
|
|
for (i = 0; i < devModParNo; i++)
|
|
|
|
|
printdesc(plist[i], csv);
|
|
|
|
|
out_printf("\n");
|
|
|
|
|
out_printf("Instance Parameters\n");
|
|
|
|
|
if (csv)
|
|
|
|
|
out_printf("id#, Name, Dir, Description\n");
|
|
|
|
|
else
|
|
|
|
|
out_printf("%5s\t %-10s\t Dir\t Description\n", "id#", "Name");
|
|
|
|
|
|
|
|
|
|
plist = ft_sim->devices[devindex]->instanceParms;
|
|
|
|
|
for (i = 0; i < devInstParNo; i++)
|
|
|
|
|
printdesc(plist[i], csv);
|
|
|
|
|
|
|
|
|
|
out_send("\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Pretty print parameter descriptions
|
|
|
|
|
* This function prints description of device parameters
|
|
|
|
|
*/
|
2012-09-20 20:30:53 +02:00
|
|
|
void
|
|
|
|
|
printdesc(IFparm p, bool csv)
|
2011-08-09 20:41:36 +02:00
|
|
|
{
|
|
|
|
|
char sep;
|
|
|
|
|
int spacer1, spacer2;
|
|
|
|
|
|
|
|
|
|
/* First we indentify the separator */
|
|
|
|
|
if (csv) {
|
|
|
|
|
sep = ',';
|
|
|
|
|
spacer1 = 0;
|
|
|
|
|
spacer2 = 0;
|
|
|
|
|
} else {
|
|
|
|
|
sep = '\t';
|
|
|
|
|
spacer1 = 5;
|
|
|
|
|
spacer2 = 10;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out_printf("%*d%c %-*s%c ", spacer1, p.id, sep, spacer2, p.keyword, sep);
|
|
|
|
|
|
|
|
|
|
if (p.dataType & IF_SET)
|
|
|
|
|
if (p.dataType & IF_ASK)
|
|
|
|
|
out_printf("inout%c ", sep);
|
|
|
|
|
else
|
|
|
|
|
out_printf("in%c ", sep);
|
|
|
|
|
else
|
|
|
|
|
out_printf("out%c ", sep);
|
|
|
|
|
|
|
|
|
|
if (p.description)
|
|
|
|
|
out_printf("%s\n", p.description);
|
|
|
|
|
else
|
|
|
|
|
out_printf("n.a.\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
/*
|
2009-02-08 15:52:16 +01:00
|
|
|
* show: list device operating point info
|
|
|
|
|
* show
|
|
|
|
|
* show devs : params
|
|
|
|
|
* show devs : params ; devs : params
|
|
|
|
|
* show dev dev dev : param param param , dev dev : param param
|
|
|
|
|
* show t : param param param, t : param param
|
2000-04-27 22:03:57 +02:00
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2009-02-08 15:52:16 +01:00
|
|
|
static int count;
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
com_showmod(wordlist *wl)
|
|
|
|
|
{
|
2010-07-20 20:41:25 +02:00
|
|
|
if (cp_getvar("altshow", CP_BOOL, NULL))
|
2007-10-09 23:27:25 +02:00
|
|
|
all_show(wl, 1);
|
2012-09-20 20:30:53 +02:00
|
|
|
else
|
2007-10-09 23:27:25 +02:00
|
|
|
all_show_old(wl, 1);
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
void
|
|
|
|
|
com_show(wordlist *wl)
|
|
|
|
|
{
|
2010-07-20 20:41:25 +02:00
|
|
|
if (cp_getvar("altshow", CP_BOOL, NULL))
|
2007-10-09 23:27:25 +02:00
|
|
|
all_show(wl, 0);
|
2012-09-20 20:30:53 +02:00
|
|
|
else
|
2007-10-09 23:27:25 +02:00
|
|
|
all_show_old(wl, 0);
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
static void
|
|
|
|
|
all_show(wordlist *wl, int mode)
|
|
|
|
|
{
|
2009-02-08 15:52:16 +01:00
|
|
|
wordlist *params, *nextgroup, *thisgroup;
|
|
|
|
|
wordlist *prev, *next, *w;
|
|
|
|
|
int screen_width;
|
2012-12-01 16:04:47 +01:00
|
|
|
dgen *dg;
|
2009-02-08 15:52:16 +01:00
|
|
|
int instances;
|
|
|
|
|
int i, j, n;
|
|
|
|
|
int param_flag, dev_flag;
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
if (!ft_curckt) {
|
|
|
|
|
fprintf(cp_err, "Error: no circuit loaded\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wl && wl->wl_word && eq(wl->wl_word, "-v")) {
|
2009-02-08 15:52:16 +01:00
|
|
|
old_show(wl->wl_next);
|
|
|
|
|
return;
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
2011-04-30 14:29:19 +02:00
|
|
|
if (!cp_getvar("width", CP_NUM, &screen_width))
|
2012-09-20 20:30:53 +02:00
|
|
|
screen_width = DEF_WIDTH;
|
2004-08-20 11:34:55 +02:00
|
|
|
count = (screen_width - LEFT_WIDTH) / (DEV_WIDTH + 1);
|
2007-10-08 17:55:34 +02:00
|
|
|
count = 1;
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
do {
|
2009-02-08 15:52:16 +01:00
|
|
|
prev = NULL;
|
|
|
|
|
params = NULL;
|
|
|
|
|
nextgroup = NULL;
|
|
|
|
|
thisgroup = wl;
|
|
|
|
|
param_flag = 0;
|
|
|
|
|
dev_flag = 0;
|
|
|
|
|
|
|
|
|
|
/* find the parameter list and the nextgroup */
|
|
|
|
|
for (w = wl; w && !nextgroup; w = next) {
|
|
|
|
|
next = w->wl_next;
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
if (eq(w->wl_word, "*")) {
|
|
|
|
|
tfree(w->wl_word);
|
|
|
|
|
w->wl_word = strdup("all");
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2009-02-08 15:52:16 +01:00
|
|
|
if (eq(w->wl_word, "++") || eq(w->wl_word, "all")) {
|
|
|
|
|
if (params) {
|
2012-09-20 20:30:53 +02:00
|
|
|
param_flag = DGEN_ALLPARAMS;
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->wl_next = w->wl_next;
|
|
|
|
|
else
|
|
|
|
|
params = next;
|
2009-02-08 15:52:16 +01:00
|
|
|
} else {
|
2012-09-20 20:30:53 +02:00
|
|
|
dev_flag = DGEN_ALLDEVS;
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->wl_next = w->wl_next;
|
|
|
|
|
else
|
|
|
|
|
thisgroup = next;
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
|
|
|
|
/* w must not be freed here */
|
|
|
|
|
w = NULL;
|
|
|
|
|
} else if (eq(w->wl_word, "+")) {
|
|
|
|
|
if (params) {
|
2012-09-20 20:30:53 +02:00
|
|
|
param_flag = DGEN_DEFPARAMS;
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->wl_next = w->wl_next;
|
|
|
|
|
else
|
|
|
|
|
params = next;
|
2009-02-08 15:52:16 +01:00
|
|
|
} else {
|
2012-09-20 20:30:53 +02:00
|
|
|
dev_flag = DGEN_DEFDEVS;
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->wl_next = w->wl_next;
|
|
|
|
|
else
|
|
|
|
|
thisgroup = next;
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
|
|
|
|
/* w must not be freed here */
|
|
|
|
|
w = NULL;
|
|
|
|
|
} else if (eq(w->wl_word, ":")) {
|
|
|
|
|
/* w must not be freed here */
|
|
|
|
|
w = NULL;
|
|
|
|
|
if (!params) {
|
|
|
|
|
params = next;
|
|
|
|
|
if (prev)
|
2012-09-20 20:30:53 +02:00
|
|
|
prev->wl_next = NULL;
|
2009-02-08 15:52:16 +01:00
|
|
|
else
|
2012-09-20 20:30:53 +02:00
|
|
|
thisgroup = NULL;
|
2009-02-08 15:52:16 +01:00
|
|
|
} else {
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->wl_next = next;
|
|
|
|
|
else
|
|
|
|
|
params = next;
|
|
|
|
|
}
|
|
|
|
|
} else if (eq(w->wl_word, ";") || eq(w->wl_word, ",")) {
|
2012-09-20 20:30:53 +02:00
|
|
|
nextgroup = next;
|
|
|
|
|
/* w must not be freed here */
|
|
|
|
|
w = NULL;
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->wl_next = NULL;
|
|
|
|
|
break;
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
|
|
|
|
prev = w;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
instances = 0;
|
|
|
|
|
for (dg = dgen_init(ft_curckt->ci_ckt, thisgroup, 1, dev_flag, mode);
|
2012-09-20 20:30:53 +02:00
|
|
|
dg; dgen_nth_next(&dg, count))
|
2009-02-08 15:52:16 +01:00
|
|
|
{
|
|
|
|
|
instances = 1;
|
|
|
|
|
if (dg->flags & DGEN_INSTANCE) {
|
|
|
|
|
instances = 2;
|
|
|
|
|
n += 1;
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "%s:\n", dg->instance->GENname);
|
|
|
|
|
fprintf(cp_out, " %-19s= %s\n", "model", dg->model->GENmodName);
|
2009-02-08 15:52:16 +01:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
if (param_flag)
|
2009-02-08 15:52:16 +01:00
|
|
|
param_forall(dg, param_flag);
|
2012-09-20 20:30:53 +02:00
|
|
|
else if (!params)
|
2009-02-08 15:52:16 +01:00
|
|
|
param_forall(dg, DGEN_DEFPARAMS);
|
2012-09-20 20:30:53 +02:00
|
|
|
|
|
|
|
|
if (params)
|
2009-02-08 15:52:16 +01:00
|
|
|
wl_forall(params, listparam, dg);
|
|
|
|
|
|
|
|
|
|
} else if (ft_sim->devices[dg->dev_type_no]->numModelParms) {
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " %s models (%s)\n",
|
2009-02-08 15:52:16 +01:00
|
|
|
ft_sim->devices[dg->dev_type_no]->name,
|
|
|
|
|
ft_sim->devices[dg->dev_type_no]->description);
|
|
|
|
|
n += 1;
|
|
|
|
|
i = 0;
|
|
|
|
|
do {
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "%*s", LEFT_WIDTH, "model");
|
|
|
|
|
j = dgen_for_n(dg, count, printstr_m, NULL, i);
|
|
|
|
|
i += 1;
|
|
|
|
|
fprintf(cp_out, "\n");
|
2009-02-08 15:52:16 +01:00
|
|
|
} while (j);
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "\n");
|
2009-02-08 15:52:16 +01:00
|
|
|
|
|
|
|
|
if (param_flag)
|
|
|
|
|
param_forall(dg, param_flag);
|
|
|
|
|
else if (!params)
|
|
|
|
|
param_forall(dg, DGEN_DEFPARAMS);
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2009-02-08 15:52:16 +01:00
|
|
|
if (params)
|
|
|
|
|
wl_forall(params, listparam, dg);
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "\n");
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wl = nextgroup;
|
2007-10-08 17:55:34 +02:00
|
|
|
|
|
|
|
|
} while (wl);
|
|
|
|
|
|
|
|
|
|
if (!n) {
|
2012-09-20 20:30:53 +02:00
|
|
|
if (instances == 0)
|
|
|
|
|
printf("No matching instances or models\n");
|
|
|
|
|
else if (instances == 1)
|
|
|
|
|
printf("No matching models\n");
|
|
|
|
|
else
|
|
|
|
|
printf("No matching elements\n");
|
2007-10-08 17:55:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2007-10-08 17:55:34 +02:00
|
|
|
static void
|
|
|
|
|
all_show_old(wordlist *wl, int mode)
|
|
|
|
|
{
|
2009-02-08 15:52:16 +01:00
|
|
|
wordlist *params, *nextgroup, *thisgroup;
|
|
|
|
|
wordlist *prev, *next, *w;
|
|
|
|
|
int screen_width;
|
2012-12-01 16:04:47 +01:00
|
|
|
dgen *dg;
|
2009-02-08 15:52:16 +01:00
|
|
|
int instances;
|
|
|
|
|
int i, j, n;
|
|
|
|
|
int param_flag, dev_flag;
|
2007-10-08 17:55:34 +02:00
|
|
|
|
|
|
|
|
if (!ft_curckt) {
|
|
|
|
|
fprintf(cp_err, "Error: no circuit loaded\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wl && wl->wl_word && eq(wl->wl_word, "-v")) {
|
2009-02-08 15:52:16 +01:00
|
|
|
old_show(wl->wl_next);
|
|
|
|
|
return;
|
2007-10-08 17:55:34 +02:00
|
|
|
}
|
|
|
|
|
|
2011-04-30 14:29:19 +02:00
|
|
|
if (!cp_getvar("width", CP_NUM, &screen_width))
|
2012-09-20 20:30:53 +02:00
|
|
|
screen_width = DEF_WIDTH;
|
2007-10-08 17:55:34 +02:00
|
|
|
count = (screen_width - LEFT_WIDTH) / (DEV_WIDTH + 1);
|
|
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
do {
|
2009-02-08 15:52:16 +01:00
|
|
|
prev = NULL;
|
|
|
|
|
params = NULL;
|
|
|
|
|
nextgroup = NULL;
|
|
|
|
|
thisgroup = wl;
|
|
|
|
|
param_flag = 0;
|
|
|
|
|
dev_flag = 0;
|
|
|
|
|
|
|
|
|
|
/* find the parameter list and the nextgroup */
|
|
|
|
|
for (w = wl; w && !nextgroup; w = next) {
|
|
|
|
|
next = w->wl_next;
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
if (eq(w->wl_word, "*")) {
|
|
|
|
|
tfree(w->wl_word);
|
|
|
|
|
w->wl_word = strdup("all");
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2009-02-08 15:52:16 +01:00
|
|
|
if (eq(w->wl_word, "++") || eq(w->wl_word, "all")) {
|
|
|
|
|
if (params) {
|
2012-09-20 20:30:53 +02:00
|
|
|
param_flag = DGEN_ALLPARAMS;
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->wl_next = w->wl_next;
|
|
|
|
|
else
|
|
|
|
|
params = next;
|
2009-02-08 15:52:16 +01:00
|
|
|
} else {
|
2012-09-20 20:30:53 +02:00
|
|
|
dev_flag = DGEN_ALLDEVS;
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->wl_next = w->wl_next;
|
|
|
|
|
else
|
|
|
|
|
thisgroup = next;
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
|
|
|
|
/* w must not be freed here */
|
|
|
|
|
w = NULL;
|
|
|
|
|
} else if (eq(w->wl_word, "+")) {
|
|
|
|
|
if (params) {
|
2012-09-20 20:30:53 +02:00
|
|
|
param_flag = DGEN_DEFPARAMS;
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->wl_next = w->wl_next;
|
|
|
|
|
else
|
|
|
|
|
params = next;
|
2009-02-08 15:52:16 +01:00
|
|
|
} else {
|
2012-09-20 20:30:53 +02:00
|
|
|
dev_flag = DGEN_DEFDEVS;
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->wl_next = w->wl_next;
|
|
|
|
|
else
|
|
|
|
|
thisgroup = next;
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
|
|
|
|
/* w must not be freed here */
|
|
|
|
|
w = NULL;
|
|
|
|
|
} else if (eq(w->wl_word, ":")) {
|
|
|
|
|
/* w must not be freed here */
|
|
|
|
|
w = NULL;
|
|
|
|
|
if (!params) {
|
|
|
|
|
params = next;
|
|
|
|
|
if (prev)
|
2012-09-20 20:30:53 +02:00
|
|
|
prev->wl_next = NULL;
|
2009-02-08 15:52:16 +01:00
|
|
|
else
|
2012-09-20 20:30:53 +02:00
|
|
|
thisgroup = NULL;
|
2009-02-08 15:52:16 +01:00
|
|
|
} else {
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->wl_next = next;
|
|
|
|
|
else
|
|
|
|
|
params = next;
|
|
|
|
|
}
|
|
|
|
|
} else if (eq(w->wl_word, ";") || eq(w->wl_word, ",")) {
|
2012-09-20 20:30:53 +02:00
|
|
|
nextgroup = next;
|
|
|
|
|
/* w must not be freed here */
|
|
|
|
|
w = NULL;
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->wl_next = NULL;
|
|
|
|
|
break;
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
|
|
|
|
prev = w;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
instances = 0;
|
|
|
|
|
for (dg = dgen_init(ft_curckt->ci_ckt, thisgroup, 1, dev_flag, mode);
|
2012-09-20 20:30:53 +02:00
|
|
|
dg; dgen_nth_next(&dg, count))
|
2009-02-08 15:52:16 +01:00
|
|
|
{
|
|
|
|
|
instances = 1;
|
|
|
|
|
if (dg->flags & DGEN_INSTANCE) {
|
|
|
|
|
instances = 2;
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " %s: %s\n",
|
2009-02-08 15:52:16 +01:00
|
|
|
ft_sim->devices[dg->dev_type_no]->name,
|
|
|
|
|
ft_sim->devices[dg->dev_type_no]->description);
|
|
|
|
|
n += 1;
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
do {
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "%*s", LEFT_WIDTH, "device");
|
|
|
|
|
j = dgen_for_n(dg, count, printstr_n, NULL, i);
|
|
|
|
|
i += 1;
|
|
|
|
|
fprintf(cp_out, "\n");
|
2009-02-08 15:52:16 +01:00
|
|
|
} while (j);
|
|
|
|
|
|
|
|
|
|
if (ft_sim->devices[dg->dev_type_no]->numModelParms) {
|
2012-09-20 20:30:53 +02:00
|
|
|
i = 0;
|
|
|
|
|
do {
|
|
|
|
|
fprintf(cp_out, "%*s", LEFT_WIDTH, "model");
|
|
|
|
|
j = dgen_for_n(dg, count, printstr_m, NULL, i);
|
|
|
|
|
i += 1;
|
|
|
|
|
fprintf(cp_out, "\n");
|
|
|
|
|
} while (j);
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (param_flag)
|
|
|
|
|
param_forall_old(dg, param_flag);
|
|
|
|
|
else if (!params)
|
|
|
|
|
param_forall_old(dg, DGEN_DEFPARAMS);
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2009-02-08 15:52:16 +01:00
|
|
|
if (params)
|
|
|
|
|
wl_forall(params, listparam, dg);
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "\n");
|
2009-02-08 15:52:16 +01:00
|
|
|
|
|
|
|
|
} else if (ft_sim->devices[dg->dev_type_no]->numModelParms) {
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " %s models (%s)\n",
|
2009-02-08 15:52:16 +01:00
|
|
|
ft_sim->devices[dg->dev_type_no]->name,
|
|
|
|
|
ft_sim->devices[dg->dev_type_no]->description);
|
|
|
|
|
n += 1;
|
|
|
|
|
i = 0;
|
|
|
|
|
do {
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "%*s", LEFT_WIDTH, "model");
|
|
|
|
|
j = dgen_for_n(dg, count, printstr_m, NULL, i);
|
|
|
|
|
i += 1;
|
|
|
|
|
fprintf(cp_out, "\n");
|
2009-02-08 15:52:16 +01:00
|
|
|
} while (j);
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "\n");
|
2009-02-08 15:52:16 +01:00
|
|
|
|
|
|
|
|
if (param_flag)
|
|
|
|
|
param_forall_old(dg, param_flag);
|
|
|
|
|
else if (!params)
|
|
|
|
|
param_forall_old(dg, DGEN_DEFPARAMS);
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2009-02-08 15:52:16 +01:00
|
|
|
if (params)
|
|
|
|
|
wl_forall(params, listparam, dg);
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "\n");
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wl = nextgroup;
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
} while (wl);
|
|
|
|
|
|
|
|
|
|
if (!n) {
|
2012-09-20 20:30:53 +02:00
|
|
|
if (instances == 0)
|
|
|
|
|
printf("No matching instances or models\n");
|
|
|
|
|
else if (instances == 1)
|
|
|
|
|
printf("No matching models\n");
|
|
|
|
|
else
|
|
|
|
|
printf("No matching elements\n");
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
int
|
2010-07-13 20:20:37 +02:00
|
|
|
printstr_n(dgen *dg, IFparm *p, int i)
|
2000-04-27 22:03:57 +02:00
|
|
|
{
|
2010-11-16 21:38:24 +01:00
|
|
|
NG_IGNORE(p);
|
|
|
|
|
NG_IGNORE(i);
|
2010-11-16 20:11:32 +01:00
|
|
|
|
2010-07-13 20:17:06 +02:00
|
|
|
if (dg->instance)
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " %*.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname);
|
2010-07-13 20:17:06 +02:00
|
|
|
else
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " %*s", DEV_WIDTH, "<\?\?\?\?\?\?\?>");
|
2010-07-13 20:17:06 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2010-07-13 20:17:06 +02:00
|
|
|
int
|
2010-07-13 20:20:37 +02:00
|
|
|
printstr_m(dgen *dg, IFparm *p, int i)
|
2010-07-13 20:17:06 +02:00
|
|
|
{
|
2010-11-16 21:38:24 +01:00
|
|
|
NG_IGNORE(p);
|
|
|
|
|
NG_IGNORE(i);
|
2010-11-16 20:11:32 +01:00
|
|
|
|
2010-07-13 20:17:06 +02:00
|
|
|
if (dg->model)
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " %*.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName);
|
2010-07-13 20:17:06 +02:00
|
|
|
else
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " %*s", DEV_WIDTH, "<\?\?\?\?\?\?\?>");
|
2000-04-27 22:03:57 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2004-08-20 11:34:55 +02:00
|
|
|
void
|
2000-04-27 22:03:57 +02:00
|
|
|
param_forall(dgen *dg, int flags)
|
|
|
|
|
{
|
2012-12-01 16:04:47 +01:00
|
|
|
int i, j, k;
|
2000-04-27 22:03:57 +02:00
|
|
|
int xcount;
|
|
|
|
|
IFparm *plist;
|
|
|
|
|
|
|
|
|
|
if (dg->flags & DGEN_INSTANCE) {
|
2009-02-08 15:52:16 +01:00
|
|
|
xcount = *ft_sim->devices[dg->dev_type_no]->numInstanceParms;
|
|
|
|
|
plist = ft_sim->devices[dg->dev_type_no]->instanceParms;
|
2000-04-27 22:03:57 +02:00
|
|
|
} else {
|
2009-02-08 15:52:16 +01:00
|
|
|
xcount = *ft_sim->devices[dg->dev_type_no]->numModelParms;
|
|
|
|
|
plist = ft_sim->devices[dg->dev_type_no]->modelParms;
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
for (i = 0; i < xcount; i++)
|
|
|
|
|
if (plist[i].dataType & IF_ASK)
|
|
|
|
|
if ((((CKTcircuit *) (dg->ckt))->CKTrhsOld ||
|
|
|
|
|
(plist[i].dataType & IF_SET)) &&
|
|
|
|
|
(!(plist[i].dataType & (IF_REDUNDANT | IF_UNINTERESTING)) ||
|
|
|
|
|
(flags == DGEN_ALLPARAMS && !(plist[i].dataType & IF_REDUNDANT))))
|
2009-02-08 15:52:16 +01:00
|
|
|
{
|
|
|
|
|
j = 0;
|
|
|
|
|
do {
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " %-19s=", plist[i].keyword);
|
2009-02-08 15:52:16 +01:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
k = dgen_for_n(dg, count, printvals, (plist + i), j);
|
|
|
|
|
fprintf(cp_out, "\n");
|
|
|
|
|
j += 1;
|
2009-02-08 15:52:16 +01:00
|
|
|
|
|
|
|
|
} while (k);
|
|
|
|
|
}
|
2007-10-08 17:55:34 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2007-10-08 17:55:34 +02:00
|
|
|
void
|
|
|
|
|
param_forall_old(dgen *dg, int flags)
|
|
|
|
|
{
|
2012-12-01 16:04:47 +01:00
|
|
|
int i, j, k;
|
2007-10-08 17:55:34 +02:00
|
|
|
int xcount;
|
|
|
|
|
IFparm *plist;
|
|
|
|
|
|
|
|
|
|
if (dg->flags & DGEN_INSTANCE) {
|
2009-02-08 15:52:16 +01:00
|
|
|
xcount = *ft_sim->devices[dg->dev_type_no]->numInstanceParms;
|
|
|
|
|
plist = ft_sim->devices[dg->dev_type_no]->instanceParms;
|
2007-10-08 17:55:34 +02:00
|
|
|
} else {
|
2009-02-08 15:52:16 +01:00
|
|
|
xcount = *ft_sim->devices[dg->dev_type_no]->numModelParms;
|
|
|
|
|
plist = ft_sim->devices[dg->dev_type_no]->modelParms;
|
2007-10-08 17:55:34 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
for (i = 0; i < xcount; i++)
|
|
|
|
|
if (plist[i].dataType & IF_ASK)
|
|
|
|
|
if ((((CKTcircuit *) (dg->ckt))->CKTrhsOld ||
|
|
|
|
|
(plist[i].dataType & IF_SET)) &&
|
|
|
|
|
(!(plist[i].dataType & (IF_REDUNDANT | IF_UNINTERESTING)) ||
|
|
|
|
|
(flags == DGEN_ALLPARAMS && !(plist[i].dataType & IF_REDUNDANT))))
|
2009-02-08 15:52:16 +01:00
|
|
|
{
|
|
|
|
|
j = 0;
|
|
|
|
|
do {
|
2012-09-20 20:30:53 +02:00
|
|
|
if (!j)
|
|
|
|
|
fprintf(cp_out, "%*.*s", LEFT_WIDTH, LEFT_WIDTH,
|
|
|
|
|
plist[i].keyword);
|
|
|
|
|
else
|
|
|
|
|
fprintf(cp_out, "%*.*s", LEFT_WIDTH, LEFT_WIDTH, " ");
|
|
|
|
|
k = dgen_for_n(dg, count, printvals_old, (plist + i), j);
|
|
|
|
|
fprintf(cp_out, "\n");
|
|
|
|
|
j += 1;
|
2009-02-08 15:52:16 +01:00
|
|
|
} while (k);
|
|
|
|
|
}
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2004-08-20 11:34:55 +02:00
|
|
|
void
|
2000-04-27 22:03:57 +02:00
|
|
|
listparam(wordlist *p, dgen *dg)
|
|
|
|
|
{
|
2009-02-08 15:52:16 +01:00
|
|
|
int i, j, k, found;
|
|
|
|
|
int xcount;
|
2000-04-27 22:03:57 +02:00
|
|
|
IFparm *plist;
|
|
|
|
|
|
|
|
|
|
found = 0;
|
|
|
|
|
|
|
|
|
|
if (dg->flags & DGEN_INSTANCE) {
|
2009-02-08 15:52:16 +01:00
|
|
|
xcount = *ft_sim->devices[dg->dev_type_no]->numInstanceParms;
|
|
|
|
|
plist = ft_sim->devices[dg->dev_type_no]->instanceParms;
|
2000-04-27 22:03:57 +02:00
|
|
|
} else {
|
2009-02-08 15:52:16 +01:00
|
|
|
xcount = *ft_sim->devices[dg->dev_type_no]->numModelParms;
|
|
|
|
|
plist = ft_sim->devices[dg->dev_type_no]->modelParms;
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
for (i = 0; i < xcount; i++)
|
|
|
|
|
if (eqc(p->wl_word, plist[i].keyword) && (plist[i].dataType & IF_ASK)) {
|
2009-02-08 15:52:16 +01:00
|
|
|
found = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
if (found) {
|
2012-09-20 20:30:53 +02:00
|
|
|
if ((((CKTcircuit *) (dg->ckt))->CKTrhsOld ||
|
|
|
|
|
(plist[i].dataType & IF_SET)))
|
2009-02-08 15:52:16 +01:00
|
|
|
{
|
|
|
|
|
j = 0;
|
|
|
|
|
do {
|
|
|
|
|
if (!j)
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
|
2009-02-08 15:52:16 +01:00
|
|
|
else
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "%*.*s", LEFT_WIDTH, LEFT_WIDTH, " ");
|
2009-02-08 15:52:16 +01:00
|
|
|
k = dgen_for_n(dg, count, printvals_old, (plist + i), j);
|
|
|
|
|
printf("\n");
|
|
|
|
|
j += 1;
|
|
|
|
|
} while (k > 0);
|
|
|
|
|
} else {
|
|
|
|
|
j = 0;
|
|
|
|
|
do {
|
|
|
|
|
if (!j)
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
|
2009-02-08 15:52:16 +01:00
|
|
|
else
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "%*s", LEFT_WIDTH, " ");
|
2009-02-08 15:52:16 +01:00
|
|
|
k = dgen_for_n(dg, count, bogus1, 0, j);
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "\n");
|
2009-02-08 15:52:16 +01:00
|
|
|
j += 1;
|
|
|
|
|
} while (k > 0);
|
|
|
|
|
}
|
2000-04-27 22:03:57 +02:00
|
|
|
} else {
|
2009-02-08 15:52:16 +01:00
|
|
|
j = 0;
|
|
|
|
|
do {
|
|
|
|
|
if (!j)
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
|
2009-02-08 15:52:16 +01:00
|
|
|
else
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "%*s", LEFT_WIDTH, " ");
|
2009-02-08 15:52:16 +01:00
|
|
|
k = dgen_for_n(dg, count, bogus2, 0, j);
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, "\n");
|
2009-02-08 15:52:16 +01:00
|
|
|
j += 1;
|
|
|
|
|
} while (k > 0);
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
|
|
|
|
int
|
|
|
|
|
bogus1(dgen *dg, IFparm *p, int i)
|
2000-04-27 22:03:57 +02:00
|
|
|
{
|
2010-11-16 21:38:24 +01:00
|
|
|
NG_IGNORE(dg);
|
|
|
|
|
NG_IGNORE(p);
|
|
|
|
|
NG_IGNORE(i);
|
2010-11-16 20:11:32 +01:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " %*s", DEV_WIDTH, "---------");
|
2000-04-27 22:03:57 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
|
|
|
|
int
|
|
|
|
|
bogus2(dgen *dg, IFparm *p, int i)
|
2000-04-27 22:03:57 +02:00
|
|
|
{
|
2010-11-16 21:38:24 +01:00
|
|
|
NG_IGNORE(dg);
|
|
|
|
|
NG_IGNORE(p);
|
|
|
|
|
NG_IGNORE(i);
|
2010-11-16 20:11:32 +01:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " %*s", DEV_WIDTH, "?????????");
|
2000-04-27 22:03:57 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
int
|
|
|
|
|
printvals(dgen *dg, IFparm *p, int i)
|
|
|
|
|
{
|
2009-02-08 15:52:16 +01:00
|
|
|
IFvalue val;
|
|
|
|
|
int n;
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
if (dg->flags & DGEN_INSTANCE)
|
2012-09-20 20:30:53 +02:00
|
|
|
ft_sim->askInstanceQuest
|
|
|
|
|
(ft_curckt->ci_ckt, dg->instance, p->id, &val, &val);
|
2000-04-27 22:03:57 +02:00
|
|
|
else
|
2012-09-20 20:30:53 +02:00
|
|
|
ft_sim->askModelQuest
|
|
|
|
|
(ft_curckt->ci_ckt, dg->model, p->id, &val, &val);
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
if (p->dataType & IF_VECTOR)
|
2009-02-08 15:52:16 +01:00
|
|
|
n = val.v.numValue;
|
2000-04-27 22:03:57 +02:00
|
|
|
else
|
2009-02-08 15:52:16 +01:00
|
|
|
n = 1;
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
if (((p->dataType & IF_VARTYPES) & ~IF_VECTOR) == IF_COMPLEX)
|
2009-02-08 15:52:16 +01:00
|
|
|
n *= 2;
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
if (i >= n) {
|
2009-02-08 15:52:16 +01:00
|
|
|
if (i == 0)
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " -");
|
2009-02-08 15:52:16 +01:00
|
|
|
else
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " ");
|
2009-02-08 15:52:16 +01:00
|
|
|
return 0;
|
2007-10-08 17:55:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (p->dataType & IF_VECTOR) {
|
|
|
|
|
/* va: ' ' is no flag for %s */
|
2009-02-08 15:52:16 +01:00
|
|
|
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
|
2012-09-20 20:30:53 +02:00
|
|
|
case IF_FLAG:
|
|
|
|
|
fprintf(cp_out, " %d", val.v.vec.iVec[i]);
|
|
|
|
|
break;
|
|
|
|
|
case IF_INTEGER:
|
|
|
|
|
fprintf(cp_out, " %d", val.v.vec.iVec[i]);
|
|
|
|
|
break;
|
|
|
|
|
case IF_REAL:
|
|
|
|
|
fprintf(cp_out, " %.6g", val.v.vec.rVec[i]);
|
|
|
|
|
break;
|
|
|
|
|
case IF_COMPLEX:
|
|
|
|
|
if (!(i % 2))
|
|
|
|
|
fprintf(cp_out, " %.6g", val.v.vec.cVec[i / 2].real);
|
|
|
|
|
else
|
|
|
|
|
fprintf(cp_out, " %.6g", val.v.vec.cVec[i / 2].imag);
|
|
|
|
|
break;
|
|
|
|
|
case IF_STRING:
|
|
|
|
|
fprintf(cp_out, " %s", val.v.vec.sVec[i]);
|
|
|
|
|
break;
|
|
|
|
|
case IF_INSTANCE:
|
|
|
|
|
fprintf(cp_out, " %s", val.v.vec.uVec[i]);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
fprintf(cp_out, " %s", " ******** ");
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
2007-10-08 17:55:34 +02:00
|
|
|
} else {
|
2009-02-08 15:52:16 +01:00
|
|
|
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
|
2012-09-20 20:30:53 +02:00
|
|
|
case IF_FLAG:
|
|
|
|
|
fprintf(cp_out, " %d", val.iValue);
|
|
|
|
|
break;
|
|
|
|
|
case IF_INTEGER:
|
|
|
|
|
fprintf(cp_out, " %d", val.iValue);
|
|
|
|
|
break;
|
|
|
|
|
case IF_REAL:
|
|
|
|
|
fprintf(cp_out, " %.6g", val.rValue);
|
|
|
|
|
break;
|
|
|
|
|
case IF_COMPLEX:
|
|
|
|
|
if (i % 2)
|
|
|
|
|
fprintf(cp_out, " %.6g", val.cValue.real);
|
|
|
|
|
else
|
|
|
|
|
fprintf(cp_out, " %.6g", val.cValue.imag);
|
|
|
|
|
break;
|
|
|
|
|
case IF_STRING:
|
|
|
|
|
fprintf(cp_out, " %s", val.sValue);
|
|
|
|
|
break;
|
|
|
|
|
case IF_INSTANCE:
|
|
|
|
|
fprintf(cp_out, " %s", val.uValue);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
fprintf(cp_out, " %s", " ******** ");
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
2007-10-08 17:55:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return n - 1;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2007-10-08 17:55:34 +02:00
|
|
|
int
|
|
|
|
|
printvals_old(dgen *dg, IFparm *p, int i)
|
|
|
|
|
{
|
2009-02-08 15:52:16 +01:00
|
|
|
IFvalue val;
|
2010-05-30 19:17:50 +02:00
|
|
|
int n, error;
|
2007-10-08 17:55:34 +02:00
|
|
|
|
|
|
|
|
if (dg->flags & DGEN_INSTANCE)
|
2012-09-20 20:30:53 +02:00
|
|
|
error = ft_sim->askInstanceQuest
|
|
|
|
|
(ft_curckt->ci_ckt, dg->instance, p->id, &val, &val);
|
2007-10-08 17:55:34 +02:00
|
|
|
else
|
2012-09-20 20:30:53 +02:00
|
|
|
error = ft_sim->askModelQuest
|
|
|
|
|
(ft_curckt->ci_ckt, dg->model, p->id, &val, &val);
|
2007-10-08 17:55:34 +02:00
|
|
|
|
|
|
|
|
if (p->dataType & IF_VECTOR)
|
2009-02-08 15:52:16 +01:00
|
|
|
n = val.v.numValue;
|
2007-10-08 17:55:34 +02:00
|
|
|
else
|
2009-02-08 15:52:16 +01:00
|
|
|
n = 1;
|
2007-10-08 17:55:34 +02:00
|
|
|
|
|
|
|
|
if (((p->dataType & IF_VARTYPES) & ~IF_VECTOR) == IF_COMPLEX)
|
2009-02-08 15:52:16 +01:00
|
|
|
n *= 2;
|
2007-10-08 17:55:34 +02:00
|
|
|
|
|
|
|
|
if (i >= n) {
|
2009-02-08 15:52:16 +01:00
|
|
|
if (i == 0)
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " -");
|
2009-02-08 15:52:16 +01:00
|
|
|
else
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_out, " ");
|
2009-02-08 15:52:16 +01:00
|
|
|
return 0;
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
if (error) {
|
|
|
|
|
fprintf(cp_out, " <<NAN, error = %d>>", error);
|
|
|
|
|
} else if (p->dataType & IF_VECTOR) {
|
2003-07-23 21:36:39 +02:00
|
|
|
/* va: ' ' is no flag for %s */
|
2009-02-08 15:52:16 +01:00
|
|
|
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
|
2012-09-20 20:30:53 +02:00
|
|
|
case IF_FLAG:
|
|
|
|
|
fprintf(cp_out, " % *d", DEV_WIDTH, val.v.vec.iVec[i]);
|
|
|
|
|
break;
|
|
|
|
|
case IF_INTEGER:
|
|
|
|
|
fprintf(cp_out, " % *d", DEV_WIDTH, val.v.vec.iVec[i]);
|
|
|
|
|
break;
|
|
|
|
|
case IF_REAL:
|
|
|
|
|
fprintf(cp_out, " % *.6g", DEV_WIDTH, val.v.vec.rVec[i]);
|
|
|
|
|
break;
|
|
|
|
|
case IF_COMPLEX:
|
|
|
|
|
if (!(i % 2))
|
|
|
|
|
fprintf(cp_out, " % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].real);
|
|
|
|
|
else
|
|
|
|
|
fprintf(cp_out, " % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].imag);
|
|
|
|
|
break;
|
|
|
|
|
case IF_STRING:
|
|
|
|
|
fprintf(cp_out, " %*.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.sVec[i]);
|
|
|
|
|
break;
|
|
|
|
|
case IF_INSTANCE:
|
|
|
|
|
fprintf(cp_out, " %*.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.uVec[i]);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
fprintf(cp_out, " %*.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
2000-04-27 22:03:57 +02:00
|
|
|
} else {
|
2009-02-08 15:52:16 +01:00
|
|
|
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
|
2012-09-20 20:30:53 +02:00
|
|
|
case IF_FLAG:
|
|
|
|
|
fprintf(cp_out, " % *d", DEV_WIDTH, val.iValue);
|
|
|
|
|
break;
|
|
|
|
|
case IF_INTEGER:
|
|
|
|
|
fprintf(cp_out, " % *d", DEV_WIDTH, val.iValue);
|
|
|
|
|
break;
|
|
|
|
|
case IF_REAL:
|
|
|
|
|
fprintf(cp_out, " % *.6g", DEV_WIDTH, val.rValue);
|
|
|
|
|
break;
|
|
|
|
|
case IF_COMPLEX:
|
|
|
|
|
if (i % 2)
|
|
|
|
|
fprintf(cp_out, " % *.6g", DEV_WIDTH, val.cValue.real);
|
|
|
|
|
else
|
|
|
|
|
fprintf(cp_out, " % *.6g", DEV_WIDTH, val.cValue.imag);
|
|
|
|
|
break;
|
|
|
|
|
case IF_STRING:
|
|
|
|
|
fprintf(cp_out, " %*.*s", DEV_WIDTH, DEV_WIDTH, val.sValue);
|
|
|
|
|
break;
|
|
|
|
|
case IF_INSTANCE:
|
|
|
|
|
fprintf(cp_out, " %*.*s", DEV_WIDTH, DEV_WIDTH, val.uValue);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
fprintf(cp_out, " %*.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return n - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* (old "show" command)
|
2004-08-20 11:34:55 +02:00
|
|
|
* Display various device parameters. The syntax of this command is
|
2000-04-27 22:03:57 +02:00
|
|
|
* show devicelist : parmlist
|
|
|
|
|
* where devicelist can be "all", the name of a device, a string like r*,
|
|
|
|
|
* which means all devices with names that begin with 'r', repeated one
|
|
|
|
|
* or more times. The parms are names of parameters that are (hopefully)
|
|
|
|
|
* valid for all the named devices, or "all".
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
old_show(wordlist *wl)
|
|
|
|
|
{
|
|
|
|
|
wordlist *devs, *parms, *tw, *ww;
|
|
|
|
|
struct variable *v;
|
|
|
|
|
char *nn;
|
|
|
|
|
|
|
|
|
|
devs = wl;
|
2012-08-03 20:48:11 +02:00
|
|
|
wl = wl_find(":", wl);
|
2012-09-20 20:30:53 +02:00
|
|
|
if (!wl) {
|
2000-04-27 22:03:57 +02:00
|
|
|
parms = NULL;
|
2012-09-20 20:30:53 +02:00
|
|
|
} else {
|
2000-04-27 22:03:57 +02:00
|
|
|
if (wl->wl_prev)
|
|
|
|
|
wl->wl_prev->wl_next = NULL;
|
|
|
|
|
parms = wl->wl_next;
|
|
|
|
|
if (parms)
|
|
|
|
|
parms->wl_prev = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now expand the devicelist... */
|
|
|
|
|
for (tw = NULL; devs; devs = devs->wl_next) {
|
|
|
|
|
inp_casefix(devs->wl_word);
|
|
|
|
|
tw = wl_append(tw, devexpand(devs->wl_word));
|
|
|
|
|
}
|
2004-08-20 11:34:55 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
devs = tw;
|
2012-07-28 12:28:25 +02:00
|
|
|
tw = wl_find("all", parms);
|
2000-04-27 22:03:57 +02:00
|
|
|
if (tw)
|
|
|
|
|
parms = NULL;
|
|
|
|
|
|
|
|
|
|
/* This is a crock... */
|
|
|
|
|
if (!devs)
|
|
|
|
|
devs = cp_cctowl(ft_curckt->ci_devices);
|
|
|
|
|
|
|
|
|
|
out_init();
|
|
|
|
|
|
|
|
|
|
while (devs) {
|
|
|
|
|
out_printf("%s:\n", devs->wl_word);
|
|
|
|
|
if (parms) {
|
|
|
|
|
for (tw = parms; tw; tw = tw->wl_next) {
|
|
|
|
|
nn = copy(devs->wl_word);
|
2012-09-20 20:30:53 +02:00
|
|
|
v = if_getparam(ft_curckt->ci_ckt, &nn, tw->wl_word, 0, 0);
|
2009-02-08 15:52:16 +01:00
|
|
|
if (!v)
|
2012-09-20 20:30:53 +02:00
|
|
|
v = if_getparam(ft_curckt->ci_ckt, &nn, tw->wl_word, 0, 1);
|
2000-04-27 22:03:57 +02:00
|
|
|
if (v) {
|
|
|
|
|
out_printf("\t%s =", tw->wl_word);
|
2012-09-20 20:30:53 +02:00
|
|
|
for (ww = cp_varwl(v); ww; ww = ww->wl_next)
|
2000-04-27 22:03:57 +02:00
|
|
|
out_printf(" %s", ww->wl_word);
|
|
|
|
|
out_send("\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
nn = copy(devs->wl_word);
|
2012-09-20 20:30:53 +02:00
|
|
|
v = if_getparam(ft_curckt->ci_ckt, &nn, "all", 0, 0);
|
2009-02-08 15:52:16 +01:00
|
|
|
if (!v)
|
2012-09-20 20:30:53 +02:00
|
|
|
v = if_getparam(ft_curckt->ci_ckt, &nn, "all", 0, 1);
|
2000-04-27 22:03:57 +02:00
|
|
|
while (v) {
|
|
|
|
|
out_printf("\t%s =", v->va_name);
|
|
|
|
|
for (ww = cp_varwl(v); ww; ww = ww->wl_next)
|
|
|
|
|
out_printf(" %s", ww->wl_word);
|
|
|
|
|
out_send("\n");
|
|
|
|
|
v = v->va_next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
devs = devs->wl_next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
/* Alter a device parameter. The new syntax here is
|
2009-02-08 15:52:16 +01:00
|
|
|
* alter @device[parameter] = expr
|
|
|
|
|
* alter device = expr
|
|
|
|
|
* alter device parameter = expr
|
2000-04-27 22:03:57 +02:00
|
|
|
* expr must be real (complex isn't handled right now, integer is fine though,
|
|
|
|
|
* but no strings ... for booleans, use 0/1).
|
|
|
|
|
*/
|
|
|
|
|
|
2010-10-16 19:09:46 +02:00
|
|
|
static void com_alter_common(wordlist *wl, int do_model);
|
|
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
void
|
|
|
|
|
com_alter(wordlist *wl)
|
|
|
|
|
{
|
|
|
|
|
if (!wl) {
|
2009-02-08 15:52:16 +01:00
|
|
|
fprintf(cp_err, "usage: alter dev param = expression\n");
|
|
|
|
|
fprintf(cp_err, " or alter @dev[param] = expression\n");
|
|
|
|
|
fprintf(cp_err, " or alter dev = expression\n");
|
|
|
|
|
return;
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
com_alter_common(wl, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
void
|
|
|
|
|
com_altermod(wordlist *wl)
|
|
|
|
|
{
|
2011-09-18 11:03:55 +02:00
|
|
|
wordlist *fileword;
|
|
|
|
|
bool newfile = FALSE;
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2011-09-18 11:03:55 +02:00
|
|
|
fileword = wl;
|
2012-09-20 20:30:53 +02:00
|
|
|
while (fileword) {
|
|
|
|
|
if (ciprefix("file", fileword->wl_word))
|
2011-09-18 11:03:55 +02:00
|
|
|
newfile = TRUE;
|
|
|
|
|
fileword = fileword->wl_next;
|
|
|
|
|
}
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2011-09-18 11:03:55 +02:00
|
|
|
if (newfile)
|
|
|
|
|
com_alter_mod(wl);
|
|
|
|
|
else
|
|
|
|
|
com_alter_common(wl, 1);
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2012-08-05 12:11:16 +02:00
|
|
|
static void
|
|
|
|
|
if_set_binned_model(CKTcircuit *ckt, char *devname, char *param, struct dvec *val)
|
|
|
|
|
{
|
2012-09-20 20:30:53 +02:00
|
|
|
char *width_length;
|
|
|
|
|
double w = 0.0, l = 0.0;
|
|
|
|
|
struct variable *v;
|
2012-08-05 12:11:16 +02:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
v = if_getparam(ckt, &devname, "w", 0, 0);
|
|
|
|
|
if (!v) {
|
|
|
|
|
fprintf(cp_err, "Error: Can't access width instance parameter.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
w = v->va_V.vV_real;
|
2012-08-05 12:11:16 +02:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
v = if_getparam(ckt, &devname, "l", 0, 0);
|
|
|
|
|
if (!v) {
|
|
|
|
|
fprintf(cp_err, "Error: Can't access length instance parameter.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
l = v->va_V.vV_real;
|
2012-08-05 12:11:16 +02:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
if (param[0] == 'w')
|
|
|
|
|
w = *val->v_realdata; /* overwrite the width with the alter param */
|
|
|
|
|
else
|
|
|
|
|
l = *val->v_realdata; /* overwrite the length with the alter param */
|
2012-08-05 12:11:16 +02:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
width_length = TMALLOC(char, 36);
|
|
|
|
|
(void) sprintf(width_length, "w=%15.7e l=%15.7e", w, l);
|
2012-08-05 12:11:16 +02:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
if_setparam_model(ft_curckt->ci_ckt, &devname, width_length);
|
|
|
|
|
FREE(width_length);
|
2012-08-05 12:11:16 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2010-10-16 19:09:46 +02:00
|
|
|
static void
|
2000-04-27 22:03:57 +02:00
|
|
|
com_alter_common(wordlist *wl, int do_model)
|
|
|
|
|
{
|
2009-10-04 13:48:37 +02:00
|
|
|
wordlist *eqword = NULL, *words;
|
2000-04-27 22:03:57 +02:00
|
|
|
char *dev, *p;
|
|
|
|
|
char *param;
|
|
|
|
|
struct dvec *dv;
|
|
|
|
|
struct pnode *names;
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2009-02-08 15:52:16 +01:00
|
|
|
/* DIE 2009_02_06 */
|
|
|
|
|
char *argument;
|
|
|
|
|
char **arglist;
|
2012-09-20 20:30:53 +02:00
|
|
|
int i = 0, step = 0, n, wlen, maxelem = 3;
|
2012-07-14 10:23:51 +02:00
|
|
|
wordlist *wl2 = NULL, *wlin, *rhs;
|
2012-12-01 16:04:47 +01:00
|
|
|
bool eqfound = FALSE;
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
if (!ft_curckt) {
|
|
|
|
|
fprintf(cp_err, "Error: no circuit loaded\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
/*
|
|
|
|
|
wordlist 'wl' will be splitted into a wordlist wl2 with three elements,
|
|
|
|
|
containing
|
|
|
|
|
1) '@dev[param]' string (i.e.: the substring before '=' char);
|
|
|
|
|
2) '=' string;
|
|
|
|
|
3) 'expression' string.
|
|
|
|
|
|
|
|
|
|
Spaces around the '=' sign have to be removed. This is provided
|
|
|
|
|
by inp_remove_excess_ws(). But take care if command is entered manually!
|
|
|
|
|
|
|
|
|
|
If the 'altermod' argument is 'altermod m1 vth0=0.7', 'm1' has to be kept as the
|
|
|
|
|
element in wl2 before splitting inserts the three new elements.
|
|
|
|
|
If 'expression' is a vector (e.g. [ 1.0 1.2 1.4 ] ), its elements
|
|
|
|
|
in wl2 have to follow the splitting. wl_splice() will take care of this.
|
2009-02-08 15:52:16 +01:00
|
|
|
*/
|
|
|
|
|
wlin = wl;
|
2012-09-20 20:30:53 +02:00
|
|
|
while (wl) {
|
|
|
|
|
argument = wl->wl_word;
|
|
|
|
|
/* searching for '=' ... */
|
|
|
|
|
i = 0;
|
|
|
|
|
while (argument[i] != '=' && argument[i] != '\0')
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
|
|
/* argument may be '=', then do nothing
|
|
|
|
|
or =token
|
|
|
|
|
or token=
|
|
|
|
|
or token1=token2
|
|
|
|
|
...and if found split argument into three chars and make a new wordlist */
|
|
|
|
|
if (argument[i] != '\0') {
|
|
|
|
|
/* We found '=' */
|
|
|
|
|
eqfound = TRUE;
|
|
|
|
|
if (strlen(argument) == 1) {
|
|
|
|
|
wl = wl->wl_next;
|
|
|
|
|
step = -1;
|
|
|
|
|
wl2 = wlin;
|
|
|
|
|
} else if (strlen(argument) > 1) {
|
|
|
|
|
arglist = TMALLOC(char*, 4);
|
|
|
|
|
arglist[3] = NULL;
|
|
|
|
|
arglist[0] = TMALLOC(char, i + 1);
|
|
|
|
|
arglist[2] = TMALLOC(char, strlen(&argument[i + 1]) + 1);
|
|
|
|
|
/* copy argument */
|
|
|
|
|
strncpy(arglist[0], argument, (size_t) i);
|
|
|
|
|
arglist[0][i] = '\0';
|
|
|
|
|
/* copy equal sign */
|
|
|
|
|
arglist[1] = copy("=");
|
|
|
|
|
/* copy expression */
|
|
|
|
|
strncpy(arglist[2], &argument[i+1], strlen(&argument[i+1])+1);
|
|
|
|
|
|
|
|
|
|
/* create a new wordlist from array arglist */
|
|
|
|
|
wl2 = wl_build(arglist);
|
|
|
|
|
/* combine wordlists into wl2, free wl */
|
|
|
|
|
wl_splice(wl, wl2);
|
|
|
|
|
wl = NULL;
|
|
|
|
|
/* free arglist */
|
|
|
|
|
for (n = 0; n < 3; n++)
|
|
|
|
|
tfree(arglist[n]);
|
|
|
|
|
tfree(arglist);
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
2012-09-20 20:30:53 +02:00
|
|
|
} else {
|
|
|
|
|
/* deal with 'altermod m1 vth0=0.7' by moving
|
|
|
|
|
forward beyond 'm1' */
|
|
|
|
|
wl = wl->wl_next;
|
|
|
|
|
step++;
|
|
|
|
|
}
|
2009-02-08 15:52:16 +01:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
if (eqfound) {
|
2009-02-08 15:52:16 +01:00
|
|
|
/* step back in the wordlist, if we have moved forward, to catch 'm1' */
|
2012-09-20 20:30:53 +02:00
|
|
|
for (n = step; n > 0; n--)
|
2011-09-18 11:03:55 +02:00
|
|
|
wl2 = wl2->wl_prev;
|
2009-02-08 15:52:16 +01:00
|
|
|
} else {
|
2012-09-20 20:30:53 +02:00
|
|
|
/* no equal sign found, probably a pre3f4 input format
|
2009-02-08 15:52:16 +01:00
|
|
|
'alter device value'
|
|
|
|
|
'alter device parameter value'
|
2012-09-20 20:30:53 +02:00
|
|
|
are supported,
|
2009-02-08 15:52:16 +01:00
|
|
|
'alter device parameter value parameter value [ parameter value ]'
|
|
|
|
|
multiple param value pairs are not supported!
|
|
|
|
|
*/
|
|
|
|
|
wl2 = wlin;
|
|
|
|
|
wlen = wl_length(wlin);
|
|
|
|
|
/* Return the last element of wlin */
|
|
|
|
|
wlin = wl_nthelem(100, wlin); /* no more than 100 vector elements */
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
if (eq(wlin->wl_word, "]")) /* we have a vector */
|
|
|
|
|
for (n = 0; n < 100; n++) { /* no more than 100 vector elements */
|
|
|
|
|
wlin = wlin->wl_prev;
|
|
|
|
|
maxelem++;
|
|
|
|
|
if (eq(wlin->wl_word, "[")) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (wlin->wl_prev == NULL) {
|
|
|
|
|
fprintf(cp_err, "Error: '[' is missing.\n");
|
|
|
|
|
fprintf(cp_err, "Cannot alter parameters.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wlen > maxelem) {
|
2009-02-08 15:52:16 +01:00
|
|
|
fprintf(cp_err, "Error: Only a single param - value pair supported.\n");
|
|
|
|
|
fprintf(cp_err, "Cannot alter parameters.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/* add the '=' */
|
|
|
|
|
wlin = wlin->wl_prev;
|
2012-07-14 10:23:51 +02:00
|
|
|
rhs = wl_chop_rest(wlin);
|
|
|
|
|
wlin = wl_append(wlin, wl_cons(copy("="), rhs));
|
2012-09-20 20:30:53 +02:00
|
|
|
/* step back until 'alter' or 'altermod' is found,
|
|
|
|
|
then move one step forward */
|
|
|
|
|
while (!ciprefix("alter", wlin->wl_word)) //while (!ciprefix(wlin->wl_word, "alter"))
|
2009-02-08 15:52:16 +01:00
|
|
|
wlin = wlin->wl_prev;
|
|
|
|
|
wlin = wlin->wl_next;
|
|
|
|
|
wl2 = wlin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Everything is ready, parsing of the wordlist starts here. */
|
2012-09-20 20:30:53 +02:00
|
|
|
words = wl2;
|
2000-04-27 22:03:57 +02:00
|
|
|
while (words) {
|
2009-02-08 15:52:16 +01:00
|
|
|
p = words->wl_word;
|
|
|
|
|
eqword = words;
|
|
|
|
|
words = words->wl_next;
|
2012-09-20 20:30:53 +02:00
|
|
|
if (eq(p, "="))
|
2009-02-08 15:52:16 +01:00
|
|
|
break;
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
if (!words) {
|
2009-02-08 15:52:16 +01:00
|
|
|
fprintf(cp_err, "Error: no assignment found.\n");
|
|
|
|
|
fprintf(cp_err, "Cannot alter parameters.\n");
|
|
|
|
|
return;
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* device parameter = expr
|
|
|
|
|
device = expr
|
|
|
|
|
@dev[param] = expr
|
2012-09-20 20:30:53 +02:00
|
|
|
*/
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
dev = NULL;
|
|
|
|
|
param = NULL;
|
2009-02-08 15:52:16 +01:00
|
|
|
words = wl2;
|
2000-04-27 22:03:57 +02:00
|
|
|
while (words != eqword) {
|
2009-02-08 15:52:16 +01:00
|
|
|
p = words->wl_word;
|
|
|
|
|
if (param) {
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_err, "Warning: excess parameter name \"%s\" ignored.\n", p);
|
2009-02-08 15:52:16 +01:00
|
|
|
} else if (dev) {
|
|
|
|
|
param = words->wl_word;
|
|
|
|
|
} else if (*p == '@' || *p == '#') {
|
|
|
|
|
dev = p + 1;
|
2012-09-20 20:30:53 +02:00
|
|
|
p = strchr(p, '[');
|
2009-02-08 15:52:16 +01:00
|
|
|
if (p) {
|
|
|
|
|
*p++ = 0;
|
|
|
|
|
param = p;
|
2012-09-20 20:30:53 +02:00
|
|
|
p = strchr(p, ']');
|
2009-02-08 15:52:16 +01:00
|
|
|
if (p)
|
|
|
|
|
*p = 0;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
dev = p;
|
|
|
|
|
}
|
|
|
|
|
words = words->wl_next;
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
if (!dev) {
|
2012-09-20 20:30:53 +02:00
|
|
|
fprintf(cp_err, "Error: no model or device name provided.\n");
|
2009-02-08 15:52:16 +01:00
|
|
|
fprintf(cp_err, "Cannot alter parameters.\n");
|
|
|
|
|
return;
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
words = eqword->wl_next;
|
2009-02-08 15:52:16 +01:00
|
|
|
/* skip next line if words is a vector */
|
2012-09-20 20:30:53 +02:00
|
|
|
if (!eq(words->wl_word, "["))
|
2009-02-08 15:52:16 +01:00
|
|
|
names = ft_getpnames(words, FALSE);
|
2012-09-20 20:30:53 +02:00
|
|
|
else
|
|
|
|
|
names = NULL;
|
|
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
if (!names) {
|
2012-09-20 20:30:53 +02:00
|
|
|
/* Put this to try to resolve the case of
|
|
|
|
|
alter @vin[pulse] = [ 0 5 10n 10n 10n 50n 100n ]
|
2009-01-15 23:16:32 +01:00
|
|
|
*/
|
2012-12-16 14:07:33 +01:00
|
|
|
char *xsbuf, *rem_xsbuf;
|
2012-09-20 20:30:53 +02:00
|
|
|
int type = IF_REALVEC, i = 0;
|
|
|
|
|
|
|
|
|
|
double *list;
|
|
|
|
|
double tmp;
|
|
|
|
|
int error;
|
|
|
|
|
/* move beyond '[' to allow INPevaluate() */
|
|
|
|
|
if (eq(words->wl_word, "["))
|
|
|
|
|
words = words->wl_next;
|
2012-12-16 14:07:33 +01:00
|
|
|
xsbuf = rem_xsbuf = wl_flatten(words);
|
2012-09-20 20:30:53 +02:00
|
|
|
/* fprintf(cp_err, "Chain converted %s \n", xsbuf); */
|
|
|
|
|
dv = TMALLOC(struct dvec, 1);
|
|
|
|
|
dv->v_name = copy("real vector");
|
|
|
|
|
type &= IF_VARTYPES;
|
|
|
|
|
if (type == IF_REALVEC) {
|
|
|
|
|
list = TMALLOC(double, 1);
|
|
|
|
|
tmp = INPevaluate(&xsbuf, &error, 1);
|
|
|
|
|
while (error == 0) {
|
|
|
|
|
/*printf(" returning vector value %g\n", tmp); */
|
|
|
|
|
i++;
|
|
|
|
|
list = TREALLOC(double, list, i);
|
2013-01-26 14:40:29 +01:00
|
|
|
list[i-1] = tmp;
|
2012-09-20 20:30:53 +02:00
|
|
|
tmp = INPevaluate(&xsbuf, &error, 1);
|
|
|
|
|
}
|
|
|
|
|
dv->v_realdata = list;
|
|
|
|
|
}
|
|
|
|
|
dv->v_length = i;
|
|
|
|
|
|
|
|
|
|
if (!dv)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (dv->v_length < 1) {
|
|
|
|
|
fprintf(cp_err, "Error: cannot evaluate new parameter value.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Here I was, to change the inclusion in the circuit.
|
|
|
|
|
* will have to revise that dv is right for its insertion.
|
|
|
|
|
*/
|
|
|
|
|
if_setparam(ft_curckt->ci_ckt, &dev, param, dv, do_model);
|
2009-01-15 23:16:32 +01:00
|
|
|
|
2012-12-16 14:07:33 +01:00
|
|
|
tfree(rem_xsbuf);
|
|
|
|
|
vec_free(dv);
|
2012-09-20 20:30:53 +02:00
|
|
|
return;
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
dv = ft_evaluate(names);
|
|
|
|
|
if (!dv)
|
2012-10-01 21:09:26 +02:00
|
|
|
goto done;
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
if (dv->v_length < 1) {
|
2009-02-08 15:52:16 +01:00
|
|
|
fprintf(cp_err, "Error: cannot evaluate new parameter value.\n");
|
2012-10-01 21:09:26 +02:00
|
|
|
goto done;
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
/* If we want alter the geometry of a MOS device
|
2012-08-05 12:11:16 +02:00
|
|
|
we have to ensure that we are in the valid model bin. */
|
2012-09-20 20:30:53 +02:00
|
|
|
if ((dev[0] == 'm') && ((param[0] == 'w') || (param[0] == 'l')))
|
2012-08-05 12:11:16 +02:00
|
|
|
if_set_binned_model(ft_curckt->ci_ckt, dev, param, dv);
|
|
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
if_setparam(ft_curckt->ci_ckt, &dev, param, dv, do_model);
|
|
|
|
|
|
2003-07-23 21:36:39 +02:00
|
|
|
/* va: garbage collection for dv, if pnode names is no simple value */
|
2012-09-20 20:30:53 +02:00
|
|
|
if (names->pn_value == NULL && dv != NULL)
|
|
|
|
|
vec_free(dv);
|
2012-10-01 21:09:26 +02:00
|
|
|
|
|
|
|
|
done:
|
2004-08-16 11:10:40 +02:00
|
|
|
free_pnode(names); /* free also dv, if pnode names is simple value */
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
/* Given a device name, possibly with wildcards, return the matches. */
|
|
|
|
|
|
|
|
|
|
static wordlist *
|
|
|
|
|
devexpand(char *name)
|
|
|
|
|
{
|
2012-07-14 10:23:51 +02:00
|
|
|
wordlist *wl, *devices;
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2012-02-06 18:46:33 +01:00
|
|
|
if (strchr(name, '*') || strchr(name, '[') || strchr(name, '?')) {
|
2000-04-27 22:03:57 +02:00
|
|
|
devices = cp_cctowl(ft_curckt->ci_devices);
|
|
|
|
|
for (wl = NULL; devices; devices = devices->wl_next)
|
2012-09-20 20:30:53 +02:00
|
|
|
if (cp_globmatch(name, devices->wl_word))
|
2012-07-14 10:23:51 +02:00
|
|
|
wl = wl_cons(devices->wl_word, wl);
|
2005-04-24 23:17:31 +02:00
|
|
|
} else if (cieq(name, "all")) {
|
2000-04-27 22:03:57 +02:00
|
|
|
wl = cp_cctowl(ft_curckt->ci_devices);
|
|
|
|
|
} else {
|
2012-07-14 10:23:51 +02:00
|
|
|
wl = wl_cons(name, NULL);
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
wl_sort(wl);
|
|
|
|
|
return (wl);
|
|
|
|
|
}
|
2011-09-18 11:03:55 +02:00
|
|
|
|
2012-09-20 20:30:53 +02:00
|
|
|
|
2011-10-02 10:29:03 +02:00
|
|
|
/* altermod mod_1 [mod_nn] file=modelparam.mod
|
|
|
|
|
load model file and overwrite models mod_1 till mod_nn with
|
|
|
|
|
all new parameters (limited to 16 models) */
|
2012-09-20 20:30:53 +02:00
|
|
|
static void
|
|
|
|
|
com_alter_mod(wordlist *wl)
|
2011-09-18 11:03:55 +02:00
|
|
|
{
|
2011-10-02 10:29:03 +02:00
|
|
|
#define MODLIM 16 /* max number of models */
|
2011-09-18 11:03:55 +02:00
|
|
|
FILE *modfile;
|
2012-09-20 20:30:53 +02:00
|
|
|
char *modellist[MODLIM] = {NULL}, *modellines[MODLIM] = {NULL}, *newmodelname, *newmodelline;
|
|
|
|
|
char *filename = NULL, *eqword, *input, *modelline = NULL, *inptoken;
|
2011-10-02 10:29:03 +02:00
|
|
|
int modno = 0, molineno = 0, i, j;
|
|
|
|
|
wordlist *newcommand;
|
2011-09-18 11:03:55 +02:00
|
|
|
struct line *modeldeck, *tmpdeck;
|
|
|
|
|
char *readmode = "r";
|
2011-10-02 10:29:03 +02:00
|
|
|
char **arglist;
|
|
|
|
|
bool modelfound = FALSE;
|
|
|
|
|
int ij[MODLIM];
|
|
|
|
|
|
|
|
|
|
/* initialize */
|
|
|
|
|
for (i = 0; i < MODLIM; i++)
|
|
|
|
|
ij[i] = -1;
|
|
|
|
|
|
|
|
|
|
/* read all model names */
|
|
|
|
|
while (!ciprefix("file", wl->wl_word)) {
|
|
|
|
|
if (modno == MODLIM) {
|
|
|
|
|
fprintf(cp_err, "Error: too many model names in altermod command\n");
|
|
|
|
|
controlled_exit(1);
|
|
|
|
|
}
|
|
|
|
|
modellist[modno] = copy(wl->wl_word);
|
|
|
|
|
modno++;
|
|
|
|
|
wl = wl->wl_next;
|
|
|
|
|
}
|
|
|
|
|
input = wl_flatten(wl);
|
|
|
|
|
/* get the file name */
|
2011-09-18 11:03:55 +02:00
|
|
|
eqword = strstr(input, "=");
|
|
|
|
|
if (eqword) {
|
|
|
|
|
eqword++;
|
2012-09-20 20:30:53 +02:00
|
|
|
while (*eqword == ' ')
|
2011-09-18 11:03:55 +02:00
|
|
|
eqword++;
|
2012-09-20 20:30:53 +02:00
|
|
|
if (eqword == '\0') {
|
2011-09-18 11:03:55 +02:00
|
|
|
fprintf(cp_err, "Error: no filename given\n");
|
2011-10-02 10:29:03 +02:00
|
|
|
controlled_exit(1);
|
|
|
|
|
}
|
2011-09-18 11:03:55 +02:00
|
|
|
filename = copy(eqword);
|
2012-09-20 20:30:53 +02:00
|
|
|
} else {
|
2011-09-18 11:03:55 +02:00
|
|
|
eqword = strstr(input, "file");
|
|
|
|
|
eqword += 4;
|
2012-09-20 20:30:53 +02:00
|
|
|
while (*eqword == ' ')
|
2011-09-18 11:03:55 +02:00
|
|
|
eqword++;
|
2012-09-20 20:30:53 +02:00
|
|
|
if (eqword == '\0') {
|
2011-09-18 11:03:55 +02:00
|
|
|
fprintf(cp_err, "Error: no filename given\n");
|
2011-10-02 10:29:03 +02:00
|
|
|
controlled_exit(1);
|
|
|
|
|
}
|
2011-09-18 11:03:55 +02:00
|
|
|
filename = copy(eqword);
|
|
|
|
|
}
|
|
|
|
|
modfile = inp_pathopen(filename, readmode);
|
2012-09-13 20:07:33 +02:00
|
|
|
{
|
|
|
|
|
char *dir_name = ngdirname(filename);
|
2013-06-02 17:15:51 +02:00
|
|
|
modeldeck = inp_readall(modfile, dir_name, 0, 0);
|
2012-09-13 20:07:33 +02:00
|
|
|
free(dir_name);
|
|
|
|
|
}
|
2011-09-18 11:03:55 +02:00
|
|
|
tfree(input);
|
|
|
|
|
tfree(filename);
|
2011-10-02 10:29:03 +02:00
|
|
|
/* get all lines starting with *model */
|
2011-09-18 11:03:55 +02:00
|
|
|
for (tmpdeck = modeldeck; tmpdeck; tmpdeck = tmpdeck->li_next)
|
|
|
|
|
if (ciprefix("*model", tmpdeck->li_line)) {
|
2012-09-20 20:30:53 +02:00
|
|
|
if (molineno == MODLIM) {
|
2011-10-02 10:29:03 +02:00
|
|
|
fprintf(cp_err, "Error: more than %d models in deck, rest ignored\n", molineno);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
modellines[molineno] = tmpdeck->li_line;
|
|
|
|
|
molineno++;
|
|
|
|
|
}
|
|
|
|
|
/* Check if all models named in altermod command are to be found in input deck.
|
|
|
|
|
Exit if not successfull */
|
|
|
|
|
for (i = 0; i < modno; i++) {
|
2012-09-20 20:30:53 +02:00
|
|
|
for (j = 0; j < molineno; j++) {
|
2011-10-02 10:29:03 +02:00
|
|
|
newmodelline = modellines[j];
|
|
|
|
|
/* get model name from model line */
|
|
|
|
|
inptoken = gettok(&newmodelline); /* *model */
|
|
|
|
|
tfree(inptoken);
|
|
|
|
|
newmodelname = gettok(&newmodelline); /* modelname */
|
2012-09-20 20:30:53 +02:00
|
|
|
if (cieq(newmodelname, modellist[i])) {
|
|
|
|
|
modelfound = TRUE;
|
2011-10-02 10:29:03 +02:00
|
|
|
tfree(newmodelname);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
tfree(newmodelname);
|
|
|
|
|
}
|
|
|
|
|
if (modelfound) {
|
|
|
|
|
modelfound = FALSE;
|
|
|
|
|
ij[i] = j; /* model in altermod, found in model line */
|
|
|
|
|
continue;
|
2012-09-20 20:30:53 +02:00
|
|
|
} else {
|
2011-10-02 10:29:03 +02:00
|
|
|
fprintf(cp_err, "Error: could not find model %s in input deck\n", modellist[i]);
|
|
|
|
|
controlled_exit(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* read the model line, generate the altermod commands as a wordlist,
|
|
|
|
|
and call com_alter_common() */
|
|
|
|
|
arglist = TMALLOC(char*, 4);
|
|
|
|
|
arglist[0] = copy("altermod");
|
|
|
|
|
arglist[3] = NULL;
|
|
|
|
|
/* for each model name of altermod command */
|
|
|
|
|
for (i = 0; i < modno; i++) {
|
|
|
|
|
/* model name */
|
|
|
|
|
arglist[1] = copy(modellist[i]);
|
|
|
|
|
/* parse model line from deck */
|
|
|
|
|
modelline = modellines[ij[i]];
|
|
|
|
|
inptoken = gettok(&modelline); /* skip *model */
|
|
|
|
|
tfree(inptoken);
|
|
|
|
|
inptoken = gettok(&modelline); /* skip modelname */
|
|
|
|
|
tfree(inptoken);
|
|
|
|
|
inptoken = gettok(&modelline); /* skip model type */
|
2011-09-18 11:03:55 +02:00
|
|
|
tfree(inptoken);
|
|
|
|
|
while ((inptoken = gettok(&modelline)) != NULL) {
|
|
|
|
|
/* exclude level and version */
|
|
|
|
|
if (ciprefix("version", inptoken) || ciprefix("level", inptoken)) {
|
|
|
|
|
tfree(inptoken);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
arglist[2] = inptoken;
|
|
|
|
|
/* create a new wordlist from array arglist */
|
|
|
|
|
newcommand = wl_build(arglist);
|
|
|
|
|
com_alter_common(newcommand->wl_next, 1);
|
|
|
|
|
wl_free(newcommand);
|
|
|
|
|
tfree(inptoken);
|
|
|
|
|
}
|
2011-10-02 10:29:03 +02:00
|
|
|
tfree(arglist[1]);
|
2011-09-18 11:03:55 +02:00
|
|
|
}
|
2011-10-02 10:29:03 +02:00
|
|
|
tfree(arglist[0]);
|
|
|
|
|
tfree(arglist[3]);
|
2011-09-18 11:03:55 +02:00
|
|
|
}
|