From: CSRG Date: Mon, 31 Jan 1983 12:16:11 +0000 (-0800) Subject: BSD 4_2 development X-Git-Tag: BSD-4_3^2~1482 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/4695eb475349b48d274b773c9e511a6249b9b186 BSD 4_2 development Work on file usr/src/ucb/pascal/pdx/command/Changes Work on file usr/src/ucb/pascal/pdx/READ_ME Work on file usr/src/ucb/pascal/pdx/intro.nroff Work on file usr/src/ucb/pascal/pdx/pdx.1 Work on file usr/src/ucb/pascal/pdx/sccs Work on file usr/src/ucb/pascal/pdx/cerror.s Synthesized-from: CSRG/cd1/4.2 --- diff --git a/usr/src/ucb/pascal/pdx/READ_ME b/usr/src/ucb/pascal/pdx/READ_ME new file mode 100644 index 0000000000..ea00b6437c --- /dev/null +++ b/usr/src/ucb/pascal/pdx/READ_ME @@ -0,0 +1,7 @@ +This directory contains the source to pdx, a Pascal debugger that +works with pi and px. Pascal-dependent stuff is primarily in the +"sym" directory, p-code dependent stuff in "machine", and +object file format in "object". + +The make file ("Makefile") is the best source of up-to-date general +comments about the pdx source. diff --git a/usr/src/ucb/pascal/pdx/cerror.s b/usr/src/ucb/pascal/pdx/cerror.s new file mode 120000 index 0000000000..3c12edfb56 --- /dev/null +++ b/usr/src/ucb/pascal/pdx/cerror.s @@ -0,0 +1 @@ +cerror.vax \ No newline at end of file diff --git a/usr/src/ucb/pascal/pdx/command/Changes b/usr/src/ucb/pascal/pdx/command/Changes new file mode 100644 index 0000000000..e69de29bb2 diff --git a/usr/src/ucb/pascal/pdx/intro.nroff b/usr/src/ucb/pascal/pdx/intro.nroff new file mode 100644 index 0000000000..83e6773c1c --- /dev/null +++ b/usr/src/ucb/pascal/pdx/intro.nroff @@ -0,0 +1,1257 @@ +.ta 5n 10n 15n 20n 25n 30n 35n 40n 45n 50n 55n 60n +.if n .po 1.25i +.if t .po 1.0i +.hy 14 +.de hd +'sp 3 +'if \\n%-1 'tl ''- % -'' +'sp 2 +.if \\n(vq>0 .xj +.nr vq 0 +'ns +.. +.de fo +.nr vk 0 +.nr dn 0 +.nr wf \\n(.pu-\\n(nlu-\\n(vmu-1v +.if \\n(vs>0 .if \\n(wf>0 .xn +.if \\n(vs>0 .if \\n(wf<=0 .xo +.ch fo -\\n(vmu +.nr vs 0 +.nr vo \\n(vmu +'bp +.. +.de fe +.br +.di +.ev +.if \\n(vs=1 .nr dn +1v +.nr vo +\\n(dnu +.nr dn 0 +.if \\n(vou>=\\n(.pu-\\n(nlu-.5v .nr vo \\n(.pu-\\n(nlu-.5v +.if \\n(vou<\\n(vmu .nr vo \\n(vmu +.ch fo -\\n(vou +.. +.de xj +.nr vs 1 +.nr vn 1 +.di +.ev 1 +.da zb +.ns +.za +.zc +.fe +.rm za +.rm zc +.. +.de xn +.ev 1 +'in 0 +'ti 0 +.ie \\n(vn \l\|6.0i\(ru\| +.el \l\|15\(ru\| +.nr vn 0 +.br +.ns +.zb +.br +.di +.rm zb +.nr vq \\n(dnu +.nr dn 0 +.nr vs 0 +.ev +.. +.de xo +.ev 1 +.di zc +.zb +.br +.di +.rm zb +.nr vq \\n(dnu +.nr dn 0 +.nr vs 0 +.nr vn 1 +.ev +.. +.de xp +.di za +.. +.nr vm 6v +.nr vo \n(vmu +.wh 0 hd +.wh -1.0i fo +.ch fo 15i +.wh -\n(vmu xp +.ch fo -\n(vmu +.if n .ll 6.5i +.if t .ll 6.0i +.if n .lt 6.5i +.if t .lt 6.0i +.ev 1 +.if n .ll 6.5i +.if t .ll 6.0i +.if n .lt 6.5i +.if t .lt 6.0i +.ev +.nr ap 1 +.af ap A +.sp 6 +.ps +2 +.ce +\fBAn Introduction to Pdx\fP +.ps -2 +.sp 1 +.ce +\fIMark Linton\fR +.sp 1 +.ce +September 27, 1981 +.sp 1 +.br +.nr wg 2v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 6 +\fBIntroduction\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti +5n +\fIPdx\fP is a tool for debugging Pascal programs +that are translated by the Berkeley Pascal translator \fIpi\fP +[Joy, Graham, and Haley 80]. +This tutorial introduces \fIpdx\fP and the basic ways that it can be used. +For a complete reference, consult the \fIpdx\fP manual page. +.br +.nr wg 2v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 6 +\fBGetting Started\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti +5n +Suppose the program we are working on is in a file called ``prog.p''. +Before using \fIpdx\fP, we must translate it with \fIpi\fP. +\fIPdx\fP cannot be used if \fIpi\fP reports any errors during translation. +To enter \fIpdx\fP, we type the following: (in examples, +the user types is in boldface, what \fIpdx\fP prints +is in normal type). +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +% \fBpdx\fP +> +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +The ``>'' is a prompt from \fIpdx\fP. +Like the shell or editor, \fIpdx\fP prints the prompt when it +is waiting for a command. +.br +.nr wg 2v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 6 +\fBRunning the Program\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti +5n +Once in \fIpdx\fP, we can begin executing our program +by typing the command ``run''. +Programs don't usually work the first time; +with one of two things happening: +.if n .nr In 5 +.if t .nr In 8 +.in +\n(Inn +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -5n +\h'1n'1.\h'2n'\c +The program tries to do something that isn't +allowed in Pascal, such as dividing by 0. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -5n +\h'1n'2.\h'2n'\c +The program runs but produces incorrect results. +.in -\n(Inn +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +Let's consider the first case. +Suppose ``prog.p'' contains the declarations +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +var + sum, count : integer; + avg : real; +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +and the statement +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 + avg := sum / count; +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +at line 15. +Suppose further that when the program is run +``count'' has the value 0. +Running under \fIpdx\fP, the following would be printed: +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBrun\fP +.sp 1 +error at line 15: real divide by zero + 15 avg := sum / count; +> +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +.br +.nr wg 2v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 6 +\fBPrinting Out Variables\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti +5n +When a program stops because of an execution error, +\fIpdx\fP prints the error and the line in the program where +the error occurred. +We can then examine the program's ``state'', that is, +print out the values of any variables that might be +of interest. +In the above example, we might want to know the value +of \fIsum\fP, so we say +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBprint sum\fP +5 +> +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +The print command can be given any number of Pascal expressions +separated by commas. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +We can print the values of all variables by using +the ``dump'' command. +Continuing our example, we might get +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBdump\fP +sum = 5 +count = 0 +avg = 0.0 +> +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +Frequently there are many variables active +so that we want to print the list of a file for perusal. +This is done by saying +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBdump > out\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +where ``out'' is the name of file which does not exist. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +There are two other commands useful for printing information +about variables. +The command ``whatis'' prints out the declaration of a variable. +Using the above example, +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBwhatis\fP sum +var sum : integer; +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +It is possible for a program to have the same name given +to two or more different variables when they are local to +different procedures. +\fIPi\fP distinguishes the variables according to which procedure +it is looking at; +however, when debugging it is possible that both procedures +are active (for example, one procedure could call the other). +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +\fIPdx\fP normally allows printing of any variable declared within +the most recently called procedure or any variables accessible +to this procedure. +A variable in an active procedure that is not normally accessible +can be printed by preceding its name with the procedure it is in +and a ``.''. +It can sometimes become difficult to remember the variable +that a given name is currently associated with. +The ``which'' command is useful in resolving this confusion. +It prints the variable name along with the procedure that it is contained in. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +Usually we want to know not only what the values of variables +are, but how the program got to where it is. +The ``where'' command lists the procedures that were called +for the program to reach its current point. +It might print, for example, +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBwhere\fP +LastCalled(parameters), line 15 +OneBeforeThat(parameters), line 30 +MainProgram, line 45 +> +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +.br +.nr wg 2v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 6 +\fBExecution Tracing\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti +5n +Now let's look at the possibility that our program doesn't +get an execution error but doesn't produce the correct results. +To figure out what and where something is going wrong, we +wish to ``watch'' execution information more closely. +The \fBtrace\fP command in \fIpdx\fP allows us to do this. +There are five classes of information that +we can watch: +.if n .nr In 5 +.if t .nr In 8 +.in +\n(Inn +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -3n +-\h'2n'\c +The execution of a particular source line. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -3n +-\h'2n'\c +A call to a particular procedure or function. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -3n +-\h'2n'\c +The value of an expression at a particular source line. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -3n +-\h'2n'\c +The value of a variable whenever it changes; and the +line at which it changes. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -3n +-\h'2n'\c +The execution of all source lines. +.in -\n(Inn +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +It should be noted that the last two kinds of information +are expensive to obtain and will cause your program to run +much more slowly than normal. +They should be used sparingly. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +These forms of tracing can be combined and there is no +limit to the number of things you can trace at any given time. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +To trace the execution of a particular source line, +type +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBtrace\fP \fIline-number\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +The next time the \fBrun\fP command is given +\fIpdx\fP will execute the program, printing the specified line +each time it is about to be executed. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +To trace every call to a procedure, +type +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBtrace\fP \fIprocedure-name\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +For each call to the named procedure during execution, +\fIpdx\fP will print the name of the procedure, the procedure +and line it was called from, and what parameters (if any) it was called with. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +To see the value of an expression at a particular line, +type +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBtrace\fP \fIexpression\fP \fBat\fP \fIsource-line-number\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +To see whenever the value of a variable is changed, +we type +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBtrace\fP \fIvariable\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +Finally, to have each source line printed +as it's about to be executed, we simply say +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +\fBtrace\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +After issuing a trace command, \fIpdx\fP +displays all currently active traces. +Each command is identified with a number in parentheses. +To turn off a trace, +give the command +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBdelete\fP \fIcommand-number\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +Tracing information will be printed every time the program is run until +it is explicitly turned off by giving the \fBdelete\fP command. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +To display the information that you are currently tracing, say +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBstatus\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +.br +.nr wg 2v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 6 +\fBStopping and Continuing\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti +5n +Sometimes, when debugging, we want to stop our program, +look at some data, and then continue execution. +The \fBstop\fP command allows the suspension of execution. +To continue execution from where it was suspended, +the \fBcont\fP command is used. +There are four ways to describe when execution should be stopped: +.in +5n +.if n .nr In 5 +.if t .nr In 8 +.in +\n(Inn +.ta \n(Inn +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -\n(Inn +\&\fBstop\fP \fBif\fP \fIcondition\fP +.br +\c +Execution is stopped if the specified condition becomes true. +The condition can be any Pascal boolean expression. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -\n(Inn +\&\fBstop\fP \fBat\fP \fIsource-line-number\fP +.br +\c +Execution is stopped when the \fIline\fP is about to executed. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -\n(Inn +\&\fBstop\fP \fBin\fP \fIprocedure\fP +.br +\c +Execution is stopped when the \fIprocedure\fP is called. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -\n(Inn +\&\fBstop\fP \fIvariable\fP +.br +\c +Execution is stopped when the \fIvariable\fP is about to be changed. +.in -\n(Inn +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -5n +Execution is also stopped by an interrupt, i.e. +by typing the RUB or DEL key. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +Execution can be momentarily continued by the commands \fBnext\fP +and \fBstep\fP. +The \fBnext\fP command stops after one source line has been executed. +The \fBstep\fP command stops at the next source line to be executed. +These are only different when the current source line +contains a call to a procedure or function. +\fBStep\fP will stop at the beginning of the subprogram, \fBnext\fP will not. +As in tracing, stops are set until explicitly unset +with the \fBdelete\fP command. +.br +.nr wg 2v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 6 +\fBSource Program Manipulation\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti +5n +\fIPdx\fP allows you to view your program during debugging. +For example, to print lines 10 to 20 from ``prog.p'', you would type +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBlist\fP 10,20 +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +If you actually wish to change your program, or look at it +in a more sophisticated manner, the command +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBedit\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +will invoke the editor on your program. +You can also say +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBedit\fP \fIprocedure\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +and \fIpdx\fP will invoke the editor on your program +and position the current line on the first line of +the \fIprocedure\fP. +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 3 +.ti +5n +If you change your program and wish to start debugging the +new version, you should give the command +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBpi\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +This command runs \fIpi\fP on your program, and automatically +reads in the new information that \fIpdx\fP needs from the new \fIobj\fP file. +.br +.nr wg 2v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 6 +\fBCommand Aliasing\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti +5n +The \fBalias\fP command is used to create a new name for a command. +This is especially useful for saving typing by defining +abbreviations as aliases. +For example, if you gave the command +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in +8n +.nf +.ne 5 +> \fBalias\fP r run +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.in -8n +.fi +then you could use ``r'' to run your program. +.br +.nr wg 2v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 6 +\fBWhere to go from here\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti +5n +If you feel comfortable what we've discussed here, +you're ready to read the \fIpdx\fP manual page. +It contains a complete, but brief, description of the +commands discussed here along with some other commands that you +might find useful. +.br +.nr wg 2v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ne 6 +\fBReferences\fP +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti +5n +.ti -5n +.if n .nr In 5 +.if t .nr In 8 +.in +\n(Inn +.ta \n(Inn +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -\n(Inn +\&[Joy, Graham and Haley 80] +.br +\c +Joy, W., Graham, S., and Haley, C., +``Berkeley Pascal User's Manual'', +version 2.0, EECS Dept., Univ. of Calif. at Berkeley, October 1980. +.in -\n(Inn +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h diff --git a/usr/src/ucb/pascal/pdx/pdx.1 b/usr/src/ucb/pascal/pdx/pdx.1 new file mode 100644 index 0000000000..117d6d3d91 --- /dev/null +++ b/usr/src/ucb/pascal/pdx/pdx.1 @@ -0,0 +1,267 @@ +.TH pdx 1 +.SH NAME +pdx - pascal debugger +.SH SYNOPSIS +pdx [\fB-r\fP] [\fIobjfile\fP] +.SH DESCRIPTION +\fIPdx\fP is a tool for source level debugging and execution of +Pascal programs. +The \fIobjfile\fP is an object file produced by the Pascal translator \fIpi\fP(1). +If no \fIobjfile\fP is specified, \fIpdx\fP looks +for a file named ``obj'' in the current directory. +The object file contains a symbol table which includes the name of the +all the source files translated by \fIpi\fP to create it. +These files are available for perusal while using the debugger. +.PP +If the file ``.pdxinit'' exists in the current directory, then the +debugger commands in it are executed. +.PP +The \fB-r\fP option causes the \fIobjfile\fP to be executed immediately; +if it terminates successfully \fIpdx\fP exits. +Otherwise it reports the reason for termination +and offers the user the option of entering the debugger +or simply letting \fIpx\fP continue with a traceback. +If \fB-r\fP is not specified, \fIpdx\fP just prompts and waits for a command. +.PP +The commands are: +.TP +\fBrun\fP [\fIargs\fP] [\fB<\fP \fIfilename\fP] [\fB>\fP \fIfilename\fP] +Start executing \fIobjfile\fP, passing \fIargs\fP as command line arguments; +\fB<\fP or \fB>\fP can be used to redirect input or output in the usual manner. +.TP +\fBtrace\fP [\fBin\fP \fIprocedure/function\fP] [\fBif\fP \fIcondition\fP] +.ns +.TP +\fBtrace\fP \fIsource-line-number\fP [\fBif\fP \fIcondition\fP] +.ns +.TP +\fBtrace\fP \fIprocedure/function\fP [\fBin\fP \fIprocedure/function\fP] [\fBif\fP \fIcondition\fP] +.ns +.TP +\fBtrace\fP \fIexpression\fP \fBat\fP \fIsource-line-number\fP [\fBif\fP \fIcondition\fP] +.ns +.TP +\fBtrace\fP \fIvariable\fP [\fBin\fP \fIprocedure/function\fP] [\fBif\fP \fIcondition\fP] +Have tracing information printed when the program is executed. +A number is associated with the command that is used +to turn the tracing off (see the \fBdelete\fP command). +.sp 1 +The first argument describes what is to be traced. +If it is a \fIsource-line-number\fP, then the line is printed +immediately prior to being executed. +Source line numbers in a file other than the current one +must be preceded by the name of the file and a colon, e.g. +``mumble.p:17''. +.sp 1 +If the argument is a procedure or function name then +every time it is called, information is printed telling +what routine called it, from what source line it was called, +and what parameters were passed to it. +In addition, its return is noted, and if it's a function +then the value it is returning is also printed. +.sp 1 +If the argument is an \fIexpression\fP with an \fBat\fP clause +then the value of the expression is printed whenever the +identified source line is reached. +.sp 1 +If the argument is a variable then the name and value of the variable +is printed whenever it changes. +Execution is substantially slower during this form of tracing. +.sp 1 +If no argument is specified then all source lines are printed +before they are executed. +Execution is substantially slower during this form of tracing. +.sp 1 +The clause ``\fBin\fP \fIprocedure/function\fP'' restricts tracing information +to be printed only while executing inside the given procedure +or function. +.sp 1 +\fICondition\fP is a Pascal boolean expression and is +evaluated prior to printing the tracing information; +if it is false then the information is not printed. +.sp 1 +There is no restriction on the amount of information +that can be traced. +.br +.ne 10 +.IP "\fBstop\fP \fBif\fP \fIcondition\fP" +.ns +.IP "\fBstop\fP \fBat\fP \fIsource-line-number\fP [\fBif\fP \fIcondition\fP]" +.ns +.IP "\fBstop\fP \fBin\fP \fIprocedure/function\fP [\fBif\fP \fIcondition\fP]" +.ns +.IP "\fBstop\fP \fIvariable\fP [\fBif\fP \fIcondition\fP]" +Stop execution when the given line is reached, procedure or function +called, variable changed, or condition true. +.IP "\fBdelete\fP \fIcommand-number\fP" +The trace or stop corresponding to the given number is removed. +The numbers associated with traces and stops are printed by +the \fBstatus\fP command. +.IP "\fBstatus\fP [\fB>\fP \fIfilename\fP]" +Print out +the currently active \fBtrace\fP and \fBstop\fP commands. +.IP \fBcont\fP +Continue execution from where it stopped. +This can only be +done when the program was stopped by an interrupt +or through use of the \fBstop\fP command. +.IP \fBstep\fP +Execute one source line. +.IP \fBnext\fP +Execute up to the next source line. +The difference between this and \fBstep\fP is that +if the line contains a call to a procedure or function +the \fBstep\fP command will stop at the beginning of that +block, while the \fBnext\fP command will not. +.IP "\fBprint\fP \fIexpression\fP [\fB,\fP \fIexpression\fP ...]" +Print out the values of the Pascal expressions. +Variables declared in an outer block but having +the same identifier as one in the current block may be +referenced as ``\fIblock-name\fP\ \fB.\fP\ \fIvariable\fP''. +.IP "\fBwhatis\fP \fIidentifier\fP" +Print the declaration of the given identifier. +.IP "\fBwhich\fP \fIidentifier\fP" +Print the full qualification of the given identifer, i.e. +the outer blocks that the identifier is associated with. +.IP "\fBassign\fP \fIvariable\fP \fIexpression\fP" +Assign the value of the expression to the variable. +.IP "\fBcall\fP \fIprocedure(parameters)\fP" +Execute the object code associated with the named procedure or function. +.IP \fBhelp\fP +Print out a synopsis of \fIpdx\fP commands. +.IP \fBgripe\fP +Invokes a mail program to send a message to the person in charge of \fIpdx\fP. +.IP \fBwhere\fP +Print out +a list of the active procedures and functions and the respective source +line where they are called. +.TP +\fBsource\fP \fIfilename\fP +Read \fIpdx\fP commands from the given \fIfilename\fP. +Especially useful when the \fIfilename\fP has been created by redirecting +a \fBstatus\fP command from an earlier debugging session. +.IP "\fBdump\fP [\fB>\fP \fIfilename\fP]" +Print the names and values of all active +data. +.IP "\fBlist\fP [\fIsource-line-number\fP [\fB,\fP \fIsource-line-number\fP]]" +.ns +.IP "\fBlist\fP \fIprocedure/function\fP" +List the lines in the current source file from the first line number to +the second inclusive. +As in the editor +``$'' can be used to refer to the last line. +If no lines are specified, the entire file is listed. +If the name of a procedure or function is given +lines \fIn-k\fP to \fIn+k\fP are listed where \fIn\fP is the first statement +in the procedure or function and \fIk\fP is small. +.IP "\fBfile\fP [\fIfilename\fP]" +Change the current source file name to \fIfilename\fP. +If none is specified then the current source file name is printed. +.IP "\fBedit\fP [\fIfilename\fP]" +.ns +.IP "\fBedit\fP \fIprocedure/function-name\fP" +Invoke an editor on \fIfilename\fP or the current source file if none +is specified. +If a \fIprocedure\fP or \fIfunction\fP name is specified, +the editor is invoked on the file that contains it. +Which editor is invoked by default depends on the installation. +The default can be overridden by setting the environment variable +EDITOR to the name of the desired editor. +.IP \fBpi\fP +Recompile the program and read in the new symbol table information. +.IP "\fBsh\fP \fIcommand-line\fP" +Pass the command line to the shell for execution. +The SHELL environment variable determines which shell is used. +.IP "\fBalias\fP \fInew-command-name\fP \fIold-command-name\fP" +This command makes \fIpdx\fP respond to \fInew-command-name\fP +the way it used to respond to \fIold-command-name\fP. +.IP "\fBquit\fP" +Exit \fIpdx\fP. +.sp 4 +.PP +The following commands deal with the program at the \fIpx\fP instruction +level rather than source level. +They are not intended for general use. +.TP +\fBtracei\fP [\fIaddress\fP] [\fBif\fP \fIcond\fP] +.ns +.TP +\fBtracei\fP [\fIvariable\fP] [\fBat\fP \fIaddress\fP] [\fBif\fP \fIcond\fP] +.ns +.TP +\fBstopi\fP [\fIaddress\fP] [\fBif\fP \fIcond\fP] +.ns +.TP +\fBstopi\fP [\fBat\fP] [\fIaddress\fP] [\fBif\fP \fIcond\fP] +Turn on tracing or set a stop using a \fIpx\fP machine +instruction addresses. +.TP +\fBxi\fP \fIaddress\fP [\fB,\fP \fIaddress\fP] +Print the instructions starting at the first \fIaddress\fP. +Instructions up to +the second \fIaddress\fP are printed. +.TP +\fBxd\fP \fIaddress\fP [\fB,\fP \fIaddress\fP] +Print in octal the specified data location(s). +.SH FILES +.nr In 25 +.in +\n(Inn +.ta \n(Inn +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -\n(Inn +\&obj \c +Pascal object file +.br +.nr wg 0v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.ti -\n(Inn +\&\&.pdxinit \c +\fIPdx\fP initialization file +.in -\n(Inn +.br +.nr wg 1v +.ie \n(.h=\n(vk .nr wg -\n(vhu +.el .nr vh 0 +.if \n(wg>0 \{\ +.sp \n(wgu +.nr vh +\n(wgu \} +.nr vk \n(.h +.SH SEE ALSO +pi(1), px(1) +.br +\fIAn Introduction to Pdx\fP +.SH BUGS +\fIPdx\fP does not understand sets, +and provides no information about files. +.sp 1 +The \fIwhatis\fP command doesn't quite work for variant records. +.sp 1 +Bad things will happen if a procedure invoked with +the \fBcall\fP command does a non-local goto. +.sp 1 +The commands \fBstep\fP and \fBnext\fP should be able to take a \fIcount\fP +that specifies how many lines to execute. +.sp 1 +There should be commands \fBstepi\fP and \fBnexti\fP that correspond +to \fBstep\fP and \fBnext\fP but work at the instruction level. +.sp 1 +There should be a way to get an address associated with +a line number, procedure or function, and variable. +.sp 1 +Most of the command names are too long. +.sp 1 +The alias facility is quite weak. +.sp 1 +A \fIcsh\fP-like history capability would improve the situation. diff --git a/usr/src/ucb/pascal/pdx/sccs b/usr/src/ucb/pascal/pdx/sccs new file mode 100644 index 0000000000..33c0677038 --- /dev/null +++ b/usr/src/ucb/pascal/pdx/sccs @@ -0,0 +1,73 @@ +#! /bin/csh -f +# +# Simple version of the "sccs" command that understands +# subdirectories better. +# + +set dir = SCCS +set command = $1 +shift +set flags = () +set files = () +foreach i ($*) + if ($i == "-*") then + set flags = ($flags $i) + else + set files = ($files $i) + endif +end + +if ($command == info) then + foreach i (SCCS/{p.*,*/p.*}) + echo $i:t `cat $i` + end + exit 0 +endif + +foreach i ($files) + if ($i:h == $i:t) then + set sfile = $dir/s.$i + else + set sfile = $dir/$i:h/s.$i:t + endif + switch ($command) + case get: + get $flags $sfile + if ($i:h != $i:t) then + mv -f $i:t $i + endif + breaksw + + case edit: + get -e $flags $sfile + if ($i:h != $i:t) then + mv -f $i:t $i + endif + breaksw + + case delta: + if ($i:h != $i:t) then + mv -f $i $i:t + endif + delta $flags $sfile + breaksw + + case delget: + ./sccs delta $i + ./sccs get $i + breaksw + + case deledit: + ./sccs delta $i + ./sccs edit $i + breaksw + + case prt: + prt $sfile + breaksw + + default: + echo $command\: unknown command + exit 1 + endsw +end