CS253: Software Development with C++

Spring 2021

HW 2

CS253 HW2: Shell                

Changes                

The output of the last example was previously truncated.                 

Description                

For this assignment, you will write a primitive shell that will read & execute commands using functional notation, sort of like sin(x ) in math.                 

Input                

Read & execute commands from each filename argument. If no arguments are given, read & execute commands from standard input.                 

Input format                

The input will be a series of lines. Each line will consist of a number of whitespace-separated words. The first word in a line will be the command, the following words will be arguments. Ignore lines that contain no words.                 

A backslash escapes the next character, making it not special. The backslash itself does not become part of the word. For example, foo\ bar is treated as the seven-character word foo bar, S\pock\(o\) is treated as the eight-character word Spock(o), \ Kirk\ is treated as the six-character word Kirk , and Bo\nes is treated as the five-letter word Bones. The effect of a backslash as the last character of a line is undefined. Unlike C++, \n and \t are not translated into newline and tab. In the examples below, the echo program is doing that translation, not hw2.                 

( and ) are always words by themselves, even if they occur next to other text, unless escaped.                 

A non-empty input line must be of this form:

command(optional arguments)

for example:

echo(hi there)

If an input line is not of this form, produce an error message and stop the program.                 

No special shell syntax is recognized. For example, the characters #*[];'"><|&~ have no particular significance.                 

Language                

I call “(” and “)” parentheses, or parens. Some people call them brackets.                 

Executing commands                

The file ~cs253/Example/execute.cc contains this function:                 

    bool execute(vector<string> command);

It executes a command with arguments, returning true iff it succeeds. It also contains a main() that you should exclude from your program. You may copy code from this file and add it to your main.cc.                 

Of course, execute() doesn’t want those opening and closing parens. They shouldn’t be in the vector that you pass to execute(). If the input command is echo(alpha beta\ gamma delta), then the vector passed to execute() should contain:

  1. echo
  2. alpha
  3. beta gamma
  4. delta

Sample Runs                

Here are sample runs, where “%” is my prompt.

% cat CMakeLists.txt
cmake_minimum_required(VERSION 3.11)
project(hw2)

# Are we in the wrong directory?
if(CMAKE_SOURCE_DIR MATCHES "[Hh][Ww]([0-9])$")
   if(PROJECT_NAME MATCHES "[^${CMAKE_MATCH_1}]$")
      message(FATAL_ERROR "Building ${PROJECT_NAME} in ${CMAKE_SOURCE_DIR}")
   endif()
endif()

# Using -Wall is required:
add_compile_options(-Wall)

# These compile flags are highly recommended, but not required:
add_compile_options(-Wextra -Wpedantic)

# Optional super-strict mode:
add_compile_options(-fmessage-length=80 -fno-diagnostics-show-option
    -fstack-protector-all -g -O3 -std=c++17 -Walloc-zero -Walloca
    -Wctor-dtor-privacy -Wduplicated-cond -Wduplicated-branches
    -Werror -Wextra-semi -Wfatal-errors -Winit-self -Wlogical-op
    -Wold-style-cast -Wshadow -Wunused-const-variable=1
    -Wzero-as-null-pointer-constant)

# add_compile_options must be BEFORE add_executable.

# Create the executable from the source file main.cc:
add_executable(${PROJECT_NAME} main.cc)

# Create a tar file every time:
add_custom_target(${PROJECT_NAME}.tar ALL COMMAND
    tar -cf ${PROJECT_NAME}.tar *.cc CMakeLists.txt)
% cmake . && make
… cmake output appears here …
… make output appears here …
% cat data
date()
echo(Good so far.)
        echo   (   \ 1   <    2 * 3 + 177777  &\&    44    >   5   )    
echo(-e 1\)  dogs\\n2\) cats)
sync()
echo(-e supercali\\n\\t\(fragilistic\)\\n\\t\\texpialidocious)
date(+%F\ %T)
goofy(this will not work)
echo(1111111111111111)
% ./hw2 <data
Wed Feb 17 16:34:28 MST 2021
Good so far.
 1 < 2 * 3 + 177777 && 44 > 5
1) dogs
2) cats
supercali
        (fragilistic)
                expialidocious
2021-02-17 16:34:28
./hw2: can’t run: goofy(this will not work)
% cat d1
  date (  )
% cat d2
echo(Hello from d2!)
% ./hw2 d1 d2
Wed Feb 17 16:34:28 MST 2021
Hello from d2!
% echo -e ' \n\r\techo\f(\talpha\fbeta\v7667711) ' | ./hw2
alpha beta 7667711

Debugging                

If you encounter “STACK FRAME LINK OVERFLOW”, then try this:

    export STACK_FRAME_LINK_OVERRIDE=ffff-ad921d60486366258809553a3db49a4a

Requirements                

If you have any questions about the requirements, ask. In the real world, your programming tasks will almost always be vague and incompletely specified. Same here.                 

Tar file                

    cmake . && make

How to submit your work:                

In Canvas, check in the file hw2.tar to the assignment “HW2”. It’s due 10:00:00ᴘᴍ MT Saturday, with a 24-hour late period for a 25% penalty.                 

How to receive negative points:                

Turn in someone else’s work.