void parser_warning( ParserContext pc, const char* msg ) { ParsingInfo* pi = (ParsingInfo*)get_extra( pc ); if( pi ) { fprintf( stderr, "%s(%d): warning: %s\n", pi->m_Name, get_line_no( pc ), msg ); } else { fprintf( stderr, "%s(0): warning: %s\n", g_inputFileName, msg ); } }
/* print all lines to the window. */ void fill_window(WINDOW *win, const char *text) { int x, y; int total_lines = get_line_no(text); int i; getmaxyx(win, y, x); /* do not go over end of line */ total_lines = min(total_lines, y); for (i = 0; i < total_lines; i++) { char tmp[x+10]; const char *line = get_line(text, i); int len = get_line_length(line); strncpy(tmp, line, min(len, x)); tmp[len] = '\0'; mvwprintw(win, i, 0, "%s", tmp); } }
void CJSourceParser::AddEnumNode( wxChar*& cur ) { // now the cursor is at "enum" keyword wxChar* start = cur; spEnumeration* pEnum = new spEnumeration(); mpCurCtx->AddMember( pEnum ); pEnum->mSrcLineNo = get_line_no(); AttachComments( *pEnum, cur ); skip_token( cur ); if ( !get_next_token( cur ) ) return; // check if enumeration has got it's identifier if ( *cur != '{' ) { pEnum->m_Name = get_token_str( cur ); } if ( !skip_imp_block( cur ) ) return; get_string_between( start, cur, &pEnum->m_EnumContent ); if ( get_next_token(cur) ) { // check if the identifier if after the {...} block if ( *cur != ';' ) pEnum->m_Name = get_token_str( cur ); } clear_commets_queue(); }
/* layman's scrollable window... */ void show_scroll_win(WINDOW *main_window, const char *title, const char *text) { int res; int total_lines = get_line_no(text); int x, y; int start_x = 0, start_y = 0; int text_lines = 0, text_cols = 0; int total_cols = 0; int win_cols = 0; int win_lines = 0; int i = 0; WINDOW *win; WINDOW *pad; PANEL *panel; /* find the widest line of msg: */ total_lines = get_line_no(text); for (i = 0; i < total_lines; i++) { const char *line = get_line(text, i); int len = get_line_length(line); total_cols = max(total_cols, len+2); } /* create the pad */ pad = newpad(total_lines+10, total_cols+10); wattrset(pad, attributes[SCROLLWIN_TEXT]); fill_window(pad, text); win_lines = min(total_lines+4, LINES-2); win_cols = min(total_cols+2, COLS-2); text_lines = max(win_lines-4, 0); text_cols = max(win_cols-2, 0); /* place window in middle of screen */ y = (LINES-win_lines)/2; x = (COLS-win_cols)/2; win = newwin(win_lines, win_cols, y, x); keypad(win, TRUE); /* show the help in the help window, and show the help panel */ wattrset(win, attributes[SCROLLWIN_BOX]); box(win, 0, 0); wattrset(win, attributes[SCROLLWIN_HEADING]); mvwprintw(win, 0, 3, " %s ", title); panel = new_panel(win); /* handle scrolling */ do { copywin(pad, win, start_y, start_x, 2, 2, text_lines, text_cols, 0); print_in_middle(win, text_lines+2, 0, text_cols, "<OK>", attributes[DIALOG_MENU_FORE]); wrefresh(win); res = wgetch(win); switch (res) { case KEY_NPAGE: case ' ': start_y += text_lines-2; break; case KEY_PPAGE: start_y -= text_lines+2; break; case KEY_HOME: start_y = 0; break; case KEY_END: start_y = total_lines-text_lines; break; case KEY_DOWN: case 'j': start_y++; break; case KEY_UP: case 'k': start_y--; break; case KEY_LEFT: case 'h': start_x--; break; case KEY_RIGHT: case 'l': start_x++; break; } if (res == 10 || res == 27 || res == 'q' || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { break; } if (start_y < 0) start_y = 0; if (start_y >= total_lines-text_lines) start_y = total_lines-text_lines; if (start_x < 0) start_x = 0; if (start_x >= total_cols-text_cols) start_x = total_cols-text_cols; } while (res); del_panel(panel); delwin(win); refresh_all_windows(main_window); }
int dialog_inputbox(WINDOW *main_window, const char *title, const char *prompt, const char *init, char *result, int result_len) { int prompt_lines = 0; int prompt_width = 0; WINDOW *win; WINDOW *prompt_win; WINDOW *form_win; PANEL *panel; int i, x, y; int res = -1; int cursor_position = strlen(init); /* find the widest line of msg: */ prompt_lines = get_line_no(prompt); for (i = 0; i < prompt_lines; i++) { const char *line = get_line(prompt, i); int len = get_line_length(line); prompt_width = max(prompt_width, len); } if (title) prompt_width = max(prompt_width, strlen(title)); /* place dialog in middle of screen */ y = (LINES-(prompt_lines+4))/2; x = (COLS-(prompt_width+4))/2; strncpy(result, init, result_len); /* create the windows */ win = newwin(prompt_lines+6, prompt_width+7, y, x); prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2); form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); keypad(form_win, TRUE); wattrset(form_win, attributes[INPUT_FIELD]); wattrset(win, attributes[INPUT_BOX]); box(win, 0, 0); wattrset(win, attributes[INPUT_HEADING]); if (title) mvwprintw(win, 0, 3, "%s", title); /* print message */ wattrset(prompt_win, attributes[INPUT_TEXT]); fill_window(prompt_win, prompt); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); mvwprintw(form_win, 0, 0, "%s", result); /* create panels */ panel = new_panel(win); /* show the cursor */ curs_set(1); touchwin(win); refresh_all_windows(main_window); while ((res = wgetch(form_win))) { int len = strlen(result); switch (res) { case 10: /* ENTER */ case 27: /* ESCAPE */ case KEY_F(F_HELP): case KEY_F(F_EXIT): case KEY_F(F_BACK): break; case 127: case KEY_BACKSPACE: if (cursor_position > 0) { memmove(&result[cursor_position-1], &result[cursor_position], len-cursor_position+1); cursor_position--; } break; case KEY_DC: if (cursor_position >= 0 && cursor_position < len) { memmove(&result[cursor_position], &result[cursor_position+1], len-cursor_position+1); } break; case KEY_UP: case KEY_RIGHT: if (cursor_position < len && cursor_position < min(result_len, prompt_width)) cursor_position++; break; case KEY_DOWN: case KEY_LEFT: if (cursor_position > 0) cursor_position--; break; default: if ((isgraph(res) || isspace(res)) && len-2 < result_len) { /* insert the char at the proper position */ memmove(&result[cursor_position+1], &result[cursor_position], len+1); result[cursor_position] = res; cursor_position++; } else { mvprintw(0, 0, "unknow key: %d\n", res); } break; } wmove(form_win, 0, 0); wclrtoeol(form_win); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); mvwprintw(form_win, 0, 0, "%s", result); wmove(form_win, 0, cursor_position); touchwin(win); refresh_all_windows(main_window); if (res == 10) { res = 0; break; } else if (res == 27 || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { res = KEY_EXIT; break; } else if (res == KEY_F(F_HELP)) { res = 1; break; } } /* hide the cursor */ curs_set(0); del_panel(panel); delwin(prompt_win); delwin(form_win); delwin(win); return res; }
int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) { va_list ap; char *btn; int btns_width = 0; int msg_lines = 0; int msg_width = 0; int total_width; int win_rows = 0; WINDOW *win; WINDOW *msg_win; WINDOW *menu_win; MENU *menu; ITEM *btns[btn_num+1]; int i, x, y; int res = -1; va_start(ap, btn_num); for (i = 0; i < btn_num; i++) { btn = va_arg(ap, char *); btns[i] = new_item(btn, ""); btns_width += strlen(btn)+1; } va_end(ap); btns[btn_num] = NULL; /* find the widest line of msg: */ msg_lines = get_line_no(msg); for (i = 0; i < msg_lines; i++) { const char *line = get_line(msg, i); int len = get_line_length(line); if (msg_width < len) msg_width = len; } total_width = max(msg_width, btns_width); /* place dialog in middle of screen */ y = (LINES-(msg_lines+4))/2; x = (COLS-(total_width+4))/2; /* create the windows */ if (btn_num > 0) win_rows = msg_lines+4; else win_rows = msg_lines+2; win = newwin(win_rows, total_width+4, y, x); keypad(win, TRUE); menu_win = derwin(win, 1, btns_width, win_rows-2, 1+(total_width+2-btns_width)/2); menu = new_menu(btns); msg_win = derwin(win, win_rows-2, msg_width, 1, 1+(total_width+2-msg_width)/2); set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); set_menu_back(menu, attributes[DIALOG_MENU_BACK]); wattrset(win, attributes[DIALOG_BOX]); box(win, 0, 0); /* print message */ wattrset(msg_win, attributes[DIALOG_TEXT]); fill_window(msg_win, msg); set_menu_win(menu, win); set_menu_sub(menu, menu_win); set_menu_format(menu, 1, btn_num); menu_opts_off(menu, O_SHOWDESC); menu_opts_off(menu, O_SHOWMATCH); menu_opts_on(menu, O_ONEVALUE); menu_opts_on(menu, O_NONCYCLIC); set_menu_mark(menu, ""); post_menu(menu); touchwin(win); refresh_all_windows(main_window); while ((res = wgetch(win))) { switch (res) { case KEY_LEFT: menu_driver(menu, REQ_LEFT_ITEM); break; case KEY_RIGHT: menu_driver(menu, REQ_RIGHT_ITEM); break; case 10: /* ENTER */ case 27: /* ESCAPE */ case ' ': case KEY_F(F_BACK): case KEY_F(F_EXIT): break; } touchwin(win); refresh_all_windows(main_window); if (res == 10 || res == ' ') { res = item_index(current_item(menu)); break; } else if (res == 27 || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { res = KEY_EXIT; break; } } unpost_menu(menu); free_menu(menu); for (i = 0; i < btn_num; i++) free_item(btns[i]); delwin(win); return res; }
void CJSourceParser::AddTypeDefNode( wxChar*& cur ) { // now the cursor at the token next to "typedef" keyword if ( !get_next_token(cur) ) return; wxChar* start = cur; spTypeDef* pTDef = new spTypeDef(); mpCurCtx->AddMember( pTDef ); pTDef->mSrcLineNo = get_line_no(); AttachComments( *pTDef, cur ); skip_statement( cur ); int tmpLnNo; store_line_no( tmpLnNo ); wxChar* tok = cur-1; skip_next_token_back( tok ); wxChar* nameEnd = tok; skip_token_back( tok ); wxChar* nameStart = tok; skip_next_token_back( tok ); wxChar* typeEnd = tok; // check if it's function prototype if ( *nameStart == ')' ) { typeEnd = nameStart+1; // skip argument list while ( *nameStart != '(' ) --nameStart; // skip to function type definition while ( *nameStart != ')' ) --nameStart; skip_next_token_back( nameStart ); nameEnd = nameStart; skip_token_back( nameStart ); if ( *nameStart == '*' ) ++nameStart; } get_string_between( start, typeEnd, &pTDef->m_OriginalType ); get_string_between( nameStart, nameEnd, &pTDef->m_Name ); clear_commets_queue(); restore_line_no( tmpLnNo ); }
void CJSourceParser::AddClassNode( char*& cur ) { char* ctxStart = cur; wxString classkeyword = get_token_str( cur ); skip_token( cur ); // skip 'class' keyword if ( !get_next_token( cur ) ) return; // in C++ if ( *cur == ':' ) { skip_token( cur ); get_next_token( cur ); } // by default all class members are private mCurVis = SP_VIS_PRIVATE; spClass* pClass = new spClass(); if ( classkeyword == "class" ) pClass->mClassSubType = SP_CLTYPE_CLASS; else if ( classkeyword == "struct" ) { pClass->mClassSubType = SP_CLTYPE_STRUCTURE; mCurVis = SP_VIS_PUBLIC; } else if ( classkeyword == "union" ) { pClass->mClassSubType = SP_CLTYPE_UNION; mCurVis = SP_VIS_PUBLIC; } else if ( classkeyword == "interface" ) pClass->mClassSubType = SP_CLTYPE_INTERFACE; else { pClass->mClassSubType = SP_CLTYPE_INVALID; wxFAIL_MSG("unknown class keyword"); } mpCurCtx->AddMember( pClass ); // attach comments about the class AttachComments( *pClass, cur ); pClass->mSrcLineNo = get_line_no(); pClass->mSrcOffset = int( ctxStart - _gSrcStart ); char* nameTok = cur; pClass->m_Name = get_token_str( cur ); bool isDerived = 0; // DANGER-MACROS:: do { skip_token( cur ); if ( !get_next_token( cur ) ) return; if ( *cur == ':' ) { isDerived = 1; char* tok = cur; int tmpLn; store_line_no( tmpLn ); skip_next_token_back( tok ); skip_token_back( tok ); restore_line_no( tmpLn ); // class name should precend ':' colon, thus // the one which was captured before was // proablty something else (like __dllexport MyClass : ... ) if ( nameTok != tok ) { pClass->m_Name = get_token_str( tok ); } } if ( *cur == '{' ) break; if ( *cur == ',' ) continue; size_t len = get_token_len( cur ); // skip neglectable C++ modifieres if ( cmp_tokens_fast( cur, "public", len ) ) continue; if ( cmp_tokens_fast( cur, "protected", len ) ) continue; if ( cmp_tokens_fast( cur, "private", len ) ) continue; if ( cmp_tokens_fast( cur, "virtual", len ) ) continue; // skip neglectable JAVA modifieres if ( cmp_tokens_fast( cur, "extends", len ) ) { isDerived = 1; continue; } if ( cmp_tokens_fast( cur, "implements", len ) ) { isDerived = 1; continue; } // all we need to know is superclass or interface char* tok = cur; int tmpLn; store_line_no( tmpLn ); skip_token(tok); get_next_token(tok); restore_line_no( tmpLn ); if ( *tok != ':' && *cur != ':' ) pClass->m_SuperClassNames.push_back( wxString( cur, len ) ); } while(1); if ( !isDerived ) { int tmpLn; store_line_no( tmpLn ); while ( pClass->m_SuperClassNames.size() ) pClass->m_SuperClassNames.erase( &pClass->m_SuperClassNames[0] ); char* tok = cur; // some non-obviouse token was following "class" keyword - // we've confused it with class name - thus now we're reverting this mistake skip_next_token_back( tok ); skip_token_back( tok ); pClass->m_Name = get_token_str( tok ); restore_line_no( tmpLn ); } ++cur; // skip opening curly brace pClass->mHeaderLength = ( cur - ctxStart ); // now, enter the class context mpCurCtx = pClass; clear_commets_queue(); }
void CJSourceParser::ParseMemberVar( char*& cur ) { MMemberListT& members = mpCurCtx->GetMembers(); bool firstMember = true; wxString type; // jump to the end of statement // and start collecting same-type varibles // back-to-front towards the type identifier skip_statement( cur ); char* savedPos = cur; int tmpLnNo; store_line_no( tmpLnNo ); --cur; // rewind back to ';' do { spAttribute* pAttr = new spAttribute(); // FOR NOW:: line not is not exact, if member declaration is multiline pAttr->mSrcLineNo = get_line_no(); mpCurCtx->AddMember( pAttr ); pAttr->mVisibility = mCurVis; pAttr->mIsConstant = 0; if ( firstMember ) { firstMember = 0; } skip_token_back( cur ); // attach comments about the attribute AttachComments( *pAttr, cur ); pAttr->m_Name = get_token_str( cur ); // guessing that this going to be variable type skip_next_token_back( cur ); skip_token_back( cur ); pAttr->m_Type = get_token_str( cur ); // if comma, than variable list continues // otherwise the variable type reached - stop if ( *cur == _T('=') ) { // yes, we've mistaken, it was not a identifier, // but it's default value pAttr->m_InitVal = pAttr->m_Name; // skip default value and '=' symbol skip_next_token_back( cur ); skip_token_back( cur ); pAttr->m_Name = get_token_str( cur ); skip_next_token_back( cur ); skip_token_back( cur ); } if ( *cur != ',' ) { type = get_token_str( cur ); break; } } while(1); size_t first = 0; // set up types for all collected (same-type) attributes; while ( first != members.size() - 1 ) { spAttribute* pAttr = members[first++]->CastToAttribute(); if ( !pAttr ) continue; if ( pAttr->m_Type.empty() ) pAttr->m_Type = type; pAttr->mVisibility = mCurVis; if ( !pAttr->m_Name.empty() ) arrange_indirection_tokens_between( pAttr->m_Type, pAttr->m_Name ); } cur = savedPos; restore_line_no( tmpLnNo ); clear_commets_queue(); }
bool CJSourceParser::ParseArguments( char*& cur ) { // DANGER-MACROS:: // now cursor position is right after the first opening bracket // of the function declaration char* blocks [16]; // used exclusivelly for iterative "lean out" // of macros and misc. not-obviouse grammar // (dirty,, but we cannot do it very nice, // we're not preprocessor-free C/C++ code) int blockSizes[16]; do { size_t blocksSkipped = 0; get_next_token( cur ); bool first_blk = true; while( *cur != ')' && *cur != ',' ) { blocks[blocksSkipped] = cur; if ( first_blk ) { char* prev = cur; skip_token( cur ); blockSizes[blocksSkipped] = size_t(cur-prev); first_blk = 0; } else blockSizes[blocksSkipped] = skip_block( cur ); get_next_token( cur ); ++blocksSkipped; } if ( blocksSkipped == 1 ) { // check if the empty arg. list stressed with "void" inside if ( cmp_tokens_fast( blocks[0] , "void", 4 ) ) { cur++; // skip ')' break; } // FIXME:: TBD:: K&R-style function declarations! // if only one block enclosed, than it's probably // some macro, there should be at least two blocks, // one for argument type and another for it's identifier return false; } if ( blocksSkipped == 0 ) { if ( *cur == 10 ) ++_gLineNo; ++cur; // skip ')' break; // function without paramters } // we should be in the operation context now spOperation* pOp = (spOperation*)mpCurCtx; spParameter* pPar = new spParameter(); pOp->AddMember( pPar ); // FOR NOW:: line number is not exact if argument list is mutiline pPar->mSrcLineNo = get_line_no(); size_t nameBlock = blocksSkipped - 1; size_t typeBlock = nameBlock - 1; // check if default values present if ( *blocks[typeBlock] == '=' ) { // expressions like "int = 5" are ignored, // since name for paramters is required if ( blocksSkipped == 3 ) { if ( *cur == ')' ) { ++cur; break; } else continue; } pPar->m_InitVal = wxString( blocks[nameBlock], blockSizes[nameBlock] ); nameBlock = nameBlock - 2; // skip '=' token and default value block typeBlock = nameBlock - 1; } // attach comments about the parameter AttachComments( *pPar, blocks[nameBlock] ); // retrieve argument name pPar->m_Name = wxString( blocks[nameBlock], blockSizes[nameBlock] ); // retreive argument type size_t len = blockSizes[ typeBlock ]; len = size_t ( (blocks[ typeBlock ] + len) - blocks[ 0 ] ); pPar->m_Type = wxString( blocks[0], len ); arrange_indirection_tokens_between( pPar->m_Type, pPar->m_Name ); if ( *cur == ')' ) { ++cur; break; } ++cur; // skip comma get_next_token(cur); } while(1); // skip possible whitespace between ')' and following "const" while ( isspace(*cur) ) cur++; // check if it was really a function not a macro, // if so, than it should be terminated with semicolon ';' // or opening implemenetaton bracket '{' char* tok = cur; int tmpLnNo; store_line_no( tmpLnNo ); bool result = true; do { if ( *tok == '{' || *tok == ';' ) { restore_line_no(tmpLnNo); break; } // check for unexpected tokens if ( *tok == '=' || *tok == '0' ) { skip_token(tok); if ( !get_next_token(tok) ) return false; continue; } if ( *tok == '}' ) return false; // if initialization list found if ( *tok == ':' ) { restore_line_no(tmpLnNo); break; } if ( cmp_tokens_fast( tok, "const", 5 ) ) { ((spOperation*)mpCurCtx)->mIsConstant = true; skip_token(tok); if ( !get_next_token(tok) ) return false; continue; } if ( CheckVisibilty( tok ) ) return false; // if next context found if ( is_keyword( tok ) ) return false; skip_token(tok); if ( !get_next_token(tok) ) return false; } while(1); return result; }
bool CJSourceParser::ParseNameAndRetVal( char*& cur, bool& isAMacro ) { isAMacro = false; // FOR NOW:: all functions in the global // scope are ignored int lineNo = get_line_no(); char* start = cur; bool isVirtual = false; while( *cur != '(' ) { if ( get_token_str( cur ) == "virtual" ) isVirtual = true; skip_token( cur ); if ( !get_next_token( cur ) ) return false; } char* bracketPos = cur; char* savedPos = cur + 1; int tmpLnNo; store_line_no( tmpLnNo ); // skip gap between function name and start of paramters list while ( *(cur-1) == ' ' ) --cur; // check if it's not a macro, and let plugin handle it, if so if ( mpPlugin ) { skip_token_back( cur ); char* tmp = cur; if ( mpPlugin->CanUnderstandContext( tmp, _gSrcEnd, mpCurCtx ) ) { cur = tmp; mpPlugin->ParseContext( _gSrcStart, cur, _gSrcEnd, mpCurCtx ); isAMacro = true; return false; } } spOperation* pOp = new spOperation(); pOp->mSrcLineNo = lineNo; pOp->mSrcOffset = int( start - _gSrcStart ); pOp->mHeaderLength = int( bracketPos - start ); if ( mpCurCtx->GetContextType() == SP_CTX_CLASS ) pOp->mScope = mpCurCtx->m_Name; mpCurCtx->AddMember( pOp ); pOp->mVisibility = mCurVis; pOp->mIsVirtual = isVirtual; // add comments about operation AttachComments( *pOp, cur ); // go backwards to method name skip_token_back( cur ); pOp->m_Name = get_token_str( cur ); // checker whether it's not an operator char chFirst = *pOp->m_Name.c_str(); if ( !isalpha(chFirst) && chFirst != '_' && chFirst != '~' ) { // skip 'operator' skip_next_token_back( cur ); skip_token_back( cur ); wxString lastToken = get_token_str( cur ); if ( lastToken == "operator" ) { lastToken += pOp->m_Name; pOp->m_Name = lastToken; } else { // ok, it wasn't an operator after all skip_token( cur ); } } else if ( pOp->m_Name == "operator" ) { skip_token( cur ); get_next_token( cur ); wxString oper = get_token_str( cur ); pOp->m_Name += oper; } // go backwards to method return type skip_next_token_back( cur ); if ( cur >= start ) { wxString rettype = wxString( start, size_t( cur-start ) ); // FIXME just for now... wxString::size_type pos = 0; wxString toerase("WXDLLEXPORT "); while((pos = rettype.find(toerase, pos)) != wxString::npos) rettype.erase(pos, toerase.length()); pOp->m_RetType = rettype; } arrange_indirection_tokens_between( pOp->m_RetType, pOp->m_Name ); cur = savedPos; restore_line_no( tmpLnNo ); // now, enter operation context mpCurCtx = pOp; return true; }
void CJSourceParser::AddMacroNode( wxChar*& cur ) { wxChar* start = cur; int lineNo = get_line_no(); skip_preprocessor_dir( cur ); int tmpLnNo; store_line_no( tmpLnNo ); if ( !mMacrosOn ) return; spPreprocessorLine* pPL = new spPreprocessorLine(); pPL->mSrcLineNo = lineNo; AttachComments( *pPL, cur ); get_string_between( start, cur, &pPL->m_Line ); ++start; // skip '#' get_next_token( start ); pPL->mDefType = SP_PREP_DEF_OTHER; // if we found a definition or redefinition, // determine the type exactly and assign // a name to the context if ( *start == _T('d') ) { if ( cmp_tokens_fast( start, _T("define"), 6 ) ) { char* tok = start+6; get_next_token( tok ); pPL->m_Name = get_token_str( tok ); skip_token( tok ); get_next_token( tok); if ( tok > cur ) pPL->mDefType = SP_PREP_DEF_DEFINE_SYMBOL; else pPL->mDefType = SP_PREP_DEF_REDEFINE_SYMBOL; } } else if ( *start == _T('i') ) { if ( cmp_tokens_fast( start, _T("include"), 7 ) ) { pPL->mDefType = SP_PREP_DEF_INCLUDE_FILE; } else if ( *++start == _T('f') ) { // either "#if" or "#ifdef" cur = start; skip_token( cur ); get_next_token( cur ); wxString condition = get_token_str( cur ); // currently, everything except '0' is true if ( condition == _T("0") ) { // skip until the following else or enif while ( cur < _gSrcEnd ) { skip_to_eol( cur ); skip_eol( cur ); get_next_token( cur ); if ( *cur++ == _T('#') && *cur == _T('e') ) break; } } // TODO parse the condition... } } else if ( cmp_tokens_fast( start, _T("else"), 4 ) ) { // skip until "#endif" while ( cur < _gSrcEnd ) { skip_to_eol( cur ); skip_eol( cur ); get_next_token( cur ); if ( *cur++ == _T('#') && cmp_tokens_fast( cur, "endif", 5 ) ) break; } } mpCurCtx->AddMember( pPL ); skip_to_eol( cur ); skip_eol( cur ); restore_line_no( tmpLnNo ); clear_commets_queue(); }
int dialog_inputbox(WINDOW *main_window, const char *title, const char *prompt, const char *init, char **resultp, int *result_len) { int prompt_lines = 0; int prompt_width = 0; WINDOW *win; WINDOW *prompt_win; WINDOW *form_win; PANEL *panel; int i, x, y; int res = -1; int cursor_position = strlen(init); int cursor_form_win; char *result = *resultp; if (strlen(init)+1 > *result_len) { *result_len = strlen(init)+1; *resultp = result = realloc(result, *result_len); } prompt_lines = get_line_no(prompt); for (i = 0; i < prompt_lines; i++) { const char *line = get_line(prompt, i); int len = get_line_length(line); prompt_width = max(prompt_width, len); } if (title) prompt_width = max(prompt_width, strlen(title)); y = (LINES-(prompt_lines+4))/2; x = (COLS-(prompt_width+4))/2; strncpy(result, init, *result_len); win = newwin(prompt_lines+6, prompt_width+7, y, x); prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2); form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); keypad(form_win, TRUE); (void) wattrset(form_win, attributes[INPUT_FIELD]); (void) wattrset(win, attributes[INPUT_BOX]); box(win, 0, 0); (void) wattrset(win, attributes[INPUT_HEADING]); if (title) mvwprintw(win, 0, 3, "%s", title); (void) wattrset(prompt_win, attributes[INPUT_TEXT]); fill_window(prompt_win, prompt); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); cursor_form_win = min(cursor_position, prompt_width-1); mvwprintw(form_win, 0, 0, "%s", result + cursor_position-cursor_form_win); panel = new_panel(win); curs_set(1); touchwin(win); refresh_all_windows(main_window); while ((res = wgetch(form_win))) { int len = strlen(result); switch (res) { case 10: case 27: case KEY_F(F_HELP): case KEY_F(F_EXIT): case KEY_F(F_BACK): break; case 127: case KEY_BACKSPACE: if (cursor_position > 0) { memmove(&result[cursor_position-1], &result[cursor_position], len-cursor_position+1); cursor_position--; cursor_form_win--; len--; } break; case KEY_DC: if (cursor_position >= 0 && cursor_position < len) { memmove(&result[cursor_position], &result[cursor_position+1], len-cursor_position+1); len--; } break; case KEY_UP: case KEY_RIGHT: if (cursor_position < len) { cursor_position++; cursor_form_win++; } break; case KEY_DOWN: case KEY_LEFT: if (cursor_position > 0) { cursor_position--; cursor_form_win--; } break; case KEY_HOME: cursor_position = 0; cursor_form_win = 0; break; case KEY_END: cursor_position = len; cursor_form_win = min(cursor_position, prompt_width-1); break; default: if ((isgraph(res) || isspace(res))) { if (len+2 > *result_len) { *result_len = len+2; *resultp = result = realloc(result, *result_len); } memmove(&result[cursor_position+1], &result[cursor_position], len-cursor_position+1); result[cursor_position] = res; cursor_position++; cursor_form_win++; len++; } else { mvprintw(0, 0, "unknown key: %d\n", res); } break; } if (cursor_form_win < 0) cursor_form_win = 0; else if (cursor_form_win > prompt_width-1) cursor_form_win = prompt_width-1; wmove(form_win, 0, 0); wclrtoeol(form_win); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); mvwprintw(form_win, 0, 0, "%s", result + cursor_position-cursor_form_win); wmove(form_win, 0, cursor_form_win); touchwin(win); refresh_all_windows(main_window); if (res == 10) { res = 0; break; } else if (res == 27 || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { res = KEY_EXIT; break; } else if (res == KEY_F(F_HELP)) { res = 1; break; } } curs_set(0); del_panel(panel); delwin(prompt_win); delwin(form_win); delwin(win); return res; }
int dialog_inputbox(WINDOW *main_window, const char *title, const char *prompt, const char *init, char **resultp, int *result_len) { int prompt_lines = 0; int prompt_width = 0; WINDOW *win; WINDOW *prompt_win; WINDOW *form_win; PANEL *panel; int i, x, y, lines, columns, win_lines, win_cols; int res = -1; int cursor_position = strlen(init); int cursor_form_win; char *result = *resultp; getmaxyx(stdscr, lines, columns); if (strlen(init)+1 > *result_len) { *result_len = strlen(init)+1; *resultp = result = realloc(result, *result_len); } /* find the widest line of msg: */ prompt_lines = get_line_no(prompt); for (i = 0; i < prompt_lines; i++) { const char *line = get_line(prompt, i); int len = get_line_length(line); prompt_width = max(prompt_width, len); } if (title) prompt_width = max(prompt_width, strlen(title)); win_lines = min(prompt_lines+6, lines-2); win_cols = min(prompt_width+7, columns-2); prompt_lines = max(win_lines-6, 0); prompt_width = max(win_cols-7, 0); /* place dialog in middle of screen */ y = (lines-win_lines)/2; x = (columns-win_cols)/2; strncpy(result, init, *result_len); /* create the windows */ win = newwin(win_lines, win_cols, y, x); prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2); form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); keypad(form_win, TRUE); (void) wattrset(form_win, attributes[INPUT_FIELD]); (void) wattrset(win, attributes[INPUT_BOX]); box(win, 0, 0); (void) wattrset(win, attributes[INPUT_HEADING]); if (title) mvwprintw(win, 0, 3, "%s", title); /* print message */ (void) wattrset(prompt_win, attributes[INPUT_TEXT]); fill_window(prompt_win, prompt); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); cursor_form_win = min(cursor_position, prompt_width-1); mvwprintw(form_win, 0, 0, "%s", result + cursor_position-cursor_form_win); /* create panels */ panel = new_panel(win); /* show the cursor */ curs_set(1); touchwin(win); refresh_all_windows(main_window); while ((res = wgetch(form_win))) { int len = strlen(result); switch (res) { case 10: /* ENTER */ case 27: /* ESCAPE */ case KEY_F(F_HELP): case KEY_F(F_EXIT): case KEY_F(F_BACK): break; case 127: case KEY_BACKSPACE: if (cursor_position > 0) { memmove(&result[cursor_position-1], &result[cursor_position], len-cursor_position+1); cursor_position--; cursor_form_win--; len--; } break; case KEY_DC: if (cursor_position >= 0 && cursor_position < len) { memmove(&result[cursor_position], &result[cursor_position+1], len-cursor_position+1); len--; } break; case KEY_UP: case KEY_RIGHT: if (cursor_position < len) { cursor_position++; cursor_form_win++; } break; case KEY_DOWN: case KEY_LEFT: if (cursor_position > 0) { cursor_position--; cursor_form_win--; } break; case KEY_HOME: cursor_position = 0; cursor_form_win = 0; break; case KEY_END: cursor_position = len; cursor_form_win = min(cursor_position, prompt_width-1); break; default: if ((isgraph(res) || isspace(res))) { /* one for new char, one for '\0' */ if (len+2 > *result_len) { *result_len = len+2; *resultp = result = realloc(result, *result_len); } /* insert the char at the proper position */ memmove(&result[cursor_position+1], &result[cursor_position], len-cursor_position+1); result[cursor_position] = res; cursor_position++; cursor_form_win++; len++; } else { mvprintw(0, 0, "unknown key: %d\n", res); } break; } if (cursor_form_win < 0) cursor_form_win = 0; else if (cursor_form_win > prompt_width-1) cursor_form_win = prompt_width-1; wmove(form_win, 0, 0); wclrtoeol(form_win); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); mvwprintw(form_win, 0, 0, "%s", result + cursor_position-cursor_form_win); wmove(form_win, 0, cursor_form_win); touchwin(win); refresh_all_windows(main_window); if (res == 10) { res = 0; break; } else if (res == 27 || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { res = KEY_EXIT; break; } else if (res == KEY_F(F_HELP)) { res = 1; break; } } /* hide the cursor */ curs_set(0); del_panel(panel); delwin(prompt_win); delwin(form_win); delwin(win); return res; }