how to view pdf file in using c# : Extract text from pdf image control SDK platform web page winforms .net web browser code_reading2-part1134

[ Team LiB ]
Chapter 1. Introduction
I regret to report that I've just recently looked again at my programs for prime factors and tic-tac-toe, and they are 
entirely free of any sort of comments or documentation.
—Donald E. Knut h
Software source code is the definitive medium for communicating a program's operation and for storing knowledge in an executable 
form. You can compile source code into an executable program, you can read it to understand what a program does and how it works, 
and you can modify it to change the program's function. Most programming courses and textbooks focus on how to write programs from 
scratch. However, 40% to 70% of the effort that goes into a software system is expended after the system is first written. That effort 
invariably involves reading, understanding, and modifying the original code. In addition, the unrelenting, inevitable accumulation of 
legacy code; the increasing emphasis placed on software reuse; the high human turnover rates associated with the software industry; 
and the rising importance of open-source development efforts and cooperative development processes (including outsourcing, code 
walkthroughs, and extreme programming) make code reading an essential skill for today's software engineer. Furthermore, reading 
real-life well-written code can give you insights on how to structure and program nontrivial systems, a skill that cannot be learned by 
writing toy-sized programs. Programs should be written to be read, and, whether they are or not, they need to be read. Although code 
reading is, in the words of Robert Glass, "an undersung, undertaught activity," [Gla00
] this need not be so.
In this book you will learn how to read code that others have written through concrete examples taken from important, real-life, 
open-source code systems. We adopt a liberal definition of code and take it to encompass all machine-readable elements of a project: 
source code (and its commentary), documentation, executable programs, source code repositories, design diagrams, and configuration 
scripts. Having mastered the book's contents, you will
Be able to read and understand nontrivial software code
Appreciate many important software development concepts
Know how to explore large bodies of code
Have a reading capability of a multitude of important high- and low-level programming languages
Appreciate the intricacies of real software projects
Although the book starts with a revision of basic programming structures, we assume you are familiar with either C, C++, or Java and 
able to use simple tools to examine on-line the code of the examples we provide. In addition, exposure to the systems and applications 
we discuss, although not required, will enhance your understanding of the presented material.
In the remainder of this chapter you will find a discussion of the different reasons that will prompt you to read code together with the 
appropriate corresponding reading strategies, and a brief "instruction manual" for following the material we present. Happy (code) 
[ Team LiB ]
Extract text from pdf image - Select, copy, paste PDF images in, ASP.NET, MVC, Ajax, WinForms, WPF
Support PDF Image Extraction from a Page, a Region on a Page, and PDF Document
pdf image extractor; extract text from image pdf file
Extract text from pdf image - VB.NET PDF Image Extract Library: Select, copy, paste PDF images in, ASP.NET, MVC, Ajax, WinForms, WPF
Support PDF Image Extraction from a Page, a Region on a Page, and PDF Document
extract jpg from pdf; how to extract images from pdf files
[ Team LiB ]
1.1 Why and How to Read Code
You may find yourself reading code because you have to, such as when fixing, inspecting, or improving existing code. You may also 
sometimes read code to learn how something works, in the manner we engineers tend to examine the innards of anything with a cover 
that can be opened. You may read code to scavenge for material to reuse or (rarely, but more commonly after reading this book, we 
hope) purely for your own pleasure, as literature. Code reading for each one of these reasons has its own set of techniques, 
emphasizing different aspects of your skills.
I am indebted to Dave Thomas for suggesting this section.
1.1.1 Code as Literature
Dick Gabriel makes the point that ours is one of the few creative professions in which writers are not allowed to read each other's work 
The effect of ownership imperatives has caused there to be no body of software as literature. It is as if all writers 
had their own private companies and only people in the Melville company could read Moby-Dick and only those in 
Hemingway's could read The Sun Also Rises. Can you imagine developing a rich literature under these 
circumstances? Under such conditions, there could be neither a curriculum in literature nor a way of teaching 
writing. And we expect people to learn to program in this exact context?
Open-source software (OSS) has changed that: we now have access to millions of lines of code (of variable quality), which we can read, 
critique, and improve and from which we can learn. In fact, many of the social processes that have contributed to the success of 
mathematical theorems as a scientific communication vehicle apply to open-source software as well. Most open-source software 
programs have been
Documented, published, and reviewed in source code form
Discussed, internalized, generalized, and paraphrased
Used for solving real problems, often in conjunction with other programs
Make it a habit to spend time reading high-quality code that others have written. Just as reading high-quality prose will enrich your 
vocabulary, trigger your imagination, and expand your mind, examining the innards of a well-designed software system will teach you 
new architectural patterns, data structures, coding methods, algorithms, style and documentation conventions, application programming 
interfaces (APIs), or even a new computer language. Reading high-quality code is also likely to raise your standards regarding the code 
you produce.
In your code-reading adventures you will inevitably encounter code that should best be treated as an example of practices to avoid. 
Being able to rapidly differentiate good code from bad code is a valuable skill; exposure to some sound coding counterexamples may 
help you develop the skill. You can easily discern code of low quality by the following signs:
An inconsistent coding style
A gratuitously complicated or unreadable structure
Obvious logical errors or omissions
C# PDF Text Extract Library: extract text content from PDF file in
Ability to extract highlighted text out of PDF document. Supports text extraction from scanned PDF by using XDoc.PDF for .NET Pro. Image text extraction control
how to extract images from pdf; extract image from pdf acrobat
VB.NET PDF Text Extract Library: extract text content from PDF
Extract highlighted text out of PDF document. Image text extraction control provides text extraction from PDF images and image files.
extract image from pdf java; extract jpg pdf
Overuse of nonportable constructs
Lack of maintenance
You should not, however, expect to learn sound programming from poorly written code; if you are reading code as literature, you are 
wasting your time, especially considering the amount of available high-quality code you can now access.
Ask yourself: Is the code I am reading really the best of breed? One of the advantages of the open-source movement is that successful 
software projects and ideas inspire competition to improve on their structure and functionality. We often have the luxury to see a second 
or third iteration over a software design; in most cases (but not always) the latter design is significantly improved over the earlier 
versions. A search on the Web with keywords based on the functionality you are looking for will easily guide you toward the competing 
Read code selectively and with a goal in your mind. Are you trying to learn new patterns, a coding style, a way to satisfy some 
requirements? Alternatively, you may find yourself browsing code to pick up random gems. In that case, be ready to study in detail 
interesting parts you don't know: language features (even if you know a language in depth, modern languages evolve with new features), 
APIs, algorithms, data structures, architectures, and design patterns.
Notice and appreciate the code's particular nonfunctional requirements that might give rise to a specific implementation style. 
Requirements for portability, time or space efficiency, readability, or even obfuscation can result in code with very peculiar 
We have seen code using six-letter external identifiers to remain portable with old-generation linkers.
There are efficient algorithms that have (in terms of source code lines) an implementation that is two orders of magnitude 
more complex than their naive counterparts.
Code for embedded or restricted-space applications (consider the various GNU/Linux or FreeBSD on-a-floppy distributions) 
can go to great lengths to save a few bytes of space.
Code written to demonstrate the functioning of an algorithm may use identifiers that may be impractically long.
Some application domains, like copy-protection schemes, may require code to be unreadable, in an (often vain) attempt to 
hinder reverse engineering efforts.
When you read code that falls in the above categories, keep in mind the specific nonfunctional requirements to see how your colleague 
satisfied them.
Sometimes you may find yourself reading code from an environment completely foreign to you (computer language, operating system, or 
API). Given a basic familiarity with programming and the underlying computer science concepts, you can in many cases use source code 
as a way to teach yourself the basics of the new environment. However, start your reading with small programs; do not immediately dive 
into the study of a large system. Build the programs you study and run them. This will provide you with both immediate feedback on the 
way the code is supposed to work and a sense of achievement. The next step involves actively changing the code to test your 
understanding. Again, begin with small changes and gradually increase their scope. Your active involvement with real code can quickly 
teach you the basics of the new environment. Once you think you have mastered them, consider investing some effort (and possibly 
some cash) to learn the environment in a more structured way. Read related books, documentation, or manual pages, or attend training 
courses; the two methods of learning complement each other.
One other way in which you can actively read existing code as literature entails improving it. In contrast to other literal works, software 
code is a live artifact that is constantly improved. If the code is valuable to you or your community, think about how you could improve it. 
This can involve using a better design or algorithm, documenting some code parts, or adding functionality. Open-source code is often not 
well documented; consider reinvesting your understanding of the code in improved documentation. When working on existing code, 
coordinate your efforts with the authors or maintainers to avoid duplication of work or bad feelings. If your changes are likely to be 
substantial, think about becoming a concurrent versions system (CVS) committer—an individual with the authority to directly commi t
code to a project's source base. Consider the benefits you receive from open-source software to be a loan; look for ways to repay it by
contributing back to the open-source community.
1.1.2 Code as Exemplar
C# PDF insert image Library: insert images into PDF in, ASP
Free PDF image processing SDK library for Visual Studio .NET program. Powerful .NET PDF image edit control, enable users to insert vector images to PDF file.
extract image from pdf in; extract pictures pdf
VB.NET PDF insert image library: insert images into PDF in
VB.NET code to add an image to the inputFilePath As String = Program.RootPath + "\\" 1.pdf" Dim doc New PDFDocument(inputFilePath) ' Get a text manager from
how to extract images from pdf in acrobat; extract pdf images
There are cases where you might find yourself wondering how a specific functionality is realized. For some application classes you may 
be able to find an answer to your questions in standard textbooks or specialized publications and research articles. However, in many 
cases if you want to know "how'd they do that" there's no better way than reading the code. Code reading is also likely to be the most 
reliable way to create software compatible with a given implementation.
The key concept when you are using code as exemplar is to be flexible. Be prepared to use a number of different strategies and 
approaches to understand how the code works. Start with any documentation you might find (see Chapter 8
). A formal software design 
document would be ideal, but even user documentation can be helpful. Actually use the system to get a feeling of its external interfaces. 
Understand what exactly are you actually looking for: a system call, an algorithm, a code sequence, an architecture? Devise a strategy 
that will uncover your target. Different search strategies are effective for different purposes. You may need to trace through the 
instruction execution sequence, run the program and place a breakpoint in a strategic location, or textually search through the code to 
find some specific code or data elements. Tools (see Chapter 10
) will help you here, but do not let one of them monopolize your 
attention. If a strategy does not quickly produce the results you want, drop it and try something different. Remember, the code you are 
looking for is there; you just have to locate it.
Once you locate the desired code, study it, ignoring irrelevant elements. This is a skill you will have to learn. Many exercises in this book 
will ask you to perform exactly this task. If you find it difficult to understand the code in its original context, copy it into a temporary file and 
remove all irrelevant parts. The formal name of this procedure is slicing (see Section 9.1.6
), but you can get the idea by examining how 
we have informally applied it in the book's annotated code examples.
1.1.3 Maintenance
In other cases code, rather than being an exemplar, may actually need fixing. If you think you have found a bug in a large system, you 
need strategies and tactics to let you read the code at increasing levels of detail until you have found the problem. The key concept in 
this case is to use tools. Use the debugger, the compiler's warnings or symbolic code output, a system call tracer, your database's 
Structured Query Language (SQL) logging facility, packet dump tools, and Windows message spy programs to locate a bug's location. 
(Read more in Chapter 10
about how tools will help your code reading.) Examine the code from the problem manifestation to the 
problem source. Do not follow unrelated paths. Compile the program with debugging support and use the debugger's stack trace facility, 
single stepping, and data and code breakpoints to narrow down your search.
If the debugger is not cooperating (the debugging of programs that run in the background such as daemons and Windows services, C++ 
template-based code, servlets, and multithreaded code is sometimes notoriously difficult), consider adding print statements in strategic 
locations of the program's execution path. When examining Java code consider using AspectJ to insert into the program code elements 
that will execute only under specific circumstances. If the problem has to do with operating system interfaces, a system call tracing facility 
will often guide you very near the problem.
1.1.4 Evolution
In most situations (more than 80% of your time by some measurements) you will be reading code not to repair a fault but to add new 
functionality, modify its existing features, adapt it to new environments and requirements, or refactor it to enhance its nonfunctional 
qualities. The key concept in these cases is to be selective in the extent of the code you are examining; in most situations you will 
actually have to understand a very small percentage of the overall system's implementation. You can in practice modify a million-line 
system (such as a typical kernel or window system) by selectively understanding and changing one or two files; the exhilarating feeling 
that follows the success of such an operation is something I urge you to strive to experience. The strategy for selectively dealing with 
parts of a large system is outlined below.
Locate the code parts that interest you.
Understand the specific parts in isolation.
Infer the code excerpt's relationship with the rest of the code.
C# Create PDF from images Library to convert Jpeg, png images to
If you want to turn PDF file into image file format in C# application, then RasterEdge XDoc.PDF for .NET can also help with this.
pdf image extractor c#; extract images from pdf files without using copy and paste
C# PDF insert text Library: insert text into PDF content in
Text to PDF. C#.NET PDF SDK - Insert Text to PDF Document in C#.NET. Providing C# Demo Code for Adding and Inserting Text to PDF File Page with .NET PDF Library.
online pdf image extractor; extract images from pdf acrobat
When adding new functionality to a system your first task is to find the implementation of a similar feature to use as a template for the 
one you will be implementing. Similarly, when modifying an existing feature you first need to locate the underlying code. To go from a 
feature's functional specification to the code implementation, follow the string messages, or search the code using keywords. As an 
example, to locate the user authentication code of the ftp command you would search the code for the Password string:
netbsdsrc/usr.bin/ftp/util.c:265–26 7
if (pass == NULL)
pass = getpass("Password:");
n = command("PASS %s", pass);
Once you have located the feature, study its implementation (following any code parts you consider relevant), design the new feature or
addition, and locate its impact area—the other code parts that will interact with your new code. In most cases, these are the only cod e
parts you will need to thoroughly understand.
Adapting code to new environments is a different task calling for another set of strategies. There are cases where the two environments 
offer similar capabilities: you may be porting code from Sun Solaris to GNU/Linux or from a Unix system to Microsoft Windows. In these 
situations the compiler can be your most valuable friend. Right from the beginning, assume you have finished the task and attempt to 
compile the system. Methodically modify the code as directed by compilation and linking errors until you end with a clean build cycle, 
then verify the system's functionality. You will find that this approach dramatically lessens the amount of code you will need to read. You 
can follow a similar strategy after you modify the interface of a function, class, template, or data structure. In many cases, instead of 
manually locating your change's impact, you follow the compiler's error or warning messages to locate the trouble spots. Fixes to those 
areas will often generate new errors; through this process the compiler will uncover for you the code location influenced by your code.
When the code's new environment is completely different from the old one (for example, as is the case when you are porting a 
command-line tool to a graphical windowing environment) you will have to follow a different approach. Here your only hope for 
minimizing your code-reading efforts is to focus at the point where the interfaces between the old code and the new environment will 
differ. In the example we outlined, this would mean concentrating on the user interaction code and completely ignoring all the system's 
algorithmic aspects.
A completely different class of code evolution changes concerns refactoring. These changes are becoming increasingly important as 
some types of development efforts adopt extreme programming and agile programming methodologies. Refactoring involves a change to 
the system that leaves its static external behavior unchanged but enhances some of its nonfunctional qualities, such as its simplicity, 
flexibility, understandability, or performance. Refactoring has a common attribute with cosmetic surgery. When refactoring you start with a 
working system and you want to ensure that you will end up with a working one. A suite of pertinent test cases will help you satisfy this 
obligation, so you should start by writing them. One type of refactoring concerns fixing a known trouble spot. Here you have to 
understand the old code part (which is what this book is about), design the new implementation, study its impact on the code that 
interfaces with your code (in many cases the new code will be a drop-in replacement), and realize the change.
A different type of refactoring involves spending some "quality time" with your software system, actively looking for code that can be 
improved. This is one of the few cases where you will need an overall picture of the system's design and architecture; refactoring 
in-the-large is likely to deliver more benefits than refactoring in-the-small. Chapter 6
discusses ways to untangle large systems, while 
Chapter 9
outlines how to move from code to the system's architecture. When reading code to search for refactoring opportunities, you 
can maximize your return on investment by starting from the system's architecture and moving downward to look at increasing levels of 
1.1.5 Reuse
You might also find yourself reading code to look for elements to reuse. The key concept here is to limit your expectations. Code 
reusability is a tempting but elusive concept; limit your expectations and you will not be disappointed. It is very hard to write reusable 
code. Over the years comparatively little software has survived the test of time and been reused in multiple and different situations. 
Software parts will typically become reuse candidates after they have been gracefully extended and iteratively adapted to work on two or 
three different systems; this is seldom the case in ad-hoc developed software. In fact, according to the COCOMO II software cost model 
], crafting reusable software can add as much as 50% to the development effort.
C# PDF Page Extract Library: copy, paste, cut PDF pages in
Page: Extract, Copy and Paste PDF Pages. Easy to Use C# Code to Extract PDF Pages, Copy Pages from One PDF File and Paste into Others in C#.NET Program.
extract image from pdf; pdf image text extractor
VB.NET PDF Form Data Read library: extract form data from PDF in
featured PDF software, it should have functions for processing text, image as well how to read or retrieve field data from PDF and how to extract and get
extract images pdf; pdf extract images
When looking for code to reuse in a specific problem you are facing, first isolate the code that will solve your problem. A keyword-based 
search through the system's code will in most cases guide you to the implementation. If the code you want to reuse is intractable, difficult 
to understand and isolate, look at larger granularity packages or different code. As an example, instead of fighting to understand the 
intricate relation of a code piece with its surrounding elements, consider using the whole library, component, process, or even system 
where the code resides.
One other reuse activity involves proactively examining code to mine reusable nuggets. Here your best bet is to look for code that is 
already reused, probably within the system you are examining. Positive signs indicating reusable code include the use of a suitable 
packaging method (see Section 9.3
) or a configuration mechanism.
1.1.6 Inspections
Finally, in some work settings, the task of code reading may be part of your job description. A number of 
software development methodologies use technical reviews such as walkthroughs, inspections, 
round-robin reviews, and other types of technical assessments as an integral part of the development 
process. Moreover, when practicing pair programming while applying the extreme programming 
methodology you will often find yourself reading code as your partner writes it. Code reading under these 
circumstances requires a different level of understanding, appreciation, and alertness. Here you need to 
be thorough. Examine code to uncover errors in function and logic. The various elements we have 
marked in the margin as dangerous (see the icon at left) are some of the things you should be wary of. In 
addition, you should be ready to discuss things you fail to see; verify that the code meets all its 
Nonfunctional issues of the code should absorb an equal part of your attention. Does the code fit with your organization's development 
standards and style guides? Is there an opportunity to refactor? Can a part be coded more readably or more efficiently? Can some 
elements reuse an existing library or component? While reviewing a software system, keep in mind that it consists of more elements than 
executable statements. Examine the file and directory structure, the build and configuration process, the user interface, and the system's 
Software inspections and related activities involve a lot of human interaction. Use software reviews as a chance to learn, teach, lend a 
hand, and receive assistance.
[ Team LiB ]
[ Team LiB ]
1.2 How to Read This Book
In this book we demonstrate important code-reading techniques and outline common programming concepts in the form they appear in 
practice, striving to improve your code-reading ability. Although you will find in the following chapters discussions of many important 
computer science and computing practice concepts such as data and control structures, coding standards, and software architectures, 
their treatment is by necessity cursory since the purpose of the book is to get you to examine the use of these ideas in the context of 
production code, rather than to introduce the ideas themselves. We have arranged the material in an order that will let you progress from 
the basic to the more sophisticated elements. However, the book is a reader, not a detective novel, so feel free to read it in the sequence 
that suits your interests.
1.2.1 Typographical Conventions
All code listings and text references to program elements (for example, function names, keywords, operators) are set in typewriter font. 
Some of our examples refer to command sequences executed in a Unix or Windows shell. We display the shell command prompt $ to 
denote Unix shell commands and the DOS command prompt
Figure 1.1 Example of an annotated listing.
main(argc, argv)        
<-- a
<-- b
if (argc > 1)
else for (;;)
(a) Simple annotation
(b) Omitted code
Annotation referenced from the text
C:\> to denote the Windows console prompt. Unix shell commands can span more than one line; we use > as the continuation line symbol.
$ grep -l malloc *.c |
> wc -l
C:\>grep -l malloc *.c | wc -l
The prompts and the continuation line symbol are displayed only to distinguish your input from the system output; you type only the 
commands after the prompt.
In some places we discuss unsafe coding practices or common pitfalls. These are identified on the 
margin with a danger symbol. You should be alert for such code when conducting a code walkthrough or 
just reading code to look for a bug. Text marked on the margin with an i identifies common coding idioms. 
When we read text we tend to recognize whole words rather than letters; similarly, recognizing these 
idioms in code will allow you to read code faster and more effectively and to understand programs at a 
higher level.
The code examples we use in this book come from real-world programs. We identify the programs we use (such as the one appearing in 
Figure 1.1
) in a footnote
giving the precise location of the program in the directory tree of the book's companion source code and the 
line numbers covered by the specific fragment. When a figure includes parts of different source code files (as is the case in Figure 5.17
page 169) the footnote will indicate the directory where these files reside.
netbsdsrc/usr.bin/yes/yes.c:53–6 4
Sometimes we omit parts from the code we list; we indicate those with an ellipsis sign [...]. In those cases the line numbers represent the 
entire range covered by the listed code. Other changes you may notice when referring back to the original code are changes of most C 
declarations from the old "Kernighan and Ritchie" style to ANSI C and the omission of some comments, white space, and program 
licensing information. We hope that these changes enhance the readability of the examples we provide without overly affecting the 
realism of the original examples. Nontrivial code samples are graphically annotated with comments using a custom-built software 
application. The use of the annotation software ensures that the examples remain correct and can be machine-verified. Sometimes we 
expand on an annotation in the narrative text. In those cases (Figure 1.1:1
) the annotation starts with a number printed in a box; the 
same number, following a colon, is used to refer to the annotation from the text.
1.2.2 Diagrams
We chose UML for our design diagrams because it is the de facto industry standard. In preparing this book, we found it useful to develop 
an open-source declarative language for generating UML diagrams,
and we also made some small improvements to the code base 
underlying GraphViz
tool. We hope you find that the resulting UML diagrams help you better understand the code we analyze.
Figure 1.2
shows examples of the notation we use in our diagrams. Keep in mind the following.
We draw processes (for example, filter-style programs) using UML's active class notation: a class box with a bold frame (for 
example, see Figure 6.14
, page 213).
We depict pointers between data elements using an association navigation relationship: a solid line with an open arrow. We 
also split each data structure into horizontal or vertical compartments to better depict its internal organization (for example, 
see Figure 4.10
, page 121).
We show the direction of associations (for example, to illustrate the flow of data) with a solid arrow located on the association 
line, rather than on top of it as prescribed by the UML (for example, see Figure 9.3
, page 274).
Figure 1.2. 
-based diagram notation.
All other relationships use standard UML notation.
Class inheritance is drawn using a generalization relationship: a solid line with an empty arrow (for example, see Figure 9.6
page 277).
An interface implementation is drawn as a realization relationship: a dashed line with an empty arrow (for example, seeFigure  
, page 278).
dependency between two elements (for example, between files of a build process) is shown with a dashed line and an open 
arrow (for example, see Figure 6.8
, page 191).
Compositions (for example, a library consisting of various modules) are depicted through an aggregation association: a line 
ending in a diamond-like shape (for example, see Figure 9.24
, page 321).
1.2.3 Exercises
The exercises you will find at the end of most sections aim to provide you with an incentive to apply the techniques we described and to 
further research particularly interesting issues, or they may be starting points for in-depth discussions. In most instances you can use 
references to the book's CD-ROM and to "code in your environment" interchangeably. What is important is to read and examine code 
from real-world, nontrivial systems. If you are currently working on such a system (be it in a proprietary development effort or an 
open-source project), it will be more productive to target the code-reading exercises toward that system instead of the book's CD-ROM.
Many exercises begin by asking you to locate particular code sequences. This task can be automated. First, express the code you are 
looking for as a regular expression. (Read more about regular expressions in Chapter 10
.) Then, search through the code base using a 
command such as the following in the Unix environment:
find /cdrom -name '*.c' -print | xargs grep 'malloc.*NULL'
or using the Perl script
in the Windows environment. (Some of the files in the source code base have the same name as old 
MS-DOS devices, causing some Windows implementations to hang when trying to access them; the Perl script explicitly codes around 
this problem.)
1.2.4 Supplementary Material
All the examples you will find in this book are based on existing open-source software code. The source code base comprises more than 
53,000 files occupying over 540 MB. All references to code examples are unambiguously identified in footnotes so you can examine the 
referenced code in its context. In addition, you can coordinate your exploration of the source code base with the book's text in three 
different ways.
You can look up the file name (the last component of the complete file path) of each referenced source file in the Index.
You can browse Appendix A
, which provides an overview of the source code base.
You can search Appendix C
, which contains a list of referenced source code files sorted according to the code directory 
1.2.5 Tools
Some of the examples we provide depend on the availability of programs found under Unix-type operating systems, such as grep and 
find. A number of such systems (for example, FreeBSD, GNU/Linux, NetBSD, OpenBSD, and Solaris) are now freely available to 
download and install on a wide variety of hardware. If you do not have access to such a system, you can still benefit from these tools by 
using ports that have been made to other operating systems such as Windows. (Section 10.9
contains further details on tool availability.)
1.2.6 Outline
In Chapter 2
we present two complete programs and examine their workings in a step-by-step fashion. In doing so we outline some basic 
Documents you may be interested
Documents you may be interested