/*
 * File:    parser/dpuser.pgplot.c
 * Purpose: dpuser bindings for the pgplot plotting library
 * Author:  Thomas Ott
 *
 * History: 06.01.2000: File created
 */

#ifdef DPQT
#include <QMutex>
#include <QWriteLocker>
#include "QFitsMainWindow.h"
#include "QFitsMainView.h"
#include "QFitsSingleBuffer.h"
#include "QFitsGlobal.h"
#include "qtdpuser.h"
#include "imred.h"
#include "events.h"
#include "dialogs.h"

extern QMutex *dpusermutex;

#endif /* DPQT */

#ifndef WIN
#include <unistd.h>
#include <dlfcn.h>
#endif /* !WIN */

#include <memory>

#ifdef HAS_PGPLOT
#include "cpgplot.h"
#ifdef HAS_DPPGPLOT
#include "cpg3d.h"
#endif /* HAS_DPPGPLOT */
#endif /* HAS_PGPLOT */

#ifdef HAS_PLPLOT
#include <plplot/plplot.h>
#endif /* HAS_PLPLOT */

#include "dpuser.h"
#include "procedures.h"
#include "dpuser.procs.h"
#include "dpuser_utils.h"
#include "dpuser.yacchelper.h"
#include "functions.h"
#include "platform.h"
#include "astrolib.h"

extern bool idlmode;
extern int variableErrors[10];
int imexasize = 25;

#ifdef HAS_GDL
int GDLEventHandler();
#endif /* HAS_GDL */

#include <stdlib.h>

void re_fail(char *msg, unsigned char op);

/* The declarations of the various pgplot subroutines */
//#define SETINTVARIABLE(NUM,VALUE) variables[la[(NUM)]].type=typeCon;variables[la[(NUM)]].lvalue=(long)(VALUE);
//#define SETDBLVARIABLE(NUM,VALUE) variables[la[(NUM)]].type=typeDbl;variables[la[(NUM)]].dvalue=(double)(VALUE);
#define SETINTVARIABLE(NUM,VALUE) pgVariables[(NUM)].type=typeCon;pgVariables[(NUM)].lvalue=(long)(VALUE);
#define SETDBLVARIABLE(NUM,VALUE) pgVariables[(NUM)].type=typeDbl;pgVariables[(NUM)].dvalue=(double)(VALUE);

#define REALNUM typeCon|typeDbl
#define ANYTHING REALNUM|typeStr|typeCom|typeFits|typeFitsFile|typeStrarr|typeDpArr

pgplot_declarations pgss[] = {
    { "pgarro", 4, 4, { REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgask", 1, 1, { typeCon }, 0 },
    { "pgaxis", 14, 14, { typeStr, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM, typeCon, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgband", 7, 7, { typeCon, typeCon, REALNUM, REALNUM, typeId|REALNUM, typeId|REALNUM, typeId|ANYTHING }, 0 },
    { "pgbbuf", 0, 0, { typeCon }, 0 },
    { "pgbeg", 4, 4, { typeCon, typeStr, typeCon, typeCon }, 0 },
    { "pgbegin", 4, 4, { typeCon, typeStr, typeCon, typeCon }, 0 },
    { "pgbin", 4, 4, { typeCon, typeFits, typeFits, typeCon }, 0 },
    { "pgbox", 6, 6, { typeStr, REALNUM, typeCon, typeStr, REALNUM, typeCon }, 0 },
    { "pgcirc", 3, 3, { REALNUM, REALNUM, REALNUM }, 0 },
    { "pgclos", 0, 0, { typeCon }, 0 },
    { "pgconb", 11, 11, { typeFits, typeCon, typeCon, typeCon, typeCon, typeCon, typeCon, typeFits, typeCon, typeFits, REALNUM }, 0 },
    { "pgconf", 10, 10, { typeFits, typeCon, typeCon, typeCon, typeCon, typeCon, typeCon, REALNUM, REALNUM, typeFits }, 0 },
    { "pgconl", 12, 12, { typeFits, typeCon, typeCon, typeCon, typeCon, typeCon, typeCon, REALNUM, typeFits, typeStr, typeCon, typeCon} },
    { "pgcons", 10, 10, { typeFits, typeCon, typeCon, typeCon, typeCon, typeCon, typeCon, typeFits, typeCon, typeFits }, 0 },
    { "pgcont", 10, 10, { typeFits, typeCon, typeCon, typeCon, typeCon, typeCon, typeCon, typeFits, typeCon, typeFits }, 0 },
    { "pgconx", 0, 0, { typeCon }, 0 },
    { "pgctab", 7, 7, { typeFits, typeFits, typeFits, typeFits, typeCon, REALNUM, REALNUM }, 0 },
    { "pgcurse", 3, 3, { typeId|REALNUM, typeId|REALNUM, typeId|ANYTHING }, 0 },
    { "pgcurs", 3, 3, { typeId|REALNUM, typeId|REALNUM, typeId|ANYTHING }, 0 },
    { "pgdraw", 2, 2, { REALNUM, REALNUM }, 0 },
    { "pgebuf", 0, 0, { typeCon }, 0 },
    { "pgend", 0, 0, { typeCon }, 0 },
    { "pgenv", 6, 6, { REALNUM, REALNUM, REALNUM, REALNUM, typeCon, typeCon }, 0 },
    { "pgeras", 0, 0, { typeCon }, 0 },
    { "pgerr1", 5, 5, { typeCon, REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgerrb", 6, 6, { typeCon, typeCon, typeFits, typeFits, typeFits, REALNUM }, 0 },
    { "pgerrx", 5, 5, { typeCon, typeFits, typeFits, typeFits, REALNUM }, 0 },
    { "pgerry", 5, 5, { typeCon, typeFits, typeFits, typeFits, REALNUM }, 0 },
    { "pgetxt", 0, 0, { typeCon }, 0 },
    { "pgfunt", 0, 0, { typeCon }, 0 },
    { "pgfunx", 0, 0, { typeCon }, 0 },
    { "pgfuny", 0, 0, { typeCon }, 0 },
    { "pggray", 10, 10, { typeFits, typeCon, typeCon, typeCon, typeCon, typeCon, typeCon, REALNUM, REALNUM, typeFits }, 0 },
    { "pghi2d", 12, 12, { typeFits, typeCon, typeCon, typeCon, typeCon, typeCon, typeCon, typeFits, typeCon, REALNUM, typeCon, typeFits }, 0 },
    { "pghist", 6, 6, { typeCon, typeFits, REALNUM, REALNUM, typeCon, typeCon }, 0 },
    { "pgiden", 0, 0, { typeCon }, 0 },
    { "pgimag", 10, 10, { typeFits, typeCon, typeCon, typeCon, typeCon, typeCon, typeCon, REALNUM, REALNUM, typeFits }, 0 },
    { "pglabel", 3, 3, { typeStr, typeStr, typeStr }, 0 },
    { "pglab", 3, 3, { typeStr, typeStr, typeStr }, 0 },
    { "pglcur", 4, 4, { typeCon, typeId|typeCon, typeId|typeFits, typeId|typeFits }, 0 },
    { "pgldev", 0, 0, { typeCon }, 0 },
    { "pglen", 4, 4, { typeCon, typeStr, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgline", 3, 3, { typeCon, typeFits, typeFits }, 0 },
    { "pgmove", 2, 2, { REALNUM, REALNUM }, 0 },
    { "pgmtext", 5, 5, { typeStr, REALNUM, REALNUM, REALNUM, typeStr }, 0 },
    { "pgmtxt", 5, 5, { typeStr, REALNUM, REALNUM, REALNUM, typeStr }, 0 },
    { "pgncur", 5, 5, { typeCon, typeId|typeCon, typeId|typeFits, typeId|typeFits, typeCon }, 0 },
    { "pgncurse", 5, 5, { typeCon, typeId|typeCon, typeId|typeFits, typeId|typeFits, typeCon }, 0 },
    { "pgnumb", 5, 5, { typeCon, typeCon, typeCon, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgolin", 5, 5, { typeCon, typeId|typeCon, typeId|typeFits, typeId|typeFits, typeCon }, 0 },
    { "pgopen", 1, 1, { typeStr }, 0 },
    { "pgpage", 0, 0, { typeCon }, 0 },
    { "pgpanl", 2, 2, { typeCon, typeCon }, 0 },
    { "pgpaper", 2, 2, { REALNUM, REALNUM }, 0 },
    { "pgpap", 2, 2, { REALNUM, REALNUM }, 0 },
    { "pgpixl", 11, 11, { typeFits, typeCon, typeCon, typeCon, typeCon, typeCon, typeCon, REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgpnts", 5, 5, { typeCon, typeFits, typeFits, typeFits, typeCon }, 0 },
    { "pgpoint", 4, 4, { typeCon, typeFits, typeFits, typeCon }, 0 },
    { "pgpoly", 3, 3, { typeCon, typeFits, typeFits }, 0 },
    { "pgpt1", 3, 3, { REALNUM, REALNUM, typeCon }, 0 },
    { "pgptext", 5, 5, { REALNUM, REALNUM, REALNUM, REALNUM, typeStr }, 0 },
    { "pgpt", 4, 4, { typeCon, typeFits, typeFits, typeCon }, 0 },
    { "pgptxt", 5, 5, { REALNUM, REALNUM, REALNUM, REALNUM, typeStr }, 0 },
    { "pgqah", 3, 3, { typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgqcf", 1, 1, { typeId|ANYTHING }, 0 },
    { "pgqch", 1, 1, { typeId|ANYTHING }, 0 },
    { "pgqci", 1, 1, { typeId|ANYTHING }, 0 },
    { "pgqcir", 2, 2, { typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgqclp", 1, 1, { typeId|ANYTHING }, 0 },
    { "pgqcol", 2, 2, { typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgqcr", 4, 4, { typeCon, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgqcs", 3, 3, { typeCon, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgqdt", 6, 6, { typeCon, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgqfs", 1, 1, { typeId|ANYTHING }, 0 },
    { "pgqhs", 3, 3, { typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgqid", 1, 1, { typeId|ANYTHING }, 0 },
    { "pgqinf", 3, 3, { typeStr, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgqitf", 1, 1, { typeId|ANYTHING }, 0 },
    { "pgqls", 1, 1, { typeId|ANYTHING }, 0 },
    { "pgqlw", 1, 1, { typeId|ANYTHING }, 0 },
    { "pgqndt", 1, 1, { typeId|ANYTHING }, 0 },
    { "pgqpos", 2, 2, { typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgqtbg", 1, 1, { typeId|ANYTHING }, 0 },
    { "pgqtxt", 7, 7, { REALNUM, REALNUM, REALNUM, REALNUM, typeStr, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgqvp", 5, 5, { typeCon, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgqvsz", 5, 5, { typeCon, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgqwin", 4, 4, { typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgrect", 4, 4, { REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgrnd", 0, 0, { typeCon }, 0 },
    { "pgrnge", 4, 4, { REALNUM, REALNUM, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "pgsah", 3, 3, { typeCon, REALNUM, REALNUM }, 0 },
    { "pgsave", 0, 0, { typeCon }, 0 },
    { "pgunsa", 0, 0, { typeCon }, 0 },
    { "pgscf", 1, 1, { typeCon }, 0 },
    { "pgsch", 1, 1, { REALNUM }, 0 },
    { "pgsci", 1, 1, { typeCon }, 0 },
    { "pgscir", 2, 2, { typeCon, typeCon }, 0 },
    { "pgsclp", 1, 1, { typeCon }, 0 },
    { "pgscr", 4, 4, { typeCon, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgscrl", 2, 2, { REALNUM, REALNUM }, 0 },
    { "pgscrn", 2, 2, { typeCon, typeStr }, 0 },
    { "pgsfs", 1, 1, { typeCon }, 0 },
    { "pgshls", 4, 4, { typeCon, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgshs", 3, 3, { REALNUM, REALNUM, REALNUM }, 0 },
    { "pgsitf", 1, 1, { typeCon }, 0 },
    { "pgslct", 1, 1, { typeCon }, 0 },
    { "pgsls", 1, 1, { typeCon }, 0 },
    { "pgslw", 1, 1, { typeCon }, 0 },
    { "pgstbg", 1, 1, { typeCon }, 0 },
    { "pgsubp", 2, 2, { typeCon, typeCon }, 0 },
    { "pgsvp", 4, 4, { REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgswin", 4, 4, { REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgtbox", 6, 6, { typeStr, REALNUM, typeCon, typeStr, REALNUM, typeCon }, 0 },
    { "pgtext", 3, 3, { REALNUM, REALNUM, typeStr }, 0 },
    { "pgtick", 10, 10, { REALNUM, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM, typeStr }, 0 },
    { "pgupdt", 0, 0, { typeCon }, 0 },
    { "pgvect", 12, 12, { typeFits, typeFits, typeCon, typeCon, typeCon, typeCon, typeCon, typeCon, REALNUM, typeCon, typeFits, REALNUM }, 0 },
    { "pgvport", 4, 4, { REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgvsize", 4, 4, { REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgvsiz", 4, 4, { REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgvstand", 0, 0, { typeCon }, 0 },
    { "pgvstd", 0, 0, { typeCon }, 0 },
    { "pgwedg", 6, 6, { typeStr, REALNUM, REALNUM, REALNUM, REALNUM, typeStr }, 0 },
    { "pgwindow", 4, 4, { REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "pgwnad", 4, 4, { REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "writefits", 2, 2, { typeStr, typeFits|typeDpArr }, 1, { "ext" } },
    { "contour", 2, 2, { typeFits, typeFits }, 0 },
    { "display", 1, 3, { typeFits, REALNUM, REALNUM }, 0 },
    { "exec", 1, 1, { typeStr }, 0 },
    { "sleep", 1, 1, { typeCon }, 0 },
    { "spec3d", 2, 2, { typeFits, typeFits }, 0 },
    { "print", 1, 20, { typeCon }, 1, { "values" } },
    { "mem", 0, 0, { typeCon }, 0 },
    { "plot", 1, 4, { typeFits, typeFits|REALNUM, REALNUM, REALNUM }, 3, { "xlog", "ylog", "noclose" } },
    { "free", 0, 1, { typeId|ANYTHING }, 0 },
    { "sao", 1, 3, { typeFits, REALNUM, REALNUM }, 2, { "log", "zscale" } },
    { "shift", 3, 4, { typeId | typeFits, REALNUM, REALNUM, typeCon }, 4, { "wrap", "linear", "fft", "poly3" } },
    { "center", 1, 1, { typeId | typeFits }, 0 },
    { "centroid", 2, 4, { typeFits, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "upper", 1, 1, { typeId | typeStr }, 0 },
    { "lower", 1, 1, { typeId | typeStr }, 0 },
    { "rotate", 2, 4, { typeId | typeFits, REALNUM, REALNUM, REALNUM }, 0 },
    { "fft", 1, 1, { typeId | typeFits }, 0 },
    { "reass", 1, 1, { typeId | typeFits }, 0 },
    { "norm", 1, 1, { typeId | typeFits }, 3, { "unity", "total", "average" } },
    { "clip", 3, 4, { typeId | typeFits, REALNUM, REALNUM, REALNUM }, 0 },
    { "smooth", 2, 2, { typeId | typeFits, REALNUM }, 4, { "xy", "z", "x", "y" } },
    { "boxcar", 2, 2, { typeId | typeFits, typeCon }, 8, { "average", "minimum", "maximum", "median", "xy", "x", "y", "z" } },
    { "3dmerge", 2, 3, { typeId | typeFits, typeFits, typeCon }, 0 },
    { "3dmegacal", 3, 3, { typeId | typeFits, typeStr, typeStr }, 0 },
    { "3dcal", 2, 2, { typeId | typeFits, typeFits }, 0 },
    { "3dcubin", 4, 4, { typeId | typeFits, typeCon, typeStr, REALNUM }, 0 },
    { "3dexpand", 1, 1, { typeId | typeFits }, 0 },
    { "flip", 2, 2, { typeId | typeFits, typeCon }, 0 },
    { "enlarge", 2, 3, { typeId | typeFits, typeCon, typeCon }, 0 },
    { "resize", 3, 4, { typeId | typeFits, typeCon, typeCon, typeCon }, 0 },
    { "wien", 2, 3, { typeId | typeFits, typeFits, REALNUM }, 0 },
    { "lucy", 3, 4, { typeId | typeFits, typeFits, typeCon, REALNUM }, 0 },
    { "3dnorm", 2, 2, { typeId | typeFits, typeStr }, 0 },
    { "correl", 2, 2, { typeId | typeFits, typeFits }, 0 },
    { "rebin", 3, 4, { typeId | typeFits, typeCon, typeCon, typeCon }, 0 },
    { "ssaplot", 1, 2, { typeFits, typeStr }, 0 },
    { "freddy", 5, 5, { typeFits, typeCon, typeCon, REALNUM, REALNUM }, 0 },
    { "surface", 2, 3, { typeFits, REALNUM, typeCon }, 0 },
    { "imexa", 1, 1, { typeFits }, 0 },
    { "sbfint", 5, 5, { typeFits, typeCon, typeCon, typeCon, typeId|ANYTHING }, 0 },
    { "sbfbkg", 3, 3, { typeCon, typeCon, typeCon }, 0 },
    { "sbfsav", 1, 1, { typeCon }, 0 },
    { "sbfcls", 1, 1, { typeCon }, 0 },
    { "colint", 6, 6, { typeFits, typeCon, typeCon, REALNUM, REALNUM, REALNUM }, 0 },
    { "coltab", 5, 5, { typeFits, typeCon, REALNUM, typeCon, typeCon }, 0 },
    { "colsrf", 9, 9, { typeFits, typeCon, REALNUM, typeCon, typeCon, typeCon, REALNUM, REALNUM, REALNUM }, 0 },
    { "sbball", 10, 10, { typeFits, typeFits, REALNUM, typeCon, typeCon, typeFits, typeCon, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "sbtbal", 11, 11, { typeFits, typeFits, REALNUM, typeCon, typeCon, typeFits, typeCon, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING, typeCon }, 0 },
    { "sbplan", 6, 6, { typeFits, REALNUM, typeFits, typeCon, typeCon, typeFits }, 0 },
    { "sbplnt", 7, 7, { typeFits, REALNUM, typeFits, typeCon, typeCon, typeFits, typeCon }, 0 },
    { "sbrod", 9, 9, { typeFits, typeFits, typeFits, REALNUM, typeCon, typeCon, typeFits, typeCon, typeCon }, 0 },
    { "sbcone", 8, 8, { typeFits, typeFits, typeFits, REALNUM, typeCon, typeCon, typeFits, typeCon }, 0 },
    { "sbelip", 12, 12, { typeFits, typeFits, typeFits, typeCon, typeCon, typeFits, typeCon, typeCon, REALNUM, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "sbline", 5, 5, { typeFits, typeFits, typeFits, typeCon, typeCon }, 0 },
    { "sbtext", 7, 7, { typeFits, typeStr, typeCon, typeFits, REALNUM, typeFits, REALNUM }, 0 },
    { "sbsurf", 11, 11, { typeFits, typeFits, typeFits, typeCon, typeCon, typeCon, REALNUM, typeCon, typeCon, typeFits, typeCon }, 0 },
    { "sbtsur", 12, 12, { typeFits, typeFits, typeFits, typeCon, typeCon, typeCon, REALNUM, typeCon, typeCon, typeFits, typeCon, typeCon }, 0 },
    { "sbslic", 13, 13, { typeFits, typeFits, typeFits, typeCon, typeCon, typeCon, REALNUM, REALNUM, typeCon, typeCon, typeFits, typeFits, typeCon }, 0 },
    { "sbcpln", 9, 9, { typeFits, typeFits, typeCon, typeCon, typeFits, typeFits, typeFits, typeCon, typeCon }, 0 },
    { "sb2srf", 13, 13, { typeFits, typeFits, typeFits, typeCon, typeCon, REALNUM, REALNUM, REALNUM, typeCon, typeCon, typeCon, typeFits, typeCon }, 0 },
    { "radialplot", 4, 4, { typeFits, typeCon, typeCon, typeCon }, 0 },
    { "setfitskey", 3, 4, { typeId | typeFits, typeStr, typeCon | typeDbl | typeStr, typeStr }, 0 },
    { "setbitpix", 2, 4, { typeId | typeFits, typeCon, REALNUM, REALNUM }, 0 },
    { "cd", 1, 1, { typeStr }, 0 },
    { "setwcs", 6, 7, { typeId | typeFits, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM }, 0 },
    { "shrink", 2, 3, { typeId | typeFits, typeCon, typeCon }, 0 },
    { "view", 1, 3, { typeId | typeFits | typeDpArr | typeStrarr, REALNUM, REALNUM }, 9, { "linear", "log", "sqrt", "minmax", "scale999", "scale995", "scale99", "scale98", "scale95" } },
    { "limits", 3, 7, { typeFits, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING, typeId|ANYTHING }, 0 },
    { "printf", 2, 2, { typeStr, REALNUM }, 0 },
    { "export", 2, 3, { typeStr, typeFits|typeStrarr, typeCon }, 0, },
    { "writebmp", 2, 4, { typeStr, typeFits, typeFits, typeFits }, 0 },
    { "swapbytes", 1, 1, { typeId | typeFits}, 0, },
    { "read", 2, 10, { typeStr, typeId|REALNUM|typeStr, typeId|REALNUM|typeStr, typeId|REALNUM|typeStr, typeId|REALNUM|typeStr, typeId|REALNUM|typeStr, typeId|REALNUM|typeStr, typeId|REALNUM|typeStr, typeId|REALNUM|typeStr, typeId|REALNUM|typeStr }, 0, },
    { "shade", 1, 1, { typeFits }, 0, },
    { "replace", 3, 3, { typeId|typeStr|typeStrarr, typeStr, typeStr }, 0, },
    { "saomarkpoint", 4, 5, { typeCon, typeCon, typeCon, typeCon, typeCon }, 0, },
    { "saoclear", 0, 0, { typeCon }, 0, },
    { "saomarklabel", 3, 6, { typeCon, typeCon, typeStr, typeCon, typeCon, typeCon }, 0, },
    { "cblank", 1, 2, { typeId | typeFits, REALNUM }, 0, },
    { "cubemerge", 2, 2, { typeStr, typeStrarr }, 0, },
    { "setenv", 2, 2, { typeStr, typeStr }, 0, },
    { "break", 0, 0, { typeCon }, 0, },
    { "run", 1, 1, { typeStr }, 1, { "idl" } },
    { "echo", 1, 1, { typeCon }, 0, },
    { "precess", 8, 8, { REALNUM, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM, REALNUM }, 0, },
    { "pwd", 0, 0, { typeCon }, 0, },
    { "dir", 0, 1, { typeStr }, 0, },
    { "newbuffer", 1, 2, { typeStr, typeCon }, 0, },
    { "setindexbase", 1, 1, { typeCon }, 0, },
    { "fortrannotation", 0, 0, { typeCon }, 0, },
    { "cnotation", 0, 0, { typeCon }, 0, },
    { "userDialog", 2, 4, { typeStr, typeStrarr, typeStrarr, typeStrarr }, 0, },
    { "cirrange", 1, 1, { typeId|REALNUM|typeFits }, 2, { "deg", "rad" } },
    { "debug", 0, 1, { typeCon }, 0, },
    { "copyheader", 2, 2, { typeId | typeFits, typeFits }, 0, },
    { "swapaxes", 4, 4, { typeId | typeFits, typeCon, typeCon, typeCon}, 0, },
    { "setfitstype", 1, 2, { typeId | typeFits | typeDpArr, typeCon }, 2, { "image", "bintable" } },
    { "watchdir", 3, 3, { typeStr, typeStr, typeStr }, 0, },
    { "message", 1, 1, { typeStr }, 3, { "information", "warning", "critical" } },
    { "updategui", 2, 2, { typeStr, typeFits|typeStrarr }, 0, },
    { "return", 0, 1, { ANYTHING }, 0, },
    { "python", 0, 1, { typeStr }, 0, },
    { "deletefitskey", 2, 2, { typeId|typeFits, typeStr}, 0, },
    { "plvpor", 4, 4, { REALNUM, REALNUM, REALNUM, REALNUM }, 0, },
    { "plsvpa", 4, 4, { REALNUM, REALNUM, REALNUM, REALNUM }, 0, },
    { "plvasp", 1, 1, { REALNUM }, 0, },
    { "plvpas", 5, 5, { REALNUM, REALNUM, REALNUM, REALNUM, REALNUM }, 0, },
    { "plvsta", 0, 0, { typeCon }, 0, },
    { "plwind", 4, 4, { REALNUM, REALNUM, REALNUM, REALNUM }, 0, },
    { "plbox", 6, 6, { typeStr, REALNUM, typeCon, typeStr, REALNUM, typeCon }, 0, },
    { "plclear", 0, 0, { typeCon }, 0, },
    { "plsstrm", 1, 1, { typeCon }, 0, },
    { "plreplot", 0, 0, { typeCon }, 0, },
    { "plline", 3, 3, { typeCon, typeFits, typeFits }, 0 },
    { "pladv", 1, 1, { typeCon }, 0 },
    { "plscol0", 4, 5, { typeCon, typeCon, typeCon, typeCon, REALNUM }, 0 },
    { "plcol0", 1, 1, { typeCon }, 0 },
    { "plstart", 3, 3, { typeStr, typeCon, typeCon }, 0 },
    { "pllsty", 1, 1, { typeCon }, 0 },
    { "plwidth", 1, 1, { REALNUM }, 0 },
    { "pllab", 3, 3, { typeStr, typeStr, typeStr }, 0 },
    { "plpoin", 4, 4, { typeCon, typeFits, typeFits, typeCon }, 0 },
    { "setBrightnessContrast", 2, 2, { typeCon, typeCon }, 0 },
    { "", 0, 0, { typeCon } }
};

void init_procedures() {
    procs.reserve(300);

    int i = 0;
    while (strcmp(pgss[i].name, "") != 0) {
        procs.push_back(FunctionDeclaration(
        pgss[i].name,
        pgss[i].minargs,
        pgss[i].maxargs,
        pgss[i].args,
        pgss[i].noptions,
        pgss[i].options));
        i++;
    }
}

void resolveProcedure(int id, std::vector<ASTNode *>args, std::vector<std::string>options) {

//void dopgplot(nodeType *p) {
    int nargs, success = true;
    long pg;
    long la[20];
    double fa[20];
    dpuserType arg[20];
    dpuserType pgVariables[20];
    std::map<std::string, dpuserType> oldglobals;
#ifdef HAS_PGPLOT
    int pgi[20];
    float pgf[20];
    char cans1[256], cans2[256];
#endif /* HAS_PGPLOT */

    /* Which routine are we calling */
    pg = id;
    nargs = 0;

    if (pg < 0) {
        return;
    }

    int procedure_options = 0;

    if (options.size() > 0) {
        if (procs[id].noptions == 0) {
            dp_output("WARNING - Procedure %s does not support options [/%s].\n",
                  options[0].c_str());
        } else {
            for (int i = 0; i < options.size(); i++) {
                if (procs[id].options.count(options[i])) {
                    procedure_options |= procs[id].options[options[i]];
                } else {
                    dp_output("WARNING - Ignoring invalid option /%s for procedure %s.\n",
                               options[i].c_str(), procs[id].name.c_str());
                }
            }
        }
    }

    // save global variables which might be overwritten
    if (dpuser_vars.count("title")) oldglobals["title"] = dpuser_vars["title"];
    if (dpuser_vars.count("xtitle")) oldglobals["xtitle"] = dpuser_vars["xtitle"];
    if (dpuser_vars.count("ytitle")) oldglobals["ytitle"] = dpuser_vars["ytitle"];
    if (dpuser_vars.count("symbol")) oldglobals["symbol"] = dpuser_vars["symbol"];

    // resolve keywords
    if (id <= npg) {
        nargs = 0;
        success = 1;
        for (int i = 0; i < args.size(); i++) {
            if (dynamic_cast<assignmentNode *>(args.at(i)) != NULL) {
                args.at(i)->evaluate();
            } else {
                if (success) {
                    if (!(procs[pg].args[i] & typeId)) {
                        arg[nargs] = args.at(i)->evaluate();
                    } else if (dynamic_cast<variableNode *>(args.at(i)) != NULL) {
                        arg[nargs].type = typeId;
/*@                    } else if ((args.at(i)->type == typeOpr) &&
                               (p->pgplot.op[i]->opr.op[0]->type == typeId) &&
                               (variables[p->pgplot.op[i]->opr.op[0]->id.i].type == typeDpArr)) {
                        arg[nargs].type = typeId; */
                    } else {
                        arg[nargs].type = typeUnknown;
                    }
                    if (arg[nargs].type == typeUnknown) {
                        if (procs[pg].args[i] & typeId) {
                            dp_output("Argument %i must be a named variable\n", nargs + 1);
                        } else {
                            dp_output("Argument %i is of unknown type\n", nargs + 1);
                        }
                        success = FALSE;
                    }
                    nargs++;
                }
            }
        }
        if (!success) return;

        // Check number of arguments
        if (nargs < procs[pg].minargs) {
            dp_output("%s: ", procs[pg].name.c_str());
            yyerror("Too few arguments for subroutine\n");
            success = 0;
        } else if (nargs > procs[pg].maxargs) {
            dp_output("%s: ", procs[pg].name.c_str());
            yyerror("Too many arguments for subroutine\n");
            success = 0;
        }

        // convert typeStr to typeFitsFile and vice versa, if appropriate
        for (int i = 0; i < nargs; i++) {
            if (arg[i].type == typeStr) {
                if (!(procs[pg].args[i] & typeStr)) {
                    if (procs[pg].args[i] & typeFitsFile) {
                        arg[i].type = typeFitsFile;
                        arg[i].ffvalue = arg[i].svalue;
                    }
                }
            } else if (arg[i].type == typeFitsFile) {
                if (!(procs[pg].args[i] & typeFitsFile)) {
                    if (procs[pg].args[i] & typeStr) {
                        arg[i].type = typeStr;
                        arg[i].svalue = arg[i].ffvalue;
                    }
                }
            }
        }

        // check argument types, but not for print
        if ((success) && (pg != 132)) {
            for (int i = 0; i < nargs; i++) {
                if (!(arg[i].type & procs[pg].args[i])) {
                    if ((procs[pg].args[i] == typeFits) && (arg[i].type == typeFitsFile)) {
                        arg[i].fvalue = CreateFits();
                        success = arg[i].fvalue->ReadFITS(arg[i].ffvalue->c_str());
                        arg[i].type = typeFits;
                    } else {
                        dp_output("%s: Argument %i", procs[pg].name.c_str(), i + 1);
                        yyerror(" is of wrong type");
                        success = 0;
                    }
                }
                if (success) if (arg[i].type == typeCon) {
                    arg[i].dvalue = (double)arg[i].lvalue;
                    if ((pg != 188) && (pg != 195)) {
                        arg[i].type = typeDbl;
                    }
                }
                if (success) if (dynamic_cast<variableNode *>(args.at(i)) != NULL) {
/*@                    if ((p->pgplot.op[i]->type == typeOpr) &&
                        (variables[p->pgplot.op[i]->opr.op[0]->id.i].type == typeDpArr) &&
                        (p->pgplot.op[i]->opr.op[1]->type == typeRng) &&
                        (p->pgplot.op[i]->opr.op[1]->rng.nops == 2) &&
                        (p->pgplot.op[i]->opr.op[1]->rng.op[1] == NULL)) {
                            if ((p->pgplot.op[i]->opr.op[1]->rng.op[0]->con.value.lvalue >= 0) &&
                                (p->pgplot.op[i]->opr.op[1]->rng.op[0]->con.value.lvalue < variables[p->pgplot.op[i]->opr.op[0]->id.i].dparrvalue->size())) {
                                arg[i].lvalue = p->pgplot.op[i]->opr.op[0]->id.i;
                                pgVariables[i] = variables[p->pgplot.op[i]->opr.op[0]->id.i].dparrvalue->at(p->pgplot.op[i]->opr.op[1]->rng.op[0]->con.value.lvalue)->toConValue();
                            } else {
                                dp_output("%s: Argument %i", procs[pg].name.c_str(), i + 1);
                                yyerror(" is out of range");
                                success = 0;
                            }
                    } else { */
/*                        arg[i].lvalue = p->pgplot.op[i]->id.i;
                        pgVariables[i] = variables[p->pgplot.op[i]->id.i]; */
                        pgVariables[i] = dpuser_vars[(dynamic_cast<variableNode *>(args.at(i)))->id];
/*                    }
                    if (success) { */
                        if (!(pgVariables[i].type & procs[pg].args[i])) {
                            dp_output("%s: Argument %i", procs[pg].name.c_str(), i + 1);
                            yyerror(" is of wrong type");
                            success = 0;
                        }
                    }
                }
            }
            if (success) {
                for (int i = 0; i < nargs; i++) {
                    if (!(arg[i].type & typeDbl)) {
                        arg[i].dvalue = 0.0;
                    }
                    la[i] = arg[i].lvalue;
                    fa[i] = arg[i].dvalue;
                }
            } else {
                return;
            }
        }
/*@    } else {
        nargs = 0;
        success = 1;
        for (int i = 0; i < p->pgplot.nops; i++) {
            if ((p->pgplot.op[i]->type == typeOpr) && (p->pgplot.op[i]->opr.oper == '=')) {
                ex(p->pgplot.op[i]);
            } else {
                if (success) {
                    if (!(p->pgplot.op[i]->type & typeId)) arg[nargs] = ex(p->pgplot.op[i]);
                    else {
                        arg[nargs].type = typeId;
                        arg[i].lvalue = p->pgplot.op[i]->id.i;
                    }
                    if (arg[nargs].type == typeUnknown) success = FALSE;
                    nargs++;
                }
            }
        }
    }*/

    float   *data1 = NULL,
            *data2 = NULL,
            *data3 = NULL,
            *data4 = NULL,
            *data5 = NULL;

    double  *ddata1 = NULL,
            *ddata2 = NULL,
            *ddata3 = NULL,
            *ddata4 = NULL,
            *ddata5 = NULL;

#ifdef DPQT
    // Lock QFitsView buffer, if necessary
    if ((nargs > 0) &&
        (procs[pg].args[0] == (typeFits | typeId)) &&
        (fitsMainWindow != NULL))
    {
        QWriteLocker locker(&buffersLock);
    }
#endif /* DPQT */

    if (success) switch (pg) {
#ifdef HAS_PGPLOT

/************************
 ***      pgarro      ***
 ************************/
        case 0:
            cpgarro(fa[0], fa[1], fa[2], fa[3]);
            break;

/************************
 ***      pgask       ***
 ************************/
        case 1:
            cpgask(la[0]);
            break;

/************************
 ***      pgaxis      ***
 ************************/
        case 2:
            cpgaxis(arg[0].svalue->c_str(), fa[1], fa[2], fa[3], fa[4], fa[5], fa[6], fa[7], la[8], fa[9], fa[10], fa[11], fa[12], fa[13]);
            break;

/************************
 ***      pgband      ***
 ************************/
        case 3: {
            float x, y;
            char ch[2];

            ch[1] = (char)0;
            if (pgVariables[4].type == typeCon) x = (float)pgVariables[4].lvalue;
            else x = (float)pgVariables[4].dvalue;
            if (pgVariables[5].type == typeCon) y = (float)pgVariables[5].lvalue;
            else y = (float)pgVariables[5].dvalue;
            cpgband(la[0], la[1], fa[2], fa[3], &x, &y, ch);
            SETDBLVARIABLE(4,x);
            SETDBLVARIABLE(5,y);
            pgVariables[6].type = typeStr;
            pgVariables[6].svalue = CreateString(ch);
//            variables[la[6]].type = typeStr;
//            variables[la[6]].svalue = CreateString(ch);
            }
            break;

/************************
 ***      pgbbuf      ***
 ************************/
        case 4:
            cpgbbuf();
            break;

/************************
 ***      pgbeg       ***
 ************************/
        case 5:
            cpgbeg(la[0], arg[1].svalue->c_str(), la[2], la[3]);
            break;

/************************
 ***      pgbegin     ***
 ************************/
        case 6:
            cpgbeg(la[0], arg[1].svalue->c_str(), la[2], la[3]);
            break;

/************************
 ***      pgbin       ***
 ************************/
        case 7:
            data1 = floatdata(*arg[1].fvalue);
            data2 = floatdata(*arg[2].fvalue);
            if (data1 && data2)
                cpgbin(la[0], data1, data2, la[3]);
            if (data1 && (data1 != arg[1].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[2].fvalue->r4data)) free(data2);
            break;

/************************
 ***      pgbox       ***
 ************************/
        case 8:
            cpgbox(arg[0].svalue->c_str(), fa[1], la[2], arg[3].svalue->c_str(), fa[4], la[5]);
            break;

/************************
 ***      pgcirc      ***
 ************************/
        case 9: cpgcirc(fa[0], fa[1], fa[2]);
            break;

/************************
 ***      pgclos      ***
 ************************/
        case 10:
            cpgclos();
            break;

/************************
 ***      pgconb      ***
 ************************/
        case 11:
            if ((la[1] > arg[0].fvalue->Naxis(1)) || (la[2] > arg[0].fvalue->Naxis(2))) {
                dp_output("pgconb: Args 2 and 3 don't match given array\n");
                break;
            }
            if (abs(la[8]) > (long)arg[7].fvalue->Nelements()) {
                dp_output("pgconb: Args 8 and 9 don't match\n");
                break;
            }
            if (arg[9].fvalue->Nelements() != 6) {
                dp_output("pgconb: Transformation matrix must have exactly 6 elements\n");
                break;
            }
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[7].fvalue);
            data3 = floatdata(*arg[9].fvalue);
            if (data1 && data2 && data3)
                cpgconb(data1, la[1], la[2], la[3], la[4], la[5], la[6], data2, la[8], data3, fa[10]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[7].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[9].fvalue->r4data)) free(data3);
            break;

/************************
 ***      pgconf      ***
 ************************/
        case 12:
            if ((la[1] > arg[0].fvalue->Naxis(1)) || (la[2] > arg[0].fvalue->Naxis(2))) {
                dp_output("pgconf: Args 2 and 3 don't match given array\n");
                break;
            }
            if (arg[9].fvalue->Nelements() != 6) {
                dp_output("pgconf: Transformation matrix must have exactly 6 elements\n");
                break;
            }
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[9].fvalue);
            if (data1 && data2)
                cpgconf(data1, la[1], la[2], la[3], la[4], la[5], la[6], fa[7], fa[8], data2);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[9].fvalue->r4data)) free(data2);
            break;

/************************
 ***      pgconl      ***
 ************************/
        case 13:
            if ((la[1] > arg[0].fvalue->Naxis(1)) || (la[2] > arg[0].fvalue->Naxis(2))) {
                dp_output("pgconl: Args 2 and 3 don't match given array\n");
                break;
            }
            if (arg[8].fvalue->Nelements() != 6) {
                dp_output("pgconb: Transformation matrix must have exactly 6 elements\n");
                break;
            }
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[8].fvalue);
            if (data1 && data2)
                cpgconl(data1, la[1], la[2], la[3], la[4], la[5], la[6], fa[7], data2, arg[9].svalue->c_str(), la[10], la[11]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[8].fvalue->r4data)) free(data2);
            break;

/************************
 ***      pgcons      ***
 ************************/
        case 14:
            if ((la[1] > arg[0].fvalue->Naxis(1)) || (la[2] > arg[0].fvalue->Naxis(2))) {
                dp_output("pgcons: Args 2 and 3 don't match given array\n");
                break;
            }
            if (abs(la[8]) > (long)arg[7].fvalue->Nelements()) {
                dp_output("pgcons: Args 8 and 9 don't match\n");
                break;
            }
            if (arg[9].fvalue->Nelements() != 6) {
                dp_output("pgcons: Transformation matrix must have exactly 6 elements\n");
                break;
            }
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[7].fvalue);
            data3 = floatdata(*arg[9].fvalue);
            if (data1 && data2 && data3)
                cpgcons(data1, la[1], la[2], la[3], la[4], la[5], la[6], data2, la[8], data3);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[7].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[9].fvalue->r4data)) free(data3);
            break;

/************************
 ***      pgcont      ***
 ************************/
        case 15:
            if ((la[1] > arg[0].fvalue->Naxis(1)) || (la[2] > arg[0].fvalue->Naxis(2))) {
                dp_output("pgcont: Args 2 and 3 don't match given array\n");
                break;
            }
            if (abs(la[8]) > (long)arg[7].fvalue->Nelements()) {
                dp_output("pgcont: Args 8 and 9 don't match\n");
                break;
            }
            if (arg[9].fvalue->Nelements() != 6) {
                dp_output("pgcont: Transformation matrix must have exactly 6 elements\n");
                break;
            }
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[7].fvalue);
            data3 = floatdata(*arg[9].fvalue);
            if (data1 && data2 && data3)
                cpgcont(data1, la[1], la[2], la[3], la[4], la[5], la[6], data2, la[8], data3);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[7].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[9].fvalue->r4data)) free(data3);
            break;

/************************
 ***      pgctab      ***
 ************************/
        case 17:
            if ((la[4] > (long)arg[0].fvalue->Nelements()) ||
                (la[4] > (long)arg[1].fvalue->Nelements()) ||
                (la[4] > (long)arg[2].fvalue->Nelements()) ||
                (la[4] > (long)arg[3].fvalue->Nelements())) {
                dp_output("pgctab: Inconsistent number of color entries\n");
                break;
            }
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[2].fvalue);
            data4 = floatdata(*arg[3].fvalue);
            if (data1 && data2 && data3 && data4)
                cpgctab(data1, data2, data3, data4, la[4], fa[5], fa[6]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[2].fvalue->r4data)) free(data3);
            if (data4 && (data4 != arg[3].fvalue->r4data)) free(data4);
            break;

/************************
 ***      pgcurse     ***
 ************************/
        case 18: {
            float x, y;
            char ch[2];

            ch[1] = (char)0;
            if (pgVariables[0].type == typeCon) x = (float)pgVariables[0].lvalue;
            else x = (float)pgVariables[0].dvalue;
            if (pgVariables[1].type == typeCon) y = (float)pgVariables[1].lvalue;
            else y = (float)pgVariables[1].dvalue;
            cpgcurs(&x, &y, ch);
            SETDBLVARIABLE(0,x);
            SETDBLVARIABLE(1,y);
            pgVariables[2].type = typeStr;
            pgVariables[2].svalue = CreateString(ch);
        }
            break;

/************************
 ***      pgcurs      ***
 ************************/
        case 19: {
            float x, y;
            char ch[2];

            ch[1] = (char)0;
            if (pgVariables[0].type == typeCon) x = (float)pgVariables[0].lvalue;
            else x = (float)pgVariables[0].dvalue;
            if (pgVariables[1].type == typeCon) y = (float)pgVariables[1].lvalue;
            else y = (float)pgVariables[1].dvalue;
            cpgcurs(&x, &y, ch);
            SETDBLVARIABLE(0,x);
            SETDBLVARIABLE(1,y);
            pgVariables[2].type = typeStr;
            pgVariables[2].svalue = CreateString(ch);
//            variables[la[0]].type = typeDbl;
//            variables[la[0]].dvalue = (double)x;
//            variables[la[1]].type = typeDbl;
//            variables[la[1]].dvalue = (double)y;
//            variables[la[2]].type = typeStr;
//            variables[la[2]].svalue = CreateString(ch);
            }
            break;

/************************
 ***      pgdraw      ***
 ************************/
        case 20:
            cpgdraw(fa[0], fa[1]);
            break;

/************************
 ***      pgebuf      ***
 ************************/
        case 21:
            cpgebuf();
            break;

/************************
 ***      pgend       ***
 ************************/
        case 22:
            cpgend();
            break;

/************************
 ***      pgenv       ***
 ************************/
        case 23:
            cpgenv(fa[0], fa[1], fa[2], fa[3], la[4], la[5]);
            break;

/************************
 ***      pgeras      ***
 ************************/
        case 24:
            cpgeras();
            break;

/************************
 ***      pgerr1      ***
 ************************/
        case 25:
            cpgerr1(la[0], fa[1], fa[2], fa[3], fa[4]);
            break;

/************************
 ***      pgerrb      ***
 ************************/
        case 26:
            if ((la[1] > (long)arg[2].fvalue->Nelements()) ||
                (la[1] > (long)arg[3].fvalue->Nelements()) ||
                (la[1] > (long)arg[4].fvalue->Nelements())) {
                dp_output("pgerrb: Inconsistent number of array elements\n");
                break;
            }
            data1 = floatdata(*arg[2].fvalue);
            data2 = floatdata(*arg[3].fvalue);
            data3 = floatdata(*arg[4].fvalue);
            if (data1 && data2 && data3)
                cpgerrb(la[0], la[1], data1, data2, data3, fa[5]);
            if (data1 && (data1 != arg[2].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[3].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[4].fvalue->r4data)) free(data3);
            break;

/************************
 ***      pgerrx      ***
 ************************/
        case 27:
            if ((la[0] > (long)arg[1].fvalue->Nelements()) ||
                (la[0] > (long)arg[2].fvalue->Nelements()) ||
                (la[0] > (long)arg[3].fvalue->Nelements())) {
                dp_output("pgerrx: Inconsistent number of array elements\n");
                break;
            }
            data1 = floatdata(*arg[1].fvalue);
            data2 = floatdata(*arg[2].fvalue);
            data3 = floatdata(*arg[3].fvalue);
            if (data1 && data2 && data3)
                cpgerrx(la[0], data1, data2, data3, fa[4]);
            if (data1 && (data1 != arg[1].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[2].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[3].fvalue->r4data)) free(data3);
            break;

/************************
 ***      pgerry      ***
 ************************/
        case 28:
            if ((la[0] > (long)arg[1].fvalue->Nelements()) ||
                (la[0] > (long)arg[2].fvalue->Nelements()) ||
                (la[0] > (long)arg[3].fvalue->Nelements())) {
                dp_output("pgerry: Inconsistent number of array elements\n");
                break;
            }
            data1 = floatdata(*arg[1].fvalue);
            data2 = floatdata(*arg[2].fvalue);
            data3 = floatdata(*arg[3].fvalue);
            if (data1 && data2 && data3)
                cpgerry(la[0], data1, data2, data3, fa[4]);
            if (data1 && (data1 != arg[1].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[2].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[3].fvalue->r4data)) free(data3);
            break;

/************************
 ***      pgetxt      ***
 ************************/
        case 29:
            cpgetxt();
            break;

/************************
 ***      pggray      ***
 ************************/
        case 33:
            if ((la[1] > arg[0].fvalue->Naxis(1)) || (la[2] > arg[0].fvalue->Naxis(2))) {
                dp_output("pggray: Dimensions don't match given array\n");
                break;
            }
            if (arg[9].fvalue->Nelements() != 6) {
                dp_output("pggray: Transformation matrix must have exactly 6 elements\n");
                break;
            }
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[9].fvalue);
            if (data1 && data2)
                cpggray(data1, la[1], la[2], la[3], la[4], la[5], la[6], fa[7], fa[8], data2);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[9].fvalue->r4data)) free(data2);
            break;

/************************
 ***      pghi2d      ***
 ************************/
        case 34:
            if ((la[1] > arg[0].fvalue->Naxis(1)) || (la[2] > arg[0].fvalue->Naxis(2))) {
                dp_output("pghi2d: Dimensions don't match given array\n");
                break;
            }
            if (la[4] <= la[3]) {
                dp_output("pghi2d: IX2 must be greater than IX1\n");
                break;
            }
            if (la[4] - la[3] + 1 > (long)arg[7].fvalue->Nelements()) {
                dp_output("pghi2d: Number of elements of abscissae too small\n");
                break;
            }
            if (la[4] - la[3] + 1 > (long)arg[9].fvalue->Nelements()) {
                dp_output("pghi2d: Work array too small\n");
                break;
            }
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[7].fvalue);
            data3 = floatdata(*arg[11].fvalue);
            if (data1 && data2 && data3)
                cpghi2d(data1, la[1], la[2], la[3], la[4], la[5], la[6], data2, la[8], fa[9], la[10], data3);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[7].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[11].fvalue->r4data)) free(data3);
            break;

/************************
 ***      pghist      ***
 ************************/
        case 35:
            if (la[0] > (long)arg[1].fvalue->Nelements()) {
                dp_output("pghist: Inconsistent number of array elements\n");
                break;
            }
            data1 = floatdata(*arg[1].fvalue);
            if (data1)
                cpghist(la[0], data1, fa[2], fa[3], la[4], la[5]);
            if (data1 && (data1 != arg[1].fvalue->r4data)) free(data1);
            break;

/************************
 ***      pgiden      ***
 ************************/
        case 36:
            cpgiden();
            break;

/************************
 ***      pgimag      ***
 ************************/
        case 37:
            if ((la[1] > arg[0].fvalue->Naxis(1)) || (la[2] > arg[0].fvalue->Naxis(2))) {
                dp_output("pgimag: Dimensions don't match given array\n");
                break;
            }
            if (arg[9].fvalue->Nelements() != 6) {
                dp_output("pgimag: Transformation matrix must have exactly 6 elements\n");
                break;
            }
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[9].fvalue);
            if (data1 && data2)
                cpgimag(data1, la[1], la[2], la[3], la[4], la[5], la[6], fa[7], fa[8], data2);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[9].fvalue->r4data)) free(data2);
            break;

/************************
 ***      pglabel     ***
 ************************/
        case 38:
            cpglab(arg[0].svalue->c_str(), arg[1].svalue->c_str(), arg[2].svalue->c_str());
            break;

/************************
 ***      pglab       ***
 ************************/
        case 39:
            cpglab(arg[0].svalue->c_str(), arg[1].svalue->c_str(), arg[2].svalue->c_str());
            break;

/************************
 ***      pglcur      ***
 ************************/
        case 40: {
            int npg = pgVariables[1].lvalue;

            pgVariables[2].fvalue->setType(R4);
            pgVariables[3].fvalue->setType(R4);
            cpglcur(la[0], &npg, pgVariables[2].fvalue->r4data, pgVariables[3].fvalue->r4data);
            pgVariables[1].lvalue = npg;
//            int npg = variables[la[1]].lvalue;

//            variables[la[2]].fvalue->setType(R4);
//            variables[la[3]].fvalue->setType(R4);
//            cpglcur(la[0], &npg, variables[la[2]].fvalue->r4data, variables[la[3]].fvalue->r4data);
//            variables[la[1]].lvalue = npg;
            }
            break;

/************************
 ***      pgldev      ***
 ************************/
        case 41:
            cpgldev();
            break;

/************************
 ***      pglen       ***
 ************************/
        case 42: {
            float xl, yl;

            cpglen(la[0], arg[1].svalue->c_str(), &xl, &yl);
            SETDBLVARIABLE(2,xl);
            SETDBLVARIABLE(3,yl);
//            variables[la[2]].type = typeDbl;
//            variables[la[2]].dvalue = (double)xl;
//            variables[la[3]].type = typeDbl;
//            variables[la[3]].dvalue = (double)yl;
            }
            break;

/************************
 ***      pgline      ***
 ************************/
        case 43:
            if ((la[0] > (long)arg[1].fvalue->Nelements()) || (la[0] > (long)arg[2].fvalue->Nelements())) {
                dp_output("pgline: Inconsistent number of points\n");
                break;
            }
            data1 = floatdata(*arg[1].fvalue);
            data2 = floatdata(*arg[2].fvalue);
            if (data1 && data2)
                cpgline(la[0], data1, data2);
            if (data1 && (data1 != arg[1].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[2].fvalue->r4data)) free(data2);
            break;

/************************
 ***      pgmove      ***
 ************************/
        case 44:
            cpgmove(fa[0], fa[1]);
            break;

/************************
 ***      pgmtext     ***
 ************************/
        case 45:
            cpgmtxt(arg[0].svalue->c_str(), fa[1], fa[2], fa[3], arg[4].svalue->c_str());
            break;

/************************
 ***      pgmtxt      ***
 ************************/
        case 46:
            cpgmtxt(arg[0].svalue->c_str(), fa[1], fa[2], fa[3], arg[4].svalue->c_str());
            break;

/************************
 ***      pgncur      ***
 ************************/
        case 47:

/************************
 ***     pgncurse     ***
 ************************/
        case 48: {
            int npg = pgVariables[1].lvalue;

            pgVariables[2].fvalue->setType(R4);
            pgVariables[3].fvalue->setType(R4);
            cpgncur(la[0], &npg, pgVariables[2].fvalue->r4data, pgVariables[3].fvalue->r4data, la[4]);
            pgVariables[1].lvalue = npg;
//            int npg = variables[la[1]].lvalue;

//            variables[la[2]].fvalue->setType(R4);
//            variables[la[3]].fvalue->setType(R4);
//            cpgncur(la[0], &npg, variables[la[2]].fvalue->r4data, variables[la[3]].fvalue->r4data, la[4]);
//            variables[la[1]].lvalue = npg;
            }
            break;

/************************
 ***      pgnumb      ***
 ************************/
        case 49: {
            int nc, i;

            for (i = 0; i < 256; i++) cans1[i] = (char)0;
            nc = 256;
            cpgnumb(la[0], la[1], la[2], cans1, &nc);
            pgVariables[3].type = typeStr;
            pgVariables[3].svalue = CreateString(cans1);
            SETINTVARIABLE(4,nc);
//            variables[3].type = typeStr;
//            variables[3].svalue = CreateString(cans1);
//            variables[la[4]].type = typeCon;
//            variables[la[4]].lvalue = (long)nc;
        }
            break;

/************************
 ***      pgolin      ***
 ************************/
        case 50: {
            int npg = pgVariables[1].lvalue;

            pgVariables[2].fvalue->setType(R4);
            pgVariables[3].fvalue->setType(R4);
            cpgolin(la[0], &npg, pgVariables[2].fvalue->r4data, pgVariables[3].fvalue->r4data, la[4]);
            pgVariables[1].lvalue = npg;
//            int npg = variables[la[1]].lvalue;

//            variables[la[2]].fvalue->setType(R4);
//            variables[la[3]].fvalue->setType(R4);
//            cpgolin(la[0], &npg, variables[la[2]].fvalue->r4data, variables[la[3]].fvalue->r4data, la[4]);
//            variables[la[1]].lvalue = npg;
        }
            break;

/************************
 ***      pgopen      ***
 ************************/
        case 51:
            cpgopen(arg[0].svalue->c_str());
            break;

/************************
 ***      pgpage      ***
 ************************/
        case 52:
            cpgpage();
            break;

/************************
 ***      pgpanl      ***
 ************************/
        case 53:
            cpgpanl(la[0], la[1]);
            break;

/************************
 ***      pgpaper     ***
 ************************/
        case 54:
            cpgpap(fa[0], fa[1]);
            break;

/************************
 ***      pgpap       ***
 ************************/
        case 55:
            cpgpap(fa[0], fa[1]);
            break;

/************************
 ***      pgpixl      ***
 ************************/
        case 56: {
            int *ia, i;

            if ((ia = (int *)malloc(la[1] * la[2] * sizeof(int))) == NULL) break;
            for (i = 0; i < la[1] * la[2]; i++) ia[i] = (int)(arg[0].fvalue->ValueAt(i));
            cpgpixl(ia, la[1], la[2], la[3], la[4], la[5], la[6], fa[7], fa[8], fa[9], fa[10]);
            free(ia);
            }
            break;

/************************
 ***      pgpnts      ***
 ************************/
        case 57: {
            if ((la[0] > (long)arg[1].fvalue->Nelements()) || (la[0] > (long)arg[2].fvalue->Nelements())) {
                dp_output("pgpnts: Inconsistent number of points\n");
                break;
            }
            if (la[4] > (long)arg[3].fvalue->Nelements()) {
                dp_output("pgpnts: Inconsistent number of symbols\n");
                break;
            }
            int *symbol, i;

            if ((symbol = (int *)malloc(la[4] * sizeof(int))) == NULL) break;
            for (i = 0; i < la[4]; i++) symbol[i] = (int)(arg[3].fvalue->ValueAt(i));
            data1 = floatdata(*arg[1].fvalue);
            data2 = floatdata(*arg[2].fvalue);
            if (data1 && data2)
                cpgpnts(la[0], data1, data2, symbol, la[4]);
            if (data1 && (data1 != arg[1].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[2].fvalue->r4data)) free(data2);
            free(symbol);
            }
            break;

/************************
 ***      pgpoint     ***
 ************************/
        case 58:
            if ((la[0] > (long)arg[1].fvalue->Nelements()) || (la[0] > (long)arg[2].fvalue->Nelements())) {
                dp_output("pgpoint: Inconsistent number of points\n");
                break;
            }
            data1 = floatdata(*arg[1].fvalue);
            data2 = floatdata(*arg[2].fvalue);
            if (data1 && data2)
                cpgpt(la[0], data1, data2, la[3]);
            if (data1 && (data1 != arg[1].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[2].fvalue->r4data)) free(data2);
            break;

/************************
 ***      pgpoly      ***
 ************************/
        case 59:
            if ((la[0] > (long)arg[1].fvalue->Nelements()) || (la[0] > (long)arg[2].fvalue->Nelements())) {
                dp_output("pgpoly: Inconsistent number of points\n");
                break;
            }
            data1 = floatdata(*arg[1].fvalue);
            data2 = floatdata(*arg[2].fvalue);
            if (data1 && data2)
                cpgpoly(la[0], data1, data2);
            if (data1 && (data1 != arg[1].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[2].fvalue->r4data)) free(data2);
            break;

/************************
 ***      pgpt1       ***
 ************************/
        case 60:
            cpgpt1(fa[0], fa[1], la[2]);
            break;

/************************
 ***      pgptext     ***
 ************************/
        case 61:
            cpgptxt(fa[0], fa[1], fa[2], fa[3], arg[4].svalue->c_str());
            break;

/************************
 ***       pgpt       ***
 ************************/
        case 62:
            if ((la[0] > (long)arg[1].fvalue->Nelements()) || (la[0] > (long)arg[2].fvalue->Nelements())) {
                dp_output("pgpt: Inconsistent number of points\n");
                break;
            }
            data1 = floatdata(*arg[1].fvalue);
            data2 = floatdata(*arg[2].fvalue);
            if (data1 && data2)
                cpgpt(la[0], data1, data2, la[3]);
            if (data1 && (data1 != arg[1].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[2].fvalue->r4data)) free(data2);
            break;

/************************
 ***      pgptxt      ***
 ************************/
        case 63:
            cpgptxt(fa[0], fa[1], fa[2], fa[3], arg[4].svalue->c_str());
            break;

/************************
 ***      pgqah       ***
 ************************/
        case 64:
            cpgqah(&pgi[0], &pgf[1], &pgf[2]);
            SETINTVARIABLE(0,pgi[0]);
            SETDBLVARIABLE(1,pgf[1]);
            SETDBLVARIABLE(2,pgf[2]);
            break;

/************************
 ***      pgqcf       ***
 ************************/
        case 65:
            cpgqcf(&pgi[0]);
            SETINTVARIABLE(0,pgi[0]);
            break;

/************************
 ***      pgqch       ***
 ************************/
        case 66:
            cpgqch(&pgf[0]);
            SETDBLVARIABLE(0,pgf[0]);
            break;

/************************
 ***      pgqci       ***
 ************************/
        case 67:
            cpgqci(&pgi[0]);
            SETINTVARIABLE(0,pgi[0]);
            break;

/************************
 ***      pgqcir      ***
 ************************/
        case 68:
            cpgqcir(&pgi[0], &pgi[1]);
            SETINTVARIABLE(0,pgi[0]);
            SETINTVARIABLE(1,pgi[1]);
            break;

/************************
 ***      pgqclp      ***
 ************************/
        case 69:
            cpgqclp(&pgi[0]);
            SETINTVARIABLE(0,pgi[0]);
            break;

/************************
 ***      pgqcol      ***
 ************************/
        case 70:
            cpgqcol(&pgi[0], &pgi[1]);
            SETINTVARIABLE(0,pgi[0]);
            SETINTVARIABLE(1,pgi[1]);
            break;

/************************
 ***      pgqcr       ***
 ************************/
        case 71:
            cpgqcr(la[0], &pgf[1], &pgf[2], &pgf[3]);
            SETDBLVARIABLE(1,pgf[1]);
            SETDBLVARIABLE(2,pgf[2]);
            SETDBLVARIABLE(3,pgf[3]);
            break;

/************************
 ***      pgqcs       ***
 ************************/
        case 72:
            cpgqcs(la[0], &pgf[1], &pgf[2]);
            SETDBLVARIABLE(1,pgf[1]);
            SETDBLVARIABLE(2,pgf[2]);
            break;

/************************
 ***      pgqdt       ***
 ************************/
        case 73: {
            int i;

            for (i = 0; i < 256; i++) cans1[i] = cans2[i] = (char)0;
            pgi[2] = pgi[4] = 256;
            cpgqdt(la[0], cans1, &pgi[2], cans2, &pgi[4], &pgi[5]);
            pgVariables[1].type = typeStr;
            pgVariables[1].svalue = CreateString(cans1);
//            variables[la[1]].type = typeStr;
//            variables[la[1]].svalue = CreateString(cans1);
            SETINTVARIABLE(2,pgi[2]);
            pgVariables[3].type = typeStr;
            pgVariables[3].svalue = CreateString(cans2);
//            variables[la[3]].type = typeStr;
//            variables[la[3]].svalue = CreateString(cans2);
            SETINTVARIABLE(4,pgi[4]);
            SETINTVARIABLE(5,pgi[5]);
            }
            break;

/************************
 ***      pgqfs       ***
 ************************/
        case 74:
            cpgqfs(&pgi[0]);
            SETINTVARIABLE(0,pgi[0]);
            break;

/************************
 ***      pgqhs       ***
 ************************/
        case 75:
            cpgqhs(&pgf[0], &pgf[1], &pgf[2]);
            SETDBLVARIABLE(0,pgf[0]);
            SETDBLVARIABLE(1,pgf[1]);
            SETDBLVARIABLE(2,pgf[2]);
            break;

/************************
 ***       pgqid      ***
 ************************/
        case 76:
            cpgqid(&pgi[0]);
            SETINTVARIABLE(0,pgi[0]);
            break;

/************************
 ***      pgqinf      ***
 ************************/
        case 77: {
            int i;

            for (i = 0; i < 256; i++) cans1[i] = (char)0;
            pgi[2] = 256;
            cpgqinf(arg[0].svalue->c_str(), cans1, &pgi[2]);
            pgVariables[1].type = typeStr;
            pgVariables[1].svalue = CreateString(cans1);
//            variables[la[1]].type = typeStr;
//            variables[la[1]].svalue = CreateString(cans1);
            SETINTVARIABLE(2,pgi[2]);
            }
            break;

/************************
 ***      pgqitf      ***
 ************************/
        case 78:
            cpgqitf(&pgi[0]);
            SETINTVARIABLE(0,pgi[0]);
            break;

/************************
 ***      pgqls       ***
 ************************/
        case 79:
            cpgqls(&pgi[0]);
            SETINTVARIABLE(0,pgi[0]);
            break;

/************************
 ***      pgqlw       ***
 ************************/
        case 80:
            cpgqlw(&pgi[0]);
            SETINTVARIABLE(0,pgi[0]);
            break;

/************************
 ***      pgqndt      ***
 ************************/
        case 81:
            cpgqndt(&pgi[0]);
            SETINTVARIABLE(0,pgi[0]);
            break;

/************************
 ***      pgqpos      ***
 ************************/
        case 82:
            cpgqpos(&pgf[0], &pgf[1]);
            SETDBLVARIABLE(0,pgf[0]);
            SETDBLVARIABLE(1,pgf[1]);
            break;

/************************
 ***      pgqtbg      ***
 ************************/
        case 83:
            cpgqtbg(&pgi[0]);
            SETINTVARIABLE(0,pgi[0]);
            break;

/************************
 ***      pgqtxt      ***
 ************************/
        case 84:
            pgVariables[5].type = typeFits;
            pgVariables[5].fvalue = CreateFits();
            if (!pgVariables[5].fvalue->create(4, 1)) break;
            pgVariables[6].type = typeFits;
            pgVariables[6].fvalue = CreateFits();
            if (!pgVariables[6].fvalue->create(4, 1)) break;
            cpgqtxt(fa[0], fa[1], fa[2], fa[3], arg[4].svalue->c_str(), pgVariables[5].fvalue->r4data, pgVariables[6].fvalue->r4data);
//            variables[la[5]].type = typeFits;
//            variables[la[5]].fvalue = CreateFits();
//            if (!variables[la[5]].fvalue->create(4, 1)) break;
//            variables[la[6]].type = typeFits;
//            variables[la[6]].fvalue = CreateFits();
//            if (!variables[la[6]].fvalue->create(4, 1)) break;
//            cpgqtxt(fa[0], fa[1], fa[2], fa[3], arg[4].svalue->c_str(), variables[la[5]].fvalue->r4data, variables[la[6]].fvalue->r4data);
            break;

/************************
 ***      pgqvp       ***
 ************************/
        case 85:
            cpgqvp(la[0], &pgf[1], &pgf[2], &pgf[3], &pgf[4]);
            SETDBLVARIABLE(1,pgf[1]);
            SETDBLVARIABLE(2,pgf[2]);
            SETDBLVARIABLE(3,pgf[3]);
            SETDBLVARIABLE(4,pgf[4]);
            break;

/************************
 ***      pgqvsz      ***
 ************************/
        case 86:
            cpgqvsz(la[0], &pgf[1], &pgf[2], &pgf[3], &pgf[4]);
            SETDBLVARIABLE(1,pgf[1]);
            SETDBLVARIABLE(2,pgf[2]);
            SETDBLVARIABLE(3,pgf[3]);
            SETDBLVARIABLE(4,pgf[4]);
            break;

/************************
 ***      pgqwin      ***
 ************************/
        case 87:
            cpgqwin(&pgf[0], &pgf[1], &pgf[2], &pgf[3]);
            SETDBLVARIABLE(0,pgf[0]);
            SETDBLVARIABLE(1,pgf[1]);
            SETDBLVARIABLE(2,pgf[2]);
            SETDBLVARIABLE(3,pgf[3]);
            break;

/************************
 ***      pgqrect      ***
 ************************/
        case 88:
            cpgrect(fa[0], fa[1], fa[2], fa[3]);
            break;

/************************
 ***      pgrnge      ***
 ************************/
        case 90:
            cpgrnge(fa[0], fa[1], &pgf[2], &pgf[3]);
            SETDBLVARIABLE(2,pgf[2]);
            SETDBLVARIABLE(3,pgf[3]);
            break;

/************************
 ***      pgsah       ***
 ************************/
        case 91:
            cpgsah(la[0], fa[1], fa[2]);
            break;

/************************
 ***      pgsave      ***
 ************************/
        case 92:
            cpgsave();
            break;

/************************
 ***      pgunsa      ***
 ************************/
        case 93:
            cpgunsa();
            break;

/************************
 ***      pgscf       ***
 ************************/
        case 94:
            cpgscf(la[0]);
            break;

/************************
 ***      pgsch       ***
 ************************/
        case 95:
            cpgsch(fa[0]);
            break;

/************************
 ***      pgsci       ***
 ************************/
        case 96:
            cpgsci(la[0]);
            break;

/************************
 ***      pgscir      ***
 ************************/
        case 97:
            cpgscir(la[0], la[1]);
            break;

/************************
 ***      pgsclp      ***
 ************************/
        case 98:
            cpgsclp(la[0]);
            break;

/************************
 ***      pgscr       ***
 ************************/
        case 99:
            cpgscr(la[0], fa[1], fa[2], fa[3]);
            break;

/************************
 ***      pgscrl      ***
 ************************/
        case 100:
            cpgscrl(fa[0], fa[1]);
            break;

/************************
 ***      pgscrn      ***
 ************************/
        case 101: {
            int i = 0;
            cpgscrn(la[0], arg[1].svalue->c_str(), &i);
            }
            break;

/************************
 ***      pgsfs       ***
 ************************/
        case 102:
            cpgsfs(la[0]);
            break;

/************************
 ***      pgshls      ***
 ************************/
        case 103:
            cpgshls(la[0], fa[1], fa[2], fa[3]);
            break;

/************************
 ***      pgshs       ***
 ************************/
        case 104:
            cpgshs(fa[0], fa[1], fa[2]);
            break;

/************************
 ***      pgsitf      ***
 ************************/
        case 105:
            cpgsitf(la[0]);
            break;

/************************
 ***      pgslct      ***
 ************************/
        case 106:
            cpgslct(la[0]);
            break;

/************************
 ***      pgsls       ***
 ************************/
        case 107:
            cpgsls(la[0]);
            break;

/************************
 ***      pgslw       ***
 ************************/
        case 108:
            cpgslw(la[0]);
            break;

/************************
 ***      pgstbg      ***
 ************************/
        case 109:
            cpgstbg(la[0]);
            break;

/************************
 ***      pgsubp      ***
 ************************/
        case 110:
            cpgsubp(la[0], la[1]);
            break;

/************************
 ***      pgsvp       ***
 ************************/
        case 111:
            cpgsvp(fa[0], fa[1], fa[2], fa[3]);
            break;

/************************
 ***      pgswin      ***
 ************************/
        case 112:
            cpgswin(fa[0], fa[1], fa[2], fa[3]);
            break;

/************************
 ***      pgtbox      ***
 ************************/
        case 113:
            cpgtbox(arg[0].svalue->c_str(), fa[1], la[2], arg[3].svalue->c_str(), fa[4], la[5]);
            break;

/************************
 ***      pgtext      ***
 ************************/
        case 114:
            cpgtext(fa[0], fa[1], arg[2].svalue->c_str());
            break;

/************************
 ***      pgtick      ***
 ************************/
        case 115:
            cpgtick(fa[0], fa[1], fa[2], fa[3], fa[4], fa[5], fa[6], fa[7], fa[8], arg[9].svalue->c_str());
            break;

/************************
 ***      pgupdt      ***
 ************************/
        case 116:
            cpgupdt();
            break;

/************************
 ***      pgvect      ***
 ************************/
        case 117:
            if ((arg[0].fvalue->Naxis(1) != arg[1].fvalue->Naxis(1)) ||
                (arg[0].fvalue->Naxis(2) != arg[1].fvalue->Naxis(2)) ||
                (la[2] != arg[0].fvalue->Naxis(1)) ||
                (la[2] != arg[0].fvalue->Naxis(1))) {
                dp_output("pgvect: Inconsistent array sizes\n");
                break;
            }
            if (arg[10].fvalue->Nelements() != 6) {
                dp_output("pgvect: Transformation matrix must have exactly 6 elements\n");
                break;
            }
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[10].fvalue);
            if (data1 && data2 && data3)
                cpgvect(data1, data2, la[2], la[3], la[4], la[5], la[6], la[7], fa[8], la[9], data3, fa[11]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[10].fvalue->r4data)) free(data3);
            break;

/************************
 ***      pgvport     ***
 ************************/
        case 118:
            cpgsvp(fa[0], fa[1], fa[2], fa[3]);
            break;

/************************
 ***      pgvsize     ***
 ************************/
        case 119:
            cpgvsiz(fa[0], fa[1], fa[2], fa[3]);
            break;

/************************
 ***      pgvsiz      ***
 ************************/
        case 120:
            cpgvsiz(fa[0], fa[1], fa[2], fa[3]);
            break;

/************************
 ***     pgvstand     ***
 ************************/
        case 121:
            cpgvstd();
            break;

/************************
 ***      pgvstd      ***
 ************************/
        case 122:
            cpgvstd();
            break;

/************************
 ***      pgwedg      ***
 ************************/
        case 123:
            cpgwedg(arg[0].svalue->c_str(), fa[1], fa[2], fa[3], fa[4], arg[5].svalue->c_str());
            break;

/************************
 ***     pgwindow     ***
 ************************/
        case 124:
            cpgswin(fa[0], fa[1], fa[2], fa[3]);
            break;

/************************
 ***      pgwnad      ***
 ************************/
        case 125:
            cpgwnad(fa[0], fa[1], fa[2], fa[3]);
            break;
#endif /* HAS_PGPLOT */

/************************
 ***    writefits     ***
 ************************/
        case 126:
            if (arg[1].type == typeDpArr) {
                if (arg[1].dparrvalue->at(0)->type == typeFits) {
                    arg[1].dparrvalue->at(0)->fvalue->WriteFITS(arg[0].svalue->c_str());
                    for (int i = 1; i < arg[1].dparrvalue->size(); i++) {
                        if (arg[1].dparrvalue->at(i)->type == typeFits) {
                            arg[1].dparrvalue->at(i)->fvalue->WriteFITSExtension(arg[0].svalue->c_str());
                        }
                    }
                }
            } else {
                if (procedure_options & 1) {
                    arg[1].fvalue->WriteFITSExtension(arg[0].svalue->c_str());
                } else {
                    arg[1].fvalue->WriteFITS(arg[0].svalue->c_str());
                }
            }
            updateQFitsViewTitle(&arg[1]);

            break;

#ifdef HAS_PGPLOT

/************************
 ***      contour     ***
 ************************/
        case 127:
            contour(arg[0].fvalue, arg[1].fvalue);
            break;

/************************
 ***      display     ***
 ************************/
        case 128:
            if (nargs == 1) graymap(arg[0].fvalue, 0.0, 0.0, dpuser_vars["method"].toInt());
            else graymap(arg[0].fvalue, fa[1], fa[2], dpuser_vars["method"].toInt());
            break;
#endif /* HAS_PGPLOT */

/************************
 ***       exec       ***
 ************************/
        case 129:
#ifdef DPQT
        {
            std::shared_ptr<FILE> pipe(popen(arg[0].svalue->c_str(), "r"), pclose);
            if (pipe) {
                char buffer[128];
                std::string output = "";
                while (!feof(pipe.get())) {
                    if (fgets(buffer, 128, pipe.get()) != NULL) {
                        output += buffer;
                    }
                }
                dp_output("%s", output.c_str());
            }
        }
#else
            system(arg[0].svalue->c_str());
#endif /* DPQT */
            break;

/************************
 ***      sleep       ***
 ************************/
        case 130:
            if (la[0] > 0) {
#ifdef WIN
            Sleep(la[0]*1000);
#else
            sleep(la[0]);
#endif
            }
            break;
#ifdef HAS_PGPLOT

/************************
 ***      spec3d      ***
 ************************/
        case 131: {
            Fits data, _tmp;

            data.create(arg[0].fvalue->Naxis(3), 1);
            for (int i = 1; i <= arg[0].fvalue->Naxis(3); i++) {
                arg[0].fvalue->extractRange(_tmp, -1, -1, -1, -1, i, i);
                _tmp *= *arg[1].fvalue;
                data.r4data[i] = (float)_tmp.get_avg();
            }
            plot(NULL, &data, 0.0, 0.0, 0, 0);
            }
            break;
#endif /* HAS_PGPLOT */

/************************
 ***      print       ***
 ************************/
        case 132: {
            for (int i = 0; i < nargs; i++) {
                print(arg[i], procedure_options);
            }
            }
            break;

/************************
 ***       mem        ***
 ************************/
        case 133:
            mem();
            break;
#ifdef HAS_PGPLOT

/************************
 ***       plot       ***
 ************************/
        case 134: {
            int method = 0;
            int closeorcontinue = 0;

            if (dpuser_vars["method"].toInt() != 0) {
                method = dpuser_vars["method"].toInt();
            } else {
                if (procedure_options & 1) method += 10;
                if (procedure_options & 2) method += 20;
            }
            closeorcontinue = procedure_options;
            if (nargs > 1) {
                if (arg[1].type == typeFits) {
                    if (nargs == 4) plot(arg[0].fvalue, arg[1].fvalue, fa[2], fa[3], method, closeorcontinue);
                    else plot(arg[0].fvalue, arg[1].fvalue, 0.0, 0.0, method, closeorcontinue);
                } else {
                    if (nargs == 3) plot(NULL, arg[0].fvalue, fa[1], fa[2], method, closeorcontinue);
                    else plot(NULL, arg[1].fvalue, 0.0, 0.0, method, closeorcontinue);
                }
            } else plot(NULL, arg[0].fvalue, 0.0, 0.0, method, closeorcontinue);
            }
            break;
#endif /* HAS_PGPLOT */

/************************
 ***       free       ***
 ************************/
        case 135:
            if (nargs == 0) {
#ifdef DPQT
                // Lock QFitsView buffer
                for (auto var:dpuser_vars) {
                    if (var.first != "buffer1") {
                        if (fitsMainWindow) {
                            dpuser_vars[var.first].type = typeCon;
                            dpUpdateVar(var.first);
                        }
//                        dpuser_vars.erase(var.first);
                    }
                }
                dpuserType buffer1 = dpuser_vars["buffer1"];
                dpuser_vars.clear();
                dpuser_vars["buffer1"] = buffer1;
                dpUpdateVar("buffer1");
#else /* !DPQT */
                dpuser_vars.clear();
#endif /* DPQT */
                createGlobalVariables();
            } else {
                std::string varname = (dynamic_cast<variableNode *>(args.at(0)))->id;
#ifdef DPQT
                // Lock QFitsView buffer
                if (varname != "buffer1") {
                    if (fitsMainWindow) {
                        dpuser_vars[varname].type = typeCon;
                        dpUpdateVar(varname);
                    }
                    dpuser_vars.erase(varname);
                }
#else /* !DPQT */
                dpuser_vars.erase(varname);
#endif /* DPQT */
                nargs = 0; // to prevent re-creation of the variable
            }
        break;
#if 0
#ifdef DPQT
            int buffer1 = -1;

            for (int i = 0; i < nvariables; i++) {
                if (svariables[i] == "buffer1") {
                    buffer1 = i;
                }
            }
#endif /* DPQT */

            if (nargs == 1) {
                int which = la[0];

                if ((which > nglobals) && (svariables[which] != "buffer1")) {
#ifdef DPQT
                    // Lock QFitsView buffer
                    if (fitsMainWindow) {
                        variables[which].type = typeCon;
                        dpUpdateVar(which);
                    }
#endif /* DPQT */
                    svariables[which] = "";
                    variables[which].cvalue = NULL;
                    variables[which].svalue = NULL;
                    variables[which].fvalue = NULL;
                    variables[which].ffvalue = NULL;
                    variables[which].arrvalue = NULL;
                    variables[which].dparrvalue = NULL;
                    variables[which].type = typeUnknown;
                }
            } else {
                for (int i = nglobals; i < nvariables; i++) {
                    if (svariables[i] != "buffer1") {
#ifdef DPQT
                        // Lock QFitsView buffer
                        if (fitsMainWindow) {
                            variables[i].type = typeCon;
                            dpUpdateVar(i);
                        }
#endif /* DPQT */
                        svariables[i] = "";
                        variables[i].cvalue = NULL;
                        variables[i].svalue = NULL;
                        variables[i].fvalue = NULL;
                        variables[i].ffvalue = NULL;
                        variables[i].arrvalue = NULL;
                        variables[i].dparrvalue = NULL;
                        variables[i].type = typeUnknown;
                    }
                }
#ifdef DPQT
                dpUpdateVar(buffer1);
#endif /* DPQT */
            }
            }
            break;
#endif
/************************
 ***        sao       ***
 ************************/
        case 136:
            if (ds9_running() == 0) {
                dp_output("ERROR: No ds9 is running! Please start first ds9 (at least v5.2)\n");
                success = false;
            }
            if (xpa == NULL) {
                if ((xpa = XPAOpen(NULL)) == NULL) {
                    dp_output("Can't open socket to image display server.");
                    success = false;
                }
            }

            if (success) {
                int nx = 0, ny = 0, ret = 0;
                char *names[NXPA];
                char *messages[NXPA];

                nx = arg[0].fvalue->Naxis(1);
                ny = arg[0].fvalue->Naxis(2);

                dpString accessPoint = "array [xdim=" + dpString::number(nx) +
                                       ",ydim=" + dpString::number(ny) +
                                       ",bitpix=" + dpString::number(arg[0].fvalue->membits) + "]";

                ret = XPASet(xpa, xpaServer, (char*)accessPoint.c_str(), NULL,
                             (char*)arg[0].fvalue->dataptr, nx * ny * (abs(arg[0].fvalue->membits) / 8),
                             names, messages, NXPA);

                if (procedure_options & 1) {
                    ret = XPASet(xpa, xpaServer, (char *)"scale log", NULL,
                                 NULL, 0, names, messages, NXPA);
                } else {
                    ret = XPASet(xpa, xpaServer, (char *)"scale linear", NULL,
                                 NULL, 0, names, messages, NXPA);
                }

                if (procedure_options & 2) {
                    ret = XPASet(xpa, xpaServer, (char *)"scale zscale", NULL,
                                 NULL, 0, names, messages, NXPA);
                    if (nargs == 3) dp_output(">>> min/max-values have been omitted, since zscale-option has been specified!\n");
                } else {
                    if (nargs == 3) {
                        accessPoint = "scale limits "  + dpString::number(arg[1].toDouble()) + " " + dpString::number(arg[2].toDouble());
                        ret = XPASet(xpa, xpaServer, (char*)accessPoint.c_str(), NULL,
                                 NULL, 0, names, messages, NXPA);
                    } else {
                        ret = XPASet(xpa, xpaServer, (char *)"scale minmax", NULL,
                                     NULL, 0, names, messages, NXPA);
                    }
                }

                /* error processing */
                for(int i = 0; i < ret; i++){
                    if(messages[i]) {
                        dp_output("ERROR: %s (%s)\n", messages[i], names[i]);
                    }
                    if(names[i]) {
                        free(names[i]);
                    }
                    if(messages[i]) {
                        free(messages[i]);
                    }
                }
            }
        break;

/************************
 ***      shift       ***
 ************************/
        case 137: {
            bool fs = TRUE;

            if (nargs == 3) {
                if ((fa[1] == (double)(int)fa[1]) &&
                    (fa[2] == (double)(int)fa[2])) {
                    fs = FALSE;
                }
            } else {
                if ((fa[1] == (double)(int)fa[1]) &&
                    (fa[2] == (double)(int)fa[2]) &&
                    (fa[3] == (double)(int)fa[3])) {
                    fs = FALSE;
                }
            }
            if (fs) {
                if (nargs == 3) {
                    // sub-pixel shift
                    int method = 0;

                    if (procedure_options & 2) method = 0; // linear
                    else if (procedure_options & 4) method = 1; // fft
                    else if (procedure_options & 8) method = 3; // poly3
                    pgVariables[0].fvalue->fshift(fa[1], fa[2], method);
                } else {
                    pgVariables[0].fvalue->fshift(fa[1], fa[2], (int)fa[3]);
                }
            } else {
                int x, y, z = 0;

                x = (int)fa[1];
                y = (int)fa[2];
                if (nargs == 4) {
                    z = (int)fa[3];
                }
                if (procedure_options == 1) {
                    pgVariables[0].fvalue->wrap(x, y, z);
                } else {
                    pgVariables[0].fvalue->ishift(x, y, z);
                }
            }
        }
        break;

/************************
 ***      center      ***
 ************************/
        case 138: {
            int x, y;

            pgVariables[0].fvalue->max_pos(&x, &y);
            pgVariables[0].fvalue->shift(pgVariables[0].fvalue->Naxis(1) / 2 + 1 - x, pgVariables[0].fvalue->Naxis(2) / 2 + 1 - y, 2);
            }
            break;

/************************
 ***     centroid     ***
 ************************/
        case 139: {
            double x, y, z;

            arg[0].fvalue->centroid(&x, &y, &z);
            SETDBLVARIABLE(1,x);
            if (nargs > 2) {
                SETDBLVARIABLE(2,y);
            }
            if (nargs == 4) {
                SETDBLVARIABLE(3,z);
            }
//            variables[la[1]].type = typeDbl;
//            variables[la[1]].dvalue = x;
//            if (nargs > 2) {
//                variables[la[2]].type = typeDbl;
//                variables[la[2]].dvalue = y;
//            }
//            if (nargs == 4) {
//                variables[la[3]].type = typeDbl;
//                variables[la[3]].dvalue = z;
//            }
            }
            break;

/************************
 ***      upper       ***
 ************************/
        case 140:
            pgVariables[0].svalue = CreateString(pgVariables[0].svalue->upper());
            break;

/************************
 ***      lower       ***
 ************************/
        case 141:
            pgVariables[0].svalue = CreateString(pgVariables[0].svalue->lower());
            break;

/************************
 ***      rotate      ***
 ************************/
        case 142:
            if (nargs == 2) pgVariables[0].fvalue->rotate(fa[1]);
            else if (nargs == 3) pgVariables[0].fvalue->rotate(fa[1], fa[2]);
            else pgVariables[0].fvalue->rotate(fa[1], fa[2], fa[3]);
            break;

/************************
 ***        fft       ***
 ************************/
        case 143:
            pgVariables[0].fvalue->fft();
            break;

/************************
 ***      reass       ***
 ************************/
        case 144:
            pgVariables[0].fvalue->reass();
            break;

/************************
 ***       norm       ***
 ************************/
        case 145:
            if (procedure_options & 2) pgVariables[0].fvalue->norf(0);
            else if (procedure_options & 4) pgVariables[0].fvalue->norf(1);
            else pgVariables[0].fvalue->norm();
            break;

/************************
 ***       clip       ***
 ************************/
        case 146:
            if (nargs == 3) pgVariables[0].fvalue->clip(fa[1], fa[2]);
            else pgVariables[0].fvalue->inclip(fa[1], fa[2], fa[3]);
            break;

/************************
 ***      smooth      ***
 ************************/
        case 147:
            if ((procedure_options & 2) && (pgVariables[0].fvalue->Naxis(3) > 1)) {
                pgVariables[0].fvalue->smooth1d(fa[1], 3);
            } else if (procedure_options & 4) {
                pgVariables[0].fvalue->smooth1d(fa[1], 1);
            } else if (procedure_options & 8) {
                pgVariables[0].fvalue->smooth1d(fa[1], 2);
            } else {
                pgVariables[0].fvalue->smooth(fa[1]);
            }
            break;

/************************
 ***      boxcar      ***
 ************************/
        case 148: {
                int method = 0, method2 = 0;
                if (procedure_options & 2) method = 1;
                else if (procedure_options & 4) method = 2;
                else if (procedure_options & 8) method = 3;

                if (procedure_options & 32) method2 = 1;
                else if (procedure_options & 64) method2 = 2;
                else if (procedure_options & 128) method2 = 3;

                Boxcar(*pgVariables[0].fvalue, la[1], method, method2);
            }
            break;

/************************
 ***     3dexpand     ***
 ************************/
        case 153: expandCal3d(*pgVariables[0].fvalue);
            break;

/************************
 ***     flip         ***
 ************************/
        case 154: pgVariables[0].fvalue->flip(la[1]);
            break;

/************************
 ***     enlarge      ***
 ************************/
        case 155:
            if (nargs == 2) pgVariables[0].fvalue->enlarge(la[1]);
            else pgVariables[0].fvalue->enlarge(la[1], la[2]);
            break;

/************************
 ***     resize       ***
 ************************/
        case 156:
            if (nargs == 3) pgVariables[0].fvalue->resize(la[1], la[2]);
            else pgVariables[0].fvalue->resize(la[1], la[2], la[3]);
            break;

/************************
 ***     wien     ***
 ************************/
        case 157:
            if (nargs == 2) pgVariables[0].fvalue->wien(*arg[1].fvalue);
            else pgVariables[0].fvalue->wien(*arg[1].fvalue, fa[2]);
            break;

/************************
 ***     lucy     ***
 ************************/
        case 158:
            if (nargs == 3) pgVariables[0].fvalue->lucy(*arg[1].fvalue, la[2]);
            else pgVariables[0].fvalue->lucy(*arg[1].fvalue, la[2], fa[3]);
            break;

/************************
 ***     3dnorm       ***
 ************************/
        case 159:
            norm3d(*pgVariables[0].fvalue, arg[1].svalue->c_str());
            break;

/************************
 ***     correl       ***
 ************************/
        case 160:
            pgVariables[0].fvalue->correl(*arg[1].fvalue);
            break;

/************************
 ***     rebin        ***
 ************************/
        case 161:
            if (nargs == 3) pgVariables[0].fvalue->rebin(la[1], la[2]);
            else pgVariables[0].fvalue->rebin(la[1], la[2], la[3]);
            break;

/************************
 ***     ssaplot     ***
 ************************/
#ifdef HAS_PGPLOT
        case 162: {
            Fits *data = arg[0].fvalue;
            float min, max, d, *xaxis, *yaxis;

            if (cpgbeg(0, dpuser_vars["plotdevice"].toString().c_str(), 1, 4) != 1) {
                break;
            }
            xaxis = (float *)malloc(data->Naxis(2) * sizeof(float));
            yaxis = (float *)malloc(data->Naxis(2) * sizeof(float));
            for (int i = 1; i <= data->Naxis(2); i++) {
                xaxis[i - 1] = (float)i;
            }
            for (int i = 3; i <= 6; i++) {
                min = max = (float)data->ValueAt(data->F_I(i, 1));
                for (int j = 1; j <= data->Naxis(2); j++) {
                    d = (float)data->ValueAt(data->F_I(i, j));
                    if (d < min) min = d;
                    else if (d > max) max = d;
                    yaxis[j - 1] = d;
                }
                cpgenv(1.0, (float)data->Naxis(2), min, max, 0, 0);
                switch (i) {
                    case 3: cpglab("Image Number", "Minimum", "");
                        if (nargs == 2) {
                            cpgsch(2.0);
                            cpgmtxt("T", 1, 0.5, 0.5, arg[1].svalue->c_str());
                            cpgsch(1.0);
                        }
                        break;
                    case 4: cpglab("Image Number", "Maximum", ""); break;
                    case 5: cpglab("Image Number", "Flux", ""); break;
                    case 6: cpglab("Image Number", "Seeing [Pixels]", ""); break;
                    default: break;
                }
                cpgslw(3);
                cpgpt(data->Naxis(2), xaxis, yaxis, -1);
                cpgslw(1);
            }
//          cpgend();
            free(xaxis);
            free(yaxis);
            }
            break;

/************************
 ***     freddy       ***
 ************************/
#ifdef HAS_DPPGPLOT
        case 163: {
            Fits *data;

            if (isVariable(arg[0].fvalue) == 1) {
                data = CreateFits();
                if (!data->copy(*arg[0].fvalue)) break;
            } else {
                data = arg[0].fvalue;
            }
            if (!data->setType(R4)) break;
            cfreddy(data->r4data, la[1], la[2], fa[3], fa[4]);
            }
            break;

/************************
 ***     surface     ***
 ************************/
        case 164:
            if (nargs != 3) la[2] = 1;
            surface(arg[0].fvalue, fa[1], la[2]);
            break;
#endif /* HAS_DPPGPLOT */

#ifdef HAS_PGPLOT
/************************
 ***     imexa     ***
 ************************/
        case 165:
            if (ds9_running() == 0) {
                dp_output("ERROR: No ds9 is running! Please start first ds9 (at least v5.2)\n");
                success = false;
            }
            if (xpa == NULL) {
                if ((xpa = XPAOpen(NULL)) == NULL) {
                    dp_output("Can't open socket to image display server.");
                    success = false;
                }
            }
            if (success) {
                int nx, ny, x, y, ret, pos;
                dpString key, tmp;
                float *pix = NULL;
                size_t lens[NXPA];
                char *bufs[NXPA];
                char *names[NXPA];
                char *messages[NXPA];

                nx = arg[0].fvalue->Naxis(1);
                ny = arg[0].fvalue->Naxis(2);

                if ((pix = (float *)malloc(arg[0].fvalue->Nelements() * sizeof(float))) == NULL) {
                    dp_output("Failed allocating memory");
                    success = false;
                }
                if (success) {
                    float *data1 = floatdata(*arg[0].fvalue);
                    if (data1) {
                        memcpy(pix, data1, arg[0].fvalue->Nelements() * sizeof(float));
                    } else {
                        free(pix);
                        dp_output("Failed copying memory");
                        success = false;
                    }
                }

                if (success) {
                    if (data1 && (data1 != arg[0].fvalue->r4data))
                        free(data1);

                    // display fits
                    dpString accessPoint = "array [xdim=" + dpString::number(nx) +
                                           ",ydim=" + dpString::number(ny) +
                                           ",bitpix=-32]";

                    ret = XPASet(xpa, xpaServer, (char*)accessPoint.c_str(), NULL,
                                 (char*)pix, nx * ny * (abs(arg[0].fvalue->membits) / 8),
                                 names, messages, NXPA);

                    /* error processing */
                    for(int i = 0; i < ret; i++){
                        if(messages[i]) {
                            dp_output("ERROR: %s (%s)\n", messages[i], names[i]);
                        }
                        if(names[i]) {
                            free(names[i]);
                        }
                        if(messages[i]) {
                            free(messages[i]);
                        }
                    }

                    dpString sp = dpString(" ");
                    key = "t";

                    while ((key.compare("q")) && (xpa != NULL)) {
                        ret = XPAGet(xpa, xpaServer, "imexam key coordinate image", NULL,
                                     bufs, lens, names, messages, NXPA);

                        if( messages[0] == NULL ){
                            /* extract key and x/y-positions */
                            tmp = bufs[0];
                            tmp = tmp.stripWhiteSpace();
                            pos = tmp.strpos(sp, false);
                            key = tmp.left(pos);
                            tmp.remove(0,pos);
                            tmp = tmp.stripWhiteSpace();
                            x = atoi(tmp.left(tmp.strpos(sp, false)).c_str());
                            y = atoi(tmp.right(tmp.length() - tmp.strpos(sp, false)).c_str());
                            free(bufs[0]);

                            if (key != "q") {
                                if ((key == "c") || (key == "s")) {
                                    int i, j, ii, jj;
                                    Fits *data = CreateFits();

                                    if (data->create(imexasize*2+1, imexasize*2+1)) {
                                        for (i = x-imexasize, ii = 1; i <= x+imexasize; i++, ii++) {
                                            for (j = y-imexasize, jj = 1; j <= y+imexasize; j++, jj++) {
                                                if ((i > 0) && (i <= nx) && (j > 0) && (j <= ny)) {
                                                    data->r4data[data->F_I(ii, jj)] = arg[0].fvalue->ValueAt((i-1) + (j-1)*nx);
                                                } else {
                                                    data->r4data[data->F_I(ii, jj)] = 0.0;
                                                }
                                            }
                                        }
                                    }
                                    if (key == "s") {
        #ifdef HAS_DPPGPLOT
                                        surface(data, 30.0, 1);
        #endif /* HAS_DPPGPLOT */
                                    } else if (key == "c") {
                                        Fits *levels = CreateFits();
                                        levels->create(9, 1);
                                        for (i = 1; i < 10; i++) {
                                            levels->setValue(i * 10.0, i, 1);
                                        }
                                        contour(data, levels);
                                    }
                                } else if (key == "h") {
                                    Fits *data = CreateFits();
                                    int i, ii;

                                    if (data->create(imexasize*2+1, 1)) {
                                        for (i = x-imexasize, ii = 1; i <= x+imexasize; i++, ii++) {
                                            if ((i > 0) && (i <= nx)) {
                                                data->r4data[data->F_I(ii, 1)] = arg[0].fvalue->ValueAt((i-1) + (y-1)*nx);
                                            } else {
                                                data->r4data[data->F_I(ii, 1)] = 0.0;
                                            }
                                        }
                                        plot(NULL, data, 0.0, 0.0, 0, 0);
                                    }
                                } else if (key == "v") {
                                    Fits *data = CreateFits();
                                    int i, ii;

                                    if (data->create(imexasize*2+1, 1)) {
                                        for (i = y-imexasize, ii = 1; i <= y+imexasize; i++, ii++) {
                                            if ((i > 0) && (i <= ny)) {
                                                data->r4data[data->F_I(ii, 1)] = arg[0].fvalue->ValueAt((x-1) + (i-1)*nx);
                                            } else {
                                                data->r4data[data->F_I(ii, 1)] = 0.0;
                                            }
                                        }
                                        plot(NULL, data, 0.0, 0.0, 0, 0);
                                    }
                                } else if (key == "i") {
                                    if (imexasize < nx/2)
                                        imexasize++;
                                } else if (key == "d") {
                                    if (imexasize > 1)
                                        imexasize--;
                                } else if (key == "r") {
                                    radialplot(arg[0].fvalue, x, y, imexasize, 5);
                                }
                            }
                            dp_output("%s [%d %d]\n", key.c_str(), x, y);
                        } else {
                                /* error processing */
                            dp_output("ERROR: %s (%s)\n", messages[0], names[0]);
                        }
                        if(names[0])
                            free(names[0]);
                        if(messages[0])
                            free(messages[0]);
                    }
                }
            }
            break;

#endif /* HAS_PGPLOT */

/************************
 ***     sbfint       ***
 ************************/
#ifdef HAS_DPPGPLOT
        case 166: {
            int maxbuf;

            data1 = floatdata(*arg[0].fvalue);
            if (data1)
                csbfint(data1, la[1], la[2], la[3], &maxbuf);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            SETINTVARIABLE(4,maxbuf);
            }
            break;

/************************
 ***     sbfbkg       ***
 ************************/
        case 167: csbfbkg(la[0], la[1], la[2]);
            break;

/************************
 ***     sbfsav       ***
 ************************/
        case 168: csbfsav(la[0]);
            break;

/************************
 ***     sbfcls       ***
 ************************/
        case 169: csbfcls(la[0]);
            break;

/************************
 ***     colint       ***
 ************************/
        case 170:
            data1 = floatdata(*arg[0].fvalue);
            if (data1)
                ccolint(data1, la[1], la[2], fa[3], fa[4], fa[5]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            break;

/************************
 ***     coltab       ***
 ************************/
        case 171:
            data1 = floatdata(*arg[0].fvalue);
            if (data1)
                ccoltab(data1, la[1], fa[2], la[3], la[4]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            break;

/************************
 ***     colsrf       ***
 ************************/
        case 172:
            data1 = floatdata(*arg[0].fvalue);
            if (data1)
                ccolsrf(data1, la[1], fa[2], la[3], la[4], la[5], fa[6], fa[7], fa[8]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            break;

/************************
 ***     sbball       ***
 ************************/
        case 173: {
            float x0, y0, r0;

            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[5].fvalue);
            if (data1 && data2 && data3)
                csbball(data1, data2, fa[2], la[3], la[4], data3, la[6], &x0, &y0, &r0);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[5].fvalue->r4data)) free(data3);
            SETDBLVARIABLE(7,x0);
            SETDBLVARIABLE(8,y0);
            SETDBLVARIABLE(9,r0);
//            variables[la[7]].type = typeDbl;
//            variables[la[7]].dvalue = (double)x0;
//            variables[la[8]].type = typeDbl;
//            variables[la[8]].dvalue = (double)y0;
//            variables[la[9]].type = typeDbl;
//            variables[la[9]].dvalue = (double)r0;
            }
            break;

/************************
 ***     sbtbal       ***
 ************************/
        case 174: {
            float x0, y0, r0;

            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[5].fvalue);
            if (data1 && data2 && data3)
                csbtbal(data1, data2, fa[2], la[3], la[4], data3, la[6], &x0, &y0, &r0, la[10]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[5].fvalue->r4data)) free(data3);
            SETDBLVARIABLE(7,x0);
            SETDBLVARIABLE(8,y0);
            SETDBLVARIABLE(9,r0);
//            variables[la[7]].type = typeDbl;
//            variables[la[7]].dvalue = (double)x0;
//            variables[la[8]].type = typeDbl;
//            variables[la[8]].dvalue = (double)y0;
//            variables[la[9]].type = typeDbl;
//            variables[la[9]].dvalue = (double)r0;
            }
            break;

/************************
 ***     sbplan       ***
 ************************/
        case 175:
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[2].fvalue);
            data3 = floatdata(*arg[5].fvalue);
            if (data1 && data2 && data3)
                csbplan(data1, fa[1], data2, la[3], la[4], data3);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[2].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[5].fvalue->r4data)) free(data3);
            break;

/************************
 ***     sbplnt     ***
 ************************/
        case 176:
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[2].fvalue);
            data3 = floatdata(*arg[5].fvalue);
            if (data1 && data2 && data3)
                csbplnt(data1, fa[1], data2, la[3], la[4], data3, la[6]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[2].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[5].fvalue->r4data)) free(data3);
            break;

/************************
 ***     sbrod        ***
 ************************/
        case 177:
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[2].fvalue);
            data4 = floatdata(*arg[6].fvalue);
            if (data1 && data2 && data3 && data4)
                csbrod(data1, data2, data3, fa[3], la[4], la[5], data4, la[7], la[8]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[2].fvalue->r4data)) free(data3);
            if (data4 && (data4 != arg[6].fvalue->r4data)) free(data4);
            break;

/************************
 ***     sbcone       ***
 ************************/
        case 178:
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[2].fvalue);
            data4 = floatdata(*arg[6].fvalue);
            if (data1 && data2 && data3 && data4)
                csbcone(data1, data2, data3, fa[3], la[4], la[5], data4, la[7]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[2].fvalue->r4data)) free(data3);
            if (data4 && (data4 != arg[6].fvalue->r4data)) free(data4);
            break;

/************************
 ***     sbelip       ***
 ************************/
        case 179: {
            float x0, y0, r0;

            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[2].fvalue);
            data4 = floatdata(*arg[5].fvalue);
            if (data1 && data2 && data3 && data4)
                csbelip(data1, data2, data3, la[3], la[4], data4, la[6], la[7], fa[8], &x0, &y0, &r0);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[2].fvalue->r4data)) free(data3);
            if (data4 && (data4 != arg[5].fvalue->r4data)) free(data4);
            SETDBLVARIABLE(9,x0);
            SETDBLVARIABLE(10,y0);
            SETDBLVARIABLE(11,r0);
//            variables[la[9]].type = typeDbl;
//            variables[la[9]].dvalue = (double)x0;
//            variables[la[10]].type = typeDbl;
//            variables[la[10]].dvalue = (double)y0;
//            variables[la[11]].type = typeDbl;
//            variables[la[11]].dvalue = (double)r0;
            }
            break;

/************************
 ***     sbline     ***
 ************************/
        case 180:
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[2].fvalue);
            if (data1 && data2 && data3)
                csbline(data1, data2, data3, la[3], la[4]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[2].fvalue->r4data)) free(data3);
            break;

/************************
 ***     sbtext     ***
 ************************/
        case 181:
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[3].fvalue);
            data3 = floatdata(*arg[5].fvalue);
            if (data1 && data2 && data3)
                csbtext(data1, arg[1].svalue->c_str(), la[2], data2, fa[4], data3, fa[6]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[3].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[5].fvalue->r4data)) free(data3);
            break;

/************************
 ***     sbsurf     ***
 ************************/

        case 182: {
            Fits *data;

            if (isVariable(arg[2].fvalue) == 1) {
                data = CreateFits();
                if (!data->copy(*arg[2].fvalue)) break;
            } else {
                data = arg[2].fvalue;
            }
            if (!data->setType(R4)) break;
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[9].fvalue);
            if (data1 && data2 && data3)
                csbsurf(data1, data2, data->r4data, la[3], la[4], la[5], fa[6], la[7], la[8], data3, la[10]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[9].fvalue->r4data)) free(data3);
            }
            break;

/************************
 ***     sbtsur       ***
 ************************/
        case 183: {
            Fits *data;

            if (isVariable(arg[2].fvalue) == 1) {
                data = CreateFits();
                if (!data->copy(*arg[2].fvalue)) break;
            } else {
                data = arg[2].fvalue;
            }
            if (!data->setType(R4)) break;
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[9].fvalue);
            if (data1 && data2 && data3)
                csbtsur(data1, data2, data->r4data, la[3], la[4], la[5], fa[6], la[7], la[8], data3, la[10], la[11]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[9].fvalue->r4data)) free(data3);
            }
            break;

/************************
 ***     sbslic       ***
 ************************/
        case 184: {
            Fits *data;

            if (isVariable(arg[2].fvalue) == 1) {
                data = CreateFits();
                if (!data->copy(*arg[2].fvalue)) break;
            } else {
                data = arg[2].fvalue;
            }
            if (!data->setType(R4)) break;
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[10].fvalue);
            data4 = floatdata(*arg[11].fvalue);
            if (data1 && data2 && data3 && data4)
                csbslic(data1, data2, data->r4data, la[3], la[4], la[5], fa[6], fa[7], la[8], la[9], data3, data4, la[12]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[10].fvalue->r4data)) free(data3);
            if (data4 && (data4 != arg[11].fvalue->r4data)) free(data4);
            }
            break;

/************************
 ***     sbcpln       ***
 ************************/
        case 185:
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[4].fvalue);
            data4 = floatdata(*arg[5].fvalue);
            data5 = floatdata(*arg[6].fvalue);
            if (data1 && data2 && data3 && data4 && data5)
                csbcpln(data1, data2, la[2], la[3], data3, data4, data5, la[7], la[8]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[4].fvalue->r4data)) free(data3);
            if (data4 && (data4 != arg[5].fvalue->r4data)) free(data4);
            if (data5 && (data5 != arg[6].fvalue->r4data)) free(data5);
            break;

/************************
 ***     sb2srf       ***
 ************************/
        case 186: {
            Fits *data;

            if (isVariable(arg[2].fvalue) == 1) {
                data = CreateFits();
                if (!data->copy(*arg[2].fvalue)) break;
            } else {
                data = arg[2].fvalue;
            }
            if (!data->setType(R4)) break;
            data1 = floatdata(*arg[0].fvalue);
            data2 = floatdata(*arg[1].fvalue);
            data3 = floatdata(*arg[11].fvalue);
            if (data1 && data2 && data3)
                csb2srf(data1, data2, data->r4data, la[3], la[4], fa[5], fa[6], fa[7], la[8], la[9], la[10], data3, la[12]);
            if (data1 && (data1 != arg[0].fvalue->r4data)) free(data1);
            if (data2 && (data2 != arg[1].fvalue->r4data)) free(data2);
            if (data3 && (data3 != arg[11].fvalue->r4data)) free(data3);
            }
            break;
#endif /* HAS_DPPGPLOT */

/************************
 ***     radialplot   ***
 ************************/
        case 187: radialplot(arg[0].fvalue, la[1], la[2], la[3], 0);
            break;

#endif /* HAS_PGPLOT */

/************************
 ***     setfitskey   ***
 ************************/
        case 188: {
            char *comment = NULL;

            pgVariables[0].fvalue->updateHeader();
            if (nargs == 4) comment = (char *)arg[3].svalue->c_str();
            switch (arg[2].type) {
                case typeCon: pgVariables[0].fvalue->SetIntKey(arg[1].svalue->c_str(), la[2], comment);
                    break;
                case typeDbl: pgVariables[0].fvalue->SetFloatKey(arg[1].svalue->c_str(), fa[2], comment);
                    break;
                case typeStr: pgVariables[0].fvalue->SetStringKey(arg[1].svalue->c_str(), arg[2].svalue->c_str(), comment);
                    break;
                default: break;
            }

//            variables[la[0]].fvalue->updateHeader();
//            if (nargs == 4) comment = (char *)arg[3].svalue->c_str();
//            switch (arg[2].type) {
//                case typeCon: variables[la[0]].fvalue->SetIntKey(arg[1].svalue->c_str(), la[2], comment);
//                    break;
//                case typeDbl: variables[la[0]].fvalue->SetFloatKey(arg[1].svalue->c_str(), fa[2], comment);
//                    break;
//                case typeStr: variables[la[0]].fvalue->SetStringKey(arg[1].svalue->c_str(), arg[2].svalue->c_str(), comment);
//                    break;
//                default: break;
//            }
            }
            break;

/************************
 ***     setbitpix    ***
 ************************/
        case 189:
            if ((la[1] != 8) && (la[1] != 16) && (la[1] != 32) && (la[1] != 64) && (la[1] != -32) && (la[1] != -64) && (la[1] != -128)) {
                dp_output(procs[pg].name.c_str());
                yyerror(": Invalid bitpix.");
                break;
            }
            if (nargs == 4) pgVariables[0].fvalue->setType((FitsBitpix)la[1], fa[2], fa[3]);
            else if (nargs == 3) pgVariables[0].fvalue->setType((FitsBitpix)la[1], fa[2]);
            else if (nargs == 2) pgVariables[0].fvalue->setType((FitsBitpix)la[1]);
            break;

/************************
 ***     cd           ***
 ************************/
        case 190:
            if (chdir(arg[0].svalue->c_str())) {
                dp_output(arg[0].svalue->c_str());
                yyerror(": no such directory");
            }
            break;

/************************
 ***     setwcs       ***
 ************************/
        case 191:
            pgVariables[0].fvalue->SetFloatKey("CRPIX1", fa[1]);
            pgVariables[0].fvalue->SetFloatKey("CRPIX2", fa[2]);
            pgVariables[0].fvalue->SetFloatKey("CRVAL1", fa[3]);
            pgVariables[0].fvalue->SetFloatKey("CRVAL2", fa[4]);
            pgVariables[0].fvalue->SetFloatKey("CDELT1", fa[5]);
            if (nargs == 6)
                pgVariables[0].fvalue->SetFloatKey("CDELT2", fa[5]);
            else
                pgVariables[0].fvalue->SetFloatKey("CDELT2", fa[6]);
//          pgVariables[0].fvalue->SetStringKey("CTYPE1", "LINEAR");
//          pgVariables[0].fvalue->SetStringKey("CTYPE2", "LINEAR");
            pgVariables[0].fvalue->DeleteKey("CD1_1");
            pgVariables[0].fvalue->DeleteKey("CD1_2");
            pgVariables[0].fvalue->DeleteKey("CD2_1");
            pgVariables[0].fvalue->DeleteKey("CD2_2");
            pgVariables[0].fvalue->DeleteKey("CROTA1");
            pgVariables[0].fvalue->DeleteKey("CROTA2");
            break;

/************************
 ***     shrink       ***
 ************************/
        case 192:
            if (nargs == 1) {
                pgVariables[0].fvalue->shrink(la[1]);
            } else {
                pgVariables[0].fvalue->shrink(la[1], la[2]);
            }
            break;

/************************
 ***     view        ***
 ************************/
        case 193:
#ifdef DPQT
// Notify QFitsView of variable change
            if (pgVariables[0].type == typeFits) {
                QFitsSingleBuffer *sb = NULL;
                for (auto var:dpuser_vars) {
                    sb = dynamic_cast<QFitsSingleBuffer*>(fitsMainWindow->getBuffer(var.first));
                    if ((sb != NULL) && (sb->getDpData()->type == typeFits)) {
                        if (sb->getDpData()->fvalue == pgVariables[0].fvalue) {
                            int scaleMethod = -1;
                            if (procedure_options & 1) scaleMethod = 0;
                            else if (procedure_options & 2) scaleMethod = 1;
                            else if (procedure_options & 4) scaleMethod = 2;
                            if (scaleMethod != -1) sb->setImageScalingMethod(scaleMethod);

                            if (nargs == 3) {
                                sb->setImageMaxValue(fa[2]);
                                sb->setImageMinValue(fa[1]);
                                sb->setImageScaleRange(ScaleManual);
                            } else {
                                dpScaleMode scaleMode = sb->getImageScaleRange();
                                if (procedure_options & 8) scaleMode = ScaleMinMax;
                                else if (procedure_options & 16) scaleMode = Scale999;
                                else if (procedure_options & 32) scaleMode = Scale995;
                                else if (procedure_options & 64) scaleMode = Scale99;
                                else if (procedure_options & 128) scaleMode = Scale98;
                                else if (procedure_options & 256) scaleMode = Scale95;
                                sb->setImageScaleRange(scaleMode);
                            }

                            int zoomLevel = -100;
                            zoomLevel = sb->getZoomFactor();

                            sb->setDirty(false);

                            break;
                        }
                    }
                }
            }
            dpUpdateView((dynamic_cast<variableNode *>(args.at(0)))->id);
#endif /* DPQT */
            break;

/************************
 ***     limits       ***
 ************************/
        case 194: {
            long x[6];

            arg[0].fvalue->limits(&x[0], &x[1], &x[2], &x[3], &x[4], &x[5]);
            for (int i = 1; i < nargs; i++) {
                pgVariables[i].type = typeCon;
                pgVariables[i].lvalue = x[i - 1];
            }
            }
            break;

/************************
 ***     printf       ***
 ************************/
        case 195: {
            dpString out;

            if (arg[1].type == typeCon) out.sprintf(arg[0].svalue->c_str(), arg[1].lvalue);
            else out.sprintf(arg[0].svalue->c_str(), arg[1].dvalue);

            dp_output("%s\n", out.c_str());
            }
            break;

/************************
 ***     export       ***
 ************************/
        case 196: {
            FILE *fd = NULL;
            char format[10];

            if ((fd = fopen(arg[0].svalue->c_str(), "w+b")) == NULL) {
                dp_output("Could not open file %s for writing\n", arg[0].svalue->c_str());
                break;
            }
            if (arg[1].type == typeStrarr) {
                for (dpint64 ii = 0; ii < arg[1].arrvalue->count(); ii++) {
                    fprintf(fd, "%s\n", (*arg[1].arrvalue)[ii].c_str());
                }
            } else if (arg[1].type == typeFits) {
                int n;
                if (nargs == 3) {
                    n = arg[2].lvalue;
                } else {
                    n = 2;
                }
                sprintf(format, "%%.%if ", n);
                for (int k = 0; k < arg[1].fvalue->Naxis(3); k++) {
                    for (int j = 0; j < arg[1].fvalue->Naxis(2); j++) {
                        for (int i = 0; i < arg[1].fvalue->Naxis(1); i++) {
                            fprintf(fd, format, arg[1].fvalue->ValueAt(arg[1].fvalue->C_I(i, j, k)));
                        }
                        fprintf(fd, "\n");
                    }
                }
            }
            fclose(fd);
            }
            break;

/************************
 ***     writebmp     ***
 ************************/
        case 197: if (nargs == 2) arg[1].fvalue->WriteBMP(arg[0].svalue->c_str());
            else if (nargs == 4) Fits::WriteBMP(arg[0].svalue->c_str(), *arg[1].fvalue, *arg[2].fvalue, *arg[3].fvalue);
            else yyerror("writebmp: must be either one or three fits");
            break;

/************************
 ***     swapbytes    ***
 ************************/
        case 198: {
            char tempr;
            char *_tmp = (char *)pgVariables[0].fvalue->dataptr;
            if (pgVariables[0].fvalue->membits == C16) {
                for (unsigned long i = 0; i < pgVariables[0].fvalue->Nelements() * 8 * 2; i += 8) {
                    SWAP(_tmp[i], _tmp[i+7]);
                    SWAP(_tmp[i+1], _tmp[i+6]);
                    SWAP(_tmp[i+2], _tmp[i+5]);
                    SWAP(_tmp[i+3], _tmp[i+4]);
                }
            } else if (pgVariables[0].fvalue->membits == R8) {
                for (unsigned long i = 0; i < pgVariables[0].fvalue->Nelements() * 8; i += 8) {
                    SWAP(_tmp[i], _tmp[i+7]);
                    SWAP(_tmp[i+1], _tmp[i+6]);
                    SWAP(_tmp[i+2], _tmp[i+5]);
                    SWAP(_tmp[i+3], _tmp[i+4]);
                }
            } else if ((pgVariables[0].fvalue->membits == R4) || (pgVariables[0].fvalue->membits == I4)) {
                for (unsigned long i = 0; i < pgVariables[0].fvalue->Nelements() * 4; i += 4) {
                    SWAP(_tmp[i], _tmp[i+3]);
                    SWAP(_tmp[i+1], _tmp[i+2]);
                }
            } else if (pgVariables[0].fvalue->membits == I2) {
                for (unsigned long i = 0; i < pgVariables[0].fvalue->Nelements() * 2; i += 2) {
                    SWAP(_tmp[i], _tmp[i+1]);
                }
            }
            }
            break;

/************************
 ***     read         ***
 ************************/
        case 199: {
            dp_output("%s", arg[0].svalue->c_str());
            char *inp = (char *)malloc(256 * sizeof(char));
            for (int i = 1; i < nargs; i++) {
                read_inp(inp);
                switch (pgVariables[i].type) {
                    case typeCon: pgVariables[i].lvalue = atol(inp); break;
                    case typeDbl: pgVariables[i].dvalue = atof(inp); break;
                    case typeStr: *pgVariables[i].svalue = inp; break;
                    default: break;
                }
            }
            free(inp);
            }
            break;

/************************
 ***     shade        ***
 ************************/
#ifdef HAS_PGPLOT
#ifdef HAS_DPPGPLOT
        case 200:
            shade(arg[0].fvalue);
            break;
#endif /* HAS_PGPLOT */
#endif /* HAS_DPPGPLOT */

/************************
 ***     replace      ***
 ************************/
        case 201:
            if (pgVariables[0].type == typeStr) {
                pgVariables[0].svalue->replace(dpRegExp(*arg[1].svalue), *arg[2].svalue);
            } else if (pgVariables[0].type == typeStrarr) {
                for (dpint64 n = 0; n < pgVariables[0].arrvalue->count(); n++)
                (*pgVariables[0].arrvalue)[n].replace(dpRegExp(*arg[1].svalue), *arg[2].svalue);
            } else success = FALSE;
            break;

/************************
 ***     saomarkpoint ***
 ************************/
        case 202:
            if (ds9_running() == 0) {
                dp_output("ERROR: No ds9 is running! Please start first ds9 (at least v5.2)\n");
                success = false;
            }
            if (ds9_frame_loaded() == 0) {
                dp_output("ERROR: First load a fits-file into ds9 either in ds9 itself or with sao in dpuser!\n");
                success = false;
            }

            if (success) {
                int ret = 0;
                char *names[NXPA];
                char *messages[NXPA];
                dpString pos = dpString::number(arg[0].toInt()) + " " + dpString::number(arg[1].toInt());
                dpString cmd = "regions command { ";
                dpString accessPoint;

                if (arg[3].toInt() & 2) {
                    // point
                    accessPoint = cmd + "point " + pos + " }";
                }
                if (arg[3].toInt() & 4) {
                    // box
                    accessPoint =    cmd + "box " + pos + " " +
                                    dpString::number(arg[2].toInt()) + " " +
                                    dpString::number(arg[2].toInt()) + " }";
                }
                if (arg[3].toInt() & 32) {
                    // diamond
                    accessPoint =    cmd + "box " + pos + " " +
                                    dpString::number(arg[2].toInt()) + " " +
                                    dpString::number(arg[2].toInt()) + " 45 }";
                }
                if (arg[3].toInt() & 64) {
                    // circle
                    accessPoint =    cmd + "circle " + pos + " " +
                                    dpString::number(arg[2].toInt() / 2) + " }";
                }

                if ((arg[3].toInt() & 2) || (arg[3].toInt() & 4) ||
                    (arg[3].toInt() & 32) || (arg[3].toInt() & 64)) {

                    ret = XPASet(xpa, xpaServer, (char*)accessPoint.c_str(), NULL,
                                NULL, 0, names, messages, NXPA);

                    /* error processing */
                    for(int i = 0; i < ret; i++){
                        if(messages[i]) {
                            dp_output("ERROR: %s (%s)\n", messages[i], names[i]);
                        }
                        if(names[i]) {
                            free(names[i]);
                        }
                        if(messages[i]) {
                            free(messages[i]);
                        }
                    }
                } else {
                    dp_output("This marker type is not supported anymore!");
                }
            }
            break;

/************************
 ***     saoclear     ***
 ************************/
        case 203:
            if (ds9_running() == 0) {
                dp_output("ERROR: No ds9 is running! Please start first ds9 (at least v5.2)\n");
                success = false;
            }
            if (ds9_frame_loaded() == 0) {
                dp_output("ERROR: First load a fits-file into ds9 either in ds9 itself or with sao in dpuser!\n");
                success = false;
            }

            if (success) {
                int ret;
                char *names[NXPA];
                char *messages[NXPA];
                ret = XPASet(xpa, xpaServer, (char *)"regions delete all", NULL,
                             NULL, 0, names, messages, NXPA);

                /* error processing */
                for(int i = 0; i < ret; i++){
                    if(messages[i]) {
                        dp_output("ERROR: %s (%s)\n", messages[i], names[i]);
                    }
                    if(names[i]) {
                        free(names[i]);
                    }
                    if(messages[i]) {
                        free(messages[i]);
                    }
                }
            }
            break;

/************************
 ***    saomarklabel  ***
 ************************/
        case 204:
            if (ds9_running() == 0) {
                dp_output("ERROR: No ds9 is running! Please start first ds9 (at least v5.2)\n");
                success = false;
            }
            if (ds9_frame_loaded() == 0) {
                dp_output("ERROR: First load a fits-file into ds9 either in ds9 itself or with sao in dpuser!\n");
                success = false;
            }

            if (success) {
                int ret;
                char *names[NXPA];
                char *messages[NXPA];

                dpString accessPoint =    "regions command { text " +
                                        dpString::number(arg[0].toInt()) + " " +
                                        dpString::number(arg[1].toInt()) + " \"" +
                                        *(arg[2].svalue) + "\" }";

                ret = XPASet(xpa, xpaServer, (char*)accessPoint.c_str(), NULL,
                             NULL, 0, names, messages, NXPA);

                /* error processing */
                for(int i = 0; i < ret; i++){
                    if(messages[i]) {
                        dp_output("ERROR: %s (%s)\n", messages[i], names[i]);
                    }
                    if(names[i]) {
                        free(names[i]);
                    }
                    if(messages[i]) {
                        free(messages[i]);
                    }
                }
            }
            break;

/************************
 ***     cblank       ***
 ************************/
        case 205:
            if (nargs == 1) pgVariables[0].fvalue->cblank();
            else pgVariables[0].fvalue->cblank(fa[1]);
            break;

/************************
 ***     cubemerge    ***
 ************************/
        case 206:
            success = CubeMerge(arg[0].svalue->c_str(), *arg[1].arrvalue);
            break;

/************************
 ***     setenv       ***
 ************************/
        case 207: {
            dpString env;

            env = *arg[0].svalue + "=" + *arg[1].svalue;
            putenv(strdup(env.c_str()));
            }
            break;

/************************
 ***     break        ***
 ************************/
        case 208:
            ScriptInterrupt = 1;
            break;

/************************
 ***     run          ***
 ************************/
        case 209: {
            FILE *fd;
            dpStringList inp;
            dpString fl;
            char *newinput;
            int irv, l, s;

            if ((fd = fopen(arg[0].svalue->c_str(), "rb")) == NULL) {
                success = FALSE;
                dp_output("Could not open file %s for reading\n", arg[0].svalue->c_str());
                break;
            }
            if ((newinput = (char *)malloc(256 * sizeof(char))) == NULL) {
                fclose(fd);
                success = FALSE;
                break;
            }
            strcpy(newinput, "");
            irv = 0;
            while (irv != EOF) {
                l = s = 0;
                do {
                    irv = fscanf(fd, "%c", &newinput[l++]);
                    s++;
                    if (s == 255) {
                        if ((newinput = (char *)realloc(newinput, (l + 256) * sizeof(char))) == NULL) {
                            fclose(fd);
                            success = FALSE;
                            break;
                        }
                        s = 0;
                    }
                } while ((newinput[l-1] != '\n') && (irv != EOF));
                l--;
                while ((l > -1) &&
                       ((newinput[l] == '\n') || (newinput[l] == '\r')))
                {
                    l--;
                }
                newinput[l+1] = (char)0;
                if (irv != EOF) {
                    inp.append(newinput);
                    free(newinput);
                    if ((newinput = (char *)malloc(256 * sizeof(char))) == NULL) {
                        fclose(fd);
                        success = FALSE;
                        break;
                    }
                    strcpy(newinput, "");
                    s = 0;
                }
            }
            fclose(fd);
            free(newinput);
            for (int i = inp.count() - 1; i >= 0; i--) {
                script.prepend(inp[i]);
            }
            if (procedure_options & 1) idlmode = true;
            }
            break;

/************************
 ***     echo         ***
 ************************/
        case 210:
            if (arg[0].lvalue) silence = 0;
            else silence = 1;
            break;

/************************
 ***     precess      ***
 ************************/
        case 211:
            precess(fa[0], fa[1], fa[2], fa[3], fa[4], fa[5], fa[6], fa[7]);
            break;

/************************
 ***       pwd        ***
 ************************/
        case 212:
            dp_output("%s\n", dpDir::currentDirPath().c_str());
            break;

/************************
 ***      dir         ***
 ************************/
        case 213: {
            dpStringList listing;
            dpString filter;

            if (nargs == 1) {
                filter = *arg[0].svalue;
            } else {
                filter = "*";
            }

            listing += dpDir::dir(filter);

            for (int i = 0; i < listing.size(); i++) {
                dp_output("%s\n", listing[i].c_str());
            }
            }
            break;

/************************
 ***     newbuffer    ***
 ************************/
        case 214: {
//                dpString name   = freeBufferName();
//                bool good       = false;
//                int extension   = 0,
//                    index       = createVariable((char *)name.c_str());
//
//                if (nargs == 2) {
//                    extension = la[1];
//                }
//
//                if (extension == -1) {
//                    // read all extensions
//                    Fits* f = new Fits;
//                    int count = f->CountExtensions(arg[0].svalue->c_str());
//                    delete f;
//
//                    if (count == -1) {
//                        yyerror("Unable to open file!\n");
//                    } else if (count == 0) {
//                        variables[index].type = typeFits;
//                        variables[index].fvalue = CreateFits();
//                        good = variables[index].fvalue->ReadFITSExtension(arg[0].svalue->c_str(), extension);
//                    } else {
//                        // read FITS-file with extensions
//                        variables[index].type = typeFitsarr;
//                        variables[index].dparrvalue = CreateDpList();
//                        good = variables[index].dparrvalue->ReadFITS(arg[0].svalue->c_str());
//                    }
//                } else {
//                    variables[index].type = typeFits;
//                    variables[index].fvalue = CreateFits();
//                    good = variables[index].fvalue->ReadFITSExtension(arg[0].svalue->c_str(), extension);
//                }
//            int index;
            bool good;
            int extension = 0;
            dpString name = freeBufferName();
//            index = createVariable((char *)name.c_str());

            if (nargs == 2) {
                extension = la[1];
                if (extension < 0) {
                    // check if file has really multiple extensions
                    // if not read it as a simple FITS file
                    Fits* f = new Fits;
                    int count = f->CountExtensions((*arg[0].svalue).c_str());
                    delete f;

                    if (count == -1) {
                        yyerror("Unable to open file!\n");
                    } else if (count == 0) {
                        // read FITS-file without extensions
                        extension = 0;
                    }
                }
            }

            if (extension == 0) {
                // Read primary
                dpuser_vars[name.c_str()].type = typeFits;
                dpuser_vars[name.c_str()].fvalue = CreateFits();
                good = dpuser_vars[name.c_str()].fvalue->ReadFITS(arg[0].svalue->c_str());
            } else if (extension < 0) {
                // read FITS-file with extensions
                dpuser_vars[name.c_str()].type = typeDpArr;
                dpuser_vars[name.c_str()].dparrvalue = CreateDpList();
                good = dpuser_vars[name.c_str()].dparrvalue->ReadFITS(arg[0].svalue->c_str());
            } else{
                // Read extension
                dpuser_vars[name.c_str()].type = typeFits;
                dpuser_vars[name.c_str()].fvalue = CreateFits();
                good = dpuser_vars[name.c_str()].fvalue->ReadFITSExtension(arg[0].svalue->c_str(), extension);
            }

            if (good) {
            } else {
                dpuser_vars.erase(name.c_str());
//                svariables[index] = "";
//                variables[index].fvalue = NULL;
            }

#ifdef DPQT
            // Notify QFitsView of variable change
            if (good)
                dpUpdateVar(name);
#endif /* DPQT */
            }
            break;

/************************
 ***   setindexbase   ***
 ************************/
        case 215:
            indexBase = la[0];
            break;

/************************
 *** fortrannotation  ***
 ************************/
        case 216:
            indexBase = 1;
            break;

/************************
 ***     cnotation    ***
 ************************/
        case 217:
            indexBase = 0;
            break;

/************************
 ***   userDialog     ***
 ************************/
#ifdef DPQT
         case 218: {
             QStringList dummy;
             userfunctionstruct data;
             for (int i = 0; i < arg[1].arrvalue->count(); i++) {
                 dummy.append(QString(""));
                 data.labels.append(QString((*arg[1].arrvalue)[i].c_str()));
                 data.types.append("");
                 data.defaultValues.append("");
             }
             if (nargs > 2) {
                 for (int i = 0; i < arg[2].arrvalue->count(); i++) {
                     data.types[i] = QString((*arg[2].arrvalue)[i].c_str());
                 }
                 if (nargs > 3) {
                     for (int i = 0; i < arg[3].arrvalue->count(); i++) {
                         data.defaultValues[i] = QString((*arg[3].arrvalue)[i].c_str());
                     }
                 }
             }
             userDialogs.erase(QString((*arg[0].svalue).c_str()));
             userDialogs[QString((*arg[0].svalue).c_str())] = data;
             }
             break;
#endif /* DPQT */

/************************
 ***    cirrange      ***
 ************************/
        case 219: {
            dpuserType range;
            long n = 0;
            range.type = typeDbl;
            range.dvalue = 360.;
            if (procedure_options & 2) range.dvalue = 2. * M_PI;

            pgVariables[0] = modulo(pgVariables[0], range);
            switch (arg[0].type) {
                case typeFits:
                    for (n = 0; n < pgVariables[0].fvalue->Nelements(); n++) {
                        if ((*pgVariables[0].fvalue)[n] < 0.) pgVariables[0].fvalue->setValue((*pgVariables[0].fvalue)[n] + range.dvalue, n+1, 1);
                    }
                break;
                case typeCon:
                    if (pgVariables[0].lvalue < 0) pgVariables[0].lvalue += 360;
                    break;
                case typeDbl:
                    if (pgVariables[0].dvalue < 0.) pgVariables[0].dvalue += range.dvalue;
                    break;
                default:
                    break;
            }
        }
        break;

/************************
 ***     debug        ***
 ************************/
        case 220:
            if (nargs == 1) {
                dpdebuglevel = arg[0].lvalue;
            } else {
/*                dp_output("Number of oStrings:\t%li\n", numberOfOStrings); */
                dp_output("Number of dpComplex:\t%li\n", numberOfdpComplex);
                dp_output("Number of Fits:\t%li\n", numberOfFits);

                if (variableErrors[0]) dp_output("svalue is variable, but dpuserType says no: %i\n", variableErrors[0]);
                if (variableErrors[1]) dp_output("svalue is no variable, but dpuserType says yes: %i\n", variableErrors[1]);
                if (variableErrors[2]) dp_output("fvalue is variable, but dpuserType says no: %i\n", variableErrors[2]);
                if (variableErrors[3]) dp_output("fvalue is no variable, but dpuserType says yes: %i\n", variableErrors[3]);
                if (variableErrors[4]) dp_output("cvalue is variable, but dpuserType says no: %i\n", variableErrors[4]);
                if (variableErrors[5]) dp_output("cvalue is no variable, but dpuserType says yes: %i\n", variableErrors[5]);
                if (variableErrors[6]) dp_output("arrvalue is variable, but dpuserType says no: %i\n", variableErrors[6]);
                if (variableErrors[7]) dp_output("arrvalue is no variable, but dpuserType says yes: %i\n", variableErrors[7]);
                if (variableErrors[8]) dp_output("dparrvalue is variable, but dpuserType says no: %i\n", variableErrors[8]);
                if (variableErrors[9]) dp_output("dparrvalue is no variable, but dpuserType says yes: %i\n", variableErrors[9]);
                FitsInfo = true;
            }
            break;

/************************
 ***     copyheader   ***
 ************************/
        case 221:
            pgVariables[0].fvalue->CopyHeader(*arg[1].fvalue);
            break;

/************************
 ***     swapaxes     ***
 ************************/
        case 222:
            success = pgVariables[0].fvalue->swapaxes(la[1], la[2], la[3]);
            break;

/************************
***    setfitstype    ***
************************/
        case 223:
            if (pgVariables[0].type == typeFits) {
                if (procedure_options == 1) {
                    pgVariables[0].fvalue->extensionType = IMAGE;
                } else if (procedure_options == 2) {
                    pgVariables[0].fvalue->extensionType = BINTABLE;
                }
            } else if (pgVariables[0].type == typeDpArr) {
                if (nargs == 1) {
                    for (int i = 0; i < pgVariables[0].dparrvalue->size(); i++) {
                        if (pgVariables[0].dparrvalue->at(i)->type == typeFits) {
                            if (procedure_options == 1) {
                                pgVariables[0].dparrvalue->at(i)->fvalue->extensionType = IMAGE;
                            } else if (procedure_options == 2) {
                                pgVariables[0].dparrvalue->at(i)->fvalue->extensionType = BINTABLE;
                            }
                        }
                    }
                } else if (la[1] >= 0 && la[1] < pgVariables[0].dparrvalue->size()) {
                    if (pgVariables[0].dparrvalue->at(la[1])->type == typeFits) {
                        if (procedure_options == 1) {
                            pgVariables[0].dparrvalue->at(la[1])->fvalue->extensionType = IMAGE;
                        } else if (procedure_options == 2) {
                            pgVariables[0].dparrvalue->at(la[1])->fvalue->extensionType = BINTABLE;
                        }
                    }
                }
            }
            break;

/************************
***     watchdir      ***
************************/
#ifdef DPQT
        case 224:
            if (nargs == 3) {
                fitsMainWindow->setDirToWatch(*(arg[0].svalue), *(arg[1].svalue), *(arg[2].svalue));
            }
            break;
#endif /* DPQT */

/************************
***      message      ***
************************/
        case 225: {
#ifdef DPQT
        dpusermutex->lock();
        dpCommandQFitsView("message", arg[0].svalue->c_str(), procedure_options);
        // now wait until the dialog has been closed;
        dpusermutex->lock();
        dpusermutex->unlock();
#else
        if (procedure_options & 2) dp_output("WARNING: ");
        else if (procedure_options & 4) dp_output("CRITICAL: ");
        else dp_output("INFORMATION: ");
        dp_output("%s", arg[0].svalue->c_str());
#endif /* DPQT */
        }
            break;

/************************
***     updategui     ***
************************/
#ifdef DPQT
        case 226:
#ifdef LBT
            if (QString(arg[0].svalue->c_str()) == "luci1align") {
                QString v;
                v.sprintf("%f %f %f", arg[1].fvalue->ValueAt(0), arg[1].fvalue->ValueAt(1), arg[1].fvalue->ValueAt(2));
                dpCommandQFitsView("luci1align", v.toStdString().c_str(), 0);
            } else if (QString(arg[0].svalue->c_str()) == "luci2align") {
                QString v;
                v.sprintf("%f %f %f", arg[1].fvalue->ValueAt(0), arg[1].fvalue->ValueAt(1), arg[1].fvalue->ValueAt(2));
                dpCommandQFitsView("luci2align", v.toStdString().c_str(), 0);
            } else if (QString(arg[0].svalue->c_str()) == "luci1files") {
                QString v;
                v = arg[1].arrvalue->at(0).c_str();
                v += " ";
                v += arg[1].arrvalue->at(1).c_str();
                v += " ";
                v += arg[1].arrvalue->at(2).c_str();
                dpCommandQFitsView("luci1files", v.toStdString().c_str(), 0);
            } else if (QString(arg[0].svalue->c_str()) == "luci2files") {
                QString v;
                v = arg[1].arrvalue->at(0).c_str();
                v += " ";
                v += arg[1].arrvalue->at(1).c_str();
                v += " ";
                v += arg[1].arrvalue->at(2).c_str();
                dpCommandQFitsView("luci2files", v.toStdString().c_str(), 0);
            }
#endif /* LBT */
            break;
#endif /* DPQT */

/************************
***       return      ***
************************/
        case 227:
            if (nargs == 1) {
                returnedValue = arg[0];
            }
            returnPassed = true;
        break;

/************************
***      python       ***
************************/
        case 228:
#ifdef HAS_PYTHON
void simple_python(std::string cmd);
extern bool pythonmode;
            if (nargs == 0) {
#ifdef DPQT
                dpuser_widget->prompt->setText("    >>>");
#endif
                pythonmode = true;
            } else {
                if ((*(arg[0].svalue) == "dpuser") || (arg[0].svalue->left(4) == "exit") || (arg[0].svalue->left(4) == "quit")) {
                    pythonmode = false;
#ifdef DPQT
                    dpuser_widget->prompt->setText("DPUSER> ");
#endif
                } else {
                    simple_python(*(arg[0].svalue));
                }
            }
#endif /* HAS_PYTHON */
        break;

/************************
***  deletefitskey    ***
************************/
        case 229:
            pgVariables[0].fvalue->DeleteKey(arg[1].svalue->c_str());
        break;

#ifdef HAS_PLPLOT

/************************
***      plvpor       ***
************************/
        case 230:
            plvpor(arg[0].toDouble(), arg[1].toDouble(), arg[2].toDouble(), arg[3].toDouble());
        break;

/************************
***      plsvpa       ***
************************/
        case 231:
            plsvpa(arg[0].toDouble(), arg[1].toDouble(), arg[2].toDouble(), arg[3].toDouble());
        break;

/************************
***      plvasp       ***
************************/
        case 232:
            plvasp(arg[0].toDouble());
        break;

/************************
***      plvpas       ***
************************/
        case 233:
            plvpas(arg[0].toDouble(), arg[1].toDouble(), arg[2].toDouble(), arg[3].toDouble(), arg[4].toDouble());
        break;

/************************
***      plvsta       ***
************************/
        case 234:
            plvsta();
        break;

/************************
***      plwind       ***
************************/
        case 235:
            plwind(arg[0].toDouble(), arg[1].toDouble(), arg[2].toDouble(), arg[3].toDouble());
        break;

/************************
***       plbox       ***
************************/
        case 236:
            plbox(arg[0].toString().c_str(), arg[1].toDouble(), arg[2].toInt(), arg[3].toString().c_str(), arg[4].toDouble(), arg[5].toInt());
        break;

/************************
***      plclear      ***
************************/
        case 237:
            plclear();
        break;

/************************
***     plsstrm       ***
************************/
        case 238:
            plsstrm(arg[0].toInt());
        break;

/************************
***     plreplot      ***
************************/
        case 239:
            plreplot();
        break;

/************************
 ***      plline      ***
 ************************/
        case 240:
            if ((la[0] > (long)arg[1].fvalue->Nelements()) || (la[0] > (long)arg[2].fvalue->Nelements())) {
                dp_output("plline: Inconsistent number of points\n");
                break;
            }
            ddata1 = doubledata(*arg[1].fvalue);
            ddata2 = doubledata(*arg[2].fvalue);
            if (ddata1 && ddata2)
                plline(la[0], ddata1, ddata2);
            if (ddata1 && (ddata1 != arg[1].fvalue->r8data)) free(ddata1);
            if (ddata2 && (ddata2 != arg[2].fvalue->r8data)) free(ddata2);
            break;

/************************
 ***      pladv       ***
 ************************/
        case 241:
            pladv(la[0]);
            break;

/************************
 ***    plscol0[a]    ***
 ************************/
        case 242:
            if (nargs == 4)
                plscol0(la[0], la[1], la[2], la[3]);
            else
                plscol0a(la[0], la[1], la[2], la[3], arg[4].toDouble());
            break;

/************************
 ***      plcol0      ***
 ************************/
        case 243:
            plcol0(la[0]);
            break;

/************************
***      plstart      ***
************************/
        case 244:
#ifdef DPQT
            if (arg[0].toString().length() == 0 || arg[0].toString().right(2) == "qt") {
                dpCommandQFitsView("plplot", "show", 0);
                plssub(arg[1].toInt(), arg[2].toInt());
                plclear();
//                plspause(0);
//            dpCommandQFitsView("plplot", "replot", unit);
            } else {
                plstart(arg[0].toString().c_str(), arg[1].toInt(), arg[2].toInt());
            }
#else /* DPQT */
            plstart(arg[0].toString().c_str(), arg[1].toInt(), arg[2].toInt());
#endif /* !DPQT */
        break;

/************************
 ***      pllsty      ***
 ************************/
        case 245:
            pllsty(la[0]);
            break;

/************************
 ***     plwidth      ***
 ************************/
        case 246:
            plwidth(arg[0].toDouble());
            break;

/************************
 ***      pllab       ***
 ************************/
        case 247:
            pllab(arg[0].toString().c_str(), arg[1].toString().c_str(), arg[2].toString().c_str());
            break;

/************************
 ***      plpoin      ***
 ************************/
        case 248:
            if ((la[0] > (long)arg[1].fvalue->Nelements()) || (la[0] > (long)arg[2].fvalue->Nelements())) {
                dp_output("plsym: Inconsistent number of points\n");
                break;
            }
            ddata1 = doubledata(*arg[1].fvalue);
            ddata2 = doubledata(*arg[2].fvalue);
            if (ddata1 && ddata2)
                plpoin(la[0], ddata1, ddata2, la[3]);
            if (ddata1 && (ddata1 != arg[1].fvalue->r8data)) free(ddata1);
            if (ddata2 && (ddata2 != arg[2].fvalue->r8data)) free(ddata2);
            break;



#endif /* HAS_PLPLOT */

/************************
 ***     updategui     ***
 ************************/
#ifdef DPQT
        case 249: {
            std::string v;
            v = std::to_string(arg[0].lvalue) + " " + std::to_string(arg[1].lvalue);
            dpCommandQFitsView("setBrightnessContrast", v.c_str(), 0);
    }
            break;
#endif /* DPQT */

        default: dp_output("%s", procs[pg].name.c_str());
            yyerror(": pgplot subroutine not implemented.");
            break;
    } /* switch (pg) */


    if (nargs > 0) {
        for (int i = 0; i < nargs; i++) {
            if (procs[pg].args[i] & typeId) {
                std::string varname = (dynamic_cast<variableNode *>(args.at(i)))->id;
                if (dpuser_vars[varname].type != typeDpArr) {
                    dpuser_vars[varname] = pgVariables[i];
                    dpuser_vars[varname].variable = true;
/*@                } else if (p->pgplot.op[i]->type == typeOpr) {
                    ((*variables[la[i]].dparrvalue)[p->pgplot.op[i]->opr.op[1]->rng.op[0]->con.value.lvalue])->copy(pgVariables[i]); */
                } else {
                    dpuser_vars[varname] = pgVariables[i];
                }
            }
        }
    }

// copy back globals
    dpuser_vars.erase("title");
    dpuser_vars.erase("xtitle");
    dpuser_vars.erase("ytitle");
    dpuser_vars.erase("symbol");
    for (auto old:oldglobals) dpuser_vars[old.first] = old.second;

#ifdef DPQT
// Notify QFitsView of variable change, except view command, this updates by itself
    if (pg != 193) {
        if (nargs > 0) {
            for (int i = 0; i < nargs; i++) {
                if (procs[pg].args[i] & typeId) {
                    dpUpdateVar((dynamic_cast<variableNode *>(args.at(i)))->id);
                }
            }
        }
    }
#ifdef HAS_PLPLOT
    if (procs[pg].name.left(2) == "pl") {
#ifdef HAS_PLOTTING
        fitsMainWindow->plplotWindow->update();
#endif /* HAS_PLOTTING */
        for (int id = 0; id < 10; id++) {
            fitsMainWindow->pg2plplotWindow[id]->update();
        }
    }
#ifdef HAS_PG2PLPLOT
    if (procs[pg].name.left(2) == "pg") {
        for (int id = 0; id < 10; id++) {
            fitsMainWindow->pg2plplotWindow[id]->update();
        }
    }
#endif /* HAS_PG2PLPLOT */
#endif /* HAS_PLPLOT */
#endif /* DPQT */
}

