aboutsummaryrefslogtreecommitdiff
path: root/src/helper
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2023-09-12 12:55:10 -0700
committerTim Newsome <tim@sifive.com>2023-09-12 12:55:10 -0700
commit8c1f1b77d33b4134fdf196df00c9896cd606221a (patch)
tree94be292a28a52a4453ceb9ac4f357833a2cc8a2d /src/helper
parent67c2835997c206ddeba58cfc0fad76789db7474b (diff)
parentee31f1578a333a75737bc5b183cd4ae98cdaf798 (diff)
downloadriscv-openocd-8c1f1b77d33b4134fdf196df00c9896cd606221a.zip
riscv-openocd-8c1f1b77d33b4134fdf196df00c9896cd606221a.tar.gz
riscv-openocd-8c1f1b77d33b4134fdf196df00c9896cd606221a.tar.bz2
Merge commit 'ee31f1578a333a75737bc5b183cd4ae98cdaf798' into from_upstream
Conflicts: Makefile.am jimtcl src/helper/Makefile.am src/rtos/rtos.c src/rtos/rtos.h src/rtos/rtos_standard_stackings.c Change-Id: I00c98d20089558744988184370a8cb7f95f03329
Diffstat (limited to 'src/helper')
-rw-r--r--src/helper/Makefile.am5
-rw-r--r--src/helper/command.c15
-rw-r--r--src/helper/command.h11
-rw-r--r--src/helper/compiler.h52
-rw-r--r--src/helper/nvp.c67
-rw-r--r--src/helper/nvp.h77
6 files changed, 221 insertions, 6 deletions
diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am
index 26ff0bd..39d93d6 100644
--- a/src/helper/Makefile.am
+++ b/src/helper/Makefile.am
@@ -16,6 +16,7 @@ noinst_LTLIBRARIES += %D%/libhelper.la
%D%/util.c \
%D%/jep106.c \
%D%/jim-nvp.c \
+ %D%/nvp.c \
%D%/align.h \
%D%/binarybuffer.h \
%D%/bits.h \
@@ -34,7 +35,9 @@ noinst_LTLIBRARIES += %D%/libhelper.la
%D%/jep106.inc \
%D%/jim-nvp.h \
%D%/base64.c \
- %D%/base64.h
+ %D%/base64.h \
+ %D%/nvp.h \
+ %D%/compiler.h
STARTUP_TCL_SRCS += %D%/startup.tcl
EXTRA_DIST += \
diff --git a/src/helper/command.c b/src/helper/command.c
index ca66cf7..b358e18 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -18,9 +18,6 @@
#include "config.h"
#endif
-/* see Embedded-HOWTO.txt in Jim Tcl project hosted on BerliOS*/
-#define JIM_EMBEDDED
-
/* @todo the inclusion of target.h here is a layering violation */
#include <jtag/jtag.h>
#include <target/target.h>
@@ -543,8 +540,16 @@ static int run_command(struct command_context *context,
if (retval != ERROR_OK)
LOG_DEBUG("Command '%s' failed with error code %d",
words[0], retval);
- /* Use the command output as the Tcl result */
- Jim_SetResult(context->interp, cmd.output);
+ /*
+ * Use the command output as the Tcl result.
+ * Drop last '\n' to allow command output concatenation
+ * while keep using command_print() everywhere.
+ */
+ const char *output_txt = Jim_String(cmd.output);
+ int len = strlen(output_txt);
+ if (len && output_txt[len - 1] == '\n')
+ --len;
+ Jim_SetResultString(context->interp, output_txt, len);
}
Jim_DecrRefCount(context->interp, cmd.output);
diff --git a/src/helper/command.h b/src/helper/command.h
index 478e5c8..42cb9cb 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -370,10 +370,21 @@ struct command_context *copy_command_context(struct command_context *cmd_ctx);
*/
void command_done(struct command_context *context);
+/*
+ * command_print() and command_print_sameline() are used to produce the TCL
+ * output of OpenOCD commands. command_print() automatically adds a '\n' at
+ * the end or the format string. Use command_print_sameline() to avoid the
+ * trailing '\n', e.g. to concatenate the command output in the same line.
+ * The very last '\n' of the command is stripped away (see run_command()).
+ * For commands that strictly require a '\n' as last output character, add
+ * it explicitly with either an empty command_print() or with a '\n' in the
+ * last command_print() and add a comment to document it.
+ */
void command_print(struct command_invocation *cmd, const char *format, ...)
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));
void command_print_sameline(struct command_invocation *cmd, const char *format, ...)
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));
+
int command_run_line(struct command_context *context, char *line);
int command_run_linef(struct command_context *context, const char *format, ...)
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));
diff --git a/src/helper/compiler.h b/src/helper/compiler.h
new file mode 100644
index 0000000..33a075d
--- /dev/null
+++ b/src/helper/compiler.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * This file contains compiler specific workarounds to handle different
+ * compilers and different compiler versions.
+ * Inspired by Linux's include/linux/compiler_attributes.h
+ * and file sys/cdefs.h in libc and newlib.
+ */
+
+#ifndef OPENOCD_HELPER_COMPILER_H
+#define OPENOCD_HELPER_COMPILER_H
+
+/*
+ * __has_attribute is supported on gcc >= 5, clang >= 2.9 and icc >= 17.
+ */
+#ifndef __has_attribute
+# define __has_attribute(x) 0
+#endif
+
+/*
+ * The __returns_nonnull function attribute marks the return type of the function
+ * as always being non-null.
+ */
+#ifndef __returns_nonnull
+# if __has_attribute(__returns_nonnull__)
+# define __returns_nonnull __attribute__((__returns_nonnull__))
+# else
+# define __returns_nonnull
+# endif
+#endif
+
+/*
+ * The __nonnull function attribute marks pointer parameters that
+ * must not be NULL.
+ *
+ * clang for Apple defines
+ * #define __nonnull _Nonnull
+ * that is a per argument attribute, incompatible with the gcc per function attribute __nonnull__.
+ * Undefine it to keep compatibility among compilers.
+ */
+#if defined(__clang__) && defined(__APPLE__)
+# undef __nonnull
+#endif
+#ifndef __nonnull
+# if __has_attribute(__nonnull__)
+# define __nonnull(params) __attribute__ ((__nonnull__ params))
+# else
+# define __nonnull(params)
+# endif
+#endif
+
+#endif /* OPENOCD_HELPER_COMPILER_H */
diff --git a/src/helper/nvp.c b/src/helper/nvp.c
new file mode 100644
index 0000000..7a8abc2
--- /dev/null
+++ b/src/helper/nvp.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: BSD-2-Clause-Views
+
+/*
+ * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
+ * Copyright 2005 Clemens Hintze <c.hintze@gmx.net>
+ * Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>
+ * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com
+ * Copyright 2008 Andrew Lunn <andrew@lunn.ch>
+ * Copyright 2008 Duane Ellis <openocd@duaneellis.com>
+ * Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>
+ * Copyright 2008 Steve Bennett <steveb@workware.net.au>
+ * Copyright 2009 Nico Coesel <ncoesel@dealogic.nl>
+ * Copyright 2009 Zachary T Welch zw@superlucidity.net
+ * Copyright 2009 David Brownell
+ * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved.
+ *
+ * This file is extracted from jim_nvp.c, originally part of jim TCL code.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <helper/command.h>
+#include <helper/nvp.h>
+
+const struct nvp *nvp_name2value(const struct nvp *p, const char *name)
+{
+ while (p->name) {
+ if (strcmp(name, p->name) == 0)
+ break;
+ p++;
+ }
+ return p;
+}
+
+const struct nvp *nvp_value2name(const struct nvp *p, int value)
+{
+ while (p->name) {
+ if (value == p->value)
+ break;
+ p++;
+ }
+ return p;
+}
+
+void nvp_unknown_command_print(struct command_invocation *cmd, const struct nvp *nvp,
+ const char *param_name, const char *param_value)
+{
+ if (param_name)
+ command_print_sameline(cmd, "%s: Unknown: %s, try one of: ", param_name, param_value);
+ else
+ command_print_sameline(cmd, "Unknown param: %s, try one of: ", param_value);
+
+ while (nvp->name) {
+ if ((nvp + 1)->name)
+ command_print_sameline(cmd, "%s, ", nvp->name);
+ else
+ command_print(cmd, "or %s", nvp->name);
+
+ nvp++;
+ }
+
+ /* We assume nvp to be not empty and loop has been taken; no need to add a '\n' */
+}
diff --git a/src/helper/nvp.h b/src/helper/nvp.h
new file mode 100644
index 0000000..14bd9b0
--- /dev/null
+++ b/src/helper/nvp.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: BSD-2-Clause-Views */
+
+/*
+ * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
+ * Copyright 2005 Clemens Hintze <c.hintze@gmx.net>
+ * Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>
+ * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com
+ * Copyright 2008 Andrew Lunn <andrew@lunn.ch>
+ * Copyright 2008 Duane Ellis <openocd@duaneellis.com>
+ * Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>
+ * Copyright 2008 Steve Bennett <steveb@workware.net.au>
+ * Copyright 2009 Nico Coesel <ncoesel@dealogic.nl>
+ * Copyright 2009 Zachary T Welch zw@superlucidity.net
+ * Copyright 2009 David Brownell
+ * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved.
+ *
+ * This file is extracted from jim_nvp.h, originally part of jim TCL code.
+ */
+
+#ifndef OPENOCD_HELPER_NVP_H
+#define OPENOCD_HELPER_NVP_H
+
+#include <helper/compiler.h>
+
+/** Name Value Pairs, aka: NVP
+ * - Given a string - return the associated int.
+ * - Given a number - return the associated string.
+ * .
+ *
+ * Very useful when the number is not a simple index into an array of
+ * known string, or there may be multiple strings (aliases) that mean then same
+ * thing.
+ *
+ * An NVP Table is terminated with ".name = NULL".
+ *
+ * During the 'name2value' operation, if no matching string is found
+ * the pointer to the terminal element (with p->name == NULL) is returned.
+ *
+ * Example:
+ * \code
+ * const struct nvp yn[] = {
+ * { "yes", 1 },
+ * { "no" , 0 },
+ * { "yep", 1 },
+ * { "nope", 0 },
+ * { NULL, -1 },
+ * };
+ *
+ * struct nvp *result;
+ * result = nvp_name2value(yn, "yes");
+ * returns &yn[0];
+ * result = nvp_name2value(yn, "no");
+ * returns &yn[1];
+ * result = jim_nvp_name2value(yn, "Blah");
+ * returns &yn[4];
+ * \endcode
+ *
+ * During the number2name operation, the first matching value is returned.
+ */
+
+struct nvp {
+ const char *name;
+ int value;
+};
+
+struct command_invocation;
+
+/* Name Value Pairs Operations */
+const struct nvp *nvp_name2value(const struct nvp *nvp_table, const char *name)
+ __returns_nonnull __nonnull((1));
+const struct nvp *nvp_value2name(const struct nvp *nvp_table, int v)
+ __returns_nonnull __nonnull((1));
+
+void nvp_unknown_command_print(struct command_invocation *cmd, const struct nvp *nvp,
+ const char *param_name, const char *param_value);
+
+#endif /* OPENOCD_HELPER_NVP_H */