.sp 2
.NH 1 "CONVENTIONS & GUIDELINES FOR ALL KHOROS ROUTINES"
.XS
\s12\*(SN  CONVENTIONS & GUIDELINES FOR ALL KHOROS ROUTINES\s0
.XE
.sp
.PP
This section contains information that is common to both vroutines and 
xvroutines.  It details conventions that must be adhered for the sake
of portability and machine independence when programming in the Khoros
environment.  Variable naming conventions that should be followed when
creating a UIS file are given here, as are file naming conventions that
are followed throughout the Khoros system.  
.sp 2
.NH 2 "GUIDELINES FOR WRITING CODE"
.XS
      \*(SN  GUIDELINES FOR WRITING CODE
.XE
.sp
.PP
There are several rules that you should follow when developing new 
programs under the Khoros environment.  Following these guidelines will help
to ensure that your new program will function properly and consistently
as a new part of the Khoros system.  
.sp
\fB"Program Structure"\fP
.PP
The motivation for breaking the program into a main *.c file and a l*.c
library file is mainly to separate the functionality 
into its two component phases.  The preliminary work is done in the main *.c 
file, which includes argument and file checking.  The library file
includes the source code for executing the vroutine on the data.  
This enables the library routine to be called from different programs 
as well as from the original. 
.PP
In xvroutines, the l*.c file is used to
integrate the main driver generated by \fBconductor\fP with the files generated
by \fBghostwriter\fP.  It is not truly a "library" file in that it will
not become part of a library, will not be called by any other xvroutines,
and will not have a man3 page installed.
However, the library file for an xvroutine should still retain its name 
and the tags generated by \fBghostwriter\fP
in order to stay maintainable and consistent under the Khoros system.
.sp
\fB"Proper Driver Behavior"\fP
.PP
Main drivers of programs must call \fIkhoros_init()\fP immediately on start-up; 
the last statement should be a call to \fIkhoros_close()\fP, and failures due
to error should result in a call to \fIexit(1)\fP. 
.sp
\fB"Proper Library Routine Behavior"\fP
.PP
An important point which needs to be stated here is that the library routine 
should always be declared to return an integer. Consequently it will return 
zero (0) upon failure or one (1) upon success.
The library should be very robust; it should not not crash for any
reason.  In order to obtain this objective, all the necessary error
checking should be done in the libraries as well as their drivers.
The library should always return to the main program, whether it completed
its work successfully or unsuccessfully. That is, the library should never
contain an \fIexit()\fP statement within its instructions.
.PP
If the library routine that is being written needs to call any of the already
existing ones, the calling format should be the same as that of the
main program; that is, the calling routine should check if the
subordinate routine returns one (1) or zero (0) upon success or
failure, respectively.  
.sp
\fB"Free Memory Properly"\fP
.PP
Whenever memory is allocated for one or more pointers, they should
be freed as soon as they no longer needed. This is to minimize
the risk of running out of memory. Also, for those working with VIFF files,
the data contained in the
memory location starting with the address given by "image->imagedata",
should be released with a call to \fIfreeimage()\fP when it is changed or 
replaced by another one; for instance, in the following example, 
"image->imagedata" is replaced by a new pointer. 
.sp
\f(CW free(image->imagedata);\fP
.br
\f(CW image->imagedata = (char *) fptr;\fP
.sp
.PP
To free the entire xvimage structure, along with all associated memory, use:
.sp
\f(CW freeimage(image);\fP
.sp
\fB"No Interdependancies"\fP
.PP
Also, one should make an effort not to introduce inter-dependencies 
into library routines.  However, you are welcome (and highly encouraged!) 
to make calls from your vroutine 
to the utilities found in the \fIverror, vgparm, vmath, vrast,\fP and 
\fIvutils\fP libraries.  On the other hand, you are not encouraged
to add dspl routines that depend on ipl routines and vice versa.  
.sp
\fB"Efficiency & Modularity"\fP
.PP
Due to the necessity to perform the same operation for different image
types, one should try to use flow control that provides fast
performance. For instance, in programs like vconvert, it is better
to have \fIfor\fP loops inside the \fIswitch\fP statement 
rather than having the \fIswitch\fP
inside the \fIfor\fP loops. The reason for this is that the latter requires more
time due to the continuous breaks(jumps).
.PP
Also, if the algorithm being implemented requires a large amount of
code, modularity is one of the important issues that one should
observe. Some kind of compromise with the efficiency issues mentioned
above should be considered.  When writing a vroutine, one should make sure
that all functionality of the program is provided by the code in the library
file.
.sp
\fB"Ensuring Portability"\fP
.PP
If you make a system call to \fIsignal(sig, function)\fP, you must define
\fIfunction\fP to be of type \fIvsignal\fP, and you must have the line:
\f(CW#include "vsignal.h"\fP in order for your code to be portable.
.PP
If you make a system call to \fIwait(status)\fP or
\fIvwait3(status,options,rusage)\fP, you must define \fIstatus\fP to be of type
\fIvstatus\fP, and you must have the line:
\f(CW#include "vsignal.h"\fP in order for your code to be portable.
.PP
If you make a system call to the directory routine \fIreaddir()\fP, or any
other system call that uses the type \fIdirent\fP or \fIdirect\fP, you must
re-define the routine that you are calling to be of type \fIvdirect\fP.  The
\fIvdirect\fP type is defined in \f(CWKHOROS_HOME/include/vinclude.h\fP. Again,
this is to allow your code to be portable to other architectures.
.PP
If you need to use the system call \fIvfork()\fP, then to make your code
portable, you must follow the approach in the example below.  This is because
not all machines support the \fIvfork()\fP system call.
.sp
\f(CW
#ifdef VFORK
.br
        if ((pid = vfork()) == 0)
.br
#else
.br
        if ((pid = fork()) == 0)
.br
#endif
.br
        {
.br
            (void) execl("/bin/csh", "csh", "-cf",
.br
                         "lpr writing_progs.ps", (char *)0);
.br
            exit(1);
.br
        }
\fP
.PP
Some system calls are not portable enough to support all architectures that
the Khoros system has been ported to.  To ensure portability of your code
to other architectures, please substitute calls to the Khoros \fIvgparm\fP
or \fIvmath\fP libraries for the following system calls:
.TS
box tab(:);
c c.
instead of system call: use Khoros routine
_
putenv():vputenv()
tempnam():ktempnam()
random():vrandom()
srandom():vsrandom()
wait3():vwait3()
.TE
.sp
\fB"String Manipulation"\fP
.PP
When doing string manipulations, there are several Khoros macros
provided for you that you should use.  All are more robust than their system
call counterparts, in that they check for NULL strings and allocate memory
for you. 
.TS
box tab(:);
c c.
instead of system call: use Khoros macros
_
strcat():VStrcat()
strcat()+strcat():VStr3cat()
strcmp():VStrcmp()
strncmp():VStrncmp()
strcpy():VStrcpy()
strlen():VStrlen()
.TE
Note that the routines above are documented as part of the \fIvgparm\fP 
library, in spite of the fact that the macros are actually defined in 
\f(CW$KHOROS_HOME/include/vdefines.h\fP.
.PP
Other routines that you may find useful in various situations include:
\fIvlower_string(), vupper_string(), vreplace_char(),\fP and 
\fIvreplace_string\fP. 
.PP
.sp
\fB"Filename Expansion"\fP
.PP
The \fIvfullpath()\fP routine must ALWAYS be used to expand filenames.  
This routine will expand environment variables such as KHOROS_HOME;
it also does exhaustive error checking on input file names.  A benefit of using 
the \fIvfullpath()\fP routine is that your program will automatically pick
up the capability of using the Khoros Keywords shorthand for input file names
(see Chapter 1 of the Khoros User's Manual for an explanation of the Keywords
capability).
.sp
\fB"Memory Allocation"\fP
.PP
When allocating memory, programs that attempt to allocate zero bytes may 
crash on some architectures.  For this reason, you may want to take advantage
of the Khoros counterparts to common system allocation routines, found in the
\fIvgparm\fP library, which check for attempts to allocate zero bytes:
.TS
box tab(:);
c c.
instead of system call: use Khoros \fIvgparm\fP routine
_
alloca():kalloca()
calloc():kcalloc()
malloc():kmalloc()
realloc():krealloc()
.TE
.sp
\fB"Data Transport / Distributed Processing"\fP
.PP
The distributed processing / data transport mechanisms of Khoros are implemented
via the \fIvgparm\fP library.  If you want your program to be able to take 
advantage of the distributed processing / data tranport capabilities, you must
make the appropriate calls to routines in the \fIvgparms\fP library.  Most of
the routines in question are substitutes for their system counterparts, and
only differ from their system counterparts in that they support data transport
and distributed processing. An important thing to remember is that these 
routines in the \fIvgparm\fP library may NOT be mixed with their system 
counterparts;  consistency is the key to success here.  To write programs that
will work with distributed processing and data transport, substitute the
system calls below with the Khoros counterparts given:
.TS
box tab(:);
c c.
instead of system call: use Khoros \fIvgparm\fP routine
_
access():kaccess()
free():kfree()
open():kopen()
close():kclose()
read():kread()
write():kwrite()
unlink():kunlink()
fopen():kfopen
fclose():kfclose()
fputc():kfputc()
fread():kfread()
fwrite():kfwrite()
lseek():klseek()
execvp():kexecvp()
gethostname():kgethostname()
system():ksystem()
tempnam():ktempnam()
.TE
.PP
Important Note:  In Chapter 7 of the Khoros Programmer's Manual, there are
examples of short programs that use these utilities to take advantage of
the data transport / distributed processing capabilities of Khoros.
.sp
\fB"Write to Stderr"\fP
.PP
When coding in the PS file, all \fIfprintf();\fP 
error message statements should use the file descriptor \fIstderr\fP, NOT 
\fIstdout\fP.
.sp
\fB"Vroutines should use check_args()"\fP
.PP
The \fIcheck_args()\fP function exists in the vgparms library. Its purpose
is to make sure the command line did not contain any invalid 
arguments/options. If the command line did contain
invalid arguments/options, \fIcheck_args()\fP will print them out and
your program will exit.  This call is not mandatory, but it is
a good idea to include it in your code.
.sp
\fB"Input file error checking"\fP
.PP
Input file error checking should be performed in each library routine, with
use of routines available in the \fIverror\fP library.  The library routine
should completely check all relevant aspects of the incoming data, and exit 
gracefully on invalid input.
.sp
\fB"Take advantage of Khoros Utilities"\fP
.PP
Aside from Khoros routines listed above, there are many other utility routines
in the public Khoros libraries that you may find useful in your programs.  For
full descriptions of these and other routines that are available for your
convenience, see Chapter 8 of the Khoros Programmer's Manual, or use the 
\f(CW% vman {library name}\fP when in need of a quick reference.  Especially
recommended for your use are those routines available in the \fIvgparm\fP, 
\fIvutils\fP, and \fIvmath\fP libraries.
.sp
\fB"Summary"\fP
.PP
The best approach for writing a new program is often to look at examples. 
For instance, there are plenty of vroutines which do image processing in the 
\f(CWKHOROS_HOME/src/vipl/Lib/\fP directory.  Spend some time browsing through 
existing programs, looking for one that is similar to the program that you 
would like to write in order to get an idea of how to approach the problem at 
hand. Experience with the C programming language, of course, will help
tremendously, as all Khoros programs are written in C.  It is highly 
recommended that you become familiar with the contents of the public Khoros 
libraries, so that you may take advantage of the utilities that are provided
for you.  There is a learning curve associated with use of the Khoros Software
Development system;  however, increased familiarity with the procedure can be 
relied upon to produce a valuable increase in efficiency and productivity.
.PP
Additional information concerning the Program Specification
file is provided in Section D of this chapter.  Certain segments of the
PS file that elaborate on the programming aspects are detailed in 
that section.
.sp 2
.NH 2 "CONVENTIONS FOR VARIABLE NAMES"
.XS
      \*(SN  CONVENTIONS FOR VARIABLE NAMES
.XE
.PP
These are conventions for the most common variable names used in the Khoros
system. Note that the \fIvariable\fP field on a particular line of the *.pane
file becomes the name of the [-flag] to the program on the command line, as
well as the name of the corresponding field in the C structure that 
\fBghostwriter\fP generates in the *.h file.
.sp
        i       single input viff file
.br
        i#      multiple input viff files
.br
                (NOTE: do not use the word "image" casually -
.br
                try to use "viff file" when you mean an image
.br
                formatted specifically for the Khoros system,
.br
                not "image file".
.br

.br
        o       single output viff file
.br
        o#      multiple viff output files
.br
        f       output ascii file
.br

.br
        t       data type (string)  This flag requires a call to \fIvget_type()\fP
.br
        d       direction of processing for 1d data
.br
        w,h    width and height
.br
        x,y     coordinates of a pixel
.br
        r,c     row and column
.br

.br
        b       bands
.br

.br
        a, A, P, U, V reserved command line arguments
.br
.sp 2
.NH 2 "KHOROS FILE NAMING CONVENTIONS"
.XS
      \*(SN  KHOROS FILE NAMING CONVENTIONS
.XE
.PP
The table below is a list of the file naming conventions used in Khoros.
.LP
.TS
box tab(:);
c l.
File suffix:Description
_
*.a:library
*.ans:Command line answer file.
*.awk:awk script files.
*.c:C source
*.cmdlog:Khoros command execution log file.
*.conf:Configuration file used by \fBghost\fP routines.
*.csh:csh script files.
*.doc:Documentation files formatted for on line help in X applications.
*.f:fortran source
*.form:UIS file describing GUI for xvroutines - used with \fBconductor\fP.
*.jp:Journal Playback files.
*.l:lex source
*.man:Files used for preparing documentation for printing.
*.ms:Manual files containing ms macros.
*.o:object file produced by cc
*.pane:UIS file describing CLUI & GUI - used with \fBcantata\fP & \fBghostwriter\fP.
*.prog:PS file for \fBghostwriter\fP and \fBghostreader\fP.
*.ps:Postscript files ready to be printed.
*.sec:Chapters or sections of the printed Khoros Manuals.
*.sh:bourne script files.
*.sub:UIS file describing subforms for \fBcantata\fP (has ref's to *.pane files).
*.txt:Text file (README(s) are the exception).
*.vec:Vector font files.
*.wksp:Saved cantata workspaces.
*.xv:Files that are in VIFF format.
*.viff:Files that are in VIFF format.
*.y:yacc source
*.1:Section one manual page.
*.3:Section three manual page.
.TE
