// given a valid XSTR() tag piece of text, extract the string portion, return it in out, nonzero on success int lcl_ext_get_text(const SCP_string &xstr, SCP_string &out) { size_t open_quote_pos, close_quote_pos; // this is some crazy wack-ass code. // look for the open quote open_quote_pos = xstr.find('\"'); if (open_quote_pos == SCP_string::npos) { error_display(0, "Error parsing XSTR() tag %s\n", xstr.c_str()); return 0; } // look for the close quote close_quote_pos = xstr.find('\"', open_quote_pos+1); if (close_quote_pos == SCP_string::npos) { error_display(0, "Error parsing XSTR() tag %s\n", xstr.c_str()); return 0; } // now that we know the boundaries of the actual string in the XSTR() tag, copy it out.assign(xstr, open_quote_pos + 1, close_quote_pos - open_quote_pos - 1); // success return 1; }
static void handle_includes_impl(SCP_vector<SCP_string>& include_stack, SCP_stringstream& output, int& include_counter, const SCP_string& filename, const SCP_string& original) { include_stack.emplace_back(filename); auto current_source_number = include_counter + 1; const char* INCLUDE_STRING = "#include"; SCP_stringstream input(original); int line_num = 1; for (SCP_string line; std::getline(input, line);) { auto include_start = line.find(INCLUDE_STRING); if (include_start != SCP_string::npos) { auto first_quote = line.find('"', include_start + strlen(INCLUDE_STRING)); auto second_quote = line.find('"', first_quote + 1); if (first_quote == SCP_string::npos || second_quote == SCP_string::npos) { Error(LOCATION, "Shader %s:%d: Malformed include line. Could not find both quote charaters.", filename.c_str(), line_num); } auto file_name = line.substr(first_quote + 1, second_quote - first_quote - 1); auto existing_name = std::find_if(include_stack.begin(), include_stack.end(), [&file_name](const SCP_string& str) { return str == file_name; }); if (existing_name != include_stack.end()) { SCP_stringstream stack_string; for (auto& name : include_stack) { stack_string << "\t" << name << "\n"; } Error(LOCATION, "Shader %s:%d: Detected cyclic include! Previous includes (top level file first):\n%s", filename.c_str(), line_num, stack_string.str().c_str()); } ++include_counter; // The second parameter defines which source string we are currently working with. We keep track of how many // excludes have been in the file so far to specify this output << "#line 1 " << include_counter + 1 << "\n"; handle_includes_impl(include_stack, output, include_counter, file_name, opengl_load_shader(file_name.c_str())); // We are done with the include file so now we can return to the original file output << "#line " << line_num + 1 << " " << current_source_number << "\n"; } else { output << line << "\n"; } ++line_num; } include_stack.pop_back(); }
// given a valid XSTR() tag piece of text, extract the id# portion, return the value in out, nonzero on success int lcl_ext_get_id(const SCP_string &xstr, int *out) { char id_buf[10]; size_t p, pnext; // find the first quote p = xstr.find('\"'); if (p == SCP_string::npos) { error_display(0, "Error parsing id# in XSTR() tag %s\n", xstr.c_str()); return 0; } p++; // continue searching until we find the close quote while(1) { pnext = xstr.find('\"', p); if (pnext == SCP_string::npos) { error_display(0, "Error parsing id# in XSTR() tag %s\n", xstr.c_str()); return 0; } // if the previous char is a \, we know its not the "end-of-string" quote if (xstr[pnext - 1] != '\\') { p = pnext; break; } // continue p = pnext; } // search until we find a , pnext = xstr.find(',', p); if (pnext == SCP_string::npos) { error_display(0, "Error parsing id# in XSTR() tag %s\n", xstr.c_str()); return 0; } pnext++; // find the close parenthesis p = pnext; pnext = xstr.find(')', p); if (pnext == SCP_string::npos) { error_display(0, "Error parsing id# in XSTR() tag %s\n", xstr.c_str()); return 0; } pnext--; // get only the number while (is_white_space(xstr[p]) && p <= pnext) p++; while (is_white_space(xstr[pnext]) && p <= pnext) pnext--; if (p > pnext) { error_display(0, "Error parsing id# in XSTR() tag %s\n", xstr.c_str()); return 0; } // now get the id string if ((pnext - p + 1) > 9) { error_display(0, "Error parsing id# in XSTR() tag %s\n", xstr.c_str()); return 0; } memset(id_buf, 0, 10); xstr.copy(id_buf, pnext - p + 1, p); // get the value and we're done *out = atoi(id_buf); // success return 1; }