{Begin SubSec File Package Types} {Title File Package Types} {Text {Tag FilePkgTypes} In addition to the definitions of functions and values of variables, source files in Interlisp can contain a variety of other information, e.g. property lists, record declarations, macro definitions, hash arrays, etc. In order to treat such a diverse assortment of data uniformly from the standpoint of file operations, the file package uses the concept of a {it typed definition}, of which a function definition is just one example. A typed definition associates with a name (usually a litatom), a definition of a given type (called the file package type). Note that the same name may have several definitions of different types. For example, a litatom may have both a function definition and a variable definition. The file package also keeps track of the file that a particular typed definition is stored on, so one can think of a typed definition as a relation between four elements: a name, a definition, a type, and a file. A file package type is an abstract notion of a class of objects which share the property that every object of the same file package type is stored, retrieved, edited, copied etc., by the file package in the same way. Each file package type is identified by a litatom, which can be given as an argument to the functions that manipulate typed definitions. The user may define new file package types, as described in {PageRef Fn FILEPKGTYPE}. {VarDef {Name FILEPKGTYPES} {Text The value of {var FILEPKGTYPES} is a list of all file package types, including any that may have been defined by the user. }} The file package is initialized with the following built-in file package types: {Begin LabeledList file package types} {Name {lisp FNS}} {Text {index *PRIMARY* FNS (File Package Type)}Function definitions. } {Name {lisp VARS}} {Text {index *PRIMARY* VARS (File Package Type)}(top-level) Variable values. } {Name {lisp PROPS}} {Text {index *PRIMARY* PROPS (File Package Type)}Property name/value pairs. When a property is changed or added, an object of type {lisp PROPS}, with "name" {lisp ({arg LITATOM} {arg PROPNAME})} is marked as being changed. Note that some properties are used to implement other file package types. For example, the property {prop MACRO} implements the file package type {lisp MACROS}, the property {prop ADVICE} implements {lisp ADVICE}, etc. This is indicated by putting the property {prop PROPTYPE},{index *PRIMARY* PROPTYPE Prop} with value of the file package type on the property list of the property name. For example, {lisp (GETPROP 'MACRO 'PROPTYPE) => MACROS}. When such a property is changed or added, an object of the corresponding file package type is marked. If {lisp (GETPROP {arg PROPNAME} 'PROPTYPE) => IGNORE}, the change is ignored. The {prop FILE}, {prop FILEMAP}, {prop FILEDATES}, etc. properties are all handled this way. (Note that {lisp IGNORE} cannot be the name of a file package type implemented as a property). } {Name {lisp ALISTS}} {Text {index *PRIMARY* ALISTS (File Package Type)}Alists (association lists); a list of dotted pairs accessed via {fn ASSOC} and {fn PUTASSOC}. A variable is declared to have an association list as its value by putting on its property list the property {prop VARTYPE}{index *PRIMARY* VARTYPE Prop} with value {lisp ALIST}. In this case, each dotted pair on the list is an object of type {lisp ALISTS}. When the value of such a variable is changed, only those entries in the a-list that are actually changed or added are marked as changed objects of type {lisp ALISTS} (with "name" {lisp ({arg LITATOM} {arg KEY})}). Objects of type {lisp ALISTS} are dumped via the {filecom ALISTS} or {filecom ADDVARS} file package commands. Note that some alists are used to "implement" other file package types. For example, the value of the global variable {var USERMACROS} implements the file package type {lisp USERMACROS} and the values of {var LISPXMACROS} and {var LISPXHISTORYMACROS} implement the file package type {lisp LISPXMACROS}. This is indicated by putting on the property list of the variable the property {prop VARTYPE} with value a list of the form {lisp (ALIST {arg FILEPKGTYPE})}. For example, {lisp (GETPROP 'LISPXHISTORYMACROS 'VARTYPE) => (ALIST LISPXMACROS)}. } {Name {lisp EXPRESSIONS}} {Text {index *PRIMARY* EXPRESSIONS (File Package Type)}Expressions. Objects of type {lisp EXPRESSIONS} are written out via the {filecom P} file package command, and marked as being changed via the {pacom REMEMBER} programmers assistant command ({PageRef PACom REMEMBER}). } {Name {lisp MACROS}} {Text {index *PRIMARY* MACROS (File Package Type)}Compiler macros. See {PageRef Tag Macros}. } {Name {lisp USERMACROS}} {Text {index *PRIMARY* USERMACROS (File Package Type)}User edit macros. See {PageRef Tag EditMacros}. } {Name {lisp LISPXMACROS}} {Text {index *PRIMARY* LISPXMACROS (File Package Type)}(values in) {lisp LISPXMACROS} and {var LISPXHISTORYMACROS}. See {PageRef Var LISPXMACROS}. } {Name {lisp ADVICE}} {Text {index *PRIMARY* ADVICE (File Package Type)}Advice. See {PageRef Tag Advising}. } {Name {lisp FILEPKGCOMS}} {Text {index *PRIMARY* FILEPKGCOMS (File Package Type)}File package commands/types. New file package types and commands can be defined as explained on {PageRef Fn FILEPKGTYPE} and {PageRef Fn FILEPKGCOM}. {note The "definition" of an object of type FILEPKGCOMS is a list structure which contains information about both the file package type and file package command of a particular name.} {Begin Note} Date: 18 FEB 1982 1622-PST From: KAPLAN Subject: New definition format for FILEPKGCOMS The definition of a FILEPKGCOMS is now a list of the form ((COM . props)(TYPE . props)), where props are the various attributes of the name thought of as a filepkg command or type. Properties not mentioned are assumed to have NIL values. This is the kind of object that GETDEF returns and that PUTDEF accepts. The functions FILEPKGCOM and FILEPKGTYPE allow for the setting of individual properties without redefining the whole thing. {End Note} } {Name {lisp RECORDS}} {Text {index *PRIMARY* RECORDS (File Package Type)}Record declarations. See {PageRef Tag RecordPackage}. } {Name {lisp FIELDS}} {Text {index *PRIMARY* FIELDS (File Package Type)}Fields of records. The "definition" of an object of type {lisp FIELDS} is a list of all the record declarations which contain the name. See {PageRef Tag RecordPackage}. } {Name {lisp I.S.OPRS}} {Text {index *PRIMARY* I.S.OPRS (File Package Type)}Iterative statement operators. See {PageRef Tag IterativeStatement}. } {Name {lisp TEMPLATES}} {Text {index *PRIMARY* TEMPLATES (File Package Type)}Masterscope templates. See {PageRef Tag Masterscope}. } {Name {lisp FILES}} {Text {index *PRIMARY* FILES (File Package Type)}Files. Files may be treated like other typed definitions. {Begin Note} Date: 16 Oct 1978 1:42 pm (Monday) From: Masinter (implementation change) GETDEF(X FILES) now returns a more complicated data structure than before (it used to just return the COMS for the file, now the value of GETDEF includes part of the FILE and FILEDATES property of X). PUTDEF(X FILE DEFINITION) will MAKEFILE(X) copying functions if necessary from the "old" file (supplied as part of the DEFINITION). This change should not affect any users (the only use I have ever made of FILES as a type is to rename them); it made it possible to remove a special check in the COPYDEF function to handle this case. {End Note} } {Name {lisp FILEVARS}} {Text {index *PRIMARY* FILEVARS (File Package Type)}Filevars. See {PageRef Tag FileVars}. } {End LabeledList file package types} {Begin Note} doc synonyms??? synonyms for file package types: (LISPXCOMS . LISPXMACROS) (FILEPKGTYPES . FILEPKGCOMS) (EDITMACROS . USERMACROS) {End Note} {Begin Note} Date: 2 DEC 1978 1449-PST From: MASINTER FILEPKGTYPE now allowed as synonym for FILEPKGCOM in calls to GETDEF, EDITDEF {End Note} {note other filepkgtypes: GLOBALRESOURCES } {Begin SubSec Functions for Manipulating Typed Definitions} {Title Functions for Manipulating Typed Definitions} {Text The functions described below can be used to manipulate typed definitions, without needing to know how the manipulations are done. For example, {lisp (GETDEF 'FOO 'FNS)} will return the function definition of {lisp FOO}, {lisp (GETDEF 'FOO 'VARS)} will return the variable value of {lisp FOO}, etc. All of the functions use the following conventions: {Begin LabeledList Typed Definitions Functions conventions} {Indent 5percent} {Name (1)} {Text Any argument that expects a list of litatoms will also accept a single litatom, operating as though it were enclosed in a list. For example, if the argument {arg FILES} should be a list of files, it may also be a single file. } {Name (2)} {Text {arg TYPE} is a file package type. {arg TYPE}={lisp NIL} is equivalent to {arg TYPE}={lisp FNS}. The singular form of a file package type is also recognized, e.g. {arg TYPE}={lisp VAR} is equivalent to {arg TYPE}={lisp VARS}. } {Name (3)} {Text {arg FILES}={lisp NIL} is equivalent to {arg FILES}={var FILELST}. } {Name (4)} {Text {arg SOURCE} is used to indicate the source of a definition, that is, where the definition should be found. {arg SOURCE} can be one of: {Begin LabeledList SOURCE} {Indent 15percent} {Name {lisp CURRENT}} {Text Get the definition currently in effect. } {Name {lisp SAVED}} {Text Get the "saved" definition, as stored by {fn SAVEDEF} ({PageRef Fn SAVEDEF}). } {Name {lisp FILE}} {Text Get the definition contained on the (first) file determined by {fn WHEREIS} ({PageRef Fn WHEREIS}). Note: {fn WHEREIS} is called with {arg FILES}={lisp T}, so that if the WHEREIS package ({PageRef Tag WhereisPackage}) is loaded, the WHEREIS data base will be used to find the file containing the definition. } {Name {lisp ?}} {Text Get the definition currently in effect if there is one, else the saved definition if there is one, otherwise the definition from a file determined by {fn WHEREIS}. Like specifying {lisp CURRENT}, {lisp SAVED}, and {lisp FILE} in order, and taking the first definition that is found. } {Name a file name or list of file names} {Text Get the definition from the first of the indicated files that contains one. } {Name {lisp NIL}} {Text In most cases, giving {arg SOURCE}={lisp NIL} (or not specifying it at all) is the same as giving {lisp ?}, to get either the current, saved, or filed definition. However, with {fn HASDEF}, {arg SOURCE}={lisp NIL} is interpreted as equal to {arg SOURCE}={lisp CURRENT}, which only tests if there is a current definition. } {End LabeledList SOURCE} } {Name (5)} {Text All functions which make destructive changes are undoable. } {End LabeledList Typed Definitions Functions conventions} {note HASDEF, GETDEF now only accept file package types (not commands), e.g. GETDEF(FOO COMS) causes error "COMS not file package type". } The operation of most of the functions described below can be changed or extended by modifying the appropriate properties for the corresponding file package type using the function {fn FILEPKGTYPE}, described on {PageRef Fn FILEPKGTYPE}. {FnDef {FnName GETDEF} {FnArgs NAME TYPE SOURCE OPTIONS} {Text Returns the definition of {arg NAME}, of type {arg TYPE}, from {arg SOURCE}. For most types, {fn GETDEF} returns the expression which would be prettyprinted when dumping {arg NAME} as {arg TYPE}. For example, for {arg TYPE}={lisp FNS}, an {lisp EXPR} definition is returned, for {arg TYPE}={lisp VARS}, the value of {arg NAME} is returned, etc. {arg OPTIONS} is a list which specifies certain options: {Begin LabeledList GETDEF options} {Indent 20percent} {Name {lisp NOERROR}} {Text {fn GETDEF} causes an error if an appropriate definition cannot be found, unless {arg OPTIONS} is or contains {lisp NOERROR}. } {Name a string} {Text If {arg OPTIONS} is or contains a string, that string will be returned if no definition is found. The caller can thus determine whether a definition was found, even for types for which {lisp NIL} or {lisp NOBIND} are acceptable definitions. } {Name {lisp NOCOPY}} {Text {fn GETDEF} returns a copy of the definition unless {arg OPTIONS} is or contains {lisp NOCOPY}. } {Name {lisp NODWIM}} {Text A {lisp FNS} definition will be dwimified if it is likely to contain CLISP unless {arg OPTIONS} is or contains {lisp NODWIM}. } {End LabeledList GETDEF options} {note additional GETDEF options which need to be explained: SPELL, HASDEF, FAST, ARGLIST} }} {FnDef {FnName PUTDEF} {FnArgs NAME TYPE DEFINITION} {Text Defines {arg NAME} of type {arg TYPE} with {arg DEFINITION}. For {arg TYPE}={lisp FNS}, does a {fn DEFINE}; for {arg TYPE}={lisp VARS}, does a {fn SAVESET}, etc. For {arg TYPE}={lisp FILES}, {fn PUTDEF} establishes the command list, notices {arg NAME}, and then calls {fn MAKEFILE} to actually dump the file {arg NAME}, copying functions if necessary from the "old" file (supplied as part of {arg DEFINITION}). }} {FnDef {FnName HASDEF} {FnArgs NAME TYPE SOURCE SPELLFLG} {Text Returns {lisp (OR {arg NAME} T)} if {arg NAME} is the name of something of type {arg TYPE}. If not, attempts spelling correction if {arg SPELLFLG}={lisp T}, and returns the spelling-corrected {arg NAME}. Otherwise returns {lisp NIL}. {lisp (HASDEF NIL {arg TYPE})} returns {lisp T} if {lisp NIL} has a valid definition. Note: if {arg SOURCE}={lisp NIL}, {arg HASDEF} interprets this as equal to {arg SOURCE}={lisp CURRENT}, which only tests if there is a current definition. }} {FnDef {FnName TYPESOF} {FnArgs NAME POSSIBLETYPES IMPOSSIBLETYPES SOURCE} {Text Returns a list of the types in {arg POSSIBLETYPES} but not in {arg IMPOSSIBLETYPES} for which {arg NAME} has a definition. {lisp FILEPKGTYPES} is used if {arg POSSIBLETYPES} is {lisp NIL}. }} {FnDef {FnName COPYDEF} {FnArgs OLD NEW TYPE SOURCE OPTIONS} {Text {tag COPYDEF} Defines {arg NEW} to have a copy of the definition of {arg OLD} by doing {fn PUTDEF} on a copy of the definition retrieved by {lisp (GETDEF {arg OLD} {arg TYPE} {arg SOURCE} {arg OPTIONS})}. {arg NEW} is substituted for {arg OLD} in the copied definition, in a manner that may depend on the {arg TYPE}. {note I assume that COPYDEF will fail miserably if given any user-defined file package type which contains internal references to its name. Perhaps there should be a COPYDEF attribute definable by FILEPKGTYPE ???} For example, {lisp (COPYDEF 'PDQ 'RST 'FILES)} sets up {lisp RSTCOMS} to be a copy of {lisp PDQCOMS}, changes things like {lisp (VARS * PDQVARS)} to be {lisp (VARS * RSTVARS)} in {lisp RSTCOMS}, and performs a {fn MAKEFILE} on {lisp RST} such that the appropriate definitions get copied from {lisp PDQ}. Note: {fn COPYDEF} disables the {lisp NOCOPY} option of {fn GETDEF}, so {arg NEW} will always have a {it copy} of the definition of {arg OLD}. }} {FnDef {FnName DELDEF} {FnArgs NAME TYPE} {Text Removes the definition of {arg NAME} as a {arg TYPE} that is currently in effect. }} {FnDef {FnName SHOWDEF} {FnArgs NAME TYPE FILE} {Text Prettyprints the definition of {arg NAME} as a {arg TYPE} to {arg FILE}. This shows the user how {arg NAME} would be written to a file. Used by {fn ADDTOFILES?} ({PageRef Fn ADDTOFILES?}). }} {FnDef {FnName EDITDEF} {FnArgs NAME TYPE SOURCE EDITCOMS} {Text Edits the definition of {arg NAME} as a {arg TYPE}. Essentially performs {lisp (PUTDEF {arg NAME} {arg TYPE} (EDITE (GETDEF {arg NAME} {arg TYPE} {arg SOURCE}) {arg EDITCOMS}))}. }} {index *PRIMARY* SAVEDEF Fn} {FnDef {FnName SAVEDEF} {FnArgs NAME TYPE DEFINITION} {Text Makes {arg DEFINITION} (or if {arg DEFINITION}={lisp NIL}, the definition of {arg NAME} as a {arg TYPE} that is currently in effect) be the "saved" definition for {arg NAME} as a {arg TYPE}. If {arg TYPE}={lisp FNS} (or {arg TYPE}={lisp NIL}), this consists of storing {arg DEFINITION} on {arg NAME}'s property list under property {prop EXPR}, {prop CODE}, or {prop SUBR}. For {arg TYPE}={lisp VARS}, the definition is stored as the value of the {prop VALUE} property. For other types, {arg DEFINITION} is stored in an internal data structure, from where it can be retrieved by {fn GETDEF} or {fn UNSAVEDEF}. }} {FnDef {FnName UNSAVEDEF} {FnArgs NAME TYPE {anonarg}} {Text Makes the "saved" definition of {arg NAME} as a {arg TYPE} be the definition currently in effect. If {arg TYPE}={lisp FNS} (or {arg TYPE}={lisp NIL}), {fn UNSAVEDEF} will unsave the {prop EXPR} property if any, else {prop CODE} or {prop SUBR}. {fn UNSAVEDEF} also recognizes {arg TYPE}={lisp EXPR}, {lisp CODE}, or {lisp SUBR}, meaning to unsave the corresponding definition only. }} {FnDef {FnName LOADDEF} {FnArgs NAME TYPE SOURCE} {Text Equivalent to {lisp (PUTDEF {arg NAME} {arg TYPE} (GETDEF {arg NAME} {arg TYPE} {arg SOURCE}))}. {fn LOADDEF} is essentially a generalization of {fn LOADFNS}, e.g. it enables loading a single record declaration from a file. Note that {lisp (LOADDEF {arg FN})} will give {arg FN} an {lisp EXPR} definition, either obtained from its property list or a file, unless it already has one. {note calls GETDEF with OPTIONS=(NODWIM NOCOPY)} }} {FnDef {FnName CHANGECALLERS} {FnArgs OLD NEW TYPES FILES METHOD} {Text Finds all of the places where {arg OLD} is used as any of the types in {arg TYPES} and changes those places to use {arg NEW}. For example, {lisp (CHANGECALLERS 'NLSETQ 'ERSETQ)} will change all calls to {fn NLSETQ} to be calls to {fn ERSETQ}. Also changes occurrences of {arg OLD} to {arg NEW} inside the filecoms of any file, inside record declarations, properties, etc. {fn CHANGECALLERS} attempts to determine if {arg OLD} might be used as more than one type; for example, if it is both a function and a record field. If so, rather than performing the transformation {lisp {arg OLD} -> {arg NEW}} automatically, the user is allowed to edit all of the places where {arg OLD} occurs. For each occurrence of {arg OLD}, the user is asked whether he wants to make the replacement. If he responds with anything except {lisp Yes} or {lisp No}, the editor is invoked on the expression containing that occurrence. There are two different methods for determining which functions are to be examined. If {arg METHOD}={lisp EDITCALLERS}, {fn EDITCALLERS} is used to search {arg FILES} (see {PageRef Fn EDITCALLERS}). If {arg METHOD}={lisp MASTERSCOPE}, then the Masterscope database is used instead. {arg METHOD}={lisp NIL} defaults to {lisp MASTERSCOPE} if the value of the variable {var DEFAULTRENAMEMETHOD}{index DEFAULTRENAMEMETHOD Var} is {lisp MASTERSCOPE} and a Masterscope database exists, otherwise it defaults to {lisp EDITCALLERS}. }} {FnDef {FnName RENAME} {FnArgs OLD NEW TYPES FILES METHOD} {Text, as documented First performs {lisp (COPYDEF {arg OLD} {arg NEW} {arg TYPE})} for all {arg TYPE} inside {arg TYPES}. It then calls {fn CHANGECALLERS} to change all occurrences of {arg OLD} to {arg NEW}, and then "deletes" {arg OLD} with {fn DELDEF}. For example, if the user has a function {lisp FOO} which he now wishes to call {lisp FIE}, he simply performs {lisp (RENAME 'FOO 'FIE)}, and {lisp FIE} will be given {lisp FOO}'s definition, and all places that {lisp FOO} are called will be changed to call {lisp FIE} instead. }} {FnDef {FnName COMPARE} {FnArgs NAME1 NAME2 TYPE SOURCE1 SOURCE2} {Text Compares definiton of {arg NAME1} with that of {arg NAME2}, i.e. performs {lisp (COMPARELISTS (GETDEF {arg NAME1} {arg TYPE} {arg SOURCE1}) (GETDEF {arg NAME2} {arg TYPE} {arg SOURCE2}))} }} {FnDef {FnName COMPAREDEFS} {FnArgs NAME TYPE SOURCES} {Text Calls {fn COMPARELISTS} on all pairs of definitions of {arg NAME} as a {arg TYPE} obtained from the various {arg SOURCES}. }} }{End SubSec Functions for Manipulating Typed Definitions} {Begin SubSec Defining New File Package Types} {Title Defining New File Package Types} {Text {index *BEGIN* defining file package types} All manipulation of typed definitions in the file package is done using the type-independent functions {fn GETDEF}, {fn PUTDEF}, etc. Therefore, to define a new file package type, it is only necessary to specify (via the function {fn FILEPKGTYPE}) what these functions should do when dealing with a typed definition of the new type. Each file package type has the following properties, whose values are functions or lists of functions: Note: These functions are defined to take a {arg TYPE} argument so that the user may have the same function for more than one type. {Begin LabeledList FILEPKGTYPE PROP is one of} {Indent 20percent} {Label {lisp GETDEF}} {Text Value is a function of three arguments, {arg NAME}, {arg TYPE}, and {arg OPTIONS}, which should return the current definition of {arg NAME} as a type {arg TYPE}. Used by {fn GETDEF} (which passes its {arg OPTION} argument). If there is no {lisp GETDEF} property, a file package command for dumping {arg NAME} is created (by {fn MAKENEWCOM}). This command is then used to write the definition of {arg NAME} as a type {arg TYPE} onto the file {lisp FILEPKG.SCRATCH}{index FILEPKG.SCRATCH (file)} (in Interlisp-D, this file is created on the {lisp {bracket CORE}} device). This expression is then read back in and returned as the current definition. {note if GETDEF prop is T (FNS, VARS, etc), this is handled by code in GETDEFCURRENT} } {Label {lisp FILEGETDEF}} {Text This enables the user to provide a way of obtaining definitions from a file that is more efficient than the default procedure used by {fn GETDEF}. Value is a function of four arguments, {arg NAME}, {arg TYPE}, {arg FILE}, and {arg OPTIONS}. The function is applied by {fn GETDEF} when it is determined that a typed definition is needed from a particular file. The function must open and search the given file and return any {arg TYPE} definition for {arg NAME} that it finds. } {Label {lisp PUTDEF}} {Text Value is a function of three arguments, {arg NAME}, {arg TYPE}, and {arg DEFINITION}, which should store {arg DEFINITION} as the definition of {arg NAME} as a type {arg TYPE}. Used by {fn PUTDEF}. } {Label {lisp DELDEF}} {Text Value is a function of two arguments, {arg NAME}, and {arg TYPE}, which removes the definition of {arg NAME} as a {arg TYPE} that is currently in effect. Used by {fn DELDEF}. } {Label {lisp NEWCOM}} {Text Value is a function of four arguments, {arg NAME}, {arg TYPE}, {arg LISTNAME}, and {arg FILE}. Specifies how to make a new (instance of a) file package command to dump {arg NAME}, an object of type {arg TYPE}. The function should return the new file package command. Used by {fn ADDTOFILE} and {fn SHOWDEF}. If {arg LISTNAME} is non-{lisp NIL}, this means that the user specified {arg LISTNAME} as the filevar in his interaction with {fn ADDTOFILES?} (see {PageRef Tag FileVars}). If no {lisp NEWCOM} is specified, the default is to call {fn DEFAULTMAKENEWCOM},{index DEFAULTMAKENEWCOM FN} which will construct and return a command of the form {lisp ({arg TYPE} {arg NAME})}. {fn DEFAULTMAKENEWCOM} can be advised or redefined by the user. } {Label {lisp WHENCHANGED}} {Text Value is a list of functions to be applied to {arg NAME}, {arg TYPE}, and {arg REASON} when {arg NAME}, an instance of type {arg TYPE}, is changed or defined (see {fn MARKASCHANGED}, {PageRef Fn MARKASCHANGED}). Used for various applications, e.g. when an object of type {lisp I.S.OPRS} changes, it is necessary to clear the corresponding translatons from {var CLISPARRAY}. The {lisp WHENCHANGED} functions are called before the object is marked as changed, so that it can, in fact, decide that the object is {it not} to be marked as changed, and execute {lisp (RETFROM 'MARKASCHANGED)}. Note: For backwards compatibility, the {arg REASON} argument passed to {lisp WHENCHANGED} functions is either {lisp T} (for {lisp DEFINED}) and {lisp NIL} (for {lisp CHANGED}). } {Label {lisp WHENFILED}} {Text Value is a list of functions to be applied to {arg NAME}, {arg TYPE}, and {arg FILE} when {arg NAME}, an instance of type {arg TYPE}, is added to {arg FILE}. } {Label {lisp WHENUNFILED}} {Text Value is a list of functions to be applied to {arg NAME}, {arg TYPE}, and {arg FILE} when {arg NAME}, an instance of type {arg TYPE}, is removed from {arg FILE}. } {Label {lisp DESCRIPTION}} {Text Value is a string which describes instances of this type. For example, for type {lisp RECORDS}, the value of {lisp DESCRIPTION} is the string {lisp "record declarations"}. } {End LabeledList FILEPKGTYPE PROP is one of} {Begin Note} Date: 4 SEP 83 11:38 PDT From: KAPLAN.PA Subject: EDITDEF filepkgtype property I'm not going to document this. As far as I can tell, it is only used by EDITFROMFILE, and then only to suppress editing if the value happens to be the function NILL. Larry, if there really is some reason for this property, you'll have to describe what it is. {End Note} The function {fn FILEPKGTYPE} is used to define new file package types, or to change the attributes of existing types. Note that it is possible to redefine the attributes of system file package types, such as {lisp FNS} or {lisp PROPS}. {FnDef {FnName FILEPKGTYPE} {FnArgs TYPE PROP{SUB 1} VAL{SUB 1} {ellipsis} PROP{SUB N} VAL{SUB N}} {Type NOSPREAD} {Text Nospread function for defining new file package types, or changing attributes of existing file package types. {arg PROP{sub i}} is one of the property names given above; {arg VAL{sub i}} is the value to be given to that property. Returns {arg TYPE}. {lisp (FILEPKGTYPE {arg TYPE} {arg PROP})} returns the value of the property {arg PROP}, without changing it. {lisp (FILEPKGTYPE {arg TYPE}} returns an alist of all of the defined properties of {arg TYPE}, using the property names as keys. }} {index *END* defining file package types} }{End SubSec Defining New File Package Types} }{End SubSec File Package Types}