NAMD
Classes | Public Member Functions | List of all members
ConfigList Class Reference

#include <ConfigList.h>

Classes

class  ConfigListNode
 

Public Member Functions

 ConfigList (void)
 
void add_element (const char *s1, int len1, const char *s2, int len2)
 
 ConfigList (const char *filename)
 
Bool okay (void)
 
 ~ConfigList (void)
 
StringListfind (const char *name) const
 
ConfigListNodehead (void) const
 

Detailed Description

Definition at line 75 of file ConfigList.h.

Constructor & Destructor Documentation

ConfigList::ConfigList ( void  )

Definition at line 116 of file ConfigList.C.

References TRUE.

117 {
118  isokay = TRUE;
119  theList = NULL;
120 }
#define TRUE
Definition: common.h:119
ConfigList::ConfigList ( const char *  filename)

Definition at line 145 of file ConfigList.C.

References add_element(), endi(), FALSE, Fclose(), FileStack::file, FileStack::filename, Fopen(), iINFO(), iout, iWARN(), FileStack::linenumber, NAMD_die(), FileStack::next, and TRUE.

146 {
147  char *filename = new char[strlen(filename_in)+1];
148  strcpy(filename,filename_in);
149  FileStack *fileStack = 0;
150  FILE *infile;
151 
152  isokay = FALSE;
153  theList = NULL;
154  int linenumber = 0; // keep track of line numbers for searching out errors
155 
156  if (!strcmp(filename,"-")) { // should the input be from stdin?
157  infile = stdin;
158  } else {
159  if ( (infile = Fopen(filename, "r")) == NULL ) {
160  iout << iWARN << "Unable to open configuration file '"
161  << filename << "'.\n" << endi;
162  isokay = FALSE;
163  return;
164  }
165  }
166  isokay = TRUE; // file is now open
167 
168  // so read and parse it
169  char buf[1000]; // give myself lots of space
170  char *namestart, *nameend, *datastart, *dataend;
171  char *s;
172  int spacecount;
173  int fileok;
174  while ((fileok = ! ! fgets(buf, 999, infile)) || fileStack) {
175  if ( fileStack && ! fileok ) { // done with "source"
176  delete [] filename;
177  filename = fileStack->filename;
178  linenumber = fileStack->linenumber;
179  infile = fileStack->file;
180  FileStack *delStack = fileStack;
181  fileStack = fileStack->next;
182  delete delStack;
183  continue;
184  }
185  linenumber ++;
186  namestart = nameend = datastart = dataend = NULL;
187  spacecount = 0;
188 
189  for (s = buf; *s && *s!='\n'; s++) { // get to the end of the line
190  if (*s == '#') // found a comment, so break
191  break;
192  if ( !isspace(*s) ) // dataend will always be the last non-blank char
193  dataend = s;
194  if ( !isspace(*s) && !namestart) // found first character of name
195  {namestart = s; continue; }
196  if ( (isspace(*s) || *s == '=') && // found last character of name
197  namestart && !nameend)
198  nameend = s - 1;
199  if ( !isspace(*s) && !datastart && // found the next char. after name
200  nameend)
201  if (*s == '=' && spacecount == 0) // an equals is allowed
202  {spacecount++; continue; } // but only once
203  else
204  {datastart = s; continue; } // otherwise, use it
205  }
206  if (*s == '\n') // cut out the newline at the end
207  *s = 0;
208  else
209  if (*s != '#') { // then there was an overflow
210  iout << iWARN << "Line " << linenumber << " of configuration file "
211  << filename << " contains more than 999 characters."
212  << " Excess characters will be ignored.\n" << endi;
213  } else {
214  *s = 0; // delete the '#' character
215  }
216 
217 // I will also ignore line that I can't understand
218 // If there is any text on the line (as compared to a blank or commented)
219 // line, then I will say that there is a problem.
220  if (!namestart || !nameend || !datastart || !dataend) {
221  if (!namestart && datastart || namestart && !datastart) {// was some data
222  iout << iWARN << "Couldn't parse line " << linenumber << " in "
223  << "configuration file " << filename << ". The line was: "
224  << buf << "\n" << endi;
225  }
226  continue; // which ever the case, go to the next line
227  }
228 
229  if ( ! strncmp(namestart, "source", nameend-namestart+1) ) {
230  // see if the the name is "source"
231 
232  // store the old file data
233  FileStack *newStack = new FileStack;
234  newStack->filename = filename;
235  newStack->linenumber = linenumber;
236  newStack->file = infile;
237  newStack->next = fileStack;
238  fileStack = newStack;
239 
240  // copy the filename
241  char *cpychar = new char[dataend-datastart+2];
242  strcpy(cpychar,datastart);
243  filename = cpychar;
244 
245  // open the sourced file
246  if ( (infile = Fopen(filename, "r")) == NULL ) {
247  iout << iWARN << "Unable to open file '"
248  << filename << "' sourced by '"
249  << fileStack->filename << "' at line "
250  << fileStack->linenumber << ".\n" << endi;
251  isokay = FALSE;
252  return;
253  }
254  iout << iINFO << "Sourcing " << filename << "\n" << endi;
255  isokay = TRUE; // file is now open
256  linenumber = 0;
257 
258  } else if (datastart[0] == '{') {
259  // check if the data begins with a '{'
260  // will remove initial '{' and final '}' to match Tcl.
261  std::ostringstream alldata;
262  char newdata[1000];
263  int found_end = 0;
264  ++datastart; // remove initial '{'
265  int open_brace_count = 1;
266  char *newline = datastart;
267  strcat(newline,"\n"); // put back newline that was removed above
268 
269  while ( 1 ) {
270  int i;
271  int escape_next = 0;
272  for (i=0; i<1000; i++) {
273  if (! newline[i]) {
274  break;
275  }
276  if (escape_next) {
277  escape_next = 0;
278  continue;
279  }
280  if (newline[i] == '\\' && ! escape_next) {
281  escape_next = 1;
282  }
283  if (newline[i] == '{' && ! escape_next) {
284  ++open_brace_count;
285  }
286  if (newline[i] == '}' && ! escape_next) {
287  if ( ( found_end = ! --open_brace_count ) ) {
288  newline[i] = 0;
289  break;
290  }
291  }
292  }
293  alldata << newline;
294  if (found_end) break;
295  newline = newdata;
296  if ( ! fgets(newdata, 999, infile) ) break;
297  linenumber ++;
298  }
299  std::string alldatastr = alldata.str();
300  add_element(namestart, nameend-namestart+1, alldatastr.c_str(), alldata.str().length());
301  // delete string?
302  if (!found_end) {
303  *(nameend+1) = 0;
304  sprintf(newdata, "configuration file ended early while parsing line "
305  "%d of keyword structure %s", linenumber, namestart);
306  NAMD_die(newdata);
307  }
308  } else {
309  // now I can add the new values to the linked list
310  add_element( namestart, nameend - namestart + 1, datastart,
311  dataend - datastart + 1 );
312  }
313  } // while I can still get data with fgets
314 
315  if (strcmp(filename,"-")) { // close the input file if not stdin
316  Fclose(infile);
317  }
318  delete [] filename;
319 }
char * filename
Definition: ConfigList.C:127
std::ostream & iINFO(std::ostream &s)
Definition: InfoStream.C:81
void add_element(const char *s1, int len1, const char *s2, int len2)
Definition: ConfigList.C:58
int linenumber
Definition: ConfigList.C:126
std::ostream & endi(std::ostream &s)
Definition: InfoStream.C:54
#define FALSE
Definition: common.h:118
std::ostream & iWARN(std::ostream &s)
Definition: InfoStream.C:82
#define iout
Definition: InfoStream.h:51
FILE * Fopen(const char *filename, const char *mode)
Definition: common.C:273
FILE * file
Definition: ConfigList.C:125
void NAMD_die(const char *err_msg)
Definition: common.C:85
int Fclose(FILE *fout)
Definition: common.C:367
FileStack * next
Definition: ConfigList.C:128
#define TRUE
Definition: common.h:119
ConfigList::~ConfigList ( void  )

Definition at line 322 of file ConfigList.C.

References next().

323 {
324  ConfigListNode *curr=theList, *next=NULL;
325 
326  while ( curr!=NULL )
327  {
328  next = curr -> next;
329  delete curr; // the nasties for deleted the linked list of string
330  // has already been defined in the typedef struct
331  // for ConfigListNode
332  curr = next;
333  }
334 
335  theList = NULL;
336 } // all done
static Units next(Units u)
Definition: ParseOptions.C:48

Member Function Documentation

void ConfigList::add_element ( const char *  s1,
int  len1,
const char *  s2,
int  len2 
)

Definition at line 58 of file ConfigList.C.

References NAMD_die(), and next().

Referenced by ConfigList().

59 {
60  char *temps = new char[len1 + 1]; // what is the name?
61  if ( temps == NULL )
62  {
63  NAMD_die("new failed in ConfigList::add_element");
64  }
65 //printf("%s %s\n",s1,s2);
66 #ifndef NAMD_NO_STDOUT_FLUSH
67  fflush(stdout);
68 #endif
69  strncpy(temps, s1, len1);
70  temps[len1] = 0; // terminate the string
71  ConfigListNode *tmpList;
72 
73  tmpList = find_key_word( temps); // go through the list
74  if (tmpList == NULL ) { // if not found
75  tmpList = new ConfigListNode( theList, temps, NULL);// create a new node
76  if ( tmpList == NULL )
77  {
78  NAMD_die("new failed in ConfigList::add_element");
79  }
80  // and stick it on the head of the list
81  theList = tmpList; // note that I can continue to use tmpList
82  }
83 
84  if (len1 < len2) { // if string is smaller, don't realloc
85  delete [] temps;
86  temps = new char[len2 + 1];
87  if ( temps == NULL )
88  {
89  NAMD_die("new failed in ConfigList::add_element");
90  }
91  }
92  strncpy(temps, s2, len2); // get the new string
93  temps[len2] = 0;
94 
95  StringList *newStrList = new StringList(temps); // new element
96  if ( newStrList == NULL )
97  {
98  NAMD_die("new failed in ConfigList::add_element");
99  }
100  newStrList -> next = NULL;
101  if (tmpList -> data == NULL) { // no previous definition
102  tmpList -> data = newStrList; // so this is the new head
103  } else {
104  StringList *tmpStrList = tmpList -> data; // else,
105  while (tmpStrList -> next != NULL) // find the end of the list
106  tmpStrList = tmpStrList -> next;
107  tmpStrList -> next = newStrList; // and stick it on the tail
108  }
109 
110  delete [] temps;
111 }
static Units next(Units u)
Definition: ParseOptions.C:48
void NAMD_die(const char *err_msg)
Definition: common.C:85
StringList * ConfigList::find ( const char *  name) const

Definition at line 341 of file ConfigList.C.

Referenced by colvarproxy_namd::colvarproxy_namd(), WorkDistrib::createAtomLists(), ParseOptions::get(), GlobalMasterSymmetry::GlobalMasterSymmetry(), NamdState::loadStructure(), Molecule::prepare_qm(), ComputeQMMgr::recvPntChrg(), and ParseOptions::set().

342 {
343  ConfigListNode *tmpList;
344  tmpList = find_key_word(name);
345  if (tmpList != NULL)
346  return tmpList -> data;
347  return NULL;
348 }
ConfigListNode* ConfigList::head ( void  ) const
inline

Definition at line 126 of file ConfigList.h.

Referenced by ParseOptions::set().

126 { return theList; } // return everything
Bool ConfigList::okay ( void  )
inline

Definition at line 120 of file ConfigList.h.

Referenced by NamdState::configListInit().

120 { return isokay; }

The documentation for this class was generated from the following files: