extern "C" {
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
}
#include <iostream>
#include <string>
#include <vector>
#include <map>
#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<double> 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; i<dataX.size(); i++) {
daX[i]= dataX[i];
daY[i]= dataY[i];
daDY[i]= dataDY[i];
}
// insert data with or without errorbars, depending on data in file:
if (numDY==dataX.size())
graph->addData(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<double> 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<nxy; i++) {
dataY[i].push_back(strtod(optr,&nptr));
if (err) { optr= nptr; dataDY[i].push_back(strtod(optr,&nptr)); }
if (optr!=nptr && 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; i<dataX.size(); i++) {
daX[i]= dataX[i];
}
for (int j=0; j<ycnt; j++) {
for (unsigned int i=0; i<dataX.size(); i++) {
daY[i]= dataY[j][i];
if (err) daDY[i]= dataDY[j][i];
}
if (err)
graph->addData(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 \""<<name<<"\" !\n";
return;
}
// get a new graph to store the data in:
GraceTMPL::Graph *graph= xmgr->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<string> files;
map<string,string> 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 "
<<"<thaller@ph.tum.de>\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<string,string>::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);
}
syntax highlighted by Code2HTML, v. 0.9.1