00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __GRACETMPL_H__
00021 #define __GRACETMPL_H__
00022
00023 #include <vector>
00024 #include <string>
00025 #include <map>
00026
00027 extern "C" {
00028 #include <stdio.h>
00029 }
00030
00031
00038 namespace GraceTMPL {
00039
00041 typedef std::vector<std::string> StringVec;
00042
00044 typedef std::vector<StringVec> String2Vec;
00045
00047 typedef std::map<int,StringVec> StringVecMap;
00048
00050 typedef std::map<int,StringVecMap> StringVec2Map;
00051
00053 typedef std::map<std::string,std::string> StringMap;
00054
00056 typedef std::map<std::string,StringMap*> StringStringMap;
00057
00060 std::string smashVars(const std::string &from);
00061
00063 std::string stringNum(double d, const char *fmt= "%lg");
00065 std::string stringNum(float d, const char *fmt= "%g");
00067 std::string stringNum(long i, const char *fmt= "%ld");
00069 std::string stringNum(int i, const char *fmt= "%d");
00070
00078 class Environment {
00079 std::string name_;
00080 Environment *parent_;
00081 std::map<std::string,std::string> variable_;
00082 std::map<std::string,Environment *> context_;
00083 int usage_;
00084
00085 public:
00087 Environment(Environment *parent= 0)
00088 : name_(""), parent_(parent), usage_(1) {};
00089
00091 void clear() {
00092 variable_.clear();
00093
00094 }
00095
00097 void setParent(Environment *parent) {
00098 parent_= parent;
00099 if (parent_ && name_!="") parent_->add(name_,this);
00100 }
00101
00103 void setName(const std::string &name) {
00104 name_= name;
00105 if (parent_ && name_!="") parent_->add(name_,this);
00106 }
00107
00109 void set(const std::string &name,const std::string &value) {
00110 variable_[name]= value;
00111 }
00112
00114 void add(const std::string &name,Environment *value) {
00115 if (context_[name]== value) return;
00116 context_[name]= value;
00117 value->setParent(this);
00118 value->setName(name);
00119
00120 }
00121
00123 Environment *use() { usage_++; return this; }
00124
00126 int unuse() { return !(--usage_); }
00127
00157 std::string expand(const std::string &, int nests=0);
00158
00165 std::string substitute(const std::string &context,
00166 const std::string &variable,
00167 const std::string &fallback);
00168 };
00169
00174 class EnvironmentUser {
00175
00176 protected:
00178 Environment *env_;
00179
00180 public:
00182 EnvironmentUser() { env_= new Environment(); }
00183
00185 ~EnvironmentUser() { if (env_ && env_->unuse()) delete env_; }
00186
00188 Environment *env() { return env_; }
00189
00195 void setenv(Environment *env)
00196 {
00197 if (!env) return;
00198 if (env_ && env_->unuse()) delete env_;
00199 env_= env->use();
00200 }
00201
00203 void setenv(const std::string &name,const std::string &value)
00204 {
00205 if (!env_) return;
00206 env_->set(name,value);
00207 }
00208
00210 void setenv(const std::string &name,double value)
00211 {
00212 setenv(name,stringNum(value));
00213 }
00214
00217 std::string expand(const std::string &str, int nests=0)
00218 {
00219 if (!env_) return "";
00220 return env_->expand(str, nests);
00221 }
00222 };
00223
00232 class Data : public EnvironmentUser {
00233
00235 std::string name_;
00236
00238 int n_;
00239
00241 int setnum_;
00242
00244 double *x_,*y_,*dx_,*dy_;
00245
00247 double xoffs_, yoffs_;
00248
00250 double scale_;
00251
00252 public:
00253
00258 Data();
00259
00266 Data(const std::string &name, int n,
00267 const double *x, const double *y,
00268 const double *dx=0, const double *dy=0);
00269
00271 std::string name() { return name_; }
00272
00274 int hasErrors() { return (dy_ || dx_); }
00275
00281 void setNum(int i) { setnum_= i; }
00282
00284 int num() { return setnum_; }
00285
00287 void setXOffset(double x) { xoffs_= x; }
00289 void setYOffset(double y) { yoffs_= y; }
00291 void setScaling(double s) { scale_= s; }
00292
00307 void autoscale(double &xmin, double &xmax, double &ymin, double &ymax,
00308 double XMIN, double XMAX, double YMIN, double YMAX,
00309 double errorfac= 1.0);
00310
00322 void saveinfo(FILE *f, const StringVec *daSet=0);
00323
00331 void savedata(FILE *f, int correctLog= 0);
00332 };
00333
00334 class Save;
00335
00345 class Graph : public EnvironmentUser {
00347 int graphnum_;
00348
00350 Save* saver_;
00351
00353 std::vector <Data *> dataVec_;
00355 std::vector <std::string> params_;
00356
00358 std::map<int, int> literalData_;
00359
00361 double xoffs_, yoffs_;
00362
00364 double scale_;
00365
00369 int correctLog_;
00370
00371 public:
00380 Graph(Save *saver, int logplot=0);
00381
00387 void setGraph(int i) { graphnum_= i; }
00388
00393 void addData(Data *d) {
00394 dataVec_.push_back(d);
00395 d->env()->setParent(env());
00396 }
00397
00399 std::vector <Data *> *data() { return &dataVec_; }
00400
00402 void setXOffset(double x) { xoffs_= x; }
00403
00405 void setYOffset(double y) { yoffs_= y; }
00406
00408 void setScaling(double s) { scale_= s; }
00409
00411 double xoffset() { return xoffs_; }
00412
00414 double yoffset() { return yoffs_; }
00415
00417 double scale() { return scale_; }
00418
00420 int correctLog() { return correctLog_; }
00421
00423 void addParam(const std::string &name,double value);
00424
00426 void saveprep(const StringVecMap *daSets);
00427
00442 void saveinfo(FILE *f,
00443 const StringVec *daGraph=0,
00444 const StringVecMap *daSets=0,
00445 const StringVecMap *daStrings= 0);
00446
00455 void savedata(FILE *f, StringMap *literalData, int dataonly= 0);
00456 };
00457
00523 class Save : public EnvironmentUser
00524 {
00525 protected:
00526
00528 struct CopySrc
00529 {
00530 int g;
00531 int s;
00532 Data *src;
00533
00535 CopySrc() : g(-1),s(-1),src(0) {};
00536 };
00537
00539 typedef std::map<int,CopySrc> CopyMap;
00540
00542 typedef std::map<int,CopyMap> Copy2Map;
00543
00550 struct Template
00551 {
00552 std::string filename_;
00553 std::string header_;
00554 StringVec common_;
00555 String2Vec strings_;
00556 StringVecMap graphs_;
00557 StringVec2Map sets_;
00558 StringVec2Map params_;
00559 String2Vec request_;
00560 StringMap data_;
00561 Copy2Map copy_;
00562 std::map<int, int> ignore_;
00563 int gpp_;
00564 int ignores_;
00565 int useG0_;
00566 int valid_;
00567 };
00568
00574 Template tmpl_;
00575
00577 std::vector<Graph*> graphsVec_;
00578
00580 StringStringMap docEnvs_;
00582 StringMap myEnv_;
00583
00585 std::string nameTmpl_;
00586
00588 int allowPipe_;
00589
00590 public:
00591
00593 Save();
00594
00596 virtual ~Save() { ; }
00597
00599 virtual Graph *newGraph(int logplot= 0) {
00600 Graph *g= new Graph(this,logplot);
00601 if (!g) return 0;
00602 graphsVec_.push_back(g);
00603 return g;
00604 }
00605
00611 int isCopydata(int g, int s);
00612
00617 Data *copydata(int g, int s)
00618 {
00619 if (isCopydata(g,s)) return tmpl_.copy_[g][s].src;
00620 return 0;
00621 }
00622
00627 void regCopydata(int g, int s, Data* src);
00628
00633 void clearCopydata();
00634
00636 virtual Graph *graph(int i)
00637 {
00638 if (i<0 || i>=int(graphsVec_.size())) return 0;
00639 return graphsVec_[i];
00640 }
00641
00643 virtual int graphs() { return graphsVec_.size(); }
00644
00653 void setOutputName(const std::string &name) { nameTmpl_= name; }
00654
00665 void enablePipe(int i) { allowPipe_= i; }
00666
00668 int pipeEnabled() { return allowPipe_; }
00669
00695 virtual int loadTemplate(const char *filename, int useS0= 0);
00696
00714 virtual String2Vec templateDataRequestInfo();
00715
00737 virtual void save();
00738 };
00739
00740 }
00741
00742
00743 #endif
00744