home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
PCTAG.ZIP
/
RETROMAC.COM
/
RETRO
next >
Wrap
Text File
|
1989-10-01
|
37KB
|
978 lines
/*
* -------------------------------------------
* PC-TAGS(tm) RETRO Program for the ME Editor
* -------------------------------------------
*
* ME Macros to Search a PC-TAGS-Generated Tagfile and Retrieve a
* Function Definition
*
* Copyright (C) 1989 by Moderne Software. All rights reserved.
* Moderne Software, P.O. Box 3638, Santa Clara, CA 95055-3638
*
* Limited permission is given to registered PC-TAGS users to modify this
* file for their own personal use only. This file may not be used for any
* purpose other than in conjunction with the PC-TAGS software package.
*
* This macro will run with ME 2.20 and greater. It can be used with an
* earlier version of ME by resetting the VER220_PLUS from "TRUE" to "FALSE".
*
* ME versions prior to 2.20 do not support the "%c" (current directory)
* parameter to the RETROEXEC special command.
*
* Entry Points
* ------------
* init -- initialize global variables
* pctags_auto -- uses word under cursor for search
* pctags_prompt -- prompts for a word to use in search
*
* Support Macros
* --------------
* _delimiter -- determine if character is a word delimiter
* _convert_slashes -- convert all slashes in string to backslashes
* _get_tagfile -- retrieve the next tagfile to search
* _parse_file_spec -- break multiple tagfile specifications into
* individual directory/filename parts
* _escape -- escape all instances of a particular character
* _line_to_reg_exp -- escape any would-be meta-characters
* _dos_shell -- execute RETROEXEC environment value thru DOS
* _pctags_main -- search and retrieval workhorse code
*
* History
* -------
* 1 Oct 89 -- Version 1.00
*
*/
/**************************************/
/* Global constants */
#define TRUE 1
#define FALSE 0
/* ME Version */
/* ********************************* IMPORTANT !!! ****************************/
/* If you are using this macro with a ME version prior to 2.20, the following
* constant value should be set to FALSE. The MACCOMP compiler will generate
* an error if it is not.
*
* When run with versions of ME before 2.20, RETRO will not support the
* "%c" substitution parameter in the RETROEXEC environment variable. All
* other operations are identical.
*/
#define VER220_PLUS TRUE
/* Return values */
#define SUCCESSFUL TRUE
#define UNSUCCESSFUL FALSE
#define CASE_SENSITIVE 0
#define CASE_INSENSITIVE 1
/**************************************/
/* Global data */
string pctags_env_tagfiles; /* RETRO env var value */
string pctags_env_path; /* Drive:path of current tagfile*/
int pctags_first_call; /* Flag used by get_tagfile() */
int pctags_tagname_case; /* Case-sensitivity of tagname search */
/**************************************
* Macro : init
* Syntax: void init( void )
* Entry : None, called automatically upon macro loading
* Exit : None.
* Description:
* Global variables are initialized. Key assignments can be made here.
*
* Use of Global Variables:
* pctags_tagname_case -- assigned
*/
init()
{
#define CTRL_A 1
#define CTRL_P 16
/* Key assignments for "pctags_auto" and "pctags_prompt" */
assign_key( "pctags_auto", CTRL_A );
assign_key( "pctags_prompt", CTRL_P );
/* You can set the next variable to CASE_INSENSITIVE if
* you want to ignore case when entering a tagname.
*/
pctags_tagname_case = CASE_SENSITIVE;
} /* init() */
/**************************************
* Macro : pctags_auto
* Syntax: int pctags_auto( void )
* Entry : None, will extract the word under the current cursor position.
* Exit : Non-zero if entire retrieval operation was successfully completed.
* Zero if operation was not successful.
* Description:
* Function/tag under cursor is extracted from line and used to search
* thru the tagfile(s). If a match is found, the file containing the
* function's definition is loaded and the cursor is placed at the
* start of the definition.
*/
pctags_auto()
{
int ch;
string tagname;
/* Make sure cursor is currently under a valid word */
if( _delimiter( currchar() ) ){
/* Not under a word */
message( "Cursor is not under a valid word. Hit any key..." );
bell();
get_tty_char();
/* Abort */
return( UNSUCCESSFUL );
}
/* Save current cursor position on position stack */
save_position();
/* Backtrack to the start of the word (first delimiter or beginning
* of line)
*/
while( !_delimiter( currchar() ) ){
/* If at beginning of line, stop backtracking */
if( is_bol() ){
/* Stop backtracking */
left(); /* Artificial backtrack for adjustment */
break; /* Out of while-loop */
}
/* Do backtrack */
left();
}
/* Move to first character in word */
right();
/* Grab characters until end of word (delimiter or end of line) */
tagname = ""; /* Initialize tagname */
while( !_delimiter( currchar() ) ){
/* Grab char and append to tagname */
tagname = strcat( tagname, chr( currchar() ) );
/* If at end of line, stop grabbing characters */
if( is_eol() ){
break; /* Out of while-loop */
}
/* Advance to next character */
right();
}
/* Restore original cursor position */
restore_position();
/* Append a blank to the tagname */
tagname = strcat( tagname, " " );
/* Perform retrieval operation */
return( _pctags_main( tagname ) );
} /* pctags_auto() */
/**************************************
* Macro : pctags_prompt
* Syntax: int pctags_prompt( void )
* Entry : None, will prompt for function to retrieve.
* Exit : Non-zero if specified function is found, file containing function
* definition is loaded and cursor is placed at beginning of
* definition.
* Zero if specified function is not found.
* Description:
* User is prompted for the name of a function. The macro loads the
* file containing the function definition and places the cursor on the
* definition's line.
*/
pctags_prompt()
{
string tagname;
/* Prompt the user for a tagname */
tagname = get_tty_str( "Enter tagname: " );
/* Trim any leading and trailing spaces from tagname */
tagname = ltrim( rtrim( tagname ) );
/* If empty string was entered, abort */
if( strlen( tagname ) == 0 ){
/* Just return */
return( UNSUCCESSFUL );
}
/* Append a blank to the tagname */
tagname = strcat( tagname, " " );
/* Perform retrieval operation */
return( _pctags_main( tagname ) );
} /* pctags_prompt() */
/**************************************
* Macro : _delimiter
* Syntax: static int _delimiter( ch )
* Entry : ch = integer character
* Exit : Non-zero if ch is a delimiter character. Else zero.
* Note : Character is considered a delimiter if it is not an alphanumeric,
* underscore or dot (for Turbo Pascal 5.5 and Microsoft QuickPascal)
* character.
*/
_delimiter( ch )
int ch;
{
/* Return values */
#define DELIMITER 1
#define NOT_DELIMITER 0
/* Hex constants for quicker execution (eliminates atoi() calls) */
#define UPPER_A 0x41
#define UPPER_Z 0x5A
#define LOWER_A 0x61
#define LOWER_Z 0x7A
#define ZERO 0x30
#define NINE 0x39
#define UNDERSCORE 0x5F
#define DOT 0x2E
/* Check if delimiter */
if( ( ch >= UPPER_A && ch <= UPPER_Z )
||
( ch >= LOWER_A && ch <= LOWER_Z )
||
( ch >= ZERO && ch <= NINE )
||
( ch == UNDERSCORE )
||
( ch == DOT ) ){
/* No, it is not a delimiter */
return( NOT_DELIMITER );
}
/* Yes, it is a delimiter */
return( DELIMITER );
} /* _delimiter() */
/**************************************
* Macro : _convert_slashes
* Syntax: static string _convert_slashes( str )
* Entry : str = string which may contain slash (/) characters.
* Exit : str with all slashes converted to backslashes.
* Note : This is done to simplify the parsing of file specs.
*/
_convert_slashes( str )
string str;
{
int i;
/* Convert all slashes to backslashes */
while( (i = index( str, "/" )) ){
/* Convert slash to backslash */
str = strcat( strcat( substr( str, 1, i - 1 ), "\\" ),
substr( str, i + 1, strlen( str ) - i ) );
}
/* Return converted string */
return( str );
} /* _convert_slashes() */
/**************************************
* Macro : _get_tagfile
* Syntax: static string _get_tagfile( void )
* Entry : None.
* Exit : Name of next tagfile to search. Empty string if no tagfiles left to
* search.
*
* Use of Global Variables:
* pctags_first_call -- access and assign
* pctags_env_tagfiles -- access
* pctags_env_path -- access
*/
_get_tagfile()
{
string file_spec;
string single_tagfile;
/* If this is the first call to this macro in this RETRO invocation,
* get the RETRO environment variable setting, if any.
*/
if( pctags_first_call == FALSE ){
/* Get the next matching file name */
single_tagfile = next_filespec();
}else{
/* Go thru this code once per RETRO invocation */
pctags_first_call = FALSE;
/* Get RETRO environment variable */
if( (file_spec = getenv( "RETRO" )) == "" ){
/* No such variable, use the default */
file_spec = "*.tag";
}
/* Convert any slash path separators to backslashes */
file_spec = _convert_slashes( file_spec );
/* Parse any multiple file specs into single spec (may contain
* wildcards).
*/
file_spec = _parse_file_spec( file_spec );
/* Find first matching file */
if( set_filespec( file_spec ) == 0 ){
/* No matching files */
single_tagfile = "";
}else{
/* Match found, get it */
single_tagfile = next_filespec();
}
}
/* Check if we got a tagfile name */
while( single_tagfile == "" ){
/* Are there more file specs in pctags_env_tagfiles? */
if( pctags_env_tagfiles == "" ){
/* Nope, this is the end of the road */
break; /* Out of while-loop */
}
/* There are more tagfile specs. Process them. */
file_spec = _parse_file_spec( pctags_env_tagfiles );
/* Get first matching file name for tagfile spec */
if( set_filespec( file_spec ) == 0 ){
/* No matching files */
single_tagfile = "";
}else{
/* Match found, get it */
single_tagfile = next_filespec();
}
}
/* If filename found, insert any drive:path */
if( single_tagfile == "" ){
/* Return empty filename */
file_spec = "";
}else{
/* Insert drive:path */
file_spec = pctags_env_path;
file_spec = strcat( file_spec, single_tagfile );
}
/* Return tagfile spec */
return( file_spec );
} /* _get_tagfile() */
/**************************************
* Macro : _parse_file_spec
* Syntax: static string _parse_file_spec( file_spec )
* Entry : file_spec is a string file specification to parse. May contain
* wildcards. May also contain multiple specs, each separated by a
* semicolon.
* Exit : Any subsequent file specs are stored in pctags_env_tagfiles.
* The first file spec is returned (may contain wildcards).
* Any drive:path in the first file spec is copied into pctags_env_path
* for later insertion before matched filename.
*
* Use of Global Variables:
* pctags_env_tagfiles -- assign
* pctags_env_path -- assign
*/
_parse_file_spec( file_spec )
string file_spec;
{
int i;
int last_path_separator;
int semicolon;
/* Does file_spec contain multiple specs? */
if( (semicolon = index( file_spec, ";" )) == 0 ){
/* No, file_spec contains one drive:path.
* Clear pctags_env_tagfiles.
*/
pctags_env_tagfiles = "";
}else{
/* Yes, store subsequent specs in pctags_env_tagfiles */
pctags_env_tagfiles = substr( file_spec,
semicolon + 1,
strlen( file_spec ) - semicolon );
/* Get first spec */
file_spec = substr( file_spec, 1, semicolon - 1 );
}
/* Does file_spec contain a drive or path spec? */
/* Find index to last path separator */
last_path_separator = index( file_spec, "\\" );
while( (i = index( substr( file_spec,
last_path_separator + 1,
strlen( file_spec ) - last_path_separator ),
"\\" )) ){
last_path_separator = last_path_separator + i;
}
/* If no path was specified, check for a drive */
if( last_path_separator == 0 ){
last_path_separator = index( file_spec, ":" );
}
/* If drive and/or path were specified, extract from file_spec and
* store in pctags_env_path.
*/
if( last_path_separator == 0 ){
/* No drive:path specified, clear pctags_env_path */
pctags_env_path = "";
}else{
pctags_env_path = substr( file_spec, 1, last_path_separator );
}
/* Return single file_spec */
return( file_spec );
} /* _parse_file_spec() */
/**************************************
* Macro : _escape
* Syntax: static string _escape( ch, line )
* Entry : ch is a single-character string of the char to be escaped in the line
* Exit : All instances of ch in line are escaped. line is returned.
*/
_escape( ch, line )
string ch;
string line;
{
int i, i2;
/* Escape all instances of ch in line */
i = index( line, ch );
while( i ){
/* Insert a backslash before character */
line = sprintf( "%s\\%s",
substr( line, 1, i - 1 ),
substr( line, i, strlen( line ) - i + 1 ) );
/* Check for more ch's */
if( (i2 = index( substr( line,
i + 2,
strlen( line ) - i - 1 ),
ch )) == 0 ){
/* No more */
i = 0;
}else{
/* Escape it, calculate index from start of line */
i = i + i2 + 1;
}
}
/* Return escaped line */
return( line );
} /* _escape() */
/**************************************
* Macro : _line_to_reg_exp
* Syntax: static string _line_to_reg_exp( line )
* Entry : line is a string which may contain characters that would be
* interpreted as meta-characters during a search operation. None
* of these characters should really be meta-characters.
* Exit : All would-be meta-characters are escaped. Line can now be used in
* a regular-expression search. Returns line.
* Note : The entry line should not contain any characters that you want to
* be interpreted as meta-characters; those should be added after this
* operation.
*/
_line_to_reg_exp( line )
string line;
{
/* Escape certain characters so they won't be interpreted as
* meta-characters. The following chars are escaped:
* \ ? * + [ ] ^ $ | : { }
*/
/* Escape each character in turn */
line = _escape( "\\", line ); /* Must do backslash first */
line = _escape( "?", line );
line = _escape( "*", line );
line = _escape( "+", line );
line = _escape( "[", line );
line = _escape( "]", line );
line = _escape( "^", line );
line = _escape( "$", line );
line = _escape( "|", line );
line = _escape( ":", line );
line = _escape( "{", line );
line = _escape( "}", line );
/* Return fully-escaped line */
return( line );
} /* _line_to_reg_exp() */
/**************************************
* Macro : _dos_shell
* Syntax: static void _dos_shell( command_line, file_spec )
* Entry : command_line is the DOS command line to have the shell
* execute. It may contain special parameters documented below.
* Case of the special parameters is significant. It may also
* contain the DOS standard output redirection characters > or >>,
* but the command must then be bracketed with double quotes. The
* quotes will be removed before executing the command line.
* file_spec is the complete name of the desired source file.
* Exit : The command line will have been executed. No return value is sent
* back.
* Special command_line parameters:
* %s - entire file specification of desired file (file_spec parm)
* %d - drive of desired file
* %p - path (no drive) of desired file (no terminating backslash)
* %f - filename of desired file (no drive or path)
* %c - current directory (in drive:path format suitable for CD'ing)
* NOTE: The %c parameter is only supported in ME v2.20 and
* greater.
* %u - user-defined substitution string
* %% - single %
*/
_dos_shell( command_line, file_spec )
string command_line;
string file_spec;
{
int i, i2;
int fname_start;
int last_path_separator;
string drive;
string path;
string fname;
string curr_dir;
string sub_str;
/* Remove any leading and trailing whitespace from command_line */
command_line = ltrim( rtrim( command_line ) );
/* If command_line is bracketed by double quotes, remove them */
if( substr( command_line, 1, 1 ) == "\""
&&
substr( command_line, strlen( command_line ), 1 ) == "\"" ){
/* Remove double quotes */
command_line = substr( command_line,
2,
strlen( command_line ) - 2 );
}
/* Create special parameter strings */
/* Get drive:path */
last_path_separator = index( file_spec, "\\" );
while( (i = index( substr( file_spec,
last_path_separator + 1,
strlen( file_spec ) - last_path_separator ),
"\\" )) ){
last_path_separator = last_path_separator + i;
}
/* Save starting index of filename */
fname_start = last_path_separator + 1;
/* If not in root, don't count last backslash */
if( last_path_separator != 3 ){
--last_path_separator;
}
/* Break drive:path into separate strings */
drive = substr( file_spec, 1, 2 ); /* %d special parm */
path = substr( file_spec, 3, last_path_separator - 2 );/* %p special parm */
/* Get filename only */
fname = substr( file_spec,
fname_start,
strlen( file_spec ) - fname_start + 1 );/* %f special parm */
/* Get current directory */
/* NOTE: Only supported in ME v2.20 or later */
if( VER220_PLUS ){
curr_dir = getcwd(); /* %c special parm */
}else{
curr_dir = ""; /* %c special parm */
}
/* Parse command line, replacing special parameters */
i = index( command_line, "%" );
while( i ){
/* Get character after "%" */
switch( substr( command_line, i + 1, 1 ) ){
case "s" : /* Entire file specification of desired file */
sub_str = file_spec;
break;
case "d" : /* Drive of desired file */
sub_str = drive;
break;
case "p" : /* Path (no drive) of desired file */
sub_str = path;
break;
case "f" : /* Filename of desired file */
sub_str = fname;
break;
case "c" : /* Current directory (ME v2.20+ only) */
sub_str = curr_dir;
break;
case "u" : /* User-defined substitution string */
sub_str = get_tty_str( "Enter substitution string: " );
break;
case "%" : /* Single percent sign */
sub_str = "%";
break;
default : /* Unrecognized, replace with empty string */
sub_str = "";
break;
}
/* Replace special parameter with substitution string */
command_line = strcat( strcat( substr( command_line, 1, i - 1 ), /* First portion */
sub_str ), /* Substitution string */
substr( command_line, /* Last portion */
i + 2,
strlen( command_line ) - sub - 1 ) );
/* Look for any more "%" */
if( (i2 = index( substr( command_line,
i + 1,
strlen( command_line ) - i + 1 ),
"%" )) ){
/* There are more parameters, process them */
i = i + i2;
}else{
/* No more parameters */
i = 0;
}
}
/* Send command line to secondary DOS command processor for execution */
/* Note: ME will notify the user of the executing command line */
os_command( command_line );
} /* _dos_shell() */
/**************************************
* Macro : _pctags_main
* Syntax: static int _pctags_main( function_name )
* Entry : function_name = function name to locate and retrieve the file in
* which it is defined
* Exit : Non-zero value if function definition is found, file containing the
* definition is loaded and cursor is placed on the definition's
* line.
* Else return zero.
* Description:
* RETRO operation is performed. This requires the following steps:
* -- Cycle through all required tagfiles. Default = *.tag or
* all tagfiles specified in RETRO environment variable
* which may contain multiple file specs, each with wildcards,
* separated by semicolons. For example,
* SET RETRO=c:\me\tagfiles\*.tag;c:\prog\*.tag
* -- Search each tagfile for the function_name string.
* -- If not found in any tagfile, display message and quit.
* -- If found, get name of file and definition line from tagfile.
* -- Close tagfile.
* -- Load file for editing.
* -- If file cannot be found, tag information contains an "EXEC"
* command and environment variable RETROEXEC is defined,
* execute the command line value assigned to it. Try to load
* the file again.
* -- Search file for definition line.
* -- If any of these operations fail, display appropriate error
* message and quit.
*
* Use of Global Variables:
* pctags_first_call -- assign
* pctags_tagname_case -- access
*/
_pctags_main( function_name )
string function_name;
{
int org_buff_id;
int buff_id;
int found_match;
int ret_value;
int file_start;
int decl_start;
int continue_search;
int exec_env;
int line_number;
int special_chars;
string tagfile_name;
string line;
string file_spec;
string decl_line;
string env_retroexec;
/* Save current buffer context */
org_buff_id = currbuf();
/* Set case sensitivity for tagname search */
ignore_case( pctags_tagname_case ); /* User-settable in init() */
/* Insert start-of-line metacharacter into function_name string */
function_name = sprintf( "^%s", function_name );
/* Initialize flags */
found_match = FALSE;
pctags_first_call = TRUE; /* Global flag for _get_tagfile() */
/* Cycle thru all RETRO (or default) tagfiles until done or match found */
while( !found_match ){
/* Get a tagfile */
tagfile_name = _get_tagfile();
/* If no more tagfiles to get, quit */
if( strlen( tagfile_name ) == 0 ){
/* Tagname not found in tagfiles */
message( "%snot found. Hit any key...",
substr( function_name,
2,
strlen( function_name ) - 1 ) );
bell();
get_tty_char();
/* Exit RETRO, return "failure" code */
ret_value = UNSUCCESSFUL;
goto exit;
}
/* Create temporary tagfile buffer and load tagfile */
/* Note: This is guaranteed to work because we already know
* the file exists.
*/
buff_id = create_buffer( tagfile_name );
setcurrbuf( buff_id ); /* Make it the current buffer */
gobof(); /* Force to start of file */
/* Search tagfile for function name */
if( fsearch( function_name ) == 0 ){
/* Did not find function_name in this tagfile */
/* Delete the buffer */
setcurrbuf( org_buff_id ); /* Reset to valid buffer */
delete_buffer( buff_id ); /* Delete tagfile buffer */
/* Try another tagfile */
continue; /* Back to while-loop */
}
/* Found a good match! */
/* Stop searching tagfiles */
found_match = TRUE;
/* Read line with match, including newline */
line = currline();
/* Done with tagfile, close it */
setcurrbuf( org_buff_id ); /* Reset to valid buffer */
delete_buffer( buff_id );
/* Format of line:
* Column 1: Function name searching for (variable length)
* Single space terminator
* Optional RETRO commands (! and #)
* Complete file specification of file containing definition
* of function (variable length)
* Single space terminator
* Caret (^) character signifying the start of the definition
* line
* Line from file that defines the function, including carriage
* return (variable length)
* End of line is the last character in the definition line,
* i.e. carriage return
* As an example:
* "function c:\dir\file.c ^int function( arg1, arg2 )\n"
*/
/* Determine starting indices of file spec and definition line */
file_start = index( line, " " );
++file_start;
decl_start = index( substr( line,
file_start,
strlen( line ) - file_start + 1 ),
" " ) + file_start;
/* Extract file spec and definition line */
file_spec = substr( line, file_start, decl_start - file_start );
/* Note: Do not include leading '^' in decl_line */
decl_line = substr( line,
decl_start + 1,
strlen( line ) - decl_start );
/* Check file_spec for special leading characters */
continue_search = TRUE;
exec_env = FALSE;
line_number = FALSE;
special_chars = 1; /* One-base strings */
while( continue_search ){
switch( substr( file_spec, special_chars, 1 ) ){
case "!" :
/* If file_spec not found, execute RETROEXEC
* environment variable command line. This is
* usually used to extract the file from a
* version-control library.
*/
exec_env = TRUE;
/* Increment string index */
++special_chars;
break;
case "#" :
/* Line number of definition is stored in
* tagfile instead of line contents.
*/
line_number = TRUE;
++special_chars;
break;
default :
/* Stop parsing special chars */
continue_search = FALSE;
break;
}
}
/* Remove all leading special chars from file_spec */
file_spec = substr( file_spec,
special_chars,
strlen( file_spec ) - special_chars );
}
/* Verify that file_spec exists */
if( set_filespec( file_spec ) == 0 ){
/* If exec_env active, get RETROEXEC value */
if( exec_env ){
if( (env_retroexec = getenv( "RETROEXEC" )) != "" ){
/* Execute the variable's value */
_dos_shell( env_retroexec, file_spec );
}
}
/* Check for file's existence now */
if( set_filespec( file_spec ) == 0 ){
/* Still not found */
message( "%s does not exist. Update tagfile. Hit any key...",
file_spec );
bell();
get_tty_char();
/* Return "failure" value */
ret_value = UNSUCCESSFUL;
goto exit; /* Cleanup and quit */
}
}
/* Create new buffer for file, make it the current buffer and load
* the file into it.
*/
buff_id = create_buffer( file_spec ); /* Should never fail, file guaranteed to exist */
setcurrbuf( buff_id );
gobof(); /* Force to beginning of file */
/* Searching for line contents or line number? */
if( line_number ){
/* Goto specified line number in source file */
goline( atoi( decl_line ) );
}else{
/* Search for definition line */
/* Escape all chars in line that would be interpreted as
* meta-characters.
*/
decl_line = _line_to_reg_exp( decl_line );
/* Surround line with start-of-line(^) and end-of-line($)
* meta-chars.
*/
decl_line = sprintf( "^%s$", decl_line );
/* Search file for definition line */
if( fsearch( decl_line ) == 0 ){
/* Line not found, tagfile is obsolete */
/* Delete file and buffer */
setcurrbuf( org_buff_id ); /* Reset current buffer */
delete_buffer( buff_id );
/* Tell user */
message( "Update %s with %s. Hit any key...",
tagfile_name,
file_spec );
bell();
get_tty_char();
/* Return "failure" code */
ret_value = UNSUCCESSFUL;
goto exit;
}
}
/* Found function definition! */
/* Show buffer in new window */
show_buffer( buff_id );
/* Set "success" return code */
ret_value = SUCCESSFUL;
exit:
/* Set case-sensitivity upon exit */
/* Note: You may change this to TRUE if you want to ignore case; ME
* does not provide a method of getting the case status so we don't
* know what it was set to on entry.
*/
ignore_case( FALSE );
/* Return SUCCESSFUL or UNSUCCESSFUL */
return( ret_value );
} /* _pctags_main() */
/**************************************/