const ClueList & Clues::GetClueList(const string_t & direction) const { const_iterator it = find(direction); if (it == end()) throw NoClues(std::string("Unknown clue direction: ") + encode_utf8(direction)); return it->second; }
// From CamelCase to snake_case std::string CamelCase(const string_t & name) { // Replace '_' + a lowercase letter with an upper case letter string_t str; str.reserve(name.size()); for (size_t i = 0; i < name.size(); ++i) { if (i == 0 || name[i] == puzT('_')) { if (i > 0) ++i; if (i < name.size()) { #if PUZ_UNICODE if (::iswlower(name[i])) str.push_back(::towupper(name[i])); #else // ! PUZ_UNICODE if (::islower(name[i])) str.push_back(::toupper(name[i])); #endif // PUZ_UNICODE/! PUZ_UNICODE else // Not lower case: so push both the underscore and letter { if (i > 0) str.push_back(name[i-1]); str.push_back(name[i]); } } else if (i > 0) // At the end of the string: push the underscore str.push_back(name[i-1]); } else // Not a hypen: push the letter str.push_back(name[i]); } return encode_utf8(str); }
void SetInnerXML(node n, const string_t & innerxml) { // Parse the XML, and add it as a child. // We need to add a dummy xml wrapper element so that plain text still // parses. pugi::xml_document doc; std::string temp("<dummy>"); temp.append(encode_utf8(innerxml)).append("</dummy>"); pugi::xml_parse_result result = doc.load(temp.c_str()); if (! result) SetText(n, innerxml); else n.append_copy(doc.first_child().first_child()); }
void unc_text::update_logtext() { if (!m_logok) { /* make a pessimistic guess at the size */ m_logtext.clear(); m_logtext.reserve(m_chars.size() * 3); for (value_type::iterator it = m_chars.begin(); it != m_chars.end(); ++it) { encode_utf8(*it, m_logtext); } m_logtext.push_back(0); m_logok = true; } }
ssize_t utf16_to_utf8(uint8_t *out, const uint16_t *in, size_t len) { ssize_t rc = 0; ssize_t units; uint32_t code; uint8_t encoded[4]; do { units = decode_utf16(&code, in); if(units == -1) return -1; if(code > 0) { in += units; units = encode_utf8(encoded, code); if(units == -1) return -1; if(out != NULL) { if(rc + units <= len) { *out++ = encoded[0]; if(units > 1) *out++ = encoded[1]; if(units > 2) *out++ = encoded[2]; if(units > 3) *out++ = encoded[3]; } } if(SSIZE_MAX - units >= rc) rc += units; else return -1; } } while(code > 0); return rc; }
const unsigned char * u2cp_(unicode_val_T u, int to, enum nbsp_mode nbsp_mode) { int j; int s; if (u < 128) return strings[u]; if (u < 0xa0) { u = strange_chars[u - 0x80]; if (!u) return NULL; } to &= ~SYSTEM_CHARSET_FLAG; if (is_cp_ptr_utf8(&codepages[to])) return encode_utf8(u); /* To mark non breaking spaces in non-UTF-8 strings, we use a * special char NBSP_CHAR. */ if (u == UCS_NO_BREAK_SPACE) { if (nbsp_mode == NBSP_MODE_HACK) return NBSP_CHAR_STRING; else /* NBSP_MODE_ASCII */ return " "; } if (u == UCS_SOFT_HYPHEN) return ""; if (u < 0xFFFF) for (j = 0; j < 0x80; j++) if (codepages[to].highhalf[j] == u) return strings[0x80 + j]; for (j = 0; codepages[to].table[j].c; j++) if (codepages[to].table[j].u == u) return strings[codepages[to].table[j].c]; BIN_SEARCH(unicode_7b, x, N_UNICODE_7B, u, s); if (s != -1) return unicode_7b[s].s; return no_str; }
/* * Return pointer to new FileIdentDesc in an allocated block to be free'd when no longer required. * Does NOT fill: descTag.checksum, descTag.tagLocation, icbTag.characteristics, icb */ struct fileIdentDesc* makeFileIdentDesc(char* name) { char uName[256]; int uLen; struct fileIdentDesc *fid; fid = (struct fileIdentDesc*) calloc(512,1); fid->descTag.tagIdent = TAG_IDENT_FID; fid->descTag.descVersion = 2; fid->descTag.tagSerialNum = lvd->descTag.tagSerialNum; fid->fileVersionNum = 1; fid->icb.extLength = 2048; if( name[0] != 0 ) { /* FID to parent directory has no name */ memset(&uName, 0, 256); uLen = encode_utf8(uName, "", name, 256); fid->lengthFileIdent = uLen; memcpy(fid->fileIdent + fid->lengthOfImpUse, uName, fid->lengthFileIdent); } return fid; }
struct fileIdentDesc* findFileIdentDesc(Directory *dir, char* name) { int i; uint8_t *data; struct fileIdentDesc *fid; char uName[256]; int uLen; uLen = encode_utf8(uName, "", name, 256); data = dir->data; for( i = 0; i < dir->fe.informationLength; i += (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3 ) { fid = (struct fileIdentDesc*)(data + i); if( fid->descTag.tagIdent == TAG_IDENT_TE ) return NULL; if( fid->descTag.tagIdent == TAG_IDENT_IE ) { printf("Indirect Entry not yet implemented\n"); continue; } if( fid->descTag.tagIdent != TAG_IDENT_FID ) fail("Unknown tag id %08X in directory\n", fid->descTag.tagIdent); // check CRC if( fid->fileCharacteristics == FID_FILE_CHAR_PARENT) continue; if( fid->lengthFileIdent == uLen && memcmp( fid->fileIdent, uName, fid->lengthFileIdent) == 0 ) return fid; } return NULL; }
void unc_text::update_logtext() { if (!m_logok) { /* make a pessimistic guess at the size */ m_logtext.clear(); m_logtext.reserve(m_chars.size() * 3); for (value_type::iterator it = m_chars.begin(); it != m_chars.end(); ++it) { int val = *it; if (*it == '\n') { val = 0x2424; } else if (*it == '\r') { val = 0x240d; } encode_utf8(val, m_logtext); } m_logtext.push_back(0); m_logok = true; } }
//----------------------------------------------------------------------------- // SaveXPF //----------------------------------------------------------------------------- void SaveXPF(Puzzle * puz, const std::string & filename, void * /* dummy */) { const Grid & grid = puz->GetGrid(); if (grid.IsScrambled()) throw ConversionError("XPF does not support scrambled puzzles"); if (! grid.HasSolution()) throw ConversionError("XPF does not support puzzles without a solution"); for (const Square * square = puz->GetGrid().First(); square != NULL; square = square->Next()) { if (square->HasImage()) throw ConversionError("XPF does not support puzzles with background images."); } xml::document doc; xml::node puzzles = doc.append_child("Puzzles"); puzzles.append_attribute("Version") = "1.0"; xml::node puzzle = puzzles.append_child("Puzzle"); // Metadata puz::Puzzle::metamap_t & meta = puz->GetMetadata(); puz::Puzzle::metamap_t::iterator it; for (it = meta.begin(); it != meta.end(); ++it) { if (it->first == puzT("notes")) // "notes" -> "Notepad" xml::Append(puzzle, "Notepad", it->second); else xml::Append(puzzle, xml::CamelCase(it->first).c_str(), it->second); } // Grid if (grid.GetType() == TYPE_DIAGRAMLESS) xml::Append(puzzle, "Type", "diagramless"); // Grid Size xml::node size = puzzle.append_child("Size"); xml::Append(size, "Rows", puz::ToString(grid.GetHeight())); xml::Append(size, "Cols", puz::ToString(grid.GetWidth())); // Answers { xml::node grid_node = puzzle.append_child("Grid"); xml::node row; std::string row_text; row_text.reserve(grid.GetWidth()); const Square * square; for (square = grid.First(); square; square = square->Next()) { if (square->IsFirst(ACROSS)) row = grid_node.append_child("Row"); if (square->IsMissing()) row_text.append(1, '~'); else if (square->IsBlack()) row_text.append(1, char(Square::Black[0])); else if (square->IsSolutionBlank()) row_text.append(1, ' '); else row_text.append(1, square->GetPlainSolution()); if (square->IsLast(ACROSS)) { xml::SetText(row, row_text.c_str()); row_text.clear(); } } } // Circles { xml::node circles = puzzle.append_child("Circles"); const Square * square; for (square = grid.First(); square; square = square->Next()) { if (square->HasCircle()) { xml::node circle = circles.append_child("Circle"); circle.append_attribute("Row") = square->GetRow() + 1; circle.append_attribute("Col") = square->GetCol() + 1; } } if (circles.empty()) puzzle.remove_child(circles); } // Rebus { xml::node rebus = puzzle.append_child("RebusEntries"); const Square * square; for (square = grid.First(); square; square = square->Next()) { if (square->HasSolutionRebus()) { xml::node entry = rebus.append_child("Rebus"); entry.append_attribute("Row") = square->GetRow() + 1; entry.append_attribute("Col") = square->GetCol() + 1; entry.append_attribute("Short") = std::string(1, square->GetPlainSolution()).c_str(); xml::SetText(entry, square->GetSolution()); } } if (rebus.empty()) puzzle.remove_child(rebus); } // Shades { xml::node shades = puzzle.append_child("Shades"); const Square * square; for (square = grid.First(); square; square = square->Next()) { if (square->HasColor()) { xml::node shade = shades.append_child("Shade"); shade.append_attribute("Row") = square->GetRow() + 1; shade.append_attribute("Col") = square->GetCol() + 1; if (square->HasHighlight()) xml::SetText(shade, "gray"); else xml::SetText(shade, square->GetHtmlColor()); } } if (shades.empty()) puzzle.remove_child(shades); } // Clues { xml::node clues_node = puzzle.append_child("Clues"); Clues & clues = puz->GetClues(); Clues::iterator clues_it; for (clues_it = clues.begin(); clues_it != clues.end(); ++clues_it) { ClueList & cluelist = clues_it->second; ClueList::iterator it; for (it = cluelist.begin(); it != cluelist.end(); ++it) { xml::node clue = clues_node.append_child("Clue"); // Find the clue direction if (! puz->IsDiagramless()) { const Word & word = it->GetWord(); switch (word.GetDirection()) { case ACROSS: clue.append_attribute("Dir") = "Across"; break; case DOWN: clue.append_attribute("Dir") = "Down"; break; case DIAGONAL_SW: clue.append_attribute("Dir") = "Diagonal"; break; default: throw ConversionError("XPF clues must be Across, Down, or Diagonal"); break; } clue.append_attribute("Row") = word.front()->GetRow() + 1; clue.append_attribute("Col") = word.front()->GetCol() + 1; } else // diagramless { puz::string_t title = cluelist.GetTitle(); if (title == puzT("Across")) clue.append_attribute("Dir") = "Across"; else if (title == puzT("Down")) clue.append_attribute("Dir") = "Down"; else if (title == puzT("Diagonal")) clue.append_attribute("Dir") = "Diagonal"; else throw ConversionError("XPF clues must be Across, Down, or Diagonal"); } clue.append_attribute("Num") = encode_utf8(it->GetNumber()).c_str(); // Clue formatting needs to be escaped if it is XHTML. // xml::SetInnerXML(clue, it->GetText()); xml::SetText(clue, it->GetText()); } } } // User Grid { xml::node usergrid = puzzle.append_child("UserGrid"); xml::node row; std::string row_text; row_text.reserve(grid.GetWidth()); const Square * square; for (square = grid.First(); square; square = square->Next()) { if (square->IsFirst(ACROSS)) row = usergrid.append_child("Row"); if (square->IsMissing()) row_text.append(1, '~'); else if (square->IsBlack()) row_text.append(1, char(Square::Black[0])); else if (square->IsBlank()) row_text.append(1, ' '); else row_text.append(1, square->GetPlainText()); if (square->IsLast(ACROSS)) { xml::SetText(row, row_text.c_str()); row_text.clear(); } } if (usergrid.empty()) puzzle.remove_child(usergrid); } // User Rebus { xml::node rebus = puzzle.append_child("UserRebusEntries"); const Square * square; for (square = grid.First(); square; square = square->Next()) { if (square->HasTextRebus()) { xml::node entry = rebus.append_child("Rebus"); entry.append_attribute("Row") = square->GetRow() + 1; entry.append_attribute("Col") = square->GetCol() + 1; entry.append_attribute("Short") = std::string(1, square->GetPlainText()).c_str(); xml::SetText(entry, square->GetText()); } } if (rebus.empty()) puzzle.remove_child(rebus); } // Square Flags { xml::node flags = puzzle.append_child("SquareFlags"); const Square * square; for (square = grid.First(); square; square = square->Next()) { if (square->GetFlag() != 0) { xml::node entry = flags.append_child("Flag"); entry.append_attribute("Row") = square->GetRow() + 1; entry.append_attribute("Col") = square->GetCol() + 1; if (square->HasFlag(FLAG_PENCIL)) entry.append_attribute("Pencil") = "true"; if (square->HasFlag(FLAG_BLACK)) entry.append_attribute("Checked") = "true"; if (square->HasFlag(FLAG_REVEALED)) entry.append_attribute("Revealed") = "true"; if (square->HasFlag(FLAG_X)) entry.append_attribute("Incorrect") = "true"; if (square->HasFlag(FLAG_CORRECT)) entry.append_attribute("Correct") = "true"; } } if (flags.empty()) puzzle.remove_child(flags); } // Timer { if (puz->GetTime() != 0) { xml::node timer = puzzle.append_child("Timer"); timer.append_attribute("Seconds") = puz->GetTime(); if (puz->IsTimerRunning()) timer.append_attribute("Running") = "true"; } } doc.save_file(filename.c_str()); }
std::list<Token> jsonnet_lex(const std::string &filename, const char *input) { unsigned long line_number = 1; const char *line_start = input; std::list<Token> r; const char *c = input; for ( ; *c!='\0' ; ++c) { Location begin(line_number, c - line_start + 1); Token::Kind kind; std::string data; switch (*c) { // Skip non-\n whitespace case ' ': case '\t': case '\r': continue; // Skip \n and maintain line numbers case '\n': line_number++; line_start = c+1; continue; case '{': kind = Token::BRACE_L; break; case '}': kind = Token::BRACE_R; break; case '[': kind = Token::BRACKET_L; break; case ']': kind = Token::BRACKET_R; break; case ':': kind = Token::COLON; break; case ',': kind = Token::COMMA; break; case '$': kind = Token::DOLLAR; break; case '.': kind = Token::DOT; break; case '(': kind = Token::PAREN_L; break; case ')': kind = Token::PAREN_R; break; case ';': kind = Token::SEMICOLON; break; // Special cases for unary operators. case '!': kind = Token::OPERATOR; if (*(c+1) == '=') { c++; data = "!="; } else { data = "!"; } break; case '~': kind = Token::OPERATOR; data = "~"; break; case '+': kind = Token::OPERATOR; data = "+"; break; case '-': kind = Token::OPERATOR; data = "-"; break; // Numeric literals. case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': kind = Token::NUMBER; data = lex_number(c, filename, begin); break; // String literals. case '"': { c++; for (; ; ++c) { if (*c == '\0') { throw StaticError(filename, begin, "Unterminated string"); } if (*c == '"') { break; } switch (*c) { case '\\': switch (*(++c)) { case '"': data += *c; break; case '\\': data += *c; break; case '/': data += *c; break; case 'b': data += '\b'; break; case 'f': data += '\f'; break; case 'n': data += '\n'; break; case 'r': data += '\r'; break; case 't': data += '\t'; break; case 'u': { ++c; // Consume the 'u'. unsigned long codepoint = 0; // Expect 4 hex digits. for (unsigned i=0 ; i<4 ; ++i) { auto x = (unsigned char)(c[i]); unsigned digit; if (x == '\0') { auto msg = "Unterminated string"; throw StaticError(filename, begin, msg); } else if (x == '"') { auto msg = "Truncated unicode escape sequence in " "string literal."; throw StaticError(filename, begin, msg); } else if (x >= '0' && x <= '9') { digit = x - '0'; } else if (x >= 'a' && x <= 'f') { digit = x - 'a' + 10; } else if (x >= 'A' && x <= 'F') { digit = x - 'A' + 10; } else { std::stringstream ss; ss << "Malformed unicode escape character, " << "should be hex: '" << x << "'"; throw StaticError(filename, begin, ss.str()); } codepoint *= 16; codepoint += digit; } encode_utf8(codepoint, data); // Leave us on the last char, ready for the ++c at // the outer for loop. c += 3; } break; case '\0': { auto msg = "Truncated escape sequence in string literal."; throw StaticError(filename, begin, msg); } default: { std::stringstream ss; ss << "Unknown escape sequence in string literal: '" << *c << "'"; throw StaticError(filename, begin, ss.str()); } } break; // Treat as a regular letter, but maintain line/column counters. case '\n': line_number++; line_start = c+1; data += *c; break; default: // Just a regular letter. data += *c; } } kind = Token::STRING; } break; // Keywords default: if (is_identifier_first(*c)) { std::string id; for (; *c != '\0' ; ++c) { if (!is_identifier(*c)) { break; } id += *c; } --c; if (id == "assert") { kind = Token::ASSERT; } else if (id == "else") { kind = Token::ELSE; } else if (id == "error") { kind = Token::ERROR; } else if (id == "false") { kind = Token::FALSE; } else if (id == "for") { kind = Token::FOR; } else if (id == "function") { kind = Token::FUNCTION; } else if (id == "if") { kind = Token::IF; } else if (id == "import") { kind = Token::IMPORT; } else if (id == "importstr") { kind = Token::IMPORTSTR; } else if (id == "in") { kind = Token::IN; } else if (id == "local") { kind = Token::LOCAL; } else if (id == "null") { kind = Token::NULL_LIT; } else if (id == "self") { kind = Token::SELF; } else if (id == "super") { kind = Token::SUPER; } else if (id == "tailstrict") { kind = Token::TAILSTRICT; } else if (id == "then") { kind = Token::THEN; } else if (id == "true") { kind = Token::TRUE; } else { // Not a keyword, must be an identifier. kind = Token::IDENTIFIER; data = id; } } else if (is_symbol(*c)) { // Single line C++ style comment if (*c == '/' && *(c+1) == '/') { while (*c != '\0' && *c != '\n') { ++c; } // Leaving it on the \n allows processing of \n on next iteration, // i.e. managing of the line & column counter. c--; continue; } // Single line # comment if (*c == '#') { while (*c != '\0' && *c != '\n') { ++c; } // Leaving it on the \n allows processing of \n on next iteration, // i.e. managing of the line & column counter. c--; continue; } // Multi-line comment. if (*c == '/' && *(c+1) == '*') { c += 2; // Avoid matching /*/: skip the /* before starting the search for */. while (*c != '\0' && !(*c == '*' && *(c+1) == '/')) { if (*c == '\n') { // Just keep track of the line / column counters. line_number++; line_start = c+1; } ++c; } if (*c == '\0') { auto msg = "Multi-line comment has no terminating */."; throw StaticError(filename, begin, msg); } // Leave the counter on the closing /. c++; continue; } // Text block if (*c == '|' && *(c+1) == '|' && *(c+2) == '|' && *(c+3) == '\n') { std::stringstream block; c += 4; // Skip the "|||\n" line_number++; line_start = c; const char *first_line = c; int ws_chars = whitespace_check(first_line, c); if (ws_chars == 0) { auto msg = "Text block's first line must start with whitespace."; throw StaticError(filename, begin, msg); } while (true) { assert(ws_chars > 0); // Read up to the \n for (c = &c[ws_chars]; *c != '\n' ; ++c) { if (*c == '\0') throw StaticError(filename, begin, "Unexpected EOF"); block << *c; } // Add the \n block << '\n'; ++c; line_number++; line_start = c; // Examine next line ws_chars = whitespace_check(first_line, c); if (ws_chars == 0) { // End of text block // Skip over any whitespace while (*c == ' ' || *c == '\t') ++c; // Expect ||| if (!(*c == '|' && *(c+1) == '|' && *(c+2) == '|')) { auto msg = "Text block not terminated with |||"; throw StaticError(filename, begin, msg); } c += 2; // Leave on the last | data = block.str(); kind = Token::STRING; break; } } break; // Out of the switch. } for (; *c != '\0' ; ++c) { if (!is_symbol(*c)) { break; } data += *c; } --c; kind = Token::OPERATOR; } else { std::stringstream ss; ss << "Could not lex the character "; auto uc = (unsigned char)(*c); if (*c < 32) ss << "code " << unsigned(uc); else ss << "'" << *c << "'"; throw StaticError(filename, begin, ss.str()); } break; } Location end(line_number, c - line_start + 1); r.push_back(Token(kind, data, LocationRange(filename, begin, end))); } Location end(line_number, c - line_start + 1); r.push_back(Token(Token::END_OF_FILE, "", LocationRange(filename, end, end))); return r; }
inline void SetText(node node, const string_t & text) { SetText(node, encode_utf8(text).c_str()); }
LRESULT KeyboardWinAPI::wndproc (HWND msgwin, UINT msg, WPARAM wParam, LPARAM lParam) { LPARAM repeat_count = lParam & 0x0000FFFF; LPARAM scan_code = lParam & 0x00FF0000; LPARAM extended = lParam & 0x01000000; LPARAM context_code = lParam & 0x20000000; LPARAM was_down = lParam & 0x40000000; LPARAM key_up = lParam & 0x80000000; std::string key; if (key_up) { key = "-"; } else { key = was_down ? "=" : "+"; } bool have_key = false; switch (msg) { case WM_CHAR: case WM_UNICHAR: { key = ":"; // control chars if (wParam < 0x20 || (wParam >= 0x7f && wParam < 0xa0)) break; encode_utf8(wParam, key); if (verbose) { CLOG << (void*)msg << ": \"" << key << "\" from " << wParam << ": " << "x" << repeat_count << std::endl; } have_key = true; }; break; case WM_KEYDOWN: case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: if (verbose) { CLOG << (void*)msg << ": " << key << wParam << ": " << "x" << repeat_count << std::endl; } switch (wParam) { #define MAP_KEY(vk, name) case vk: { \ key += name; \ have_key = true; \ }; break MAP_KEY(VK_SPACE, "Space"); MAP_KEY(VK_BACK, "BackSpace"); MAP_KEY(VK_ESCAPE,"Escape"); MAP_KEY(VK_CAPITAL, "CapsLock"); MAP_KEY(VK_TAB, "Tab"); MAP_KEY(VK_RETURN, "Return"); MAP_KEY(VK_CONTROL, "Ctrl"); //MAP_KEY(VK_LCONTROL, "Ctrl"); //MAP_KEY(VK_RCONTROL, "Ctrl"); MAP_KEY(VK_MENU, "Alt"); //MAP_KEY(VK_LMENU, "Alt"); //MAP_KEY(VK_RMENU, "Alt"); MAP_KEY(VK_F1, "F1"); MAP_KEY(VK_F2, "F2"); MAP_KEY(VK_F3, "F3"); MAP_KEY(VK_F4, "F4"); MAP_KEY(VK_F5, "F5"); MAP_KEY(VK_F6, "F6"); MAP_KEY(VK_F7, "F7"); MAP_KEY(VK_F8, "F8"); MAP_KEY(VK_F9, "F9"); MAP_KEY(VK_F10, "F10"); MAP_KEY(VK_F11, "F11"); MAP_KEY(VK_F12, "F12"); MAP_KEY(VK_F13, "F13"); MAP_KEY(VK_F14, "F14"); MAP_KEY(VK_F15, "F15"); MAP_KEY(VK_NUMPAD0, "NUMPAD0"); MAP_KEY(VK_NUMPAD1, "NUMPAD1"); MAP_KEY(VK_NUMPAD2, "NUMPAD2"); MAP_KEY(VK_NUMPAD3, "NUMPAD3"); MAP_KEY(VK_NUMPAD4, "NUMPAD4"); MAP_KEY(VK_NUMPAD5, "NUMPAD5"); MAP_KEY(VK_NUMPAD6, "NUMPAD6"); MAP_KEY(VK_NUMPAD7, "NUMPAD7"); MAP_KEY(VK_NUMPAD8, "NUMPAD8"); MAP_KEY(VK_NUMPAD9, "NUMPAD9"); MAP_KEY(VK_UP, "Up"); MAP_KEY(VK_DOWN, "Down"); MAP_KEY(VK_LEFT, "Left"); MAP_KEY(VK_RIGHT, "Right"); MAP_KEY(VK_PRIOR, "PageUp"); MAP_KEY(VK_NEXT, "PageDown"); MAP_KEY(VK_HOME, "Home"); MAP_KEY(VK_END, "End"); MAP_KEY(VK_NUMLOCK, "NumLock"); MAP_KEY(VK_SCROLL, "Scroll"); MAP_KEY(VK_PAUSE, "Pause"); MAP_KEY(VK_SHIFT, "Shift"); MAP_KEY(VK_INSERT, "Insert"); MAP_KEY(VK_DELETE, "Delete"); MAP_KEY(VK_LWIN, "Win"); MAP_KEY(VK_RWIN, "Win"); MAP_KEY(VK_APPS, "Menu"); MAP_KEY(VK_SNAPSHOT, "PrintScreen"); MAP_KEY(VK_CONVERT, "Convert"); MAP_KEY(VK_NONCONVERT, "Nonconvert"); MAP_KEY(VK_ACCEPT, "Accept"); MAP_KEY(VK_MODECHANGE, "Modechange"); MAP_KEY(VK_SELECT, "Select"); MAP_KEY(VK_PRINT, "Print"); MAP_KEY(VK_EXECUTE, "Execute"); MAP_KEY(VK_HELP, "Help"); default: { key += getPress(wParam, scan_code); have_key = true; } } break; } if (have_key) { for (int i=0 ; i<repeat_count ; ++i) presses.push_back(key); } return CallWindowProc(old_wndproc, msgwin, msg, wParam, lParam); }
String jsonnet_string_unescape(const LocationRange &loc, const String &s) { String r; const char32_t *s_ptr = s.c_str(); for (const char32_t *c = s_ptr; *c != U'\0' ; ++c) { switch (*c) { case '\\': switch (*(++c)) { case '"': case '\'': r += *c; break; case '\\': r += *c; break; case '/': r += *c; break; case 'b': r += '\b'; break; case 'f': r += '\f'; break; case 'n': r += '\n'; break; case 'r': r += '\r'; break; case 't': r += '\t'; break; case 'u': { ++c; // Consume the 'u'. unsigned long codepoint = 0; // Expect 4 hex digits. for (unsigned i=0 ; i<4 ; ++i) { auto x = (unsigned char)(c[i]); unsigned digit; if (x == '\0') { auto msg = "Truncated unicode escape sequence in string literal."; throw StaticError(loc, msg); } else if (x >= '0' && x <= '9') { digit = x - '0'; } else if (x >= 'a' && x <= 'f') { digit = x - 'a' + 10; } else if (x >= 'A' && x <= 'F') { digit = x - 'A' + 10; } else { std::stringstream ss; ss << "Malformed unicode escape character, " << "should be hex: '" << x << "'"; throw StaticError(loc, ss.str()); } codepoint *= 16; codepoint += digit; } r += codepoint; // Leave us on the last char, ready for the ++c at // the outer for loop. c += 3; } break; case '\0': { auto msg = "Truncated escape sequence in string literal."; throw StaticError(loc, msg); } default: { std::stringstream ss; std::string utf8; encode_utf8(*c, utf8); ss << "Unknown escape sequence in string literal: '" << utf8 << "'"; throw StaticError(loc, ss.str()); } } break; default: // Just a regular letter. r += *c; } } return r; }
int file_ascmagic(RMagic *ms, const ut8 *buf, size_t nbytes) { return 0; size_t i; ut8 *nbuf = NULL, *utf8_buf = NULL, *utf8_end; unichar *ubuf = NULL; size_t ulen, mlen; const struct names *p; int rv = -1; int mime = ms->flags & R_MAGIC_MIME; const char *code = NULL; const char *code_mime = NULL; const char *type = NULL; const char *subtype = NULL; const char *subtype_mime = NULL; int has_escapes = 0; int has_backspace = 0; int seen_cr = 0; int n_crlf = 0; int n_lf = 0; int n_cr = 0; int n_nel = 0; size_t last_line_end = (size_t)-1; int has_long_lines = 0; /* * Undo the NUL-termination kindly provided by process() * but leave at least one byte to look at */ while (nbytes > 1 && buf[nbytes - 1] == '\0') nbytes--; if (!(nbuf = calloc(1, (nbytes + 1) * sizeof(nbuf[0])))) goto done; if (!(ubuf = calloc(1, (nbytes + 1) * sizeof(ubuf[0])))) goto done; /* * Then try to determine whether it's any character code we can * identify. Each of these tests, if it succeeds, will leave * the text converted into one-unichar-per-character Unicode in * ubuf, and the number of characters converted in ulen. */ if (looks_ascii(buf, nbytes, ubuf, &ulen)) { code = "ASCII"; code_mime = "us-ascii"; type = "text"; } else if (looks_utf8_with_BOM(buf, nbytes, ubuf, &ulen) > 0) { code = "UTF-8 Unicode (with BOM)"; code_mime = "utf-8"; type = "text"; } else if (file_looks_utf8(buf, nbytes, ubuf, &ulen) > 1) { code = "UTF-8 Unicode"; code_mime = "utf-8"; type = "text"; } else if ((i = looks_ucs16(buf, nbytes, ubuf, &ulen)) != 0) { if (i == 1) code = "Little-endian UTF-16 Unicode"; else code = "Big-endian UTF-16 Unicode"; type = "character data"; code_mime = "utf-16"; /* is this defined? */ } else if (looks_latin1(buf, nbytes, ubuf, &ulen)) { if (!memcmp (buf, "\xff\xff\xff\xff", 4)) { // uninitialized memory is not iso-8859!! goto done; } code = "ISO-8859"; type = "text"; code_mime = "iso-8859-1"; } else if (looks_extended(buf, nbytes, ubuf, &ulen)) { code = "Non-ISO extended-ASCII"; type = "text"; code_mime = "unknown"; } else { from_ebcdic(buf, nbytes, nbuf); if (looks_ascii(nbuf, nbytes, ubuf, &ulen)) { code = "EBCDIC"; type = "character data"; code_mime = "ebcdic"; } else if (looks_latin1(nbuf, nbytes, ubuf, &ulen)) { code = "International EBCDIC"; type = "character data"; code_mime = "ebcdic"; } else { rv = 0; goto done; /* doesn't look like text at all */ } } if (nbytes <= 1) { rv = 0; goto done; } /* Convert ubuf to UTF-8 and try text soft magic */ /* If original was ASCII or UTF-8, could use nbuf instead of re-converting. */ /* malloc size is a conservative overestimate; could be re-converting improved, or at least realloced after re-converting conversion. */ mlen = ulen * 6; if (!(utf8_buf = malloc(mlen))) { file_oomem(ms, mlen); goto done; } if (!(utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen))) goto done; if (file_softmagic(ms, utf8_buf, utf8_end - utf8_buf, TEXTTEST) != 0) { rv = 1; goto done; } /* look for tokens from names.h - this is expensive! */ if ((ms->flags & R_MAGIC_NO_CHECK_TOKENS) != 0) goto subtype_identified; i = 0; while (i < ulen) { size_t end; /* skip past any leading space */ while (i < ulen && ISSPC(ubuf[i])) i++; if (i >= ulen) break; /* find the next whitespace */ for (end = i + 1; end < nbytes; end++) if (ISSPC(ubuf[end])) break; /* compare the word thus isolated against the token list */ for (p = names; p < names + NNAMES; p++) { if (ascmatch((const ut8 *)p->name, ubuf + i, end - i)) { subtype = types[p->type].human; subtype_mime = types[p->type].mime; goto subtype_identified; } } i = end; } subtype_identified: /* Now try to discover other details about the file. */ for (i = 0; i < ulen; i++) { if (ubuf[i] == '\n') { if (seen_cr) n_crlf++; else n_lf++; last_line_end = i; } else if (seen_cr) n_cr++; seen_cr = (ubuf[i] == '\r'); if (seen_cr) last_line_end = i; if (ubuf[i] == 0x85) { /* X3.64/ECMA-43 "next line" character */ n_nel++; last_line_end = i; } /* If this line is _longer_ than MAXLINELEN, remember it. */ if (i > last_line_end + MAXLINELEN) has_long_lines = 1; if (ubuf[i] == '\033') has_escapes = 1; if (ubuf[i] == '\b') has_backspace = 1; } /* Beware, if the data has been truncated, the final CR could have been followed by a LF. If we have HOWMANY bytes, it indicates that the data might have been truncated, probably even before this function was called. */ if (seen_cr && nbytes < HOWMANY) n_cr++; if (mime) { if (mime & R_MAGIC_MIME_TYPE) { if (subtype_mime) { if (file_printf(ms, subtype_mime) == -1) goto done; } else { if (file_printf(ms, "text/plain") == -1) goto done; } } if ((mime == 0 || mime == R_MAGIC_MIME) && code_mime) { if ((mime & R_MAGIC_MIME_TYPE) && file_printf(ms, " charset=") == -1) goto done; if (file_printf(ms, code_mime) == -1) goto done; } if (mime == R_MAGIC_MIME_ENCODING) if (file_printf(ms, "binary") == -1){ rv = 1; goto done; } } else { if (file_printf(ms, code) == -1) goto done; if (subtype) { if (file_printf(ms, " ") == -1) goto done; if (file_printf(ms, subtype) == -1) goto done; } if (file_printf(ms, " ") == -1) goto done; if (file_printf(ms, type) == -1) goto done; if (has_long_lines) if (file_printf(ms, ", with very long lines") == -1) goto done; /* * Only report line terminators if we find one other than LF, * or if we find none at all. */ if ((n_crlf == 0 && n_cr == 0 && n_nel == 0 && n_lf == 0) || (n_crlf != 0 || n_cr != 0 || n_nel != 0)) { if (file_printf(ms, ", with") == -1) goto done; if (n_crlf == 0 && n_cr == 0 && n_nel == 0 && n_lf == 0) { if (file_printf(ms, " no") == -1) goto done; } else { if (n_crlf) { if (file_printf(ms, " CRLF") == -1) goto done; if (n_cr || n_lf || n_nel) if (file_printf(ms, ",") == -1) goto done; } if (n_cr) { if (file_printf(ms, " CR") == -1) goto done; if (n_lf || n_nel) if (file_printf(ms, ",") == -1) goto done; } if (n_lf) { if (file_printf(ms, " LF") == -1) goto done; if (n_nel) if (file_printf(ms, ",") == -1) goto done; } if (n_nel) if (file_printf(ms, " NEL") == -1) goto done; } if (file_printf(ms, " line terminators") == -1) goto done; } if (has_escapes) if (file_printf(ms, ", with escape sequences") == -1) goto done; if (has_backspace) if (file_printf(ms, ", with overstriking") == -1) goto done; } rv = 1; done: free (nbuf); free (ubuf); free (utf8_buf); return rv; }
/** Following should match the screen_char.color field. */ unsigned char color[SCREEN_COLOR_SIZE]; }; #if defined(CONFIG_TRUE_COLOR) #define INIT_SCREEN_STATE { 0xFF, 0xFF, 0xFF, 0xFF, 0, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} } #elif defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) #define INIT_SCREEN_STATE { 0xFF, 0xFF, 0xFF, 0xFF, 0, { 0xFF, 0xFF } } #else #define INIT_SCREEN_STATE { 0xFF, 0xFF, 0xFF, 0xFF, 0, { 0xFF } } #endif #ifdef CONFIG_TRUE_COLOR static inline int compare_color_true(unsigned char *a, unsigned char *b) { return !memcmp(a, b, 6); } static inline int compare_bg_color_true(unsigned char *a, unsigned char *b) { return (a[3] == b[3] && a[4] == b[4] && a[5] == b[5]); } static inline int compare_fg_color_true(unsigned char *a, unsigned char *b) { return (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]); } static inline void copy_color_true(unsigned char *a, unsigned char *b) { memcpy(a, b, 6); } static inline int background_is_black(unsigned char *a) { static unsigned char b[6] = {0, 0, 0, 0, 0, 0}; return compare_bg_color_true(a, b); } #endif #if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) static inline int compare_color_256(unsigned char *a, unsigned char *b) { return (a[0] == b[0] && a[1] == b[1]); } static inline int compare_bg_color_256(unsigned char *a, unsigned char *b) { return (a[1] == b[1]); } static inline int compare_fg_color_256(unsigned char *a, unsigned char *b) { return (a[0] == b[0]); } static inline void copy_color_256(unsigned char *a, unsigned char *b) { a[0] = b[0]; a[1] = b[1]; } #endif static inline int compare_color_16(unsigned char *a, unsigned char *b) { return (a[0] == b[0]); } static inline int compare_bg_color_16(unsigned char *a, unsigned char *b) { return (TERM_COLOR_BACKGROUND_16(a) == TERM_COLOR_BACKGROUND_16(b)); } static inline int compare_fg_color_16(unsigned char *a, unsigned char *b) { return (TERM_COLOR_FOREGROUND_16(a) == TERM_COLOR_FOREGROUND_16(b)); } static inline void copy_color_16(unsigned char *a, unsigned char *b) { a[0] = b[0]; } #ifdef CONFIG_UTF8 static inline void add_char_data(struct string *screen, struct screen_driver *driver, unicode_val_T data, unsigned char border) #else /* !CONFIG_UTF8 */ static inline void add_char_data(struct string *screen, struct screen_driver *driver, unsigned char data, unsigned char border) #endif /* !CONFIG_UTF8 */ { /* charset use_utf8_io border data add_to_string * ------- ----------- ------ ---------------- ---------------- * unibyte 0 0 terminal unibyte terminal unibyte * unibyte 0 1 enum border_char border unibyte * unibyte 1 0 terminal unibyte UTF-8 * unibyte 1 1 enum border_char UTF-8 * UTF-8 1 0 UTF-32 (*) UTF-8 * UTF-8 1 1 enum border_char UTF-8 * * (*) For "UTF-32" above, data can also be UCS_NO_CHAR, * in which case this function must not alter *screen. */ if (border && driver->opt.frame && data >= 176 && data < 224) data = driver->opt.frame[data - 176]; #ifdef CONFIG_UTF8 if (driver->opt.utf8_cp) { if (border) { data = cp2u(driver->opt.charsets[1], (unsigned char) data); } if (data == UCS_NO_CHAR) return; #ifdef CONFIG_COMBINE if (data >= UCS_BEGIN_COMBINED && data <= last_combined) { unicode_val_T *text = combined[data - UCS_BEGIN_COMBINED]; if (driver->opt.combine) { /* XTerm */ while (*text != UCS_END_COMBINED) { add_to_string(screen, encode_utf8(*text)); text++; } return; } else { /* Others */ data = *text; } } #endif /* CONFIG_COMBINE */ if (!isscreensafe_ucs(data)) data = UCS_SPACE; add_to_string(screen, encode_utf8(data)); } else #endif /* CONFIG_UTF8 */ if (use_utf8_io(driver)) { int charset = driver->opt.charsets[!!border]; if (border || isscreensafe(data)) add_to_string(screen, cp2utf8(charset, data)); else /* UCS_SPACE <= 0x7F and so fits in one UTF-8 byte */ add_char_to_string(screen, UCS_SPACE); } else { if (border || isscreensafe(data)) add_char_to_string(screen, (unsigned char)data); else add_char_to_string(screen, ' '); } }