Lab 7: CPS 6: Classes, Recursion, Scope

Introduction This lab provides practice with using classes, with recursion, and may help you find large files you can remove to ease quota problems.

Change into your cps6 directory and create a lab7 subdirectory (use mkdir lab7 ). Then change into your lab7 subdirectory and copy files by typing what's below (don't forget the trailing dot).

      cp ~ola/cps6/lab7/*  .
If you type ls you should see the following files: Makefile, subdir.cc, and usedir.cc . Use the menu-bar to invoke emacs or type emacs & to get an emacs window. You want to use the ampersand & which leaves you with control of your xterm (so you can run programs from it). Be sure to leave the emacs window up, don't quit it until you log off.

Processing Directories

Use the emacs commands C-x C-f to find/load the file usedir.cc . Then compile this command using
C-x c and type make usedir in the minibuffer. If this doesn't invoke the compile command you can always type M-x compile (that's ESCAPE-x compile).

Before running this program, type pwd to see your pathname. Then run usedir . You'll be prompted for the name of a directory. You can type a dot `` . '' for the current directory, or you can type the complete path which is similar to /afs/acpub.duke.edu/users8/ola , but the number 8 may be different and use your login instead of ola . This will print a list of all files in your directory. The program does NOT print subdirectories.

Then use C-x C-f to find/load the file subdir.cc . Compile and execute this program. Run the program and enter the name of your directory. This will print a listing of all your files and subdirectories. This can take a long time if you have many directories. You'll make a few changes to this program so that it will print the size of each file/subdirectory. If you run the program a second time it will be MUCH FASTER. This is because the file query information has been cached on the computer you're using.

Sizes of files/directories

Change the return type of the function ProcessDir from void to int . The function should return the size of all the files in the directory specified by the parameter s . In addition, the size of each individual file will be printed before the name of the file.

To do this, use the member function Size() for the DirEntry variable entry . Print the size before the name of the file:

     cout << entry.Size() << "\t" << entry.Name() << endl;

You should also define an int variable size that is initialized to 0 (define it after entry is defined in ProcessDir ). The variable size will be used to accumulate the size of all files in a given directory as well as the sizes of files in subdirectories. This value will be returned by ProcessDir .

Increment size appropriately by the size of each file before the file is printed. You must also increment size by the value of all files in each subdirectory. To do this you'll modify the recursive call as shown below.

        size += ProcessDir(s + "/" + entry.Name(),tabCount+1);

Finally, you'll need to return a value. The last statement of the function, after the if statement , should be return size . In the function main you should define an integer variable to use for the value returned by ProcessDir in main --- print this value in main .

After making these changes, compile and run your program. Use the name of your own directory as input. How big is this directory _______________? (Note: the counts may not be precisely correct, but are fairly accurate). How big is the directory /afs/acpub.duke.edu/users8/ola __________________?

If you see files that are larger than 200000 bytes you should check to see if these files are executables. If so, you should remove them since they will contribute to your quota limit. Since you can always recompile the source code to generate the executables, you don't need to keep the executables around.


Vectors/Arrays/Debugging

Copy the file usedir.cc to mydir.cc using
    cp usedir.cc mydir.cc
You'll modify the file so that each file name is placed in an array, and then printed. To do this follow the steps below (in emacs using mydir.cc ).

Run the program and enter . as the name of the directory. Then rerun the program and enter /dev as the name of the directory. What happens? Why? Now change the definition of names so that it uses a built-in array rather than a Vector

    string names[200];

Run the program again. You should get the error message:

  Segmentation fault (core dumped)
To see what's happening, you'll use a symbolic debugger. In later assignments you'll want to use the debugger more.

Warning!! The debugger gdb on the acpub machines doesn't always work properly, hopefully this will be fixed soon. If you can't run it, just skip the section below.

Using the debugger

Type gdb mydir , this will run the Gnu Debugger on the file mydir . When you get the prompt (gdb) , type: run.

When prompted for the name of the directory, enter /dev . The program will bomb/crash, but print an error message. At this point you can type where and the program should print where the error occurs. In what line of main is the error ______________________?

Notice the # signs when you typed where , they indicate how ``deep'' function calls are. Type up , this will move you ``up'' a function call. Then type print num to print the value of the variable num . You should get

    No symbol "num" in current context.
Type up again followed by print num until a value of num is printed. What is the value _______________________?

Submission

When your modified programs works, you can submit them, along with a README describing how long it took you and what your impressions of the lab are. To submit, type the command below (Replace N in lab7secN with your section number: 1, 2, 3, 4, or 5).

submit6 lab7secN README mydir.cc subdir.cc

The README file should include your name, how long you worked on the program, and anyone you received significant help from. You should also include any comments you have about the lab.

You should receive a message telling you that the programs were submitted correctly. If you get a message indicating that submit6 isn't found, you can always type the full path name:

      ~ola/bin/submit6 lab7secN README mydir.cc subdir.cc