/* * Processor.cpp * stepmania * * Created by Steve Checkoway on Sun Sep 07 2003. * Copyright (c) 2003 Steve Checkoway. All rights reserved. * */ using namespace std; #include #include #include #include #include "StdString.h" #include "Processor.h" void split(const CString& Source, const CString& Deliminator, vector& AddIt) { unsigned startpos = 0; do { unsigned pos = Source.find(Deliminator, startpos); if (pos == Source.npos) pos=Source.size(); CString AddCString = Source.substr(startpos, pos-startpos); AddIt.push_back(AddCString); startpos=pos+Deliminator.size(); } while (startpos <= Source.size()); } bool IsAVar(const CString& var) { return var[0] == '$'; } CString StripVar(const CString& var) { if (!IsAVar(var)) return var; return var.substr(1, var.npos); } Processor::Processor(CString& path, handleFileFunc f, getPathFunc p, askFunc a, bool i) : mDoGoto(false), mPath(path), mHandleFile(f), mGetPath(p), mAsk(a), mError(Processor::DefaultError), mInstalling(i) { char cwd[MAXPATHLEN]; getwd(cwd); mCWD = cwd; mConditionals["INSTALLING"] = i; } void Processor::ProcessLine(const CString& line, unsigned& nextLine) { CStringArray parts; split(line, ":", parts); if (parts[0] == "LABEL") { printf("%u: %s\n", nextLine, line.c_str()); if (parts.size() != 2) goto error; if (mDoGoto && parts[1] == mLabel) { mDoGoto = false; mLabel = ""; } mLabels[parts[1]] = ++nextLine; // set mLabel to be the next line return; } if (mDoGoto) { ++nextLine; return; } printf("%u: %s\n", nextLine, line.c_str()); if (parts[0] == "FILE") { if (parts.size() != 3) goto error; bool overwrite = ResolveConditional(parts[2]); (*mHandleFile)(parts[1], mCWD, mPath, overwrite); ++nextLine; return; } if (parts[0] == "GETPATH") { if (parts.size() != 3) goto error; mVars[parts[2]] = (*mGetPath)(parts[1]); ++nextLine; return; } if (parts[0] == "CD") { if (parts.size() != 3) goto error; ++nextLine; if (!ResolveConditional(parts[2])) return; CString path = ResolveVar(parts[1]); if (path[0] == '/') mCWD = path; else mCWD += "/" + path; struct stat st; if (stat(mCWD, &st)) (*mError)("%s\n", strerror(errno)); if (!(st.st_mode & S_IFDIR)) (*mError)("%s is not a directory.\n", mCWD.c_str()); return; } if (!mInstalling) { ++nextLine; return; } if (parts[0] == "GOTO") { if (parts.size() != 2) goto error; if (parts[1] == "") goto error; mLabel = parts[1]; if (mLabels.find(mLabel) != mLabels.end()) { mReturnStack.push(nextLine + 1); nextLine = mLabels[mLabel]; mLabel = ""; return; } mDoGoto = true; mReturnStack.push(++nextLine); return; } if (parts[0] == "IF") { if (parts.size() != 4) goto error; if (ResolveConditional(parts[1])) mLabel = parts[2]; else mLabel = parts[3]; if (mLabel == "") { ++nextLine; return; } mReturnStack.push(nextLine + 1); if (mLabels.find(mLabel) != mLabels.end()) { nextLine = mLabels[mLabel]; mLabel = ""; return; } mDoGoto = true; ++nextLine; return; } if (parts[0] == "RETURN") { if (mReturnStack.empty()) nextLine = unsigned(-1); // quite large else { nextLine = mReturnStack.top(); mReturnStack.pop(); } return; } if (parts[0] == "SETVAR") { if (parts.size() < 3) goto error; CString temp = ""; for (unsigned i=2; i