You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1087 lines
32 KiB

/*============================================================================
FILE pp_lst.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 functions used in processing the files:
modpath.lst
udnpath.lst
The files 'modpath.lst' and 'udnpath.lst' are read to get
the pathnames to directories containing the models and node types
desired in the simulator to be built. Files in each of these
directories are then examined to get the names of functions and/or
data structures that the simulator must know about. The names
are then checked for uniqueness, and finally, a collection of
files needed in the 'make' for the simulator are written.
INTERFACES
preprocess_lst_files()
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#include "cmpp.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
extern int str_to_lower(char *s);
/*
void *malloc(unsigned size);
void *realloc(void *ptr, unsigned size);
*/
/* *********************************************************************** */
/*
* Information for processing the pathname files
*/
typedef struct {
char *path_name; /* Pathname read from model path file */
char *spice_name; /* Name of model from ifspec.ifs */
char *cfunc_name; /* Name of C fcn from ifspec.ifs */
Boolean_t spice_unique; /* True if spice name unique */
Boolean_t cfunc_unique; /* True if C fcn name unique */
} Model_Info_t;
typedef struct {
char *path_name; /* Pathname read from udn path file */
char *node_name; /* Name of node type */
Boolean_t unique; /* True if node type name unique */
} Node_Info_t;
/* *********************************************************************** */
static Status_t read_modpath(int *num_models, Model_Info_t **model_info);
static Status_t read_udnpath(int *num_nodes, Node_Info_t **node_info);
static Status_t read_model_names(int num_models, Model_Info_t *model_info);
static Status_t read_node_names(int num_nodes, Node_Info_t *node_info);
static Status_t check_uniqueness(int num_models, Model_Info_t *model_info,
int num_nodes, Node_Info_t *node_info);
static Status_t write_CMextrn(int num_models, Model_Info_t *model_info);
static Status_t write_CMinfo(int num_models, Model_Info_t *model_info);
static Status_t write_UDNextrn(int num_nodes, Node_Info_t *node_info);
static Status_t write_UDNinfo(int num_nodes, Node_Info_t *node_info);
static Status_t write_objects_inc(int num_models, Model_Info_t *model_info,
int num_nodes, Node_Info_t *node_info);
static Status_t read_udn_type_name(char *path, char **node_name);
/* *********************************************************************** */
/*
preprocess_lst_files
Function preprocess_lst_files is the top-level driver function for
preprocessing a simulator model path list file (modpath.lst).
This function calls read_ifs_file() requesting it to read and
parse the Interface Specification file (ifspec.ifs) to extract
the model name and associated C function name and place this
information into an internal data structure. It then calls
check_uniqueness() to verify that the model names and function
names are unique with respect to each other and to the models and
functions internal to SPICE 3C1. Following this check, it calls
write_CMextrn(), write_CMinfo(), and write_make_include() to
write out the C include files CMextrn.h and CMinfo.h required by
SPICE function SPIinit.c to define the models known to the
simulator, and to write out a make include file used by the make
utility to locate the object modules necessary to link the models
into the simulator.
*/
void preprocess_lst_files(void)
{
Status_t status; /* Return status */
Model_Info_t *model_info; /* Info about each model */
Node_Info_t *node_info; /* Info about each user-defined node type */
int num_models; /* The number of models */
int num_nodes; /* The number of user-defined nodes */
/* Get list of models from model pathname file */
status = read_modpath(&num_models, &model_info);
if(status != OK) {
exit(1);
}
/* Get list of node types from udn pathname file */
status = read_udnpath(&num_nodes, &node_info);
if(status != OK) {
exit(1);
}
/* Get the spice and C function names from the ifspec.ifs files */
status = read_model_names(num_models, model_info);
if(status != OK) {
exit(1);
}
/* Get the user-defined node type names */
status = read_node_names(num_nodes, node_info);
if(status != OK) {
exit(1);
}
/* Check to be sure the names are unique */
status = check_uniqueness(num_models, model_info,
num_nodes, node_info);
if(status != OK) {
exit(1);
}
/* Write out the CMextrn.h file used to compile SPIinit.c */
status = write_CMextrn(num_models, model_info);
if(status != OK) {
exit(1);
}
/* Write out the CMinfo.h file used to compile SPIinit.c */
status = write_CMinfo(num_models, model_info);
if(status != OK) {
exit(1);
}
/* Write out the UDNextrn.h file used to compile SPIinit.c */
status = write_UDNextrn(num_nodes, node_info);
if(status != OK) {
exit(1);
}
/* Write out the UDNinfo.h file used to compile SPIinit.c */
status = write_UDNinfo(num_nodes, node_info);
if(status != OK) {
exit(1);
}
/* Write the make_include file used to link the models and */
/* user-defined node functions with the simulator */
status = write_objects_inc(num_models, model_info,
num_nodes, node_info);
if(status != OK) {
exit(1);
}
}
/* *********************************************************************** */
/*
read_modpath
This function opens the modpath.lst file, reads the pathnames from the
file, and puts them into an internal data structure for future
processing.
*/
static Status_t read_modpath(
int *num_models, /* Number of model pathnames found */
Model_Info_t **model_info /* Info about each model */
)
{
FILE *fp; /* Model pathname file pointer */
char msg[MAX_PATH_LEN+257]; /* space for an error message */
char path[MAX_PATH_LEN+2]; /* space to read pathnames into */
Model_Info_t *model = NULL; /* temporary pointer to model info */
int n;
int i;
int j;
int len;
int line_num;
static char *filename = MODPATH_FILENAME;
/* Initialize number of models to zero in case of error */
*num_models = 0;
/* Open the model pathname file */
fp = fopen(filename, "r");
if(fp == NULL) {
sprintf(msg, "ERROR - File not found: %s", filename);
print_error(msg);
return(ERROR);
}
/* Read the pathnames from the file, one line at a time until EOF */
n = 0;
line_num = 0;
while( fgets(path, sizeof(path), fp) ) {
line_num++;
len = strlen(path);
/* If line was too long for buffer, exit with error */
if(len > MAX_PATH_LEN) {
sprintf(msg, "ERROR - Line %d of %s exceeds %d characters",
line_num, filename, MAX_PATH_LEN);
print_error(msg);
return(ERROR);
}
/* Strip white space including newline */
for(i = 0, j = 0; i < len; ) {
if(isspace(path[i])) {
i++;
}
else {
path[j] = path[i];
i++;
j++;
}
}
path[j] = '\0';
len = j;
/* Strip trailing '/' if any */
if(path[len - 1] == '/')
path[--len] = '\0';
/* If blank line, continue */
if(len == 0)
continue;
/* Make sure pathname is short enough to add a filename at the end */
if(len > (MAX_PATH_LEN - (MAX_FN_LEN + 1)) ) {
sprintf(msg, "ERROR - Pathname on line %d of %s exceeds %d characters",
line_num, filename, (MAX_PATH_LEN - (MAX_FN_LEN + 1)));
print_error(msg);
return(ERROR);
}
/* Allocate and initialize a new model info structure */
if(n == 0)
model = (Model_Info_t *) malloc(sizeof(Model_Info_t));
else
model = (Model_Info_t *) realloc(model, (n + 1) * sizeof(Model_Info_t));
model[n].path_name = NULL;
model[n].spice_name = NULL;
model[n].cfunc_name = NULL;
model[n].spice_unique = TRUE;
model[n].cfunc_unique = TRUE;
/* Put pathname into info structure */
model[n].path_name = (char *) malloc(len+1);
strcpy(model[n].path_name, path);
/* Increment count of paths read */
n++;
}
/* Close model pathname file and return data read */
fclose(fp);
*num_models = n;
*model_info = model;
return(OK);
}
/* *********************************************************************** */
/*
read_udnpath
This function opens the udnpath.lst file, reads the pathnames from the
file, and puts them into an internal data structure for future
processing.
*/
static Status_t read_udnpath(
int *num_nodes, /* Number of node pathnames found */
Node_Info_t **node_info /* Info about each node */
)
{
FILE *fp; /* Udn pathname file pointer */
char msg[MAX_PATH_LEN+257]; /* space for an error message */
char path[MAX_PATH_LEN+2]; /* space to read pathnames into */
Node_Info_t *node = NULL; /* temporary pointer to node info */
int n;
int i;
int j;
int len;
int line_num;
static char *filename = UDNPATH_FILENAME;
/* Initialize number of nodes to zero in case of error */
*num_nodes = 0;
/* Open the node pathname file */
fp = fopen(filename, "r");
/* For backward compatibility, return with WARNING only if file not found */
if(fp == NULL) {
sprintf(msg, "WARNING - File not found: %s", filename);
print_error(msg);
return(OK);
}
/* Read the pathnames from the file, one line at a time until EOF */
n = 0;
line_num = 0;
while( fgets(path, sizeof(path), fp) ) {
line_num++;
len = strlen(path);
/* If line was too long for buffer, exit with error */
if(len > MAX_PATH_LEN) {
sprintf(msg, "ERROR - Line %d of %s exceeds %d characters",
line_num, filename, MAX_PATH_LEN);
print_error(msg);
return(ERROR);
}
/* Strip white space including newline */
for(i = 0, j = 0; i < len; ) {
if(isspace(path[i])) {
i++;
}
else {
path[j] = path[i];
i++;
j++;
}
}
path[j] = '\0';
len = j;
/* Strip trailing '/' if any */
if(path[len - 1] == '/')
path[--len] = '\0';
/* If blank line, continue */
if(len == 0)
continue;
/* Make sure pathname is short enough to add a filename at the end */
if(len > (MAX_PATH_LEN - (MAX_FN_LEN + 1)) ) {
sprintf(msg, "ERROR - Pathname on line %d of %s exceeds %d characters",
line_num, filename, (MAX_PATH_LEN - (MAX_FN_LEN + 1)));
print_error(msg);
return(ERROR);
}
/* Allocate and initialize a new node info structure */
if(n == 0)
node = (Node_Info_t *) malloc(sizeof(Node_Info_t));
else
node = (Node_Info_t *) realloc(node, (n + 1) * sizeof(Node_Info_t));
node[n].path_name = NULL;
node[n].node_name = NULL;
node[n].unique = TRUE;
/* Put pathname into info structure */
node[n].path_name = (char *) malloc(len+1);
strcpy(node[n].path_name, path);
/* Increment count of paths read */
n++;
}
/* Close node pathname file and return data read */
fclose(fp);
*num_nodes = n;
*node_info = node;
return(OK);
}
/* *********************************************************************** */
/*
read_model_names
This function opens each of the models and gets the names of the model
and the C function into the internal model information structure.
*/
static Status_t read_model_names(
int num_models, /* Number of model pathnames */
Model_Info_t *model_info /* Info about each model */
)
{
Boolean_t all_found; /* True if all ifspec files read */
int i; /* A temporary counter */
char msg[MAX_PATH_LEN+257]; /* space for an error message */
char path[MAX_PATH_LEN+1]; /* full pathname to ifspec file */
Status_t status; /* Return status */
Ifs_Table_t ifs_table; /* Repository for info read from ifspec file */
/* For each model found in model pathname file, read the interface */
/* spec file to get the SPICE and C function names into model_info */
for(i = 0, all_found = TRUE; i < num_models; i++) {
/* Form the full pathname to the interface spec file */
strcpy(path, model_info[i].path_name);
strcat(path, "/");
strcat(path, IFSPEC_FILENAME);
/* Read the SPICE and C function names from the interface spec file */
status = read_ifs_file(path, GET_IFS_NAME, &ifs_table);
/* Transfer the names into the model_info structure */
if(status == OK) {
model_info[i].spice_name = ifs_table.name.model_name;
model_info[i].cfunc_name = ifs_table.name.c_fcn_name;
}
else {
all_found = FALSE;
sprintf(msg, "ERROR - Problems reading %s in directory %s",
IFSPEC_FILENAME, model_info[i].path_name);
print_error(msg);
}
}
if(all_found)
return(OK);
else
return(ERROR);
}
/* *********************************************************************** */
/*
read_node_names
This function opens each of the user-defined node definition files
and gets the names of the node into the internal information structure.
*/
static Status_t read_node_names(
int num_nodes, /* Number of node pathnames */
Node_Info_t *node_info /* Info about each node */
)
{
Boolean_t all_found; /* True if all files read OK */
int i; /* A temporary counter */
char msg[MAX_PATH_LEN+257]; /* space for an error message */
char path[MAX_PATH_LEN+1]; /* full pathname to file */
Status_t status; /* Return status */
char *node_name; /* Name of node type read from file */
/* For each node found in node pathname file, read the udnfunc.c */
/* file to get the node type names into node_info */
for(i = 0, all_found = TRUE; i < num_nodes; i++) {
/* Form the full pathname to the interface spec file */
strcpy(path, node_info[i].path_name);
strcat(path, "/");
strcat(path, UDNFUNC_FILENAME);
/* Read the udn node type name from the file */
status = read_udn_type_name(path, &node_name);
/* Transfer the names into the node_info structure */
if(status == OK) {
node_info[i].node_name = node_name;
}
else {
all_found = FALSE;
sprintf(msg, "ERROR - Problems reading %s in directory %s",
UDNFUNC_FILENAME, node_info[i].path_name);
print_error(msg);
}
}
if(all_found)
return(OK);
else
return(ERROR);
}
/* *********************************************************************** */
/*
check_uniqueness
Function check_uniqueness determines if model names and function
names are unique with respect to each other and to the models and
functions internal to SPICE 3C1.
*/
static Status_t check_uniqueness(
int num_models, /* Number of model pathnames */
Model_Info_t *model_info, /* Info about each model */
int num_nodes, /* Number of node type pathnames */
Node_Info_t *node_info /* Info about each node type */
)
{
int i; /* A temporary counter */
int j; /* A temporary counter */
char msg[MAX_PATH_LEN+257]; /* space for an error message */
Boolean_t all_unique; /* true if names are unique */
/* Define a list of model names used internally by XSPICE */
/* These names (except 'poly') are defined in src/sim/INP/INPdomodel.c and */
/* are case insensitive */
static char *SPICEmodel[] = { "npn",
"pnp",
"d",
"njf",
"pjf",
"nmf",
"pmf",
"urc",
"nmos",
"pmos",
"r",
"c",
"sw",
"csw",
"poly" };
static int numSPICEmodels = sizeof(SPICEmodel) / sizeof(char *);
/* Define a list of node type names used internally by the simulator */
/* These names are defined in src/sim/include/MIFtypes.h and are case */
/* insensitive */
static char *UDNidentifier[] = { "v",
"vd",
"i",
"id",
"vnam",
"g",
"gd",
"h",
"hd",
"d" };
static int numUDNidentifiers = sizeof(UDNidentifier) / sizeof(char *);
/* First, normalize case of all model and node names to lower since */
/* SPICE is case insensitive in parsing decks */
for(i = 0; i < num_models; i++)
str_to_lower(model_info[i].spice_name);
for(i = 0; i < num_nodes; i++)
str_to_lower(node_info[i].node_name);
/* Then, loop through all model names and report errors if same as SPICE */
/* model name or same as another model name in list */
for(i = 0, all_unique = TRUE; i < num_models; i++) {
/* First check against list of SPICE internal names */
for(j = 0; j < numSPICEmodels; j++) {
if(strcmp(model_info[i].spice_name, SPICEmodel[j]) == 0) {
all_unique = FALSE;
sprintf(msg,
"ERROR - Model name '%s' is same as internal SPICE model name\n",
model_info[i].spice_name);
print_error(msg);
}
}
/* Skip if already seen once */
if(model_info[i].spice_unique == FALSE)
continue;
/* Then check against other names in list */
for(j = 0; j < num_models; j++) {
/* Skip checking against itself */
if(i == j)
continue;
/* Compare the names */
if(strcmp(model_info[i].spice_name, model_info[j].spice_name) == 0) {
all_unique = FALSE;
model_info[i].spice_unique = FALSE;
model_info[j].spice_unique = FALSE;
sprintf(msg,
"ERROR - Model name '%s' in directory: %s",
model_info[i].spice_name,
model_info[i].path_name);
print_error(msg);
print_error(" is same as");
sprintf(msg,
" model name '%s' in directory: %s\n",
model_info[j].spice_name,
model_info[j].path_name);
print_error(msg);
}
}
}
/* Loop through all C function names and report errors if duplicates found */
for(i = 0; i < num_models; i++) {
/* Skip if already seen once */
if(model_info[i].cfunc_unique == FALSE)
continue;
/* Check against other names in list only, not against SPICE identifiers */
/* Let linker catch collisions with SPICE identifiers for now */
for(j = 0; j < num_models; j++) {
/* Skip checking against itself */
if(i == j)
continue;
/* Compare the names */
if(strcmp(model_info[i].cfunc_name, model_info[j].cfunc_name) == 0) {
all_unique = FALSE;
model_info[i].cfunc_unique = FALSE;
model_info[j].cfunc_unique = FALSE;
sprintf(msg,
"ERROR - C function name '%s' in directory: %s",
model_info[i].cfunc_name,
model_info[i].path_name);
print_error(msg);
print_error(" is same as");
sprintf(msg,
" C function name '%s' in directory: %s\n",
model_info[j].cfunc_name,
model_info[j].path_name);
print_error(msg);
}
}
}
/* Loop through all node type names and report errors if same as internal */
/* name or same as another name in list */
for(i = 0; i < num_nodes; i++) {
/* First check against list of internal names */
for(j = 0; j < numUDNidentifiers; j++) {
if(strcmp(node_info[i].node_name, UDNidentifier[j]) == 0) {
all_unique = FALSE;
sprintf(msg,
"ERROR - Node type '%s' is same as internal node type\n",
node_info[i].node_name);
print_error(msg);
}
}
/* Skip if already seen once */
if(node_info[i].unique == FALSE)
continue;
/* Then check against other names in list */
for(j = 0; j < num_nodes; j++) {
/* Skip checking against itself */
if(i == j)
continue;
/* Compare the names */
if(strcmp(node_info[i].node_name, node_info[j].node_name) == 0) {
all_unique = FALSE;
node_info[i].unique = FALSE;
node_info[j].unique = FALSE;
sprintf(msg,
"ERROR - Node type '%s' in directory: %s",
node_info[i].node_name,
node_info[i].path_name);
print_error(msg);
print_error(" is same as");
sprintf(msg,
" node type '%s' in directory: %s\n",
node_info[j].node_name,
node_info[j].path_name);
print_error(msg);
}
}
}
/* Return error status */
if(all_unique)
return(OK);
else
return(ERROR);
}
/* *********************************************************************** */
/*
write_CMextrn
Function write_CMextrn writes the CMextrn.h file used in
compiling SPIinit.c immediately prior to linking the simulator
and code models. This SPICE source file uses the structures
mentioned in the include file to define the models known to the
simulator.
*/
static Status_t write_CMextrn(
int num_models, /* Number of model pathnames */
Model_Info_t *model_info /* Info about each model */
)
{
int i; /* A temporary counter */
FILE *fp; /* File pointer for writing CMextrn.h */
/* Open the file to be written */
fp = fopen("cmextrn.h", "w");
if(fp == NULL) {
print_error("ERROR - Problems opening CMextrn.h for write");
return(ERROR);
}
/* Write out the data */
for(i = 0; i < num_models; i++) {
fprintf(fp, "extern SPICEdev %s_info;\n", model_info[i].cfunc_name);
}
/* Close the file and return */
fclose(fp);
return(OK);
}
/* *********************************************************************** */
/*
write_CMinfo
Function write_CMinfo writes the CMinfo.h file used in compiling
SPIinit.c immediately prior to linking the simulator and code
models. This SPICE source file uses the structures mentioned in
the include file to define the models known to the simulator.
*/
static Status_t write_CMinfo(
int num_models, /* Number of model pathnames */
Model_Info_t *model_info /* Info about each model */
)
{
int i; /* A temporary counter */
FILE *fp; /* File pointer for writing CMinfo.h */
/* Open the file to be written */
fp = fopen("cminfo.h", "w");
if(fp == NULL) {
print_error("ERROR - Problems opening CMinfo.h for write");
return(ERROR);
}
/* Write out the data */
for(i = 0; i < num_models; i++) {
fprintf(fp, "&%s_info,\n", model_info[i].cfunc_name);
}
/* Close the file and return */
fclose(fp);
return(OK);
}
/* *********************************************************************** */
/*
write_UDNextrn
Function write_UDNextrn writes the UDNextrn.h file used in
compiling SPIinit.c immediately prior to linking the simulator
and user-defined nodes. This SPICE source file uses the structures
mentioned in the include file to define the node types known to the
simulator.
*/
static Status_t write_UDNextrn(
int num_nodes, /* Number of node pathnames */
Node_Info_t *node_info /* Info about each node */
)
{
int i; /* A temporary counter */
FILE *fp; /* File pointer for writing UDNextrn.h */
/* Open the file to be written */
fp = fopen("udnextrn.h", "w");
if(fp == NULL) {
print_error("ERROR - Problems opening UDNextrn.h for write");
return(ERROR);
}
/* Write out the data */
for(i = 0; i < num_nodes; i++) {
fprintf(fp, "extern Evt_Udn_Info_t udn_%s_info;\n", node_info[i].node_name);
}
/* Close the file and return */
fclose(fp);
return(OK);
}
/* *********************************************************************** */
/*
write_UDNinfo
Function write_UDNinfo writes the UDNinfo.h file used in
compiling SPIinit.c immediately prior to linking the simulator
and user-defined nodes. This SPICE source file uses the structures
mentioned in the include file to define the node types known to the
simulator.
*/
static Status_t write_UDNinfo(
int num_nodes, /* Number of node pathnames */
Node_Info_t *node_info /* Info about each node */
)
{
int i; /* A temporary counter */
FILE *fp; /* File pointer for writing UDNinfo.h */
/* Open the file to be written */
fp = fopen("udninfo.h", "w");
if(fp == NULL) {
print_error("ERROR - Problems opening UDNinfo.h for write");
return(ERROR);
}
/* Write out the data */
for(i = 0; i < num_nodes; i++) {
fprintf(fp, "&udn_%s_info,\n", node_info[i].node_name);
}
/* Close the file and return */
fclose(fp);
return(OK);
}
/* *********************************************************************** */
/*
write_objects_inc
Function write_objects_inc writes a make include file used by
the make utility to locate the object modules needed to link the
simulator with the code models and user-defined node types.
*/
static Status_t write_objects_inc(
int num_models, /* Number of model pathnames */
Model_Info_t *model_info, /* Info about each model */
int num_nodes, /* Number of udn pathnames */
Node_Info_t *node_info /* Info about each node type */
)
{
int i; /* A temporary counter */
FILE *fp; /* File pointer for writing make_include */
/* Open the file to be written */
fp = fopen("objects.inc", "w");
if(fp == NULL) {
print_error("ERROR - Problems opening objects.inc file for write");
return(ERROR);
}
/* Write out the data */
for(i = 0; i < num_models; i++) {
fprintf(fp, "%s/*.o", model_info[i].path_name);
if((i < (num_models - 1)) || (num_nodes > 0))
fprintf(fp, " \\\n");
else
fprintf(fp, "\n");
}
for(i = 0; i < num_nodes; i++) {
fprintf(fp, "%s/*.o", node_info[i].path_name);
if(i < (num_nodes - 1))
fprintf(fp, " \\\n");
else
fprintf(fp, "\n");
}
/* Close the file and return */
fclose(fp);
return(OK);
}
/*
read_udn_type_name
This function reads a User-Defined Node Definition File until
the definition of the Evt_Udn_Info_t struct
is found, and then gets the name of the node type from the first
member of the structure.
*/
static Status_t read_udn_type_name(
char *path, /* the path to the node definition file */
char **node_name /* the node type name found in the file */
)
{
FILE *fp; /* file pointer for opened file */
/*char msg[MAX_PATH_LEN+257];*/ /* space for an error message */
Boolean_t found; /* true if name found successfully */
Boolean_t in_struct; /* true if found struct with name */
char name[MAX_NAME_LEN + 1]; /* temporary storage for name read */
int c; /* a character read from the file */
int i; /* a counter */
static char *struct_type = "Evt_Udn_Info_t";
/* Open the file from which the node type name will be read */
fp = fopen(path, "r");
if(fp == NULL)
return(ERROR);
/* Read the file until the definition of the Evt_Udn_Info_t struct */
/* is found, then get the name of the node type from the first */
/* member of the structure */
found = FALSE;
do {
/* read the next character */
c = fgetc(fp);
/* check for and gobble up comments */
if(c == '/') {
c = fgetc(fp);
if(c == '*') {
do {
c = fgetc(fp);
if(c == '*') {
c = fgetc(fp);
if((c == '/') || (c == EOF))
break;
else
ungetc(c, fp);
}
} while(c != EOF);
}
}
if(c == EOF)
break;
/* read until "Evt_Udn_Info_t" is encountered */
for(i = 0, in_struct = FALSE; ; i++) {
if(c != struct_type[i])
break;
else if(i == (sizeof(struct_type) - 2)) {
in_struct = TRUE;
break;
}
else
c = fgetc(fp);
}
/* if found it, read until open quote found */
/* and then read the name until the closing quote is found */
if(in_struct) {
do {
c = fgetc(fp);
if(c == '"') {
i = 0;
do {
c = fgetc(fp);
if(c == '"') {
found = TRUE;
name[i] = '\0';
}
else if(c != EOF)
name[i++] = c;
} while((c != EOF) && (! found));
}
} while((c != EOF) && (! found));
}
} while((c != EOF) && (! found));
/* Close the file and return */
fclose(fp);
if(found) {
*node_name = (char *) malloc(strlen(name) + 1);
strcpy(*node_name, name);
return(OK);
}
else {
*node_name = NULL;
return(ERROR);
}
}