4.3BSD/usr/contrib/spms/doc/2.simple.ms

Compare this file to the similar file:
Show the results in this format:

.nr PS 12
.NH
Simple Tasks
.nr PS 10
.XS
\*(SN Simple Tasks
.XE
.PP
In this document several examples related to an interactive screen-oriented
spreadsheet program are presented to demonstrate the use of SPMS for
software development and project management. It is assumed that the
reader is familiar with the
.UX
operating system and a text editor such as
.I ex.
In these examples, user input is shown in \fBbold\fR face.
.NH 2
Getting Started
.XS
\*(SN Getting Started
.XE
.PP
Before using SPMS for the first time the following steps must be performed\**
.FS
For C shell, (\fIcsh\fR), users only. Consult the UNIX Programmer's
Manual for instructions on how to set up SPMS for the Bourne shell,
(\fIsh\fR).
.FE
.IP 1.
Include the directory `/usr/new' in the
command search path. This is done by altering the PATH environment variable
in one of the startup files, `.cshrc'  or `.login', in the home directory.
.IP 2.
Add the following aliases to the `.cshrc' file located in the home directory
.br
	alias chproject  \'eval \`\^"chproject"  \\!*\`\^\'
.br
	alias pd  \'eval \`\^"pd"  \\!*\`\^\'
.IP 3.
Add the following command to the `.login' file located in the home directory
.br
	chproject  ^
.IP 4.
Convert the home directory to a project root directory by typing
.br
	\fB/usr/new/mkproject  \-d  ^\fR
.IP 5.
Execute the `.cshrc' and `.login' files by typing
.br
	\fBsource  .cshrc\fR
.br
	\fBsource  .login\fR
.NH 2
Building a Project
.XS
\*(SN Building a Project
.XE
.PP
The directory structure to support a software package is created by the
.I mkproject
and
.I pmkdir
commands. These commands create directories using the standard
.UX
.I mkdir
command, and record information about each directory in a project database
called the
.I
project link directory.
.R
This information is used by various SPMS commands to control the development
and maintenance activities for a project.
.PP
The steps for building the project structure are:
.IP 1.
Initialize the project using the
.I mkproject
command.
.I Mkproject
creates a directory known as a
.I
project root directory,
.R
to serve as the focus for a project, and initializes the project database.
After
.I mkproject
creates the project root directory, the user is prompted for a line
describing the purpose of the project.
.IP 2.
Use the \fI\%chproject\fR command to change to the root directory of
the new project and make it the \fIworking project\fR (see \(sc\|2.13).
.IP 3.
Create the project directories using the
.I pmkdir
command. After
.I pmkdir
creates each directory, the user is prompted for a line describing the
purpose of the directory.
.PP
To illustrate this process, the following commands create project `vs'
with directories `doc', `src', and `work' (see fig. 2) to support a
`Visual Spreadsheet' program\** called \fIvs\fR.
.FS
\fIVs\fR is a fictitious name bearing no resemblance to any actual program.
.FE
.DS
%  \fBmkproject vs\fR
vs: description? (1 line): \fBVisual Spreadsheet\fR
%  \fBchproject vs\fR
%  \fBpmkdir doc src work\fR
doc: description? (1 line): \fBvs user's guide\fR
src: description? (1 line): \fBvs program source code\fR
work: description? (1 line): \fBvs workbench\fR
%
.DE
.KF
.sp 11
.SM
.ce
\fIFigure 2.  \fRLayout of the project `vs'

.NL
.KE
.NH 2
Displaying a Project
.XS
\*(SN Displaying a Project
.XE
.PP
The
.I ppd
``\fBp\fRrint \fBp\fRroject \fBd\fRirectory'' command may be used to list
the directories belonging to `vs':
.DS
%  \fBppd\fR
doc		src		work
%
.DE
Alternatively, a table of contents for the project can be obtained by using
.I ppd
with the \fB\-d\fR description option to print the description of each project
directory.
.DS
%  \fBppd  \-d\fR
doc		vs user's guide
src		vs program source code
work	vs workbench
%
.DE
.NH 2
Moving Around Inside a Project
.XS
\*(SN Moving Around Inside a Project
.XE
.PP
The
.I pd
command provides a convenient way for changing to another project directory
without the user having to remember it's precise location. For example,
to move to the source code directory `src', type
.ID
%  \fBpd  src\fR
.DE
To change to the directory `work', type
.ID
%  \fBpd  work\fR
.DE
To return to the project root directory, type
.ID
%  \fBpd\fR
.DE
without any arguments.
.NH 2
Compiling a Program
.XS
\*(SN Compiling a Program
.XE
.PP
Program development and maintenance is handled by the
.I make
command\|[3].
.I Make
mechanizes many development and maintenance activities, including
compiling and linking of programs, printing of source code, and the removal
of unneeded files. The instructions which tell
.I make
how to perform these duties are kept in a special file known as a makefile,
together with the names of the source code files which make up the
program. The makefile editor program,
.I mkmf,
creates the makefile (named `Makefile' by default) by gathering up
the names of all the source code files in the current working directory and
inserting them into a standard makefile.
.PP
The following example shows how to produce the program for the visual
spreadsheet, given the file `vs.c' containing the source code in the directory
`src'.
.DS
%  \fBmkmf\fR
mkmf: creating Makefile from template /usr/new/lib/p.Makefile
%  \fBmake\fR
cc \-c vs.c
Loading a.out ... done
%
.DE
In this example the executable program is called `a.out'. However, by using the
makefile editor interactively the name `vs' could have been specified instead:
.DS
%  \fBmkmf  \-i\fR
mkmf: creating Makefile from template /usr/new/lib/p.Makefile
program name? \fBvs\fR
destination directory?
%  \fBmake\fR
cc \-c vs.c
Loading vs ... done
%
.DE
Since a carriage return was typed in response to the second question in
the example above, the destination directory for the program remains the
current directory.
.PP
Because program
.I vs
is a screen-oriented program, it would not be
surprising if it requires special functions to control cursor movement
and updating of the terminal screen. There is a standard package of C
library functions for this purpose called `curses'\|[1], and if the program
has taken advantage of these functions, this library should be included
in the makefile together with the terminal database package `termlib'.
This can be done by including the LIBS macro definition as an argument to the
.I mkmf
command\**
.FS
Arguments with embedded blanks in UNIX commands must be enclosed by double
quotes.
.FE
.ID
%  \fBmkmf  \-i  "LIBS=\-lcurses \-ltermlib"\fR
.DE
.NH 2
Moving Files Within a Project
.XS
\*(SN Moving Files Within a Project
.XE
.PP
A file can be moved to another project directory by using the
.I pmv
command. For instance, the following command moves the executable program
.I vs
from the current working directory to the `work' directory
.ID
%  \fBpmv  vs  work\fR
.DE
In a similar manner, files can be copied from one project directory
to another using the
.I pcp
command.
.I Pmv
and
.I pcp
behave very similarly to the standard
.UX
.I mv
and
.I cp
commands in that they blindly overwrite any existing files of the same
name in the destination directory unless the
.B \-i
interactive option is used.
.NH 2
More on Building a Project
.XS
\*(SN More on Building a Project
.XE
.PP
As development of a software package continues, extra project directories may
be needed to support the work. For example, project `vs' must accommodate
an additional program called
.I vstutor
which provides instruction on the use of the visual spreadsheet program;
two library packages called `hash' and `list' for hash table and linked
list operations; and three files that are ``included'' in more than one
source file \- `vs.h' which contains common program definitions,
`hash.h' which defines hash tables, and `list.h' which holds linked
list definitions. Figure 3 shows the extra directories needed for
these components and the following command sequence creates them
.DS
%  \fBpd\fR
%  \fBpmkdir bin include lib\fR
bin: description? (1 line): \fBvs and vstutor programs\fR
include: description? (1 line): \fBcommon included files\fR
lib: description? (1 line): \fBcompiled hash table and list libraries\fR
%  \fBpd src\fR
%  \fBpmkdir vs vstutor libhash liblist\fR
vs: description? (1 line): \fBvs program source code\fR
vstutor: description? (1 line): \fBvstutor program source code\fR
libhash: description? (1 line): \fBhash table library source code\fR
liblist: description? (1 line): \fBlist library source code\fR
%
.DE
The final step is to change the description of the `src' directory now
that it has been subdivided into four separate source code
directories. This can be done by using the
.I pmkdir
with the \fB+d\fR (change \fBd\fRescription) option
.DS
%  \fBpmkdir +d  src\fR
src: description? (1 line): \fBC source code\fR
%
.DE
.KF
.sp 17
.SM
.ce
\fIFigure 3.  \fRRevised layout of project `vs'

.NL
.KE
Note that in Figure 3 there are two directories called `vs'. The top one
bears the name of the project, and the bottom one is named according to the
program contained within it. Similarly, the directories `libhash' and
`liblist' are named according to libraries that they contain.
.NH 2
Creating a Program Library
.XS
\*(SN Creating a Program Library
.XE
.PP
A program library is a collection of compiled subroutines that are shared
by more than one program. In the
.UX
environment a program library is stored as an
.I archive
file. Each member of the archive is an object file containing one or
more compiled subroutines. By convention a library archive file is named
\fBlib\fIname\fR.\fBa\fR where
.I name
is the name of the program library.
.PP
The example below shows how to create a program library for the hash table
subroutines in the `libhash' directory. Note that the
.I mkmf
command must be given with the \fB\-l\fR option so that a makefile will be
created for a library rather than a program.
.DS
% \fBmkmf  \-i  \-l\fR
mkmf: creating Makefile from template /usr/new/lib/l.Makefile
library name? \fBlibhash.a\fR
destination directory? \fB../../lib\fR
% \fBmake\fR
cc \-c hthash.c
cc \-c htinit.c
cc \-c htinstall.c
cc \-c htlookup.c
cc \-c htrm.c
Loading libhash.a ... done
%
.DE
Since the `lib' directory is in the same
project as the `libhash' directory, the path to `lib' is
made
.I relative
to `libhash' so that the project will be portable.
.PP
The next step is to install the program library in the `lib' project directory
where the
.I vs
and
.I vstutor
programs can access it easily.
.DS
% \fBmake install\fR
Installing libhash.a in ../../lib
%
.DE
.NH 2
More on Developing a Program
.XS
\*(SN More on Developing a Program
.XE
.NH 3
\fIIncluded files\fR
.XS
\*(SN Included files
.XE
.PP
Definitions which are common to more than one source code file (e.g. buffer
sizes, data structure definitions) should be declared only once in a program.
This can be achieved by keeping such definitions in files separate from the
main program and ``including'' them at compilation time. In C, Fortran, and
Pascal programs, the contents of a file can be included by the statement
.ID
#include  "filename"
.DE
By convention
.I filename
ends in \fB.h\fR and is commonly referred to as a
.I header
file. Hence, in the source code for programs
.I vs
and
.I vstutor,
the statements
.DS
#include "vs.h"
#include "hash.h"
#include "list.h"
.DE
include common program definitions, hash table definitions, and linked
list definitions respectively.
.PP
Since the header files in this example are used in more than
one program, they should be placed in the `include' directory where they can
be accessed easily. Although the include statements can be rewritten as
.DS
#include "../../include/vs.h"
#include "../../include/hash.h"
#include "../../include/list.h"
.DE
it is better to tell the compiler where the header files are by using the
.B \-I
compiler option\** as follows
.FS
C and Fortran compilers only.
.FE
.ID
\-I../../include
.DE
This is done most conveniently by adding the option to the compiler
flags in the makefile (see \(sc\|4.1.1).
.NH 3
\fIProgram libraries\fR
.XS
\*(SN Program libraries
.XE
.PP
The LIBS macro definition in a makefile specifies the libraries that
are to be used by the link editor for resolving references to
subroutines that are not found in the program source code. Because
.I make
checks to see if the libraries needed by a program have changed since
the last time the program was made, their pathnames must be defined
explicitly. In the makefiles belonging to programs
.I vs
and
.I vstutor,
the LIBS macro definition looks like
.DS
LIBS = \kx../../lib/libhash.a \\\\
\h'|\nxu'\&../../lib/liblist.a \\\\
\h'|\nxu'\&/usr/lib/libcurses.a \\\\
\h'|\nxu'\&/usr/lib/libtermlib.a
.DE
Note also that when this macro definition was added to the makefile by
the command
.PP
%  \fBmkmf "LIBS=../../lib/libhash.a  ../../lib/liblist.a  \-lcurses  \-ltermlib"\fR
.LP
to include the `hash' and `list' libraries, the `curses' and `termlib'
libraries were automatically expanded to full pathnames by the makefile editor.
.NH 3
\fIInstallation\fR
.XS
\*(SN Installation
.XE
.PP
Once a program has been completed, it should be installed in a place
where it will be generally available \- that is, in a directory which
is in the command search path specified by the PATH environment
variable. In the case of the project `vs', if the `bin' directory is in
the search path, this might be a good place to install the
.I vs
and
.I vstutor
programs. If the makefiles for these programs do not already specify `bin' as
their destination directory, it can be added by the command
.ID
%  \fBmkmf  "DEST=../../bin"\fR
.DE
Then, each program can be installed by the
.I
make install
.R
command. For the program \fIvs\fR:
.DS
%  \fBpd vs\fR
%  \fBmake install\fR
Installing vs in ../../bin
%
.DE
and for the program \fIvstutor\fR:
.DS
%  \fBpd vstutor\fR
%  \fBmake install\fR
Installing vstutor in ../../bin
%
.DE
.NH 2
Global Operations
.XS
\*(SN Global Operations
.XE
.PP
One of the goals of SPMS is to reduce the effort associated with software
maintenance. This can be achieved by treating a software package as an
atomic unit \- that is, a single entity on which to perform operations.
The mechanism for executing a command over an entire software package
is provided by the
.I pexec
command. This command takes another command as an argument and executes it
in each of the directories belonging to a project, as in
.ID
%  \fBpexec  ls\fR
.DE
which lists the names of all the files in a project.
.NH 3
\fIDirectory selection\fR
.XS
\*(SN Directory selection
.XE
.PP
By labeling each project directory according to the type of activity that it
supports, global operations can be restricted to specific directories. These
labels, which are known as
.I
type labels,
.R
are attached to project directories by the
.I pmkdir
command, and removed by the
.I prmdir
command\**.
.FS
Except in the case of project root directories, where
.I mkproject
and
.I rmproject
must be used.
.FE
For instance, if the directories containing source code in project `vs'  are
labeled `src' by
.ID
%  \fBpmkdir  +T\|src  include libhash liblist vs vstutor\fR
.DE
then, the total number of lines of source code in a project can be counted by
giving the command
.ID
%  \fBpexec  \-T\|src  \'cat \(**.h \(**.c\^\'  |  wc \-l\fR
.DE
where quotes surround the
.I cat
command to prevent file name expansion in the current directory.
.PP
If a project directory supports more than one type of activity,
labels corresponding to each of the activities can be attached to
the directory.
.NH 3
\fIDirectory order\fR
.XS
\*(SN Directory order
.XE
.PP
In some instances the directories affected by a global command must be
processed in a particular order. For example, when installing a software
package which has both libraries and programs, the libraries should be
installed first. This ordering is achieved by appending priorities to type
labels. In the case of the project `vs', if the directories containing the
program and library source code are labeled `install' with the following
priorities
.so install.tbl
by the commands
.DS
%  \fBpmkdir  +T\|install.1  libhash  liblist\fR
%  \fBpmkdir  +T\|install.2  vs  vstutor\fR
.DE
then, the command
.ID
%  \fBpexec  \-T\|install  make  install\fR
.DE
installs the `vs' software package in the order shown in figure 4.
.KF
.sp 18
.SM
.ce
\fIFigure 4.  \fROrdering for `install' directories

.NL
.KE
.KS
.PP
In a similar fashion, if the directories containing source code are
labeled `print' with the following priorities,
.so print.tbl
.KE
a source code listing for the entire project may be obtained by the command
.ID
%  \fBpexec  \-T\|print  \'pr  \(**.h  \(**.c\'  |  lpr\fR
.DE
in the order shown in figure 5.
.KF
.sp 18
.SM
.ce
\fIFigure 5.  \fROrdering for `print' directories

.NL
.KE
.NH 2
Locating Files in a Project
.XS
\*(SN Locating Files in a Project
.XE
.PP
When the location of a file within a project is unknown, it can be
found by using the
.I pfind
command. For example, the command
.ID
%  \fB pfind  Makefile\fR
.DE
searches for all occurrences of `Makefile' in project `vs' and produces
the output
.ID
\&...^vs/Makefile
\&...^vstutor/Makefile
\&...^libhash/Makefile
\&...^liblist/Makefile
.DE
.PP
In a large project, the time required to search for a file can be reduced
by telling
.I pfind
to scan only those directories in which there is some likelihood of the
file being found. In the example above, since makefiles are only likely
to be found in source code directories (i.e. directories having type
label `src'), the command could have been given as
.ID
%  \fBpfind  \-T\|src  Makefile\fR
.DE
.NH 2
Searching Files for Patterns
.XS
\*(SN Searching Files for Patterns
.XE
.PP
Sometimes it is necessary to look at all the files in a software
package that contain a certain pattern\**.
.FS
The term
.I pattern
is used to denote a set of strings.
.FE
One reason might be to find all of the places from which a subroutine
is called, perhaps with the intent of altering its arguments. The
.I pgrep
command searchs through specified files in a project for lines
matching a given pattern. For example,
.ID
%  \fBpgrep  \-T\|src  listappend  \'\(**.h \(**.c\'\fR
.DE
will search all the C source code files in project `vs' for the function
`listappend'. Because of the
.B \-T
option,
.I pgrep
searchs only in those directories which have the `src' type label.
.PP
An alternative way for specifying file names is to use the
.B \-m
option. This causes
.I pgrep
to fetch the names of source code files from the HDRS and SRCS macro
definitions in a makefile. Consequently, the command in the example
above could have been expressed as
.ID
%  \fBpgrep  \-T\|src  \-m  listappend\fR
.DE
.PP
If the pattern contains characters that have a special meaning to the
shell, such as \fB\(**\fR or \fB^\fR, the pattern should be quoted.
For example,
.ID
%  \fBpgrep  \-T\|src  \-m  \'ht.\(**(\'\fR
.DE
finds all of the places where functions from the hash table library
are used.
.NH 2
Changing the Working Project
.XS
\*(SN Changing the Working Project
.XE
.PP
Along with a working directory, each user has a
.I
working project.
.R
Immediately after logging in, the working project is the root project `^'.
To change to a new working project, the
.I chproject
command must be used, as in
.ID
%  \fBchproject vs\fR
.DE
which makes `vs' the current (or working) project. To return to the
root project, execute the command
.ID
%  \fBchproject  ^\fR
.DE
To find out the name of the working project, type
.ID
%  \fBpwp\fR
.DE