UWA Logo Computer Science & Software Engineering
C Programming (CITS1210) - Project 2
   Faculty Home  |  CSSE Home  |  csentry  |  CITS1210  |  help1210

Document version number: 1.3.
Please check the CITS1210 web-site to ensure that you have the latest version.

Project 2: mymake

(thanks to Chris McDonald for the idea)
Submission deadline: 4pm, Friday 23 October 2009

Clarifications about the project description and requirements.

This is the second programming project for CITS1210: C Programming. This project is worth 25% of your overall mark for the unit. This project is to be completed in pairs (teams of two).

You should construct an ISO-C99 program containing your solution to the following problem. You must submit your program electronically using the cssubmit facility, available via the URL: https://secure.csse.uwa.edu.au/run/cssubmit. No other method of submission is allowed.

You are expected to have read and understood the CS&SE Policy on Plagiarism. In accordance with this policy, you may discuss with other students the general principles required to understand this project, but the work you submit must be the result of your own team's effort.

You must submit your project before the submission deadline above. The penalty for late submission is discussed in the unit outline.


The Problem

The make program is a powerful utility for automatically rebuilding out-of-date components based on a set of rules that define dependencies between files. The aim of this project is create your own version of the make program called mymake, that will read the specification of a set of rules from a mymakefile and automatically rebuild out-of-date files as required.

make operates over a series of rules, each rule defining a dependency relationship between a target file and a list of zero or more dependency files. When a target file is deemed to be out-of-date, make executes the list of zero or more actions associated with the target in an attempt to rebuild it (we say attempt, as there is no requirement that an action must actually rebuild the target). Recall, the basic semantics of make are:

if (the target file does not exist) or
if (any dependency file on which a certain target file depends)
       i) does not exist, or
      ii) is more recent than the target file
then
      attempt to create an up-to-date version of the target file
      by executing all associated actions for the target file
The make program operates recursively, checking whether dependencies of a target should first be rebuilt before rebuilding the target file. You must replicate this behaviour in your mymake program.

Rules in a mymakefile take the following form:

target : dependency1 dependency2 ...
	action1
	action2
	...

where the target is separated from the list of dependencies with a : character, dependencies are separated by whitespace (space or tab) characters, and actions are listed on separate lines. Note that there need not be any whitespace between the target, the : separator, and the list of dependencies, or there may be multiple whitespace characters separating these fields. Recall, either or both of the list of dependencies or actions may be empty.

For the standard part of the project, we constrain the target and dependency file names such that they may only consist of alphanumeric characters or the following punctuation characters: _.#!~. That is, any other character in a target or dependency name is deemed illegal and should generate an error.

Different rules are separated by blank (empty) lines or lines containing only whitespace (space or tab) characters. Comments are also allowed in a mymakefile - they are denoted by lines commencing with a # character as the first non-whitespace character on the line. Leading and trailing whitespace can appear on any line and should be ignored.

With no command-line arguments, mymake will process the first target listed in the mymakefile (called the default target), checking whether this default target needs to be updated or not. If the default target does not exist, or if any of its dependencies do not exist or are newer than the target file, mymake will perform the corresponding actions associated with the rule in an attempt to rebuild the target file. However, before mymake performs any of these actions, it first determines if any of the dependencies have an associated rule in the mymakefile, and if so, checks whether that dependency should first be rebuilt using the same semantics as above. Note that a dependency that does not exist and has no associated rule in the mymakefile generates an error.

When presented with command-line arguments, mymake behaves similarly, except that instead of the using the default target, mymake uses each command-line argument in turn as the target to check.

mymake will also accept command-line switches that change the behaviour of how the program behaves. An explanation of each of the command-line switches follows:

-f By default, mymake will attempt to read rules from a file called mymakefile in the current directory. The -f switch allows the user to provide the name of another mymakefile to read.
-n By default, mymake will determine which targets need to be rebuilt, displaying then executing the corresponding actions that need to be undertaken. The -n switch suppresses the actual execution of the action strings.
-p By default, mymake silently reads a mymakefile without reporting any diagnostic messages before processing the targets that need to be rebuilt. The -p switch requests that mymake prints the rules in a human-readable form prior to processing targets.
-s By default, mymake will determine which targets need to be rebuilt, displaying then executing the corresponding actions that need to be undertaken. The -s switch suppresses the displaying of the action strings before execution.
-v By default, the output of mymake is minimalistic, displaying just the necessary actions undertaken to rebuild out-of-date target files. The -v switch requests that mymake be more verbose in its output, detailing the rationale for each of the decisions it makes.

For the standard project, we will assume mymakefiles do not contain user-defined or automatic variables, do not allow lines to be split across multiple lines, nor allow any form of wildcards in either the target or dependency strings. That is, all target and dependency strings must refer to concrete filenames and hence cannot include any wildcard characters. We will also assume that a mymakefile does not contain any circular dependencies (dependencies that create loops between one or more targets), except for rules that directly depend on itself.

One possible extension to this problem is detailed in the document Advanced Functionality. Note that you do not need to complete these advanced tasks in order to obtain full marks (100%) for the project.

A sample solution has been provided to assist you in completing this project. Submissions that fail to replicate the exact behaviour of this sample solution precisely, including the format of the output, will be penalised.


Provided Files

A number of files have been provided to assist you in completing the project:

  1. mymake.h - a template ISO-C99 header file that contains all the constants (#defines) and structure definitions that you must use in your program. Make sure that you understand them fully before you start, noting that you cannot change them.
  2. template.c - a template ISO-C99 code file that contains the (very) start of a solution to the project. This template file provides function "stubs" for three functions that you must complete. While you are free to add your own additional functions, you must meet the specifications of these three required functions precisely, including the name and type of each function specified in the template file. This means that under no circumstances can you change how one of these function behaves. Note that you need not write all your code for your solution in one file. Indeed, you will be assessed on how you structure your program, including the modularisation of your solution across multiple source files.
  3. mymakefile - a sample mymakefile that can be used in testing your solution to the project.
  4. mymake (execute /cslinux/examples/CITS1210/WWW/Project2/mymake) - a MacOSX binary executable file that constitutes a working sample solution to the problem. You should use this executable to compare your program to the sample solution. You must replicate the behaviour of this solution (including the format of the output) precisely.
  5. mymake-linux (execute /cslinux/examples/CITS1210/WWW/Project2/mymake-linux) - the same code, compiled as a Linux binary executable file. Note that while there should be no observable differences in behaviour between the Linux version and the Macintosh version above, the Macintosh version forms the sample solution and is hence the definitive resource that should be used for comparison purposes.
  6. TestDirectory (cp -r /cslinux/examples/CITS1210/WWW/Project2/TestDirectory <loc>) - a directory containing a small C project that can be used to test the behaviour of your solution. In combination with the sample solution and provided sample mymakefile, your local copy of this directory can also be used to compare the behaviour of your solution to the sample solution.
  7. libproj2.a (link with /cslinux/examples/CITS1210/WWW/Project2/libproj2.a) - a MacOSX library archive that contains an implementation of the three required functions detailed in template.c. By linking your code with this library, you will have access to working solutions for the three required functions using the same function prototypes listed in template.c. This should help you to develop, debug, and test your own solution for the project. Assuming you have not modified the external function prototypes provided in mymake.h, to use the library, compile your program as:
    gcc -std=c99 -Wall -Werror -pedantic -o mymake <your object files> -lproj2 -L/cslinux/examples/CITS1210/WWW/Project2
    
    thus linking your code with this provided library. Since the linker only includes library functions should none of the supplied object files provide them, you can continue to compile your program this way throughout the project - the linker only including the missing sample solution functions should you not provide them in your own code.
To begin, download a copy of the provided C99 source files. Before you begin coding, think carefully about how you will design a solution to the program, the structure definitions provided for you, and the requirements of each function stub in the template file. You will not be able to make any significant progress until you completely understand the provided code. You will find this task EXTREMELY difficult unless you have a solid understanding of the underlying material and a clear design for how to build a solution to the problem.

The sample solution uses the following C99 and Unix system functions. It is strongly recommended that you first read the online documentation for each of these:

getopt, malloc, realloc, strdup, free, stat, system, fopen, fflush.

New, but trivially easy, is the system function - a function that executes a parameter string as a Unix command. Within a loop, this function can be used to execute the corresponding actions for an out-of-date target file. We will assume in this project that all actions succeed, and hence need not worry about the return results of any action string.

A sample solution has been provided to assist you in completing this project. Submissions that fail to replicate the exact behaviour of this sample solution precisely, including the format of the output, will be penalised.


Assessment

This project is worth 25% of your final mark for CITS1210: C Programming. It will be marked out of 25.

The project should be completed in pairs (teams of two).

As always, you are expected to show professionalism in your approach by making appropriate use of the features of the language, following the principles of good program design, and adhering to the programming conventions outlined in this unit. During the marking, attention will obviously be given to the correctness of your solution. However, a correct and efficient solution should not be considered as the perfect nor necessarily desirable form of solution. Preference will be given to well designed, well presented, well documented solutions that use the appropriate features of the language to complete tasks in an easy to understand and easy to follow manner. That is, do not expect to receive full marks for your program simply because it works correctly. Remember, a computer program should not only convey a message to the computer, but also to other human programmers.

Marks will be allocated for:

  1. correctness: your program must implement the specification exactly and completely,
  2. clarity: your program must be easy to understand,
  3. design: your program must be decomposed appropriately, including modularisation across multiple source files, and
  4. appropriate use of the features of the language.

As a rough estimate, marks will be awarded as follows: 15 (out of 25) marks to program correctness (i.e., how well your functions match the specification of the questions asked), and 10 (out of 25) marks to coding style (i.e. how well you have designed your solution and how well you have written the functions in terms of clarity and use of the features of the language).

Your project will be marked on the Apple Macs in Lab 2.01 of the Computer Science building. Ensure that your project is compiling and working correctly on these machines before you submit your project. No allowance will be made for projects that "work at home", but do not work on the Apple Macs in Lab 2.01.

Part marks to questions may be awarded, so if you are not able to get a function working correctly, you should still submit what you have done. However, you will be significantly penalised if:

  1. your submitted program does not compile successfully (e.g. if it contains any compilation errors), or
  2. your functions do not meet the provided specification, including the name and type of the function.

You do not need to complete the tasks detailed in the Advanced Functionality document in order to obtain full marks (100%) for the project. Those who undertake and complete significant parts of the advanced functionality tasks will have the opportunity to "recover" marks lost (deducted) in the first part of the project. As a rough estimate, completing the advanced part of the project may allow a student to recover up to 5 (out of 30) lost marks. Note: a score of >100% is not possible.

A sample solution has been provided to assist you in completing this project. Submissions that fail to replicate the exact behaviour of this sample solution precisely, including the format of the output, will be penalised.


Submission

Your submission for this project will consist of all ISO-C99 source files that constitutes your solution to the problem. You must additionally include a Makefile that successfully builds your program. Make sure you submit all ISO-C99 header (.h) and code (.c) files that you wish to be considered for assessment.

You must match the specification of the required functions precisely, including their names, parameter lists, and error conditions and messages. You will be penalised if any of your functions do not match the provided specification precisely.

Each of the ISO-C99 source files you submit should begin with the following lines:

/*
   CITS1210 Project 2
   Names: <your name> <your name>
   Student numbers: <your student number> <your student number>
   Date: <date of submission>
*/

You must submit your program electronically using the cssubmit facility, available via the URL: https://secure.csse.uwa.edu.au/run/cssubmit. No other method of submission is allowed. The cssubmit facility will give you a receipt of your submission. You should print and retain this receipt in case of any dispute.

Ensure that you submit the correct files to cssubmit. The system does not perform any checks on your submission. Submitting the wrong files may result in a mark of zero for your project. Note also that the cssubmit facility does not archive submissions and will simply overwrite any previous submission with your latest submission.

Only one team member should submit a solution to the project. Teams which make multiple submissions under different user accounts may have their submission incorrectly assessed. Ensure the names and student numbers of team members are listed at the top of your submission.

Good luck!

Submission deadline: 4pm, Friday 23 October 2009

Top of Page CRICOS Provider Code: 00126G Valid HTML 4.01 Transitional