- CIO
- Description
- Introduction
- I. Inoput routines
- II. Text and numerical manipulations
- III. Output routines
- IV. CIO variables
- V. File manipulation
- VI. Error handling
- VII. Ready made commands
- VIII. Graphics
- IX. Miscelaneous
- APPENDIX A. Structures and types
- APPENDIX B. PROGRAMMING NOTES
- Programming examples
- See also
- Files
CIO
CIO - procedures for interactives programsDescription
This file gives detailed descriptions of CIO procedures, including instructions for the use in C and Fortran programs.- Introduction
- I. Input routines
- II. Text and numerical manipulations
- III. Output routines
- IV. CIO variables
- V. File manipulation
- VI. Error handling
- VII. Ready made commands
- VIII. Graphics
- IX. Miscelleneous
- APPENDIX A. Structures and types
- APPENDIX B. Programming notes
- Programming examples
- See also
- Files
Introduction
cio.h, proto.h
Most routines make use of definitions made in file cio.h. The file cio.h is referred to in source text modules in the following way: #ifndef cio_h #include <cio/cio.h> #endif The #ifndef directive prevents duplications when several source text modules are merged to one larger file. Notice the fact that the directory above directory "cio" is assumed to be in the include path. On the nvsf HP720 system the full path name of cio.h is /usr/local/include/cio/cio.h The C compiler may then be called with a directive: cc -I /usr/local/include ..... cio.h contains #include directives for setjmp.h, ctype.h, stdio.h, math.h, errno.h, time.h and a few other system include files. The CIO package is written in "Kernighan and Ritchie" C. For compilation with an ANSII-C compiler a separate file proto.h containing prototype definitions is available. This file is automatically included when the compile directive -DANSI is given.
integer types: int and int4
To improve portability, most integers are declared as 'int4', which is aliased in cio.h to 'long int'. Make sure 'int4' is a 4-byte integer when porting this package to other systems. While 'int4' always has 4 bytes, 'int' may be 2 or 4 bytes long, depending on the compiler.
error handling
The return value of many routines, stat (of type int4) is to be considered as an array of bits each with a specific meaning. The usual value of stat is 0, indicating no errors or warnings. For other possible values see TABLE I. The standard way of handling errors is - display an error message - return to a well defined point of the program. - discard unprocessed ("typed ahead") command input. - if a cio script is being processed, exit this script. These functions are taken care of by the routine eruit. One does not always want errors and irregularities to be treated this way. Therefore for many functions there is the choice between routines where errors are handled by eruit and routines where error handling is left to the programmer.See also VI. Error handling
CIO status bits (TABLE I)
TABLE I. STATUS BITS RETURNED BY VARIOUS CIO FUNCTIONS. ------------------------------------------------------- mnemonic value explanation ------------------------------------------------------- errstat 0x80000000 set if error status notinteger 0x00000001 number is non-integer isciovar 0x00000001 text is a CIO variable nonumber 0x00000002 no number decoded EOString 0x00000004 end of string encountered delimiterr 0x00000008 delimiter ) or ] encountered illterm 0x00020000 ill. terminator, not ) or ] defstat 0x00000010 default value used numerr 0x00000020 numerical error syntaxerr 0x00000040 syntax error undefined 0x00010000 undefined variable varnamerr 0x00000080 error in variable name nosubscrpt 0x00008000 subscript missing operanderr 0x00000100 bad operand truncaterr 0x00000200 text truncated rangerr 0x00000400 outside permissible range filerr 0x00000800 file error conflict 0x00001000 name or type conflict Qstat 0x00002000 "q" when number was asked EOFstat 0x00004000 end of file encountered ------------------------------------------------------- Example: Say, function call stat = getint("prompt:",number,false); returns the value stat == 0x80010002. According to the mnemonics as defined above this is equivalent with stat == (errstat | undefined | nonumber). The interpretation of this value of stat is, that an error occurred, due to a reference to an undefined variable. As a result, no number was decoded. Use of these mnemonics is recommended to make the program more readable. The calling program should at least test the errstat bit, e.g. by if ( stat & errstat ) { ... } before using the number returned.
input options
Several options for pre-processing of the input data are available. Generally the first character of each argument is inspected, and special action is taken for the following first characters: #: indicates that the remainder of the current line is comment ': in text following the quote normal separators such as space, comma and end-of-command character lose their special meaning. This lasts until the next quote, or an EOL, is encountered. ?: An argument is asked from stdin instead of the current input stream. The text following the ? is used as prompt. This text should be enclosed in single quotes (') if it consists of more than one word. &: The effect of this symbol, when given instead of an argument, is to force an error condition and cancel the current command. $: In contrast with other special symbols, the $ may occur anywhere in the text, not necessarily as the first character of the argument. The symbol $ leads to action in the following cases: 1. The $ is followed by the name of a variable of type 'c'. The $name is substituted by the contents of this variable. 2. The $ is followed by the name of an environmental variable. Again, $name is substituted by the contents of this variable. Example: $HOME 3. The $ is followed by a numerical expression enclosed in parentheses. Example $(atan(1)*4). The expression is evaluated in double precision, and the result is substituted in formatted form. A format specifier may be given after the expression, before the ). All valid C control strings, containing a conversion specification for a double float, may be used. To separate the control string from the expression, a ',' should be used. Example: $(atan(1)*4,pi = %.12g) Note that the name of a char variable may be used as a command, even if it is not preceded by a $. On the other hand, for further arguments of a command, the name of a char variable must be prefixed with a $, if substitution by its contents is wanted. Names of a numerical (e.g. int) variables should never be prefixed with a $. Substitution of char variables takes precedence over substitution of environmental variables.
I. Input routines
In this section some routines are described to transfer data from the input stream to the application program. The verbs EOK and EOL will be used, meaning: EOK: The end-of-command character, i.e. the semicolon. EOL: End-of-line. In general these routines try to extract the data from the current line. If this line is exhausted a new line is obtained from the input stream. This line becomes the current line and the process of extracting data is repeated. If however an EOK is encountered no further data are taken from the input stream until the EOK status is reset. Instead the routine then returns a default argument, or an argument that is unchanged. The routines have a calling sequence of the type stat = getxxx(prompt,argument,cdefault) ; where prompt is the appropriate prompt string, displayed in interactive mode if a new line is read, and cdefault specifies what is wanted when an empty argument (e.g. EOK) is obtained. if true: leave argument unchanged if false: fill argument with default value, i.e. the null string for text arguments, or a large negative value for numeric arguments. The standard way of error handling is provided by routines whose name starts with xget (such as xgetint). In case of errors these routines escape by calling 'eruit'. Hence a normal return only occurs when no errors have been found and thus there is often no need to test the returned value of stat. A possible use of stat is to check if a default parameter was input. On the other hand, when the routines whose name starts with get (such as getint) are used, it is assumed that the calling program checks the value of stat after every call, and takes appropriate action in case of irregularities. Also available are a few routines whose name starts with cget. These routines have the same effect as their xget counterparts, and in addition, the prompt as well as the value obtained are echoed to stdout. This may be a handy way for the user to obtain a listing of default parameters, by typing a ';' when input is asked.
The basic input routine
getargtextint4 getargtext(char *prompt, char *T, int4 len, int4 cdefault, int4 termflag, int4 skipflag); Get a text argument from the inputstream, return it in *T. prompt is prompt string, len is maximum length of argument. cdefault specifies what to do when the argument is empty: if cdefault is true : leave string T unchanged if cdefault is false: fill T with bytes '\0'. termflag specifies what conditions terminate the argument, also the request for enabling alias substitution (see getcommand) may be put in here. skipflag specifies the actions before extracting the argument. For possible values of termflag and skipflag, see TABLES II and III, or file cio.h. This is the most elementary routine for processing the input stream that may be called from an application program.See also getcommand, xgetcommand
function bits for input routines (TABLE II)
TABLE II. FUNCTION OF BITS OF termflag AND skipflag FOR USE IN getargtext. ------------------------------------------------------------------------- mnemonic value explanation ------------------------------------------------------------------------- termEOL 1 get text terminated by end of line termEOK 2 get text term. by EOL or EOK termspace 4 " " term. by EOL, EOK or space termcomma 8 " " term. by EOL, EOK or comma termA termspace|termcomma any of the above substalias 32 allow alias substitution skipblank 64 skip leading spaces skipEOL 128 read new line when at EOL skipEOK 256 skip to next command, on current line skipA skipblank|skipEOL skip spaces, new line if at EOL skipC skipA|skipEOK skip to next command resetLN 512 "rewind" current line resetCMD 1024 "rewind" current command dontread 2048 process "skipflag" only termquote 4096 for internal use only rawread 8192 ignore special meaning of symbols ------------------------------------------------------------------------- Note that setting the termEOK bit in termflag implies that both EOK and EOL are terminators. However, when only termEOL is set, EOL is a terminator, but EOK is not. Specifying termEOL allows semicolons to be included in the text. The skipEOL bit is ignored when prompt is an empty argument, i.e. prompt either is the null pointer (prompt == NULL), or points to the null string ( *prompt == '\0' ). Combinations of these function bits are used by functions such as getcommand, gettext, getline and getrawline, see below. Variations can easily be implemented. For instance, to get a text argument terminated by a comma, but not by a space, one might call: stat = getargtext("text:", T, 80, termcomma, skipEOL); In this example, also leading spaces are included in the result.
function bits used by CIO routines (TABLE III)
TABLE III. FUNCTION BITS USED BY STANDARD CIO INPUT ROUTINES. --------------------------------------------------- function termflag skipflag --------------------------------------------------- gettext termA skipA getline termEOK skipA getrawline rawread | termEOL skipEOL getcommand termA | substalias skipC ---------------------------------------------------
The standard input routines
xgetxxx and getxxxwhere xxx = { command, int, real, ixpr, var, text, line, rawline }. The arguments input by getint, getreal, and getixpr, cgetint, xgetint, cgetreal, xgetreal, and xgetixpr may be numbers, variable names, or even expressions.See also evalxp_
getcommand, xgetcommand
int4 getcommand(char *prompt, char *T, int4 len, int4 cdefault); int4 xgetcommand(char *prompt, char *T, int4 len, int4 cdefault); Get a command from the input stream. The remaining input, if any, of the current command is skipped (up till EOK or EOL), then a text argument is obtained. Terminators are space,comma, EOK, or EOL. If the text argument is a the name of a char variable, the contents of this variable (usually a CIO script) are substituted in the input stream (alias substitution), and after that a new command is obtained.
getint, xgetint, cgetint
int4 getint(char *prompt, int4 *I, int4 cdefault); int4 xgetint(char *prompt, int4 *I, int4 cdefault); int4 cgetint(char *prompt, int4 *I, int4 cdefault); Get a text argument from the inputstream, using function gettext, and convert this to an integer value, answer in *I. When an empty argument is obtained, *I is unchanged if cdefault is true, but *I is set to a large negative number if cdefault is false. Example: first = 0; /* set default value to 0 */ stat = getint("first:", &first, true); if (stat) { /* check stat for errors, not needed for xgetint */ ... } Notice the & in parameter &first. Omission of this & is a common cause of 'bus errors'.
getreal, xgetreal, cgetreal
int4 getreal(char *prompt, double *R, int4 cdefault); int4 xgetreal(char *prompt, double *R, int4 cdefault); int4 cgetreal(char *prompt, double *R, int4 cdefault); Get a text argument from the inputstream, using function gettext, and convert this to a double precision real value, answer in *R. When an empty argument is obtained, *R is unchanged if cdefault is true, but *R is set to a large negative number if cdefault is false.
getixpr, xgetixpr
int4 getixpr(char *prompt, int4 *I, int4 cdefault); int4 xgetixpr(char *prompt, int4 *I, int4 cdefault); Get a text argument from the inputstream, using function getline. Difference with getint: the expression may contain spaces. Used by commands if and while.
getvar, xgetvar
int4 getvar(char *prompt, VARIABLE **V, Varname name, int4 cdefault); int4 xgetvar(char *prompt, VARIABLE **V, Varname name, int4 cdefault); Get a text argument from the inputstream, using function gettext, and convert this to a pointer *V, and a name 'name', of a basic variable, (of type 'c', 'i', 'f', or 'd') if possible. Useful when an array of variables is required. Variables of type 'v' are resolved. When an empty argument is obtained, name is unchanged if cdefault is true,and set to the null string if cdefault is false. If the argument does not lead to a valid basic variable, *V is set to the NULL pointer, and 'name' contains the last obtained name, or the null string. Return value: If a valid pointer is obtained, the status returned is either 0 or 'defstat'. Otherwise, getvar returns a negative value, see Table I for possibilities, while xgetvar takes an error exit.See also CIO status bits (TABLE I) and xgetsp
Note: When getvar obtains a varlist name without subscript, *V is set to NULL, and the status returned is (errstat|nosubscrpt). In a routine such as keepvar, see further on, where all types of variables qualify, this "error" should be intercepted. Example: VARIABLE *ptr; char vartype; int length; float *spec; Varname name; ..... xgetvar("spectrum:", &ptr, name, true); vartype = ptr->type; if (vartype == 'f') spec = (float *) ptr->valpt; else eruit("array %s is not of type 'f'",name); length = ptr->size / sizeof(float); /* now spec may be used as a float array spec[length] */ ..... If an array of a specific type and (minimum) size is required, a useful follow-up of xgetvar is function checkvar.See also fgetvar (Fortran callable) and CIO variables in Section IV.
xgetsp
int4 xgetsp(char *prompt, VARIABLE **pV, Varname spname, int4 *plen, int4 cdefault); Similar to xgetvar with the following extra's The array length is also returned, in *plen. The variable obtained from the input must be defined. It must be a numerical variable, of type 'i', 'f', or 'd'. If not, an error exit occurs.See also getvar, xgetvar
gettext, xgettext
int4 gettext(char *prompt,char *T,int4 len,int4 cdefault); int4 xgettext(char *prompt,char *T,int4 len,int4 cdefault); Get a text from the input stream. Skip leading spaces, possible terminators space, comma, EOL and EOK. The result (of maximum length len) is returned in *T, terminated by a '\0'. When an empty argument is obtained, *T is not changed if cdefault is true, and set to the null string if cdefault is false.
getline, xgetline
int4 getline(char *prompt,char *T,int4 len,int4 cdefault); int4 xgetline(char *prompt,char *T,int4 len,int4 cdefault); Get a text from the input stream. Skip leading spaces, possible terminators are EOL and EOK. The result (of maximum length len) is returned in *T, terminated by a '\0'. When an empty argument is obtained, *T is unchanged if cdefault is true, and set to the null string if cdefault is false.
getrawline, xgetrawline
int4 getrawline(char *prompt, char *T, int4 len, int4 cdefault); int4 xgetrawline(char *prompt, char *T, int4 len, int4 cdefault); Get a text from the input stream. Skip leading spaces, possible terminator is EOL only. The result (of maximum length len) is returned in *T, terminated by a '\0'. When an empty argument is obtained, *T is unchanged if cdefault is true, and set to the null string if cdefault is false. Difference with getline: The special meaning of characters such as '$', '#', '?', ';' is ignored.
Routines to change the input pointer
skipper, resetcmd and resetlnskipper
int4 skipper(void) Skip to next command on current line. This is a way to get past a semicolon (;) in the input stream, as an alternative to getcommand.
resetcmd
int4 resetcmd(void) Reset the input pointer to the beginning of the current command. This is only guaranteed to work if no new line has since been read, i.e. it should only be used directly after a getcommand call.
resetln
int4 resetln(void) Reset the input pointer to the beginning of the current line.
Fortran callable input routines:
intarg, dparg, realarg, txtarg, linearg, and fgetvarThese routines allow prompt to be of Fortran type CHARACTER. The parameter nprompt, specifying the length of the prompt, should be omitted in calls from Fortran subprograms, as it is supplied automatically by the compiler (at least in the HP SGI, and SUN implementations of Fortran). When an empty input is obtained from the input stream: for numerical routines (intarg, dparg, realarg) the value of number is not changed, for txtarg and linearg a string of all spaces is returned. On errors an exit takes place via eruit.
intarg
void intarg(int4 *number, char *prompt, int nprompt); Ask an integer number, result in *number Fortran callable alternative of getint. Example of a Fortran call: CALL INTARG(NANGLES,'How many angles:') If the argument is empty the value of *number (i.e. NANGLES in the example) is left unchanged.
dparg
void dparg(double *dnumber, char *prompt,int nprompt); Ask a double precision number result in *dnumber Fortran callable alternative of getreal.
realarg
void realarg(float *number,char *prompt,int nprompt); Ask a real number (single precision float), result in *number.
txtarg, linearg
void txtarg(char *text,char *prompt, int ntxt, int nprompt); void linearg(char *text,char *prompt, int ntxt, int nprompt); Fortran callable alternatives of gettext, getline. txtarg: get text terminated by space, comma, ';',or end-of-line. linearg: get text terminated by ';' or end-of-line. The text is padded with spaces.
fgetvar
int4 fgetvar(char *prompt, VARIABLE **V, Varname name, int4 *fdefault, int nprompt); fgetvar is a Fortran callable variation of getvar. Here fdefault is a pointer to cdefault.See getvar, xgetvar for the details.
Miscellaneous applications
yesno, asklu, iselect, and cselectyesno
int4 yesno(char *text, int qdefault) Type text, followed by 'Yes/No', ask response. Return 0 if No, 1 if Yes. Else return 0 if qdefault is 0, 1 otherwise.
asklu
int asklu(char *prompt, int ludefault); This routine asks a unit number (logical unit, LU) used for accessing files. The text string referred to by the parameter prompt is extended with the string "LU:", and used as a prompt to ask for an integer (using xgetint). The number is checked to be in the permissible range for LU numbers. If the user types an empty argument the value ludefault is used. If no default is permitted set ludefault = -1.
iselect, cselect
int iselect (char *text, int ntext); int iselect1(char *text, int *promptflag, int ntext); int cselect (char *text); int cselect1(char *text, int promptflag); int cselect2(char *text, int promptflag, char response[12]); iselect Ask for a text argument (via gettext), using as prompt a list of options present in text. Options are to be separated by a single non-alphabetic character. Required letters in capitals, optional letters in lower case. The text argument is compared with the options list, via mscan, and the order number in the options list is returned. More specifically, return value > 0 : a match was found 0 : an empty argument was input -1 : a non-matching argument was input Example of a Fortran call: GOTO(301,305,306,308), + ISELECT('Sp/Ivar/Rvar/TERmnl/: ') CALL ERUIT_('Illegal option') iselect1: Same effect as iselect when *promptflag is non-zero, else no prompt is issued, which implies that only the current line is scanned for the response. cselect: For C applications. Parameter ntext is not needed, and text should be a null-terminated string. Further as the above. cselect1: Same effect as cselect when promptflag is non-zero, else no prompt is issued, which implies that only the current line is scanned for the response. promptflag is an int, not a pointer to an int cselect2: A variation that also returns the response.
Auxiliary routines
sprompt, itxtostr_, upcase, mscan, cscan, mprompt, substenv, and check_termsprompt
char *sprompt(char *prompt, int nprompt); Translate Fortran prompt into C prompt, i.e. copy prompt, append a '\0', and return pointer. Stop when nprompt characters are copied, or, a null character is encountered, or, 79 characters are copied, whichever happens first. The resulting string remains available until the next call to sprompt occurs. Used by intarg, realarg, etc.
itxtostr_
int itxtostr_(char *txt, char *str, int txtlen, int strlength); Convert text to standard Unix string. A terminating byte '\0' is placed after the last printing character of txt. The length of the character variables txt and str is given in txtlen and strlength. The actual length of the string, i.e. the number of characters before the '\0', is returned. If an error is detected, the return value is negative. txt and str may be the same variable, (if room for the extra 0 is present!!). Example of a Fortran call: CHARACTER*20 STR ... NN = ITXTOSTR_ ("ABCD ",STR) In this example NN will be set to 4, and STR contains "ABCD" with a '\0' following the D.
upcase
void upcase(char *text, int ntext); Replace lower case letters in text by upper case letters. Example of a Fortran call: CHARACTER*(*) STRING CALL UPCASE(STRING)
mscan
int mscan(char key[], char options[]); Compare key with the list of mnemonics present in options. The string key is terminated by any non-alphanumeric character. Mnemonics in options are separated by a non-alphanumeric. The list is terminated by two such characters, or a '\0'. Required characters in CAPITALS, optional characters lower case. The procedure is not sensitive to the case of characters of key. Return order number in options if match is found: 1 for first item -1 if no match is found 0 if key is empty Used by iselect.
cscan
int cscan(char key[], COMMAND list[]); Compare argument key with entries in list[nopt].keyword. return: nopt+1 when a match is found -1 if no match is found 0 if key is empty
mprompt
char *mprompt(COMMAND list[]); Form a suitable prompt from the entries in list[].keyword. Returns a pointer to this prompt. The maximum length of the prompt is 40 characters.
substenv
int4 substenv(char *text, int4 maxlen); This routine replaces the names of char variables, and the names of environmental variables, by the contents of those variables. Each name should be prefixed with a $. The $ character may appear anywhere in the input, text[]. At return text[] contains the expanded text, with a maximum of maxlen characters. The return value, stat, is normally zero,but contains (errstat|truncaterr) if the expanded text did not fit. Used by getargtext(). Restriction: maxlen < LINE_LEN ( = 256)See also expandfn, fexpandfn
check_term
int check_term(int fd); fd is the filedescriptor of the file or device to be tested (e.g. 0 for stdin, 1 for stdout). Returns 0 (false) if fd is not a terminal.
II. Text and numerical manipulations
Conversion of text to numeric
intchar_, intget_, numget_, and evalxp_int4 intchar_ convert ASCII coded decimal text to a numeric value int4 intget_ decode an integer number from an ASCII string int4 numget_ decode a integer or real number from an ASCII string int4 evalxp_ evaluates an expression from an ASCII string The most elaborate routine is this section is evalxp_. It evaluates expressions that may contain CIO variables, arithmetic operators, and mathematical functions. The evaluation of pure numbers is done by numget_ called by evalxp_. A shortened version of numget_, handling only integer numbers, is intget_. A simpler, but less versatile alternative of intget_ is intchar_. The routines are callable from Fortran as well as from C. This is the reason why call by address is used for most parameters. The routines evalxp_ and numget_ have identical calling sequences. The text string does not have to be terminated by a binary 0. evalxp_ is called by getint and getreal. The result of intget_ and the integer answer of numget_ may be different if the text contains the characters '.', 'e' or 'E'. For intget_, these are terminators, for numget_ they are considered as part of a number.
intchar_
int4 intchar_(char *txt, int txtlen); convert ASCII coded decimal text to a numeric value Example of a Fortran call: NUMBER = INTCHAR_(' -523.999 ') NUMBER receives the value -523 leading spaces are ignored terminators are end-of-text, or non-numeric character
intget_
int4 intget_ (char *line,int4 *len, int4 *ipt, int4 *ianswer, int4 *term); usage : stat= intget_(line,&len,&ipt,&ianswer,&term); decode a number from an ASCII string format : {spaces}{sign}{digits} arguments : line (input) = string *len (input) = nr of characters in line *ipt (input/output) = index within line *ianswer (output) = result (integer) *term (output) = terminating character stat : 0 = number decoded, result O.K. (errstat|notinteger) = number decoded, not an integer nonumber = no number, terminator only EOString = no number, end of string if no number is decoded, ianswer is unchanged ipt input value : index of first character to be inspected (0 for first character of line) ipt output value : index of character following the terminator
numget_
int4 numget_(char line[], int4 *len, int4 *ipt, int4 *ianswer, double *fanswer, int4 *term); usage : stat=numget_(line,&len,&ipt,&ianswer,&fanswer,&term); decode a number from an ASCII string format : {spaces}{sign}{0x}{digits}{.}{digits}{e}{sign}{digits} arguments: line (input) = string *len (input) = nr of characters in line *ipt (input/output) = index within line *ianswer (output) = result (integer) *fanswer (output) = result (double) *term (output) = terminating character stat : 0 = number decoded, both results O.K. notinteger = number decoded, not an integer nonumber = no number, terminator only EOString = no number, end of string errstat|numerr = not a number, real overflow if no number is decoded, ianswer and fanswer are unchanged ipt input value : index of first character to be inspected (0 for first character of line) ipt output value : index of character following terminator
evalxp_
int4 evalxp_(char line[],int4 *len, int4 *ipt, int4 *ianswer, double *fanswer, int4 *term); evalxp_ : decode an expression from an ASCII string Expressions are evaluated from left to right. Arithmetic and relational operators are + - * / ** > < >= <= == != There are no priority rules for these operators !!! Brackets ( and ) may be used to group expressions Numbers may consists of the following parts <sign><0x><digits><.><digits><e><sign><digits><k> where 0x means 'hexadecimal' and k means '*1024' The following functions are available: sin, cos, tan, asin, acos, atan, exp, ln, sqrt The expression may contain CIO variables, of numerical type. Assignment operators are := += -= *= /= Assignment takes place from right to left and has lowest priority usage: stat=evalxp_(line,&len,&ipt,&ianswer,&fanswer,&term); arguments : line[] (input) = string *len (input) = nr of characters in line *ipt (input/output) = index within line *ianswer (output) = result (integer) *fanswer (output) = result (double) *term (output) = terminating character stat: 0 = expression decoded, integer result notinteger = expression decoded, not an integer nonumber = no expression, terminator only EOString|nonumber = no expression, end of string. delimiterr = terminated by unmatched ] or ) illterm = terminated before end of string, by an illegal character, not unmatched ] or ) errstat|numerr = division by 0 , overflow , etc. errstat|syntaxerr = syntax errors errstat|Qstat = a Q or q (for quit) was encountered if no expression is decoded, ianswer and fanswer are unchanged ipt input value : index of first character to be inspected (0 for first character of line) ipt output value : index of character following the terminator
Miscellaneous routines
dxxi, n_int and mv_bytesdxxi
double dxxi(double d, int4 i) Return d to the power i.
n_int
int4 n_int(double x); Round double precision x to the nearest integer.
mv_bytes
void mv_bytes(char *from, char *to, int4 nbytes); Copy nbytes bytes from one place to another.
III. Output routines
Standard output
putout, sput1, sput2, ... sput12, sputout, cputout, out_ , needlines, fneedlines, and newlineThe standard output of CIO routines takes place via these routines, rather then via printf(). This makes it easier to convert to a system where printf() is not wanted. The logging of input and output to a file relies on the fact that console output uses these routines.
putout, sput1, sput2, ... sput12
void putout(void) sput1(char *string) sput2(char *controlstring, arg2) sput3(char *controlstring, arg2, arg3) .... putout: Text should first be formatted into the global array OUTPUTline, e.g. with sprintf(OUTPUTline,controlstring,arg, ...). Then a call to putout() will output OUTPUTline to the screen, and also reset OUTPUTline. sput1, sput2, ... sput12: These macros facilitate the procedure described above. sput1 is just an alias for sputout, see below. sput3 ... sput12 take as first argument a controlstring. This string, and further arguments, are inserted in sprintf(OUTPUTline, .. ), and subsequently putout() is called. Thus, these macos look like 'printf', with the difference that the programmer has to count the arguments. Example: sput3("sum=%.6g, average=%.6g\n",sum, aver);
sputout, cputout, out_
void sputout(char *text) int cputout(char *text) void out_(char *text, int ntext) sputout: Output text to the screen. Newline characters may be embedded in the text. cputout: Like sputout.In addition, the output pauses after every page. Used by command 'type' to output variables of type 'c'. out_: Fortran callable. Output one line of text. Strips trailing spaces and adds a newline character.
needlines, fneedlines
int needlines(int N) int fneedlines(int *pN) Pause if less then N lines are left on the screen. To initialize paging, call needlines with N <=0. Then the absolute value of N is the number of lines remaining on the screen when scrolling after a pause. For proper operation, subsequent calls, with N > 0, should precede screen output, with N equal to the number of lines actually send to the screen. Use this technique when output lines are generated one by one.To output a whole chunk of text, see cputout. fneedlines Fortran callable alternative of needlines.See also sputout, cputout, out_
newline
void newline(void) Output a newline character to the screen.
Buffered text and numbers to stdout
These routines use a common buffer, named writbuf, of length 80 characters. Text and numbers are buffered, until the buffer is full (i.e. the next text won't fit), or until crlf() or wrflush() is called.
Fortran callable
writt, writi, writr, wrflush, crlf, wrclean, and wrgetFortran calls: CALL WRITT('text') CALL WRITI('text', INTEGER, NFIELD) CALL WRITR('text', REAL,NFIELD, NDECs) CALL CRLF CALL WRFLUSH CALL WRCLEAN CALL WRGET(STRING, NS) If NFIELD is "too small" the minimal required length is used. If NFIELD < 0 floating point format is used (writr only). CRLF : if the buffer is empty, output a new line only; else, write the buffer and output a new line WRFLUSH : do nothing if the buffer is empty; else, write the buffer and output a new line WRCLEAN : reset the buffer pointer, do not write anything WRGET(STRING, NS) : copies writbuf to STRING and returns the number of characters used in NS
writt
void writt(char *text, int ntxt); Output ntxt symbols from *text.
writi
void writi(char *text, int4 *int_4, int *ndig, int ntxt); Output ntxt symbols from *text, followed by integer *int_4, formatted with a field length of *ndig.
writr
void writr(char *text, float *real, int *nfield, int *ndecs, int ntxt); Output ntxt symbols from *text, followed by single precision float *real, formatted with a field length of *nfield, and *ndecs decimal figures. If nfield < 0, floating point format with field length abs(nfield), is used.
wrflush
void wrflush(void) Do nothing if the buffer is empty, else write buffer and reset pointer.
crlf
void crlf(void) As wrflush, but also write new-line if the buffer was empty.
wrclean
void wrclean(void) Reset the buffer pointer, do not write anything.
wrget
void wrget(char *text, int *nused, int ntext); Copies writbuf to *text and returns the number of characters used in *nused.
C callable buffered free format numerical output
cwritt, cwritg, and cwritdcwritt
void cwritt(char *text); Output 0-terminated string *text.
cwritg
void cwritg(char *text, double dreal, int prec); Output the null-terminated string text, followed by double precision dreal. The format and field length are chosen by cwritg. Large or very small absolute values are represented in floating point format, intermediate values in fixed point format, integer values in integer format. The requested relative accuracy is 10 to the power ( - prec).
cwritd
void cwritd(char *text, double dreal, int ndecs); Output the null-terminated string text, followed by double precision dreal, in fixed point format, with ndecs decimals.
Miscellaneous routines
get_the_time, prtime, printtime, ap_gettime, cls, linesonscreen, enter_standout, exit_standout, get_more_char, get_single_char, listcom, and listcom_get_the_time
void get_the_time(int4 *day, int4 *month, int4 *year, int4 *hour, int4 *minute, int4 *second); Get the local date and time in the 6 integers pointed to by the arguments. Not actually an output routine, but closely related to the following two. Updates global variable double time_since_start, that keeps the time in seconds since the first call (set to 0 on first call). Note: in previous versions this function was called 'gettime'.
prtime
void prtime(void) Write to stdout the formatted local date and time dd/mm/yy hh:mm as well as time_since_start, without appending a <newline>.
printtime
void printtime(void) write to stdout formatted the local date and time dd/mm/yy hh:mm as well as time_since_start, <newline>.
ap_gettime
int ap_gettime(void) First, calls printtime, see above. Then calls gettext, to read a text from the current line. If successful, this text is interpreted as a CIO variable and time_since_start is assigned to it.
cls
int cls(void) Clear the screen. Requires linking with the termcap library, ( -ltermcap or -lcurses in the cc command).
linesonscreen
int linesonscreen(void) Returns the number of lines on the terminal screen. Requires linking with the termcap library, ( -ltermcap or -lcurses in the cc command).
enter_standout, exit_standout
int enter_standout(void) int exit_standout(void) Enter (exit) standout mode on the terminal screen. Requires linking with the termcap library, ( -ltermcap or -lcurses in the cc command).
get_more_char, get_single_char
int get_more_char(void) int get_single_char(char *text) Used to create a pause in a long output, such as a help file. get_more_char : output the string "- more -" get_single_char : output a text of the programmer's choice Both then read a keyboard character, and return the ascii value of this character. Requires linking with the termcap library, ( -ltermcap or -lcurses in the cc command).
listcom, listcom_
void listcom(void) void listcom_(COMMAND list[]) Functions listcom and listcom_ both display a list of commands. listcom : takes the global command list "command" listcom_ : takes the command list specified by the argument
IV. CIO variables
This section deals with the access of CIO variables by the programmer. How these variables are defined and manipulated by the user of the application program is described elsewhere.See CIO Ccommand language.
The program maintains a 'linked list' of dynamically declared variables. The parameter varlink in the following is a pointer to the top of this list. The type of this pointer, VARIABLE * , is described in cio.h. The global variable VARLINK is a pointer of this type, and points to the top of the main (and probably only) list of variables, of a program using the present package. To declare variables dynamically within a program one may use the routine declaration, whose input is a text string, the same as would be given by the user of the program. When using declaration, the parameter ier should always be checked, before setting the global variable VARLINK equal to the newly obtained value for this pointer. Example: VARIABLE *newvarlink; ... newvarlink=declaration(VARLINK,vartext,vartype,&ier); if (ier) printerr(ier) else VARLINK = newvarlink; An alternative are the routines vardefc, vardefi, vardeff and vardefd. usage: VARLINK=vardefx(VARLINK, name, nelements, initial_value); where x stands for c, i, d or f. These routines take an error exit when an error is detected, in other words, a normal return implies no detected errors. There counterparts, the routines vargetc, vargeti and vargetd, may be used to obtain a pointer to a variable whose name is known. In all cases the null pointer is returned if the variable could not be found. If the type of the variable is not known beforehand one may use getvarpointer, or, evalvar. To obtain the value of a numerical array element, DAT may be used (in Fortran ddat). How a pointer to a user selected variable may be obtained has been mentioned already in Section I; see xgetvar and xgetsp. For the purpose of assigning a value to a user selected variable, one may use xgettext, followed by valtovar. A number of functions are available to declare and/or assign CIO variables whose name is selected by the application program: varstore, arstore, flarstore, intarstore, fglobvar. Each variable has an associated level, with the convention: level 0: permanent variable level 1: global variables level 2 and higher: local variables Usually the level reflects the nesting depth at which the variable was defined. The current level is kept in global variable VARLEVEL. A special type of variables are the overlap variables. These are variables who coincide in memory with a subarray of another variable. Elements of such variables are accessed indirectly: the overlap variable has a descriptor, with type 'o', that supplies information about the "parent". Function testvar returns a pointer to this descriptor, with type 'o', and function testoverlap converts this to a pointer to the descriptor of the actual variable. Function retrieve always returns a pointer to the actual variable.
Declaration of CIO variables
declaration, vardefc, vardefi, vardefd, vardeff, instalv, instalvv, varstore, varalias, doublearray, doubledef, floatarray, ffarray, fglobvar, intarray, arstore, intarstore, and flarstoredeclaration
VARIABLE *declaration(VARIABLE *varlink, char *vartext, int vartype, int4 *ier); Define a variable of type vartype ('d','f','i', 'c','C', or 'v'), vartext contains "name" or "name=expression" or "name[size]" On return from declaration, the parameter ier should always be checked. The value ier=0 means no errors. See TABLE I for bits set by various errors. Possible errors are syntaxerr, varnamerr,and errors in the expressions for the variable's value or subscript. Both parameter values 'c' and 'C' define a variable of type 'c'. The difference is in the layout expected for vartext: for 'c' vartext should contain name=<text> for 'C' vartext should contain name <text>.
vardefc
VARIABLE *vardefc(VARIABLE *varlink, Varname name, int4 nelements, char *text); vardefc : define an array of char
vardefi, vardefd, vardeff
VARIABLE *vardefi(VARIABLE *varlink, Varname name, int4 nelements, int4 ivalue); VARIABLE *vardefd(VARIABLE *varlink, Varname name, int4 nelements, double dvalue); VARIABLE *vardeff(VARIABLE *varlink, Varname name, int4 nelements, double fvalue); vardefi : define an integer variable or array vardefd : define a double float variable or array vardeff : define a float variable or array
instalv, instalvv
VARIABLE *instalv (VARIABLE *varlink, Varname vname, int vtype, char *vvalpt, unsigned int4 vsize); VARIABLE *instalvv(VARIABLE *varlink, Varname vname, int vtype, char *vvalpt, unsigned int4 vsize); instalv is the basic routine, used to add a variable to the list. instalvv does the same, but first performs some checks on the syntax, and range, and also on the existence of another variable with the same name. In case of detected errors, an exit is taken via eruit. This in contrast with instalv, where error handling is left to the calling program. The parameter vvalpt is a pointer to the data to be stored in the variable. If vvalpt is the NULL pointer the variable is filled with binary zeroes, else vsize bytes are copied. The parameter vsize is the size (in bytes) of the CIO variable. This size is allocated in addition to the memory already used by the current process (C function malloc).
varstore
void varstore(Varname name, double value); Store value in a CIO variable of type 'd' Allocate a permanent CIO variable with the specified name, and type 'd', if necessary. If a CIO variable with the specified name exists already, but is not of type 'd', an error exit is taken. Used by command SUM.
varalias
void varalias(Varname name, char type[1], int4 *pnelements, char *pointer); This procedure may be used to install a variable whose memory storage locations are already in use by the program. To make this procedure Fortran callable type and pnelements are pointers! The value pointed to by pnelements is the size expressed in number of elements of the specified type. The value pointed to by type, i.e. type[0], is 'c','i','d',or 'f'. The parameter pointer points to the first memory location of the variable. Needless to say that this routine should be used with caution.
doublearray, doubledef
void doublearray(Varname name,int4 size,double **pointer); double *doubledef(Varname name, int4 size) If necessary, allocate a permanent CIO array with the specified name and size, and type 'd'. size may be equal to 1. If a CIO variable with the specified name exists already, but is not of type 'd', or too small, an error exit is taken. doublearray : on return, *pointer contains the begin address of the array. doubledef : this functions returns a pointer to a double float variable or array. Example: double *vari; doublearray("parameter",16,&vari); /* now vari can be treated as an array, double vari[16] */
floatarray
void floatarray(Varname name, int4 size, float **pointer); If necessary, allocate a permanent CIO array with the specified name and size, and type 'f'. If a CIO variable with the specified name exists already, but is not of type 'f', or too small, an error exit is taken. On return, *pointer contains the begin address of the array.
ffarray
void ffarray(char *name, int4 *psize, float *base, int4 *offset) Fortran callable alternative of floatarray. On return, offset contains the offset, with respect to 'base', of the allocated array. The name should be terminated by a space, or a binary 0. If a cio variable 'name' exists already, it is first wiped out! In Fortran, declare 'base' as a REAL ARRAY, see example below. Example of use common /combase/ BASE(0:0) INTEGER OFFSET CALL FFARRAY('Arie ',1024,BASE,OFFSET) The allocated space is BASE(OFFSET) ... BASE(OFFSET+1023). The user can address it as Arie[0] ... Arie[1023].
fglobvar
float *fglobvar(Varname name, nt4 length, VARIABLE **varptr); Allocate a global array of type float, with given name and length. The pointer to the array is returned, the pointer to the variable descriptor is returned in *varptr. If a CIO variable 'name' exists already, it is first wiped out! If the variable can't be allocated, the NULL pointer is returned.
intarray
void intarray(Varname name, int4 size, int4 **pointer); If necessary, allocate a permanent CIO array with the specified name and size, and type 'i'. If a CIO variable with the specified name exists already, but is not of type 'i', or too small, an error exit is taken. On return, *pointer contains the begin address of the array.
arstore
void arstore(Varname name, int4 size, int4 ar_index, double value); Store value in a CIO array of type 'd' of size elements, at index ar_index. Allocate a CIO variable with the specified name, and type 'd', if necessary, by calling doublearray, see above.
intarstore
void intarstore(Varname name, int4 size, int4 i_index, int4 value); Store value in a CIO array of type 'i' of size elements, at index i_index. Allocate a CIO variable with the specified name, and type 'i', if necessary, by calling intarray, see above.
flarstore
void flarstore(Varname name, int4 size, int4 f_index, double value); Store value in a CIO array of type 'f' of size elements, at index f_index. Allocate a CIO variable with the specified name, and type 'f', if necessary, by calling floatarray, see above.
Access of CIO variables
existvar, evalvar, testvar, testoverlap, testrange, DAT, ddat, storeDAT, putinsp, valtovar, vargetc, vargeti, vargetd, vargetf, vargetv, getvarpointer, and retrieveexistvar
VARIABLE *existvar(char *vartext, int minlevel,int maxlevel); Test if a variable exists already, if so, return its pointer. The match is only valid if the variable's level is not less than minlevel and not larger than maxlevel. Returns the null pointer if unsuccesful. Example. Test if name is a local variable: minlevel=0; if(VARLEVEL>1) minlevel=VARLEVEL; tmpvar= existvar(name,minlevel,VARLEVEL);
evalvar
int4 evalvar(char text[], int4 *nt, int4 *ipt, VARIABLE **V, char name[], int4 *term); Decode a pointer to a variable from an ASCII string. If a reference to a varlist member is encountered (i.e. varlist_name[subscript]), this reference is resolved, and the returned pointer *V points to a variable of type c, i, d, or f. text, nt, ipt, and term have the same roles as in evalxp_ The return value should be checked for errors. ipt is only updated when a variable is found. The parameter name is set to the final name decided on. If no corresponding variable of type c, i, d, or f exists, *V is set to the NULL pointer, and the return status is set to (errstat|undefined). Used by getvar and by evalxp.
testvar, testoverlap
VARIABLE *testvar(Varname varname); VARIABLE *testoverlap(VARIABLE *varptr); testvar : input variable name, return pointer to descriptor Differences with function 'existvar': varname must be a string, terminated with a binary zero Parameters minlevel and maxlevel are absent: all variables qualify If unsuccesful, a NULL pointer is returned. Used by evalxp testoverlap : test if the variable pointed to by varptr is an overlap variable. If so return a pointer to the actual variable, else return the input varptr.
testrange
char *testrange(VARIABLE *varptr, unsigned int4 offset); testrange : input pointer to descriptor, return pointer to variable. offset (input) is displacement in array index units. If offset is out of range the null pointer is returned. Used by evalxp.
DAT, ddat
double DAT(VARIABLE *V, int4 indx); double ddat(VARIABLE **pV, int4 *pindx) Pick up array element V[indx], of a numerical variable V. The input parameter V is a pointer to V's descriptor. The result is returned as a 'double float' value This function may be used if the type of variable ('i', 'f', 'd') does not matter, and if the utmost in speed is not required. At every call a check is made whether index is within the allowed range. If not, an error exit occurs via eruit. ddat: Interface between DAT and Fortran. Example of use: DOUBLE PRECISION DDAT INTEGER PV CHARACTER*11 PROMPT, SPNAME DATA PROMPT/'inp.array:'/ CALL ITXTOSTR_(PROMPT,PROMPT) CALL XGETSP(PROMPT, PV, SPNAME, LEN) [ check value of LEN ] DO 80 J=0,LEN SP(J)=DDAT(PV,J) 80 CONTINUE
storeDAT, putinsp
void storeDAT(VARIABLE *V, int4 indx, double value); void putinsp(VARIABLE **pV, int4 *pindx, double *pvalue); storeDAT: Store value in array element V[indx], counterpart of function DAT. putinsp: Fortran wrapper for storeDAT. Example: INTEGER PV [ set PV using xgetsp, see the example of ddat above ] ... CALL PUTINSP(PV,indx,dble(value))
valtovar
void valtovar(char *vartext, double dvalue); Store dvalue in a CIO variable of type 'd' 'f' or 'i'. The variable is specified by the string vartext, which contains the name of an existing variable, optionally followed by a subscript. The subscript should be a valid expression enclosed by []. Example: list[j+5]. See also varstore. Differences: the variable must exist, it may be of any numerical type, it may be subscripted.
vargetc, vargeti, vargetd, vargetf, vargetv
char *vargetc(VARIABLE *varlink, Varname name, int4 *nelements); int4 *vargeti(VARIABLE *varlink, Varname name, int4 *nelements); double *vargetd(VARIABLE *varlink, Varname name, int4 *nelements); float *vargetf(VARIABLE *varlink, Varname name, int4 *nelements); Varname *vargetv(VARIABLE *varlink, Varname name, int4 *nelements); vargetc : get pointer to a an array of char vargeti : get pointer to an int, or an array of int vargetd : get pointer to a double, or an array of double vargetf : get pointer to a float, or an array of float vargetv : get pointer to a variable of type 'v', i.e. an array of Varnames. Input arguments are the list pointer varlink, and the variable's name. Output argument nelements is a pointer to the number of elements of the variable. The return value is a pointer to the variable itself. If the variable does not exist, or is of the wrong type, the NULL pointer is returned.
getvarpointer
char *getvarpointer(VARIABLE *varlink, Varname name, char *type, int4 *size); getvarpointer : get pointer to a variable or array of any type. Input arguments are the list pointer varlink, and the variable's name. Output arguments are (pointers to) the variable's type and size. The return value is a pointer to the variable itself. If a pointer to the variable's descriptor is wanted one should use retrieve, see below.
retrieve
VARIABLE *retrieve(VARIABLE *varlink, Varname vname,char *vtype, char **vvalpt, unsigned int4 *vsize); function retrieve : get a variable from the list Input arguments are the name of the variable vname, and the list pointer varlink. Output are pointers to the variable and its size in bytes. The return value is a pointer to the variable descriptor. Called by getvarpointer.
Utilities for CIO variables
varcleanup, forgetvar, forgetvarl, globalvar, keepvar, xkeepvar, checkvar, varsize, listvar, listVAR, prodir, and filetovarvarcleanup
void varcleanup(int varlevel); Delete all variables with level >= varlevel.
forgetvar, forgetvarl
void forgetvar(Varname vname); void forgetvarl(Varname vname, int varlevel); Delete the local variable with name vname. forgetvar(varname) is equivalent with forgetvarl(varname, VARLEVEL), see below. The request is only accepted if the variable's level >= varlevel. To allow deleting local variables only, set varlevel = VARLEVEL. To allow also deletion of global variables, varlevel=1. To allow deletion of 'permanent' variables, set varlevel = 0. If the variable specified by varname does not exist, no error condition occurs. If the variable exists, but can not be deleted an error exit occurs.
globalvar
int4 globalvar(char vartext[]); Make a variable global, as in command keep -g. No action if the variable is already global or permanent. See also keepvar and xkeepvar, below.
keepvar, xkeepvar
int4 keepvar(char vartext[]); int4 xkeepvar(char vartext[]); Make a variable more or less permanent, as in command keep -p. vartext contains the name of a CIO variable. Nothing happens, and a 0 status is returned, if the variable is already permanent. keepvar returns an error status if the variable does not exist (errstat|varnamerr), or if a different variable of the same name is already permanent (errstat|conflict), but leaves the error handling to the calling program. xkeepvar takes an error exit via eruit on these error conditions.
checkvar
void checkvar( VARIABLE *varpt, int type, int4 nelements); Checks if the CIO variable pointed to by varpt is of the type specified by type ('d', 'i' ...) and is sufficiently long to contain at least nelements elements of this type. Useful in combination with xgetvar; see Section I.
varsize
int varsize(int type); Returns the length in bytes of an elementary variable of type, where type = 'c', 'd', 'f', or 'i'.
listvar, listVAR
void listvar(VARIABLE *varlink); int listVAR(void); List currently defined variables. listVAR() is equivalent to listvar(VARLINK).
prodir
char *prodir(char *buffer, char *name); Construct a directory name from the environmental variable given in name, postfixed with "/pro". For instance name contains "HOME". Then the string returned in buffer is the explicit name equivalent to $HOME/pro.
filetovar
int4 filetovar(char *name, char *extension, char **dirlist, char *subfile, int qwipe, int qload, int qlist, char *myvarname); First search for a file specified by the arguments (see searchfile), then, if qload is true, copy the contents of the file to a variable of type char and name 'myvarname'. However, if parameter myvarname contains the NULL pointer, or points to an empty string, the variable name is derived from 'name' or 'subfile'. Return the status (0 is success). If subfile is non-NULL, a subfile of the file found is used. Such a subfile should be preceded by a header line ####<subfile name> and terminated by another line beginning with ####, or end-of-file. If qwipe is true (non-zero) a variable of the same name will first be deleted, if it exists. If qload is true (non-zero) the variable is loaded into memory. If qlist is true (non-zero) the 'subfile names', i.e. lines starting with #### will be listed.See also searchfile, set_Dirlist
V. File manipulation
Files may be opened by the user of the program and associated with a unit number, LU. This LU is not identical to the Unix file designator, but similar to the Fortran unit number. The user can select both the LU and the corresponding file name. In further commands, only the LU has to be specified. For text files that are to be read line by line, one and the same file can be shared by MSDOS, OS-9 as well as Unix computers, when function ugets is used. In combination with NFS this prevents the need to maintain more than one copy of scripts, help files and the like. To open such a file in a C program, use 'ufopen', see below. Data files, consisting of "spectra", i.e. arrays of integers, may be stored and retrieved in packed binary format. This format is identical to the one used during over ten years on the Perkin-Elmer computers. Each spectrum in a file is associated with a sequence number, and the complete specification of the spectrum in the file is thus the combination of LU and sequence number. For each spectrum the file contains a label record where useful information concerning the spectrum is recorded.
General
ufopen, ugets, searchfile, set_Dirlist, filelen, expandfn, and fexpandfnufopen
FILE *ufopen(char *filename, char *mode) Universal substitute for fopen, for UNIX, OS9 as well as MSDOS. All CIO routines that open a file use function ufopen. For Unix and OS9 ufopen behaves exactly as the standard function fopen. For MSDOS it appends a 'b' to the mode, ensuring a consistent way of handling end-of-line sequences.
ugets
char *ugets(char *ptr, int4 cnt, FILE *fp); Universal substitute for fgets, for UNIX as well as OS9 files. Both <return> (ctrl-M, '\013') as well as <linefeed> (ctrl-J, '\010') are considered as line terminators, so that text files prepared on a UNIX system may be read without any change on a OS9 system and vice versa. ugets() reads characters from file fp, and places them in the buffer *ptr, up to a line terminator (see above), or up to cnt1 characters. A '\0' is appended. return value : ptr after normal completion, NULL upon end-of-file.
searchfile, set_Dirlist
FILE *searchfile(char *name, char *extension, char **dirlist); search directories in dirlist for file "name.extension" if succesful, file is opened for read and fp returned. char **set_Dirlist(void); char *Dirlist[5]; The global array Dirlist[] is set by function set_Dirlist. set_Dirlist can be used as an argument in calls to searchfile and filetovar, e.g. fp=searchfile(filename, ".pro", set_Dirlist()); This list contains the entries Dirlist[0] = "."; Dirlist[1] = prodir(home,"HOME"); Dirlist[2] = prodir(group,"GROUP"); Dirlist[3] = getenv("PRO"); Dirlist[4] = NULL;
filelen
int4 filelen(FILE *fp); Get the length in bytes of a file (-1 if fp=NULL) side effect : the file is rewound
expandfn, fexpandfn
char *expandfn(char *path) void fexpandfn(char *path) Expand filenames. In string 'path' the following are substituted: $<environment var> ~<user>, when ~ is the first char of string path Substrings are terminated by a null byte, or by a slash '/'. Difference with normal shell behaviour: If $<string> or ~<string> cannot be resolved, it is left unmodified, and no error or or warning is given. expandfn : The string 'path' itself is not modified. The return value is a pointer to the modified string, which remains available until the next call of expandfn. Used by most file handling routines of CIO. fexpandfn : In this case the expanded filename replaces the original string 'path'.
Packed binary spectrum files
cputsp, getsp, printlabel, and getlabelcputsp
int4 cputsp(FILE *file, int4 *spectr, int type, LABELRECORD *label); Write spectrum to disk, in packed binary format. 'spectrum' is an array of type float or int parameters : FILE *file : pointer to output file int *spectr : pointer to the spectrum data data may be either int or float. In the last case the pointer spectr is interpreted as (float *)spectr. The actual type is specified by: int type : data type, 'i' or 'f' (for int or float), or 'r' (raw data, no packing/unpacking) LABELRECORD *label : pointer to a label structure
cgetsp
int4 cgetsp(FILE *file, int4 *spectr,int type, LABELRECORD *label, int4 seqnr, int4 nchan); Read and unpack a spectrum from a packed binary spectrum file. parameters: file, spectr, type, label : as for cputsp, see above int seqnr : sequence number on the file int nchan : array length of spectr[], the receiving spectrum
printlabel
void printlabel(LABELRECORD *labr, int shortlab); Print to stdout the contents of LABELRECORD *labr. shortlab is a switch: if true, only the seqnr and notes are printed.
getlabel
LABELRECORD *getlabel(Varname spname, LABELRECORD *labout); Get the labelrecord of a memory spectrum, return NULL if not found.
Miscellaneous routines
getbase, dinamex, and onlinehelpgetbase
char *getbase(char *name, char *basename); Copies string name to string basename with directories and .ext stripped. Returns the pointer *basename. Example: input: *name = "/hp3/evert/pro/klad.pro" output: *basename = "klad"
dinamex
void dinamex(char *dir, char *name, char *ext, char *path); function: build a path name out of the strings dir, name, ext The result is returned in path. "name" is prefixed with "dir/" (or "dir" if "dir" ends with '/') This step is omitted if "name" already contains a '/'. Then "name" is postfixed with "ext" ("ext" assumed to start with '.') This step is omitted if "name" contains a '.' not followed by a '/'.
onlinehelp
int onlinehelp(char **filenames); The utility onlinehelp provides a way to show online help on the console, in response to a command HELP <mnemonic>. The verb HELP is supposed to be processed before calling onlinehelp. The user is asked by "onlinehelp" for a mnemonic. This mnemonic is checked against the global command list "command", and if recognized as a valid command, the corresponding section is looked up and displayed on the screen. If, instead of a mnemonic, the user types an empty string or a "*", listcom() is called and the command list is displayed. The argument filenames is an array of pointers to file names, terminated by a NULL pointer. The files specified by each filename should have a structure as follows: A section starts with a line containing "****" in columns 1,2,3,4 and the command name in columns 5 and further. Following lines contain the help text and are displayed by "onlinehelp". The return code is non zero if the file filename could not be opened, or an invalid mnemonic was given by the user, or no help was found for a valid mnemonic. For an example of use, see aphelp. In addition to one of the valid commands, <mnemonic> may also be one of a list of subcommands specified in the help file itself. To enable this extra feature, the first line of the helpfile should contain a list of these extra subcommands. Mnemonics in this list are separated by a non-alphanumeric character and the list is terminated by two such characters in sequence, or by end-of-line. In the mnemonic, specify required letters by capitals, optional letters by lower case. The total list should not exceed LINE_LEN ( = 256)See also aphelp and CIO help
Logical units
luname, lu_close, lu_open, lu_rewind, and lu_initLogical units provide a way for file/device independent IO programming. A file is accessed by its logical unit number, and the association between logical unit number and actual file or device name is made by the user. Some commands pertaining to logical units are given in this section. Some global parameters, specified in cio.h (see Appendix A), associated with logical units: FILE *lu[MAXLU]; char lumode[MAXLU]; char fname[MAXLU][80];* See also function asklu
luname
char *luname(int lunr); input is lunr, returned is a pointer to the corresponding filename (an expanded version of fname[lunr])
lu_close, lu_open, lu_rewind
int4 lu_close(int lunr); int4 lu_open(int lunr, int filetype, int readonly); int4 lu_rewind(int lunr); The actions of lu_close() and lu_rewind() are self evident. lu_rewind() may also be used to test if a LU is opened. In that case the return code is 0, if not the value 1 is returned. lu_open requires the file to exist if readonly is true. If readonly is false (0) it will create the file if necessary. The valid values of filetype are as specified in cio.h, (ASCIIFILE, GETSPFILE). If the file is an ascii file, the file pointer is at the begin of the file, whether or not readonly is true. If the file is a 'getsp' spectrum file, and a new file is created, an initial labelrecord is written. If lu_open fails, a negative value is returned, on succesful return the return value is 0.
lu_init
int4 lu_init(char ftype[MAXLU]); lu_init is intended for use at the startup of an application program, to open files specified via start options. It will open all the files whose names are given in the global array fname[MAXLU]. The filetype and write permission are specified in ftype[MAXLU]. See main program control.c for an example of use.
VI. Error handling
eruit, ieruit, eruit_, xprinterr, and printerrSee also error handling
eruit, ieruit, eruit_
void eruit(char *control_string, char *value); void ieruit(char *control_string, int4 value); void eruit_(char* text, int ntext); Display an error message and return to main() via longjmp: - leave the current command - discard possible unprocessed ("typed ahead") command input - terminate processing of scripts eruit, ieruit: control_string : a control string, suitable for printf(), containing at most 1 %format descriptor value : the second argument for printf(), type 'char *' for eruit, 'int' for ieruit Examples: ieruit("cgetsp: seqnr %d not found",seqnr); eruit("cputsp: write error",NULL); eruit_ : write text, then take an error exit. Fortran callable variation of eruit().
xprinterr, printerr
int4 xprinterr(int4 stat); int4 printerr(int4 stat); Display error messages, depending on bits in stat. Do nothing when stat = 0. xprinterr : When (stat & errstat), in other words, when stat < 0, eruit is called and no return occurs. Example: if(stat & errstat) xprinterr(stat); printerr : In contrast with xprinterr, printerr always returns to the calling statement.
VII. Ready made commands
Any int function with 0 or 1 int arguments, such as cls(), can be used as a command, by incorporating it in the command list. The following are specifically made for this purpose.
Program flow
cwhile, cendwh ... cif, cendif
int cwhile(), int cendwh(), int crepeat(), int cendrep(), int cdo(), int cenddo(), int cif(), int cendif() This group of procedures carries uit the CIO commands 'while', 'endwhile', 'repeat', 'endrep', 'do', 'enddo', 'if', 'endif'. When any of these commands are incorporated, they should be specified as the first entries in the command list. Global variable 'nbreak' should be set equal to the number of commands from this group. The CIO procedure mojump will do this automatically if nbreak is given an initial value less then or equal 0. See program control.c for an example.
errout
int errout(void) Command ERROR For user defined error exits in CIO scripts. Read a text from the input stream (presumably a CIO script), write this text, then take an error exit.
cio_exit
int cio_exit(int internal) Command EXIT. Leave a cio script. The parameter internal = 0 when invoked by command 'exit', and 1 when invoked internally, e.g. due to end-of-file.
cio_stop, ap_stop
int cio_stop(void) int ap_stop(void) Command STOP Print " ... program quitting ... " and leave the program. ap_stop : If the program uses grint graphics a call ap_stopgrint(0) is required. ap_stop combines ap_stopgrint and cio_exit. Note: It may be useful to make a customized version of the procedure to be called by command STOP.
File manipulation
ap_open, ap_close, ap_dlu, and ap_rewindap_open
int ap_open(void) command OPEN Open a file and associate it with a logical unit (LU).
ap_close
int ap_close(void) command CLOSE Close file and LU.
ap_dlu
int ap_dlu(void) command DLU Display logical units.
ap_rewind
int ap_rewind(void) command REWIND Rewind the file associated with a logical unit (LU).
File input and output
ap_get, ap_put, ap_lablst, spcopy, ap_xex, ap_import, and read_asciap_get
int ap_get(int opt) command GET Ask the necessary input, then read a spectrum via cgetsp. If opt is 'r', raw data are read (no packing/unpacking).
ap_put
int ap_put(int opt) command PUT Write a spectrum to disk, via cputsp. If opt is 'r', raw data are written (no packing/unpacking).
ap_lablst
int ap_lablist(void) command LABLST List the labels on a spectrum file, associated with a given LU.
spcopy
int spcopy(void) Command SPCOPY Copy spectra from one spectrum file to another.
ap_xex
int ap_xex(void) command XPORT Output data in ASCII form, suitable for processing by xgraph.
ap_import
int ap_import(void) Command IMPORT Read numerical data from an ASCII file. The file should be in xgraph format, and should be previously opened and associated with a LU number.
read_asci
int read_asci(void) Command RDAscii Read numerical data from an ASCII file. The file should be previously opened and associated with a LU number. More versatile then ap_import.
CIO variables
setvarlst, setvar, overlap, listVAR, wipeout, keepm, and xctloadsetvarlst
int setvarlst(void) command VAR Declaration of variables of type 'v'.
setvar
int setvar(int type) commands INT, DOUBLE, FLOAT, CHAR and ALIAS. Define variables of type int, double, float or char. int type should be set to 'i', 'd', 'f' or 'c' or 'C'. Options 'c' and 'C' are equivalent, only the prompt is different.
overlap
int overlap(void) command OVAR Declaration of variables of type 'o'.
listVAR
int listVAR(void) Lists the currently defined variables.
wipeout
int wipeout(void) command WIPE Delete variable(s).
keepm
int keepm(void) command KEEP Promote temporary variable to permanent or to global variable
xctload
int xctload(int mode) commands LOAD and LGO Load a CIO script, and store it in a variable of type char. If mode = 1 : immediately start execution (LGO command).
Spectra residing in memory
ap_defsp, ap_undef, ap_spl, ap_prlab, get_sp, def_sp, and undef_spap_defsp
int ap_defsp(void) command DEF Define spectra in memory.
ap_undef
int ap_undef(void) command UNDEF Delete spectra from memory, and free the memory space.
ap_spl
int ap_spl(void) command SPLIST List the currently defined memory spectra.
ap_prlab
int ap_prlab(void) command PRLAB List the labels of spectra present in memory.
get_sp
spectrum *get_sp(char *sp_name) Get the pointer to a struct spectrum, given it's name.
def_sp, undef_sp
spectrum *def_sp(Varname sp_name, int4 sp_len, int sp_type, int O_exist, int O_common); int undef_sp(Varname sp_name); def_sp : Define a spectrum (called by ap_defsp) sp_name : the spectrum name sp_len : length, in channels, of spectrum sp_type : 'i' of 'f' O_exist : if true, the numerical array of the same name exists already, but is not yet defined as a 'spectrum'. O_common: for future use. undef_sp: Remove a spectrum from the list of spectra, and also delete the associated CIO array. Called by ap_undef.
Operations on arrays of variables
uno, duo, trio, functions used by uno/duo/trio, ap_move, shiftsp, ctr, ctrinp, ctroutp, interpol, and erpoluno
int uno(int option); commands RESET, SUM, INC, MINMAX, NORM, TRUNC, MULR, INPUT, TYPE Manipulate arrays. valid options for arrays of type char: u_reset : set all array elements to '\0' u_type : write the array to stdout u_input : read the array, using xgetrawline valid options for numerical arrays (type 'd' 'f' or 'i'): u_reset : set all array elements to zero u_sum : calculate and display the sum over a specified region u_inc : increment a specified region with a specified increment u_minmax: calculate and display, for a specified region, the minimum, the maximum, the sum and the average. u_norm : normalizea an array such that the sum over a specified region becomes equal to a specified value u_trunc : truncate a specified region, to specified values of min and max. Values > max are set to max, values < min are set to min u_mult : multiply a specified region by a constant factor. u_input : input a specified region, from stdin. u_type : output to stdout of a specified region.
duo
int duo(int option); commands MULT, VSQRT, VLN, VLOG, INTEG, DIFFER Array processing B := f(A) valid options for numerical arrays (type 'd' 'f' or 'i'): d_mult : multiply A by constant factor d_sqrt : square root of A if (A[i] < 0) B[i]:= -sqrt(-A[i]) d_ln : natural logarithm d_log10 : 10log d_int : integral d_diff : first derivative type of A: 'f' or 'i', type of B: 'f'
trio
int trio(int option); commands ADD, SUB, ADDF, MULS, DIVS Array processing C[i] := A[i] (operand) B[i] valid options, for numerical arrays (type 'd' 'f' or 'i'): t_add : A[i] + B[i] t_sub : A[i] - B[i] t_fradd : A[i] + f*B[i] t_muls : A[i] * B[i] t_divs : A[i] / B[i]
functions used by uno/duo/trio
double spsum(int4 *sp, int4 len, int type); void reset(int4 *sp, int4 len, int type); void spinc(int4 *sp, int4 len, int type, double inc); double minmax(int4 *sp, int4 len, int type, double *min, double *max, int4 *chmin, int4 *chmax, double *aver); void spmult(int4 *sp, int4 len, int type, double factor); void sptrunc(int4 *sp, int4 len, int type, double min, double max) double spzero(int4 *sp, int4 first, int4 last, int type, int csign, int4 *Nzro, float *store, double Noise); void differentiate(float *fsp[2], char type[2], int4 minlen, int4 ns)
ap_move
int ap_move(void) command MOVE Move data from one array to another.
shiftsp
int shiftsp(void) command SHIFT Move data from one array to another, with possibility of stretching and compressing the distribution.
ctr, ctrinp, ctroutp
int4 ctr(VARIABLE *V, int4 mark[6], float abc[4], float err[4]); int ctrinp(void) int ctroutp(int4 ier, VARIABLE *V, int4 mark[6], float abc[4], float err[4]); ctr : Compute the area and centroid of a peak in a spectrum. V is a pointer to the array descriptor of a numerical array. Array mark contains 6 indices (channel numbers) of the array. Two background regions are defined by mark[0] to mark[1] and by mark[4] to mark[5]. The peak region is mark[2] to mark[3]. A straight line is fitted through the background, and the centroid and area of the background corrected peak are calculated. On return, abc[0] = area, abc[1] = background, abc[2] = centroid, and abc[3] = estimate of width. err[0] to err[3] contain the corresponding error estimates. Return value: 0 in normal cases, -1 = error, +1 = warning. Note. The estimate of width is calculated assuming a gaussian peak. In other cases this number should not be trusted. ctrinp : command CTR. Asks the necessary input, then calls ctr and ctroutp. ctroutp : Output results of the calculations made by ctr.
interpol, erpol
double interpol(double x1, float x[], float y[], int4 n) int erpol(void) interpol : quadratic interpolation x[n] is an array of x-values, y[n] an array of y-values. y1 = interpol(x1,x,y,n) returns the value of y corresponding to x1, i.e. y1=y(x1). Both arrays x and y should be monotonously increasing or decreasing. No extrapolation is done. If extrapolation is attempted, the value at the the end of the range (either y[0] or y[n-1]) is returned. erpol : command INTERPOL. Takes care of necessary input, and then calls interpol.
Evaluation of expressions
kalk and printexprkalk
int kalk(int mode) Calculator This routine is entered by command KALK (with mode = 0) but also if the program expects a command, but obtains a text that is found to be a numerical variable. Then, kalk is entered with mode = 1 and the text is subsequently interpreted as an expression. mode 0 : command kalk. verbose mode 1 : command eval. silent mode
printexpr
int printexpr(void) command PRINTX Display the resulting value of an expression.
Assorted commands
printtext, sprinttext, fprinttext, aphelp, ap_system, ap_shell, ap_edit, ap_more, ap_dir, bekijkm, and ap_sleepprinttext
int printtext(void) command PRINT Display a formatted line of text.
sprinttext
int sprinttext(void) command SPRINT Store a formatted line of text in a char variable.
fprinttext
int fprinttext(void) command FPRINT Write a formatted line of text to an ascii file.
aphelp
int aphelp(void) command HELP Calls function onlinehelp(helpfiles), see Section V. The application programmer should define the list of files to search, with a global list pointer named helpfiles, e.g. char *helpfiles[] = { "/hp3/peter/cio/ciohlp.html", "/hp3/peter/cio/control.hlp", NULL}; ... aphelp(void);See also onlinehelp
ap_system
int ap_system(void) command SYS. Get a line of text from the input stream, and process it as a shell command. This command may be used for an arbitrary shell command. For some shell commands special CIO commands are available, see e.g. ap_edit, ap_dir and ap_sleep
ap_shell
int ap_shell(void) command SHELL. Fork a shell, as specified in environmental variable SHELL. Subsequent intput is interpreted as shell commands. Return to the calling program occurs after logging out of this shell.
ap_edit, ap_more
int ap_edit(int iopt) int ap_more(char *filename) ap_edit : iopt=0: view a file (command MORE) iopt=1: edit a file (command EDIT) iopt=2: view current CIO program (command MP) iopt=3: edit current CIO program (command EP) ap_more : A simple text viewer, that is called by ap_edit, options 0 and 2, but only if the symbol BUILTINMORE is defined at compilation of the CIO library. Otherwise an external viewer will be called.
ap_dir
int ap_dir(int iopt) iopt=0: change working directory (command CDIR) iopt=1: list directories (command DIR)
bekijkm
int bekijkm (char *filename, char *env, char *defcmd); Used by ap_edit. String env contains the name of an environmental variable (e.g. "EDITOR"), defcmd contains a unix command (e.g. "vi"). A command is composed of the filename, preceded by the variable specified by env, or if the variable is not found, by defcmd. This command is executed by the shell.
ap_sleep
int ap_sleep(void) Asks for an integer number of seconds, then calls sleep(seconds).
VIII. Graphics
waitgrint, init_graph, init_picture, wr[xsver]data, ap_graph, ap_display, ap_displayv, ap_dix, ap_grint, ap_plot, ap_cur, ap_map, ap_mapopt, ap_redraw, and ap_stopgrintThe following routines make use of the GRINT package. The basic routines istartgrint, iwr_grint, ire_grint, iflush_grint, close_grint and destroygrint, not described here, come in two versions: The routines required to communicate with program grint on the local host are included in the CIO library. However, if program grint is run on a remote machine, use instead the set of rgrint routines (source files rgrint.c, rgrint_clnt.c, rgrint_xdr.c). The calling sequence for both alternatives is the same.
waitgrint
void waitgrint(void) Synchronize to grint: wait until program grint is finished with buffered output.
init_graph
void init_graph(void) Start grint. No further init_graph calls are needed, unless ap_stopgrint is called.
init_picture
void init_picture(void) Initialize a new picture. Closes the current picture, if any.
wr[xsver]data
All of the following write npts data points to grint, making use of the global variable ifrom. The difference is in the type of the the arrays (float, or CIO variable of arbitray type), and in the amount of values per data point [(x,y), (x,y,error), or (y)]. void wrxdata(int4 npts, float *xas, float *spectr); void wrerdata(int4 npts, float *xas, float *spectr, float *errors); void wrvdata(int4 npts, VARIABLE *xas, VARIABLE *spectr); void wrsdata(int4 npts, VARIABLE *spectr); extern int ifrom; Writes npts data points (xas[j+ifrom], spectr[j+ifrom]) to grint. wrxdata : xas and spectr are given as float arrays wrerdata : xas, spectr, errors, specified as float arrays wrvdata : xas and spectr are given as pointers to CIO variables. The data type of the actual arrays may be int, float, or double. wrsdata : Data specified as CIO variable, x coordinates default to ifrom+j.
ap_graph
int ap_graph(void) Draws a graph, as specified by the input of commands DIS and/or DIX.
ap_display
int ap_display(int disopt) disopt = 0 : command DIS. Display a spectrum (by a series of requests to grint). Parameters, asked from the input stream by ap_display(0): - spectrum_name, first_channel_number, last_channel_number. - zero or more options. Some possibilities: SCL ymin ymax set vertical scale SYM symbol_nr plot symbols SAF plot in SAme Frame, and with the same scale disopt = 1 : command GRINT, see ap_grint disopt = 2 : call via command slice disopt = 3 : call via ap_displayv
ap_displayv
int ap_displayv(VARIABLE *pV, int4 from, int4 to); Wrapper to call ap_display from a C program.
ap_dix
int ap_dix(void) command DIX. Ask input, then display a spectrum, in the current picture. Parameters, asked from the input stream: - spectrum_name. - zero or more options, such as SYM symbol_nr.
ap_grint
int ap_grint(void) command GRINT. Ask parameters and options for graphics display. Some possible options: FONT font_nr specify font for texts IDEV idev idev=0: don't make a plot file idev=10: do make a plot file (default) HOST host_name specify host for remote grint no effect for local grint. When remote grint is used (such as on an OS9 system) the host_name should be specified before the first display request. When idev=0, the display may be somewhat faster. However, command PLOT is ineffective in that case.
ap_plot
int ap_plot(void) command PLOT. Request grint to keep plotfile output of the current picture. A current picture must be defined, i.e. the command may be given any time after opening a picture, but before closing it.
ap_cur
int ap_cur(void) command CURSOR Starts Graphics Cursor Input Mode. Activate graphics cursor, and wait for user response. Reacts to subsequent hitting of keyboard keys and mouse buttons. Return cursor coordinates.
ap_map
int ap_map(void) Display a 'false color' map of a two-dimensional spectrum.
ap_mapopt
int ap_mapopt(void) Asks the user for options for ap_map(), i.e. command MAP.
ap_redraw
int ap_redraw(void) Send a REDRAW request to grint.
ap_stopgrint
int ap_stopgrint(int ipost) Stops program grint. ap_stopgrint should be called just before a program terminates. Also called by command GEPPOST. If ipost is non-zero, a directive is sent to grint causing the plotfile to be post-processed.
IX. Miscellaneaous
getcommandline, initf, and mojumpgetcommandline
int getcommandline(int argc, char **argv, char *line, int MAX); Get the parameters of the UNIX command given to start the program and store them in array line[MAX] of type char. argc and argv are the standard arguments of main(argc,argv). return value: the total length of the command line arguments.
initf
int initf(void) This routine, that should be called only once in a program, sets up a handler to intercept the "keyboard interrupt signal", generated when ctrl-C is typed. Subsequently, the effect of ctrl-C is similar to a call of eruit, see Section VI.
mojump
int mojump(int val); Command processor. Mojump expects that the program contains an array of commands, named command, i.e. COMMAND command[], see struct COMMAND below. The order of the commands is free with the exception that the flow controlling commands, such as while, if, repeat, do, endif, endw, endr, endd should be the first ones, and the last one of this group is one of the commands endif, endw, endr, endd. void (*FIRST_PROC)() and void (*SECOND_PROC)() are pointers defined in CIO, initially set to NULL. At the first call mojump does some initializing, and calls procdure (*FIRST_PROC)(), if set. At subsequent calls, before processing a command (*SECOND_PROC)() is called, if set.
APPENDIX A. Structures and types
Some type definitions typedef struct { char *keyword; /* pointer to keyword string */ int (*function)(); /* pointer to function returning int */ int argument; } COMMAND; typedef char Varname[9]; /* variable name (string) */ typedef struct var { Varname name; /* variable name */ char type; /* c, i, f, d */ char level; /* VARLEVEL, 0=permanent */ char mtype; /* Reserved */ int4 size; /* size in bytes */ char *valpt; /* pointer to contents */ struct var *next; /* pointer to next var */ int4 base; /* room for variable value */ } VARIABLE; typedef struct { Varname parent; /* original name */ int4 offset; /* offset in units of elementary variable */ int4 nelements; /* number of elements */ VARIABLE vardes; /* room for variable descriptor */ } overlapvar; typedef struct { int4 seq; /* sequence number */ int4 extranum; /* extra number to identify set of spectra */ int4 length; /* length of spectrum (in channels) */ int4 seconds; /* duration of measurement in seconds */ int4 day; int4 month; int4 year; /* day, month, year of data acquisition */ int4 rtime; /* real time clock */ int4 ltime1; /* live time clock */ int4 ltime2; /* second live time clock */ int4 ltime3; /* third live time clock */ int4 offset; /* offset subtracted of each channel */ int4 factor; /* multiplier applied before packing */ /* the above are set by the program calling PUTSP, the next items, i.e. nbits .. lastnz, are determined by PUTSP */ int4 nbits; /* number of bits of each channel */ int4 nrecords; /* number of 256-byte records written */ int4 lastnz; /* last channel not containing zero */ float rlab; /* 16 single float numbers R-var's */ char notes[128]; /* descriptive text */ } LABELRECORD; typedef struct sp_type { Varname name; LABELRECORD lab; int4 length; char sptype; struct sp_type *next; struct sp_type *previous; } spectrum; Some general definitions: #define true 1 #define false 0 #define NOTHING 0x80000000 /* default default values */ #define DNOTHING -1.0E+300 #define EPS 1.0e-12 /* estimated "double" accuracy */ #define twoxx32 0.4294967296e10 /* 2^32 as a "double" constant */ #define twoxx31 0.2147483648e10 /* 2^31 as a "double" constant */ Some global variables: For an up to date list, check modules cio.h and global.c char *PROGRAMNAME; VARIABLE *VARLINK; int VARLEVEL; jmp_buf environment; char *INPUTchpt,INPUTline[LINE_LEN],INPUTEOL,INPUTEOK,CMDLINE,ITRACE,ISTEP; int INPUTlen, INPUTpt; CONTEXT contexts[maxcontexts]; int ncontext; char controlstack[Ncontrolstack]; int controlpointer; char breakflag; spectrum *sp1; Definitions and variables related to LU's #define MAXLU 16 FILE *lu[MAXLU]; char lumode[MAXLU]; char fname[MAXLU][80]; lumode[lunr] is either CLOSED (=0), or contains a combination of the following flags: #define CLOSED 0 #define OPEN_READ 1 #define OPEN_RW 2 #define ASCIIFILE 16 #define GETSPFILE 32 #define PEGETSPFILE 64
APPENDIX B. Programming notes
a. Minimum requirements. When incorporating CIO routines in a program that has a fixed flow scheme, special adjustments are needed when the CIO routines have possible error exits. A simple strategy for error recovery may be obtained with the CIO function ciobeg. With this routine one supplies a function to be called after CIO errors. An example in Fortran follows: PROGRAM MAIN CALL SUB() END SUBROUTINE SUB() LOGICAL INIT SAVE INIT DATA INIT / .FALSE. / EXTERNAL CIORESET IF(INIT)GOTO 66 CALL CIOBEG(SUB) [ put once only stuff here] INIT = .TRUE. C C return here after cio errors 66 CONTINUE [ ... ] A simpe example in C language: #include <cio/cio.h> error() { /* come here on input (and possibly other types of) error */ printf("ERROR\n"); exit(1); } main() { ciobeg(error); [ ... rest of the program ... ] } b. Fully interactive programs. The CIO procedures are well suited for the type of program where the program flow is decided on by the user at run time. With the CIO command language it is possible for the user to implement simple as well as elaborate algorithms. For the application programmer, we recommend the use of the 'standard' CIO routines main() and mojump(). A file specifying the commands to be included should be made. The module control.c (contained in the source file, see below) may be used as a template. The command should be declared in an extern statement, and also included in the command list, by a line of the form: "MNEMonic", command, arg, where "MNEMonic" stands for the mnemonic, by which the user may access the command (required letters in capitals, optional letters in lower case), command is the name of the function to be called, and arg its argument: int command(int arg) The return value is currently not used. The argument may be used to distinguish between different cases handled by the same function. Example: "CHAR", setvar, 'c', "DOUBLE", setvar, 'd',
Programming examples
A repeating command
The following two functions implement a command with a variable number of arguments. From the user point of view the two functions behave differently when an end-of-line is given. The input of res1() may occupy several lines. When an end of line is given the prompt is repeated, and the command is normally only terminated when an empty line or a semicolon is encountered. res1() { char spname[9]; VARIABLE *ptr; while(true) /* loop */ { xgetvar("spectrum name:",&ptr,spname,false); if(!(*spname)) break; /* exit when no name given */ reset(spname); /* process spname */ } } In the following version the prompt is reset in the first pass. As a result, the input of res2() occupies at most two lines. If any arguments are given on the command line, only the command line is processed. If, on the other hand, the command is directly followed by an end-of-line, the prompt is output, a new line is read, and this line only is processed. res2() { char spname[9], *prompt="spectrum name:"; VARIABLE *ptr; while(true) { xgetvar(prompt,&ptr,spname,false); if(!(*spname)) break; reset(spname); prompt=NULL; /* now xgetvar will not read a new line */ } } The technique illustrated in res2() may be used for all functions based on getargtext, i.e. all routines whose name starts with get or xget or cget.
See also
The cio syntax is described in CIO command languageFiles
$GROUP/lib/libcio.a precompiled procedures of CIO /hp3/peter/cio/ciohlp.html online help file An organized collection of the source files may be found in subdirectories of /hp3/peter/cio/source. subdir contents ================================================================ general the most basic parts of CIO are in this directory tools some less essential parts The division between general and tools is quite arbitrary. putget things that have to do with CIO binary spectrum files graphic things that have to do with graphics menu things that have to do with the menu frontend mains Make files for different architectures (hp, sgi) and main program control.c Note: different applications (control, mctl, pctl) may be generated by twiddling the makefiles. See the 'ifdefs' in control.c aux obsolete functions, and new functions that require further testing. control specific commands for program control mos things particular to program mctl pac things particular to program pctl fit package for non-linear least squares, used by mctl and pctl. include include files for CIO and applications include/cio include files for CIO itself. Alternative location of the source files: $GROUP/cprogr/sourcecio.a source of CIO functions This file is in ar format. To extract a module, give ar x $GROUP/cprogr/sourcecio.a <module(s)> $GROUP/include/cio/cio.h include file