Files
sicspsi/hardsup/c_interfaces.c
2009-02-13 09:01:24 +00:00

499 lines
17 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#define ident "1A05"
#ifdef VAXC
#module C_INTERFACES ident
#endif
#ifdef __DECC
#pragma module C_INTERFACES ident
#endif
/*
** +--------------------------------------------------------------+
** | Paul Scherrer Institute |
** | Computing Section |
** | |
** | This software may be used freely by non-profit organizations.|
** | It may be copied provided that the name of P.S.I. and of the |
** | author is included. Neither P.S.I. nor the author assume any |
** | responsibility for the use of this software outside of P.S.I.|
** +--------------------------------------------------------------+
**
** Module Name . . . . . . . . : [...LIB.SINQ]C_INTERFACES.C
**
** Author . . . . . . . . . . : D. Maden
** Date of creation . . . . . . : Nov 1993
**
** C_INTERFACES.C provides some routines which make it easier for C programs
** to call some of the Fortran routines in SINQ.OLB.
**
** To include this module in SINQ.OLB, use:
$ import tasmad
$ define/job sinq_c_tlb mad_lib:sinq_c_tlb.tlb
$ define/job sinq_olb mad_lib:sinq.olb
$ @lnsa09::tasmad_disk:[mad.psi.lib.sinq]sinq_olb c_interfaces debug
$
$ define/job sinq_olb mad_lib:sinq.olb
$ @lnsa09::tasmad_disk:[mad.psi.lib.sinq]sinq_olb c_interfaces
**
** Updates:
** 1A01 16-Nov-1993 DM. Initial version.
** 1A02 24-Nov-1994 DM. Make compatible with DEC C (as opposed to VAX C)
** 1A03 28-Nov-1994 DM. Add the TT_PORT_... entry points.
**====================================================================
** The following entry pointd are included:
** C_log_arr_get : interface routine from C to LOG_ARR_GET.
** C_log_flt_get : interface routine from C to LOG_FLT_GET.
** C_log_int_get : interface routine from C to LOG_INT_GET.
** C_log_str_get : interface routine from C to LOG_STR_GET.
**
** C_str_edit : interface routine to STR_EDIT.
**
** C_tt_port_connect : interface routine to TT_PORT_CONNECT.
** C_tt_port_disconnect: interface routine to TT_PORT_DISCONNECT.
** C_tt_port_io : interface routine to TT_PORT_IO.
** C_tt_port_config : interface routine to TT_PORT_CONFIG.
**====================================================================
** Global Definitions
*/
#ifdef VAXC
#include stdio
#include descrip
#include string
#include sinq_prototypes
#else
#include <stdio.h>
#include <sys/descrip.h>
#include <sys/string.h>
#include <sinq_prototypes.h>
#endif
/*--------------------------------------------------------------------------
** Global Variables
*/
extern int C_gbl_status = 0;
extern struct dsc$descriptor_s C_name_desc = { 0,
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
0
};
/*--------------------------------------------------------------------------
** Old-style prototypes of routines which we are
** bridging to.
*/
int log_arr_get();
int log_int_get();
int log_flt_get();
int log_str_get();
int str_edit();
int tt_port_connect();
int tt_port_disconnect();
int tt_port_io();
int tt_port_config();
/* --------------------------------------------------------------------------*/
int C_log_arr_get(char *name, int arr_size, int *value, int indx)
{
/* =============
**
** This routine is useful for calling LOG_ARR_GET from a C program.
**
** Inputs:
** name - a pointer to the zero-terminated logical name.
** arr_size - the number of elements in the array value.
** indx - the index of the logical name.
** Outputs:
** value - an array of size arr_size set to the values converted
** to binary.
** Return status:
** the return status of the function is zero (false) if LOG_ARR_GET
** returns an error (even) condition code.
** Global variables:
** C_gbl_status - set to the VAX/VMS return status of LOG_ARR_GET.
** C_name_desc - set up as a string descriptor for name. It can
** be used to generate an error message if return status == 0.
*/
C_name_desc.dsc$w_length = strlen(name);
C_name_desc.dsc$a_pointer = name;
C_gbl_status = log_arr_get(&C_name_desc, &arr_size, value, &indx);
return (C_gbl_status & 1);
}
/*--------------------------------------------------------------------------*/
int C_log_int_get(char *name, long int *value, int indx)
{
/* =============
**
** This routine is useful for calling LOG_INT_GET from a C program.
**
** Inputs:
** name - a pointer to the zero-terminated logical name.
** indx - the index of the logical name.
** Outputs:
** value - the value of the logical converted to binary.
** Return status:
** the return status of the function is zero (false) if LOG_INT_GET
** returns an error (even) condition code.
** Global variables:
** C_gbl_status - set to the VAX/VMS return status of LOG_INT_GET.
** C_name_desc - set up as a string descriptor for name. It can
** be used to generate an error message if return status == 0.
*/
C_name_desc.dsc$w_length = strlen(name);
C_name_desc.dsc$a_pointer = name;
C_gbl_status = log_int_get(&C_name_desc, value, &indx);
return (C_gbl_status & 1);
}
/*--------------------------------------------------------------------------*/
int C_log_flt_get(char *name, float *value, int indx)
{
/* =============
**
** This routine is useful for calling LOG_FLT_GET from a C program.
**
** Inputs:
** name - a pointer to the zero-terminated logical name.
** indx - the index of the logical name.
** Outputs:
** value - the value of the logical converted to binary.
** Return status:
** the return status of the function is zero (false) if LOG_FLT_GET
** returns an error (even) condition code.
** Global variables:
** C_gbl_status - set to the VAX/VMS return status of LOG_FLT_GET.
** C_name_desc - set up as a string descriptor for name. It can
** be used to generate an error message if return status == 0.
*/
C_name_desc.dsc$w_length = strlen(name);
C_name_desc.dsc$a_pointer = name;
C_gbl_status = log_flt_get(&C_name_desc, value, &indx);
return (C_gbl_status & 1);
}
/*--------------------------------------------------------------------------*/
int C_log_str_get(char *name, char *value, int val_size, int indx)
{
/* =============
**
** This routine is useful for calling LOG_STR_GET from a C program.
**
** Inputs:
** name - a pointer to the zero-terminated logical name.
** val_size - the size of the value string.
** indx - the index of the logical name.
** Outputs:
** value - zero-terminated string giving the value of the logical.
** Trailing space characters will have been stripped.
** Return status:
** the return status of the function is zero (false) if LOG_STR_GET
** returns an error (even) condition code.
** Global variables:
** C_gbl_status - set to the VAX/VMS return status of LOG_STR_GET.
** C_name_desc - set up as a string descriptor for name. It can
** be used to generate an error message if return status == 0.
*/
struct dsc$descriptor_s my_val_desc = { 0,
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
0
};
C_name_desc.dsc$w_length = strlen(name);
C_name_desc.dsc$a_pointer = name;
my_val_desc.dsc$w_length = val_size - 1;
my_val_desc.dsc$a_pointer = value;
C_gbl_status = log_str_get(&C_name_desc, &my_val_desc, &indx);
value[val_size - 1] = 0; /* Zero-terminate the string */
if (C_gbl_status & 1) { /* If success, strip trailing spaces */
while ((strlen(value) > 0) && (value[strlen(value) - 1] == ' ')) {
value[strlen(value) - 1] = 0;
}
}
return (C_gbl_status & 1);
}
/*--------------------------------------------------------------------------*/
int C_str_edit(char *out, char *in, char *ctrl, int *length)
{
/* ==========
**
** This routine is useful for calling STR_EDIT from a C program.
**
** Inputs:
** in - the string to be edited.
** ctrl - the string specifying what editing is to be done.
** Outputs:
** out - the edited string. The maximum size of this string must
** be specified as input parameter *length. The string
** will be zero terminated on return.
** Modified:
** *length - an integer specifying, on input, the length of "out" in
** bytes. This must include room for the zero termination.
** On return, length will be set to the number of characters
** copied to "out" (not counting the zero termination byte).
** Return status:
** the return status of the function is zero (false) if STR_EDIT
** returns an error (even) condition code.
** Global variables:
** C_gbl_status - set to the VAX/VMS return status of STR_EDIT.
*/
struct dsc$descriptor_s out_desc = { 0,
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
0
};
struct dsc$descriptor_s in_desc = { 0,
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
0
};
struct dsc$descriptor_s ctrl_desc = { 0,
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
0
};
out_desc.dsc$w_length = *length - 1;
out_desc.dsc$a_pointer = out;
in_desc.dsc$w_length = strlen(in);
in_desc.dsc$a_pointer = in;
ctrl_desc.dsc$w_length = strlen(ctrl);
ctrl_desc.dsc$a_pointer = ctrl;
C_gbl_status = str_edit(&out_desc, &in_desc, &ctrl_desc, length);
if (*length >= 0) { /* zero-terminate the output string */
out[*length] = '\0';
} else {
out[0] = '\0';
}
return (C_gbl_status & 1);
}
/*--------------------------------------------------------------------------*/
int C_tt_port_connect(int *hndl, int *chan, char *lognam, char *pwd)
{
/* =================
**
** This routine is useful for calling TT_PORT_CONNECT from a C program.
**
** Inputs:
** lognam - a zero-terminated string specifying a logical name which
** defines the RS-232-C port to be connected. See description
** of TT_PORT_CONNECT for full details.
** pwd - a zero-terminated string specifying an optional password.
** This is the password associated with a terminal server
** service. See description of TT_PORT_CONNECT for full
** details. Specify NULL if no password.
** Outputs:
** hndl - an integer handle identifying the connection. It will be
** the address of a dynamically allocated data structure.
** chan - an integer (actually only 16 bit) giving the I/O channel
** associated with the connection. This can be used in QIO
** system calls to the terminal driver.
** Return status:
** the return status of the function is zero (false) if TT_PORT_CONNECT
** returns an error (even) condition code.
** Global variables:
** C_gbl_status - set to the VAX/VMS return status of TT_PORT_CONNECT.
*/
struct dsc$descriptor_s lognam_desc = { 0,
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
0
};
struct dsc$descriptor_s pwd_desc = { 0,
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
0
};
lognam_desc.dsc$w_length = strlen(lognam);
lognam_desc.dsc$a_pointer = lognam;
if (pwd != NULL) {
pwd_desc.dsc$w_length = strlen(pwd);
pwd_desc.dsc$a_pointer = pwd;
C_gbl_status = tt_port_connect(hndl, chan, &lognam_desc, &pwd_desc);
} else {
C_gbl_status = tt_port_connect(hndl, chan, &lognam_desc, NULL);
}
return (C_gbl_status & 1);
}
/*--------------------------------------------------------------------------*/
int C_tt_port_disconnect(int *hndl)
{
/* ====================
**
** This routine is useful for calling TT_PORT_DISCONNECT from a C program.
**
** Inputs:
** hndl - the integer handle identifying the connection as returned
** by C_tt_port_connect. It is the address of a dynamically
** allocated data structure which will also be released
** after the connection has been closed.
** Return status:
** the return status of the function is zero (false) if TT_PORT_DISCONNECT
** returns an error (even) condition code.
** Global variables:
** C_gbl_status - set to the VAX/VMS return status of TT_PORT_DISCONNECT.
*/
C_gbl_status = tt_port_disconnect(hndl);
return (C_gbl_status & 1);
}
/*--------------------------------------------------------------------------*/
int C_tt_port_io(
/* ============
*/ int *hndl,
char *rqst, char *term, char *answ, int *answ_len, /* Attention -- Read/Write argument!! */
int flush, int tmo)
{
/*
** This routine is useful for calling TT_PORT_IO from a C program.
** Refer to the DELTAT.OLB description of TT_PORT_IO to clarify any
** uncertainties in the following description. Note that all arguments
** must be present (there is no portable method in C of getting the
** number of arguments in the call!).
** Inputs:
** hndl - the integer handle identifying the connection as returned
** by C_tt_port_connect.
** rqst - an optional zero-terminated string specifying a character
** string to be sent to the port. Specify NULL to not send
** any characters to the port.
** term - an optional zero-terminated string specifying a list of
** terminating characters for input read from the port.
** Specify NULL to terminate input on an exact character cnt.
** flush - an integer specifying if the type-ahead buffer should be
** flushed before the operation. If non-zero, the buffer
** is flushed.
** tmo - an integer (recommended value = 2) specifying a read
** time-out in seconds. Zero or negative indicates infinity.
** Outputs:
** answ - an optional string buffer to receive characters read from
** the port. If answ is not NULL, answ_len must also be
** not NULL. On return, answ will be zero terminated. The
** terminating character, if any (there is no terminating
** char if the buffer overflows) and if there is room in
** the buffer, will follow the zero character. No padding is
** done. If answ is NULL, no characters are read from the
** port.
** Modify:
** answ_len - an integer specifying, on input, the length of answ in
** bytes. This must include room for the zero termination.
** On return, answ_len will be set to the number of
** characters read (not counting the zero termination byte or
** any terminating character).
** Return status:
** the return status of the function is zero (false) if TT_PORT_IO
** returns an error (even) condition code.
** Global variables:
** C_gbl_status - set to the VAX/VMS return status of TT_PORT_IO.
*/
struct dsc$descriptor_s rqst_desc = { 0,
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
0
};
struct dsc$descriptor_s term_desc = { 0,
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
0
};
struct dsc$descriptor_s answ_desc = { 0,
DSC$K_DTYPE_T,
DSC$K_CLASS_S,
0
};
char *my_rqst = NULL;
char *my_term = NULL;
char *my_answ = NULL;
int my_answ_len = 0;
int my_flush = 1;
int my_tmo = 2;
my_tmo = tmo;
if (my_tmo < 0)
my_tmo = 0;
my_flush = flush;
if (my_flush != 0)
my_flush = 1;
if (answ != NULL) {
if (answ_len == 0) {
printf("C_tt_port_io -- argument error.\n");
printf(" %s\n",
"answ_len must be present if answ is present.");
C_gbl_status = FALSE;
return FALSE;
}
answ_desc.dsc$w_length = *answ_len - 1;
answ_desc.dsc$a_pointer = answ;
}
if (term != NULL) {
term_desc.dsc$w_length = strlen(term);
term_desc.dsc$a_pointer = term;
}
if (rqst != NULL) {
rqst_desc.dsc$w_length = strlen(rqst);
rqst_desc.dsc$a_pointer = rqst;
}
C_gbl_status = tt_port_io(hndl, &rqst_desc, &term_desc,
&answ_desc, &my_answ_len, &my_flush, &my_tmo);
if (answ_desc.dsc$w_length > 0) { /* Process any input string */
if (answ_desc.dsc$w_length > my_answ_len) { /* Room for terminator? */
answ[my_answ_len + 1] = answ[my_answ_len]; /* Yes, so move it. */
}
answ[my_answ_len] = '\0'; /* Put in null terminator */
*answ_len = my_answ_len; /* Return value to caller */
}
return (C_gbl_status & 1);
}
/*--------------------------------------------------------------------------*/
int C_tt_port_config(
/* ================
*/ int *hndl,
int mask)
{
/*
** This routine is useful for calling TT_PORT_CONFIG from a C program.
** Refer to the DELTAT.OLB description of TT_PORT_CONFIG to clarify any
** uncertainties in the following description.
** Inputs:
** hndl - the integer handle identifying the connection as returned
** by C_tt_port_connect.
** mask - an integer specifying the configuration options. Set bits
** TT_PORT__NO_RETRY = 0x0001 to suppress retries on error
** TT_PORT__NO_SIG = 0x0002 to suppress signals on error
** Outputs:
** None
** Modify:
** None
** Return status:
** always non-zero (true).
** Global variables:
** C_gbl_status - set to the VAX/VMS return status of TT_PORT_CONFIG.
*/
C_gbl_status = tt_port_config(hndl, &mask);
return (C_gbl_status & 1);
}
/*=========================================== End of C_INTERFACES.C ========*/