1 /*- 2 * Copyright (c) 2005-2019 Michael Scholz <mi-scholz@users.sourceforge.net> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * @(#)utils.h 2.2 11/18/19 27 */ 28 29 #if !defined(_UTILS_H_) 30 #define _UTILS_H_ 31 32 #define PROPERTY_HASH_SIZE 101 33 34 /* 35 * Shell environment variables and default values: 36 * 37 * $FTH_INIT_FILE ~/.fthrc 38 * $FTH_HISTORY ~/.fth-history 39 * $FTH_HISTORY_LENGTH 100 40 * $FTH_FTHPATH "" 41 * $FTH_LIBPATH "" 42 * 43 * $FTH_DICTIONARY_SIZE 1024 * 1024 44 * $FTH_STACK_SIZE 1024 * 8 45 * $FTH_RETURN_SIZE 1024 46 * $FTH_LOCALS_SIZE 2048 47 */ 48 49 #define FTH_ENV_INIT_FILE "FTH_INIT_FILE" 50 #define FTH_ENV_HIST "FTH_HISTORY" 51 #define FTH_ENV_HIST_LEN "FTH_HISTORY_LENGTH" 52 #define FTH_ENV_FTHPATH "FTH_FTHPATH" 53 #define FTH_ENV_LIBPATH "FTH_LIBPATH" 54 55 #define FTH_ENV_DICTIONARY_SIZE "FTH_DICTIONARY_SIZE" 56 #define FTH_ENV_STACK_SIZE "FTH_STACK_SIZE" 57 #define FTH_ENV_RETURN_SIZE "FTH_RETURN_SIZE" 58 #define FTH_ENV_LOCALS_SIZE "FTH_LOCALS_SIZE" 59 60 #define _FTH_String(X) #X 61 #define FTH_XString(X) _FTH_String(X) 62 63 /* proc.c */ 64 #define fth_make_proc_from_vfunc(Name, Func, Req, Opt, Rest) \ 65 fth_make_proc_from_func(Name, (FTH (*)())Func, 1, Req, Opt, Rest) 66 67 #define FTH_SET_CONSTANT(Name) \ 68 fth_define_constant(#Name, (FTH)(Name), NULL) 69 70 /*- 71 * MAKE_MEMBER(Object, Name, Type, Member) 72 * 73 * Object = object type, e.g. FArray, FHash etc. 74 * Name = prefix string, e.g. ary, str 75 * Type = what ficl/stack.c provides, e.g. Integer, Float etc. 76 * Member = struct member name, e.g. length 77 * 78 * MAKE_MEMBER(FArray, ary, Integer, length) 79 * 80 * creates two static C functions: 81 * 82 * cb_ary_length() 83 * init_ary_length() 84 * 85 * The latter can be called e.g. in init_array() to create the Ficl 86 * word: 87 * 88 * ary->length 89 * 90 */ 91 #define MAKE_MEMBER(Object, Name, Type, Member) \ 92 static void \ 93 cb_ ## Name ## _ ## Member(ficlVm *vm) \ 94 { \ 95 FTH obj; \ 96 \ 97 FTH_STACK_CHECK(vm, 1, 1); \ 98 obj = fth_pop_ficl_cell(vm); \ 99 \ 100 if (fth_instance_p(obj)) \ 101 ficlStackPush ## Type(vm->dataStack, \ 102 FTH_INSTANCE_REF_GEN(obj, Object)->Member); \ 103 else \ 104 ficlStackPushBoolean(vm->dataStack, 0); \ 105 } \ 106 static void \ 107 init_ ## Name ## _ ## Member(void) \ 108 { \ 109 ficlDictionaryAppendPrimitive(FTH_FICL_DICT(), \ 110 #Name "->" #Member, cb_ ## Name ## _ ## Member, \ 111 FICL_WORD_DEFAULT); \ 112 } 113 114 /* Simple Array */ 115 typedef struct { 116 void **data; 117 unsigned length; 118 unsigned incr; 119 } simple_array; 120 121 /* === IO === */ 122 123 #if defined(HAVE_SYS_SOCKET_H) 124 #include <sys/socket.h> 125 #endif 126 #if defined(HAVE_SYS_UN_H) 127 #include <sys/un.h> 128 #endif 129 #if defined(HAVE_NETINET_IN_H) 130 #include <netinet/in.h> 131 #endif 132 #if defined(HAVE_NETDB_H) 133 #include <netdb.h> 134 #endif 135 #if defined(HAVE_SYS_UIO_H) 136 #include <sys/uio.h> 137 #endif 138 139 #if !defined(HAVE_STRUCT_SOCKADDR_UN) || defined(_WIN32) 140 #define HAVE_SOCKET 0 141 #define FTH_DEFAULT_ADDRFAM 0 142 #else /* !_WIN32 */ 143 #define HAVE_SOCKET 1 144 #if defined(AF_INET) 145 #define FTH_DEFAULT_ADDRFAM AF_INET 146 #else 147 #define FTH_DEFAULT_ADDRFAM 2 148 #endif 149 #endif /* _WIN32 */ 150 151 #define FTH_DEFAULT_PORT 1024 152 153 /* Keywords for xxx_open(:if-exists). */ 154 #define FTH_KEYWORD_ERROR fth_keyword("error") 155 #define FTH_KEYWORD_RENAME fth_keyword("rename") 156 #define FTH_KEYWORD_OVERWRITE fth_keyword("overwrite") 157 158 typedef enum { 159 FTH_IO_UNDEF, 160 FTH_IO_FILE, 161 FTH_IO_PIPE, 162 FTH_IO_SOCKET, 163 FTH_IO_STRING, 164 FTH_IO_PORT 165 } io_t; 166 167 typedef struct { 168 io_t type; 169 FTH name; 170 FTH filename; 171 FTH buffer; 172 int fam; 173 void *data; 174 ficl2Integer length; 175 int input_p; 176 int output_p; 177 int closed_p; 178 int (*read_char) (void *); 179 void (*write_char) (void *, int); 180 char *(*read_line) (void *); 181 void (*write_line) (void *, const char *); 182 int (*eof_p) (void *); 183 ficl2Integer (*tell) (void *); 184 ficl2Integer (*seek) (void *, ficl2Integer, int); 185 void (*flush) (void *); 186 void (*rewind) (void *); 187 void (*close) (void *); 188 } FIO; 189 190 #define FTH_IO_OBJECT(Obj) FTH_INSTANCE_REF_GEN(Obj, FIO) 191 192 #define FTH_IO_TYPE(Obj) FTH_IO_OBJECT(Obj)->type 193 #define FTH_IO_NAME(Obj) FTH_IO_OBJECT(Obj)->name 194 #define FTH_IO_FILENAME(Obj) FTH_IO_OBJECT(Obj)->filename 195 #define FTH_IO_FAM(Obj) FTH_IO_OBJECT(Obj)->fam 196 #define FTH_IO_DATA(Obj) FTH_IO_OBJECT(Obj)->data 197 #define FTH_IO_LENGTH(Obj) FTH_IO_OBJECT(Obj)->length 198 #define FTH_IO_BUFFER(Obj) FTH_IO_OBJECT(Obj)->buffer 199 #define FTH_IO_INPUT_P(Obj) FTH_IO_OBJECT(Obj)->input_p 200 #define FTH_IO_OUTPUT_P(Obj) FTH_IO_OBJECT(Obj)->output_p 201 #define FTH_IO_CLOSED_P(Obj) FTH_IO_OBJECT(Obj)->closed_p 202 203 #define FTH_IO_READ_CHAR(Obj) \ 204 (*FTH_IO_OBJECT(Obj)->read_char)(FTH_IO_DATA(Obj)) 205 #define FTH_IO_WRITE_CHAR(Obj, val) \ 206 (*FTH_IO_OBJECT(Obj)->write_char)(FTH_IO_DATA(Obj), val) 207 #define FTH_IO_READ_LINE(Obj) \ 208 (*FTH_IO_OBJECT(Obj)->read_line)(FTH_IO_DATA(Obj)) 209 #define FTH_IO_WRITE_LINE(Obj, val) \ 210 (*FTH_IO_OBJECT(Obj)->write_line)(FTH_IO_DATA(Obj), val) 211 #define FTH_IO_EOF_P(Obj) \ 212 (*FTH_IO_OBJECT(Obj)->eof_p)(FTH_IO_DATA(Obj)) 213 #define FTH_IO_TELL(Obj) \ 214 (*FTH_IO_OBJECT(Obj)->tell)(FTH_IO_DATA(Obj)) 215 #define FTH_IO_SEEK(Obj, pos, w) \ 216 (*FTH_IO_OBJECT(Obj)->seek)(FTH_IO_DATA(Obj), pos, w) 217 #define FTH_IO_FLUSH(Obj) \ 218 (*FTH_IO_OBJECT(Obj)->flush)(FTH_IO_DATA(Obj)) 219 #define FTH_IO_REWIND(Obj) \ 220 (*FTH_IO_OBJECT(Obj)->rewind)(FTH_IO_DATA(Obj)) 221 #define FTH_IO_CLOSE(Obj) \ 222 (*FTH_IO_OBJECT(Obj)->close)(FTH_IO_DATA(Obj)) 223 224 #define keyword_args_string "\ 225 The following keyword arguments exist:\n\ 226 :filename file name (string) => file IO\n\ 227 :fam default r/o\n\ 228 :command cmd (string or array-of-strings) => pipe IO\n\ 229 :fam default r/o\n\ 230 :string string (string) => string IO\n\ 231 :fam default r/o\n\ 232 :socket host (string) => socket IO\n\ 233 :domain default AF_INET\n\ 234 :port default 1024\n\ 235 :soft-port port name (string) => soft-port IO\n\ 236 :fam default r/o\n\ 237 :port-name default \"soft-port-name\"\n\ 238 :read-char proc ( -- c )\n\ 239 :write-char proc ( c -- )\n\ 240 :read-line proc ( -- line )\n\ 241 :write-line proc ( line -- )\n\ 242 :flush proc ( -- )\n\ 243 :close proc ( -- )\n\ 244 See also io-open-file, io-open-input-file, io-open-output-file, \ 245 with-input-port, with-output-port, with-input-from-port, \ 246 with-output-to-port, with-error-to-port." 247 248 __BEGIN_DECLS 249 250 void init_gc(void); 251 void init_array_type(void); 252 void init_hash_type(void); 253 void init_io_type(void); 254 void init_hook_type(void); 255 void init_string_type(void); 256 void init_regexp_type(void); 257 void init_number_types(void); 258 void init_array(void); 259 void init_hash (void); 260 void init_io (void); 261 void init_port (void); 262 void init_file (void); 263 void init_number(void); 264 void init_object(void); 265 void init_proc (void); 266 void init_hook (void); 267 void init_string(void); 268 void init_regexp(void); 269 void init_symbol(void); 270 void init_utils(void); 271 272 /* array.c */ 273 /* Next two have no bound checks! */ 274 FTH fth_array_fast_set(FTH, ficlInteger, FTH); 275 FTH fth_array_fast_ref(FTH, ficlInteger); 276 277 /* io.c */ 278 FTH make_io_base(int); 279 280 /* misc.c */ 281 void forth_init(void); 282 void forth_init_before_load(void); 283 extern int fth_signal_caught_p; 284 #if !defined(_WIN32) 285 extern sigjmp_buf fth_sig_toplevel; 286 void signal_check(int); 287 #endif 288 void fth_reset_loop_and_depth(void); 289 290 /* numbers.c */ 291 int ficl_parse_number(ficlVm *, ficlString); 292 #if HAVE_COMPLEX 293 int ficl_parse_complex(ficlVm *, ficlString); 294 #endif 295 int ficl_parse_bignum(ficlVm *, ficlString); 296 int ficl_parse_ratio(ficlVm *, ficlString); 297 298 /* object.c */ 299 FTH make_object_type(const char *, fobj_t); 300 FTH make_object_type_from(const char *, fobj_t, FTH); 301 302 void gc_free_all(void); 303 void gc_push(ficlWord *); 304 void gc_pop(void); 305 void gc_loop_reset(void); 306 void fth_set_backtrace(FTH); 307 void fth_show_backtrace(int); 308 309 /* port.c */ 310 FTH io_keyword_args_ref(int); 311 312 /* proc.c */ 313 FTH fth_word_dump(FTH); 314 FTH fth_word_inspect(FTH); 315 FTH fth_word_to_source(ficlWord *); 316 FTH fth_word_to_string(FTH); 317 void ficl_init_locals(ficlVm *, ficlDictionary *); 318 319 /* string.c */ 320 /* Next two have no bound checks! */ 321 char fth_string_c_char_fast_ref(FTH, ficlInteger); 322 char fth_string_c_char_fast_set(FTH, ficlInteger, char); 323 /* Doesn't remove sep_str. */ 324 FTH fth_string_split_2(FTH, FTH); 325 326 /* symbol.c */ 327 FTH ficl_ans_real_exc(int); 328 329 /* utils.c */ 330 simple_array *make_simple_array(int); 331 simple_array *make_simple_array_var(int,...); 332 int simple_array_length(simple_array *); 333 int simple_array_equal_p(simple_array *, simple_array *); 334 void *simple_array_ref(simple_array *, int); 335 void simple_array_set(simple_array *, int, void *); 336 void simple_array_push(simple_array *, void *); 337 void *simple_array_pop(simple_array *); 338 int simple_array_index(simple_array *, void *); 339 int simple_array_rindex(simple_array *, void *); 340 int simple_array_member_p(simple_array *, void *); 341 void *simple_array_delete(simple_array *, void *); 342 void *simple_array_rdelete(simple_array *, void *); 343 simple_array *simple_array_reverse(simple_array *); 344 simple_array *simple_array_clear(simple_array *); 345 void simple_array_free(simple_array *); 346 FTH simple_array_to_array(simple_array *); 347 348 void push_forth_string(ficlVm *, char *); 349 350 char *parse_input_buffer(ficlVm *, char *); 351 char *parse_tib_with_restart(ficlVm *, char *, int, 352 ficlString (*) (ficlVm *, int)); 353 354 __END_DECLS 355 356 #endif /* _UTILS_H_ */ 357 358 /* 359 * utils.h ends here 360 */ 361