Home modules.gotpike.org
Username: Password: [Create Account]
[Forgot Password?]
Return to module

File Contents

Contents of /wx-0.5/gpp.pike:

#!/usr/local/bin/pike
/*
   wxPike - (c) 2005 Julio César Gázquez
 
   gpp.pike:
   Small generic preprocessor

   
   Note: gpp is not doing macro replacement at this time,
   as was not in my needs.
*/

string ppd="#";
mapping (string:string) macros;
int parseNestLevel, outputNestLevel;
Stdio.File out;

void pp_define(string name,string value)
{
	macros[name]=value;
}

void pp_undef(string name)
{
	macros-= ({ name });
}

int pp_include(string name)
{
	Stdio.FILE in;
	in=Stdio.FILE(name,"r");
	int r=parse(in);
	in->close();
}

string _eval(string word)
{
	string v=macros[word];
	if (zero_type(v)) v=word;
	return v;
}

int eval(array(string) words)
{
	string a=_eval(words[0]);
	string op=words[1];
	string b=_eval(words[2]);
	int result;
	switch (op) {
	case "==":
		result=a==b;
		break;
	case "!=":
		result=a!=b;
		break;
	case ">":
		result=a>b;
		break;
	case "<":
		result=a<b;
		break;
	case ">=":
		result=a>=b;
		break;
	case "<=":
		result=a<=b;
		break;
	}
	return result;
}

void pp_if(int cond)
{
	if (cond && outputNestLevel==parseNestLevel)
		outputNestLevel++;
	parseNestLevel++;
}

void pp_else()
{
	if (outputNestLevel==parseNestLevel)	// Cond was true
		outputNestLevel--;		// then skip else block
	else if (outputNestLevel==parseNestLevel-1) // Cond was false
		outputNestLevel++;		// Enter in else block
	// else, failed in an outer level, keep discarding output
}

void pp_endif()
{
	if (outputNestLevel==parseNestLevel)
		outputNestLevel--;
	parseNestLevel--;
}

int parse(Stdio.FILE in)
{
	string line;
	while (line=in->gets()) {
		array(string) words = line / " ";
		if (words[0]==ppd+"define") {
			pp_define(words[1],line[search(line,words[2])..]);
		} else if (words[0]==ppd+"undef") {
			pp_undef(words[1]);
		} else if (words[0]==ppd+"include") {
			if (pp_include(words[1]))
				return 1;
		} else if (words[0]==ppd+"if") {
			pp_if(eval(words[1..]));
		} else if (words[0]==ppd+"ifdef") {
			pp_if(!zero_type(macros[words[1]]));
		} else if (words[0]==ppd+"ifndef") {
			pp_if(zero_type(macros[words[1]]));
		} else if (words[0]==ppd+"else") {
			pp_else();
		} else if (words[0]==ppd+"endif") {
			pp_endif();		
		} else
			if (parseNestLevel==outputNestLevel) {
				out->write("%s\n",line);
			}
	}
	return 0;
}

int main(int argc,array(string)argv)
{
	Stdio.FILE in;
	if (argc>1)
		if (argv[1][0..3]=="-ppd") {
			ppd=argv[1][4..4];
			argc--;
			argv=argv-({ argv[1] });
		}
	if (argc>1) {
		in=Stdio.FILE(argv[1],"r");
		if (argc>2) {
			out=Stdio.File(argv[2],"cwt");
			
		} else {
			out=Stdio.stdout;
		}		
	} else {
		in=Stdio.stdin;
		out=Stdio.stdout;
	}
	parseNestLevel=0;
	outputNestLevel=0;
	macros=([ ]);
	return parse(in);
}

gotpike.org | Copyright © 2004 - 2011 | Pike is a trademark of Department of Computer and Information Science, Linköping University