// <DEFINE_MODIFIER> void SettingLoader::load_DEFINE_MODIFIER() { Token *t = getToken(); Modifier::Type mt; if (*t == _T("shift") ) mt = Modifier::Type_Shift; else if (*t == _T("alt") || *t == _T("meta") || *t == _T("menu") ) mt = Modifier::Type_Alt; else if (*t == _T("control") || *t == _T("ctrl") ) mt = Modifier::Type_Control; else if (*t == _T("windows") || *t == _T("win") ) mt = Modifier::Type_Windows; else throw ErrorMessage() << _T("`") << *t << _T("': invalid modifier name."); if (*getToken() != _T("=")) throw ErrorMessage() << _T("there must be `=' after modifier name."); while (!isEOL()) { t = getToken(); Key *key = m_setting->m_keyboard.searchKeyByNonAliasName(t->getString()); if (!key) throw ErrorMessage() << _T("`") << *t << _T("': invalid key name."); m_setting->m_keyboard.addModifier(mt, key); } }
unsigned int skipWhiteSpace(const char *&str) { unsigned int flags = 0; while (1) { if (IsWhiteSpace(*str)) { ++str; } else if (isEOL(*str)) { /*while (isEOL(*str)) ++str;*/ flags |= EPF_PASSED_EOL; break; } else if (*str == 0) { flags |= EPF_PASSED_EOF; break; } else break; } return flags; }
// <IF> void SettingLoader::load_IF() { if (!getToken()->isOpenParen()) throw ErrorMessage() << _T("there must be `(' after `if'."); Token *t = getToken(); // <SYMBOL> or ! bool not = false; if (*t == _T("!")) { not = true; t = getToken(); // <SYMBOL> } bool doesSymbolExist = (m_setting->m_symbols.find(t->getString()) != m_setting->m_symbols.end()); bool doesRead = ((doesSymbolExist && !not) || (!doesSymbolExist && not)); if (0 < m_canReadStack.size()) doesRead = doesRead && m_canReadStack.back(); if (!getToken()->isCloseParen()) throw ErrorMessage() << _T("there must be `)'."); m_canReadStack.push_back(doesRead); if (!isEOL()) { size_t len = m_canReadStack.size(); load_LINE(); if (len < m_canReadStack.size()) { bool r = m_canReadStack.back(); m_canReadStack.pop_back(); m_canReadStack[len - 1] = r && doesRead; } else if (len == m_canReadStack.size()) m_canReadStack.pop_back(); else ; // `end' found } }
void SerialPort::writeLine(std::string line) { // if string does not end with new line, add it if( line.length()==0 || !isEOL( *line.rbegin() ) ) line+="\n"; // now send the data Lock lock{m_}; writeData( std::move(line) ); return; }
// argument "(" bool SettingLoader::getOpenParen(bool i_doesThrow, const _TCHAR *i_name) { if (!isEOL() && lookToken()->isOpenParen()) { getToken(); return true; } if (i_doesThrow) throw ErrorMessage() << _T("there must be `(' after `&") << i_name << _T("'."); return false; }
// argument ")" bool SettingLoader::getCloseParen(bool i_doesThrow, const _TCHAR *i_name) { if (!isEOL() && lookToken()->isCloseParen()) { getToken(); return true; } if (i_doesThrow) throw ErrorMessage() << _T("`&") << i_name << _T("': too many arguments."); return false; }
// argument "," bool SettingLoader::getComma(bool i_doesThrow, const _TCHAR *i_name) { if (!isEOL() && lookToken()->isComma()) { getToken(); return true; } if (i_doesThrow) throw ErrorMessage() << _T("`&") << i_name << _T("': comma expected."); return false; }
void Tokenizer::absorbed(std::streambuf::int_type ch) { if (isTab(ch)) { mCurrentColumn += nTabSize - mCurrentColumn % nTabSize; } else if (isEOL(ch)) { ++mCurrentLine; mCurrentColumn = 0; if (!eof()) { int nch = mpInput->peek(); if (isEOL(nch) && (nch != ch)) mpInput->get(); } } else { ++mCurrentColumn; } }
// <KEY_SEQUENCE> KeySeq *SettingLoader::load_KEY_SEQUENCE( const tstringi &i_name, bool i_isInParen, Modifier::Type i_mode) { KeySeq keySeq(i_name); while (!isEOL()) { Modifier::Type mode; Modifier modifier = load_MODIFIER(i_mode, m_defaultKeySeqModifier, &mode); keySeq.setMode(mode); Token *t = lookToken(); if (t->isCloseParen() && i_isInParen) break; else if (t->isOpenParen()) { getToken(); // open paren KeySeq *ks = load_KEY_SEQUENCE(_T(""), true, i_mode); getToken(); // close paren keySeq.add(ActionKeySeq(ks)); } else if (*t == _T("$")) { // <KEYSEQ_NAME> getToken(); t = getToken(); KeySeq *ks = m_setting->m_keySeqs.searchByName(t->getString()); if (ks == NULL) throw ErrorMessage() << _T("`$") << *t << _T("': unknown keyseq name."); if (!ks->isCorrectMode(i_mode)) throw ErrorMessage() << _T("`$") << *t << _T("': Some of R-, IL-, IC-, NL-, CL-, SL-, KL-, MAX-, MIN-, MMAX-, MMIN-, T-, TS-, M0...M9- and L0...L9- are used in the keyseq. They are prohibited in this context."); keySeq.setMode(ks->getMode()); keySeq.add(ActionKeySeq(ks)); } else if (*t == _T("&")) { // <FUNCTION_NAME> getToken(); t = getToken(); // search function ActionFunction af(createFunctionData(t->getString()), modifier); if (af.m_functionData == NULL) throw ErrorMessage() << _T("`&") << *t << _T("': unknown function name."); af.m_functionData->load(this); keySeq.add(af); } else { // <KEYSEQ_MODIFIED_KEY_NAME> ModifiedKey mkey; mkey.m_modifier = modifier; mkey.m_key = load_KEY_NAME(); keySeq.add(ActionKey(mkey)); } } return m_setting->m_keySeqs.add(keySeq); }
std::string SerialPort::recvData(const unsigned int timeout) { constexpr size_t bufSize=32; // TODO: magic value char buf[bufSize]; // input buffer char *ptr =buf; // start from size_t left=bufSize-1; // max more bytes to read while(true) // note: will stop on timeout from select(), on data read { // wait for data or timeout fd_set rdfd; FD_ZERO(&rdfd); FD_SET(fd_.get(), &rdfd); struct timeval tout={0, timeout*1000}; // wait a while for the data const int ret=select(fd_.get()+1, &rdfd, nullptr, nullptr, &tout); if(ret<0) throw ExceptionIO{"select() failed for some reason"}; if(ret==0) throw ExceptionTimeout{"response didn't arrived in expected time"}; // read new data const int n=read(fd_.get(), ptr, 1); if(n<0) throw ExceptionIO{"read() failed for some reason"}; // check for the end of line bool eol=false; std::for_each(ptr, ptr+n, [&eol](const char c){ if( isEOL(c) ) eol=true; }); if(eol) { ptr[n]=0; assert( std::string{buf}.length()<bufSize ); return std::string{buf}; } // ok - something more to be read... ptr +=n; left-=n; // check for buffer end if(left==0) throw ExceptionIO{"buffer full of junk - discarding content"}; } // while(true) assert(!"code never reaches here"); return "?? code never reaches here ??"; }
void Tokenizer::skipEOL() { if (eof()) return; auto ch = mpInput->get(); if (isEOL(ch)) { absorbed(ch); } else { mpInput->clear(); mpInput->unget(); } }
void Tokenizer::consumeCStyleBlockComment() { mpCurrent->setType(Token::TYPE_COMMENT); for(;;) { if (eof()) { mpMessageCollector->addMessage( Message::SEVERITY_ERROR, Message::t_unterminatedComment, mpSourceId, mpCurrent->line(), mpCurrent->beginColumn()); mpCurrent.reset(); return; } auto ch = mpInput->get(); if (isEOL(ch)) { mBlockComment = true; mpInput->clear(); mpInput->unget(); break; } if (isCStyleBlockCommentSecondChar(ch)) { if (eof()) { mpMessageCollector->addMessage( Message::SEVERITY_ERROR, Message::t_unterminatedComment, mpSourceId, mpCurrent->line(), mpCurrent->beginColumn()); mpCurrent.reset(); return; } auto nch = mpInput->get(); if (isCStyleInitialCommentChar(nch)) { absorbed(ch); absorbed(nch); mBlockComment = false; break; } mpInput->clear(); mpInput->unget(); } absorbed(ch); mpCurrent->addChar(ch); } mpCurrent->setEndColumn(column()); }
void Tokenizer::consumeCStyleLineComment() { mpCurrent->setType(Token::TYPE_COMMENT); while (!eof()) { auto ch = mpInput->get(); if (isEOL(ch)) { mpInput->clear(); mpInput->unget(); break; } absorbed(ch); mpCurrent->addChar(ch); } mpCurrent->setEndColumn(column()); }
//------------------------------------------------------------------------------ void TextWrapper::update(sn::u32 width, const Font & font, const FontFormat & format) { if (m_wrapMode == TGUI_WRAP_NONE) { updateNoWrap(); return; } // TODO Implement word-based wrapping m_wraps.resize(r_model.getLineCount()); u32 wrapCount = 0; for (u32 j = 0; j < r_model.getLineCount(); ++j) { const std::string & str = r_model.getLine(j); u32 x = 0; for (u32 i = 0; i < str.size(); ++i) { char c = str[i]; if (isEOL(c)) break; const Glyph & glyph = font.getGlyph(c, format); u32 offset = glyph.advance; x += offset; if (x > width) { if (m_wraps.size() == wrapCount) m_wraps.push_back({ j, i }); else m_wraps[wrapCount] = { j, i }; ++wrapCount; x = 0; } } if (m_wraps.size() == wrapCount) m_wraps.push_back({ j, str.size() }); else m_wraps[wrapCount] = { j, str.size() }; ++wrapCount; } }
// <SCAN_CODES> void SettingLoader::load_SCAN_CODES(Key *o_key) { for (int j = 0; j < Key::MAX_SCAN_CODES_SIZE && !isEOL(); ++ j) { ScanCode sc; sc.m_flags = 0; while (true) { Token *t = getToken(); if (t->isNumber()) { sc.m_scan = (u_char)t->getNumber(); o_key->addScanCode(sc); break; } if (*t == _T("E0-")) sc.m_flags |= ScanCode::E0; else if (*t == _T("E1-")) sc.m_flags |= ScanCode::E1; else throw ErrorMessage() << _T("`") << *t << _T("': invalid modifier."); } } }
/* * eSearch - scan a file for a search string (extended) */ static vi_rc eSearch( char *fn, char *res ) { int i; char *buff; FILE *f; /* * init for file i/o */ f = fopen( fn, "r" ); if( f == NULL ) { return( ERR_FILE_NOT_FOUND ); } /* * read lines from the file, and search through them */ buff = StaticAlloc(); while( fgets( buff, EditVars.MaxLine, f ) != NULL ) { for( i = strlen( buff ); i && isEOL( buff[i - 1] ); --i ) { buff[i - 1] = 0; } i = RegExec( cRx, buff, TRUE ); if( RegExpError != ERR_NO_ERR ) { StaticFree( buff ); return( RegExpError ); } if( i ) { for( i = 0; i < MAX_DISP; i++ ) { res[i] = buff[i]; } res[i] = 0; fclose( f ); StaticFree( buff ); return( FGREP_FOUND_STRING ); } } fclose( f ); StaticFree( buff ); return( ERR_NO_ERR ); } /* eSearch */
// <ELSE> <ELSEIF> void SettingLoader::load_ELSE(bool i_isElseIf, const tstringi &i_token) { bool doesRead = !load_ENDIF(i_token); if (0 < m_canReadStack.size()) doesRead = doesRead && m_canReadStack.back(); m_canReadStack.push_back(doesRead); if (!isEOL()) { size_t len = m_canReadStack.size(); if (i_isElseIf) load_IF(); else load_LINE(); if (len < m_canReadStack.size()) { bool r = m_canReadStack.back(); m_canReadStack.pop_back(); m_canReadStack[len - 1] = doesRead && r; } else if (len == m_canReadStack.size()) m_canReadStack.pop_back(); else ; // `end' found } }
// <LINE> void SettingLoader::load_LINE() { Token *i_token = getToken(); // <COND_SYMBOL> if (*i_token == _T("if") || *i_token == _T("and")) load_IF(); else if (*i_token == _T("else")) load_ELSE(false, i_token->getString()); else if (*i_token == _T("elseif") || *i_token == _T("elsif") || *i_token == _T("elif") || *i_token == _T("or")) load_ELSE(true, i_token->getString()); else if (*i_token == _T("endif")) load_ENDIF(_T("endif")); else if (0 < m_canReadStack.size() && !m_canReadStack.back()) { while (!isEOL()) getToken(); } else if (*i_token == _T("define")) load_DEFINE(); // <INCLUDE> else if (*i_token == _T("include")) load_INCLUDE(); // <KEYBOARD_DEFINITION> else if (*i_token == _T("def")) load_KEYBOARD_DEFINITION(); // <KEYMAP_DEFINITION> else if (*i_token == _T("keymap") || *i_token == _T("keymap2") || *i_token == _T("window")) load_KEYMAP_DEFINITION(i_token); // <KEY_ASSIGN> else if (*i_token == _T("key")) load_KEY_ASSIGN(); // <EVENT_ASSIGN> else if (*i_token == _T("event")) load_EVENT_ASSIGN(); // <MODIFIER_ASSIGNMENT> else if (*i_token == _T("mod")) load_MODIFIER_ASSIGNMENT(); // <KEYSEQ_DEFINITION> else if (*i_token == _T("keyseq")) load_KEYSEQ_DEFINITION(); else throw ErrorMessage() << _T("syntax error `") << *i_token << _T("'."); }
// load (called from load(Setting *, const tstringi &) only) void SettingLoader::load(const tstringi &i_filename) { m_currentFilename = i_filename; tstring data; if (!readFile(&data, m_currentFilename)) { Acquire a(m_soLog); *m_log << m_currentFilename << _T(" : error: file not found") << std::endl; #if 1 *m_log << data << std::endl; #endif m_isThereAnyError = true; return; } // prefix if (m_prefixesRefCcount == 0) { static const _TCHAR *prefixes[] = { _T("="), _T("=>"), _T("&&"), _T("||"), _T(":"), _T("$"), _T("&"), _T("-="), _T("+="), _T("!!!"), _T("!!"), _T("!"), _T("E0-"), _T("E1-"), // <SCAN_CODE_EXTENTION> _T("S-"), _T("A-"), _T("M-"), _T("C-"), // <BASIC_MODIFIER> _T("W-"), _T("*"), _T("~"), _T("U-"), _T("D-"), // <KEYSEQ_MODIFIER> _T("R-"), _T("IL-"), _T("IC-"), _T("I-"), // <ASSIGN_MODIFIER> _T("NL-"), _T("CL-"), _T("SL-"), _T("KL-"), _T("MAX-"), _T("MIN-"), _T("MMAX-"), _T("MMIN-"), _T("T-"), _T("TS-"), _T("M0-"), _T("M1-"), _T("M2-"), _T("M3-"), _T("M4-"), _T("M5-"), _T("M6-"), _T("M7-"), _T("M8-"), _T("M9-"), _T("L0-"), _T("L1-"), _T("L2-"), _T("L3-"), _T("L4-"), _T("L5-"), _T("L6-"), _T("L7-"), _T("L8-"), _T("L9-"), }; m_prefixes = new std::vector<tstringi>; for (size_t i = 0; i < NUMBER_OF(prefixes); ++ i) m_prefixes->push_back(prefixes[i]); std::sort(m_prefixes->begin(), m_prefixes->end(), prefixSortPred); } m_prefixesRefCcount ++; // create parser Parser parser(data.c_str(), data.size()); parser.setPrefixes(m_prefixes); while (true) { try { if (!parser.getLine(&m_tokens)) break; m_ti = m_tokens.begin(); } catch (ErrorMessage &e) { if (m_log && m_soLog) { Acquire a(m_soLog); *m_log << m_currentFilename << _T("(") << parser.getLineNumber() << _T(") : error: ") << e << std::endl; } m_isThereAnyError = true; continue; } try { load_LINE(); if (!isEOL()) throw WarningMessage() << _T("back garbage is ignored."); } catch (WarningMessage &w) { if (m_log && m_soLog) { Acquire a(m_soLog); *m_log << i_filename << _T("(") << parser.getLineNumber() << _T(") : warning: ") << w << std::endl; } } catch (ErrorMessage &e) { if (m_log && m_soLog) { Acquire a(m_soLog); *m_log << i_filename << _T("(") << parser.getLineNumber() << _T(") : error: ") << e << std::endl; } m_isThereAnyError = true; } } // m_prefixes -- m_prefixesRefCcount; if (m_prefixesRefCcount == 0) delete m_prefixes; if (0 < m_canReadStack.size()) { Acquire a(m_soLog); *m_log << m_currentFilename << _T("(") << parser.getLineNumber() << _T(") : error: unbalanced `if'. ") << _T("you forget `endif', didn'i_token you?") << std::endl; m_isThereAnyError = true; } }
// <KEYMAP_DEFINITION> void SettingLoader::load_KEYMAP_DEFINITION(const Token *i_which) { Keymap::Type type = Keymap::Type_keymap; Token *name = getToken(); // <KEYMAP_NAME> tstringi windowClassName; tstringi windowTitleName; KeySeq *keySeq = NULL; Keymap *parentKeymap = NULL; bool isKeymap2 = false; bool doesLoadDefaultKeySeq = false; if (!isEOL()) { Token *t = lookToken(); if (*i_which == _T("window")) { // <WINDOW> if (t->isOpenParen()) // "(" <WINDOW_CLASS_NAME> "&&" <WINDOW_TITLE_NAME> ")" // "(" <WINDOW_CLASS_NAME> "||" <WINDOW_TITLE_NAME> ")" { getToken(); windowClassName = getToken()->getRegexp(); t = getToken(); if (*t == _T("&&")) type = Keymap::Type_windowAnd; else if (*t == _T("||")) type = Keymap::Type_windowOr; else throw ErrorMessage() << _T("`") << *t << _T("': unknown operator."); windowTitleName = getToken()->getRegexp(); if (!getToken()->isCloseParen()) throw ErrorMessage() << _T("there must be `)'."); } else if (t->isRegexp()) { // <WINDOW_CLASS_NAME> getToken(); type = Keymap::Type_windowAnd; windowClassName = t->getRegexp(); } } else if (*i_which == _T("keymap")) ; else if (*i_which == _T("keymap2")) isKeymap2 = true; else ASSERT(false); if (!isEOL()) doesLoadDefaultKeySeq = true; } m_currentKeymap = m_setting->m_keymaps.add( Keymap(type, name->getString(), windowClassName, windowTitleName, NULL, NULL)); if (doesLoadDefaultKeySeq) { Token *t = lookToken(); // <KEYMAP_PARENT> if (*t == _T(":")) { getToken(); t = getToken(); parentKeymap = m_setting->m_keymaps.searchByName(t->getString()); if (!parentKeymap) throw ErrorMessage() << _T("`") << *t << _T("': unknown keymap name."); } if (!isEOL()) { t = getToken(); if (!(*t == _T("=>") || *t == _T("="))) throw ErrorMessage() << _T("`") << *t << _T("': syntax error."); keySeq = SettingLoader::load_KEY_SEQUENCE(); } } if (keySeq == NULL) { FunctionData *fd; if (type == Keymap::Type_keymap && !isKeymap2) fd = createFunctionData(_T("KeymapParent")); else if (type == Keymap::Type_keymap && !isKeymap2) fd = createFunctionData(_T("Undefined")); else // (type == Keymap::Type_windowAnd || type == Keymap::Type_windowOr) fd = createFunctionData(_T("KeymapParent")); ASSERT( fd ); keySeq = m_setting->m_keySeqs.add( KeySeq(name->getString()).add(ActionFunction(fd))); } m_currentKeymap->setIfNotYet(keySeq, parentKeymap); }
// <..._MODIFIER> Modifier SettingLoader::load_MODIFIER( Modifier::Type i_mode, Modifier i_modifier, Modifier::Type *o_mode) { if (o_mode) *o_mode = Modifier::Type_begin; Modifier isModifierSpecified; enum { PRESS, RELEASE, DONTCARE } flag = PRESS; int i; for (i = i_mode; i < Modifier::Type_ASSIGN; ++ i) { i_modifier.dontcare(Modifier::Type(i)); isModifierSpecified.on(Modifier::Type(i)); } Token *t = NULL; continue_loop: while (!isEOL()) { t = lookToken(); const static struct { const _TCHAR *m_s; Modifier::Type m_mt; } map[] = { // <BASIC_MODIFIER> { _T("S-"), Modifier::Type_Shift }, { _T("A-"), Modifier::Type_Alt }, { _T("M-"), Modifier::Type_Alt }, { _T("C-"), Modifier::Type_Control }, { _T("W-"), Modifier::Type_Windows }, // <KEYSEQ_MODIFIER> { _T("U-"), Modifier::Type_Up }, { _T("D-"), Modifier::Type_Down }, // <ASSIGN_MODIFIER> { _T("R-"), Modifier::Type_Repeat }, { _T("IL-"), Modifier::Type_ImeLock }, { _T("IC-"), Modifier::Type_ImeComp }, { _T("I-"), Modifier::Type_ImeComp }, { _T("NL-"), Modifier::Type_NumLock }, { _T("CL-"), Modifier::Type_CapsLock }, { _T("SL-"), Modifier::Type_ScrollLock }, { _T("KL-"), Modifier::Type_KanaLock }, { _T("MAX-"), Modifier::Type_Maximized }, { _T("MIN-"), Modifier::Type_Minimized }, { _T("MMAX-"), Modifier::Type_MdiMaximized }, { _T("MMIN-"), Modifier::Type_MdiMinimized }, { _T("T-"), Modifier::Type_Touchpad }, { _T("TS-"), Modifier::Type_TouchpadSticky }, { _T("M0-"), Modifier::Type_Mod0 }, { _T("M1-"), Modifier::Type_Mod1 }, { _T("M2-"), Modifier::Type_Mod2 }, { _T("M3-"), Modifier::Type_Mod3 }, { _T("M4-"), Modifier::Type_Mod4 }, { _T("M5-"), Modifier::Type_Mod5 }, { _T("M6-"), Modifier::Type_Mod6 }, { _T("M7-"), Modifier::Type_Mod7 }, { _T("M8-"), Modifier::Type_Mod8 }, { _T("M9-"), Modifier::Type_Mod9 }, { _T("L0-"), Modifier::Type_Lock0 }, { _T("L1-"), Modifier::Type_Lock1 }, { _T("L2-"), Modifier::Type_Lock2 }, { _T("L3-"), Modifier::Type_Lock3 }, { _T("L4-"), Modifier::Type_Lock4 }, { _T("L5-"), Modifier::Type_Lock5 }, { _T("L6-"), Modifier::Type_Lock6 }, { _T("L7-"), Modifier::Type_Lock7 }, { _T("L8-"), Modifier::Type_Lock8 }, { _T("L9-"), Modifier::Type_Lock9 }, }; for (int i = 0; i < NUMBER_OF(map); ++ i) if (*t == map[i].m_s) { getToken(); Modifier::Type mt = map[i].m_mt; if (static_cast<int>(i_mode) <= static_cast<int>(mt)) throw ErrorMessage() << _T("`") << *t << _T("': invalid modifier at this context."); switch (flag) { case PRESS: i_modifier.press(mt); break; case RELEASE: i_modifier.release(mt); break; case DONTCARE: i_modifier.dontcare(mt); break; } isModifierSpecified.on(mt); flag = PRESS; if (o_mode && *o_mode < mt) { if (mt < Modifier::Type_BASIC) *o_mode = Modifier::Type_BASIC; else if (mt < Modifier::Type_KEYSEQ) *o_mode = Modifier::Type_KEYSEQ; else if (mt < Modifier::Type_ASSIGN) *o_mode = Modifier::Type_ASSIGN; } goto continue_loop; } if (*t == _T("*")) { getToken(); flag = DONTCARE; continue; } if (*t == _T("~")) { getToken(); flag = RELEASE; continue; } break; } for (i = Modifier::Type_begin; i != Modifier::Type_end; ++ i) if (!isModifierSpecified.isOn(Modifier::Type(i))) switch (flag) { case PRESS: break; case RELEASE: i_modifier.release(Modifier::Type(i)); break; case DONTCARE: i_modifier.dontcare(Modifier::Type(i)); break; } // fix up and down bool isDontcareUp = i_modifier.isDontcare(Modifier::Type_Up); bool isDontcareDown = i_modifier.isDontcare(Modifier::Type_Down); bool isOnUp = i_modifier.isOn(Modifier::Type_Up); bool isOnDown = i_modifier.isOn(Modifier::Type_Down); if (isDontcareUp && isDontcareDown) ; else if (isDontcareUp) i_modifier.on(Modifier::Type_Up, !isOnDown); else if (isDontcareDown) i_modifier.on(Modifier::Type_Down, !isOnUp); else if (isOnUp == isOnDown) { i_modifier.dontcare(Modifier::Type_Up); i_modifier.dontcare(Modifier::Type_Down); } // fix repeat if (!isModifierSpecified.isOn(Modifier::Type_Repeat)) i_modifier.dontcare(Modifier::Type_Repeat); return i_modifier; }
void CWavefrontObjParser::parseMesh(CMesh &mesh, bool flip) { enum EOBJElement { OE_POSITION, OE_NORMAL, OE_UV, OE_NONE, }; int vertexElementTypeOrder[] = {-1, -1, -1}; int vertexElementTypeCount = -1; EOBJElement LastElementType = OE_NONE; std::cout << "Parsing mesh" << std::endl; struct sUniqueVertexIndex { sUniqueVertexIndex(){} sUniqueVertexIndex(size_t pos,size_t normal,size_t uv) : mPosition(pos), mNormal(normal), mUv(uv){} sUniqueVertexIndex(const sUniqueVertexIndex &other) : mPosition(other.mPosition), mNormal(other.mNormal), mUv(other.mUv){} CHash GetHash() const { CHash hash(mPosition); hash.next_hash(mNormal); hash.next_hash(mUv); return hash; } size_t mPosition; size_t mNormal; size_t mUv; }; std::vector<CVector3f> positions; std::vector<CVector3f> normals; std::vector<CVector2f> uvs; size_t vertex_capacity = mesh.m_vertex_capacity; positions.reserve(vertex_capacity); normals.reserve(vertex_capacity); uvs.reserve(vertex_capacity); CVector3f t_vertex; CVector3f t_normal; CVector2f t_uv; enum {MAX_FACE_EDGE_COUNT = 64}; int tmpFace[MAX_FACE_EDGE_COUNT * 3]; std::vector<sUniqueVertexIndex> vVertexIndices; CHashMapInt *sUniqueVertices = new CHashMapInt(); //TODO: read these in properely mesh.mVertexBuffer.Lock(); mesh.mIndexBuffer.Lock(); // The while-read only consumes the first part of the header. #ifdef USETIMER CHighResolutionTimer ctimer; ctimer.StartHRTimer(); #endif while(fscanf_s(mPfile,"%s",mReadHeader,sizeof(mReadHeader)) != EOF ) { // Match a Vertex if (strcmp(mReadHeader,"v") == 0) { fscanf_s(mPfile,"%f%f%f",&t_vertex[0],&t_vertex[1],&t_vertex[2]); // range-based looper for each element (doesn't work for this compiler) positions.push_back(t_vertex * mesh_scale_factor); if (LastElementType != OE_POSITION) { ++vertexElementTypeCount; vertexElementTypeOrder[OE_POSITION] = vertexElementTypeCount; LastElementType = OE_POSITION; } } else if (strcmp(mReadHeader,"vn") == 0) { fscanf_s(mPfile,"%f%f%f",&t_normal[0],&t_normal[1],&t_normal[2]); normals.push_back(t_normal); if (LastElementType != OE_NORMAL) { ++vertexElementTypeCount; vertexElementTypeOrder[OE_NORMAL] = vertexElementTypeCount; LastElementType = OE_NORMAL; } } else if (strcmp(mReadHeader,"vt") == 0) { fscanf_s(mPfile,"%f%f",&t_uv.x,&t_uv.y); uvs.push_back(t_uv); if (LastElementType != OE_UV) { ++vertexElementTypeCount; vertexElementTypeOrder[OE_UV] = vertexElementTypeCount; LastElementType = OE_UV; } } else //mMesh.beg int lineNumber = 0; if (strcmp(mReadHeader,"f") == 0) { char szLine[4096]; fgets(szLine, 4096, mPfile); int cidx = 0; int pcidx = 0; int element_count = 0; int max_element_count =0; const char *ch = szLine; while (!isEOL(*ch) && (*ch)) { if (IsWhiteSpace(*ch)) { if (element_count > max_element_count) max_element_count = element_count; element_count = 0; skipWhiteSpace(ch); } const char *startch = ch; while (isalnum(*ch)) { ++ch; } tmpFace[cidx++] = atoiSimpleCount(startch, ch - startch); if (*ch == '/') { ++element_count; while (*ch == '/') { ++ch; } } } //std::cout << lineNumber << std::endl; element_count = max_element_count + 1; size_t vcount = (cidx) / element_count; std::vector<size_t> polygon_indices; int *cface= tmpFace; if (uvs.size() == 0) uvs.push_back(CVector2f(0,0)); for (unsigned int i = 0; i < vcount; ++i) { //sUniqueVertexIndex vref = (element_count == 2) ? sUniqueVertexIndex(cface[vertexElementTypeOrder[0]] - 1, cface[vertexElementTypeOrder[1]] - 1, 0) : sUniqueVertexIndex(cface[vertexElementTypeOrder[0]] - 1, cface[vertexElementTypeOrder[1]] - 1, cface[vertexElementTypeOrder[2]] - 1); sUniqueVertexIndex vref = (element_count == 2) ? sUniqueVertexIndex(cface[0] - 1, cface[1] - 1, 0) : sUniqueVertexIndex(cface[0] - 1, cface[2] - 1, cface[1] - 1); cface += element_count; CHash hash = vref.GetHash(); //hash.next_hash(t_uvIndex[i]) //auto itr = sUniqueVertices->find(hash); size_t vIndex = 0; //if (itr == sUniqueVertices->end()) { vIndex = vVertexIndices.size(); //could //sUniqueVertices->insert(CHashMapInt::value_type(hash, vIndex)); vVertexIndices.push_back(vref); //OBJ starts indices at 1 but C++ starts at 0 if ((vref.mPosition>positions.size()) || (vref.mNormal>normals.size()) || (vref.mUv>uvs.size())) { int a = 10; } mesh.mVertexBuffer.AddVertex(SVertex_P_D4B_N_UV(positions[vref.mPosition], vref.mNormal < normals.size() ? normals[vref.mNormal] : CVector3f(1,0,0), vref.mUv < uvs.size() ? uvs[vref.mUv] : CVector2f(0,0), 0xFFFFFFFF)); //add } /*else { vIndex = itr->second; }*/ polygon_indices.push_back(vIndex); //++lineNumber; } mesh.add_polygon(polygon_indices, flip); //std::cout << mesh.m_index_count / 3 << std::endl; } } if (normals.size() == 0) mesh.calculate_normals(); #ifdef USE_TIMER ctimer.StopHRTimer(); std::cout << "Obj loader took " << ctimer.GetElapsedTime() << std::endl; ctimer.StartHRTimer(); #endif mesh.mIndexBuffer.UnLock(); //Copy back to GPU mesh.mVertexBuffer.UnLock(); //mesh.CalculateGeometryMetrics(); #ifdef USE_TIMER ctimer.StopHRTimer(); std::cout << "Uploading data to GPU took " << ctimer.GetElapsedTime() << std::endl; ctimer.StartHRTimer(); #endif //Very, very slow in windows and in debug (fine in release, fine in Linux) so for the sake of sanity, I'm causing a memory leak in debug. #ifndef _DEBUG sUniqueVertices->clear(); delete sUniqueVertices; #endif #ifdef USE_TIMER ctimer.StopHRTimer(); std::cout << "Clearing map took " << ctimer.GetElapsedTime() << std::endl; #endif fclose(mPfile); }
// <MODIFIER_ASSIGNMENT> void SettingLoader::load_MODIFIER_ASSIGNMENT() { // <MODIFIER_NAME> Token *t = getToken(); Modifier::Type mt; while (true) { Keymap::AssignMode am = Keymap::AM_notModifier; if (*t == _T("!") ) am = Keymap::AM_true, t = getToken(); else if (*t == _T("!!") ) am = Keymap::AM_oneShot, t = getToken(); else if (*t == _T("!!!")) am = Keymap::AM_oneShotRepeatable, t = getToken(); if (*t == _T("shift")) mt = Modifier::Type_Shift; else if (*t == _T("alt") || *t == _T("meta") || *t == _T("menu") ) mt = Modifier::Type_Alt; else if (*t == _T("control") || *t == _T("ctrl") ) mt = Modifier::Type_Control; else if (*t == _T("windows") || *t == _T("win") ) mt = Modifier::Type_Windows; else if (*t == _T("mod0") ) mt = Modifier::Type_Mod0; else if (*t == _T("mod1") ) mt = Modifier::Type_Mod1; else if (*t == _T("mod2") ) mt = Modifier::Type_Mod2; else if (*t == _T("mod3") ) mt = Modifier::Type_Mod3; else if (*t == _T("mod4") ) mt = Modifier::Type_Mod4; else if (*t == _T("mod5") ) mt = Modifier::Type_Mod5; else if (*t == _T("mod6") ) mt = Modifier::Type_Mod6; else if (*t == _T("mod7") ) mt = Modifier::Type_Mod7; else if (*t == _T("mod8") ) mt = Modifier::Type_Mod8; else if (*t == _T("mod9") ) mt = Modifier::Type_Mod9; else throw ErrorMessage() << _T("`") << *t << _T("': invalid modifier name."); if (am == Keymap::AM_notModifier) break; m_currentKeymap->addModifier(mt, Keymap::AO_overwrite, am, NULL); if (isEOL()) return; t = getToken(); } // <ASSIGN_OP> t = getToken(); Keymap::AssignOperator ao; if (*t == _T("=") ) ao = Keymap::AO_new; else if (*t == _T("+=")) ao = Keymap::AO_add; else if (*t == _T("-=")) ao = Keymap::AO_sub; else throw ErrorMessage() << _T("`") << *t << _T("': is unknown operator."); // <ASSIGN_MODE>? <KEY_NAME> while (!isEOL()) { // <ASSIGN_MODE>? t = getToken(); Keymap::AssignMode am = Keymap::AM_normal; if (*t == _T("!") ) am = Keymap::AM_true, t = getToken(); else if (*t == _T("!!") ) am = Keymap::AM_oneShot, t = getToken(); else if (*t == _T("!!!")) am = Keymap::AM_oneShotRepeatable, t = getToken(); // <KEY_NAME> Key *key = m_setting->m_keyboard.searchKey(t->getString()); if (!key) throw ErrorMessage() << _T("`") << *t << _T("': invalid key name."); // we can ignore warning C4701 m_currentKeymap->addModifier(mt, ao, am, key); if (ao == Keymap::AO_new) ao = Keymap::AO_add; } }
int main(int argc, char * argv[]) { int ch, opt; int errflag; char *optargTrainingSet=NULL, optargSep=','; std::vector<char> trainingSet; while ((opt = getopt(argc, argv, ":hc:s:")) != -1) { switch (opt) { case 'h': errflag++; break; case 'c': optargTrainingSet = optarg; break; case 's': sscanf(optarg, "%c", &optargSep); break; case ':': std::cerr << "option -" << optopt << "requires an operand" << std::endl; errflag++; break; case '?': std::cerr << "unrecognized option:-" << optopt << std::endl; errflag++; break; } } if (errflag || (optargTrainingSet == NULL)) { printCLHelp(argv[0]); return EXIT_FAILURE; } if (splitStringToChar(optargTrainingSet, trainingSet, optargSep) != 0) { return EXIT_FAILURE; } // Initialize app initTT(); //char a[] = {'a', 's', 'd', 'f', ' '}; charsRefer = generateString(trainingSet.data(), (int)trainingSet.size(), buffersize); charsTyped.resize(buffersize); charsTyped.clear(); setupScreen(); updateReferLine(charsRefer); updateActionLine(charsTyped, charsRefer); updateInfoLine(); updateCursorPosition(charsTyped); ch = getch(); while (ch != ASCII_CTRL_C) { if (!isPrintableKey(ch) && !isSpecialKey(ch)) { ch = getch(); continue; } switch (ch) { case ASCII_BACKSPACE: case ASCII_DELETE: std::cout << (char) ASCII_CTRL_G; // sound the bell refresh(); break; case ASCII_CTRL_R: resetStatistics(); case ASCII_NEWLINE: case ASCII_CRETURN: if (isEOL(charsTyped) || (ch == ASCII_CTRL_R)) { charsRefer = generateString(trainingSet.data(), (int)trainingSet.size(), buffersize); updateReferLine(charsRefer); clearActionLine(); clearBuffer(charsTyped); } break; default: if (addChar(charsTyped, ch)) { updateActionLine(charsTyped, charsRefer); } updateInfoLine(); updateCursorPosition(charsTyped); } ch = getch(); } refresh(); endwin(); /* std::cout << "buffersize= " << buffersize << std::endl; std::cout << "reference = " << charsRefer.size() << std::endl; std::cout << "capacity = " << charsTyped.capacity() << std::endl; std::cout << "typed_in = " << charsTyped.size() << std::endl; */ printf("Goodbye!\n"); return 0; }
// TODO: number escape sequence bool Tokenizer::consumeString(std::streambuf::int_type ch) { mpCurrent.reset(new Token); mpCurrent->setLine(line()); mpCurrent->setBeginColumn(column()); mpCurrent->setType(Token::TYPE_STRING_LITERAL); absorbed(ch); auto openQuotationMark = ch; for (;;) { if (eof()) { mpMessageCollector->addMessage( Message::SEVERITY_ERROR, Message::t_missingTerminatingQuotationMark, mpSourceId, line(), column()); mpCurrent.reset(); return false; } ch = mpInput->get(); if (isEOL(ch)) { mpMessageCollector->addMessage( Message::SEVERITY_ERROR, Message::t_missingTerminatingQuotationMark, mpSourceId, line(), column()); mpCurrent.reset(); return false; } absorbed(ch); if (ch == openQuotationMark) { break; } if (isEscape(ch)) { if (eof()) { mpMessageCollector->addMessage( Message::SEVERITY_ERROR, Message::t_unknownEscapeSequence, mpSourceId, line(), column()); mpCurrent.reset(); return false; } auto nch = mpInput->get(); if (!isEscapee(nch)) { mpMessageCollector->addMessage( Message::SEVERITY_ERROR, Message::t_unknownEscapeSequence, mpSourceId, line(), column()); mpCurrent.reset(); return false; } mpCurrent->addChar(ch); absorbed(nch); ch = nch; } mpCurrent->addChar(ch); } mpCurrent->setEndColumn(column()); return true; }
// look next token Token *SettingLoader::lookToken() { if (isEOL()) throw ErrorMessage() << _T("too few words."); return &*m_ti; }
// get next token Token *SettingLoader::getToken() { if (isEOL()) throw ErrorMessage() << _T("too few words."); return &*(m_ti ++); }