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