- Rearranged directory structure for forking out ANSTO
- Refactored site specific stuff into a site module - PSI specific stuff is now in the PSI directory. - The old version has been tagged with pre-ansto
This commit is contained in:
472
hardsup/c_interfaces.c
Normal file
472
hardsup/c_interfaces.c
Normal file
@ -0,0 +1,472 @@
|
||||
#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 ========*/
|
Reference in New Issue
Block a user