/*
 *   Copyright (C) 1988-2006 Lucent Technologies Inc. and others.
 *   All Rights Reserved.
 */

/*	cscope - interactive C symbol cross-reference
 *
 *	global type, data, and function definitions
 */

#include <signal.h>	/* SIGINT and SIGQUIT */
#include <stdio.h>	/* standard I/O package */
#include "constants.h"	/* misc. constants */
#include "invlib.h"	/* inverted index library */
#include "library.h"	/* library function return values */
#include "mouse.h"	/* mouse interface */
#ifdef __BORLANDC__
#include <alloc.h>	/* memory allocation function prototypes */
#endif
#if defined(FOR_WIN32)
#include <sys/types.h>
#endif
#ifdef CCS
#include "ccstypes.h"	/* pid_t */
#else
#if uts || ilinux || darwin
#include <sys/types.h>	/* pid_t */
#else
#if !defined( _POSIX_SOURCE ) && !defined( __sys_stdtypes_h ) && \
	!defined( _SYS_TYPES_INCLUDED ) && !defined( _SYS_TYPES_H ) && !sgi
#if pyr
typedef short   pid_t;
#else
#if AIX
typedef	long	pid_t;
#else
typedef	int	pid_t;
#endif
#endif
#endif
#endif
#endif

#if SVR2 || BSD42 || RESEARCH
#define SIGTYPE int
#else
#define SIGTYPE void
#endif

#if cygwin
/* these fix up the static initialization of yyin and yyout... */
#define _IO_stdin ((FILE *)0)
#define _IO_stdout ((FILE *)0)
#endif

typedef	enum	{		/* boolean data type */
	NO,
	YES
} BOOL;

typedef	enum	{		/* findinit return code */
	NOERROR,
	NOTSYMBOL,
	REGCMPERROR
} FINDINIT;

typedef	struct	history	{		/* command history */
	int	field;
	char	*text;
	struct	history *previous;
	struct	history *next;
} HISTORY;

typedef	enum	{			/* keyword type */
	DECL,	/* type declaration */
	FLOW,	/* control flow (do, if, for, while, switch, etc.) */
	MISC	/* misc.: sizeof or table placeholder for compression */
} KEYWORD;

/* 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 */

/* main.c global data */
extern	char	*editor, *home, *shell;	/* environment variables */
extern	char	*tools;		/* exptools variable */
extern	BOOL	compress;	/* compress the characters in the crossref */
extern	int	cscopedepth;	/* cscope invocation nesting depth */
extern	char	currentdir[];	/* current directory */
extern	BOOL	dbtruncated;	/* database symbols are truncated to 8 chars */
extern	char	**dbvpdirs;	/* directories (including current) in database view path */
extern	int	dbvpndirs;	/* number of directories in database view path */
extern	int	dispcomponents;	/* file path components to display */
#if CCS
extern	BOOL	displayversion;	/* display the C Compilation System version */
#endif
extern	BOOL	editallprompt;	/* prompt between editing files */
extern	BOOL	extendedmenu;	/* extended menu support */
extern	int	fileargc;	/* file argument count */
extern	char	**fileargv;	/* file argument values */
extern	int	fileversion;	/* cross-reference file version */
extern	BOOL	incurses;	/* in curses */
extern	INVCONTROL invcontrol;	/* inverted file control structure */
extern	BOOL	invertedindex;	/* the database has an inverted index */
extern	BOOL	isuptodate;	/* consider the crossref up-to-date */
extern	BOOL	kernelmode;	/* don't use /usr/include - bad for kernels */
extern	BOOL	linemode;	/* use line oriented user interface */
#ifdef MULTILINGUAL
extern	char	*multilingual;	/* multi-lingual language */
#endif
extern	char	*namefile;	/* file of file names */
extern	char	*newreffile;	/* new cross-reference file name */
extern	FILE	*newrefs;	/* new cross-reference */
extern	BOOL	noacttimeout;	/* no activity timeout occurred */
extern	BOOL	ogs;		/* display OGS book and subsystem names */
extern	FILE	*postings;	/* new inverted index postings */
extern	char	*prependpath;	/* prepend path to file names */
extern	BOOL	recurse_dir;	/* recurse dirs when searching for src files */
extern	BOOL	returnrequired;	/* RETURN required after selection number */
extern	int	symrefs;	/* cross-reference file */
extern	BOOL	systemcalls;	/* system calls ignored */
extern	char	temp1[];	/* temporary file name */
extern	char	temp2[];	/* temporary file name */
extern	long	totalterms;	/* total inverted index terms */
extern	BOOL	truncateto8;	/* truncate symbols to 8 characters */
extern	char	*invname;	/* inverted index to the database */
extern	char	*invpost;	/* inverted index postings */
extern	char	*reffile;	/* cross-reference file path name */
extern	char	*tmpdir;	/* temporary directory */

/* command.c global data */
extern	BOOL	caseless;	/* ignore letter case when searching */
extern	BOOL	*change;	/* change this line */
extern	BOOL	changing;	/* changing text */
extern	char	newpat[];	/* new pattern */
extern	char	pattern[];	/* symbol or text pattern */

extern	BOOL	askegrep;	/* ask for subdirs for "Find this egrep pattern:" */
extern	char	subdirpat[]; /* pattern for list of subdirectories or file */
extern	BOOL	filterfiles;	/* Filter filenames */

/* crossref.c global data */
extern	long	dboffset;	/* new database offset */
extern	BOOL	errorsfound;	/* prompt before clearing error messages */
extern	long	fileindex;	/* source file name index */
extern	long	lineoffset;	/* source line database offset */
extern	long	npostings;	/* number of postings */
extern	int	symbols;	/* number of symbols */

/* dir.c global data */
extern	char	**incdirs;	/* #include directories */
extern	char	**srcdirs;	/* source directories */
extern	char	**srcfiles;	/* source files */
extern	int	nincdirs;	/* number of #include directories */
extern	int	nsrcdirs;	/* number of source directories */
extern	int	nsrcfiles;	/* number of source files */
extern	int	msrcfiles;	/* maximum number of source files */

/* display.c global data */
extern	int	*displine;	/* screen line of displayed reference */
extern	int	disprefs;	/* displayed references */
extern	int	field;		/* input field */
extern	unsigned fldcolumn;	/* input field column */
extern	int	mdisprefs;	/* maximum displayed references */
extern	int	selectlen;		/* selection number field length */
extern	int	nextline;	/* next line to be shown */
extern	int	topline;	/* top line of page */
extern	int	bottomline;	/* bottom line of page */
extern	int	totallines;	/* total reference lines */
extern	FILE	*refsfound;	/* references found file */
extern	FILE	*nonglobalrefs;	/* non-global references file */

/* exec.c global data */
extern	pid_t	childpid;	/* child's process ID */

/* find.c global data */
extern	char	block[];	/* cross-reference file block */
extern	int	blocklen;	/* length of disk block read */
extern	char	blockmark;	/* mark character to be searched for */
extern	long	blocknumber;	/* block number */
extern	char	*blockp;	/* pointer to current character in block */
extern	long	lastfcnoffset;	/* last function name offset */
extern	char	lastfilepath[];	/* last file that full path was computed for */
extern	char	*regexp;	/* regular expression */

/* lookup.c global data */
extern	struct	keystruct {
	char	*text;
	char	delim;
	KEYWORD	type;
	struct	keystruct *next;
#ifdef MULTILINGUAL
} ckeyword[], jkeyword[], skeyword[];
#else
} keyword[];
#endif

#ifdef MULTILINGUAL
/* lexscanner.c global data */
#else
/* scanner.l global data */
#endif
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 */
#if cygwin
extern	FILE	*yyout;		/* output file descriptor */
#endif
extern	int	yyleng;		/* input line length */
extern	int	yylineno;	/* input line number */
#ifdef MULTILINGUAL
extern	char	*yytext;	/* input line text */
#else
#if 0				/* hpux */
extern	unsigned char	yytext[];	/* input line text */
#else
extern	char	yytext[];	/* input line text */
#endif
#endif

#ifdef MULTILINGUAL
/* cscanner.l global data */
extern	int	cfirst;		/* buffer index for first char of symbol */
extern	int	clast;		/* buffer index for last char of symbol */
extern	int	clineno;	/* symbol line number */
extern	FILE	*cyyin;		/* input file descriptor */
extern	int	cyyleng;	/* input line length */
extern	int	cmyylineno;	/* input line number */
extern	char	cyytext[];	/* input line text */

/* jscanner.l global data */
extern	int	jfirst;		/* buffer index for first char of symbol */
extern	int	jlast;		/* buffer index for last char of symbol */
extern	int	jlineno;	/* symbol line number */
extern	FILE	*jyyin;		/* input file descriptor */
extern	int	jyyleng;	/* input line length */
extern	int	jmyylineno;	/* input line number */
extern	char	jyytext[];	/* input line text */

/* sscanner.l global data */
extern	int	sfirst;		/* buffer index for first char of symbol */
extern	int	slast;		/* buffer index for last char of symbol */
extern	int	slineno;	/* symbol line number */
extern	FILE	*syyin;		/* input file descriptor */
extern	int	syyleng;	/* input line length */
extern	int	smyylineno;	/* input line number */
extern	char	syytext[];	/* input line text */

#endif
/* vpinit.c global data */
extern	char	*argv0;		/* command name */

/* cscope functions called from more than one function or between files */
#if defined( __STDC__ ) || defined( __BORLANDC__ )

/* ccalls.c */

void	findincludes(void);
void	finddefine(void);
void	findtypedef(void);
void	findglobals(void);
void	findlocals(void);
void	findstructures(void);
void	findparameters(void);
void	findccalling(void);
void	findccalls(void);
void	findregexpfcns(void);

/* cgrep.c */
void	egrepcaseless(int i);
char	*egrepinit(char *expression);
int	egrep(char *f, FILE *o, char *fo);

/* command.c */
BOOL	command(int commandc);
void	clearprompt(void);
BOOL	readrefs(char *filename);
BOOL	changestring(void);
void	mark(int i);

/* crossref.c */
void	crossref(char *srcfile);
void	savesymbol(int token);
void	putfilename(char *srcfile);
void	putcrossref(void);
void	putposting(char *term, int type);
void	putstring(char *s);
void	warning(char *text);

/* dir.c */
void	sourcedir(char *dirlist);
void	includedir(char *dirlist);
void	makefilelist(void);
void	getsrcfiles(char *vpdir, char *dir);
BOOL	issrcfile(char *file);
void	incfile(char *file, char type);
BOOL	infilelist(char *file);
void	addsrcfile(char *path);
void	freefilelist(void);

/* display.c */
void	dispinit(void);
void	display(void);
void	initfield(void);
void	setfield(void);
void	atfield(void);
void	jumpback(int sig);
BOOL	search(void);
BOOL	writerefsfound(void);
void	countrefs(void);
void	myperror(char *text);
void	putmsg(char *msg);
void	clearmsg2(void);
void	putmsg2(char *msg);
void	seekline(int line);
void	ogsnames(char *file, char **subsystem, char **book);
char	*pathcomponents(char *path, int components);

/* dir.c */
void	strtoupper(char *s);

/* edit.c */
void	editref(int i);
void	editall(void);
void	edit(char *file, char *linenum);

/* find.c */
void	findsymbol(void);
void	finddef(void);
void	findallfcns(void);
void	findcalledby(void);
void	findcalledbysub(char *file);
void	findcalling(void);
void	findassignments(void);
char	*findgreppat(void);
char	*findegreppat(char *egreppat);
void	findfile(void);
void	findinclude(void);
FINDINIT findinit(void);
void	findcleanup(void);
void	findterm(void);
void	fileprogress(void);
void	initprogress(void);
void	progress(char *format, long n1, long n2);
BOOL	match(void);
BOOL	matchrest(void);
POSTING *peekposting(void);
POSTING	*getposting(void);
void	putpostingref(POSTING *p);
void	putref(char *file, char *function);
void	putsource(FILE *output);
void	putline(FILE *output);
void	getstring(char *s);
char	*scanpast(register char c);
char	*readblock(void);
long	dbseek(long offset);
char	*strtolower(char *s);
char	*filepath(char *file);

/* help.c */
void	help(void);

/* history.c */
void	addcmd(int f, char *s);
void	resetcmd(void);

/* input.c */
void	catchint(int sig);
int	ungetch(int c);
int	mygetch(void);
int	getline(char s[], unsigned size, int firstchar, BOOL iscaseless);
void	askforchar(void);
void	askforreturn(void);
void	shellpath(char *out, int limit, char *in);

#ifdef MULTILINGUAL
/* lexscanner.c */
int	yylex(void);
void	setscanner(char *srcfile);
void	initscanner(char *srcfile);
void	initsymtab(void);
void	csavesymbol(int token);
void	jsavesymbol(int token);
void	ssavesymbol(int token);
struct	keystruct *keyword(unsigned c);
struct	keystruct *lookup(char *ident);
int	hash(char *s);

/* clookup.c */
void	cinitsymtab(void);
struct	keystruct *clookup(char *ident);

/* jlookup.c */
void	jinitsymtab(void);
struct	keystruct *jlookup(char *ident);

/* slookup.c */
void	sinitsymtab(void);
struct	keystruct *slookup(char *ident);
#else
/* lookup.c */
void	initsymtab(void);
struct	keystruct *lookup(char *ident);
int	hash(char *s);
#endif

/* main.c */
int	main(int argc, char **argv);
void	options(int argc, char **argv);
void	printusage(void);
void	removeindex(void);
void	cannotindex(void);
void	cannotopen(char *file);
void	cannotwrite(char *file);
void	initcompress(void);
void	opendatabase(void);
void	closedatabase(void);
void	rebuild(void);
void	build(void);
int	compare(const void *s1, const void *s2);
char	*getoldfile(void);
void	putheader(char *dir);
void	putlist(char **names, int count);
BOOL	samelist(FILE *oldrefs, char **names, int count);
void	skiplist(FILE *oldrefs);
void	copydata(void);
void	copyinverted(void);
void	putinclude(char *s);
void	movefile(char *new, char *old);
void	entercurses(void);
void	exitcurses(void);
void	timedout(int sig);
void	myexit(int sig);

/* menu.c */
void	initmenu(void);
#else
void	addcmd();
void	addsrcfile();
void	askforchar();
void	askforreturn();
void	atfield();
void	build();
void	cannotindex();
void	cannotopen();
void	cannotwrite();
void	clearmsg2();
BOOL	command();
void	countrefs();
void	crossref();
#ifdef MULTILINGUAL
void	cinitsymtab();
struct	keystruct *clookup();
void	csavesymbol();
#endif
HISTORY	*currentcmd();
long	dbseek();
void	dispinit();
void	display();
void	edit();
char	*egrepinit();
void	egrepcaseless();
void	entercurses();
void	exitcurses();
char	*filepath();
void	findcleanup();
char	*findegreppat();
FINDINIT findinit();
void	freefilelist();
POSTING *peekposting();
POSTING	*getposting();
void	getstring();
void	incfile();
void	includedir();
BOOL	infilelist();
void	initfield();
void	initmenu();
void	initprogress();
void	initscanner();
void	initsymtab();
#ifdef MULTILINGUAL
void	jinitsymtab();
struct	keystruct *jlookup();
void	jsavesymbol();
struct	keystruct *keyword();
#endif
struct	keystruct *lookup();
void	makefilelist();
void	myexit();
void	myperror();
HISTORY	*nextcmd();
HISTORY	*prevcmd();
void	progress();
void	putfilename();
void	putmsg();
void	putmsg2();
void	putposting();
void	putstring();
char	*readblock();
BOOL	readrefs();
void	rebuild();
void	resetcmd();
void	savesymbol();
char	*scanpast();
BOOL	search();
void	seekline();
void	setfield();
#ifdef MULTILINGUAL
void	setscanner();
#endif
void	shellpath();
void	sourcedir();
#ifdef MULTILINGUAL
void	sinitsymtab();
struct	keystruct *slookup();
void	ssavesymbol();
#endif
char	*strtolower();
void	warning();
BOOL	writerefsfound();
#endif
