static void fill_in_array(awk_value_t *new_array) { awk_array_t a_cookie; awk_value_t index, value; a_cookie = create_array(); (void) make_const_string("hello", 5, & index); (void) make_const_string("world", 5, & value); if (! set_array_element(a_cookie, & index, & value)) { printf("fill_in_array:%d: set_array_element failed\n", __LINE__); return; } (void) make_const_string("answer", 6, & index); (void) make_number(42.0, & value); if (! set_array_element(a_cookie, & index, & value)) { printf("fill_in_array:%d: set_array_element failed\n", __LINE__); return; } new_array->val_type = AWK_ARRAY; new_array->array_cookie = a_cookie; }
static void fill_path_element(awk_array_t element_array, const char *path) { awk_value_t index, value; (void) make_const_string("path", 4, & index); (void) make_const_string(path, strlen(path), & value); if (! set_array_element(element_array, & index, & value)) { warning(ext_id, _("fill_path_element: could not set element")); fts_errors++; } }
static void fill_error_element(awk_array_t element_array, const int errcode) { awk_value_t index, value; const char *err = strerror(errcode); (void) make_const_string("error", 5, & index); (void) make_const_string(err, strlen(err), & value); if (! set_array_element(element_array, & index, & value)) { warning(ext_id, _("fill_error_element: could not set element")); fts_errors++; } }
/* <file> .filename false */ static int zfilename(i_ctx_t *i_ctx_p) { os_ptr op = osp; stream *s; gs_const_string fname; byte *str; check_file(s, op); if (sfilename(s, &fname) < 0) { make_false(op); return 0; } check_ostack(1); str = ialloc_string(fname.size, "filename"); if (str == 0) return_error(e_VMerror); memcpy(str, fname.data, fname.size); push(1); /* can't fail */ make_const_string( op - 1 , a_all | imemory_space((const struct gs_ref_memory_s*) imemory), fname.size, str); make_true(op); return 0; }
/* Run the initialization procedures of the individual operator files. */ int zop_init(i_ctx_t *i_ctx_p) { const op_def *const *tptr; int code; /* Because of a bug in Sun's SC1.0 compiler, */ /* we have to spell out the typedef for op_def_ptr here: */ const op_def *def; for (tptr = op_defs_all; *tptr != 0; tptr++) { for (def = *tptr; def->oname != 0; def++) DO_NOTHING; if (def->proc != 0) { code = def->proc(i_ctx_p); if (code < 0) { lprintf2("op_init proc 0x%lx returned error %d!\n", (ulong)def->proc, code); return code; } } } /* Initialize the predefined names other than operators. */ /* Do this here in case op_init changed any of them. */ { ref vcr, vpr, vpf, vre, vrd; make_const_string(&vcr, a_readonly | avm_foreign, strlen(gs_copyright), (const byte *)gs_copyright); make_const_string(&vpr, a_readonly | avm_foreign, strlen(gs_product), (const byte *)gs_product); make_const_string(&vpf, a_readonly | avm_foreign, strlen(gs_productfamily), (const byte *)gs_productfamily); make_int(&vre, gs_revision); make_int(&vrd, gs_revisiondate); if ((code = initial_enter_name("copyright", &vcr)) < 0 || (code = initial_enter_name("product", &vpr)) < 0 || (code = initial_enter_name("productfamily", &vpf)) < 0 || (code = initial_enter_name("revision", &vre)) < 0 || (code = initial_enter_name("revisiondate", &vrd)) < 0) return code; } return 0; }
static void array_set(awk_array_t array, const char *sub, awk_value_t *value) { awk_value_t index; set_array_element(array, make_const_string(sub, strlen(sub), & index), value); }
/* - .filenamelistseparator <string> */ static int zfilenamelistseparator(i_ctx_t *i_ctx_p) { os_ptr op = osp; push(1); make_const_string(op, avm_foreign | a_readonly, 1, (const byte *)&gp_file_name_list_separator); return 0; }
/* <device> .devicename <string> */ static int zdevicename(i_ctx_t *i_ctx_p) { os_ptr op = osp; const char *dname; check_read_type(*op, t_device); dname = op->value.pdevice->dname; make_const_string(op, avm_foreign | a_readonly, strlen(dname), (const byte *)dname); return 0; }
/* <cid9font> <cid> .type9mapcid <charstring> <font_index> */ int ztype9mapcid(i_ctx_t *i_ctx_p) { os_ptr op = osp; gs_font *pfont; gs_font_cid0 *pfcid; int code = font_param(op - 1, &pfont); gs_glyph_data_t gdata; int fidx; if (code < 0) return code; if (pfont->FontType != ft_CID_encrypted) return_error(e_invalidfont); check_type(*op, t_integer); pfcid = (gs_font_cid0 *)pfont; gdata.memory = pfont->memory; code = pfcid->cidata.glyph_data((gs_font_base *)pfcid, (gs_glyph)(gs_min_cid_glyph + op->value.intval), &gdata, &fidx); /* return code; original error-sensitive & fragile code */ if (code < 0) { /* failed to load glyph data, put CID 0 */ int default_fallback_CID = 0 ; if_debug2('J', "[J]ztype9cidmap() use CID %d instead of glyph-missing CID %d\n", default_fallback_CID, op->value.intval); op->value.intval = default_fallback_CID; /* reload glyph for default_fallback_CID */ code = pfcid->cidata.glyph_data((gs_font_base *)pfcid, (gs_glyph)(gs_min_cid_glyph + default_fallback_CID), &gdata, &fidx); if (code < 0) { if_debug1('J', "[J]ztype9cidmap() could not load default glyph (CID %d)\n", op->value.intval); return_error(e_invalidfont); } } /****** FOLLOWING IS NOT GENERAL W.R.T. ALLOCATION OF GLYPH DATA ******/ make_const_string(op - 1, a_readonly | imemory_space((gs_ref_memory_t *)pfont->memory), gdata.bits.size, gdata.bits.data); make_int(op, fidx); return code; }
/* r_size(op1) was set just above. */ static int do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1) { os_ptr op = osp; ref *arefs = op1->value.refs; uint asize = r_size(op1); uint i; ref *rq; /* * Copy elements from the stack to the array, * optionally skipping executable nulls. * Clear the executable bit in any internal operators, and * convert t_structs and t_astructs (which can only appear * in connection with stack marks, which means that they will * probably be freed when unwinding) to something harmless. */ for (i = 0, rq = arefs + asize; rq != arefs; ++i) { const ref *rp = ref_stack_index(&e_stack, (long)i); if (r_has_type_attrs(rp, t_null, a_executable) && !include_marks) continue; --rq; ref_assign_old(op1, rq, rp, "execstack"); switch (r_type(rq)) { case t_operator: { uint opidx = op_index(rq); if (opidx == 0 || op_def_is_internal(op_index_def(opidx))) r_clear_attrs(rq, a_executable); break; } case t_struct: case t_astruct: { const char *tname = rq->value.pstruct ? gs_struct_type_name_string( gs_object_type(imemory, rq->value.pstruct)) : "NULL"; make_const_string(rq, a_readonly | avm_foreign, strlen(tname), (const byte *)tname); break; } default: ; } } pop(op - op1); return 0; }
static awk_bool_t init_testext(void) { awk_value_t value; static const char message[] = "hello, world"; /* of course */ static const char message2[] = "i am a scalar"; /* add at_exit functions */ awk_atexit(at_exit0, NULL); awk_atexit(at_exit1, & data_for_1); awk_atexit(at_exit2, NULL); /* BEGIN { printf("answer_num = %g\n", answer_num); printf("message_string = %s\n", message_string); for (i in new_array) printf("new_array[\"%s\"] = \"%s\"\n", i, new_array[i]) print "" } */ /* install some variables */ if (! sym_update("answer_num", make_number(42, & value))) printf("testext: sym_update(\"answer_num\") failed!\n"); if (! sym_update("message_string", make_const_string(message, strlen(message), & value))) printf("testext: sym_update(\"answer_num\") failed!\n"); if (! sym_update("the_scalar", make_const_string(message2, strlen(message2), & value))) printf("testext: sym_update(\"the_scalar\") failed!\n"); create_new_array(); return awk_true; }
/* Prepare to write a string value. */ static int ref_param_write_string_value(ref * pref, const gs_param_string * pvalue, gs_ref_memory_t *imem) { const byte *pdata = pvalue->data; uint n = pvalue->size; if (pvalue->persistent) make_const_string(pref, a_readonly | avm_foreign, n, pdata); else { byte *pstr = gs_alloc_string((gs_memory_t *)imem, n, "ref_param_write_string"); if (pstr == 0) return_error(e_VMerror); memcpy(pstr, pdata, n); make_string(pref, a_readonly | imemory_space(imem), n, pstr); } return 0; }
/* <int> .getiodevice <string|null> */ static int zgetiodevice(i_ctx_t *i_ctx_p) { os_ptr op = osp; gx_io_device *iodev; const byte *dname; check_type(*op, t_integer); if (op->value.intval != (int)op->value.intval) return_error(e_rangecheck); iodev = gs_getiodevice((int)(op->value.intval)); if (iodev == 0) /* index out of range */ return_error(e_rangecheck); dname = (const byte *)iodev->dname; if (dname == 0) make_null(op); else make_const_string(op, a_readonly | avm_foreign, strlen((const char *)dname), dname); return 0; }
static void fill_stat_element(awk_array_t element_array, const char *name, struct stat *sbuf) { awk_value_t index, value; awk_array_t stat_array; stat_array = create_array(); if (stat_array == NULL) { warning(ext_id, _("fill_stat_element: could not create array")); fts_errors++; return; } fill_stat_array(name, stat_array, sbuf); (void) make_const_string("stat", 4, & index); value.val_type = AWK_ARRAY; value.array_cookie = stat_array; if (! set_array_element(element_array, & index, & value)) { warning(ext_id, _("fill_stat_element: could not set element")); fts_errors++; } }
static awk_value_t * test_scalar(int nargs, awk_value_t *result) { awk_value_t new_value, new_value2; awk_value_t the_scalar; (void) nargs; /* silence warnings */ make_number(0.0, result); if (! sym_lookup("the_scalar", AWK_SCALAR, & the_scalar)) { printf("test_scalar: could not get scalar cookie\n"); goto out; } if (! get_argument(0, AWK_UNDEFINED, & new_value)) { printf("test_scalar: could not get argument\n"); goto out; } else if (new_value.val_type != AWK_STRING && new_value.val_type != AWK_NUMBER) { printf("test_scalar: argument is not a scalar\n"); goto out; } if (new_value.val_type == AWK_STRING) { make_const_string(new_value.str_value.str, new_value.str_value.len, & new_value2); } else { new_value2 = new_value; } if (! sym_update_scalar(the_scalar.scalar_cookie, & new_value2)) { printf("test_scalar: could not update new_value2!\n"); goto out; } make_number(1.0, result); out: return result; }
static awk_value_t * try_modify_environ(int nargs, awk_value_t *result) { awk_value_t value, index, newvalue; awk_flat_array_t *flat_array; awk_array_t environ_array; size_t count; int i; assert(result != NULL); make_number(0.0, result); if (nargs != 0) { printf("try_modify_environ: nargs not right (%d should be 0)\n", nargs); goto out; } /* get ENVIRON array */ if (sym_lookup("ENVIRON", AWK_ARRAY, & value)) printf("try_modify_environ: sym_lookup of ENVIRON passed\n"); else { printf("try_modify_environ: sym_lookup of ENVIRON failed\n"); goto out; } environ_array = value.array_cookie; if (! get_element_count(environ_array, & count)) { printf("try_modify_environ: get_element_count failed\n"); goto out; } /* setting an array element should fail */ (void) make_const_string("testext2", 8, & index); (void) make_const_string("a value", 7, & value); if (set_array_element(environ_array, & index, & newvalue)) { printf("try_modify_environ: set_array_element of ENVIRON passed\n"); } else { printf("try_modify_environ: set_array_element of ENVIRON failed\n"); gawk_free(index.str_value.str); gawk_free(value.str_value.str); } if (! flatten_array(environ_array, & flat_array)) { printf("try_modify_environ: could not flatten array\n"); goto out; } if (flat_array->count != count) { printf("try_modify_environ: flat_array->count (%lu) != count (%lu)\n", (unsigned long) flat_array->count, (unsigned long) count); goto out; } for (i = 0; i < flat_array->count; i++) { /* don't print */ /* printf("\t%s[\"%.*s\"] = %s\n", name, (int) flat_array->elements[i].index.str_value.len, flat_array->elements[i].index.str_value.str, valrep2str(& flat_array->elements[i].value)); */ if (strcmp("testext", flat_array->elements[i].index.str_value.str) == 0) { flat_array->elements[i].flags |= AWK_ELEMENT_DELETE; printf("try_modify_environ: marking element \"%s\" for deletion\n", flat_array->elements[i].index.str_value.str); } } if (! release_flattened_array(environ_array, flat_array)) { printf("try_modify_environ: could not release flattened array\n"); goto out; } make_number(1.0, result); out: return result; }
/* <prefix|null> <access_string> .tempfile <name_string> <file> */ static int ztempfile(i_ctx_t *i_ctx_p) { os_ptr op = osp; const char *pstr; char fmode[4]; int code = parse_file_access_string(op, fmode); char prefix[gp_file_name_sizeof]; char fname[gp_file_name_sizeof]; uint fnlen; FILE *sfile; stream *s; byte *buf; if (code < 0) return code; strcat(fmode, gp_fmode_binary_suffix); if (r_has_type(op - 1, t_null)) pstr = gp_scratch_file_name_prefix; else { uint psize; check_read_type(op[-1], t_string); psize = r_size(op - 1); if (psize >= gp_file_name_sizeof) return_error(e_rangecheck); memcpy(prefix, op[-1].value.const_bytes, psize); prefix[psize] = 0; pstr = prefix; } if (gp_file_name_is_absolute(pstr, strlen(pstr))) { if (check_file_permissions(i_ctx_p, pstr, strlen(pstr), "PermitFileWriting") < 0) { return_error(e_invalidfileaccess); } } else if (!prefix_is_simple(pstr)) { return_error(e_invalidfileaccess); } s = file_alloc_stream(imemory, "ztempfile(stream)"); if (s == 0) return_error(e_VMerror); buf = gs_alloc_bytes(imemory, file_default_buffer_size, "ztempfile(buffer)"); if (buf == 0) return_error(e_VMerror); sfile = gp_open_scratch_file(pstr, fname, fmode); if (sfile == 0) { gs_free_object(imemory, buf, "ztempfile(buffer)"); return_error(e_invalidfileaccess); } fnlen = strlen(fname); file_init_stream(s, sfile, fmode, buf, file_default_buffer_size); code = ssetfilename(s, (const unsigned char*) fname, fnlen); if (code < 0) { sclose(s); iodev_default->procs.delete_file(iodev_default, fname); return_error(e_VMerror); } make_const_string(op - 1, a_readonly | icurrent_space, fnlen, s->file_name.data); make_stream_file(op, s, fmode); return code; }
static int fill_stat_array(const char *name, awk_array_t array, struct stat *sbuf) { char *pmode; /* printable mode */ const char *type = "unknown"; awk_value_t tmp; static struct ftype_map { unsigned int mask; const char *type; } ftype_map[] = { { S_IFREG, "file" }, { S_IFBLK, "blockdev" }, { S_IFCHR, "chardev" }, { S_IFDIR, "directory" }, #ifdef S_IFSOCK { S_IFSOCK, "socket" }, #endif #ifdef S_IFIFO { S_IFIFO, "fifo" }, #endif #ifdef S_IFLNK { S_IFLNK, "symlink" }, #endif #ifdef S_IFDOOR /* Solaris weirdness */ { S_IFDOOR, "door" }, #endif /* S_IFDOOR */ }; int j, k; /* empty out the array */ clear_array(array); /* fill in the array */ array_set(array, "name", make_const_string(name, strlen(name), & tmp)); array_set_numeric(array, "dev", sbuf->st_dev); array_set_numeric(array, "ino", sbuf->st_ino); array_set_numeric(array, "mode", sbuf->st_mode); array_set_numeric(array, "nlink", sbuf->st_nlink); array_set_numeric(array, "uid", sbuf->st_uid); array_set_numeric(array, "gid", sbuf->st_gid); array_set_numeric(array, "size", sbuf->st_size); array_set_numeric(array, "blocks", sbuf->st_blocks); array_set_numeric(array, "atime", sbuf->st_atime); array_set_numeric(array, "mtime", sbuf->st_mtime); array_set_numeric(array, "ctime", sbuf->st_ctime); /* for block and character devices, add rdev, major and minor numbers */ if (S_ISBLK(sbuf->st_mode) || S_ISCHR(sbuf->st_mode)) { array_set_numeric(array, "rdev", sbuf->st_rdev); array_set_numeric(array, "major", major(sbuf->st_rdev)); array_set_numeric(array, "minor", minor(sbuf->st_rdev)); } #ifdef HAVE_ST_BLKSIZE array_set_numeric(array, "blksize", sbuf->st_blksize); #endif /* HAVE_ST_BLKSIZE */ pmode = format_mode(sbuf->st_mode); array_set(array, "pmode", make_const_string(pmode, strlen(pmode), & tmp)); /* for symbolic links, add a linkval field */ if (S_ISLNK(sbuf->st_mode)) { char *buf; ssize_t linksize; if ((buf = read_symlink(name, sbuf->st_size, & linksize)) != NULL) array_set(array, "linkval", make_malloced_string(buf, linksize, & tmp)); else warning(ext_id, "stat: unable to read symbolic link `%s'", name); } /* add a type field */ type = "unknown"; /* shouldn't happen */ for (j = 0, k = sizeof(ftype_map)/sizeof(ftype_map[0]); j < k; j++) { if ((sbuf->st_mode & S_IFMT) == ftype_map[j].mask) { type = ftype_map[j].type; break; } } array_set(array, "type", make_const_string(type, strlen(type), &tmp)); return 0; }
/* BEGIN { n = split("one two three four five six", test_array2) ret = test_array_elem(test_array2, "3") printf("test_array_elem() returned %d, test_array2[3] = %g\n", ret, test_array2[3]) if ("5" in test_array2) printf("error: test_array_elem() did not remove element \"5\"\n") else printf("test_array_elem() did remove element \"5\"\n") if ("7" in test_array2) printf("test_array_elem() added element \"7\" --> %s\n", test_array2[7]) else printf("test_array_elem() did not add element \"7\"\n") if ("subarray" in test_array2) { if (isarray(test_array2["subarray"])) { for (i in test_array2["subarray"]) printf("test_array2[\"subarray\"][\"%s\"] = %s\n", i, test_array2["subarray"][i]) } else printf("test_array_elem() added element \"subarray\" as scalar\n") } else printf("test_array_elem() did not add element \"subarray\"\n") print "" } */ static awk_value_t * test_array_elem(int nargs, awk_value_t *result) { awk_value_t array, index, index2, value; make_number(0.0, result); /* default return until full success */ assert(result != NULL); if (nargs != 2) { printf("test_array_elem: nargs not right (%d should be 2)\n", nargs); goto out; } /* look up an array element and print the value */ if (! get_argument(0, AWK_ARRAY, & array)) { printf("test_array_elem: get_argument 0 (array) failed\n"); goto out; } if (! get_argument(1, AWK_STRING, & index)) { printf("test_array_elem: get_argument 1 (index) failed\n"); goto out; } (void) make_const_string(index.str_value.str, index.str_value.len, & index2); if (! get_array_element(array.array_cookie, & index2, AWK_UNDEFINED, & value)) { printf("test_array_elem: get_array_element failed\n"); goto out; } printf("test_array_elem: a[\"%.*s\"] = %s\n", (int) index.str_value.len, index.str_value.str, valrep2str(& value)); /* change the element - "3" */ (void) make_number(42.0, & value); (void) make_const_string(index.str_value.str, index.str_value.len, & index2); if (! set_array_element(array.array_cookie, & index2, & value)) { printf("test_array_elem: set_array_element failed\n"); goto out; } /* delete another element - "5" */ (void) make_const_string("5", 1, & index); if (! del_array_element(array.array_cookie, & index)) { printf("test_array_elem: del_array_element failed\n"); goto out; } /* add a new element - "7" */ (void) make_const_string("7", 1, & index); (void) make_const_string("seven", 5, & value); if (! set_array_element(array.array_cookie, & index, & value)) { printf("test_array_elem: set_array_element failed\n"); goto out; } /* add a subarray */ (void) make_const_string("subarray", 8, & index); fill_in_array(& value); if (! set_array_element(array.array_cookie, & index, & value)) { printf("test_array_elem: set_array_element (subarray) failed\n"); goto out; } /* change and deletion should be reflected in awk script */ make_number(1.0, result); out: return result; }
static void process(FTS *heirarchy, awk_array_t destarray, int seedot) { FTSENT *fentry; awk_value_t index, value; awk_array_t element_array, newdir_array, dot_array; int bad_ret = 0; /* path is full path, pathlen is length thereof */ /* name is name in directory, namelen is length thereof */ while ((fentry = fts_read(heirarchy)) != NULL) { bad_ret = 0; switch (fentry->fts_info) { case FTS_D: /* directory */ /* create array to hold entries */ newdir_array = create_array(); if (newdir_array == NULL) { warning(ext_id, _("fts-process: could not create array")); fts_errors++; break; } /* store new directory in its parent directory */ (void) make_const_string(fentry->fts_name, fentry->fts_namelen, & index); value.val_type = AWK_ARRAY; value.array_cookie = newdir_array; if (! set_array_element(destarray, & index, & value)) { warning(ext_id, _("fts-process: could not set element")); fts_errors++; break; } newdir_array = value.array_cookie; /* push current directory */ stack_push(destarray); /* new directory becomes current */ destarray = newdir_array; break; case FTS_DNR: case FTS_DC: case FTS_ERR: case FTS_NS: /* error */ bad_ret = 1; /* fall through */ case FTS_NSOK: case FTS_SL: case FTS_SLNONE: case FTS_F: case FTS_DOT: /* if see dot, skip "." */ if (seedot && strcmp(fentry->fts_name, ".") == 0) break; /* * File case. * destarray is the directory we're reading. * step 1: create new empty array */ element_array = create_array(); if (element_array == NULL) { warning(ext_id, _("fts-process: could not create array")); fts_errors++; break; } /* step 2: add element array to parent array */ (void) make_const_string(fentry->fts_name, fentry->fts_namelen, & index); value.val_type = AWK_ARRAY; value.array_cookie = element_array; if (! set_array_element(destarray, & index, & value)) { warning(ext_id, _("fts-process: could not set element")); fts_errors++; break; } /* step 3: fill in path, stat, error elements */ fill_default_elements(element_array, fentry, bad_ret); break; case FTS_DP: /* create "." subarray */ dot_array = create_array(); /* add it to parent */ (void) make_const_string(".", 1, & index); value.val_type = AWK_ARRAY; value.array_cookie = dot_array; if (! set_array_element(destarray, & index, & value)) { warning(ext_id, _("fts-process: could not set element")); fts_errors++; break; } /* fill it in with path, stat, error elements */ fill_default_elements(dot_array, fentry, bad_ret); /* now pop the parent directory off the stack */ if (! stack_empty()) { /* pop stack */ destarray = stack_pop(); } break; case FTS_DEFAULT: /* nothing to do */ break; } } }