*/ void Throw_Error(REBSER *err) /* ** Throw the C stack. ** ***********************************************************************/ { if (!Saved_State) Crash(RP_NO_SAVED_STATE); SET_ERROR(TASK_THIS_ERROR, ERR_NUM(err), err); if (Trace_Level) Trace_Error(TASK_THIS_ERROR); longjmp(*Saved_State, 1); }
/* expand a view - given the handle to the compitem to expand. * * called from view_expand, and also to re-do an expanded view * after options change in view_changediffoptions and _changeviewoptions * * we get the composite section list from the compitem, * and pick out all the sections that are includable (according * to the global option expand_mode: we include all sections, or * just those in one side left or right). Once we know the count of rows, * allocate the mapping array: in each element of the array we keep * a handle to the section for that row (to get the state and hence the * tag text), and a handle to the line within that section (for the line text). * * We no longer insist on only expanding text files that differ - if the * compitem can give us a composite section list, we will map it. * * We need to be able to give a line number for a line, in either of * the original files according to which option is in force. Each section * can give us its base line number (number of first line in section) in * each of the two files or 0 if not present, and we track these here. * * MUST BE INSIDE CSView BEFORE CALLING HERE. */ BOOL view_expand_item( VIEW view, COMPITEM ci ) { LIST li; SECTION sh; LINE line1, line2; int i, base_left, base_right, state; // We could be on a second thread trying to expand while it's // already going on. That ain't clever! if (view->bExpandGuard) { Trace_Error(NULL, "Expansion in progress. Please wait.", FALSE); ViewLeave(); return FALSE; } // Ensure that the world knows that we are expanding // before we leave the critical section. // This is the only way into getcomposite. view->bExpandGuard = TRUE; // the compitem_getcomposite could take a long time // if the file is large and remote. We need to // release the critsec during this operation. ViewLeave(); /* get the composite section list */ li = compitem_getcomposite(ci); if (li == NULL) { view->bExpanding = FALSE; view->bExpandGuard = FALSE; return FALSE; } ViewEnter(); /* remember the compitem we are expanding */ view->ciSelect = ci; /* switch modes and free the current mapping * * NOTE: must do this AFTER the compitem_getcomposite, * since that can fail: if it fails it could put up a * message box, and that could cause a queued paint message * to be processed, which would cause us to use these mappings * and gpfault if they had been cleared first. */ view->bExpand = TRUE; view->bExpanding = FALSE; view->bExpandGuard = FALSE; view_freemappings(view); /* loop through totalling the lines in sections * that we should include */ view->rows = 0; for ( sh = (SECTION) List_First(li); sh != NULL; sh = (SECTION) List_Next(sh)) { state = section_getstate(sh); if (expand_mode == IDM_RONLY) { if ((state == STATE_LEFTONLY) || (state == STATE_SIMILARLEFT) || (state == STATE_MOVEDLEFT)) { continue; } } else if (expand_mode == IDM_LONLY) { if ((state == STATE_RIGHTONLY) || (state == STATE_SIMILARRIGHT) || (state == STATE_MOVEDRIGHT)) { continue; } } /* include all lines in this section if the section meets the include criteria */ if ( ((state == STATE_SAME) && (expand_include & INCLUDE_SAME)) || ((state == STATE_LEFTONLY) && (expand_include & INCLUDE_LEFTONLY)) || ((state == STATE_RIGHTONLY) && (expand_include & INCLUDE_RIGHTONLY)) || ((state == STATE_MOVEDLEFT) && (expand_include & INCLUDE_MOVEDLEFT)) || ((state == STATE_MOVEDRIGHT) && (expand_include & INCLUDE_MOVEDRIGHT)) || ((state == STATE_SIMILARLEFT) && (expand_include & INCLUDE_SIMILARLEFT)) || ((state == STATE_SIMILARRIGHT) && (expand_include & INCLUDE_SIMILARRIGHT))) { view->rows += section_getlinecount(sh); } } /* allocate the memory for the mapping array */ { /* DO NOT chain in any storage with garbage pointers in it */ PVIEWLINE temp; temp = (PVIEWLINE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, view->rows * sizeof(VIEWLINE)); if (temp == NULL) { return FALSE; } view->pLines = temp; } /* loop through the sections again filling in the mapping array */ i = 0; view->maxtag = 5; view->maxrest = 0; for (sh = (SECTION) List_First(li); sh != NULL; sh = (SECTION) List_Next(sh)) { state = section_getstate(sh); if (expand_mode == IDM_RONLY) { if ((state == STATE_LEFTONLY) || (state == STATE_SIMILARLEFT) || (state == STATE_MOVEDLEFT)) { continue; } } else if (expand_mode == IDM_LONLY) { if ((state == STATE_RIGHTONLY) || (state == STATE_SIMILARRIGHT) || (state == STATE_MOVEDRIGHT)) { continue; } } /* include all lines in this section if the section meets the include criteria */ if ( ((state == STATE_SAME) && (expand_include & INCLUDE_SAME)) || ((state == STATE_LEFTONLY) && (expand_include & INCLUDE_LEFTONLY)) || ((state == STATE_RIGHTONLY) && (expand_include & INCLUDE_RIGHTONLY)) || ((state == STATE_MOVEDLEFT) && (expand_include & INCLUDE_MOVEDLEFT)) || ((state == STATE_MOVEDRIGHT) && (expand_include & INCLUDE_MOVEDRIGHT)) || ((state == STATE_SIMILARLEFT) && (expand_include & INCLUDE_SIMILARLEFT)) || ((state == STATE_SIMILARRIGHT) && (expand_include & INCLUDE_SIMILARRIGHT))) { /* find the base line number in each file */ base_left = section_getleftbasenr(sh); base_right = section_getrightbasenr(sh); /* add each line in section to the view. section_getfirst() * returns us to a handle that is in a list. We can * call List_Next and will eventually get to the * line returned by section_getlast(). Sections always have * at least one line */ line1 = section_getfirstline(sh); line2 = section_getlastline(sh); for (; line1 != NULL; line1 = (LINE) List_Next(line1)) { view->pLines[i].line = line1; view->pLines[i].section = sh; /* calculate the line number for this line by * incrementing the base nr for this section. * Note SIMILAR_RIGHT (or LEFT) lines DO have * left (or right) numbers, but they are dummies. */ view->pLines[i].nr_left = base_left; if (state!=STATE_SIMILARRIGHT && base_left != 0) { base_left++; } view->pLines[i].nr_right = base_right; if (state!=STATE_SIMILARLEFT && base_right != 0) { base_right++; } /* increment index into view */ i++; /* check the column widths */ view->maxrest = max(view->maxrest, (line_gettabbedlength(line1, g_tabwidth))); /* end of section ? */ if (line1 == line2) { break; } } } } /* We must NOT hold a critical section here as SendMessage may hang */ ViewLeave(); /*inform table window of revised mapping */ SendMessage(view->hwnd, TM_NEWLAYOUT, 0, (LPARAM) view); return(TRUE); }