extern "C" { #include #include #include } #include #include #include #include #include "gracetmpl.h" int debug= 0; using namespace GraceTMPL; using namespace std; void loadXYdY(FILE *f, GraceTMPL::Graph *graph, const char *name=0) { std::vector dataX, dataY, dataDY; unsigned int numDY= 0, cmtCNT=0; char line[3000]; fgets(line,3000,f); while (fgets(line,3000,f)) { double x,y,dy; // eat comments (anything beginning with '#') // and store the comment for use in the template char *cmt= index(line,'#'); if (cmt) { cmt++; char comment[20]; snprintf(comment,20,"comment%d",cmtCNT++); char *eol= index(cmt,'\n'); if (eol) *eol= 0; graph->setenv(comment,cmt+1); cmt=0; } switch(sscanf(line,"%lg %lg %lg",&x,&y,&dy)) { case 3: dataDY.push_back(dy); dataY.push_back(y); dataX.push_back(x); numDY++; break; case 2: dataDY.push_back(0); dataY.push_back(y); dataX.push_back(x); break; case 1: dataDY.push_back(0); dataY.push_back(0); dataX.push_back(x); break; default: break; } } if (!dataX.size()) return; double *daX= new double[dataX.size()]; double *daY= new double[dataY.size()]; double *daDY= new double[dataDY.size()]; for (unsigned int i=0; iaddData(new GraceTMPL::Data((name)?name:"data",dataX.size(),daX,daY,0,daDY)); else graph->addData(new GraceTMPL::Data((name)?name:"data",dataX.size(),daX,daY,0,0)); delete[] daX; delete[] daY; delete[] daDY; } void loadBlockData(FILE *f, GraceTMPL::Graph *graph, int nxy, const char *name= 0, int err= 0) { typedef std::vector DVec; DVec dataX, dataY[nxy], dataDY[nxy]; unsigned int cmtCNT=0; int ycnt= 0; fprintf(stderr,"trying to get %d values %sfrom %s\n",nxy,err?"with errors ":"",name?name:""); char line[3000]; fgets(line,3000,f); while (fgets(line,3000,f)) { double x; char *optr= line, *nptr; // eat comments (anything beginning with '#') // and store the comment for use in the template char *cmt= index(line,'#'); if (cmt) { cmt++; char comment[20]; snprintf(comment,20,"comment%d",cmtCNT++); char *eol= index(cmt,'\n'); if (eol) *eol= 0; graph->setenv(comment,cmt+1); cmt=0; } x= strtod(optr,&nptr); if (nptr!=optr) { optr= nptr; dataX.push_back(x); for (int i=0; i=ycnt) ycnt= i+1; optr= nptr; } } } if (!dataX.size()) return; double *daX= new double[dataX.size()]; double *daY= new double[dataX.size()]; double *daDY= new double[dataX.size()]; for (unsigned int i=0; iaddData(new GraceTMPL::Data((name)?name:"data",dataX.size(),daX,daY,0,daDY)); else graph->addData(new GraceTMPL::Data((name)?name:"data",dataX.size(),daX,daY,0,0)); } delete[] daX; delete[] daY; delete[] daDY; } void loadFile(const string &name, GraceTMPL::Save *xmgr) { if (!xmgr) return; int nxy= 0,nxyerr=0; FILE *f= fopen(name.c_str(),"r"); if (!f) { cerr << "could not open file \""<newGraph(); // split filename into path and rest: string file(name); string path; string fname(name); typedef string::size_type ST; ST p1= file.rfind("/"); if (p1!=string::npos) { path= file.substr(0,p1); fname= file.substr(p1+1,file.length()); } if (path[0]!='/') { path= string(getenv("PWD"))+string("/")+path; } char rpath[PATH_MAX]; if (realpath(path.c_str(),rpath)) path= rpath; // set path, filename and the original name in the environment: graph->setenv("path",path); graph->setenv("file",fname); graph->setenv("filename",name); char line[3000]; fgets(line,3000,f); if (!strncmp(line,"# NXYDY",7)) { nxy= atoi(line+8); nxyerr= 1; } else if (!strncmp(line,"# NXY",5)) { nxy= atoi(line+6); nxyerr= 0; } else { fseek(f,0,SEEK_SET); } if (nxy) loadBlockData(f,graph,nxy,fname.c_str(),nxyerr); else loadXYdY(f,graph,fname.c_str()); fclose(f); } int main(int argc, char **argv) { // default template for the destination filename: string outname("${template}-${pz}.agr"); string tmpl; vector files; map defines; int oc, spg; int simple=0; while (1) { int option_index = 0; static struct option long_options[] = { {"help", 0, 0, 'h'}, {"output", 1, 0, 'o'}, {"simple", 0, 0, 's'}, {"spg", 1, 0, 'S'}, {"template",1, 0, 't'}, {0, 0, 0, 0} }; oc = getopt_long (argc, argv, "-?D:ho:t:S:sV", long_options, &option_index); if (oc == -1) break; switch (oc) { case '?': case 'h': cerr <<"gracetmpldemo (C) 1999,2000 by Andy Thaller " <<"\n" <<"\n" <<"Usage: gracetmpldemo [-h] [options] file [..]\n" <<"\n" <<"Options:\n" <<" -h, --help : show this help and exit\n" <<" -t, --template: use xmgrace template for outputting data\n" <<" -s, --simple : use set formats from 'g0' for all graphs\n" <<" -S, --spg : number of Sets Per Graph\n" <<" -o, --output : specify an alternative destination filename\n" <<" -D name=value : set a variable in the sheet's environment\n" <<"\n"; exit(-1); break; case 'd': debug++; break; case 't': tmpl = string(optarg); break; case 's': simple = 1; break; case 'S': spg = atoi(optarg); break; case 'o': outname = string(optarg); break; case 'D': { string oa(optarg),name,value; string::size_type pos=oa.find("="); if (pos!=string::npos) { name= oa.substr(0,pos); value= oa.substr(pos+1,oa.length()); defines[name]= value; } else { cerr << "Warning: option '-D' needs an argument in the form " << "'name=value'\n"; } break; } case 1: /* see getopt_long(3): generated by "-" in optstring to denote non-opt */ files.push_back(string(optarg)); break; } } if (!files.size()) { cerr << "no files given on command line, bailing out.\n"; exit(1); } /* One and only one template (if any) for all the stuff to follow: * We search for a template "TMPL" both in "./" and "~/.grace/" */ GraceTMPL::Save *xmgr= 0; if (tmpl.length()) { if (!(xmgr= new GraceTMPL::Save())) { cerr << "Could not produce GraceTMPL::Save\n"; exit(1); } const char *homedir= getenv("HOME"); int l= tmpl.length()+strlen(homedir)+9; char *tmpl2= new char[l]; snprintf(tmpl2,l,"%s/.grace/%s",homedir,tmpl.c_str()); if (xmgr->loadTemplate(tmpl.c_str(),simple) || xmgr->loadTemplate(tmpl2,simple)) { /* set the filename of the template in the environment * regardless of where we found it: */ xmgr->setenv("template",tmpl); xmgr->setOutputName(outname); map::iterator daDef; for (daDef=defines.begin(); daDef!=defines.end(); ++daDef) { xmgr->setenv(daDef->first,daDef->second); } } } for (unsigned int i=0; i < files.size(); i++) { loadFile(files[i],xmgr); } if (xmgr) { xmgr->save(); delete xmgr; } exit(0); }