home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-09-27 | 25.8 KB | 1,104 lines |
- # $Header: P:/source/ppee/macros/nucleus.pev 1.160 27 Sep 1990 09:58:58 skipr $
-
- ##############################################################################
- #
- # Sage Software - POLYTRON Division
- # 1700 NW 167th Place
- # Beaverton, OR 97006
- #
- # Copyright 1990, Sage Software, Inc.
- #
- # Permission is hereby granted for licensed users of Sage Professional
- # Editor and PolyAwk to copy and modify this source code for their own
- # personal use. These derivative works may be distributed only to other
- # licensed Sage Professional Editor and PolyAwk users. All other usage
- # is prohibited without express written permission from Sage Software.
- #
- ##############################################################################
-
- #### $Workfile: nucleus.pel $: manifest constants and core utilities
-
-
- # reserved global variables
-
- global TRUE = 1
- global FALSE = 0
-
- global emulation_mode
- global backup_files_enabled;
-
-
- ## DOS file attributes:
- global FILEMODE_NORMAL = 0
- global _READ_ONLY = 1
- global _HIDDEN = 2
- global _SYSTEM = 4
- global _VOL_ID = 8
- global _SUBDIR = 16
- global _ARCHIVE = 32
- global _NORMAL = 64
-
- ## Event numbers:
- global EVENT_EMULATION_CHANGED = 9
- global EVENT_IDLE_TIME = 10
- global EVENT_CTRL_BREAK = 11
- global EVENT_INVALID_PCHAR = 12
- global EVENT_UNASSGN_KEY = 13
- global EVENT_NEW_EDIT_FILE = 14
- global EVENT_NEW_CURNT_BUFFER = 15
- global EVENT_NEW_CURNT_WINDOW = 16
- global EVENT_HELP_INVOKED = 17
- global EVENT_IDLE_THRESHOLD = 18
- global EVENT_EXIT_EDITOR = 19
- global EVENT_TEMP_SPACE_OVFLW = 20
- global EVENT_EDIT_FILE_SAVE = 21
- global EVENT_KEYPRESS = 22
- global EVENT_FIRST_MOD = 23
- global EVENT_NEW_SCREEN_SIZE = 24
- global EVENT_DISPLAY_UPDATE = 26
- global EVENT_PROCESS_COMPLETE = 27
- global EVENT_MOUSE_LEFT_DOWN = 28
- global EVENT_MOUSE_RIGHT_DOWN = 29
- global EVENT_MOUSE_MID_DOWN = 30
- global EVENT_MOUSE_LEFT_UP = 31
- global EVENT_MOUSE_RIGHT_UP = 32
- global EVENT_MOUSE_MID_UP = 33
- global EVENT_MOUSE_LEFT_CLICK1 = 34
- global EVENT_MOUSE_RIGHT_CLICK1 = 35
- global EVENT_MOUSE_MID_CLICK1 = 36
- global EVENT_MOUSE_LEFT_CLICK2 = 37
- global EVENT_MOUSE_RIGHT_CLICK2 = 38
- global EVENT_MOUSE_MID_CLICK2 = 39
- global EVENT_INSERT_KEY = 40
- global EVENT_INSERT_STRING = 41
- global EVENT_DELETE_CHARS = 42
- global EVENT_INSERT_NEWLINE = 43
- global EVENT_SHELL_EXIT = 44
- global EVENT_FUNCTION_CHANGED = 45
- global EVENT_DELETING_BUFFER = 46
-
-
- ## System file numbers: (see locate_sageedit_file)
- global SAGEEDIT_FILE_CONFIG = 1 # sageedit.cfg
- global SAGEEDIT_FILE_AE = 2 # sageedit.ae
- global SAGEEDIT_FILE_HELP = 3 # help.txt
- global SAGEEDIT_FILE_BINDINGS = 4 # bindings.txt
- global SAGEEDIT_FILE_REFMAN = 5 # refman.txt
-
-
- ## 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 poe
- local recordKeysFile
- local playbackKeysFile
-
- # process command line arguments one at a time
-
- for ( iarg=1; iarg<ARGC; iarg++ ) {
-
- arg = ARGV[iarg]
-
- # process switches from left to right
-
- if ( substr(arg,1,1) == "-" ) {
- arg = substr(arg,2)
-
- while ( arg ) {
-
- option = substr(arg,1,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 )
- set_buffer_flag( \
- BUFFER_READ_ONLY, \
- TRUE )
-
- #
- # 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 = ""
-
- #
- # invoke awk function Library
- #
- # specified .ae filename is processed
- # in C code so skip to the next argument
- #
- } else if (option == "a" || option == "A" ) {
- if ( arg == "" )
- iarg++
- arg = ""
-
- #
- # unrecognized switch character
- #
- } else {
- cmd_line_error = "option " option " not recognized"
- arg = ""
- }
- }
- } else {
- # treat arguments not beginning with "-" as filenames
- edit_file(arg)
- }
- }
-
- # make the first buffer in the list the current buffer
- next_buffer()
-
- # ============================================================= #
-
- if ( emulation_mode == "" ) {
- poe = pause_on_error
- pause_on_error = 1
- warning( "no emulation mode defined - <Alt-Q> to exit" )
- pause_on_error = poe
- }
-
- # 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 )
- } else {
- message( version_label() )
- }
- }
-
-
- ## display copyright notice and version label
- #
- global function print_version() {
- warning( version_label() )
- }
-
- local function version_label() {
- return "Sage Professional Editor v" version \
- " - Copyright 1990, Sage Software, Inc."
- }
-
-
- ## prompt user for filename for edit_file() and read_file() operations
- #
- global function edit_file_key( display_menu ) {
- local fn
-
- # If optional argument "display_menu" is set to TRUE, we unget a
- # tab key so that prompt_history brings up a menu of files in the
- # current directory. This enables file selection using a mouse.
- #
- if ( 0+display_menu ){
- flush_keyboard()
- ungetkey( KEYCODE_TAB )
- }
-
- fn = prompt_history( "EDITFILE", "File: ", "" )
-
- if( fn ){
- if( !edit_file( fn ))
- message( "Cannot open file '%s'", fn )
- else
- display_filename()
- }
- }
-
- global function read_file_key() {
- local fn
- local result = FALSE
-
- fn = prompt_history( "EDITFILE", "File to read: ", "" )
-
- if ( fn ) {
- result = read_file( fn )
- if ( !result )
- message( "Cannot read '%s'", fn )
- }
- return result
- }
-
-
- ## prompt the user for a command, and run it
- #
- global function system_key() {
- local com, err
-
- com = ltrim( prompt_history( "SYSTEM", "System Command: ", "" ))
-
- if( com && ( err = system( com )))
- warning( "Command exited with %d", err )
- else
- message( "" )
- }
-
-
- ## 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 "]"
- }
- 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
- i++
- }
- result = result ch
- }
- return result
- }
-
-
- ## goto_line() -- move the cursor to column one of the specified line
- #
- global function goto_line( line ) { #PUBLIC #INT
- if ( !(0+line) )
- line = 1
- return goto_pos(0+line, 1)
- }
-
-
- ## 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
- #
- global keymapStack
- global 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
- }
- return FALSE
- }
-
-
- ## invoke a filter and replace the marked region with the result
- #
- global function filter( command ) { #PUBLIC #VOID
-
- local save_buffer_name,
- first_temp_file,
- second_temp_file,
- block_marked,
- status
-
- first_temp_file = create_temp_name()
- second_temp_file = create_temp_name()
-
- block_marked = region_type()
- save_position()
-
- #
- # temporarily change the current buffer's file name and write
- # the marked block out to the temp file.
- #
- if (!block_marked) {
- goto_buffer_top()
- drop_anchor( LINE_SELECTION )
- goto_buffer_bottom()
- } else if (block_marked == COLUMN_SELECTION) {
- # position at tope of column block
- if (current_line >= mark_line()) {
- if (current_line > mark_line())
- swap_marks();
- else if (current_column > mark_column())
- swap_marks();
- }
- }
-
- write_marked_block( first_temp_file )
-
- #
- # filter first_temp_file through the "command" to generate
- # second_temp_file and then read in the file.
- #
- if (system( command " <" first_temp_file " >&" second_temp_file) != -1) {
- delete_chars() # delete the selection
-
- if (block_marked == LINE_SELECTION)
- goto_bol();
- else if ( and(buffer_flags, BUFFER_IN_VIRTUAL_SPACE) )
- prev_char();
-
- read_file( second_temp_file )
- restore_position( status = FALSE )
- } else {
- if (!block_marked)
- raise_anchor()
- restore_position( status = TRUE )
- }
-
- unlink( second_temp_file )
- unlink( first_temp_file )
- return status
- }
-
-
- #-------------- code to record and playback an edit session ---------------#
-
- local recordFileHandle
- local playbackFileHandle
- local recordKeys
- local playbackKeys
- local playbackMacroId
- local recordMacroId
-
- local function recordKeysInitialize( keyfname ) {
-
- recordFileHandle = fopen( keyfname, 1 ) # open file for write only
-
- if ( recordFileHandle >= 0 ) {
- recordMacroId = function_id( "recordkeys" )
- attach_event_handler( EVENT_KEYPRESS, recordMacroId )
- return TRUE
- } else {
- warning( "Can't open '%s.'", keyfname )
- return FALSE
- }
- }
-
- local function playbackKeysInitialize( keyfname ) {
-
- playbackFileHandle = fopen( keyfname, 0 ) # open file for read only
-
- if ( playbackFileHandle >= 0 ) {
- playbackMacroId = function_id( "playbackkeys" )
- attach_event_handler( EVENT_IDLE_TIME, playbackMacroId )
- return TRUE
- } else {
- warning( "Can't open '%s.'", keyfname )
- return FALSE
- }
- }
-
- global function recordkeys() {
- local ch1 = shiftr( and( current_key, 0x0FF00), 8)
- local ch2 = and( current_key, 0x00FF )
-
- fputc( (ch1 == 0) ? 255 : ch1, recordFileHandle )
- fputc( (ch1 == 0) ? 255 : ch2, recordFileHandle )
-
- if ( and( ch1, 0xF0 ) == 0xF0 ) {
- fputc( mouse_event_x, recordFileHandle )
- fputc( mouse_event_y, recordFileHandle )
- }
-
- }
-
-
- local prevMouseButtons
-
- global function get_mouse_buttons() {
- local buttons
-
- if (playbackKeys) {
- buttons = and(shiftl(fgetc( playbackFileHandle ),8),0xFF00) + \
- and(fgetc( playbackFileHandle ), 0x00FF)
- mouse_display_x = fgetc( playbackFileHandle )
- mouse_display_y = fgetc( playbackFileHandle )
- if (buttons != prevMouseButtons) {
- mouse_event_x = fgetc( playbackFileHandle )
- mouse_event_y = fgetc( playbackFileHandle )
- }
- } else if (recordKeys) {
- buttons = mouse_buttons
- fputc(shiftr( and( buttons, 0x0FF00), 8), recordFileHandle )
- fputc( and( buttons, 0x000FF), recordFileHandle )
-
- fputc( mouse_display_x, recordFileHandle )
- fputc( mouse_display_y, recordFileHandle )
- if (buttons != prevMouseButtons) {
- fputc( mouse_event_x, recordFileHandle )
- fputc( mouse_event_y, recordFileHandle )
- }
- } else {
- buttons = mouse_buttons
- }
- prevMouseButtons = buttons
- return buttons
-
- }
-
-
-
- local reload_count = 1 # 0 => free run
-
- ## reload keys from a saved key file
- #
- # this function allows the user to interrupt the playback and
- # intervene manually with the restoration.
- #
- # Recommendations:
- # 1. rename your original file to *.old
- # 2. rename your reckeys.__$ to *.rec
- # 3. save the file at useful points during the recovery.
- # 4. you may ESC out of a playback session, do some cleanup
- # and then resume playback via <F10>reloadkeys<Enter>
- # 5. while single-stepping, be careful not to type too fast
- # else some spaces will be processed as input. This is most
- # likely to happen on slow commands. It's always safe to type
- # when the prompt appears.
- #
- global function playbackkeys() {
- local key, ch, ch1, ch2
-
- # first obey playback controls:
-
- if( and( keyboard_flags, 0x7F ) \
- ||( reload_count > 0 && reload_count-- == 1 )){
- delete_event( EVENT_IDLE_TIME, playbackMacroId )
-
- for(;;){
- message( "press ESC to stop playback; SPACE to single step; ENTER to resume.." )
- ch = and( getkey(), 255 )
-
- if( ch == 13 || ch == 10 ){
- reload_count = 0
- break
-
- } else if( ch == 27 ){
- message( "" )
- delete_event( EVENT_IDLE_TIME, playbackMacroId )
- return
-
- } else if( ch == 32 ){
- reload_count = 1
- break
-
- } else if( 48 <= ch && ch <= 57 ){
- reload_count = prompt( "Enter playback count: ", chr( ch ))
- if( reload_count > 0 )
- break
- } else if( key == 18432 ){
- up()
- } else if( key == 20480 ){
- down()
- } else if( key == 19200 ){
- left()
- } else if( key == 19712 ){
- right()
- } else
- beep()
- }
- attach_event_handler( EVENT_IDLE_TIME, playbackMacroId )
- message( "" )
- }
-
- # now playback the next character:
-
- ch1 = fgetc( playbackFileHandle )
- ch2 = fgetc( playbackFileHandle )
-
- ch1 = (ch1==255) ? 0 : ch1
- ch2 = (ch2==255) ? 0 : ch2
-
- if ((ch1 == -1) && (ch2 == -1)) {
- delete_event( EVENT_IDLE_TIME, playbackMacroId )
- return
- } else if (and(ch1,0xF0) == 0xF0) {
- mouse_event_x = mouse_display_x = fgetc( playbackFileHandle )
- mouse_event_y = mouse_display_y = fgetc( playbackFileHandle )
- }
- ungetkey( or( shiftl( ch1,8 ), ch2 ))
- }
-
- # -------------------------------------------------------------------------- #
-
- ## attach_cleanup_handler()
- #
- # If the sageedit.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( region_type() != LINE_SELECTION )
- drop_anchor( LINE_SELECTION )
- delete_to_scrap()
- }
-
- ## toggle insert mode
- #
- global function toggle_insert_mode( on ) {
-
- if( argcount() < 1 )
- on = and( buffer_flags, BUFFER_OVERTYPE_MODE )
- else
- on = 0+on
-
- if ( on ) {
- buffer_flags = and(buffer_flags, not(BUFFER_OVERTYPE_MODE ))
- message( "Insert Mode" )
- } else {
- buffer_flags = or(buffer_flags, BUFFER_OVERTYPE_MODE )
- message( "Overtype Mode" )
- }
- }
-
-
- ## toggle tabs to spaces
- #
- global function toggle_tabs_to_spaces( on ){
-
- if( argcount() < 1 )
- on = !and( buffer_flags, BUFFER_TABS_TO_SPACES )
- else
- on = 0+on
-
- set_buffer_flag( BUFFER_TABS_TO_SPACES, on )
- message( "Tabs to spaces " ( on ? "enabled." : "disabled." ))
- }
-
-
- ## 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 sageedit system files
- #
- global sageedit_filename
- local existing_sageedit_file
- local primary_sageedit_dir
-
- ## return the name of an existing file using the SAGEEDIT path
- #
- # valid argument values are:
- # SAGEEDIT_FILE_CONFIG # sageedit.cfg
- # SAGEEDIT_FILE_AE # sageedit.ae
- # SAGEEDIT_FILE_HELP # help.txt
- # SAGEEDIT_FILE_BINDINGS # bindings.txt
- # SAGEEDIT_FILE_REFMAN # refman.txt
- #
- global function locate_sageedit_file( sageedit_id ) {
- local fn
- local element
- local path
- local result
-
- # initialize filename array if necessary
- if ( !sageedit_filename ) {
- sageedit_filename[SAGEEDIT_FILE_CONFIG] = "sageedit.cfg"
- sageedit_filename[SAGEEDIT_FILE_AE] = "sageedit.ae"
- sageedit_filename[SAGEEDIT_FILE_HELP] = "help\\help.txt"
- sageedit_filename[SAGEEDIT_FILE_BINDINGS] = "help\\bindings.txt"
- sageedit_filename[SAGEEDIT_FILE_REFMAN] = "help\\refman.txt"
- }
-
- # has the file already been located?
- if ( sageedit_id in existing_sageedit_file ) {
- return existing_sageedit_file[sageedit_id]
- }
-
- if ( sageedit_id in sageedit_filename ) {
-
- fn = sageedit_filename[sageedit_id]
- do {
- # look first in the current directory
- if ( filemode( fn ) >= 0 ) {
- existing_sageedit_file[sageedit_id] \
- = fn \
- = buildpath( fn )
- return fn
- }
-
- # search the sageedit path
- path = ENV[ "SAGEEDIT" ]
- 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_sageedit_file[sageedit_id] \
- = result
- return result
- }
- }
-
- # try ARGV[0]
- if ( match( ARGV[0], /.*\\/ )) {
- result = buildpath( \
- substr( ARGV[0], RSTART, RLENGTH ) fn )
- if ( filemode( result ) >= 0 ) {
- existing_sageedit_file[sageedit_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\\" )
- break
- fn = substr( fn, 6 )
- } while ( fn )
- }
- # return null
- }
-
- ## return the first directory given in the SAGEEDIT path
- #
- global function editor_path( sageedit_id ) {
- # sageedit_id is an optional argument containing the id of
- # one of the editor support files (e.g. SAGEEDIT_FILE_CONFIG).
- # If specified, the name of the file will be appended
-
- local path
- local fmode
-
- if ( primary_sageedit_dir ) {
- # sageedit path has already been processed
- path = primary_sageedit_dir
-
- } else if (( path = ENV[ "SAGEEDIT" ] )) {
-
- # 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_sageedit_dir = path
- }
-
- # if an optional file argument was specified, append the name of the
- # appropriate file
- if ( sageedit_id in sageedit_filename ) {
- return path sageedit_filename[sageedit_id]
- }
-
- return path
- }
-
- ## path_path
- #
- # return the drive:path of a filespec, trailing slash/backslash
- # is included.
- #
- global function path_path(fspec) {
- local len;
-
- if ((len = length(fspec)) == 0)
- return "";
-
- len -= length(path_ext(fspec));
- len -= length(path_fname(fspec));
-
- return substr(fspec, 1, len);
- }
-
-
- ## 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
- return name4
-
- }
-
-
- ## quit from editor
- #
- global function done(){
- local buf
- local priorMessageLevel
- local i = buffers_modified
-
- if ( i ) {
- buf = sprintf( "%d %s been modified, Exit[ynw]? ", \
- i, i > 1 ? "buffers have" : "buffer has")
- begin_dialog()
- i = tolower( confirm(buf, "yYnNwW") )
- if (i == "w") {
- priorMessageLevel = message_level
- message_level = 0
- if ( !write_all_buffers() ) {
- message_level = priorMessageLevel
- end_dialog()
- return
- }
- } else if (i != "y") {
- end_dialog()
- return
- }
- }
- 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:
- # window_flags = set_flag_bits( window_flags, WINDOW_CHARS, WINDOW_HEX )
- #
- global function set_flag_bits( srcFlag, mask, newBits ) { #PUBLIC #INT
- return or( \
- and( srcFlag, not(mask) ), \
- and( newBits, mask) )
- }
-
-
- ## 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 ){
- local fid
- local filename
- if (( fid = function_id( fn_name ))){
- execute_function( fid );
- } else {
- if ( fn_name == "local_setup" ) {
- return # no warning if not present
- } else if ( fn_name == "read_config_file" ) {
- return # no warning if not present
- } else if ( fn_name == "native" ) {
- filename = "NATIVE.PEL"
- } else if ( fn_name == "display_ascii_table" ) {
- filename = "ASCII.PEL"
- } else if ( fn_name == "routines" ) {
- filename = "ROUTINES.PEL"
- } else {
- filename = ".PEL file"
- }
- warning( "function \"%s\": %s is not in current function library",
- fn_name, filename )
- }
- }
-
-
-
-
-
-
- ## 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;
- }
-
-
-