\chapter{Enhancements to the CDS Environment}
Part of the development of this thesis project involved enhancing the CDS
executable itself. Sourabh Niyogi '93 implemented the CDS SCHEME interpreter
in January 1991.
The installation of the SCHEME interpreter
opened the door to serious application development. 
As the convolution application and other CDS applications grew,
limitations in CDS became apparent, and improvements to CDS became
necessary. Some enhancements included the implementation of 
SCHEME primitives to manipulate the menu bar, primitives
to add barcharts and edit their attributes, mathematical
SCHEME primitives, and the removal of segmentation violations related
to the management of CDS files, SCHEME files, and using barcharts.

This chapter documents enhancements made to CDS that were necessary
to the development of the convolution application.

\section{Menu Primitives}
The menu primitives discussed in Chapter 4 were implemented in C++
and incorporated into the SCHEME interpreter. In the CDS implementation,
the interpreter is a module called {\tt CmScheme}. Primitives are then
defined as external procedures which are incorporated into the model
through a procedure called AddMethod. The procedure {\tt sjohnnyp(CmScheme*)}
is called, along with other procedures that add primitives to the 
{\tt CmScheme} object, just after the constructor of the {\tt CmScheme} module
is called during the startup of CDS. {\tt sjohnnyp()}, at the time
of this publication, registered six primitives implemented in C++
into the interpreter:

\begin{singlespace}
\begin{verbatim}
void sjohnnyp(CmScheme* s)
{
  s->AddMethod("set-barchart-resource", handle_set_barchart_resource,3);
  s->AddMethod("add-menu-pane", handle_add_menu_pane, 1);
  s->AddMethod("add-menu-item", handle_add_menu_item, 2);
  s->AddMethod("add-menu-function", handle_add_menu_function,3);
  s->AddMethod("remove-menu-function", handle_remove_menu_function,2);
  s->AddMethod("convolve", handle_convolve, 2);
}
\end{verbatim}
\end{singlespace}

The first argument to {\tt AddMethod} specifies how the method is called
from the SCHEME interpreter inside CDS. The second argument specifies the
C++ procedure which executes the primitive. The third argument is
the number of arguments that the primitive takes.

The menu primitives, {\tt (add-menu-pane)}, {\tt (add-menu-item)},
{\tt (add-menu-function)}, and {\tt(remove-menu-function)} needed
minimal amounts of code, since a C++ module called {\tt CmMenu}
already existed for CDS. The {\tt CmMenu} module had functions
like {\tt AddPane()} which automatically added panes to the menu. So the
primitives were little more than another layer on top of {\tt CmMenu.}

The problem was initially that {\tt CmMenu} was not a robust module. It
was written with the intent that it would be called at CDS startup only,
to set the menus for the entire application. This being a stable code
environment, greater robustness was not originally necessary.
But since the primitive allows the user to manipulate the menu in 
any way, it became necessary to prevent such invalid situations such
as adding multiple panes of the same name, multiple items of the
same name, etc. For a listing of the updated source code for the
{\tt CmMenu} module, see Appendix B.

Once {\tt CmMenu} became robust, the primitives could be built. The key to
them is the fact that SCHEME primitives are bound to the callback handlers
of the Motif widgets that make up the menu itself in X. The crucial
call within the {\tt add-menu-function} routine is a call to
{\tt XtAddCallback}, which binds the SCHEME action to the callback of the
menu item:
\begin{singlespace}
\begin{verbatim}
 XtAddCallback(menu->GetItem(arg[0],arg[1]), XmNactivateCallback,
                menu_callback_handler, (caddr_t) wad);
\end{verbatim}
\end{singlespace}

{\tt arg[0]} is the panename, {\tt arg[1]} is the item name, and 
{\tt GetItem} is in the {\tt CmMenu} module, and returns the corresponding
widget in the menu. \linebreak
{\tt XmNactivateCallback} identifies the callback
to be used. {\tt menu\_callback\_handler} is a C++ function that is executed
when the callback is activated. It takes the information stored in the
argument
{\tt wad}, which is the text of the SCHEME action to be executed, and executes
it in the {\tt CmScheme} module. By this mechanism, menus created can
have functions tied to them through the CDS SCHEME interpreter.

For a complete listing of the menu primitives, see Appendix B.

\section{Barchart Primitives}
CDS has plotting capabilities, built on top of the AtPlotter widget. 
The AtPlotter creates barcharts by creating a child AtBarchart widget. The problem is that CDS cannot directly
edit widgets that are children of other widgets which are CDS objects. 
Thus, a method to edit the resources of barcharts was needed, and it
would need to be forward-compatible for the day when CDS obtains
the ability to edit child widgets directly.
This was done by
implementing a primitive called {\tt set-barchart-resource} to 
specifically edit AtBarchart widget resources. {\tt set-barchart-resource}
is used just like the primitive {\tt set-resource}, except that it applies
to barcharts only.

They key to the implementation of this primitive is that the barchart
resources are explicitly type-converted from {\tt CmScheme} character strings
to the type needed for setting barchart resources (i.e. to int, float, etc...).
Since there are very
few barchart resources, this is a simple task.
The section of the {\tt set-barchart-resource} handler which 
performs the conversion follows:

\begin{singlespace}
\begin{verbatim}
 Arg args;
  if(!strcmp(arg[1], "numPoints") || !strcmp(arg[1], "position")){
    int i = atoi(arg[2]);
    XtSetArg(args, arg[1], atoi(arg[2]));
  }
  else if (!strcmp(arg[1], "shading")){
    if (!strcmp(arg[2], "True") || !strcmp(arg[2], "true"))
      XtSetArg(args, arg[1], 1);
    else XtSetArg(args, arg[1], 0);
  }
  else if(!strcmp(arg[1], "pattern")) {
    if (!strncmp(arg[2],"AtGRAY",6)){
      CmString arg2 = arg[2]; arg2 = arg2.After("AtGRAY");
      int j = atoi(arg2.Chars());
      XtSetArg(args, arg[1], atoi(arg2.Chars()));
    }
  }
  else {
    val = atof(arg[2]);
    XtSetArg(args, arg[1], &val);
  }
  XtSetValues(barchart, &args, 1);
\end{verbatim}
\end{singlespace}

A complete listing of this procedure is in Appendix B.

\section{Mathematical Primitives}
During development of this application, the need for setting the
precision of variables became apparent. Adam Feder, a class of '94
undergraduate at MIT UROPing for CDS, developed a set of five
primitives which provide truncation, rounding, and other
numerical functions. His primitive procedure
\begin{singlespace}
\begin{verbatim}
(precision exp places) - return exp with places accuracy
\end{verbatim}
\end{singlespace}
was used to format the values displayed in the sliding labels in 
Figure 3-7.

During the application's development, a procedure was defined within
SCHEME which convolved two lists of values, returning the
convolved list. The run time of the procedure was extremely slow,
too slow to provide the interactive approach to the interface
as described in Chapter 3. As a result, a {\tt convolve}
primitive was needed to perform the convolutions faster:

{\tt char* handle\_convolve(char** arg, CmScheme* s)}

A complete listing of the C++ code for this procedure can be found
in Appendix B.

\section{SCHEME Development}
The {\tt CmScheme} module was implemented by Sourabh Niyogi '93 
during January, 1991. It was an extensive module that needed 
full testing, which was provided by the convolution application.
Many small bugs were ironed out, such as the
primitives {\tt (and)}, {\tt (or)}, and {\tt (quote)}. 
This all occurred in addition to the implementation
of many primitives to aid general application development.

\section{Segmentation Violations}
As the first CDS applications began to grow in complexity, the size of
the files in which they were stored grew as well.
As CDS files grew past a certain size, CDS would seg fault while
trying to load them in.
It was found that statically-defined character buffers declared
in the parsing routines were being overwritten, leading to bad memory
addressing. The buffers were replaced using the {\tt CmString}
module, a CDS application module which dynamically handles memory
allocation for character arrays, by creating a string abstraction.

Similar problems were ironed out of the {\tt eval-file} primitive,
which was also buffering its input with character arrays that were being
overwritten.

Finally, the {\tt barchart} primitive, which plots a list onto a barchart,
was under development as well. Its code was overwriting data at times
that led to seg faults. These particular problems have been removed from 
the system.


