english version "1.0" identify "wxyz" #: Copyright (c) 1995, 2002 by Wayne C. Gramlich. #, All rights reserved. #, #, Permission to use, copy, modify, distribute, and sell this software #, for any purpose is hereby granted without fee provided that the above #, copyright notice and this permission are retained. The author makes #, no representations about the suitability of this software for any purpose. #, It is provided "as is" without express or implied warranty. module slice #: This module implements the slice abstraction. import address character command_parse command_types directory errors file_name file_system format in_stream integer logical out_stream project resources status string svms system table time timer unsigned vector define slice #: Slice of files in project record project_files project_files #: {project_files} list project project #: {project} slice is part of resources resources #: Resources everything is from generate address_get, allocate, erase, identical, print #: {slice} procedures: procedure xallocate@slice takes project project returns slice #: This procedure will allocate and return a new {slice} object #, allocated from {project}. assert project !== ?? resources :@= project.resources assert resources !== ?? project_files :@= xallocate@project_files(resources) slice :@= slice_allocate@(resources) slice.project_files := project_files slice.resources := resources slice.project := project #debug_stream :@= resources.global.debug_stream #format@format2[address, address](debug_stream, # "allocate@slice()=>%X% (project_files=%X%)\n\", # slice.address, project_files.address) return slice procedure deallocate@slice takes slice slice returns_nothing #: This procedure will deallocate {slice} and make it available for #, subsequent reuse. assert slice !== ?? resources :@= slice.resources project_files :@= slice.project_files truncate@(project_files, 0) deallocate@(project_files) erase@(slice) slice.resources := resources slice_deallocate@(resources, slice) procedure expand@slice takes file_name_strings vector[string] project project expand_trees logical open_only logical returns slice #: This procedure will take a list of file name strings and return #, a corresponding {slice} object. {project} specifies the root #, of non-relative file names in {file_names}. If {expand_trees} #, is {true}, any trees are expanded to their components; otherwise #, an error message is generated if a tree specification is encountered. #, Whenever any errors occur, ??@{slice} is returned. resources :@= project.resources global :@= project.global errors :@= global.errors #debug_stream :@= global.debug_stream #put@("expand@slice()\n\", debug_stream) file_system :@= global.file_system at_sign :@= "@"[0] colon :@= ":"[0] slice :@= xallocate@slice(project) project_files :@= slice.project_files size :@= file_name_strings.size index :@= 0 loop while index < size file_name_string :@= file_name_strings[index] #format@format2[unsigned, string](debug_stream, # "[%d%]: %ds%\n\", index, file_name_string) # Deal with any indirection files: if file_name_string.size != 0 && file_name_string[0] = at_sign # We have an indirection file: buffer :@= string_allocate@(resources) character_lop@(buffer) #format@format1[string](debug_stream, # 'Indirect file: %ds%\n\', buffer) string_deallocate@(resources, buffer) assert false else # Convert {file_name_string} to a project relative file: file_name :@= file_name_convert@(file_name_string) directory_file_name :@= (file_name.depth = 0) ? file_name.file_system.relative : file_name.parent #format@format3[unsigned, file_name, file_name](debug_stream, # "[%d%]: file_name: %ds% dir_name: %ds%\n\", # index, file_name, directory_file_name) project_directory :@= parse@project_directory(directory_file_name, project) #put@("project_directory: ", debug_stream) #print@(project_directory, debug_stream) #put@("\n\", debug_stream) if file_name.name = "..." # We have a directory tree: #put@("file_name: '...'\n\", debug_stream) if expand_trees expand@(project_directory, project_files, open_only) else format@errors1[file_name](errors, "No trees (like %ds%) are allowed by this command!\n\", file_name) break else project_file :@= create@project_file(project_directory, file_name.name) append@(project_files, project_file) index :+= 1 # Get rid of duplicates: if errors.exist deallocate@(slice) slice := ?? else sort@(project_files) unique@(project_files) return slice procedure no_deleted@slice takes slice slice command string returns logical #: This procedure will ensure that {slice} contains no deleted file #, specifications. If {slice} does contain some deleted files #, an error message containing {command} is output and {ture} is #, is returned; otherwise, {false} is returned. result :@= no_mode@(slice, command, deleted, 'Deleted') return result procedure no_directories@slice takes slice slice command string returns logical #: This procedure will ensure that {slice} contains no directory #, specifications. If {slice} does contain some directories, #, an error message containing {command} is output and {true} is #, returned; otherwise, {false} is returned. result :@= no_mode@(slice, command, directory, 'Directory') return result procedure no_files@slice takes slice slice command string returns logical #: This procedure will ensure that {slice} contains no file #, specifications. If {slice} does contain some files, an error #, message containing {command} is output and {true} is returned; #, otherwise, {false} is returned. result :@= no_mode@(slice, command, regular_file, 'Regular file') return result procedure no_links@slice takes slice slice command string returns logical #: This procedure will ensure that {slice} contains no symbolic link #, specifications. If {slice} does contain some directories, #, an error message containing {command} is output and {true} is #, returned; otherwise, {false} is returned. result :@= no_mode@(slice, command, symbolic_link, 'Symbolic link') return result procedure no_mode@slice takes slice slice command string mode status_mode mode_name string returns logical #: This procedure will ensure that {slice} contains no {project_file}'s #, of mode {status_mode}. If {slice} does, an error message is output #, that contains {command} and {true} is returned; otherwise {false} #, is returned. result:: logical := false errors :@= slice.project.global.errors project_files :@= slice.project_files size :@= project_files.size index :@= 0 loop while index < size project_file :@= project_files[index] actual_file_name :@= project_file.actual_file_name status :@= actual_file_name.status status_update@(actual_file_name) status := actual_file_name.status if status.mode = mode format@errors3[file_name, string, string](errors, '%ds% is of type %ds% and is not allowed in a %ds% command!\n\', actual_file_name, mode_name, command) result := true index :+= 1 return result procedure show@slice takes slice slice out_stream out_stream returns_nothing #: This procedure will output each file in {slice} to {out_stream}. show@(slice.project_files, out_stream, 0)