Пример #1
0
/* template proc scratch  filenameforall  -
   execute proc for all filenames matching template using scratch string */
static
int xpost_op_filenameforall (Xpost_Context *ctx,
                             Xpost_Object Tmp,
                             Xpost_Object Proc,
                             Xpost_Object Scr)
{
    char *tmpbuf;
    glob_t *globbuf;
    Xpost_Object oglob;
    int ret;

    tmpbuf = alloca(Tmp.comp_.sz + 1);
    memcpy(tmpbuf, xpost_string_get_pointer(ctx, Tmp), Tmp.comp_.sz);
    tmpbuf[Tmp.comp_.sz] = '\0';
    globbuf = malloc(sizeof *globbuf);
    if (!globbuf)
        return unregistered;
    ret = xpost_glob(tmpbuf, globbuf);
    if (ret != 0)
    {
        free(globbuf);
        return ioerror;
    }

    oglob.glob_.tag = globtype;
    oglob.glob_.off = 0;
    oglob.glob_.ptr = globbuf;

    xpost_op_contfilenameforall(ctx, oglob, Proc, xpost_object_cvlit(Scr));
    return 0;
}
Пример #2
0
/* obj   cvlit  obj
   set executable attribute in obj to literal (quoted) */
static
int Acvlit(Xpost_Context *ctx,
            Xpost_Object o)
{
    xpost_stack_push(ctx->lo, ctx->os, xpost_object_cvlit(o));
    return 0;
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
0
/* filename mode  file  file
   create file object for filename with access mode */
static
int xpost_op_string_mode_file (Xpost_Context *ctx,
                               Xpost_Object fn,
                               Xpost_Object mode)
{
    Xpost_Object f;
    char *cfn, *cmode;
    int ret;

    cfn = alloca(fn.comp_.sz + 1);
    memcpy(cfn, xpost_string_get_pointer(ctx, fn), fn.comp_.sz);
    cfn[fn.comp_.sz] = '\0';
    cmode = alloca(mode.comp_.sz + 1);
    memcpy(cmode, xpost_string_get_pointer(ctx, mode), mode.comp_.sz);
    cmode[mode.comp_.sz] = '\0';

    ret = xpost_file_open(ctx->lo, cfn, cmode, &f);
    if (ret)
        return ret;
    xpost_stack_push(ctx->lo, ctx->os, xpost_object_cvlit(f));
    return 0;
}
Пример #7
0
/*
   set global pagesize,
   initialize eval's jump-tabl
   allocate global itpdata interpreter instance
   call xpost_interpreter_init
        which initializes the first context
 */
static
int initalldata(const char *device)
{
    int ret;

    initevaltype();
    xpost_object_install_dict_get_access(xpost_dict_get_access);
    xpost_object_install_dict_set_access(xpost_dict_set_access);

    /* allocate the top-level itpdata data structure. */
    null = xpost_object_cvlit(null);
    itpdata = malloc(sizeof*itpdata);
    if (!itpdata)
    {
        XPOST_LOG_ERR("itpdata=malloc failed");
        return 0;
    }
    memset(itpdata, 0, sizeof*itpdata);

    /* allocate and initialize the first context structure
       and associated memory structures.
       populate OPTAB and systemdict with operators.
       push systemdict, globaldict, and userdict on dict stack
     */
    ret = xpost_interpreter_init(itpdata, device);
    if (!ret)
    {
        return 0;
    }

    /* set global shortcut to context_0
       (the only context in a single-threaded interpreter)
       TODO remove this variable
     */
    xpost_ctx = &itpdata->ctab[0];

    return 1;
}
Пример #8
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);
}
Пример #9
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;
}
Пример #10
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;
}