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=20);
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=20)
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
00268 Data(const std::string &name, int n,
00269 const double *x, const double *y,
00270 const double *dx=0, const double *dy=0);
00271
00273 std::string name() { return name_; }
00274
00276 int hasErrors() { return (dy_ || dx_); }
00277
00283 void setNum(int i) { setnum_= i; }
00284
00286 int num() { return setnum_; }
00287
00289 void setXOffset(double x) { xoffs_= x; }
00291 void setYOffset(double y) { yoffs_= y; }
00293 void setScaling(double s) { scale_= s; }
00294
00309 void autoscale(double &xmin, double &xmax, double &ymin, double &ymax,
00310 double XMIN, double XMAX, double YMIN, double YMAX,
00311 double errorfac= 1.0);
00312
00324 void saveinfo(FILE *f, const StringVec *daSet=0);
00325
00333 void savedata(FILE *f, int correctLog= 0);
00334 };
00335
00336 class Save;
00337
00347 class Graph : public EnvironmentUser {
00349 int graphnum_;
00350
00352 Save* saver_;
00353
00355 std::vector <Data *> dataVec_;
00357 std::vector <std::string> params_;
00358
00360 std::map<int, int> literalData_;
00361
00363 double xoffs_, yoffs_;
00364
00366 double scale_;
00367
00371 int correctLog_;
00372
00373 public:
00382 Graph(Save *saver, int logplot=0);
00383
00389 void setGraph(int i) { graphnum_= i; }
00390
00395 void addData(Data *d) {
00396 dataVec_.push_back(d);
00397 d->env()->setParent(env());
00398 }
00399
00401 std::vector <Data *> *data() { return &dataVec_; }
00402
00404 void setXOffset(double x) { xoffs_= x; }
00405
00407 void setYOffset(double y) { yoffs_= y; }
00408
00410 void setScaling(double s) { scale_= s; }
00411
00413 double xoffset() { return xoffs_; }
00414
00416 double yoffset() { return yoffs_; }
00417
00419 double scale() { return scale_; }
00420
00422 int correctLog() { return correctLog_; }
00423
00425 void addParam(const std::string &name,double value);
00426
00428 void saveprep(const StringVecMap *daSets);
00429
00444 void saveinfo(FILE *f,
00445 const StringVec *daGraph=0,
00446 const StringVecMap *daSets=0,
00447 const StringVecMap *daStrings= 0);
00448
00457 void savedata(FILE *f, StringMap *literalData, int dataonly= 0);
00458 };
00459
00525 class Save : public EnvironmentUser
00526 {
00527 protected:
00528
00530 struct CopySrc
00531 {
00532 int g;
00533 int s;
00534 Data *src;
00535
00537 CopySrc() : g(-1),s(-1),src(0) {};
00538 };
00539
00541 typedef std::map<int,CopySrc> CopyMap;
00542
00544 typedef std::map<int,CopyMap> Copy2Map;
00545
00552 struct Template
00553 {
00554 std::string filename_;
00555 std::string header_;
00556 StringVec common_;
00557 String2Vec strings_;
00558 StringVecMap graphs_;
00559 StringVec2Map sets_;
00560 StringVec2Map params_;
00561 String2Vec request_;
00562 StringMap data_;
00563 Copy2Map copy_;
00564 std::map<int, int> ignore_;
00565 int gpp_;
00566 int ignores_;
00567 int useG0_;
00568 int valid_;
00569 };
00570
00576 Template tmpl_;
00577
00579 std::vector<Graph*> graphsVec_;
00580
00582 StringStringMap docEnvs_;
00584 StringMap myEnv_;
00585
00587 std::string nameTmpl_;
00588
00590 int allowPipe_;
00591
00592 public:
00593
00595 Save();
00596
00598 virtual ~Save() { ; }
00599
00601 virtual Graph *newGraph(int logplot= 0) {
00602 Graph *g= new Graph(this,logplot);
00603 if (!g) return 0;
00604 graphsVec_.push_back(g);
00605 return g;
00606 }
00607
00613 int isCopydata(int g, int s);
00614
00619 Data *copydata(int g, int s)
00620 {
00621 if (isCopydata(g,s)) return tmpl_.copy_[g][s].src;
00622 return 0;
00623 }
00624
00629 void regCopydata(int g, int s, Data* src);
00630
00635 void clearCopydata();
00636
00638 virtual Graph *graph(int i)
00639 {
00640 if (i<0 || i>=int(graphsVec_.size())) return 0;
00641 return graphsVec_[i];
00642 }
00643
00645 virtual int graphs() { return graphsVec_.size(); }
00646
00655 void setOutputName(const std::string &name) { nameTmpl_= name; }
00656
00667 void enablePipe(int i) { allowPipe_= i; }
00668
00670 int pipeEnabled() { return allowPipe_; }
00671
00697 virtual int loadTemplate(const char *filename, int useS0= 0);
00698
00716 virtual String2Vec templateDataRequestInfo();
00717
00739 virtual void save();
00740 };
00741
00742 }
00743
00744
00745 #endif
00746