📄 display.c
字号:
/*=========================================================================== Copyright (c) 1998-2000, The Santa Cruz Operation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: *Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. *Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. *Neither name of The Santa Cruz Operation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*//* cscope - interactive C symbol cross-reference * * display functions */#include "global.h"#include "build.h"#ifdef CCS#include "sgs.h" /* ESG_PKG and ESG_REL */#else#include "version.h" /* FILEVERSION and FIXVERSION */#endif#if defined(USE_NCURSES) && !defined(RENAMED_NCURSES)#include <ncurses.h>#else#include <curses.h>#endif#include <setjmp.h> /* jmp_buf */#include <stdarg.h> /* va_list stuff */#include <time.h>#include <errno.h>#include <stdarg.h>static char const rcsid[] = "$Id: display.c,v 1.22 2003/06/12 17:11:38 broeker Exp $";int booklen; /* OGS book name display field length */int *displine; /* screen line of displayed reference */int disprefs; /* displayed references */int field; /* input field */int filelen; /* file name display field length */int fcnlen; /* function name display field length */int mdisprefs; /* maximum displayed references */int nextline; /* next line to be shown */FILE *nonglobalrefs; /* non-global references file */int numlen; /* line number display field length */int topline = 1; /* top line of page */int bottomline; /* bottom line of page */long searchcount; /* count of files searched */int subsystemlen; /* OGS subsystem name display field length */int totallines; /* total reference lines */unsigned fldcolumn; /* input field column */const char dispchars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";static int fldline; /* input field line */static jmp_buf env; /* setjmp/longjmp buffer */static int lastdispline; /* last displayed reference line */static char lastmsg[MSGLEN + 1]; /* last message displayed */static char helpstring[] = "Press the ? key for help";static char selprompt[] = "Select lines to change (press the ? key for help): ";typedef char * (*FP)(char *); /* pointer to function returning a character pointer *//* HBB 2000/05/05: I removed the casts to function pointer type. It is * fundamentally unsafe to call a function through a pointer of a * different type ('undefined behaviour' in the words of the ANSI/ISO * C standard). Instead, I made all the find...() functions adhere to * the same function type, by changing argument passing a bit. */static struct { /* text of input fields */ char *text1; char *text2; FP findfcn;} fields[FIELDS + 1] = { /* samuel has a search that is not part of the cscope display */ {"Find this", "C symbol", findsymbol}, {"Find this", "global definition", finddef}, {"Find", "functions called by this function", findcalledby}, {"Find", "functions calling this function", findcalling}, {"Find this", "text string", findstring}, {"Change this", "text string", findstring}, {"Find this", "egrep pattern", findregexp}, {"Find this", "file", findfile}, {"Find", "files #including this file", findinclude}, {"Find all", "function definitions", findallfcns}, /* samuel only */};/* Internal prototypes: */static RETSIGTYPE jumpback(int sig);/* initialize display parameters */voiddispinit(void){ /* calculate the maximum displayed reference lines */ lastdispline = FLDLINE - 3; mdisprefs = lastdispline - REFLINE + 1; if (mdisprefs <= 0) { (void) fprintf(stderr, "%s: screen too small\n", argv0); myexit(1); } if (mouse == NO && mdisprefs > strlen(dispchars)) mdisprefs = strlen(dispchars); /* allocate the displayed line array */ displine = mymalloc(mdisprefs * sizeof(int));}/* display a page of the references */voiddisplay(void){ char *subsystem; /* OGS subsystem name */ char *book; /* OGS book name */ char file[PATHLEN + 1]; /* file name */ char function[PATLEN + 1]; /* function name */ char linenum[NUMLEN + 1]; /* line number */ int screenline; /* screen line number */ int width; /* source line display width */ int i; char *s; /* see if this is the initial display */ erase(); if (refsfound == NULL) {#if CCS if (displayversion == YES) { printw("cscope %s", ESG_REL); } else { printw("cscope"); }#else printw("Cscope version %d%s", FILEVERSION, FIXVERSION);#endif move(0, COLS - (int) sizeof(helpstring)); addstr(helpstring); } else if (totallines == 0) { /* if no references were found */ /* redisplay the last message */ addstr(lastmsg); } else { /* display the pattern */ if (changing == YES) { printw("Change \"%s\" to \"%s\"", pattern, newpat); } else { printw("%c%s: %s", toupper((unsigned char)fields[field].text2[0]), fields[field].text2 + 1, pattern); } /* display the column headings */ move(2, 2); if (ogs == YES && field != FILENAME) { printw("%-*s ", subsystemlen, "Subsystem"); printw("%-*s ", booklen, "Book"); } if (dispcomponents > 0) printw("%-*s ", filelen, "File"); if (field == SYMBOL || field == CALLEDBY || field == CALLING) { printw("%-*s ", fcnlen, "Function"); } if (field != FILENAME) { addstr("Line"); } addch('\n'); /* if at end of file go back to beginning */ if (nextline > totallines) { seekline(1); } /* calculate the source text column */ width = COLS - numlen - 3; if (ogs == YES) { width -= subsystemlen + booklen + 2; } if (dispcomponents > 0) { width -= filelen + 1; } if (field == SYMBOL || field == CALLEDBY || field == CALLING) { width -= fcnlen + 1; } /* until the max references have been displayed or there is no more room */ topline = nextline; for (disprefs = 0, screenline = REFLINE; disprefs < mdisprefs && screenline <= lastdispline; ++disprefs, ++screenline) { /* read the reference line */ if (fscanf(refsfound, "%s%s%s %[^\n]", file, function, linenum, tempstring) < 4) { break; } ++nextline; displine[disprefs] = screenline; /* if no mouse, display the selection number */ if (mouse == YES) { addch(' '); } else { printw("%c", dispchars[disprefs]); } /* display any change mark */ if (changing == YES && change[topline + disprefs - 1] == YES) { addch('>'); } else { addch(' '); } /* display the file name */ if (field == FILENAME) { printw("%-*s ", filelen, file); } else { /* if OGS, display the subsystem and book names */ if (ogs == YES) { ogsnames(file, &subsystem, &book); printw("%-*.*s ", subsystemlen, subsystemlen, subsystem); printw("%-*.*s ", booklen, booklen, book); } /* display the requested path components */ if (dispcomponents > 0) { printw("%-*.*s ", filelen, filelen, pathcomponents(file, dispcomponents)); } } /* else(field == FILENAME) */ /* display the function name */ if (field == SYMBOL || field == CALLEDBY || field == CALLING) { printw("%-*.*s ", fcnlen, fcnlen, function); } if (field == FILENAME) { addch('\n'); /* go to next line */ continue; } /* display the line number */ printw("%*s ", numlen, linenum); /* there may be tabs in egrep output */ while ((s = strchr(tempstring, '\t')) != NULL) { *s = ' '; } /* display the source line */ s = tempstring; for (;;) { /* see if the source line will fit */ if ((i = strlen(s)) > width) { /* find the nearest blank */ for (i = width; s[i] != ' ' && i > 0; --i) { ; } if (i == 0) { i = width; /* no blank */ } } /* print up to this point */ printw("%.*s", i, s); s += i; /* if line didn't wrap around */ if (i < width) { addch('\n'); /* go to next line */ } /* skip blanks */ while (*s == ' ') { ++s; } /* see if there is more text */ if (*s == '\0') { break; } /* if the source line is too long */ if (++screenline > lastdispline) { /* if this is the first displayed line, display what will fit on the screen */ if (topline == nextline -1) { disprefs++; /* break out of two loops */ goto endrefs; } /* erase the reference */ while (--screenline >= displine[disprefs]) { move(screenline, 0); clrtoeol(); } ++screenline; /* go back to the beginning of this reference */ --nextline; seekline(nextline); goto endrefs; } /* indent the continued source line */ move(screenline, COLS - width); } /* for(ever) */ } /* for(reference output lines) */ endrefs: /* position the cursor for the message */ i = FLDLINE - 1; if (screenline < i) { addch('\n'); } else { move(i, 0); } /* check for more references */ i = totallines - nextline + 1; bottomline = nextline; if (i > 0) { s = "s"; if (i == 1) { s = ""; } printw("* %d more line%s - press the space bar to display more *", i, s); } /* if this is the last page of references */ else if (topline > 1 && nextline > totallines) { addstr("* Press the space bar to display the first lines again *"); } } /* display the input fields */ move(FLDLINE, 0); for (i = 0; i < FIELDS; ++i) { printw("%s %s:\n", fields[i].text1, fields[i].text2); } /* display any prompt */ if (changing == YES) { move(PRLINE, 0); addstr(selprompt); } drawscrollbar(topline, nextline); /* display the scrollbar */ refresh();}/* set the cursor position for the field */voidsetfield(void){ fldline = FLDLINE + field; fldcolumn = strlen(fields[field].text1) + strlen(fields[field].text2) + 3;}/* move to the current input field */voidatfield(void){ move(fldline, fldcolumn);}/* move to the changing lines prompt */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -