@@ -33,38 +33,38 @@ | |||
#ifndef CSCOPE_BUILD_H | |||
#define CSCOPE_BUILD_H | |||
#include "global.h" /* FIXME: temp. only */ | |||
#include "global.h" /* FIXME: temp. only */ | |||
#include "invlib.h" | |||
/* types and macros of build.c to be used by other modules */ | |||
/* 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 */ | |||
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 */ | |||
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 */ |
@@ -36,14 +36,14 @@ | |||
*/ | |||
#include "global.h" | |||
#include "build.h" /* for rebuild() */ | |||
#include "build.h" /* for rebuild() */ | |||
#include <stdlib.h> | |||
#if defined(USE_NCURSES) && !defined(RENAMED_NCURSES) | |||
#include <ncurses.h> | |||
# include <ncurses.h> | |||
#else | |||
#include <curses.h> | |||
# include <curses.h> | |||
#endif | |||
#include <ctype.h> | |||
@@ -54,164 +54,135 @@ | |||
* In the original version this was handled by | |||
* "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; | |||
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: */ | |||
static void scrollbar(MOUSE *p); | |||
static void scrollbar(MOUSE *p); | |||
/* 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 */ | |||
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 */ | |||
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 | |||
#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) */ | |||
#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 */ | |||
#define setmark(c) (blockmark = c, block[blocklen] = blockmark) | |||
#define setmark(c) (blockmark = c, block[blocklen] = blockmark) | |||
/* get the next character in the cross-reference */ | |||
/* 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 */ | |||
/* note that blockp is assumed not to be null and that | |||
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) | |||
/* input fields (value matches field order on screen) */ | |||
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 | |||
#define bazdki 1 | |||
/* file open modes */ | |||
#ifndef R_OK | |||
# define READ R_OK | |||
# define READ R_OK | |||
#else | |||
# define READ 4 | |||
# define READ 4 | |||
#endif | |||
#ifdef W_OK | |||
# define WRITE W_OK | |||
# define WRITE W_OK | |||
#else | |||
# define WRITE 2 | |||
# define WRITE 2 | |||
#endif | |||
#define O_TEXT 0x00 | |||
#define O_TEXT 0x00 | |||
#define O_BINARY 0x00 | |||
@@ -46,447 +46,408 @@ | |||
#include <sys/stat.h> | |||
/* 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 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 | |||
--yyleng; /* remove the newline */ | |||
--yyleng; /* remove the newline */ | |||
#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 | |||
/* 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 | |||
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 */ | |||
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 */ | |||
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 */ | |||
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 | |||
dboffset = ftell(newrefs); /* fprintf doesn't return chars written */ | |||
dboffset = ftell(newrefs); /* fprintf doesn't return chars written */ | |||
#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 */ | |||
/* 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 */ | |||
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 */ | |||
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 */ | |||
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" | |||
#if defined(USE_NCURSES) && !defined(RENAMED_NCURSES) | |||
#include <ncurses.h> | |||
# include <ncurses.h> | |||
#else | |||
#include <curses.h> | |||
# include <curses.h> | |||
#endif | |||
/* 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 */ | |||
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); | |||
/* 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 */ | |||
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 | |||
* file has more lines thant the screen does. | |||
* The way to get them to pause, is to pass in /dev/null too, | |||
* 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; | |||
} | |||
} | |||
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 */ | |||
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. */ | |||
#ifndef YY_YY_EGREP_H_INCLUDED | |||
# define YY_YY_EGREP_H_INCLUDED | |||
#define YY_YY_EGREP_H_INCLUDED | |||
/* Debug traces. */ | |||
#ifndef YYDEBUG | |||
# define YYDEBUG 0 | |||
@@ -48,43 +48,43 @@ extern int yydebug; | |||
/* Token kinds. */ | |||
#ifndef 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 | |||
/* Token kinds. */ | |||
#define YYEMPTY -2 | |||
#define YYEOF 0 | |||
#define YYEOF 0 | |||
#define YYerror 256 | |||
#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. */ | |||
#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 | |||
#endif | |||
@@ -92,7 +92,7 @@ typedef int YYSTYPE; | |||
extern YYSTYPE yylval; | |||
int yyparse (void); | |||
int yyparse(void); | |||
#endif /* !YY_YY_EGREP_H_INCLUDED */ |
@@ -39,20 +39,20 @@ | |||
#include "global.h" | |||
#include <stdarg.h> | |||
#include <sys/wait.h> | |||
#include <sys/types.h> /* pid_t */ | |||
#include <sys/types.h> /* pid_t */ | |||
#ifdef __DJGPP__ | |||
#include <process.h> | |||
# include <process.h> | |||
#endif | |||
#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 | |||
/* execute forks and executes a program or shell script, waits for it to | |||
@@ -60,39 +60,37 @@ static pid_t myfork(void); | |||
*/ | |||
/*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__ | |||
/* 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 | |||
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 */ | |||
entercurses(); | |||
va_end(ap); | |||
return(exitcode); | |||
va_end(ap); | |||
return (exitcode); | |||
} | |||
#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 | |||
* 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 */ | |||
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 */ | |||
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 */ |
@@ -43,46 +43,47 @@ | |||
#include <unistd.h> | |||
#include <sys/types.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 <fcntl.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 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; | |||
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 { | |||
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 { | |||
INPUT_NORMAL, | |||
INPUT_APPEND, | |||
@@ -97,224 +98,225 @@ enum { | |||
#endif | |||
/* 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: */ | |||
/* 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 */ | |||
#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" | |||
/* 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 */ | |||
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 */ | |||
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 */ | |||
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 */ | |||
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 */ | |||
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 */ | |||
extern struct keystruct { | |||
char *text; | |||
char delim; | |||
struct keystruct *next; | |||
extern struct keystruct { | |||
char *text; | |||
char delim; | |||
struct keystruct *next; | |||
} keyword[]; | |||
/* mouse.c global data */ | |||
extern bool mouse; /* mouse interface */ | |||
extern bool mouse; /* mouse interface */ | |||
/* 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 */ | |||
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; | |||
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 */ |
@@ -39,101 +39,91 @@ | |||
#include "global.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_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; | |||
} else { | |||
} else { | |||
return changeing_help_msg; | |||
} | |||
} | |||
} | |||
/* 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 */ | |||
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 */ | |||
void | |||
longusage(void) | |||
{ | |||
usage(); | |||
fprintf(stderr, "\ | |||
void longusage(void) { | |||
usage(); | |||
fprintf(stderr, | |||
"\ | |||
\n\ | |||
-b Build the cross-reference only.\n\ | |||
-C Ignore letter case when searching.\n\ | |||
@@ -142,16 +132,18 @@ longusage(void) | |||
-e Suppress the <Ctrl>-e command prompt between files.\n\ | |||
-F symfile Read symbol reference lines from symfile.\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\ | |||
-I incdir Look in incdir for any #include files.\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", | |||
DFLT_INCDIR); | |||
fputs("\ | |||
DFLT_INCDIR); | |||
fputs("\ | |||
-L Do a single search with line-oriented output.\n\ | |||
-l Line-oriented interface.\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\ | |||
\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 */ | |||
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 */ | |||
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 */ | |||
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 */ | |||
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 <ncurses.h> | |||
#include <setjmp.h> /* jmp_buf */ | |||
#include <setjmp.h> /* jmp_buf */ | |||
#include <stdlib.h> | |||
#include <errno.h> | |||
#if HAVE_SYS_TERMIOS_H | |||
@@ -48,522 +48,489 @@ | |||
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: */ | |||
static void catchint(int sig); | |||
/* catch the interrupt signal */ | |||
static void | |||
catchint(int sig){ | |||
static void catchint(int sig) { | |||
UNUSED(sig); | |||
signal(SIGINT, catchint); | |||
longjmp(env, 1); | |||
signal(SIGINT, catchint); | |||
longjmp(env, 1); | |||
} | |||
/* 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 */ | |||
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 */ | |||
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 */ | |||
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; | |||
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; | |||
case KEY_HOME: /* go to first input field */ | |||
field = 0; | |||
resetcmd(); | |||
case KEY_HOME: /* go to first input field */ | |||
field = 0; | |||
resetcmd(); | |||
break; | |||
case KEY_LL: /* go to last input field */ | |||
curdispline = disprefs; | |||
case KEY_LL: /* go to last input field */ | |||
curdispline = disprefs; | |||
break; | |||
default: | |||
return 0; | |||
} | |||
} | |||
window_change |= CH_MODE; | |||
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; | |||
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; | |||
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; | |||
case KEY_HOME: | |||
curdispline = 0; | |||
case KEY_HOME: | |||
curdispline = 0; | |||
break; | |||
case KEY_LL: | |||
field = FIELDS - 1; | |||
resetcmd(); | |||
case KEY_LL: | |||
field = FIELDS - 1; | |||
resetcmd(); | |||
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; | |||
} | |||
} | |||
window_change |= CH_RESULT; | |||
noredisp: | |||
noredisp: | |||
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'): | |||
field = (field + (FIELDS - 1)) % FIELDS; | |||
resetcmd(); | |||
field = (field + (FIELDS - 1)) % FIELDS; | |||
resetcmd(); | |||
window_change |= CH_MODE; | |||
break; | |||
break; | |||
case ctrl('J'): | |||
field = (field + 1) % FIELDS; | |||
resetcmd(); | |||
field = (field + 1) % FIELDS; | |||
resetcmd(); | |||
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; | |||
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; | |||
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; | |||
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; | |||
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; | |||
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; | |||
} | |||
/* 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; | |||
} | |||
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; | |||
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); | |||
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); | |||
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 */ | |||
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 */ | |||
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); | |||
if(islower((unsigned char)*s)) { | |||
putc(toupper((unsigned char)*s), script); | |||
putc(*s, script); | |||
putc(toupper((unsigned char)*s), script); | |||
putc(*s, script); | |||
} else { | |||
putc(*s, script); | |||
putc(tolower((unsigned char)*s), script); | |||
putc(*s, script); | |||
putc(tolower((unsigned char)*s), script); | |||
} | |||
putc(']', script); | |||
} else { | |||
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); | |||
} | |||
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 */ | |||
fprintf(stderr, "Changed lines:\n\r"); | |||
execute("sh", "sh", temp2, NULL); | |||
askforchar(); | |||
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 - */ | |||
if(do_press_any_key){ | |||
if(do_press_any_key) { | |||
do_press_any_key = false; | |||
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: | |||
if(*current_window == winput){ | |||
if(*current_window == winput) { | |||
return interpret(c); | |||
}else if(*current_window == wmode){ | |||
} else if(*current_window == wmode) { | |||
return wmode_input(c); | |||
}else if(*current_window == wresult){ | |||
} else if(*current_window == wresult) { | |||
return wresult_input(c); | |||
} | |||
assert("'current_window' dangling."); | |||
@@ -574,5 +541,5 @@ handle_input(const int c){ | |||
return change_input(c); | |||
} | |||
return 0; | |||
return 0; | |||
} |
@@ -33,82 +33,82 @@ | |||
#ifndef 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 */ | |||
/* 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 | |||
# 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 | |||
#error Need a platform with 8 bits in a char value | |||
# error Need a platform with 8 bits in a char value | |||
# endif | |||
#endif | |||
/* 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 */ | |||
#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 */ | |||
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; | |||
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; | |||
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; | |||
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; | |||
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 */ |
@@ -12,48 +12,48 @@ | |||
#define KEY_UNDEF_BASE 0 | |||
#ifndef KEY_DOWN | |||
# define KEY_DOWN KEY_UNDEF_BASE-1 | |||
# define KEY_DOWN KEY_UNDEF_BASE - 1 | |||
#endif | |||
#ifndef KEY_UP | |||
# define KEY_UP KEY_UNDEF_BASE-2 | |||
# define KEY_UP KEY_UNDEF_BASE - 2 | |||
#endif | |||
#ifndef KEY_LEFT | |||
# define KEY_LEFT KEY_UNDEF_BASE-3 | |||
# define KEY_LEFT KEY_UNDEF_BASE - 3 | |||
#endif | |||
#ifndef KEY_RIGHT | |||
# define KEY_RIGHT KEY_UNDEF_BASE-4 | |||
# define KEY_RIGHT KEY_UNDEF_BASE - 4 | |||
#endif | |||
#ifndef KEY_HOME | |||
# define KEY_HOME _KEY_UNDEF_BASE-5 | |||
# define KEY_HOME _KEY_UNDEF_BASE - 5 | |||
#endif | |||
#ifndef KEY_LL | |||
# define KEY_LL KEY_UNDEF_BASE-6 | |||
# define KEY_LL KEY_UNDEF_BASE - 6 | |||
#endif | |||
#ifndef KEY_PPAGE | |||
# define KEY_PPAGE KEY_UNDEF_BASE-7 | |||
# define KEY_PPAGE KEY_UNDEF_BASE - 7 | |||
#endif | |||
#ifndef KEY_NPAGE | |||
# define KEY_NPAGE KEY_UNDEF_BASE-8 | |||
# define KEY_NPAGE KEY_UNDEF_BASE - 8 | |||
#endif | |||
#ifndef KEY_ENTER | |||
# define KEY_ENTER KEY_UNDEF_BASE-9 | |||
# define KEY_ENTER KEY_UNDEF_BASE - 9 | |||
#endif | |||
#ifndef KEY_CLEAR | |||
# define KEY_CLEAR KEY_UNDEF_BASE-10 | |||
# define KEY_CLEAR KEY_UNDEF_BASE - 10 | |||
#endif | |||
#ifndef KEY_RESIZE | |||
# define KEY_RESIZE KEY_UNDEF_BASE-11 | |||
# define KEY_RESIZE KEY_UNDEF_BASE - 11 | |||
#endif | |||
#ifndef KEY_END | |||
# define KEY_END KEY_UNDEF_BASE-12 | |||
# define KEY_END KEY_UNDEF_BASE - 12 | |||
#endif | |||
/* Always define these keys */ | |||
#ifndef ESC | |||
# define ESC '\033' /* escape character */ | |||
# define ESC '\033' /* escape character */ | |||
#endif | |||
#ifndef DEL | |||
# define DEL '\177' /* delete character */ | |||
# define DEL '\177' /* delete character */ | |||
#endif | |||
@@ -33,19 +33,19 @@ | |||
#ifndef CSCOPE_LIBRARY_H | |||
#define CSCOPE_LIBRARY_H | |||
#include <stdio.h> /* need FILE* type def. */ | |||
#include <stdio.h> /* need FILE* type def. */ | |||
/* 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 */ |
@@ -43,58 +43,50 @@ | |||
#include <string.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: */ | |||
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" | |||
/* 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 | |||
* 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 | |||
* 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 */ | |||
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 */ | |||
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 */ | |||
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 */ | |||
/* 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 */ |
@@ -37,439 +37,392 @@ | |||
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" | |||
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 | |||
typedef struct { /* menu */ | |||
char *text; | |||
char *value; | |||
typedef struct { /* menu */ | |||
char *text; | |||
char *value; | |||
} 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 */ | |||
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 | |||
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 | |||
if (mouse == true) { | |||
loadmenu(mainmenu); | |||
} | |||
if(mouse == true) { loadmenu(mainmenu); } | |||
} | |||
/* 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 */ | |||
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 */ | |||
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 */ | |||
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 */ | |||
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 */ | |||
MOUSE * | |||
getmouseaction(char leading_char) | |||
{ | |||
static MOUSE m; | |||
MOUSE *getmouseaction(char leading_char) { | |||
static MOUSE m; | |||
#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 */ | |||
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 */ | |||
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; | |||
} |
@@ -36,14 +36,10 @@ | |||
/* 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 <sys/types.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 */ | |||
#ifdef FD_CLOEXEC | |||
@@ -49,132 +49,112 @@ | |||
#endif | |||
#ifdef HAVE_IO_H | |||
# include <io.h> /* for setmode() */ | |||
# include <io.h> /* for setmode() */ | |||
#endif | |||
static pid_t popen_pid[20]; | |||
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 (! (flag | O_BINARY)) | |||
flag |= O_TEXT; | |||
if(!(flag | O_BINARY)) flag |= O_TEXT; | |||
#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 | |||
if (fp && ! strchr(mode, 'b')) { | |||
SETMODE(fileno(fp), O_TEXT); | |||
} | |||
if(fp && !strchr(mode, 'b')) { SETMODE(fileno(fp), O_TEXT); } | |||
#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 | |||
* 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 "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> | |||
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 > \ | |||
%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 \ | |||
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" | |||
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 */ | |||
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) | |||
* | |||
@@ -79,162 +70,150 @@ pathcomponents(char *path, int components) | |||
* 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 <ncurses.h> | |||
static int input_available = 0; | |||
static int input_available = 0; | |||
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); | |||
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: | |||
strncpy(input_line, line, PATLEN); | |||
strncpy(input_line, line, PATLEN); | |||
search(input_line); | |||
curdispline = 0; | |||
PCS_reset(); | |||
current_page = 0; | |||
break; | |||
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; | |||
horswp_field(); | |||
return; | |||
} | |||
switch(field){ | |||
switch(field) { | |||
case CHANGE: | |||
input_mode = INPUT_CHANGE_TO; | |||
break; | |||
case DEFINITION: | |||
case FILENAME: | |||
if(totallines == 1){ editref(0); } | |||
if(totallines == 1) { editref(0); } | |||
break; | |||
} | |||
} | |||
static int ctrl_z(){ | |||
kill(0, SIGTSTP); | |||
static int ctrl_z() { | |||
kill(0, SIGTSTP); | |||
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; | |||
} | |||
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; | |||
/* Page cursor stack */ | |||
static FILE** hto_page = &refsfound; | |||
static FILE **hto_page = &refsfound; | |||
#define PCS_MAXPAGE 16 | |||
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); | |||
return PCS_pos[i]; | |||
} | |||
@@ -20,62 +20,59 @@ long seekpage(const size_t i){ | |||
fseek(*hto_page, PCS_pos[PCS_top], SEEK_SET); | |||
size_t lc = 0; | |||
while(PCS_top < i){ | |||
while(PCS_top < i) { | |||
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]; | |||
} | |||
long seekrelline(unsigned i){ | |||
long seekrelline(unsigned i) { | |||
seekpage(current_page); | |||
size_t lc = 0; | |||
while(lc < i){ | |||
while(lc < i) { | |||
const char c = getc(*hto_page); | |||
assert("seekrelline() tried to read past the reference file" && !(c == EOF)); | |||
if(c == '\n'){ ++lc; } | |||
if(c == '\n') { ++lc; } | |||
} | |||
return ftell(*hto_page); | |||
} | |||
void PCS_reset(void){ | |||
void PCS_reset(void) { | |||
PCS_top = 0; | |||
} | |||
///* 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); | |||
//} | |||
// } | |||
// | |||
///* 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> | |||
#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, | |||
* 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 */ | |||
#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 */ | |||
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 | |||
/* 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: */ | |||
/* 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_yyleng yyleng | |||
#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 | |||
/* 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 */ |
@@ -39,7 +39,7 @@ | |||
#ifndef 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 | |||
#define CSCOPE_VP_H | |||
#define MAXPATH 200 /* max length for entire name */ | |||
#define MAXPATH 200 /* max length for entire name */ | |||
#ifdef HAVE_CONFIG_H | |||
# include "config.h" | |||
#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 | |||
#ifdef HAVE_FCNTL_H | |||
# include <fcntl.h> /* needed for O_... open flags */ | |||
# include <fcntl.h> /* needed for O_... open flags */ | |||
#endif | |||
#include <sys/types.h> | |||
#include <sys/stat.h> | |||
#if !falseMALLOC | |||
extern char **vpdirs; /* directories (including current) in view path */ | |||
extern char **vpdirs; /* directories (including current) in view path */ | |||
#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 | |||
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 */ |
@@ -37,21 +37,17 @@ | |||
#include "vp.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 "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 */ | |||
#include <stdio.h> /* stderr */ | |||
#include <stdio.h> /* stderr */ | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <unistd.h> | |||
@@ -43,127 +43,119 @@ | |||
#include "constants.h" | |||
#if !falseMALLOC | |||
char **vpdirs; /* directories (including current) in view path */ | |||
char **vpdirs; /* directories (including current) in view path */ | |||
#else | |||
char vpdirs[MAXDIR][DIRLEN + 1]; | |||
#define MAXVPATH (MAXDIR * (DIRLEN + 1)) | |||
char vpdirs[MAXDIR][DIRLEN + 1]; | |||
# define MAXVPATH (MAXDIR * (DIRLEN + 1)) | |||
#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 | |||
char *node; /* view path node */ | |||
char vpathbuf[MAXVPATH + 1]; | |||
char *node; /* view path node */ | |||
char vpathbuf[MAXVPATH + 1]; | |||
#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 | |||
for (i = 0; i < vpndirs; ++i) { | |||
free(vpdirs[i]); | |||
} | |||
free(vpdirs); | |||
for(i = 0; i < vpndirs; ++i) { | |||
free(vpdirs[i]); | |||
} | |||
free(vpdirs); | |||
#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 | |||
/* 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 | |||
/* 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 | |||
} |
@@ -37,24 +37,20 @@ | |||
#include "global.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); | |||
} |