这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统

源代码在线查看: script.cpp

软件大小: 23539 K
上传用户: hwyzy
关键词: WIN WINNT 2003 开放源代码
下载地址: 免注册下载 普通下载 VIP

相关代码

				////////////////////////////////////////////////////////
				//
				// script.cpp
				// 
				// Implementaion of a basic basic :) interpreter
				//
				//
				// Maarten Bosma, 09.01.2004
				// maarten.paul@bosma.de
				//
				////////////////////////////////////////////////////////////////////
				
				#include "package.hpp"
				#include "script.h"
				#include "log.h"
				#include 
				
				using namespace std;
				
				// just a few Helpers
				void Replace (string* Where, string Old, string New, int start = 0, int end = -1, int instring = 1);
				int FindCount (string What, string Where, int start = 0, int end = -1);
				int Find (string Where, string What, int start = 0, int end = -1, int instring = 1);
				
				
				// Loads script from file, checks if it's synaxially correct
				// and converts it into a easy to interprete one.
				int RPS_Load (SCRIPT** script, const char* path)
				{
					string source;
				
					/* We have to do it that way (doublepointer) because MinGw 
					   calls "delete" at the end of function otherwise. */
					(*script) = new SCRIPT;	
				
					// Load file to string
					ifstream file(path, ios_base::in);
					if (!file.is_open())
						return ERR_FILE;
				
					getline(file, source, '\0');
				
					// make sure last char is a new line
					source += "\n"; 
					
					// Are all subs and strings closed ?
					// FIXME: Just a quick hack sould be both checked line by line
					if(FindCount(source, "\"")%2) // if count is uneven not all strings are closed 
						return ERR_SYNATX;
				
					if(FindCount(source, "Sub ") != FindCount(source, "End Sub\n"))
						return ERR_SYNATX;
				
					// Delete comments
					while (true)
					{
						int start = Find(source, "'");
						if(start == NOTFOUND)
							break;
						int end = Find(source, "\n", start);
						source.erase(start, end-start); // needs size not line
					}
				
					// Converte the file into some thing easier to interprete
					Replace(&source, "(", " ");
					Replace(&source, ")", " ");
					Replace(&source, ";", " ");
					Replace(&source, ",", " ");
					Replace(&source, "\"", " \" ");
					Replace(&source, "\t", " ");
				
					Replace(&source, "  ", " ");
					Replace(&source, "\n ", "\n");
					Replace(&source, " \n", "\n");
					Replace(&source, "\n\n", "\n");
				
					if(source[0]=='\n')
						source.erase(0,1);
				
					// copy string into struct (line by line)
					UINT i, line=0;
					for (i=0; i < source.size(); i++)
					{
						// Make everything non capital letters
						if (source[i] >= 65 && source[i] 						{
							source[i] += 32; // ASCII-Code (a-z 97-122)
						}
				
						else if (source[i] == '\"')
						{
							while(source[++i]!='\"');
						}
				
						else if (source[i] == '\n')
						{
							(*script)->code.push_back(source.substr(line, i-line));
							line = i+1;
						}
					}
				
					// create a sub table (with name, beginnig and end of function)
					for (i=0; i < (*script)->code.size(); i++) // code.size() is the cout of lines
					{
						SUB sub;
						
						if((*script)->code[i].substr(0,4) != "sub ")
							return ERR_SYNATX; // script has to start with sub
				
						sub.name = (*script)->code[i].substr(4,((*script)->code[i].size()-4));
						sub.start = i+1;
				
						while ((*script)->code[i] != "end sub")
						{
							i++;
							//if script does not end with "end sub" we got a problem
							if (i>(*script)->code.size())
								return ERR_SYNATX; 
						}
				
						sub.end = i;
						(*script)->subs.push_back(sub);
					}
				
					return ERR_OK;
				}
				
				
				// Executes a subroutine of the script
				int RPS_Execute (SCRIPT* script, const char* function)
				{
					char *argv[100];
					char *buffer;
					int a, b, c, nr = NOTFOUND, argc = 0;
				
					// find the right fuction
					for(a=0; (UINT)asubs.size(); a++)
						if(script->subs[a].name == function)
							nr = a;
				
					// if there isn't a fuction with this name we can't do anything
					if(nr == NOTFOUND)
						return ERR_OK;
				
					// call the function
					for (a=script->subs[nr].start; asubs[nr].end; a++)
					{
						// create a temporarry buffer 
						buffer = new char[script->code[a].size()];
						strcpy(buffer, script->code[a].c_str());
				
						// make the fist argument the function's name
						argv[0] = &buffer[0];
					
						int buffer_size = (int)strlen(buffer);
						for (b=0; b						{
							// ignore chars in strings
							if(buffer[b]=='\"')
							{
								argv[argc] = &buffer[b+1];
				
								while(buffer[++b]!='\"');
				
								buffer[b] = '\0';
							}
				
							// create a new argument
							else if(buffer[b]==' ')
							{
								argc++;
								argv[argc] = &buffer[b+1];
								buffer[b] = '\0';
				
								// we don't want buffer overflows
								if(argc == 99) 
									return ERR_GENERIC;
				
							}
				
							// call the function
							else if(buffer[b]=='\0')
							{
								int error = 0;
				
								// log the name
								Log("*   excute command: ");
								for(c=0; c								{
									LogAdd(argv[c]); 
									LogAdd(" ");
								}
				
								for(c=0; c									if(!strcmp(argv[0], FuncTable[c].name))
										error = FuncTable[c].function(argc, &argv[0]);
				
								if(error)
									return error;
							}
				
						}
				
						// start again with next line
						delete[] buffer;
						argc = 0;
					}
				
					return ERR_OK;
				}
				
				// get a Constant or a variavle
				int RPS_getVar (const char* name)
				{
					return ERR_OK;
				}
				
				// Clears up Memory
				void RPS_Clear (SCRIPT* script)
				{
					if(script)
						delete script;
				}
				
				/* Helper Functions */
				
				// How often do we find a string inside another one
				int FindCount (string where, string what, int start, int end)
				{
					int counter = 0, pos;
					
					while(true)
					{
						pos = (int)where.find (what, start);
						//could could not be found or is outside of search area 
						if (pos == (int)string::npos || (end!=-1 && pos>end)) 
							break;
						start = pos+1;
						counter++;
					}
				
					return counter;
				}
				
				// Find (with only or not in Strings option)
				int Find (string where, string what, int start, int end, int instring)
				{
					int pos = (int)where.find (what, start);
				
					//could could not be found or is outside of search area 
					if (pos == (int)string::npos || (end!=-1 && pos>end)) 
						return -1;
				
					// if the count of this quotes is eaven we are in string 
					int isInString = FindCount(where, "\"", start, pos)%2;
				
					// if so we go on searching 
				    if(isInString == instring)
						return Find (where, what, pos+1, end, instring);
				
					return pos;
				
				}
				
				// Replace (using Find)
				void Replace (string* String, string Old, string New, int start, int end, int instring)
				{
					int pos = start;
				
					while(true)
					{
						pos = Find(String->c_str(), Old, pos, end, instring);
						if (pos == -1)
							break;
				
						String->replace (pos, Old.length(), New);
					}
				}
							

相关资源