|
|
1.1 root 1: .nr PS 12
2: .NH
3: Simple Tasks
4: .nr PS 10
5: .XS
6: \*(SN Simple Tasks
7: .XE
8: .PP
9: In this document several examples related to an interactive screen-oriented
10: spreadsheet program are presented to demonstrate the use of SPMS for
11: software development and project management. It is assumed that the
12: reader is familiar with the
13: .UX
14: operating system and a text editor such as
15: .I ex.
16: In these examples, user input is shown in \fBbold\fR face.
17: .NH 2
18: Getting Started
19: .XS
20: \*(SN Getting Started
21: .XE
22: .PP
23: Before using SPMS for the first time the following steps must be performed\**
24: .FS
25: For C shell, (\fIcsh\fR), users only. Consult the UNIX Programmer's
26: Manual for instructions on how to set up SPMS for the Bourne shell,
27: (\fIsh\fR).
28: .FE
29: .IP 1.
30: Include the directory `/usr/new' in the
31: command search path. This is done by altering the PATH environment variable
32: in one of the startup files, `.cshrc' or `.login', in the home directory.
33: .IP 2.
34: Add the following aliases to the `.cshrc' file located in the home directory
35: .br
36: alias chproject \'eval \`\^"chproject" \\!*\`\^\'
37: .br
38: alias pd \'eval \`\^"pd" \\!*\`\^\'
39: .IP 3.
40: Add the following command to the `.login' file located in the home directory
41: .br
42: chproject ^
43: .IP 4.
44: Convert the home directory to a project root directory by typing
45: .br
46: \fB/usr/new/mkproject \-d ^\fR
47: .IP 5.
48: Execute the `.cshrc' and `.login' files by typing
49: .br
50: \fBsource .cshrc\fR
51: .br
52: \fBsource .login\fR
53: .NH 2
54: Building a Project
55: .XS
56: \*(SN Building a Project
57: .XE
58: .PP
59: The directory structure to support a software package is created by the
60: .I mkproject
61: and
62: .I pmkdir
63: commands. These commands create directories using the standard
64: .UX
65: .I mkdir
66: command, and record information about each directory in a project database
67: called the
68: .I
69: project link directory.
70: .R
71: This information is used by various SPMS commands to control the development
72: and maintenance activities for a project.
73: .PP
74: The steps for building the project structure are:
75: .IP 1.
76: Initialize the project using the
77: .I mkproject
78: command.
79: .I Mkproject
80: creates a directory known as a
81: .I
82: project root directory,
83: .R
84: to serve as the focus for a project, and initializes the project database.
85: After
86: .I mkproject
87: creates the project root directory, the user is prompted for a line
88: describing the purpose of the project.
89: .IP 2.
90: Use the \fI\%chproject\fR command to change to the root directory of
91: the new project and make it the \fIworking project\fR (see \(sc\|2.13).
92: .IP 3.
93: Create the project directories using the
94: .I pmkdir
95: command. After
96: .I pmkdir
97: creates each directory, the user is prompted for a line describing the
98: purpose of the directory.
99: .PP
100: To illustrate this process, the following commands create project `vs'
101: with directories `doc', `src', and `work' (see fig. 2) to support a
102: `Visual Spreadsheet' program\** called \fIvs\fR.
103: .FS
104: \fIVs\fR is a fictitious name bearing no resemblance to any actual program.
105: .FE
106: .DS
107: % \fBmkproject vs\fR
108: vs: description? (1 line): \fBVisual Spreadsheet\fR
109: % \fBchproject vs\fR
110: % \fBpmkdir doc src work\fR
111: doc: description? (1 line): \fBvs user's guide\fR
112: src: description? (1 line): \fBvs program source code\fR
113: work: description? (1 line): \fBvs workbench\fR
114: %
115: .DE
116: .KF
117: .sp 11
118: .SM
119: .ce
120: \fIFigure 2. \fRLayout of the project `vs'
121:
122: .NL
123: .KE
124: .NH 2
125: Displaying a Project
126: .XS
127: \*(SN Displaying a Project
128: .XE
129: .PP
130: The
131: .I ppd
132: ``\fBp\fRrint \fBp\fRroject \fBd\fRirectory'' command may be used to list
133: the directories belonging to `vs':
134: .DS
135: % \fBppd\fR
136: doc src work
137: %
138: .DE
139: Alternatively, a table of contents for the project can be obtained by using
140: .I ppd
141: with the \fB\-d\fR description option to print the description of each project
142: directory.
143: .DS
144: % \fBppd \-d\fR
145: doc vs user's guide
146: src vs program source code
147: work vs workbench
148: %
149: .DE
150: .NH 2
151: Moving Around Inside a Project
152: .XS
153: \*(SN Moving Around Inside a Project
154: .XE
155: .PP
156: The
157: .I pd
158: command provides a convenient way for changing to another project directory
159: without the user having to remember it's precise location. For example,
160: to move to the source code directory `src', type
161: .ID
162: % \fBpd src\fR
163: .DE
164: To change to the directory `work', type
165: .ID
166: % \fBpd work\fR
167: .DE
168: To return to the project root directory, type
169: .ID
170: % \fBpd\fR
171: .DE
172: without any arguments.
173: .NH 2
174: Compiling a Program
175: .XS
176: \*(SN Compiling a Program
177: .XE
178: .PP
179: Program development and maintenance is handled by the
180: .I make
181: command\|[3].
182: .I Make
183: mechanizes many development and maintenance activities, including
184: compiling and linking of programs, printing of source code, and the removal
185: of unneeded files. The instructions which tell
186: .I make
187: how to perform these duties are kept in a special file known as a makefile,
188: together with the names of the source code files which make up the
189: program. The makefile editor program,
190: .I mkmf,
191: creates the makefile (named `Makefile' by default) by gathering up
192: the names of all the source code files in the current working directory and
193: inserting them into a standard makefile.
194: .PP
195: The following example shows how to produce the program for the visual
196: spreadsheet, given the file `vs.c' containing the source code in the directory
197: `src'.
198: .DS
199: % \fBmkmf\fR
200: mkmf: creating Makefile from template /usr/new/lib/p.Makefile
201: % \fBmake\fR
202: cc \-c vs.c
203: Loading a.out ... done
204: %
205: .DE
206: In this example the executable program is called `a.out'. However, by using the
207: makefile editor interactively the name `vs' could have been specified instead:
208: .DS
209: % \fBmkmf \-i\fR
210: mkmf: creating Makefile from template /usr/new/lib/p.Makefile
211: program name? \fBvs\fR
212: destination directory?
213: % \fBmake\fR
214: cc \-c vs.c
215: Loading vs ... done
216: %
217: .DE
218: Since a carriage return was typed in response to the second question in
219: the example above, the destination directory for the program remains the
220: current directory.
221: .PP
222: Because program
223: .I vs
224: is a screen-oriented program, it would not be
225: surprising if it requires special functions to control cursor movement
226: and updating of the terminal screen. There is a standard package of C
227: library functions for this purpose called `curses'\|[1], and if the program
228: has taken advantage of these functions, this library should be included
229: in the makefile together with the terminal database package `termlib'.
230: This can be done by including the LIBS macro definition as an argument to the
231: .I mkmf
232: command\**
233: .FS
234: Arguments with embedded blanks in UNIX commands must be enclosed by double
235: quotes.
236: .FE
237: .ID
238: % \fBmkmf \-i "LIBS=\-lcurses \-ltermlib"\fR
239: .DE
240: .NH 2
241: Moving Files Within a Project
242: .XS
243: \*(SN Moving Files Within a Project
244: .XE
245: .PP
246: A file can be moved to another project directory by using the
247: .I pmv
248: command. For instance, the following command moves the executable program
249: .I vs
250: from the current working directory to the `work' directory
251: .ID
252: % \fBpmv vs work\fR
253: .DE
254: In a similar manner, files can be copied from one project directory
255: to another using the
256: .I pcp
257: command.
258: .I Pmv
259: and
260: .I pcp
261: behave very similarly to the standard
262: .UX
263: .I mv
264: and
265: .I cp
266: commands in that they blindly overwrite any existing files of the same
267: name in the destination directory unless the
268: .B \-i
269: interactive option is used.
270: .NH 2
271: More on Building a Project
272: .XS
273: \*(SN More on Building a Project
274: .XE
275: .PP
276: As development of a software package continues, extra project directories may
277: be needed to support the work. For example, project `vs' must accommodate
278: an additional program called
279: .I vstutor
280: which provides instruction on the use of the visual spreadsheet program;
281: two library packages called `hash' and `list' for hash table and linked
282: list operations; and three files that are ``included'' in more than one
283: source file \- `vs.h' which contains common program definitions,
284: `hash.h' which defines hash tables, and `list.h' which holds linked
285: list definitions. Figure 3 shows the extra directories needed for
286: these components and the following command sequence creates them
287: .DS
288: % \fBpd\fR
289: % \fBpmkdir bin include lib\fR
290: bin: description? (1 line): \fBvs and vstutor programs\fR
291: include: description? (1 line): \fBcommon included files\fR
292: lib: description? (1 line): \fBcompiled hash table and list libraries\fR
293: % \fBpd src\fR
294: % \fBpmkdir vs vstutor libhash liblist\fR
295: vs: description? (1 line): \fBvs program source code\fR
296: vstutor: description? (1 line): \fBvstutor program source code\fR
297: libhash: description? (1 line): \fBhash table library source code\fR
298: liblist: description? (1 line): \fBlist library source code\fR
299: %
300: .DE
301: The final step is to change the description of the `src' directory now
302: that it has been subdivided into four separate source code
303: directories. This can be done by using the
304: .I pmkdir
305: with the \fB+d\fR (change \fBd\fRescription) option
306: .DS
307: % \fBpmkdir +d src\fR
308: src: description? (1 line): \fBC source code\fR
309: %
310: .DE
311: .KF
312: .sp 17
313: .SM
314: .ce
315: \fIFigure 3. \fRRevised layout of project `vs'
316:
317: .NL
318: .KE
319: Note that in Figure 3 there are two directories called `vs'. The top one
320: bears the name of the project, and the bottom one is named according to the
321: program contained within it. Similarly, the directories `libhash' and
322: `liblist' are named according to libraries that they contain.
323: .NH 2
324: Creating a Program Library
325: .XS
326: \*(SN Creating a Program Library
327: .XE
328: .PP
329: A program library is a collection of compiled subroutines that are shared
330: by more than one program. In the
331: .UX
332: environment a program library is stored as an
333: .I archive
334: file. Each member of the archive is an object file containing one or
335: more compiled subroutines. By convention a library archive file is named
336: \fBlib\fIname\fR.\fBa\fR where
337: .I name
338: is the name of the program library.
339: .PP
340: The example below shows how to create a program library for the hash table
341: subroutines in the `libhash' directory. Note that the
342: .I mkmf
343: command must be given with the \fB\-l\fR option so that a makefile will be
344: created for a library rather than a program.
345: .DS
346: % \fBmkmf \-i \-l\fR
347: mkmf: creating Makefile from template /usr/new/lib/l.Makefile
348: library name? \fBlibhash.a\fR
349: destination directory? \fB../../lib\fR
350: % \fBmake\fR
351: cc \-c hthash.c
352: cc \-c htinit.c
353: cc \-c htinstall.c
354: cc \-c htlookup.c
355: cc \-c htrm.c
356: Loading libhash.a ... done
357: %
358: .DE
359: Since the `lib' directory is in the same
360: project as the `libhash' directory, the path to `lib' is
361: made
362: .I relative
363: to `libhash' so that the project will be portable.
364: .PP
365: The next step is to install the program library in the `lib' project directory
366: where the
367: .I vs
368: and
369: .I vstutor
370: programs can access it easily.
371: .DS
372: % \fBmake install\fR
373: Installing libhash.a in ../../lib
374: %
375: .DE
376: .NH 2
377: More on Developing a Program
378: .XS
379: \*(SN More on Developing a Program
380: .XE
381: .NH 3
382: \fIIncluded files\fR
383: .XS
384: \*(SN Included files
385: .XE
386: .PP
387: Definitions which are common to more than one source code file (e.g. buffer
388: sizes, data structure definitions) should be declared only once in a program.
389: This can be achieved by keeping such definitions in files separate from the
390: main program and ``including'' them at compilation time. In C, Fortran, and
391: Pascal programs, the contents of a file can be included by the statement
392: .ID
393: #include "filename"
394: .DE
395: By convention
396: .I filename
397: ends in \fB.h\fR and is commonly referred to as a
398: .I header
399: file. Hence, in the source code for programs
400: .I vs
401: and
402: .I vstutor,
403: the statements
404: .DS
405: #include "vs.h"
406: #include "hash.h"
407: #include "list.h"
408: .DE
409: include common program definitions, hash table definitions, and linked
410: list definitions respectively.
411: .PP
412: Since the header files in this example are used in more than
413: one program, they should be placed in the `include' directory where they can
414: be accessed easily. Although the include statements can be rewritten as
415: .DS
416: #include "../../include/vs.h"
417: #include "../../include/hash.h"
418: #include "../../include/list.h"
419: .DE
420: it is better to tell the compiler where the header files are by using the
421: .B \-I
422: compiler option\** as follows
423: .FS
424: C and Fortran compilers only.
425: .FE
426: .ID
427: \-I../../include
428: .DE
429: This is done most conveniently by adding the option to the compiler
430: flags in the makefile (see \(sc\|4.1.1).
431: .NH 3
432: \fIProgram libraries\fR
433: .XS
434: \*(SN Program libraries
435: .XE
436: .PP
437: The LIBS macro definition in a makefile specifies the libraries that
438: are to be used by the link editor for resolving references to
439: subroutines that are not found in the program source code. Because
440: .I make
441: checks to see if the libraries needed by a program have changed since
442: the last time the program was made, their pathnames must be defined
443: explicitly. In the makefiles belonging to programs
444: .I vs
445: and
446: .I vstutor,
447: the LIBS macro definition looks like
448: .DS
449: LIBS = \kx../../lib/libhash.a \\\\
450: \h'|\nxu'\&../../lib/liblist.a \\\\
451: \h'|\nxu'\&/usr/lib/libcurses.a \\\\
452: \h'|\nxu'\&/usr/lib/libtermlib.a
453: .DE
454: Note also that when this macro definition was added to the makefile by
455: the command
456: .PP
457: % \fBmkmf "LIBS=../../lib/libhash.a ../../lib/liblist.a \-lcurses \-ltermlib"\fR
458: .LP
459: to include the `hash' and `list' libraries, the `curses' and `termlib'
460: libraries were automatically expanded to full pathnames by the makefile editor.
461: .NH 3
462: \fIInstallation\fR
463: .XS
464: \*(SN Installation
465: .XE
466: .PP
467: Once a program has been completed, it should be installed in a place
468: where it will be generally available \- that is, in a directory which
469: is in the command search path specified by the PATH environment
470: variable. In the case of the project `vs', if the `bin' directory is in
471: the search path, this might be a good place to install the
472: .I vs
473: and
474: .I vstutor
475: programs. If the makefiles for these programs do not already specify `bin' as
476: their destination directory, it can be added by the command
477: .ID
478: % \fBmkmf "DEST=../../bin"\fR
479: .DE
480: Then, each program can be installed by the
481: .I
482: make install
483: .R
484: command. For the program \fIvs\fR:
485: .DS
486: % \fBpd vs\fR
487: % \fBmake install\fR
488: Installing vs in ../../bin
489: %
490: .DE
491: and for the program \fIvstutor\fR:
492: .DS
493: % \fBpd vstutor\fR
494: % \fBmake install\fR
495: Installing vstutor in ../../bin
496: %
497: .DE
498: .NH 2
499: Global Operations
500: .XS
501: \*(SN Global Operations
502: .XE
503: .PP
504: One of the goals of SPMS is to reduce the effort associated with software
505: maintenance. This can be achieved by treating a software package as an
506: atomic unit \- that is, a single entity on which to perform operations.
507: The mechanism for executing a command over an entire software package
508: is provided by the
509: .I pexec
510: command. This command takes another command as an argument and executes it
511: in each of the directories belonging to a project, as in
512: .ID
513: % \fBpexec ls\fR
514: .DE
515: which lists the names of all the files in a project.
516: .NH 3
517: \fIDirectory selection\fR
518: .XS
519: \*(SN Directory selection
520: .XE
521: .PP
522: By labeling each project directory according to the type of activity that it
523: supports, global operations can be restricted to specific directories. These
524: labels, which are known as
525: .I
526: type labels,
527: .R
528: are attached to project directories by the
529: .I pmkdir
530: command, and removed by the
531: .I prmdir
532: command\**.
533: .FS
534: Except in the case of project root directories, where
535: .I mkproject
536: and
537: .I rmproject
538: must be used.
539: .FE
540: For instance, if the directories containing source code in project `vs' are
541: labeled `src' by
542: .ID
543: % \fBpmkdir +T\|src include libhash liblist vs vstutor\fR
544: .DE
545: then, the total number of lines of source code in a project can be counted by
546: giving the command
547: .ID
548: % \fBpexec \-T\|src \'cat \(**.h \(**.c\^\' | wc \-l\fR
549: .DE
550: where quotes surround the
551: .I cat
552: command to prevent file name expansion in the current directory.
553: .PP
554: If a project directory supports more than one type of activity,
555: labels corresponding to each of the activities can be attached to
556: the directory.
557: .NH 3
558: \fIDirectory order\fR
559: .XS
560: \*(SN Directory order
561: .XE
562: .PP
563: In some instances the directories affected by a global command must be
564: processed in a particular order. For example, when installing a software
565: package which has both libraries and programs, the libraries should be
566: installed first. This ordering is achieved by appending priorities to type
567: labels. In the case of the project `vs', if the directories containing the
568: program and library source code are labeled `install' with the following
569: priorities
570: .so install.tbl
571: by the commands
572: .DS
573: % \fBpmkdir +T\|install.1 libhash liblist\fR
574: % \fBpmkdir +T\|install.2 vs vstutor\fR
575: .DE
576: then, the command
577: .ID
578: % \fBpexec \-T\|install make install\fR
579: .DE
580: installs the `vs' software package in the order shown in figure 4.
581: .KF
582: .sp 18
583: .SM
584: .ce
585: \fIFigure 4. \fROrdering for `install' directories
586:
587: .NL
588: .KE
589: .KS
590: .PP
591: In a similar fashion, if the directories containing source code are
592: labeled `print' with the following priorities,
593: .so print.tbl
594: .KE
595: a source code listing for the entire project may be obtained by the command
596: .ID
597: % \fBpexec \-T\|print \'pr \(**.h \(**.c\' | lpr\fR
598: .DE
599: in the order shown in figure 5.
600: .KF
601: .sp 18
602: .SM
603: .ce
604: \fIFigure 5. \fROrdering for `print' directories
605:
606: .NL
607: .KE
608: .NH 2
609: Locating Files in a Project
610: .XS
611: \*(SN Locating Files in a Project
612: .XE
613: .PP
614: When the location of a file within a project is unknown, it can be
615: found by using the
616: .I pfind
617: command. For example, the command
618: .ID
619: % \fB pfind Makefile\fR
620: .DE
621: searches for all occurrences of `Makefile' in project `vs' and produces
622: the output
623: .ID
624: \&...^vs/Makefile
625: \&...^vstutor/Makefile
626: \&...^libhash/Makefile
627: \&...^liblist/Makefile
628: .DE
629: .PP
630: In a large project, the time required to search for a file can be reduced
631: by telling
632: .I pfind
633: to scan only those directories in which there is some likelihood of the
634: file being found. In the example above, since makefiles are only likely
635: to be found in source code directories (i.e. directories having type
636: label `src'), the command could have been given as
637: .ID
638: % \fBpfind \-T\|src Makefile\fR
639: .DE
640: .NH 2
641: Searching Files for Patterns
642: .XS
643: \*(SN Searching Files for Patterns
644: .XE
645: .PP
646: Sometimes it is necessary to look at all the files in a software
647: package that contain a certain pattern\**.
648: .FS
649: The term
650: .I pattern
651: is used to denote a set of strings.
652: .FE
653: One reason might be to find all of the places from which a subroutine
654: is called, perhaps with the intent of altering its arguments. The
655: .I pgrep
656: command searchs through specified files in a project for lines
657: matching a given pattern. For example,
658: .ID
659: % \fBpgrep \-T\|src listappend \'\(**.h \(**.c\'\fR
660: .DE
661: will search all the C source code files in project `vs' for the function
662: `listappend'. Because of the
663: .B \-T
664: option,
665: .I pgrep
666: searchs only in those directories which have the `src' type label.
667: .PP
668: An alternative way for specifying file names is to use the
669: .B \-m
670: option. This causes
671: .I pgrep
672: to fetch the names of source code files from the HDRS and SRCS macro
673: definitions in a makefile. Consequently, the command in the example
674: above could have been expressed as
675: .ID
676: % \fBpgrep \-T\|src \-m listappend\fR
677: .DE
678: .PP
679: If the pattern contains characters that have a special meaning to the
680: shell, such as \fB\(**\fR or \fB^\fR, the pattern should be quoted.
681: For example,
682: .ID
683: % \fBpgrep \-T\|src \-m \'ht.\(**(\'\fR
684: .DE
685: finds all of the places where functions from the hash table library
686: are used.
687: .NH 2
688: Changing the Working Project
689: .XS
690: \*(SN Changing the Working Project
691: .XE
692: .PP
693: Along with a working directory, each user has a
694: .I
695: working project.
696: .R
697: Immediately after logging in, the working project is the root project `^'.
698: To change to a new working project, the
699: .I chproject
700: command must be used, as in
701: .ID
702: % \fBchproject vs\fR
703: .DE
704: which makes `vs' the current (or working) project. To return to the
705: root project, execute the command
706: .ID
707: % \fBchproject ^\fR
708: .DE
709: To find out the name of the working project, type
710: .ID
711: % \fBpwp\fR
712: .DE
713:
714:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.