示例#1
0
/* print a dump of the name string stacks, global and local */
void xpost_name_dump_names(Xpost_Context *ctx)
{
    unsigned int stk;
    unsigned int cnt, i;
    Xpost_Object str;
    char *s;

    xpost_memory_table_get_addr(ctx->gl,
            XPOST_MEMORY_TABLE_SPECIAL_NAME_STACK, &stk);
    cnt = xpost_stack_count(ctx->gl, stk);
    printf("global names:\n");
    for (i=0; i < cnt; i++){
        str = xpost_stack_bottomup_fetch(ctx->gl, stk, i);
        s = xpost_string_get_pointer(ctx, str);
        printf("%u: %*s\n", i, str.comp_.sz, s);
    }
    xpost_memory_table_get_addr(ctx->lo,
            XPOST_MEMORY_TABLE_SPECIAL_NAME_STACK, &stk);
    cnt = xpost_stack_count(ctx->lo, stk);
    printf("local names:\n");
    for (i=0; i < cnt; i++) {
        str = xpost_stack_bottomup_fetch(ctx->lo, stk, i);
        s = xpost_string_get_pointer(ctx, str);
        printf("%u: %*s\n", i, str.comp_.sz, s);
    }
}
示例#2
0
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;
}
示例#3
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;
}
示例#4
0
/* yield the string object from the name string stack
    */
Xpost_Object xpost_name_get_string(Xpost_Context *ctx,
               Xpost_Object n)
{
    Xpost_Memory_File *mem = xpost_context_select_memory(ctx, n);
    unsigned int names;
    Xpost_Object str;
    xpost_memory_table_get_addr(mem,
            XPOST_MEMORY_TABLE_SPECIAL_NAME_STACK, &names);
    str = xpost_stack_bottomup_fetch(mem, names, n.mark_.padw);
    //str.tag |= XPOST_OBJECT_TAG_DATA_FLAG_BANK;
    return str;
}
示例#5
0
/*
   destroy the given context and associated memory files (if not in use by a shared context)
   exit interpreter if all contexts are destroyed.
 */
XPAPI void xpost_destroy(Xpost_Context *ctx)
{

    if (!xpost_dict_known_key(ctx, ctx->gl, xpost_stack_bottomup_fetch(ctx->lo, ctx->ds, 0), xpost_name_cons(ctx, "QUIET")))
    {
        printf("bye!\n");
        fflush(NULL);
    }
    /*xpost_garbage_collect(itpdata->ctab->gl, 1, 1); */
    /*xpost_garbage_collect(itpdata->ctab->lo, 1, 1); */
#if 0
#ifndef XPOST_NO_GC
    xpost_garbage_collect(ctx->gl, 1, 1);
    xpost_garbage_collect(ctx->lo, 1, 0);
#endif
#endif

    /* exit if all contexts are destroyed */
    /*xpost_interpreter_exit(itpdata); */
    /*free(itpdata); */
}
示例#6
0
/* called by mainloop() after propagated error codes.
   pushes postscript-level error procedures
   and resumes normal execution.
 */
static
void _onerror(Xpost_Context *ctx,
        unsigned int err)
{
    Xpost_Object sd;
    Xpost_Object ed;
    Xpost_Object dollarerror;

    if (err > unknownerror) err = unknownerror;

    if (!validate_context(ctx))
        XPOST_LOG_ERR("context not valid");

    if (itpdata->in_onerror > 5)
    {
        fprintf(stderr, "LOOP in error handler\nabort\n");
        ++ctx->quit;
        /*exit(undefinedresult); */
    }

    ++itpdata->in_onerror;

#ifdef EMITONERROR
    fprintf(stderr, "err: %s\n", errorname[err]);
#endif

    /* reset stack */
    if ((xpost_object_get_type(ctx->currentobject) == operatortype) &&
        (ctx->currentobject.tag & XPOST_OBJECT_TAG_DATA_FLAG_OPARGSINHOLD))
    {
        int n = ctx->currentobject.mark_.pad0;
        int i;
        for (i = 0; i < n; i++)
        {
            xpost_stack_push(ctx->lo, ctx->os,
                    xpost_stack_bottomup_fetch(ctx->lo, ctx->hold, i));
        }
    }

    /* printf("1\n"); */
    sd = xpost_stack_bottomup_fetch(ctx->lo, ctx->ds, 0);

    /* printf("2\n"); */
    dollarerror = xpost_dict_get(ctx, sd, namedollarerror);
    if (xpost_object_get_type(dollarerror) == invalidtype)
    {
        XPOST_LOG_ERR("cannot load $error dict for error: %s",
                errorname[err]);
        xpost_stack_push(ctx->lo, ctx->es,
                xpost_object_cvx(xpost_name_cons(ctx, "stop")));
        /*itpdata->in_onerror = 0; */
        return;
    }

    /* printf("3\n"); */
    /* printf("4\n"); */
    /* printf("5\n"); */
    xpost_stack_push(ctx->lo, ctx->os, ctx->currentobject);

#if 0
    /* printf("6\n"); */
    xpost_stack_push(ctx->lo, ctx->os, xpost_object_cvlit(xpost_name_cons(ctx, errorname[err])));
    /* printf("7\n"); */
    xpost_stack_push(ctx->lo, ctx->es, xpost_object_cvx(xpost_name_cons(ctx, "signalerror")));
#endif
    ed = xpost_dict_get(ctx, sd, nameerrordict);
    xpost_stack_push(ctx->lo, ctx->es,
            xpost_dict_get(ctx, ed,
                xpost_name_cons(ctx, errorname[err])));

    /* printf("8\n"); */
    itpdata->in_onerror = 0;
}
示例#7
0
/* 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;
}
示例#8
0
/*
   execute ps program until quit, fall-through to quit,
   SHOWPAGE_RETURN semantic, or error (default action: message, purge and quit).
 */
XPAPI int xpost_run(Xpost_Context *ctx, Xpost_Input_Type input_type, const void *inputptr, size_t set_size)
{
    Xpost_Object lsav = null;
    int llev = 0;
    unsigned int vs;
    const char *ps_str = NULL;
    const char *ps_file = NULL;
    const FILE *ps_file_ptr = NULL;
    int ret;
    Xpost_Object device;
    Xpost_Object semantic;

    switch(input_type)
    {
        case XPOST_INPUT_FILENAME:
            ps_file = inputptr;
            break;
        case XPOST_INPUT_STRING:
            ps_str = inputptr;
            ps_file_ptr = tmpfile();
            if (set_size)
                fwrite(ps_str, 1, set_size, (FILE*)ps_file_ptr);
            else
                fwrite(ps_str, 1, strlen(ps_str), (FILE*)ps_file_ptr);
            rewind((FILE*)ps_file_ptr);
            break;
        case XPOST_INPUT_FILEPTR:
            ps_file_ptr = inputptr;
            break;
        case XPOST_INPUT_RESUME: /* resuming a returned session, skip startup */
            goto run;
    }

    /* prime the exec stack
       so it starts with a 'start*' procedure,
       and if it ever gets to the bottom, it quits.
       These procedures are all defined in data/init.ps
     */
    xpost_stack_push(ctx->lo, ctx->es, xpost_operator_cons(ctx, "quit", NULL,0,0));
    /*
       if ps_file is NULL:
         if stdin is a tty
           `start` proc defined in init.ps runs `executive` which prompts for user input
         else
           'startstdin' executes stdin but does not prompt

       if ps_file is not NULL:
       'startfile' executes a named file wrapped in a stopped context with handleerror
    */
    if (ps_file)
    {
        /*printf("ps_file\n"); */
        xpost_stack_push(ctx->lo, ctx->os, xpost_object_cvlit(xpost_string_cons(ctx, strlen(ps_file), ps_file)));
        xpost_stack_push(ctx->lo, ctx->es, xpost_object_cvx(xpost_name_cons(ctx, "startfilename")));
    }
    else if (ps_file_ptr)
    {
        xpost_stack_push(ctx->lo, ctx->os, xpost_object_cvlit(xpost_file_cons(ctx->lo, ps_file_ptr)));
        xpost_stack_push(ctx->lo, ctx->es, xpost_object_cvx(xpost_name_cons(ctx, "startfile")));
    }
    else
    {
        if (xpost_isatty(fileno(stdin)))
            xpost_stack_push(ctx->lo, ctx->es, xpost_object_cvx(xpost_name_cons(ctx, "start")));
        else
            xpost_stack_push(ctx->lo, ctx->es, xpost_object_cvx(xpost_name_cons(ctx, "startstdin")));
    }

    (void) xpost_save_create_snapshot_object(ctx->gl);
    lsav = xpost_save_create_snapshot_object(ctx->lo);

    /* Run! */
run:
    ctx->quit = 0;
    ctx->state = C_RUN;
    ret = mainloop(ctx);

    semantic = xpost_dict_get(ctx,
                  xpost_stack_bottomup_fetch(ctx->lo, ctx->ds, 0),
                  xpost_name_cons(ctx, "ShowpageSemantics"));
    if (semantic.int_.val == XPOST_SHOWPAGE_RETURN)
        return ret == 1 ? yieldtocaller : 0;

    XPOST_LOG_INFO("destroying device");
    device = xpost_dict_get(ctx,
            xpost_stack_bottomup_fetch(ctx->lo, ctx->ds, 2),
            xpost_name_cons(ctx, "DEVICE"));
    XPOST_LOG_INFO("device type=%s", xpost_object_type_names[xpost_object_get_type(device)]);
    /*xpost_operator_dump(ctx, 1); // is this pointer value constant? */
    if (xpost_object_get_type(device) == arraytype){
        XPOST_LOG_INFO("running proc");
        xpost_stack_push(ctx->lo, ctx->es, xpost_operator_cons(ctx, "quit", NULL,0,0));
        xpost_stack_push(ctx->lo, ctx->es, device);

        ctx->quit = 0;
        mainloop(ctx);

        device = xpost_stack_pop(ctx->lo, ctx->os);
    }
    if (xpost_object_get_type(device) == dicttype)
    {
        Xpost_Object Destroy;
        XPOST_LOG_INFO("destroying device dict");
        Destroy = xpost_dict_get(ctx, device, xpost_name_cons(ctx, "Destroy"));
        if (xpost_object_get_type(Destroy) == operatortype)
        {
            int res;
            xpost_stack_push(ctx->lo, ctx->os, device);
            res = xpost_operator_exec(ctx, Destroy.mark_.padw);
            if (res)
                XPOST_LOG_ERR("%s error destroying device", errorname[res]);
            else
                XPOST_LOG_INFO("destroyed device");
        }
    }

    xpost_save_restore_snapshot(ctx->gl);
    xpost_memory_table_get_addr(ctx->lo,
                                XPOST_MEMORY_TABLE_SPECIAL_SAVE_STACK, &vs);
    if (xpost_object_get_type(lsav) == savetype)
    {
        for ( llev = xpost_stack_count(ctx->lo, vs);
                llev > lsav.save_.lev;
                llev-- )
        {
            xpost_save_restore_snapshot(ctx->lo);
        }
    }

    return noerror;
}
示例#9
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;
}