\begindata{text,538374540} \textdsversion{12} \template{be2guide} \define{global } \define{underline menu:[Font~1,Underline~41] attr:[Flags Underline Int Set]} \define{index menu:[Title,Index~91] attr:[FontFace Italic Int Set]} \define{indexi menu:[Title,InvisibleIndex~92] attr:[Script PreviousScriptMovement Point -2] attr:[Flags Hidden Int Set] attr:[FontFace Italic Int Set]} \define{fixedtext menu:[Region~4,Fixedtext] attr:[Justification LeftJustified Point 0] attr:[FontFace FixedFace Int Set] attr:[FontFamily AndyType Int 0] attr:[FontSize ConstantFontSize Point 10]} \define{fixedindent menu:[Region~4,Fixedindent] attr:[LeftMargin LeftMargin Cm 83230] attr:[Justification LeftJustified Point 0] attr:[FontFace FixedFace Int Set] attr:[FontFamily AndyType Int 0] attr:[FontSize ConstantFontSize Point 10]} \define{paramname menu:[Font~1,Paramname] attr:[FontFace Italic Int Set]} \formatnote{\chapter{Procedure Table}}\indexi{Proctable class} \indexi{Procedure table} The procedure table (a.k.a. \bold{proctable}) is a global table containing all of the commands bound to either keys or menu items in the system. One does not create the proctable: there is only one in the system; it is created at compile time and never destroyed. Why is there a proctable? First, the proctable provides a global name for every command procedure, allowing users to rebind command names to keys or menu entries at run-time. Second, since all of the commands and some short documentation are contained in a single proctable, an on-line help system can consult a database containing all of the commands, should a user make a "apropos" query (the "apropos" mechanism is a keyword-based search command provided by Emacs). Third, a proctable entry describes the type of object the command procedure requires in order to operate correctly. Several commands may be active simultaneously, each requiring different objects in order to operate correctly. The auxiliary type information associated with a proctable entry allows the interaction manager to invoke the invoked commands with an object of the appropriate type. For instance, you might bind a \italic{frame} command to some key in your .ezinit file; this mechanism ensures that this command will be applies to the \italic{frame} object when invoked. The interaction manager locates the appropriate object by searching up the view tree from the input focus, looking for an object whose type is a (possibly trivial) subclass of the type associated with the proctable entry. The command is applied to the first such object found. Finally, one can use proctable entries to dynamically load a module full of commands when an appropriate command is typed. If you simply used the dynamic loader to provide the address of a command that you might not really use in a particular run, the dynamic loader would have to load the function anyway, in order to return the required function's address. By using what is called an \bold{autoload} proctable entry, you can avoid actually loading the command's code until the command is actually invoked. An autoload proctable entry is created by providing a module name (the module parameter) instead of a procedure address (the proc parameter) in the \italic{proctable_DefineProc} call described below. For more information on dynamically loading command files, see the section entitled \italic{Dynamic Loading} below. Before binding a procedure to either a key sequence or a menu entry, you will have to create a proctable entry for it. Once a function is created and entered, an application program will be able to find it by looking in the procedure table. The class procedures provided by the proctable package can be used to add a procedure to the table, to look up procedures in the table, apply a procedure to all elements in the table, and force a table to be loaded. \subheading{Dynamic Loading} There is, in addition, a way of using proctable entries to dynamically load modules containing extra commands. To use the proctable in this manner, one defines a proctable entry that provides a module to dynamically load, but no procedure to invoke. When this command is invoked, the appropriate module will be loaded via the dynamic linking facilities of the Andrew Toolkit. Then, the newly-loaded module's \italic{InitializeClass} class procedure will re-define the particular proctable entry, officially exporting the justloaded command procedures. In order to actually export the real proctable entries, the module's \italic{InitializeClass} routine should call proctable_DefineProc with the same proctable name, but providing a null name for the module, and the real procedure's address for the \italic{proc} parameter. \section{Quick reference list for }proctable \fixedtext{\bold{proctable_}Defined }\fixedindent{(\paramname{self});} \fixedtext{void \bold{proctable_}DefineProcsWithTypes }\fixedindent{(struct proctable_DescriptionWithType *\paramname{procs});} \fixedtext{void \bold{proctable_}DefineProcs }\fixedindent{(struct proctable_Description *\paramname{procs});} \fixedtext{struct proctable_Entry *\bold{proctable_}DefineProc }\fixedindent{(char *\paramname{name}, procedure *\paramname{proc}, struct classinfo *\paramname{type}, char *\paramname{module}, char *\paramname{doc});} \fixedtext{struct proctable_Entry *\bold{proctable_}DefineTypedProc }\fixedindent{(char *\paramname{name}, procedure *\paramname{proc}, struct classinfo *\paramname{type}, char *\paramname{module}, char *\paramname{doc}, enum proctable_Type \paramname{returntype});} \fixedtext{void \bold{proctable_}Enumerate }\fixedindent{(procedure *\paramname{proc}, char *\paramname{procdata});} \fixedtext{void \bold{proctable_}ForceLoaded }\fixedindent{(struct proctable_Entry *\paramname{pe});} \fixedtext{\bold{proctable_}GetDocumentation }\fixedindent{(\paramname{self});} \fixedtext{\bold{proctable_}GetFunction }\fixedindent{(\paramname{self});} \fixedtext{\bold{proctable_}GetModule }\fixedindent{(\paramname{self});} \fixedtext{\bold{proctable_}GetName }\fixedindent{(\paramname{self});} \fixedtext{\bold{proctable_}GetReturnType }\fixedindent{(\paramname{self});} \fixedtext{\bold{proctable_}GetType }\fixedindent{(\paramname{self});} \fixedtext{boolean \bold{proctable_}InitializeClass }\fixedindent{();} \fixedtext{struct proctable_Entry *\bold{proctable_}Lookup }\fixedindent{(char *\paramname{name});} \paragraph{Defining a procedure in the table} \indexi{ \italic{proctable_Entry}} \indexi{ \italic{proctable_DefineProc}} \example{struct proctable_Entry *proctable_DefineProc(classID, name, proc, type, module, doc) char *name; int (*proc)(); struct classinfo *type; char *module; char *doc;} \leftindent{\bold{Class procedure description. } \italic{proctable_DefineProc} adds an entry to the procedure table. Only the parameter \italic{name}, the name of the procedure, which matches the fields in an entry, needs to be defined. However, all storage elements pointed to by the entry must be permanent. This means that you should have malloc handled by the caller, or pass literals. The optional parameters are\italic{ proc}, a pointer to the procedure, \italic{type}, the type of object the procedure is applied to, \italic{module}, the name of a dynamically loaded file to get the procedure, and \italic{doc}, a prose description of the function. \bold{Return value.} A pointer to the new procedure table entry. \bold{Usage.} The first call to DefineProc will make an entry into the table; subsequent calls to DefineProc can be used to update an existing entry. \bold{Example.} The following example creates a procedure that centers the string "helloworld" and also adds the procedure to a menu list. The code would be part of the InitializeClass procedure written for the program. \example{ struct proctable_Entry *tempProc; helloworldMenulist = menulist_New(); tempProc = proctable_DefineProc("helloworld-center", Center, &helloworld_classinfo,NULL, "Center the helloworld string."); menulist_AddToML(helloworldMenulist, "Center", tempProc, NULL);} } \begindata{bp,538928520} \enddata{bp,538928520} \view{bpv,538928520,1184,0,0} \paragraph{Looking up an entry in a table} \indexi{ \italic{proctable_Lookup}} \indexi{ \italic{proctable_Entry}} \example{struct proctable_Entry *proctable_Lookup(classID, name) register char *name;} \leftindent{\bold{Class procedure description. } \italic{proctable_Lookup} will look up an entry, given the name of the procedure. \bold{Return value.} The proctable entry, if found. \bold{Usage.} You can find any procedure in the procedure table by calling \italic{Lookup} with the name of the procedure. } \paragraph{Examining all procedures in the table.} \indexi{ \italic{proctable_Enumerate}} \example{void proctable_Enumerate(classID, proc, procdata) int (*proc)(); char *procdata;} \leftindent{\bold{Class procedure description. } \italic{proctable_Enumerate} calls the procedure\italic{ proc} on every entry in the procedure table. \bold{Usage.} If you are creating a function or an application that requires each entry in the procedure table to be accessed, you would use this procedure. \bold{Example.} If you want to create a function that will list all the functions a user can call, for example, like \italic{ Apropos} in Unix, then you might call \italic{proctable_Enumerate} with the procedure \italic{list}. } \paragraph{Forcing a function package to be loaded} \indexi{ \italic{proctable_ForceLoaded}} \example{void proctable_ForceLoaded(classID, procentry) struct proctable_Entry *procentry;} \leftindent{\bold{Class procedure description. } A call to \italic{proctable_ForceLoaded} will force a function package \italic{ procentry} to be loaded. \bold{Usage.} This procedure is typically used to ensure delayed evaluation or while debugging. \bold{Example.} Spell checking requires an entire file of procedures to be loaded into the editor. By having a delayed evaluation, i.e. by not loading the file until the key(s) that call the spell checker is hit, both time and space can be saved. \italic{proctable_ForceLoaded }would be called as soon as the spell checker is initiated to load up the spell check procedure file. } \begindata{bp,538928456} \enddata{bp,538928456} \view{bpv,538928456,1185,0,0} \paragraph{Access Macros } The following are access macros for the structure elements provided by this class. \programexample{ #define proctable_Defined(pe) ((pe)->proc != (int (*)()) 0) #define proctable_GetName(pe) ((pe)->name) #define proctable_GetFunction(pe) ((pe)->proc) #define proctable_GetType(pe) ((pe)->type) #define proctable_GetModule(pe) ((pe)->module) #define proctable_GetDocumentation(pe) ((pe)->doc) } \begindata{bp,537558784} \enddata{bp,537558784} \view{bpv,537558784,1187,0,0} Copyright 1992 Carnegie Mellon University and IBM. All rights reserved. \smaller{\smaller{$Disclaimer: Permission to use, copy, modify, and distribute this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice, this permission notice, and the following disclaimer appear in supporting documentation, and that the names of IBM, Carnegie Mellon University, and other copyright holders, not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. IBM, CARNEGIE MELLON UNIVERSITY, AND THE OTHER COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL IBM, CARNEGIE MELLON UNIVERSITY, OR ANY OTHER COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. $ }}\enddata{text,538374540}