Python Scripting
================

LLDB has been structured from the beginning to be scriptable in two
ways -- a Unix Python session can initiate/run a debug session
non-interactively using LLDB; and within the LLDB debugger tool, Python
scripts can be used to help with many tasks, including inspecting
program data, iterating over containers and determining if a breakpoint
should stop execution or continue. This document will show how to do
some of these things by going through an example, explaining how to use
Python scripting to find a bug in a program that searches for text in a
large binary tree.

.. contents::
   :local:

The Test Program and Input
--------------------------

We have a simple C program (dictionary.c) that reads in a text file,
and stores all the words from the file in a Binary Search Tree, sorted
alphabetically. It then enters a loop prompting the user for a word,
searching for the word in the tree (using Binary Search), and reporting
to the user whether or not it found the word in the tree.

The input text file we are using to test our program contains the text
for William Shakespeare's famous tragedy "Romeo and Juliet".

The Bug
-------

When we try running our program, we find there is a problem. While it
successfully finds some of the words we would expect to find, such as
"love" or "sun", it fails to find the word "Romeo", which MUST be in
the input text file:

::

   % ./dictionary Romeo-and-Juliet.txt
   Dictionary loaded.
   Enter search word: love
   Yes!
   Enter search word: sun
   Yes!
   Enter search word: Romeo
   No!
   Enter search word: ^D
   %

Using Depth First Search
------------------------

Our first job is to determine if the word "Romeo" actually got inserted
into the tree or not. Since "Romeo and Juliet" has thousands of words,
trying to examine our binary search tree by hand is completely
impractical. Therefore we will write a Python script to search the tree
for us. We will write a recursive Depth First Search function that
traverses the entire tree searching for a word, and maintaining
information about the path from the root of the tree to the current
node. If it finds the word in the tree, it returns the path from the
root to the node containing the word. This is what our DFS function in
Python would look like, with line numbers added for easy reference in
later explanations:

::

   1: def DFS (root, word, cur_path):
   2:     root_word_ptr = root.GetChildMemberWithName ("word")
   3:     left_child_ptr = root.GetChildMemberWithName ("left")
   4:     right_child_ptr = root.GetChildMemberWithName ("right")
   5:     root_word = root_word_ptr.GetSummary()
   6:     end = len (root_word) - 1
   7:     if root_word[0] == '"' and root_word[end] == '"':
   8:         root_word = root_word[1:end]
   9:     end = len (root_word) - 1
   10:     if root_word[0] == '\'' and root_word[end] == '\'':
   11:        root_word = root_word[1:end]
   12:     if root_word == word:
   13:         return cur_path
   14:     elif word < root_word:
   15:         if left_child_ptr.GetValue() == None:
   16:             return ""
   17:         else:
   18:             cur_path = cur_path + "L"
   19:             return DFS (left_child_ptr, word, cur_path)
   20:     else:
   21:         if right_child_ptr.GetValue() == None:
   22:             return ""
   23:         else:
   24:             cur_path = cur_path + "R"
   25:             return DFS (right_child_ptr, word, cur_path)


Accessing & Manipulating Program Variables
------------------------------------------

Before we can call any Python function on any of our program's
variables, we need to get the variable into a form that Python can
access. To show you how to do this we will look at the parameters for
the DFS function. The first parameter is going to be a node in our
binary search tree, put into a Python variable. The second parameter is
the word we are searching for (a string), and the third parameter is a
string representing the path from the root of the tree to our current
node.

The most interesting parameter is the first one, the Python variable
that needs to contain a node in our search tree. How can we take a
variable out of our program and put it into a Python variable? What
kind of Python variable will it be? The answers are to use the LLDB API
functions, provided as part of the LLDB Python module. Running Python
from inside LLDB, LLDB will automatically give us our current frame
object as a Python variable, "lldb.frame". This variable has the type
`SBFrame` (see the LLDB API for more information about `SBFrame`
objects). One of the things we can do with a frame object, is to ask it
to find and return its local variable. We will call the API function
`SBFrame.FindVariable` on the lldb.frame object to give us our dictionary
variable as a Python variable:

::

   root = lldb.frame.FindVariable ("dictionary")

The line above, executed in the Python script interpreter in LLDB, asks the
current frame to find the variable named "dictionary" and return it. We then
store the returned value in the Python variable named "root". This answers the
question of HOW to get the variable, but it still doesn't explain WHAT actually
gets put into "root". If you examine the LLDB API, you will find that the
`SBFrame` method "FindVariable" returns an object of type `SBValue`. `SBValue`
objects are used, among other things, to wrap up program variables and values.
There are many useful methods defined in the `SBValue` class to allow you to get
information or children values out of SBValues. For complete information, see
the header file SBValue.h. The `SBValue` methods that we use in our DFS function
are ``GetChildMemberWithName()``, ``GetSummary()``, and ``GetValue()``.


Explaining DFS Script in Detail
-------------------------------

Before diving into the details of this code, it would be best to give a
high-level overview of what it does. The nodes in our binary search tree were
defined to have type ``tree_node *``, which is defined as:

::

   typedef struct tree_node
   {
      const char *word;
      struct tree_node *left;
      struct tree_node *right;
   } tree_node;

Lines 2-11 of DFS are getting data out of the current tree node and getting
ready to do the actual search; lines 12-25 are the actual depth-first search.
Lines 2-4 of our DFS function get the word, left and right fields out of the
current node and store them in Python variables. Since root_word_ptr is a
pointer to our word, and we want the actual word, line 5 calls GetSummary() to
get a string containing the value out of the pointer. Since GetSummary() adds
quotes around its result, lines 6-11 strip surrounding quotes off the word.

Line 12 checks to see if the word in the current node is the one we are
searching for. If so, we are done, and line 13 returns the current path.
Otherwise, line 14 checks to see if we should go left (search word comes before
the current word). If we decide to go left, line 15 checks to see if the left
pointer child is NULL ("None" is the Python equivalent of NULL). If the left
pointer is NULL, then the word is not in this tree and we return an empty path
(line 16). Otherwise, we add an "L" to the end of our current path string, to
indicate we are going left (line 18), and then recurse on the left child (line
19). Lines 20-25 are the same as lines 14-19, except for going right rather
than going left.

One other note: Typing something as long as our DFS function directly into the
interpreter can be difficult, as making a single typing mistake means having to
start all over. Therefore we recommend doing as we have done: Writing your
longer, more complicated script functions in a separate file (in this case
tree_utils.py) and then importing it into your LLDB Python interpreter.


The DFS Script in Action
------------------------

At this point we are ready to use the DFS function to see if the word "Romeo"
is in our tree or not. To actually use it in LLDB on our dictionary program,
you would do something like this:

::

   % lldb
   (lldb) process attach -n "dictionary"
   Architecture set to: x86_64.
   Process 521 stopped
   * thread #1: tid = 0x2c03, 0x00007fff86c8bea0 libSystem.B.dylib`read$NOCANCEL + 8, stop reason = signal SIGSTOP
   frame #0: 0x00007fff86c8bea0 libSystem.B.dylib`read$NOCANCEL + 8
   (lldb) breakpoint set -n find_word
   Breakpoint created: 1: name = 'find_word', locations = 1, resolved = 1
   (lldb) continue
   Process 521 resuming
   Process 521 stopped
   * thread #1: tid = 0x2c03, 0x0000000100001830 dictionary`find_word + 16
   at dictionary.c:105, stop reason = breakpoint 1.1
   frame #0: 0x0000000100001830 dictionary`find_word + 16 at dictionary.c:105
   102 int
   103 find_word (tree_node *dictionary, char *word)
   104 {
   -> 105 if (!word || !dictionary)
   106 return 0;
   107
   108 int compare_value = strcmp (word, dictionary->word);
   (lldb) script
   Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
   >>> import tree_utils
   >>> root = lldb.frame.FindVariable ("dictionary")
   >>> current_path = ""
   >>> path = tree_utils.DFS (root, "Romeo", current_path)
   >>> print path
   LLRRL
   >>> ^D
   (lldb)

The first bit of code above shows starting lldb, attaching to the dictionary
program, and getting to the find_word function in LLDB. The interesting part
(as far as this example is concerned) begins when we enter the script command
and drop into the embedded interactive Python interpreter. We will go over this
Python code line by line. The first line

::

   import tree_utils


imports the file where we wrote our DFS function, tree_utils.py, into Python.
Notice that to import the file we leave off the ".py" extension. We can now
call any function in that file, giving it the prefix "tree_utils.", so that
Python knows where to look for the function. The line

::

   root = lldb.frame.FindVariable ("dictionary")


gets our program variable "dictionary" (which contains the binary search tree)
and puts it into the Python variable "root". See Accessing & Manipulating
Program Variables in Python above for more details about how this works. The
next line is

::

   current_path = ""

This line initializes the current_path from the root of the tree to our current
node. Since we are starting at the root of the tree, our current path starts as
an empty string. As we go right and left through the tree, the DFS function
will append an 'R' or an 'L' to the current path, as appropriate. The line

::

   path = tree_utils.DFS (root, "Romeo", current_path)

calls our DFS function (prefixing it with the module name so that Python can
find it). We pass in our binary tree stored in the variable root, the word we
are searching for, and our current path. We assign whatever path the DFS
function returns to the Python variable path.

Finally, we want to see if the word was found or not, and if so we want to see
the path through the tree to the word. So we do

::

   print path

From this we can see that the word "Romeo" was indeed found in the tree, and
the path from the root of the tree to the node containing "Romeo" is
left-left-right-right-left.

Using Breakpoint Command Scripts
--------------------------------

We are halfway to figuring out what the problem is. We know the word we are
looking for is in the binary tree, and we know exactly where it is in the
binary tree. Now we need to figure out why our binary search algorithm is not
finding the word. We will do this using breakpoint command scripts.

The idea is as follows. The binary search algorithm has two main decision
points: the decision to follow the right branch; and, the decision to follow
the left branch. We will set a breakpoint at each of these decision points, and
attach a Python breakpoint command script to each breakpoint. The breakpoint
commands will use the global path Python variable that we got from our DFS
function. Each time one of these decision breakpoints is hit, the script will
compare the actual decision with the decision the front of the path variable
says should be made (the first character of the path). If the actual decision
and the path agree, then the front character is stripped off the path, and
execution is resumed. In this case the user never even sees the breakpoint
being hit. But if the decision differs from what the path says it should be,
then the script prints out a message and does NOT resume execution, leaving the
user sitting at the first point where a wrong decision is being made.

Python Breakpoint Command Scripts Are Not What They Seem
--------------------------------------------------------

What do we mean by that? When you enter a Python breakpoint command in LLDB, it
appears that you are entering one or more plain lines of Python. BUT LLDB then
takes what you entered and wraps it into a Python FUNCTION (just like using the
"def" Python command). It automatically gives the function an obscure, unique,
hard-to-stumble-across function name, and gives it two parameters: frame and
bp_loc. When the breakpoint gets hit, LLDB wraps up the frame object where the
breakpoint was hit, and the breakpoint location object for the breakpoint that
was hit, and puts them into Python variables for you. It then calls the Python
function that was created for the breakpoint command, and passes in the frame
and breakpoint location objects.

So, being practical, what does this mean for you when you write your Python
breakpoint commands? It means that there are two things you need to keep in
mind: 1. If you want to access any Python variables created outside your
script, you must declare such variables to be global. If you do not declare
them as global, then the Python function will treat them as local variables,
and you will get unexpected behavior. 2. All Python breakpoint command scripts
automatically have a frame and a bp_loc variable. The variables are pre-loaded
by LLDB with the correct context for the breakpoint. You do not have to use
these variables, but they are there if you want them.

The Decision Point Breakpoint Commands
--------------------------------------

This is what the Python breakpoint command script would look like for the
decision to go right:

::

   global path
   if path[0] == 'R':
      path = path[1:]
      thread = frame.GetThread()
      process = thread.GetProcess()
      process.Continue()
   else:
      print "Here is the problem; going right, should go left!"
   Just as a reminder, LLDB is going to take this script and wrap it up in a function, like this:


   def some_unique_and_obscure_function_name (frame, bp_loc):
      global path
      if path[0] == 'R':
         path = path[1:]
         thread = frame.GetThread()
         process = thread.GetProcess()
         process.Continue()
      else:
         print "Here is the problem; going right, should go left!"

LLDB will call the function, passing in the correct frame and breakpoint
location whenever the breakpoint gets hit. There are several things to notice
about this function. The first one is that we are accessing and updating a
piece of state (the path variable), and actually conditioning our behavior
based upon this variable. Since the variable was defined outside of our script
(and therefore outside of the corresponding function) we need to tell Python
that we are accessing a global variable. That is what the first line of the
script does. Next we check where the path says we should go and compare it to
our decision (recall that we are at the breakpoint for the decision to go
right). If the path agrees with our decision, then we strip the first character
off of the path.

Since the decision matched the path, we want to resume execution. To do this we
make use of the frame parameter that LLDB guarantees will be there for us. We
use LLDB API functions to get the current thread from the current frame, and
then to get the process from the thread. Once we have the process, we tell it
to resume execution (using the Continue() API function).

If the decision to go right does not agree with the path, then we do not resume
execution. We allow the breakpoint to remain stopped (by doing nothing), and we
print an informational message telling the user we have found the problem, and
what the problem is.

Actually Using The Breakpoint Commands
--------------------------------------

Now we will look at what happens when we actually use these breakpoint commands
on our program. Doing a source list -n find_word shows us the function
containing our two decision points. Looking at the code below, we see that we
want to set our breakpoints on lines 113 and 115:

::

   (lldb) source list -n find_word
   File: /Volumes/Data/HD2/carolinetice/Desktop/LLDB-Web-Examples/dictionary.c.
   101
   102 int
   103 find_word (tree_node *dictionary, char *word)
   104 {
   105   if (!word || !dictionary)
   106     return 0;
   107
   108   int compare_value = strcmp (word, dictionary->word);
   109
   110   if (compare_value == 0)
   111     return 1;
   112   else if (compare_value < 0)
   113     return find_word (dictionary->left, word);
   114   else
   115     return find_word (dictionary->right, word);
   116 }
   117


So, we set our breakpoints, enter our breakpoint command scripts, and see what happens:

::

   (lldb) breakpoint set -l 113
   Breakpoint created: 2: file ='dictionary.c', line = 113, locations = 1, resolved = 1
   (lldb) breakpoint set -l 115
   Breakpoint created: 3: file ='dictionary.c', line = 115, locations = 1, resolved = 1
   (lldb) breakpoint command add -s python 2
   Enter your Python command(s). Type 'DONE' to end.
   > global path
   > if (path[0] == 'L'):
   >     path = path[1:]
   >     thread = frame.GetThread()
   >     process = thread.GetProcess()
   >     process.Continue()
   > else:
   >     print "Here is the problem. Going left, should go right!"
   > DONE
   (lldb) breakpoint command add -s python 3
   Enter your Python command(s). Type 'DONE' to end.
   > global path
   > if (path[0] == 'R'):
   >     path = path[1:]
   >     thread = frame.GetThread()
   >     process = thread.GetProcess()
   >     process.Continue()
   > else:
   >     print "Here is the problem. Going right, should go left!"
   > DONE
   (lldb) continue
   Process 696 resuming
   Here is the problem. Going right, should go left!
   Process 696 stopped
   * thread #1: tid = 0x2d03, 0x000000010000189f dictionary`find_word + 127 at dictionary.c:115, stop reason = breakpoint 3.1
   frame #0: 0x000000010000189f dictionary`find_word + 127 at dictionary.c:115
      112   else if (compare_value < 0)
      113     return find_word (dictionary->left, word);
      114   else
   -> 115     return find_word (dictionary->right, word);
      116 }
      117
      118 void
   (lldb)


After setting our breakpoints, adding our breakpoint commands and continuing,
we run for a little bit and then hit one of our breakpoints, printing out the
error message from the breakpoint command. Apparently at this point in the
tree, our search algorithm decided to go right, but our path says the node we
want is to the left. Examining the word at the node where we stopped, and our
search word, we see:

::

   (lldb) expr dictionary->word
   (const char *) $1 = 0x0000000100100080 "dramatis"
   (lldb) expr word
   (char *) $2 = 0x00007fff5fbff108 "romeo"

So the word at our current node is "dramatis", and the word we are searching
for is "romeo". "romeo" comes after "dramatis" alphabetically, so it seems like
going right would be the correct decision. Let's ask Python what it thinks the
path from the current node to our word is:

::

   (lldb) script print path
   LLRRL

According to Python we need to go left-left-right-right-left from our current
node to find the word we are looking for. Let's double check our tree, and see
what word it has at that node:

::

   (lldb) expr dictionary->left->left->right->right->left->word
   (const char *) $4 = 0x0000000100100880 "Romeo"

So the word we are searching for is "romeo" and the word at our DFS location is
"Romeo". Aha! One is uppercase and the other is lowercase: We seem to have a
case conversion problem somewhere in our program (we do).

This is the end of our example on how you might use Python scripting in LLDB to
help you find bugs in your program.

Source Files for The Example
----------------------------

The complete code for the Dictionary program (with case-conversion bug), the
DFS function and other Python script examples (tree_utils.py) used for this
example are available below.

tree_utils.py - Example Python functions using LLDB's API, including DFS

::

   """
   # ===-- tree_utils.py ---------------------------------------*- Python -*-===//
   #
   #                     The LLVM Compiler Infrastructure
   #
   # This file is distributed under the University of Illinois Open Source
   # License. See LICENSE.TXT for details.
   #
   # ===---------------------------------------------------------------------===//

   tree_utils.py  - A set of functions for examining binary
   search trees, based on the example search tree defined in
   dictionary.c.  These functions contain calls to LLDB API
   functions, and assume that the LLDB Python module has been
   imported.

   For a thorough explanation of how the DFS function works, and
   for more information about dictionary.c go to
   http://lldb.llvm.org/scripting.html
   """


   def DFS(root, word, cur_path):
      """
      Recursively traverse a binary search tree containing
      words sorted alphabetically, searching for a particular
      word in the tree.  Also maintains a string representing
      the path from the root of the tree to the current node.
      If the word is found in the tree, return the path string.
      Otherwise return an empty string.

      This function assumes the binary search tree is
      the one defined in dictionary.c  It uses LLDB API
      functions to examine and traverse the tree nodes.
      """

      # Get pointer field values out of node 'root'

      root_word_ptr = root.GetChildMemberWithName("word")
      left_child_ptr = root.GetChildMemberWithName("left")
      right_child_ptr = root.GetChildMemberWithName("right")

      # Get the word out of the word pointer and strip off
      # surrounding quotes (added by call to GetSummary).

      root_word = root_word_ptr.GetSummary()
      end = len(root_word) - 1
      if root_word[0] == '"' and root_word[end] == '"':
         root_word = root_word[1:end]
      end = len(root_word) - 1
      if root_word[0] == '\'' and root_word[end] == '\'':
         root_word = root_word[1:end]

      # Main depth first search

      if root_word == word:
         return cur_path
      elif word < root_word:

         # Check to see if left child is NULL

         if left_child_ptr.GetValue() is None:
               return ""
         else:
               cur_path = cur_path + "L"
               return DFS(left_child_ptr, word, cur_path)
      else:

         # Check to see if right child is NULL

         if right_child_ptr.GetValue() is None:
               return ""
         else:
               cur_path = cur_path + "R"
               return DFS(right_child_ptr, word, cur_path)


   def tree_size(root):
      """
      Recursively traverse a binary search tree, counting
      the nodes in the tree.  Returns the final count.

      This function assumes the binary search tree is
      the one defined in dictionary.c  It uses LLDB API
      functions to examine and traverse the tree nodes.
      """
      if (root.GetValue is None):
         return 0

      if (int(root.GetValue(), 16) == 0):
         return 0

      left_size = tree_size(root.GetChildAtIndex(1))
      right_size = tree_size(root.GetChildAtIndex(2))

      total_size = left_size + right_size + 1
      return total_size


   def print_tree(root):
      """
      Recursively traverse a binary search tree, printing out
      the words at the nodes in alphabetical order (the
      search order for the binary tree).

      This function assumes the binary search tree is
      the one defined in dictionary.c  It uses LLDB API
      functions to examine and traverse the tree nodes.
      """
      if (root.GetChildAtIndex(1).GetValue() is not None) and (
               int(root.GetChildAtIndex(1).GetValue(), 16) != 0):
         print_tree(root.GetChildAtIndex(1))

      print root.GetChildAtIndex(0).GetSummary()

      if (root.GetChildAtIndex(2).GetValue() is not None) and (
               int(root.GetChildAtIndex(2).GetValue(), 16) != 0):
         print_tree(root.GetChildAtIndex(2))


dictionary.c - Sample dictionary program, with bug

::

   //===-- dictionary.c ---------------------------------------------*- C -*-===//
   //
   //                     The LLVM Compiler Infrastructure
   //
   // This file is distributed under the University of Illinois Open Source
   // License. See LICENSE.TXT for details.
   //
   //===---------------------------------------------------------------------===//
   #include <ctype.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>

   typedef struct tree_node {
   const char *word;
   struct tree_node *left;
   struct tree_node *right;
   } tree_node;

   /* Given a char*, returns a substring that starts at the first
      alphabet character and ends at the last alphabet character, i.e. it
      strips off beginning or ending quotes, punctuation, etc. */

   char *strip(char **word) {
   char *start = *word;
   int len = strlen(start);
   char *end = start + len - 1;

   while ((start < end) && (!isalpha(start[0])))
      start++;

   while ((end > start) && (!isalpha(end[0])))
      end--;

   if (start > end)
      return NULL;

   end[1] = '\0';
   *word = start;

   return start;
   }

   /* Given a binary search tree (sorted alphabetically by the word at
      each node), and a new word, inserts the word at the appropriate
      place in the tree.  */

   void insert(tree_node *root, char *word) {
   if (root == NULL)
      return;

   int compare_value = strcmp(word, root->word);

   if (compare_value == 0)
      return;

   if (compare_value < 0) {
      if (root->left != NULL)
         insert(root->left, word);
      else {
         tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
         new_node->word = strdup(word);
         new_node->left = NULL;
         new_node->right = NULL;
         root->left = new_node;
      }
   } else {
      if (root->right != NULL)
         insert(root->right, word);
      else {
         tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
         new_node->word = strdup(word);
         new_node->left = NULL;
         new_node->right = NULL;
         root->right = new_node;
      }
   }
   }

   /* Read in a text file and storea all the words from the file in a
      binary search tree.  */

   void populate_dictionary(tree_node **dictionary, char *filename) {
   FILE *in_file;
   char word[1024];

   in_file = fopen(filename, "r");
   if (in_file) {
      while (fscanf(in_file, "%s", word) == 1) {
         char *new_word = (strdup(word));
         new_word = strip(&new_word);
         if (*dictionary == NULL) {
         tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
         new_node->word = new_word;
         new_node->left = NULL;
         new_node->right = NULL;
         *dictionary = new_node;
         } else
         insert(*dictionary, new_word);
      }
   }
   }

   /* Given a binary search tree and a word, search for the word
      in the binary search tree.  */

   int find_word(tree_node *dictionary, char *word) {
   if (!word || !dictionary)
      return 0;

   int compare_value = strcmp(word, dictionary->word);

   if (compare_value == 0)
      return 1;
   else if (compare_value < 0)
      return find_word(dictionary->left, word);
   else
      return find_word(dictionary->right, word);
   }

   /* Print out the words in the binary search tree, in sorted order.  */

   void print_tree(tree_node *dictionary) {
   if (!dictionary)
      return;

   if (dictionary->left)
      print_tree(dictionary->left);

   printf("%s\n", dictionary->word);

   if (dictionary->right)
      print_tree(dictionary->right);
   }

   int main(int argc, char **argv) {
   tree_node *dictionary = NULL;
   char buffer[1024];
   char *filename;
   int done = 0;

   if (argc == 2)
      filename = argv[1];

   if (!filename)
      return -1;

   populate_dictionary(&dictionary, filename);
   fprintf(stdout, "Dictionary loaded.\nEnter search word: ");
   while (!done && fgets(buffer, sizeof(buffer), stdin)) {
      char *word = buffer;
      int len = strlen(word);
      int i;

      for (i = 0; i < len; ++i)
         word[i] = tolower(word[i]);

      if ((len > 0) && (word[len - 1] == '\n')) {
         word[len - 1] = '\0';
         len = len - 1;
      }

      if (find_word(dictionary, word))
         fprintf(stdout, "Yes!\n");
      else
         fprintf(stdout, "No!\n");

      fprintf(stdout, "Enter search word: ");
   }

   fprintf(stdout, "\n");
   return 0;
   }


The text for "Romeo and Juliet" can be obtained from the Gutenberg Project
(http://www.gutenberg.org).

