示例#1
0
static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
				  struct jtag_tap *pTap)
{
	jim_wide w;
	int e = Jim_GetOpt_Wide(goi, &w);
	if (e != JIM_OK) {
		Jim_SetResultFormatted(goi->interp, "option: %s bad parameter",
				       n->name);
		return e;
	}

	unsigned expected_len = sizeof(uint32_t) * pTap->expected_ids_cnt;
	uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t));
	if (new_expected_ids == NULL) {
		Jim_SetResultFormatted(goi->interp, "no memory");
		return JIM_ERR;
	}

	memcpy(new_expected_ids, pTap->expected_ids, expected_len);

	new_expected_ids[pTap->expected_ids_cnt] = w;

	free(pTap->expected_ids);
	pTap->expected_ids = new_expected_ids;
	pTap->expected_ids_cnt++;

	return JIM_OK;
}
示例#2
0
void Jim_SetResult_NvpUnknown(Jim_Interp *interp,
                              Jim_Obj *param_name, Jim_Obj *param_value, const Jim_Nvp *nvp)
{
    if (param_name)
        Jim_SetResultFormatted(interp,
                               "%#s: Unknown: %#s, try one of: ",
                               param_name,
                               param_value);
    else
        Jim_SetResultFormatted(interp, "Unknown param: %#s, try one of: ", param_value);
    while (nvp->name) {
        const char *a;
        const char *b;

        if ((nvp + 1)->name) {
            a = nvp->name;
            b = ", ";
        } else {
            a = "or ";
            b = nvp->name;
        }
        Jim_AppendStrings(interp, Jim_GetResult(interp), a, b, NULL);
        nvp++;
    }
}
示例#3
0
文件: jim-load.c 项目: AllardJ/Tomato
/**
 * Note that Jim_LoadLibrary() requires a path to an existing file.
 *
 * If it is necessary to search JIM_LIBPATH, use Jim_PackageRequire() instead.
 */
int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName)
{
    void *handle = dlopen(pathName, RTLD_NOW | RTLD_LOCAL);
    if (handle == NULL) {
        Jim_SetResultFormatted(interp, "error loading extension \"%s\": %s", pathName,
            dlerror());
    }
    else {
        /* We use a unique init symbol depending on the extension name.
         * This is done for compatibility between static and dynamic extensions.
         * For extension readline.so, the init symbol is "Jim_readlineInit"
         */
        const char *pt;
        const char *pkgname;
        int pkgnamelen;
        char initsym[40];
        int (*onload) (Jim_Interp *);

        pt = strrchr(pathName, '/');
        if (pt) {
            pkgname = pt + 1;
        }
        else {
            pkgname = pathName;
        }
        pt = strchr(pkgname, '.');
        if (pt) {
            pkgnamelen = pt - pkgname;
        }
        else {
            pkgnamelen = strlen(pkgname);
        }
        snprintf(initsym, sizeof(initsym), "Jim_%.*sInit", pkgnamelen, pkgname);

        if ((onload = dlsym(handle, initsym)) == NULL) {
            Jim_SetResultFormatted(interp,
                "No %s symbol found in extension %s", initsym, pathName);
        }
        else if (onload(interp) != JIM_ERR) {
            /* Add this handle to the stack of handles to be freed */
            if (!interp->loadHandles) {
                interp->loadHandles = Jim_Alloc(sizeof(*interp->loadHandles));
                Jim_InitStack(interp->loadHandles);
            }
            Jim_StackPush(interp->loadHandles, handle);

            Jim_SetEmptyResult(interp);

            return JIM_OK;
        }
    }
    if (handle) {
        dlclose(handle);
    }
    return JIM_ERR;
}
示例#4
0
static int file_cmd_delete(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    int force = Jim_CompareStringImmediate(interp, argv[0], "-force");

    if (force || Jim_CompareStringImmediate(interp, argv[0], "--")) {
        argc++;
        argv--;
    }

    while (argc--) {
        const char *path = Jim_String(argv[0]);

        if (unlink(path) == -1 && errno != ENOENT) {
            if (rmdir(path) == -1) {
                /* Maybe try using the script helper */
                if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) {
                    Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path,
                        strerror(errno));
                    return JIM_ERR;
                }
            }
        }
        argv++;
    }
    return JIM_OK;
}
示例#5
0
文件: jim-signal.c 项目: dgsb/jimtcl
/**
 * Given the name of a signal, returns the signal value if found,
 * or returns -1 (and sets an error) if not found.
 * We accept -SIGINT, SIGINT, INT or any lowercase version or a number,
 * either positive or negative.
 */
static int find_signal_by_name(Jim_Interp *interp, const char *name)
{
    int i;
    const char *pt = name;

    /* Remove optional - and SIG from the front of the name */
    if (*pt == '-') {
        pt++;
    }
    if (strncasecmp(name, "sig", 3) == 0) {
        pt += 3;
    }
    if (isdigit(UCHAR(pt[0]))) {
        i = atoi(pt);
        if (i > 0 && i < MAX_SIGNALS) {
            return i;
        }
    }
    else {
        for (i = 1; i < MAX_SIGNALS; i++) {
            /* Jim_SignalId() returns names such as SIGINT, and
             * returns "unknown signal" if unknown, so this will work
             */
            if (strcasecmp(Jim_SignalId(i) + 3, pt) == 0) {
                return i;
            }
        }
    }
    Jim_SetResultFormatted(interp, "unknown signal %s", name);

    return -1;
}
示例#6
0
文件: tcl.c 项目: cz172638/openocd
static int jtag_tap_configure_cmd(Jim_GetOptInfo *goi, struct jtag_tap *tap)
{
	/* parse config or cget options */
	while (goi->argc > 0) {
		Jim_SetEmptyResult(goi->interp);

		Jim_Nvp *n;
		int e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
		if (e != JIM_OK) {
			Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
			return e;
		}

		switch (n->value) {
			case JCFG_EVENT:
				e = jtag_tap_configure_event(goi, tap);
				if (e != JIM_OK)
					return e;
				break;
			default:
				Jim_SetResultFormatted(goi->interp, "unknown event: %s", n->name);
				return JIM_ERR;
		}
	}

	return JIM_OK;
}
示例#7
0
文件: jim-exec.c 项目: dokterp/jimtcl
/*
 * Create error messages for unusual process exits.  An
 * extra newline gets appended to each error message, but
 * it gets removed below (in the same fashion that an
 * extra newline in the command's output is removed).
 */
static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus)
{
    Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0);
    int rc = JIM_ERR;

    if (WIFEXITED(waitStatus)) {
        if (WEXITSTATUS(waitStatus) == 0) {
            Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "NONE", -1));
            rc = JIM_OK;
        }
        else {
            Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1));
            Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
            Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WEXITSTATUS(waitStatus)));
        }
    }
    else {
        const char *type;
        const char *action;

        if (WIFSIGNALED(waitStatus)) {
            type = "CHILDKILLED";
            action = "killed";
        }
        else {
            type = "CHILDSUSP";
            action = "suspended";
        }

        Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, type, -1));

#ifdef jim_ext_signal
        Jim_SetResultFormatted(interp, "child %s by signal %s", action, Jim_SignalId(WTERMSIG(waitStatus)));
        Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalId(WTERMSIG(waitStatus)), -1));
        Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, pid));
        Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalName(WTERMSIG(waitStatus)), -1));
#else
        Jim_SetResultFormatted(interp, "child %s by signal %d", action, WTERMSIG(waitStatus));
        Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus)));
        Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
        Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus)));
#endif
    }
    Jim_SetGlobalVariableStr(interp, "errorCode", errorCode);
    return rc;
}
示例#8
0
static void JimAioSetError(Jim_Interp *interp, Jim_Obj *name)
{
    if (name) {
        Jim_SetResultFormatted(interp, "%#s: %s", name, strerror(errno));
    }
    else {
        Jim_SetResultString(interp, strerror(errno), -1);
    }
}
示例#9
0
文件: tcl.c 项目: cz172638/openocd
struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
{
	const char *cp = Jim_GetString(o, NULL);
	struct jtag_tap *t = cp ? jtag_tap_by_string(cp) : NULL;
	if (NULL == cp)
		cp = "(unknown)";
	if (NULL == t)
		Jim_SetResultFormatted(interp, "Tap '%s' could not be found", cp);
	return t;
}
示例#10
0
FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command)
{
    Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG);

    if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) {
        return ((AioFile *) cmdPtr->u.native.privData)->fp;
    }
    Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", command);
    return NULL;
}
示例#11
0
static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    AioFile *af = Jim_CmdPrivData(interp);
    long count = 0;
    long maxlen = LONG_MAX;
    FILE *outfh = Jim_AioFilehandle(interp, argv[0]);

    if (outfh == NULL) {
        return JIM_ERR;
    }

    if (argc == 2) {
        if (Jim_GetLong(interp, argv[1], &maxlen) != JIM_OK) {
            return JIM_ERR;
        }
    }

    while (count < maxlen) {
        int ch = fgetc(af->fp);

        if (ch == EOF || fputc(ch, outfh) == EOF) {
            break;
        }
        count++;
    }

    if (ferror(af->fp)) {
        Jim_SetResultFormatted(interp, "error while reading: %s", strerror(errno));
        clearerr(af->fp);
        return JIM_ERR;
    }

    if (ferror(outfh)) {
        Jim_SetResultFormatted(interp, "error while writing: %s", strerror(errno));
        clearerr(outfh);
        return JIM_ERR;
    }

    Jim_SetResultInt(interp, count);

    return JIM_OK;
}
示例#12
0
文件: tcl.c 项目: artynet/OpenOCD
static int jtag_tap_configure_cmd(Jim_GetOptInfo *goi, struct jtag_tap *tap)
{
	/* parse config or cget options */
	while (goi->argc > 0) {
		Jim_SetEmptyResult(goi->interp);

		Jim_Nvp *n;
		int e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
		if (e != JIM_OK) {
			Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
			return e;
		}

		switch (n->value) {
			case JCFG_EVENT:
				e = jtag_tap_configure_event(goi, tap);
				if (e != JIM_OK)
					return e;
				break;
			case JCFG_IDCODE:
				if (goi->isconfigure) {
					Jim_SetResultFormatted(goi->interp,
							"not settable: %s", n->name);
					return JIM_ERR;
				} else {
					if (goi->argc != 0) {
						Jim_WrongNumArgs(goi->interp,
								goi->argc, goi->argv,
								"NO PARAMS");
						return JIM_ERR;
					}
				}
				Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, tap->idcode));
				break;
			default:
				Jim_SetResultFormatted(goi->interp, "unknown value: %s", n->name);
				return JIM_ERR;
		}
	}

	return JIM_OK;
}
示例#13
0
文件: tcl.c 项目: cz172638/openocd
static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
	struct jtag_tap *pTap)
{
	jim_wide w;
	int e = Jim_GetOpt_Wide(goi, &w);
	if (e != JIM_OK) {
		Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", n->name);
		return e;
	}

	uint32_t *p = realloc(pTap->expected_ids,
			      (pTap->expected_ids_cnt + 1) * sizeof(uint32_t));
	if (!p) {
		Jim_SetResultFormatted(goi->interp, "no memory");
		return JIM_ERR;
	}

	pTap->expected_ids = p;
	pTap->expected_ids[pTap->expected_ids_cnt++] = w;

	return JIM_OK;
}
示例#14
0
static int jim_newtap_ir_param(Jim_Nvp *n, Jim_GetOptInfo *goi,
		struct jtag_tap *pTap)
{
	jim_wide w;
	int e = Jim_GetOpt_Wide(goi, &w);
	if (e != JIM_OK)
	{
		Jim_SetResultFormatted(goi->interp,
				"option: %s bad parameter", n->name);
		free((void *)pTap->dotted_name);
		return e;
	}
	switch (n->value) {
	case NTAP_OPT_IRLEN:
		if (w > (jim_wide) (8 * sizeof(pTap->ir_capture_value)))
		{
			LOG_WARNING("%s: huge IR length %d",
					pTap->dotted_name, (int) w);
		}
		pTap->ir_length = w;
		break;
	case NTAP_OPT_IRMASK:
		if (is_bad_irval(pTap->ir_length, w))
		{
			LOG_ERROR("%s: IR mask %x too big",
					pTap->dotted_name,
					(int) w);
			return JIM_ERR;
		}
		if ((w & 3) != 3)
			LOG_WARNING("%s: nonstandard IR mask", pTap->dotted_name);
		pTap->ir_capture_mask = w;
		break;
	case NTAP_OPT_IRCAPTURE:
		if (is_bad_irval(pTap->ir_length, w))
		{
			LOG_ERROR("%s: IR capture %x too big",
					pTap->dotted_name, (int) w);
			return JIM_ERR;
		}
		if ((w & 3) != 1)
			LOG_WARNING("%s: nonstandard IR value",
					pTap->dotted_name);
		pTap->ir_capture_value = w;
		break;
	default:
		return JIM_ERR;
	}
	return JIM_OK;
}
示例#15
0
static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb)
{
    /* Just use a list to store the data */
    Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);

    AppendStatElement(interp, listObj, "dev", sb->st_dev);
    AppendStatElement(interp, listObj, "ino", sb->st_ino);
    AppendStatElement(interp, listObj, "mode", sb->st_mode);
    AppendStatElement(interp, listObj, "nlink", sb->st_nlink);
    AppendStatElement(interp, listObj, "uid", sb->st_uid);
    AppendStatElement(interp, listObj, "gid", sb->st_gid);
    AppendStatElement(interp, listObj, "size", sb->st_size);
    AppendStatElement(interp, listObj, "atime", sb->st_atime);
    AppendStatElement(interp, listObj, "mtime", sb->st_mtime);
    AppendStatElement(interp, listObj, "ctime", sb->st_ctime);
    Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1));
    Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1));

    /* Was a variable specified? */
    if (varName) {
        Jim_Obj *objPtr = Jim_GetVariable(interp, varName, JIM_NONE);
        if (objPtr) {
            if (Jim_DictSize(interp, objPtr) < 0) {
                /* This message matches the one from Tcl */
                Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName);
                Jim_FreeNewObj(interp, listObj);
                return JIM_ERR;
            }

            if (Jim_IsShared(objPtr))
                objPtr = Jim_DuplicateObj(interp, objPtr);

            /* Just cheat here and append as a list and convert to a dict */
            Jim_ListAppendList(interp, objPtr, listObj);
            Jim_DictSize(interp, objPtr);
            Jim_InvalidateStringRep(objPtr);

            Jim_FreeNewObj(interp, listObj);
            listObj = objPtr;
        }
        Jim_SetVariable(interp, varName, listObj);
    }

    /* And also return the value */
    Jim_SetResult(interp, listObj);

    return JIM_OK;
}
示例#16
0
static int file_cmd_mkdir(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    while (argc--) {
        char *path = Jim_StrDup(Jim_String(argv[0]));
        int rc = mkdir_all(path);

        Jim_Free(path);
        if (rc != 0) {
            Jim_SetResultFormatted(interp, "can't create directory \"%#s\": %s", argv[0],
                strerror(errno));
            return JIM_ERR;
        }
        argv++;
    }
    return JIM_OK;
}
示例#17
0
int Jim_GetOpt_Double(Jim_GetOptInfo *goi, double *puthere)
{
    int r;
    Jim_Obj *o;
    double _safe;

    if (puthere == NULL)
        puthere = &_safe;

    r = Jim_GetOpt_Obj(goi, &o);
    if (r == JIM_OK) {
        r = Jim_GetDouble(goi->interp, o, puthere);
        if (r != JIM_OK)
            Jim_SetResultFormatted(goi->interp, "not a number: %#s", o);
    }
    return r;
}
示例#18
0
int Jim_CreateNamespaceVariable(Jim_Interp *interp, Jim_Obj *varNameObj, Jim_Obj *targetNameObj)
{
    int rc;
    Jim_IncrRefCount(varNameObj);
    Jim_IncrRefCount(targetNameObj);

    /* push non-namespace vars if in namespace eval? */
    rc  = Jim_SetVariableLink(interp, varNameObj, targetNameObj, interp->topFramePtr);
    if (rc == JIM_ERR) {
        /* This is the only reason the link can fail */
        Jim_SetResultFormatted(interp, "can't define \"%#s\": name refers to an element in an array", varNameObj);
    }

    Jim_DecrRefCount(interp, varNameObj);
    Jim_DecrRefCount(interp, targetNameObj);

    return rc;
}
示例#19
0
static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *args)
{
	tap_state_t states[8];

	if ((argc < 2) || ((size_t)argc > (ARRAY_SIZE(states) + 1)))
	{
		Jim_WrongNumArgs(interp, 1, args, "wrong arguments");
		return JIM_ERR;
	}

	script_debug(interp, "pathmove", argc, args);

	int i;
	for (i = 0; i < argc-1; i++)
	{
		const char *cp;
		cp = Jim_GetString(args[i + 1], NULL);
		states[i] = tap_state_by_name(cp);
		if (states[i] < 0)
		{
			/* update the error message */
			Jim_SetResultFormatted(interp,"endstate: %s invalid", cp);
			return JIM_ERR;
		}
	}

	if ((jtag_add_statemove(states[0]) != ERROR_OK) || (jtag_execute_queue()!= ERROR_OK))
	{
		Jim_SetResultString(interp, "pathmove: jtag execute failed",-1);
		return JIM_ERR;
	}

	jtag_add_pathmove(argc-2, states + 1);

	if (jtag_execute_queue()!= ERROR_OK)
	{
		Jim_SetResultString(interp, "pathmove: failed",-1);
		return JIM_ERR;
	}

	return JIM_OK;
}
示例#20
0
static int file_cmd_normalize(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
#ifdef HAVE_REALPATH
    const char *path = Jim_String(argv[0]);
    char *newname = Jim_Alloc(MAXPATHLEN + 1);

    if (realpath(path, newname)) {
        Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, -1));
        return JIM_OK;
    }
    else {
        Jim_Free(newname);
        Jim_SetResultFormatted(interp, "can't normalize \"%#s\": %s", argv[0], strerror(errno));
        return JIM_ERR;
    }
#else
    Jim_SetResultString(interp, "Not implemented", -1);
    return JIM_ERR;
#endif
}
示例#21
0
int rtos_create(Jim_GetOptInfo *goi, struct target *target)
{
	int x;
	const char *cp;
	struct Jim_Obj *res;

	if (!goi->isconfigure && goi->argc != 0) {
		Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "NO PARAMS");
		return JIM_ERR;
	}

	os_free(target);

	Jim_GetOpt_String(goi, &cp, NULL);

	if (0 == strcmp(cp, "auto")) {
		/* Auto detect tries to look up all symbols for each RTOS,
		 * and runs the RTOS driver's _detect() function when GDB
		 * finds all symbols for any RTOS. See rtos_qsymbol(). */
		target->rtos_auto_detect = true;

		/* rtos_qsymbol() will iterate over all RTOSes. Allocate
		 * target->rtos here, and set it to the first RTOS type. */
		return os_alloc(target, rtos_types[0]);
	}

	for (x = 0; rtos_types[x]; x++)
		if (0 == strcmp(cp, rtos_types[x]->name))
			return os_alloc_create(target, rtos_types[x]);

	Jim_SetResultFormatted(goi->interp, "Unknown RTOS type %s, try one of: ", cp);
	res = Jim_GetResult(goi->interp);
	for (x = 0; rtos_types[x]; x++)
		Jim_AppendStrings(goi->interp, res, rtos_types[x]->name, ", ", NULL);
	Jim_AppendStrings(goi->interp, res, " or auto", NULL);

	return JIM_ERR;
}
示例#22
0
static regex_t *SetRegexpFromAny(Jim_Interp *interp, Jim_Obj *objPtr, unsigned flags)
{
    regex_t *compre;
    const char *pattern;
    int ret;

    /* Check if the object is already an uptodate variable */
    if (objPtr->typePtr == &regexpObjType &&
        objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) {
        /* nothing to do */
        return objPtr->internalRep.regexpValue.compre;
    }

    /* Not a regexp or the flags do not match */

    /* Get the string representation */
    pattern = Jim_String(objPtr);
    compre = Jim_Alloc(sizeof(regex_t));

    if ((ret = regcomp(compre, pattern, REG_EXTENDED | flags)) != 0) {
        char buf[100];

        regerror(ret, compre, buf, sizeof(buf));
        Jim_SetResultFormatted(interp, "couldn't compile regular expression pattern: %s", buf);
        regfree(compre);
        Jim_Free(compre);
        return NULL;
    }

    Jim_FreeIntRep(interp, objPtr);

    objPtr->typePtr = &regexpObjType;
    objPtr->internalRep.regexpValue.flags = flags;
    objPtr->internalRep.regexpValue.compre = compre;

    return compre;
}
示例#23
0
文件: jim-exec.c 项目: dokterp/jimtcl
/*
 *----------------------------------------------------------------------
 *
 * JimCreatePipeline --
 *
 *  Given an argc/argv array, instantiate a pipeline of processes
 *  as described by the argv.
 *
 * Results:
 *  The return value is a count of the number of new processes
 *  created, or -1 if an error occurred while creating the pipeline.
 *  *pidArrayPtr is filled in with the address of a dynamically
 *  allocated array giving the ids of all of the processes.  It
 *  is up to the caller to free this array when it isn't needed
 *  anymore.  If inPipePtr is non-NULL, *inPipePtr is filled in
 *  with the file id for the input pipe for the pipeline (if any):
 *  the caller must eventually close this file.  If outPipePtr
 *  isn't NULL, then *outPipePtr is filled in with the file id
 *  for the output pipe from the pipeline:  the caller must close
 *  this file.  If errFilePtr isn't NULL, then *errFilePtr is filled
 *  with a file id that may be used to read error output after the
 *  pipeline completes.
 *
 * Side effects:
 *  Processes and pipes are created.
 *
 *----------------------------------------------------------------------
 */
static int
JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype **pidArrayPtr,
    fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr)
{
    pidtype *pidPtr = NULL;         /* Points to malloc-ed array holding all
                                 * the pids of child processes. */
    int numPids = 0;            /* Actual number of processes that exist
                                 * at *pidPtr right now. */
    int cmdCount;               /* Count of number of distinct commands
                                 * found in argc/argv. */
    const char *input = NULL;   /* Describes input for pipeline, depending
                                 * on "inputFile".  NULL means take input
                                 * from stdin/pipe. */
    int input_len = 0;          /* Length of input, if relevant */

#define FILE_NAME   0           /* input/output: filename */
#define FILE_APPEND 1           /* output only:  filename, append */
#define FILE_HANDLE 2           /* input/output: filehandle */
#define FILE_TEXT   3           /* input only:   input is actual text */

    int inputFile = FILE_NAME;  /* 1 means input is name of input file.
                                 * 2 means input is filehandle name.
                                 * 0 means input holds actual
                                 * text to be input to command. */

    int outputFile = FILE_NAME; /* 0 means output is the name of output file.
                                 * 1 means output is the name of output file, and append.
                                 * 2 means output is filehandle name.
                                 * All this is ignored if output is NULL
                                 */
    int errorFile = FILE_NAME;  /* 0 means error is the name of error file.
                                 * 1 means error is the name of error file, and append.
                                 * 2 means error is filehandle name.
                                 * All this is ignored if error is NULL
                                 */
    const char *output = NULL;  /* Holds name of output file to pipe to,
                                 * or NULL if output goes to stdout/pipe. */
    const char *error = NULL;   /* Holds name of stderr file to pipe to,
                                 * or NULL if stderr goes to stderr/pipe. */
    fdtype inputId = JIM_BAD_FD;
                                 /* Readable file id input to current command in
                                 * pipeline (could be file or pipe).  JIM_BAD_FD
                                 * means use stdin. */
    fdtype outputId = JIM_BAD_FD;
                                 /* Writable file id for output from current
                                 * command in pipeline (could be file or pipe).
                                 * JIM_BAD_FD means use stdout. */
    fdtype errorId = JIM_BAD_FD;
                                 /* Writable file id for all standard error
                                 * output from all commands in pipeline.  JIM_BAD_FD
                                 * means use stderr. */
    fdtype lastOutputId = JIM_BAD_FD;
                                 /* Write file id for output from last command
                                 * in pipeline (could be file or pipe).
                                 * -1 means use stdout. */
    fdtype pipeIds[2];           /* File ids for pipe that's being created. */
    int firstArg, lastArg;      /* Indexes of first and last arguments in
                                 * current command. */
    int lastBar;
    int i;
    pidtype pid;
    char **save_environ;
    struct WaitInfoTable *table = Jim_CmdPrivData(interp);

    /* Holds the args which will be used to exec */
    char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1));
    int arg_count = 0;

    JimReapDetachedPids(table);

    if (inPipePtr != NULL) {
        *inPipePtr = JIM_BAD_FD;
    }
    if (outPipePtr != NULL) {
        *outPipePtr = JIM_BAD_FD;
    }
    if (errFilePtr != NULL) {
        *errFilePtr = JIM_BAD_FD;
    }
    pipeIds[0] = pipeIds[1] = JIM_BAD_FD;

    /*
     * First, scan through all the arguments to figure out the structure
     * of the pipeline.  Count the number of distinct processes (it's the
     * number of "|" arguments).  If there are "<", "<<", or ">" arguments
     * then make note of input and output redirection and remove these
     * arguments and the arguments that follow them.
     */
    cmdCount = 1;
    lastBar = -1;
    for (i = 0; i < argc; i++) {
        const char *arg = Jim_String(argv[i]);

        if (arg[0] == '<') {
            inputFile = FILE_NAME;
            input = arg + 1;
            if (*input == '<') {
                inputFile = FILE_TEXT;
                input_len = Jim_Length(argv[i]) - 2;
                input++;
            }
            else if (*input == '@') {
                inputFile = FILE_HANDLE;
                input++;
            }

            if (!*input && ++i < argc) {
                input = Jim_GetString(argv[i], &input_len);
            }
        }
        else if (arg[0] == '>') {
            int dup_error = 0;

            outputFile = FILE_NAME;

            output = arg + 1;
            if (*output == '>') {
                outputFile = FILE_APPEND;
                output++;
            }
            if (*output == '&') {
                /* Redirect stderr too */
                output++;
                dup_error = 1;
            }
            if (*output == '@') {
                outputFile = FILE_HANDLE;
                output++;
            }
            if (!*output && ++i < argc) {
                output = Jim_String(argv[i]);
            }
            if (dup_error) {
                errorFile = outputFile;
                error = output;
            }
        }
        else if (arg[0] == '2' && arg[1] == '>') {
            error = arg + 2;
            errorFile = FILE_NAME;

            if (*error == '@') {
                errorFile = FILE_HANDLE;
                error++;
            }
            else if (*error == '>') {
                errorFile = FILE_APPEND;
                error++;
            }
            if (!*error && ++i < argc) {
                error = Jim_String(argv[i]);
            }
        }
        else {
            if (strcmp(arg, "|") == 0 || strcmp(arg, "|&") == 0) {
                if (i == lastBar + 1 || i == argc - 1) {
                    Jim_SetResultString(interp, "illegal use of | or |& in command", -1);
                    goto badargs;
                }
                lastBar = i;
                cmdCount++;
            }
            /* Either |, |& or a "normal" arg, so store it in the arg array */
            arg_array[arg_count++] = (char *)arg;
            continue;
        }

        if (i >= argc) {
            Jim_SetResultFormatted(interp, "can't specify \"%s\" as last word in command", arg);
            goto badargs;
        }
    }

    if (arg_count == 0) {
        Jim_SetResultString(interp, "didn't specify command to execute", -1);
badargs:
        Jim_Free(arg_array);
        return -1;
    }

    /* Must do this before vfork(), so do it now */
    save_environ = JimSaveEnv(JimBuildEnv(interp));

    /*
     * Set up the redirected input source for the pipeline, if
     * so requested.
     */
    if (input != NULL) {
        if (inputFile == FILE_TEXT) {
            /*
             * Immediate data in command.  Create temporary file and
             * put data into file.
             */
            inputId = JimCreateTemp(interp, input, input_len);
            if (inputId == JIM_BAD_FD) {
                goto error;
            }
        }
        else if (inputFile == FILE_HANDLE) {
            /* Should be a file descriptor */
            FILE *fh = JimGetAioFilehandle(interp, input);

            if (fh == NULL) {
                goto error;
            }
            inputId = JimDupFd(JimFileno(fh));
        }
        else {
            /*
             * File redirection.  Just open the file.
             */
            inputId = JimOpenForRead(input);
            if (inputId == JIM_BAD_FD) {
                Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", input, JimStrError());
                goto error;
            }
        }
    }
    else if (inPipePtr != NULL) {
        if (JimPipe(pipeIds) != 0) {
            Jim_SetResultErrno(interp, "couldn't create input pipe for command");
            goto error;
        }
        inputId = pipeIds[0];
        *inPipePtr = pipeIds[1];
        pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
    }

    /*
     * Set up the redirected output sink for the pipeline from one
     * of two places, if requested.
     */
    if (output != NULL) {
        if (outputFile == FILE_HANDLE) {
            FILE *fh = JimGetAioFilehandle(interp, output);
            if (fh == NULL) {
                goto error;
            }
            fflush(fh);
            lastOutputId = JimDupFd(JimFileno(fh));
        }
        else {
            /*
             * Output is to go to a file.
             */
            lastOutputId = JimOpenForWrite(output, outputFile == FILE_APPEND);
            if (lastOutputId == JIM_BAD_FD) {
                Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", output, JimStrError());
                goto error;
            }
        }
    }
    else if (outPipePtr != NULL) {
        /*
         * Output is to go to a pipe.
         */
        if (JimPipe(pipeIds) != 0) {
            Jim_SetResultErrno(interp, "couldn't create output pipe");
            goto error;
        }
        lastOutputId = pipeIds[1];
        *outPipePtr = pipeIds[0];
        pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
    }
    /* If we are redirecting stderr with 2>filename or 2>@fileId, then we ignore errFilePtr */
    if (error != NULL) {
        if (errorFile == FILE_HANDLE) {
            if (strcmp(error, "1") == 0) {
                /* Special 2>@1 */
                if (lastOutputId != JIM_BAD_FD) {
                    errorId = JimDupFd(lastOutputId);
                }
                else {
                    /* No redirection of stdout, so just use 2>@stdout */
                    error = "stdout";
                }
            }
            if (errorId == JIM_BAD_FD) {
                FILE *fh = JimGetAioFilehandle(interp, error);
                if (fh == NULL) {
                    goto error;
                }
                fflush(fh);
                errorId = JimDupFd(JimFileno(fh));
            }
        }
        else {
            /*
             * Output is to go to a file.
             */
            errorId = JimOpenForWrite(error, errorFile == FILE_APPEND);
            if (errorId == JIM_BAD_FD) {
                Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", error, JimStrError());
                goto error;
            }
        }
    }
    else if (errFilePtr != NULL) {
        /*
         * Set up the standard error output sink for the pipeline, if
         * requested.  Use a temporary file which is opened, then deleted.
         * Could potentially just use pipe, but if it filled up it could
         * cause the pipeline to deadlock:  we'd be waiting for processes
         * to complete before reading stderr, and processes couldn't complete
         * because stderr was backed up.
         */
        errorId = JimCreateTemp(interp, NULL, 0);
        if (errorId == JIM_BAD_FD) {
            goto error;
        }
        *errFilePtr = JimDupFd(errorId);
    }

    /*
     * Scan through the argc array, forking off a process for each
     * group of arguments between "|" arguments.
     */

    pidPtr = Jim_Alloc(cmdCount * sizeof(*pidPtr));
    for (i = 0; i < numPids; i++) {
        pidPtr[i] = JIM_BAD_PID;
    }
    for (firstArg = 0; firstArg < arg_count; numPids++, firstArg = lastArg + 1) {
        int pipe_dup_err = 0;
        fdtype origErrorId = errorId;

        for (lastArg = firstArg; lastArg < arg_count; lastArg++) {
            if (arg_array[lastArg][0] == '|') {
                if (arg_array[lastArg][1] == '&') {
                    pipe_dup_err = 1;
                }
                break;
            }
        }
        /* Replace | with NULL for execv() */
        arg_array[lastArg] = NULL;
        if (lastArg == arg_count) {
            outputId = lastOutputId;
        }
        else {
            if (JimPipe(pipeIds) != 0) {
                Jim_SetResultErrno(interp, "couldn't create pipe");
                goto error;
            }
            outputId = pipeIds[1];
        }

        /* Now fork the child */

#ifdef __MINGW32__
        pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ ? save_environ[0] : NULL, inputId, outputId, errorId);
        if (pid == JIM_BAD_PID) {
            Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]);
            goto error;
        }
#else
        /*
         * Disable SIGPIPE signals:  if they were allowed, this process
         * might go away unexpectedly if children misbehave.  This code
         * can potentially interfere with other application code that
         * expects to handle SIGPIPEs;  what's really needed is an
         * arbiter for signals to allow them to be "shared".
         */
        if (table->info == NULL) {
            (void)signal(SIGPIPE, SIG_IGN);
        }

        /* Need to do this befor vfork() */
        if (pipe_dup_err) {
            errorId = outputId;
        }

        /*
         * Make a new process and enter it into the table if the fork
         * is successful.
         */
        pid = vfork();
        if (pid < 0) {
            Jim_SetResultErrno(interp, "couldn't fork child process");
            goto error;
        }
        if (pid == 0) {
            /* Child */

            if (inputId != -1) dup2(inputId, 0);
            if (outputId != -1) dup2(outputId, 1);
            if (errorId != -1) dup2(errorId, 2);

            for (i = 3; (i <= outputId) || (i <= inputId) || (i <= errorId); i++) {
                close(i);
            }

            execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron());

            /* Need to prep an error message before vfork(), just in case */
            fprintf(stderr, "couldn't exec \"%s\"", arg_array[firstArg]);
            _exit(127);
        }
#endif

        /* parent */

        /*
         * Enlarge the wait table if there isn't enough space for a new
         * entry.
         */
        if (table->used == table->size) {
            table->size += WAIT_TABLE_GROW_BY;
            table->info = Jim_Realloc(table->info, table->size * sizeof(*table->info));
        }

        table->info[table->used].pid = pid;
        table->info[table->used].flags = 0;
        table->used++;

        pidPtr[numPids] = pid;

        /* Restore in case of pipe_dup_err */
        errorId = origErrorId;

        /*
         * Close off our copies of file descriptors that were set up for
         * this child, then set up the input for the next child.
         */

        if (inputId != JIM_BAD_FD) {
            JimCloseFd(inputId);
        }
        if (outputId != JIM_BAD_FD) {
            JimCloseFd(outputId);
        }
        inputId = pipeIds[0];
        pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
    }
    *pidArrayPtr = pidPtr;

    /*
     * All done.  Cleanup open files lying around and then return.
     */

  cleanup:
    if (inputId != JIM_BAD_FD) {
        JimCloseFd(inputId);
    }
    if (lastOutputId != JIM_BAD_FD) {
        JimCloseFd(lastOutputId);
    }
    if (errorId != JIM_BAD_FD) {
        JimCloseFd(errorId);
    }
    Jim_Free(arg_array);

    JimRestoreEnv(save_environ);

    return numPids;

    /*
     * An error occurred.  There could have been extra files open, such
     * as pipes between children.  Clean them all up.  Detach any child
     * processes that have been created.
     */

  error:
    if ((inPipePtr != NULL) && (*inPipePtr != JIM_BAD_FD)) {
        JimCloseFd(*inPipePtr);
        *inPipePtr = JIM_BAD_FD;
    }
    if ((outPipePtr != NULL) && (*outPipePtr != JIM_BAD_FD)) {
        JimCloseFd(*outPipePtr);
        *outPipePtr = JIM_BAD_FD;
    }
    if ((errFilePtr != NULL) && (*errFilePtr != JIM_BAD_FD)) {
        JimCloseFd(*errFilePtr);
        *errFilePtr = JIM_BAD_FD;
    }
    if (pipeIds[0] != JIM_BAD_FD) {
        JimCloseFd(pipeIds[0]);
    }
    if (pipeIds[1] != JIM_BAD_FD) {
        JimCloseFd(pipeIds[1]);
    }
    if (pidPtr != NULL) {
        for (i = 0; i < numPids; i++) {
            if (pidPtr[i] != JIM_BAD_PID) {
                JimDetachPids(interp, 1, &pidPtr[i]);
            }
        }
        Jim_Free(pidPtr);
    }
    numPids = -1;
    goto cleanup;
}
示例#24
0
文件: jim-exec.c 项目: dokterp/jimtcl
static void Jim_SetResultErrno(Jim_Interp *interp, const char *msg)
{
    Jim_SetResultFormatted(interp, "%s: %s", msg, JimStrError());
}
示例#25
0
int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    int regcomp_flags = 0;
    int regexec_flags = 0;
    int opt_all = 0;
    int offset = 0;
    regex_t *regex;
    const char *p;
    int result;
    regmatch_t pmatch[MAX_SUB_MATCHES + 1];
    int num_matches = 0;

    int i, j, n;
    Jim_Obj *varname;
    Jim_Obj *resultObj;
    const char *source_str;
    int source_len;
    const char *replace_str;
    int replace_len;
    const char *pattern;
    int option;
    enum {
        OPT_NOCASE, OPT_LINE, OPT_ALL, OPT_START, OPT_END
    };
    static const char * const options[] = {
        "-nocase", "-line", "-all", "-start", "--", NULL
    };

    if (argc < 4) {
      wrongNumArgs:
        Jim_WrongNumArgs(interp, 1, argv,
            "?-switch ...? exp string subSpec ?varName?");
        return JIM_ERR;
    }

    for (i = 1; i < argc; i++) {
        const char *opt = Jim_String(argv[i]);

        if (*opt != '-') {
            break;
        }
        if (Jim_GetEnum(interp, argv[i], options, &option, "switch", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
            return JIM_ERR;
        }
        if (option == OPT_END) {
            i++;
            break;
        }
        switch (option) {
            case OPT_NOCASE:
                regcomp_flags |= REG_ICASE;
                break;

            case OPT_LINE:
                regcomp_flags |= REG_NEWLINE;
                break;

            case OPT_ALL:
                opt_all = 1;
                break;

            case OPT_START:
                if (++i == argc) {
                    goto wrongNumArgs;
                }
                if (Jim_GetIndex(interp, argv[i], &offset) != JIM_OK) {
                    return JIM_ERR;
                }
                break;
        }
    }
    if (argc - i != 3 && argc - i != 4) {
        goto wrongNumArgs;
    }

    regex = SetRegexpFromAny(interp, argv[i], regcomp_flags);
    if (!regex) {
        return JIM_ERR;
    }
    pattern = Jim_String(argv[i]);

    source_str = Jim_GetString(argv[i + 1], &source_len);
    replace_str = Jim_GetString(argv[i + 2], &replace_len);
    varname = argv[i + 3];

    /* Create the result string */
    resultObj = Jim_NewStringObj(interp, "", 0);

    /* If an offset has been specified, adjust for that now.
     * If it points past the end of the string, point to the terminating null
     */
    if (offset) {
        if (offset < 0) {
            offset += source_len + 1;
        }
        if (offset > source_len) {
            offset = source_len;
        }
        else if (offset < 0) {
            offset = 0;
        }
    }

    /* Copy the part before -start */
    Jim_AppendString(interp, resultObj, source_str, offset);

    /*
     * The following loop is to handle multiple matches within the
     * same source string;  each iteration handles one match and its
     * corresponding substitution.  If "-all" hasn't been specified
     * then the loop body only gets executed once.
     */

    n = source_len - offset;
    p = source_str + offset;
    do {
        int match = regexec(regex, p, MAX_SUB_MATCHES, pmatch, regexec_flags);

        if (match >= REG_BADPAT) {
            char buf[100];

            regerror(match, regex, buf, sizeof(buf));
            Jim_SetResultFormatted(interp, "error while matching pattern: %s", buf);
            return JIM_ERR;
        }
        if (match == REG_NOMATCH) {
            break;
        }

        num_matches++;

        /*
         * Copy the portion of the source string before the match to the
         * result variable.
         */
        Jim_AppendString(interp, resultObj, p, pmatch[0].rm_so);

        /*
         * Append the subSpec (replace_str) argument to the variable, making appropriate
         * substitutions.  This code is a bit hairy because of the backslash
         * conventions and because the code saves up ranges of characters in
         * subSpec to reduce the number of calls to Jim_SetVar.
         */

        for (j = 0; j < replace_len; j++) {
            int idx;
            int c = replace_str[j];

            if (c == '&') {
                idx = 0;
            }
            else if (c == '\\' && j < replace_len) {
                c = replace_str[++j];
                if ((c >= '0') && (c <= '9')) {
                    idx = c - '0';
                }
                else if ((c == '\\') || (c == '&')) {
                    Jim_AppendString(interp, resultObj, replace_str + j, 1);
                    continue;
                }
                else {
                    /* If the replacement is a trailing backslash, just replace with a backslash, otherwise
                     * with the literal backslash and the following character
                     */
                    Jim_AppendString(interp, resultObj, replace_str + j - 1, (j == replace_len) ? 1 : 2);
                    continue;
                }
            }
            else {
                Jim_AppendString(interp, resultObj, replace_str + j, 1);
                continue;
            }
            if ((idx < MAX_SUB_MATCHES) && pmatch[idx].rm_so != -1 && pmatch[idx].rm_eo != -1) {
                Jim_AppendString(interp, resultObj, p + pmatch[idx].rm_so,
                    pmatch[idx].rm_eo - pmatch[idx].rm_so);
            }
        }

        p += pmatch[0].rm_eo;
        n -= pmatch[0].rm_eo;

        /* If -all is not specified, or there is no source left, we are done */
        if (!opt_all || n == 0) {
            break;
        }

        /* An anchored pattern without -line must be done */
        if ((regcomp_flags & REG_NEWLINE) == 0 && pattern[0] == '^') {
            break;
        }

        /* If the pattern is empty, need to step forwards */
        if (pattern[0] == '\0' && n) {
            /* Need to copy the char we are moving over */
            Jim_AppendString(interp, resultObj, p, 1);
            p++;
            n--;
        }

        regexec_flags |= REG_NOTBOL;
    } while (n);

    /*
     * Copy the portion of the string after the last match to the
     * result variable.
     */
    Jim_AppendString(interp, resultObj, p, -1);

    /* And now set or return the result variable */
    if (argc - i == 4) {
        result = Jim_SetVariable(interp, varname, resultObj);

        if (result == JIM_OK) {
            Jim_SetResultInt(interp, num_matches);
        }
        else {
            Jim_FreeObj(interp, resultObj);
        }
    }
    else {
        Jim_SetResult(interp, resultObj);
        result = JIM_OK;
    }

    return result;
}
示例#26
0
文件: tcl.c 项目: cz172638/openocd
static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args)
{
	int retval;
	struct scan_field *fields;
	int num_fields;
	int field_count = 0;
	int i, e;
	struct jtag_tap *tap;
	tap_state_t endstate;

	/* args[1] = device
	 * args[2] = num_bits
	 * args[3] = hex string
	 * ... repeat num bits and hex string ...
	 *
	 * .. optionally:
	*     args[N-2] = "-endstate"
	 *     args[N-1] = statename
	 */
	if ((argc < 4) || ((argc % 2) != 0)) {
		Jim_WrongNumArgs(interp, 1, args, "wrong arguments");
		return JIM_ERR;
	}

	endstate = TAP_IDLE;

	script_debug(interp, "drscan", argc, args);

	/* validate arguments as numbers */
	e = JIM_OK;
	for (i = 2; i < argc; i += 2) {
		long bits;
		const char *cp;

		e = Jim_GetLong(interp, args[i], &bits);
		/* If valid - try next arg */
		if (e == JIM_OK)
			continue;

		/* Not valid.. are we at the end? */
		if (((i + 2) != argc)) {
			/* nope, then error */
			return e;
		}

		/* it could be: "-endstate FOO"
		 * e.g. DRPAUSE so we can issue more instructions
		 * before entering RUN/IDLE and executing them.
		 */

		/* get arg as a string. */
		cp = Jim_GetString(args[i], NULL);
		/* is it the magic? */
		if (0 == strcmp("-endstate", cp)) {
			/* is the statename valid? */
			cp = Jim_GetString(args[i + 1], NULL);

			/* see if it is a valid state name */
			endstate = tap_state_by_name(cp);
			if (endstate < 0) {
				/* update the error message */
				Jim_SetResultFormatted(interp, "endstate: %s invalid", cp);
			} else {
				if (!scan_is_safe(endstate))
					LOG_WARNING("drscan with unsafe "
						"endstate \"%s\"", cp);

				/* valid - so clear the error */
				e = JIM_OK;
				/* and remove the last 2 args */
				argc -= 2;
			}
		}

		/* Still an error? */
		if (e != JIM_OK)
			return e;	/* too bad */
	}	/* validate args */

	assert(e == JIM_OK);

	tap = jtag_tap_by_jim_obj(interp, args[1]);
	if (tap == NULL)
		return JIM_ERR;

	num_fields = (argc-2)/2;
	if (num_fields <= 0) {
		Jim_SetResultString(interp, "drscan: no scan fields supplied", -1);
		return JIM_ERR;
	}
	fields = malloc(sizeof(struct scan_field) * num_fields);
	for (i = 2; i < argc; i += 2) {
		long bits;
		int len;
		const char *str;

		Jim_GetLong(interp, args[i], &bits);
		str = Jim_GetString(args[i + 1], &len);

		fields[field_count].num_bits = bits;
		void *t = malloc(DIV_ROUND_UP(bits, 8));
		fields[field_count].out_value = t;
		str_to_buf(str, len, t, bits, 0);
		fields[field_count].in_value = t;
		field_count++;
	}

	jtag_add_dr_scan(tap, num_fields, fields, endstate);

	retval = jtag_execute_queue();
	if (retval != ERROR_OK) {
		Jim_SetResultString(interp, "drscan: jtag execute failed", -1);
		return JIM_ERR;
	}

	field_count = 0;
	Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
	for (i = 2; i < argc; i += 2) {
		long bits;
		char *str;

		Jim_GetLong(interp, args[i], &bits);
		str = buf_to_str(fields[field_count].in_value, bits, 16);
		free(fields[field_count].in_value);

		Jim_ListAppendElement(interp, list, Jim_NewStringObj(interp, str, strlen(str)));
		free(str);
		field_count++;
	}

	Jim_SetResult(interp, list);

	free(fields);

	return JIM_OK;
}
示例#27
0
文件: rtos.c 项目: Xplorer001/openocd
int rtos_create(Jim_GetOptInfo *goi, struct target * target)
{
	int x;
	char *cp;

	if (! goi->isconfigure) {
		if (goi->argc != 0) {
			if (goi->argc != 0) {
				Jim_WrongNumArgs(goi->interp,
						goi->argc, goi->argv,
						"NO PARAMS");
				return JIM_ERR;
			}

			Jim_SetResultString(goi->interp,
					target_type_name(target), -1);
		}
	}

	if (target->rtos) {
		free((void *)(target->rtos));
	}
//			e = Jim_GetOpt_String(goi, &cp, NULL);
//			target->rtos = strdup(cp);

	Jim_GetOpt_String(goi, &cp, NULL);
	/* now does target type exist */

	if ( 0 == strcmp( cp, "auto") )
	{
		// auto detection of RTOS
		target->rtos_auto_detect = true;
		x = 0;
	}
	else
	{

		for (x = 0 ; rtos_types[x] ; x++) {
			if (0 == strcmp(cp, rtos_types[x]->name)) {
				/* found */
				break;
			}
		}
		if (rtos_types[x] == NULL) {
			Jim_SetResultFormatted(goi->interp, "Unknown rtos type %s, try one of ", cp);
			for (x = 0 ; rtos_types[x] ; x++) {
				if (rtos_types[x + 1]) {
					Jim_AppendStrings(goi->interp,
									   Jim_GetResult(goi->interp),
									   rtos_types[x]->name,
									   ", ", NULL);
				} else {
					Jim_AppendStrings(goi->interp,
									   Jim_GetResult(goi->interp),
									   " or ",
									   rtos_types[x]->name,NULL);
				}
			}
			return JIM_ERR;
		}
	}
	/* Create it */
	target->rtos = calloc(1,sizeof(struct rtos));
	target->rtos->type = rtos_types[x];
	target->rtos->current_thread = 0;
	target->rtos->symbols = NULL;
	target->rtos->target = target;

	if ( 0 != strcmp( cp, "auto") )
	{
		target->rtos->type->create( target );
	}

	return JIM_OK;
}
示例#28
0
void Jim_SetResultErrno(Jim_Interp *interp, const char *msg)
{
    Jim_SetResultFormatted(interp, "%s: %s", msg, strerror(Jim_Errno()));
}
示例#29
0
static int JimELAfterCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    Jim_EventLoop *eventLoop = Jim_CmdPrivData(interp);
    double ms = 0;
    jim_wide id;
    Jim_Obj *objPtr, *idObjPtr;
    static const char * const options[] = {
        "cancel", "info", "idle", NULL
    };
    enum
    { AFTER_CANCEL, AFTER_INFO, AFTER_IDLE, AFTER_RESTART, AFTER_EXPIRE, AFTER_CREATE };
    int option = AFTER_CREATE;

    if (argc < 2) {
        Jim_WrongNumArgs(interp, 1, argv, "option ?arg ...?");
        return JIM_ERR;
    }
    if (Jim_GetDouble(interp, argv[1], &ms) != JIM_OK) {
        if (Jim_GetEnum(interp, argv[1], options, &option, "argument", JIM_ERRMSG) != JIM_OK) {
            return JIM_ERR;
        }
        Jim_SetEmptyResult(interp);
    }
    else if (argc == 2) {
        /* Simply a sleep */
        usleep(ms * 1000);
        return JIM_OK;
    }

    switch (option) {
        case AFTER_IDLE:
            if (argc < 3) {
                Jim_WrongNumArgs(interp, 2, argv, "script ?script ...?");
                return JIM_ERR;
            }
            /* fall through */
        case AFTER_CREATE: {
            Jim_Obj *scriptObj = Jim_ConcatObj(interp, argc - 2, argv + 2);
            Jim_IncrRefCount(scriptObj);
            id = Jim_CreateTimeHandler(interp, (jim_wide)(ms * 1000), JimAfterTimeHandler, scriptObj,
                JimAfterTimeEventFinalizer);
            objPtr = Jim_NewStringObj(interp, NULL, 0);
            Jim_AppendString(interp, objPtr, "after#", -1);
            idObjPtr = Jim_NewIntObj(interp, id);
            Jim_IncrRefCount(idObjPtr);
            Jim_AppendObj(interp, objPtr, idObjPtr);
            Jim_DecrRefCount(interp, idObjPtr);
            Jim_SetResult(interp, objPtr);
            return JIM_OK;
        }
        case AFTER_CANCEL:
            if (argc < 3) {
                Jim_WrongNumArgs(interp, 2, argv, "id|command");
                return JIM_ERR;
            }
            else {
                jim_wide remain = 0;

                id = JimParseAfterId(argv[2]);
                if (id <= 0) {
                    /* Not an event id, so search by script */
                    Jim_Obj *scriptObj = Jim_ConcatObj(interp, argc - 2, argv + 2);
                    id = JimFindAfterByScript(eventLoop, scriptObj);
                    Jim_FreeNewObj(interp, scriptObj);
                    if (id <= 0) {
                        /* Not found */
                        break;
                    }
                }
                remain = Jim_DeleteTimeHandler(interp, id);
                if (remain >= 0) {
                    Jim_SetResultInt(interp, remain);
                }
            }
            break;

        case AFTER_INFO:
            if (argc == 2) {
                Jim_TimeEvent *te = eventLoop->timeEventHead;
                Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
                char buf[30];
                const char *fmt = "after#%" JIM_WIDE_MODIFIER;

                while (te) {
                    snprintf(buf, sizeof(buf), fmt, te->id);
                    Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, buf, -1));
                    te = te->next;
                }
                Jim_SetResult(interp, listObj);
            }
            else if (argc == 3) {
                id = JimParseAfterId(argv[2]);
                if (id >= 0) {
                    Jim_TimeEvent *e = JimFindTimeHandlerById(eventLoop, id);
                    if (e && e->timeProc == JimAfterTimeHandler) {
                        Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
                        Jim_ListAppendElement(interp, listObj, e->clientData);
                        Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, e->initialus ? "timer" : "idle", -1));
                        Jim_SetResult(interp, listObj);
                        return JIM_OK;
                    }
                }
                Jim_SetResultFormatted(interp, "event \"%#s\" doesn't exist", argv[2]);
                return JIM_ERR;
            }
            else {
                Jim_WrongNumArgs(interp, 2, argv, "?id?");
                return JIM_ERR;
            }
            break;
    }
    return JIM_OK;
}
示例#30
0
int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    int opt_indices = 0;
    int opt_all = 0;
    int opt_inline = 0;
    regex_t *regex;
    int match, i, j;
    int offset = 0;
    regmatch_t *pmatch = NULL;
    int source_len;
    int result = JIM_OK;
    const char *pattern;
    const char *source_str;
    int num_matches = 0;
    int num_vars;
    Jim_Obj *resultListObj = NULL;
    int regcomp_flags = 0;
    int eflags = 0;
    int option;
    enum {
        OPT_INDICES,  OPT_NOCASE, OPT_LINE, OPT_ALL, OPT_INLINE, OPT_START, OPT_END
    };
    static const char * const options[] = {
        "-indices", "-nocase", "-line", "-all", "-inline", "-start", "--", NULL
    };

    if (argc < 3) {
      wrongNumArgs:
        Jim_WrongNumArgs(interp, 1, argv,
            "?-switch ...? exp string ?matchVar? ?subMatchVar ...?");
        return JIM_ERR;
    }

    for (i = 1; i < argc; i++) {
        const char *opt = Jim_String(argv[i]);

        if (*opt != '-') {
            break;
        }
        if (Jim_GetEnum(interp, argv[i], options, &option, "switch", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
            return JIM_ERR;
        }
        if (option == OPT_END) {
            i++;
            break;
        }
        switch (option) {
            case OPT_INDICES:
                opt_indices = 1;
                break;

            case OPT_NOCASE:
                regcomp_flags |= REG_ICASE;
                break;

            case OPT_LINE:
                regcomp_flags |= REG_NEWLINE;
                break;

            case OPT_ALL:
                opt_all = 1;
                break;

            case OPT_INLINE:
                opt_inline = 1;
                break;

            case OPT_START:
                if (++i == argc) {
                    goto wrongNumArgs;
                }
                if (Jim_GetIndex(interp, argv[i], &offset) != JIM_OK) {
                    return JIM_ERR;
                }
                break;
        }
    }
    if (argc - i < 2) {
        goto wrongNumArgs;
    }

    regex = SetRegexpFromAny(interp, argv[i], regcomp_flags);
    if (!regex) {
        return JIM_ERR;
    }

    pattern = Jim_String(argv[i]);
    source_str = Jim_GetString(argv[i + 1], &source_len);

    num_vars = argc - i - 2;

    if (opt_inline) {
        if (num_vars) {
            Jim_SetResultString(interp, "regexp match variables not allowed when using -inline",
                -1);
            result = JIM_ERR;
            goto done;
        }
        num_vars = regex->re_nsub + 1;
    }

    pmatch = Jim_Alloc((num_vars + 1) * sizeof(*pmatch));

    /* If an offset has been specified, adjust for that now.
     * If it points past the end of the string, point to the terminating null
     */
    if (offset) {
        if (offset < 0) {
            offset += source_len + 1;
        }
        if (offset > source_len) {
            source_str += source_len;
        }
        else if (offset > 0) {
            source_str += offset;
        }
        eflags |= REG_NOTBOL;
    }

    if (opt_inline) {
        resultListObj = Jim_NewListObj(interp, NULL, 0);
    }

  next_match:
    match = regexec(regex, source_str, num_vars + 1, pmatch, eflags);
    if (match >= REG_BADPAT) {
        char buf[100];

        regerror(match, regex, buf, sizeof(buf));
        Jim_SetResultFormatted(interp, "error while matching pattern: %s", buf);
        result = JIM_ERR;
        goto done;
    }

    if (match == REG_NOMATCH) {
        goto done;
    }

    num_matches++;

    if (opt_all && !opt_inline) {
        /* Just count the number of matches, so skip the substitution h */
        goto try_next_match;
    }

    /*
     * If additional variable names have been specified, return
     * index information in those variables.
     */

    j = 0;
    for (i += 2; opt_inline ? j < num_vars : i < argc; i++, j++) {
        Jim_Obj *resultObj;

        if (opt_indices) {
            resultObj = Jim_NewListObj(interp, NULL, 0);
        }
        else {
            resultObj = Jim_NewStringObj(interp, "", 0);
        }

        if (pmatch[j].rm_so == -1) {
            if (opt_indices) {
                Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, -1));
                Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, -1));
            }
        }
        else {
            int len = pmatch[j].rm_eo - pmatch[j].rm_so;

            if (opt_indices) {
                Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp,
                        offset + pmatch[j].rm_so));
                Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp,
                        offset + pmatch[j].rm_so + len - 1));
            }
            else {
                Jim_AppendString(interp, resultObj, source_str + pmatch[j].rm_so, len);
            }
        }

        if (opt_inline) {
            Jim_ListAppendElement(interp, resultListObj, resultObj);
        }
        else {
            /* And now set the result variable */
            result = Jim_SetVariable(interp, argv[i], resultObj);

            if (result != JIM_OK) {
                Jim_FreeObj(interp, resultObj);
                break;
            }
        }
    }

  try_next_match:
    if (opt_all && (pattern[0] != '^' || (regcomp_flags & REG_NEWLINE)) && *source_str) {
        if (pmatch[0].rm_eo) {
            offset += pmatch[0].rm_eo;
            source_str += pmatch[0].rm_eo;
        }
        else {
            source_str++;
            offset++;
        }
        if (*source_str) {
            eflags = REG_NOTBOL;
            goto next_match;
        }
    }

  done:
    if (result == JIM_OK) {
        if (opt_inline) {
            Jim_SetResult(interp, resultListObj);
        }
        else {
            Jim_SetResultInt(interp, num_matches);
        }
    }

    Jim_Free(pmatch);
    return result;
}