示例#1
0
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;
}
示例#2
0
文件: xml.cpp 项目: oeuftete/wx-xword
// 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);
}
示例#3
0
文件: xml.cpp 项目: oeuftete/wx-xword
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());
}
示例#4
0
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;
   }
}
示例#5
0
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;
}
示例#6
0
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;
}
示例#7
0
/*
 *	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;
} 
示例#8
0
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;
}
示例#9
0
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;
   }
}
示例#10
0
//-----------------------------------------------------------------------------
// 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());
}
示例#11
0
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;
}
示例#12
0
文件: xml.hpp 项目: oeuftete/wx-xword
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);
}
示例#14
0
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;
}
示例#15
0
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;
}
示例#16
0
文件: screen.c 项目: rkd77/elinks-tv
	/** 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, ' ');
	}
}