Click here to Skip to main content
15,896,118 members
Articles / Programming Languages / C++

Building a simple C++ script compiler from Scintilla and CINT

Rate me:
Please Sign up or sign in to vote.
4.74/5 (26 votes)
8 Jul 2006CPOL7 min read 154.4K   7.6K   85  
How to build a simple C++ script compiler from Scintilla and CINT.
/***************************************************************************
* graphbuf.h
*
*  array and carray type graph data buffer
*
*	buf  << x << y << "\n";
*
*	buf  << "title of graph"
*            << x  << "xunit"           << xmin | xmax << LOG
*     	     << y1 << "name of y1 data" << ymin | ymax << LOG
*     	     << y2 << "name of y2 data"  // multiple y axis data(optional)
*     	     << y3 << "name of y3 data"  //
*     	     << "yunit\n" ;              // must end with \n
*
*       plot << buf ;
*       arrayostream("fname") << buf ;
*       arrayostream("fname") >> buf ;
*
****************************************************************************/


#ifndef G__GRAPHBUF_H
#define G__GRAPHBUF_H

#ifndef G__ARRAY_H
class array;
#endif

#ifndef G__CARRAY_H
class carray;
#endif

#define G__ARRAYMAX 100

typedef unsigned char ISLOG;
ISLOG LIN=0;  // log flag linear
ISLOG LOG=1;  // log flag log

/**********************************************************
* graphbuf
**********************************************************/
class graphbuf {
public:
  enum DATATYPE { G__ARRAYTYPE, G__CARRAYTYPE, G__CARRAYTYPE_RE, G__CARRAYTYPE_IM };
  enum GRSTATUS { G__GRAPHBUF_PUSHING , G__GRAPHBUF_FIXED };

private:
  // data member
  int minn;                     // minimum of n[]
  int pout;                     // output pointer
  int status;                   // input status
  int iden[G__ARRAYMAX];        // identity, array, carray re,im
  int nplot;                    // number of data, input pointer
  int xlog,ylog;                // log flag
  double xmin,xmax,ymin,ymax;   // scale
  int n[G__ARRAYMAX];           // array of number of data
  
  char *title;                  // title of graph
  char *yunit;                  // y axis unit
  
  char *dataname[G__ARRAYMAX];  // name of data
public:
  double *pdat[G__ARRAYMAX];    // pointer to data array
  
public:
  // constructor, destructor, initialization
  graphbuf(void);
  ~graphbuf(void);
  void setnull(void);
  void freebuf(void);
  
  // assignment operator
  graphbuf& operator =(graphbuf& X);
  
  // ostream pipeline operator
  graphbuf& operator <<(array& a);
  graphbuf& operator <<(carray& a);
  graphbuf& operator <<(char *s);    // give name or title+do plot
  graphbuf& operator <<(double min); // specify min scale
  graphbuf& operator  |(double max); // specify max scale
  graphbuf& operator <<(ISLOG log);  // specify log scale
  virtual graphbuf& operator <<(char c);  // do plot
  
  // istream pipeline operator
  graphbuf& operator >>(array& a);
  graphbuf& operator >>(carray& a);
  graphbuf& operator >>(char *s);    // give name or title+do plot
  graphbuf& operator >>(double min); // dummy
  graphbuf& operator >>(ISLOG log);  // dummy
  graphbuf& operator >>(char c);     // 
  
  int isterminate(void) {
    if(G__GRAPHBUF_FIXED==status) return(1);
    else                          return(0);
  }
  
  int Nplot(void)   { return(nplot); }
  int Npoint(int i) { return(n[i]); }
  int Minn(void)    { return(minn); }
  char *Name(int i) { return(dataname[i]); }
  char *Title(void) { return(title); }
  char *Yunit(void) { return(yunit); }
  double *Pdat(int i) { return(pdat[i]); }
  double Dat(int i,int n) { return(pdat[i][n]); }
  int Xlog(void)    { return(xlog); }
  int Ylog(void)    { return(ylog); }
  double Xmin(void) { return(xmin); }
  double Xmax(void) { return(xmax); }
  double Ymin(void) { return(ymin); }
  double Ymax(void) { return(ymax); }
  int Pout(void) { return(pout); }
  int Status(void) { return(status); }
  int Iden(int i)  { return(iden[i]); }
  void setStatus(int stat) { status = stat; }
  
  void dumpdata(FILE *fp);
  void loaddata(FILE *fp);
} ;


// constructor
graphbuf::graphbuf(void)
{
  setnull();
  pout=0;
}

// initialization
void graphbuf::setnull(void)
{
	int i;
	for(i=0;i<G__ARRAYMAX;i++) {
		pdat[i] = NULL;
		n[i] = 0;
		dataname[i] = NULL;
	}
	title=NULL;
	yunit=NULL;
	nplot=0;
	status=G__GRAPHBUF_PUSHING;
	minn=2000000;
	xmin=xmax=ymin=ymax=0;
	xlog=ylog=0;
}

void graphbuf::freebuf(void)
{
	int i;
	for(i=nplot-1;i>=0;i--) {
		if(dataname[i]) free(dataname[i]);
		if(pdat[i])     free(pdat[i]);
	}
	if(yunit) free(yunit);
	if(title) free(title);
	setnull();
}


// destructor
graphbuf::~graphbuf(void)
{
	freebuf();
}


/**************************************************************************
* operator overloading
**************************************************************************/
graphbuf& graphbuf::operator =(graphbuf& a)
{
	int i;
	if(G__GRAPHBUF_FIXED==status) {
		freebuf();
	}
	if(title) free(title);
	if(a.Title()) {
		title=malloc(strlen(a.Title())+1);
		strcpy(title,a.Title());
	}
	else title=NULL;

	if(yunit) free(yunit);
	if(a.Yunit()) {
		yunit=malloc(strlen(a.Yunit())+1);
		strcpy(yunit,a.Yunit());
	}
	else yunit=NULL;
	
	minn=a.Minn();
	xlog=a.Xlog();
	ylog=a.Ylog();
	xmin=a.Xmin();
	xmax=a.Xmax();
	ymin=a.Ymin();
	ymax=a.Ymax();
	nplot=a.Nplot();
	pout=a.Pout();
	status=a.Status();

	for(i=0;i<nplot;i++) {
		n[i]=a.Npoint(i);
		iden[i]=a.Iden(i);

		if(pdat[i]) free(pdat[i]);
		pdat[i] = malloc(n[i]*sizeof(double));
		memcpy((char*)pdat[i],(char*)a.pdat[i],n[i]*sizeof(double));

		if(dataname[i]) free(dataname);
		if(a.Name(i)) {
			dataname[i]=malloc(strlen(a.Name(i))+1);
			strcpy(dataname[i],a.Name(i));
		}
		else dataname[i]=NULL;
	}
	return(*this);
}


// add array or carray to plot
graphbuf& graphbuf::operator <<(array& a)
{
	if(G__GRAPHBUF_FIXED==status) {
		freebuf();
	}
	if(pdat[nplot]) free(pdat[nplot]);
	pdat[nplot] = malloc(a.n*sizeof(double));
	memcpy((char*)pdat[nplot],(char*)a.dat,a.n*sizeof(double));
	iden[nplot]=G__ARRAYTYPE;
	n[nplot]=a.n;
	if(minn>a.n) minn=a.n;
	++nplot;
	return(*this);
}

graphbuf& graphbuf::operator <<(carray& a)
{
	if(G__GRAPHBUF_FIXED==status) {
		freebuf();
	}
	// real part
	if(pdat[nplot]) free(pdat[nplot]);
	pdat[nplot] = malloc(a.n*sizeof(double));
	memcpy((char*)pdat[nplot],(char*)a.re,a.n*sizeof(double));
	iden[nplot]=G__CARRAYTYPE_RE;
	n[nplot]=a.n;
	if(minn>a.n) minn=a.n;
	++nplot;
	// imaginary part
	if(pdat[nplot]) free(pdat[nplot]);
	pdat[nplot] = malloc(a.n*sizeof(double));
	memcpy((char*)pdat[nplot],(char*)a.im,a.n*sizeof(double));
	iden[nplot]=G__CARRAYTYPE_IM;
	n[nplot]=a.n;
	++nplot;
	return(*this);
}


// add min scale information
graphbuf& graphbuf::operator <<(double min)
{
	if(1==nplot) { // on x data
		xmin=min;
	}
	else { // on y data
		ymin=min;
	}
	return(*this);
}

// add max scale information
graphbuf& graphbuf::operator |(double max)
{
	if(G__GRAPHBUF_PUSHING==status) {
		if(1==nplot) { // on x data
			xmax=max;
		}
		else { // on y data
			ymax=max;
		}
	}
	return(*this);
}

// add log information
graphbuf& graphbuf::operator <<(ISLOG log)
{
	if(1==nplot) xlog = (int)log;
	else         ylog = (int)log;
	return(*this);
}

// add title of plot
graphbuf& graphbuf::operator <<(char *s)
{
	if(G__GRAPHBUF_FIXED==status) {
		freebuf();
	}
	if(strcmp(s,"\n")==0) {
		*this << '\n';
	}
	else if(strlen(s)>0 && s[strlen(s)-1]=='\n') {
		if(yunit) free(yunit);
		yunit=malloc(strlen(s)+1);
		sprintf(yunit,"%s",s);
		yunit[strlen(s)-1]='\0';
		*this << '\n';
	}
	else {
		if(nplot>0) {
			if(G__ARRAYTYPE==iden[nplot-1]) {
				if(dataname[nplot-1]) free(dataname[nplot-1]);
				dataname[nplot-1]=malloc(strlen(s)+1);
				strcpy(dataname[nplot-1],s);
			}
			else {
				if(dataname[nplot-2]) free(dataname[nplot-2]);
				dataname[nplot-2]=malloc(strlen(s)+5);
				sprintf(dataname[nplot-2],"%s(re)",s);
				if(dataname[nplot-1]) free(dataname[nplot-1]);
				dataname[nplot-1]=malloc(strlen(s)+5);
				sprintf(dataname[nplot-1],"%s(im)",s);
			}
		}
		else  {
			if(title) free(title);
			title=malloc(strlen(s)+1);
			strcpy(title,s);
		}
	}
	return(*this);
}

// do plot or print
graphbuf& graphbuf::operator <<(char c)
{
	status=G__GRAPHBUF_FIXED;
	return(*this);
}


/**********************************************************
* output
**********************************************************/

// add array or carray 
graphbuf& graphbuf::operator >>(array& a)
{
	if(pout>nplot) {
		cerr << "Error: no more data in graphbuf\n";
		return(*this);
	}
	a = array(pdat[pout],n[pout]);
	++pout;
	return(*this);
}

graphbuf& graphbuf::operator >>(carray& a)
{
	if(pout>nplot-1) {
		cerr << "Error: no more data in graphbuf\n";
		return(*this);
	}
	a = carray(pdat[pout],pdat[pout+1],n[pout]);
	pout+=2;
	return(*this);
}

// dummy 
graphbuf& graphbuf::operator >>(double d)
{
	return(*this);
}

#ifdef NEVER
graphbuf& graphbuf::operator |(double d)
{
	return(*this);
}
#endif

graphbuf& graphbuf::operator >>(ISLOG log)
{
	return(*this);
}

// reset ouput pointer
graphbuf& graphbuf::operator >>(char *s)
{
	pout=0;
	return(*this);
}

graphbuf& graphbuf::operator >>(char c)
{
	pout=0;
	return(*this);
}


/********************************************************************
*  binary dump
********************************************************************/
void graphbuf::dumpdata(FILE *fp)
{
	int i;
	int len;

	fwrite(&nplot,sizeof(nplot),1,fp);
	fwrite(&xlog,sizeof(xlog),1,fp);
	fwrite(&ylog,sizeof(ylog),1,fp);
	fwrite(&xmin,sizeof(xmin),1,fp);
	fwrite(&xmax,sizeof(xmax),1,fp);
	fwrite(&ymin,sizeof(ymin),1,fp);
	fwrite(&ymax,sizeof(ymax),1,fp);
	fwrite(&minn,sizeof(minn),1,fp);
	fwrite(&pout,sizeof(pout),1,fp);
	fwrite(&status,sizeof(status),1,fp);
	fwrite(&n,sizeof(n),1,fp);
	fwrite(&iden,sizeof(iden),1,fp);

	if(title) len=strlen(title);
	else      len=0;
	fwrite(&len,sizeof(len),1,fp);
	if(len) fwrite(title,len+1,1,fp);
	

	if(yunit) len=strlen(yunit);
	else      len=0;
	fwrite(&len,sizeof(len),1,fp);
	if(len) fwrite(yunit,len+1,1,fp);

	for(i=0;i<nplot;i++) {
		fwrite(pdat[i],n[i]*sizeof(double),1,fp);

		if(dataname[i]) len=strlen(dataname[i]);
		else            len=0;
		fwrite(&len,sizeof(len),1,fp);
		if(len) fwrite(dataname[i],len+1,1,fp);
	}
}


/********************************************************************
*  binary load
********************************************************************/
void graphbuf::loaddata(FILE *fp)
{
	int i;
	int len;

	fread(&nplot,sizeof(nplot),1,fp);
	fread(&xlog,sizeof(xlog),1,fp);
	fread(&ylog,sizeof(ylog),1,fp);
	fread(&xmin,sizeof(xmin),1,fp);
	fread(&xmax,sizeof(xmax),1,fp);
	fread(&ymin,sizeof(ymin),1,fp);
	fread(&ymax,sizeof(ymax),1,fp);
	fread(&minn,sizeof(minn),1,fp);
	fread(&pout,sizeof(pout),1,fp);
	fread(&status,sizeof(status),1,fp);
	fread(&n,sizeof(n),1,fp);
	fread(&iden,sizeof(iden),1,fp);

	fread(&len,sizeof(len),1,fp);
	if(title) {
		free(title);
		title=NULL;
	}
	if(len) {
		title=malloc(len+1);
		fread(title,len+1,1,fp);
	}

	fread(&len,sizeof(len),1,fp);
	if(yunit) {
		free(yunit);
		yunit=NULL;
	}
	if(len) {
		yunit=malloc(len+1);
		fread(yunit,len+1,1,fp);
	}

	for(i=0;i<nplot;i++) {
		if(pdat[i]) free(pdat[i]);
		pdat[i]=malloc(n[i]*sizeof(double));
		fread(pdat[i],n[i]*sizeof(double),1,fp);

		fread(&len,sizeof(len),1,fp);
		if(dataname[i]) {
			free(dataname[i]);
			dataname[i]=NULL;
		}
		if(len) {
			dataname[i]=malloc(len+1);
			fread(dataname[i],len+1,1,fp);
		}
	}
}

#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions