XPAPI int xpost_add_definitions(Xpost_Context *ctx, int cnt, char *defs[])
{
    int i;
    Xpost_Object ud;

    if (!ctx) return 0;
    XPOST_LOG_INFO("adding %d defs", cnt);

    ud = xpost_stack_bottomup_fetch(ctx->lo, ctx->ds, 2);
    for (i = 0; i < cnt; i++)
    {
        char *eq = strchr(defs[i], '=');

        XPOST_LOG_INFO("%s", defs[i]);
        if (eq)
        {
            *eq++ = '\0';
            xpost_dict_put(ctx, ud,
                    xpost_name_cons(ctx, defs[i]),
                    get_token(ctx, eq));
            eq[-1] = '=';
        }
        else
        {
            xpost_dict_put(ctx, ud,
                    xpost_name_cons(ctx, defs[i]),
                    null);
        }
    }
    return 1;
}
Exemple #2
0
int xpost_oper_init_stack_ops (Xpost_Context *ctx,
             Xpost_Object sd)
{
    Xpost_Operator *optab;
    Xpost_Object n,op;
    unsigned int optadr;

    assert(ctx->gl->base);
    xpost_memory_table_get_addr(ctx->gl,
            XPOST_MEMORY_TABLE_SPECIAL_OPERATOR_TABLE, &optadr);
    optab = (void *)(ctx->gl->base + optadr);
    op = xpost_operator_cons(ctx, "pop", (Xpost_Op_Func)Apop, 0, 1, anytype);
    INSTALL;
    op = xpost_operator_cons(ctx, "exch", (Xpost_Op_Func)AAexch, 2, 2, anytype, anytype);
    INSTALL;
    op = xpost_operator_cons(ctx, "dup", (Xpost_Op_Func)Adup, 2, 1, anytype);
    INSTALL;
    op = xpost_operator_cons(ctx, "copy", (Xpost_Op_Func)Icopy, 0, 1, integertype);
    INSTALL;
    op = xpost_operator_cons(ctx, "index", (Xpost_Op_Func)Iindex, 1, 1, integertype);
    INSTALL;
    //xpost_dict_dump_memory (ctx->gl, sd); fflush(NULL);
    op = xpost_operator_cons(ctx, "roll", (Xpost_Op_Func)IIroll, 0, 2, integertype, integertype);
    INSTALL;
    op = xpost_operator_cons(ctx, "clear", (Xpost_Op_Func)Zclear, 0, 0);
    INSTALL;
    op = xpost_operator_cons(ctx, "count", (Xpost_Op_Func)Zcount, 1, 0);
    INSTALL;
    xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "mark"), mark);
    op = xpost_operator_cons(ctx, "cleartomark", (Xpost_Op_Func)xpost_op_cleartomark, 0, 0);
    INSTALL;
    op = xpost_operator_cons(ctx, "counttomark", (Xpost_Op_Func)xpost_op_counttomark, 1, 0);
    INSTALL;
    return 0;
}
Exemple #3
0
/* initialize the C-level data
   and define in the device instance */
static
int _create_cont (Xpost_Context *ctx,
                  Xpost_Object w,
                  Xpost_Object h,
                  Xpost_Object devdic)
{
    Xpost_Object privatestr;
    PrivateData private;
    xcb_screen_iterator_t iter;
    xcb_get_geometry_reply_t *geom;
    integer width = w.int_.val;
    integer height = h.int_.val;
    int scrno;
    unsigned char depth;

    /* create a string to contain device data structure */
    privatestr = xpost_string_cons(ctx, sizeof(PrivateData), NULL);
    if (xpost_object_get_type(privatestr) == invalidtype)
    {
        XPOST_LOG_ERR("cannot allocat private data structure");
        return unregistered;
    }
    xpost_dict_put(ctx, devdic, namePrivate, privatestr);

    private.width = width;
/* copy userdict names to systemdict
    Problem: This is clearly an invalidaccess,
    and yet is required by the PLRM. Discussion:
https://groups.google.com/d/msg/comp.lang.postscript/VjCI0qxkGY4/y0urjqRA1IoJ
    The ignoreinvalidaccess exception has been isolated to this one case.
 */
static int copyudtosd(Xpost_Context *ctx, Xpost_Object ud, Xpost_Object sd)
{
    Xpost_Object ed, de;

    ctx->ignoreinvalidaccess = 1;
    xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "userdict"), ud);
    ed = xpost_dict_get(ctx, ud, xpost_name_cons(ctx, "errordict"));
    if (xpost_object_get_type(ed) == invalidtype)
        return undefined;
    xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "errordict"), ed);
    de = xpost_dict_get(ctx, ud, xpost_name_cons(ctx, "$error"));
    if (xpost_object_get_type(de) == invalidtype)
        return undefined;
    xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "$error"), de);
    ctx->ignoreinvalidaccess = 0;
    return 0;
}
static
int setpacking (Xpost_Context *ctx,
                 Xpost_Object b)
{
    Xpost_Object sd = xpost_stack_bottomup_fetch(ctx->lo, ctx->ds, 0);
    xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "currentpacking"), b);
    return 0;
}
Exemple #6
0
/* create an instance of the device
   using the class .copydict procedure */
static
int _create (Xpost_Context *ctx,
             Xpost_Object width,
             Xpost_Object height,
             Xpost_Object classdic)
{
    xpost_stack_push(ctx->lo, ctx->os, width);
    xpost_stack_push(ctx->lo, ctx->os, height);
    xpost_stack_push(ctx->lo, ctx->os, classdic);
    xpost_dict_put(ctx, classdic, namewidth, width);
    xpost_dict_put(ctx, classdic, nameheight, height);

    /* call device class's ps-level .copydict procedure,
       then call _create_cont, by continuation. */
    if (!xpost_stack_push(ctx->lo, ctx->es, xpost_operator_cons_opcode(_create_cont_opcode)))
        return execstackoverflow;
    if (!xpost_stack_push(ctx->lo, ctx->es, xpost_dict_get(ctx, classdic,
                    //xpost_name_cons(ctx, ".copydict")
                    namedotcopydict
                    )))
        return execstackoverflow;

    return 0;
}
int xpost_oper_init_packedarray_ops (Xpost_Context *ctx,
              Xpost_Object sd)
{
    Xpost_Operator *optab;
    Xpost_Object n,op;
    unsigned int optadr;

    assert(ctx->gl->base);
    xpost_memory_table_get_addr(ctx->gl,
            XPOST_MEMORY_TABLE_SPECIAL_OPERATOR_TABLE, &optadr);
    optab = (void *)(ctx->gl->base + optadr);

    op = xpost_operator_cons(ctx, "packedarray", (Xpost_Op_Func)packedarray, 1, 1, integertype);
    INSTALL;
    xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "currentpacking"), xpost_bool_cons(0));
    op = xpost_operator_cons(ctx, "setpacking", (Xpost_Op_Func)setpacking, 0, 1, booleantype);
    INSTALL;

    /* xpost_dict_dump_memory (ctx->gl, sd); fflush(NULL);
    xpost_dict_put(ctx, sd, xpost_name_cons(ctx, "mark"), mark); */

    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);
}
/* initialize the name string stacks and name search trees (per memory file).
   seed the search trees.
   initialize and populate the optab and systemdict (global memory file).
   push systemdict on dict stack.
   allocate and push globaldict on dict stack.
   allocate and push userdict on dict stack.
   return 1 on success, 0 on failure
 */
static
int _xpost_interpreter_extra_context_init(Xpost_Context *ctx, const char *device)
{
    int ret;
    ret = xpost_name_init(ctx); /* NAMES NAMET */
    if (!ret)
    {
        xpost_memory_file_exit(ctx->lo);
        xpost_memory_file_exit(ctx->gl);
        return 0;
    }
    ctx->vmmode = GLOBAL;

    ret = xpost_operator_init_optab(ctx); /* allocate and zero the optab structure */
    if (!ret)
    {
        xpost_memory_file_exit(ctx->lo);
        xpost_memory_file_exit(ctx->gl);
        return 0;
    }

    /* seed the tree with a word from the middle of the alphabet */
    /* middle of the start */
    /* middle of the end */
    if (xpost_object_get_type(xpost_name_cons(ctx, "maxlength")) == invalidtype)
        return 0;
    if (xpost_object_get_type(xpost_name_cons(ctx, "getinterval")) == invalidtype)
        return 0;
    if (xpost_object_get_type(xpost_name_cons(ctx, "setmiterlimit")) == invalidtype)
        return 0;
    if (xpost_object_get_type((namedollarerror = xpost_name_cons(ctx, "$error"))) == invalidtype)
        return 0;
    if (xpost_object_get_type((nameerrordict = xpost_name_cons(ctx, "errordict"))) == invalidtype)
        return 0;

    xpost_oplib_init_ops(ctx); /* populate the optab (and systemdict) with operators */

    {
        Xpost_Object gd; /*globaldict */
        gd = xpost_dict_cons (ctx, 100);
        if (xpost_object_get_type(gd) == nulltype)
        {
            XPOST_LOG_ERR("cannot allocate globaldict");
            return 0;
        }
        ret = xpost_dict_put(ctx, xpost_stack_bottomup_fetch(ctx->lo, ctx->ds, 0), xpost_name_cons(ctx, "globaldict"), gd);
        if (ret)
            return 0;
        xpost_stack_push(ctx->lo, ctx->ds, gd);
    }

    ctx->vmmode = LOCAL;
    /* seed the tree with a word from the middle of the alphabet */
    /* middle of the start */
    /* middle of the end */
    if (xpost_object_get_type(xpost_name_cons(ctx, "minimal")) == invalidtype)
        return 0;
    if (xpost_object_get_type(xpost_name_cons(ctx, "interest")) == invalidtype)
        return 0;
    if (xpost_object_get_type(xpost_name_cons(ctx, "solitaire")) == invalidtype)
        return 0;
    {
        Xpost_Object ud; /*userdict */
        ud = xpost_dict_cons (ctx, 100);
        if (xpost_object_get_type(ud) == nulltype)
        {
            XPOST_LOG_ERR("cannot allocate userdict");
            return 0;
        }
        ret = xpost_dict_put(ctx, ud, xpost_name_cons(ctx, "userdict"), ud);
        if (ret)
            return 0;
        xpost_stack_push(ctx->lo, ctx->ds, ud);
    }

    ctx->device_str = device;

    return 1;
}
Exemple #10
0
/*
   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;
}