extern bool IndexOkay( instruction *ins, name *index ) { /**********************************************************/ name *name; conflict_node *conf; name = index->i.index; if( name->n.class == N_REGISTER ) { return( IsIndexReg( name->r.reg, name->n.name_class, 0 ) ); } if( name->v.conflict == NULL ) return( FALSE ); if( name->v.usage & USE_MEMORY ) return( FALSE ); if( name->n.class != N_TEMP ) return( FALSE ); conf = NameConflict( ins, name ); if( conf == NULL ) return( FALSE ); if( _Is( conf, NEEDS_INDEX_SPLIT ) ) { _SetFalse( conf, NEEDS_INDEX ); return( FALSE ); } else { _SetTrue( conf, NEEDS_INDEX ); ins->head.state = OPERANDS_NEED_WORK; ins->t.index_needs = MarkIndex( ins, name, 0 ); return( TRUE ); } }
extern bool WndGetLine( a_window *wnd, int row, int piece, wnd_line_piece *line ) { int virtual_row; bool success; virtual_row = WndVirtualRow( wnd, row ); if( _Is( wnd, WSW_CACHE_LINES ) ) { if( FindCacheLine( wnd, virtual_row, piece, line ) ) return( TRUE ); } line->attr = WndPlainAttr; line->indent = 0; line->static_text = FALSE; line->tabstop = TRUE; line->hot = FALSE; line->extent = WND_NO_EXTEND; line->master_tabstop = FALSE; line->underline = FALSE; line->draw_bar = FALSE; line->vertical_line = FALSE; line->draw_hook = FALSE; line->draw_line_hook = FALSE; line->bitmap = FALSE; line->use_piece0_attr = FALSE; line->use_prev_attr = FALSE; line->use_key = TRUE; line->text = ""; line->hint = ""; if( virtual_row < -wnd->title_size ) return( FALSE ); if( row == wnd->u.button_down.row && piece == wnd->u.button_down.piece ) { _Set( wnd, WSW_ALTERNATE_BIT ); } success = wnd->info->getline( wnd, virtual_row, piece, line ); _Clr( wnd, WSW_ALTERNATE_BIT ); if( success ) { if( !(line->bitmap|line->vertical_line|line->draw_hook|line->draw_line_hook|line->draw_bar) ) { line->length = strlen( line->text ); } if( virtual_row > wnd->max_row ) wnd->max_row = virtual_row; } if( success ) { if( _Is( wnd, WSW_CACHE_LINES ) ) { SetCacheLine( wnd, virtual_row, piece, line ); } } return( success ); }
static void WndPaintRows( a_window *wnd, wnd_row start_row, int num ) { wnd_row row; wnd_row row_to_get; int piece; wnd_line_piece line; wnd_row notify_row; int notify_piece; wnd_attr piece0_attr; wnd_attr prev_attr; bool had_cache; had_cache = WndSetCache( wnd, FALSE ); WndBegPaint( wnd, start_row, num ); notify_row = WND_NO_ROW; for( row = start_row; row < start_row + num; ++row ) { for( piece = 0; ; ++piece ) { if( row < wnd->title_size ) { row_to_get = row - wnd->top; } else { row_to_get = row; } if( !WndGetLine( wnd, row_to_get, piece, &line ) ) break; if( line.tabstop && wnd->current.row == row && wnd->current.piece == piece ) { notify_row = row; notify_piece = piece; if( _Is( wnd, WSW_HIGHLIGHT_CURRENT ) ) { line.attr = WndMapTabAttr( line.attr ); } } if( piece == 0 ) { piece0_attr = line.attr; } else if( line.use_piece0_attr ) { line.attr = piece0_attr; } if( line.use_prev_attr ) { line.attr = prev_attr; } prev_attr = line.attr; WndDrawTheLine( wnd, &line, row ); if( !line.bitmap ) { WndDrawSelect( wnd, &line, row, piece ); WndDrawCursor( wnd, &line, row, piece ); } } } WndEndPaint( wnd, start_row, num ); WndSetCache( wnd, had_cache ); if( wnd->max_indent != 0 ) { GUISetHScrollRange( wnd->gui, wnd->max_indent ); } if( notify_row != WND_NO_ROW ) { WndNotify( wnd, notify_row, notify_piece ); } }
bool WndSetCache( a_window *wnd, bool on ) { bool old; old = _Is( wnd, WSW_CACHE_LINES ); if( on ) { _Set( wnd, WSW_CACHE_LINES ); } else { _Clr( wnd, WSW_CACHE_LINES ); } return( old ); }
static void WndDrawSelect( a_window *wnd, wnd_line_piece *line, wnd_row row, int piece ) { int first; int len; gui_ord indent; if( _Is( wnd, WSW_NOT_TO_SCREEN ) ) return; if( WndSelected( wnd, line, row, piece, &first, &len ) ){ indent = line->indent; if( first != 0 ) { indent += GUIGetExtentX( wnd->gui, line->text, first ); } GUIDrawText( wnd->gui, line->text+first, len, row, indent, WndSelectedAttr ); } }
static void WndDrawCursor( a_window *wnd, wnd_line_piece *line, wnd_row row, int piece ) { const char *p; if( _Is( wnd, WSW_NOT_TO_SCREEN ) ) return; if( _Isnt( wnd, WSW_CHAR_CURSOR ) ) return; if( !line->tabstop ) return; if( wnd->current.row != row ) return; if( wnd->current.piece != piece ) return; if( wnd->current.col < 0 ) return; if( line->length == 0 ) { GUIDrawText( wnd->gui, " ", 1, row, line->indent, WndCursorAttr ); } else if( wnd->current.col < line->length ) { line->indent += GUIGetExtentX( wnd->gui, line->text, wnd->current.col ); p = line->text + wnd->current.col; GUIDrawText( wnd->gui, p, GUICharLen( *p ), row, line->indent, WndCursorAttr ); } }
extern void CalcSavings( conflict_node *conf ) { /**************************************************/ /* NB: <regsave> relies on the fact that "conf" is a parm to this routine*/ save_def block_save; save_def block_cost; save_def cost; save_def save; #undef _InRegAssgn #include "savcache.h" if( ( conf->name->v.usage & USE_IN_ANOTHER_BLOCK ) && ( conf->name->v.usage & ( NEEDS_MEMORY | USE_ADDRESS ) ) ) { CalcLoadStore( conf ); } if( _Is( conf, CONFLICT_ON_HOLD ) ) { conf->savings = 0; } else if( conf->available == 0 && _Isnt( conf, ( NEEDS_INDEX | NEEDS_SEGMENT ) ) ) { conf->savings = 0; } else if( conf->ins_range.first == conf->ins_range.last ) { conf->savings = 0; /* don't try - the world screws up*/ } else { cost = 0; save = 0; block_cost = 0; block_save = 0; opnd = conf->name; #include "savcode.h" if( save <= cost ) { conf->savings = 0; } else if( save - cost < MAX_SAVE ) { conf->savings = save - cost; } else { conf->savings = MAX_SAVE - 1; } } }
extern void SplitVars( void ) /*******************************/ /* For each variable, find out if it can be split into two separate variables.*/ /* This often happens when programmers re-use variables rather than defining*/ /* a new one.*/ { name *op; conflict_node *conf; for( ;; ) { for( conf = ConfList; conf != NULL; conf = conf->next_conflict ) { op = conf->name; if( (op->v.usage & USE_IN_ANOTHER_BLOCK) == 0 ) continue; if( op->n.class != N_TEMP ) continue; if( _Is( conf, CST_CONF_VISITED ) ) continue; _SetFalse( conf, CST_CONFLICT_ON_HOLD ); if( _GBitEmpty( conf->id.out_of_block ) ) continue; if( op->t.alias == op ) Split1Var( conf ); _GBitInit( conf->id.out_of_block, EMPTY ); _SetTrue( conf, CST_CONFLICT_ON_HOLD | CST_CONF_VISITED ); } if( !MoreConflicts() ) { break; } } CleanUp(); FreeConflicts(); InsDead(); NullConflicts( EMPTY ); FindReferences(); MakeConflicts(); }
extern void DumpAConf( conflict_node *conf ) { /************************************************/ DumpOperand( conf->name ); DumpLiteral( " id " ); DumpGBit( &conf->id.out_of_block ); DumpChar( ' ' ); DumpLBit( &conf->id.within_block ); DumpPossible( conf->possible ); DumpNL(); DumpLiteral( " " ); DumpInsRange( conf ); DumpLiteral( " Start block " ); DumpPtr( conf->start_block ); DumpNL(); DumpLiteral( " Conflicts with " ); DumpGBit( &conf->with.out_of_block ); DumpChar( ' ' ); DumpLBit( &conf->with.within_block ); DumpChar( ' ' ); DumpRegName( conf->with.regs ); DumpNL(); DumpLiteral( " Constrained " ); DumpInt( conf->num_constrained ); DumpLiteral( " vs " ); DumpInt( conf->available ); DumpNL(); if( _Is( conf, CST_SAVINGS_CALCULATED ) ) { DumpLiteral( " Savings " ); DumpLong( conf->savings ); DumpNL(); } if( _Is( conf, CST_CONFLICT_ON_HOLD ) ) { DumpLiteral( " On hold" ); DumpNL(); } if( _Is( conf, CST_CHANGES_OTHERS ) ) { DumpLiteral( " Changes Others" ); DumpNL(); } if( _Is( conf, CST_NEEDS_SEGMENT ) ) { DumpLiteral( " Needs segment" ); DumpNL(); } if( _Is( conf, CST_NEEDS_SEGMENT_SPLIT ) ) { DumpLiteral( " Needs segment split" ); DumpNL(); } if( _Is( conf, CST_SEGMENT_SPLIT ) ) { DumpLiteral( " Is segment split" ); DumpNL(); } if( _Is( conf, CST_NEEDS_INDEX ) ) { DumpLiteral( " Needs index" ); DumpNL(); } if( _Is( conf, CST_NEEDS_INDEX_SPLIT ) ) { DumpLiteral( " Needs index split" ); DumpNL(); } if( _Is( conf, CST_INDEX_SPLIT ) ) { DumpLiteral( " Is index split" ); DumpNL(); } }
extern bool WndSearch( a_window *wnd, bool from_top, int direction ) { wnd_line_piece line; regexp *rx; char *pos; char *endpos; bool wrap; int rows; bool rc; bool had_cache; char *not_found; char *top_of_window; char *end_of_window; char *search_wrapped; wnd_subpiece next_occurence; wnd_subpiece prev_occurence; wnd_subpiece curr; wnd_coord starting_pos; if( direction == 0 ) return( FALSE ); if( wnd == NULL ) return( FALSE ); if( wnd->searchitem == NULL ) return( FALSE ); rx = WndCompileRX( wnd->searchitem ); if( rx == NULL ) return( FALSE ); not_found = WndLoadString( LITERAL_Not_Found ); top_of_window = WndLoadString( LITERAL_Top_Of_Window ); end_of_window = WndLoadString( LITERAL_End_Of_Window ); search_wrapped = WndLoadString( LITERAL_Search_Wrapped ); wrap = FALSE; starting_pos.piece = 0; starting_pos.col = direction > 0 ? -1 : WND_MAX_COL; if( from_top ) { curr.row = 0; } else if( WndHasCurrent( wnd ) ) { curr.row = WndVirtualRow( wnd, wnd->current.row ); starting_pos.piece = wnd->current.piece; starting_pos.col = wnd->current.col; } else { curr.row = WndVirtualTop( wnd ); } starting_pos.row = curr.row; WndNextRow( wnd, WND_NO_ROW, WND_SAVE_ROW ); WndStatusText( "" ); WndDoingSearch = TRUE; had_cache = WndSetCache( wnd, FALSE ); for( ;; ) { if( curr.row < 0 ) { if( wrap ) { NotFound( wnd, rx, not_found ); rc = FALSE; goto done; } else if( _Is( wnd, WSW_SEARCH_WRAP ) ) { rows = WndNumRows( wnd ); if( rows == -1 ) { WndRepaint( wnd ); WndScrollAbs( wnd, -wnd->title_size ); rows = WndScrollAbs( wnd, WND_MAX_ROW ) + WndRows( wnd ); } curr.row = rows - 1; curr.col = 0; curr.piece = -1; wrap = TRUE; continue; } else { NotFound( wnd, rx, top_of_window ); rc = FALSE; goto done; } } next_occurence.col = -1; prev_occurence.col = -1; for( curr.piece = 0;; ++curr.piece ) { // look for both next and prev match if( !WndGetLineAbs( wnd, curr.row, curr.piece, &line ) ) { if( curr.piece != 0 ) break; if( wrap ) { NotFound( wnd, rx, not_found ); rc = FALSE; goto done; } else if( _Is( wnd, WSW_SEARCH_WRAP ) ) { curr.row = 0; curr.col = 0; curr.piece = -1; wrap = TRUE; continue; } else { NotFound( wnd, rx, end_of_window ); rc = FALSE; goto done; } } if( line.bitmap ) continue; pos = line.text; endpos = NULL; while( WndRXFind( rx, &pos, &endpos ) ) { curr.end = endpos - line.text; curr.col = pos - line.text; if( curr.piece < starting_pos.piece ) { prev_occurence = curr; } else if( curr.piece > starting_pos.piece ) { if( next_occurence.col == -1 ) { next_occurence = curr; } } else if( curr.col > starting_pos.col ) { if( next_occurence.col == -1 ) { next_occurence = curr; } } else if( curr.col < starting_pos.col ) { prev_occurence = curr; } ++pos; } } if( direction < 0 ) { next_occurence = prev_occurence; } if( next_occurence.col != -1 ) { WndDoingSearch = FALSE; WndKillCacheLines( wnd ); WndDirtyCurr( wnd ); WndNoSelect( wnd ); WndNoCurrent( wnd ); if( curr.row < WndVirtualTop( wnd ) ) { if( curr.row > wnd->rows / 2 ) { WndRepaint( wnd ); WndScrollAbs( wnd, curr.row - wnd->rows / 2 ); } else { WndRepaint( wnd ); WndScrollAbs( wnd, -wnd->title_size ); } } else if( curr.row >= WndVirtualBottom( wnd ) ) { WndRepaint( wnd ); WndScrollAbs( wnd, curr.row - wnd->rows / 2 ); } wnd->sel_start.row = WndScreenRow( wnd, curr.row ); wnd->sel_start.piece = next_occurence.piece; wnd->sel_start.col = next_occurence.col; wnd->sel_end = wnd->sel_start; wnd->sel_end.col = next_occurence.end - 1; wnd->current.col = wnd->sel_end.col; wnd->current = wnd->sel_start; WndSetCurrCol( wnd ); WndCurrVisible( wnd ); WndDirtyCurr( wnd ); WndFreeRX( rx ); if( wrap ) WndStatusText( search_wrapped ); rc = TRUE; goto done; } if( direction > 0 ) { if( wrap && curr.row > starting_pos.row ) { NotFound( wnd, rx, not_found ); rc = FALSE; goto done; } starting_pos.col = -1; starting_pos.piece = 0; curr.row = WndNextRow( wnd, curr.row, 1 ); } else { starting_pos.col = WND_MAX_COL; starting_pos.piece = WND_MAX_COL; curr.row = WndNextRow( wnd, curr.row, -1 ); } curr.piece = 0; } done:; WndSetCache( wnd, had_cache ); WndFree( not_found ); WndFree( top_of_window ); WndFree( end_of_window ); WndFree( search_wrapped ); return( rc ); }
void WndPaintDirt( a_window *wnd ) { int i; wnd_line_piece line; wnd_line_piece next_piece_line; gui_rect rect; wnd_dirt *dirt; gui_coord size; gui_coord half_char; a_window *next; // a_window *last; // last = NULL; for( wnd = WndNext( NULL ); wnd != NULL; wnd = next ) { next = WndNext( wnd ); if( wnd->vscroll_pending != 0 ) { if( wnd->hscroll_pending != -1 ) { _Set( wnd, WSW_REPAINT ); } if( _Is( wnd, WSW_REPAINT ) ) { if( wnd->hscroll_pending != -1 ) { GUIInitHScroll( wnd->gui, wnd->hscroll_pending ); } WndRepaint( wnd ); wnd->hscroll_pending = -1; wnd->vscroll_pending = 0; } else { for( i = 0; i < wnd->title_size; ++i ) { GUIDrawTextExtent( wnd->gui, " ", 1, i, 0, GUI_BACKGROUND, GUI_NO_COLUMN ); } GUIDoVScrollClip( wnd->gui, wnd->vscroll_pending, wnd->title_size, wnd->rows - 1 ); wnd->vscroll_pending = 0; } } if( _Is( wnd, WSW_REPAINT ) ) { _Clr( wnd, WSW_REPAINT ); WndKillCacheLines( wnd ); WndCheckCurrentValid( wnd ); GUIWndDirty( wnd->gui ); if( wnd->max_indent != 0 && wnd->width >= wnd->max_indent ) { GUISetHScroll( wnd->gui, 0 ); wnd->hscroll_pending = -1; GUISetHScrollRange( wnd->gui, wnd->max_indent ); } next = wnd; } else { for( i = 0; i < wnd->dirtyrects; ++i ) { dirt = &wnd->dirty[i]; if( dirt->row < 0 ) continue; if( dirt->row >= wnd->rows ) continue; if( dirt->piece == WND_NO_PIECE ) { if( !WndGetLine( wnd, dirt->row, 0, &line ) ) continue; GUIWndDirtyRow( wnd->gui, dirt->row ); } else { if( !WndGetLine( wnd, dirt->row, dirt->piece, &line ) ) continue; if( line.bitmap ) { GUIGetHotSpotSize( line.text[0], &size ); rect.x = line.indent; rect.y = dirt->row * wnd->max_char.y; rect.width = line.length; rect.height = size.y; } else if( dirt->col != WND_NO_COL ) { if( line.length == 0 ) line.text = " "; rect.x = line.indent; rect.x += GUIGetExtentX(wnd->gui, line.text, dirt->col); rect.y = dirt->row * wnd->max_char.y; rect.width = GUIGetExtentX( wnd->gui, line.text+dirt->col, dirt->end_col-dirt->col+GUICharLen( line.text[dirt->col] ) ); rect.height = wnd->max_char.y; } else if( line.extent == WND_MAX_EXTEND || line.master_tabstop ) { rect.width = 0; rect.height = 0; GUIWndDirtyRow( wnd->gui, dirt->row ); } else { rect.x = line.indent; if( WndGetLine( wnd, dirt->row, dirt->piece+1, &next_piece_line ) ) { if( next_piece_line.indent < line.indent ) { rect.width = WND_APPROX_SIZE; } else { rect.width = next_piece_line.indent - line.indent; } } else { rect.width = WND_APPROX_SIZE; } rect.y = dirt->row * wnd->max_char.y; rect.height = wnd->max_char.y; } /* begin kludge for Kerning problem */ if( rect.width != 0 || rect.height != 0 ) { half_char.x = WndAvgCharX( wnd ) / 2; half_char.y = 0; GUITruncToPixel( &half_char ); if( rect.x < half_char.x ) { rect.width += half_char.x + rect.x; rect.x = 0; } else { rect.x -= half_char.x; rect.width += half_char.x + half_char.x; } GUIWndDirtyRect( wnd->gui, &rect ); } } } } if( wnd->hscroll_pending != -1 ) { GUISetHScroll( wnd->gui, wnd->hscroll_pending ); wnd->hscroll_pending = -1; } wnd->dirtyrects = 0; WndSetThumb( wnd ); } }