258 Chapter 17 ■ Software robustness
The programming language Pascal has a strong reputation for being a secure lan-
guage, with extensive compile-time checking to prevent software faults. But these
three authors set out to show how vulnerable it actually is. It is a study in paranoia:
J. Walsh, W.J. Sneeringer and C.A.R. Hoare, Ambiguities and insecurities in
Pascal, Software – Practice and Experience, 7 (1977), pp. 685–96.
For a more detailed treatment of some of the topics described in this chapter, see:
Hoang Pham (ed.), Fault-Tolerant Software Systems: Techniques and Applications, IEEE
Computer Society Press, 1992.
The following book has a chapter that explains how software errors can be quantified:
M.L. Shooman, Software Engineering, McGraw-Hill International, 1986.
17.5 The answer depends on the particular software
17.6 Forward, because you continued your journey. It was an anticipated fault.
However, as far as the tire is concerned, it is backward error recovery,
because it is replaced by some other component.
17.7 Add the line:
if (string.length() == 0) throw new
NumberFormatException();
at the start of the method.
17.8 Control continues down the program, which dangerously tests the value
of the information returned by parseInt.
17.9 The precondition is assert oldCount > 0;
The postcondition is assert newCount = oldCount - 1;
Further reading
•
BELL_C17.QXD 1/30/05 4:24 PM Page 258
Scripting is the duct tape or glue of computing. It is a means of constructing soft-
ware quickly, usually by combining existing components and programs. The product
may not be elegant, but it works. For example, suppose we write an e-mail program.
We would like the user to be able to click on a URL within an e-mail and get taken
immediately into a web browser that displays the page. So we need the e-mail program
to be able to invoke the web browser. This is the kind of interoperability that can be
provided by a scripting language.
A scripting language is a particular kind of programming language. Examples include
the Unix shell scripting language, Perl and Python. However, general-purpose lan-
guages, such as Visual Basic and C, can also be used for scripting.
Traditionally scripting languages have been interpreted, but this is no longer an iden-
tifying feature.
In this chapter, we use the Unix shell language as the example to expose the script-
ing approach.
Unix is a general-purpose operating system available widely on personal computers,
servers and mainframe computers. Two workers at Bell telephones reputedly developed
it in an attic. This pedigree explains its conceptual simplicity and beauty. From such
small beginnings, Unix has become widely popular and has spawned such derivatives as
18.2
●
Unix
18.1
●
Introduction
CHAPTER
18
Scripting
This chapter:
■ explains the principles of scripting languages
■ gives examples of using scripting languages.
BELL_C18.QXD 1/30/05 4:24 PM Page 259
260 Chapter 18 ■ Scripting
GNU/Linux. For reasons that we shall shortly see, Unix can act as an excellent basis
for scripting.
Unix provides:
■ a textual command language, based on command verbs followed by parameters
■ the facility to write programs in the command language
■ a filing system, with tree-structured directories (folders)
■ a set of useful utility programs, called filters, e.g. a file copy tool
■ a facility, called pipes, for joining filters together.
These facilities are now commonly found in many operating systems, but Unix was
the first system to provide them.
Unix consists of a small kernel, augmented by a rich set of small utility programs, the
filters. An example of a filter is a program to display a list of the files within a particu-
lar directory. Perhaps because only two people designed it, Unix is built around a few
simple concepts. One of the fundamental ideas of Unix is the notion that software
(including Unix itself ) should be built from small general-purpose components that are
developed individually. These components can be used individually but also can be
combined as necessary in order to satisfy a new requirement. A filter is a program that
inputs a serial stream of information, processes it and outputs a second serial stream.
Other examples of Unix-provided filters:
■ count the number of lines or characters in a file
■ a file copy program
■ print a file with specified formatting
■ spool a file to the printer
■ print all lines in a file that contain a specified textual pattern
■ a lexical analyzer.
Filters are combined by taking the output from one and feeding it as input to
another. The stream of data that flows from one filter to another is known as a pipe.
This combination of filters and pipes is carried out by Unix under the control of the
command language.
An example of using a filter is the command:
ls
When you type a Unix command such as this, you invoke the filter with the same
name. The filter named
ls displays on the screen the names of all the files in the current
directory, one per line. Another tool, named
wc, inputs a file and gives a line, word and
character count for that file. The output of
wc can be controlled by providing parameters,
and the parameter
-l specifies that lines should be counted, so that the command:
wc -l file
BELL_C18.QXD 1/30/05 4:24 PM Page 260
18.2 Unix 261
tells us how many lines the file file contains. (The majority of Unix commands offer
a choice of parameters to modify their output). Putting these two tools together, the
Unix command:
ls | wc -l
pipes the output from the filter ls into the input for the filter wc. The final output is
therefore the number of files in the current directory.
SELF-TEST QUESTION
18.1 The command:
grep "Alice" < file
outputs those lines in the file file that contain the string Alice. Write
a pipelined command to count how many lines in the file contain the
string
Alice.
The vertical bar symbol in a Unix command signifies that the output stream from
one filter is to be directed not to its default file, but to the input of another filter.
We have seen that Unix provides a useful but limited number of facilities as filters,
plus a facility to combine filters. Thus when some new software is required, there are
three options:
1. use an existing filter
2. combine the existing filters using pipes
3. write a new filter and combine it with existing filters using pipes.
Combining filters is rather like writing programs, but at a higher level – the Unix
filters are the language primitives, and pipes provide the mechanism for combining
them to produce more powerful facilities. The command language describes the
interactions.
Filters tend to be short and simple – 90 of the standard Unix filters (other than
compilers) are less than 1,200 lines (about 20 pages) of high-level programming
language statements. An individual filter is usually written in the programming lan-
guage C, which is the core language of Unix. A filter reads from an input pipe and
outputs to an output pipe. It opens an input pipe just as if it was opening a file,
then it reads data serially from the pipe (or file) until the end of data (file) is
encountered. The filter sends its output to an output stream by writing data as if
to a serial file.
All the Unix tools are designed to do a specific single task well, rather than sup-
porting many, optional features. However, any options are specified using parameters.
BELL_C18.QXD 1/30/05 4:24 PM Page 261
262 Chapter 18 ■ Scripting
A successful scripting language needs to provide the following features:
■ easy manipulation of file and folder (directory) names. The user needs to be able to
change file names, create files, create folders, move files and copy files with ease.
■ good string manipulation. The user needs to be able to analyze strings, such as an
HTML file, and create files of new strings.
■ calling other programs and components. The user needs a convenient facility to call
programs and components written in other languages. This includes accessing a
large and comprehensive library of classes and methods.
■ combining programs and components. This is the facility to combine existing com-
ponents or programs. In Unix, this is accomplished using the pipe mechanism.
■ weak data typing. A scripting language is often used to read data from a file (or an
internet connection), analyze it and convert it into some other form. An example is
a file in a particular graphics file format which needs to be rendered or converted
into some other file format. Thus the program needs to be relaxed about the exact
type of the data it is processing. In contrast, a strongly typed data language insists
on the clear separation of data types.
What is the essential difference between a scripting language and a programming
language? In a programming language, a typical operation is adding two numbers; in
a scripting language a typical operation is invoking a program (perhaps to add two
numbers).
18.3
●
Discussion
SELF-TEST QUESTION
18.2 Name another mechanism for connecting components.
In summary, the main virtues of Unix as a basis for scripting are:
■ a number of small, highly modular, general-purpose components called filters are
provided
■ under the control of the command language, software is constructed by combining
filters with other filters using pipes.
The Unix approach is based on the assumption that connecting programs via serial
streams is modular and flexible.
BELL_C18.QXD 1/30/05 4:24 PM Page 262
Answers to self-test questions 263
Exercises
Summary
A scripting language is a language that glues existing programs together. It allows
us to combine existing programs in useful ways. It is a means of reusing software.
The key characteristic of a scripting language is that it provides a facility to invoke
other programs. The programs can be passed information as parameters or alter-
natively the programs can pass information as data streams.
In addition scripting languages typically provide comprehensive facilities for
manipulating strings, files and directories.
18.1
Compare and contrast the facilities of a language for scripting with those required of
a conventional programming language.
18.2 Review the features of the Unix scripting language.
18.3 Compare and contrast the Unix pipes and filters approach to constructing software
with an approach that makes the maximum reuse of libraries, as in Java and C#.
18.4 Assess Perl or Python as a scripting language.
•
Answers to self-test questions
18.1 grep "Alice" < file | wc -l
18.2 Method calls
There are lots of good books on Unix. But if you want to read the original classic paper,
it is: B.W. Kernighan and J.R. Mashey, The Unix programming environment, IEEE
Computer, April 1981, pp. 12–24.
Further reading
•
BELL_C18.QXD 1/30/05 4:24 PM Page 263
BELL_C18.QXD 1/30/05 4:24 PM Page 264
PART
D
VERIFICATION
BELL_CPARTD.QXD 1/30/05 4:30 PM Page 265
BELL_CPARTD.QXD 1/30/05 4:30 PM Page 266
Verification is the general term for techniques that aim to produce fault-free software.
Testing is a widely used technique for verification, but note that testing is just one tech-
nique amongst several others. This chapter explains several approaches to testing.
Remember that there is a separate collection of techniques for carrying out valida-
tion – which are techniques which strive to make sure that software meets its users needs
Software is complex and it is difficult to make it work correctly. Currently the dom-
inant technique used for verification is testing. And testing typically consumes an enor-
mous proportion (sometimes as much as 50%) of the effort of developing a system.
Microsoft employ teams of programmers (who write programs) and completely sepa-
rate teams of testers (who test them). At Microsoft there are as many people involved
in testing as there are in programming.
Arguably, verification is a major problem and we need good techniques to tackle it.
Often, towards the end of a project, the difficult decision has to be made between con-
tinuing the testing or delivering the software to its customers or clients.
19.1
●
Introduction
CHAPTER
19
Testing
This chapter:
■ identifies the problem of effective testing
■ explains how to carry out black box (functional) testing
■ explains how to carry out white box (structural) testing
■ explains the principles behind these approaches to testing
■ introduces some other testing techniques
■ explains how to carry out unit testing
■ explains how to carry out system (integration) testing.
BELL_C19.QXD 1/30/05 4:25 PM Page 267