Esempio n. 1
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;
Esempio n. 2
0
/* load executable name */
static
int evalload(Xpost_Context *ctx)
{
    int ret;
    if (_xpost_interpreter_is_tracing)
    {
        Xpost_Object s = xpost_name_get_string(ctx, xpost_stack_topdown_fetch(ctx->lo, ctx->es, 0));
        XPOST_LOG_DUMP("evalload <name \"%*s\">", s.comp_.sz, xpost_string_get_pointer(ctx, s));
    }

    if (!xpost_stack_push(ctx->lo, ctx->os,
            xpost_stack_pop(ctx->lo, ctx->es)))
        return stackoverflow;
    assert(ctx->gl->base);
    /*xpost_operator_exec(ctx, xpost_operator_cons(ctx, "load", NULL,0,0).mark_.padw); */
    ret = xpost_operator_exec(ctx, ctx->opcode_shortcuts.load);
    if (ret)
        return ret;
    if (xpost_object_is_exe(xpost_stack_topdown_fetch(ctx->lo, ctx->os, 0)))
    {
        Xpost_Object q;
        q = xpost_stack_pop(ctx->lo, ctx->os);
        if (xpost_object_get_type(q) == invalidtype)
            return undefined;
        if (!xpost_stack_push(ctx->lo, ctx->es, q))
            return ret;
    }
    return 0;
}
Esempio n. 3
0
/* add the name to the name stack, return index */
static
unsigned int addname(Xpost_Context *ctx,
                     const char *s)
{
    Xpost_Memory_File *mem = ctx->vmmode==GLOBAL?ctx->gl:ctx->lo;
    unsigned int names;
    unsigned int u;
    Xpost_Object str;

    xpost_memory_table_get_addr(mem,
            XPOST_MEMORY_TABLE_SPECIAL_NAME_STACK, &names);
    u = xpost_stack_count(mem, names);

    //xpost_memory_file_dump(ctx->gl);
    //dumpmtab(ctx->gl, 0);
    //unsigned int vmmode = ctx->vmmode;
    //ctx->vmmode = GLOBAL;
    str = xpost_string_cons(ctx, strlen(s), s);
    if (xpost_object_get_type(str) == nulltype)
    {
        XPOST_LOG_ERR("cannot allocate name string");
        return 0;
    }
    xpost_stack_push(mem, names, str);
    //ctx->vmmode = vmmode;
    return u;
}
Esempio n. 4
0
/* pop the execution stack */
static
int evalpop(Xpost_Context *ctx)
{
    if (!xpost_object_get_type(xpost_stack_pop(ctx->lo, ctx->es)) == invalidtype)
        return stackunderflow;
    return 0;
}
Esempio n. 5
0
static
int _event_handler (Xpost_Context *ctx,
                    Xpost_Object devdic)
{
    Xpost_Object privatestr;
    PrivateData private;
    xcb_generic_event_t *event;


    /* load private data struct from string */
    privatestr = xpost_dict_get(ctx, devdic, namePrivate);
    if (xpost_object_get_type(privatestr) == invalidtype)
        return undefined;
    xpost_memory_get(xpost_context_select_memory(ctx, privatestr),
            xpost_object_get_ent(privatestr), 0, sizeof private, &private);

    event = xcb_poll_for_event(private.c);
    if (event)
    {
        switch(event->response_type & ~0x80)
        {
        case XCB_EXPOSE:
            _flush(ctx, devdic);
            break;
        default:
            break;
        }
        free(event);
    }
    else if (xcb_connection_has_error(private.c))
        return unregistered;

    return 0;
}
Esempio n. 6
0
/* 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;
}
Esempio n. 7
0
/* number  cvi  int
   convert number to integer */
static
int Ncvi(Xpost_Context *ctx,
          Xpost_Object n)
{
    if (xpost_object_get_type(n) == realtype)
        n = xpost_int_cons((integer)n.real_.val);
    xpost_stack_push(ctx->lo, ctx->os, n);
    return 0;
}
Esempio n. 8
0
/* number  cvr  real
   convert number to real */
static
int Ncvr(Xpost_Context *ctx,
         Xpost_Object n)
{
    if (xpost_object_get_type(n) == integertype)
        n = xpost_real_cons((real)n.int_.val);
    xpost_stack_push(ctx->lo, ctx->os, n);
    return 0;
}
Esempio n. 9
0
/*
   one iteration of the central loop
   called repeatedly by mainloop()
 */
int eval(Xpost_Context *ctx)
{
    int ret;
    Xpost_Object t = xpost_stack_topdown_fetch(ctx->lo, ctx->es, 0);

    ctx->currentobject = t; /* for _onerror to determine if hold stack contents are restoreable.
                               if opexec(opcode) discovers opcode != ctx->currentobject.mark_.padw
                               it sets a flag indicating the hold stack does not contain
                               ctx->currentobject's arguments.
                               if an error is encountered, currentobject is reported as the
                               errant object since it is the "entry point" to the interpreter.
                             */

    if (!validate_context(ctx))
        return unregistered;

    if (_xpost_interpreter_is_tracing)
    {
        XPOST_LOG_DUMP("eval(): Executing: ");
        xpost_object_dump(t);
        XPOST_LOG_DUMP("Stack: ");
        xpost_stack_dump(ctx->lo, ctx->os);
        XPOST_LOG_DUMP("Dict Stack: ");
        xpost_stack_dump(ctx->lo, ctx->ds);
        XPOST_LOG_DUMP("Exec Stack: ");
        xpost_stack_dump(ctx->lo, ctx->es);
    }

    ret = idleproc(ctx); /* periodically process asynchronous events */
    if (ret)
        return ret;

    { /* check object for sanity before using jump table */
        Xpost_Object_Type type = xpost_object_get_type(t);
        if (type == invalidtype || type >= XPOST_OBJECT_NTYPES)
            return unregistered;
    }
    if ( xpost_object_is_exe(t) ) /* if executable */
        ret = evaltype[xpost_object_get_type(t)](ctx);
    else
        ret = evalpush(ctx);

    return ret;
}
Esempio n. 10
0
/* mark obj1..objN  cleartomark  -
   discard elements down through mark */
int xpost_op_cleartomark (Xpost_Context *ctx)
{
    Xpost_Object o;
    do {
        o = xpost_stack_pop(ctx->lo, ctx->os);
        if (xpost_object_get_type(o) == invalidtype)
            return unmatchedmark;
    } while (o.tag != marktype);
    return 0;
}
Esempio n. 11
0
/* any  type  name
   return type of any as a nametype object */
static
int Atype(Xpost_Context *ctx,
           Xpost_Object o)
{
    if (xpost_object_get_type(o) >= XPOST_OBJECT_NTYPES)
        //return unregistered;
        o = invalid; /* normalize to the all-zero invalid object */
    xpost_stack_push(ctx->lo, ctx->os, xpost_object_cvx(xpost_name_cons(ctx, xpost_object_type_names[xpost_object_get_type(o)])));
    return 0;
}
Esempio n. 12
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;
}
Esempio n. 13
0
/* -  currentfile  file
   return topmost file from the exec stack */
static
int xpost_op_currentfile (Xpost_Context *ctx)
{
    int z = xpost_stack_count(ctx->lo, ctx->es);
    int i;
    Xpost_Object o;
    for (i = 0; i<z; i++)
    {
        o = xpost_stack_topdown_fetch(ctx->lo, ctx->es, i);
        if (xpost_object_get_type(o) == filetype)
        {
            xpost_stack_push(ctx->lo, ctx->os, o);
            return 0;
        }
    }
    o = xpost_file_cons(ctx->lo, NULL);
    if (xpost_object_get_type(o) == invalidtype)
        return VMerror;
    xpost_stack_push(ctx->lo, ctx->os, o);
    return 0;
}
Esempio n. 14
0
/* a(n-1)..a(0) n j  roll  a((j-1)mod n)..a(0) a(n-1)..a(j mod n)
   roll n elements j times */
static
int IIroll (Xpost_Context *ctx,
             Xpost_Object N,
             Xpost_Object J)
{
    Xpost_Object *t;
    Xpost_Object r;
    int i;
    int n = N.int_.val;
    int j = J.int_.val;
    if (n < 0)
        return rangecheck;
    if (n == 0) return 0;
    if (j < 0) j = n - ( (- j) % n);
    j %= n;
    if (j == 0) return 0;
    
    t = alloca((n-j) * sizeof(Xpost_Object));
    for (i = 0; i < n-j; i++)
    {
        r = xpost_stack_topdown_fetch(ctx->lo, ctx->os, n - 1 - i);
        if (xpost_object_get_type(r) == invalidtype)
            return stackunderflow;
        t[i] = r;
    }
    for (i = 0; i < j; i++)
    {
        r = xpost_stack_topdown_fetch(ctx->lo, ctx->os, j - 1 - i);
        if (xpost_object_get_type(r) == invalidtype)
            return stackunderflow;
        if (!xpost_stack_topdown_replace(ctx->lo, ctx->os, n - 1 - i, r))
            return stackunderflow;
    }
    for (i = 0; i < n-j; i++)
    {
        if (!xpost_stack_topdown_replace(ctx->lo, ctx->os, n - j - 1 - i, t[i]))
            return stackunderflow;
    }
    return 0;
}
Esempio n. 15
0
/* extract token from string */
static
int evalstring(Xpost_Context *ctx)
{
    Xpost_Object b,t,s;
    int ret;

    s = xpost_stack_pop(ctx->lo, ctx->es);
    if (!xpost_stack_push(ctx->lo, ctx->os, s))
        return stackoverflow;
    assert(ctx->gl->base);
    /*xpost_operator_exec(ctx, xpost_operator_cons(ctx, "token",NULL,0,0).mark_.padw); */
    ret = xpost_operator_exec(ctx, ctx->opcode_shortcuts.token);
    if (ret)
        return ret;
    b = xpost_stack_pop(ctx->lo, ctx->os);
    if (xpost_object_get_type(b) == invalidtype)
        return stackunderflow;
    if (b.int_.val)
    {
        t = xpost_stack_pop(ctx->lo, ctx->os);
        if (xpost_object_get_type(t) == invalidtype)
            return stackunderflow;
        s = xpost_stack_pop(ctx->lo, ctx->os);
        if (xpost_object_get_type(s) == invalidtype)
            return stackunderflow;
        if (!xpost_stack_push(ctx->lo, ctx->es, s))
            return execstackoverflow;
        if (xpost_object_get_type(t)==arraytype)
        {
            if (!xpost_stack_push(ctx->lo, ctx->os , t))
                return stackoverflow;
        }
        else
        {
            if (!xpost_stack_push(ctx->lo, ctx->es , t))
                return execstackoverflow;
        }
    }
    return 0;
}
Esempio n. 16
0
/*
   call window device's event_handler function
   which should check for Events or Messages from the
   underlying Window System, process one or more of them,
   and then return 0.
   it should leave all stacks undisturbed.
 */
int idleproc (Xpost_Context *ctx)
{
    int ret;

    if ((xpost_object_get_type(ctx->event_handler) == operatortype) &&
        (xpost_object_get_type(ctx->window_device) == dicttype))
    {
        if (!xpost_stack_push(ctx->lo, ctx->os, ctx->window_device))
        {
            return stackoverflow;
        }
        ret = xpost_operator_exec(ctx, ctx->event_handler.mark_.padw);
        if (ret)
        {
            XPOST_LOG_ERR("event_handler returned %d (%s)",
                    ret, errorname[ret]);
            XPOST_LOG_ERR("disabling event_handler");
            ctx->event_handler = null;
            return ret;
        }
    }
    return 0;
}
Esempio n. 17
0
/* extract head (&tail) of array */
static
int evalarray(Xpost_Context *ctx)
{
    Xpost_Object a = xpost_stack_pop(ctx->lo, ctx->es);
    Xpost_Object b;

    if (xpost_object_get_type(a) == invalidtype)
        return stackunderflow;

    switch (a.comp_.sz)
    {
        default /* > 1 */:
        {
            Xpost_Object interval;
            interval = xpost_object_get_interval(a, 1, a.comp_.sz - 1);
            if (xpost_object_get_type(interval) == invalidtype)
                return rangecheck;
            xpost_stack_push(ctx->lo, ctx->es, interval);
        }
        /*@fallthrough@*/
        case 1:
            b = xpost_array_get(ctx, a, 0);
            if (xpost_object_get_type(b) == arraytype)
            {
                if (!xpost_stack_push(ctx->lo, ctx->os, b))
                    return stackoverflow;
            }
            else
            {
                if (!xpost_stack_push(ctx->lo, ctx->es, b))
                    return execstackoverflow;
            }
            /*@fallthrough@*/
        case 0: /* drop */;
    }
    return 0;
}
Esempio n. 18
0
/* execute operator */
static
int evaloperator(Xpost_Context *ctx)
{
    int ret;
    Xpost_Object op = xpost_stack_pop(ctx->lo, ctx->es);
    if (xpost_object_get_type(op) == invalidtype)
        return stackunderflow;

    if (_xpost_interpreter_is_tracing)
        xpost_operator_dump(ctx, op.mark_.padw);
    ret = xpost_operator_exec(ctx, op.mark_.padw);
    if (ret)
        return ret;
    return 0;
}
Esempio n. 19
0
/* any  gcheck  bool
   check whether value is a legal element of a global compound object */
static
int Agcheck (Xpost_Context *ctx,
              Xpost_Object A)
{
    Xpost_Object r;
    switch(xpost_object_get_type(A)) {
    default:
            r = xpost_bool_cons(0); break;
    case stringtype:
    case nametype:
    case dicttype:
    case arraytype:
            r = xpost_bool_cons((A.tag&XPOST_OBJECT_TAG_DATA_FLAG_BANK)!=0);
    }
    xpost_stack_push(ctx->lo, ctx->os, r);
    return 0;
}
Esempio n. 20
0
/* number radix string  cvrs  string
   convert number to a radix representation in string */
static
int NRScvrs (Xpost_Context *ctx,
              Xpost_Object num,
              Xpost_Object rad,
              Xpost_Object str)
{
    int r, n;
    if (xpost_object_get_type(num) == realtype) num = xpost_int_cons((integer)num.real_.val);
    r = rad.int_.val;
    if (r < 2 || r > 36)
        return rangecheck;
    n = conv_rad(num.int_.val, r, xpost_string_get_pointer(ctx, str), str.comp_.sz);
    if (n == -1)
        return rangecheck;
    if (n < str.comp_.sz) str.comp_.sz = n;
    xpost_stack_push(ctx->lo, ctx->os, str);
    return 0;
}
Esempio n. 21
0
/* internal continuation operator for filenameforall */
static
int xpost_op_contfilenameforall (Xpost_Context *ctx,
                                 Xpost_Object oglob,
                                 Xpost_Object Proc,
                                 Xpost_Object Scr)
{
    glob_t *globbuf;
    char *str;
    char *src;
    int len;
    Xpost_Object interval;

    globbuf = oglob.glob_.ptr;
    if (oglob.glob_.off < globbuf->gl_pathc)
    {
        /* xpost_stack_push(ctx->lo, ctx->es, xpost_operator_cons(ctx, "contfilenameforall", NULL,0,0)); */
        xpost_stack_push(ctx->lo, ctx->es, xpost_operator_cons_opcode(ctx->opcode_shortcuts.contfilenameforall));
        xpost_stack_push(ctx->lo, ctx->es, Scr);
        /* xpost_stack_push(ctx->lo, ctx->es, xpost_operator_cons(ctx, "cvx", NULL,0,0)); */
        xpost_stack_push(ctx->lo, ctx->es, xpost_operator_cons_opcode(ctx->opcode_shortcuts.cvx));
        xpost_stack_push(ctx->lo, ctx->es, xpost_object_cvlit(Proc));
        ++oglob.glob_.off;
        xpost_stack_push(ctx->lo, ctx->es, oglob);

        str = xpost_string_get_pointer(ctx, Scr);
        src = globbuf->gl_pathv[ oglob.glob_.off-1 ];
        len = strlen(src);
        if (len > Scr.comp_.sz)
            return rangecheck;
        memcpy(str, src, len);
        interval = xpost_object_get_interval(Scr, 0, len);
        if (xpost_object_get_type(interval) == invalidtype)
            return rangecheck;
        xpost_stack_push(ctx->lo, ctx->os, interval);
        xpost_stack_push(ctx->lo, ctx->es, Proc);

    }
    else
    {
        xpost_glob_free(globbuf); /* reference has already been popped */
    }
    return 0;
}
Esempio n. 22
0
/* string  cvn  name
   convert string to name */
static
int Scvn(Xpost_Context *ctx,
         Xpost_Object s)
{
    char *t;
    Xpost_Object name;

    t = alloca(s.comp_.sz+1);
    memcpy(t, xpost_string_get_pointer(ctx, s), s.comp_.sz);
    t[s.comp_.sz] = '\0';
    name = xpost_name_cons(ctx, t);
    if (xpost_object_get_type(name) == invalidtype)
        return VMerror;
    if (xpost_object_is_exe(s))
        name = xpost_object_cvx(name);
    else
        name = xpost_object_cvlit(name);
    xpost_stack_push(ctx->lo, ctx->os, name);
    return 0;
}
Esempio n. 23
0
/* file  read  int true
               false
   read a byte from file */
static
int xpost_op_file_read(Xpost_Context *ctx,
                       Xpost_Object f)
{
    Xpost_Object b;
    if (!xpost_object_is_readable(ctx,f))
        return invalidaccess;
    b = xpost_file_read_byte(ctx->lo, f);
    if (xpost_object_get_type(b) == invalidtype)
        return ioerror;
    if (b.int_.val != EOF)
    {
        xpost_stack_push(ctx->lo, ctx->os, b);
        xpost_stack_push(ctx->lo, ctx->os, xpost_bool_cons(1));
    }
    else
    {
        xpost_stack_push(ctx->lo, ctx->os, xpost_bool_cons(0));
    }
    return 0;
}
Esempio n. 24
0
/* extract token from file */
static
int evalfile(Xpost_Context *ctx)
{
    Xpost_Object b,f,t;
    int ret;

    f = xpost_stack_pop(ctx->lo, ctx->es);
    if (!xpost_stack_push(ctx->lo, ctx->os, f))
        return stackoverflow;
    assert(ctx->gl->base);
    /*xpost_operator_exec(ctx, xpost_operator_cons(ctx, "token",NULL,0,0).mark_.padw); */
    ret = xpost_operator_exec(ctx, ctx->opcode_shortcuts.token);
    if (ret)
        return ret;
    b = xpost_stack_pop(ctx->lo, ctx->os);
    if (b.int_.val)
    {
        t = xpost_stack_pop(ctx->lo, ctx->os);
        if (!xpost_stack_push(ctx->lo, ctx->es, f))
            return execstackoverflow;
        if (xpost_object_get_type(t)==arraytype)
        {
            if (!xpost_stack_push(ctx->lo, ctx->os, t))
                return stackoverflow;
        }
        else
        {
            if (!xpost_stack_push(ctx->lo, ctx->es, t))
                return execstackoverflow;
        }
    }
    else
    {
        ret = xpost_file_object_close(ctx->lo, f);
        if (ret)
            XPOST_LOG_ERR("%s error closing file", errorname[ret]);
    }
    return 0;
}
Esempio n. 25
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;
}
Esempio n. 26
0
/* any string  cvs  string
   convert any object to string representation */
static
int AScvs (Xpost_Context *ctx,
            Xpost_Object any,
            Xpost_Object str)
{
    char nostringval[] = "-nostringval-";
    char strue[] = "true";
    char sfalse[] = "false";
    char smark[] = "-mark-";
    char ssave[] = "-save-";
    int n;
    int ret;

    switch(xpost_object_get_type(any)) {
    default:
        if (str.comp_.sz < sizeof(nostringval)-1)
            return rangecheck;
        memcpy(xpost_string_get_pointer(ctx, str), nostringval, sizeof(nostringval)-1);
        str.comp_.sz = sizeof(nostringval)-1;
        break;

    case savetype:
        if (str.comp_.sz < sizeof(ssave)-1)
            return rangecheck;
        memcpy(xpost_string_get_pointer(ctx, str), ssave, sizeof(ssave)-1);
        str.comp_.sz = sizeof(ssave)-1;
        break;

    case marktype:
        if (str.comp_.sz < sizeof(smark)-1)
            return rangecheck;
        memcpy(xpost_string_get_pointer(ctx, str), smark, sizeof(smark)-1);
        str.comp_.sz = sizeof(smark)-1;
        break;

    case booleantype:
        {
            if (any.int_.val) {
                if (str.comp_.sz < sizeof(strue)-1)
                    return rangecheck;
                memcpy(xpost_string_get_pointer(ctx, str), strue, sizeof(strue)-1);
                str.comp_.sz = sizeof(strue)-1;
            } else {
                if (str.comp_.sz < sizeof(sfalse)-1)
                    return rangecheck;
                memcpy(xpost_string_get_pointer(ctx, str), sfalse, sizeof(sfalse)-1);
                str.comp_.sz = sizeof(sfalse)-1;
            }
        }
        break;
    case integertype:
        {
            //n = conv_rad(any.int_.val, 10, xpost_string_get_pointer(ctx, str), str.comp_.sz);
            char *s = xpost_string_get_pointer(ctx, str);
            int sz = str.comp_.sz;
            n = 0;
            if (any.int_.val < 0) {
                s[n++] = '-';
                any.int_.val = abs(any.int_.val);
                --sz;
            }
            n += conv_integ((real)any.int_.val, s + n, sz);
            if (n == -1)
                return rangecheck;
            if (n < str.comp_.sz) str.comp_.sz = n;
            break;
        }
    case realtype:
        n = conv_real(any.real_.val, xpost_string_get_pointer(ctx, str), str.comp_.sz);
        if (n == -1)
            return rangecheck;
        if (n < str.comp_.sz) str.comp_.sz = n;
        break;

    case operatortype:
        {
            unsigned int optadr;
            Xpost_Operator *optab;
            Xpost_Operator op;
            Xpost_Object_Mark nm;
            ret = xpost_memory_table_get_addr(ctx->gl,
                    XPOST_MEMORY_TABLE_SPECIAL_OPERATOR_TABLE, &optadr);
            if (!ret)
            {
                XPOST_LOG_ERR("cannot load optab!");
                return VMerror;
            }
            optab = (void *)(ctx->gl->base + optadr);
            op = optab[any.mark_.padw];
            nm.tag = nametype | XPOST_OBJECT_TAG_DATA_FLAG_BANK;
            nm.pad0 = 0;
            nm.padw = op.name;
            any.mark_ = nm;
        }
        /*@fallthrough@*/
    case nametype:
        any = xpost_name_get_string(ctx, any);
        /*@fallthrough@*/
    case stringtype:
        if (any.comp_.sz > str.comp_.sz)
            return rangecheck;
        if (any.comp_.sz < str.comp_.sz) str.comp_.sz = any.comp_.sz;
        memcpy(xpost_string_get_pointer(ctx, str), xpost_string_get_pointer(ctx, any), any.comp_.sz);
        break;
    }

    xpost_stack_push(ctx->lo, ctx->os, str);
    return 0;
}
Esempio n. 27
0
/* traverse the contents of composite objects
   if markall is true, this is a collection of global vm,
   so we must mark objects and recurse
   even if it means switching memory files
 */
static
int _xpost_garbage_mark_object(Xpost_Context *ctx,
        Xpost_Memory_File *mem,
        Xpost_Object o,
        int markall)
{
    unsigned int ad;
    int ret;

    if (!mem) return 0;

    switch(xpost_object_get_type(o)) {
    default: break;

    case arraytype:
#ifdef DEBUG_GC
    printf("markobject: %d, %s (size %d)\n",
            xpost_object_get_ent(o),
            xpost_object_type_names[xpost_object_get_type(o)],
            o.comp_.sz);
#endif
        if (xpost_context_select_memory(ctx, o) != mem) {
            if (markall)
                mem = xpost_context_select_memory(ctx, o);
            else
                break;
        }
        if (!mem) return 0;
        if (!_xpost_garbage_ent_is_marked(mem, xpost_object_get_ent(o), &ret))
            return 0;
        if (!ret) {
            ret = _xpost_garbage_mark_ent(mem, xpost_object_get_ent(o));
            if (!ret)
            {
                XPOST_LOG_ERR("cannot mark array");
                return 0;
            }
            ret = xpost_memory_table_get_addr(mem, xpost_object_get_ent(o), &ad);
            if (!ret)
            {
                XPOST_LOG_ERR("cannot retrieve address for array ent %u", xpost_object_get_ent(o));
                return 0;
            }
            if (!_xpost_garbage_mark_array(ctx, mem, ad, o.comp_.sz, markall))
                return 0;
        }
        break;

    case dicttype:
#ifdef DEBUG_GC
    printf("markobject: %d, %s (size %d)\n",
            xpost_object_get_ent(o),
            xpost_object_type_names[xpost_object_get_type(o)],
            o.comp_.sz);
#endif
        if (xpost_context_select_memory(ctx, o) != mem) {
            if (markall)
                mem = xpost_context_select_memory(ctx, o);
            else
                break;
        }
        if (!_xpost_garbage_ent_is_marked(mem, xpost_object_get_ent(o), &ret))
            return 0;
        if (!ret) {
            ret = _xpost_garbage_mark_ent(mem, xpost_object_get_ent(o));
            if (!ret)
            {
                XPOST_LOG_ERR("cannot mark dict");
                return 0;
            }
            ret = xpost_memory_table_get_addr(mem, xpost_object_get_ent(o), &ad);
            if (!ret)
            {
                XPOST_LOG_ERR("cannot retrieve address for dict ent %u", xpost_object_get_ent(o));
                return 0;
            }
            if (!_xpost_garbage_mark_dict(ctx, mem, ad, markall))
                return 0;
        }
        break;

    case stringtype:
#ifdef DEBUG_GC
    printf("markobject: %d, %s (size %d)\n",
            xpost_object_get_ent(o),
            xpost_object_type_names[xpost_object_get_type(o)],
            o.comp_.sz);
#endif
        if (xpost_context_select_memory(ctx, o) != mem) {
            if (markall)
                mem = xpost_context_select_memory(ctx, o);
            else
                break;
        }
        ret = _xpost_garbage_mark_ent(mem, xpost_object_get_ent(o));
        if (!ret)
        {
            XPOST_LOG_ERR("cannot mark string");
            return 0;
        }
        break;

    case filetype:
        if (mem == ctx->gl) {
            printf("file found in global vm\n");
        } else {
            ret = _xpost_garbage_mark_ent(mem, o.mark_.padw);
            if (!ret)
            {
                XPOST_LOG_ERR("cannot mark file");
                return 0;
            }
        }
        break;
    }
    return 1;
}
Esempio n. 28
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;
}
Esempio n. 29
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;
}