1*7dd7cddfSDavid du Colombier /* Copyright (C) 1989, 1995, 1997, 1999 Aladdin Enterprises. All rights reserved. 2*7dd7cddfSDavid du Colombier 3*7dd7cddfSDavid du Colombier This file is part of Aladdin Ghostscript. 4*7dd7cddfSDavid du Colombier 5*7dd7cddfSDavid du Colombier Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author 6*7dd7cddfSDavid du Colombier or distributor accepts any responsibility for the consequences of using it, 7*7dd7cddfSDavid du Colombier or for whether it serves any particular purpose or works at all, unless he 8*7dd7cddfSDavid du Colombier or she says so in writing. Refer to the Aladdin Ghostscript Free Public 9*7dd7cddfSDavid du Colombier License (the "License") for full details. 10*7dd7cddfSDavid du Colombier 11*7dd7cddfSDavid du Colombier Every copy of Aladdin Ghostscript must include a copy of the License, 12*7dd7cddfSDavid du Colombier normally in a plain ASCII text file named PUBLIC. The License grants you 13*7dd7cddfSDavid du Colombier the right to copy, modify and redistribute Aladdin Ghostscript, but only 14*7dd7cddfSDavid du Colombier under certain conditions described in the License. Among other things, the 15*7dd7cddfSDavid du Colombier License requires that the copyright notice and this notice be preserved on 16*7dd7cddfSDavid du Colombier all copies. 17*7dd7cddfSDavid du Colombier */ 18*7dd7cddfSDavid du Colombier 19*7dd7cddfSDavid du Colombier /*$Id: zmisc.c,v 1.1 2000/03/09 08:40:45 lpd Exp $ */ 20*7dd7cddfSDavid du Colombier /* Miscellaneous operators */ 21*7dd7cddfSDavid du Colombier #include "errno_.h" 22*7dd7cddfSDavid du Colombier #include "memory_.h" 23*7dd7cddfSDavid du Colombier #include "string_.h" 24*7dd7cddfSDavid du Colombier #include "ghost.h" 25*7dd7cddfSDavid du Colombier #include "gscdefs.h" /* for gs_serialnumber */ 26*7dd7cddfSDavid du Colombier #include "gp.h" 27*7dd7cddfSDavid du Colombier #include "oper.h" 28*7dd7cddfSDavid du Colombier #include "ialloc.h" 29*7dd7cddfSDavid du Colombier #include "idict.h" 30*7dd7cddfSDavid du Colombier #include "dstack.h" /* for name lookup in bind */ 31*7dd7cddfSDavid du Colombier #include "iname.h" 32*7dd7cddfSDavid du Colombier #include "ipacked.h" 33*7dd7cddfSDavid du Colombier #include "ivmspace.h" 34*7dd7cddfSDavid du Colombier #include "store.h" 35*7dd7cddfSDavid du Colombier 36*7dd7cddfSDavid du Colombier /* <proc> bind <proc> */ 37*7dd7cddfSDavid du Colombier inline private bool 38*7dd7cddfSDavid du Colombier r_is_ex_oper(const ref *rp) 39*7dd7cddfSDavid du Colombier { 40*7dd7cddfSDavid du Colombier return (r_has_attr(rp, a_executable) && 41*7dd7cddfSDavid du Colombier (r_btype(rp) == t_operator || r_type(rp) == t_oparray)); 42*7dd7cddfSDavid du Colombier } 43*7dd7cddfSDavid du Colombier private int 44*7dd7cddfSDavid du Colombier zbind(i_ctx_t *i_ctx_p) 45*7dd7cddfSDavid du Colombier { 46*7dd7cddfSDavid du Colombier os_ptr op = osp; 47*7dd7cddfSDavid du Colombier uint depth = 1; 48*7dd7cddfSDavid du Colombier ref defn; 49*7dd7cddfSDavid du Colombier register os_ptr bsp; 50*7dd7cddfSDavid du Colombier 51*7dd7cddfSDavid du Colombier switch (r_type(op)) { 52*7dd7cddfSDavid du Colombier case t_array: 53*7dd7cddfSDavid du Colombier case t_mixedarray: 54*7dd7cddfSDavid du Colombier case t_shortarray: 55*7dd7cddfSDavid du Colombier defn = *op; 56*7dd7cddfSDavid du Colombier break; 57*7dd7cddfSDavid du Colombier case t_oparray: 58*7dd7cddfSDavid du Colombier defn = *op->value.const_refs; 59*7dd7cddfSDavid du Colombier break; 60*7dd7cddfSDavid du Colombier default: 61*7dd7cddfSDavid du Colombier return_op_typecheck(op); 62*7dd7cddfSDavid du Colombier } 63*7dd7cddfSDavid du Colombier push(1); 64*7dd7cddfSDavid du Colombier *op = defn; 65*7dd7cddfSDavid du Colombier bsp = op; 66*7dd7cddfSDavid du Colombier /* 67*7dd7cddfSDavid du Colombier * We must not make the top-level procedure read-only, 68*7dd7cddfSDavid du Colombier * but we must bind it even if it is read-only already. 69*7dd7cddfSDavid du Colombier * 70*7dd7cddfSDavid du Colombier * Here are the invariants for the following loop: 71*7dd7cddfSDavid du Colombier * `depth' elements have been pushed on the ostack; 72*7dd7cddfSDavid du Colombier * For i < depth, p = ref_stack_index(&o_stack, i): 73*7dd7cddfSDavid du Colombier * *p is an array (or packedarray) ref. 74*7dd7cddfSDavid du Colombier */ 75*7dd7cddfSDavid du Colombier while (depth) { 76*7dd7cddfSDavid du Colombier while (r_size(bsp)) { 77*7dd7cddfSDavid du Colombier ref_packed *const tpp = (ref_packed *)bsp->value.packed; /* break const */ 78*7dd7cddfSDavid du Colombier 79*7dd7cddfSDavid du Colombier r_dec_size(bsp, 1); 80*7dd7cddfSDavid du Colombier if (r_is_packed(tpp)) { 81*7dd7cddfSDavid du Colombier /* Check for a packed executable name */ 82*7dd7cddfSDavid du Colombier ushort elt = *tpp; 83*7dd7cddfSDavid du Colombier 84*7dd7cddfSDavid du Colombier if (r_packed_is_exec_name(&elt)) { 85*7dd7cddfSDavid du Colombier ref nref; 86*7dd7cddfSDavid du Colombier ref *pvalue; 87*7dd7cddfSDavid du Colombier 88*7dd7cddfSDavid du Colombier name_index_ref(packed_name_index(&elt), 89*7dd7cddfSDavid du Colombier &nref); 90*7dd7cddfSDavid du Colombier if ((pvalue = dict_find_name(&nref)) != 0 && 91*7dd7cddfSDavid du Colombier r_is_ex_oper(pvalue) 92*7dd7cddfSDavid du Colombier ) { 93*7dd7cddfSDavid du Colombier store_check_dest(bsp, pvalue); 94*7dd7cddfSDavid du Colombier /* 95*7dd7cddfSDavid du Colombier * Always save the change, since this can only 96*7dd7cddfSDavid du Colombier * happen once. 97*7dd7cddfSDavid du Colombier */ 98*7dd7cddfSDavid du Colombier ref_do_save(bsp, tpp, "bind"); 99*7dd7cddfSDavid du Colombier *tpp = pt_tag(pt_executable_operator) + 100*7dd7cddfSDavid du Colombier op_index(pvalue); 101*7dd7cddfSDavid du Colombier } 102*7dd7cddfSDavid du Colombier } 103*7dd7cddfSDavid du Colombier bsp->value.packed = tpp + 1; 104*7dd7cddfSDavid du Colombier } else { 105*7dd7cddfSDavid du Colombier ref *const tp = bsp->value.refs++; 106*7dd7cddfSDavid du Colombier 107*7dd7cddfSDavid du Colombier switch (r_type(tp)) { 108*7dd7cddfSDavid du Colombier case t_name: /* bind the name if an operator */ 109*7dd7cddfSDavid du Colombier if (r_has_attr(tp, a_executable)) { 110*7dd7cddfSDavid du Colombier ref *pvalue; 111*7dd7cddfSDavid du Colombier 112*7dd7cddfSDavid du Colombier if ((pvalue = dict_find_name(tp)) != 0 && 113*7dd7cddfSDavid du Colombier r_is_ex_oper(pvalue) 114*7dd7cddfSDavid du Colombier ) { 115*7dd7cddfSDavid du Colombier store_check_dest(bsp, pvalue); 116*7dd7cddfSDavid du Colombier ref_assign_old(bsp, tp, pvalue, "bind"); 117*7dd7cddfSDavid du Colombier } 118*7dd7cddfSDavid du Colombier } 119*7dd7cddfSDavid du Colombier break; 120*7dd7cddfSDavid du Colombier case t_array: /* push into array if writable */ 121*7dd7cddfSDavid du Colombier if (!r_has_attr(tp, a_write)) 122*7dd7cddfSDavid du Colombier break; 123*7dd7cddfSDavid du Colombier case t_mixedarray: 124*7dd7cddfSDavid du Colombier case t_shortarray: 125*7dd7cddfSDavid du Colombier if (r_has_attr(tp, a_executable)) { 126*7dd7cddfSDavid du Colombier /* Make reference read-only */ 127*7dd7cddfSDavid du Colombier r_clear_attrs(tp, a_write); 128*7dd7cddfSDavid du Colombier if (bsp >= ostop) { 129*7dd7cddfSDavid du Colombier /* Push a new stack block. */ 130*7dd7cddfSDavid du Colombier ref temp; 131*7dd7cddfSDavid du Colombier int code; 132*7dd7cddfSDavid du Colombier 133*7dd7cddfSDavid du Colombier temp = *tp; 134*7dd7cddfSDavid du Colombier osp = bsp; 135*7dd7cddfSDavid du Colombier code = ref_stack_push(&o_stack, 1); 136*7dd7cddfSDavid du Colombier if (code < 0) { 137*7dd7cddfSDavid du Colombier ref_stack_pop(&o_stack, depth); 138*7dd7cddfSDavid du Colombier return_error(code); 139*7dd7cddfSDavid du Colombier } 140*7dd7cddfSDavid du Colombier bsp = osp; 141*7dd7cddfSDavid du Colombier *bsp = temp; 142*7dd7cddfSDavid du Colombier } else 143*7dd7cddfSDavid du Colombier *++bsp = *tp; 144*7dd7cddfSDavid du Colombier depth++; 145*7dd7cddfSDavid du Colombier } 146*7dd7cddfSDavid du Colombier } 147*7dd7cddfSDavid du Colombier } 148*7dd7cddfSDavid du Colombier } 149*7dd7cddfSDavid du Colombier bsp--; 150*7dd7cddfSDavid du Colombier depth--; 151*7dd7cddfSDavid du Colombier if (bsp < osbot) { /* Pop back to the previous stack block. */ 152*7dd7cddfSDavid du Colombier osp = bsp; 153*7dd7cddfSDavid du Colombier ref_stack_pop_block(&o_stack); 154*7dd7cddfSDavid du Colombier bsp = osp; 155*7dd7cddfSDavid du Colombier } 156*7dd7cddfSDavid du Colombier } 157*7dd7cddfSDavid du Colombier osp = bsp; 158*7dd7cddfSDavid du Colombier return 0; 159*7dd7cddfSDavid du Colombier } 160*7dd7cddfSDavid du Colombier 161*7dd7cddfSDavid du Colombier /* - serialnumber <int> */ 162*7dd7cddfSDavid du Colombier private int 163*7dd7cddfSDavid du Colombier zserialnumber(i_ctx_t *i_ctx_p) 164*7dd7cddfSDavid du Colombier { 165*7dd7cddfSDavid du Colombier os_ptr op = osp; 166*7dd7cddfSDavid du Colombier 167*7dd7cddfSDavid du Colombier push(1); 168*7dd7cddfSDavid du Colombier make_int(op, gs_serialnumber); 169*7dd7cddfSDavid du Colombier return 0; 170*7dd7cddfSDavid du Colombier } 171*7dd7cddfSDavid du Colombier 172*7dd7cddfSDavid du Colombier /* - realtime <int> */ 173*7dd7cddfSDavid du Colombier private int 174*7dd7cddfSDavid du Colombier zrealtime(i_ctx_t *i_ctx_p) 175*7dd7cddfSDavid du Colombier { 176*7dd7cddfSDavid du Colombier os_ptr op = osp; 177*7dd7cddfSDavid du Colombier long secs_ns[2]; 178*7dd7cddfSDavid du Colombier 179*7dd7cddfSDavid du Colombier gp_get_realtime(secs_ns); 180*7dd7cddfSDavid du Colombier push(1); 181*7dd7cddfSDavid du Colombier make_int(op, secs_ns[0] * 1000 + secs_ns[1] / 1000000); 182*7dd7cddfSDavid du Colombier return 0; 183*7dd7cddfSDavid du Colombier } 184*7dd7cddfSDavid du Colombier 185*7dd7cddfSDavid du Colombier /* - usertime <int> */ 186*7dd7cddfSDavid du Colombier private int 187*7dd7cddfSDavid du Colombier zusertime(i_ctx_t *i_ctx_p) 188*7dd7cddfSDavid du Colombier { 189*7dd7cddfSDavid du Colombier os_ptr op = osp; 190*7dd7cddfSDavid du Colombier long secs_ns[2]; 191*7dd7cddfSDavid du Colombier 192*7dd7cddfSDavid du Colombier gp_get_usertime(secs_ns); 193*7dd7cddfSDavid du Colombier push(1); 194*7dd7cddfSDavid du Colombier make_int(op, secs_ns[0] * 1000 + secs_ns[1] / 1000000); 195*7dd7cddfSDavid du Colombier return 0; 196*7dd7cddfSDavid du Colombier } 197*7dd7cddfSDavid du Colombier 198*7dd7cddfSDavid du Colombier /* ---------------- Non-standard operators ---------------- */ 199*7dd7cddfSDavid du Colombier 200*7dd7cddfSDavid du Colombier /* <string> getenv <value_string> true */ 201*7dd7cddfSDavid du Colombier /* <string> getenv false */ 202*7dd7cddfSDavid du Colombier private int 203*7dd7cddfSDavid du Colombier zgetenv(i_ctx_t *i_ctx_p) 204*7dd7cddfSDavid du Colombier { 205*7dd7cddfSDavid du Colombier os_ptr op = osp; 206*7dd7cddfSDavid du Colombier char *str; 207*7dd7cddfSDavid du Colombier byte *value; 208*7dd7cddfSDavid du Colombier int len = 0; 209*7dd7cddfSDavid du Colombier 210*7dd7cddfSDavid du Colombier check_read_type(*op, t_string); 211*7dd7cddfSDavid du Colombier str = ref_to_string(op, imemory, "getenv key"); 212*7dd7cddfSDavid du Colombier if (str == 0) 213*7dd7cddfSDavid du Colombier return_error(e_VMerror); 214*7dd7cddfSDavid du Colombier if (gp_getenv(str, (char *)0, &len) > 0) { /* key missing */ 215*7dd7cddfSDavid du Colombier ifree_string((byte *) str, r_size(op) + 1, "getenv key"); 216*7dd7cddfSDavid du Colombier make_false(op); 217*7dd7cddfSDavid du Colombier return 0; 218*7dd7cddfSDavid du Colombier } 219*7dd7cddfSDavid du Colombier value = ialloc_string(len, "getenv value"); 220*7dd7cddfSDavid du Colombier if (value == 0) { 221*7dd7cddfSDavid du Colombier ifree_string((byte *) str, r_size(op) + 1, "getenv key"); 222*7dd7cddfSDavid du Colombier return_error(e_VMerror); 223*7dd7cddfSDavid du Colombier } 224*7dd7cddfSDavid du Colombier DISCARD(gp_getenv(str, (char *)value, &len)); /* can't fail */ 225*7dd7cddfSDavid du Colombier ifree_string((byte *) str, r_size(op) + 1, "getenv key"); 226*7dd7cddfSDavid du Colombier /* Delete the stupid C string terminator. */ 227*7dd7cddfSDavid du Colombier value = iresize_string(value, len, len - 1, 228*7dd7cddfSDavid du Colombier "getenv value"); /* can't fail */ 229*7dd7cddfSDavid du Colombier push(1); 230*7dd7cddfSDavid du Colombier make_string(op - 1, a_all | icurrent_space, len - 1, value); 231*7dd7cddfSDavid du Colombier make_true(op); 232*7dd7cddfSDavid du Colombier return 0; 233*7dd7cddfSDavid du Colombier } 234*7dd7cddfSDavid du Colombier 235*7dd7cddfSDavid du Colombier /* <name> <proc> .makeoperator <oper> */ 236*7dd7cddfSDavid du Colombier private int 237*7dd7cddfSDavid du Colombier zmakeoperator(i_ctx_t *i_ctx_p) 238*7dd7cddfSDavid du Colombier { 239*7dd7cddfSDavid du Colombier os_ptr op = osp; 240*7dd7cddfSDavid du Colombier op_array_table *opt; 241*7dd7cddfSDavid du Colombier uint count; 242*7dd7cddfSDavid du Colombier ref *tab; 243*7dd7cddfSDavid du Colombier 244*7dd7cddfSDavid du Colombier check_type(op[-1], t_name); 245*7dd7cddfSDavid du Colombier check_proc(*op); 246*7dd7cddfSDavid du Colombier switch (r_space(op)) { 247*7dd7cddfSDavid du Colombier case avm_global: 248*7dd7cddfSDavid du Colombier opt = &op_array_table_global; 249*7dd7cddfSDavid du Colombier break; 250*7dd7cddfSDavid du Colombier case avm_local: 251*7dd7cddfSDavid du Colombier opt = &op_array_table_local; 252*7dd7cddfSDavid du Colombier break; 253*7dd7cddfSDavid du Colombier default: 254*7dd7cddfSDavid du Colombier return_error(e_invalidaccess); 255*7dd7cddfSDavid du Colombier } 256*7dd7cddfSDavid du Colombier count = opt->count; 257*7dd7cddfSDavid du Colombier tab = opt->table.value.refs; 258*7dd7cddfSDavid du Colombier /* 259*7dd7cddfSDavid du Colombier * restore doesn't reset op_array_table.count, but it does 260*7dd7cddfSDavid du Colombier * remove entries from op_array_table.table. Since we fill 261*7dd7cddfSDavid du Colombier * the table in order, we can detect that a restore has occurred 262*7dd7cddfSDavid du Colombier * by checking whether what should be the most recent entry 263*7dd7cddfSDavid du Colombier * is occupied. If not, we scan backwards over the vacated entries 264*7dd7cddfSDavid du Colombier * to find the true end of the table. 265*7dd7cddfSDavid du Colombier */ 266*7dd7cddfSDavid du Colombier while (count > 0 && r_has_type(&tab[count - 1], t_null)) 267*7dd7cddfSDavid du Colombier --count; 268*7dd7cddfSDavid du Colombier if (count == r_size(&opt->table)) 269*7dd7cddfSDavid du Colombier return_error(e_limitcheck); 270*7dd7cddfSDavid du Colombier ref_assign_old(&opt->table, &tab[count], op, "makeoperator"); 271*7dd7cddfSDavid du Colombier opt->nx_table[count] = name_index(op - 1); 272*7dd7cddfSDavid du Colombier op_index_ref(opt->base_index + count, op - 1); 273*7dd7cddfSDavid du Colombier opt->count = count + 1; 274*7dd7cddfSDavid du Colombier pop(1); 275*7dd7cddfSDavid du Colombier return 0; 276*7dd7cddfSDavid du Colombier } 277*7dd7cddfSDavid du Colombier 278*7dd7cddfSDavid du Colombier /* - .oserrno <int> */ 279*7dd7cddfSDavid du Colombier private int 280*7dd7cddfSDavid du Colombier zoserrno(i_ctx_t *i_ctx_p) 281*7dd7cddfSDavid du Colombier { 282*7dd7cddfSDavid du Colombier os_ptr op = osp; 283*7dd7cddfSDavid du Colombier 284*7dd7cddfSDavid du Colombier push(1); 285*7dd7cddfSDavid du Colombier make_int(op, errno); 286*7dd7cddfSDavid du Colombier return 0; 287*7dd7cddfSDavid du Colombier } 288*7dd7cddfSDavid du Colombier 289*7dd7cddfSDavid du Colombier /* <int> .setoserrno - */ 290*7dd7cddfSDavid du Colombier private int 291*7dd7cddfSDavid du Colombier zsetoserrno(i_ctx_t *i_ctx_p) 292*7dd7cddfSDavid du Colombier { 293*7dd7cddfSDavid du Colombier os_ptr op = osp; 294*7dd7cddfSDavid du Colombier 295*7dd7cddfSDavid du Colombier check_type(*op, t_integer); 296*7dd7cddfSDavid du Colombier errno = op->value.intval; 297*7dd7cddfSDavid du Colombier pop(1); 298*7dd7cddfSDavid du Colombier return 0; 299*7dd7cddfSDavid du Colombier } 300*7dd7cddfSDavid du Colombier 301*7dd7cddfSDavid du Colombier /* <int> .oserrorstring <string> true */ 302*7dd7cddfSDavid du Colombier /* <int> .oserrorstring false */ 303*7dd7cddfSDavid du Colombier private int 304*7dd7cddfSDavid du Colombier zoserrorstring(i_ctx_t *i_ctx_p) 305*7dd7cddfSDavid du Colombier { 306*7dd7cddfSDavid du Colombier os_ptr op = osp; 307*7dd7cddfSDavid du Colombier const char *str; 308*7dd7cddfSDavid du Colombier int code; 309*7dd7cddfSDavid du Colombier uint len; 310*7dd7cddfSDavid du Colombier byte ch; 311*7dd7cddfSDavid du Colombier 312*7dd7cddfSDavid du Colombier check_type(*op, t_integer); 313*7dd7cddfSDavid du Colombier str = gp_strerror((int)op->value.intval); 314*7dd7cddfSDavid du Colombier if (str == 0 || (len = strlen(str)) == 0) { 315*7dd7cddfSDavid du Colombier make_false(op); 316*7dd7cddfSDavid du Colombier return 0; 317*7dd7cddfSDavid du Colombier } 318*7dd7cddfSDavid du Colombier check_ostack(1); 319*7dd7cddfSDavid du Colombier code = string_to_ref(str, op, iimemory, ".oserrorstring"); 320*7dd7cddfSDavid du Colombier if (code < 0) 321*7dd7cddfSDavid du Colombier return code; 322*7dd7cddfSDavid du Colombier /* Strip trailing end-of-line characters. */ 323*7dd7cddfSDavid du Colombier while ((len = r_size(op)) != 0 && 324*7dd7cddfSDavid du Colombier ((ch = op->value.bytes[--len]) == '\r' || ch == '\n') 325*7dd7cddfSDavid du Colombier ) 326*7dd7cddfSDavid du Colombier r_dec_size(op, 1); 327*7dd7cddfSDavid du Colombier push(1); 328*7dd7cddfSDavid du Colombier make_true(op); 329*7dd7cddfSDavid du Colombier return 0; 330*7dd7cddfSDavid du Colombier } 331*7dd7cddfSDavid du Colombier 332*7dd7cddfSDavid du Colombier /* <string> <bool> .setdebug - */ 333*7dd7cddfSDavid du Colombier private int 334*7dd7cddfSDavid du Colombier zsetdebug(i_ctx_t *i_ctx_p) 335*7dd7cddfSDavid du Colombier { 336*7dd7cddfSDavid du Colombier os_ptr op = osp; 337*7dd7cddfSDavid du Colombier check_read_type(op[-1], t_string); 338*7dd7cddfSDavid du Colombier check_type(*op, t_boolean); 339*7dd7cddfSDavid du Colombier { 340*7dd7cddfSDavid du Colombier int i; 341*7dd7cddfSDavid du Colombier 342*7dd7cddfSDavid du Colombier for (i = 0; i < r_size(op - 1); i++) 343*7dd7cddfSDavid du Colombier gs_debug[op[-1].value.bytes[i] & 127] = 344*7dd7cddfSDavid du Colombier op->value.boolval; 345*7dd7cddfSDavid du Colombier } 346*7dd7cddfSDavid du Colombier pop(2); 347*7dd7cddfSDavid du Colombier return 0; 348*7dd7cddfSDavid du Colombier } 349*7dd7cddfSDavid du Colombier 350*7dd7cddfSDavid du Colombier /* ------ Initialization procedure ------ */ 351*7dd7cddfSDavid du Colombier 352*7dd7cddfSDavid du Colombier const op_def zmisc_op_defs[] = 353*7dd7cddfSDavid du Colombier { 354*7dd7cddfSDavid du Colombier {"1bind", zbind}, 355*7dd7cddfSDavid du Colombier {"1getenv", zgetenv}, 356*7dd7cddfSDavid du Colombier {"2.makeoperator", zmakeoperator}, 357*7dd7cddfSDavid du Colombier {"0.oserrno", zoserrno}, 358*7dd7cddfSDavid du Colombier {"1.oserrorstring", zoserrorstring}, 359*7dd7cddfSDavid du Colombier {"0realtime", zrealtime}, 360*7dd7cddfSDavid du Colombier {"1serialnumber", zserialnumber}, 361*7dd7cddfSDavid du Colombier {"2.setdebug", zsetdebug}, 362*7dd7cddfSDavid du Colombier {"1.setoserrno", zsetoserrno}, 363*7dd7cddfSDavid du Colombier {"0usertime", zusertime}, 364*7dd7cddfSDavid du Colombier op_def_end(0) 365*7dd7cddfSDavid du Colombier }; 366