2 * The Regina Rexx Interpreter
3 * Copyright (C) 2000 Mark Hessling <M.Hessling@qut.edu.au>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #include "rexxbif.h" /* C functions that mimic REXX BIFs */
21 #define FIFO_LINE(buf,line) { \
22 /* This macro adds a line to a buffer in FIFO manner. \
23 * The line's higher/lower elements will be overwritten both. \
25 (line)->lower = NULL ; \
26 (line)->higher = (buf)->bottom ; \
27 (buf)->bottom = line ; \
28 if ( (line)->higher != NULL ) \
29 (line)->higher->lower = (line) ; \
32 (buf)->top = (line) ; /* buffer was empty previously */ \
33 assert( (buf)->elements == 0 ) ; \
38 #define LIFO_LINE(buf,line) { \
39 /* This macro adds a line to a buffer in LIFO manner. \
40 * The line's higher/lower elements will be overwritten both. \
42 (line)->higher = NULL ; \
43 (line)->lower = (buf)->top ; \
45 if ( (line)->lower != NULL ) \
46 (line)->lower->higher = (line) ; \
49 (buf)->bottom = (line) ; /* buffer was empty previously */ \
50 assert( (buf)->elements == 0 ) ; \
55 #define POP_LINE(buf,line) { \
56 /* This macro removes a line from a buffer. The argument "line" \
57 * will be overwritten. The higher/older elements of that value \
58 * won't be overwritten. \
60 if ( ( (line) = (buf)->top ) != NULL ) \
63 if ( ( (buf)->top = (line)->lower ) == NULL ) \
65 (buf)->bottom = NULL ; \
66 assert( (buf)->elements == 0 ) ; \
67 (buf)->elements = 0 ; /* if assert is defined out */ \
71 (buf)->top->higher = NULL ; \
76 #define GLUE_BUFFER1(buf1,buf2) { \
77 /* This macro glues buf2 at the top of buf1 and writes the result \
78 * to buf1. buf2's top/bottom/elements fields are reset. \
80 if ( (buf2)->bottom != NULL ) \
82 if ( (buf1)->top == NULL ) \
84 assert( ( (buf1)->bottom == NULL ) && ( (buf1)->elements == 0 ) ) ;\
85 (buf1)->top = (buf2)->top ; \
86 (buf1)->bottom = (buf2)->bottom ; \
87 (buf1)->elements = (buf2)->elements ; \
91 (buf1)->top->higher = (buf2)->bottom ; \
92 (buf2)->bottom->lower = (buf1)->top ; \
93 (buf1)->top = (buf2)->top ; \
94 (buf1)->elements += (buf2)->elements ; \
99 assert( ( (buf2)->top == NULL ) && ( (buf2)->elements == 0 ) ) ; \
101 (buf2)->top = NULL ; \
102 (buf2)->bottom = NULL ; \
103 (buf2)->elements = 0 ; \
106 #define GLUE_BUFFER2(buf1,buf2) { \
107 /* This macro glues buf2 at the top of buf1 and writes the result \
108 * to buf2. buf1's top/bottom/elements fields are reset. \
110 if ( (buf1)->bottom != NULL ) \
112 if ( (buf2)->top == NULL ) \
114 assert( ( (buf2)->bottom == NULL ) && ( (buf2)->elements == 0 ) ) ;\
115 (buf2)->top = (buf1)->top ; \
116 (buf2)->bottom = (buf1)->bottom ; \
117 (buf2)->elements = (buf1)->elements ; \
121 (buf1)->top->higher = (buf2)->bottom ; \
122 (buf2)->bottom->lower = (buf1)->top ; \
123 (buf2)->bottom = (buf1)->bottom ; \
124 (buf2)->elements += (buf2)->elements ; \
129 assert( ( (buf1)->top == NULL ) && ( (buf1)->elements == 0 ) ) ; \
131 (buf1)->top = NULL ; \
132 (buf1)->bottom = NULL ; \
133 (buf1)->elements = 0 ; \
136 void showerror( int err
, int suberr
, char *tmpl
, ...);
137 int init_external_queue( const tsd_t
*TSD
);
138 void term_external_queue( void );
139 int default_port_number( void ) ;
140 int default_external_address( void ) ;
141 streng
*default_external_name( const tsd_t
*TSD
) ;
142 int connect_to_rxstack( tsd_t
*TSD
, Queue
*q
) ;
143 int disconnect_from_rxstack( const tsd_t
*TSD
, Queue
*q
) ;
144 int parse_queue( tsd_t
*TSD
, streng
*queue
, Queue
*q
) ;
145 int send_command_to_rxstack( const tsd_t
*TSD
, int sock
, const char *action
, const char *str
, int len
);
146 streng
*read_result_from_rxstack( const tsd_t
*TSD
, int sock
, int result_size
);
147 int delete_queue_from_rxstack( const tsd_t
*TSD
, int sock
, const streng
*queue_name
);
148 int set_queue_in_rxstack( const tsd_t
*TSD
, int sock
, const streng
*queue_name
);
149 int get_number_in_queue_from_rxstack( const tsd_t
*TSD
, int sock
, int *errcode
);
150 int clear_queue_on_rxstack( const tsd_t
*TSD
, int sock
) ;
151 int get_queue_from_rxstack( const tsd_t
*TSD
, const Queue
*q
, streng
**result
);
152 int create_queue_on_rxstack( const tsd_t
*TSD
, const Queue
*q
, const streng
*queue
, streng
**result
);
153 int timeout_queue_on_rxstack( const tsd_t
*TSD
, int sock
, long timeout
);
154 int get_line_from_rxstack( const tsd_t
*TSD
, int sock
, streng
**result
, int nowait
);
155 int queue_line_lifo_to_rxstack( const tsd_t
*TSD
, int sock
, const streng
*line
);
156 int queue_line_fifo_to_rxstack( const tsd_t
*TSD
, int sock
, const streng
*line
);
157 int get_length_from_header( const tsd_t
*TSD
, const streng
*header
);
159 #define RXSTACK_EXIT 'X'
160 #define RXSTACK_EXIT_STR "X"
161 #define RXSTACK_KILL 'Z'
162 #define RXSTACK_KILL_STR "Z"
163 #define RXSTACK_QUEUE_FIFO 'F'
164 #define RXSTACK_QUEUE_FIFO_STR "F"
165 #define RXSTACK_QUEUE_LIFO 'L'
166 #define RXSTACK_QUEUE_LIFO_STR "L"
167 #define RXSTACK_CREATE_QUEUE 'C'
168 #define RXSTACK_CREATE_QUEUE_STR "C"
169 #define RXSTACK_DELETE_QUEUE 'D'
170 #define RXSTACK_DELETE_QUEUE_STR "D"
171 #define RXSTACK_EMPTY_QUEUE 'E'
172 #define RXSTACK_EMPTY_QUEUE_STR "E"
173 #define RXSTACK_PULL 'P'
174 #define RXSTACK_PULL_STR "P"
175 #define RXSTACK_FETCH 'p'
176 #define RXSTACK_FETCH_STR "p"
177 #define RXSTACK_SET_QUEUE 'S'
178 #define RXSTACK_SET_QUEUE_STR "S"
179 #define RXSTACK_GET_QUEUE 'G'
180 #define RXSTACK_GET_QUEUE_STR "G"
181 #define RXSTACK_NUMBER_IN_QUEUE 'N'
182 #define RXSTACK_NUMBER_IN_QUEUE_STR "N"
183 #define RXSTACK_TIMEOUT_QUEUE 'T'
184 #define RXSTACK_TIMEOUT_QUEUE_STR "T"
185 #define RXSTACK_UNKNOWN '?'
186 #define RXSTACK_UNKNOWN_STR "?"
187 #define RXSTACK_HEADER_SIZE 7
188 #define RXSTACK_TIMEOUT_SIZE 6
191 # define RXSOCKET 5757
194 #define ERR_RXSTACK_CANT_CONNECT 101
195 #define ERR_RXSTACK_CANT_CONNECT_TMPL "Error connecting to %s on port %d: \"%s\""
196 #define ERR_RXSTACK_NO_IP 102
197 #define ERR_RXSTACK_NO_IP_TMPL "Unable to obtain IP address for %s"
198 #define ERR_RXSTACK_INVALID_SERVER 103
199 #define ERR_RXSTACK_INVALID_SERVER_TMPL "Invalid format for server in specified queue name: \"%s\""
200 #define ERR_RXSTACK_INVALID_QUEUE 104
201 #define ERR_RXSTACK_INVALID_QUEUE_TMPL "Invalid format for queue name: \"%s\""
202 #define ERR_RXSTACK_NO_WINSOCK 105
203 #define ERR_RXSTACK_NO_WINSOCK_TMPL "Unable to start Windows Socket interface: %s"
204 #define ERR_RXSTACK_TOO_MANY_QUEUES 106
205 #define ERR_RXSTACK_TOO_MANY_QUEUES_TMPL "Maximum number of external queues exceeded: %d"
206 #define ERR_RXSTACK_READING_SOCKET 107
207 #define ERR_RXSTACK_READING_SOCKET_TMPL "Error occured reading socket: %s"
208 #define ERR_RXSTACK_INVALID_SWITCH 108
209 #define ERR_RXSTACK_INVALID_SWITCH_TMPL "Invalid switch passed. Must be one of \"%s\""
211 #define ERR_RXSTACK_INTERNAL 99
212 #define ERR_RXSTACK_INTERNAL_TMPL "Internal error with external queue interface: %d \"%s\""
213 #define ERR_RXSTACK_GENERAL 100
214 #define ERR_RXSTACK_GENERAL_TMPL "General system error with external queue interface. %s. %s"
216 #define ERR_STORAGE_EXHAUSTED_TMPL "System resources exhausted"
219 * Return codes from interacting with rxstack
222 #define RXSTACK_EMPTY 1
223 #define RXSTACK_ERROR 2
224 #define RXSTACK_WAITING 3
225 #define RXSTACK_TIMEOUT 4