double wtof_test(const WString& string, bool& success) { wchar_t* endptr = 0; double result = wcstod(string.Buffer(), &endptr); success = endptr == string.Buffer() + string.Length(); return result; }
vint wtoi_test(const WString& string, bool& success) { wchar_t* endptr = 0; vint result = wcstol(string.Buffer(), &endptr, 10); success = endptr == string.Buffer() + string.Length() && itow(result) == string; return result; }
vuint64_t wtou64_test(const WString& string, bool& success) { wchar_t* endptr = 0; vuint64_t result = _wcstoui64(string.Buffer(), &endptr, 10); success = endptr == string.Buffer() + string.Length() && u64tow(result) == string; return result; }
bool GuiSinglelineTextBox::TextElementOperatorCallback::BeforeModify(TextPos start, TextPos end, const WString& originalText, WString& inputText) { vint length=inputText.Length(); const wchar_t* input=inputText.Buffer(); for(vint i=0;i<length;i++) { if(*input==0 || *input==L'\r' || *input==L'\n') { length=i; break; } } if(length!=inputText.Length()) { inputText=inputText.Left(length); } return true; }
bool Semaphore::Create(vint initialCount, vint maxCount, const WString& name) { if (internalData) return false; if (initialCount > maxCount) return false; internalData = new SemaphoreData; #if defined(__APPLE__) AString auuid; if(name.Length() == 0) { CFUUIDRef cfuuid = CFUUIDCreate(kCFAllocatorDefault); CFStringRef cfstr = CFUUIDCreateString(kCFAllocatorDefault, cfuuid); auuid = CFStringGetCStringPtr(cfstr, kCFStringEncodingASCII); CFRelease(cfstr); CFRelease(cfuuid); } auuid = auuid.Insert(0, "/"); // OSX SEM_NAME_LENGTH = 31 if(auuid.Length() >= 30) auuid = auuid.Sub(0, 30); if ((internalData->semNamed = sem_open(auuid.Buffer(), O_CREAT, O_RDWR, initialCount)) == SEM_FAILED) { delete internalData; internalData = 0; return false; } #else if (name == L"") { if(sem_init(&internalData->semUnnamed, 0, (int)initialCount) == -1) { delete internalData; internalData = 0; return false; } } else { AString astr = wtoa(name); if ((internalData->semNamed = sem_open(astr.Buffer(), O_CREAT, 0777, initialCount)) == SEM_FAILED) { delete internalData; internalData = 0; return false; } } #endif Release(initialCount); return true; }
void HexToBinary(stream::IStream& stream, const WString& hexText) { const wchar_t* buffer = hexText.Buffer(); vint count = hexText.Length() / 2; for (vint i = 0; i < count; i++) { vuint8_t byte = (vuint8_t)(HexToInt(buffer[0]) * 16 + HexToInt(buffer[1])); buffer += 2; stream.Write(&byte, 1); } }
WString GetDirectory(const WString& fileName) { int index=0; for(int i=0;i<fileName.Length();i++) { if(fileName[i]==PATH_DELIMITER) { index=i; } } return fileName.Left(index+1); }
bool DataNode::SaveToFile(const String& fileName, Format format /*= Format::Xml*/) const { WString data = SaveAsWString(format); OutFile file(fileName); if (!file.IsOpened()) return false; file.WriteData(data.Data(), data.Length()*sizeof(wchar_t)); return false; }
void FilePath::GetPathComponents(WString path, collections::List<WString>& components) { WString pathRemaining = path; WString delimiter = Delimiter; components.Clear(); while(true) { auto index = INVLOC.FindFirst(pathRemaining, delimiter, Locale::None); if (index.key == -1) break; if(index.key != 0) components.Add(pathRemaining.Left(index.key)); else { #if defined VCZH_GCC // Unix absolute path starting with "/" // components[0] will be L"/" components.Add(delimiter); #elif defined VCZH_MSVC if(pathRemaining.Length() >= 2 && pathRemaining[1] == Delimiter) { // Windows UNC Path starting with "\\" // components[0] will be L"\\" components.Add(L"\\"); index.value++; } #endif } pathRemaining = pathRemaining.Right(pathRemaining.Length() - (index.key + index.value)); } if(pathRemaining.Length() != 0) { components.Add(pathRemaining); } }
Ptr<ShortcutBuilder> ParseInternal(const WString& text, collections::List<Ptr<ParsingError>>& errors)override { Ptr<RegexMatch> match=regexShortcut.MatchHead(text); if (match && match->Result().Length() != text.Length()) { errors.Add(new ParsingError(L"Failed to parse a shortcut \"" + text + L"\".")); return 0; } Ptr<ShortcutBuilder> builder = new ShortcutBuilder; builder->text = text; builder->ctrl = match->Groups().Contains(L"ctrl"); builder->shift = match->Groups().Contains(L"shift"); builder->alt = match->Groups().Contains(L"alt"); WString name = match->Groups()[L"key"][0].Value(); builder->key = GetCurrentController()->InputService()->GetKey(name); return builder->key == VKEY::_UNKNOWN ? nullptr : builder; }
void Console::Write(const WString& string) { DWORD count = 0; WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), string.Buffer(), (int)string.Length(), &count, 0); }
WString wupper(const WString& string) { WString result = string.Buffer(); _wcsupr_s((wchar_t*)result.Buffer(), result.Length() + 1); return result; }
// Generates a line of text rendered from this element bool ElementTextDefault::GenerateLine(WString& line, int& line_length, float& line_width, int line_begin, float maximum_line_width, float right_spacing_width, bool trim_whitespace_prefix) { FontFaceHandle* font_face_handle = GetFontFaceHandle(); // Initialise the output variables. line.Clear(); line_length = 0; line_width = 0; // Bail if we don't have a valid font face. if (font_face_handle == NULL) return true; // Determine how we are processing white-space while formatting the text. int white_space_property = GetProperty< int >(WHITE_SPACE); bool collapse_white_space = white_space_property == WHITE_SPACE_NORMAL || white_space_property == WHITE_SPACE_NOWRAP || white_space_property == WHITE_SPACE_PRE_LINE; bool break_at_line = maximum_line_width >= 0 && (white_space_property == WHITE_SPACE_NORMAL || white_space_property == WHITE_SPACE_PRE_WRAP || white_space_property == WHITE_SPACE_PRE_LINE); bool break_at_endline = white_space_property == WHITE_SPACE_PRE || white_space_property == WHITE_SPACE_PRE_WRAP || white_space_property == WHITE_SPACE_PRE_LINE; // Determine what (if any) text transformation we are putting the characters through. int text_transform_property = GetProperty< int >(TEXT_TRANSFORM); // Starting at the line_begin character, we generate sections of the text (we'll call them tokens) depending on the // white-space parsing parameters. Each section is then appended to the line if it can fit. If not, or if an // endline is found (and we're processing them), then the line is ended. kthxbai! const word* token_begin = text.CString() + line_begin; const word* string_end = text.CString() + text.Length(); while (token_begin != string_end) { WString token; const word* next_token_begin = token_begin; // Generate the next token and determine its pixel-length. bool break_line = BuildToken(token, next_token_begin, string_end, line.Empty() && trim_whitespace_prefix, collapse_white_space, break_at_endline, text_transform_property); int token_width = font_face_handle->GetStringWidth(token, line.Empty() ? 0 : line[line.Length() - 1]); // If we're breaking to fit a line box, check if the token can fit on the line before we add it. if (break_at_line) { if (!line.Empty() && (line_width + token_width > maximum_line_width || LastToken(next_token_begin, string_end, collapse_white_space, break_at_endline) && line_width + token_width > maximum_line_width - right_spacing_width)) { return false; } } // The token can fit on the end of the line, so add it onto the end and increment our width and length // counters. line += token; line_length += (next_token_begin - token_begin); line_width += token_width; // Break out of the loop if an endline was forced. if (break_line) return false; // Set the beginning of the next token. token_begin = next_token_begin; } return true; }
/* * Returns file descriptor of the read-pipe or -1 on error. */ void ScriptController::StartProcess(int* pipein, int* pipeout) { CString workingDir = m_workingDir; if (workingDir.Empty()) { workingDir = FileSystem::GetCurrentDirectory(); } const char* script = m_args[0]; #ifdef WIN32 char* cmdLine = m_cmdLine; char cmdLineBuf[2048]; if (!*m_cmdLine) { BuildCommandLine(cmdLineBuf, sizeof(cmdLineBuf)); cmdLine = cmdLineBuf; } debug("Starting process: %s", cmdLine); WString wideWorkingDir = FileSystem::UtfPathToWidePath(workingDir); if (strlen(workingDir) > 260 - 14) { GetShortPathNameW(wideWorkingDir, wideWorkingDir, wideWorkingDir.Length() + 1); } // create pipes to write and read data HANDLE readPipe, readProcPipe; HANDLE writePipe = 0, writeProcPipe = 0; SECURITY_ATTRIBUTES securityAttributes = { 0 }; securityAttributes.nLength = sizeof(securityAttributes); securityAttributes.bInheritHandle = TRUE; CreatePipe(&readPipe, &readProcPipe, &securityAttributes, 0); SetHandleInformation(readPipe, HANDLE_FLAG_INHERIT, 0); if (m_needWrite) { CreatePipe(&writeProcPipe, &writePipe, &securityAttributes, 0); SetHandleInformation(writePipe, HANDLE_FLAG_INHERIT, 0); } STARTUPINFOW startupInfo = { 0 }; startupInfo.cb = sizeof(startupInfo); startupInfo.dwFlags = STARTF_USESTDHANDLES; startupInfo.hStdInput = writeProcPipe; startupInfo.hStdOutput = readProcPipe; startupInfo.hStdError = readProcPipe; PROCESS_INFORMATION processInfo = { 0 }; std::unique_ptr<wchar_t[]> environmentStrings = m_environmentStrings.GetStrings(); BOOL ok = CreateProcessW(nullptr, WString(cmdLine), nullptr, nullptr, TRUE, NORMAL_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP | CREATE_UNICODE_ENVIRONMENT, environmentStrings.get(), wideWorkingDir, &startupInfo, &processInfo); if (!ok) { DWORD errCode = GetLastError(); char errMsg[255]; errMsg[255 - 1] = '\0'; if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, errCode, 0, errMsg, 255, nullptr)) { PrintMessage(Message::mkError, "Could not start %s: %s", *m_infoName, errMsg); } else { PrintMessage(Message::mkError, "Could not start %s: error %i", *m_infoName, errCode); } if (!FileSystem::FileExists(script)) { PrintMessage(Message::mkError, "Could not find file %s", script); } if (wcslen(wideWorkingDir) > 260) { PrintMessage(Message::mkError, "Could not build short path for %s", workingDir); } CloseHandle(readPipe); CloseHandle(readProcPipe); CloseHandle(writePipe); CloseHandle(writeProcPipe); return; } debug("Child Process-ID: %i", (int)processInfo.dwProcessId); m_processId = processInfo.hProcess; m_dwProcessId = processInfo.dwProcessId; // close unused pipe ends CloseHandle(readProcPipe); CloseHandle(writeProcPipe); *pipein = _open_osfhandle((intptr_t)readPipe, _O_RDONLY); if (m_needWrite) { *pipeout = _open_osfhandle((intptr_t)writePipe, _O_WRONLY); } #else int pin[] = {0, 0}; int pout[] = {0, 0}; // create the pipes if (pipe(pin)) { PrintMessage(Message::mkError, "Could not open read pipe: errno %i", errno); return; } if (m_needWrite && pipe(pout)) { PrintMessage(Message::mkError, "Could not open write pipe: errno %i", errno); close(pin[0]); close(pin[1]); return; } *pipein = pin[0]; *pipeout = pout[1]; std::vector<char*> environmentStrings = m_environmentStrings.GetStrings(); char** envdata = environmentStrings.data(); ArgList args; std::copy(m_args.begin(), m_args.end(), std::back_inserter(args)); args.emplace_back(nullptr); char* const* argdata = (char* const*)args.data(); #ifdef DEBUG debug("Starting process: %s", script); for (const char* arg : m_args) { debug("arg: %s", arg); } #endif debug("forking"); pid_t pid = fork(); if (pid == -1) { PrintMessage(Message::mkError, "Could not start %s: errno %i", *m_infoName, errno); close(pin[0]); close(pin[1]); if (m_needWrite) { close(pout[0]); close(pout[1]); } return; } else if (pid == 0) { // here goes the second instance // only certain functions may be used here or the program may hang. // for a list of functions see chapter "async-signal-safe functions" in // http://man7.org/linux/man-pages/man7/signal.7.html // create new process group (see Terminate() where it is used) setsid(); // make the pipeout to be the same as stdout and stderr dup2(pin[1], 1); dup2(pin[1], 2); close(pin[0]); close(pin[1]); if (m_needWrite) { // make the pipein to be the same as stdin dup2(pout[0], 0); close(pout[0]); close(pout[1]); } #ifdef CHILD_WATCHDOG write(1, "\n", 1); fsync(1); #endif chdir(workingDir); environ = envdata; execvp(script, argdata); if (errno == EACCES) { write(1, "[WARNING] Fixing permissions for", 32); write(1, script, strlen(script)); write(1, "\n", 1); fsync(1); FileSystem::FixExecPermission(script); execvp(script, argdata); } // NOTE: the text "[ERROR] Could not start " is checked later, // by changing adjust the dependent code below. write(1, "[ERROR] Could not start ", 24); write(1, script, strlen(script)); write(1, ": ", 2); char* errtext = strerror(errno); write(1, errtext, strlen(errtext)); write(1, "\n", 1); fsync(1); _exit(FORK_ERROR_EXIT_CODE); } // continue the first instance debug("forked"); debug("Child Process-ID: %i", (int)pid); m_processId = pid; // close unused pipe ends close(pin[1]); if (m_needWrite) { close(pout[0]); } #endif }
int main(int argc, char* argv[]) #endif { WString baseDirectory; { #if defined VCZH_MSVC wchar_t currentDirectory[MAX_PATH]={0}; GetCurrentDirectory(MAX_PATH, currentDirectory); baseDirectory=currentDirectory; #elif defined VCZHGCC char currentDirectory[1024]={0}; getcwd(currentDirectory, 1024); baseDirectory=atow(currentDirectory); #endif if(baseDirectory[baseDirectory.Length()-1]!=PATH_DELIMITER) { baseDirectory+=PATH_DELIMITER; } } Regex regexPathSplitter(L"[///\\]"); Ptr<ParsingGeneralParser> parser=CreateBootstrapStrictParser(); Console::SetTitle(L"Vczh Parser Generator for C++"); Console::SetColor(false, true, false, true); Console::WriteLine(L"parsing>Files : "+itow(argc-1)); for(int i=1;i<argc;i++) { Console::WriteLine(L"------------------------------------------------------------"); #if defined VCZH_MSVC WString inputPath=argv[i]; #elif defined VCZH_GCC WString inputPath=atow(argv[i]); #endif if(inputPath.Length()<2 || inputPath[1]!=L':') { inputPath=baseDirectory+inputPath; } Console::WriteLine(L"parsing>Making : "+inputPath); if(inputPath.Length()<11 || inputPath.Right(11)!=L".parser.txt") { Console::SetColor(true, false, false, true); Console::WriteLine(L"error> The extenion name of the input file path must be \".parser.txt\"."); Console::SetColor(false, true, false, true); } else { WString name; { List<Ptr<RegexMatch>> matches; regexPathSplitter.Split(inputPath, true, matches); name=matches[matches.Count()-1]->Result().Value(); name=name.Left(name.Length()-11); } WString outputMetaPath=inputPath.Left(inputPath.Length()-11); WString outputHeaderPath=outputMetaPath+L".h"; WString outputCppPath=outputMetaPath+L".cpp"; WString logPath=outputMetaPath+L".log"; Console::WriteLine(L"parsing>Output header path : "+outputHeaderPath); Console::WriteLine(L"parsing>Output cpp path : "+outputCppPath); Console::WriteLine(L"parsing>Log path : "+logPath); CodegenConfig config; WString codeGrammar; { FileStream fileStream(inputPath, FileStream::ReadOnly); if(!fileStream.IsAvailable()) { Console::SetColor(true, false, false, true); Console::WriteLine(L"error> Cannot open \""+inputPath+L" for read."); Console::SetColor(false, true, false, true); goto STOP_PARSING; } BomDecoder decoder; DecoderStream decoderStream(fileStream, decoder); StreamReader reader(decoderStream); if(!config.ReadConfig(reader)) { goto STOP_PARSING; } codeGrammar=reader.ReadToEnd(); } Ptr<ParsingDefinition> definition; Ptr<ParsingTable> table; { FileStream fileStream(logPath, FileStream::WriteOnly); if(!fileStream.IsAvailable()) { Console::SetColor(true, false, false, true); Console::WriteLine(L"error> Cannot open \""+logPath+L" for write."); Console::SetColor(false, true, false, true); goto STOP_PARSING; } BomEncoder encoder(BomEncoder::Utf16); EncoderStream encoderStream(fileStream, encoder); StreamWriter writer(encoderStream); if(codeGrammar==L"<bootstrap-grammar>") { definition=CreateParserDefinition(); MemoryStream bootstrapStream; { StreamWriter bootstrapWriter(bootstrapStream); Log(definition, bootstrapWriter); } bootstrapStream.SeekFromBegin(0); StreamReader bootstrapReader(bootstrapStream); codeGrammar=bootstrapReader.ReadToEnd(); } else { definition=CreateDefinition(parser, codeGrammar, writer); } if(!definition) { Console::SetColor(true, false, false, true); Console::WriteLine(L"error> Error happened. Open \""+logPath+L" for details."); Console::SetColor(false, true, false, true); goto STOP_PARSING; } table=CreateTable(definition, writer, config.ambiguity); if(!table) { Console::SetColor(true, false, false, true); Console::WriteLine(L"error> Error happened. Open \""+logPath+L" for details."); Console::SetColor(false, true, false, true); goto STOP_PARSING; } } { FileStream fileStream(outputHeaderPath, FileStream::WriteOnly); if(!fileStream.IsAvailable()) { Console::SetColor(true, false, false, true); Console::WriteLine(L"error> Cannot open \""+outputHeaderPath+L" for write."); Console::SetColor(false, true, false, true); goto STOP_PARSING; } BomEncoder encoder(BomEncoder::Mbcs); EncoderStream encoderStream(fileStream, encoder); StreamWriter writer(encoderStream); WriteHeaderFile(name, definition, table, config, writer); } { FileStream fileStream(outputCppPath, FileStream::WriteOnly); if(!fileStream.IsAvailable()) { Console::SetColor(true, false, false, true); Console::WriteLine(L"error> Cannot open \""+outputCppPath+L" for write."); Console::SetColor(false, true, false, true); goto STOP_PARSING; } BomEncoder encoder(BomEncoder::Mbcs); EncoderStream encoderStream(fileStream, encoder); StreamWriter writer(encoderStream); config.includes.Clear(); config.includes.Add(L"\""+name+L".h\""); WriteCppFile(name, codeGrammar, definition, table, config, writer); } } STOP_PARSING:; } Console::WriteLine(L"Finished!"); return 0; }
// Generates the geometry required to render a single line of text. int FontFaceHandle::GenerateString(GeometryList& geometry, const WString& string, const Vector2f& position, const Colourb& colour, int layer_configuration_index, word default_character) const { int geometry_index = 0; int line_width = 0; ROCKET_ASSERT(layer_configuration_index >= 0); ROCKET_ASSERT(layer_configuration_index < (int) layer_configurations.size()); // Fetch the requested configuration and generate the geometry for each one. const LayerConfiguration& layer_configuration = layer_configurations[layer_configuration_index]; for (size_t i = 0; i < layer_configuration.size(); ++i) { FontFaceLayer* layer = layer_configuration[i]; Colourb layer_colour; if (layer == base_layer) layer_colour = colour; else layer_colour = layer->GetColour(); // Resize the geometry list if required. if ((int) geometry.size() < geometry_index + layer->GetNumTextures()) geometry.resize(geometry_index + layer->GetNumTextures()); // Bind the textures to the geometries. for (int i = 0; i < layer->GetNumTextures(); ++i) geometry[geometry_index + i].SetTexture(layer->GetTexture(i)); line_width = 0; word prior_character = 0; const word* string_iterator = string.CString(); const word* string_end = string.CString() + string.Length(); word final_character; for (; string_iterator != string_end; string_iterator++) { final_character = *string_iterator; FontGlyphMap::const_iterator iterator = glyphs.find(*string_iterator); if (iterator == glyphs.end()) { if (default_character >= 32) { iterator = glyphs.find(default_character); if (iterator == glyphs.end()) { continue; } else { final_character = default_character; } } else { continue; } } // Adjust the cursor for the kerning between this character and the previous one. if (prior_character != 0) line_width += GetKerning(prior_character, final_character); layer->GenerateGeometry(&geometry[geometry_index], final_character, Vector2f(position.x + line_width, position.y), layer_colour); line_width += iterator->second.advance; prior_character = final_character; } geometry_index += layer->GetNumTextures(); } // Cull any excess geometry from a previous generation. geometry.resize(geometry_index); return line_width; }