% Copyright (C) 1989, Digital Equipment Corporation % All rights reserved. % See the file COPYRIGHT for a full description. % % Last modified on Mon Dec 21 13:24:38 PST 1992 by detlefs % modified on Tue Dec 15 10:58:01 PST 1992 by kalsow % modified on Mon Jul 1 19:27:55 1991 by muller \chapter{Local Guide} \label{local} This chapter describes how \srcmodula is installed at SRC, how to use it and how to contribute to it. \section{Your Environment} %------------------------- Find a DECstation (Pmax or 3max). Modula-3 runs on Vaxen, but almost nobody bothers. Modula-3 doesn't run on Alphas, yet. Before you work in Modula-3, login and make sure that your home directory contains the files listed below. It's important that you have these files in at least minimal working order. Beware! Getting everything perfect can be a {\em huge} time sink. \begin{description} \item[\tt .xsession] \index{.xsession@{\tt .xsession}} \index{xsession@{\tt .xsession}} \index{window manager} Your \verb|.xsession| file is run first, it selects your window manager and gets your X server initialized. After the comments, around line 38, there's a line that looks like: \begin{verbatim} set WINMGR = "tvtwm" \end{verbatim} \index{tvtwm@{\tt tvtwm}} \index{dxwm@{\tt dxwm}} \index{mwm@{\tt mwm}} \index{.tvtwmrc@{\tt .tvtwmrc}} The window managers that are allowed are \verb|tvtwm|, \verb|dxwm|, and \verb|mwm|. Today most people are using \verb|tvtwm|. Most window managers can be configured with a \verb|rc| file. I have a file named \verb|.tvtwmrc| that \verb|tvtwm| reads during startup. I don't know exactly what the file does, nor what it could do. I suggest you copy a version of the file from a friend and read the \verb|tvtwm| man page. \item[\tt .login] \index{.login@{\tt .login}} \index{login@{\tt .login}} \index{system.login@{\tt system.login}} Your \verb|.login| file should begin by reading the system-defined \verb|.login| file using the shell command: \begin{verbatim} source /proj/local/lib/system.login \end{verbatim} \index{search paths} This command will work on all our machines (Fireflies, VAX mainframes, DECstations). The file it refers to figures out what kind of machine you are running on and sets your basic environment accordingly. In particular, the programs {\tt m3}, {\tt m3pp}, {\tt m3make} and their man pages should be on your search paths. Put your personal customizations after the \verb|source| command given above. \item[\tt .cshrc] \index{.cshrc@{\tt .cshrc}} \index{cshrc@{\tt .cshrc}} \index{system.cshrc@{\tt system.cshrc}} Similarly, your \verb|.cshrc| file should begin with the line \begin{verbatim} source /proj/mips/lib/system.cshrc \end{verbatim} and conclude with your personal customizations. \item[\tt .X11Startup] \index{.X11Startup@{\tt .X11Startup}} Your \verb|.X11Startup| file is used to start a set of X applications each time you login. My \verb|.X11Startup| contains: \begin{verbatim} xmodmap /udir/kalsow/.xmodmaprc xload -geometry 130x70-0+135 & xclock -geometry 130x130-0+0 & xterm -iconic -geometry "80x55" & xterm -iconic -geometry "80x55" & xmh -iconic -geometry "685x750" & xrn -iconic -geometry "685x750" & \end{verbatim} \index{xmodmap@{\tt xmodmap}} \index{.xmodmaprc@{\tt .xmodmaprc}} \index{keyboard, bindings} \verb|xmodmap| is a program that can redefine the mapping of your keyboard. My \verb|.xmodmaprc| file fixes the brain damaged DECstation keyboard so that the escape key is in the right place and the shift lock is disabled. If you do nothing, the mystery key labelled ``F11'' is your escape key. Here's my \verb|.xmodmaprc| file: \begin{verbatim} ! ! Caps_Lock -> Control ! F1 -> Caps_Lock ! remove Lock = Caps_Lock keysym F1 = Caps_Lock keysym Caps_Lock = Control_R add Lock = Caps_Lock add Control = Control_R ! ! key cap character (first unshifted, second shifted) ! ! , , , < ! . . , > ! < > ` ~ ! ` ~ ESC ESC ! keysym less = quoteleft asciitilde keysym comma = comma less keysym period = period greater keysym quoteleft = Escape Escape \end{verbatim} \index{xmh@{\tt xmh}} \index{xload@{\tt xload}} \index{xrn@{\tt xrn}} I also start a program that displays my system's load average -- \verb|xload|, a clock, a few X terminals, my mail reader -- \verb|xmh|, and my news reader -- \verb|xrn|. \item[\tt .Xdefaults] \index{.Xdefaults@{\tt .Xdefaults}} \index{Xdefaults@{\tt .Xdefaults}} Your \verb|.Xdefaults| file defines some of the ten bazillion options that make X applications so much fun. My advice is to steal a copy from someone who's screen looks OK. When you're really bored, diddle with your \verb|.Xdefaults|. (You need to login again or run \verb|xdb| to reload your \verb|.Xdefaults| file.) \end{description} \section{Editing} %---------------- \index{editing} \index{gnuemacs@{\tt gnuemacs}} \index{epoch@{\tt epoch}} \index{emacs@{\tt emacs}} Several people at SRC have spent some time doing various things to try to make Modula-3 programming in \verb|gnuemacs| and \verb|epoch| more pleasant and productive. Our editing czar says, ``use \verb|epoch|''. \verb|Epoch| is a version of \verb|gnuemacs| that's been feature-ified to fit better with X; it is very similar to \verb|gnuemacs| and can even share the same elisp code. As always, you should probably read its man page. \index{.emacs@{\tt .emacs}} \index{e-lisp} You'll need a \verb|.emacs| file to hold your personal configuration. At SRC, you should copy this from \verb|/proj/generic/lib/_emacs| and uncomment lines that enable features you want to use; outside of SRC, the best way to get started is probably to copy a \verb|.emacs| from someone you trust. \index{.epoch@{\tt .epoch}} The following \verb|gnuemacs| elisp packages are included in the Modula 3 distribution. At SRC, these are kept in \verb|/proj/m3/pkg/gnuemacs/src|. \begin{itemize} \item {\tt nm3.el} \index{gnuemacs!Modula-3 mode} This package defines \verb|modula-3-mode|, an emacs ``major mode'' for editing Modula-3 source code. It provides mechanisms for formatting code and for quickly uppercasing and prefix-completing keywords. \item {\tt m3tags} \index{gnuemacs!tags} \index{m3tags@{\tt m3tags}} \index{tags} Eric Muller has adapted the emacs \verb|tags| facility to work for Modula-3. This allows one to quickly go to the definition of a sytactic unit when the cursor is pointing at a use of that unit. \end{itemize} \subsection*{\tt modula-3-mode} %------------------------ \index{gnuemacs!Modula-3 mode} \index{command completion} Here is a list of the key things Modula-3 mode provides: \begin{itemize} \item Indenting/pretty-printing \index{pretty-printing} Modula-3 mode gives you access two two methods of formatting code, one ``batch'' and one ``interactive.'' The batch method invokes the program \verb|m3pp|, which takes a program unit such as a procedure and formats it completely. The \verb|gnuemacs| commands that invoke \verb|m3pp| are \verb|M-x m3pp-region|, which pretty-prints the code between mark and point, and \verb|M-x m3pp-unit|, which pretty-prints the ``unit'' containing the cursor. (A unit is a top-level construct such as \verb|CONST|, \verb|TYPE|, \verb|VAR|, or \verb|PROCEDURE|.) \verb|m3pp-region| and \verb|m3pp-unit| are bound to the keys \verb|^cr| and \verb|^cu|, respectively. The other method of formatting text is a more traditional one for \verb|gnuemacs|, in which there the language mode provides a key that indents the current line appropriately. In keeping with the convention used in modes for other languages such as Lisp and C, the key used is \verb||. Typing \verb|| on a line indents the current line in a way that is (we hope) appropriate given the lines that precede it. The two formatting methods are not mutually exclusive; perhaps you like the way \verb|m3pp| lines up columns in declarations, but you also like to keep things indented while you type. You can use the electric mode to get things close, then invoke \verb|m3pp| when you're done. \item Avoidance of typing: \index{electric Modula-3 mode} Modula-3 mode offers some aid if you don't like typing a lot of uppercase keywords. The \verb|| actually serves double duty; it not only indents the current line, but when invoked at the end of a word, it attempts to complete the current word as a keyword. For example \verb|b| expands the \verb|b| to \verb|BEGIN|, provided the \verb|b| appears in a context where \verb|BEGIN| may be a valid keyword. There are some fairly extensive rules governing the contexts in which a given keyword is a valid completion; the net result is that it is seldom necessary to type more than one letter to get the correct completion. If you specify a non-unique prefix of a set of keywords, it chooses the first in an ordering intended to capture frequency of use; it also presents the other choices, and typing \verb|| repeatedly cycles through these choices. A pair of related features are ``\verb|END|-completion'' and ``\verb|END|-matching.'' If the elisp variable \verb|m3::electric-end| is set to \verb|'all|, completing the keyword \verb|END| has the additional effect of finding the construct that the \verb|END| completes. If that construct is a an interface, module, or procedure, it fills in the name of the completed construct after the \verb|END|; otherwise, it inserts a comment containing the keyword of the completed construct. If \verb|m3::electric-end| is \verb|'proc-mod|, it only fills in real names, never keyword comments. Independently, a non-\verb|nil| value of the elisp variable \verb|m3::blink-end-matchers| causes completion of \verb|END| to blink the cursor briefly at the beginning of the completed construct. \item Finding files. \index{mpindex} \index{interfaces, finding} \index{browsing interfaces} The key \verb|^ci| is bound to \verb|m3::show-interface|, which expects the point to be in an interface name, and attempts to find that interface and display it in another window. (If you are using \verb|epoch| and the value of \verb|m3::show-file-new-screen| is \verb|t|, which is the default, the interface will be displayed in a new \verb|epoch| screen, that is, a top-level X window. If you use \verb|m3-path| files, \verb|m3::show-interface| will use those to provide a search path; otherwise, it uses a built-in list of directories. The default value of this list is the one used at SRC; other sites will probably need to modify this. The key \verb|^cm| is bound to \verb|m3::show-implementation|. This attempts to find the module that implements the interface in the current buffer. This function relies on a SRC-specific convention where public interfaces are symbolic links to home directories for the packages that export them, which also contain the implementations. Obviously, this site-specific convention may not work outside of SRC, and \verb|m3::show-implementation| may need to be re-implemented or abandoned. \end{itemize} At SRC, \verb|gnuemacs| and \verb|epoch| are set up to automatically invoke Modula-3 mode to edit Modula-3 source code. Outside of SRC, you will need to put the following lines in your \verb|.emacs| file: \begin{verbatim} (setq auto-mode-alist (append (list '("\\.m3$\\|\\.i3$\\|\\.ig$\\|\\.mg$" . modula-3-mode)) auto-mode-alist)) \end{verbatim} The \verb|auto-mode-alist| says what mode you should enter when a file extension matches the given regular expression. \begin{verbatim} (autoload 'modula-3-mode "nm3" "A special mode for M3." t) \end{verbatim} The autoload command tells \verb|gnuemacs| what elisp file to load to get the definition for a given function. \begin{verbatim} (setq completion-ignored-extensions (append '(".mo" ".mx" ".mc" ".io" ".ix") completion-ignored-extensions)) \end{verbatim} When you find files, you would rather not be offered files with these extensions as possible completions. \subsection*{\tt m3-tags} %------------------------- \index{gnuemacs!tags} \index{m3tags@{\tt m3tags}} \index{tags} ``Tags'' is supposed to allow you to quickly find the definition of a given construct when the point is at a use. Eric Muller is the local master of tags. The program \verb|m3tags| builds tags for the public interfaces. To use the tag database from \verb|epoch| you need to add the line \begin{verbatim} (visit-tags-table "/proj/m3/lib.mips/FTAGS") \end{verbatim} to your \verb|.emacs| file. {\em INSERT how to use Steve Glassman's ``mpindex''. } \subsection*{to do (i.e. Dave Detlefs' wish list)} %----------------------------- \item Identifier completion. \index{command completion} \index{identifier completion} Dave has an experimental \verb|m3-complete-identifier| command, that constructs the complete list of identifiers declared in the current file, and then uses the current word as a prefix to pick out a set of possibilites. It is buggy, and too slow to use on even medium-sized files. He may try to make it robust, fast enough, and more ambitious: completing record field names or second parts of qualified names, etc. \item \verb|Epoch| display of the call stack in debugging. It would be kind of neat if, while debugging, the buffers on the source files for the call stack appeared as some sort of stack of windows. \end{itemize} \section{Compiling} %------------------ \index{m3make@{\tt m3make}} \index{packages!makefiles} You should use \verb|m3make|. The best advice for beginners is to copy an existing package that's similar to the one you want to create. You'll probably find the following files: \begin{verbatim} ./README - a top-level description created by m3create ./src/m3makefile - the input to m3make ./src/*.[im][3g] - the Modula-3 sources of the program ./mips/*.[im][ox] - the compiled objects for a DECstation ./vax/* - the compiled objects for a VAX \end{verbatim} There's a man page for \verb|m3make|, at some point you should read it. \index{gnuemacs!compile@{\tt compile}} \index{gnuemacs!next-error@{\tt next-error}} You can use \verb|epoch|'s \verb|compile| command to run \verb|m3make| and then use the \verb|next-error| facitility to quickly move to the source lines containing errors. The standard \verb|epoch| \verb|M-x compile| command will work with Modula-3 and \verb|m3make|. Invoke this command in a buffer whose current directory is the one containing your derived files (i.e. if your cursor is in a source file then first visit \verb|../mips|). When you invoke this command, it presents the current \verb|compile command| in the minibuffer for your approval. The first time you run this, the command will be \verb|make -k|. If you modify this to \verb|m3make|, that will become the new current command on subsequent makes. The results of the \verb|m3make| will be displayed in a buffer called \verb|*compilation*|. When a compile is finished, \verb|next-error| (\verb|^X-`|) will parse the \verb|*compilation*| buffer and find the first error in the file, moving the current error to the top of the \verb|*compilation*| buffer, and moving the point to the line containing the error in the appropriate source buffer. When you invoke \verb|next-error| again, it will go to the start of the next line containing an error. The big advantage of using \verb|next-error| is that uses the \verb|gnuemacs| ``marker'' facility to keep things straight if you edit the file to fix errors, changing the line numbers. Barring drastic edits, \verb|next-error| will still get you to the right line. \index{m3check@{\tt m3check}} Mick Jordan has also defined some commands that let you use \verb|m3check| in a shell window, and get about the same \verb|next-error| behavior. {\em INSERT the details...} \section{Debugging} %------------------- \index{debugging} \index{gdb@{\tt gdb}} \index{dbx@{\tt dbx}} Today you get your choice of debugger -- either \verb|gdb| or \verb|dbx|. At the moment most SRCers prefer \verb|gdb|, although it can't read DECstation core files. \subsection*{with {\tt dbx}} \index{.dbxinit@{\tt .dbxinit}} \index{timers} Like everything else, \verb|dbx| will read a start-up file. It reads the file named \verb|.dbxinit| in your home directory. In that file you place any commands that you'd like executed each time you start the debugger. Here's a suggested \verb|.dbxinit| file: \begin{verbatim} ignore 26 set $casesense = 1 set $printwide = 1 stop in RTException__NoHandler alias typeof(r) "print (_types[(*(int *)(r-4))//2]).name" alias wide "set $printwide = (1-$printwide)" alias threads "call Thread__DumpEverybody()" use src ../src /udir/XYZ/pkg/A/src /udir/XYZ/pkg/B/src \end{verbatim} The first line tells \verb|dbx| to ignore signal 26 -- the thread switching timer. The second line tells \verb|dbx| that all input is case-sensitive. The third line tells \verb|dbx| to print folded lines of output for large structures. The fourth line sets a break point in the runtime routine that's called for unhandled exceptions. The fifth line defines a new command that examines runtime data structures and prints the type of a reference. The fifth line defines a new command that toggles the folded output behavior. The sixth line defines a new command that produces a listing of all threads. The last line gives \verb|dbx| a list of directories to search when it's looking for source files. \subsection*{with {\tt gdb}} \index{.gdbinit@{\tt .gdbinit}} Like \verb|dbx| and everything else, \verb|gdb| will read a start-up file. It reads the file named \verb|.gdbinit| in your home directory. In that file you place any commands that you'd like executed each time you start the debugger. Here's a suggested \verb|.gdbinit| file: \begin{verbatim} dir dir /udir/steveg/b.e/mg/src dir /udir/steveg/b.e/zeus/src dir /udir/steveg/b.e/lego/src define ss nexti x/i $pc end define breaks info breakpoints end break RTException__NoHandler define threads call Thread__DumpEverybody() end \end{verbatim} The first set of lines gives \verb|gdb| a search path for locating source files. The next set defines a single step command. The third set defines a simple command to list the active breakpoints. The fourth sets a break point in the runtime routine that catches unhandled exceptions. And the last set of lines defines a \verb|threads| command to list all threads. \subsection*{from {\tt gnuemacs} or {\tt epoch}} \index{debugging!from the editor} There are some advantages to debugging Modula-3 programs under \verb|gnuemacs| or \verb|epoch|. You get \begin{itemize} \item Automatic display of the source file with the current line indicated when you stop at a breakpoint or move around in the stack while the program is stopped. \item You can set a breakpoint at the current line in a source file using the \verb|^X-| command. \item Special commands take \verb|REF| or \verb|OBJECT| variables (or their pointer values) and print their types and the values of the referents. (This feature depends on intimate knowledge of the \srcmodula implementation.) The command \verb|ESC-p| takes the word containing the current point as the variable or value to print. \verb|ESC-r| does the same thing with a record value. \end{itemize} These functions are built from \verb|gnuemacs|' \verb|gdb-mode| and \verb|dbx-mode| and are available in the \verb|m3-debug.el| elisp package. To use them outside of SRC, put these lines in your \verb|.emacs| file: \begin{verbatim} (autoload 'run-m3-gdb "m3-debug" "" t) (autoload 'run-m3-dbx "m3-debug" "" t) \end{verbatim} At SRC these autoloads are part of the default editing environment. You can then use \verb|M-x run-m3-gdb| or \verb|M-x run-m3-dbx| to start gdb or dbx, respectively, in inferior shells in the appropriate modes. \section{Packages} %---------------- \index{packages} We use the same package tools that everyone else at SRC is using. There are special variants of the commands that make it a little simpler for Modula-3 users. \index{.rhosts@{\tt .rhosts}} To get the Modula-3 package tools to work on your DECstation named \verb|foobaz|, you must have a \verb|.rhosts| file in your home directory on \verb|bigtop|. It should contain the line: \begin{verbatim} foobaz.pa.dec.com \end{verbatim} To manipulate a Modula-3 package named \verb|foo|, the last component of your working directory must be named \verb|foo|. \index{m3create@{\tt m3create}} \index{m3delete@{\tt m3delete}} \index{m3get@{\tt m3get}} \index{m3setlock@{\tt m3setlock}} \index{m3unlock@{\tt m3unlock}} \index{m3ship@{\tt m3ship}} \index{m3compare@{\tt m3compare}} Briefly, here's the available commands and what they do when issued in a directory named \verb|XYZ|. \begin{description} \item[m3create] -- creates a new package named \verb|XYZ|. \item[m3delete] -- deletes the package named \verb|XYZ|. \item[m3get] -- acquires the lock and updates the current directory with the contents of the package \verb|XYZ|. \item[m3setlock] -- acquires the lock on package \verb|XYZ|. \item[m3unlock] -- unlocks the package \verb|XYZ|. \item[m3ship] -- ships a copy of the current directory as the new contents of package \verb|XYZ|. \item[m3compare] -- compares the current directory with the existing version of package \verb|XYZ|. \end{description} For more details, see the man pages \section{Public Directories} %--------------------------- \index{export directories} \index{public directories} \index{pub.mips@{\tt pub.mips}} \index{lib.mips@{\tt lib.mips}} All the basic Modula-3 software lives in packages. These packages live in subdirectories of \verb|/proj/m3/pkg|. The public files are exported to public directories: \begin{center} \begin{tabular}{l|l|l} symbol & public directory & decription \\ \hline {\tt PUB} & {\tt /proj/m3/pub.{\it cpu\_type}} & interfaces\\ {\tt LIB} & {\tt /proj/m3/lib.{\it cpu\_type}} & libraries\\ {\tt BIN} & {\tt /proj/\{mips,ultrix\}/bin} & programs\\ {\tt CAT}{\it n} & {\tt /proj/man/{\it cpu\_type}/man/cat}{\it n} & plain-text man pages\\ \end{tabular} \end{center} where {\it cpu\_type} is either {\tt vax} or {\tt mips}, and {\it n} can vary from {\tt 1} to {\tt 8}. The Modula-3 compiler ({\tt m3}) knows about the public directories. By default, it will search the current directory and {\tt PUB} for interfaces. It will also try to locate libraries specified in the {\tt -l} syntax in {\tt LIB}. It will systematically link your programs with {\tt -lm3} and {\tt -lm}. \section{Package Organization} %----------------------------- \index{packages} We have four kinds of packages: \begin{itemize} \item source packages: They contain \modula sources and produce no derived objects. For an example, see the {\tt text} package. \item library packages: They usually contain a small number of source files, export a few interfaces to {\tt PUB} and export a single library containing all the objects to {\tt LIB}. For example, the {\tt tcl} package contains the source files for the binding to \verb|Tcl|. It exports {\tt TclC.i3} to {\tt PUB} and {\tt libm3tcl.a} to {\tt LIB}. \item umbrella packages: It is inconvenient to work with a large number of small libraries. An umbrella library collects a number of smaller libraries; it is essentially a list of source packages and it exports a library containing all the objects of the smaller packages. An example is {\tt libm3.a}. This library collects the contents of several source packages into a single large library. \item program packages: They contain a single program, exported to {\tt BIN}, with its man page exported to {\tt CAT1}. For an example, see the {\tt solitaire} or {\tt calculator} package. \end{itemize} %% %----------------- %% %% There is a limited facility to store packages under Vesta as well as %% in {\tt /proj}. The following targets are supported by {\tt m3make}: %% \begin{center} %% \begin{tabular}{l|l} %% target & action \\ \hline %% {\tt checkin} & \verb|vmake -noeval| \\ %% & \verb|vmake -ci < /dev/null| \\ %% {\tt chekout} & \verb|vmake -co $(PACKAGE) < /dev/null| \\ %% {\tt vestacreate} & \verb|vmake -co $(PACKAGE).1| \\ %% \end{tabular} %% \end{center} %% %% \section{Editing} %% %---------------- %% %% Your \verb|.emacs| file should begin with: %% \begin{verbatim} %% (if (boundp 'epoch::version) %% (progn %% (load "dot.emacs" nil t) %% (setq auto-raise-screen nil))) %% %% ;;-------------------- m3-mode -------------------- %% %% (setq gdb-mode-hook 'm3-gdb-mode-hook-function) %% %% (defun m3-gdb-mode-hook-function () %% (dbx-prompt) %% (shell-mods-add-to-keymap gdb-mode-map)) %% %% (setq dbx-mode-hook 'm3-dbx-mode-hook-function) %% %% (defun m3-dbx-mode-hook-function () %% (dbx-prompt) %% (shell-mods-add-to-keymap inferior-dbx-mode-map)) %% %% \end{verbatim} %% %% There's a simple Modula-3 browsing facitilty. To use it, %% add %% \begin{verbatim} %% (global-set-key "\C-C2" 'm3-find-interface) %% (global-set-key "\C-C3" 'm3-find-module) %% \end{verbatim} %% to your \verb|.emacs| file and so that the commands \verb|2| %% and \verb|3| are bound. Then, in a Modula-3 file place the %% cursor on the name of an interface and type \verb|2|. %% If possible, a new window will pop-up containing the named interface. %% Typing \verb|3| will cause the corresponding implementation to be %% displayed. %%