CS 370 Lab 1: Writing C Programs on UNIX Systems

Name: ____________________________________________________

Labs in CS370 will in general be available as web pages. Their content are subject to revision and addition up until the start of lab. Labs will in general are due (firm deadline) by the start of the following lab. So for each lab you have one week. Labs will generally support homework assignments, which count more towards your grade. Today we have 5 parts: If you already know all this stuff, you should just sail through the material until the last part, which should reuire some thought.

Part I: Accounts, UNIX Command Line and Text Editor

Most of you will be able to skip this part due to prior courses, but if you have not worked on UNIX before, please inform Dr. J and expect to spend an extra 2-4 hours on this week's lab getting familiar with UNIX.

  • Get a working account on our CS machines if you do not have one.
  • Read a book about UNIX if you do not know about basic UNIX commands.
  • You had better know a UNIX text editor pretty well by now.
  • If you do not already know about the UNIX manual page system, run "man man" to read about the man program. As you learn other UNIX tools, you have a standing order to read the "man" page on every other tool we use ("man cc", "man make", "man gdb", etc.)

    Part II: the C Compiler

    On our Linux systems "cc" and "gcc" are two different versions of the same compiler. You probably have used it before. After reading the man page for "gcc", fill in the following table with an example of the following command line options, and tell what they do:

    optionexample           does...                                                                                                         
    -c
    -g
    -l
    -o
    -E

  • You can turnin this part by printing a hard copy of the first page of the lab and filling in the blanks, or by including your answers in a plain text file.
  • If you have not compiled a C program on a UNIX system recently, copy the sample program given last class into a file named sample.c and compile and run it.

    Part III: the Make program

    Read the man page for "make" and then do the following exercises. Make a list of questions to ask me about "make" in class.

    Introduction

    Make is a program which is used to maintain, update, and regenerate related programs and files.

    Make provides a simple mechanism for maintaining the latest version of programs that result from many operations on a number of files. It is possible to tell Make the sequence of commands that create certain files, and the list of files that require other files to be current before the operations can be done. Whenever a change is made in any part of the program, the Make command will create the proper files with  minimum effort.

    You can look up the online manual pages for more information or type in your command line as:

            man make

    In the simplest case, make is executed without explicit parameters:

            make
     

    Makefile

    Make reads an input file ("makefile") that defines which files make up a program. In addition, the makefile shows the relationships between the files, which comprise a DEPENDENCY graph. Make takes responsibility for recompiling any source files that has been changed since the last time it had been compiled and also for recompiling any source file that depends on other source files that have changed. This means you no longer have to remember which files have recently changed. You don't have to recompile everything, just in case. And, once you've written in the makefile the complete (for large programs, very long) rules for compiling and linking, you don't have to remember them any more.

    make can also do other routine tasks often required in program administration. For example, make can be used to list and make backup copies for only those source files that had been changed since their last printing and backup.

    When you run make with no arguments, it searches for a file named makefile in the current directory, or if there is no file by that name then Makefile. Make has a -f option, followed by an arbitrary filename, that specifies an alternative makefile with a non-default name.

    A makefile contains the following information:

    1. Macro definitions at the beginning of the description file have the following form:

            name = string

    e.g.    CFLAGS = -O

    2. Information on file dependencies followed by executable commands
    A dependency line shows the relationship between a target file name given to the left of the colon, and the files that the target depends on, given to the right of the colon. The command line(s), also called RULES that follow the dependency line are assumed to transform the dependency files into the target file. The basic format for dependency rule is:

            target: [ dependency ...]
                                   [ command line ....]

    As shown above, the commands are grouped below the dependency line and are typed on lines that begin with a tab. Subsequent lines that start with a tab symbol are taken as the command lines that comprise the targets rule. A common error is to use space characters instead of the leading tab. Lines that start with a # are treated as comments. If make finds a makefile, it begins the dependency check with the first target entry in the file. You can also indicate the target explicitly as a parameter when calling make.
     

    A simple example of a Makefile

    # Makefile for creating an executable file from two independently compiled
    # C source files
    CFLAGS= -O -g
    CC= gcc
    try: try.o functions.o
    	$(CC) $(CFLAGS) -o try try.o functions.o
    # note: the preceding line, and all make build commands,
    # must start with a tab symbol, not spaces
    
    try.o: try.c
    	$(CC) $(CFLAGS) -c try.c
    
    functions.o: functions.c
    	$(CC) $(CFLAGS) -c functions.c
    
    clean:
    	rm try try.o functions.o
    

    The first two lines define two macros, one for compilation flags and the other the CC (Compiling Command) macro.

    When make is run on this makefile it sets its target to the first target in the Makefile - the file try.

    The executable file try depends on try.o and functions.o .The command for creating the try is

            gcc -O -g -o try try.o functions.o

    In order to complete the creation of the file try,  it will set subtargets try.o and functions.o, as described in the dependency rule. The -o option places the output in file try.  This applies regardless  to  whatever sort of output gcc is producing, whether it be an executable file, an object file, an  assembler  file or preprocessed C code. The  -g  option  produces debugging information in the operating system's native  format . GDB can  work with this debugging information. With the option  `-O'  the compiler tries to reduce code  size  and execution time. Without `-O', the compiler's goal is to reduce the cost  of  compilation  and  to make debugging produce the expected results.

    The try.o file depends on try.c and is created by the command

            gcc -O -g -c try.c

    Similarly, functions.o depends on functions.c and is created by the command

            gcc -O -g -c functions.c

    Another way to do the same is to run

            make try

    indicating the main target explicitly.

    The last two lines define a rule used to remove the executable and object files. It will work when this target is indicated explicitly:

            make clean

    Because the target clean is not mentioned in other dependency rules it can be achieved only when called explicitly. Note that in both cases make uses (by default) the same Makefile.
     

    Assignment Your "make" portion of this lab is to write the makefile specified in Homework #1. Turn it in as part of Homework #1 when you turn that in.

    1. Its 1st (default) rule builds an executable named scan
    2. Its 2nd and 3rd rules show how to build .o files from yylex.c and main.c
    3. Its 4th rule builds your .tar file, containing your complete program source code, including your .c files and your makefile.

    Part IV: Fun with GDB

    GDB is the GNU Debugger.
    1. Read the GDB manual page, and skim the web site "Debugging with GDB"
    2. Turnin (via www.cs.nmsu.edu/~jeffery/turnin.html) what GDB says for the sample buggy program:
      • consisting of main.c and tree.c
      • Compile these two files with debugging support (-g), use gdb, run the program to a coredump (gdb will say "Program received signal SIGSEGV, Segmentation fault."), and use gdb's "where" command

    Part V: Ordinary Regular Expressions

    This lab is practice with regular expressions and finite automata in order to prepare you to do the main lexical analysis assignment. Do as much as you can during the lab; when you have a solution bring it up and I will look it over. Print a hard copy of this page. Fill in the blanks. Turn it in to Dr. J along with a printed listing of the flex .l file you write for that part of the lab. Due: before next week's lab.

    1. What is the regular expression for...

    C/C++ comments
    C comments look like /* this */ and may not be nested. Make sure you pass on /** this **/, /*** this ***/ etc. C++ comments start with // and go to the end of the line.


    C/C++ character literals
    These are single quoted character constants in 'x' format, with escape characters such as \n or \003


    C string literals
    " ... " format, but consider escape characters


    Concatenated C string constants
    These are a sequences of one or more simple C string constants, separated by zero or more spaces or tabs or newlines. Example: "Hello" " Las Cruces"


    C integers
    real or integer. Real numbers do not have to start with digits; for example .5 is OK.


    C float literals?
    Integer part, decimal point, fraction part, e or E, optionally signed integer exponent, optional type suffix (f, F, l, or L). Either integer part or fraction part (not both) may be missing.


    Turning the Lab In

    1. Turnin (via the turnin.html) a GDB session working with your Homework #1. This should be when your Homework #1 is finished or almost finished.
      • Compile your Homework Assignment #1 with debugging support
      • Run gdb, and set a breakpoint in your yylex() function. Run your program up to the breakpoint.
      • Take two steps into the yylex() function, and print out the values of its local variable(s).
    2. Turnin (at http://www.cs.nmsu.edu/~jeffery/turnin.html) the output from a script(1) session for #2 and #3. Be sure you select "Lab 1" not "Homework 1" or something else on the web page.
    3. Remember, GDB is Your Friend!! In my professional opinion, your choosing to learn GDB well will pay for itself in time saved on later homework assignments, and not learning GDB might cost you your passing grade.