CIS-3012 Homework #4: PipeWord

Due: Friday, March 31, 2017

This assignment gives you an opportunity to use C++'s OOP features in the context of a larger program.

  1. Be sure you are fully up to date with the source code of the Y editor. To clone the full source of Y, along with the two supporting projects it requires, use commands such as:

            $ git clone Spica
            $ git clone Scr
            $ git clone Y

    Be mindful of the case used for the names. The build control files depend on these names spelled in exactly this way.

    If you already have the source code cloned, go into each folder and do:

            $ git pull

    This ensures you have the latest version. Next execute the following commands, in this order, to build the supporting projects and then Y itself:

            $ cd Spica/Cpp
            $ make
            $ cd ../../Scr
            $ make
            $ cd ../Y/src
            $ make
  2. The purpose of this assignment is to add a feature to Y so that it can run arbitrary processes and then execute the Y macros produced by those processes. Recall that Y continuously executes "macro words" that it obtains from some kind of word source.

    Start by modifying WordSource.hpp and WordSource.cpp to add a class PipeWord that is derived from WordSource. The constructor of PipeWord should take a string that it will interpret to be a command (such as you might type at a shell prompt). It should then "open" the command for reading using the library popen function. See the manual page for popen for more information. Class PipeWord also needs to override get and unget since they are pure virtual methods in the base class. However, it should be able to just inherit get_word. See the implementation of FileWord for inspiration.

  3. Once PipeWord is ready it is now necessary to hook it into Y's execution engine so it can be used. Start by creating a command function that can be used to execute processes. In the file command_e.cpp add a function such as:

            bool execute_process_command( );

    The logic can be quite similar to that of execute_file_command except that it should call a function start_macro_process.

  4. Add the function start_macro_process to the file macro_stack.cpp in a manner similar to the way start_macro_file is implemented.

  5. Next it is necessary to associate a command name with the command function you just implemented. In command_table.cpp add an entry that associates the name "execute_process" with your implementation function.

  6. At this point one might want to associate a keystroke with the newly created command so that users can invoke the command by typing some appropriate key combination. However, it is not necessary to do this because Y has a feature that allows users to enter arbitrary macro text at any time. Thus you are now ready to try the new feature.

    You will need a program that generates Y macro text. One simple possibility would be to use the standard cat program on a text file. This is a bit unsatisfying, however, because Y already has a feature that allows you to execute macro text stored in a file. Instead consider the following Perl program:

            print "\"Hello, Macro Processes!\"" . " add_text";

    The dot operator is Perl's string concatenation operator. Save this program to and use a command such as:

            $ chmod 755

    to make it executable. If you run it at the prompt it should output:

            "Hello, Macro Processes!" add_text

    Imagine that this program computes the macro text in some complex way. Now run Y on a scratch file such as afile.txt. Inside Y use 'Ctrl+A m' (this is Ctrl+A followed by m) to open a box for entering arbitrary macro commands. Try running:

            "" execute_process

    If everything works as desired the output of the Perl program should be executed by Y causing "Hello, Macro Processes!" to be added to the current file. Use 'Ctrl+A q' to exit Y without saving any files.

Zip together the files where you made significant changes and submit them to Moodle.

Last Revised: 2017-03-24
© Copyright 2017 by Peter C. Chapin <>