ConfigList Class Reference

#include <ConfigList.h>

List of all members.

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

Classes

class  ConfigListNode


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.

00117 {
00118   isokay = TRUE;
00119   theList = NULL;
00120 }

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.

00146 {
00147   char *filename = new char[strlen(filename_in)+1];
00148   strcpy(filename,filename_in);
00149   FileStack *fileStack = 0;
00150   FILE *infile;
00151   
00152   isokay = FALSE;
00153   theList = NULL;
00154   int linenumber = 0;   // keep track of line numbers for searching out errors
00155 
00156   if (!strcmp(filename,"-")) {  // should the input be from stdin?
00157     infile = stdin;
00158   } else {
00159     if ( (infile = Fopen(filename, "r")) == NULL ) {
00160         iout << iWARN << "Unable to open configuration file '" 
00161                  << filename << "'.\n" << endi;
00162         isokay = FALSE;
00163         return;
00164     }
00165   }
00166   isokay = TRUE;         // file is now open
00167 
00168      // so read and parse it
00169   char buf[1000]; // give myself lots of space
00170   char *namestart, *nameend, *datastart, *dataend;
00171   char *s;
00172   int spacecount;
00173   int fileok;
00174   while ((fileok = ! ! fgets(buf, 999, infile)) || fileStack) {
00175     if ( fileStack && ! fileok ) { // done with "source"
00176       delete [] filename;
00177       filename = fileStack->filename;
00178       linenumber = fileStack->linenumber;
00179       infile = fileStack->file;
00180       FileStack *delStack = fileStack;
00181       fileStack = fileStack->next;
00182       delete delStack;
00183       continue;
00184     }
00185     linenumber ++;        
00186     namestart = nameend = datastart = dataend = NULL;
00187     spacecount = 0;
00188     
00189     for (s = buf; *s && *s!='\n'; s++) {    // get to the end of the line
00190        if (*s == '#')                       // found a comment, so break
00191           break;
00192        if ( !isspace(*s) )    // dataend will always be the last non-blank char
00193           dataend = s;
00194        if ( !isspace(*s) && !namestart)     // found first character of name
00195           {namestart = s; continue; }
00196        if ( (isspace(*s)  || *s == '=') &&  // found last character of name
00197                  namestart && !nameend)
00198           nameend = s - 1;
00199        if ( !isspace(*s) && !datastart &&   // found the next char. after name
00200                  nameend)
00201           if (*s == '=' && spacecount == 0) // an equals is allowed
00202              {spacecount++; continue; }     // but only once
00203             else
00204              {datastart = s; continue; }    // otherwise, use it
00205     }
00206     if (*s == '\n')          // cut out the newline at the end
00207       *s = 0;
00208      else
00209       if (*s != '#') {       // then there was an overflow
00210         iout << iWARN << "Line " << linenumber << " of configuration file "
00211                  << filename << " contains more than 999 characters."
00212                  << "  Excess characters will be ignored.\n" << endi;
00213       } else {
00214         *s = 0;  // delete the '#' character
00215       }
00216 
00217 // I will also ignore line that I can't understand
00218 // If there is any text on the line (as compared to a blank or commented)
00219 //   line, then I will say that there is a problem.
00220     if (!namestart || !nameend || !datastart || !dataend) {
00221       if (!namestart && datastart || namestart && !datastart) {// was some data
00222         iout << iWARN << "Couldn't parse line " << linenumber << " in "
00223                  << "configuration file " << filename << ".  The line was: "
00224                  << buf << "\n" << endi;
00225       }
00226       continue;  // which ever the case, go to the next line
00227     }
00228 
00229    if ( ! strncmp(namestart, "source", nameend-namestart+1) )  {
00230      // see if the the name is "source"
00231 
00232      // store the old file data
00233      FileStack *newStack = new FileStack;
00234      newStack->filename = filename;
00235      newStack->linenumber = linenumber;
00236      newStack->file = infile;
00237      newStack->next = fileStack;
00238      fileStack = newStack;
00239 
00240      // copy the filename
00241      char *cpychar = new char[dataend-datastart+2];
00242      strcpy(cpychar,datastart);
00243      filename = cpychar;
00244 
00245      // open the sourced file
00246      if ( (infile = Fopen(filename, "r")) == NULL ) {
00247         iout << iWARN << "Unable to open file '" 
00248                  << filename << "' sourced by '"
00249                 << fileStack->filename << "' at line "
00250                 << fileStack->linenumber << ".\n" << endi;
00251         isokay = FALSE;
00252         return;
00253      }
00254      iout << iINFO << "Sourcing " << filename << "\n" << endi;
00255      isokay = TRUE;         // file is now open
00256      linenumber = 0;
00257      
00258    } else if (datastart[0] == '{') {
00259      // check if the data begins with a '{'
00260      // will remove initial '{' and final '}' to match Tcl.
00261      std::ostringstream alldata;
00262      char newdata[1000];
00263      int found_end = 0;
00264      ++datastart;  // remove initial '{'
00265      int open_brace_count = 1;
00266      char *newline = datastart;
00267      strcat(newline,"\n");  // put back newline that was removed above
00268 
00269      while ( 1 ) {
00270        int i;
00271        int escape_next = 0;
00272        for (i=0; i<1000; i++) {
00273          if (! newline[i]) {
00274            break;
00275          }
00276          if (escape_next) {
00277            escape_next = 0;
00278            continue;
00279          }
00280          if (newline[i] == '\\' && ! escape_next) {
00281            escape_next = 1;
00282          }
00283          if (newline[i] == '{' && ! escape_next) {
00284            ++open_brace_count;
00285          }
00286          if (newline[i] == '}' && ! escape_next) {
00287            if ( ( found_end = ! --open_brace_count ) ) {
00288              newline[i] = 0;
00289              break;
00290            }
00291          }
00292        }
00293        alldata << newline;
00294        if (found_end) break;
00295        newline = newdata;
00296        if ( ! fgets(newdata, 999, infile) ) break;
00297        linenumber ++;
00298      }
00299      std::string alldatastr = alldata.str();
00300      add_element(namestart, nameend-namestart+1, alldatastr.c_str(), alldata.str().length());
00301      // delete string?
00302      if (!found_end) {
00303        *(nameend+1) = 0;
00304        sprintf(newdata, "configuration file ended early while parsing line "
00305                "%d of keyword structure %s", linenumber, namestart);
00306        NAMD_die(newdata);
00307      }
00308    } else {
00309      // now I can add the new values to the linked list
00310      add_element( namestart, nameend - namestart + 1, datastart,
00311                   dataend - datastart + 1 );
00312    }
00313   } // while I can still get data with fgets
00314   
00315   if (strcmp(filename,"-")) {  // close the input file if not stdin
00316     Fclose(infile);
00317   }
00318   delete [] filename;
00319 }

ConfigList::~ConfigList ( void   ) 

Definition at line 322 of file ConfigList.C.

References next().

00323 {
00324   ConfigListNode *curr=theList, *next=NULL;
00325 
00326   while ( curr!=NULL ) 
00327   {
00328      next = curr -> next;
00329      delete curr;     // the nasties for deleted the linked list of string
00330                       // has already been defined in the typedef struct
00331                       // for ConfigListNode
00332      curr = next;
00333   }
00334 
00335   theList = NULL;
00336 } // all done


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().

00059 {
00060     char *temps = new char[len1 + 1];  // what is the name?
00061     if ( temps == NULL )
00062     {
00063       NAMD_die("new failed in ConfigList::add_element");
00064     }
00065 //printf("%s %s\n",s1,s2);
00066 #ifndef NAMD_NO_STDOUT_FLUSH
00067     fflush(stdout);
00068 #endif
00069     strncpy(temps, s1, len1);
00070     temps[len1] = 0;                   //       terminate the string
00071     ConfigListNode *tmpList;
00072                                        
00073     tmpList = find_key_word( temps);  // go through the list
00074     if (tmpList == NULL )  {          // if not found
00075        tmpList = new ConfigListNode( theList, temps, NULL);// create a new node
00076        if ( tmpList == NULL )
00077        {
00078          NAMD_die("new failed in ConfigList::add_element");
00079        }
00080                                     // and stick it on the head of the list
00081        theList = tmpList;           // note that I can continue to use tmpList
00082     }
00083 
00084     if (len1 < len2) {                  // if string is smaller, don't realloc
00085       delete [] temps;
00086       temps = new char[len2 + 1];
00087       if ( temps == NULL )
00088       {
00089         NAMD_die("new failed in ConfigList::add_element");
00090       }
00091     }
00092     strncpy(temps, s2, len2);           // get the new string
00093     temps[len2] = 0;
00094 
00095     StringList *newStrList = new StringList(temps);  // new element
00096     if ( newStrList == NULL )
00097     {
00098       NAMD_die("new failed in ConfigList::add_element");
00099     }
00100     newStrList -> next = NULL;
00101     if (tmpList -> data == NULL) {       // no previous definition
00102       tmpList -> data = newStrList;      //    so this is the new head
00103     } else {
00104       StringList *tmpStrList = tmpList -> data;   // else,
00105       while (tmpStrList -> next != NULL)          // find the end of the list
00106         tmpStrList = tmpStrList -> next;
00107       tmpStrList -> next = newStrList;            // and stick it on the tail
00108     }
00109     
00110     delete [] temps;
00111 }

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().

00342 {
00343   ConfigListNode *tmpList;
00344   tmpList = find_key_word(name);
00345   if (tmpList != NULL)
00346     return tmpList -> data;
00347   return NULL;
00348 }

ConfigListNode* ConfigList::head ( void   )  const [inline]

Definition at line 126 of file ConfigList.h.

00126 { return theList;  } // return everything

Bool ConfigList::okay ( void   )  [inline]

Definition at line 120 of file ConfigList.h.

Referenced by NamdState::configListInit().

00120 { return isokay; }


The documentation for this class was generated from the following files:
Generated on Wed Nov 22 01:17:20 2017 for NAMD by  doxygen 1.4.7