\documentclass[11pt]{article}
\usepackage[left=1in,right=1in,top=0.75in,bottom=0.75in]{geometry}
\usepackage[svgnames]{xcolor}
\usepackage[colorlinks,urlcolor=DarkRed]{hyperref}
\usepackage{url}
\usepackage{upquote}
\usepackage{fancyvrb}
\usepackage{textcomp}

\pagestyle{myheadings}
\markright{MAT 4370: Programming Assignment 11}

\begin{document}
\thispagestyle{empty}
\begin{center}
{\Large  MAT 4370: Programming Assignment 11}\\
Due: Monday, April 1
\end{center}


\subsection*{The Big Picture}
Your task is to produce a software utility modeled after the Unix {\tt
  uniq} program.  Your program doesn't need to do everything the Unix
utility does --- you will end up with a ``poor man's version,'' which
we will name {\tt pmuniq}.  Here's what I hope you will learn by completing
this exercise:

\begin{itemize}

\item How to process command-line arguments.

To process command-line arguments, your program will use the \verb!getopt()!
function found in the Standard C Library.  Examples of how to use this function
may be found on the course website.

\item How to use the C \verb!struct!.

You will also be asked to use C's structure type to summarize the
command-line arguments given to your program.  See Chapter~16 of our textbook for more
information about the \verb!struct! data type.

\item How C programs can be subdivided into separate compilation
  units.

You are already familiar with this idea; completing this exercise will provide
reinforcement.

\item Appreciate how to validate command-line arguments and perform
  essential ``sanity tests.''

Users make mistakes.  When we implement utilities, we must adopt the point of
view that our program might be given incorrect inputs.  Planning for
the validation of command-line arguments takes a conscious effort.
\end{itemize}

\subsection*{Requirements}

\subsubsection*{Requirement 1: Syntax}
The syntax for your program is as follows:

\begin{quote}
\verb!pmuniq [ -c | -d | -u ] [ inputfile ]!
\end{quote}
The square brackets in this syntax show optional components and the
vertical bar can be read as ``or.''  Here are some legal ways to
invoke this program:
\begin{quote}
\begin{verbatim}
pmuniq
pmuniq -c
pmuniq -d
pmuniq -u
pmuniq myfile
pmuniq -c myfile
pmuniq -c -c -c myfile
\end{verbatim}
\end{quote}
The first few examples do not specify an input file.  For these
situations, \verb!pmuniq! should assume the ``standard input'' file is
to be processed. The meaning of the three optional switches is
identical to the Unix \verb!uniq! command.

The last example is a little bit silly, but it should not be
considered an error.  It's simply asking for the \verb!-c! option in a
redundant way.

\newpage
There are a variety of ways to incorrectly specify an execution of
this program, including these:
\begin{quote}
\begin{verbatim}
pmuniq -d -c myfile
pmuniq -x myfile
pmuniq -c myfile anotherfile
pmuniq missing
\end{verbatim}
\end{quote}
(In the last example, assume the file \verb!missing! does not exist.)
Your program will need to process the given command-line arguments and
validate them to see if they are correct.  Ensure that all error
messages are written to the ``standard error'' file.  When in doubt as
to what an error message should look like,
follow the pattern of errors given by \verb!uniq!.


\subsubsection*{Requirement 2: Memory Efficiency}
Lines in a text file can be arbitrarily long.  Therefore, use the
\verb!read_line()! function from the previous assignment.  
However, your program may \textbf{not}
store more than a small number of lines --- do not use an array of
strings and do not use \verb!read_lines()!.  Since \verb!pmuniq! only
needs to check for adjacent lines, it would be very wasteful of memory
to store the entire contents of the file in memory.

Your program should have no memory leaks. You will need to keep this
in mind as you design your program.  Use Valgrind during your testing.

\subsubsection*{Requirement 3: Modularity}
Your program should be subdivided into files, as follows:
\begin{center}
\begin{tabular}{ll}
 \verb!Makefile! & minimum targets: \verb!pmuniq! and \verb!clean!\\
 \verb!util.h! and \verb!util.c! & as in assignment 10\\
 \verb!arg.h! and \verb!arg.c! & for argument processing\\
 \verb!pmuniq.c!&main program and possible support functions
\end{tabular}
\end{center}

\subsection*{Processing Command-Line Arguments}
For a correct invocation of \verb!pmuniq!, there are two important
facts --- the name of the input file and the requested option, if any.
This information is to be stored in a variable of type 
\verb!struct args_t!, declared as follows:
\begin{quote}
\begin{verbatim}
struct args_t{
    char option;       
    char *inputFile;
};
\end{verbatim}
\end{quote}
Observe the trailing semicolon above!

If one of the legal options was given on the command line, 
\verb!option! will store that letter.  If no options were
given, then we can use any other letter, such as \verb!x! to indicate
this.
Similarly, \verb!inputFile! is used to store the name of the desired
input file, as given on the command line.  If no input file was given,
use \verb!NULL! to indicate this fact.

Include a function, \verb!process_args()!, which will parse the
command-line arguments, check for usage errors, and fill in the two members in an
\verb!args_t! structure.  The prototype for this function is:
\begin{quote}
\verb!void process_args(int argc, char *argv[ ], struct args_t *argument);!
\end{quote}
If errors are detected, issue an appropriate message and terminate the program.
The files \verb!arg.h! and \verb!arg.c! will hold the relevant definitions
for argument-related processing.

\subsection*{Desired Results}
As mentioned earlier, \verb!pmuniq! should act like \verb!uniq! in
many respects.  To get a better sense of what \verb!uniq! does, first
take a look at its manual page.  Then consider the following simple
\verb!testfile!:
\begin{quote}
\begin{verbatim}
alpha
beta
beta
beta
gamma
delta
delta
\end{verbatim} 
\end{quote}
Create a file with this content, then experiment with the following
commands:
\begin{quote}
\begin{verbatim}
uniq testfile
uniq -c testfile
uniq -d testfile
uniq -u testfile
\end{verbatim}
\end{quote}

\subsection*{Incremental Development and Advice}
\begin{itemize}
\item Respect the problem.  Although it is relatively ``easy,'' if you
  wait until the night before it is due, you might be unpleasantly
  surprised.  As I'm sure you know, computer programming is often the
  source of such surprises --- syntax errors, incorrect behavior, and
  all types of peculiar problems.

\item Your first steps should not involve writing C code.  Instead,
  step back and think about what steps are needed to get the desired
  output. Sketch a solution using pseudo-code, making use of
  higher-level thinking.

\item  Work in small sections.  Identify something much smaller than the
final result and work on just that much.  You could, for example,
ignore the command-line processing at first and just ``hard-code'' the
file name and option to use. Alternately, you may choose to focus on
just the command-line processing aspect, ignoring how to determine the unique
lines.  You may find it
helpful to build small ``throw-away'' programs which allow you to
experiment with \verb!getopt()! and C's \verb!struct! type.

\end{itemize} 

\subsection*{What to Submit}
Before submitting your work, ask yourself these questions:
\begin{itemize}
 \item Does \verb!make clean! put your directory in a pristine state?
   (In other words, only source code remains?)

 \item Does \verb!make pmuniq! compile (without warnings) all the
   required components?

 \item Does Valgrind claim that your program is free of memory leaks?
 \end{itemize}
 If so, put all the required files in a directory named \verb!hw11! and
submit in the usual manner.



\end{document}
