/* obj readonly obj reduce access attribute for obj to read-only */ static int Areadonly(Xpost_Context *ctx, Xpost_Object o) { //o.tag &= ~XPOST_OBJECT_TAG_DATA_FLAG_ACCESS_MASK; //o.tag |= (XPOST_OBJECT_TAG_ACCESS_READ_ONLY << XPOST_OBJECT_TAG_DATA_FLAG_ACCESS_OFFSET); o = xpost_object_set_access(ctx, o, XPOST_OBJECT_TAG_ACCESS_READ_ONLY); xpost_stack_push(ctx->lo, ctx->os, o); return 0; }
static int packedarray (Xpost_Context *ctx, Xpost_Object n) { int i; Xpost_Object a, v; a = xpost_array_cons(ctx, n.int_.val); if (xpost_object_get_type(a) == nulltype) return VMerror; for (i=n.int_.val; i > 0; i--) { v = xpost_stack_pop(ctx->lo, ctx->os); if (xpost_object_get_type(v) == invalidtype) return stackunderflow; xpost_array_put(ctx, a, i-1, v); } a = xpost_object_set_access(ctx, xpost_object_cvlit(a), XPOST_OBJECT_TAG_ACCESS_READ_ONLY); xpost_stack_push(ctx->lo, ctx->os, a); return 0; }
/* FIXME remove duplication of effort here and in bin/xpost_main.c (ie. there should be 1 table, not 2) Generates postscript code to initialize the selected device currentglobal false setglobal % allocate in local memory device_requires_loading? { loadXXXdevice } if % load if necessary userdict /DEVICE 612 792 newXXXdevice put % instantiate the device setglobal % reset previous allocation mode initialization of the device is deferred until the start procedure has initialized graphics (importantly, the ppmimage base class). the loadXXXdevice operators all specialize the ppmimage base class and so must wait until it is available. also creates the definitions PACKAGE_DATA_DIR PACKAGE_INSTALL_DIR and EXE_DIR */ static void setlocalconfig(Xpost_Context *ctx, Xpost_Object sd, const char *device, const char *outfile, const char *bufferin, char **bufferout, Xpost_Showpage_Semantics semantics, Xpost_Set_Size set_size, int width, int height) { const char *device_strings[][3] = { { "pgm", "", "newPGMIMAGEdevice" }, { "ppm", "", "newPPMIMAGEdevice" }, { "null", "", "newnulldevice" }, { "xcb", "loadxcbdevice", "newxcbdevice" }, { "gdi", "loadwin32device", "newwin32device" }, { "gl", "loadwin32device", "newwin32device" }, { "bgr", "loadbgrdevice", "newbgrdevice" }, { "raster", "loadrasterdevice", "newrasterdevice" }, { "png", "loadpngdevice", "newpngdevice" }, { "jpeg", "loadjpegdevice", "newjpegdevice" }, { NULL, NULL, NULL } }; const char *strtemplate = "currentglobal false setglobal " "%s userdict /DEVICE %s %s put " "setglobal"; Xpost_Object namenewdev; Xpost_Object newdevstr; int i; char *devstr; char *subdevice; char *dimensions; ctx->vmmode = GLOBAL; #ifdef _WIN32 xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "WIN32"), xpost_bool_cons(1)); #endif devstr = strdup(device); /* Parse device string for mode selector "dev:mode" */ if ((subdevice=strchr(devstr, ':'))) { *subdevice++ = '\0'; xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "SUBDEVICE"), xpost_object_cvlit(xpost_string_cons(ctx, strlen(subdevice), subdevice))); } /* define the /newdefaultdevice name called by /start */ for (i = 0; device_strings[i][0]; i++) { if (strcmp(devstr, device_strings[i][0]) == 0) { break; } } if (set_size == XPOST_USE_SIZE){ dimensions = malloc(2 + (int)ceil(log10(width)) + (int)ceil(log10(height))); sprintf(dimensions, "%d %d", width, height); } else { static char x[] = "612 792"; dimensions = x; } newdevstr = xpost_string_cons(ctx, strlen(strtemplate) - 6 + strlen(device_strings[i][1]) + strlen(dimensions) + strlen(device_strings[i][2]) + 1, NULL); sprintf(xpost_string_get_pointer(ctx, newdevstr), strtemplate, device_strings[i][1], dimensions, device_strings[i][2]); --newdevstr.comp_.sz; /* trim the '\0' */ namenewdev = xpost_name_cons(ctx, "newdefaultdevice"); xpost_dict_put(ctx, sd, namenewdev, xpost_object_cvx(newdevstr)); xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "ShowpageSemantics"), xpost_int_cons(semantics)); if (outfile) { xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "OutputFileName"), xpost_object_cvlit(xpost_string_cons(ctx, strlen(outfile), outfile))); } if (bufferin) { Xpost_Object s = xpost_object_cvlit(xpost_string_cons(ctx, sizeof(bufferin), NULL)); xpost_object_set_access(ctx, s, XPOST_OBJECT_TAG_ACCESS_NONE); memcpy(xpost_string_get_pointer(ctx, s), &bufferin, sizeof(bufferin)); xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "OutputBufferIn"), s); } if (bufferout) { Xpost_Object s = xpost_object_cvlit(xpost_string_cons(ctx, sizeof(bufferout), NULL)); xpost_object_set_access(ctx, s, XPOST_OBJECT_TAG_ACCESS_NONE); memcpy(xpost_string_get_pointer(ctx, s), &bufferout, sizeof(bufferout)); xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "OutputBufferOut"), s); } ctx->vmmode = LOCAL; free(devstr); }
/* create an executable context using the given device, output configuration, and semantics. */ XPAPI Xpost_Context *xpost_create(const char *device, Xpost_Output_Type output_type, const void *outputptr, Xpost_Showpage_Semantics semantics, Xpost_Output_Message output_msg, Xpost_Set_Size set_size, int width, int height) { Xpost_Object sd, ud; int ret; const char *outfile = NULL; const char *bufferin = NULL; char **bufferout = NULL; int quiet; switch (output_msg) { case XPOST_OUTPUT_MESSAGE_QUIET: quiet = 1; _xpost_interpreter_is_tracing = 0; break; case XPOST_OUTPUT_MESSAGE_VERBOSE: quiet = 0; _xpost_interpreter_is_tracing = 0; break; case XPOST_OUTPUT_MESSAGE_TRACING: quiet = 0; _xpost_interpreter_is_tracing = 1; break; default: XPOST_LOG_ERR("Wrong output message value"); return NULL;; } switch (output_type) { case XPOST_OUTPUT_FILENAME: outfile = outputptr; break; case XPOST_OUTPUT_BUFFERIN: bufferin = outputptr; break; case XPOST_OUTPUT_BUFFEROUT: bufferout = (char **)outputptr; break; case XPOST_OUTPUT_DEFAULT: break; } #if 0 test_memory(); if (!test_garbage_collect(xpost_interpreter_cid_init, xpost_interpreter_cid_get_context, xpost_interpreter_get_initializing, xpost_interpreter_set_initializing, xpost_interpreter_alloc_local_memory, xpost_interpreter_alloc_global_memory)) return NULL; #endif nextid = 0; /*reset process counter */ /* Allocate and initialize all interpreter data structures. */ ret = initalldata(device); if (!ret) { return NULL; } /* extract systemdict and userdict for additional definitions */ sd = xpost_stack_bottomup_fetch(xpost_ctx->lo, xpost_ctx->ds, 0); ud = xpost_stack_bottomup_fetch(xpost_ctx->lo, xpost_ctx->ds, 2); setlocalconfig(xpost_ctx, sd, device, outfile, bufferin, bufferout, semantics, set_size, width, height); if (quiet) { xpost_dict_put(xpost_ctx, sd /*xpost_stack_bottomup_fetch(ctx->lo, ctx->ds, 0)*/ , xpost_name_cons(xpost_ctx, "QUIET"), null); } xpost_stack_clear(xpost_ctx->lo, xpost_ctx->hold); xpost_interpreter_set_initializing(0); loadinitps(xpost_ctx); ret = copyudtosd(xpost_ctx, ud, sd); if (ret) { XPOST_LOG_ERR("%s error in copyudtosd", errorname[ret]); return NULL; } /* make systemdict readonly FIXME: use new access semantics */ xpost_dict_put(xpost_ctx, sd, xpost_name_cons(xpost_ctx, "systemdict"), sd); xpost_object_set_access(xpost_ctx, sd, XPOST_OBJECT_TAG_ACCESS_READ_ONLY); #if 0 if (!xpost_stack_bottomup_replace(xpost_ctx->lo, xpost_ctx->ds, 0, xpost_object_set_access(xpost_ctx, sd, XPOST_OBJECT_TAG_ACCESS_READ_ONLY))) { XPOST_LOG_ERR("cannot replace systemdict in dict stack"); return NULL; } #endif xpost_interpreter_set_initializing(0); return xpost_ctx; }