home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
p2demo21.exe
/
PEL
/
NUCLEUS.PEL
< prev
next >
Wrap
Text File
|
1995-03-22
|
58KB
|
2,275 lines
# $Header: P:\source\wmacros\nucleus.pev 1.158 22 Mar 1995 13:45:32 pfhmlw0 $
##############################################################################
#
# Compuware Corporation
# 31440 Northwestern Highway
# Farmington Hills, Michigan 48334-2564
#
# This source code listing contains information that is
# proprietary to Compuware Corporation and may not be copied
# duplicated, translated, transmitted, stored, retrieved
# or in any manner or by any method conveyed or disclosed
# to a third party or parties without express written
# permission from Compuware Corporation.
#
#
##############################################################################
#### $Workfile: nucleus.pel $: manifest constants and core utilities
# reserved global variables
global TRUE = 1
global FALSE = 0
global UNINITIALIZED = "uninitialized"
global backup_files_enabled;
global testmode = 0; # Editor was started in test mode.
## DOS file attributes:
global FILEMODE_NORMAL = 0x00000021
global _READ_ONLY = 0x00000001
global _HIDDEN = 0x00000002
global _SYSTEM = 0x00000004
global _VOL_ID = 0x00000008 # Not valid for OS/2
global _SUBDIR = 0x00000010
global _ARCHIVE = 0x00000020
global _NORMAL = 0x00000021
global ONLY_READ_ONLY = 0x00000101
global ONLY_HIDDEN = 0x00000202
global ONLY_SYSTEM = 0x00000404
global ONLY_VOL_ID = 0x00000808 # Not valid for OS/2
global ONLY_SUBDIR = 0x00001010
global ONLY_ARCHIVE = 0x00002020
## Event numbers:
global EVENT
local EVENT_setup = setup_events()
global function setup_events()
{
EVENT.EMULATION_CHANGED = 9
EVENT.IDLE_TIME = 10
EVENT.CTRL_BREAK = 11
EVENT.INVALID_PCHAR = 12
EVENT.UNASSGN_KEY = 13
EVENT.NEW_EDIT_FILE = 14
EVENT.NEW_CURNT_BUFFER = 15
EVENT.NEW_CURNT_WINDOW = 16
EVENT.HELP_INVOKED = 17
EVENT.IDLE_THRESHOLD = 18
EVENT.EXIT_EDITOR = 19
EVENT.TEMP_SPACE_OVFLW = 20
EVENT.EDIT_FILE_SAVE = 21
EVENT.KEYPRESS = 22
EVENT.READ_ONLY_MOD = 23
EVENT.NEW_SCREEN_SIZE = 24
EVENT.NEW_CURNT_SCREEN = 25 # (Reserved)
EVENT.DISPLAY_UPDATE = 26
EVENT.PROCESS_COMPLETE = 27
EVENT.MOUSE_LEFT_DOWN = 28
EVENT.MOUSE_RIGHT_DOWN = 29
EVENT.MOUSE_MID_DOWN = 30
EVENT.MOUSE_LEFT_UP = 31
EVENT.MOUSE_RIGHT_UP = 32
EVENT.MOUSE_MID_UP = 33
EVENT.MOUSE_LEFT_CLICK1 = 34
EVENT.MOUSE_RIGHT_CLICK1 = 35
EVENT.MOUSE_MID_CLICK1 = 36
EVENT.MOUSE_LEFT_CLICK2 = 37
EVENT.MOUSE_RIGHT_CLICK2 = 38
EVENT.MOUSE_MID_CLICK2 = 39
EVENT.INSERT_KEY = 40
EVENT.INSERT_STRING = 41
EVENT.DELETE_CHARS = 42
EVENT.INSERT_NEWLINE = 43
EVENT.SHELL_EXIT = 44
EVENT.FUNCTION_CHANGED = 45
EVENT.DELETING_BUFFER = 46
EVENT.DELETING_WINDOW = 47
EVENT.SYSTEM_MENU_KEY = 48
EVENT.WINDOW_MODE_CHANGE = 49
EVENT.BUFFER_CREATED = 50
EVENT.CPM = 51
EVENT.ERROR = 52 # (Reserved)
EVENT.LMOUSE_DRAG = 53
EVENT.MMOUSE_DRAG = 54
EVENT.RMOUSE_DRAG = 55
EVENT.RESIZE_EDITWIN = 56
EVENT.SCROLL_HORZ = 57
EVENT.SCROLL_VERT = 58
EVENT.NEW_EMPTY_BUFFER = 59
EVENT.KEYPRESS_AFTER = 60
EVENT.EDITOR_RUNNING = 61
EVENT.MENU_COMMAND = 62
EVENT.TOOLBAR_COMMAND = 63
EVENT.PIPE_DATA = 64
EVENT.FIRST_MOD = 65
EVENT.CLOSING_REMOTE_WINDOW = 66
EVENT.FILE_DROPPED = 67
EVENT.UNMOD = 68
EVENT.UNABLE_TO_OPEN_FILE = 69
EVENT.NEW_CURNT_EDITWIN = 70
EVENT.ACTIVATE = 71
EVENT.DEACTIVATE = 72
EVENT.WINDOW_CREATED = 73
EVENT.TRACKING_DONE = 74
EVENT_setup = 1; # prevent warning that EVENT_setup is not used!
return 1 # return someting
}
## System file numbers: (see locate_cpe_file)
global CPE_FILE_CONFIG = 1 # cpe.cfg
global CPE_FILE_AE = 2 # cpe.ae
global CPE_FILE_BINDINGS = 3 # bindings.txt
global CPE_FILE_KEYMAP = 4 # keymap.txt
global CPE_FILE_LANGUAGE = 5 # language.pel
global CPE_FILE_INI = 6 # cpe.ini
global CPE_FILE_HELP = 7 # cpe.hlp
## System flags (for the system() primitive)
global SYS_NONE = 0x0000
global SYS_SHELL = 0x0002
global SYS_ASYNC = 0x0004
global SYS_DETACHED = 0x0008 # in Windows this is the same as SYS_ASYNC.
global SYS_NOEXPOSE = 0x0010
## System flags (for the system() primitive) for OS/2 Only.
global SYS_SESSION = 0x0001
global SYS_NOSESSION = 0x0020
global SYS_QUIET = 0x0100
global SYS_DOSSHELL = 0x0200
## System flags (for the system() primitive) for Windows Only.
global SYS_HIDE = 0x0020
global SYS_MAXIMIZE = 0x0040
global SYS_MINIMIZE = 0x0080
# Pleae note that SYS_NOSESSION and SYS_HIDE both have similar effects,
# the window is hidden in windows, a seperate session is NOT started and
# therefore not viewable in OS/2. (However, a PM or Full-Screen program
# is started with SYS_NOSESSION set will still be visible, it will only
# hide Windowed (Character-Mode) programs)
#
# If a DOS box is started by the system command in Windows, the SYS_HIDE,
# SYS_MAXIMIZE, and SYS_MINIMIZE will only take affect if the _default.pif
# file specifies minimized. If it specifies full-screen the DOS box will
# be full-screen and nothing can be done to alter that.
#
# If a Windows (or DOS) program is started using SYS_HIDE and SYS_ASYNC
# is NOT set, Preditor may be locked forever as it waits for the program
# to exit unless it exits by itself (since it will be hidden, it can NOT
# be closed and it won't even show up in the Task-List!)
## Operating system constants for use with the isWindows() function
global OS2 = 0
global WINDOWS = 1
global WIN_OS2 = 2
## count_command_line_files()
#
# count command line filenames
#
local files_on_command_line = 0; # Counts # of files on command line.
local files_counted = 0; # TRUE if the files have been counted.
global start_editor_minimized = 0;
global function count_command_line_files()
{
local arg, iarg, option
if (!files_counted)
{
files_counted = TRUE
files_on_command_line = 0
for ( iarg=1; iarg<ARGC; iarg++ )
{
arg = ARGV[iarg]
option = prefix(arg,1)
if ( option == "-" || option == "/")
{
arg = substr(arg,2)
option = prefix(arg,1)
if ( option == "m" || option == "M" )
start_editor_minimized = 1
while ( arg )
{
# Check options that accept arguments
if (cindex("fFlLPRgGaAcCiI", prefix(arg,1)))
{
arg = substr(arg,2)
if ( arg == "" )
iarg++
else
arg = ""
}
else
arg = substr(arg,2)
}
}
else
files_on_command_line++
}
}
return files_on_command_line
}
## process_command_line()
#
# handle command line options and invoke edit_file on filenames
#
global function process_command_line()
{
local cmd_line_error
local arg, iarg, i, option
local recordKeysFile
local playbackKeysFile
local files_specified = FALSE
# process command line arguments one at a time
for ( iarg=1; iarg<ARGC; iarg++ )
{
arg = ARGV[iarg]
option = prefix(arg,1)
if ( option == "-" || option == "/")
{
arg = substr(arg,2)
while ( arg )
{
option = prefix(arg,1)
arg = substr(arg,2)
#
# invoke startup Function
#
if ( option == "f" || option == "F" )
{
if ( arg == "" )
arg = ARGV[ ++iarg ]
arg = trim( ltrim( arg ));
arg = trim( ltrim( arg, "\"" ), "\"" );
execute_function( arg )
arg = ""
}
#
# Readonly option
#
else if ( option == "r" )
{
set_default_buffer_flag( BUFFER_READ_ONLY, TRUE )
toggle_buffer_flags( BUFFER_READ_ONLY, TRUE )
}
#
# Load PVCS group file
#
else if ( option == "l" || option == "L" )
{
if ( arg == "" )
arg = ARGV[ ++iarg ]
pvcs_get_group( arg );
arg = ""
}
#
# control-Z is eof option
#
else if ( option == "z" || option == "Z" )
{
default_buffer_eof_string = buffer_eof_string = chr( 26 )
}
#
# playback keys stored in key file
#
else if ( option == "P" )
{
playbackKeys = TRUE
if ( arg == "" )
arg = ARGV[ ++iarg ]
playbackKeysFile = arg
arg = ""
}
#
# save all keys to playback file
#
else if ( option == "R" )
{
recordKeys = TRUE
if ( arg == "" )
arg = ARGV[ ++iarg ]
recordKeysFile = arg
arg = ""
}
#
# start editor for WorkFrame communications
#
else if (option == "w" || option == "W" )
{
optional_function("initialize_wf_dde")
}
#
# start editor for DDE communications
#
else if (option == "d" || option == "D" )
{
optional_function("initialize_dde")
}
#
# Goto Line-number option.
#
else if ( option == "g" || option == "G" )
{
if ( arg == "" )
arg = ARGV[ ++iarg ]
goto_line( atoi(arg) );
arg = ""
}
#
# start editor in test mode
#
else if (option == "t" || option == "T" )
{
testmode = TRUE
}
#
# start editor minimized
#
else if (option == "m" || option == "M" )
{
start_editor_minimized = 1
}
else if (option == "n" || option == "N" )
{
# this parameter handled in the editor
}
#
# invoke awk function Library
# or Load Config file.
# or Load Ini file.
#
# specified filename is processed
# in C code so skip to the next argument
#
else if (option == "a" || option == "A" || \
option == "c" || option == "C" || \
option == "i" || option == "I" )
{
if ( arg == "" )
iarg++
arg = ""
}
#
# unrecognized switch character
#
else if (optional_function("xpp_command_line", option))
{
}
else if (optional_function("user_command_line", option))
{
}
else
{
cmd_line_error = "option " option " not recognized"
arg = ""
}
}
}
else
{
# treat arguments not beginning with "-" or "/" as filenames
create_buf_and_win(arg)
files_specified = TRUE
if (!files_counted)
files_on_command_line++
}
}
files_counted = TRUE
# make the first buffer in the list the current buffer
# if there were command-line files specified
if ( files_specified && mdi_mode != 2 )
next_buffer()
# record/playback session support
if ( playbackKeys )
playbackKeysInitialize( playbackKeysFile )
else if ( recordKeys )
recordKeysInitialize( recordKeysFile )
display_update() # so following messages show up
if (cmd_line_error)
warning( cmd_line_error )
}
## display copyright notice and version label
#
global function print_version()
{
optional_function( "enable_status_bar_messages" )
notify( version_label() )
optional_function( "restore_status_bar" )
}
local function version_label()
{
return editor_title "\n" \
version "- Copyright (c) 1994, 1995\n" \
"Compuware Corporation\n" \
"All Rights Reserved."
}
## prompt the user for a command, and run it
#
global function system_key(com)
{
local err = 0
if (!com)
com = ltrim( prompt_history( "SYSTEM", "System Command: ", "", 1, 1, "command" ))
if(com)
{
add_prompt_history( "SYSTEM", com )
err = system_pause(com)
}
# else
# err = system()
if (err)
{
if (!com || match(com, "^.*[@&].* "))
message("process id = %d", err)
else
warning("%s exited with %d", com ? com : "System Command", err)
}
else
message( "" )
}
## Utility function to set an environment variable from the command line.
#
global function setenv(var, value)
{
ENV[var] = value
}
## Define cd as an alias for chdir
#
global function cd(path)
{
if (argcount())
chdir(path)
message(getcwd())
}
## Define pwd to diaplay the current directory.
#
global function pwd()
{
message(getcwd())
}
## utilities
#
global function min(a,b)
{
return (a<b) ? a : b;
}
global function max(a,b)
{
return (a>b) ? a : b;
}
global function abs(n)
{
return (n+0<0) ? -n : n;
}
# quote all regex characters in a string
function quote_regex( s ) #PUBLIC #STR
{
local r = s
gsub( "[\\\\.*+?<>{}()^$|\\[\\]]", "\\\\&", r )
return r
}
# quote all escape characters in a string,
function quote_string( s ) #PUBLIC #STR
{
local r = s
gsub( "[\"\\\\]", "\\\\&", r )
return r
}
function quote_quote( s ) #PUBLIC #STR
{
local r = s
gsub( "\"", "\\\"", r )
return r
}
# unquote all escape characters {backslashes(\) & quotes(")} in a string,
function unquote_string( s ) #PUBLIC #STR
{
gsub(/\\\\/, "\\", s)
gsub(/\\\"/, "\"", s)
return s
}
## string manipulation utilities
#
global function strrepeat( s, n ) #PUBLIC #STR
{
local t = ""
while (n-- > 0)
{
t = s t
}
return t
}
global function compress( s, t ) #PUBLIC #STR
{
local repl
if (s)
{
repl = length(t) ? substr(t,1,1) : " "
gsub( build_cc(t) "+", repl, s )
}
return s
}
global function ltrim( s, t ) #PUBLIC #STR
{
if (s)
sub( "^" build_cc(t) "+", "", s )
return s
}
global function trim( s, t ) #PUBLIC #STR
{
if (s)
sub( build_cc(t) "+$", "", s )
return s
}
local function build_cc( t )
{
#
# Build a regular expression "character class" containing the specified
# list of characters. If no characters are specified, return the character
# class "[ \t]" (the default pattern used by trim, ltrim and compress)
# which matches either the space or tab characters.
#
if (t)
{
# quote the "\" and "]" characters; also quote "^" only
# if it is the first character in the list
gsub( /\\/, "\\\\", t )
gsub( /\]/, "\\]", t )
sub( /^\^/, "\\^", t )
return "[" t "]"
}
else
return "[ \t]"
}
global function trans( s, tr, repl ) #PUBLIC #STR
{
local len
local i
local result = ""
local ch
if (!tr)
return ""
if (!repl)
repl = ""
while (s != "")
{
ch = substr( s,1,1 )
s = substr( s,2 )
len = length( tr )
i = 1
while (len--)
{
if (gsub( quote_regex(substr( tr, i, 1 )), substr( repl, i, 1 ), ch ))
break
else
i++
}
result = result ch
}
return result
}
## push_keymap and pop_keymap
#
# push the specified keymap id onto the keymap stack. If no keymap
# id is specified, push the current keymap
#
# pop of the top element on the keymap stack and make it the current
# keymap
#
local keymapStack
local keymapIndex
global function push_keymap( kid ) #PUBLIC #INT
{
local oldkmp = current_keymap
keymapStack[ keymapIndex++ ] = current_keymap
if ( argcount() ) # set to new keymap if one was specified
{
if (kid != current_keymap)
{
current_keymap = kid
if (current_keymap == oldkmp)
{
keymapIndex--
return FALSE # didn't set it
}
}
}
return TRUE
}
global function pop_keymap() #PUBLIC #INT
{
if( keymapIndex > 0 )
{
current_keymap = keymapStack[ --keymapIndex ]
return TRUE
}
else
return FALSE
}
local function read_temp_file( sel_type, second_temp_file )
{
local longest_line
local old_cb = current_buffer
local i
if ( sel_type != COLUMN_SELECTION )
read_file( second_temp_file )
else
{
current_buffer = create_buffer( "", second_temp_file, BUFFER_SYSTEM )
for ( i = 1; i <= buffer_last_line; i++ )
{
current_line = i
longest_line = max( longest_line, current_line_width )
}
goto_buffer_top()
begin_selection( COLUMN_SELECTION )
goto_buffer_bottom()
current_column = longest_line
copy_to_scrap()
delete_buffer()
current_buffer = old_cb
insert_scrap()
}
}
## invoke a filter and replace the selected region with the result
#
global function filter( command ) #PUBLIC #VOID
{
local first_temp_file
local second_temp_file
local block_marked
local status
first_temp_file = create_temp_name()
second_temp_file = create_temp_name()
save_position()
#
# Write the marked block out to the first temp file.
#
block_marked = selection_type()
if ( block_marked )
{
end_selection()
goto_mark( selection_mark_top() )
if ( block_marked == LINE_SELECTION )
goto_bol()
else if ( and(buffer_flags, BUFFER_IN_VIRTUAL_SPACE) )
prev_char()
}
else
{
# no selection - select the entire buffer
goto_buffer_bottom()
begin_selection( LINE_SELECTION )
goto_buffer_top()
end_selection()
}
write_marked_block( first_temp_file )
#
# Filter the first_temp_file through the "command" to generate
# the second_temp_file.
#
if ( system(command, first_temp_file, second_temp_file, second_temp_file) >= 0 )
{
#
# Delete the selection, then replace it with the contents
# of the second_temp_file.
#
delete_chars() # delete the selection
# read_file( second_temp_file )
read_temp_file( block_marked, second_temp_file )
restore_position( 0 )
status = FALSE
}
else
{
# system command failed
if ( !block_marked )
remove_selection()
restore_position( 1 )
status = TRUE
}
unlink( second_temp_file )
unlink( first_temp_file )
return status
}
#-------------- code to record and playback an edit session ---------------#
local recordFileName
local recordKeys
local playbackFile
local playbackKeys
local playbackMacroId
local recordMacroId
global function recordKeysInitialize( keyfname )
{
recordFileName = keyfname
recordMacroId = function_id( "record_macro_exit" )
attach_event_handler( EVENT.EXIT_EDITOR, recordMacroId )
record_macro()
return TRUE
}
global function playbackKeysInitialize( keyfname )
{
if ( filemode(keyfname) >= 0 )
{
playbackFile = keyfname
playbackMacroId = function_id( "playbackkeys" )
playbackkeys()
return TRUE
}
else
{
warning( "File '%s' doesn't exist", keyfname )
return FALSE
}
}
global function playbackkeys()
{
load_key_file(0, playbackFile)
playback_macro()
}
global function record_macro_exit()
{
delete_event( EVENT.EXIT_EDITOR, recordMacroId )
# end record
record_macro()
write_key_file(recordFileName)
}
# -------------------------------------------------------------------------- #
## attach_cleanup_handler()
#
# If the pvcsedit.ae file is changed while the editor is running (typically
# by recompiling a .pel file), the error "Currently executing function has
# been changed" may result. In this case, an event is triggered upon
# return from the system command. Here, we use that event to finish up
# whatever function was running at the time. The "cleanup_handler" function
# must reside in a different file than that from which it was called to be
# effective. (See also the comments within the system_window_command()
# function in system.pel).
local function_to_call
global function attach_cleanup_handler( handler_name )
{
if (( function_to_call = function_id( handler_name )))
{
attach_event_handler( EVENT.FUNCTION_CHANGED, "cleanup_handler" )
}
}
global function cleanup_handler()
{
delete_event( EVENT.FUNCTION_CHANGED, "cleanup_handler" )
execute_function( function_to_call )
}
# -------------------------------------------------------------------------- #
## insert whole lines
#
global function paste_lines()
{
goto_bol()
insert_scrap()
}
## delete whole lines
#
global function cut_lines()
{
if( selection_type() != LINE_SELECTION )
begin_selection( LINE_SELECTION )
delete_to_scrap()
}
## toggle pause on error flag
#
global function toggle_pause( on ) #PUBLIC #VOID
{
if (argcount())
pe( on )
else
pe()
}
global function pe( on ) #PUBLIC #VOID
{
if( argcount() < 1 )
pause_on_error = !pause_on_error
else
pause_on_error = !!(0+on) != 0
if( pause_on_error )
message( "pause_on_error Enabled" )
else
message( "pause_on_error Disabled" )
}
## arrays containing the names of the editor system files
#
global cpe_filename
local existing_cpe_file
local primary_cpe_dir
## setup the cpe_filename array
#
global function init_cpe_filename()
{
# initialize filename array if necessary
if ( !cpe_filename )
{
cpe_filename[CPE_FILE_CONFIG] = editor_config
cpe_filename[CPE_FILE_AE] = editor_ae
cpe_filename[CPE_FILE_BINDINGS] = "bindings.txt"
cpe_filename[CPE_FILE_KEYMAP] = "keymap.txt"
cpe_filename[CPE_FILE_LANGUAGE] = "language.pel"
cpe_filename[CPE_FILE_INI] = editor_inifile
cpe_filename[CPE_FILE_HELP] = editor_helpfile
}
}
## return the name of an existing file using the CPE path
#
# valid argument values are:
# CPE_FILE_AE # cpe.ae
# CPE_FILE_CONFIG # cpe.cfg
# CPE_FILE_KEYMAP # keymap.txt
# CPE_FILE_BINDINGS # bindings.txt
# CPE_FILE_LANGUAGE # language.pel
# CPE_FILE_INI # cpe.ini
# CPE_FILE_HELP # cpe.hlp
#
global function locate_cpe_file( cpe_id )
{
local fn
local element
local path
local result
init_cpe_filename()
# has the file already been located?
if ( cpe_id in existing_cpe_file )
return existing_cpe_file[cpe_id]
else if ( cpe_id in cpe_filename )
{
fn = cpe_filename[cpe_id]
do
{
# look first in the current or specified directory
if ( filemode( fn ) >= 0 )
{
existing_cpe_file[cpe_id] = fn = buildpath( fn )
return fn
}
else
{
# strip out the filename and look in the current directory
fn = path_fname(fn) path_ext(fn)
if (fn != cpe_filename[cpe_id])
{
if ( filemode( fn ) >= 0 )
{
existing_cpe_file[cpe_id] = fn = buildpath( fn )
return fn
}
}
# search the editor_path_var path
#
path = ENV[ editor_path_var ]
while ( path )
{
# extract a directory from the semicolon separated list
if ( match( path, /;/ ))
{
element = trim( substr( path, 1, RSTART-1 ))
path = ltrim( substr( path, RSTART+1 ))
}
else
{
element = path
path = 0
}
# treat path elements consisting only of a
# drive letter as the cwd on that drive
if ( match( element, /:$/ ))
element = element "."
# assemble filename (multiple backslashes are ok)
result = buildpath( element "\\" fn )
# check existence
if ( filemode( result ) >= 0 )
{
existing_cpe_file[cpe_id] = result
return result
}
}
# try ARGV[0]
if ( match( ARGV[0], /.*\\/ ))
{
result = buildpath( substr( ARGV[0], RSTART, RLENGTH ) fn )
if ( filemode( result ) >= 0 )
{
existing_cpe_file[cpe_id] = result
return result
}
}
# if all of that failed, try again after removing
# the "help\" part of the name, before giving up
if ( substr(fn,1,5) == "help\\" )
fn = substr( fn, 6 )
else
break
}
} while ( fn )
}
# return null
}
## return the first directory given in the CPE path
#
global function editor_path( cpe_id )
{
# cpe_id is an optional argument containing the id of
# one of the editor support files (e.g. CPE_FILE_CONFIG).
# If specified, the name of the file will be appended
local fn
local path
local fmode
if ( primary_cpe_dir )
{
# cpe path has already been processed
path = primary_cpe_dir
}
else if (( path = ENV[ editor_path_var ] ))
{
# handle a semicolon separated list of directories
if ( match( path, /;/ ))
path = substr( path, 1, RSTART-1 )
# treat path elements consisting only of a
# drive letter as the cwd on that drive
if ( match( path, /:$/ ))
path = path "."
path = buildpath( path "\\" )
# handle root as a special case since filemode of
# root is unreliable on certain networks
if ( path !~ /:[\\/]$/ )
{
# if the directory doesn't exist, use the cwd
fmode = substr( path, length( path )) == "\\" \
? filemode( substr( path, 1, length( path )-1 )) \
: -1
if ( (fmode <= 0) || !and( fmode, _SUBDIR ))
path = buildpath( "." )
}
primary_cpe_dir = path
}
init_cpe_filename()
# if an optional file argument was specified, append the name of the
# appropriate file
if ( cpe_id in cpe_filename )
{
fn = cpe_filename[cpe_id]
if (fn == path_fname(fn) path_ext(fn))
return path fn
else
return fn
}
else
return path
}
## path_path
#
# return the drive:path of a filespec, trailing slash/backslash
# is included.
#
global function path_path(fspec)
{
local last_fs
local last_bs
if (length(fspec) == 0)
return "";
else
{
last_fs = rindex( fspec, "/" )
last_bs = rindex( fspec, "\\" )
return prefix( fspec, (last_fs > last_bs) ? last_fs : last_bs );
}
}
## bld_fnam
#
# build a filename out of its components
#
global function bld_fnam(path, name, suffix)
{
local name1, name2, name3, name4;
name1 = path_path(path);
name2 = path_fname(name);
name3 = path_ext(suffix);
if (length(name3) == 0)
name3 = "." suffix;
name4 = name1 name2 name3
gsub("\"", "", name4)
return name4
}
## mkpath
#
# create a directoy including all intermediate directories.
#
global function mkpath(path)
{
local dirs, i
local subdir = ""
path = buildpath(path)
split(path, dirs, "\\")
for (i in dirs)
{
if (i == 1)
subdir = dirs[i]
else
{
subdir = subdir "\\" dirs[i]
if (filemode(subdir) != _SUBDIR)
{
if (!mkdir(subdir))
return FALSE
}
}
}
return TRUE
}
## quit from editor
#
# don't want to do exit_editor if in_exit is TRUE
local in_exit = FALSE
global function exit_editor()
{
local buf
local priorMessageLevel
local i = buffers_modified
local oldBuffer = current_buffer
really_close = TRUE
############################################
# new way of saving changes before quiting #
############################################
optional_function( "exit_vdiff", 0 ) # if vdiff is active, close it down
save_changes_list = TRUE
if ( in_exit )
{
save_changes_list = FALSE
return
}
else if ( buffer_list(0, 1) )
{
really_close = TRUE
in_exit = TRUE
return
# quit( 1, 0 )
}
else
{
really_close = FALSE
save_changes_list = FALSE
in_exit = FALSE
return
}
############################################
############################################
if ( i && in_exit == FALSE )
{
buf = sprintf( "%d %s been modified, Exit[ynw]? ", \
i, i > 1 ? "buffers have" : "buffer has")
i = tolower( confirm(buf, "yYnNwW") )
if (i == "w")
{
priorMessageLevel = message_level
message_level = 0
if ( !write_all_buffers() )
{
message_level = priorMessageLevel
current_buffer = oldBuffer
really_close = FALSE
return
}
else
really_close = TRUE
}
else if ( i == "y" )
really_close = TRUE;
else if ( i == "n" )
really_close = FALSE;
else
really_close = FALSE;
}
}
global function done2()
{
# if we are in detached mode just close the current
# window
if ( mdi_mode == 2 )
{
delete_window()
return
}
else
{
done()
}
}
global function done(exit_editor)
{
local buf
local priorMessageLevel
local i = buffers_modified
#CFV added if-statement so that we can just do a quit without getting
# the save-buffer-list if there are modifications
if (exit_editor)
{
delete_event(EVENT.EXIT_EDITOR, "exit_editor")
quit(1, 0);
return;
}
# don't quit by default
really_close = FALSE
############################################
# new way of saving changes before quiting #
############################################
save_changes_list = TRUE
if ( buffer_list(0, 1) )
{
in_exit = TRUE
really_close = TRUE
quit( 1, 0 )
}
else
{
in_exit = FALSE
really_close = FALSE
save_changes_list = FALSE
return
}
############################################
############################################
if ( i )
{
buf = sprintf( "%d %s been modified, Exit[ynw]? ", \
i, i > 1 ? "buffers have" : "buffer has")
i = tolower( confirm(buf, "yYnNwW") )
if ( i != "n" )
in_exit = TRUE
if (i == "w")
{
priorMessageLevel = message_level
message_level = 0
if ( !write_all_buffers() )
{
message_level = priorMessageLevel
return
}
}
else if (i != "y")
return
}
really_close = TRUE
quit( 0, 0 )
}
## write all buffers and exit
#
global function write_and_exit()
{
if (write_all_buffers())
quit(0,0)
}
## set_flag_bits() - set the value of one or more bits in a flag
#
#
# arguments:
#
# srcFlag - the value of the input flag
#
# mask - which bits in the input flag are to be changed
#
# newBits - what the new flag should be (only those bits specified
# in the mask will be affected)
#
# function result: new flag
#
#
# example:
# This example sets the WINDOW_HEX(0x4000) bit contained in the
# WINDOW_CHARS(0x6000) group of flags:
# window_flags = set_flag_bits( window_flags, WINDOW_CHARS, WINDOW_HEX )
#
# To turn on a bit specify the same mask and newBits paramters, for example:
# flags = set_flag_bits( flags, 0x0101, 0x0001 )
# will turn on bit 1 of the flags variable.
#
# To turn off a bit specify opposite mask and newBits paramters, for example:
# flags = set_flag_bits( flags, 0x0101, 0x0100 )
# will turn off bit 1 of the flags variable.
#
global function set_flag_bits( srcFlag, mask, newBits ) #PUBLIC #INT
{
# first turn off all bits in mask
srcFlag = and( srcFlag, not(mask) )
# newBits should be a part of the mask
# if ( and( mask, newBits ) )
srcFlag = or( srcFlag, and( newBits, mask) )
# This section caused problems when run into accidentally;
# if newBits not part of mask, but it equals 1, turn on bits of mask
# else if ( newBits == 1 )
# srcFlag = or( srcFlag, mask)
return srcFlag
}
## toggle_file_backup()
#
global function toggle_file_backup( on )
{
if ( argcount() < 1 ) # no argument specified
backup_files_enabled = !backup_files_enabled;
else
backup_files_enabled = 0+on # use the argument specified
message( backup_files_enabled ? "Backup files will be created." \
: "Backup files will not be created.")
}
### push_dir()
# Push the name of the current working directory on a stack and change to
# the specified directory.
#
### pop_dir()
# Change back to a previously pushed directory and pop the element off the
# stack. Returns TRUE if successful, FALSE if there is no directory element
# on the stack.
#
local cwd_stack
local cwd_stack_size
global function push_dir( new_dir )
{
cwd_stack[ ++cwd_stack_size ] = getcwd()
if ( new_dir )
chdir( new_dir )
}
global function pop_dir()
{
if ( cwd_stack_size in cwd_stack )
{
chdir( cwd_stack[ cwd_stack_size ] )
delete cwd_stack[ cwd_stack_size-- ]
return TRUE
}
else
return FALSE
}
## support for functions in optional .PEL files
#
function optional_function( fn_name, arg1 ,arg2, arg3, arg4, arg5 )
{
local fid, count = argcount();
if((count < 1) || !fn_name)
fid = 0
else if (count == 1 )
fid = function_id( fn_name );
else if (count == 2)
fid = function_id( fn_name, arg1 );
else if (count == 3)
fid = function_id( fn_name, arg1, arg2 );
else if (count == 4)
fid = function_id( fn_name, arg1, arg2, arg3 );
else if (count == 5)
fid = function_id( fn_name, arg1, arg2, arg3, arg4 );
else
fid = function_id( fn_name, arg1, arg2, arg3, arg4, arg5 );
if (fid)
return execute_function( fid )
else
return FALSE
}
## create_semaphore_fname()
#
# Create a new extension for the file name specified. The extension needs
# to be unique or else conflicts may occur and files will be reported as
# locked when they actually aren't.
#
# All extensions will appear in the form xxx.__! or xxx.x_! or xxx.xx!
#
global function create_semaphore_fname( fname, lastchar )
{
local bname;
local ext;
local ppath;
local count;
fname = buildpath( fname );
bname = path_fname( fname );
ext = path_ext( fname );
ppath = substr( fname, 1, length( fname ) - length( bname ) - length( ext ));
if (ext == "")
ext = ".";
ext = substr(substr( ext "___", 1, 3) lastchar, 1, 4);
return ppath bname ext;
}
global function system_pause( cmd, sys_flags )
{
local flags
local fileid
local cmdFileName
local semfile
local semid
if (match(cmd, "^[@&*+?=]"))
{
flags = substr(cmd, RSTART, RLENGTH)
cmd = substr(cmd, RSTART + RLENGTH)
}
if (isWindows())
cmdFileName = create_temp_name(0, "bat")
else
cmdFileName = create_temp_name(0, "cmd")
fileid = fopen(cmdFileName, 2)
# Win-OS/2 get complicated since OS/2 never informs Windows when a DOS
# program started by him exits, forcing all system commands to run ASYNC.
if (isWindows() == WIN_OS2)
{
# Create a Semaphore-File for the Batch file to delete.
semfile = create_temp_name(0, "sem")
semid = fopen(semfile, 2)
fprintf( semid, "%s\n", cmd);
fclose(semid)
# Create the batch file and execute it.
fprintf( fileid, "%s\n@pause\n@del %s\n", cmd, semfile);
fclose(fileid)
system( flags cmdFileName, 0, 0, 0,
or(or(sys_flags, SYS_SESSION), SYS_ASYNC))
# Wait for the batch file to delete the semaphore file.
while (filemode(semfile) != -1)
idle(TRUE)
}
else
{
fprintf( fileid, "%s\n@pause\n", cmd, cmdFileName );
fclose(fileid)
system( flags cmdFileName, 0, 0, 0, or(sys_flags, SYS_SESSION) )
}
unlink( cmdFileName )
}
global function resize_editwin()
{
# maintain zoomed state
if ( current_window && and(window_flags, WINDOW_ZOOM) == WINDOW_EXPANDED && mdi_mode < 2 )
expand_window()
}
# DWM 5/18/94
# deletes all events in the range and returns an array
# containing all of the gids removed
global function save_and_remove_events( event_start, event_end )
{
local event
local macro
local event_list[]
if ( argcount() >= 2 && event_start <= event_end )
{
for ( event = event_start; event <= event_end; event++ )
{
event_list[ event ] = query_event( event )
for ( macro in event_list[ event ] )
delete_event( event, event_list[event][macro] )
}
}
else
warning( "save_and_remove_events: invalid parameters" )
return event_list
}
# DWM 5/28/94
# restores events removed by save_and_remove_events
global function restore_events( event_list[] )
{
local event
local macro
for ( event in event_list )
{
for ( macro in event_list[ event ] )
attach_event_handler( event, event_list[event][macro] )
}
}
#
# Searches for string in the array and returns the index. If not found,
# it just returns. Keep in mind that the type of the return value will
# be "uninitialized" and that is how you can tell if the item was found
#
function find_in_array( theArray[], theString )
{
local i
for ( i in theArray )
if ( theArray[i] == theString )
return i
return
}
# DWM 5/28/94
# return an array containing all of the elements of both arrays.
# If there is a collision, favor the second array
global function merge_arrays( array1[], array2[] )
{
local item
local array[]
for ( item in array1 )
array[ item ] = array1[ item ]
for ( item in array2 )
array[ item ] = array2[ item ]
return array
}
# Event handler called when a file is dropped
# onto a running editor. The dropped_file variable
# contains the name of the file dropped onto
# the editor
global function file_dropped()
{
if ( dropped_file )
{
# set_editwin_property( EWC_TO_TOP )
create_buf_and_win_key( dropped_file )
update_current_view()
}
}
## SYMBOL_REGEX
#
# A search argument which defines an "identifier", such as a function or
# variable name. The default is to use "C++" rules.
#
global SYMBOL_REGEX = "[a-zA-Z0-9_:~]+"
global SYMBOL_REGEX2 = "[/\\#\\(\\)\\{\\}\\[\\]\\*\\&a-zA-Z0-9_:~]+"
## symbol_under_cursor()
#
# This function returns the name of the identifier presently under the
# cursor. The default identifier is defined as any consecutive string of upper
# or lower case letters, numbers, underscores, and dots. If the cursor is
# not on one of those characters, or is in "virtual space", this function
# returns the NULL value.
#
global function symbol_under_cursor( symbol_regex )
{
local symbol
local prevCol
local cursorPos
local last
if ( !symbol_regex )
symbol_regex = SYMBOL_REGEX
# is the cursor on a character?
if ( and( buffer_flags, BUFFER_IN_VIRTUAL_SPACE ))
return ""
# read the entire current line into a string, then restore
# the cursor position
#
prevCol = current_column
cursorPos = buffer_offset
current_column = 1
cursorPos = cursorPos + 1 - buffer_offset
symbol = read_buffer()
current_column = prevCol
# ensure that the cursor is on a valid symbol
if ( !match( substr( symbol, cursorPos ), "^" symbol_regex ))
return ""
last = cursorPos + RLENGTH
# find the first character in the symbol
if ( !match( substr( symbol, 1, cursorPos), symbol_regex "$" ))
{
# should never happen
return ""
}
# read symbol from buffer
return substr( symbol, RSTART, last - RSTART )
}
## left_symbol_under_cursor
#
# just like symbol_under_cursor above, but if it doesn't find a symbol, it
# moves left once and tries again
#
function left_symbol_under_cursor( symbol_regex )
{
local key = symbol_under_cursor( symbol_regex )
if ( !key )
{
save_position();
left();
key = symbol_under_cursor( symbol_regex )
restore_position(1);
}
return key
}
#
# strtok function: Similar to the C function of the same name,
# breaks up a string using the supplied delimiters
# (which are specified in a regular expression)
#
local tokstring
local tokdelim
global function strtok( str, delimeter )
{
local temp
local match_ret
local ret_str = FALSE
# if there is a string, make it and the delimeter current
if ( (argcount() > 0) && str )
tokstring = str
if ( (argcount() == 2) && delimeter )
tokdelim = delimeter
if ( tokstring )
{
# replace '\' char with "\\" for regex matching
gsub( "\\", "\\\\", tokstring )
match_ret = match( tokstring, tokdelim )
if ( match_ret && (RSTART == 1) )
tokstring = substr( tokstring, RLENGTH + 1, length(tokstring) )
if ( !match_ret )
{
ret_str = tokstring
tokstring = ""
}
else
{
ret_str = substr( tokstring, 1, RSTART - 1 )
tokstring = substr( tokstring, RSTART + RLENGTH, length(tokstring) )
}
}
return ret_str
}
global function get_tokstring()
{
return tokstring
}
#
# Function to set an environment variable.
#
global function set_environment( env_string, value_string )
{
if ( env_string )
ENV[ env_string ] = value_string
else
warning("bad arguments sent to set_environment(%s, %s)", env_string, value_string )
}
#
# Function to check if you are in the Windows environment
# Return values - 0: not in (windows or win/os2)
# 1: Windows
# 2: Win-OS2
#
global function isWindows()
{
local result = 0;
if(tolower(substr(os_name, 1, 1)) == "w")
{
result++;
if(tolower(substr(os_name, 4, 1)) == "-")
result++
}
return result;
}
##############
# File Access
##############
global copy_lan_files_on_action = ""
global copy_floppy_files_on_action = ""
global copy_local_files_on_action = ""
global function copy_lan_files_on( action )
{
local act = tolower( action )
if ( act && (act != "mod" && act != "open") )
warning( "copy_lan_files_on: invalid copy action--" action )
copy_lan_files_on_action = act
}
global function copy_floppy_files_on( action )
{
local act = tolower( action )
if ( act && (act != "mod" && act != "open") )
warning( "copy_floppy_files_on: invalid copy action--" action )
copy_floppy_files_on_action = act
}
global function copy_local_files_on( action )
{
local act = tolower( action )
if ( act && (act != "mod" && act != "open") )
warning( "copy_lan_files_on: invalid copy action--" action )
copy_local_files_on_action = act
}
global lock_lan_files_on_mod = FALSE
global lock_floppy_files_on_mod = FALSE
global lock_local_files_on_mod = FALSE
global function set_file_access( p1, p2, p3, p4, p5, p6 )
{
# add + 0 to ensure values are numeric
lock_lan_files_on_mod = p1 + 0
copy_lan_files_on_action = p2
lock_local_files_on_mod = p3 + 0
copy_local_files_on_action = p4
lock_floppy_files_on_mod = p5 + 0
copy_floppy_files_on_action = p6
}
global function toggle_lock_lan_files_on_mod( onOff )
{
if ( !argcount() )
onOff = !lock_lan_files_on_mod
lock_lan_files_on_mod = !!onOff
}
global function toggle_lock_floppy_files_on_mod( onOff )
{
if ( !argcount() )
onOff = !lock_floppy_files_on_mod
lock_floppy_files_on_mod = !!onOff
}
global function toggle_lock_local_files_on_mod( onOff )
{
if ( !argcount() )
onOff = !lock_local_files_on_mod
lock_local_files_on_mod = !!onOff
}
global lock_on_mod = FALSE
global function toggle_lock_on_mod( bool )
{
if ( !argcount() )
bool = !lock_on_mod
if ( bool )
{
# only turn it on if it's off
if ( !lock_on_mod )
{
attach_event_handler( EVENT.FIRST_MOD, "lock_buffer" )
attach_event_handler( EVENT.UNMOD, "unlock_buffer" )
lock_on_mod = TRUE
}
}
# only turn it off if it's on
else if ( lock_on_mod )
{
delete_event( EVENT.FIRST_MOD, "lock_buffer" )
delete_event( EVENT.UNMOD, "unlock_buffer" )
lock_on_mod = FALSE
}
}
global copy_on_mod = FALSE
global function toggle_copy_on_mod( bool )
{
if ( !argcount() )
bool = !copy_on_mod
if ( bool )
{
# only turn it on if it's off
if ( !copy_on_mod )
{
attach_event_handler( EVENT.FIRST_MOD, "copy_buffer_internally" )
copy_on_mod = TRUE
}
}
# only turn it off if it's on
else if ( copy_on_mod )
{
delete_event( EVENT.FIRST_MOD, "copy_buffer_internally" )
copy_on_mod = FALSE
}
}
global function is_lan_drive( path )
{
local is = FALSE
local drive_letter
if ( argcount() < 1 )
path = buffer_filename
if ( disk_is_removeable(path) )
{
drive_letter = tolower( prefix(path, 1) )
if ( drive_letter != "a" && drive_letter != "b" )
is = TRUE
}
return is
}
global function is_floppy_drive( path )
{
local is = FALSE
local drive_letter
if ( argcount() < 1 )
path = buffer_filename
if ( disk_is_removeable(path) )
{
drive_letter = tolower( prefix(path, 1) )
if ( drive_letter == "a" || drive_letter == "b" )
is = TRUE
}
return is
}
global function is_local_drive( path )
{
local is = FALSE
if ( argcount() < 1 )
path = buffer_filename
if ( !disk_is_removeable(path) )
is = TRUE
return is
}
global file_access_list[]
global function file_access_first_mod_handler()
{
if ( filemode(buffer_filename) != -1 )
{
if ( is_lan_drive(buffer_filename) )
{
if ( lock_lan_files_on_mod )
{
if ( lock_buffer() )
file_access_list[ buffer_filename ] = BUFFER_LOCKED
else
warning( "unable to lock file " buffer_filename )
}
if ( copy_lan_files_on_action == "mod" )
{
if ( !copy_buffer_internally() )
warning( "unable to copy file " buffer_filename " internally" )
}
}
else if ( is_floppy_drive(buffer_filename) )
{
if ( lock_floppy_files_on_mod )
{
if ( !lock_buffer() )
warning( "unable to lock file " buffer_filename )
}
if ( copy_floppy_files_on_action == "mod" )
{
if ( !copy_buffer_internally() )
warning( "unable to copy file " buffer_filename " internally" )
}
}
else
{
if ( lock_local_files_on_mod )
{
if ( lock_buffer() )
file_access_list[ buffer_filename ] = BUFFER_LOCKED
else
warning( "unable to lock file " buffer_filename )
}
if ( copy_local_files_on_action == "mod" )
{
if ( !copy_buffer_internally() )
warning( "unable to copy file " buffer_filename " internally" )
}
}
}
}
global function file_access_unmod_handler()
{
if ( buffer_filename in file_access_list )
{
if ( file_access_list[buffer_filename] == BUFFER_LOCKED )
unlock_buffer()
}
}
global function file_access_file_open_handler()
{
if ( filemode(buffer_filename) != -1 )
{
if ( is_lan_drive(buffer_filename) )
{
if ( copy_lan_files_on_action == "open" )
{
if ( !copy_buffer_internally() )
warning( "unable to copy file " buffer_filename " internally" )
}
}
else if ( is_floppy_drive(buffer_filename) )
{
if ( copy_floppy_files_on_action == "open" )
{
if ( !copy_buffer_internally() )
warning( "unable to copy file " buffer_filename " internally" )
}
}
else
{
if ( copy_local_files_on_action == "open" )
{
if ( !copy_buffer_internally() )
warning( "unable to copy file " buffer_filename " internally" )
}
}
}
}
local file_error_status = 0
global function file_error_callback()
{
local ret_val = DRC_CONTINUE
if ( callback_msg == DM_CLICK )
{
if ( callback_index == IDB_FILE_ERROR_RETRY )
refresh_buffer()
else if ( callback_index == IDB_FILE_ERROR_FAIL )
file_error_status = -1
}
return ret_val
}
local in_file_error[]
local failed[]
local dhErrorDlg[]
global function file_error_prompt()
{
if ( !(current_buffer in failed) )
{
if ( !in_file_error[buffer_filename] )
{
dhErrorDlg[buffer_filename] = create_dialog( function_id( "file_error_callback" ),
0, IDD_FILE_ERROR, resource_dll );
set_dialog_window( dhErrorDlg[buffer_filename], DWC_TITLE,
"File Error--" buffer_filename )
set_dialog_item( dhErrorDlg[buffer_filename], IDB_FILE_ERROR_DISCARD,
DAC_DISABLE )
}
in_file_error[buffer_filename]++
beep()
begin_dialog( dhErrorDlg[buffer_filename] )
if ( file_error_status < 0 )
failed[ current_buffer ] = TRUE
display_redraw()
in_file_error[buffer_filename]--
# delete the dialog when our nesting level is zero
if ( !in_file_error[buffer_filename] )
{
file_error_status = 0
delete_dialog( dhErrorDlg[buffer_filename] )
}
}
}
global function catch_file_open_error()
{
file_error_prompt()
}
local find_paths[]
local find_num = 1
global function findfirst_path( path_list )
{
local first
local path
local mask
local traversed
local count = split( path_list, find_paths, ";" )
while ( !first && count > traversed )
{
traversed++
mask = path_fname( find_paths[traversed] ) path_ext( find_paths[traversed] )
path = path_path( find_paths[traversed] )
first = findfirst( path mask )
}
if ( !first )
{
delete find_paths
find_num = 1
}
else
find_num = traversed
return first
}
global function findnext_path()
{
local path
local mask
local more_paths = TRUE
local next_file = findnext()
while ( !next_file && more_paths )
{
if ( (find_num + 1) in find_paths )
{
find_num++
mask = path_fname( find_paths[find_num] ) path_ext( find_paths[find_num] )
path = path_path( find_paths[find_num] )
next_file = findfirst( path mask )
}
else
more_paths = FALSE
}
if ( !next_file )
{
delete find_paths
find_num = 1
}
return next_file
}
global function current_find_path()
{
local fpath
if ( find_num in find_paths )
fpath = path_path( find_paths[find_num] )
return fpath
}
# this function is attached to the EVENT.TRACKING_DONE event handler.
# it simply creates a new window of the same size as the tracking
# rectangle. It accounts for one buffer per window.
global function create_track_window()
{
local w1;
local newBuffer;
if ( (abs(tracking_width) >= 20) && (abs(tracking_height) >= 20) )
{
if(create_new_bufwin)
{
newBuffer = new_buffer_name();
if(newBuffer)
{
create_buf_and_win(newBuffer, 0, tracking_left, tracking_bottom, tracking_width, tracking_height );
buffer_flags = or(buffer_flags, BUFFER_SCRATCH);
}
}
else
{
w1 = create_window( tracking_left, tracking_bottom, tracking_width, tracking_height )
attach_window_buffer( w1, current_buffer )
current_window = w1
}
}
}
global function new_buffer_name()
{
local BufNum = 1;
local newBuffer = "Scratch.001"
local buf_orig_name = ""
local scratch_list[]
local start_buf
local wf
# loop through all buffers
start_buf = current_buffer
do
{
buf_orig_name = path_fname(buffer_original_filename) path_ext(buffer_original_filename)
# if the buffer's name or its original name was Scratch.xxx, try
# the next scratch num
if ( tolower(buffer_name) ~ /scratch.[0-9][0-9][0-9]/ )
scratch_list[ atoi(substr(buffer_name, 9)) ] = TRUE
else if ( tolower(buf_orig_name) ~ /scratch.[0-9][0-9][0-9]/ )
scratch_list[ atoi(substr(buf_orig_name, 9)) ] = TRUE
}
while ( start_buf != next_buffer("", 1, 1) )
BufNum = 1
while ( scratch_list[ BufNum ] )
BufNum++
while ( BufNum < 1000 )
{
newBuffer = sprintf("Scratch.%03d", BufNum)
# if the file already exists skip it.
if ( filemode( newBuffer ) == -1 )
{
break;
}
BufNum++
while ( scratch_list[ BufNum ] && BufNum < 1000 )
BufNum++
}
if ( BufNum >= 1000 )
{
warning("No more scratch buffers allowed!")
newBuffer = "";
}
return newBuffer;
}