1 //
2 // files.cc
3 //
4 // Copyright (C) 1996 Limit Point Systems, Inc.
5 //
6 // Author: Curtis Janssen <cljanss@limitpt.com>
7 // Maintainer: LPS
8 //
9 // This file is part of the SC Toolkit.
10 //
11 // The SC Toolkit is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // The SC Toolkit is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
23 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 //
25 // The U.S. Government is granted a limited license as per AL 91-7.
26 //
27 
28 #include <ctype.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <fstream>
32 
33 #include <scconfig.h>
34 #ifdef HAVE_SSTREAM
35 #  include <sstream>
36 #else
37 #  include <strstream.h>
38 #endif
39 
40 #include <sys/stat.h>
41 
42 #include <util/misc/formio.h>
43 #include <util/group/message.h>
44 #include <chemistry/qc/basis/files.h>
45 
46 using namespace std;
47 using namespace sc;
48 
BasisFileSet(const Ref<KeyVal> & keyval)49 BasisFileSet::BasisFileSet(const Ref<KeyVal>& keyval)
50 {
51   nbasissets_ = 0;
52   basissets_ = 0;
53 
54   dir_[0] = keyval->pcharvalue("basisdir");
55   dir_[1] = getenv("SCLIBDIR");
56   if (dir_[1]) {
57       char *tmp = strchr(dir_[1],'=');
58       if (!tmp) tmp = dir_[1];
59       else tmp = &tmp[1];
60       dir_[1] = strcpy(new char[strlen(tmp)+6+1], tmp);
61       strcat(dir_[1], "/basis");
62     }
63   else {
64       struct stat sb;
65       const char *bdir = SCDATADIR "/basis";
66 #ifdef SRC_SCLIBDIR
67       if (stat(bdir, &sb) != 0) {
68           bdir = SRC_SCLIBDIR "/basis";
69         }
70 #endif
71       dir_[1] = strcpy(new char[strlen(bdir)+1], bdir);
72     }
73 }
74 
~BasisFileSet()75 BasisFileSet::~BasisFileSet()
76 {
77   int i;
78   for (i=0; i<nbasissets_; i++) delete[] basissets_[i];
79   delete[] basissets_;
80   delete[] dir_[0];
81   delete[] dir_[1];
82 }
83 
84 Ref<KeyVal>
keyval(const Ref<KeyVal> & keyval,const char * basisname)85 BasisFileSet::keyval(const Ref<KeyVal> &keyval, const char *basisname)
86 {
87   int i;
88 
89   // check if the basisname has already been located
90   for (i=0; i<nbasissets_; i++) {
91       if (!strcmp(basisname, basissets_[i])) return keyval;
92     }
93 
94   char *filename = new char[strlen(basisname)+1];
95 
96   for (i=0; basisname[i] != '\0'; i++) {
97       if (basisname[i] >= 'A' && basisname[i] <= 'Z') {
98           filename[i] = tolower(basisname[i]);
99         }
100       else if (basisname[i] == ','
101                || basisname[i] == ' ') {
102           filename[i] = '_';
103         }
104       else if (basisname[i] == '+') {
105           filename[i] = 'P';
106         }
107       else if (basisname[i] == '*') {
108           filename[i] = 'S';
109         }
110       else if (basisname[i] == '(') {
111           filename[i] = 'L';
112         }
113       else if (basisname[i] == ')') {
114           filename[i] = 'R';
115         }
116       else {
117           filename[i] = basisname[i];
118         }
119     }
120   filename[i] = '\0';
121 
122   Ref<MessageGrp> grp = MessageGrp::get_default_messagegrp();
123 
124   // find the basis file
125   Ref<KeyVal> newkeyval(keyval);
126   for (i=0; i<2; i++) {
127       if (!dir_[i]) continue;
128       if (grp->me() == 0) {
129           char *path = new char[strlen(dir_[i]) + strlen(filename) + 5];
130           strcpy(path, dir_[i]);
131           strcat(path, "/");
132           strcat(path, filename);
133           strcat(path, ".kv");
134 
135           // test to see if the file can be opened read only.
136           ifstream is(path);
137           if (is.good()) {
138               int status = 1;
139               ExEnv::out0() << indent << "Reading file " << path << "." << endl;
140               grp->bcast(status);
141 #ifdef HAVE_SSTREAM
142               ostringstream ostrs;
143 #else
144               ostrstream ostrs;
145 #endif
146               is >> ostrs.rdbuf();
147 #ifdef HAVE_SSTREAM
148               int n = 1 + strlen(ostrs.str().c_str());
149               char *in_char_array = strcpy(new char[n],ostrs.str().c_str());
150 #else
151               ostrs << ends;
152               char *in_char_array = ostrs.str();
153               int n = ostrs.pcount();
154 #endif
155               grp->bcast(n);
156               grp->bcast(in_char_array, n);
157               Ref<ParsedKeyVal> parsedkv = new ParsedKeyVal;
158               parsedkv->parse_string(in_char_array);
159               delete[] in_char_array;
160               Ref<KeyVal> libkeyval = parsedkv.pointer();
161               newkeyval = new AggregateKeyVal(keyval,libkeyval);
162               delete[] path;
163               break;
164             }
165           else {
166               int status = 0;
167               grp->bcast(status);
168             }
169           delete[] path;
170         }
171       else {
172           int status;
173           grp->bcast(status);
174           if (status) {
175               int n;
176               grp->bcast(n);
177               char *in_char_array = new char[n];
178               grp->bcast(in_char_array, n);
179               Ref<ParsedKeyVal> parsedkv = new ParsedKeyVal;
180               parsedkv->parse_string(in_char_array);
181               delete[] in_char_array;
182               Ref<KeyVal> libkeyval = parsedkv.pointer();
183               newkeyval = new AggregateKeyVal(keyval,libkeyval);
184               break;
185             }
186         }
187     }
188 
189   // add the current basis set to basissets_
190   char **newbasissets = new char*[nbasissets_+1];
191   for (i=0; i<nbasissets_; i++) newbasissets[i] = basissets_[i];
192   newbasissets[nbasissets_] = strcpy(new char[strlen(basisname)+1],
193                                      basisname);
194   nbasissets_++;
195   delete[] basissets_;
196   basissets_ = newbasissets;
197 
198   delete[] filename;
199 
200   return newkeyval;
201 }
202 
203 /////////////////////////////////////////////////////////////////////////////
204 
205 // Local Variables:
206 // mode: c++
207 // c-file-style: "CLJ"
208 // End:
209