@@ -33,38 +33,38 @@ | |||||
#ifndef CSCOPE_BUILD_H | #ifndef CSCOPE_BUILD_H | ||||
#define CSCOPE_BUILD_H | #define CSCOPE_BUILD_H | ||||
#include "global.h" /* FIXME: temp. only */ | |||||
#include "global.h" /* FIXME: temp. only */ | |||||
#include "invlib.h" | #include "invlib.h" | ||||
/* types and macros of build.c to be used by other modules */ | /* types and macros of build.c to be used by other modules */ | ||||
/* database output macros that update its offset */ | /* database output macros that update its offset */ | ||||
#define dbputc(c) (++dboffset, (void) putc(c, newrefs)) | |||||
#define dbfputs(s) (dboffset += strlen(s), fputs(s, newrefs)) | |||||
#define dbputc(c) (++dboffset, (void)putc(c, newrefs)) | |||||
#define dbfputs(s) (dboffset += strlen(s), fputs(s, newrefs)) | |||||
/* declarations for globals defined in build.c */ | /* declarations for globals defined in build.c */ | ||||
extern bool buildonly; /* only build the database */ | |||||
extern bool unconditional; /* unconditionally build database */ | |||||
extern bool fileschanged; /* assume some files changed */ | |||||
extern bool buildonly; /* only build the database */ | |||||
extern bool unconditional; /* unconditionally build database */ | |||||
extern bool fileschanged; /* assume some files changed */ | |||||
extern char *reffile; /* cross-reference file path name */ | |||||
extern char *invname; /* inverted index to the database */ | |||||
extern char *invpost; /* inverted index postings */ | |||||
extern char *newreffile; /* new cross-reference file name */ | |||||
extern FILE *newrefs; /* new cross-reference */ | |||||
extern FILE *postings; /* new inverted index postings */ | |||||
extern int symrefs; /* cross-reference file */ | |||||
extern char *reffile; /* cross-reference file path name */ | |||||
extern char *invname; /* inverted index to the database */ | |||||
extern char *invpost; /* inverted index postings */ | |||||
extern char *newreffile; /* new cross-reference file name */ | |||||
extern FILE *newrefs; /* new cross-reference */ | |||||
extern FILE *postings; /* new inverted index postings */ | |||||
extern int symrefs; /* cross-reference file */ | |||||
extern INVCONTROL invcontrol; /* inverted file control structure */ | |||||
extern INVCONTROL invcontrol; /* inverted file control structure */ | |||||
/* Prototypes of external functions defined by build.c */ | /* Prototypes of external functions defined by build.c */ | ||||
void build(void); | |||||
void free_newbuildfiles(void); | |||||
void opendatabase(void); | |||||
void rebuild(void); | |||||
void setup_build_filenames(char *reffile); | |||||
void seek_to_trailer(FILE *f); | |||||
void build(void); | |||||
void free_newbuildfiles(void); | |||||
void opendatabase(void); | |||||
void rebuild(void); | |||||
void setup_build_filenames(char *reffile); | |||||
void seek_to_trailer(FILE *f); | |||||
#endif /* CSCOPE_BUILD_H */ | #endif /* CSCOPE_BUILD_H */ |
@@ -36,14 +36,14 @@ | |||||
*/ | */ | ||||
#include "global.h" | #include "global.h" | ||||
#include "build.h" /* for rebuild() */ | |||||
#include "build.h" /* for rebuild() */ | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#if defined(USE_NCURSES) && !defined(RENAMED_NCURSES) | #if defined(USE_NCURSES) && !defined(RENAMED_NCURSES) | ||||
#include <ncurses.h> | |||||
# include <ncurses.h> | |||||
#else | #else | ||||
#include <curses.h> | |||||
# include <curses.h> | |||||
#endif | #endif | ||||
#include <ctype.h> | #include <ctype.h> | ||||
@@ -54,164 +54,135 @@ | |||||
* In the original version this was handled by | * In the original version this was handled by | ||||
* "int selecting // whether the (upper) symbol list is being browsed". | * "int selecting // whether the (upper) symbol list is being browsed". | ||||
*/ | */ | ||||
extern const void *const winput; | |||||
extern const void *const wmode; | |||||
extern const void *const wresult; | |||||
extern const void *const winput; | |||||
extern const void *const wmode; | |||||
extern const void *const wresult; | |||||
extern const void *const *const current_window; | extern const void *const *const current_window; | ||||
bool caseless; /* ignore letter case when searching */ | |||||
bool *change; /* change this line */ | |||||
char newpat[PATLEN + 1]; /* new pattern */ | |||||
bool caseless; /* ignore letter case when searching */ | |||||
bool *change; /* change this line */ | |||||
char newpat[PATLEN + 1]; /* new pattern */ | |||||
/* Internal prototypes: */ | /* Internal prototypes: */ | ||||
static void scrollbar(MOUSE *p); | |||||
static void scrollbar(MOUSE *p); | |||||
/* read references from a file */ | /* read references from a file */ | ||||
bool | |||||
readrefs(char *filename) | |||||
{ | |||||
FILE *file; | |||||
int c; | |||||
if ((file = myfopen(filename, "rb")) == NULL) { | |||||
cannotopen(filename); | |||||
return(false); | |||||
} | |||||
if ((c = getc(file)) == EOF) { /* if file is empty */ | |||||
fclose(file); | |||||
return(false); | |||||
} | |||||
totallines = 0; | |||||
disprefs = 0; | |||||
nextline = 1; | |||||
if (writerefsfound() == true) { | |||||
putc(c, refsfound); | |||||
while ((c = getc(file)) != EOF) { | |||||
putc(c, refsfound); | |||||
} | |||||
fclose(file); | |||||
fclose(refsfound); | |||||
if ( (refsfound = myfopen(temp1, "rb")) == NULL) { | |||||
cannotopen(temp1); | |||||
return(false); | |||||
} | |||||
countrefs(); | |||||
} else | |||||
fclose(file); | |||||
return(true); | |||||
bool readrefs(char *filename) { | |||||
FILE *file; | |||||
int c; | |||||
if((file = myfopen(filename, "rb")) == NULL) { | |||||
cannotopen(filename); | |||||
return (false); | |||||
} | |||||
if((c = getc(file)) == EOF) { /* if file is empty */ | |||||
fclose(file); | |||||
return (false); | |||||
} | |||||
totallines = 0; | |||||
disprefs = 0; | |||||
nextline = 1; | |||||
if(writerefsfound() == true) { | |||||
putc(c, refsfound); | |||||
while((c = getc(file)) != EOF) { | |||||
putc(c, refsfound); | |||||
} | |||||
fclose(file); | |||||
fclose(refsfound); | |||||
if((refsfound = myfopen(temp1, "rb")) == NULL) { | |||||
cannotopen(temp1); | |||||
return (false); | |||||
} | |||||
countrefs(); | |||||
} else | |||||
fclose(file); | |||||
return (true); | |||||
} | } | ||||
/* scrollbar actions */ | /* scrollbar actions */ | ||||
static void | |||||
scrollbar(MOUSE *p) | |||||
{ | |||||
///* reposition list if it makes sense */ | |||||
//if (totallines == 0) { | |||||
//return; | |||||
//} | |||||
//switch (p->percent) { | |||||
//case 101: /* scroll down one page */ | |||||
//if (nextline + mdisprefs > totallines) { | |||||
// nextline = totallines - mdisprefs + 1; | |||||
//} | |||||
//break; | |||||
//case 102: /* scroll up one page */ | |||||
//nextline = topline - mdisprefs; | |||||
//if (nextline < 1) { | |||||
// nextline = 1; | |||||
//} | |||||
//break; | |||||
//case 103: /* scroll down one line */ | |||||
//nextline = topline + 1; | |||||
//break; | |||||
//case 104: /* scroll up one line */ | |||||
//if (topline > 1) { | |||||
// nextline = topline - 1; | |||||
//} | |||||
//break; | |||||
//default: | |||||
//nextline = p->percent * totallines / 100; | |||||
//} | |||||
////seekline(nextline); | |||||
static void scrollbar(MOUSE *p) { | |||||
///* reposition list if it makes sense */ | |||||
// if (totallines == 0) { | |||||
// return; | |||||
// } | |||||
// switch (p->percent) { | |||||
// case 101: /* scroll down one page */ | |||||
// if (nextline + mdisprefs > totallines) { | |||||
// nextline = totallines - mdisprefs + 1; | |||||
// } | |||||
// break; | |||||
// case 102: /* scroll up one page */ | |||||
// nextline = topline - mdisprefs; | |||||
// if (nextline < 1) { | |||||
// nextline = 1; | |||||
// } | |||||
// break; | |||||
// case 103: /* scroll down one line */ | |||||
// nextline = topline + 1; | |||||
// break; | |||||
// case 104: /* scroll up one line */ | |||||
// if (topline > 1) { | |||||
// nextline = topline - 1; | |||||
// } | |||||
// break; | |||||
// default: | |||||
// nextline = p->percent * totallines / 100; | |||||
// } | |||||
////seekline(nextline); | |||||
} | } | ||||
/* count the references found */ | /* count the references found */ | ||||
void | |||||
countrefs(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 i; | |||||
/* count the references found and find the length of the file, | |||||
function, and line number display fields */ | |||||
/* HBB falseTE 2012-04-07: it may look like we shouldn't assing tempstring here, | |||||
* since it's not used. But it has to be assigned just so the return value | |||||
* of fscanf will actually reach 4. */ | |||||
while (EOF != (i = fscanf(refsfound, | |||||
"%" PATHLEN_STR "s%" PATLEN_STR "s%" NUMLEN_STR "s %" TEMPSTRING_LEN_STR "[^\n]", | |||||
file, function, linenum, tempstring | |||||
) | |||||
) | |||||
) { | |||||
if ( (i != 4) | |||||
|| !isgraph((unsigned char) *file) | |||||
|| !isgraph((unsigned char) *function) | |||||
|| !isdigit((unsigned char) *linenum) | |||||
) { | |||||
postmsg("File does not have expected format"); | |||||
totallines = 0; | |||||
disprefs = 0; | |||||
return; | |||||
} | |||||
if ((i = strlen(pathcomponents(file, dispcomponents))) > filelen) { | |||||
filelen = i; | |||||
} | |||||
if (ogs == true) { | |||||
ogsnames(file, &subsystem, &book); | |||||
if ((i = strlen(subsystem)) > subsystemlen) { | |||||
subsystemlen = i; | |||||
} | |||||
if ((i = strlen(book)) > booklen) { | |||||
booklen = i; | |||||
} | |||||
} | |||||
if ((i = strlen(function)) > fcnlen) { | |||||
fcnlen = i; | |||||
} | |||||
if ((i = strlen(linenum)) > numlen) { | |||||
numlen = i; | |||||
} | |||||
++totallines; | |||||
} | |||||
rewind(refsfound); | |||||
/* restrict the width of displayed columns */ | |||||
/* HBB FIXME 20060419: magic number alert! */ | |||||
i = (COLS - 5) / 3; | |||||
if (ogs == true) { | |||||
i = (COLS - 7) / 5; | |||||
} | |||||
if (filelen > i && i > 4) { | |||||
filelen = i; | |||||
} | |||||
if (subsystemlen > i && i > 9) { | |||||
subsystemlen = i; | |||||
} | |||||
if (booklen > i && i > 4) { | |||||
booklen = i; | |||||
} | |||||
if (fcnlen > i && i > 8) { | |||||
fcnlen = i; | |||||
} | |||||
void countrefs(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 i; | |||||
/* count the references found and find the length of the file, | |||||
function, and line number display fields */ | |||||
/* HBB falseTE 2012-04-07: it may look like we shouldn't assing tempstring here, | |||||
* since it's not used. But it has to be assigned just so the return value | |||||
* of fscanf will actually reach 4. */ | |||||
while(EOF != (i = fscanf(refsfound, | |||||
"%" PATHLEN_STR "s%" PATLEN_STR "s%" NUMLEN_STR | |||||
"s %" TEMPSTRING_LEN_STR "[^\n]", | |||||
file, | |||||
function, | |||||
linenum, | |||||
tempstring))) { | |||||
if((i != 4) || !isgraph((unsigned char)*file) || | |||||
!isgraph((unsigned char)*function) || !isdigit((unsigned char)*linenum)) { | |||||
postmsg("File does not have expected format"); | |||||
totallines = 0; | |||||
disprefs = 0; | |||||
return; | |||||
} | |||||
if((i = strlen(pathcomponents(file, dispcomponents))) > filelen) { filelen = i; } | |||||
if(ogs == true) { | |||||
ogsnames(file, &subsystem, &book); | |||||
if((i = strlen(subsystem)) > subsystemlen) { subsystemlen = i; } | |||||
if((i = strlen(book)) > booklen) { booklen = i; } | |||||
} | |||||
if((i = strlen(function)) > fcnlen) { fcnlen = i; } | |||||
if((i = strlen(linenum)) > numlen) { numlen = i; } | |||||
++totallines; | |||||
} | |||||
rewind(refsfound); | |||||
/* restrict the width of displayed columns */ | |||||
/* HBB FIXME 20060419: magic number alert! */ | |||||
i = (COLS - 5) / 3; | |||||
if(ogs == true) { i = (COLS - 7) / 5; } | |||||
if(filelen > i && i > 4) { filelen = i; } | |||||
if(subsystemlen > i && i > 9) { subsystemlen = i; } | |||||
if(booklen > i && i > 4) { booklen = i; } | |||||
if(fcnlen > i && i > 8) { fcnlen = i; } | |||||
} | } |
@@ -38,77 +38,79 @@ | |||||
#ifndef CSCOPE_CONSTANTS_H | #ifndef CSCOPE_CONSTANTS_H | ||||
#define CSCOPE_CONSTANTS_H | #define CSCOPE_CONSTANTS_H | ||||
#define ctrl(x) (x & 037) /* control character macro */ | |||||
#define ctrl(x) (x & 037) /* control character macro */ | |||||
/* fast string equality tests (avoids most strcmp() calls) */ | /* fast string equality tests (avoids most strcmp() calls) */ | ||||
#define strequal(s1, s2) (*(s1) == *(s2) && strcmp(s1, s2) == 0) | |||||
#define strnotequal(s1, s2) (*(s1) != *(s2) || strcmp(s1, s2) != 0) | |||||
#define strequal(s1, s2) (*(s1) == *(s2) && strcmp(s1, s2) == 0) | |||||
#define strnotequal(s1, s2) (*(s1) != *(s2) || strcmp(s1, s2) != 0) | |||||
/* set the mark character for searching the cross-reference file */ | /* set the mark character for searching the cross-reference file */ | ||||
#define setmark(c) (blockmark = c, block[blocklen] = blockmark) | |||||
#define setmark(c) (blockmark = c, block[blocklen] = blockmark) | |||||
/* get the next character in the cross-reference */ | /* get the next character in the cross-reference */ | ||||
/* note that blockp is assumed not to be null */ | /* note that blockp is assumed not to be null */ | ||||
#define getrefchar() (*(++blockp + 1) != '\0' ? *blockp : \ | |||||
(read_block() != NULL ? *blockp : '\0')) | |||||
#define getrefchar() \ | |||||
(*(++blockp + 1) != '\0' ? *blockp : (read_block() != NULL ? *blockp : '\0')) | |||||
/* skip the next character in the cross-reference */ | /* skip the next character in the cross-reference */ | ||||
/* note that blockp is assumed not to be null and that | /* note that blockp is assumed not to be null and that | ||||
this macro will always be in a statement by itself */ | this macro will always be in a statement by itself */ | ||||
#define skiprefchar() if (*(++blockp + 1) == '\0') (void) read_block() | |||||
#define DUMMYCHAR ' ' /* use space as a dummy character */ | |||||
#define MSGLEN ((PATLEN) + 80) /* displayed message length */ | |||||
#define NUMLEN 10 /* line number length */ | |||||
#define PATHLEN 250 /* file pathname length */ | |||||
#define PATLEN 250 /* symbol pattern length */ | |||||
#define TEMPSTRING_LEN 8191 /* max strlen() of the global temp string */ | |||||
#define REFFILE "cscope.out" /* cross-reference output file */ | |||||
#define NAMEFILE "cscope.files" /* default list-of-files file */ | |||||
#define INVNAME "cscope.in.out" /* inverted index to the database */ | |||||
#define INVPOST "cscope.po.out" /* inverted index postings */ | |||||
#define INVNAME2 "cscope.out.in"/* follows correct naming convention */ | |||||
#define INVPOST2 "cscope.out.po"/* follows correct naming convention */ | |||||
#define STMTMAX 10000 /* maximum source statement length */ | |||||
#define STR2(x) #x | |||||
#define STRINGIZE(x) STR2(x) | |||||
#define PATLEN_STR STRINGIZE(PATLEN) | |||||
#define PATHLEN_STR STRINGIZE(PATHLEN) | |||||
#define NUMLEN_STR STRINGIZE(NUMLEN) | |||||
#define skiprefchar() \ | |||||
if(*(++blockp + 1) == '\0') (void)read_block() | |||||
#define DUMMYCHAR ' ' /* use space as a dummy character */ | |||||
#define MSGLEN ((PATLEN) + 80) /* displayed message length */ | |||||
#define NUMLEN 10 /* line number length */ | |||||
#define PATHLEN 250 /* file pathname length */ | |||||
#define PATLEN 250 /* symbol pattern length */ | |||||
#define TEMPSTRING_LEN 8191 /* max strlen() of the global temp string */ | |||||
#define REFFILE "cscope.out" /* cross-reference output file */ | |||||
#define NAMEFILE "cscope.files" /* default list-of-files file */ | |||||
#define INVNAME "cscope.in.out" /* inverted index to the database */ | |||||
#define INVPOST "cscope.po.out" /* inverted index postings */ | |||||
#define INVNAME2 "cscope.out.in" /* follows correct naming convention */ | |||||
#define INVPOST2 "cscope.out.po" /* follows correct naming convention */ | |||||
#define STMTMAX 10000 /* maximum source statement length */ | |||||
#define STR2(x) #x | |||||
#define STRINGIZE(x) STR2(x) | |||||
#define PATLEN_STR STRINGIZE(PATLEN) | |||||
#define PATHLEN_STR STRINGIZE(PATHLEN) | |||||
#define NUMLEN_STR STRINGIZE(NUMLEN) | |||||
#define TEMPSTRING_LEN_STR STRINGIZE(TEMPSTRING_LEN) | #define TEMPSTRING_LEN_STR STRINGIZE(TEMPSTRING_LEN) | ||||
/* input fields (value matches field order on screen) */ | /* input fields (value matches field order on screen) */ | ||||
enum { | enum { | ||||
SYMBOL = 0, | |||||
DEFINITION = 1, | |||||
CALLEDBY = 2, | |||||
CALLING = 3, | |||||
STRING = 4, | |||||
CHANGE = 5, | |||||
REGEXP = 6, | |||||
FILENAME = 7, | |||||
INCLUDES = 8 | |||||
SYMBOL = 0, | |||||
DEFINITION = 1, | |||||
CALLEDBY = 2, | |||||
CALLING = 3, | |||||
STRING = 4, | |||||
CHANGE = 5, | |||||
REGEXP = 6, | |||||
FILENAME = 7, | |||||
INCLUDES = 8 | |||||
}; | }; | ||||
#define FIELDS 10 | |||||
#define FIELDS 10 | |||||
// XXX | // XXX | ||||
#define bazdki 1 | #define bazdki 1 | ||||
/* file open modes */ | /* file open modes */ | ||||
#ifndef R_OK | #ifndef R_OK | ||||
# define READ R_OK | |||||
# define READ R_OK | |||||
#else | #else | ||||
# define READ 4 | |||||
# define READ 4 | |||||
#endif | #endif | ||||
#ifdef W_OK | #ifdef W_OK | ||||
# define WRITE W_OK | |||||
# define WRITE W_OK | |||||
#else | #else | ||||
# define WRITE 2 | |||||
# define WRITE 2 | |||||
#endif | #endif | ||||
#define O_TEXT 0x00 | |||||
#define O_TEXT 0x00 | |||||
#define O_BINARY 0x00 | #define O_BINARY 0x00 | ||||
@@ -46,447 +46,408 @@ | |||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
/* convert long to a string in base BASE notation */ | /* convert long to a string in base BASE notation */ | ||||
#define ltobase(value) \ | |||||
do { \ | |||||
n = (value); \ | |||||
s = buf + (sizeof(buf) - 1); \ | |||||
*s = '\0'; \ | |||||
digits = 1; \ | |||||
while (n >= BASE) { \ | |||||
++digits; \ | |||||
i = n; \ | |||||
n /= BASE; \ | |||||
*--s = i - n * BASE + '!'; \ | |||||
} \ | |||||
*--s = n + '!'; \ | |||||
} while (0) | |||||
#define SYMBOLINC 20 /* symbol list size increment */ | |||||
long dboffset; /* new database offset */ | |||||
bool errorsfound; /* prompt before clearing messages */ | |||||
long lineoffset; /* source line database offset */ | |||||
long npostings; /* number of postings */ | |||||
int nsrcoffset; /* number of file name database offsets */ | |||||
long *srcoffset; /* source file name database offsets */ | |||||
unsigned long symbols; /* number of symbols */ | |||||
static char *filename; /* file name for warning messages */ | |||||
static long fcnoffset; /* function name database offset */ | |||||
static long macrooffset; /* macro name database offset */ | |||||
static unsigned long msymbols = SYMBOLINC; /* maximum number of symbols */ | |||||
struct symbol { /* symbol data */ | |||||
int type; /* type */ | |||||
unsigned int first; /* index of first character in text */ | |||||
unsigned int last; /* index of last+1 character in text */ | |||||
unsigned int length; /* symbol length */ | |||||
unsigned int fcn_level; /* function level of the symbol */ | |||||
#define ltobase(value) \ | |||||
do { \ | |||||
n = (value); \ | |||||
s = buf + (sizeof(buf) - 1); \ | |||||
*s = '\0'; \ | |||||
digits = 1; \ | |||||
while(n >= BASE) { \ | |||||
++digits; \ | |||||
i = n; \ | |||||
n /= BASE; \ | |||||
*--s = i - n * BASE + '!'; \ | |||||
} \ | |||||
*--s = n + '!'; \ | |||||
} while(0) | |||||
#define SYMBOLINC 20 /* symbol list size increment */ | |||||
long dboffset; /* new database offset */ | |||||
bool errorsfound; /* prompt before clearing messages */ | |||||
long lineoffset; /* source line database offset */ | |||||
long npostings; /* number of postings */ | |||||
int nsrcoffset; /* number of file name database offsets */ | |||||
long *srcoffset; /* source file name database offsets */ | |||||
unsigned long symbols; /* number of symbols */ | |||||
static char *filename; /* file name for warning messages */ | |||||
static long fcnoffset; /* function name database offset */ | |||||
static long macrooffset; /* macro name database offset */ | |||||
static unsigned long msymbols = SYMBOLINC; /* maximum number of symbols */ | |||||
struct symbol { /* symbol data */ | |||||
int type; /* type */ | |||||
unsigned int first; /* index of first character in text */ | |||||
unsigned int last; /* index of last+1 character in text */ | |||||
unsigned int length; /* symbol length */ | |||||
unsigned int fcn_level; /* function level of the symbol */ | |||||
}; | }; | ||||
static struct symbol *symbol; | static struct symbol *symbol; | ||||
static void putcrossref(void); | |||||
static void savesymbol(int token, int num); | |||||
void | |||||
crossref(char *srcfile) | |||||
{ | |||||
unsigned int i; | |||||
unsigned int length; /* symbol length */ | |||||
unsigned int entry_no; /* function level of the symbol */ | |||||
int token; /* current token */ | |||||
struct stat st; | |||||
if (! ((stat(srcfile, &st) == 0) | |||||
&& S_ISREG(st.st_mode))) { | |||||
cannotopen(srcfile); | |||||
errorsfound = true; | |||||
return; | |||||
} | |||||
entry_no = 0; | |||||
/* open the source file */ | |||||
if ((yyin = myfopen(srcfile, "r")) == NULL) { | |||||
cannotopen(srcfile); | |||||
errorsfound = true; | |||||
return; | |||||
} | |||||
filename = srcfile; /* save the file name for warning messages */ | |||||
putfilename(srcfile); /* output the file name */ | |||||
dbputc('\n'); | |||||
dbputc('\n'); | |||||
/* read the source file */ | |||||
initscanner(srcfile); | |||||
fcnoffset = macrooffset = 0; | |||||
symbols = 0; | |||||
if (symbol == NULL) { | |||||
symbol = malloc(msymbols * sizeof(*symbol)); | |||||
} | |||||
for (;;) { | |||||
/* get the next token */ | |||||
switch (token = yylex()) { | |||||
default: | |||||
/* if requested, truncate C symbols */ | |||||
length = last - first; | |||||
if (trun_syms == true && length > 8 && | |||||
token != INCLUDE && token != NEWFILE) { | |||||
length = 8; | |||||
last = first + 8; | |||||
} | |||||
/* see if the token has a symbol */ | |||||
if (length == 0) { | |||||
savesymbol(token, entry_no); | |||||
break; | |||||
} | |||||
/* update entry_no if see function entry */ | |||||
if (token == FCNDEF) { | |||||
entry_no++; | |||||
} | |||||
/* see if the symbol is already in the list */ | |||||
for (i = 0; i < symbols; ++i) { | |||||
if (length == symbol[i].length | |||||
&& strncmp(my_yytext + first, | |||||
my_yytext + symbol[i].first, | |||||
length) == 0 | |||||
&& entry_no == symbol[i].fcn_level | |||||
&& token == symbol[i].type | |||||
) { /* could be a::a() */ | |||||
break; | |||||
} | |||||
} | |||||
if (i == symbols) { /* if not already in list */ | |||||
savesymbol(token, entry_no); | |||||
} | |||||
break; | |||||
case NEWLINE: /* end of line containing symbols */ | |||||
entry_no = 0; /* reset entry_no for each line */ | |||||
static void putcrossref(void); | |||||
static void savesymbol(int token, int num); | |||||
void crossref(char *srcfile) { | |||||
unsigned int i; | |||||
unsigned int length; /* symbol length */ | |||||
unsigned int entry_no; /* function level of the symbol */ | |||||
int token; /* current token */ | |||||
struct stat st; | |||||
if(!((stat(srcfile, &st) == 0) && S_ISREG(st.st_mode))) { | |||||
cannotopen(srcfile); | |||||
errorsfound = true; | |||||
return; | |||||
} | |||||
entry_no = 0; | |||||
/* open the source file */ | |||||
if((yyin = myfopen(srcfile, "r")) == NULL) { | |||||
cannotopen(srcfile); | |||||
errorsfound = true; | |||||
return; | |||||
} | |||||
filename = srcfile; /* save the file name for warning messages */ | |||||
putfilename(srcfile); /* output the file name */ | |||||
dbputc('\n'); | |||||
dbputc('\n'); | |||||
/* read the source file */ | |||||
initscanner(srcfile); | |||||
fcnoffset = macrooffset = 0; | |||||
symbols = 0; | |||||
if(symbol == NULL) { symbol = malloc(msymbols * sizeof(*symbol)); } | |||||
for(;;) { | |||||
/* get the next token */ | |||||
switch(token = yylex()) { | |||||
default: | |||||
/* if requested, truncate C symbols */ | |||||
length = last - first; | |||||
if(trun_syms == true && length > 8 && token != INCLUDE && | |||||
token != NEWFILE) { | |||||
length = 8; | |||||
last = first + 8; | |||||
} | |||||
/* see if the token has a symbol */ | |||||
if(length == 0) { | |||||
savesymbol(token, entry_no); | |||||
break; | |||||
} | |||||
/* update entry_no if see function entry */ | |||||
if(token == FCNDEF) { entry_no++; } | |||||
/* see if the symbol is already in the list */ | |||||
for(i = 0; i < symbols; ++i) { | |||||
if(length == symbol[i].length && | |||||
strncmp(my_yytext + first, my_yytext + symbol[i].first, length) == | |||||
0 && | |||||
entry_no == symbol[i].fcn_level && | |||||
token == symbol[i].type) { /* could be a::a() */ | |||||
break; | |||||
} | |||||
} | |||||
if(i == symbols) { /* if not already in list */ | |||||
savesymbol(token, entry_no); | |||||
} | |||||
break; | |||||
case NEWLINE: /* end of line containing symbols */ | |||||
entry_no = 0; /* reset entry_no for each line */ | |||||
#ifdef USING_LEX | #ifdef USING_LEX | ||||
--yyleng; /* remove the newline */ | |||||
--yyleng; /* remove the newline */ | |||||
#endif | #endif | ||||
putcrossref(); /* output the symbols and source line */ | |||||
lineno = myylineno; /* save the symbol line number */ | |||||
putcrossref(); /* output the symbols and source line */ | |||||
lineno = myylineno; /* save the symbol line number */ | |||||
#ifndef USING_LEX | #ifndef USING_LEX | ||||
/* HBB 20010425: replaced yyleng-- by this chunk: */ | |||||
if (my_yytext) | |||||
*my_yytext = '\0'; | |||||
my_yyleng = 0; | |||||
/* HBB 20010425: replaced yyleng-- by this chunk: */ | |||||
if(my_yytext) *my_yytext = '\0'; | |||||
my_yyleng = 0; | |||||
#endif | #endif | ||||
break; | |||||
case LEXERR: /* Lexer error, abort further parsing of this file */ | |||||
case LEXEOF: /* end of file; last line may not have \n */ | |||||
/* if there were symbols, output them and the source line */ | |||||
if (symbols > 0) { | |||||
putcrossref(); | |||||
} | |||||
(void) fclose(yyin); /* close the source file */ | |||||
/* output the leading tab expected by the next call */ | |||||
dbputc('\t'); | |||||
return; | |||||
} | |||||
} | |||||
break; | |||||
case LEXERR: /* Lexer error, abort further parsing of this file */ | |||||
case LEXEOF: /* end of file; last line may not have \n */ | |||||
/* if there were symbols, output them and the source line */ | |||||
if(symbols > 0) { putcrossref(); } | |||||
(void)fclose(yyin); /* close the source file */ | |||||
/* output the leading tab expected by the next call */ | |||||
dbputc('\t'); | |||||
return; | |||||
} | |||||
} | |||||
} | } | ||||
/* save the symbol in the list */ | /* save the symbol in the list */ | ||||
static void | |||||
savesymbol(int token, int num) | |||||
{ | |||||
/* make sure there is room for the symbol */ | |||||
if (symbols == msymbols) { | |||||
msymbols += SYMBOLINC; | |||||
symbol = realloc(symbol, msymbols * sizeof(*symbol)); | |||||
} | |||||
/* save the symbol */ | |||||
symbol[symbols].type = token; | |||||
symbol[symbols].first = first; | |||||
symbol[symbols].last = last; | |||||
symbol[symbols].length = last - first; | |||||
symbol[symbols].fcn_level = num; | |||||
++symbols; | |||||
static void savesymbol(int token, int num) { | |||||
/* make sure there is room for the symbol */ | |||||
if(symbols == msymbols) { | |||||
msymbols += SYMBOLINC; | |||||
symbol = realloc(symbol, msymbols * sizeof(*symbol)); | |||||
} | |||||
/* save the symbol */ | |||||
symbol[symbols].type = token; | |||||
symbol[symbols].first = first; | |||||
symbol[symbols].last = last; | |||||
symbol[symbols].length = last - first; | |||||
symbol[symbols].fcn_level = num; | |||||
++symbols; | |||||
} | } | ||||
/* output the file name */ | /* output the file name */ | ||||
void | |||||
putfilename(char *srcfile) | |||||
{ | |||||
/* check for file system out of space */ | |||||
/* note: dbputc is not used to avoid lint complaint */ | |||||
if (putc(NEWFILE, newrefs) == EOF) { | |||||
cannotwrite(newreffile); | |||||
/* NOTREACHED */ | |||||
} | |||||
++dboffset; | |||||
if (invertedindex == true) { | |||||
srcoffset[nsrcoffset++] = dboffset; | |||||
} | |||||
dbfputs(srcfile); | |||||
fcnoffset = macrooffset = 0; | |||||
void putfilename(char *srcfile) { | |||||
/* check for file system out of space */ | |||||
/* note: dbputc is not used to avoid lint complaint */ | |||||
if(putc(NEWFILE, newrefs) == EOF) { | |||||
cannotwrite(newreffile); | |||||
/* NOTREACHED */ | |||||
} | |||||
++dboffset; | |||||
if(invertedindex == true) { srcoffset[nsrcoffset++] = dboffset; } | |||||
dbfputs(srcfile); | |||||
fcnoffset = macrooffset = 0; | |||||
} | } | ||||
/* output the symbols and source line */ | /* output the symbols and source line */ | ||||
static void | |||||
putcrossref(void) | |||||
{ | |||||
unsigned int i, j; | |||||
unsigned char c; | |||||
bool blank; /* blank indicator */ | |||||
unsigned int symput = 0; /* symbols output */ | |||||
int type; | |||||
/* output the source line */ | |||||
lineoffset = dboffset; | |||||
dboffset += fprintf(newrefs, "%d ", lineno); | |||||
static void putcrossref(void) { | |||||
unsigned int i, j; | |||||
unsigned char c; | |||||
bool blank; /* blank indicator */ | |||||
unsigned int symput = 0; /* symbols output */ | |||||
int type; | |||||
/* output the source line */ | |||||
lineoffset = dboffset; | |||||
dboffset += fprintf(newrefs, "%d ", lineno); | |||||
#ifdef PRINTF_RETVAL_BROKEN | #ifdef PRINTF_RETVAL_BROKEN | ||||
dboffset = ftell(newrefs); /* fprintf doesn't return chars written */ | |||||
dboffset = ftell(newrefs); /* fprintf doesn't return chars written */ | |||||
#endif | #endif | ||||
/* HBB 20010425: added this line: */ | |||||
my_yytext[my_yyleng] = '\0'; | |||||
blank = false; | |||||
for (i = 0; i < my_yyleng; ++i) { | |||||
/* change a tab to a blank and compress blanks */ | |||||
if ((c = my_yytext[i]) == ' ' || c == '\t') { | |||||
blank = true; | |||||
} else if (symput < symbols && i == symbol[symput].first) { | |||||
/* look for the start of a symbol */ | |||||
/* check for compressed blanks */ | |||||
if (blank == true) { | |||||
blank = false; | |||||
dbputc(' '); | |||||
} | |||||
dbputc('\n'); /* symbols start on a new line */ | |||||
/* output any symbol type */ | |||||
if ((type = symbol[symput].type) != IDENT) { | |||||
dbputc('\t'); | |||||
dbputc(type); | |||||
} else { | |||||
type = ' '; | |||||
} | |||||
/* output the symbol */ | |||||
j = symbol[symput].last; | |||||
c = my_yytext[j]; | |||||
my_yytext[j] = '\0'; | |||||
if (invertedindex == true) { | |||||
putposting(my_yytext + i, type); | |||||
} | |||||
writestring(my_yytext + i); | |||||
dbputc('\n'); | |||||
my_yytext[j] = c; | |||||
i = j - 1; | |||||
++symput; | |||||
} else { | |||||
/* HBB: try to save some time by early-out handling of | |||||
* non-compressed mode */ | |||||
if (compress == false) { | |||||
if (blank == true) { | |||||
dbputc(' '); | |||||
blank = false; | |||||
} | |||||
j = i + strcspn(my_yytext+i, "\t "); | |||||
if (symput < symbols | |||||
&& j >= symbol[symput].first) | |||||
j = symbol[symput].first; | |||||
c = my_yytext[j]; | |||||
my_yytext[j] = '\0'; | |||||
writestring(my_yytext + i); | |||||
my_yytext[j] = c; | |||||
i = j - 1; | |||||
/* finished this 'i', continue with the blank */ | |||||
continue; | |||||
} | |||||
/* check for compressed blanks */ | |||||
if (blank == true) { | |||||
if (dicode2[c]) { | |||||
c = DICODE_COMPRESS(' ', c); | |||||
} else { | |||||
dbputc(' '); | |||||
} | |||||
} else if (IS_A_DICODE(c, my_yytext[i + 1]) | |||||
&& symput < symbols | |||||
&& i + 1 != symbol[symput].first) { | |||||
/* compress digraphs */ | |||||
c = DICODE_COMPRESS(c, my_yytext[i + 1]); | |||||
++i; | |||||
} | |||||
dbputc((int) c); | |||||
blank = false; | |||||
/* skip compressed characters */ | |||||
if (c < ' ') { | |||||
++i; | |||||
/* skip blanks before a preprocesor keyword */ | |||||
/* note: don't use isspace() because \f and \v | |||||
are used for keywords */ | |||||
while ((j = my_yytext[i]) == ' ' || j == '\t') { | |||||
++i; | |||||
} | |||||
/* skip the rest of the keyword */ | |||||
while (isalpha((unsigned char)my_yytext[i])) { | |||||
++i; | |||||
} | |||||
/* skip space after certain keywords */ | |||||
if (keyword[c].delim != '\0') { | |||||
while ((j = my_yytext[i]) == ' ' || j == '\t') { | |||||
++i; | |||||
} | |||||
} | |||||
/* skip a '(' after certain keywords */ | |||||
if (keyword[c].delim == '(' | |||||
&& my_yytext[i] == '(') { | |||||
++i; | |||||
} | |||||
--i; /* compensate for ++i in for() */ | |||||
} /* if compressed char */ | |||||
} /* else: not a symbol */ | |||||
} /* for(i) */ | |||||
/* ignore trailing blanks */ | |||||
dbputc('\n'); | |||||
dbputc('\n'); | |||||
/* output any #define end marker */ | |||||
/* note: must not be part of #define so putsource() doesn't discard it | |||||
so findcalledbysub() can find it and return */ | |||||
if (symput < symbols && symbol[symput].type == DEFINEEND) { | |||||
dbputc('\t'); | |||||
dbputc(DEFINEEND); | |||||
dbputc('\n'); | |||||
dbputc('\n'); /* mark beginning of next source line */ | |||||
macrooffset = 0; | |||||
} | |||||
symbols = 0; | |||||
/* HBB 20010425: added this line: */ | |||||
my_yytext[my_yyleng] = '\0'; | |||||
blank = false; | |||||
for(i = 0; i < my_yyleng; ++i) { | |||||
/* change a tab to a blank and compress blanks */ | |||||
if((c = my_yytext[i]) == ' ' || c == '\t') { | |||||
blank = true; | |||||
} else if(symput < symbols && i == symbol[symput].first) { | |||||
/* look for the start of a symbol */ | |||||
/* check for compressed blanks */ | |||||
if(blank == true) { | |||||
blank = false; | |||||
dbputc(' '); | |||||
} | |||||
dbputc('\n'); /* symbols start on a new line */ | |||||
/* output any symbol type */ | |||||
if((type = symbol[symput].type) != IDENT) { | |||||
dbputc('\t'); | |||||
dbputc(type); | |||||
} else { | |||||
type = ' '; | |||||
} | |||||
/* output the symbol */ | |||||
j = symbol[symput].last; | |||||
c = my_yytext[j]; | |||||
my_yytext[j] = '\0'; | |||||
if(invertedindex == true) { putposting(my_yytext + i, type); } | |||||
writestring(my_yytext + i); | |||||
dbputc('\n'); | |||||
my_yytext[j] = c; | |||||
i = j - 1; | |||||
++symput; | |||||
} else { | |||||
/* HBB: try to save some time by early-out handling of | |||||
* non-compressed mode */ | |||||
if(compress == false) { | |||||
if(blank == true) { | |||||
dbputc(' '); | |||||
blank = false; | |||||
} | |||||
j = i + strcspn(my_yytext + i, "\t "); | |||||
if(symput < symbols && j >= symbol[symput].first) | |||||
j = symbol[symput].first; | |||||
c = my_yytext[j]; | |||||
my_yytext[j] = '\0'; | |||||
writestring(my_yytext + i); | |||||
my_yytext[j] = c; | |||||
i = j - 1; | |||||
/* finished this 'i', continue with the blank */ | |||||
continue; | |||||
} | |||||
/* check for compressed blanks */ | |||||
if(blank == true) { | |||||
if(dicode2[c]) { | |||||
c = DICODE_COMPRESS(' ', c); | |||||
} else { | |||||
dbputc(' '); | |||||
} | |||||
} else if(IS_A_DICODE(c, my_yytext[i + 1]) && symput < symbols && | |||||
i + 1 != symbol[symput].first) { | |||||
/* compress digraphs */ | |||||
c = DICODE_COMPRESS(c, my_yytext[i + 1]); | |||||
++i; | |||||
} | |||||
dbputc((int)c); | |||||
blank = false; | |||||
/* skip compressed characters */ | |||||
if(c < ' ') { | |||||
++i; | |||||
/* skip blanks before a preprocesor keyword */ | |||||
/* note: don't use isspace() because \f and \v | |||||
are used for keywords */ | |||||
while((j = my_yytext[i]) == ' ' || j == '\t') { | |||||
++i; | |||||
} | |||||
/* skip the rest of the keyword */ | |||||
while(isalpha((unsigned char)my_yytext[i])) { | |||||
++i; | |||||
} | |||||
/* skip space after certain keywords */ | |||||
if(keyword[c].delim != '\0') { | |||||
while((j = my_yytext[i]) == ' ' || j == '\t') { | |||||
++i; | |||||
} | |||||
} | |||||
/* skip a '(' after certain keywords */ | |||||
if(keyword[c].delim == '(' && my_yytext[i] == '(') { ++i; } | |||||
--i; /* compensate for ++i in for() */ | |||||
} /* if compressed char */ | |||||
} /* else: not a symbol */ | |||||
} /* for(i) */ | |||||
/* ignore trailing blanks */ | |||||
dbputc('\n'); | |||||
dbputc('\n'); | |||||
/* output any #define end marker */ | |||||
/* note: must not be part of #define so putsource() doesn't discard it | |||||
so findcalledbysub() can find it and return */ | |||||
if(symput < symbols && symbol[symput].type == DEFINEEND) { | |||||
dbputc('\t'); | |||||
dbputc(DEFINEEND); | |||||
dbputc('\n'); | |||||
dbputc('\n'); /* mark beginning of next source line */ | |||||
macrooffset = 0; | |||||
} | |||||
symbols = 0; | |||||
} | } | ||||
/* HBB 20000421: new function, for avoiding memory leaks */ | /* HBB 20000421: new function, for avoiding memory leaks */ | ||||
/* free the cross reference symbol table */ | /* free the cross reference symbol table */ | ||||
void | |||||
freecrossref() | |||||
{ | |||||
if (symbol) | |||||
free(symbol); | |||||
symbol = NULL; | |||||
symbols = 0; | |||||
void freecrossref() { | |||||
if(symbol) free(symbol); | |||||
symbol = NULL; | |||||
symbols = 0; | |||||
} | } | ||||
/* output the inverted index posting */ | /* output the inverted index posting */ | ||||
void | |||||
putposting(char *term, int type) | |||||
{ | |||||
long i, n; | |||||
char *s; | |||||
int digits; /* digits output */ | |||||
long offset; /* function/macro database offset */ | |||||
char buf[11]; /* number buffer */ | |||||
/* get the function or macro name offset */ | |||||
offset = fcnoffset; | |||||
if (macrooffset != 0) { | |||||
offset = macrooffset; | |||||
} | |||||
/* then update them to avoid negative relative name offset */ | |||||
switch (type) { | |||||
case DEFINE: | |||||
macrooffset = dboffset; | |||||
break; | |||||
case DEFINEEND: | |||||
macrooffset = 0; | |||||
return; /* null term */ | |||||
case FCNDEF: | |||||
fcnoffset = dboffset; | |||||
break; | |||||
case FCNEND: | |||||
fcnoffset = 0; | |||||
return; /* null term */ | |||||
} | |||||
/* ignore a null term caused by a enum/struct/union without a tag */ | |||||
if (*term == '\0') { | |||||
return; | |||||
} | |||||
/* skip any #include secondary type char (< or ") */ | |||||
if (type == INCLUDE) { | |||||
++term; | |||||
} | |||||
/* output the posting, which should be as small as possible to reduce | |||||
the temp file size and sort time */ | |||||
(void) fputs(term, postings); | |||||
(void) putc(' ', postings); | |||||
/* the line offset is padded so postings for the same term will sort | |||||
in ascending line offset order to order the references as they | |||||
appear withing a source file */ | |||||
ltobase(lineoffset); | |||||
for (i = PRECISION - digits; i > 0; --i) { | |||||
(void) putc('!', postings); | |||||
} | |||||
do { | |||||
(void) putc(*s, postings); | |||||
} while (*++s != '\0'); | |||||
/* postings are also sorted by type */ | |||||
(void) putc(type, postings); | |||||
/* function or macro name offset */ | |||||
if (offset > 0) { | |||||
(void) putc(' ', postings); | |||||
ltobase(offset); | |||||
do { | |||||
(void) putc(*s, postings); | |||||
} while (*++s != '\0'); | |||||
} | |||||
if (putc('\n', postings) == EOF) { | |||||
cannotwrite(temp1); | |||||
/* NOTREACHED */ | |||||
} | |||||
++npostings; | |||||
void putposting(char *term, int type) { | |||||
long i, n; | |||||
char *s; | |||||
int digits; /* digits output */ | |||||
long offset; /* function/macro database offset */ | |||||
char buf[11]; /* number buffer */ | |||||
/* get the function or macro name offset */ | |||||
offset = fcnoffset; | |||||
if(macrooffset != 0) { offset = macrooffset; } | |||||
/* then update them to avoid negative relative name offset */ | |||||
switch(type) { | |||||
case DEFINE: | |||||
macrooffset = dboffset; | |||||
break; | |||||
case DEFINEEND: | |||||
macrooffset = 0; | |||||
return; /* null term */ | |||||
case FCNDEF: | |||||
fcnoffset = dboffset; | |||||
break; | |||||
case FCNEND: | |||||
fcnoffset = 0; | |||||
return; /* null term */ | |||||
} | |||||
/* ignore a null term caused by a enum/struct/union without a tag */ | |||||
if(*term == '\0') { return; } | |||||
/* skip any #include secondary type char (< or ") */ | |||||
if(type == INCLUDE) { ++term; } | |||||
/* output the posting, which should be as small as possible to reduce | |||||
the temp file size and sort time */ | |||||
(void)fputs(term, postings); | |||||
(void)putc(' ', postings); | |||||
/* the line offset is padded so postings for the same term will sort | |||||
in ascending line offset order to order the references as they | |||||
appear withing a source file */ | |||||
ltobase(lineoffset); | |||||
for(i = PRECISION - digits; i > 0; --i) { | |||||
(void)putc('!', postings); | |||||
} | |||||
do { | |||||
(void)putc(*s, postings); | |||||
} while(*++s != '\0'); | |||||
/* postings are also sorted by type */ | |||||
(void)putc(type, postings); | |||||
/* function or macro name offset */ | |||||
if(offset > 0) { | |||||
(void)putc(' ', postings); | |||||
ltobase(offset); | |||||
do { | |||||
(void)putc(*s, postings); | |||||
} while(*++s != '\0'); | |||||
} | |||||
if(putc('\n', postings) == EOF) { | |||||
cannotwrite(temp1); | |||||
/* NOTREACHED */ | |||||
} | |||||
++npostings; | |||||
} | } | ||||
/* put the string into the new database */ | /* put the string into the new database */ | ||||
void | |||||
writestring(char *s) | |||||
{ | |||||
unsigned char c; | |||||
int i; | |||||
if (compress == false) { | |||||
/* Save some I/O overhead by using puts() instead of putc(): */ | |||||
dbfputs(s); | |||||
return; | |||||
} | |||||
/* compress digraphs */ | |||||
for (i = 0; (c = s[i]) != '\0'; ++i) { | |||||
if (/* dicode1[c] && dicode2[(unsigned char) s[i + 1]] */ | |||||
IS_A_DICODE(c, s[i + 1])) { | |||||
/* c = (0200 - 2) + dicode1[c] + dicode2[(unsigned char) s[i + 1]]; */ | |||||
c = DICODE_COMPRESS(c, s[i + 1]); | |||||
++i; | |||||
} | |||||
dbputc(c); | |||||
} | |||||
void writestring(char *s) { | |||||
unsigned char c; | |||||
int i; | |||||
if(compress == false) { | |||||
/* Save some I/O overhead by using puts() instead of putc(): */ | |||||
dbfputs(s); | |||||
return; | |||||
} | |||||
/* compress digraphs */ | |||||
for(i = 0; (c = s[i]) != '\0'; ++i) { | |||||
if(/* dicode1[c] && dicode2[(unsigned char) s[i + 1]] */ | |||||
IS_A_DICODE(c, s[i + 1])) { | |||||
/* c = (0200 - 2) + dicode1[c] + dicode2[(unsigned char) s[i + 1]]; */ | |||||
c = DICODE_COMPRESS(c, s[i + 1]); | |||||
++i; | |||||
} | |||||
dbputc(c); | |||||
} | |||||
} | } | ||||
/* print a warning message with the file name and line number */ | /* print a warning message with the file name and line number */ | ||||
void | |||||
warning(char *text) | |||||
{ | |||||
void warning(char *text) { | |||||
(void) fprintf(stderr, PROGRAM_NAME ": \"%s\", line %d: warning: %s\n", filename, | |||||
myylineno, text); | |||||
errorsfound = true; | |||||
(void)fprintf(stderr, | |||||
PROGRAM_NAME ": \"%s\", line %d: warning: %s\n", | |||||
filename, | |||||
myylineno, | |||||
text); | |||||
errorsfound = true; | |||||
} | } |
@@ -37,111 +37,95 @@ | |||||
#include "global.h" | #include "global.h" | ||||
#if defined(USE_NCURSES) && !defined(RENAMED_NCURSES) | #if defined(USE_NCURSES) && !defined(RENAMED_NCURSES) | ||||
#include <ncurses.h> | |||||
# include <ncurses.h> | |||||
#else | #else | ||||
#include <curses.h> | |||||
# include <curses.h> | |||||
#endif | #endif | ||||
/* edit this displayed reference */ | /* edit this displayed reference */ | ||||
void | |||||
editref(int i) | |||||
{ | |||||
char file[PATHLEN + 1]; /* file name */ | |||||
char linenum[NUMLEN + 1]; /* line number */ | |||||
/* verify that there is a references found file */ | |||||
if (refsfound == NULL) { | |||||
return; | |||||
} | |||||
/* get the selected line */ | |||||
seekrelline(i); | |||||
/* get the file name and line number */ | |||||
if (fscanf(refsfound, "%" PATHLEN_STR "s%*s%" NUMLEN_STR "s", file, linenum) == 2) { | |||||
edit(file, linenum); | |||||
} | |||||
void editref(int i) { | |||||
char file[PATHLEN + 1]; /* file name */ | |||||
char linenum[NUMLEN + 1]; /* line number */ | |||||
/* verify that there is a references found file */ | |||||
if(refsfound == NULL) { return; } | |||||
/* get the selected line */ | |||||
seekrelline(i); | |||||
/* get the file name and line number */ | |||||
if(fscanf(refsfound, "%" PATHLEN_STR "s%*s%" NUMLEN_STR "s", file, linenum) == 2) { | |||||
edit(file, linenum); | |||||
} | |||||
} | } | ||||
/* edit all references */ | /* edit all references */ | ||||
void | |||||
editall(void) | |||||
{ | |||||
char file[PATHLEN + 1]; /* file name */ | |||||
char linenum[NUMLEN + 1]; /* line number */ | |||||
int c; | |||||
/* verify that there is a references found file */ | |||||
if (refsfound == NULL) { | |||||
return; | |||||
} | |||||
/* get the first line */ | |||||
void editall(void) { | |||||
char file[PATHLEN + 1]; /* file name */ | |||||
char linenum[NUMLEN + 1]; /* line number */ | |||||
int c; | |||||
/* verify that there is a references found file */ | |||||
if(refsfound == NULL) { return; } | |||||
/* get the first line */ | |||||
fseek(refsfound, 0, SEEK_SET); | fseek(refsfound, 0, SEEK_SET); | ||||
/* get each file name and line number */ | |||||
while (fscanf(refsfound, "%" PATHLEN_STR "s%*s%" NUMLEN_STR "s%*[^\n]", file, linenum) == 2) { | |||||
edit(file, linenum); /* edit it */ | |||||
if (editallprompt == true) { | |||||
addstr("Type ^D to stop editing all lines, or any other character to continue: "); | |||||
if ((c = getch()) == EOF || c == ctrl('D') || c == ctrl('Z')) { | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
/* get each file name and line number */ | |||||
while( | |||||
fscanf(refsfound, "%" PATHLEN_STR "s%*s%" NUMLEN_STR "s%*[^\n]", file, linenum) == | |||||
2) { | |||||
edit(file, linenum); /* edit it */ | |||||
if(editallprompt == true) { | |||||
addstr( | |||||
"Type ^D to stop editing all lines, or any other character to continue: "); | |||||
if((c = getch()) == EOF || c == ctrl('D') || c == ctrl('Z')) { break; } | |||||
} | |||||
} | |||||
} | } | ||||
/* call the editor */ | /* call the editor */ | ||||
void | |||||
edit(char *file, const char *const linenum) | |||||
{ | |||||
const char *const editor_basename = basename(editor); | |||||
char msg[MSGLEN + 1]; /* message */ | |||||
char plusnum[NUMLEN + 20]; /* line number option: allow space for wordy line# flag */ | |||||
file = filepath(file); | |||||
snprintf(msg, sizeof(msg), "%s +%s %s", basename(editor), linenum, file); | |||||
postmsg(msg); | |||||
snprintf(plusnum, sizeof(plusnum), lineflag, linenum); | |||||
void edit(char *file, const char *const linenum) { | |||||
const char *const editor_basename = basename(editor); | |||||
char msg[MSGLEN + 1]; /* message */ | |||||
char plusnum[NUMLEN + 20]; /* line number option: allow space for wordy line# flag */ | |||||
file = filepath(file); | |||||
snprintf(msg, sizeof(msg), "%s +%s %s", basename(editor), linenum, file); | |||||
postmsg(msg); | |||||
snprintf(plusnum, sizeof(plusnum), lineflag, linenum); | |||||
/* Some pagers will not start paging, unless the input | /* Some pagers will not start paging, unless the input | ||||
* file has more lines thant the screen does. | * file has more lines thant the screen does. | ||||
* The way to get them to pause, is to pass in /dev/null too, | * The way to get them to pause, is to pass in /dev/null too, | ||||
* imatating endless blank lines. | * imatating endless blank lines. | ||||
*/ | */ | ||||
const char* const shit_pagers[] = { | |||||
"page", | |||||
"more", | |||||
NULL | |||||
}; | |||||
for(const char *const *sp = shit_pagers; *sp != NULL; sp++){ | |||||
if(!strcmp(editor_basename, *sp)){ | |||||
execute(editor, editor, plusnum, file, "/dev/null", NULL); | |||||
const char *const shit_pagers[] = {"page", "more", NULL}; | |||||
for(const char *const *sp = shit_pagers; *sp != NULL; sp++) { | |||||
if(!strcmp(editor_basename, *sp)) { | |||||
execute(editor, editor, plusnum, file, "/dev/null", NULL); | |||||
goto end; | goto end; | ||||
} | } | ||||
} | } | ||||
if (lineflagafterfile) { | |||||
execute(editor, editor, file, plusnum, NULL); | |||||
} | |||||
else { | |||||
execute(editor, editor, plusnum, file, NULL); | |||||
} | |||||
if(lineflagafterfile) { | |||||
execute(editor, editor, file, plusnum, NULL); | |||||
} else { | |||||
execute(editor, editor, plusnum, file, NULL); | |||||
} | |||||
end: | |||||
clear(); /* redisplay screen */ | |||||
end: | |||||
clear(); /* redisplay screen */ | |||||
} | } | ||||
/* if requested, prepend a path to a relative file name */ | /* if requested, prepend a path to a relative file name */ | ||||
char * | |||||
filepath(char *file) | |||||
{ | |||||
static char path[PATHLEN + 1]; | |||||
char *filepath(char *file) { | |||||
static char path[PATHLEN + 1]; | |||||
if (prependpath != NULL && *file != '/') { | |||||
(void) snprintf(path, sizeof(path), "%s/%s", prependpath, file); | |||||
file = path; | |||||
} | |||||
return(file); | |||||
if(prependpath != NULL && *file != '/') { | |||||
(void)snprintf(path, sizeof(path), "%s/%s", prependpath, file); | |||||
file = path; | |||||
} | |||||
return (file); | |||||
} | } |
@@ -36,7 +36,7 @@ | |||||
private implementation details that can be changed or removed. */ | private implementation details that can be changed or removed. */ | ||||
#ifndef YY_YY_EGREP_H_INCLUDED | #ifndef YY_YY_EGREP_H_INCLUDED | ||||
# define YY_YY_EGREP_H_INCLUDED | |||||
#define YY_YY_EGREP_H_INCLUDED | |||||
/* Debug traces. */ | /* Debug traces. */ | ||||
#ifndef YYDEBUG | #ifndef YYDEBUG | ||||
# define YYDEBUG 0 | # define YYDEBUG 0 | ||||
@@ -48,43 +48,43 @@ extern int yydebug; | |||||
/* Token kinds. */ | /* Token kinds. */ | ||||
#ifndef YYTOKENTYPE | #ifndef YYTOKENTYPE | ||||
# define YYTOKENTYPE | # define YYTOKENTYPE | ||||
enum yytokentype | |||||
{ | |||||
YYEMPTY = -2, | |||||
YYEOF = 0, /* "end of file" */ | |||||
YYerror = 256, /* error */ | |||||
YYUNDEF = 257, /* "invalid token" */ | |||||
CHAR = 258, /* CHAR */ | |||||
DOT = 259, /* DOT */ | |||||
CCL = 260, /* CCL */ | |||||
NCCL = 261, /* NCCL */ | |||||
OR = 262, /* OR */ | |||||
CAT = 263, /* CAT */ | |||||
STAR = 264, /* STAR */ | |||||
PLUS = 265, /* PLUS */ | |||||
QUEST = 266 /* QUEST */ | |||||
}; | |||||
typedef enum yytokentype yytoken_kind_t; | |||||
enum yytokentype { | |||||
YYEMPTY = -2, | |||||
YYEOF = 0, /* "end of file" */ | |||||
YYerror = 256, /* error */ | |||||
YYUNDEF = 257, /* "invalid token" */ | |||||
CHAR = 258, /* CHAR */ | |||||
DOT = 259, /* DOT */ | |||||
CCL = 260, /* CCL */ | |||||
NCCL = 261, /* NCCL */ | |||||
OR = 262, /* OR */ | |||||
CAT = 263, /* CAT */ | |||||
STAR = 264, /* STAR */ | |||||
PLUS = 265, /* PLUS */ | |||||
QUEST = 266 /* QUEST */ | |||||
}; | |||||
typedef enum yytokentype yytoken_kind_t; | |||||
#endif | #endif | ||||
/* Token kinds. */ | /* Token kinds. */ | ||||
#define YYEMPTY -2 | #define YYEMPTY -2 | ||||
#define YYEOF 0 | |||||
#define YYEOF 0 | |||||
#define YYerror 256 | #define YYerror 256 | ||||
#define YYUNDEF 257 | #define YYUNDEF 257 | ||||
#define CHAR 258 | |||||
#define DOT 259 | |||||
#define CCL 260 | |||||
#define NCCL 261 | |||||
#define OR 262 | |||||
#define CAT 263 | |||||
#define STAR 264 | |||||
#define PLUS 265 | |||||
#define QUEST 266 | |||||
#define CHAR 258 | |||||
#define DOT 259 | |||||
#define CCL 260 | |||||
#define NCCL 261 | |||||
#define OR 262 | |||||
#define CAT 263 | |||||
#define STAR 264 | |||||
#define PLUS 265 | |||||
#define QUEST 266 | |||||
/* Value type. */ | /* Value type. */ | ||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED | |||||
typedef int YYSTYPE; | |||||
# define YYSTYPE_IS_TRIVIAL 1 | |||||
#if !defined YYSTYPE && !defined YYSTYPE_IS_DECLARED | |||||
typedef int YYSTYPE; | |||||
# define YYSTYPE_IS_TRIVIAL 1 | |||||
# define YYSTYPE_IS_DECLARED 1 | # define YYSTYPE_IS_DECLARED 1 | ||||
#endif | #endif | ||||
@@ -92,7 +92,7 @@ typedef int YYSTYPE; | |||||
extern YYSTYPE yylval; | extern YYSTYPE yylval; | ||||
int yyparse (void); | |||||
int yyparse(void); | |||||
#endif /* !YY_YY_EGREP_H_INCLUDED */ | #endif /* !YY_YY_EGREP_H_INCLUDED */ |
@@ -39,20 +39,20 @@ | |||||
#include "global.h" | #include "global.h" | ||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include <sys/wait.h> | #include <sys/wait.h> | ||||
#include <sys/types.h> /* pid_t */ | |||||
#include <sys/types.h> /* pid_t */ | |||||
#ifdef __DJGPP__ | #ifdef __DJGPP__ | ||||
#include <process.h> | |||||
# include <process.h> | |||||
#endif | #endif | ||||
#include <ncurses.h> | #include <ncurses.h> | ||||
static sighandler_t oldsigquit; /* old value of quit signal */ | |||||
static sighandler_t oldsighup; /* old value of hangup signal */ | |||||
static sighandler_t oldsigtstp; /* old value of SIGTSTP */ | |||||
static sighandler_t oldsigquit; /* old value of quit signal */ | |||||
static sighandler_t oldsighup; /* old value of hangup signal */ | |||||
static sighandler_t oldsigtstp; /* old value of SIGTSTP */ | |||||
#ifndef __MSDOS__ /* none of these is needed, there */ | |||||
static int join(pid_t p); | |||||
static int myexecvp(char *a, char **args); | |||||
static pid_t myfork(void); | |||||
#ifndef __MSDOS__ /* none of these is needed, there */ | |||||
static int join(pid_t p); | |||||
static int myexecvp(char *a, char **args); | |||||
static pid_t myfork(void); | |||||
#endif | #endif | ||||
/* execute forks and executes a program or shell script, waits for it to | /* execute forks and executes a program or shell script, waits for it to | ||||
@@ -60,39 +60,37 @@ static pid_t myfork(void); | |||||
*/ | */ | ||||
/*VARARGS1*/ | /*VARARGS1*/ | ||||
int | |||||
execute(char *a, ...) /* NOTE: "exec" is already defined on u370 */ | |||||
int execute(char *a, ...) /* NOTE: "exec" is already defined on u370 */ | |||||
{ | { | ||||
va_list ap; | |||||
int exitcode = -1; | |||||
char *argv[BUFSIZ]; | |||||
pid_t p; | |||||
va_list ap; | |||||
int exitcode = -1; | |||||
char *argv[BUFSIZ]; | |||||
pid_t p; | |||||
/* fork and exec the program or shell script */ | |||||
endwin(); /* restore the terminal modes */ | |||||
mousecleanup(); | |||||
fflush(stdout); | |||||
va_start(ap, a); | |||||
/* fork and exec the program or shell script */ | |||||
endwin(); /* restore the terminal modes */ | |||||
mousecleanup(); | |||||
fflush(stdout); | |||||
va_start(ap, a); | |||||
for (p = 0; (argv[p] = va_arg(ap, char *)) != 0; p++){} | |||||
for(p = 0; (argv[p] = va_arg(ap, char *)) != 0; p++) { } | |||||
#ifdef __MSDOS__ | #ifdef __MSDOS__ | ||||
/* HBB 20010313: in MSDOG, everything is completely different. | |||||
* No fork()/exec()/wait(), but rather a single libc call: */ | |||||
exitcode = spawnvp(P_WAIT, a, argv); | |||||
/* HBB 20010313: in MSDOG, everything is completely different. | |||||
* No fork()/exec()/wait(), but rather a single libc call: */ | |||||
exitcode = spawnvp(P_WAIT, a, argv); | |||||
#else | #else | ||||
if ((p = myfork()) == 0) { | |||||
myexecvp(a, argv); /* child */ | |||||
} | |||||
else { | |||||
exitcode = join(p); /* parent */ | |||||
} | |||||
if((p = myfork()) == 0) { | |||||
myexecvp(a, argv); /* child */ | |||||
} else { | |||||
exitcode = join(p); /* parent */ | |||||
} | |||||
#endif /* MSDOS */ | #endif /* MSDOS */ | ||||
entercurses(); | entercurses(); | ||||
va_end(ap); | |||||
return(exitcode); | |||||
va_end(ap); | |||||
return (exitcode); | |||||
} | } | ||||
#ifndef __MSDOS__ /* None of the following functions is used there */ | #ifndef __MSDOS__ /* None of the following functions is used there */ | ||||
@@ -100,79 +98,71 @@ execute(char *a, ...) /* NOTE: "exec" is already defined on u370 */ | |||||
/* myexecvp is an interface to the execvp system call to | /* myexecvp is an interface to the execvp system call to | ||||
* modify argv[0] to reference the last component of its path-name. | * modify argv[0] to reference the last component of its path-name. | ||||
*/ | */ | ||||
static int | |||||
myexecvp(char *a, char **args) | |||||
{ | |||||
char msg[MSGLEN + 1]; | |||||
/* modify argv[0] to reference the last component of its path name */ | |||||
args[0] = basename(args[0]); | |||||
/* execute the program or shell script */ | |||||
execvp(a, args); /* returns only on failure */ | |||||
snprintf(msg, sizeof(msg), "\nCannot exec %s", a); | |||||
perror(msg); /* display the reason */ | |||||
askforreturn(); /* wait until the user sees the message */ | |||||
myexit(1); /* exit the child */ | |||||
/* NOTREACHED */ | |||||
return 0; | |||||
static int myexecvp(char *a, char **args) { | |||||
char msg[MSGLEN + 1]; | |||||
/* modify argv[0] to reference the last component of its path name */ | |||||
args[0] = basename(args[0]); | |||||
/* execute the program or shell script */ | |||||
execvp(a, args); /* returns only on failure */ | |||||
snprintf(msg, sizeof(msg), "\nCannot exec %s", a); | |||||
perror(msg); /* display the reason */ | |||||
askforreturn(); /* wait until the user sees the message */ | |||||
myexit(1); /* exit the child */ | |||||
/* NOTREACHED */ | |||||
return 0; | |||||
} | } | ||||
/* myfork acts like fork but also handles signals */ | /* myfork acts like fork but also handles signals */ | ||||
static pid_t | |||||
myfork(void) | |||||
{ | |||||
pid_t p; /* process number */ | |||||
p = fork(); | |||||
/* the parent ignores the interrupt, quit, and hangup signals */ | |||||
if (p > 0) { | |||||
oldsigquit = signal(SIGQUIT, SIG_IGN); | |||||
oldsighup = signal(SIGHUP, SIG_IGN); | |||||
#ifdef SIGTSTP | |||||
oldsigtstp = signal(SIGTSTP, SIG_DFL); | |||||
#endif | |||||
} | |||||
/* so they can be used to stop the child */ | |||||
else if (p == 0) { | |||||
signal(SIGINT, SIG_DFL); | |||||
signal(SIGQUIT, SIG_DFL); | |||||
signal(SIGHUP, SIG_DFL); | |||||
#ifdef SIGTSTP | |||||
signal(SIGTSTP, SIG_DFL); | |||||
#endif | |||||
} | |||||
/* check for fork failure */ | |||||
if (p == -1) { | |||||
myperror("Cannot fork"); | |||||
} | |||||
return p; | |||||
static pid_t myfork(void) { | |||||
pid_t p; /* process number */ | |||||
p = fork(); | |||||
/* the parent ignores the interrupt, quit, and hangup signals */ | |||||
if(p > 0) { | |||||
oldsigquit = signal(SIGQUIT, SIG_IGN); | |||||
oldsighup = signal(SIGHUP, SIG_IGN); | |||||
# ifdef SIGTSTP | |||||
oldsigtstp = signal(SIGTSTP, SIG_DFL); | |||||
# endif | |||||
} | |||||
/* so they can be used to stop the child */ | |||||
else if(p == 0) { | |||||
signal(SIGINT, SIG_DFL); | |||||
signal(SIGQUIT, SIG_DFL); | |||||
signal(SIGHUP, SIG_DFL); | |||||
# ifdef SIGTSTP | |||||
signal(SIGTSTP, SIG_DFL); | |||||
# endif | |||||
} | |||||
/* check for fork failure */ | |||||
if(p == -1) { myperror("Cannot fork"); } | |||||
return p; | |||||
} | } | ||||
/* join is the compliment of fork */ | /* join is the compliment of fork */ | ||||
static int | |||||
join(pid_t p) | |||||
{ | |||||
int status = -1; | |||||
pid_t w; | |||||
/* wait for the correct child to exit */ | |||||
do { | |||||
w = wait(&status); | |||||
} while (p != -1 && w != p); | |||||
/* restore signal handling */ | |||||
signal(SIGQUIT, oldsigquit); | |||||
signal(SIGHUP, oldsighup); | |||||
#ifdef SIGTSTP | |||||
signal(SIGTSTP, oldsigtstp); | |||||
#endif | |||||
static int join(pid_t p) { | |||||
int status = -1; | |||||
pid_t w; | |||||
/* wait for the correct child to exit */ | |||||
do { | |||||
w = wait(&status); | |||||
} while(p != -1 && w != p); | |||||
/* restore signal handling */ | |||||
signal(SIGQUIT, oldsigquit); | |||||
signal(SIGHUP, oldsighup); | |||||
# ifdef SIGTSTP | |||||
signal(SIGTSTP, oldsigtstp); | |||||
# endif | |||||
/* return the child's exit code */ | |||||
return(status >> 8); | |||||
/* return the child's exit code */ | |||||
return (status >> 8); | |||||
} | } | ||||
#endif /* !MSDOS */ | #endif /* !MSDOS */ |
@@ -43,46 +43,47 @@ | |||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <assert.h> | #include <assert.h> | ||||
#include <ctype.h> /* isalpha, isdigit, etc. */ | |||||
#include <signal.h> /* SIGINT and SIGQUIT */ | |||||
#include <stdio.h> /* standard I/O package */ | |||||
#include <stdlib.h> /* standard library functions */ | |||||
#include <ctype.h> /* isalpha, isdigit, etc. */ | |||||
#include <signal.h> /* SIGINT and SIGQUIT */ | |||||
#include <stdio.h> /* standard I/O package */ | |||||
#include <stdlib.h> /* standard library functions */ | |||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <string.h> /* string functions */ | |||||
#include <string.h> /* string functions */ | |||||
#include "constants.h" /* misc. constants */ | |||||
#include "invlib.h" /* inverted index library */ | |||||
#include "library.h" /* library function return values */ | |||||
#include "stddef.h" /* size_t */ | |||||
#include "constants.h" /* misc. constants */ | |||||
#include "invlib.h" /* inverted index library */ | |||||
#include "library.h" /* library function return values */ | |||||
#include "stddef.h" /* size_t */ | |||||
typedef void (*sighandler_t)(int); | typedef void (*sighandler_t)(int); | ||||
typedef struct { /* mouse action */ | |||||
int button; | |||||
int percent; | |||||
int x1; | |||||
int y1; | |||||
int x2; | |||||
int y2; | |||||
typedef struct { /* mouse action */ | |||||
int button; | |||||
int percent; | |||||
int x1; | |||||
int y1; | |||||
int x2; | |||||
int y2; | |||||
} MOUSE; | } MOUSE; | ||||
struct cmd { /* command history struct */ | |||||
struct cmd *prev, *next; /* list ptrs */ | |||||
int field; /* input field number */ | |||||
char *text; /* input field text */ | |||||
struct cmd { /* command history struct */ | |||||
struct cmd *prev, *next; /* list ptrs */ | |||||
int field; /* input field number */ | |||||
char *text; /* input field text */ | |||||
}; | }; | ||||
enum { | enum { | ||||
CH_NONE = 0x0000, | |||||
CH_RESULT = 0x0001 << 0, | |||||
CH_INPUT = 0x0001 << 1, | |||||
CH_MODE = 0x0001 << 2, | |||||
CH_HELP = 0x0001 << 3, /* do NOT add to CH_ALL */ | |||||
CH_ALL = CH_RESULT | CH_INPUT | CH_MODE | |||||
CH_NONE = 0x0000, | |||||
CH_RESULT = 0x0001 << 0, | |||||
CH_INPUT = 0x0001 << 1, | |||||
CH_MODE = 0x0001 << 2, | |||||
CH_HELP = 0x0001 << 3, /* do NOT add to CH_ALL */ | |||||
CH_ALL = CH_RESULT | CH_INPUT | CH_MODE | |||||
}; | }; | ||||
enum { | enum { | ||||
INPUT_NORMAL, | INPUT_NORMAL, | ||||
INPUT_APPEND, | INPUT_APPEND, | ||||
@@ -97,224 +98,225 @@ enum { | |||||
#endif | #endif | ||||
/* digraph data for text compression */ | /* digraph data for text compression */ | ||||
extern char dichar1[]; /* 16 most frequent first chars */ | |||||
extern char dichar2[]; /* 8 most frequent second chars | |||||
using the above as first chars */ | |||||
extern char dicode1[]; /* digraph first character code */ | |||||
extern char dicode2[]; /* digraph second character code */ | |||||
extern char dichar1[]; /* 16 most frequent first chars */ | |||||
extern char dichar2[]; /* 8 most frequent second chars | |||||
using the above as first chars */ | |||||
extern char dicode1[]; /* digraph first character code */ | |||||
extern char dicode2[]; /* digraph second character code */ | |||||
/* and some macros to help using dicodes: */ | /* and some macros to help using dicodes: */ | ||||
/* Check if a given pair of chars is compressable as a dicode: */ | /* Check if a given pair of chars is compressable as a dicode: */ | ||||
#define IS_A_DICODE(inchar1, inchar2) \ | |||||
(dicode1[(unsigned char)(inchar1)] && dicode2[(unsigned char)(inchar2)]) | |||||
#define IS_A_DICODE(inchar1, inchar2) \ | |||||
(dicode1[(unsigned char)(inchar1)] && dicode2[(unsigned char)(inchar2)]) | |||||
/* Combine the pair into a dicode */ | /* Combine the pair into a dicode */ | ||||
#define DICODE_COMPRESS(inchar1, inchar2) \ | |||||
((0200 - 2) + dicode1[(unsigned char)(inchar1)] \ | |||||
+ dicode2[(unsigned char)(inchar2)]) | |||||
#define DICODE_COMPRESS(inchar1, inchar2) \ | |||||
((0200 - 2) + dicode1[(unsigned char)(inchar1)] + dicode2[(unsigned char)(inchar2)]) | |||||
#define PROGRAM_NAME "Csope" | #define PROGRAM_NAME "Csope" | ||||
/* main.c global data */ | /* main.c global data */ | ||||
extern char *editor, *home, *shell, *lineflag; /* environment variables */ | |||||
extern char *home; /* Home directory */ | |||||
extern bool lineflagafterfile; | |||||
extern bool compress; /* compress the characters in the crossref */ | |||||
extern bool dbtruncated; /* database symbols truncated to 8 chars */ | |||||
extern int dispcomponents; /* file path components to display */ | |||||
extern bool editallprompt; /* prompt between editing files */ | |||||
extern unsigned int fileargc; /* file argument count */ | |||||
extern char **fileargv; /* file argument values */ | |||||
extern int fileversion; /* cross-reference file version */ | |||||
extern bool incurses; /* in curses */ | |||||
extern bool invertedindex; /* the database has an inverted index */ | |||||
extern bool isuptodate; /* consider the crossref up-to-date */ | |||||
extern bool kernelmode; /* don't use DFLT_INCDIR - bad for kernels */ | |||||
extern bool linemode; /* use line oriented user interface */ | |||||
extern bool verbosemode; /* print extra information on line mode */ | |||||
extern bool recurse_dir; /* recurse dirs when searching for src files */ | |||||
extern char *namefile; /* file of file names */ | |||||
extern bool ogs; /* display OGS book and subsystem names */ | |||||
extern char *prependpath; /* prepend path to file names */ | |||||
extern FILE *refsfound; /* references found file */ | |||||
extern long totalterms; /* total inverted index terms */ | |||||
extern bool trun_syms; /* truncate symbols to 8 characters */ | |||||
extern char tempstring[TEMPSTRING_LEN + 1]; /* global dummy string buffer */ | |||||
extern char *tmpdir; /* temporary directory */ | |||||
extern char temp1[]; /* temporary file name */ | |||||
extern char temp2[]; /* temporary file name */ | |||||
extern char *editor, *home, *shell, *lineflag; /* environment variables */ | |||||
extern char *home; /* Home directory */ | |||||
extern bool lineflagafterfile; | |||||
extern bool compress; /* compress the characters in the crossref */ | |||||
extern bool dbtruncated; /* database symbols truncated to 8 chars */ | |||||
extern int dispcomponents; /* file path components to display */ | |||||
extern bool editallprompt; /* prompt between editing files */ | |||||
extern unsigned int fileargc; /* file argument count */ | |||||
extern char **fileargv; /* file argument values */ | |||||
extern int fileversion; /* cross-reference file version */ | |||||
extern bool incurses; /* in curses */ | |||||
extern bool invertedindex; /* the database has an inverted index */ | |||||
extern bool isuptodate; /* consider the crossref up-to-date */ | |||||
extern bool kernelmode; /* don't use DFLT_INCDIR - bad for kernels */ | |||||
extern bool linemode; /* use line oriented user interface */ | |||||
extern bool verbosemode; /* print extra information on line mode */ | |||||
extern bool recurse_dir; /* recurse dirs when searching for src files */ | |||||
extern char *namefile; /* file of file names */ | |||||
extern bool ogs; /* display OGS book and subsystem names */ | |||||
extern char *prependpath; /* prepend path to file names */ | |||||
extern FILE *refsfound; /* references found file */ | |||||
extern long totalterms; /* total inverted index terms */ | |||||
extern bool trun_syms; /* truncate symbols to 8 characters */ | |||||
extern char tempstring[TEMPSTRING_LEN + 1]; /* global dummy string buffer */ | |||||
extern char *tmpdir; /* temporary directory */ | |||||
extern char temp1[]; /* temporary file name */ | |||||
extern char temp2[]; /* temporary file name */ | |||||
/* command.c global data */ | /* command.c global data */ | ||||
extern bool caseless; /* ignore letter case when searching */ | |||||
extern bool *change; /* change this line */ | |||||
extern unsigned int curdispline; | |||||
extern char newpat[]; /* new pattern */ | |||||
extern bool caseless; /* ignore letter case when searching */ | |||||
extern bool *change; /* change this line */ | |||||
extern unsigned int curdispline; | |||||
extern char newpat[]; /* new pattern */ | |||||
/* crossref.c global data */ | /* crossref.c global data */ | ||||
extern long dboffset; /* new database offset */ | |||||
extern bool errorsfound; /* prompt before clearing error messages */ | |||||
extern long lineoffset; /* source line database offset */ | |||||
extern long npostings; /* number of postings */ | |||||
extern unsigned long symbols; /* number of symbols */ | |||||
extern long dboffset; /* new database offset */ | |||||
extern bool errorsfound; /* prompt before clearing error messages */ | |||||
extern long lineoffset; /* source line database offset */ | |||||
extern long npostings; /* number of postings */ | |||||
extern unsigned long symbols; /* number of symbols */ | |||||
/* dir.c global data */ | /* dir.c global data */ | ||||
extern char currentdir[]; /* current directory */ | |||||
extern char **incdirs; /* #include directories */ | |||||
extern char **srcdirs; /* source directories */ | |||||
extern char **srcfiles; /* source files */ | |||||
extern size_t nincdirs; /* number of #include directories */ | |||||
extern size_t nsrcdirs; /* number of source directories */ | |||||
extern size_t nsrcfiles; /* number of source files */ | |||||
extern size_t msrcfiles; /* maximum number of source files */ | |||||
extern char currentdir[]; /* current directory */ | |||||
extern char **incdirs; /* #include directories */ | |||||
extern char **srcdirs; /* source directories */ | |||||
extern char **srcfiles; /* source files */ | |||||
extern size_t nincdirs; /* number of #include directories */ | |||||
extern size_t nsrcdirs; /* number of source directories */ | |||||
extern size_t nsrcfiles; /* number of source files */ | |||||
extern size_t msrcfiles; /* maximum number of source files */ | |||||
/* display.c global data */ | /* display.c global data */ | ||||
extern int subsystemlen; /* OGS subsystem name display field length */ | |||||
extern int booklen; /* OGS book name display field length */ | |||||
extern int filelen; /* file name display field length */ | |||||
extern int fcnlen; /* function name display field length */ | |||||
extern int numlen; /* line number display field length */ | |||||
extern int *displine; /* screen line of displayed reference */ | |||||
extern unsigned int disprefs; /* displayed references */ | |||||
extern int field; /* input field */ | |||||
extern unsigned int mdisprefs; /* maximum displayed references */ | |||||
extern unsigned int nextline; /* next line to be shown */ | |||||
extern long searchcount; /* count of files searched */ | |||||
extern unsigned int totallines; /* total reference lines */ | |||||
extern int window_change; /* bitmask type to mark which windows have to be rerendered by display() */ | |||||
extern int subsystemlen; /* OGS subsystem name display field length */ | |||||
extern int booklen; /* OGS book name display field length */ | |||||
extern int filelen; /* file name display field length */ | |||||
extern int fcnlen; /* function name display field length */ | |||||
extern int numlen; /* line number display field length */ | |||||
extern int *displine; /* screen line of displayed reference */ | |||||
extern unsigned int disprefs; /* displayed references */ | |||||
extern int field; /* input field */ | |||||
extern unsigned int mdisprefs; /* maximum displayed references */ | |||||
extern unsigned int nextline; /* next line to be shown */ | |||||
extern long searchcount; /* count of files searched */ | |||||
extern unsigned int totallines; /* total reference lines */ | |||||
extern int window_change; /* bitmask type to mark which windows have to be rerendered by | |||||
display() */ | |||||
/* find.c global data */ | /* find.c global data */ | ||||
extern char block[]; /* cross-reference file block */ | |||||
extern char blockmark; /* mark character to be searched for */ | |||||
extern long blocknumber; /* block number */ | |||||
extern char *blockp; /* pointer to current character in block */ | |||||
extern int blocklen; /* length of disk block read */ | |||||
extern char block[]; /* cross-reference file block */ | |||||
extern char blockmark; /* mark character to be searched for */ | |||||
extern long blocknumber; /* block number */ | |||||
extern char *blockp; /* pointer to current character in block */ | |||||
extern int blocklen; /* length of disk block read */ | |||||
/* lookup.c global data */ | /* lookup.c global data */ | ||||
extern struct keystruct { | |||||
char *text; | |||||
char delim; | |||||
struct keystruct *next; | |||||
extern struct keystruct { | |||||
char *text; | |||||
char delim; | |||||
struct keystruct *next; | |||||
} keyword[]; | } keyword[]; | ||||
/* mouse.c global data */ | /* mouse.c global data */ | ||||
extern bool mouse; /* mouse interface */ | |||||
extern bool mouse; /* mouse interface */ | |||||
/* readline.c global data */ | /* readline.c global data */ | ||||
extern char* rl_line_buffer; | |||||
extern char input_line[PATLEN + 1]; | |||||
extern int rl_point; | |||||
extern char *rl_line_buffer; | |||||
extern char input_line[PATLEN + 1]; | |||||
extern int rl_point; | |||||
//extern bool unixpcmouse; /* UNIX PC mouse interface */ | |||||
// extern bool unixpcmouse; /* UNIX PC mouse interface */ | |||||
/* cscope functions called from more than one function or between files */ | /* cscope functions called from more than one function or between files */ | ||||
char *filepath(char *file); | |||||
char *findsymbol(const char *pattern); | |||||
char *finddef(const char *pattern); | |||||
char *findcalledby(const char *pattern); | |||||
char *findcalling(const char *pattern); | |||||
char *findstring(const char *pattern); | |||||
char *findregexp(const char *egreppat); | |||||
char *findfile(const char *dummy); | |||||
char *findinclude(const char *pattern); | |||||
char *findassign(const char *pattern); | |||||
char *findallfcns(const char *dummy); | |||||
char *inviewpath(char *file); | |||||
char *lookup(char *ident); | |||||
char *pathcomponents(char *path, int components); | |||||
char *read_block(void); | |||||
char *scanpast(char c); | |||||
char ** parse_options(int *argc, char **argv); | |||||
void error_usage(void); | |||||
void longusage(void); | |||||
void usage(void); | |||||
extern bool remove_symfile_onexit; | |||||
extern bool onesearch; /* one search only in line mode */ | |||||
extern char *reflines; /* symbol reference lines file */ | |||||
extern bool do_press_any_key; /* wait for any key to continue */ | |||||
extern int current_page; | |||||
#define topref current_page*mdisprefs | |||||
void verswp_field(void); | |||||
void horswp_field(void); | |||||
bool interpret(int c); // XXX: probably rename | |||||
int handle_input(const int c); | |||||
int dispchar2int(const char c); | |||||
int process_mouse(); | |||||
char *filepath(char *file); | |||||
char *findsymbol(const char *pattern); | |||||
char *finddef(const char *pattern); | |||||
char *findcalledby(const char *pattern); | |||||
char *findcalling(const char *pattern); | |||||
char *findstring(const char *pattern); | |||||
char *findregexp(const char *egreppat); | |||||
char *findfile(const char *dummy); | |||||
char *findinclude(const char *pattern); | |||||
char *findassign(const char *pattern); | |||||
char *findallfcns(const char *dummy); | |||||
char *inviewpath(char *file); | |||||
char *lookup(char *ident); | |||||
char *pathcomponents(char *path, int components); | |||||
char *read_block(void); | |||||
char *scanpast(char c); | |||||
char **parse_options(int *argc, char **argv); | |||||
void error_usage(void); | |||||
void longusage(void); | |||||
void usage(void); | |||||
extern bool remove_symfile_onexit; | |||||
extern bool onesearch; /* one search only in line mode */ | |||||
extern char *reflines; /* symbol reference lines file */ | |||||
extern bool do_press_any_key; /* wait for any key to continue */ | |||||
extern int current_page; | |||||
#define topref current_page *mdisprefs | |||||
void verswp_field(void); | |||||
void horswp_field(void); | |||||
bool interpret(int c); // XXX: probably rename | |||||
int handle_input(const int c); | |||||
int dispchar2int(const char c); | |||||
int process_mouse(); | |||||
extern int input_mode; | extern int input_mode; | ||||
int changestring(const char* from, const char* to, const bool *const change, const int change_len); | |||||
long seekpage(const size_t i); | |||||
long seekrelline(unsigned i); | |||||
void PCS_reset(void); | |||||
void rlinit(void); | |||||
void addcmd(int f, char *s); | |||||
void addsrcfile(char *path); | |||||
void askforchar(void); | |||||
void askforreturn(void); | |||||
void cannotwrite(const char *const file); | |||||
void cannotopen(const char *const file); | |||||
void clearmsg(void); | |||||
void clearmsg2(void); | |||||
void countrefs(void); | |||||
void crossref(char *srcfile); | |||||
void dispinit(void); | |||||
void display(void); | |||||
void drawscrollbar(int top, int bot); | |||||
void edit(char *file, const char *const linenum); | |||||
void editall(void); | |||||
void editref(int); | |||||
void entercurses(void); | |||||
void exitcurses(void); | |||||
void findcleanup(void); | |||||
void freesrclist(void); | |||||
void freeinclist(void); | |||||
void freecrossref(void); | |||||
void freefilelist(void); | |||||
const char* help(void); | |||||
void incfile(char *file, char *type); | |||||
void includedir(char *_dirname); | |||||
void initsymtab(void); | |||||
void makefilelist(void); | |||||
void mousecleanup(void); | |||||
void mousemenu(void); | |||||
void mouseinit(void); | |||||
void mousereinit(void); | |||||
void myexit(int sig); | |||||
void myperror(char *text); | |||||
void ogsnames(char *file, char **subsystem, char **book); | |||||
void progress(char *what, long current, long max); | |||||
void putfilename(char *srcfile); | |||||
void postmsg(char *msg); | |||||
void postmsg2(char *msg); | |||||
void posterr(char *msg,...); | |||||
void postfatal(const char *msg,...); | |||||
void putposting(char *term, int type); | |||||
void fetch_string_from_dbase(char *, size_t); | |||||
void resetcmd(void); | |||||
void shellpath(char *out, int limit, char *in); | |||||
void sourcedir(char *dirlist); | |||||
void myungetch(int c); | |||||
void warning(char *text); | |||||
void writestring(char *s); | |||||
bool infilelist(char *file); | |||||
bool readrefs(char *filename); | |||||
bool search(const char* query); | |||||
bool writerefsfound(void); | |||||
int findinit(const char *pattern_); | |||||
MOUSE *getmouseaction(char leading_char); | |||||
struct cmd *currentcmd(void); | |||||
struct cmd *prevcmd(void); | |||||
struct cmd *nextcmd(void); | |||||
int egrep(char *file, FILE *output, char *format); | |||||
int hash(char *ss); | |||||
int execute(char *a, ...); | |||||
long dbseek(long offset); | |||||
int changestring(const char *from, const char *to, const bool *const change, | |||||
const int change_len); | |||||
long seekpage(const size_t i); | |||||
long seekrelline(unsigned i); | |||||
void PCS_reset(void); | |||||
void rlinit(void); | |||||
void addcmd(int f, char *s); | |||||
void addsrcfile(char *path); | |||||
void askforchar(void); | |||||
void askforreturn(void); | |||||
void cannotwrite(const char *const file); | |||||
void cannotopen(const char *const file); | |||||
void clearmsg(void); | |||||
void clearmsg2(void); | |||||
void countrefs(void); | |||||
void crossref(char *srcfile); | |||||
void dispinit(void); | |||||
void display(void); | |||||
void drawscrollbar(int top, int bot); | |||||
void edit(char *file, const char *const linenum); | |||||
void editall(void); | |||||
void editref(int); | |||||
void entercurses(void); | |||||
void exitcurses(void); | |||||
void findcleanup(void); | |||||
void freesrclist(void); | |||||
void freeinclist(void); | |||||
void freecrossref(void); | |||||
void freefilelist(void); | |||||
const char *help(void); | |||||
void incfile(char *file, char *type); | |||||
void includedir(char *_dirname); | |||||
void initsymtab(void); | |||||
void makefilelist(void); | |||||
void mousecleanup(void); | |||||
void mousemenu(void); | |||||
void mouseinit(void); | |||||
void mousereinit(void); | |||||
void myexit(int sig); | |||||
void myperror(char *text); | |||||
void ogsnames(char *file, char **subsystem, char **book); | |||||
void progress(char *what, long current, long max); | |||||
void putfilename(char *srcfile); | |||||
void postmsg(char *msg); | |||||
void postmsg2(char *msg); | |||||
void posterr(char *msg, ...); | |||||
void postfatal(const char *msg, ...); | |||||
void putposting(char *term, int type); | |||||
void fetch_string_from_dbase(char *, size_t); | |||||
void resetcmd(void); | |||||
void shellpath(char *out, int limit, char *in); | |||||
void sourcedir(char *dirlist); | |||||
void myungetch(int c); | |||||
void warning(char *text); | |||||
void writestring(char *s); | |||||
bool infilelist(char *file); | |||||
bool readrefs(char *filename); | |||||
bool search(const char *query); | |||||
bool writerefsfound(void); | |||||
int findinit(const char *pattern_); | |||||
MOUSE *getmouseaction(char leading_char); | |||||
struct cmd *currentcmd(void); | |||||
struct cmd *prevcmd(void); | |||||
struct cmd *nextcmd(void); | |||||
int egrep(char *file, FILE *output, char *format); | |||||
int hash(char *ss); | |||||
int execute(char *a, ...); | |||||
long dbseek(long offset); | |||||
#endif /* CSCOPE_GLOBAL_H */ | #endif /* CSCOPE_GLOBAL_H */ |
@@ -39,101 +39,91 @@ | |||||
#include "global.h" | #include "global.h" | ||||
#include <ncurses.h> | #include <ncurses.h> | ||||
/* | /* | ||||
max num of lines of help screen - | |||||
this number needs to be increased if more than n help items are needed | |||||
max num of lines of help screen - | |||||
this number needs to be increased if more than n help items are needed | |||||
*/ | */ | ||||
const char tooltip_winput[] = "Search [Enter] -Mode [^k] +Mode [^j] Right [Tab] Down [%]"; | const char tooltip_winput[] = "Search [Enter] -Mode [^k] +Mode [^j] Right [Tab] Down [%]"; | ||||
const char tooltip_wmode[] = "-Mode [Up] +Mode [Down] Right [Tab] Up [%]"; | |||||
const char tooltip_wresult[] = "Edit [Enter] Up [Up] Down [Down] Left [Tab] Previous [-] Next [+]"; | |||||
const char tooltip_wmode[] = "-Mode [Up] +Mode [Down] Right [Tab] Up [%]"; | |||||
const char tooltip_wresult[] = | |||||
"Edit [Enter] Up [Up] Down [Down] Left [Tab] Previous [-] Next [+]"; | |||||
static char help_msg[] = | |||||
"Press the RETURN key repeatedly to move to the desired input field, type the\n" | |||||
"pattern to search for, and then press the RETURN key. For the first 4 and\n" | |||||
"last 2 input fields, the pattern can be a regcomp(3) regular expression.\n" | |||||
"If the search is successful, you can use these single-character commands:\n\n" | |||||
"0-9a-zA-Z\tEdit the file containing the displayed line.\n" | |||||
"space bar\tDisplay next set of matching lines.\n" | |||||
"+\t\tDisplay next set of matching lines.\n" | |||||
"^V\t\tDisplay next set of matching lines.\n" | |||||
"-\t\tDisplay previous set of matching lines.\n" | |||||
"^E\t\tEdit all lines.\n" | |||||
">\t\tWrite the list of lines being displayed to a file.\n" | |||||
">>\t\tAppend the list of lines being displayed to a file.\n" | |||||
"<\t\tRead lines from a file.\n" | |||||
"^\t\tFilter all lines through a shell command.\n" | |||||
"|\t\tPipe all lines to a shell command.\n" | |||||
"\nAt any time you can use these single-character commands:\n\n" | |||||
"TAB\t\tSwap positions between input and output areas.\n" | |||||
"RETURN\t\tMove to the next input field.\n" | |||||
"^N\t\tMove to the next input field.\n" | |||||
"^P\t\tMove to the previous input field.\n" | |||||
"^Y / ^A\t\tSearch with the last pattern typed.\n" | |||||
"^B\t\tRecall previous input field and search pattern.\n" | |||||
"^F\t\tRecall next input field and search pattern.\n" | |||||
"^C\t\tToggle ignore/use letter case when searching.\n" | |||||
"^R\t\tRebuild the cross-reference.\n" | |||||
"!\t\tStart an interactive shell (type ^D to return).\n" | |||||
"^L\t\tRedraw the screen.\n" | |||||
"?\t\tDisplay this list of commands.\n" | |||||
"^D\t\tExit the program.\n" | |||||
"\nNote: If the first character of the pattern you want to search for matches\n" | |||||
"a command, type a \\ character first.\n" | |||||
"Note: Some ctrl keys may be occupied by your terminal configuration.\n" | |||||
; | |||||
static char help_msg[] = | |||||
"Press the RETURN key repeatedly to move to the desired input field, type the\n" | |||||
"pattern to search for, and then press the RETURN key. For the first 4 and\n" | |||||
"last 2 input fields, the pattern can be a regcomp(3) regular expression.\n" | |||||
"If the search is successful, you can use these single-character commands:\n\n" | |||||
"0-9a-zA-Z\tEdit the file containing the displayed line.\n" | |||||
"space bar\tDisplay next set of matching lines.\n" | |||||
"+\t\tDisplay next set of matching lines.\n" | |||||
"^V\t\tDisplay next set of matching lines.\n" | |||||
"-\t\tDisplay previous set of matching lines.\n" | |||||
"^E\t\tEdit all lines.\n" | |||||
">\t\tWrite the list of lines being displayed to a file.\n" | |||||
">>\t\tAppend the list of lines being displayed to a file.\n" | |||||
"<\t\tRead lines from a file.\n" | |||||
"^\t\tFilter all lines through a shell command.\n" | |||||
"|\t\tPipe all lines to a shell command.\n" | |||||
"\nAt any time you can use these single-character commands:\n\n" | |||||
"TAB\t\tSwap positions between input and output areas.\n" | |||||
"RETURN\t\tMove to the next input field.\n" | |||||
"^N\t\tMove to the next input field.\n" | |||||
"^P\t\tMove to the previous input field.\n" | |||||
"^Y / ^A\t\tSearch with the last pattern typed.\n" | |||||
"^B\t\tRecall previous input field and search pattern.\n" | |||||
"^F\t\tRecall next input field and search pattern.\n" | |||||
"^C\t\tToggle ignore/use letter case when searching.\n" | |||||
"^R\t\tRebuild the cross-reference.\n" | |||||
"!\t\tStart an interactive shell (type ^D to return).\n" | |||||
"^L\t\tRedraw the screen.\n" | |||||
"?\t\tDisplay this list of commands.\n" | |||||
"^D\t\tExit the program.\n" | |||||
"\nNote: If the first character of the pattern you want to search for matches\n" | |||||
"a command, type a \\ character first.\n" | |||||
"Note: Some ctrl keys may be occupied by your terminal configuration.\n"; | |||||
static char changeing_help_msg[] = | |||||
"When changing text, you can use these single-character commands:\n\n" | |||||
"0-9a-zA-Z\tMark or unmark the line to be changed.\n" | |||||
"*\t\tMark or unmark all displayed lines to be changed.\n" | |||||
"space bar\tDisplay next set of lines.\n" | |||||
"+\t\tDisplay next set of lines.\n" | |||||
"-\t\tDisplay previous set of lines.\n" | |||||
"^A\t\tMark or unmark all lines to be changed.\n" | |||||
"^D\t\tChange the marked lines and exit.\n" | |||||
"ESC\t\tExit without changing the marked lines.\n" | |||||
"!\t\tStart an interactive shell (type ^D to return).\n" | |||||
"^L\t\tRedraw the screen.\n" | |||||
"?\t\tDisplay this list of commands.\n" | |||||
; | |||||
static char changeing_help_msg[] = | |||||
"When changing text, you can use these single-character commands:\n\n" | |||||
"0-9a-zA-Z\tMark or unmark the line to be changed.\n" | |||||
"*\t\tMark or unmark all displayed lines to be changed.\n" | |||||
"space bar\tDisplay next set of lines.\n" | |||||
"+\t\tDisplay next set of lines.\n" | |||||
"-\t\tDisplay previous set of lines.\n" | |||||
"^A\t\tMark or unmark all lines to be changed.\n" | |||||
"^D\t\tChange the marked lines and exit.\n" | |||||
"ESC\t\tExit without changing the marked lines.\n" | |||||
"!\t\tStart an interactive shell (type ^D to return).\n" | |||||
"^L\t\tRedraw the screen.\n" | |||||
"?\t\tDisplay this list of commands.\n"; | |||||
const char* | |||||
help(void) | |||||
{ | |||||
if (input_mode == INPUT_CHANGE) { | |||||
const char *help(void) { | |||||
if(input_mode == INPUT_CHANGE) { | |||||
return help_msg; | return help_msg; | ||||
} else { | |||||
} else { | |||||
return changeing_help_msg; | return changeing_help_msg; | ||||
} | |||||
} | |||||
} | } | ||||
/* error exit including short usage information */ | /* error exit including short usage information */ | ||||
void | |||||
error_usage(void) | |||||
{ | |||||
usage(); | |||||
fputs("Try the -h option for more information.\n", stderr); | |||||
myexit(1); | |||||
void error_usage(void) { | |||||
usage(); | |||||
fputs("Try the -h option for more information.\n", stderr); | |||||
myexit(1); | |||||
} | } | ||||
/* normal usage message */ | /* normal usage message */ | ||||
void | |||||
usage(void) | |||||
{ | |||||
fputs( | |||||
"Usage: " PROGRAM_NAME " [-bcCdehklLqRTuUvV] [-f file] [-F file] [-i file] [-I dir] [-s dir]\n" | |||||
" [-p number] [-P path] [-[0-8] pattern] [source files]\n", | |||||
stderr | |||||
); | |||||
void usage(void) { | |||||
fputs("Usage: " PROGRAM_NAME | |||||
" [-bcCdehklLqRTuUvV] [-f file] [-F file] [-i file] [-I dir] [-s dir]\n" | |||||
" [-p number] [-P path] [-[0-8] pattern] [source files]\n", | |||||
stderr); | |||||
} | } | ||||
/* long usage message */ | /* long usage message */ | ||||
void | |||||
longusage(void) | |||||
{ | |||||
usage(); | |||||
fprintf(stderr, "\ | |||||
void longusage(void) { | |||||
usage(); | |||||
fprintf(stderr, | |||||
"\ | |||||
\n\ | \n\ | ||||
-b Build the cross-reference only.\n\ | -b Build the cross-reference only.\n\ | ||||
-C Ignore letter case when searching.\n\ | -C Ignore letter case when searching.\n\ | ||||
@@ -142,16 +132,18 @@ longusage(void) | |||||
-e Suppress the <Ctrl>-e command prompt between files.\n\ | -e Suppress the <Ctrl>-e command prompt between files.\n\ | ||||
-F symfile Read symbol reference lines from symfile.\n\ | -F symfile Read symbol reference lines from symfile.\n\ | ||||
-f reffile Use reffile as cross-ref file name instead of %s.\n", | -f reffile Use reffile as cross-ref file name instead of %s.\n", | ||||
REFFILE); | |||||
fprintf(stderr, "\ | |||||
REFFILE); | |||||
fprintf(stderr, | |||||
"\ | |||||
-h This help screen.\n\ | -h This help screen.\n\ | ||||
-I incdir Look in incdir for any #include files.\n\ | -I incdir Look in incdir for any #include files.\n\ | ||||
-i namefile Browse through files listed in namefile, instead of %s\n", | -i namefile Browse through files listed in namefile, instead of %s\n", | ||||
NAMEFILE); | |||||
fprintf(stderr, "\ | |||||
NAMEFILE); | |||||
fprintf(stderr, | |||||
"\ | |||||
-k Kernel Mode - don't use %s for #include files.\n", | -k Kernel Mode - don't use %s for #include files.\n", | ||||
DFLT_INCDIR); | |||||
fputs("\ | |||||
DFLT_INCDIR); | |||||
fputs("\ | |||||
-L Do a single search with line-oriented output.\n\ | -L Do a single search with line-oriented output.\n\ | ||||
-l Line-oriented interface.\n\ | -l Line-oriented interface.\n\ | ||||
-num pattern Go to input field num (counting from 0) and find pattern.\n\ | -num pattern Go to input field num (counting from 0) and find pattern.\n\ | ||||
@@ -167,5 +159,5 @@ longusage(void) | |||||
-V Print the version number.\n\ | -V Print the version number.\n\ | ||||
\n\ | \n\ | ||||
Please see the manpage for more information.\n", | Please see the manpage for more information.\n", | ||||
stderr); | |||||
stderr); | |||||
} | } |
@@ -39,66 +39,57 @@ | |||||
static struct cmd *tail, *current; | |||||
static struct cmd *tail, *current; | |||||
/* add a cmd to the history list */ | /* add a cmd to the history list */ | ||||
void | |||||
addcmd(int f, char *s) /* field number and command text */ | |||||
void addcmd(int f, char *s) /* field number and command text */ | |||||
{ | { | ||||
struct cmd *h; | |||||
h = malloc(sizeof(struct cmd)); | |||||
if( tail) { | |||||
tail->next = h; | |||||
h->next = 0; | |||||
h->prev = tail; | |||||
tail = h; | |||||
} else { | |||||
tail = h; | |||||
h->next = h->prev = 0; | |||||
} | |||||
h->field = f; | |||||
h->text = strdup( s); | |||||
current = 0; | |||||
struct cmd *h; | |||||
h = malloc(sizeof(struct cmd)); | |||||
if(tail) { | |||||
tail->next = h; | |||||
h->next = 0; | |||||
h->prev = tail; | |||||
tail = h; | |||||
} else { | |||||
tail = h; | |||||
h->next = h->prev = 0; | |||||
} | |||||
h->field = f; | |||||
h->text = strdup(s); | |||||
current = 0; | |||||
} | } | ||||
/* return previous history item */ | /* return previous history item */ | ||||
struct cmd * | |||||
prevcmd(void) | |||||
{ | |||||
if( current) { | |||||
if( current->prev) /* stay on first item */ | |||||
return current = current->prev; | |||||
else | |||||
return current; | |||||
} else if( tail) | |||||
return current = tail; | |||||
else | |||||
return NULL; | |||||
struct cmd *prevcmd(void) { | |||||
if(current) { | |||||
if(current->prev) /* stay on first item */ | |||||
return current = current->prev; | |||||
else | |||||
return current; | |||||
} else if(tail) | |||||
return current = tail; | |||||
else | |||||
return NULL; | |||||
} | } | ||||
/* return next history item */ | /* return next history item */ | ||||
struct cmd * | |||||
nextcmd(void) | |||||
{ | |||||
if( current) { | |||||
if( current->next) /* stay on first item */ | |||||
return current = current->next; | |||||
else | |||||
return current; | |||||
} else | |||||
return NULL; | |||||
struct cmd *nextcmd(void) { | |||||
if(current) { | |||||
if(current->next) /* stay on first item */ | |||||
return current = current->next; | |||||
else | |||||
return current; | |||||
} else | |||||
return NULL; | |||||
} | } | ||||
/* reset current to tail */ | /* reset current to tail */ | ||||
void | |||||
resetcmd(void) | |||||
{ | |||||
current = 0; | |||||
void resetcmd(void) { | |||||
current = 0; | |||||
} | } | ||||
struct cmd * | |||||
currentcmd(void) | |||||
{ | |||||
return current; | |||||
struct cmd *currentcmd(void) { | |||||
return current; | |||||
} | } |
@@ -37,7 +37,7 @@ | |||||
#include "global.h" | #include "global.h" | ||||
#include <ncurses.h> | #include <ncurses.h> | ||||
#include <setjmp.h> /* jmp_buf */ | |||||
#include <setjmp.h> /* jmp_buf */ | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#if HAVE_SYS_TERMIOS_H | #if HAVE_SYS_TERMIOS_H | ||||
@@ -48,522 +48,489 @@ | |||||
bool do_press_any_key = false; | bool do_press_any_key = false; | ||||
static jmp_buf env; /* setjmp/longjmp buffer */ | |||||
static int prevchar; /* previous, ungotten character */ | |||||
static jmp_buf env; /* setjmp/longjmp buffer */ | |||||
static int prevchar; /* previous, ungotten character */ | |||||
/* Internal prototypes: */ | /* Internal prototypes: */ | ||||
static void catchint(int sig); | static void catchint(int sig); | ||||
/* catch the interrupt signal */ | /* catch the interrupt signal */ | ||||
static void | |||||
catchint(int sig){ | |||||
static void catchint(int sig) { | |||||
UNUSED(sig); | UNUSED(sig); | ||||
signal(SIGINT, catchint); | |||||
longjmp(env, 1); | |||||
signal(SIGINT, catchint); | |||||
longjmp(env, 1); | |||||
} | } | ||||
/* unget a character */ | /* unget a character */ | ||||
void | |||||
myungetch(int c) | |||||
{ | |||||
prevchar = c; | |||||
void myungetch(int c) { | |||||
prevchar = c; | |||||
} | } | ||||
/* ask user to enter a character after reading the message */ | /* ask user to enter a character after reading the message */ | ||||
void | |||||
askforchar(void){ | |||||
addstr("Type any character to continue: "); | |||||
getch(); | |||||
void askforchar(void) { | |||||
addstr("Type any character to continue: "); | |||||
getch(); | |||||
} | } | ||||
/* ask user to press the RETURN key after reading the message */ | /* ask user to press the RETURN key after reading the message */ | ||||
void | |||||
askforreturn(void){ | |||||
fprintf(stderr, "Press the RETURN key to continue: "); | |||||
getchar(); | |||||
/* HBB 20060419: message probably messed up the screen --- redraw */ | |||||
if (incurses == true) { | |||||
redrawwin(curscr); | |||||
} | |||||
void askforreturn(void) { | |||||
fprintf(stderr, "Press the RETURN key to continue: "); | |||||
getchar(); | |||||
/* HBB 20060419: message probably messed up the screen --- redraw */ | |||||
if(incurses == true) { redrawwin(curscr); } | |||||
} | } | ||||
/* expand the ~ and $ shell meta characters in a path */ | /* expand the ~ and $ shell meta characters in a path */ | ||||
void | |||||
shellpath(char *out, int limit, char *in){ | |||||
char *lastchar; | |||||
char *s, *v; | |||||
/* skip leading white space */ | |||||
while (isspace((unsigned char)*in)) { | |||||
++in; | |||||
} | |||||
lastchar = out + limit - 1; | |||||
/* a tilde (~) by itself represents $HOME; followed by a name it | |||||
represents the $LOGDIR of that login name */ | |||||
if (*in == '~') { | |||||
*out++ = *in++; /* copy the ~ because it may not be expanded */ | |||||
/* get the login name */ | |||||
s = out; | |||||
while (s < lastchar && *in != '/' && *in != '\0' && !isspace((unsigned char)*in)) { | |||||
*s++ = *in++; | |||||
} | |||||
*s = '\0'; | |||||
/* if the login name is null, then use $HOME */ | |||||
if (*out == '\0') { | |||||
v = getenv("HOME"); | |||||
} else { /* get the home directory of the login name */ | |||||
v = logdir(out); | |||||
} | |||||
/* copy the directory name if it isn't too big */ | |||||
if (v != NULL && strlen(v) < (lastchar - out)) { | |||||
strcpy(out - 1, v); | |||||
out += strlen(v) - 1; | |||||
} else { | |||||
/* login not found, so ~ must be part of the file name */ | |||||
out += strlen(out); | |||||
} | |||||
} | |||||
/* get the rest of the path */ | |||||
while (out < lastchar && *in != '\0' && !isspace((unsigned char)*in)) { | |||||
/* look for an environment variable */ | |||||
if (*in == '$') { | |||||
*out++ = *in++; /* copy the $ because it may not be expanded */ | |||||
/* get the variable name */ | |||||
s = out; | |||||
while (s < lastchar && *in != '/' && *in != '\0' && | |||||
!isspace((unsigned char)*in)) { | |||||
*s++ = *in++; | |||||
} | |||||
*s = '\0'; | |||||
/* get its value, but only it isn't too big */ | |||||
if ((v = getenv(out)) != NULL && strlen(v) < (lastchar - out)) { | |||||
strcpy(out - 1, v); | |||||
out += strlen(v) - 1; | |||||
} else { | |||||
/* var not found, or too big, so assume $ must be part of the | |||||
* file name */ | |||||
out += strlen(out); | |||||
} | |||||
} | |||||
else { /* ordinary character */ | |||||
*out++ = *in++; | |||||
} | |||||
} | |||||
*out = '\0'; | |||||
void shellpath(char *out, int limit, char *in) { | |||||
char *lastchar; | |||||
char *s, *v; | |||||
/* skip leading white space */ | |||||
while(isspace((unsigned char)*in)) { | |||||
++in; | |||||
} | |||||
lastchar = out + limit - 1; | |||||
/* a tilde (~) by itself represents $HOME; followed by a name it | |||||
represents the $LOGDIR of that login name */ | |||||
if(*in == '~') { | |||||
*out++ = *in++; /* copy the ~ because it may not be expanded */ | |||||
/* get the login name */ | |||||
s = out; | |||||
while(s < lastchar && *in != '/' && *in != '\0' && !isspace((unsigned char)*in)) { | |||||
*s++ = *in++; | |||||
} | |||||
*s = '\0'; | |||||
/* if the login name is null, then use $HOME */ | |||||
if(*out == '\0') { | |||||
v = getenv("HOME"); | |||||
} else { /* get the home directory of the login name */ | |||||
v = logdir(out); | |||||
} | |||||
/* copy the directory name if it isn't too big */ | |||||
if(v != NULL && strlen(v) < (lastchar - out)) { | |||||
strcpy(out - 1, v); | |||||
out += strlen(v) - 1; | |||||
} else { | |||||
/* login not found, so ~ must be part of the file name */ | |||||
out += strlen(out); | |||||
} | |||||
} | |||||
/* get the rest of the path */ | |||||
while(out < lastchar && *in != '\0' && !isspace((unsigned char)*in)) { | |||||
/* look for an environment variable */ | |||||
if(*in == '$') { | |||||
*out++ = *in++; /* copy the $ because it may not be expanded */ | |||||
/* get the variable name */ | |||||
s = out; | |||||
while(s < lastchar && *in != '/' && *in != '\0' && | |||||
!isspace((unsigned char)*in)) { | |||||
*s++ = *in++; | |||||
} | |||||
*s = '\0'; | |||||
/* get its value, but only it isn't too big */ | |||||
if((v = getenv(out)) != NULL && strlen(v) < (lastchar - out)) { | |||||
strcpy(out - 1, v); | |||||
out += strlen(v) - 1; | |||||
} else { | |||||
/* var not found, or too big, so assume $ must be part of the | |||||
* file name */ | |||||
out += strlen(out); | |||||
} | |||||
} else { /* ordinary character */ | |||||
*out++ = *in++; | |||||
} | |||||
} | |||||
*out = '\0'; | |||||
} | } | ||||
static int | |||||
wmode_input(const int c){ | |||||
switch (c) { | |||||
case KEY_ENTER: | |||||
case '\r': | |||||
case '\n': | |||||
case ctrl('N'): /* go to next input field */ | |||||
case KEY_DOWN: | |||||
case KEY_RIGHT: | |||||
field = (field + 1) % FIELDS; | |||||
resetcmd(); | |||||
static int wmode_input(const int c) { | |||||
switch(c) { | |||||
case KEY_ENTER: | |||||
case '\r': | |||||
case '\n': | |||||
case ctrl('N'): /* go to next input field */ | |||||
case KEY_DOWN: | |||||
case KEY_RIGHT: | |||||
field = (field + 1) % FIELDS; | |||||
resetcmd(); | |||||
break; | break; | ||||
case ctrl('P'): /* go to previous input field */ | |||||
case KEY_UP: | |||||
case KEY_LEFT: | |||||
field = (field + (FIELDS - 1)) % FIELDS; | |||||
resetcmd(); | |||||
case ctrl('P'): /* go to previous input field */ | |||||
case KEY_UP: | |||||
case KEY_LEFT: | |||||
field = (field + (FIELDS - 1)) % FIELDS; | |||||
resetcmd(); | |||||
break; | break; | ||||
case KEY_HOME: /* go to first input field */ | |||||
field = 0; | |||||
resetcmd(); | |||||
case KEY_HOME: /* go to first input field */ | |||||
field = 0; | |||||
resetcmd(); | |||||
break; | break; | ||||
case KEY_LL: /* go to last input field */ | |||||
curdispline = disprefs; | |||||
case KEY_LL: /* go to last input field */ | |||||
curdispline = disprefs; | |||||
break; | break; | ||||
default: | default: | ||||
return 0; | return 0; | ||||
} | |||||
} | |||||
window_change |= CH_MODE; | window_change |= CH_MODE; | ||||
return 1; | return 1; | ||||
} | } | ||||
static int | |||||
wresult_input(const int c){ | |||||
switch (c) { | |||||
case KEY_ENTER: /* open for editing */ | |||||
case '\r': | |||||
case '\n': | |||||
editref(curdispline); | |||||
window_change = CH_ALL; | |||||
static int wresult_input(const int c) { | |||||
switch(c) { | |||||
case KEY_ENTER: /* open for editing */ | |||||
case '\r': | |||||
case '\n': | |||||
editref(curdispline); | |||||
window_change = CH_ALL; | |||||
break; | break; | ||||
case ctrl('N'): | |||||
case KEY_DOWN: | |||||
case KEY_RIGHT: | |||||
if ((curdispline + 1) < disprefs) { | |||||
++curdispline; | |||||
} | |||||
case ctrl('N'): | |||||
case KEY_DOWN: | |||||
case KEY_RIGHT: | |||||
if((curdispline + 1) < disprefs) { ++curdispline; } | |||||
break; | break; | ||||
case ctrl('P'): | |||||
case KEY_UP: | |||||
case KEY_LEFT: | |||||
if (curdispline) { | |||||
--curdispline; | |||||
} | |||||
case ctrl('P'): | |||||
case KEY_UP: | |||||
case KEY_LEFT: | |||||
if(curdispline) { --curdispline; } | |||||
break; | break; | ||||
case KEY_HOME: | |||||
curdispline = 0; | |||||
case KEY_HOME: | |||||
curdispline = 0; | |||||
break; | break; | ||||
case KEY_LL: | |||||
field = FIELDS - 1; | |||||
resetcmd(); | |||||
case KEY_LL: | |||||
field = FIELDS - 1; | |||||
resetcmd(); | |||||
break; | break; | ||||
default: | |||||
if(c > mdisprefs){ goto noredisp; } | |||||
const int pos = dispchar2int(c); | |||||
if(pos > -1){ editref(pos); } | |||||
default: | |||||
if(c > mdisprefs) { goto noredisp; } | |||||
const int pos = dispchar2int(c); | |||||
if(pos > -1) { editref(pos); } | |||||
goto noredisp; | goto noredisp; | ||||
} | |||||
} | |||||
window_change |= CH_RESULT; | window_change |= CH_RESULT; | ||||
noredisp: | |||||
noredisp: | |||||
return 1; | return 1; | ||||
} | } | ||||
static int | |||||
global_input(const int c){ | |||||
switch(c){ | |||||
case '\t': | |||||
horswp_field(); | |||||
break; | |||||
case '%': | |||||
verswp_field(); | |||||
break; | |||||
static int global_input(const int c) { | |||||
switch(c) { | |||||
case '\t': | |||||
horswp_field(); | |||||
break; | |||||
case '%': | |||||
verswp_field(); | |||||
break; | |||||
case ctrl('K'): | case ctrl('K'): | ||||
field = (field + (FIELDS - 1)) % FIELDS; | |||||
resetcmd(); | |||||
field = (field + (FIELDS - 1)) % FIELDS; | |||||
resetcmd(); | |||||
window_change |= CH_MODE; | window_change |= CH_MODE; | ||||
break; | |||||
break; | |||||
case ctrl('J'): | case ctrl('J'): | ||||
field = (field + 1) % FIELDS; | |||||
resetcmd(); | |||||
field = (field + 1) % FIELDS; | |||||
resetcmd(); | |||||
window_change |= CH_MODE; | window_change |= CH_MODE; | ||||
break; | |||||
case ctrl('H'): /* display previous page */ | |||||
case '-': | |||||
case KEY_PPAGE: | |||||
if (totallines == 0) { return 0; } /* don't redisplay if there are no lines */ | |||||
curdispline = 0; | |||||
if(current_page > 0){ | |||||
break; | |||||
case ctrl('H'): /* display previous page */ | |||||
case '-': | |||||
case KEY_PPAGE: | |||||
if(totallines == 0) { return 0; } /* don't redisplay if there are no lines */ | |||||
curdispline = 0; | |||||
if(current_page > 0) { | |||||
--current_page; | --current_page; | ||||
window_change |= CH_RESULT; | window_change |= CH_RESULT; | ||||
} | } | ||||
break; | |||||
case '+': | |||||
case ctrl('L'): | |||||
case KEY_NPAGE: | |||||
if (totallines == 0) { return 0; } /* don't redisplay if there are no lines */ | |||||
curdispline = 0; | |||||
break; | |||||
case '+': | |||||
case ctrl('L'): | |||||
case KEY_NPAGE: | |||||
if(totallines == 0) { return 0; } /* don't redisplay if there are no lines */ | |||||
curdispline = 0; | |||||
++current_page; | ++current_page; | ||||
window_change |= CH_RESULT; | window_change |= CH_RESULT; | ||||
break; | |||||
case '>': /* write or append the lines to a file */ | |||||
break; // XXX | |||||
//char filename[PATHLEN + 1]; | |||||
//char* s; | |||||
//char ch; | |||||
//FILE* file; | |||||
//if (totallines == 0) { | |||||
// postmsg("There are no lines to write to a file"); | |||||
// return(NO); | |||||
//} | |||||
//move(PRLINE, 0); | |||||
////addstr("Write to file: "); // XXX | |||||
//s = "w"; | |||||
//if ((ch = getch()) == '>') { | |||||
//move(PRLINE, 0); | |||||
////addstr(appendprompt); // XXX fix | |||||
////ch = '\0'; | |||||
////s = "a"; | |||||
////} | |||||
////if (ch != '\r' && mygetline("", newpat, COLS - sizeof(appendprompt), c, NO) > 0) { | |||||
//// shellpath(filename, sizeof(filename), newpat); | |||||
//// if ((file = myfopen(filename, s)) == NULL) { | |||||
//// cannotopen(filename); | |||||
//// } else { | |||||
//// seekline(1); | |||||
//// while ((ch = getc(refsfound)) != EOF) { | |||||
//// putc(ch, file); | |||||
//// } | |||||
//// seekline(topline); | |||||
//// fclose(file); | |||||
//// } | |||||
////} | |||||
////clearprompt(); | |||||
break; | |||||
case '<': /* read lines from a file */ | |||||
break; // XXX | |||||
//move(PRLINE, 0); | |||||
//addstr(readprompt); // XXX fix | |||||
//if (mygetline("", newpat, COLS - sizeof(readprompt), '\0', NO) > 0) { | |||||
// clearprompt(); | |||||
// shellpath(filename, sizeof(filename), newpat); | |||||
// if (readrefs(filename) == NO) { | |||||
// postmsg2("Ignoring an empty file"); | |||||
// return(NO); | |||||
// } | |||||
// window_change |= CH_INPUT; | |||||
// return(YES); | |||||
//} | |||||
//clearprompt(); | |||||
return 0; | |||||
case '|': /* pipe the lines to a shell command */ | |||||
case '^': | |||||
break; // XXX fix | |||||
if (totallines == 0) { | |||||
postmsg("There are no lines to pipe to a shell command"); | |||||
return 0; | |||||
} | |||||
/* get the shell command */ | |||||
//move(PRLINE, 0); | |||||
//addstr(pipeprompt); | |||||
//if (mygetline("", newpat, COLS - sizeof(pipeprompt), '\0', NO) == 0) { | |||||
// clearprompt(); | |||||
// return(NO); | |||||
//} | |||||
///* if the ^ command, redirect output to a temp file */ | |||||
//if (commandc == '^') { | |||||
// strcat(strcat(newpat, " >"), temp2); | |||||
// /* HBB 20020708: somebody might have even | |||||
// * their non-interactive default shells | |||||
// * complain about clobbering | |||||
// * redirections... --> delete before | |||||
// * overwriting */ | |||||
// remove(temp2); | |||||
//} | |||||
//exitcurses(); | |||||
//if ((file = mypopen(newpat, "w")) == NULL) { | |||||
// fprintf(stderr, "cscope: cannot open pipe to shell command: %s\n", newpat); | |||||
//} else { | |||||
// seekline(1); | |||||
// while ((c = getc(refsfound)) != EOF) { | |||||
// putc(c, file); | |||||
// } | |||||
// seekline(topline); | |||||
// mypclose(file); | |||||
//} | |||||
//if (commandc == '^') { | |||||
// if (readrefs(temp2) == NO) { | |||||
// postmsg("Ignoring empty output of ^ command"); | |||||
// } | |||||
//} | |||||
//askforreturn(); | |||||
//entercurses(); | |||||
break; | |||||
case '!': /* shell escape */ | |||||
execute(shell, shell, NULL); | |||||
break; | |||||
case '>': /* write or append the lines to a file */ | |||||
break; // XXX | |||||
// char filename[PATHLEN + 1]; | |||||
// char* s; | |||||
// char ch; | |||||
// FILE* file; | |||||
// if (totallines == 0) { | |||||
// postmsg("There are no lines to write to a file"); | |||||
// return(NO); | |||||
// } | |||||
// move(PRLINE, 0); | |||||
////addstr("Write to file: "); // XXX | |||||
// s = "w"; | |||||
// if ((ch = getch()) == '>') { | |||||
// move(PRLINE, 0); | |||||
////addstr(appendprompt); // XXX fix | |||||
////ch = '\0'; | |||||
////s = "a"; | |||||
////} | |||||
////if (ch != '\r' && mygetline("", newpat, COLS - sizeof(appendprompt), c, | |||||
///NO) > 0) { / shellpath(filename, sizeof(filename), newpat); / if | |||||
///((file = myfopen(filename, s)) == NULL) { / cannotopen(filename); / | |||||
///} else { / seekline(1); / while ((ch = getc(refsfound)) != | |||||
///EOF) { / putc(ch, file); / } / seekline(topline); / | |||||
///fclose(file); / } | |||||
////} | |||||
////clearprompt(); | |||||
break; | |||||
case '<': /* read lines from a file */ | |||||
break; // XXX | |||||
// move(PRLINE, 0); | |||||
// addstr(readprompt); // XXX fix | |||||
// if (mygetline("", newpat, COLS - sizeof(readprompt), '\0', NO) > 0) { | |||||
// clearprompt(); | |||||
// shellpath(filename, sizeof(filename), newpat); | |||||
// if (readrefs(filename) == NO) { | |||||
// postmsg2("Ignoring an empty file"); | |||||
// return(NO); | |||||
// } | |||||
// window_change |= CH_INPUT; | |||||
// return(YES); | |||||
// } | |||||
// clearprompt(); | |||||
return 0; | |||||
case '|': /* pipe the lines to a shell command */ | |||||
case '^': | |||||
break; // XXX fix | |||||
if(totallines == 0) { | |||||
postmsg("There are no lines to pipe to a shell command"); | |||||
return 0; | |||||
} | |||||
/* get the shell command */ | |||||
// move(PRLINE, 0); | |||||
// addstr(pipeprompt); | |||||
// if (mygetline("", newpat, COLS - sizeof(pipeprompt), '\0', NO) == 0) { | |||||
// clearprompt(); | |||||
// return(NO); | |||||
// } | |||||
///* if the ^ command, redirect output to a temp file */ | |||||
// if (commandc == '^') { | |||||
// strcat(strcat(newpat, " >"), temp2); | |||||
// /* HBB 20020708: somebody might have even | |||||
// * their non-interactive default shells | |||||
// * complain about clobbering | |||||
// * redirections... --> delete before | |||||
// * overwriting */ | |||||
// remove(temp2); | |||||
// } | |||||
// exitcurses(); | |||||
// if ((file = mypopen(newpat, "w")) == NULL) { | |||||
// fprintf(stderr, "cscope: cannot open pipe to shell command: %s\n", | |||||
// newpat); | |||||
// } else { | |||||
// seekline(1); | |||||
// while ((c = getc(refsfound)) != EOF) { | |||||
// putc(c, file); | |||||
// } | |||||
// seekline(topline); | |||||
// mypclose(file); | |||||
// } | |||||
// if (commandc == '^') { | |||||
// if (readrefs(temp2) == NO) { | |||||
// postmsg("Ignoring empty output of ^ command"); | |||||
// } | |||||
// } | |||||
// askforreturn(); | |||||
// entercurses(); | |||||
break; | |||||
case '!': /* shell escape */ | |||||
execute(shell, shell, NULL); | |||||
current_page = 0; | current_page = 0; | ||||
break; | |||||
case KEY_RESIZE: | |||||
/* XXX: fill in*/ | |||||
break; | |||||
case ctrl('U'): /* redraw screen */ | |||||
case KEY_CLEAR: | |||||
window_change = CH_ALL; | |||||
break; | |||||
case '?': /* help */ | |||||
break; | |||||
case KEY_RESIZE: | |||||
/* XXX: fill in*/ | |||||
break; | |||||
case ctrl('U'): /* redraw screen */ | |||||
case KEY_CLEAR: | |||||
window_change = CH_ALL; | |||||
break; | |||||
case '?': /* help */ | |||||
window_change = CH_HELP; | window_change = CH_HELP; | ||||
break; | |||||
case ctrl('E'): /* edit all lines */ | |||||
editall(); | |||||
break; | |||||
default: | |||||
return 0; | |||||
} | |||||
return 1; | |||||
break; | |||||
case ctrl('E'): /* edit all lines */ | |||||
editall(); | |||||
break; | |||||
default: | |||||
return 0; | |||||
} | |||||
return 1; | |||||
} | } | ||||
extern const void *const winput; | |||||
extern const void *const wmode; | |||||
extern const void *const wresult; | |||||
extern const void *const winput; | |||||
extern const void *const wmode; | |||||
extern const void *const wresult; | |||||
extern const void *const *const current_window; | extern const void *const *const current_window; | ||||
int | |||||
change_input(const int c){ | |||||
MOUSE *p; /* mouse data */ | |||||
switch(c){ | |||||
case '*': /* invert page */ | |||||
for(int i = 0; topref + i < nextline; i++){ | |||||
change[topref + i] = !change[topref + i]; | |||||
} | |||||
window_change |= CH_RESULT; | |||||
break; | |||||
case ctrl('A'): /* invert all lines */ | |||||
for(unsigned i = 0; i < totallines; i++) { | |||||
change[i] = !change[i]; | |||||
} | |||||
window_change |= CH_RESULT; | |||||
break; | |||||
case ctrl('X'): /* mouse selection */ | |||||
if ((p = getmouseaction(DUMMYCHAR)) == NULL) { | |||||
break; /* unknown control sequence */ | |||||
} | |||||
/* if the button number is a scrollbar tag */ | |||||
if (p->button == '0') { | |||||
//scrollbar(p); | |||||
int change_input(const int c) { | |||||
MOUSE *p; /* mouse data */ | |||||
switch(c) { | |||||
case '*': /* invert page */ | |||||
for(int i = 0; topref + i < nextline; i++) { | |||||
change[topref + i] = !change[topref + i]; | |||||
} | |||||
window_change |= CH_RESULT; | |||||
break; | break; | ||||
} | |||||
/* find the selected line */ | |||||
/* NOTE: the selection is forced into range */ | |||||
{ | |||||
int i; | |||||
for(i = disprefs - 1; i > 0; --i) { | |||||
if (p->y1 >= displine[i]) { | |||||
break; | |||||
case ctrl('A'): /* invert all lines */ | |||||
for(unsigned i = 0; i < totallines; i++) { | |||||
change[i] = !change[i]; | |||||
} | |||||
window_change |= CH_RESULT; | |||||
break; | |||||
case ctrl('X'): /* mouse selection */ | |||||
if((p = getmouseaction(DUMMYCHAR)) == NULL) { | |||||
break; /* unknown control sequence */ | |||||
} | |||||
/* if the button number is a scrollbar tag */ | |||||
if(p->button == '0') { | |||||
// scrollbar(p); | |||||
break; | |||||
} | |||||
/* find the selected line */ | |||||
/* NOTE: the selection is forced into range */ | |||||
{ | |||||
int i; | |||||
for(i = disprefs - 1; i > 0; --i) { | |||||
if(p->y1 >= displine[i]) { break; } | |||||
} | } | ||||
change[i] = !change[i]; | |||||
} | } | ||||
change[i] = !change[i]; | |||||
} | |||||
break; | |||||
case ctrl('D'): | |||||
changestring(input_line, newpat, change, totallines); | |||||
break; | |||||
default: | |||||
{ | |||||
/* if a line was selected */ | |||||
const int cc = dispchar2int(c); | |||||
if(cc != -1){ | |||||
change[cc] = !change[cc]; | |||||
window_change |= CH_RESULT; | |||||
break; | |||||
case ctrl('D'): | |||||
changestring(input_line, newpat, change, totallines); | |||||
break; | |||||
default: | |||||
{ | |||||
/* if a line was selected */ | |||||
const int cc = dispchar2int(c); | |||||
if(cc != -1) { | |||||
change[cc] = !change[cc]; | |||||
window_change |= CH_RESULT; | |||||
} | |||||
} | } | ||||
} | |||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
int | |||||
changestring(const char* from, | |||||
const char* to, | |||||
const bool *const change, | |||||
const int change_len | |||||
){ | |||||
char newfile[PATHLEN + 1]; /* new file name */ | |||||
char oldfile[PATHLEN + 1]; /* old file name */ | |||||
char linenum[NUMLEN + 1]; /* file line number */ | |||||
char msg[MSGLEN + 1]; /* message */ | |||||
FILE *script; /* shell script file */ | |||||
/* Return early */ | |||||
bool anymarked = false; /* any line marked */ | |||||
for(int i = 0; i < change_len; i++){ | |||||
if(change[i]){ | |||||
int changestring(const char *from, const char *to, const bool *const change, | |||||
const int change_len) { | |||||
char newfile[PATHLEN + 1]; /* new file name */ | |||||
char oldfile[PATHLEN + 1]; /* old file name */ | |||||
char linenum[NUMLEN + 1]; /* file line number */ | |||||
char msg[MSGLEN + 1]; /* message */ | |||||
FILE *script; /* shell script file */ | |||||
/* Return early */ | |||||
bool anymarked = false; /* any line marked */ | |||||
for(int i = 0; i < change_len; i++) { | |||||
if(change[i]) { | |||||
anymarked = true; | anymarked = true; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if(!anymarked){ return false; } | |||||
if(!anymarked) { return false; } | |||||
/* open the temporary file */ | |||||
if((script = myfopen(temp2, "w")) == NULL) { | |||||
/* open the temporary file */ | |||||
if((script = myfopen(temp2, "w")) == NULL) { | |||||
cannotopen(temp2); | cannotopen(temp2); | ||||
return(false); | |||||
} | |||||
return (false); | |||||
} | |||||
/* for each line containing the old text */ | |||||
fprintf(script, "ed - <<\\!\n"); | |||||
*oldfile = '\0'; | |||||
/* for each line containing the old text */ | |||||
fprintf(script, "ed - <<\\!\n"); | |||||
*oldfile = '\0'; | |||||
fseek(refsfound, 0, SEEK_SET); | fseek(refsfound, 0, SEEK_SET); | ||||
for(int i = 0; | |||||
fscanf(refsfound, "%" PATHLEN_STR "s%*s%" NUMLEN_STR "s%*[^\n]", newfile, linenum) == 2; | |||||
++i) | |||||
{ | |||||
for(int i = 0; fscanf(refsfound, | |||||
"%" PATHLEN_STR "s%*s%" NUMLEN_STR "s%*[^\n]", | |||||
newfile, | |||||
linenum) == 2; | |||||
++i) { | |||||
/* see if the line is to be changed */ | /* see if the line is to be changed */ | ||||
if (!change[i]) { break; } | |||||
/* if this is a new file */ | |||||
if (strcmp(newfile, oldfile) != 0) { | |||||
/* make sure it can be changed */ | |||||
if (access(newfile, WRITE) != 0) { | |||||
snprintf(msg, sizeof(msg), "Cannot write to file %s", newfile); | |||||
postmsg(msg); | |||||
goto end; | |||||
} | |||||
/* if there was an old file */ | |||||
if (*oldfile != '\0') { | |||||
fprintf(script, "w\n"); /* save it */ | |||||
if(!change[i]) { break; } | |||||
/* if this is a new file */ | |||||
if(strcmp(newfile, oldfile) != 0) { | |||||
/* make sure it can be changed */ | |||||
if(access(newfile, WRITE) != 0) { | |||||
snprintf(msg, sizeof(msg), "Cannot write to file %s", newfile); | |||||
postmsg(msg); | |||||
goto end; | |||||
} | |||||
/* if there was an old file */ | |||||
if(*oldfile != '\0') { fprintf(script, "w\n"); /* save it */ } | |||||
/* edit the new file */ | |||||
strcpy(oldfile, newfile); | |||||
fprintf(script, "e %s\n", oldfile); | |||||
} | } | ||||
/* edit the new file */ | |||||
strcpy(oldfile, newfile); | |||||
fprintf(script, "e %s\n", oldfile); | |||||
} | |||||
/* output substitute command */ | |||||
fprintf(script, "%ss/", linenum); /* change */ | |||||
for(const char *s = from; *s != '\0'; ++s) { | |||||
/* output substitute command */ | |||||
fprintf(script, "%ss/", linenum); /* change */ | |||||
for(const char *s = from; *s != '\0'; ++s) { | |||||
/* old text */ | /* old text */ | ||||
if (strchr("/\\[.^*", *s) != NULL) { | |||||
putc('\\', script); | |||||
} | |||||
if (caseless == true && isalpha((unsigned char)*s)) { | |||||
if(strchr("/\\[.^*", *s) != NULL) { putc('\\', script); } | |||||
if(caseless == true && isalpha((unsigned char)*s)) { | |||||
putc('[', script); | putc('[', script); | ||||
if(islower((unsigned char)*s)) { | if(islower((unsigned char)*s)) { | ||||
putc(toupper((unsigned char)*s), script); | |||||
putc(*s, script); | |||||
putc(toupper((unsigned char)*s), script); | |||||
putc(*s, script); | |||||
} else { | } else { | ||||
putc(*s, script); | |||||
putc(tolower((unsigned char)*s), script); | |||||
putc(*s, script); | |||||
putc(tolower((unsigned char)*s), script); | |||||
} | } | ||||
putc(']', script); | putc(']', script); | ||||
} else { | } else { | ||||
putc(*s, script); | putc(*s, script); | ||||
} | } | ||||
} | |||||
putc('/', script); /* to */ | |||||
for(const char *s = to; *s != '\0'; ++s) { /* new text */ | |||||
if (strchr("/\\&", *s) != NULL) { | |||||
putc('\\', script); | |||||
} | |||||
} | |||||
putc('/', script); /* to */ | |||||
for(const char *s = to; *s != '\0'; ++s) { /* new text */ | |||||
if(strchr("/\\&", *s) != NULL) { putc('\\', script); } | |||||
putc(*s, script); | putc(*s, script); | ||||
} | |||||
fprintf(script, "/gp\n"); /* and print */ | |||||
} | |||||
fprintf(script, "w\nq\n!\n"); /* write and quit */ | |||||
fflush(script); | |||||
} | |||||
fprintf(script, "/gp\n"); /* and print */ | |||||
} | |||||
fprintf(script, "w\nq\n!\n"); /* write and quit */ | |||||
fflush(script); | |||||
/* edit the files */ | /* edit the files */ | ||||
fprintf(stderr, "Changed lines:\n\r"); | fprintf(stderr, "Changed lines:\n\r"); | ||||
execute("sh", "sh", temp2, NULL); | execute("sh", "sh", temp2, NULL); | ||||
askforchar(); | askforchar(); | ||||
end: | end: | ||||
fclose(script); | |||||
return true; | |||||
fclose(script); | |||||
return true; | |||||
} | } | ||||
int | |||||
handle_input(const int c){ | |||||
int handle_input(const int c) { | |||||
/* - was wating for any input - */ | /* - was wating for any input - */ | ||||
if(do_press_any_key){ | |||||
if(do_press_any_key) { | |||||
do_press_any_key = false; | do_press_any_key = false; | ||||
return 0; | return 0; | ||||
} | } | ||||
/* --- global --- */ | |||||
const int r = global_input(c); | |||||
if(r){ return 0; } | |||||
/* --- mode specific --- */ | |||||
switch(input_mode){ | |||||
/* --- global --- */ | |||||
const int r = global_input(c); | |||||
if(r) { return 0; } | |||||
/* --- mode specific --- */ | |||||
switch(input_mode) { | |||||
case INPUT_NORMAL: | case INPUT_NORMAL: | ||||
if(*current_window == winput){ | |||||
if(*current_window == winput) { | |||||
return interpret(c); | return interpret(c); | ||||
}else if(*current_window == wmode){ | |||||
} else if(*current_window == wmode) { | |||||
return wmode_input(c); | return wmode_input(c); | ||||
}else if(*current_window == wresult){ | |||||
} else if(*current_window == wresult) { | |||||
return wresult_input(c); | return wresult_input(c); | ||||
} | } | ||||
assert("'current_window' dangling."); | assert("'current_window' dangling."); | ||||
@@ -574,5 +541,5 @@ handle_input(const int c){ | |||||
return change_input(c); | return change_input(c); | ||||
} | } | ||||
return 0; | |||||
return 0; | |||||
} | } |
@@ -33,82 +33,82 @@ | |||||
#ifndef CSCOPE_INVLIB_H | #ifndef CSCOPE_INVLIB_H | ||||
#define CSCOPE_INVLIB_H | #define CSCOPE_INVLIB_H | ||||
#include <stdio.h> /* need definition of FILE* */ | |||||
#include <limits.h> /* need definition of CHAR_MAX */ | |||||
#include <stdio.h> /* need definition of FILE* */ | |||||
#include <limits.h> /* need definition of CHAR_MAX */ | |||||
/* inverted index definitions */ | /* inverted index definitions */ | ||||
/* postings temporary file long number coding into characters */ | /* postings temporary file long number coding into characters */ | ||||
#if CHAR_MAX==255 | |||||
# define BASE 223 /* 255 - ' ' */ | |||||
# define PRECISION 4 /* maximum digits after converting a long */ | |||||
#if CHAR_MAX == 255 | |||||
# define BASE 223 /* 255 - ' ' */ | |||||
# define PRECISION 4 /* maximum digits after converting a long */ | |||||
#else | #else | ||||
# if CHAR_MAX==127 /* assume sign-extension of a char when converted to an int */ | |||||
# define BASE 95 /* 127 - ' ' */ | |||||
# define PRECISION 5 /* maximum digits after converting a long */ | |||||
# if CHAR_MAX == 127 /* assume sign-extension of a char when converted to an int */ | |||||
# define BASE 95 /* 127 - ' ' */ | |||||
# define PRECISION 5 /* maximum digits after converting a long */ | |||||
# else | # else | ||||
#error Need a platform with 8 bits in a char value | |||||
# error Need a platform with 8 bits in a char value | |||||
# endif | # endif | ||||
#endif | #endif | ||||
/* inverted index access parameters */ | /* inverted index access parameters */ | ||||
#define INVAVAIL 0 | |||||
#define INVBUSY 1 | |||||
#define INVALONE 2 | |||||
#define INVAVAIL 0 | |||||
#define INVBUSY 1 | |||||
#define INVALONE 2 | |||||
/* boolean set operations */ | /* boolean set operations */ | ||||
#define bool_OR 3 | |||||
#define AND 4 | |||||
#define falseT 5 | |||||
#define REVERSEfalseT 6 | |||||
#define bool_OR 3 | |||||
#define AND 4 | |||||
#define falseT 5 | |||||
#define REVERSEfalseT 6 | |||||
/* note that the entire first block is for parameters */ | /* note that the entire first block is for parameters */ | ||||
typedef struct { | |||||
long version; /* inverted index format version */ | |||||
long filestat; /* file status word */ | |||||
long sizeblk; /* size of logical block in bytes */ | |||||
long startbyte; /* first byte of superfinger */ | |||||
long supsize; /* size of superfinger in bytes */ | |||||
long cntlsize; /* size of max cntl space (should be a multiple of BUFSIZ) */ | |||||
long share; /* flag whether to use shared memory */ | |||||
typedef struct { | |||||
long version; /* inverted index format version */ | |||||
long filestat; /* file status word */ | |||||
long sizeblk; /* size of logical block in bytes */ | |||||
long startbyte; /* first byte of superfinger */ | |||||
long supsize; /* size of superfinger in bytes */ | |||||
long cntlsize; /* size of max cntl space (should be a multiple of BUFSIZ) */ | |||||
long share; /* flag whether to use shared memory */ | |||||
} PARAM; | } PARAM; | ||||
typedef struct { | |||||
FILE *invfile; /* the inverted file ptr */ | |||||
FILE *postfile; /* posting file ptr */ | |||||
PARAM param; /* control parameters for the file */ | |||||
char *iindex; /* ptr to space for superindex */ | |||||
union logicalblk *logblk; /* ptr to space for a logical block */ | |||||
long numblk; /* number of block presently at *logblk */ | |||||
long keypnt; /* number item in present block found */ | |||||
typedef struct { | |||||
FILE *invfile; /* the inverted file ptr */ | |||||
FILE *postfile; /* posting file ptr */ | |||||
PARAM param; /* control parameters for the file */ | |||||
char *iindex; /* ptr to space for superindex */ | |||||
union logicalblk *logblk; /* ptr to space for a logical block */ | |||||
long numblk; /* number of block presently at *logblk */ | |||||
long keypnt; /* number item in present block found */ | |||||
} INVCONTROL; | } INVCONTROL; | ||||
typedef struct { | |||||
short offset; /* offset in this logical block */ | |||||
unsigned char size; /* size of term */ | |||||
unsigned char space; /* number of longs of growth space */ | |||||
long post; /* number of postings for this entry */ | |||||
typedef struct { | |||||
short offset; /* offset in this logical block */ | |||||
unsigned char size; /* size of term */ | |||||
unsigned char space; /* number of longs of growth space */ | |||||
long post; /* number of postings for this entry */ | |||||
} ENTRY; | } ENTRY; | ||||
typedef struct { | |||||
long lineoffset; /* source line database offset */ | |||||
long fcnoffset; /* function name database offset */ | |||||
long fileindex : 24; /* source file name index */ | |||||
long type : 8; /* reference type (mark character) */ | |||||
typedef struct { | |||||
long lineoffset; /* source line database offset */ | |||||
long fcnoffset; /* function name database offset */ | |||||
long fileindex : 24; /* source file name index */ | |||||
long type : 8; /* reference type (mark character) */ | |||||
} POSTING; | } POSTING; | ||||
extern long *srcoffset; /* source file name database offsets */ | |||||
extern int nsrcoffset; /* number of file name database offsets */ | |||||
extern long *srcoffset; /* source file name database offsets */ | |||||
extern int nsrcoffset; /* number of file name database offsets */ | |||||
void boolclear(void); | |||||
POSTING *boolfile(INVCONTROL *invcntl, long *num, int boolarg); | |||||
void invclose(INVCONTROL *invcntl); | |||||
void invdump(INVCONTROL *invcntl, char *term); | |||||
long invfind(INVCONTROL *invcntl, char *searchterm); | |||||
int invforward(INVCONTROL *invcntl); | |||||
int invopen(INVCONTROL *invcntl, char *invname, char *invpost, int status); | |||||
long invmake(char *invname, char *invpost, FILE *infile); | |||||
long invterm(INVCONTROL *invcntl, char *term); | |||||
void boolclear(void); | |||||
POSTING *boolfile(INVCONTROL *invcntl, long *num, int boolarg); | |||||
void invclose(INVCONTROL *invcntl); | |||||
void invdump(INVCONTROL *invcntl, char *term); | |||||
long invfind(INVCONTROL *invcntl, char *searchterm); | |||||
int invforward(INVCONTROL *invcntl); | |||||
int invopen(INVCONTROL *invcntl, char *invname, char *invpost, int status); | |||||
long invmake(char *invname, char *invpost, FILE *infile); | |||||
long invterm(INVCONTROL *invcntl, char *term); | |||||
#endif /* CSCOPE_INVLIB_H */ | #endif /* CSCOPE_INVLIB_H */ |
@@ -12,48 +12,48 @@ | |||||
#define KEY_UNDEF_BASE 0 | #define KEY_UNDEF_BASE 0 | ||||
#ifndef KEY_DOWN | #ifndef KEY_DOWN | ||||
# define KEY_DOWN KEY_UNDEF_BASE-1 | |||||
# define KEY_DOWN KEY_UNDEF_BASE - 1 | |||||
#endif | #endif | ||||
#ifndef KEY_UP | #ifndef KEY_UP | ||||
# define KEY_UP KEY_UNDEF_BASE-2 | |||||
# define KEY_UP KEY_UNDEF_BASE - 2 | |||||
#endif | #endif | ||||
#ifndef KEY_LEFT | #ifndef KEY_LEFT | ||||
# define KEY_LEFT KEY_UNDEF_BASE-3 | |||||
# define KEY_LEFT KEY_UNDEF_BASE - 3 | |||||
#endif | #endif | ||||
#ifndef KEY_RIGHT | #ifndef KEY_RIGHT | ||||
# define KEY_RIGHT KEY_UNDEF_BASE-4 | |||||
# define KEY_RIGHT KEY_UNDEF_BASE - 4 | |||||
#endif | #endif | ||||
#ifndef KEY_HOME | #ifndef KEY_HOME | ||||
# define KEY_HOME _KEY_UNDEF_BASE-5 | |||||
# define KEY_HOME _KEY_UNDEF_BASE - 5 | |||||
#endif | #endif | ||||
#ifndef KEY_LL | #ifndef KEY_LL | ||||
# define KEY_LL KEY_UNDEF_BASE-6 | |||||
# define KEY_LL KEY_UNDEF_BASE - 6 | |||||
#endif | #endif | ||||
#ifndef KEY_PPAGE | #ifndef KEY_PPAGE | ||||
# define KEY_PPAGE KEY_UNDEF_BASE-7 | |||||
# define KEY_PPAGE KEY_UNDEF_BASE - 7 | |||||
#endif | #endif | ||||
#ifndef KEY_NPAGE | #ifndef KEY_NPAGE | ||||
# define KEY_NPAGE KEY_UNDEF_BASE-8 | |||||
# define KEY_NPAGE KEY_UNDEF_BASE - 8 | |||||
#endif | #endif | ||||
#ifndef KEY_ENTER | #ifndef KEY_ENTER | ||||
# define KEY_ENTER KEY_UNDEF_BASE-9 | |||||
# define KEY_ENTER KEY_UNDEF_BASE - 9 | |||||
#endif | #endif | ||||
#ifndef KEY_CLEAR | #ifndef KEY_CLEAR | ||||
# define KEY_CLEAR KEY_UNDEF_BASE-10 | |||||
# define KEY_CLEAR KEY_UNDEF_BASE - 10 | |||||
#endif | #endif | ||||
#ifndef KEY_RESIZE | #ifndef KEY_RESIZE | ||||
# define KEY_RESIZE KEY_UNDEF_BASE-11 | |||||
# define KEY_RESIZE KEY_UNDEF_BASE - 11 | |||||
#endif | #endif | ||||
#ifndef KEY_END | #ifndef KEY_END | ||||
# define KEY_END KEY_UNDEF_BASE-12 | |||||
# define KEY_END KEY_UNDEF_BASE - 12 | |||||
#endif | #endif | ||||
/* Always define these keys */ | /* Always define these keys */ | ||||
#ifndef ESC | #ifndef ESC | ||||
# define ESC '\033' /* escape character */ | |||||
# define ESC '\033' /* escape character */ | |||||
#endif | #endif | ||||
#ifndef DEL | #ifndef DEL | ||||
# define DEL '\177' /* delete character */ | |||||
# define DEL '\177' /* delete character */ | |||||
#endif | #endif | ||||
@@ -33,19 +33,19 @@ | |||||
#ifndef CSCOPE_LIBRARY_H | #ifndef CSCOPE_LIBRARY_H | ||||
#define CSCOPE_LIBRARY_H | #define CSCOPE_LIBRARY_H | ||||
#include <stdio.h> /* need FILE* type def. */ | |||||
#include <stdio.h> /* need FILE* type def. */ | |||||
/* private library */ | /* private library */ | ||||
char *compath(char *pathname); | |||||
char *egrepinit(const char *egreppat); | |||||
char *logdir(char *name); | |||||
const char *basename(const char *path); | |||||
FILE *myfopen(char *path, char *mode); | |||||
char *mygetenv(char *variable, char *deflt); | |||||
int myopen(char *path, int flag, int mode); | |||||
FILE *mypopen(char *cmd, char *mode); | |||||
int mypclose(FILE *ptr); | |||||
FILE *vpfopen(char *filename, char *type); | |||||
void egrepcaseless(int i); | |||||
char *compath(char *pathname); | |||||
char *egrepinit(const char *egreppat); | |||||
char *logdir(char *name); | |||||
const char *basename(const char *path); | |||||
FILE *myfopen(char *path, char *mode); | |||||
char *mygetenv(char *variable, char *deflt); | |||||
int myopen(char *path, int flag, int mode); | |||||
FILE *mypopen(char *cmd, char *mode); | |||||
int mypclose(FILE *ptr); | |||||
FILE *vpfopen(char *filename, char *type); | |||||
void egrepcaseless(int i); | |||||
#endif /* CSCOPE_LIBRARY_H */ | #endif /* CSCOPE_LIBRARY_H */ |
@@ -43,58 +43,50 @@ | |||||
#include <string.h> | #include <string.h> | ||||
#include "global.h" | #include "global.h" | ||||
#define OURBUFSIZ 160 /* renamed: avoid conflict with <stdio.h> */ | |||||
#define OURBUFSIZ 160 /* renamed: avoid conflict with <stdio.h> */ | |||||
static char line[OURBUFSIZ+1]; | |||||
static char line[OURBUFSIZ + 1]; | |||||
/* Internal prototypes: */ | /* Internal prototypes: */ | ||||
static char *nextfield(char *p); | |||||
static char *nextfield(char *p); | |||||
static char * | |||||
nextfield(char *p) | |||||
{ | |||||
while (*p && *p != ':') | |||||
++p; | |||||
if (*p) *p++ = 0; | |||||
return(p); | |||||
static char *nextfield(char *p) { | |||||
while(*p && *p != ':') | |||||
++p; | |||||
if(*p) *p++ = 0; | |||||
return (p); | |||||
} | } | ||||
char * | |||||
logdir(char *name) | |||||
{ | |||||
char *p; | |||||
int i, j; | |||||
int pwf; | |||||
/* attempt to open the password file */ | |||||
if ((pwf = myopen("/etc/passwd", 0, 0)) == -1) | |||||
return(0); | |||||
/* find the matching password entry */ | |||||
do { | |||||
/* get the next line in the password file */ | |||||
i = read(pwf, line, OURBUFSIZ); | |||||
for (j = 0; j < i; j++) | |||||
if (line[j] == '\n') | |||||
break; | |||||
/* return a null pointer if the whole file has been read */ | |||||
if (j >= i) | |||||
return(0); | |||||
line[++j] = 0; /* terminate the line */ | |||||
(void) lseek(pwf, (long) (j - i), 1); /* point at the next line */ | |||||
p = nextfield(line); /* get the logname */ | |||||
} while (*name != *line || /* fast pretest */ | |||||
strcmp(name, line) != 0); | |||||
(void) close(pwf); | |||||
/* skip the intervening fields */ | |||||
p = nextfield(p); | |||||
p = nextfield(p); | |||||
p = nextfield(p); | |||||
p = nextfield(p); | |||||
/* return the login directory */ | |||||
(void) nextfield(p); | |||||
return(p); | |||||
char *logdir(char *name) { | |||||
char *p; | |||||
int i, j; | |||||
int pwf; | |||||
/* attempt to open the password file */ | |||||
if((pwf = myopen("/etc/passwd", 0, 0)) == -1) return (0); | |||||
/* find the matching password entry */ | |||||
do { | |||||
/* get the next line in the password file */ | |||||
i = read(pwf, line, OURBUFSIZ); | |||||
for(j = 0; j < i; j++) | |||||
if(line[j] == '\n') break; | |||||
/* return a null pointer if the whole file has been read */ | |||||
if(j >= i) return (0); | |||||
line[++j] = 0; /* terminate the line */ | |||||
(void)lseek(pwf, (long)(j - i), 1); /* point at the next line */ | |||||
p = nextfield(line); /* get the logname */ | |||||
} while(*name != *line || /* fast pretest */ | |||||
strcmp(name, line) != 0); | |||||
(void)close(pwf); | |||||
/* skip the intervening fields */ | |||||
p = nextfield(p); | |||||
p = nextfield(p); | |||||
p = nextfield(p); | |||||
p = nextfield(p); | |||||
/* return the login directory */ | |||||
(void)nextfield(p); | |||||
return (p); | |||||
} | } |
@@ -39,11 +39,11 @@ | |||||
#include "lookup.h" | #include "lookup.h" | ||||
/* keyword text for fast testing of keywords in the scanner */ | /* keyword text for fast testing of keywords in the scanner */ | ||||
char enumtext[] = "enum"; | |||||
char externtext[] = "extern"; | |||||
char structtext[] = "struct"; | |||||
char typedeftext[] = "typedef"; | |||||
char uniontext[] = "union"; | |||||
char enumtext[] = "enum"; | |||||
char externtext[] = "extern"; | |||||
char structtext[] = "struct"; | |||||
char typedeftext[] = "typedef"; | |||||
char uniontext[] = "union"; | |||||
/* This keyword table is also used for keyword text compression. Keywords | /* This keyword table is also used for keyword text compression. Keywords | ||||
* with an index less than the numeric value of a space are replaced with the | * with an index less than the numeric value of a space are replaced with the | ||||
@@ -51,99 +51,93 @@ char uniontext[] = "union"; | |||||
* without changing the database file version and adding compatibility code | * without changing the database file version and adding compatibility code | ||||
* for old databases. | * for old databases. | ||||
*/ | */ | ||||
struct keystruct keyword[] = { | |||||
{"", '\0', NULL}, /* dummy entry */ | |||||
{"#define", ' ', NULL}, /* must be table entry 1 */ | |||||
{"#include", ' ', NULL}, /* must be table entry 2 */ | |||||
{"break", '\0', NULL}, /* rarely in cross-reference */ | |||||
{"case", ' ', NULL}, | |||||
{"char", ' ', NULL}, | |||||
{"continue", '\0', NULL}, /* rarely in cross-reference */ | |||||
{"default", '\0', NULL}, /* rarely in cross-reference */ | |||||
{"double", ' ', NULL}, | |||||
{"\t", '\0', NULL}, /* must be the table entry 9 */ | |||||
{"\n", '\0', NULL}, /* must be the table entry 10 */ | |||||
{"else", ' ', NULL}, | |||||
{enumtext, ' ', NULL}, | |||||
{externtext, ' ', NULL}, | |||||
{"float", ' ', NULL}, | |||||
{"for", '(', NULL}, | |||||
{"goto", ' ', NULL}, | |||||
{"if", '(', NULL}, | |||||
{"int", ' ', NULL}, | |||||
{"long", ' ', NULL}, | |||||
{"register", ' ', NULL}, | |||||
{"return", '\0', NULL}, | |||||
{"short", ' ', NULL}, | |||||
{"sizeof", '\0', NULL}, | |||||
{"static", ' ', NULL}, | |||||
{structtext, ' ', NULL}, | |||||
{"switch", '(', NULL}, | |||||
{typedeftext, ' ', NULL}, | |||||
{uniontext, ' ', NULL}, | |||||
{"unsigned", ' ', NULL}, | |||||
{"void", ' ', NULL}, | |||||
{"while", '(', NULL}, | |||||
/* these keywords are not compressed */ | |||||
{"do", '\0', NULL}, | |||||
{"auto", ' ', NULL}, | |||||
{"fortran", ' ', NULL}, | |||||
{"const", ' ', NULL}, | |||||
{"signed", ' ', NULL}, | |||||
{"volatile", ' ', NULL}, | |||||
struct keystruct keyword[] = { | |||||
{"", '\0', NULL}, /* dummy entry */ | |||||
{"#define", ' ', NULL}, /* must be table entry 1 */ | |||||
{"#include", ' ', NULL}, /* must be table entry 2 */ | |||||
{"break", '\0', NULL}, /* rarely in cross-reference */ | |||||
{"case", ' ', NULL}, | |||||
{"char", ' ', NULL}, | |||||
{"continue", '\0', NULL}, /* rarely in cross-reference */ | |||||
{"default", '\0', NULL}, /* rarely in cross-reference */ | |||||
{"double", ' ', NULL}, | |||||
{"\t", '\0', NULL}, /* must be the table entry 9 */ | |||||
{"\n", '\0', NULL}, /* must be the table entry 10 */ | |||||
{"else", ' ', NULL}, | |||||
{enumtext, ' ', NULL}, | |||||
{externtext, ' ', NULL}, | |||||
{"float", ' ', NULL}, | |||||
{"for", '(', NULL}, | |||||
{"goto", ' ', NULL}, | |||||
{"if", '(', NULL}, | |||||
{"int", ' ', NULL}, | |||||
{"long", ' ', NULL}, | |||||
{"register", ' ', NULL}, | |||||
{"return", '\0', NULL}, | |||||
{"short", ' ', NULL}, | |||||
{"sizeof", '\0', NULL}, | |||||
{"static", ' ', NULL}, | |||||
{structtext, ' ', NULL}, | |||||
{"switch", '(', NULL}, | |||||
{typedeftext, ' ', NULL}, | |||||
{uniontext, ' ', NULL}, | |||||
{"unsigned", ' ', NULL}, | |||||
{"void", ' ', NULL}, | |||||
{"while", '(', NULL}, | |||||
/* these keywords are not compressed */ | |||||
{"do", '\0', NULL}, | |||||
{"auto", ' ', NULL}, | |||||
{"fortran", ' ', NULL}, | |||||
{"const", ' ', NULL}, | |||||
{"signed", ' ', NULL}, | |||||
{"volatile", ' ', NULL}, | |||||
}; | }; | ||||
#define KEYWORDS (sizeof(keyword) / sizeof(keyword[0])) | |||||
#define KEYWORDS (sizeof(keyword) / sizeof(keyword[0])) | |||||
#define HASHMOD (KEYWORDS * 2 + 1) | |||||
#define HASHMOD (KEYWORDS * 2 + 1) | |||||
static struct keystruct *hashtab[HASHMOD]; /* pointer table */ | |||||
static struct keystruct *hashtab[HASHMOD]; /* pointer table */ | |||||
/* put the keywords into the symbol table */ | /* put the keywords into the symbol table */ | ||||
void | |||||
initsymtab(void) | |||||
{ | |||||
unsigned int i, j; | |||||
struct keystruct *p; | |||||
for (i = 1; i < KEYWORDS; ++i) { | |||||
p = keyword + i; | |||||
j = hash(p->text) % HASHMOD; | |||||
p->next = hashtab[j]; | |||||
hashtab[j] = p; | |||||
} | |||||
void initsymtab(void) { | |||||
unsigned int i, j; | |||||
struct keystruct *p; | |||||
for(i = 1; i < KEYWORDS; ++i) { | |||||
p = keyword + i; | |||||
j = hash(p->text) % HASHMOD; | |||||
p->next = hashtab[j]; | |||||
hashtab[j] = p; | |||||
} | |||||
} | } | ||||
/* see if this identifier is a keyword */ | /* see if this identifier is a keyword */ | ||||
char * | |||||
lookup(char *ident) | |||||
{ | |||||
struct keystruct *p; | |||||
int c; | |||||
/* look up the identifier in the keyword table */ | |||||
for (p = hashtab[hash(ident) % HASHMOD]; p != NULL; p = p->next) { | |||||
if (strequal(ident, p->text)) { | |||||
if (compress == true && (c = p - keyword) < ' ') { | |||||
ident[0] = c; /* compress the keyword */ | |||||
} | |||||
return(p->text); | |||||
} | |||||
} | |||||
/* this is an identifier */ | |||||
return(NULL); | |||||
char *lookup(char *ident) { | |||||
struct keystruct *p; | |||||
int c; | |||||
/* look up the identifier in the keyword table */ | |||||
for(p = hashtab[hash(ident) % HASHMOD]; p != NULL; p = p->next) { | |||||
if(strequal(ident, p->text)) { | |||||
if(compress == true && (c = p - keyword) < ' ') { | |||||
ident[0] = c; /* compress the keyword */ | |||||
} | |||||
return (p->text); | |||||
} | |||||
} | |||||
/* this is an identifier */ | |||||
return (NULL); | |||||
} | } | ||||
/* form hash value for string */ | /* form hash value for string */ | ||||
int | |||||
hash(char *ss) | |||||
{ | |||||
int i; | |||||
unsigned char *s = (unsigned char *)ss; | |||||
for (i = 0; *s != '\0'; ) | |||||
i += *s++; /* += is faster than <<= for cscope */ | |||||
return(i); | |||||
int hash(char *ss) { | |||||
int i; | |||||
unsigned char *s = (unsigned char *)ss; | |||||
for(i = 0; *s != '\0';) | |||||
i += *s++; /* += is faster than <<= for cscope */ | |||||
return (i); | |||||
} | } |
@@ -36,10 +36,10 @@ | |||||
/* declarations for objects defined in lookup.c */ | /* declarations for objects defined in lookup.c */ | ||||
/* keyword text for fast testing of keywords in the scanner */ | /* keyword text for fast testing of keywords in the scanner */ | ||||
extern char enumtext[]; | |||||
extern char externtext[]; | |||||
extern char structtext[]; | |||||
extern char typedeftext[]; | |||||
extern char uniontext[]; | |||||
extern char enumtext[]; | |||||
extern char externtext[]; | |||||
extern char structtext[]; | |||||
extern char typedeftext[]; | |||||
extern char uniontext[]; | |||||
#endif /* CSCOPE_LOOKUP_H */ | #endif /* CSCOPE_LOOKUP_H */ |
@@ -37,439 +37,392 @@ | |||||
extern int LINES; | extern int LINES; | ||||
#define FLDLINE (LINES - FIELDS - 1 - 1) /* first input field line */ | |||||
#define FLDLINE (LINES - FIELDS - 1 - 1) /* first input field line */ | |||||
#include "global.h" | #include "global.h" | ||||
bool mouse = false; /* mouse interface */ | |||||
bool mouse = false; /* mouse interface */ | |||||
#ifdef UNIXPC /* build command requires #ifdef instead of #if */ | |||||
#include <sys/window.h> | |||||
bool unixpcmouse = false; /* running with a mouse on the Unix PC? */ | |||||
static int uw_hs, uw_vs; /* character height and width */ | |||||
#ifdef UNIXPC /* build command requires #ifdef instead of #if */ | |||||
# include <sys/window.h> | |||||
bool unixpcmouse = false; /* running with a mouse on the Unix PC? */ | |||||
static int uw_hs, uw_vs; /* character height and width */ | |||||
#endif | #endif | ||||
typedef struct { /* menu */ | |||||
char *text; | |||||
char *value; | |||||
typedef struct { /* menu */ | |||||
char *text; | |||||
char *value; | |||||
} MENU; | } MENU; | ||||
static MENU mainmenu[] = { /* main menu */ | |||||
{"Send", "##\033s##\r"}, | |||||
{"Repeat", "\031"}, | |||||
{"Edit All", "\05"}, | |||||
{"Rebuild", "\022"}, | |||||
{"Shell", "!"}, | |||||
{"Redraw", "\f"}, | |||||
{"Help", "?"}, | |||||
{"Exit", "\04"}, | |||||
{NULL, NULL} | |||||
static MENU mainmenu[] = { | |||||
/* main menu */ | |||||
{"Send", "##\033s##\r"}, | |||||
{"Repeat", "\031" }, | |||||
{"Edit All", "\05" }, | |||||
{"Rebuild", "\022" }, | |||||
{"Shell", "!" }, | |||||
{"Redraw", "\f" }, | |||||
{"Help", "?" }, | |||||
{"Exit", "\04" }, | |||||
{NULL, NULL } | |||||
}; | }; | ||||
static MENU changemenu[] = { /* change mode menu */ | |||||
{"Mark Screen", "*"}, | |||||
{"Mark All", "a"}, | |||||
{"Change", "\04"}, | |||||
{"No Change", "\033"}, | |||||
{"Shell", "!"}, | |||||
{"Redraw", "\f"}, | |||||
{"Help", "?"}, | |||||
{NULL, NULL} | |||||
static MENU changemenu[] = { | |||||
/* change mode menu */ | |||||
{"Mark Screen", "*" }, | |||||
{"Mark All", "a" }, | |||||
{"Change", "\04" }, | |||||
{"No Change", "\033"}, | |||||
{"Shell", "!" }, | |||||
{"Redraw", "\f" }, | |||||
{"Help", "?" }, | |||||
{NULL, NULL } | |||||
}; | }; | ||||
static MENU *loaded; /* menu loaded */ | |||||
static bool emacsviterm = false; /* terminal type */ | |||||
static MENU *loaded; /* menu loaded */ | |||||
static bool emacsviterm = false; /* terminal type */ | |||||
static void loadmenu(MENU *menu); | |||||
static int getcoordinate(void); | |||||
static int getpercent(void); | |||||
static void loadmenu(MENU *menu); | |||||
static int getcoordinate(void); | |||||
static int getpercent(void); | |||||
/* see if there is a mouse interface */ | /* see if there is a mouse interface */ | ||||
void | |||||
mouseinit(void) | |||||
{ | |||||
char *term; | |||||
/* see if this is emacsterm or viterm */ | |||||
term = mygetenv("TERM", ""); | |||||
if (strcmp(term, "emacsterm") == 0 || | |||||
strcmp(term, "viterm") == 0) { | |||||
emacsviterm = true; | |||||
mouse = true; | |||||
} | |||||
/* the MOUSE enviroment variable is for 5620 terminal programs that have | |||||
mouse support but the TERM environment variable is the same as a | |||||
terminal without a mouse, such as myx */ | |||||
else if (strcmp(mygetenv("MOUSE", ""), "myx") == 0) { | |||||
mouse = true; | |||||
} | |||||
void mouseinit(void) { | |||||
char *term; | |||||
/* see if this is emacsterm or viterm */ | |||||
term = mygetenv("TERM", ""); | |||||
if(strcmp(term, "emacsterm") == 0 || strcmp(term, "viterm") == 0) { | |||||
emacsviterm = true; | |||||
mouse = true; | |||||
} | |||||
/* the MOUSE enviroment variable is for 5620 terminal programs that have | |||||
mouse support but the TERM environment variable is the same as a | |||||
terminal without a mouse, such as myx */ | |||||
else if(strcmp(mygetenv("MOUSE", ""), "myx") == 0) { | |||||
mouse = true; | |||||
} | |||||
#if UNIXPC | #if UNIXPC | ||||
else if (strcmp(term,"s4") == 0 || | |||||
strcmp(term,"s120") == 0 || | |||||
strcmp(term,"s90") == 0) { | |||||
int retval; | |||||
struct uwdata uwd; /* Window data structure */ | |||||
struct umdata umd; /* Mouse data structure */ | |||||
/* Ask for character size info */ | |||||
retval = ioctl(1,WIOCGETD,&uwd); | |||||
if(retval || uwd.uw_hs <= 0 || uwd.uw_vs <= 0) { | |||||
/************************************************** | |||||
* something wrong with the kernel, so fake it... | |||||
**************************************************/ | |||||
if(!strcmp(term,"s4")) { | |||||
uw_hs = 9; | |||||
uw_vs = 12; | |||||
} | |||||
else { | |||||
uw_hs = 6; | |||||
uw_vs = 10; | |||||
} | |||||
} | |||||
else { | |||||
/* Kernel is working and knows about this font */ | |||||
uw_hs = uwd.uw_hs; | |||||
uw_vs = uwd.uw_vs; | |||||
} | |||||
/************************************************** | |||||
* Now turn on mouse reporting so we can actually | |||||
* make use of all this stuff. | |||||
**************************************************/ | |||||
if((retval = ioctl(1,WIOCGETMOUSE,&umd)) != -1) { | |||||
umd.um_flags= MSDOWN+MSUP; | |||||
ioctl(1,WIOCSETMOUSE,&umd); | |||||
} | |||||
unixpcmouse = true; | |||||
} | |||||
else if(strcmp(term, "s4") == 0 || strcmp(term, "s120") == 0 || | |||||
strcmp(term, "s90") == 0) { | |||||
int retval; | |||||
struct uwdata uwd; /* Window data structure */ | |||||
struct umdata umd; /* Mouse data structure */ | |||||
/* Ask for character size info */ | |||||
retval = ioctl(1, WIOCGETD, &uwd); | |||||
if(retval || uwd.uw_hs <= 0 || uwd.uw_vs <= 0) { | |||||
/************************************************** | |||||
* something wrong with the kernel, so fake it... | |||||
**************************************************/ | |||||
if(!strcmp(term, "s4")) { | |||||
uw_hs = 9; | |||||
uw_vs = 12; | |||||
} else { | |||||
uw_hs = 6; | |||||
uw_vs = 10; | |||||
} | |||||
} else { | |||||
/* Kernel is working and knows about this font */ | |||||
uw_hs = uwd.uw_hs; | |||||
uw_vs = uwd.uw_vs; | |||||
} | |||||
/************************************************** | |||||
* Now turn on mouse reporting so we can actually | |||||
* make use of all this stuff. | |||||
**************************************************/ | |||||
if((retval = ioctl(1, WIOCGETMOUSE, &umd)) != -1) { | |||||
umd.um_flags = MSDOWN + MSUP; | |||||
ioctl(1, WIOCSETMOUSE, &umd); | |||||
} | |||||
unixpcmouse = true; | |||||
} | |||||
#endif | #endif | ||||
if (mouse == true) { | |||||
loadmenu(mainmenu); | |||||
} | |||||
if(mouse == true) { loadmenu(mainmenu); } | |||||
} | } | ||||
/* load the correct mouse menu */ | /* load the correct mouse menu */ | ||||
void | |||||
mousemenu(void) | |||||
{ | |||||
if (mouse == true) { | |||||
if (input_mode == INPUT_CHANGE) { | |||||
loadmenu(changemenu); | |||||
} | |||||
else { | |||||
loadmenu(mainmenu); | |||||
} | |||||
} | |||||
void mousemenu(void) { | |||||
if(mouse == true) { | |||||
if(input_mode == INPUT_CHANGE) { | |||||
loadmenu(changemenu); | |||||
} else { | |||||
loadmenu(mainmenu); | |||||
} | |||||
} | |||||
} | } | ||||
/* download a menu */ | /* download a menu */ | ||||
static void | |||||
loadmenu(MENU *menu) | |||||
{ | |||||
int i; | |||||
if (emacsviterm == true) { | |||||
mousereinit(); | |||||
(void) printf("\033V1"); /* display the scrollbar */ | |||||
(void) printf("\033M0@%s@%s@", menu[0].text, menu[0].value); | |||||
for (i = 1; menu[i].text != NULL; ++i) { | |||||
(void) printf("\033M@%s@%s@", menu[i].text, menu[i].value); | |||||
} | |||||
} | |||||
else { /* myx */ | |||||
int len; | |||||
mousecleanup(); | |||||
(void) printf("\033[6;1X\033[9;1X"); | |||||
for (i = 0; menu[i].text != NULL; ++i) { | |||||
len = strlen(menu[i].text); | |||||
(void) printf("\033[%d;%dx%s%s", len, | |||||
(int) (len + strlen(menu[i].value)), | |||||
menu[i].text, menu[i].value); | |||||
} | |||||
loaded = menu; | |||||
} | |||||
(void) fflush(stdout); | |||||
static void loadmenu(MENU *menu) { | |||||
int i; | |||||
if(emacsviterm == true) { | |||||
mousereinit(); | |||||
(void)printf("\033V1"); /* display the scrollbar */ | |||||
(void)printf("\033M0@%s@%s@", menu[0].text, menu[0].value); | |||||
for(i = 1; menu[i].text != NULL; ++i) { | |||||
(void)printf("\033M@%s@%s@", menu[i].text, menu[i].value); | |||||
} | |||||
} else { /* myx */ | |||||
int len; | |||||
mousecleanup(); | |||||
(void)printf("\033[6;1X\033[9;1X"); | |||||
for(i = 0; menu[i].text != NULL; ++i) { | |||||
len = strlen(menu[i].text); | |||||
(void)printf("\033[%d;%dx%s%s", | |||||
len, | |||||
(int)(len + strlen(menu[i].value)), | |||||
menu[i].text, | |||||
menu[i].value); | |||||
} | |||||
loaded = menu; | |||||
} | |||||
(void)fflush(stdout); | |||||
} | } | ||||
/* reinitialize the mouse in case curses changed the attributes */ | /* reinitialize the mouse in case curses changed the attributes */ | ||||
void | |||||
mousereinit(void) | |||||
{ | |||||
if (emacsviterm == true) { | |||||
void mousereinit(void) { | |||||
if(emacsviterm == true) { | |||||
/* enable the mouse click and sweep coordinate control sequence */ | |||||
/* and switch to menu 2 */ | |||||
(void) printf("\033{2\033#2"); | |||||
(void) fflush(stdout); | |||||
} | |||||
/* enable the mouse click and sweep coordinate control sequence */ | |||||
/* and switch to menu 2 */ | |||||
(void)printf("\033{2\033#2"); | |||||
(void)fflush(stdout); | |||||
} | |||||
} | } | ||||
/* restore the mouse attributes */ | /* restore the mouse attributes */ | ||||
void | |||||
mousecleanup(void) | |||||
{ | |||||
int i; | |||||
void mousecleanup(void) { | |||||
int i; | |||||
if (loaded != NULL) { /* only true for myx */ | |||||
if(loaded != NULL) { /* only true for myx */ | |||||
/* remove the mouse menu */ | |||||
(void) printf("\033[6;0X\033[9;0X"); | |||||
for (i = 0; loaded[i].text != NULL; ++i) { | |||||
(void) printf("\033[0;0x"); | |||||
} | |||||
loaded = NULL; | |||||
} | |||||
/* remove the mouse menu */ | |||||
(void)printf("\033[6;0X\033[9;0X"); | |||||
for(i = 0; loaded[i].text != NULL; ++i) { | |||||
(void)printf("\033[0;0x"); | |||||
} | |||||
loaded = NULL; | |||||
} | |||||
} | } | ||||
/* draw the scrollbar */ | /* draw the scrollbar */ | ||||
void | |||||
drawscrollbar(int top, int bot) | |||||
{ | |||||
int p1, p2; | |||||
if (emacsviterm == true) { | |||||
if (bot > top) { | |||||
p1 = 16 + (top - 1) * 100 / totallines; | |||||
p2 = 16 + (bot - 1) * 100 / totallines; | |||||
if (p2 > 116) { | |||||
p2 = 116; | |||||
} | |||||
if (p1 < 16) { | |||||
p1 = 16; | |||||
} | |||||
/* don't send ^S or ^Q because it will hang a layer using cu(1) */ | |||||
if (p1 == ctrl('Q') || p1 == ctrl('S')) { | |||||
++p1; | |||||
} | |||||
if (p2 == ctrl('Q') || p2 == ctrl('S')) { | |||||
++p2; | |||||
} | |||||
} | |||||
else { | |||||
p1 = p2 = 16; | |||||
} | |||||
(void) printf("\033W%c%c", p1, p2); | |||||
} | |||||
void drawscrollbar(int top, int bot) { | |||||
int p1, p2; | |||||
if(emacsviterm == true) { | |||||
if(bot > top) { | |||||
p1 = 16 + (top - 1) * 100 / totallines; | |||||
p2 = 16 + (bot - 1) * 100 / totallines; | |||||
if(p2 > 116) { p2 = 116; } | |||||
if(p1 < 16) { p1 = 16; } | |||||
/* don't send ^S or ^Q because it will hang a layer using cu(1) */ | |||||
if(p1 == ctrl('Q') || p1 == ctrl('S')) { ++p1; } | |||||
if(p2 == ctrl('Q') || p2 == ctrl('S')) { ++p2; } | |||||
} else { | |||||
p1 = p2 = 16; | |||||
} | |||||
(void)printf("\033W%c%c", p1, p2); | |||||
} | |||||
} | } | ||||
/* get the mouse information */ | /* get the mouse information */ | ||||
MOUSE * | |||||
getmouseaction(char leading_char) | |||||
{ | |||||
static MOUSE m; | |||||
MOUSE *getmouseaction(char leading_char) { | |||||
static MOUSE m; | |||||
#if UNIXPC | #if UNIXPC | ||||
if(unixpcmouse == true && leading_char == ESC) { | |||||
/* Called if cscope received an ESC character. See if it is | |||||
* a mouse report and if so, decipher it. A mouse report | |||||
* looks like: "<ESC>[?xx;yy;b;rM" | |||||
*/ | |||||
int x = 0, y = 0, button = 0, reason = 0; | |||||
int i; | |||||
/* Get a mouse report. The form is: XX;YY;B;RM where | |||||
* XX is 1,2, or 3 decimal digits with the X pixel position. | |||||
* Similarly for YY. B is a single decimal digit with the | |||||
* button number (4 for one, 2 for two, and 1 for three). | |||||
* R is the reason for the mouse report. | |||||
* | |||||
* In general, the input is read until the mouse report has | |||||
* been completely read in or we have discovered that this | |||||
* escape sequence is falseT a mouse report. In the latter case | |||||
* return the last character read to the input stream with | |||||
* myungetch(). | |||||
*/ | |||||
/* Check for "[?" being next 2 chars */ | |||||
if(((i = getch()) != '[') || ((i = getch()) != '?')) { | |||||
myungetch(i); | |||||
return(NULL); | |||||
} | |||||
/* Grab the X position (in pixels) */ | |||||
while(isdigit(i = getch())) { | |||||
x = (x*10) + (i - '0'); | |||||
} | |||||
if(i != ';') { | |||||
myungetch(i); | |||||
return(NULL); /* not a mouse report after all */ | |||||
} | |||||
/* Grab the Y position (in pixels) */ | |||||
while(isdigit(i = getch())) { | |||||
y = (y*10) + (i - '0'); | |||||
} | |||||
if(i != ';') { | |||||
myungetch(i); | |||||
return(NULL); | |||||
} | |||||
/* Get which button */ | |||||
if((button = getch()) > '4') { | |||||
myungetch(button); | |||||
return(NULL); | |||||
} | |||||
if((i = getch()) != ';') { | |||||
myungetch(i); | |||||
return(NULL); | |||||
} | |||||
/* Get the reason for this mouse report */ | |||||
if((reason = getch()) > '8') { | |||||
myungetch(reason); | |||||
return(NULL); | |||||
} | |||||
/* sequence should terminate with an 'M' */ | |||||
if((i = getch()) != 'M') { | |||||
myungetch(i); | |||||
return(NULL); | |||||
} | |||||
/* OK. We get a mouse report whenever a button is depressed | |||||
* or released. Let's ignore the report whenever the button | |||||
* is depressed until when I am ready to implement sweeping. | |||||
*/ | |||||
if(reason != '2') { | |||||
return(NULL); /* '2' means button is released */ | |||||
} | |||||
/************************************************************ | |||||
* Always indicate button 1 irregardless of which button was | |||||
* really pushed. | |||||
************************************************************/ | |||||
m.button = 1; | |||||
/************************************************************ | |||||
* Convert pixel coordinates to line and column coords. | |||||
* The height and width are obtained using an ioctl() call | |||||
* in mouseinit(). This assumes that variable width chars | |||||
* are not being used ('though it would probably work anyway). | |||||
************************************************************/ | |||||
m.x1 = x/uw_hs; /* pixel/horizontal_spacing */ | |||||
m.y1 = y/uw_vs; /* pixel/vertical_spacing */ | |||||
/* "null" out the other fields */ | |||||
m.percent = m.x2 = m.y2 = -1; | |||||
} | |||||
else | |||||
#endif /* not UNIXPC */ | |||||
if (mouse == true && leading_char == ctrl('X')) { | |||||
switch (getch()) { | |||||
case ctrl('_'): /* click */ | |||||
if ((m.button = getch()) == '0') { /* if scrollbar */ | |||||
m.percent = getpercent(); | |||||
} | |||||
else { | |||||
m.x1 = getcoordinate(); | |||||
m.y1 = getcoordinate(); | |||||
m.x2 = m.y2 = -1; | |||||
} | |||||
break; | |||||
case ctrl(']'): /* sweep */ | |||||
m.button = getch(); | |||||
m.x1 = getcoordinate(); | |||||
m.y1 = getcoordinate(); | |||||
m.x2 = getcoordinate(); | |||||
m.y2 = getcoordinate(); | |||||
break; | |||||
default: | |||||
return(NULL); | |||||
} | |||||
} | |||||
else return(NULL); | |||||
return(&m); | |||||
if(unixpcmouse == true && leading_char == ESC) { | |||||
/* Called if cscope received an ESC character. See if it is | |||||
* a mouse report and if so, decipher it. A mouse report | |||||
* looks like: "<ESC>[?xx;yy;b;rM" | |||||
*/ | |||||
int x = 0, y = 0, button = 0, reason = 0; | |||||
int i; | |||||
/* Get a mouse report. The form is: XX;YY;B;RM where | |||||
* XX is 1,2, or 3 decimal digits with the X pixel position. | |||||
* Similarly for YY. B is a single decimal digit with the | |||||
* button number (4 for one, 2 for two, and 1 for three). | |||||
* R is the reason for the mouse report. | |||||
* | |||||
* In general, the input is read until the mouse report has | |||||
* been completely read in or we have discovered that this | |||||
* escape sequence is falseT a mouse report. In the latter case | |||||
* return the last character read to the input stream with | |||||
* myungetch(). | |||||
*/ | |||||
/* Check for "[?" being next 2 chars */ | |||||
if(((i = getch()) != '[') || ((i = getch()) != '?')) { | |||||
myungetch(i); | |||||
return (NULL); | |||||
} | |||||
/* Grab the X position (in pixels) */ | |||||
while(isdigit(i = getch())) { | |||||
x = (x * 10) + (i - '0'); | |||||
} | |||||
if(i != ';') { | |||||
myungetch(i); | |||||
return (NULL); /* not a mouse report after all */ | |||||
} | |||||
/* Grab the Y position (in pixels) */ | |||||
while(isdigit(i = getch())) { | |||||
y = (y * 10) + (i - '0'); | |||||
} | |||||
if(i != ';') { | |||||
myungetch(i); | |||||
return (NULL); | |||||
} | |||||
/* Get which button */ | |||||
if((button = getch()) > '4') { | |||||
myungetch(button); | |||||
return (NULL); | |||||
} | |||||
if((i = getch()) != ';') { | |||||
myungetch(i); | |||||
return (NULL); | |||||
} | |||||
/* Get the reason for this mouse report */ | |||||
if((reason = getch()) > '8') { | |||||
myungetch(reason); | |||||
return (NULL); | |||||
} | |||||
/* sequence should terminate with an 'M' */ | |||||
if((i = getch()) != 'M') { | |||||
myungetch(i); | |||||
return (NULL); | |||||
} | |||||
/* OK. We get a mouse report whenever a button is depressed | |||||
* or released. Let's ignore the report whenever the button | |||||
* is depressed until when I am ready to implement sweeping. | |||||
*/ | |||||
if(reason != '2') { return (NULL); /* '2' means button is released */ } | |||||
/************************************************************ | |||||
* Always indicate button 1 irregardless of which button was | |||||
* really pushed. | |||||
************************************************************/ | |||||
m.button = 1; | |||||
/************************************************************ | |||||
* Convert pixel coordinates to line and column coords. | |||||
* The height and width are obtained using an ioctl() call | |||||
* in mouseinit(). This assumes that variable width chars | |||||
* are not being used ('though it would probably work anyway). | |||||
************************************************************/ | |||||
m.x1 = x / uw_hs; /* pixel/horizontal_spacing */ | |||||
m.y1 = y / uw_vs; /* pixel/vertical_spacing */ | |||||
/* "null" out the other fields */ | |||||
m.percent = m.x2 = m.y2 = -1; | |||||
} else | |||||
#endif /* not UNIXPC */ | |||||
if(mouse == true && leading_char == ctrl('X')) { | |||||
switch(getch()) { | |||||
case ctrl('_'): /* click */ | |||||
if((m.button = getch()) == '0') { /* if scrollbar */ | |||||
m.percent = getpercent(); | |||||
} else { | |||||
m.x1 = getcoordinate(); | |||||
m.y1 = getcoordinate(); | |||||
m.x2 = m.y2 = -1; | |||||
} | |||||
break; | |||||
case ctrl(']'): /* sweep */ | |||||
m.button = getch(); | |||||
m.x1 = getcoordinate(); | |||||
m.y1 = getcoordinate(); | |||||
m.x2 = getcoordinate(); | |||||
m.y2 = getcoordinate(); | |||||
break; | |||||
default: | |||||
return (NULL); | |||||
} | |||||
} else | |||||
return (NULL); | |||||
return (&m); | |||||
} | } | ||||
/* get a row or column coordinate from a mouse button click or sweep */ | /* get a row or column coordinate from a mouse button click or sweep */ | ||||
static int | |||||
getcoordinate(void) | |||||
{ | |||||
int c, next; | |||||
c = getch(); | |||||
next = 0; | |||||
if (c == ctrl('A')) { | |||||
next = 95; | |||||
c = getch(); | |||||
} | |||||
if (c < ' ') { | |||||
return (0); | |||||
} | |||||
return (next + c - ' '); | |||||
static int getcoordinate(void) { | |||||
int c, next; | |||||
c = getch(); | |||||
next = 0; | |||||
if(c == ctrl('A')) { | |||||
next = 95; | |||||
c = getch(); | |||||
} | |||||
if(c < ' ') { return (0); } | |||||
return (next + c - ' '); | |||||
} | } | ||||
/* get a percentage */ | /* get a percentage */ | ||||
static int | |||||
getpercent(void) | |||||
{ | |||||
int c; | |||||
c = getch(); | |||||
if (c < 16) { | |||||
return(0); | |||||
} | |||||
if (c > 120) { | |||||
return(100); | |||||
} | |||||
return(c - 16); | |||||
static int getpercent(void) { | |||||
int c; | |||||
c = getch(); | |||||
if(c < 16) { return (0); } | |||||
if(c > 120) { return (100); } | |||||
return (c - 16); | |||||
} | } | ||||
int process_mouse(){ | |||||
int i; | |||||
MOUSE* p; | |||||
if ((p = getmouseaction(DUMMYCHAR)) == NULL) { | |||||
return(false); /* unknown control sequence */ | |||||
} | |||||
/* if the button number is a scrollbar tag */ | |||||
if (p->button == '0') { | |||||
//scrollbar(p); // XXX | |||||
return(false); | |||||
} | |||||
/* ignore a sweep */ | |||||
if (p->x2 >= 0) { | |||||
return(false); | |||||
} | |||||
/* if this is a line selection */ | |||||
if (p->y1 > FLDLINE) { | |||||
/* find the selected line */ | |||||
/* note: the selection is forced into range */ | |||||
for (i = disprefs - 1; i > 0; --i) { | |||||
if (p->y1 >= displine[i]) { | |||||
return(false); | |||||
} | |||||
} | |||||
/* display it in the file with the editor */ | |||||
editref(i); | |||||
} else { /* this is an input field selection */ | |||||
field = p->y1 - FLDLINE; | |||||
/* force it into range */ | |||||
if (field >= FIELDS) { | |||||
field = FIELDS - 1; | |||||
} | |||||
resetcmd(); | |||||
return(false); | |||||
} | |||||
int process_mouse() { | |||||
int i; | |||||
MOUSE *p; | |||||
if((p = getmouseaction(DUMMYCHAR)) == NULL) { | |||||
return (false); /* unknown control sequence */ | |||||
} | |||||
/* if the button number is a scrollbar tag */ | |||||
if(p->button == '0') { | |||||
// scrollbar(p); // XXX | |||||
return (false); | |||||
} | |||||
/* ignore a sweep */ | |||||
if(p->x2 >= 0) { return (false); } | |||||
/* if this is a line selection */ | |||||
if(p->y1 > FLDLINE) { | |||||
/* find the selected line */ | |||||
/* note: the selection is forced into range */ | |||||
for(i = disprefs - 1; i > 0; --i) { | |||||
if(p->y1 >= displine[i]) { return (false); } | |||||
} | |||||
/* display it in the file with the editor */ | |||||
editref(i); | |||||
} else { /* this is an input field selection */ | |||||
field = p->y1 - FLDLINE; | |||||
/* force it into range */ | |||||
if(field >= FIELDS) { field = FIELDS - 1; } | |||||
resetcmd(); | |||||
return (false); | |||||
} | |||||
return false; | return false; | ||||
} | } |
@@ -36,14 +36,10 @@ | |||||
/* return the non-null environment value or the default argument */ | /* return the non-null environment value or the default argument */ | ||||
char * | |||||
mygetenv(char *variable, char *deflt) | |||||
{ | |||||
char *value; | |||||
value = getenv(variable); | |||||
if (value == NULL || *value == '\0') { | |||||
return(deflt); | |||||
} | |||||
return(value); | |||||
char *mygetenv(char *variable, char *deflt) { | |||||
char *value; | |||||
value = getenv(variable); | |||||
if(value == NULL || *value == '\0') { return (deflt); } | |||||
return (value); | |||||
} | } |
@@ -35,11 +35,11 @@ | |||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/wait.h> | #include <sys/wait.h> | ||||
#include "global.h" /* pid_t, shell, and basename() */ | |||||
#include "global.h" /* pid_t, shell, and basename() */ | |||||
#define tst(a,b) (*mode == 'r'? (b) : (a)) | |||||
#define RDR 0 | |||||
#define WTR 1 | |||||
#define tst(a, b) (*mode == 'r' ? (b) : (a)) | |||||
#define RDR 0 | |||||
#define WTR 1 | |||||
/* HBB 20010312: make this a bit safer --- don't blindly assume it's 1 */ | /* HBB 20010312: make this a bit safer --- don't blindly assume it's 1 */ | ||||
#ifdef FD_CLOEXEC | #ifdef FD_CLOEXEC | ||||
@@ -49,132 +49,112 @@ | |||||
#endif | #endif | ||||
#ifdef HAVE_IO_H | #ifdef HAVE_IO_H | ||||
# include <io.h> /* for setmode() */ | |||||
# include <io.h> /* for setmode() */ | |||||
#endif | #endif | ||||
static pid_t popen_pid[20]; | static pid_t popen_pid[20]; | ||||
static void (*tstat)(int); | static void (*tstat)(int); | ||||
int | |||||
myopen(char *path, int flag, int mode) | |||||
{ | |||||
/* opens a file descriptor and then sets close-on-exec for the file */ | |||||
int fd; | |||||
int myopen(char *path, int flag, int mode) { | |||||
/* opens a file descriptor and then sets close-on-exec for the file */ | |||||
int fd; | |||||
/* If file is not explicitly in Binary mode, make | |||||
* sure we override silly Cygwin behaviour of automatic binary | |||||
* mode for files in "binary mounted" paths */ | |||||
/* If file is not explicitly in Binary mode, make | |||||
* sure we override silly Cygwin behaviour of automatic binary | |||||
* mode for files in "binary mounted" paths */ | |||||
#if O_BINARY != O_TEXT | #if O_BINARY != O_TEXT | ||||
if (! (flag | O_BINARY)) | |||||
flag |= O_TEXT; | |||||
if(!(flag | O_BINARY)) flag |= O_TEXT; | |||||
#endif | #endif | ||||
if(mode) | |||||
fd = open(path, flag, mode); | |||||
else | |||||
fd = open(path, flag); | |||||
if(fd != -1 && (fcntl(fd, F_SETFD, CLOSE_ON_EXEC) != -1)) | |||||
return(fd); | |||||
else | |||||
{ | |||||
/* Ensure that if the fcntl fails and fd is valid, then | |||||
the file is closed properly. In general this should | |||||
not happen. */ | |||||
if (fd != -1) | |||||
{ | |||||
close (fd); | |||||
} | |||||
return(-1); | |||||
} | |||||
if(mode) | |||||
fd = open(path, flag, mode); | |||||
else | |||||
fd = open(path, flag); | |||||
if(fd != -1 && (fcntl(fd, F_SETFD, CLOSE_ON_EXEC) != -1)) | |||||
return (fd); | |||||
else { | |||||
/* Ensure that if the fcntl fails and fd is valid, then | |||||
the file is closed properly. In general this should | |||||
not happen. */ | |||||
if(fd != -1) { close(fd); } | |||||
return (-1); | |||||
} | |||||
} | } | ||||
FILE * | |||||
myfopen(char *path, char *mode) | |||||
{ | |||||
/* opens a file pointer and then sets close-on-exec for the file */ | |||||
FILE *fp; | |||||
FILE *myfopen(char *path, char *mode) { | |||||
/* opens a file pointer and then sets close-on-exec for the file */ | |||||
FILE *fp; | |||||
fp = fopen(path, mode); | |||||
fp = fopen(path, mode); | |||||
#ifdef SETMODE | #ifdef SETMODE | ||||
if (fp && ! strchr(mode, 'b')) { | |||||
SETMODE(fileno(fp), O_TEXT); | |||||
} | |||||
if(fp && !strchr(mode, 'b')) { SETMODE(fileno(fp), O_TEXT); } | |||||
#endif /* SETMODE */ | #endif /* SETMODE */ | ||||
if(fp && (fcntl(fileno(fp), F_SETFD, CLOSE_ON_EXEC) != -1)) | |||||
return(fp); | |||||
if(fp && (fcntl(fileno(fp), F_SETFD, CLOSE_ON_EXEC) != -1)) | |||||
return (fp); | |||||
else { | |||||
if (fp) | |||||
fclose(fp); | |||||
return(NULL); | |||||
} | |||||
else { | |||||
if(fp) fclose(fp); | |||||
return (NULL); | |||||
} | |||||
} | } | ||||
FILE * | |||||
mypopen(char *cmd, char *mode) | |||||
{ | |||||
int p[2]; | |||||
pid_t *poptr; | |||||
int myside, yourside; | |||||
pid_t pid; | |||||
if(pipe(p) < 0) | |||||
return(NULL); | |||||
myside = tst(p[WTR], p[RDR]); | |||||
yourside = tst(p[RDR], p[WTR]); | |||||
if((pid = fork()) == 0) { | |||||
/* myside and yourside reverse roles in child */ | |||||
int stdio; | |||||
/* close all pipes from other popen's */ | |||||
for (poptr = popen_pid; poptr < popen_pid+20; poptr++) { | |||||
if(*poptr) | |||||
(void) close(poptr - popen_pid); | |||||
} | |||||
stdio = tst(0, 1); | |||||
close(myside); | |||||
close(stdio); | |||||
fcntl(yourside, F_DUPFD, stdio); | |||||
close(yourside); | |||||
execlp(shell, basename(shell), "-c", cmd, (void *)0); | |||||
_exit(1); | |||||
} else if (pid > 0) | |||||
tstat = signal(SIGTSTP, SIG_DFL); | |||||
if(pid == -1) | |||||
return(NULL); | |||||
popen_pid[myside] = pid; | |||||
(void) close(yourside); | |||||
return(fdopen(myside, mode)); | |||||
FILE *mypopen(char *cmd, char *mode) { | |||||
int p[2]; | |||||
pid_t *poptr; | |||||
int myside, yourside; | |||||
pid_t pid; | |||||
if(pipe(p) < 0) return (NULL); | |||||
myside = tst(p[WTR], p[RDR]); | |||||
yourside = tst(p[RDR], p[WTR]); | |||||
if((pid = fork()) == 0) { | |||||
/* myside and yourside reverse roles in child */ | |||||
int stdio; | |||||
/* close all pipes from other popen's */ | |||||
for(poptr = popen_pid; poptr < popen_pid + 20; poptr++) { | |||||
if(*poptr) (void)close(poptr - popen_pid); | |||||
} | |||||
stdio = tst(0, 1); | |||||
close(myside); | |||||
close(stdio); | |||||
fcntl(yourside, F_DUPFD, stdio); | |||||
close(yourside); | |||||
execlp(shell, basename(shell), "-c", cmd, (void *)0); | |||||
_exit(1); | |||||
} else if(pid > 0) | |||||
tstat = signal(SIGTSTP, SIG_DFL); | |||||
if(pid == -1) return (NULL); | |||||
popen_pid[myside] = pid; | |||||
(void)close(yourside); | |||||
return (fdopen(myside, mode)); | |||||
} | } | ||||
/* HBB 20010705: renamed from 'pclose', which would collide with | /* HBB 20010705: renamed from 'pclose', which would collide with | ||||
* system-supplied function of same name */ | * system-supplied function of same name */ | ||||
int | |||||
mypclose(FILE *ptr) | |||||
{ | |||||
int f; | |||||
pid_t r; | |||||
int status = -1; | |||||
sighandler_t hstat, istat, qstat; | |||||
f = fileno(ptr); | |||||
(void) fclose(ptr); | |||||
istat = signal(SIGINT, SIG_IGN); | |||||
qstat = signal(SIGQUIT, SIG_IGN); | |||||
hstat = signal(SIGHUP, SIG_IGN); | |||||
while((r = wait(&status)) != popen_pid[f] && r != -1) | |||||
; /* nothing */ | |||||
if(r == -1) | |||||
status = -1; | |||||
(void) signal(SIGINT, istat); | |||||
(void) signal(SIGQUIT, qstat); | |||||
(void) signal(SIGHUP, hstat); | |||||
(void) signal(SIGTSTP, tstat); | |||||
/* mark this pipe closed */ | |||||
popen_pid[f] = 0; | |||||
return(status); | |||||
int mypclose(FILE *ptr) { | |||||
int f; | |||||
pid_t r; | |||||
int status = -1; | |||||
sighandler_t hstat, istat, qstat; | |||||
f = fileno(ptr); | |||||
(void)fclose(ptr); | |||||
istat = signal(SIGINT, SIG_IGN); | |||||
qstat = signal(SIGQUIT, SIG_IGN); | |||||
hstat = signal(SIGHUP, SIG_IGN); | |||||
while((r = wait(&status)) != popen_pid[f] && r != -1) | |||||
; /* nothing */ | |||||
if(r == -1) status = -1; | |||||
(void)signal(SIGINT, istat); | |||||
(void)signal(SIGQUIT, qstat); | |||||
(void)signal(SIGHUP, hstat); | |||||
(void)signal(SIGTSTP, tstat); | |||||
/* mark this pipe closed */ | |||||
popen_pid[f] = 0; | |||||
return (status); | |||||
} | } |
@@ -2,157 +2,159 @@ | |||||
#include "build.h" | #include "build.h" | ||||
#include "vp.h" | #include "vp.h" | ||||
#include "version.h" /* FILEVERSION and FIXVERSION */ | |||||
#include "version.h" /* FILEVERSION and FIXVERSION */ | |||||
#include <stdlib.h> /* atoi */ | |||||
#include <stdlib.h> /* atoi */ | |||||
#include <getopt.h> | #include <getopt.h> | ||||
bool remove_symfile_onexit = false; | |||||
bool onesearch; /* one search only in line mode */ | |||||
char *reflines; /* symbol reference lines file */ | |||||
bool remove_symfile_onexit = false; | |||||
bool onesearch; /* one search only in line mode */ | |||||
char *reflines; /* symbol reference lines file */ | |||||
char ** parse_options(int *argc, char **argv) | |||||
{ | |||||
int opt; | |||||
int longind; | |||||
char path[PATHLEN + 1]; /* file path */ | |||||
char *s; | |||||
int argcc = *argc; | |||||
char **parse_options(int *argc, char **argv) { | |||||
int opt; | |||||
int longind; | |||||
char path[PATHLEN + 1]; /* file path */ | |||||
char *s; | |||||
int argcc = *argc; | |||||
struct option lopts[] = { | |||||
{"help", 0, NULL, 'h'}, | |||||
{"version", 0, NULL, 'V'}, | |||||
{0, 0, 0, 0} | |||||
}; | |||||
struct option lopts[] = { | |||||
{"help", 0, NULL, 'h'}, | |||||
{"version", 0, NULL, 'V'}, | |||||
{0, 0, 0, 0 } | |||||
}; | |||||
while ((opt = getopt_long(argcc, argv, | |||||
"hVbcCdeF:f:I:i:kLl0:1:2:3:4:5:6:7:8:9:P:p:qRs:TUuvX", | |||||
lopts, &longind)) != -1) { | |||||
switch(opt) { | |||||
while((opt = getopt_long(argcc, | |||||
argv, | |||||
"hVbcCdeF:f:I:i:kLl0:1:2:3:4:5:6:7:8:9:P:p:qRs:TUuvX", | |||||
lopts, | |||||
&longind)) != -1) { | |||||
switch(opt) { | |||||
case '?': | |||||
usage(); | |||||
myexit(1); | |||||
break; | |||||
case 'X': | |||||
remove_symfile_onexit = true; | |||||
break; | |||||
case '0': | |||||
case '1': | |||||
case '2': | |||||
case '3': | |||||
case '4': | |||||
case '5': | |||||
case '6': | |||||
case '7': | |||||
case '8': | |||||
case '9': | |||||
/* The input fields numbers for line mode operation */ | |||||
field = opt - '0'; | |||||
if (strlen(optarg) > PATHLEN) { | |||||
postfatal("\ | |||||
case '?': | |||||
usage(); | |||||
myexit(1); | |||||
break; | |||||
case 'X': | |||||
remove_symfile_onexit = true; | |||||
break; | |||||
case '0': | |||||
case '1': | |||||
case '2': | |||||
case '3': | |||||
case '4': | |||||
case '5': | |||||
case '6': | |||||
case '7': | |||||
case '8': | |||||
case '9': | |||||
/* The input fields numbers for line mode operation */ | |||||
field = opt - '0'; | |||||
if(strlen(optarg) > PATHLEN) { | |||||
postfatal("\ | |||||
cscope: pattern too long, cannot be > \ | cscope: pattern too long, cannot be > \ | ||||
%d characters\n", PATLEN); | |||||
} | |||||
strcpy(input_line, optarg); | |||||
break; | |||||
case 'b': /* only build the cross-reference */ | |||||
buildonly = true; | |||||
linemode = true; | |||||
break; | |||||
case 'c': /* ASCII characters only in crossref */ | |||||
compress = false; | |||||
break; | |||||
case 'C': /* turn on caseless mode for symbol searches */ | |||||
caseless = true; | |||||
egrepcaseless(caseless); /* simulate egrep -i flag */ | |||||
break; | |||||
case 'd': /* consider crossref up-to-date */ | |||||
isuptodate = true; | |||||
break; | |||||
case 'e': /* suppress ^E prompt between files */ | |||||
editallprompt = false; | |||||
break; | |||||
case 'h': | |||||
longusage(); | |||||
myexit(1); | |||||
break; | |||||
case 'k': /* ignore DFLT_INCDIR */ | |||||
kernelmode = true; | |||||
break; | |||||
case 'L': | |||||
onesearch = true; | |||||
/* FALLTHROUGH */ | |||||
case 'l': | |||||
linemode = true; | |||||
break; | |||||
case 'v': | |||||
verbosemode = true; | |||||
break; | |||||
case 'V': | |||||
fprintf(stderr, PROGRAM_NAME ": version %d%s\n", | |||||
FILEVERSION, FIXVERSION); | |||||
myexit(0); | |||||
break; | |||||
case 'q': /* quick search */ | |||||
invertedindex = true; | |||||
break; | |||||
case 'T': /* truncate symbols to 8 characters */ | |||||
trun_syms = true; | |||||
break; | |||||
case 'u': /* unconditionally build the cross-reference */ | |||||
unconditional = true; | |||||
break; | |||||
case 'U': /* assume some files have changed */ | |||||
fileschanged = true; | |||||
break; | |||||
case 'R': | |||||
recurse_dir = true; | |||||
break; | |||||
case 'f': /* alternate cross-reference file */ | |||||
reffile = optarg; | |||||
if (strlen(reffile) > sizeof(path) - 3) { | |||||
postfatal("\ | |||||
%d characters\n", | |||||
PATLEN); | |||||
} | |||||
strcpy(input_line, optarg); | |||||
break; | |||||
case 'b': /* only build the cross-reference */ | |||||
buildonly = true; | |||||
linemode = true; | |||||
break; | |||||
case 'c': /* ASCII characters only in crossref */ | |||||
compress = false; | |||||
break; | |||||
case 'C': /* turn on caseless mode for symbol searches */ | |||||
caseless = true; | |||||
egrepcaseless(caseless); /* simulate egrep -i flag */ | |||||
break; | |||||
case 'd': /* consider crossref up-to-date */ | |||||
isuptodate = true; | |||||
break; | |||||
case 'e': /* suppress ^E prompt between files */ | |||||
editallprompt = false; | |||||
break; | |||||
case 'h': | |||||
longusage(); | |||||
myexit(1); | |||||
break; | |||||
case 'k': /* ignore DFLT_INCDIR */ | |||||
kernelmode = true; | |||||
break; | |||||
case 'L': | |||||
onesearch = true; | |||||
/* FALLTHROUGH */ | |||||
case 'l': | |||||
linemode = true; | |||||
break; | |||||
case 'v': | |||||
verbosemode = true; | |||||
break; | |||||
case 'V': | |||||
fprintf(stderr, PROGRAM_NAME ": version %d%s\n", FILEVERSION, FIXVERSION); | |||||
myexit(0); | |||||
break; | |||||
case 'q': /* quick search */ | |||||
invertedindex = true; | |||||
break; | |||||
case 'T': /* truncate symbols to 8 characters */ | |||||
trun_syms = true; | |||||
break; | |||||
case 'u': /* unconditionally build the cross-reference */ | |||||
unconditional = true; | |||||
break; | |||||
case 'U': /* assume some files have changed */ | |||||
fileschanged = true; | |||||
break; | |||||
case 'R': | |||||
recurse_dir = true; | |||||
break; | |||||
case 'f': /* alternate cross-reference file */ | |||||
reffile = optarg; | |||||
if(strlen(reffile) > sizeof(path) - 3) { | |||||
postfatal("\ | |||||
cscope: reffile too long, cannot \ | cscope: reffile too long, cannot \ | ||||
be > %d characters\n", sizeof(path) - 3); | |||||
/* NOTREACHED */ | |||||
} | |||||
strcpy(path, reffile); | |||||
be > %d characters\n", | |||||
sizeof(path) - 3); | |||||
/* NOTREACHED */ | |||||
} | |||||
strcpy(path, reffile); | |||||
s = path + strlen(path); | |||||
strcpy(s, ".in"); | |||||
/*coverity[overwrite_var]*/ | |||||
invname = strdup(path); | |||||
strcpy(s, ".po"); | |||||
/*coverity[overwrite_var]*/ | |||||
invpost = strdup(path); | |||||
break; | |||||
s = path + strlen(path); | |||||
strcpy(s, ".in"); | |||||
/*coverity[overwrite_var]*/ | |||||
invname = strdup(path); | |||||
strcpy(s, ".po"); | |||||
/*coverity[overwrite_var]*/ | |||||
invpost = strdup(path); | |||||
break; | |||||
case 'F': /* symbol reference lines file */ | |||||
reflines = optarg; | |||||
break; | |||||
case 'i': /* file containing file names */ | |||||
namefile = optarg; | |||||
break; | |||||
case 'I': /* #include file directory */ | |||||
includedir(optarg); | |||||
break; | |||||
case 'p': /* file path components to display */ | |||||
dispcomponents = atoi(optarg); | |||||
break; | |||||
case 'P': /* prepend path to file names */ | |||||
prependpath = optarg; | |||||
break; | |||||
case 's': /* additional source file directory */ | |||||
sourcedir(optarg); | |||||
break; | |||||
} | |||||
} | |||||
/* | |||||
* This adjusts argv so that we only see the remaining | |||||
* args. Its ugly, but we need to do it so that the rest | |||||
* of the main routine doesn't get all confused | |||||
*/ | |||||
*argc = *argc - optind; | |||||
return argv + optind; | |||||
case 'F': /* symbol reference lines file */ | |||||
reflines = optarg; | |||||
break; | |||||
case 'i': /* file containing file names */ | |||||
namefile = optarg; | |||||
break; | |||||
case 'I': /* #include file directory */ | |||||
includedir(optarg); | |||||
break; | |||||
case 'p': /* file path components to display */ | |||||
dispcomponents = atoi(optarg); | |||||
break; | |||||
case 'P': /* prepend path to file names */ | |||||
prependpath = optarg; | |||||
break; | |||||
case 's': /* additional source file directory */ | |||||
sourcedir(optarg); | |||||
break; | |||||
} | |||||
} | |||||
/* | |||||
* This adjusts argv so that we only see the remaining | |||||
* args. Its ugly, but we need to do it so that the rest | |||||
* of the main routine doesn't get all confused | |||||
*/ | |||||
*argc = *argc - optind; | |||||
return argv + optind; | |||||
} | } |
@@ -34,37 +34,28 @@ | |||||
#include "global.h" | #include "global.h" | ||||
const char * | |||||
basename(const char *path) | |||||
{ | |||||
const char *s; | |||||
const char *basename(const char *path) { | |||||
const char *s; | |||||
if ((s = strrchr(path, '/')) != 0) { | |||||
return(s + 1); | |||||
} | |||||
return(path); | |||||
if((s = strrchr(path, '/')) != 0) { return (s + 1); } | |||||
return (path); | |||||
} | } | ||||
/* get the requested path components */ | /* get the requested path components */ | ||||
char * | |||||
pathcomponents(char *path, int components) | |||||
{ | |||||
int i; | |||||
char *s; | |||||
s = path + strlen(path) - 1; | |||||
for (i = 0; i < components; ++i) { | |||||
while (s > path && *--s != '/') { | |||||
; | |||||
} | |||||
} | |||||
if (s > path && *s == '/') { | |||||
++s; | |||||
} | |||||
return(s); | |||||
char *pathcomponents(char *path, int components) { | |||||
int i; | |||||
char *s; | |||||
s = path + strlen(path) - 1; | |||||
for(i = 0; i < components; ++i) { | |||||
while(s > path && *--s != '/') { | |||||
; | |||||
} | |||||
} | |||||
if(s > path && *s == '/') { ++s; } | |||||
return (s); | |||||
} | } | ||||
/* | /* | ||||
* compath(pathname) | * compath(pathname) | ||||
* | * | ||||
@@ -79,162 +70,150 @@ pathcomponents(char *path, int components) | |||||
* and stored in global structures. | * and stored in global structures. | ||||
*/ | */ | ||||
char * | |||||
compath(char *pathname) /*FDEF*/ | |||||
char *compath(char *pathname) /*FDEF*/ | |||||
{ | { | ||||
char *nextchar; | |||||
char *lastchar; | |||||
char *sofar; | |||||
char *pnend; | |||||
int pnlen; | |||||
/* | |||||
* do not change the path if it has no "/" | |||||
*/ | |||||
if (strchr(pathname, '/') == NULL) | |||||
return(pathname); | |||||
/* | |||||
* find all strings consisting of more than one '/' | |||||
*/ | |||||
for (lastchar = pathname + 1; *lastchar != '\0'; lastchar++) | |||||
if ((*lastchar == '/') && (*(lastchar - 1) == '/')) | |||||
{ | |||||
/* | |||||
* find the character after the last slash | |||||
*/ | |||||
nextchar = lastchar; | |||||
while (*++lastchar == '/') | |||||
{ | |||||
} | |||||
/* | |||||
* eliminate the extra slashes by copying | |||||
* everything after the slashes over the slashes | |||||
*/ | |||||
sofar = nextchar; | |||||
while ((*nextchar++ = *lastchar++) != '\0') | |||||
; | |||||
lastchar = sofar; | |||||
} | |||||
/* | |||||
* find all strings of "./" | |||||
*/ | |||||
for (lastchar = pathname + 1; *lastchar != '\0'; lastchar++) | |||||
if ((*lastchar == '/') && (*(lastchar - 1) == '.') && | |||||
((lastchar - 1 == pathname) || (*(lastchar - 2) == '/'))) | |||||
{ | |||||
/* | |||||
* copy everything after the "./" over the "./" | |||||
*/ | |||||
nextchar = lastchar - 1; | |||||
sofar = nextchar; | |||||
while ((*nextchar++ = *++lastchar) != '\0') | |||||
; | |||||
lastchar = sofar; | |||||
} | |||||
/* | |||||
* find each occurrence of "/.." | |||||
*/ | |||||
for (lastchar = pathname + 1; *lastchar != '\0'; lastchar++) | |||||
if ((lastchar != pathname) && (*lastchar == '/') && | |||||
(*(lastchar + 1) == '.') && (*(lastchar + 2) == '.') && | |||||
((*(lastchar + 3) == '/') || (*(lastchar + 3) == '\0'))) | |||||
{ | |||||
/* | |||||
* find the directory name preceding the "/.." | |||||
*/ | |||||
nextchar = lastchar - 1; | |||||
while ((nextchar != pathname) && | |||||
(*(nextchar - 1) != '/')) | |||||
--nextchar; | |||||
/* | |||||
* make sure the preceding directory's name | |||||
* is not "." or ".." | |||||
*/ | |||||
if ((*nextchar == '.') && | |||||
((*(nextchar + 1) == '/') || | |||||
((*(nextchar + 1) == '.') && (*(nextchar + 2) == '/')))) | |||||
/* EMPTY */; | |||||
else | |||||
{ | |||||
/* | |||||
* prepare to eliminate either | |||||
* "dir_name/../" or "dir_name/.." | |||||
*/ | |||||
if (*(lastchar + 3) == '/') | |||||
lastchar += 4; | |||||
else | |||||
lastchar += 3; | |||||
/* | |||||
* copy everything after the "/.." to | |||||
* before the preceding directory name | |||||
*/ | |||||
sofar = nextchar - 1; | |||||
while ((*nextchar++ = *lastchar++) != '\0'); | |||||
lastchar = sofar; | |||||
/* | |||||
* if the character before what was taken | |||||
* out is '/', set up to check if the | |||||
* slash is part of "/.." | |||||
*/ | |||||
if ((sofar + 1 != pathname) && (*sofar == '/')) | |||||
--lastchar; | |||||
} | |||||
} | |||||
/* | |||||
* if the string is more than a character long and ends | |||||
* in '/', eliminate the '/'. | |||||
*/ | |||||
pnlen = strlen(pathname); | |||||
pnend = strchr(pathname, '\0') - 1; | |||||
if ((pnlen > 1) && (*pnend == '/')) | |||||
{ | |||||
*pnend-- = '\0'; | |||||
pnlen--; | |||||
} | |||||
/* | |||||
* if the string has more than two characters and ends in | |||||
* "/.", remove the "/.". | |||||
*/ | |||||
if ((pnlen > 2) && (*(pnend - 1) == '/') && (*pnend == '.')) | |||||
*--pnend = '\0'; | |||||
/* | |||||
* if all characters were deleted, return "."; | |||||
* otherwise return pathname | |||||
*/ | |||||
if (*pathname == '\0') | |||||
(void) strcpy(pathname, "."); | |||||
return(pathname); | |||||
char *nextchar; | |||||
char *lastchar; | |||||
char *sofar; | |||||
char *pnend; | |||||
int pnlen; | |||||
/* | |||||
* do not change the path if it has no "/" | |||||
*/ | |||||
if(strchr(pathname, '/') == NULL) return (pathname); | |||||
/* | |||||
* find all strings consisting of more than one '/' | |||||
*/ | |||||
for(lastchar = pathname + 1; *lastchar != '\0'; lastchar++) | |||||
if((*lastchar == '/') && (*(lastchar - 1) == '/')) { | |||||
/* | |||||
* find the character after the last slash | |||||
*/ | |||||
nextchar = lastchar; | |||||
while(*++lastchar == '/') { } | |||||
/* | |||||
* eliminate the extra slashes by copying | |||||
* everything after the slashes over the slashes | |||||
*/ | |||||
sofar = nextchar; | |||||
while((*nextchar++ = *lastchar++) != '\0') | |||||
; | |||||
lastchar = sofar; | |||||
} | |||||
/* | |||||
* find all strings of "./" | |||||
*/ | |||||
for(lastchar = pathname + 1; *lastchar != '\0'; lastchar++) | |||||
if((*lastchar == '/') && (*(lastchar - 1) == '.') && | |||||
((lastchar - 1 == pathname) || (*(lastchar - 2) == '/'))) { | |||||
/* | |||||
* copy everything after the "./" over the "./" | |||||
*/ | |||||
nextchar = lastchar - 1; | |||||
sofar = nextchar; | |||||
while((*nextchar++ = *++lastchar) != '\0') | |||||
; | |||||
lastchar = sofar; | |||||
} | |||||
/* | |||||
* find each occurrence of "/.." | |||||
*/ | |||||
for(lastchar = pathname + 1; *lastchar != '\0'; lastchar++) | |||||
if((lastchar != pathname) && (*lastchar == '/') && (*(lastchar + 1) == '.') && | |||||
(*(lastchar + 2) == '.') && | |||||
((*(lastchar + 3) == '/') || (*(lastchar + 3) == '\0'))) { | |||||
/* | |||||
* find the directory name preceding the "/.." | |||||
*/ | |||||
nextchar = lastchar - 1; | |||||
while((nextchar != pathname) && (*(nextchar - 1) != '/')) | |||||
--nextchar; | |||||
/* | |||||
* make sure the preceding directory's name | |||||
* is not "." or ".." | |||||
*/ | |||||
if((*nextchar == '.') && | |||||
((*(nextchar + 1) == '/') || | |||||
((*(nextchar + 1) == '.') && (*(nextchar + 2) == '/')))) | |||||
/* EMPTY */; | |||||
else { | |||||
/* | |||||
* prepare to eliminate either | |||||
* "dir_name/../" or "dir_name/.." | |||||
*/ | |||||
if(*(lastchar + 3) == '/') | |||||
lastchar += 4; | |||||
else | |||||
lastchar += 3; | |||||
/* | |||||
* copy everything after the "/.." to | |||||
* before the preceding directory name | |||||
*/ | |||||
sofar = nextchar - 1; | |||||
while((*nextchar++ = *lastchar++) != '\0') | |||||
; | |||||
lastchar = sofar; | |||||
/* | |||||
* if the character before what was taken | |||||
* out is '/', set up to check if the | |||||
* slash is part of "/.." | |||||
*/ | |||||
if((sofar + 1 != pathname) && (*sofar == '/')) --lastchar; | |||||
} | |||||
} | |||||
/* | |||||
* if the string is more than a character long and ends | |||||
* in '/', eliminate the '/'. | |||||
*/ | |||||
pnlen = strlen(pathname); | |||||
pnend = strchr(pathname, '\0') - 1; | |||||
if((pnlen > 1) && (*pnend == '/')) { | |||||
*pnend-- = '\0'; | |||||
pnlen--; | |||||
} | |||||
/* | |||||
* if the string has more than two characters and ends in | |||||
* "/.", remove the "/.". | |||||
*/ | |||||
if((pnlen > 2) && (*(pnend - 1) == '/') && (*pnend == '.')) *--pnend = '\0'; | |||||
/* | |||||
* if all characters were deleted, return "."; | |||||
* otherwise return pathname | |||||
*/ | |||||
if(*pathname == '\0') (void)strcpy(pathname, "."); | |||||
return (pathname); | |||||
} | } |
@@ -4,121 +4,122 @@ | |||||
#include "build.h" | #include "build.h" | ||||
#include <ncurses.h> | #include <ncurses.h> | ||||
static int input_available = 0; | |||||
static int input_available = 0; | |||||
static char input_char; | static char input_char; | ||||
char input_line[PATLEN + 1]; | |||||
char input_line[PATLEN + 1]; | |||||
bool interpret(int c){ | |||||
input_char = c; | |||||
input_available = 1; | |||||
rl_callback_read_char(); | |||||
bool interpret(int c) { | |||||
input_char = c; | |||||
input_available = 1; | |||||
rl_callback_read_char(); | |||||
return 0; | |||||
return 0; | |||||
} | } | ||||
static int getc_function(FILE* ignore){ | |||||
static int getc_function(FILE *ignore) { | |||||
UNUSED(ignore); | UNUSED(ignore); | ||||
input_available = 0; | |||||
return (int)input_char; | |||||
input_available = 0; | |||||
return (int)input_char; | |||||
} | } | ||||
static int input_available_hook(){ | |||||
return input_available; | |||||
static int input_available_hook() { | |||||
return input_available; | |||||
} | } | ||||
static void redisplay_function(){ | |||||
window_change |= CH_INPUT; | |||||
static void redisplay_function() { | |||||
window_change |= CH_INPUT; | |||||
} | } | ||||
static void callback_handler(char* line){ | |||||
if(!line){ return; } | |||||
static void callback_handler(char *line) { | |||||
if(!line) { return; } | |||||
switch(input_mode){ | |||||
switch(input_mode) { | |||||
case INPUT_NORMAL: | case INPUT_NORMAL: | ||||
strncpy(input_line, line, PATLEN); | |||||
strncpy(input_line, line, PATLEN); | |||||
search(input_line); | search(input_line); | ||||
curdispline = 0; | curdispline = 0; | ||||
PCS_reset(); | PCS_reset(); | ||||
current_page = 0; | current_page = 0; | ||||
break; | break; | ||||
case INPUT_CHANGE_TO: | case INPUT_CHANGE_TO: | ||||
strncpy(newpat, line, PATLEN); | |||||
change = calloc(totallines, sizeof(*change)); | |||||
strncpy(newpat, line, PATLEN); | |||||
change = calloc(totallines, sizeof(*change)); | |||||
input_mode = INPUT_CHANGE; | input_mode = INPUT_CHANGE; | ||||
horswp_field(); | horswp_field(); | ||||
return; | return; | ||||
} | } | ||||
switch(field){ | |||||
switch(field) { | |||||
case CHANGE: | case CHANGE: | ||||
input_mode = INPUT_CHANGE_TO; | input_mode = INPUT_CHANGE_TO; | ||||
break; | break; | ||||
case DEFINITION: | case DEFINITION: | ||||
case FILENAME: | case FILENAME: | ||||
if(totallines == 1){ editref(0); } | |||||
if(totallines == 1) { editref(0); } | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
static int ctrl_z(){ | |||||
kill(0, SIGTSTP); | |||||
static int ctrl_z() { | |||||
kill(0, SIGTSTP); | |||||
return 0; | return 0; | ||||
} | } | ||||
static int toggle_caseless(){ | |||||
if (caseless == false) { | |||||
caseless = true; | |||||
postmsg2("Caseless mode is now ON"); | |||||
} else { | |||||
caseless = false; | |||||
postmsg2("Caseless mode is now OFF"); | |||||
} | |||||
egrepcaseless(caseless); /* turn on/off -i flag */ | |||||
static int toggle_caseless() { | |||||
if(caseless == false) { | |||||
caseless = true; | |||||
postmsg2("Caseless mode is now ON"); | |||||
} else { | |||||
caseless = false; | |||||
postmsg2("Caseless mode is now OFF"); | |||||
} | |||||
egrepcaseless(caseless); /* turn on/off -i flag */ | |||||
return 0; | return 0; | ||||
} | } | ||||
static int rebuild_reference(){ | |||||
if (isuptodate == true) { | |||||
postmsg("The -d option prevents rebuilding the symbol database"); | |||||
return(false); | |||||
} | |||||
exitcurses(); | |||||
freefilelist(); /* remake the source file list */ | |||||
makefilelist(); | |||||
rebuild(); | |||||
if (errorsfound == true) { | |||||
errorsfound = false; | |||||
askforreturn(); | |||||
} | |||||
entercurses(); | |||||
postmsg(""); /* clear any previous message */ | |||||
totallines = 0; | |||||
disprefs = 0; | |||||
return(true); | |||||
static int rebuild_reference() { | |||||
if(isuptodate == true) { | |||||
postmsg("The -d option prevents rebuilding the symbol database"); | |||||
return (false); | |||||
} | |||||
exitcurses(); | |||||
freefilelist(); /* remake the source file list */ | |||||
makefilelist(); | |||||
rebuild(); | |||||
if(errorsfound == true) { | |||||
errorsfound = false; | |||||
askforreturn(); | |||||
} | |||||
entercurses(); | |||||
postmsg(""); /* clear any previous message */ | |||||
totallines = 0; | |||||
disprefs = 0; | |||||
return (true); | |||||
} | } | ||||
void rlinit(){ | |||||
rl_catch_signals = 0; | |||||
rl_catch_sigwinch = 0; | |||||
rl_prep_term_function = NULL; | |||||
rl_deprep_term_function = NULL; | |||||
rl_change_environment = 0; | |||||
rl_getc_function = getc_function; | |||||
rl_input_available_hook = input_available_hook; | |||||
rl_redisplay_function = redisplay_function; | |||||
rl_callback_handler_install("", callback_handler); | |||||
rl_bind_key(7, rl_rubout); // XXX: 7 is backspace for some reason (on my system anyways?) | |||||
rl_bind_key(KEY_BACKSPACE, rl_rubout); | |||||
rl_bind_key(EOF, myexit); | |||||
rl_bind_key(ctrl('Z'), ctrl_z); | |||||
rl_bind_key(ctrl('Z'), toggle_caseless); | |||||
rl_bind_key(ctrl('R'), rebuild_reference); | |||||
rl_bind_key(ESC, process_mouse); /* possible unixpc mouse selection */ | |||||
rl_bind_key(ctrl('X'), process_mouse); /* mouse selection */ | |||||
//rl_bind_key(ctrl('\\'), /**/); /* bypass bindings */ | |||||
void rlinit() { | |||||
rl_catch_signals = 0; | |||||
rl_catch_sigwinch = 0; | |||||
rl_prep_term_function = NULL; | |||||
rl_deprep_term_function = NULL; | |||||
rl_change_environment = 0; | |||||
rl_getc_function = getc_function; | |||||
rl_input_available_hook = input_available_hook; | |||||
rl_redisplay_function = redisplay_function; | |||||
rl_callback_handler_install("", callback_handler); | |||||
rl_bind_key(7, | |||||
rl_rubout); // XXX: 7 is backspace for some reason (on my system anyways?) | |||||
rl_bind_key(KEY_BACKSPACE, rl_rubout); | |||||
rl_bind_key(EOF, myexit); | |||||
rl_bind_key(ctrl('Z'), ctrl_z); | |||||
rl_bind_key(ctrl('Z'), toggle_caseless); | |||||
rl_bind_key(ctrl('R'), rebuild_reference); | |||||
rl_bind_key(ESC, process_mouse); /* possible unixpc mouse selection */ | |||||
rl_bind_key(ctrl('X'), process_mouse); /* mouse selection */ | |||||
// rl_bind_key(ctrl('\\'), /**/); /* bypass bindings */ | |||||
} | } |
@@ -4,15 +4,15 @@ | |||||
struct FILE; | struct FILE; | ||||
/* Page cursor stack */ | /* Page cursor stack */ | ||||
static FILE** hto_page = &refsfound; | |||||
static FILE **hto_page = &refsfound; | |||||
#define PCS_MAXPAGE 16 | #define PCS_MAXPAGE 16 | ||||
static size_t PCS_pos[PCS_MAXPAGE] = {0}; | static size_t PCS_pos[PCS_MAXPAGE] = {0}; | ||||
static size_t PCS_top = 0; | |||||
static size_t PCS_top = 0; | |||||
long seekpage(const size_t i){ | |||||
if(i > PCS_MAXPAGE-1){ return -1; } | |||||
long seekpage(const size_t i) { | |||||
if(i > PCS_MAXPAGE - 1) { return -1; } | |||||
if(i < PCS_top){ | |||||
if(i < PCS_top) { | |||||
fseek(*hto_page, PCS_pos[i], SEEK_SET); | fseek(*hto_page, PCS_pos[i], SEEK_SET); | ||||
return PCS_pos[i]; | return PCS_pos[i]; | ||||
} | } | ||||
@@ -20,62 +20,59 @@ long seekpage(const size_t i){ | |||||
fseek(*hto_page, PCS_pos[PCS_top], SEEK_SET); | fseek(*hto_page, PCS_pos[PCS_top], SEEK_SET); | ||||
size_t lc = 0; | size_t lc = 0; | ||||
while(PCS_top < i){ | |||||
while(PCS_top < i) { | |||||
const char c = getc(*hto_page); | const char c = getc(*hto_page); | ||||
if(c == '\n'){ ++lc; } | |||||
if(c == EOF){ return -1; } | |||||
if(lc == mdisprefs){ | |||||
PCS_pos[++PCS_top] = ftell(*hto_page); | |||||
} | |||||
if(c == '\n') { ++lc; } | |||||
if(c == EOF) { return -1; } | |||||
if(lc == mdisprefs) { PCS_pos[++PCS_top] = ftell(*hto_page); } | |||||
} | } | ||||
return PCS_pos[PCS_top]; | return PCS_pos[PCS_top]; | ||||
} | } | ||||
long seekrelline(unsigned i){ | |||||
long seekrelline(unsigned i) { | |||||
seekpage(current_page); | seekpage(current_page); | ||||
size_t lc = 0; | size_t lc = 0; | ||||
while(lc < i){ | |||||
while(lc < i) { | |||||
const char c = getc(*hto_page); | const char c = getc(*hto_page); | ||||
assert("seekrelline() tried to read past the reference file" && !(c == EOF)); | assert("seekrelline() tried to read past the reference file" && !(c == EOF)); | ||||
if(c == '\n'){ ++lc; } | |||||
if(c == '\n') { ++lc; } | |||||
} | } | ||||
return ftell(*hto_page); | return ftell(*hto_page); | ||||
} | } | ||||
void PCS_reset(void){ | |||||
void PCS_reset(void) { | |||||
PCS_top = 0; | PCS_top = 0; | ||||
} | } | ||||
///* position references found file at specified line */ | ///* position references found file at specified line */ | ||||
//void | |||||
//seekline(unsigned int line) | |||||
// void | |||||
// seekline(unsigned int line) | |||||
//{ | //{ | ||||
// /* verify that there is a references found file */ | |||||
// if (refsfound == NULL) { | |||||
// return; | |||||
// } | |||||
// /* go to the beginning of the file */ | |||||
// rewind(refsfound); | |||||
// /* verify that there is a references found file */ | |||||
// if (refsfound == NULL) { | |||||
// return; | |||||
// } | |||||
// /* go to the beginning of the file */ | |||||
// rewind(refsfound); | |||||
// /**/ | // /**/ | ||||
// seekrelline(line); | // seekrelline(line); | ||||
//} | |||||
// } | |||||
// | // | ||||
///* XXX: this is just dodging the problem */ | ///* XXX: this is just dodging the problem */ | ||||
//void | |||||
//seekrelline(unsigned int line){ | |||||
// int c; | |||||
// void | |||||
// seekrelline(unsigned int line){ | |||||
// int c; | |||||
// | // | ||||
// /* verify that there is a references found file */ | |||||
// if (refsfound == NULL) { | |||||
// return; | |||||
// } | |||||
// /* verify that there is a references found file */ | |||||
// if (refsfound == NULL) { | |||||
// return; | |||||
// } | |||||
// | // | ||||
// /* find the requested line */ | |||||
// nextline = 1; | |||||
// while (nextline < line && (c = getc(refsfound)) != EOF) { | |||||
// if (c == '\n') { | |||||
// nextline++; | |||||
// } | |||||
// } | |||||
//} | |||||
// /* find the requested line */ | |||||
// nextline = 1; | |||||
// while (nextline < line && (c = getc(refsfound)) != EOF) { | |||||
// if (c == '\n') { | |||||
// nextline++; | |||||
// } | |||||
// } | |||||
// } |
@@ -35,60 +35,60 @@ | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#undef YYLMAX | |||||
#define YYLMAX STMTMAX + PATLEN + 1 /* scanner line buffer size */ | |||||
#undef YYLMAX | |||||
#define YYLMAX STMTMAX + PATLEN + 1 /* scanner line buffer size */ | |||||
/* cross-reference database mark characters (when new ones are added, | /* cross-reference database mark characters (when new ones are added, | ||||
* update the cscope.out format description in cscope.1) | * update the cscope.out format description in cscope.1) | ||||
*/ | */ | ||||
#define CLASSDEF 'c' | |||||
#define DEFINE '#' | |||||
#define DEFINEEND ')' | |||||
#define ENUMDEF 'e' | |||||
#define FCNCALL '`' | |||||
#define FCNDEF '$' | |||||
#define FCNEND '}' | |||||
#define GLOBALDEF 'g' | |||||
#define INCLUDE '~' | |||||
#define MEMBERDEF 'm' | |||||
#define NEWFILE '@' | |||||
#define STRUCTDEF 's' | |||||
#define TYPEDEF 't' | |||||
#define UNIONDEF 'u' | |||||
#define CLASSDEF 'c' | |||||
#define DEFINE '#' | |||||
#define DEFINEEND ')' | |||||
#define ENUMDEF 'e' | |||||
#define FCNCALL '`' | |||||
#define FCNDEF '$' | |||||
#define FCNEND '}' | |||||
#define GLOBALDEF 'g' | |||||
#define INCLUDE '~' | |||||
#define MEMBERDEF 'm' | |||||
#define NEWFILE '@' | |||||
#define STRUCTDEF 's' | |||||
#define TYPEDEF 't' | |||||
#define UNIONDEF 'u' | |||||
/* other scanner token types */ | /* other scanner token types */ | ||||
#define LEXEOF 0 | |||||
#define LEXERR 1 | |||||
#define IDENT 2 | |||||
#define NEWLINE 3 | |||||
#define LEXEOF 0 | |||||
#define LEXERR 1 | |||||
#define IDENT 2 | |||||
#define NEWLINE 3 | |||||
/* scanner.l global data */ | /* scanner.l global data */ | ||||
extern int first; /* buffer index for first char of symbol */ | |||||
extern int last; /* buffer index for last char of symbol */ | |||||
extern int lineno; /* symbol line number */ | |||||
extern FILE *yyin; /* input file descriptor */ | |||||
extern FILE *yyout; /* output file */ | |||||
extern int myylineno; /* input line number */ | |||||
extern int first; /* buffer index for first char of symbol */ | |||||
extern int last; /* buffer index for last char of symbol */ | |||||
extern int lineno; /* symbol line number */ | |||||
extern FILE *yyin; /* input file descriptor */ | |||||
extern FILE *yyout; /* output file */ | |||||
extern int myylineno; /* input line number */ | |||||
#ifdef USING_LEX | #ifdef USING_LEX | ||||
/* HBB 20010430: if lex is used instead of flex, have to simulate the | /* HBB 20010430: if lex is used instead of flex, have to simulate the | ||||
* private copies of yytext and yytext for the world outside scanner.l: */ | * private copies of yytext and yytext for the world outside scanner.l: */ | ||||
/* FIXME: there should be a feature test for this! */ | /* FIXME: there should be a feature test for this! */ | ||||
#if defined(__OSF1__) || defined(__sun) || defined(_AIX) | |||||
extern char yytext[]; | |||||
#else | |||||
extern unsigned char yytext[]; | |||||
#endif | |||||
extern int yyleng; | |||||
# if defined(__OSF1__) || defined(__sun) || defined(_AIX) | |||||
extern char yytext[]; | |||||
# else | |||||
extern unsigned char yytext[]; | |||||
# endif | |||||
extern int yyleng; | |||||
# define my_yytext yytext | # define my_yytext yytext | ||||
# define my_yyleng yyleng | # define my_yyleng yyleng | ||||
#else | #else | ||||
extern char *my_yytext; /* private copy of input line */ | |||||
extern size_t my_yyleng; /* ... and current length of it */ | |||||
extern char *my_yytext; /* private copy of input line */ | |||||
extern size_t my_yyleng; /* ... and current length of it */ | |||||
#endif | #endif | ||||
/* The master function exported by scanner.l */ | /* The master function exported by scanner.l */ | ||||
int yylex(void); | |||||
void initscanner(char *srcfile); | |||||
int yylex(void); | |||||
void initscanner(char *srcfile); | |||||
#endif /* CSCOPE_SCANNER_H ends */ | #endif /* CSCOPE_SCANNER_H ends */ |
@@ -39,7 +39,7 @@ | |||||
#ifndef CSCOPE_VERSION_H | #ifndef CSCOPE_VERSION_H | ||||
#define CSCOPE_VERSION_H | #define CSCOPE_VERSION_H | ||||
#define FILEVERSION 15 /* Initial Open Source and Linux Port */ | |||||
#define FIXVERSION ".9" /* feature and bug fix version */ | |||||
#define FILEVERSION 15 /* Initial Open Source and Linux Port */ | |||||
#define FIXVERSION ".9" /* feature and bug fix version */ | |||||
#endif /* CSCOPE_VERSION_H */ | |||||
#endif /* CSCOPE_VERSION_H */ |
@@ -40,31 +40,31 @@ | |||||
#ifndef CSCOPE_VP_H | #ifndef CSCOPE_VP_H | ||||
#define CSCOPE_VP_H | #define CSCOPE_VP_H | ||||
#define MAXPATH 200 /* max length for entire name */ | |||||
#define MAXPATH 200 /* max length for entire name */ | |||||
#ifdef HAVE_CONFIG_H | #ifdef HAVE_CONFIG_H | ||||
# include "config.h" | # include "config.h" | ||||
#else | #else | ||||
# define HAVE_FCNTL_H 1 /* in case of doubt, assume it's there */ | |||||
# define HAVE_FCNTL_H 1 /* in case of doubt, assume it's there */ | |||||
#endif | #endif | ||||
#ifdef HAVE_FCNTL_H | #ifdef HAVE_FCNTL_H | ||||
# include <fcntl.h> /* needed for O_... open flags */ | |||||
# include <fcntl.h> /* needed for O_... open flags */ | |||||
#endif | #endif | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#if !falseMALLOC | #if !falseMALLOC | ||||
extern char **vpdirs; /* directories (including current) in view path */ | |||||
extern char **vpdirs; /* directories (including current) in view path */ | |||||
#else | #else | ||||
#define MAXDIR 25 /* same as libVP */ | |||||
#define DIRLEN 80 /* same as libVP */ | |||||
extern char vpdirs[MAXDIR][DIRLEN + 1]; | |||||
# define MAXDIR 25 /* same as libVP */ | |||||
# define DIRLEN 80 /* same as libVP */ | |||||
extern char vpdirs[MAXDIR][DIRLEN + 1]; | |||||
#endif | #endif | ||||
extern int vpndirs; /* number of directories in view path */ | |||||
extern int vpndirs; /* number of directories in view path */ | |||||
void vpinit(char *current_dir); | |||||
int vpopen(char *path, int oflag); | |||||
int vpaccess(char *path, mode_t amode); | |||||
void vpinit(char *current_dir); | |||||
int vpopen(char *path, int oflag); | |||||
int vpaccess(char *path, mode_t amode); | |||||
#endif /* CSCOPE_VP_H */ | #endif /* CSCOPE_VP_H */ |
@@ -37,21 +37,17 @@ | |||||
#include "vp.h" | #include "vp.h" | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
int | |||||
vpaccess(char *path, mode_t amode) | |||||
{ | |||||
char buf[MAXPATH + 1]; | |||||
int returncode; | |||||
int i; | |||||
if ((returncode = access(path, amode)) == -1 && path[0] != '/') { | |||||
vpinit(NULL); | |||||
for (i = 1; i < vpndirs; i++) { | |||||
(void) snprintf(buf, sizeof(buf), "%s/%s", vpdirs[i], path); | |||||
if ((returncode = access(buf, amode)) != -1) { | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
return(returncode); | |||||
int vpaccess(char *path, mode_t amode) { | |||||
char buf[MAXPATH + 1]; | |||||
int returncode; | |||||
int i; | |||||
if((returncode = access(path, amode)) == -1 && path[0] != '/') { | |||||
vpinit(NULL); | |||||
for(i = 1; i < vpndirs; i++) { | |||||
(void)snprintf(buf, sizeof(buf), "%s/%s", vpdirs[i], path); | |||||
if((returncode = access(buf, amode)) != -1) { break; } | |||||
} | |||||
} | |||||
return (returncode); | |||||
} | } |
@@ -37,26 +37,20 @@ | |||||
#include "vp.h" | #include "vp.h" | ||||
#include "global.h" | #include "global.h" | ||||
FILE * | |||||
vpfopen(char *filename, char *type) | |||||
{ | |||||
char buf[MAXPATH + 1]; | |||||
FILE *returncode; | |||||
int i; | |||||
if ((returncode = myfopen(filename, type)) == NULL | |||||
&& filename[0] != '/' | |||||
/* && strcmp(type, "r") == 0 */ /* HBB: this breaks if type=="rb" */ | |||||
&& type[0] == 'r' | |||||
) { | |||||
vpinit(NULL); | |||||
for (i = 1; i < vpndirs; i++) { | |||||
(void) snprintf(buf, sizeof(buf), "%s/%s", vpdirs[i], filename); | |||||
if ((returncode = myfopen(buf, type)) != NULL) { | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
return(returncode); | |||||
FILE *vpfopen(char *filename, char *type) { | |||||
char buf[MAXPATH + 1]; | |||||
FILE *returncode; | |||||
int i; | |||||
if((returncode = myfopen(filename, type)) == NULL && | |||||
filename[0] != '/' | |||||
/* && strcmp(type, "r") == 0 */ /* HBB: this breaks if type=="rb" */ | |||||
&& type[0] == 'r') { | |||||
vpinit(NULL); | |||||
for(i = 1; i < vpndirs; i++) { | |||||
(void)snprintf(buf, sizeof(buf), "%s/%s", vpdirs[i], filename); | |||||
if((returncode = myfopen(buf, type)) != NULL) { break; } | |||||
} | |||||
} | |||||
return (returncode); | |||||
} | } |
@@ -32,7 +32,7 @@ | |||||
/* vpinit - initialize vpdirs or update vpdirs based on currentdir */ | /* vpinit - initialize vpdirs or update vpdirs based on currentdir */ | ||||
#include <stdio.h> /* stderr */ | |||||
#include <stdio.h> /* stderr */ | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
@@ -43,127 +43,119 @@ | |||||
#include "constants.h" | #include "constants.h" | ||||
#if !falseMALLOC | #if !falseMALLOC | ||||
char **vpdirs; /* directories (including current) in view path */ | |||||
char **vpdirs; /* directories (including current) in view path */ | |||||
#else | #else | ||||
char vpdirs[MAXDIR][DIRLEN + 1]; | |||||
#define MAXVPATH (MAXDIR * (DIRLEN + 1)) | |||||
char vpdirs[MAXDIR][DIRLEN + 1]; | |||||
# define MAXVPATH (MAXDIR * (DIRLEN + 1)) | |||||
#endif | #endif | ||||
int vpndirs; /* number of directories in view path */ | |||||
void | |||||
vpinit(char *current_dir) | |||||
{ | |||||
char *suffix; /* path from view path node */ | |||||
char *vpath; /* VPATH environment variable value */ | |||||
char buf[MAXPATH + 1]; | |||||
int i; | |||||
char *s; | |||||
int vpndirs; /* number of directories in view path */ | |||||
void vpinit(char *current_dir) { | |||||
char *suffix; /* path from view path node */ | |||||
char *vpath; /* VPATH environment variable value */ | |||||
char buf[MAXPATH + 1]; | |||||
int i; | |||||
char *s; | |||||
#if falseMALLOC | #if falseMALLOC | ||||
char *node; /* view path node */ | |||||
char vpathbuf[MAXVPATH + 1]; | |||||
char *node; /* view path node */ | |||||
char vpathbuf[MAXVPATH + 1]; | |||||
#endif | #endif | ||||
/* if an existing directory list is to be updated, free it */ | |||||
if (current_dir != NULL && vpndirs > 0) { | |||||
/* if an existing directory list is to be updated, free it */ | |||||
if(current_dir != NULL && vpndirs > 0) { | |||||
#if !falseMALLOC | #if !falseMALLOC | ||||
for (i = 0; i < vpndirs; ++i) { | |||||
free(vpdirs[i]); | |||||
} | |||||
free(vpdirs); | |||||
for(i = 0; i < vpndirs; ++i) { | |||||
free(vpdirs[i]); | |||||
} | |||||
free(vpdirs); | |||||
#endif | #endif | ||||
vpndirs = 0; | |||||
} | |||||
/* return if the directory list has been computed */ | |||||
/* or there isn't a view path environment variable */ | |||||
if (vpndirs > 0 || (vpath = getenv("VPATH")) == NULL || | |||||
*vpath == '\0') { | |||||
return; | |||||
} | |||||
/* if not given, get the current directory name */ | |||||
if (current_dir == NULL && (current_dir = getcwd(buf, MAXPATH)) == NULL) { | |||||
fprintf(stderr, PROGRAM_NAME ": cannot get current directory name\n"); | |||||
return; | |||||
} | |||||
/* see if this directory is in the first view path node */ | |||||
for (i = 0; vpath[i] == current_dir[i] && vpath[i] != '\0'; ++i) { | |||||
; | |||||
} | |||||
if ((vpath[i] != ':' && vpath[i] != '\0') || | |||||
(current_dir[i] != '/' && current_dir[i] != '\0')) { | |||||
return; | |||||
} | |||||
suffix = ¤t_dir[i]; | |||||
vpndirs = 0; | |||||
} | |||||
/* return if the directory list has been computed */ | |||||
/* or there isn't a view path environment variable */ | |||||
if(vpndirs > 0 || (vpath = getenv("VPATH")) == NULL || *vpath == '\0') { return; } | |||||
/* if not given, get the current directory name */ | |||||
if(current_dir == NULL && (current_dir = getcwd(buf, MAXPATH)) == NULL) { | |||||
fprintf(stderr, PROGRAM_NAME ": cannot get current directory name\n"); | |||||
return; | |||||
} | |||||
/* see if this directory is in the first view path node */ | |||||
for(i = 0; vpath[i] == current_dir[i] && vpath[i] != '\0'; ++i) { | |||||
; | |||||
} | |||||
if((vpath[i] != ':' && vpath[i] != '\0') || | |||||
(current_dir[i] != '/' && current_dir[i] != '\0')) { | |||||
return; | |||||
} | |||||
suffix = ¤t_dir[i]; | |||||
#if !falseMALLOC | #if !falseMALLOC | ||||
/* count the nodes in the view path */ | |||||
vpndirs = 1; | |||||
for (i = 0; vpath[i] != '\0'; ++i) { | |||||
if (vpath[i] == ':' && vpath[i + 1]) { | |||||
++vpndirs; | |||||
} | |||||
} | |||||
/* create the source directory list */ | |||||
vpdirs = malloc(vpndirs * sizeof(*vpdirs)); | |||||
/* don't change VPATH in the environment */ | |||||
vpath = strdup(vpath); | |||||
/* split the view path into nodes */ | |||||
for (i = 0, s = vpath; *s != '\0'; ++i) { | |||||
vpdirs[i] = s; | |||||
while (*s != '\0' && *++s != ':') { | |||||
if (*s == '\n') { | |||||
*s = '\0'; | |||||
} | |||||
} | |||||
if (*s != '\0') { | |||||
*s++ = '\0'; | |||||
} | |||||
} | |||||
/* convert the view path nodes to directories */ | |||||
for (i = 0; i < vpndirs; ++i) { | |||||
s = malloc(strlen(vpdirs[i]) + strlen(suffix) + 1); | |||||
(void) strcpy(s, vpdirs[i]); | |||||
(void) strcat(s, suffix); | |||||
vpdirs[i] = s; | |||||
} | |||||
free(vpath); | |||||
/* count the nodes in the view path */ | |||||
vpndirs = 1; | |||||
for(i = 0; vpath[i] != '\0'; ++i) { | |||||
if(vpath[i] == ':' && vpath[i + 1]) { ++vpndirs; } | |||||
} | |||||
/* create the source directory list */ | |||||
vpdirs = malloc(vpndirs * sizeof(*vpdirs)); | |||||
/* don't change VPATH in the environment */ | |||||
vpath = strdup(vpath); | |||||
/* split the view path into nodes */ | |||||
for(i = 0, s = vpath; *s != '\0'; ++i) { | |||||
vpdirs[i] = s; | |||||
while(*s != '\0' && *++s != ':') { | |||||
if(*s == '\n') { *s = '\0'; } | |||||
} | |||||
if(*s != '\0') { *s++ = '\0'; } | |||||
} | |||||
/* convert the view path nodes to directories */ | |||||
for(i = 0; i < vpndirs; ++i) { | |||||
s = malloc(strlen(vpdirs[i]) + strlen(suffix) + 1); | |||||
(void)strcpy(s, vpdirs[i]); | |||||
(void)strcat(s, suffix); | |||||
vpdirs[i] = s; | |||||
} | |||||
free(vpath); | |||||
#else | #else | ||||
/* don't change VPATH in the environment */ | |||||
if (strlen(vpath) > MAXVPATH) { | |||||
(void) fprintf(stderr, "%s: VPATH is longer than %d characters: %s\n", argv0, MAXVPATH, vpath); | |||||
return; | |||||
} | |||||
(void) strcpy(vpathbuf, vpath); | |||||
s = vpathbuf; | |||||
/* convert the view path nodes to directories */ | |||||
while (*s != '\0') { | |||||
/* get the next node */ | |||||
node = s; | |||||
while (*s != '\0' && *++s != ':') { | |||||
if (*s == '\n') { | |||||
*s = '\0'; | |||||
} | |||||
} | |||||
if (*s != '\0') { | |||||
*s++ = '\0'; | |||||
} | |||||
/* ignore a directory that is too long */ | |||||
if (strlen(node) + strlen(suffix) > DIRLEN) { | |||||
(void) fprintf(stderr, "%s: VPATH directory is longer than %d characters: %s%s\n", argv0, DIRLEN, node, suffix); | |||||
} | |||||
else if (vpndirs >= MAXDIR) { | |||||
(void) fprintf(stderr, "%s: VPATH has more than %d nodes\n", argv0, vpndirs); | |||||
return; | |||||
} | |||||
else { | |||||
/* create the view path directory */ | |||||
(void) strcpy(vpdirs[vpndirs], node); | |||||
(void) strcat(vpdirs[vpndirs], suffix); | |||||
++vpndirs; | |||||
} | |||||
} | |||||
/* don't change VPATH in the environment */ | |||||
if(strlen(vpath) > MAXVPATH) { | |||||
(void)fprintf(stderr, | |||||
"%s: VPATH is longer than %d characters: %s\n", | |||||
argv0, | |||||
MAXVPATH, | |||||
vpath); | |||||
return; | |||||
} | |||||
(void)strcpy(vpathbuf, vpath); | |||||
s = vpathbuf; | |||||
/* convert the view path nodes to directories */ | |||||
while(*s != '\0') { | |||||
/* get the next node */ | |||||
node = s; | |||||
while(*s != '\0' && *++s != ':') { | |||||
if(*s == '\n') { *s = '\0'; } | |||||
} | |||||
if(*s != '\0') { *s++ = '\0'; } | |||||
/* ignore a directory that is too long */ | |||||
if(strlen(node) + strlen(suffix) > DIRLEN) { | |||||
(void)fprintf(stderr, | |||||
"%s: VPATH directory is longer than %d characters: %s%s\n", | |||||
argv0, | |||||
DIRLEN, | |||||
node, | |||||
suffix); | |||||
} else if(vpndirs >= MAXDIR) { | |||||
(void)fprintf(stderr, "%s: VPATH has more than %d nodes\n", argv0, vpndirs); | |||||
return; | |||||
} else { | |||||
/* create the view path directory */ | |||||
(void)strcpy(vpdirs[vpndirs], node); | |||||
(void)strcat(vpdirs[vpndirs], suffix); | |||||
++vpndirs; | |||||
} | |||||
} | |||||
#endif | #endif | ||||
} | } |
@@ -37,24 +37,20 @@ | |||||
#include "global.h" | #include "global.h" | ||||
#include "vp.h" | #include "vp.h" | ||||
#define OPENFLAG_READ 0 | |||||
int | |||||
vpopen(char *path, int oflag) | |||||
{ | |||||
char buf[MAXPATH + 1]; | |||||
int returncode; | |||||
int i; | |||||
if ((returncode = myopen(path, oflag, 0666)) == -1 && path[0] != '/' && | |||||
oflag == OPENFLAG_READ) { | |||||
vpinit(NULL); | |||||
for (i = 1; i < vpndirs; i++) { | |||||
(void) snprintf(buf, sizeof(buf), "%s/%s", vpdirs[i], path); | |||||
if ((returncode = myopen(buf, oflag, 0666)) != -1) { | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
return(returncode); | |||||
#define OPENFLAG_READ 0 | |||||
int vpopen(char *path, int oflag) { | |||||
char buf[MAXPATH + 1]; | |||||
int returncode; | |||||
int i; | |||||
if((returncode = myopen(path, oflag, 0666)) == -1 && path[0] != '/' && | |||||
oflag == OPENFLAG_READ) { | |||||
vpinit(NULL); | |||||
for(i = 1; i < vpndirs; i++) { | |||||
(void)snprintf(buf, sizeof(buf), "%s/%s", vpdirs[i], path); | |||||
if((returncode = myopen(buf, oflag, 0666)) != -1) { break; } | |||||
} | |||||
} | |||||
return (returncode); | |||||
} | } |