QString Interpreter::printArgType(uint8_t *type, int &index)
{
    if (*type==CRP_TYPE_HINT)
    {
        int n = strlen((char *)type);
        QString print = "HINT(";
        if (n>4)
        {
            print += printType(FOURCC(type[1], type[2], type[3], type[4]), false) + ") ";
            index += 4;
        }
        else
        {
            index += n-1;
            print += "error)";
        }
        return print;
    }
    else
        return printArgType(*type, PRM_FLAG_SIGNED);
}
QString Interpreter::printProc(const ProcInfo *info, int level)
{
    ArgList list;
    QString print;
    QStringList sections;
    int i, j;

    print = QString(info->procName) + "(";
    if (getArgs(info, &list)<0)
        return "";
    for (i=0; i<(int)list.size(); i++)
    {
        if (i>0)
            print +=  ", ";
	j = i;
        print += printArgType(&info->argTypes[i], i) + " " + list[j].first;
    }
    print += ")\n";

    if (level>0)
    {
        sections = getSections("", info->procInfo);
        if (sections.size()>0)
            print += sections[0] + "\n";
        print += "Parameters:\n";
        if (list.size()==0)
            print += "<NONE>\n";
        for (i=0; i<(int)list.size(); i++)
        {
            print += "   " + list[i].first + ": ";
            print += list[i].second + "\n";
        }
        sections = getSections("@r", info->procInfo);
        print += "Returns:\n";
        for (i=0; i<sections.size(); i++)
            print += "   " + sections[i] + "\n";
    }

    return print;
}
int Interpreter::call(const QStringList &argv, bool interactive)
{
    ChirpProc proc;
    ProcInfo info;
    int args[20];
    int i, j, k, n, base, res;
    bool ok;
    uint type;
    ArgList list;

    // not allowed
    if (argv.size()<1)
        return -1;

    // check modules to see if they handle this command, if so, skip to end
    emit enableConsole(false);
    for (i=0; i<m_modules.size(); i++)
    {
        if (m_modules[i]->command(argv))
            return 0;
    }

    // a procedure needs extension info (arg info, etc) in order for us to call...
    if ((proc=m_chirp->getProc(argv[0].toLocal8Bit()))>=0 &&
            m_chirp->getProcInfo(proc, &info)>=0)
    {
        memset(args, 0, sizeof(args)); // zero args
        getArgs(&info, &list);
        n = strlen((char *)info.argTypes);

        // if we have fewer args than required...
        if ((int)list.size()>argv.size()-1)
        {
            // if we're interactive, ask for values
            if (interactive && argv.size()>0)
            {
                QStringList cargv = argv;
                QString pstring, pstring2;
                for (i=cargv.size()-1; i<(int)list.size(); i++)
                {
                    if (info.argTypes[i]==CRP_TYPE_HINT)
                    {
                        if (n>i+4)
                        {
                            type = *(uint *)&info.argTypes[i+1];
                            if (type==FOURCC('R','E','G','1'))
                            {
                                emit videoInput(VideoWidget::REGION);
                                pstring2 = "(select region with mouse)";
                            }
                            if (type==FOURCC('P','N','T','1'))
                            {
                                emit videoInput(VideoWidget::POINT);
                                pstring2 = "(select point with mouse)";
                            }
                        }
                    }
                    k = i;
                    pstring = printArgType(&info.argTypes[i], i) + " " + list[k].first +
                            (list[k].second=="" ? "?" : " (" + list[k].second + ")?") + " " + pstring2;

                    emit enableConsole(true);
                    emit prompt(pstring);
                    m_mutexInput.lock();
                    m_waiting = true;
                    m_waitInput.wait(&m_mutexInput);
                    m_waiting = false;
                    m_mutexInput.unlock();
                    emit prompt(PROMPT);
                    emit enableConsole(false);

                    if (m_key==Qt::Key_Escape)
                        return -1;
                    cargv << m_command.split(QRegExp("\\s+"));
                }
                // call ourselves again, now that we have all the args
                return call(cargv, true);
            }
            else
            {
                emit error("too few arguments.\n");
                return -1;
            }
        }


        augmentProcInfo(&info);
        // if we have all the args we need, parse, put in args array
        for (i=0, j=0; m_argTypes[i]; i++)
        {
            if (argv.size()>i+1)
            {
                if (m_argTypes[i]==CRP_INT8 || m_argTypes[i]==CRP_INT16 || m_argTypes[i]==CRP_INT32)
                {
                    args[j++] = m_argTypes[i];
                    if (argv[i+1].left(2)=="0x")
                        base = 16;
                    else
                        base = 10;
                    args[j++] = argv[i+1].toInt(&ok, base);
                    if (!ok)
                    {
                        emit error("argument didn't parse.\n");
                        return -1;
                    }
                }
#if 0
                else if (m_argTypes[i]==CRP_STRING)
                {
                    args[j++] = m_argTypes[i];
                    // string goes where?  can't cast pointer to int...
                }
#endif
                else
                {
                    // deal with non-integer types
                    return -1;
                }
            }
        }
#if 0
        // print helpful chirp argument string
        if (interactive && argv.size()>1)
        {
            QString callString = "Chirp arguments for " + argv[0] +
                    " (ChirpProc=" + QString::number(proc) + "): ";
            for (i=1; i<argv.size(); i++)
            {
                if (i>1)
                    callString += ", ";
                j = i;
                callString += printArgType(&m_argTypes[i-1], i) + "(" + argv[j] + ")";
            }
            emit textOut(callString + "\n");
        }
#endif

        // make chirp call
        res = m_chirp->callAsync(proc, args[0], args[1], args[2], args[3], args[4], args[5], args[6],
                           args[7], args[8], args[9], args[10], args[11], args[12], args[13], args[14], args[15],
                           args[16], args[17], args[18], args[19], END_OUT_ARGS);

        // check for cable disconnect
        if (res<0 && !m_notified) //res==LIBUSB_ERROR_PIPE)
        {
            m_notified = true;
            emit connected(PIXY, false);
            return res;
        }
        // get response if we're not programming, save text if we are
        if (m_programming)
            addProgram(argv);
        else
            m_chirp->serviceChirp();
    }
    else
    {
        emit error("procedure unsupported.\n");
        return -1;
    }

    return 0;
}
示例#4
0
void Interpreter::handleLoadParams()
{
    qDebug("loading...");
    uint i;
    char *id, *desc;
    uint32_t len;
    uint32_t flags;
    int response, res;
    uint8_t *data, *argList;
    int running;

    // if we're running, stop so this doesn't take too long....
    // (ie it would proceed with 1 property to returned frame, which could take 1 second or 2)
    running = m_running;
    if (running==1) // only if we're running and not in forced state (running==2)
        sendStop();

    for (i=0; true; i++)
    {
        QString category;

        res = m_chirp->callSync(m_getAll_param, UINT16(i), END_OUT_ARGS, &response, &flags, &argList, &id, &desc, &len, &data, END_IN_ARGS);
        if (res<0)
            break;

        if (response<0)
            break;

        QString sdesc(desc);

        // deal with param category
        QStringList words = QString(desc).split(QRegExp("\\s+"));
        int i = words.indexOf("@c");
        if (i>=0 && words.size()>i+1)
        {
            category = words[i+1];
            sdesc = sdesc.remove("@c "); // remove form description
            sdesc = sdesc.remove(category + " "); // remove from description
            category = category.replace('_', ' '); // make it look prettier
        }
        else
            category = CD_GENERAL;

        Parameter parameter(id, (PType)argList[0], "("+printArgType(argList[0], flags)+") "+sdesc);
        parameter.setProperty(PP_CATEGORY, category);
        parameter.setProperty(PP_FLAGS, flags);
        if (strlen((char *)argList)>1)
        {
            QByteArray a((char *)data, len);
            parameter.set(a);
        }
        else
        {
            if (argList[0]==CRP_INT8 || argList[0]==CRP_INT16 || argList[0]==CRP_INT32)
            {
                int32_t val = 0;
                Chirp::deserialize(data, len, &val, END);
                parameter.set(val);
            }
            else if (argList[0]==CRP_FLT32)
            {
                float val;
                Chirp::deserialize(data, len, &val, END);
                parameter.set(val);
            }
            else // not sure what to do with it, so we'll save it as binary
            {
                QByteArray a((char *)data, len);
                parameter.set(a);
            }
        }
        m_pixyParameters.add(parameter);
    }

    // if we're running, we've stopped, now resume
    if (running==1)
    {
        sendRun();
        m_fastPoll = false; // turn off fast polling...
    }

    qDebug("loaded");
    emit paramLoaded();
    if (m_paramDirty) // emit first time to update any modules waiting to get paramter info
    {
        m_paramDirty = false;
        emit paramChange();
    }
}