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