module.cpp
来自「Shorthand是一个强大的脚本语言」· C++ 代码 · 共 655 行 · 第 1/2 页
CPP
655 行
*/
void ShhModule::parse_posted_data()
{
string s;
const char* v = safe_getenv("CONTENT_LENGTH", s);
int content_length = (v != NULL) ? atoi(v) : 0;
TRACE((3, "reading posted data: CONTENT_LENGTH = %d (\"%s\")\n", content_length, v));
if (content_length <= 0) return;
int bytes_left = content_length;
string input;
char buffer[1024]; int count;
while(bytes_left > 0 && (count = m_http_stream->http_read(buffer, sizeof(buffer))) > 0)
{
input.append(buffer, count);
bytes_left -= count;
}
//input.save_to_file("c://tmp//shorthand.post.txt");
TRACE((3, "got posted data...\n"));
parse_vars_into_map((char*) input.cstr(), m_context->m_put_fields);
}
/**
* Parses a list of URL-encoded variables into string map.
*/
void ShhModule::parse_vars_into_map(char* source, cchar_map& target)
{
char* token = strtok(source, "&");
while(token != NULL )
{
char* q = strchr(token, '=');
if (q != NULL)
{
char* name = token;
while(*name && isspace(*name)) name++;
*q = '\0';
char* value = q+1;
while(q > name && isspace(q[-1])) *(--q) = '\0';
string raw_value(value);
string raw_name(name);
string real_name, real_value;
raw_name.urldecode(real_name);
raw_value.urldecode(real_value);
target.put(m_context->m_memory.strdup(real_name),
m_context->m_memory.strdup(real_value));
}
token = strtok( NULL, "&" );
}
}
/**
* Executes the body of parsed script.
*/
void ShhModule::execute_body()
{
if (m_parent == NULL)
{
parse_query_string();
parse_posted_data();
m_http_stream->http_add_header("Cache-Control", "no-cache");
m_http_stream->http_add_header("Pragma", "no-cache");
datetime dt; dt.import_ydm(1980, 1, 1);
string exp; dt.export_rfc(exp);
m_http_stream->http_add_header("Expires", exp);
var("script")->value() = m_own_context.m_memory.strdup(getenv("PATH_INFO"));
var("ip")->value() = m_own_context.m_memory.strdup(getenv("REMOTE_ADDR"));
}
try
{
if (m_entry != NULL)
{
m_entry->execute();
}
}
catch(ShhExitException* exex)
{
// call to exit()
delete exex;
}
m_own_context.m_memory.purge();
if (m_parent == NULL)
{
m_http_stream->http_finalize();
}
}
#ifdef WIN32
#define PATH_SEPARATOR ";"
#else
#define PATH_SEPARATOR ":"
#endif
/**
* Executes another module in the current context.
*
* parameters:
* location: location where another module was mentioned
* name: name of the module to include
* do_return: indicates whether or not we should return
* after finishing with another module
* flags: reserved
*/
void ShhModule::switch_module(ShhNode& location, const char* name, bool do_return, int flags)
{
ShhModule* topm = this->top();
bool is_full_name;
string full_name;
#ifdef WIN32
is_full_name = strlen(name) > 1 && (name[1] == ':' || name[0] == '\\' && name[1] == '\\');
#else
is_full_name = name[0] == '\0';
#endif
struct stat stinfo;
const char* path_translated = getenv("PATH_TRANSLATED");
/*
this->printf("path_translated = %s; m_script_name = %s\n",
path_translated != NULL ? path_translated : "NULL", m_script_name.cstr());
return;*/
if (is_full_name)
{
full_name = name;
if (stat(full_name, &stinfo) != 0)
{
throw location.mkexception(1270, "file %s was not found", name);
}
}
else
{
string local_dir, include_path;
bool found = false;
string candidate;
string this_script_name;
if (path_translated != NULL)
{
this_script_name = path_translated;
}
else
{
this_script_name = m_script_name;
}
//TRACE((1, "path_translated = %s\n", getenv("PATH_TRANSLATED")));
TRACE((1, "script_name = %s\n", this_script_name.cstr()));
include_path = getenv("SHH_INCLUDE_PATH");
// first, try to find it in the same dir as original script:
const char* last_slash = strrchr(this_script_name, '/');
#ifdef WIN32
const char* last_backslash = strrchr(this_script_name, '\\');
if (last_slash == NULL || last_backslash > last_slash)
last_slash = last_backslash;
#endif
if (last_slash != NULL)
{
string path; path.set(this_script_name, last_slash - (const char*)this_script_name);
path.chop("/\\");
string local_attempt;
local_dir = path;
TRACE((1, "local_dir = %s\n", path.cstr()));
}
else
{
char buf[512];
local_dir = getcwd(buf, 512);
local_dir.chop("/\\");
}
candidate.printf("%s"SLASH"%s", local_dir.cstr(), name);
if (stat(candidate, &stinfo) == 0)
found = true;
if (!found)
{
// first, find another module source file
string_array paths; string::split(include_path, paths, PATH_SEPARATOR);
for(int i=0,n=paths.size(); i<n; i++)
{
string* path = paths.get(i);
path->chop("/\\");
candidate.printf("%s"SLASH"%s", path->cstr(), name);
if (stat(candidate, &stinfo) == 0)
{
found = true;
break;
}
}
}
if (!found)
{
throw location.mkexception(1271, "file \"%s\" cannot be not found in the local directory (\"%s\") or include path (\"%s\")", name, local_dir.cstr(), include_path.cstr());
}
full_name = candidate;
}
for(int i=0,n=topm->m_modules.size(); i<n; i++)
{
int diff;
#ifdef WIN32
diff = stricmp(topm->m_modules.get(i)->getName(), full_name);
#else
diff = strcmp(topm->m_modules.get(i)->getName(), full_name);
#endif
if (diff == 0)
return;
}
ShhModule* module = new ShhModule(full_name, this);
topm->m_modules.add(module);
string content;
try
{
content.load_from_file(full_name);
}
catch(ShhException*)
{
throw location.mkexception(1274, "Cannot open file %s", full_name.cstr());
}
try
{
module->execute_script(content, m_http_stream);
}
catch(ShhException* ex)
{
string msg = ex->message();
msg.chop("\r\n");
if (msg.ends_with("<br>")) msg.set_length(msg.length() - 4);
ShhException* wrapper = new ShhException(1272,
"%s<BR>\nin file included from <B>%s</B> at line <b>%d</b>",
msg.cstr(), m_script_name.cstr(), location.lineno());
delete ex;
throw wrapper;
}
if (!do_return) throw new ShhExitException();
}
ShhModule* ShhModule::top()
{
if (m_parent != NULL) return m_parent->top();
else return this;
}
/**
* Returns a reference to the global list of user-defined functions.
*/
ShhDefunList& ShhModule::getFunctionList()
{
if (m_parent == NULL)
return m_ufds;
else
return m_parent->getFunctionList();
}
/**
* Tries to execute named function
*/
ShhValue ShhModule::executeFunction(const char* name, const ShhValueList& args)
{
const ShhDefun* udf;
// lock for user-defined function
ShhDefunList& udfs = getFunctionList();
udf = udfs.find(name);
ShhModule* topModule = top();
if (udf != NULL)
{
ShhValue returnValue;
ShhValue* oldReturnValue = m_return_value;
topModule->m_return_value = &returnValue;
try
{
udf->execute(this, args);
}
catch(ShhReturnException*)
{
}
topModule->m_return_value = oldReturnValue;
return returnValue;
}
else
{
// look for built-in function
const ShhBuiltin* bi = g_builtins.find(name);
if (bi == NULL)
throw new ShhObjectException(1050, "call to undefined function '%s'", name);
return bi->execute(this, args);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?