debuggers: import openocd-0.7.0
Initial check-in of openocd-0.7.0 as it can be downloaded from http://sourceforge.net/projects/openocd/files/openocd/0.7.0/ Any modifications will follow. Change-Id: I6949beaefd589e046395ea0cb80f4e1ab1654d55
This commit is contained in:
59
debuggers/openocd/src/helper/Makefile.am
Normal file
59
debuggers/openocd/src/helper/Makefile.am
Normal file
@ -0,0 +1,59 @@
|
||||
include $(top_srcdir)/common.mk
|
||||
|
||||
METASOURCES = AUTO
|
||||
noinst_LTLIBRARIES = libhelper.la
|
||||
|
||||
CONFIGFILES = options.c time_support_common.c
|
||||
|
||||
libhelper_la_SOURCES = \
|
||||
binarybuffer.c \
|
||||
$(CONFIGFILES) \
|
||||
configuration.c \
|
||||
log.c \
|
||||
command.c \
|
||||
time_support.c \
|
||||
replacements.c \
|
||||
fileio.c \
|
||||
util.c \
|
||||
jim-nvp.c
|
||||
|
||||
if IOUTIL
|
||||
libhelper_la_SOURCES += ioutil.c
|
||||
else
|
||||
libhelper_la_SOURCES += ioutil_stubs.c
|
||||
endif
|
||||
|
||||
libhelper_la_CFLAGS =
|
||||
if IS_MINGW
|
||||
# FD_* macros are sloppy with their signs on MinGW32 platform
|
||||
libhelper_la_CFLAGS += -Wno-sign-compare
|
||||
endif
|
||||
|
||||
noinst_HEADERS = \
|
||||
binarybuffer.h \
|
||||
configuration.h \
|
||||
ioutil.h \
|
||||
list.h \
|
||||
util.h \
|
||||
types.h \
|
||||
log.h \
|
||||
command.h \
|
||||
time_support.h \
|
||||
replacements.h \
|
||||
fileio.h \
|
||||
system.h \
|
||||
bin2char.c \
|
||||
jim-nvp.h
|
||||
|
||||
EXTRA_DIST = startup.tcl
|
||||
|
||||
BIN2C = bin2char$(EXEEXT_FOR_BUILD)
|
||||
|
||||
BUILT_SOURCES = $(BIN2C)
|
||||
|
||||
$(BIN2C): bin2char.c
|
||||
${CC_FOR_BUILD} ${CFLAGS_FOR_BUILD} $(srcdir)/bin2char.c -o $@
|
||||
|
||||
CLEANFILES = bin2char$(EXEEXT_FOR_BUILD)
|
||||
|
||||
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
|
||||
716
debuggers/openocd/src/helper/Makefile.in
Normal file
716
debuggers/openocd/src/helper/Makefile.in
Normal file
@ -0,0 +1,716 @@
|
||||
# Makefile.in generated by automake 1.13.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2012 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
am__make_dryrun = \
|
||||
{ \
|
||||
am__dry=no; \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
|
||||
| grep '^AM OK$$' >/dev/null || am__dry=yes;; \
|
||||
*) \
|
||||
for am__flg in $$MAKEFLAGS; do \
|
||||
case $$am__flg in \
|
||||
*=*|--*) ;; \
|
||||
*n*) am__dry=yes; break;; \
|
||||
esac; \
|
||||
done;; \
|
||||
esac; \
|
||||
test $$am__dry = yes; \
|
||||
}
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
DIST_COMMON = $(top_srcdir)/common.mk $(srcdir)/Makefile.in \
|
||||
$(srcdir)/Makefile.am $(top_srcdir)/depcomp $(noinst_HEADERS)
|
||||
@INTERNAL_JIMTCL_TRUE@am__append_1 = -I$(top_srcdir)/jimtcl \
|
||||
@INTERNAL_JIMTCL_TRUE@ -I$(top_builddir)/jimtcl
|
||||
|
||||
@IOUTIL_TRUE@am__append_2 = ioutil.c
|
||||
@IOUTIL_FALSE@am__append_3 = ioutil_stubs.c
|
||||
# FD_* macros are sloppy with their signs on MinGW32 platform
|
||||
@IS_MINGW_TRUE@am__append_4 = -Wno-sign-compare
|
||||
subdir = src/helper
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/config_subdir.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||
libhelper_la_LIBADD =
|
||||
am__libhelper_la_SOURCES_DIST = binarybuffer.c options.c \
|
||||
time_support_common.c configuration.c log.c command.c \
|
||||
time_support.c replacements.c fileio.c util.c jim-nvp.c \
|
||||
ioutil.c ioutil_stubs.c
|
||||
am__objects_1 = libhelper_la-options.lo \
|
||||
libhelper_la-time_support_common.lo
|
||||
@IOUTIL_TRUE@am__objects_2 = libhelper_la-ioutil.lo
|
||||
@IOUTIL_FALSE@am__objects_3 = libhelper_la-ioutil_stubs.lo
|
||||
am_libhelper_la_OBJECTS = libhelper_la-binarybuffer.lo \
|
||||
$(am__objects_1) libhelper_la-configuration.lo \
|
||||
libhelper_la-log.lo libhelper_la-command.lo \
|
||||
libhelper_la-time_support.lo libhelper_la-replacements.lo \
|
||||
libhelper_la-fileio.lo libhelper_la-util.lo \
|
||||
libhelper_la-jim-nvp.lo $(am__objects_2) $(am__objects_3)
|
||||
libhelper_la_OBJECTS = $(am_libhelper_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
am__v_lt_0 = --silent
|
||||
am__v_lt_1 =
|
||||
libhelper_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libhelper_la_CFLAGS) \
|
||||
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
|
||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||
$(AM_CFLAGS) $(CFLAGS)
|
||||
AM_V_CC = $(am__v_CC_@AM_V@)
|
||||
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
am__v_CC_1 =
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
|
||||
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
|
||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
am__v_CCLD_1 =
|
||||
SOURCES = $(libhelper_la_SOURCES)
|
||||
DIST_SOURCES = $(am__libhelper_la_SOURCES_DIST)
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
HEADERS = $(noinst_HEADERS)
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
am__uniquify_input = $(AWK) '\
|
||||
BEGIN { nonempty = 0; } \
|
||||
{ items[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in items) print i; }; } \
|
||||
'
|
||||
# Make sure the list of sources is unique. This is necessary because,
|
||||
# e.g., the same source file might be shared among _SOURCES variables
|
||||
# for different programs/libraries.
|
||||
am__define_uniq_tagged_files = \
|
||||
list='$(am__tagged_files)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CC_FOR_BUILD = @CC_FOR_BUILD@
|
||||
CFLAGS = @CFLAGS@
|
||||
CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBTOOL_DEPS = @LIBTOOL_DEPS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
doxygen_as_html = @doxygen_as_html@
|
||||
doxygen_as_pdf = @doxygen_as_pdf@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
subdirs = @subdirs@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
# common flags used in openocd build
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src \
|
||||
-I$(top_srcdir)/src/helper -DPKGDATADIR=\"$(pkgdatadir)\" \
|
||||
-DPKGLIBDIR=\"$(pkglibdir)\" $(am__append_1)
|
||||
METASOURCES = AUTO
|
||||
noinst_LTLIBRARIES = libhelper.la
|
||||
CONFIGFILES = options.c time_support_common.c
|
||||
libhelper_la_SOURCES = binarybuffer.c $(CONFIGFILES) configuration.c \
|
||||
log.c command.c time_support.c replacements.c fileio.c util.c \
|
||||
jim-nvp.c $(am__append_2) $(am__append_3)
|
||||
libhelper_la_CFLAGS = $(am__append_4)
|
||||
noinst_HEADERS = \
|
||||
binarybuffer.h \
|
||||
configuration.h \
|
||||
ioutil.h \
|
||||
list.h \
|
||||
util.h \
|
||||
types.h \
|
||||
log.h \
|
||||
command.h \
|
||||
time_support.h \
|
||||
replacements.h \
|
||||
fileio.h \
|
||||
system.h \
|
||||
bin2char.c \
|
||||
jim-nvp.h
|
||||
|
||||
EXTRA_DIST = startup.tcl
|
||||
BIN2C = bin2char$(EXEEXT_FOR_BUILD)
|
||||
BUILT_SOURCES = $(BIN2C)
|
||||
CLEANFILES = bin2char$(EXEEXT_FOR_BUILD)
|
||||
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
|
||||
all: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/common.mk $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/helper/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu src/helper/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
$(top_srcdir)/common.mk:
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
clean-noinstLTLIBRARIES:
|
||||
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
|
||||
@list='$(noinst_LTLIBRARIES)'; \
|
||||
locs=`for p in $$list; do echo $$p; done | \
|
||||
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
|
||||
sort -u`; \
|
||||
test -z "$$locs" || { \
|
||||
echo rm -f $${locs}; \
|
||||
rm -f $${locs}; \
|
||||
}
|
||||
libhelper.la: $(libhelper_la_OBJECTS) $(libhelper_la_DEPENDENCIES) $(EXTRA_libhelper_la_DEPENDENCIES)
|
||||
$(AM_V_CCLD)$(libhelper_la_LINK) $(libhelper_la_OBJECTS) $(libhelper_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-binarybuffer.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-command.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-configuration.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-fileio.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-ioutil.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-ioutil_stubs.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-jim-nvp.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-log.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-options.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-replacements.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-time_support.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-time_support_common.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhelper_la-util.Plo@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
libhelper_la-binarybuffer.lo: binarybuffer.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-binarybuffer.lo -MD -MP -MF $(DEPDIR)/libhelper_la-binarybuffer.Tpo -c -o libhelper_la-binarybuffer.lo `test -f 'binarybuffer.c' || echo '$(srcdir)/'`binarybuffer.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-binarybuffer.Tpo $(DEPDIR)/libhelper_la-binarybuffer.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='binarybuffer.c' object='libhelper_la-binarybuffer.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-binarybuffer.lo `test -f 'binarybuffer.c' || echo '$(srcdir)/'`binarybuffer.c
|
||||
|
||||
libhelper_la-options.lo: options.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-options.lo -MD -MP -MF $(DEPDIR)/libhelper_la-options.Tpo -c -o libhelper_la-options.lo `test -f 'options.c' || echo '$(srcdir)/'`options.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-options.Tpo $(DEPDIR)/libhelper_la-options.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='options.c' object='libhelper_la-options.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-options.lo `test -f 'options.c' || echo '$(srcdir)/'`options.c
|
||||
|
||||
libhelper_la-time_support_common.lo: time_support_common.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-time_support_common.lo -MD -MP -MF $(DEPDIR)/libhelper_la-time_support_common.Tpo -c -o libhelper_la-time_support_common.lo `test -f 'time_support_common.c' || echo '$(srcdir)/'`time_support_common.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-time_support_common.Tpo $(DEPDIR)/libhelper_la-time_support_common.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='time_support_common.c' object='libhelper_la-time_support_common.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-time_support_common.lo `test -f 'time_support_common.c' || echo '$(srcdir)/'`time_support_common.c
|
||||
|
||||
libhelper_la-configuration.lo: configuration.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-configuration.lo -MD -MP -MF $(DEPDIR)/libhelper_la-configuration.Tpo -c -o libhelper_la-configuration.lo `test -f 'configuration.c' || echo '$(srcdir)/'`configuration.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-configuration.Tpo $(DEPDIR)/libhelper_la-configuration.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='configuration.c' object='libhelper_la-configuration.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-configuration.lo `test -f 'configuration.c' || echo '$(srcdir)/'`configuration.c
|
||||
|
||||
libhelper_la-log.lo: log.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-log.lo -MD -MP -MF $(DEPDIR)/libhelper_la-log.Tpo -c -o libhelper_la-log.lo `test -f 'log.c' || echo '$(srcdir)/'`log.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-log.Tpo $(DEPDIR)/libhelper_la-log.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='log.c' object='libhelper_la-log.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-log.lo `test -f 'log.c' || echo '$(srcdir)/'`log.c
|
||||
|
||||
libhelper_la-command.lo: command.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-command.lo -MD -MP -MF $(DEPDIR)/libhelper_la-command.Tpo -c -o libhelper_la-command.lo `test -f 'command.c' || echo '$(srcdir)/'`command.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-command.Tpo $(DEPDIR)/libhelper_la-command.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='command.c' object='libhelper_la-command.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-command.lo `test -f 'command.c' || echo '$(srcdir)/'`command.c
|
||||
|
||||
libhelper_la-time_support.lo: time_support.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-time_support.lo -MD -MP -MF $(DEPDIR)/libhelper_la-time_support.Tpo -c -o libhelper_la-time_support.lo `test -f 'time_support.c' || echo '$(srcdir)/'`time_support.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-time_support.Tpo $(DEPDIR)/libhelper_la-time_support.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='time_support.c' object='libhelper_la-time_support.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-time_support.lo `test -f 'time_support.c' || echo '$(srcdir)/'`time_support.c
|
||||
|
||||
libhelper_la-replacements.lo: replacements.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-replacements.lo -MD -MP -MF $(DEPDIR)/libhelper_la-replacements.Tpo -c -o libhelper_la-replacements.lo `test -f 'replacements.c' || echo '$(srcdir)/'`replacements.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-replacements.Tpo $(DEPDIR)/libhelper_la-replacements.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='replacements.c' object='libhelper_la-replacements.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-replacements.lo `test -f 'replacements.c' || echo '$(srcdir)/'`replacements.c
|
||||
|
||||
libhelper_la-fileio.lo: fileio.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-fileio.lo -MD -MP -MF $(DEPDIR)/libhelper_la-fileio.Tpo -c -o libhelper_la-fileio.lo `test -f 'fileio.c' || echo '$(srcdir)/'`fileio.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-fileio.Tpo $(DEPDIR)/libhelper_la-fileio.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fileio.c' object='libhelper_la-fileio.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-fileio.lo `test -f 'fileio.c' || echo '$(srcdir)/'`fileio.c
|
||||
|
||||
libhelper_la-util.lo: util.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-util.lo -MD -MP -MF $(DEPDIR)/libhelper_la-util.Tpo -c -o libhelper_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-util.Tpo $(DEPDIR)/libhelper_la-util.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util.c' object='libhelper_la-util.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c
|
||||
|
||||
libhelper_la-jim-nvp.lo: jim-nvp.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-jim-nvp.lo -MD -MP -MF $(DEPDIR)/libhelper_la-jim-nvp.Tpo -c -o libhelper_la-jim-nvp.lo `test -f 'jim-nvp.c' || echo '$(srcdir)/'`jim-nvp.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-jim-nvp.Tpo $(DEPDIR)/libhelper_la-jim-nvp.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='jim-nvp.c' object='libhelper_la-jim-nvp.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-jim-nvp.lo `test -f 'jim-nvp.c' || echo '$(srcdir)/'`jim-nvp.c
|
||||
|
||||
libhelper_la-ioutil.lo: ioutil.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-ioutil.lo -MD -MP -MF $(DEPDIR)/libhelper_la-ioutil.Tpo -c -o libhelper_la-ioutil.lo `test -f 'ioutil.c' || echo '$(srcdir)/'`ioutil.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-ioutil.Tpo $(DEPDIR)/libhelper_la-ioutil.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ioutil.c' object='libhelper_la-ioutil.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-ioutil.lo `test -f 'ioutil.c' || echo '$(srcdir)/'`ioutil.c
|
||||
|
||||
libhelper_la-ioutil_stubs.lo: ioutil_stubs.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -MT libhelper_la-ioutil_stubs.lo -MD -MP -MF $(DEPDIR)/libhelper_la-ioutil_stubs.Tpo -c -o libhelper_la-ioutil_stubs.lo `test -f 'ioutil_stubs.c' || echo '$(srcdir)/'`ioutil_stubs.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhelper_la-ioutil_stubs.Tpo $(DEPDIR)/libhelper_la-ioutil_stubs.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ioutil_stubs.c' object='libhelper_la-ioutil_stubs.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libhelper_la_CFLAGS) $(CFLAGS) -c -o libhelper_la-ioutil_stubs.lo `test -f 'ioutil_stubs.c' || echo '$(srcdir)/'`ioutil_stubs.c
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
ID: $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||
tags: tags-am
|
||||
TAGS: tags
|
||||
|
||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
$(am__define_uniq_tagged_files); \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: ctags-am
|
||||
|
||||
CTAGS: ctags
|
||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
cscopelist: cscopelist-am
|
||||
|
||||
cscopelist-am: $(am__tagged_files)
|
||||
list='$(am__tagged_files)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) check-am
|
||||
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
|
||||
installdirs:
|
||||
install: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am:
|
||||
|
||||
.MAKE: all check install install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
|
||||
clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
|
||||
ctags-am distclean distclean-compile distclean-generic \
|
||||
distclean-libtool distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-html install-html-am install-info \
|
||||
install-info-am install-man install-pdf install-pdf-am \
|
||||
install-ps install-ps-am install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags tags-am uninstall uninstall-am
|
||||
|
||||
|
||||
$(BIN2C): bin2char.c
|
||||
${CC_FOR_BUILD} ${CFLAGS_FOR_BUILD} $(srcdir)/bin2char.c -o $@
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
58
debuggers/openocd/src/helper/bin2char.c
Normal file
58
debuggers/openocd/src/helper/bin2char.c
Normal file
@ -0,0 +1,58 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
unsigned int n;
|
||||
const char *name;
|
||||
|
||||
if (argc == 1) {
|
||||
fprintf(stderr, "bin2char <varname>\n");
|
||||
fprintf(stderr, "read from standard input and write a char"
|
||||
" array out to standard output\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/* for win32 set stdin/stdout to binary mode */
|
||||
_setmode(_fileno(stdin), _O_BINARY);
|
||||
_setmode(_fileno(stdout), _O_BINARY);
|
||||
#endif
|
||||
|
||||
n = 0;
|
||||
name = argv[1];
|
||||
fprintf(stdout, "/* autogenerated from %s */\n", argv[0]);
|
||||
fprintf(stdout, "unsigned const char %s[] = {\n", name);
|
||||
while ((c = getc(stdin)) != EOF) {
|
||||
fprintf(stdout, "0x%02x,", c & 0xff);
|
||||
if ((++n % 16) == 0)
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
fprintf(stdout, "0 /* terminate with a null */};\n");
|
||||
return 0;
|
||||
}
|
||||
399
debuggers/openocd/src/helper/binarybuffer.c
Normal file
399
debuggers/openocd/src/helper/binarybuffer.c
Normal file
@ -0,0 +1,399 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "binarybuffer.h"
|
||||
|
||||
static const unsigned char bit_reverse_table256[] = {
|
||||
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
|
||||
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
|
||||
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
|
||||
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
|
||||
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
|
||||
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
|
||||
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
|
||||
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
|
||||
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
|
||||
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
|
||||
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
|
||||
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
|
||||
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
|
||||
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
|
||||
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
|
||||
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
|
||||
};
|
||||
|
||||
void *buf_cpy(const void *from, void *_to, unsigned size)
|
||||
{
|
||||
if (NULL == from || NULL == _to)
|
||||
return NULL;
|
||||
|
||||
/* copy entire buffer */
|
||||
memcpy(_to, from, DIV_ROUND_UP(size, 8));
|
||||
|
||||
/* mask out bits that don't belong to the buffer */
|
||||
unsigned trailing_bits = size % 8;
|
||||
if (trailing_bits) {
|
||||
uint8_t *to = _to;
|
||||
to[size / 8] &= (1 << trailing_bits) - 1;
|
||||
}
|
||||
return _to;
|
||||
}
|
||||
|
||||
static bool buf_cmp_masked(uint8_t a, uint8_t b, uint8_t m)
|
||||
{
|
||||
return (a & m) != (b & m);
|
||||
}
|
||||
static bool buf_cmp_trailing(uint8_t a, uint8_t b, uint8_t m, unsigned trailing)
|
||||
{
|
||||
uint8_t mask = (1 << trailing) - 1;
|
||||
return buf_cmp_masked(a, b, mask & m);
|
||||
}
|
||||
|
||||
bool buf_cmp(const void *_buf1, const void *_buf2, unsigned size)
|
||||
{
|
||||
if (!_buf1 || !_buf2)
|
||||
return _buf1 != _buf2;
|
||||
|
||||
unsigned last = size / 8;
|
||||
if (memcmp(_buf1, _buf2, last) != 0)
|
||||
return false;
|
||||
|
||||
unsigned trailing = size % 8;
|
||||
if (!trailing)
|
||||
return false;
|
||||
|
||||
const uint8_t *buf1 = _buf1, *buf2 = _buf2;
|
||||
return buf_cmp_trailing(buf1[last], buf2[last], 0xff, trailing);
|
||||
}
|
||||
|
||||
bool buf_cmp_mask(const void *_buf1, const void *_buf2,
|
||||
const void *_mask, unsigned size)
|
||||
{
|
||||
if (!_buf1 || !_buf2)
|
||||
return _buf1 != _buf2 || _buf1 != _mask;
|
||||
|
||||
const uint8_t *buf1 = _buf1, *buf2 = _buf2, *mask = _mask;
|
||||
unsigned last = size / 8;
|
||||
for (unsigned i = 0; i < last; i++) {
|
||||
if (buf_cmp_masked(buf1[i], buf2[i], mask[i]))
|
||||
return true;
|
||||
}
|
||||
unsigned trailing = size % 8;
|
||||
if (!trailing)
|
||||
return false;
|
||||
return buf_cmp_trailing(buf1[last], buf2[last], mask[last], trailing);
|
||||
}
|
||||
|
||||
|
||||
void *buf_set_ones(void *_buf, unsigned size)
|
||||
{
|
||||
uint8_t *buf = _buf;
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
memset(buf, 0xff, size / 8);
|
||||
|
||||
unsigned trailing_bits = size % 8;
|
||||
if (trailing_bits)
|
||||
buf[size / 8] = (1 << trailing_bits) - 1;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void *buf_set_buf(const void *_src, unsigned src_start,
|
||||
void *_dst, unsigned dst_start, unsigned len)
|
||||
{
|
||||
const uint8_t *src = _src;
|
||||
uint8_t *dst = _dst;
|
||||
unsigned i, sb, db, sq, dq, lb, lq;
|
||||
|
||||
sb = src_start / 8;
|
||||
db = dst_start / 8;
|
||||
sq = src_start % 8;
|
||||
dq = dst_start % 8;
|
||||
lb = len / 8;
|
||||
lq = len % 8;
|
||||
|
||||
src += sb;
|
||||
dst += db;
|
||||
|
||||
/* check if both buffers are on byte boundary and
|
||||
* len is a multiple of 8bit so we can simple copy
|
||||
* the buffer */
|
||||
if ((sq == 0) && (dq == 0) && (lq == 0)) {
|
||||
for (i = 0; i < lb; i++)
|
||||
*dst++ = *src++;
|
||||
return (uint8_t *)_dst;
|
||||
}
|
||||
|
||||
/* fallback to slow bit copy */
|
||||
for (i = 0; i < len; i++) {
|
||||
if (((*src >> (sq&7)) & 1) == 1)
|
||||
*dst |= 1 << (dq&7);
|
||||
else
|
||||
*dst &= ~(1 << (dq&7));
|
||||
if (sq++ == 7) {
|
||||
sq = 0;
|
||||
src++;
|
||||
}
|
||||
if (dq++ == 7) {
|
||||
dq = 0;
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
|
||||
return (uint8_t *)_dst;
|
||||
}
|
||||
|
||||
uint32_t flip_u32(uint32_t value, unsigned int num)
|
||||
{
|
||||
uint32_t c = (bit_reverse_table256[value & 0xff] << 24) |
|
||||
(bit_reverse_table256[(value >> 8) & 0xff] << 16) |
|
||||
(bit_reverse_table256[(value >> 16) & 0xff] << 8) |
|
||||
(bit_reverse_table256[(value >> 24) & 0xff]);
|
||||
|
||||
if (num < 32)
|
||||
c = c >> (32 - num);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static int ceil_f_to_u32(float x)
|
||||
{
|
||||
if (x < 0) /* return zero for negative numbers */
|
||||
return 0;
|
||||
|
||||
uint32_t y = x; /* cut off fraction */
|
||||
|
||||
if ((x - y) > 0.0) /* if there was a fractional part, increase by one */
|
||||
y++;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
char *buf_to_str(const void *_buf, unsigned buf_len, unsigned radix)
|
||||
{
|
||||
float factor;
|
||||
switch (radix) {
|
||||
case 16:
|
||||
factor = 2.0; /* log(256) / log(16) = 2.0 */
|
||||
break;
|
||||
case 10:
|
||||
factor = 2.40824; /* log(256) / log(10) = 2.40824 */
|
||||
break;
|
||||
case 8:
|
||||
factor = 2.66667; /* log(256) / log(8) = 2.66667 */
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned str_len = ceil_f_to_u32(DIV_ROUND_UP(buf_len, 8) * factor);
|
||||
char *str = calloc(str_len + 1, 1);
|
||||
|
||||
const uint8_t *buf = _buf;
|
||||
int b256_len = DIV_ROUND_UP(buf_len, 8);
|
||||
for (int i = b256_len - 1; i >= 0; i--) {
|
||||
uint32_t tmp = buf[i];
|
||||
if (((unsigned)i == (buf_len / 8)) && (buf_len % 8))
|
||||
tmp &= (0xff >> (8 - (buf_len % 8)));
|
||||
|
||||
/* base-256 digits */
|
||||
for (unsigned j = str_len; j > 0; j--) {
|
||||
tmp += (uint32_t)str[j-1] * 256;
|
||||
str[j-1] = (uint8_t)(tmp % radix);
|
||||
tmp /= radix;
|
||||
}
|
||||
}
|
||||
|
||||
const char *DIGITS = "0123456789ABCDEF";
|
||||
for (unsigned j = 0; j < str_len; j++)
|
||||
str[j] = DIGITS[(int)str[j]];
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/** identify radix, and skip radix-prefix (0, 0x or 0X) */
|
||||
static void str_radix_guess(const char **_str, unsigned *_str_len,
|
||||
unsigned *_radix)
|
||||
{
|
||||
unsigned radix = *_radix;
|
||||
if (0 != radix)
|
||||
return;
|
||||
const char *str = *_str;
|
||||
unsigned str_len = *_str_len;
|
||||
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
|
||||
radix = 16;
|
||||
str += 2;
|
||||
str_len -= 2;
|
||||
} else if ((str[0] == '0') && (str_len != 1)) {
|
||||
radix = 8;
|
||||
str += 1;
|
||||
str_len -= 1;
|
||||
} else
|
||||
radix = 10;
|
||||
*_str = str;
|
||||
*_str_len = str_len;
|
||||
*_radix = radix;
|
||||
}
|
||||
|
||||
int str_to_buf(const char *str, unsigned str_len,
|
||||
void *_buf, unsigned buf_len, unsigned radix)
|
||||
{
|
||||
str_radix_guess(&str, &str_len, &radix);
|
||||
|
||||
float factor;
|
||||
if (radix == 16)
|
||||
factor = 0.5; /* log(16) / log(256) = 0.5 */
|
||||
else if (radix == 10)
|
||||
factor = 0.41524; /* log(10) / log(256) = 0.41524 */
|
||||
else if (radix == 8)
|
||||
factor = 0.375; /* log(8) / log(256) = 0.375 */
|
||||
else
|
||||
return 0;
|
||||
|
||||
/* copy to zero-terminated buffer */
|
||||
char *charbuf = strndup(str, str_len);
|
||||
|
||||
/* number of digits in base-256 notation */
|
||||
unsigned b256_len = ceil_f_to_u32(str_len * factor);
|
||||
uint8_t *b256_buf = calloc(b256_len, 1);
|
||||
|
||||
/* go through zero terminated buffer
|
||||
* input digits (ASCII) */
|
||||
unsigned i;
|
||||
for (i = 0; charbuf[i]; i++) {
|
||||
uint32_t tmp = charbuf[i];
|
||||
if ((tmp >= '0') && (tmp <= '9'))
|
||||
tmp = (tmp - '0');
|
||||
else if ((tmp >= 'a') && (tmp <= 'f'))
|
||||
tmp = (tmp - 'a' + 10);
|
||||
else if ((tmp >= 'A') && (tmp <= 'F'))
|
||||
tmp = (tmp - 'A' + 10);
|
||||
else
|
||||
continue; /* skip characters other than [0-9,a-f,A-F] */
|
||||
|
||||
if (tmp >= radix)
|
||||
continue; /* skip digits invalid for the current radix */
|
||||
|
||||
/* base-256 digits */
|
||||
for (unsigned j = 0; j < b256_len; j++) {
|
||||
tmp += (uint32_t)b256_buf[j] * radix;
|
||||
b256_buf[j] = (uint8_t)(tmp & 0xFF);
|
||||
tmp >>= 8;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint8_t *buf = _buf;
|
||||
for (unsigned j = 0; j < DIV_ROUND_UP(buf_len, 8); j++) {
|
||||
if (j < b256_len)
|
||||
buf[j] = b256_buf[j];
|
||||
else
|
||||
buf[j] = 0;
|
||||
}
|
||||
|
||||
/* mask out bits that don't belong to the buffer */
|
||||
if (buf_len % 8)
|
||||
buf[(buf_len / 8)] &= 0xff >> (8 - (buf_len % 8));
|
||||
|
||||
free(b256_buf);
|
||||
free(charbuf);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void bit_copy_queue_init(struct bit_copy_queue *q)
|
||||
{
|
||||
INIT_LIST_HEAD(&q->list);
|
||||
}
|
||||
|
||||
int bit_copy_queued(struct bit_copy_queue *q, uint8_t *dst, unsigned dst_offset, const uint8_t *src,
|
||||
unsigned src_offset, unsigned bit_count)
|
||||
{
|
||||
struct bit_copy_queue_entry *qe = malloc(sizeof(*qe));
|
||||
if (!qe)
|
||||
return ERROR_FAIL;
|
||||
|
||||
qe->dst = dst;
|
||||
qe->dst_offset = dst_offset;
|
||||
qe->src = src;
|
||||
qe->src_offset = src_offset;
|
||||
qe->bit_count = bit_count;
|
||||
list_add_tail(&qe->list, &q->list);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
void bit_copy_execute(struct bit_copy_queue *q)
|
||||
{
|
||||
struct bit_copy_queue_entry *qe;
|
||||
struct bit_copy_queue_entry *tmp;
|
||||
list_for_each_entry_safe(qe, tmp, &q->list, list) {
|
||||
bit_copy(qe->dst, qe->dst_offset, qe->src, qe->src_offset, qe->bit_count);
|
||||
list_del(&qe->list);
|
||||
free(qe);
|
||||
}
|
||||
}
|
||||
|
||||
void bit_copy_discard(struct bit_copy_queue *q)
|
||||
{
|
||||
struct bit_copy_queue_entry *qe;
|
||||
struct bit_copy_queue_entry *tmp;
|
||||
list_for_each_entry_safe(qe, tmp, &q->list, list) {
|
||||
list_del(&qe->list);
|
||||
free(qe);
|
||||
}
|
||||
}
|
||||
|
||||
int unhexify(char *bin, const char *hex, int count)
|
||||
{
|
||||
int i, tmp;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (sscanf(hex + (2 * i), "%02x", &tmp) != 1)
|
||||
return i;
|
||||
bin[i] = tmp;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int hexify(char *hex, const char *bin, int count, int out_maxlen)
|
||||
{
|
||||
int i, cmd_len = 0;
|
||||
|
||||
/* May use a length, or a null-terminated string as input. */
|
||||
if (count == 0)
|
||||
count = strlen(bin);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
cmd_len += snprintf(hex + cmd_len, out_maxlen - cmd_len, "%02x", bin[i] & 0xff);
|
||||
|
||||
return cmd_len;
|
||||
}
|
||||
164
debuggers/openocd/src/helper/binarybuffer.h
Normal file
164
debuggers/openocd/src/helper/binarybuffer.h
Normal file
@ -0,0 +1,164 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef BINARYBUFFER_H
|
||||
#define BINARYBUFFER_H
|
||||
|
||||
#include "list.h"
|
||||
|
||||
/** @file
|
||||
* Support functions to access arbitrary bits in a byte array
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets @c num bits in @c _buffer, starting at the @c first bit,
|
||||
* using the bits in @c value. This routine fast-paths writes
|
||||
* of little-endian, byte-aligned, 32-bit words.
|
||||
* @param _buffer The buffer whose bits will be set.
|
||||
* @param first The bit offset in @c _buffer to start writing (0-31).
|
||||
* @param num The number of bits from @c value to copy (1-32).
|
||||
* @param value Up to 32 bits that will be copied to _buffer.
|
||||
*/
|
||||
static inline void buf_set_u32(void *_buffer,
|
||||
unsigned first, unsigned num, uint32_t value)
|
||||
{
|
||||
uint8_t *buffer = (uint8_t *)_buffer;
|
||||
|
||||
if ((num == 32) && (first == 0)) {
|
||||
buffer[3] = (value >> 24) & 0xff;
|
||||
buffer[2] = (value >> 16) & 0xff;
|
||||
buffer[1] = (value >> 8) & 0xff;
|
||||
buffer[0] = (value >> 0) & 0xff;
|
||||
} else {
|
||||
for (unsigned i = first; i < first + num; i++) {
|
||||
if (((value >> (i - first)) & 1) == 1)
|
||||
buffer[i / 8] |= 1 << (i % 8);
|
||||
else
|
||||
buffer[i / 8] &= ~(1 << (i % 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Retrieves @c num bits from @c _buffer, starting at the @c first bit,
|
||||
* returning the bits in a 32-bit word. This routine fast-paths reads
|
||||
* of little-endian, byte-aligned, 32-bit words.
|
||||
* @param _buffer The buffer whose bits will be read.
|
||||
* @param first The bit offset in @c _buffer to start reading (0-31).
|
||||
* @param num The number of bits from @c _buffer to read (1-32).
|
||||
* @returns Up to 32-bits that were read from @c _buffer.
|
||||
*/
|
||||
static inline uint32_t buf_get_u32(const void *_buffer,
|
||||
unsigned first, unsigned num)
|
||||
{
|
||||
uint8_t *buffer = (uint8_t *)_buffer;
|
||||
|
||||
if ((num == 32) && (first == 0)) {
|
||||
return (((uint32_t)buffer[3]) << 24) |
|
||||
(((uint32_t)buffer[2]) << 16) |
|
||||
(((uint32_t)buffer[1]) << 8) |
|
||||
(((uint32_t)buffer[0]) << 0);
|
||||
} else {
|
||||
uint32_t result = 0;
|
||||
for (unsigned i = first; i < first + num; i++) {
|
||||
if (((buffer[i / 8] >> (i % 8)) & 1) == 1)
|
||||
result |= 1 << (i - first);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverts the ordering of bits inside a 32-bit word (e.g. 31..0 -> 0..31).
|
||||
* This routine can be used to flip smaller data types by using smaller
|
||||
* values for @c width.
|
||||
* @param value The word to flip.
|
||||
* @param width The number of bits in value (2-32).
|
||||
* @returns A 32-bit word with @c value in reversed bit-order.
|
||||
*/
|
||||
uint32_t flip_u32(uint32_t value, unsigned width);
|
||||
|
||||
bool buf_cmp(const void *buf1, const void *buf2, unsigned size);
|
||||
bool buf_cmp_mask(const void *buf1, const void *buf2,
|
||||
const void *mask, unsigned size);
|
||||
|
||||
/**
|
||||
* Copies @c size bits out of @c from and into @c to. Any extra
|
||||
* bits in the final byte will be set to zero.
|
||||
* @param from The buffer to copy into @c to.
|
||||
* @param to The buffer that will receive the copy of @c from.
|
||||
* @param size The number of bits to copy.
|
||||
*/
|
||||
void *buf_cpy(const void *from, void *to, unsigned size);
|
||||
|
||||
/**
|
||||
* Set the contents of @c buf with @c count bits, all set to 1.
|
||||
* @param buf The buffer to fill with ones.
|
||||
* @param size The number of bits.
|
||||
* @returns The original buffer (@c buf).
|
||||
*/
|
||||
void *buf_set_ones(void *buf, unsigned size);
|
||||
|
||||
void *buf_set_buf(const void *src, unsigned src_start,
|
||||
void *dst, unsigned dst_start, unsigned len);
|
||||
|
||||
int str_to_buf(const char *str, unsigned len,
|
||||
void *bin_buf, unsigned buf_size, unsigned radix);
|
||||
char *buf_to_str(const void *buf, unsigned size, unsigned radix);
|
||||
|
||||
/* read a uint32_t from a buffer in target memory endianness */
|
||||
static inline uint32_t fast_target_buffer_get_u32(const void *p, bool le)
|
||||
{
|
||||
return le ? le_to_h_u32(p) : be_to_h_u32(p);
|
||||
}
|
||||
|
||||
static inline void bit_copy(uint8_t *dst, unsigned dst_offset, const uint8_t *src,
|
||||
unsigned src_offset, unsigned bit_count)
|
||||
{
|
||||
buf_set_buf(src, src_offset, dst, dst_offset, bit_count);
|
||||
}
|
||||
|
||||
struct bit_copy_queue {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct bit_copy_queue_entry {
|
||||
uint8_t *dst;
|
||||
unsigned dst_offset;
|
||||
const uint8_t *src;
|
||||
unsigned src_offset;
|
||||
unsigned bit_count;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
void bit_copy_queue_init(struct bit_copy_queue *q);
|
||||
int bit_copy_queued(struct bit_copy_queue *q, uint8_t *dst, unsigned dst_offset, const uint8_t *src,
|
||||
unsigned src_offset, unsigned bit_count);
|
||||
void bit_copy_execute(struct bit_copy_queue *q);
|
||||
void bit_copy_discard(struct bit_copy_queue *q);
|
||||
|
||||
/* functions to convert to/from hex encoded buffer
|
||||
* used in ti-icdi driver and gdb server */
|
||||
int unhexify(char *bin, const char *hex, int count);
|
||||
int hexify(char *hex, const char *bin, int count, int out_maxlen);
|
||||
|
||||
#endif /* BINARYBUFFER_H */
|
||||
1466
debuggers/openocd/src/helper/command.c
Normal file
1466
debuggers/openocd/src/helper/command.c
Normal file
File diff suppressed because it is too large
Load Diff
419
debuggers/openocd/src/helper/command.h
Normal file
419
debuggers/openocd/src/helper/command.h
Normal file
@ -0,0 +1,419 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef COMMAND_H
|
||||
#define COMMAND_H
|
||||
|
||||
#include <jim-nvp.h>
|
||||
|
||||
/* To achieve C99 printf compatibility in MinGW, gnu_printf should be
|
||||
* used for __attribute__((format( ... ))), with GCC v4.4 or later
|
||||
*/
|
||||
#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004))
|
||||
#define PRINTF_ATTRIBUTE_FORMAT gnu_printf
|
||||
#else
|
||||
#define PRINTF_ATTRIBUTE_FORMAT printf
|
||||
#endif
|
||||
|
||||
enum command_mode {
|
||||
COMMAND_EXEC,
|
||||
COMMAND_CONFIG,
|
||||
COMMAND_ANY,
|
||||
};
|
||||
|
||||
struct command_context;
|
||||
|
||||
/** The type signature for command context's output handler. */
|
||||
typedef int (*command_output_handler_t)(struct command_context *context,
|
||||
const char *line);
|
||||
|
||||
struct command_context {
|
||||
Jim_Interp *interp;
|
||||
enum command_mode mode;
|
||||
struct command *commands;
|
||||
int current_target;
|
||||
command_output_handler_t output_handler;
|
||||
void *output_handler_priv;
|
||||
};
|
||||
|
||||
struct command;
|
||||
|
||||
/**
|
||||
* When run_command is called, a new instance will be created on the
|
||||
* stack, filled with the proper values, and passed by reference to the
|
||||
* required COMMAND_HANDLER routine.
|
||||
*/
|
||||
struct command_invocation {
|
||||
struct command_context *ctx;
|
||||
struct command *current;
|
||||
const char *name;
|
||||
unsigned argc;
|
||||
const char **argv;
|
||||
};
|
||||
|
||||
/**
|
||||
* Command handlers may be defined with more parameters than the base
|
||||
* set provided by command.c. This macro uses C99 magic to allow
|
||||
* defining all such derivative types using this macro.
|
||||
*/
|
||||
#define __COMMAND_HANDLER(name, extra ...) \
|
||||
int name(struct command_invocation *cmd, ## extra)
|
||||
|
||||
/**
|
||||
* Use this to macro to call a command helper (or a nested handler).
|
||||
* It provides command handler authors protection against reordering or
|
||||
* removal of unused parameters.
|
||||
*
|
||||
* @b Note: This macro uses lexical capture to provide some arguments.
|
||||
* As a result, this macro should be used @b only within functions
|
||||
* defined by the COMMAND_HANDLER or COMMAND_HELPER macros. Those
|
||||
* macros provide the expected lexical context captured by this macro.
|
||||
* Furthermore, it should be used only from the top-level of handler or
|
||||
* helper function, or care must be taken to avoid redefining the same
|
||||
* variables in intervening scope(s) by accident.
|
||||
*/
|
||||
#define CALL_COMMAND_HANDLER(name, extra ...) \
|
||||
name(cmd, ## extra)
|
||||
|
||||
/**
|
||||
* Always use this macro to define new command handler functions.
|
||||
* It ensures the parameters are ordered, typed, and named properly, so
|
||||
* they be can be used by other macros (e.g. COMMAND_PARSE_NUMBER).
|
||||
* All command handler functions must be defined as static in scope.
|
||||
*/
|
||||
#define COMMAND_HANDLER(name) \
|
||||
static __COMMAND_HANDLER(name)
|
||||
|
||||
/**
|
||||
* Similar to COMMAND_HANDLER, except some parameters are expected.
|
||||
* A helper is globally-scoped because it may be shared between several
|
||||
* source files (e.g. the s3c24xx device command helper).
|
||||
*/
|
||||
#define COMMAND_HELPER(name, extra ...) __COMMAND_HANDLER(name, extra)
|
||||
|
||||
/**
|
||||
* Use this macro to access the context of the command being handled,
|
||||
* rather than accessing the variable directly. It may be moved.
|
||||
*/
|
||||
#define CMD_CTX (cmd->ctx)
|
||||
/**
|
||||
* Use this macro to access the number of arguments for the command being
|
||||
* handled, rather than accessing the variable directly. It may be moved.
|
||||
*/
|
||||
#define CMD_ARGC (cmd->argc)
|
||||
/**
|
||||
* Use this macro to access the arguments for the command being handled,
|
||||
* rather than accessing the variable directly. It may be moved.
|
||||
*/
|
||||
#define CMD_ARGV (cmd->argv)
|
||||
/**
|
||||
* Use this macro to access the name of the command being handled,
|
||||
* rather than accessing the variable directly. It may be moved.
|
||||
*/
|
||||
#define CMD_NAME (cmd->name)
|
||||
/**
|
||||
* Use this macro to access the current command being handled,
|
||||
* rather than accessing the variable directly. It may be moved.
|
||||
*/
|
||||
#define CMD_CURRENT (cmd->current)
|
||||
/**
|
||||
* Use this macro to access the invoked command handler's data pointer,
|
||||
* rather than accessing the variable directly. It may be moved.
|
||||
*/
|
||||
#define CMD_DATA (CMD_CURRENT->jim_handler_data)
|
||||
|
||||
/**
|
||||
* The type signature for command handling functions. They are
|
||||
* usually registered as part of command_registration, providing
|
||||
* a high-level means for executing a command.
|
||||
*
|
||||
* If the command fails, it *MUST* return a value != ERROR_OK
|
||||
* (many commands break this rule, patches welcome!)
|
||||
*
|
||||
* This is *especially* important for commands such as writing
|
||||
* to flash or verifying memory. The reason is that those commands
|
||||
* can be used by programs to determine if the operation succeded
|
||||
* or not. If the operation failed, then a program can try
|
||||
* an alternative approach.
|
||||
*
|
||||
* Returning ERROR_COMMAND_SYNTAX_ERROR will have the effect of
|
||||
* printing out the syntax of the command.
|
||||
*/
|
||||
typedef __COMMAND_HANDLER((*command_handler_t));
|
||||
|
||||
struct command {
|
||||
const char *name;
|
||||
const char *help;
|
||||
const char *usage;
|
||||
struct command *parent;
|
||||
struct command *children;
|
||||
command_handler_t handler;
|
||||
Jim_CmdProc jim_handler;
|
||||
void *jim_handler_data;
|
||||
enum command_mode mode;
|
||||
struct command *next;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param c The command to be named.
|
||||
* @param delim The character to place between command names.
|
||||
* @returns A malloc'd string containing the full command name,
|
||||
* which may include one or more ancestor components. Multiple names
|
||||
* are separated by single spaces. The caller must free() the string
|
||||
* when done with it.
|
||||
*/
|
||||
char *command_name(struct command *c, char delim);
|
||||
|
||||
/*
|
||||
* Commands should be registered by filling in one or more of these
|
||||
* structures and passing them to register_command().
|
||||
*
|
||||
* A conventioal format should be used for help strings, to provide both
|
||||
* usage and basic information:
|
||||
* @code
|
||||
* "@<options@> ... - some explanation text"
|
||||
* @endcode
|
||||
*
|
||||
* @param name The name of the command to register, which must not have
|
||||
* been registered previously in the intended context.
|
||||
* @param handler The callback function that will be called. If NULL,
|
||||
* then the command serves as a placeholder for its children or a script.
|
||||
* @param mode The command mode(s) in which this command may be run.
|
||||
* @param help The help text that will be displayed to the user.
|
||||
*/
|
||||
struct command_registration {
|
||||
const char *name;
|
||||
command_handler_t handler;
|
||||
Jim_CmdProc jim_handler;
|
||||
void *jim_handler_data;
|
||||
enum command_mode mode;
|
||||
const char *help;
|
||||
/** a string listing the options and arguments, required or optional */
|
||||
const char *usage;
|
||||
|
||||
/**
|
||||
* If non-NULL, the commands in @c chain will be registered in
|
||||
* the same context and scope of this registration record.
|
||||
* This allows modules to inherit lists commands from other
|
||||
* modules.
|
||||
*/
|
||||
const struct command_registration *chain;
|
||||
};
|
||||
|
||||
/** Use this as the last entry in an array of command_registration records. */
|
||||
#define COMMAND_REGISTRATION_DONE { .name = NULL, .chain = NULL }
|
||||
|
||||
/**
|
||||
* Register a command @c handler that can be called from scripts during
|
||||
* the execution @c mode specified.
|
||||
*
|
||||
* If @c parent is non-NULL, the new command will be registered as a
|
||||
* sub-command under it; otherwise, it will be available as a top-level
|
||||
* command.
|
||||
*
|
||||
* @param cmd_ctx The command_context in which to register the command.
|
||||
* @param parent Register this command as a child of this, or NULL to
|
||||
* register a top-level command.
|
||||
* @param rec A command_registration record that contains the desired
|
||||
* command parameters.
|
||||
* @returns The new command, if successful; otherwise, NULL.
|
||||
*/
|
||||
struct command *register_command(struct command_context *cmd_ctx,
|
||||
struct command *parent, const struct command_registration *rec);
|
||||
|
||||
/**
|
||||
* Register one or more commands in the specified context, as children
|
||||
* of @c parent (or top-level commends, if NULL). In a registration's
|
||||
* record contains a non-NULL @c chain member and name is NULL, the
|
||||
* commands on the chain will be registered in the same context.
|
||||
* Otherwise, the chained commands are added as children of the command.
|
||||
*
|
||||
* @param cmd_ctx The command_context in which to register the command.
|
||||
* @param parent Register this command as a child of this, or NULL to
|
||||
* register a top-level command.
|
||||
* @param cmds Pointer to an array of command_registration records that
|
||||
* contains the desired command parameters. The last record must have
|
||||
* NULL for all fields.
|
||||
* @returns ERROR_OK on success; ERROR_FAIL if any registration fails.
|
||||
*/
|
||||
int register_commands(struct command_context *cmd_ctx, struct command *parent,
|
||||
const struct command_registration *cmds);
|
||||
|
||||
|
||||
/**
|
||||
* Unregisters command @c name from the given context, @c cmd_ctx.
|
||||
* @param cmd_ctx The context of the registered command.
|
||||
* @param parent The parent of the given command, or NULL.
|
||||
* @param name The name of the command to unregister.
|
||||
* @returns ERROR_OK on success, or an error code.
|
||||
*/
|
||||
int unregister_command(struct command_context *cmd_ctx,
|
||||
struct command *parent, const char *name);
|
||||
/**
|
||||
* Unregisters all commands from the specfied context.
|
||||
* @param cmd_ctx The context that will be cleared of registered commands.
|
||||
* @param parent If given, only clear commands from under this one command.
|
||||
* @returns ERROR_OK on success, or an error code.
|
||||
*/
|
||||
int unregister_all_commands(struct command_context *cmd_ctx,
|
||||
struct command *parent);
|
||||
|
||||
struct command *command_find_in_context(struct command_context *cmd_ctx,
|
||||
const char *name);
|
||||
struct command *command_find_in_parent(struct command *parent,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* Update the private command data field for a command and all descendents.
|
||||
* This is used when creating a new heirarchy of commands that depends
|
||||
* on obtaining a dynamically created context. The value will be available
|
||||
* in command handlers by using the CMD_DATA macro.
|
||||
* @param c The command (group) whose data pointer(s) will be updated.
|
||||
* @param p The new data pointer to use for the command or its descendents.
|
||||
*/
|
||||
void command_set_handler_data(struct command *c, void *p);
|
||||
|
||||
void command_set_output_handler(struct command_context *context,
|
||||
command_output_handler_t output_handler, void *priv);
|
||||
|
||||
|
||||
int command_context_mode(struct command_context *context, enum command_mode mode);
|
||||
|
||||
/* Return the current command context associated with the Jim interpreter or
|
||||
* alternatively the global default command interpreter
|
||||
*/
|
||||
struct command_context *current_command_context(Jim_Interp *interp);
|
||||
/**
|
||||
* Creates a new command context using the startup TCL provided and
|
||||
* the existing Jim interpreter, if any. If interp == NULL, then command_init
|
||||
* creates a command interpreter.
|
||||
*/
|
||||
struct command_context *command_init(const char *startup_tcl, Jim_Interp *interp);
|
||||
/**
|
||||
* Creates a copy of an existing command context. This does not create
|
||||
* a deep copy of the command list, so modifications in one context will
|
||||
* affect all shared contexts. The caller must track reference counting
|
||||
* and ensure the commands are freed before destroying the last instance.
|
||||
* @param cmd_ctx The command_context that will be copied.
|
||||
* @returns A new command_context with the same state as the original.
|
||||
*/
|
||||
struct command_context *copy_command_context(struct command_context *cmd_ctx);
|
||||
/**
|
||||
* Frees the resources associated with a command context. The commands
|
||||
* are not removed, so unregister_all_commands() must be called first.
|
||||
* @param context The command_context that will be destroyed.
|
||||
*/
|
||||
void command_done(struct command_context *context);
|
||||
|
||||
void command_print(struct command_context *context, const char *format, ...)
|
||||
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));
|
||||
void command_print_sameline(struct command_context *context, 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)));
|
||||
void command_output_text(struct command_context *context, const char *data);
|
||||
|
||||
void process_jim_events(struct command_context *cmd_ctx);
|
||||
|
||||
#define ERROR_COMMAND_CLOSE_CONNECTION (-600)
|
||||
#define ERROR_COMMAND_SYNTAX_ERROR (-601)
|
||||
#define ERROR_COMMAND_NOTFOUND (-602)
|
||||
#define ERROR_COMMAND_ARGUMENT_INVALID (-603)
|
||||
#define ERROR_COMMAND_ARGUMENT_OVERFLOW (-604)
|
||||
#define ERROR_COMMAND_ARGUMENT_UNDERFLOW (-605)
|
||||
|
||||
int parse_ulong(const char *str, unsigned long *ul);
|
||||
int parse_ullong(const char *str, unsigned long long *ul);
|
||||
|
||||
int parse_long(const char *str, long *ul);
|
||||
int parse_llong(const char *str, long long *ul);
|
||||
|
||||
#define DECLARE_PARSE_WRAPPER(name, type) \
|
||||
int parse ## name(const char *str, type * ul)
|
||||
|
||||
DECLARE_PARSE_WRAPPER(_uint, unsigned);
|
||||
DECLARE_PARSE_WRAPPER(_u32, uint32_t);
|
||||
DECLARE_PARSE_WRAPPER(_u16, uint16_t);
|
||||
DECLARE_PARSE_WRAPPER(_u8, uint8_t);
|
||||
|
||||
DECLARE_PARSE_WRAPPER(_int, int);
|
||||
DECLARE_PARSE_WRAPPER(_s32, int32_t);
|
||||
DECLARE_PARSE_WRAPPER(_s16, int16_t);
|
||||
DECLARE_PARSE_WRAPPER(_s8, int8_t);
|
||||
|
||||
/**
|
||||
* @brief parses the string @a in into @a out as a @a type, or prints
|
||||
* a command error and passes the error code to the caller. If an error
|
||||
* does occur, the calling function will return the error code produced
|
||||
* by the parsing function (one of ERROR_COMMAND_ARGUMENT_*).
|
||||
*
|
||||
* This function may cause the calling function to return immediately,
|
||||
* so it should be used carefully to avoid leaking resources. In most
|
||||
* situations, parsing should be completed in full before proceding
|
||||
* to allocate resources, and this strategy will most prevents leaks.
|
||||
*/
|
||||
#define COMMAND_PARSE_NUMBER(type, in, out) \
|
||||
do { \
|
||||
int retval_macro_tmp = parse_ ## type(in, &(out)); \
|
||||
if (ERROR_OK != retval_macro_tmp) { \
|
||||
command_print(CMD_CTX, stringify(out) \
|
||||
" option value ('%s') is not valid", in); \
|
||||
return retval_macro_tmp; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Parse the string @c as a binary parameter, storing the boolean value
|
||||
* in @c out. The strings @c on and @c off are used to match different
|
||||
* strings for true and false options (e.g. "on" and "off" or
|
||||
* "enable" and "disable").
|
||||
*/
|
||||
#define COMMAND_PARSE_BOOL(in, out, on, off) \
|
||||
do { \
|
||||
bool value; \
|
||||
int retval_macro_tmp = command_parse_bool_arg(in, &value); \
|
||||
if (ERROR_OK != retval_macro_tmp) { \
|
||||
command_print(CMD_CTX, stringify(out) \
|
||||
" option value ('%s') is not valid", in); \
|
||||
command_print(CMD_CTX, " choices are '%s' or '%s'", \
|
||||
on, off); \
|
||||
return retval_macro_tmp; \
|
||||
} \
|
||||
out = value; \
|
||||
} while (0)
|
||||
|
||||
int command_parse_bool_arg(const char *in, bool *out);
|
||||
COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label);
|
||||
|
||||
/** parses an on/off command argument */
|
||||
#define COMMAND_PARSE_ON_OFF(in, out) \
|
||||
COMMAND_PARSE_BOOL(in, out, "on", "off")
|
||||
/** parses an enable/disable command argument */
|
||||
#define COMMAND_PARSE_ENABLE(in, out) \
|
||||
COMMAND_PARSE_BOOL(in, out, "enable", "disable")
|
||||
|
||||
void script_debug(Jim_Interp *interp, const char *cmd,
|
||||
unsigned argc, Jim_Obj * const *argv);
|
||||
|
||||
#endif /* COMMAND_H */
|
||||
174
debuggers/openocd/src/helper/configuration.c
Normal file
174
debuggers/openocd/src/helper/configuration.c
Normal file
@ -0,0 +1,174 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "configuration.h"
|
||||
#include "log.h"
|
||||
|
||||
static size_t num_config_files;
|
||||
static char **config_file_names;
|
||||
|
||||
static size_t num_script_dirs;
|
||||
static char **script_search_dirs;
|
||||
|
||||
void add_script_search_dir(const char *dir)
|
||||
{
|
||||
num_script_dirs++;
|
||||
script_search_dirs =
|
||||
(char **)realloc(script_search_dirs, (num_script_dirs + 1) * sizeof(char *));
|
||||
|
||||
script_search_dirs[num_script_dirs-1] = strdup(dir);
|
||||
script_search_dirs[num_script_dirs] = NULL;
|
||||
|
||||
LOG_DEBUG("adding %s", dir);
|
||||
}
|
||||
|
||||
void add_config_command(const char *cfg)
|
||||
{
|
||||
num_config_files++;
|
||||
config_file_names =
|
||||
(char **)realloc(config_file_names, (num_config_files + 1) * sizeof(char *));
|
||||
|
||||
config_file_names[num_config_files-1] = strdup(cfg);
|
||||
config_file_names[num_config_files] = NULL;
|
||||
}
|
||||
|
||||
/* return full path or NULL according to search rules */
|
||||
char *find_file(const char *file)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
char **search_dirs = script_search_dirs;
|
||||
char *dir;
|
||||
char const *mode = "r";
|
||||
char *full_path;
|
||||
|
||||
/* Check absolute and relative to current working dir first.
|
||||
* This keeps full_path reporting belowing working. */
|
||||
full_path = alloc_printf("%s", file);
|
||||
fp = fopen(full_path, mode);
|
||||
|
||||
while (!fp) {
|
||||
free(full_path);
|
||||
full_path = NULL;
|
||||
dir = *search_dirs++;
|
||||
|
||||
if (!dir)
|
||||
break;
|
||||
|
||||
full_path = alloc_printf("%s/%s", dir, file);
|
||||
fp = fopen(full_path, mode);
|
||||
}
|
||||
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
LOG_DEBUG("found %s", full_path);
|
||||
return full_path;
|
||||
}
|
||||
|
||||
free(full_path);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE *open_file_from_path(const char *file, const char *mode)
|
||||
{
|
||||
if (mode[0] != 'r')
|
||||
return fopen(file, mode);
|
||||
else {
|
||||
char *full_path = find_file(file);
|
||||
if (full_path == NULL)
|
||||
return NULL;
|
||||
FILE *fp = NULL;
|
||||
fp = fopen(full_path, mode);
|
||||
free(full_path);
|
||||
return fp;
|
||||
}
|
||||
}
|
||||
|
||||
int parse_config_file(struct command_context *cmd_ctx)
|
||||
{
|
||||
int retval;
|
||||
char **cfg;
|
||||
|
||||
if (!config_file_names) {
|
||||
command_run_line(cmd_ctx, "script openocd.cfg");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
cfg = config_file_names;
|
||||
|
||||
while (*cfg) {
|
||||
retval = command_run_line(cmd_ctx, *cfg);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
cfg++;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
char *get_home_dir(const char *append_path)
|
||||
{
|
||||
char *home = getenv("HOME");
|
||||
|
||||
if (home == NULL) {
|
||||
|
||||
#ifdef _WIN32
|
||||
home = getenv("USERPROFILE");
|
||||
|
||||
if (home == NULL) {
|
||||
|
||||
char homepath[MAX_PATH];
|
||||
char *drive = getenv("HOMEDRIVE");
|
||||
char *path = getenv("HOMEPATH");
|
||||
if (drive && path) {
|
||||
snprintf(homepath, MAX_PATH, "%s/%s", drive, path);
|
||||
home = homepath;
|
||||
}
|
||||
}
|
||||
#else
|
||||
struct passwd *pwd = getpwuid(getuid());
|
||||
if (pwd)
|
||||
home = pwd->pw_dir;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
if (home == NULL)
|
||||
return home;
|
||||
|
||||
char *home_path;
|
||||
|
||||
if (append_path)
|
||||
home_path = alloc_printf("%s/%s", home, append_path);
|
||||
else
|
||||
home_path = alloc_printf("%s", home);
|
||||
|
||||
return home_path;
|
||||
}
|
||||
45
debuggers/openocd/src/helper/configuration.h
Normal file
45
debuggers/openocd/src/helper/configuration.h
Normal file
@ -0,0 +1,45 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef CONFIGURATION_H
|
||||
#define CONFIGURATION_H
|
||||
|
||||
#include <helper/command.h>
|
||||
|
||||
int parse_cmdline_args(struct command_context *cmd_ctx,
|
||||
int argc, char *argv[]);
|
||||
|
||||
int parse_config_file(struct command_context *cmd_ctx);
|
||||
void add_config_command(const char *cfg);
|
||||
|
||||
void add_script_search_dir(const char *dir);
|
||||
|
||||
int configuration_output_handler(struct command_context *cmd_ctx,
|
||||
const char *line);
|
||||
|
||||
FILE *open_file_from_path(const char *file, const char *mode);
|
||||
|
||||
char *find_file(const char *name);
|
||||
char *get_home_dir(const char *append_path);
|
||||
|
||||
#endif /* CONFIGURATION_H */
|
||||
253
debuggers/openocd/src/helper/fileio.c
Normal file
253
debuggers/openocd/src/helper/fileio.c
Normal file
@ -0,0 +1,253 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
* spen@spen-soft.co.uk *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "configuration.h"
|
||||
#include "fileio.h"
|
||||
|
||||
struct fileio_internal {
|
||||
const char *url;
|
||||
ssize_t size;
|
||||
enum fileio_type type;
|
||||
enum fileio_access access;
|
||||
FILE *file;
|
||||
};
|
||||
|
||||
static inline int fileio_close_local(struct fileio_internal *fileio);
|
||||
static inline int fileio_open_local(struct fileio_internal *fileio)
|
||||
{
|
||||
char file_access[4];
|
||||
|
||||
switch (fileio->access) {
|
||||
case FILEIO_READ:
|
||||
strcpy(file_access, "r");
|
||||
break;
|
||||
case FILEIO_WRITE:
|
||||
strcpy(file_access, "w");
|
||||
break;
|
||||
case FILEIO_READWRITE:
|
||||
strcpy(file_access, "w+");
|
||||
break;
|
||||
case FILEIO_APPEND:
|
||||
strcpy(file_access, "a");
|
||||
break;
|
||||
case FILEIO_APPENDREAD:
|
||||
strcpy(file_access, "a+");
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("BUG: access neither read, write nor readwrite");
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
/* win32 always opens in binary mode */
|
||||
#ifndef _WIN32
|
||||
if (fileio->type == FILEIO_BINARY)
|
||||
#endif
|
||||
strcat(file_access, "b");
|
||||
|
||||
fileio->file = open_file_from_path(fileio->url, file_access);
|
||||
if (!fileio->file) {
|
||||
LOG_ERROR("couldn't open %s", fileio->url);
|
||||
return ERROR_FILEIO_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
if ((fileio->access != FILEIO_WRITE) || (fileio->access == FILEIO_READWRITE)) {
|
||||
/* NB! Here we use fseek() instead of stat(), since stat is a
|
||||
* more advanced operation that might not apply to e.g. a disk path
|
||||
* that refers to e.g. a tftp client */
|
||||
int result, result2;
|
||||
|
||||
result = fseek(fileio->file, 0, SEEK_END);
|
||||
|
||||
fileio->size = ftell(fileio->file);
|
||||
|
||||
result2 = fseek(fileio->file, 0, SEEK_SET);
|
||||
|
||||
if ((fileio->size < 0) || (result < 0) || (result2 < 0)) {
|
||||
fileio_close_local(fileio);
|
||||
return ERROR_FILEIO_OPERATION_FAILED;
|
||||
}
|
||||
} else
|
||||
fileio->size = 0x0;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int fileio_open(struct fileio *fileio_p,
|
||||
const char *url,
|
||||
enum fileio_access access_type,
|
||||
enum fileio_type type)
|
||||
{
|
||||
int retval = ERROR_OK;
|
||||
|
||||
struct fileio_internal *fileio = malloc(sizeof(struct fileio_internal));
|
||||
fileio_p->fp = fileio;
|
||||
|
||||
fileio->type = type;
|
||||
fileio->access = access_type;
|
||||
fileio->url = strdup(url);
|
||||
|
||||
retval = fileio_open_local(fileio);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline int fileio_close_local(struct fileio_internal *fileio)
|
||||
{
|
||||
int retval = fclose(fileio->file);
|
||||
if (retval != 0) {
|
||||
if (retval == EBADF)
|
||||
LOG_ERROR("BUG: fileio_local->file not a valid file descriptor");
|
||||
else
|
||||
LOG_ERROR("couldn't close %s: %s", fileio->url, strerror(errno));
|
||||
|
||||
return ERROR_FILEIO_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int fileio_close(struct fileio *fileio_p)
|
||||
{
|
||||
int retval;
|
||||
struct fileio_internal *fileio = fileio_p->fp;
|
||||
|
||||
retval = fileio_close_local(fileio);
|
||||
|
||||
free((void *)fileio->url);
|
||||
fileio->url = NULL;
|
||||
|
||||
free(fileio);
|
||||
fileio_p->fp = NULL;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int fileio_seek(struct fileio *fileio_p, size_t position)
|
||||
{
|
||||
int retval;
|
||||
struct fileio_internal *fileio = fileio_p->fp;
|
||||
retval = fseek(fileio->file, position, SEEK_SET);
|
||||
if (retval != 0) {
|
||||
LOG_ERROR("couldn't seek file %s: %s", fileio->url, strerror(errno));
|
||||
return ERROR_FILEIO_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int fileio_local_read(struct fileio_internal *fileio,
|
||||
size_t size, void *buffer, size_t *size_read)
|
||||
{
|
||||
ssize_t retval = fread(buffer, 1, size, fileio->file);
|
||||
*size_read = (retval >= 0) ? retval : 0;
|
||||
return (retval < 0) ? retval : ERROR_OK;
|
||||
}
|
||||
|
||||
int fileio_read(struct fileio *fileio_p, size_t size, void *buffer,
|
||||
size_t *size_read)
|
||||
{
|
||||
struct fileio_internal *fileio = fileio_p->fp;
|
||||
return fileio_local_read(fileio, size, buffer, size_read);
|
||||
}
|
||||
|
||||
int fileio_read_u32(struct fileio *fileio_p, uint32_t *data)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
size_t size_read;
|
||||
struct fileio_internal *fileio = fileio_p->fp;
|
||||
int retval = fileio_local_read(fileio, sizeof(uint32_t), buf, &size_read);
|
||||
if (ERROR_OK == retval && sizeof(uint32_t) != size_read)
|
||||
retval = -EIO;
|
||||
if (ERROR_OK == retval)
|
||||
*data = be_to_h_u32(buf);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int fileio_local_fgets(struct fileio_internal *fileio,
|
||||
size_t size, void *buffer)
|
||||
{
|
||||
if (fgets(buffer, size, fileio->file) == NULL)
|
||||
return ERROR_FILEIO_OPERATION_FAILED;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int fileio_fgets(struct fileio *fileio_p, size_t size, void *buffer)
|
||||
{
|
||||
struct fileio_internal *fileio = fileio_p->fp;
|
||||
return fileio_local_fgets(fileio, size, buffer);
|
||||
}
|
||||
|
||||
static int fileio_local_write(struct fileio_internal *fileio,
|
||||
size_t size, const void *buffer, size_t *size_written)
|
||||
{
|
||||
ssize_t retval = fwrite(buffer, 1, size, fileio->file);
|
||||
*size_written = (retval >= 0) ? retval : 0;
|
||||
return (retval < 0) ? retval : ERROR_OK;
|
||||
}
|
||||
|
||||
int fileio_write(struct fileio *fileio_p,
|
||||
size_t size, const void *buffer, size_t *size_written)
|
||||
{
|
||||
struct fileio_internal *fileio = fileio_p->fp;
|
||||
int retval = fileio_local_write(fileio, size, buffer, size_written);
|
||||
if (retval == ERROR_OK)
|
||||
fileio->size += *size_written;
|
||||
return retval;
|
||||
}
|
||||
|
||||
int fileio_write_u32(struct fileio *fileio_p, uint32_t data)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
h_u32_to_be(buf, data);
|
||||
size_t size_written;
|
||||
int retval = fileio_write(fileio_p, 4, buf, &size_written);
|
||||
if (ERROR_OK == retval && size_written != sizeof(uint32_t))
|
||||
retval = -EIO;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* FIX!!!!
|
||||
*
|
||||
* For now this can not fail, but that's because a seek was executed
|
||||
* on startup.
|
||||
*
|
||||
* Avoiding the seek on startup opens up for using streams.
|
||||
*
|
||||
*/
|
||||
int fileio_size(struct fileio *fileio_p, int *size)
|
||||
{
|
||||
struct fileio_internal *fileio = fileio_p->fp;
|
||||
*size = fileio->size;
|
||||
return ERROR_OK;
|
||||
}
|
||||
74
debuggers/openocd/src/helper/fileio.h
Normal file
74
debuggers/openocd/src/helper/fileio.h
Normal file
@ -0,0 +1,74 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
* spen@spen-soft.co.uk *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef FILEIO_H
|
||||
#define FILEIO_H
|
||||
|
||||
#define FILEIO_MAX_ERROR_STRING (128)
|
||||
|
||||
enum fileio_type {
|
||||
FILEIO_TEXT,
|
||||
FILEIO_BINARY,
|
||||
};
|
||||
|
||||
enum fileio_access {
|
||||
FILEIO_NONE, /* open without any access (invalid mode) */
|
||||
FILEIO_READ, /* open for reading, position at beginning */
|
||||
FILEIO_WRITE, /* open for writing, position at beginning */
|
||||
FILEIO_READWRITE, /* open for writing, position at beginning, allow reading */
|
||||
FILEIO_APPEND, /* open for writing, position at end */
|
||||
FILEIO_APPENDREAD, /* open for writing, position at end, allow reading */
|
||||
};
|
||||
|
||||
struct fileio {
|
||||
/* The structure is opaque */
|
||||
struct fileio_internal *fp;
|
||||
};
|
||||
|
||||
int fileio_open(struct fileio *fileio,
|
||||
const char *url, enum fileio_access access_type, enum fileio_type type);
|
||||
int fileio_close(struct fileio *fileio);
|
||||
|
||||
int fileio_seek(struct fileio *fileio, size_t position);
|
||||
int fileio_fgets(struct fileio *fileio, size_t size, void *buffer);
|
||||
|
||||
int fileio_read(struct fileio *fileio,
|
||||
size_t size, void *buffer, size_t *size_read);
|
||||
int fileio_write(struct fileio *fileio,
|
||||
size_t size, const void *buffer, size_t *size_written);
|
||||
|
||||
int fileio_read_u32(struct fileio *fileio, uint32_t *data);
|
||||
int fileio_write_u32(struct fileio *fileio, uint32_t data);
|
||||
int fileio_size(struct fileio *fileio, int *size);
|
||||
|
||||
#define ERROR_FILEIO_LOCATION_UNKNOWN (-1200)
|
||||
#define ERROR_FILEIO_NOT_FOUND (-1201)
|
||||
#define ERROR_FILEIO_OPERATION_FAILED (-1202)
|
||||
#define ERROR_FILEIO_ACCESS_NOT_SUPPORTED (-1203)
|
||||
#define ERROR_FILEIO_RESOURCE_TYPE_UNKNOWN (-1204)
|
||||
#define ERROR_FILEIO_OPERATION_NOT_SUPPORTED (-1205)
|
||||
|
||||
#endif /* FILEIO_H */
|
||||
648
debuggers/openocd/src/helper/ioutil.c
Normal file
648
debuggers/openocd/src/helper/ioutil.c
Normal file
@ -0,0 +1,648 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007-2010 by Øyvind Harboe *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
/* this file contains various functionality useful to standalone systems */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "time_support.h"
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_IFADDRS_H
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
/* loads a file and returns a pointer to it in memory. The file contains
|
||||
* a 0 byte(sentinel) after len bytes - the length of the file. */
|
||||
int loadFile(const char *fileName, void **data, size_t *len)
|
||||
{
|
||||
/* ensure returned length is always sane */
|
||||
*len = 0;
|
||||
|
||||
FILE *pFile;
|
||||
pFile = fopen(fileName, "rb");
|
||||
if (pFile == NULL) {
|
||||
LOG_ERROR("Can't open %s", fileName);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
if (fseek(pFile, 0, SEEK_END) != 0) {
|
||||
LOG_ERROR("Can't open %s", fileName);
|
||||
fclose(pFile);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
long fsize = ftell(pFile);
|
||||
if (fsize == -1) {
|
||||
LOG_ERROR("Can't open %s", fileName);
|
||||
fclose(pFile);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
*len = fsize;
|
||||
|
||||
if (fseek(pFile, 0, SEEK_SET) != 0) {
|
||||
LOG_ERROR("Can't open %s", fileName);
|
||||
fclose(pFile);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
*data = malloc(*len + 1);
|
||||
if (*data == NULL) {
|
||||
LOG_ERROR("Can't open %s", fileName);
|
||||
fclose(pFile);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (fread(*data, 1, *len, pFile) != *len) {
|
||||
fclose(pFile);
|
||||
free(*data);
|
||||
LOG_ERROR("Can't open %s", fileName);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
fclose(pFile);
|
||||
|
||||
/* 0-byte after buffer (not included in *len) serves as a sentinel */
|
||||
char *buf = (char *)*data;
|
||||
buf[*len] = 0;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_cat_command)
|
||||
{
|
||||
if (CMD_ARGC != 1)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
/* NOTE!!! we only have line printing capability so we print the entire file as a single
|
||||
* line. */
|
||||
void *data;
|
||||
size_t len;
|
||||
|
||||
int retval = loadFile(CMD_ARGV[0], &data, &len);
|
||||
if (retval == ERROR_OK) {
|
||||
command_print(CMD_CTX, "%s", (char *)data);
|
||||
free(data);
|
||||
} else
|
||||
command_print(CMD_CTX, "%s not found", CMD_ARGV[0]);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_trunc_command)
|
||||
{
|
||||
if (CMD_ARGC != 1)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
FILE *config_file = NULL;
|
||||
config_file = fopen(CMD_ARGV[0], "w");
|
||||
if (config_file != NULL)
|
||||
fclose(config_file);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
#ifdef HAVE_MALLOC_H
|
||||
COMMAND_HANDLER(handle_meminfo_command)
|
||||
{
|
||||
static int prev;
|
||||
struct mallinfo info;
|
||||
|
||||
if (CMD_ARGC != 0)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
info = mallinfo();
|
||||
|
||||
if (prev > 0)
|
||||
command_print(CMD_CTX, "Diff: %d", prev - info.fordblks);
|
||||
prev = info.fordblks;
|
||||
|
||||
command_print(CMD_CTX, "Available ram: %d", info.fordblks);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
COMMAND_HANDLER(handle_append_command)
|
||||
{
|
||||
if (CMD_ARGC < 1)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
int retval = ERROR_FAIL;
|
||||
FILE *config_file = NULL;
|
||||
|
||||
config_file = fopen(CMD_ARGV[0], "a");
|
||||
if (config_file != NULL) {
|
||||
fseek(config_file, 0, SEEK_END);
|
||||
|
||||
unsigned i;
|
||||
for (i = 1; i < CMD_ARGC; i++) {
|
||||
if (fwrite(CMD_ARGV[i], 1, strlen(CMD_ARGV[i]),
|
||||
config_file) != strlen(CMD_ARGV[i]))
|
||||
break;
|
||||
if (i != CMD_ARGC - 1) {
|
||||
if (fwrite(" ", 1, 1, config_file) != 1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((i == CMD_ARGC) && (fwrite("\n", 1, 1, config_file) == 1))
|
||||
retval = ERROR_OK;
|
||||
|
||||
fclose(config_file);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_cp_command)
|
||||
{
|
||||
if (CMD_ARGC != 2)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
/* NOTE!!! we only have line printing capability so we print the entire file as a single
|
||||
* line. */
|
||||
void *data;
|
||||
size_t len;
|
||||
|
||||
int retval = loadFile(CMD_ARGV[0], &data, &len);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
FILE *f = fopen(CMD_ARGV[1], "wb");
|
||||
if (f == NULL)
|
||||
retval = ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
size_t pos = 0;
|
||||
for (;; ) {
|
||||
size_t chunk = len - pos;
|
||||
static const size_t maxChunk = 512 * 1024; /* ~1/sec */
|
||||
if (chunk > maxChunk)
|
||||
chunk = maxChunk;
|
||||
|
||||
if ((retval == ERROR_OK) && (fwrite(((char *)data) + pos, 1, chunk, f) != chunk))
|
||||
retval = ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
if (retval != ERROR_OK)
|
||||
break;
|
||||
|
||||
command_print(CMD_CTX, "%zu", len - pos);
|
||||
|
||||
pos += chunk;
|
||||
|
||||
if (pos == len)
|
||||
break;
|
||||
}
|
||||
|
||||
if (retval == ERROR_OK)
|
||||
command_print(CMD_CTX, "Copied %s to %s", CMD_ARGV[0], CMD_ARGV[1]);
|
||||
else
|
||||
command_print(CMD_CTX, "copy failed");
|
||||
|
||||
if (data != NULL)
|
||||
free(data);
|
||||
if (f != NULL)
|
||||
fclose(f);
|
||||
|
||||
if (retval != ERROR_OK)
|
||||
unlink(CMD_ARGV[1]);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define SHOW_RESULT(a, b) LOG_ERROR(# a " failed %d\n", (int)b)
|
||||
|
||||
#define IOSIZE 512
|
||||
void copyfile(char *name2, char *name1)
|
||||
{
|
||||
|
||||
int err;
|
||||
char buf[IOSIZE];
|
||||
int fd1, fd2;
|
||||
ssize_t done, wrote;
|
||||
|
||||
fd1 = open(name1, O_WRONLY | O_CREAT, 0664);
|
||||
if (fd1 < 0)
|
||||
SHOW_RESULT(open, fd1);
|
||||
|
||||
fd2 = open(name2, O_RDONLY);
|
||||
if (fd2 < 0)
|
||||
SHOW_RESULT(open, fd2);
|
||||
|
||||
for (;; ) {
|
||||
done = read(fd2, buf, IOSIZE);
|
||||
if (done < 0) {
|
||||
SHOW_RESULT(read, done);
|
||||
break;
|
||||
}
|
||||
|
||||
if (done == 0)
|
||||
break;
|
||||
|
||||
wrote = write(fd1, buf, done);
|
||||
if (wrote != done)
|
||||
SHOW_RESULT(write, wrote);
|
||||
|
||||
if (wrote != done)
|
||||
break;
|
||||
}
|
||||
|
||||
err = close(fd1);
|
||||
if (err < 0)
|
||||
SHOW_RESULT(close, err);
|
||||
|
||||
err = close(fd2);
|
||||
if (err < 0)
|
||||
SHOW_RESULT(close, err);
|
||||
}
|
||||
|
||||
/* utility fn to copy a directory */
|
||||
void copydir(char *name, char *destdir)
|
||||
{
|
||||
int err;
|
||||
DIR *dirp;
|
||||
|
||||
dirp = opendir(destdir);
|
||||
if (dirp == NULL)
|
||||
mkdir(destdir, 0777);
|
||||
else
|
||||
err = closedir(dirp);
|
||||
|
||||
dirp = opendir(name);
|
||||
if (dirp == NULL)
|
||||
SHOW_RESULT(opendir, -1);
|
||||
|
||||
for (;; ) {
|
||||
struct dirent *entry = readdir(dirp);
|
||||
|
||||
if (entry == NULL)
|
||||
break;
|
||||
|
||||
if (strcmp(entry->d_name, ".") == 0)
|
||||
continue;
|
||||
if (strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
int isDir = 0;
|
||||
struct stat buf;
|
||||
char fullPath[PATH_MAX];
|
||||
strncpy(fullPath, name, PATH_MAX);
|
||||
strcat(fullPath, "/");
|
||||
strncat(fullPath, entry->d_name, PATH_MAX - strlen(fullPath));
|
||||
|
||||
if (stat(fullPath, &buf) == -1) {
|
||||
LOG_ERROR("unable to read status from %s", fullPath);
|
||||
break;
|
||||
}
|
||||
isDir = S_ISDIR(buf.st_mode) != 0;
|
||||
|
||||
if (isDir)
|
||||
continue;
|
||||
|
||||
/* diag_printf("<INFO>: entry %14s",entry->d_name); */
|
||||
char fullname[PATH_MAX];
|
||||
char fullname2[PATH_MAX];
|
||||
|
||||
strcpy(fullname, name);
|
||||
strcat(fullname, "/");
|
||||
strcat(fullname, entry->d_name);
|
||||
|
||||
strcpy(fullname2, destdir);
|
||||
strcat(fullname2, "/");
|
||||
strcat(fullname2, entry->d_name);
|
||||
/* diag_printf("from %s to %s\n", fullname, fullname2); */
|
||||
copyfile(fullname, fullname2);
|
||||
|
||||
/* diag_printf("\n"); */
|
||||
}
|
||||
|
||||
err = closedir(dirp);
|
||||
if (err < 0)
|
||||
SHOW_RESULT(stat, err);
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_rm_command)
|
||||
{
|
||||
if (CMD_ARGC != 1)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
bool del = false;
|
||||
if (rmdir(CMD_ARGV[0]) == 0)
|
||||
del = true;
|
||||
else if (unlink(CMD_ARGV[0]) == 0)
|
||||
del = true;
|
||||
|
||||
return del ? ERROR_OK : ERROR_FAIL;
|
||||
}
|
||||
|
||||
static int ioutil_Jim_Command_ls(Jim_Interp *interp,
|
||||
int argc,
|
||||
Jim_Obj * const *argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
char *name = (char *) Jim_GetString(argv[1], NULL);
|
||||
|
||||
DIR *dirp = NULL;
|
||||
dirp = opendir(name);
|
||||
if (dirp == NULL)
|
||||
return JIM_ERR;
|
||||
Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
|
||||
|
||||
for (;; ) {
|
||||
struct dirent *entry = NULL;
|
||||
entry = readdir(dirp);
|
||||
if (entry == NULL)
|
||||
break;
|
||||
|
||||
if ((strcmp(".", entry->d_name) == 0) || (strcmp("..", entry->d_name) == 0))
|
||||
continue;
|
||||
|
||||
Jim_ListAppendElement(interp, objPtr,
|
||||
Jim_NewStringObj(interp, entry->d_name, strlen(entry->d_name)));
|
||||
}
|
||||
closedir(dirp);
|
||||
|
||||
Jim_SetResult(interp, objPtr);
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
static int ioutil_Jim_Command_peek(Jim_Interp *interp,
|
||||
int argc,
|
||||
Jim_Obj *const *argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
Jim_WrongNumArgs(interp, 1, argv, "peek ?address?");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
long address;
|
||||
if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
|
||||
return JIM_ERR;
|
||||
|
||||
int value = *((volatile int *) address);
|
||||
|
||||
Jim_SetResult(interp, Jim_NewIntObj(interp, value));
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
static int ioutil_Jim_Command_poke(Jim_Interp *interp,
|
||||
int argc,
|
||||
Jim_Obj *const *argv)
|
||||
{
|
||||
if (argc != 3) {
|
||||
Jim_WrongNumArgs(interp, 1, argv, "poke ?address? ?value?");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
long address;
|
||||
if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
|
||||
return JIM_ERR;
|
||||
long value;
|
||||
if (Jim_GetLong(interp, argv[2], &value) != JIM_OK)
|
||||
return JIM_ERR;
|
||||
|
||||
*((volatile int *) address) = value;
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
/* not so pretty code to fish out ip number*/
|
||||
static int ioutil_Jim_Command_ip(Jim_Interp *interp, int argc,
|
||||
Jim_Obj *const *argv)
|
||||
{
|
||||
#if !defined(__CYGWIN__)
|
||||
Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
|
||||
|
||||
struct ifaddrs *ifa = NULL, *ifp = NULL;
|
||||
|
||||
if (getifaddrs(&ifp) < 0)
|
||||
return JIM_ERR;
|
||||
|
||||
for (ifa = ifp; ifa; ifa = ifa->ifa_next) {
|
||||
char ip[200];
|
||||
socklen_t salen;
|
||||
|
||||
if (ifa->ifa_addr->sa_family == AF_INET)
|
||||
salen = sizeof(struct sockaddr_in);
|
||||
else if (ifa->ifa_addr->sa_family == AF_INET6)
|
||||
salen = sizeof(struct sockaddr_in6);
|
||||
else
|
||||
continue;
|
||||
|
||||
if (getnameinfo(ifa->ifa_addr, salen, ip, sizeof(ip), NULL, 0,
|
||||
NI_NUMERICHOST) < 0)
|
||||
continue;
|
||||
|
||||
Jim_AppendString(interp, tclOutput, ip, strlen(ip));
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
freeifaddrs(ifp);
|
||||
#else
|
||||
Jim_Obj *tclOutput = Jim_NewStringObj(interp, "fixme!!!", 0);
|
||||
LOG_ERROR("NOT IMPLEMENTED!!!");
|
||||
#endif
|
||||
Jim_SetResult(interp, tclOutput);
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#ifdef SIOCGIFHWADDR
|
||||
/* not so pretty code to fish out eth0 mac address */
|
||||
static int ioutil_Jim_Command_mac(Jim_Interp *interp, int argc,
|
||||
Jim_Obj *const *argv)
|
||||
{
|
||||
struct ifreq *ifr, *ifend;
|
||||
struct ifreq ifreq;
|
||||
struct ifconf ifc;
|
||||
struct ifreq ifs[5];
|
||||
int SockFD;
|
||||
|
||||
SockFD = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (SockFD < 0)
|
||||
return JIM_ERR;
|
||||
|
||||
ifc.ifc_len = sizeof(ifs);
|
||||
ifc.ifc_req = ifs;
|
||||
if (ioctl(SockFD, SIOCGIFCONF, &ifc) < 0) {
|
||||
close(SockFD);
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
|
||||
for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
|
||||
/* if (ifr->ifr_addr.sa_family == AF_INET) */
|
||||
{
|
||||
if (strcmp("eth0", ifr->ifr_name) != 0)
|
||||
continue;
|
||||
strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
|
||||
if (ioctl(SockFD, SIOCGIFHWADDR, &ifreq) < 0) {
|
||||
close(SockFD);
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
close(SockFD);
|
||||
|
||||
Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
|
||||
|
||||
char buffer[256];
|
||||
sprintf(buffer, "%02x-%02x-%02x-%02x-%02x-%02x",
|
||||
ifreq.ifr_hwaddr.sa_data[0]&0xff,
|
||||
ifreq.ifr_hwaddr.sa_data[1]&0xff,
|
||||
ifreq.ifr_hwaddr.sa_data[2]&0xff,
|
||||
ifreq.ifr_hwaddr.sa_data[3]&0xff,
|
||||
ifreq.ifr_hwaddr.sa_data[4]&0xff,
|
||||
ifreq.ifr_hwaddr.sa_data[5]&0xff);
|
||||
|
||||
Jim_AppendString(interp, tclOutput, buffer, strlen(buffer));
|
||||
|
||||
Jim_SetResult(interp, tclOutput);
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
}
|
||||
close(SockFD);
|
||||
|
||||
return JIM_ERR;
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static const struct command_registration ioutil_command_handlers[] = {
|
||||
{
|
||||
.name = "cat",
|
||||
.handler = handle_cat_command,
|
||||
.mode = COMMAND_ANY,
|
||||
.help = "display text file content",
|
||||
.usage = "file_name",
|
||||
},
|
||||
{
|
||||
.name = "trunc",
|
||||
.handler = handle_trunc_command,
|
||||
.mode = COMMAND_ANY,
|
||||
.help = "truncate a file to zero length",
|
||||
.usage = "file_name",
|
||||
},
|
||||
{
|
||||
.name = "cp",
|
||||
.handler = handle_cp_command,
|
||||
.mode = COMMAND_ANY,
|
||||
.help = "copy a file",
|
||||
.usage = "src_file_name dst_file_name",
|
||||
},
|
||||
{
|
||||
.name = "append_file",
|
||||
.handler = handle_append_command,
|
||||
.mode = COMMAND_ANY,
|
||||
.help = "append a variable number of strings to a file",
|
||||
.usage = "file_name [<string1>, [<string2>, ...]]",
|
||||
},
|
||||
#ifdef HAVE_MALLOC_H
|
||||
{
|
||||
.name = "meminfo",
|
||||
.handler = handle_meminfo_command,
|
||||
.mode = COMMAND_ANY,
|
||||
.help = "display free heap space",
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.name = "rm",
|
||||
.mode = COMMAND_ANY,
|
||||
.handler = handle_rm_command,
|
||||
.help = "remove a directory or file",
|
||||
.usage = "file_name",
|
||||
},
|
||||
|
||||
/*
|
||||
* Peek and poke are security holes -- they manipulate
|
||||
* server-internal addresses.
|
||||
*/
|
||||
|
||||
/* jim handlers */
|
||||
{
|
||||
.name = "peek",
|
||||
.mode = COMMAND_ANY,
|
||||
.jim_handler = ioutil_Jim_Command_peek,
|
||||
.help = "peek at a memory address",
|
||||
.usage = "address",
|
||||
},
|
||||
{
|
||||
.name = "poke",
|
||||
.mode = COMMAND_ANY,
|
||||
.jim_handler = ioutil_Jim_Command_poke,
|
||||
.help = "poke at a memory address",
|
||||
.usage = "address value",
|
||||
},
|
||||
{
|
||||
.name = "ls",
|
||||
.mode = COMMAND_ANY,
|
||||
.jim_handler = ioutil_Jim_Command_ls,
|
||||
.help = "show a listing of files",
|
||||
.usage = "dirname",
|
||||
},
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#ifdef SIOCGIFHWADDR
|
||||
{
|
||||
.name = "mac",
|
||||
.mode = COMMAND_ANY,
|
||||
.jim_handler = ioutil_Jim_Command_mac,
|
||||
.help = "show MAC address",
|
||||
},
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
.name = "ip",
|
||||
.jim_handler = ioutil_Jim_Command_ip,
|
||||
.mode = COMMAND_ANY,
|
||||
.help = "show IP address",
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
int ioutil_init(struct command_context *cmd_ctx)
|
||||
{
|
||||
return register_commands(cmd_ctx, NULL, ioutil_command_handlers);
|
||||
}
|
||||
27
debuggers/openocd/src/helper/ioutil.h
Normal file
27
debuggers/openocd/src/helper/ioutil.h
Normal file
@ -0,0 +1,27 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef HELPER_IOUTILS_H
|
||||
#define HELPER_IOUTILS_H
|
||||
|
||||
struct command_context;
|
||||
|
||||
int ioutil_init(struct command_context *cmd_ctx);
|
||||
|
||||
#endif /* HELPER_IOUTILS_H */
|
||||
30
debuggers/openocd/src/helper/ioutil_stubs.c
Normal file
30
debuggers/openocd/src/helper/ioutil_stubs.c
Normal file
@ -0,0 +1,30 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include "ioutil.h"
|
||||
#include "log.h"
|
||||
|
||||
int ioutil_init(struct command_context *cmd_ctx)
|
||||
{
|
||||
LOG_DEBUG("libocdhelper was built without I/O utility support");
|
||||
return ERROR_OK;
|
||||
}
|
||||
342
debuggers/openocd/src/helper/jim-nvp.c
Normal file
342
debuggers/openocd/src/helper/jim-nvp.c
Normal file
@ -0,0 +1,342 @@
|
||||
/* Jim - A small embeddable Tcl interpreter
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* official policies, either expressed or implied, of the Jim Tcl Project.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <jim-nvp.h>
|
||||
|
||||
int Jim_GetNvp(Jim_Interp *interp,
|
||||
Jim_Obj *objPtr, const Jim_Nvp *nvp_table, const Jim_Nvp **result)
|
||||
{
|
||||
Jim_Nvp *n;
|
||||
int e;
|
||||
|
||||
e = Jim_Nvp_name2value_obj(interp, nvp_table, objPtr, &n);
|
||||
if (e == JIM_ERR)
|
||||
return e;
|
||||
|
||||
/* Success? found? */
|
||||
if (n->name) {
|
||||
/* remove const */
|
||||
*result = (Jim_Nvp *) n;
|
||||
return JIM_OK;
|
||||
} else
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
Jim_Nvp *Jim_Nvp_name2value_simple(const Jim_Nvp *p, const char *name)
|
||||
{
|
||||
while (p->name) {
|
||||
if (0 == strcmp(name, p->name))
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
return (Jim_Nvp *) (p);
|
||||
}
|
||||
|
||||
Jim_Nvp *Jim_Nvp_name2value_nocase_simple(const Jim_Nvp *p, const char *name)
|
||||
{
|
||||
while (p->name) {
|
||||
if (0 == strcasecmp(name, p->name))
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
return (Jim_Nvp *) (p);
|
||||
}
|
||||
|
||||
int Jim_Nvp_name2value_obj(Jim_Interp *interp, const Jim_Nvp *p, Jim_Obj *o, Jim_Nvp **result)
|
||||
{
|
||||
return Jim_Nvp_name2value(interp, p, Jim_String(o), result);
|
||||
}
|
||||
|
||||
int Jim_Nvp_name2value(Jim_Interp *interp, const Jim_Nvp *_p, const char *name, Jim_Nvp **result)
|
||||
{
|
||||
const Jim_Nvp *p;
|
||||
|
||||
p = Jim_Nvp_name2value_simple(_p, name);
|
||||
|
||||
/* result */
|
||||
if (result)
|
||||
*result = (Jim_Nvp *) (p);
|
||||
|
||||
/* found? */
|
||||
if (p->name)
|
||||
return JIM_OK;
|
||||
else
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
int Jim_Nvp_name2value_obj_nocase(Jim_Interp *interp,
|
||||
const Jim_Nvp *p,
|
||||
Jim_Obj *o,
|
||||
Jim_Nvp **puthere)
|
||||
{
|
||||
return Jim_Nvp_name2value_nocase(interp, p, Jim_String(o), puthere);
|
||||
}
|
||||
|
||||
int Jim_Nvp_name2value_nocase(Jim_Interp *interp, const Jim_Nvp *_p, const char *name,
|
||||
Jim_Nvp **puthere)
|
||||
{
|
||||
const Jim_Nvp *p;
|
||||
|
||||
p = Jim_Nvp_name2value_nocase_simple(_p, name);
|
||||
|
||||
if (puthere)
|
||||
*puthere = (Jim_Nvp *) (p);
|
||||
/* found */
|
||||
if (p->name)
|
||||
return JIM_OK;
|
||||
else
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
int Jim_Nvp_value2name_obj(Jim_Interp *interp, const Jim_Nvp *p, Jim_Obj *o, Jim_Nvp **result)
|
||||
{
|
||||
int e;
|
||||
jim_wide w;
|
||||
|
||||
e = Jim_GetWide(interp, o, &w);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
return Jim_Nvp_value2name(interp, p, w, result);
|
||||
}
|
||||
|
||||
Jim_Nvp *Jim_Nvp_value2name_simple(const Jim_Nvp *p, int value)
|
||||
{
|
||||
while (p->name) {
|
||||
if (value == p->value)
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
return (Jim_Nvp *) (p);
|
||||
}
|
||||
|
||||
int Jim_Nvp_value2name(Jim_Interp *interp, const Jim_Nvp *_p, int value, Jim_Nvp **result)
|
||||
{
|
||||
const Jim_Nvp *p;
|
||||
|
||||
p = Jim_Nvp_value2name_simple(_p, value);
|
||||
|
||||
if (result)
|
||||
*result = (Jim_Nvp *) (p);
|
||||
|
||||
if (p->name)
|
||||
return JIM_OK;
|
||||
else
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
int Jim_GetOpt_Setup(Jim_GetOptInfo *p, Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->interp = interp;
|
||||
p->argc = argc;
|
||||
p->argv = argv;
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
void Jim_GetOpt_Debug(Jim_GetOptInfo *p)
|
||||
{
|
||||
int x;
|
||||
|
||||
fprintf(stderr, "---args---\n");
|
||||
for (x = 0; x < p->argc; x++)
|
||||
fprintf(stderr, "%2d) %s\n", x, Jim_String(p->argv[x]));
|
||||
fprintf(stderr, "-------\n");
|
||||
}
|
||||
|
||||
int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere)
|
||||
{
|
||||
Jim_Obj *o;
|
||||
|
||||
o = NULL; /* failure */
|
||||
if (goi->argc) {
|
||||
/* success */
|
||||
o = goi->argv[0];
|
||||
goi->argc -= 1;
|
||||
goi->argv += 1;
|
||||
}
|
||||
if (puthere)
|
||||
*puthere = o;
|
||||
if (o != NULL)
|
||||
return JIM_OK;
|
||||
else
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
int Jim_GetOpt_String(Jim_GetOptInfo *goi, char **puthere, int *len)
|
||||
{
|
||||
int r;
|
||||
Jim_Obj *o;
|
||||
const char *cp;
|
||||
|
||||
r = Jim_GetOpt_Obj(goi, &o);
|
||||
if (r == JIM_OK) {
|
||||
cp = Jim_GetString(o, len);
|
||||
if (puthere) {
|
||||
/* remove const */
|
||||
*puthere = (char *)(cp);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int Jim_GetOpt_Wide(Jim_GetOptInfo *goi, jim_wide *puthere)
|
||||
{
|
||||
int r;
|
||||
Jim_Obj *o;
|
||||
jim_wide _safe;
|
||||
|
||||
if (puthere == NULL)
|
||||
puthere = &_safe;
|
||||
|
||||
r = Jim_GetOpt_Obj(goi, &o);
|
||||
if (r == JIM_OK)
|
||||
r = Jim_GetWide(goi->interp, o, puthere);
|
||||
return r;
|
||||
}
|
||||
|
||||
int Jim_GetOpt_Nvp(Jim_GetOptInfo *goi, const Jim_Nvp *nvp, Jim_Nvp **puthere)
|
||||
{
|
||||
Jim_Nvp *_safe;
|
||||
Jim_Obj *o;
|
||||
int e;
|
||||
|
||||
if (puthere == NULL)
|
||||
puthere = &_safe;
|
||||
|
||||
e = Jim_GetOpt_Obj(goi, &o);
|
||||
if (e == JIM_OK)
|
||||
e = Jim_Nvp_name2value_obj(goi->interp, nvp, o, puthere);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
void Jim_GetOpt_NvpUnknown(Jim_GetOptInfo *goi, const Jim_Nvp *nvptable, int hadprefix)
|
||||
{
|
||||
if (hadprefix)
|
||||
Jim_SetResult_NvpUnknown(goi->interp, goi->argv[-2], goi->argv[-1], nvptable);
|
||||
else
|
||||
Jim_SetResult_NvpUnknown(goi->interp, NULL, goi->argv[-1], nvptable);
|
||||
}
|
||||
|
||||
int Jim_GetOpt_Enum(Jim_GetOptInfo *goi, const char *const *lookup, int *puthere)
|
||||
{
|
||||
int _safe;
|
||||
Jim_Obj *o;
|
||||
int e;
|
||||
|
||||
if (puthere == NULL)
|
||||
puthere = &_safe;
|
||||
e = Jim_GetOpt_Obj(goi, &o);
|
||||
if (e == JIM_OK)
|
||||
e = Jim_GetEnum(goi->interp, o, lookup, puthere, "option", JIM_ERRMSG);
|
||||
return e;
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
static Jim_Obj *debug_string_obj;
|
||||
|
||||
int x;
|
||||
|
||||
if (debug_string_obj)
|
||||
Jim_FreeObj(interp, debug_string_obj);
|
||||
|
||||
debug_string_obj = Jim_NewEmptyStringObj(interp);
|
||||
for (x = 0; x < argc; x++)
|
||||
Jim_AppendStrings(interp, debug_string_obj, Jim_String(argv[x]), " ", NULL);
|
||||
|
||||
return Jim_String(debug_string_obj);
|
||||
}
|
||||
|
||||
int Jim_nvpInit(Jim_Interp *interp)
|
||||
{
|
||||
/* This is really a helper library, not an extension, but this is the easy way */
|
||||
return JIM_OK;
|
||||
}
|
||||
329
debuggers/openocd/src/helper/jim-nvp.h
Normal file
329
debuggers/openocd/src/helper/jim-nvp.h
Normal file
@ -0,0 +1,329 @@
|
||||
/* Jim - A small embeddable Tcl interpreter
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* official policies, either expressed or implied, of the Jim Tcl Project.
|
||||
*/
|
||||
|
||||
#ifndef JIM_NVP_H
|
||||
#define JIM_NVP_H
|
||||
|
||||
#include <jim.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 Jim_Nvp yn[] = {
|
||||
* { "yes", 1 },
|
||||
* { "no" , 0 },
|
||||
* { "yep", 1 },
|
||||
* { "nope", 0 },
|
||||
* { NULL, -1 },
|
||||
* };
|
||||
*
|
||||
* Jim_Nvp *result
|
||||
* e = Jim_Nvp_name2value(interp, yn, "y", &result);
|
||||
* returns &yn[0];
|
||||
* e = Jim_Nvp_name2value(interp, yn, "n", &result);
|
||||
* returns &yn[1];
|
||||
* e = Jim_Nvp_name2value(interp, yn, "Blah", &result);
|
||||
* returns &yn[4];
|
||||
* \endcode
|
||||
*
|
||||
* During the number2name operation, the first matching value is returned.
|
||||
*/
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int value;
|
||||
} Jim_Nvp;
|
||||
|
||||
int Jim_GetNvp(Jim_Interp *interp,
|
||||
Jim_Obj *objPtr,
|
||||
const Jim_Nvp *nvp_table,
|
||||
const Jim_Nvp **result);
|
||||
|
||||
/* Name Value Pairs Operations */
|
||||
Jim_Nvp *Jim_Nvp_name2value_simple(const Jim_Nvp *nvp_table, const char *name);
|
||||
Jim_Nvp *Jim_Nvp_name2value_nocase_simple(const Jim_Nvp *nvp_table, const char *name);
|
||||
Jim_Nvp *Jim_Nvp_value2name_simple(const Jim_Nvp *nvp_table, int v);
|
||||
|
||||
int Jim_Nvp_name2value(Jim_Interp *interp,
|
||||
const Jim_Nvp *nvp_table,
|
||||
const char *name,
|
||||
Jim_Nvp **result);
|
||||
int Jim_Nvp_name2value_nocase(Jim_Interp *interp,
|
||||
const Jim_Nvp *nvp_table,
|
||||
const char *name,
|
||||
Jim_Nvp **result);
|
||||
int Jim_Nvp_value2name(Jim_Interp *interp, const Jim_Nvp *nvp_table, int value, Jim_Nvp **result);
|
||||
|
||||
int Jim_Nvp_name2value_obj(Jim_Interp *interp,
|
||||
const Jim_Nvp *nvp_table,
|
||||
Jim_Obj *name_obj,
|
||||
Jim_Nvp **result);
|
||||
int Jim_Nvp_name2value_obj_nocase(Jim_Interp *interp,
|
||||
const Jim_Nvp *nvp_table,
|
||||
Jim_Obj *name_obj,
|
||||
Jim_Nvp **result);
|
||||
int Jim_Nvp_value2name_obj(Jim_Interp *interp,
|
||||
const Jim_Nvp *nvp_table,
|
||||
Jim_Obj *value_obj,
|
||||
Jim_Nvp **result);
|
||||
|
||||
/** prints a nice 'unknown' parameter error message to the 'result' */
|
||||
void Jim_SetResult_NvpUnknown(Jim_Interp *interp,
|
||||
Jim_Obj *param_name,
|
||||
Jim_Obj *param_value,
|
||||
const Jim_Nvp *nvp_table);
|
||||
|
||||
/** Debug: convert argc/argv into a printable string for printf() debug
|
||||
*
|
||||
* \param interp - the interpeter
|
||||
* \param argc - arg count
|
||||
* \param argv - the objects
|
||||
*
|
||||
* \returns string pointer holding the text.
|
||||
*
|
||||
* Note, next call to this function will free the old (last) string.
|
||||
*
|
||||
* For example might want do this:
|
||||
* \code
|
||||
* fp = fopen("some.file.log", "a");
|
||||
* fprintf(fp, "PARAMS are: %s\n", Jim_DebugArgvString(interp, argc, argv));
|
||||
* fclose(fp);
|
||||
* \endcode
|
||||
*/
|
||||
const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
||||
|
||||
|
||||
/** A TCL -ish GetOpt like code.
|
||||
*
|
||||
* Some TCL objects have various "configuration" values.
|
||||
* For example - in Tcl/Tk the "buttons" have many options.
|
||||
*
|
||||
* Usefull when dealing with command options.
|
||||
* that may come in any order...
|
||||
*
|
||||
* Does not support "-foo = 123" type options.
|
||||
* Only supports tcl type options, like "-foo 123"
|
||||
*/
|
||||
|
||||
typedef struct jim_getopt {
|
||||
Jim_Interp *interp;
|
||||
int argc;
|
||||
Jim_Obj *const *argv;
|
||||
int isconfigure; /* non-zero if configure */
|
||||
} Jim_GetOptInfo;
|
||||
|
||||
/** GetOpt - how to.
|
||||
*
|
||||
* Example (short and incomplete):
|
||||
* \code
|
||||
* Jim_GetOptInfo goi;
|
||||
*
|
||||
* Jim_GetOpt_Setup(&goi, interp, argc, argv);
|
||||
*
|
||||
* while (goi.argc) {
|
||||
* e = Jim_GetOpt_Nvp(&goi, nvp_options, &n);
|
||||
* if (e != JIM_OK) {
|
||||
* Jim_GetOpt_NvpUnknown(&goi, nvp_options, 0);
|
||||
* return e;
|
||||
* }
|
||||
*
|
||||
* switch (n->value) {
|
||||
* case ALIVE:
|
||||
* printf("Option ALIVE specified\n");
|
||||
* break;
|
||||
* case FIRST:
|
||||
* if (goi.argc < 1) {
|
||||
* .. not enough args error ..
|
||||
* }
|
||||
* Jim_GetOpt_String(&goi, &cp, NULL);
|
||||
* printf("FIRSTNAME: %s\n", cp);
|
||||
* case AGE:
|
||||
* Jim_GetOpt_Wide(&goi, &w);
|
||||
* printf("AGE: %d\n", (int)(w));
|
||||
* break;
|
||||
* case POLITICS:
|
||||
* e = Jim_GetOpt_Nvp(&goi, nvp_politics, &n);
|
||||
* if (e != JIM_OK) {
|
||||
* Jim_GetOpt_NvpUnknown(&goi, nvp_politics, 1);
|
||||
* return e;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
|
||||
/** Setup GETOPT
|
||||
*
|
||||
* \param goi - get opt info to be initialized
|
||||
* \param interp - jim interp
|
||||
* \param argc - argc count.
|
||||
* \param argv - argv (will be copied)
|
||||
*
|
||||
* \code
|
||||
* Jim_GetOptInfo goi;
|
||||
*
|
||||
* Jim_GetOptSetup(&goi, interp, argc, argv);
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
int Jim_GetOpt_Setup(Jim_GetOptInfo *goi,
|
||||
Jim_Interp *interp,
|
||||
int argc,
|
||||
Jim_Obj *const *argv);
|
||||
|
||||
|
||||
/** Debug - Dump parameters to stderr
|
||||
* \param goi - current parameters
|
||||
*/
|
||||
void Jim_GetOpt_Debug(Jim_GetOptInfo *goi);
|
||||
|
||||
/** Remove argv[0] from the list.
|
||||
*
|
||||
* \param goi - get opt info
|
||||
* \param puthere - where param is put
|
||||
*
|
||||
*/
|
||||
int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere);
|
||||
|
||||
/** Remove argv[0] as string.
|
||||
*
|
||||
* \param goi - get opt info
|
||||
* \param puthere - where param is put
|
||||
* \param len - return its length
|
||||
*/
|
||||
int Jim_GetOpt_String(Jim_GetOptInfo *goi, char **puthere, int *len);
|
||||
|
||||
/** Remove argv[0] as double.
|
||||
*
|
||||
* \param goi - get opt info
|
||||
* \param puthere - where param is put.
|
||||
*
|
||||
*/
|
||||
int Jim_GetOpt_Double(Jim_GetOptInfo *goi, double *puthere);
|
||||
|
||||
/** Remove argv[0] as wide.
|
||||
*
|
||||
* \param goi - get opt info
|
||||
* \param puthere - where param is put.
|
||||
*/
|
||||
int Jim_GetOpt_Wide(Jim_GetOptInfo *goi, jim_wide *puthere);
|
||||
|
||||
/** Remove argv[0] as NVP.
|
||||
*
|
||||
* \param goi - get opt info
|
||||
* \param lookup - nvp lookup table
|
||||
* \param puthere - where param is put.
|
||||
*
|
||||
*/
|
||||
int Jim_GetOpt_Nvp(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, Jim_Nvp **puthere);
|
||||
|
||||
/** Create an appropriate error message for an NVP.
|
||||
*
|
||||
* \param goi - options info
|
||||
* \param lookup - the NVP table that was used.
|
||||
* \param hadprefix - 0 or 1 if the option had a prefix.
|
||||
*
|
||||
* This function will set the "interp->result" to a human readable
|
||||
* error message listing the available options.
|
||||
*
|
||||
* This function assumes the previous option argv[-1] is the unknown string.
|
||||
*
|
||||
* If this option had some prefix, then pass "hadprefix = 1" else pass "hadprefix = 0"
|
||||
*
|
||||
* Example:
|
||||
* \code
|
||||
*
|
||||
* while (goi.argc) {
|
||||
* // Get the next option
|
||||
* e = Jim_GetOpt_Nvp(&goi, cmd_options, &n);
|
||||
* if (e != JIM_OK) {
|
||||
* // option was not recognized
|
||||
* // pass 'hadprefix = 0' because there is no prefix
|
||||
* Jim_GetOpt_NvpUnknown(&goi, cmd_options, 0);
|
||||
* return e;
|
||||
* }
|
||||
*
|
||||
* switch (n->value) {
|
||||
* case OPT_SEX:
|
||||
* // handle: --sex male | female | lots | needmore
|
||||
* e = Jim_GetOpt_Nvp(&goi, &nvp_sex, &n);
|
||||
* if (e != JIM_OK) {
|
||||
* Jim_GetOpt_NvpUnknown(&ogi, nvp_sex, 1);
|
||||
* return e;
|
||||
* }
|
||||
* printf("Code: (%d) is %s\n", n->value, n->name);
|
||||
* break;
|
||||
* case ...:
|
||||
* [snip]
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
void Jim_GetOpt_NvpUnknown(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, int hadprefix);
|
||||
|
||||
|
||||
/** Remove argv[0] as Enum
|
||||
*
|
||||
* \param goi - get opt info
|
||||
* \param lookup - lookup table.
|
||||
* \param puthere - where param is put.
|
||||
*
|
||||
*/
|
||||
int Jim_GetOpt_Enum(Jim_GetOptInfo *goi, const char *const *lookup, int *puthere);
|
||||
|
||||
#endif
|
||||
737
debuggers/openocd/src/helper/list.h
Normal file
737
debuggers/openocd/src/helper/list.h
Normal file
@ -0,0 +1,737 @@
|
||||
#ifndef _LINUX_LIST_H
|
||||
#define _LINUX_LIST_H
|
||||
|
||||
/* begin local changes */
|
||||
#include <helper/types.h>
|
||||
|
||||
#define prefetch(x) ((void)x)
|
||||
#define LIST_POISON1 NULL
|
||||
#define LIST_POISON2 NULL
|
||||
|
||||
struct list_head {
|
||||
struct list_head *next, *prev;
|
||||
};
|
||||
struct hlist_head {
|
||||
struct hlist_node *first;
|
||||
};
|
||||
struct hlist_node {
|
||||
struct hlist_node *next, **pprev;
|
||||
};
|
||||
/* end local changes */
|
||||
|
||||
/*
|
||||
* Simple doubly linked list implementation.
|
||||
*
|
||||
* Some of the internal functions ("__xxx") are useful when
|
||||
* manipulating whole lists rather than single entries, as
|
||||
* sometimes we already know the next/prev entries and we can
|
||||
* generate better code by using them directly rather than
|
||||
* using the generic single-entry routines.
|
||||
*/
|
||||
|
||||
#define LIST_HEAD_INIT(name) { &(name), &(name) }
|
||||
|
||||
#define LIST_HEAD(name) \
|
||||
struct list_head name = LIST_HEAD_INIT(name)
|
||||
|
||||
static inline void INIT_LIST_HEAD(struct list_head *list)
|
||||
{
|
||||
list->next = list;
|
||||
list->prev = list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a new entry between two known consecutive entries.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
#ifndef CONFIG_DEBUG_LIST
|
||||
static inline void __list_add(struct list_head *new,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
}
|
||||
#else
|
||||
extern void __list_add(struct list_head *new,
|
||||
struct list_head *prev,
|
||||
struct list_head *next);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* list_add - add a new entry
|
||||
* @new: new entry to be added
|
||||
* @head: list head to add it after
|
||||
*
|
||||
* Insert a new entry after the specified head.
|
||||
* This is good for implementing stacks.
|
||||
*/
|
||||
static inline void list_add(struct list_head *new, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head, head->next);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* list_add_tail - add a new entry
|
||||
* @new: new entry to be added
|
||||
* @head: list head to add it before
|
||||
*
|
||||
* Insert a new entry before the specified head.
|
||||
* This is useful for implementing queues.
|
||||
*/
|
||||
static inline void list_add_tail(struct list_head *new, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head->prev, head);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete a list entry by making the prev/next entries
|
||||
* point to each other.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
static inline void __list_del(struct list_head *prev, struct list_head *next)
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_del - deletes entry from list.
|
||||
* @entry: the element to delete from the list.
|
||||
* Note: list_empty() on entry does not return true after this, the entry is
|
||||
* in an undefined state.
|
||||
*/
|
||||
#ifndef CONFIG_DEBUG_LIST
|
||||
static inline void __list_del_entry(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
}
|
||||
|
||||
static inline void list_del(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
entry->next = LIST_POISON1;
|
||||
entry->prev = LIST_POISON2;
|
||||
}
|
||||
#else
|
||||
extern void __list_del_entry(struct list_head *entry);
|
||||
extern void list_del(struct list_head *entry);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* list_replace - replace old entry by new one
|
||||
* @old : the element to be replaced
|
||||
* @new : the new element to insert
|
||||
*
|
||||
* If @old was empty, it will be overwritten.
|
||||
*/
|
||||
static inline void list_replace(struct list_head *old,
|
||||
struct list_head *new)
|
||||
{
|
||||
new->next = old->next;
|
||||
new->next->prev = new;
|
||||
new->prev = old->prev;
|
||||
new->prev->next = new;
|
||||
}
|
||||
|
||||
static inline void list_replace_init(struct list_head *old,
|
||||
struct list_head *new)
|
||||
{
|
||||
list_replace(old, new);
|
||||
INIT_LIST_HEAD(old);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_del_init - deletes entry from list and reinitialize it.
|
||||
* @entry: the element to delete from the list.
|
||||
*/
|
||||
static inline void list_del_init(struct list_head *entry)
|
||||
{
|
||||
__list_del_entry(entry);
|
||||
INIT_LIST_HEAD(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_move - delete from one list and add as another's head
|
||||
* @list: the entry to move
|
||||
* @head: the head that will precede our entry
|
||||
*/
|
||||
static inline void list_move(struct list_head *list, struct list_head *head)
|
||||
{
|
||||
__list_del_entry(list);
|
||||
list_add(list, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_move_tail - delete from one list and add as another's tail
|
||||
* @list: the entry to move
|
||||
* @head: the head that will follow our entry
|
||||
*/
|
||||
static inline void list_move_tail(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
__list_del_entry(list);
|
||||
list_add_tail(list, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_is_last - tests whether @list is the last entry in list @head
|
||||
* @list: the entry to test
|
||||
* @head: the head of the list
|
||||
*/
|
||||
static inline int list_is_last(const struct list_head *list,
|
||||
const struct list_head *head)
|
||||
{
|
||||
return list->next == head;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_empty - tests whether a list is empty
|
||||
* @head: the list to test.
|
||||
*/
|
||||
static inline int list_empty(const struct list_head *head)
|
||||
{
|
||||
return head->next == head;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_empty_careful - tests whether a list is empty and not being modified
|
||||
* @head: the list to test
|
||||
*
|
||||
* Description:
|
||||
* tests whether a list is empty _and_ checks that no other CPU might be
|
||||
* in the process of modifying either member (next or prev)
|
||||
*
|
||||
* NOTE: using list_empty_careful() without synchronization
|
||||
* can only be safe if the only activity that can happen
|
||||
* to the list entry is list_del_init(). Eg. it cannot be used
|
||||
* if another CPU could re-list_add() it.
|
||||
*/
|
||||
static inline int list_empty_careful(const struct list_head *head)
|
||||
{
|
||||
struct list_head *next = head->next;
|
||||
return (next == head) && (next == head->prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_rotate_left - rotate the list to the left
|
||||
* @head: the head of the list
|
||||
*/
|
||||
static inline void list_rotate_left(struct list_head *head)
|
||||
{
|
||||
struct list_head *first;
|
||||
|
||||
if (!list_empty(head)) {
|
||||
first = head->next;
|
||||
list_move_tail(first, head);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* list_is_singular - tests whether a list has just one entry.
|
||||
* @head: the list to test.
|
||||
*/
|
||||
static inline int list_is_singular(const struct list_head *head)
|
||||
{
|
||||
return !list_empty(head) && (head->next == head->prev);
|
||||
}
|
||||
|
||||
static inline void __list_cut_position(struct list_head *list,
|
||||
struct list_head *head, struct list_head *entry)
|
||||
{
|
||||
struct list_head *new_first = entry->next;
|
||||
list->next = head->next;
|
||||
list->next->prev = list;
|
||||
list->prev = entry;
|
||||
entry->next = list;
|
||||
head->next = new_first;
|
||||
new_first->prev = head;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_cut_position - cut a list into two
|
||||
* @list: a new list to add all removed entries
|
||||
* @head: a list with entries
|
||||
* @entry: an entry within head, could be the head itself
|
||||
* and if so we won't cut the list
|
||||
*
|
||||
* This helper moves the initial part of @head, up to and
|
||||
* including @entry, from @head to @list. You should
|
||||
* pass on @entry an element you know is on @head. @list
|
||||
* should be an empty list or a list you do not care about
|
||||
* losing its data.
|
||||
*
|
||||
*/
|
||||
static inline void list_cut_position(struct list_head *list,
|
||||
struct list_head *head, struct list_head *entry)
|
||||
{
|
||||
if (list_empty(head))
|
||||
return;
|
||||
if (list_is_singular(head) &&
|
||||
(head->next != entry && head != entry))
|
||||
return;
|
||||
if (entry == head)
|
||||
INIT_LIST_HEAD(list);
|
||||
else
|
||||
__list_cut_position(list, head, entry);
|
||||
}
|
||||
|
||||
static inline void __list_splice(const struct list_head *list,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
{
|
||||
struct list_head *first = list->next;
|
||||
struct list_head *last = list->prev;
|
||||
|
||||
first->prev = prev;
|
||||
prev->next = first;
|
||||
|
||||
last->next = next;
|
||||
next->prev = last;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_splice - join two lists, this is designed for stacks
|
||||
* @list: the new list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*/
|
||||
static inline void list_splice(const struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list))
|
||||
__list_splice(list, head, head->next);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_splice_tail - join two lists, each list being a queue
|
||||
* @list: the new list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*/
|
||||
static inline void list_splice_tail(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list))
|
||||
__list_splice(list, head->prev, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_splice_init - join two lists and reinitialise the emptied list.
|
||||
* @list: the new list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*
|
||||
* The list at @list is reinitialised
|
||||
*/
|
||||
static inline void list_splice_init(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list)) {
|
||||
__list_splice(list, head, head->next);
|
||||
INIT_LIST_HEAD(list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* list_splice_tail_init - join two lists and reinitialise the emptied list
|
||||
* @list: the new list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*
|
||||
* Each of the lists is a queue.
|
||||
* The list at @list is reinitialised
|
||||
*/
|
||||
static inline void list_splice_tail_init(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list)) {
|
||||
__list_splice(list, head->prev, head);
|
||||
INIT_LIST_HEAD(list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* list_entry - get the struct for this entry
|
||||
* @ptr: the &struct list_head pointer.
|
||||
* @type: the type of the struct this is embedded in.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_entry(ptr, type, member) \
|
||||
container_of(ptr, type, member)
|
||||
|
||||
/**
|
||||
* list_first_entry - get the first element from a list
|
||||
* @ptr: the list head to take the element from.
|
||||
* @type: the type of the struct this is embedded in.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Note, that list is expected to be not empty.
|
||||
*/
|
||||
#define list_first_entry(ptr, type, member) \
|
||||
list_entry((ptr)->next, type, member)
|
||||
|
||||
/**
|
||||
* list_for_each - iterate over a list
|
||||
* @pos: the &struct list_head to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
*/
|
||||
#define list_for_each(pos, head) \
|
||||
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
|
||||
pos = pos->next)
|
||||
|
||||
/**
|
||||
* __list_for_each - iterate over a list
|
||||
* @pos: the &struct list_head to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
*
|
||||
* This variant differs from list_for_each() in that it's the
|
||||
* simplest possible list iteration code, no prefetching is done.
|
||||
* Use this for code that knows the list to be very short (empty
|
||||
* or 1 entry) most of the time.
|
||||
*/
|
||||
#define __list_for_each(pos, head) \
|
||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||
|
||||
/**
|
||||
* list_for_each_prev - iterate over a list backwards
|
||||
* @pos: the &struct list_head to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
*/
|
||||
#define list_for_each_prev(pos, head) \
|
||||
for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
|
||||
pos = pos->prev)
|
||||
|
||||
/**
|
||||
* list_for_each_safe - iterate over a list safe against removal of list entry
|
||||
* @pos: the &struct list_head to use as a loop cursor.
|
||||
* @n: another &struct list_head to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
*/
|
||||
#define list_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
||||
pos = n, n = pos->next)
|
||||
|
||||
/**
|
||||
* list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
|
||||
* @pos: the &struct list_head to use as a loop cursor.
|
||||
* @n: another &struct list_head to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
*/
|
||||
#define list_for_each_prev_safe(pos, n, head) \
|
||||
for (pos = (head)->prev, n = pos->prev; \
|
||||
prefetch(pos->prev), pos != (head); \
|
||||
pos = n, n = pos->prev)
|
||||
|
||||
/**
|
||||
* list_for_each_entry - iterate over list of given type
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_for_each_entry(pos, head, member) \
|
||||
for (pos = list_entry((head)->next, typeof(*pos), member); \
|
||||
prefetch(pos->member.next), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_reverse - iterate backwards over list of given type.
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_for_each_entry_reverse(pos, head, member) \
|
||||
for (pos = list_entry((head)->prev, typeof(*pos), member); \
|
||||
prefetch(pos->member.prev), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.prev, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
|
||||
* @pos: the type * to use as a start point
|
||||
* @head: the head of the list
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Prepares a pos entry for use as a start point in list_for_each_entry_continue().
|
||||
*/
|
||||
#define list_prepare_entry(pos, head, member) \
|
||||
((pos) ? : list_entry(head, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_continue - continue iteration over list of given type
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Continue to iterate over list of given type, continuing after
|
||||
* the current position.
|
||||
*/
|
||||
#define list_for_each_entry_continue(pos, head, member) \
|
||||
for (pos = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
prefetch(pos->member.next), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_continue_reverse - iterate backwards from the given point
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Start to iterate over list of given type backwards, continuing after
|
||||
* the current position.
|
||||
*/
|
||||
#define list_for_each_entry_continue_reverse(pos, head, member) \
|
||||
for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
|
||||
prefetch(pos->member.prev), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.prev, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_from - iterate over list of given type from the current point
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Iterate over list of given type, continuing from current position.
|
||||
*/
|
||||
#define list_for_each_entry_from(pos, head, member) \
|
||||
for (; prefetch(pos->member.next), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @n: another type * to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_for_each_entry_safe(pos, n, head, member) \
|
||||
for (pos = list_entry((head)->next, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe_continue - continue list iteration safe against removal
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @n: another type * to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Iterate over list of given type, continuing after current point,
|
||||
* safe against removal of list entry.
|
||||
*/
|
||||
#define list_for_each_entry_safe_continue(pos, n, head, member) \
|
||||
for (pos = list_entry(pos->member.next, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe_from - iterate over list from current point safe against removal
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @n: another type * to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Iterate over list of given type from current point, safe against
|
||||
* removal of list entry.
|
||||
*/
|
||||
#define list_for_each_entry_safe_from(pos, n, head, member) \
|
||||
for (n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @n: another type * to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Iterate backwards over list of given type, safe against removal
|
||||
* of list entry.
|
||||
*/
|
||||
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
|
||||
for (pos = list_entry((head)->prev, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.prev, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
|
||||
|
||||
/**
|
||||
* list_safe_reset_next - reset a stale list_for_each_entry_safe loop
|
||||
* @pos: the loop cursor used in the list_for_each_entry_safe loop
|
||||
* @n: temporary storage used in list_for_each_entry_safe
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* list_safe_reset_next is not safe to use in general if the list may be
|
||||
* modified concurrently (eg. the lock is dropped in the loop body). An
|
||||
* exception to this is if the cursor element (pos) is pinned in the list,
|
||||
* and list_safe_reset_next is called after re-taking the lock and before
|
||||
* completing the current iteration of the loop body.
|
||||
*/
|
||||
#define list_safe_reset_next(pos, n, member) \
|
||||
n = list_entry(pos->member.next, typeof(*pos), member)
|
||||
|
||||
/*
|
||||
* Double linked lists with a single pointer list head.
|
||||
* Mostly useful for hash tables where the two pointer list head is
|
||||
* too wasteful.
|
||||
* You lose the ability to access the tail in O(1).
|
||||
*/
|
||||
|
||||
#define HLIST_HEAD_INIT { .first = NULL }
|
||||
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
|
||||
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
|
||||
static inline void INIT_HLIST_NODE(struct hlist_node *h)
|
||||
{
|
||||
h->next = NULL;
|
||||
h->pprev = NULL;
|
||||
}
|
||||
|
||||
static inline int hlist_unhashed(const struct hlist_node *h)
|
||||
{
|
||||
return !h->pprev;
|
||||
}
|
||||
|
||||
static inline int hlist_empty(const struct hlist_head *h)
|
||||
{
|
||||
return !h->first;
|
||||
}
|
||||
|
||||
static inline void __hlist_del(struct hlist_node *n)
|
||||
{
|
||||
struct hlist_node *next = n->next;
|
||||
struct hlist_node **pprev = n->pprev;
|
||||
*pprev = next;
|
||||
if (next)
|
||||
next->pprev = pprev;
|
||||
}
|
||||
|
||||
static inline void hlist_del(struct hlist_node *n)
|
||||
{
|
||||
__hlist_del(n);
|
||||
n->next = LIST_POISON1;
|
||||
n->pprev = LIST_POISON2;
|
||||
}
|
||||
|
||||
static inline void hlist_del_init(struct hlist_node *n)
|
||||
{
|
||||
if (!hlist_unhashed(n)) {
|
||||
__hlist_del(n);
|
||||
INIT_HLIST_NODE(n);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
|
||||
{
|
||||
struct hlist_node *first = h->first;
|
||||
n->next = first;
|
||||
if (first)
|
||||
first->pprev = &n->next;
|
||||
h->first = n;
|
||||
n->pprev = &h->first;
|
||||
}
|
||||
|
||||
/* next must be != NULL */
|
||||
static inline void hlist_add_before(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
{
|
||||
n->pprev = next->pprev;
|
||||
n->next = next;
|
||||
next->pprev = &n->next;
|
||||
*(n->pprev) = n;
|
||||
}
|
||||
|
||||
static inline void hlist_add_after(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
{
|
||||
next->next = n->next;
|
||||
n->next = next;
|
||||
next->pprev = &n->next;
|
||||
|
||||
if (next->next)
|
||||
next->next->pprev = &next->next;
|
||||
}
|
||||
|
||||
/* after that we'll appear to be on some hlist and hlist_del will work */
|
||||
static inline void hlist_add_fake(struct hlist_node *n)
|
||||
{
|
||||
n->pprev = &n->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move a list from one list head to another. Fixup the pprev
|
||||
* reference of the first entry if it exists.
|
||||
*/
|
||||
static inline void hlist_move_list(struct hlist_head *old,
|
||||
struct hlist_head *new)
|
||||
{
|
||||
new->first = old->first;
|
||||
if (new->first)
|
||||
new->first->pprev = &new->first;
|
||||
old->first = NULL;
|
||||
}
|
||||
|
||||
#define hlist_entry(ptr, type, member) container_of(ptr, type, member)
|
||||
|
||||
#define hlist_for_each(pos, head) \
|
||||
for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
|
||||
pos = pos->next)
|
||||
|
||||
#define hlist_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
|
||||
pos = n)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry - iterate over list of given type
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry(tpos, pos, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
pos && ({ prefetch(pos->next); 1; }) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
|
||||
pos = pos->next)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_continue - iterate over a hlist continuing after current point
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry_continue(tpos, pos, member) \
|
||||
for (pos = (pos)->next; \
|
||||
pos && ({ prefetch(pos->next); 1; }) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
|
||||
pos = pos->next)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_from - iterate over a hlist continuing from current point
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry_from(tpos, pos, member) \
|
||||
for (; pos && ({ prefetch(pos->next); 1; }) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
|
||||
pos = pos->next)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @n: another &struct hlist_node to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
pos && ({ n = pos->next; 1; }) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
|
||||
pos = n)
|
||||
|
||||
#endif
|
||||
469
debuggers/openocd/src/helper/log.c
Normal file
469
debuggers/openocd/src/helper/log.c
Normal file
@ -0,0 +1,469 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007-2010 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
* spen@spen-soft.co.uk *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "time_support.h"
|
||||
/* @todo the inclusion of server.h here is a layering violation */
|
||||
#include <server/server.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef _DEBUG_FREE_SPACE_
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#error "malloc.h is required to use --enable-malloc-logging"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int debug_level = -1;
|
||||
|
||||
static FILE *log_output;
|
||||
static struct log_callback *log_callbacks;
|
||||
|
||||
static long long last_time;
|
||||
static long long current_time;
|
||||
|
||||
static long long start;
|
||||
|
||||
static char *log_strings[5] = {
|
||||
"User : ",
|
||||
"Error: ",
|
||||
"Warn : ", /* want a space after each colon, all same width, colons aligned */
|
||||
"Info : ",
|
||||
"Debug: "
|
||||
};
|
||||
|
||||
static int count;
|
||||
|
||||
static struct store_log_forward *log_head;
|
||||
static int log_forward_count;
|
||||
|
||||
struct store_log_forward {
|
||||
struct store_log_forward *next;
|
||||
const char *file;
|
||||
int line;
|
||||
const char *function;
|
||||
const char *string;
|
||||
};
|
||||
|
||||
/* either forward the log to the listeners or store it for possible forwarding later */
|
||||
static void log_forward(const char *file, unsigned line, const char *function, const char *string)
|
||||
{
|
||||
if (log_forward_count == 0) {
|
||||
struct log_callback *cb, *next;
|
||||
cb = log_callbacks;
|
||||
/* DANGER!!!! the log callback can remove itself!!!! */
|
||||
while (cb) {
|
||||
next = cb->next;
|
||||
cb->fn(cb->priv, file, line, function, string);
|
||||
cb = next;
|
||||
}
|
||||
} else {
|
||||
struct store_log_forward *log = malloc(sizeof(struct store_log_forward));
|
||||
log->file = strdup(file);
|
||||
log->line = line;
|
||||
log->function = strdup(function);
|
||||
log->string = strdup(string);
|
||||
log->next = NULL;
|
||||
if (log_head == NULL)
|
||||
log_head = log;
|
||||
else {
|
||||
/* append to tail */
|
||||
struct store_log_forward *t;
|
||||
t = log_head;
|
||||
while (t->next != NULL)
|
||||
t = t->next;
|
||||
t->next = log;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The log_puts() serves to somewhat different goals:
|
||||
*
|
||||
* - logging
|
||||
* - feeding low-level info to the user in GDB or Telnet
|
||||
*
|
||||
* The latter dictates that strings without newline are not logged, lest there
|
||||
* will be *MANY log lines when sending one char at the time(e.g.
|
||||
* target_request.c).
|
||||
*
|
||||
*/
|
||||
static void log_puts(enum log_levels level,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *function,
|
||||
const char *string)
|
||||
{
|
||||
char *f;
|
||||
if (level == LOG_LVL_OUTPUT) {
|
||||
/* do not prepend any headers, just print out what we were given and return */
|
||||
fputs(string, log_output);
|
||||
fflush(log_output);
|
||||
return;
|
||||
}
|
||||
|
||||
f = strrchr(file, '/');
|
||||
if (f != NULL)
|
||||
file = f + 1;
|
||||
|
||||
if (strlen(string) > 0) {
|
||||
if (debug_level >= LOG_LVL_DEBUG) {
|
||||
/* print with count and time information */
|
||||
int t = (int)(timeval_ms()-start);
|
||||
#ifdef _DEBUG_FREE_SPACE_
|
||||
struct mallinfo info;
|
||||
info = mallinfo();
|
||||
#endif
|
||||
fprintf(log_output, "%s%d %d %s:%d %s()"
|
||||
#ifdef _DEBUG_FREE_SPACE_
|
||||
" %d"
|
||||
#endif
|
||||
": %s", log_strings[level + 1], count, t, file, line, function,
|
||||
#ifdef _DEBUG_FREE_SPACE_
|
||||
info.fordblks,
|
||||
#endif
|
||||
string);
|
||||
} else {
|
||||
/* if we are using gdb through pipes then we do not want any output
|
||||
* to the pipe otherwise we get repeated strings */
|
||||
fprintf(log_output, "%s%s",
|
||||
(level > LOG_LVL_USER) ? log_strings[level + 1] : "", string);
|
||||
}
|
||||
} else {
|
||||
/* Empty strings are sent to log callbacks to keep e.g. gdbserver alive, here we do
|
||||
*nothing. */
|
||||
}
|
||||
|
||||
fflush(log_output);
|
||||
|
||||
/* Never forward LOG_LVL_DEBUG, too verbose and they can be found in the log if need be */
|
||||
if (level <= LOG_LVL_INFO)
|
||||
log_forward(file, line, function, string);
|
||||
}
|
||||
|
||||
void log_printf(enum log_levels level,
|
||||
const char *file,
|
||||
unsigned line,
|
||||
const char *function,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
char *string;
|
||||
va_list ap;
|
||||
|
||||
count++;
|
||||
if (level > debug_level)
|
||||
return;
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
string = alloc_vprintf(format, ap);
|
||||
if (string != NULL) {
|
||||
log_puts(level, file, line, function, string);
|
||||
free(string);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void log_printf_lf(enum log_levels level,
|
||||
const char *file,
|
||||
unsigned line,
|
||||
const char *function,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
char *string;
|
||||
va_list ap;
|
||||
|
||||
count++;
|
||||
if (level > debug_level)
|
||||
return;
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
string = alloc_vprintf(format, ap);
|
||||
if (string != NULL) {
|
||||
strcat(string, "\n"); /* alloc_vprintf guaranteed the buffer to be at least one
|
||||
*char longer */
|
||||
log_puts(level, file, line, function, string);
|
||||
free(string);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_debug_level_command)
|
||||
{
|
||||
if (CMD_ARGC == 1) {
|
||||
int new_level;
|
||||
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], new_level);
|
||||
if ((new_level > LOG_LVL_DEBUG) || (new_level < LOG_LVL_SILENT)) {
|
||||
LOG_ERROR("level must be between %d and %d", LOG_LVL_SILENT, LOG_LVL_DEBUG);
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
debug_level = new_level;
|
||||
} else if (CMD_ARGC > 1)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
command_print(CMD_CTX, "debug_level: %i", debug_level);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_log_output_command)
|
||||
{
|
||||
if (CMD_ARGC == 1) {
|
||||
FILE *file = fopen(CMD_ARGV[0], "w");
|
||||
|
||||
if (file)
|
||||
log_output = file;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static struct command_registration log_command_handlers[] = {
|
||||
{
|
||||
.name = "log_output",
|
||||
.handler = handle_log_output_command,
|
||||
.mode = COMMAND_ANY,
|
||||
.help = "redirect logging to a file (default: stderr)",
|
||||
.usage = "file_name",
|
||||
},
|
||||
{
|
||||
.name = "debug_level",
|
||||
.handler = handle_debug_level_command,
|
||||
.mode = COMMAND_ANY,
|
||||
.help = "Sets the verbosity level of debugging output. "
|
||||
"0 shows errors only; 1 adds warnings; "
|
||||
"2 (default) adds other info; 3 adds debugging.",
|
||||
.usage = "number",
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
int log_register_commands(struct command_context *cmd_ctx)
|
||||
{
|
||||
return register_commands(cmd_ctx, NULL, log_command_handlers);
|
||||
}
|
||||
|
||||
void log_init(void)
|
||||
{
|
||||
/* set defaults for daemon configuration,
|
||||
* if not set by cmdline or cfgfile */
|
||||
if (debug_level == -1)
|
||||
debug_level = LOG_LVL_INFO;
|
||||
|
||||
char *debug_env = getenv("OPENOCD_DEBUG_LEVEL");
|
||||
if (NULL != debug_env) {
|
||||
int value;
|
||||
int retval = parse_int(debug_env, &value);
|
||||
if (ERROR_OK == retval &&
|
||||
debug_level >= LOG_LVL_SILENT &&
|
||||
debug_level <= LOG_LVL_DEBUG)
|
||||
debug_level = value;
|
||||
}
|
||||
|
||||
if (log_output == NULL)
|
||||
log_output = stderr;
|
||||
|
||||
start = last_time = timeval_ms();
|
||||
}
|
||||
|
||||
int set_log_output(struct command_context *cmd_ctx, FILE *output)
|
||||
{
|
||||
log_output = output;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* add/remove log callback handler */
|
||||
int log_add_callback(log_callback_fn fn, void *priv)
|
||||
{
|
||||
struct log_callback *cb;
|
||||
|
||||
/* prevent the same callback to be registered more than once, just for sure */
|
||||
for (cb = log_callbacks; cb; cb = cb->next) {
|
||||
if (cb->fn == fn && cb->priv == priv)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
/* alloc memory, it is safe just to return in case of an error, no need for the caller to
|
||||
*check this */
|
||||
cb = malloc(sizeof(struct log_callback));
|
||||
if (cb == NULL)
|
||||
return ERROR_BUF_TOO_SMALL;
|
||||
|
||||
/* add item to the beginning of the linked list */
|
||||
cb->fn = fn;
|
||||
cb->priv = priv;
|
||||
cb->next = log_callbacks;
|
||||
log_callbacks = cb;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int log_remove_callback(log_callback_fn fn, void *priv)
|
||||
{
|
||||
struct log_callback *cb, **p;
|
||||
|
||||
for (p = &log_callbacks; (cb = *p); p = &(*p)->next) {
|
||||
if (cb->fn == fn && cb->priv == priv) {
|
||||
*p = cb->next;
|
||||
free(cb);
|
||||
return ERROR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* no such item */
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
/* return allocated string w/printf() result */
|
||||
char *alloc_vprintf(const char *fmt, va_list ap)
|
||||
{
|
||||
va_list ap_copy;
|
||||
int len;
|
||||
char *string;
|
||||
|
||||
/* determine the length of the buffer needed */
|
||||
va_copy(ap_copy, ap);
|
||||
len = vsnprintf(NULL, 0, fmt, ap_copy);
|
||||
va_end(ap_copy);
|
||||
|
||||
/* allocate and make room for terminating zero. */
|
||||
/* FIXME: The old version always allocated at least one byte extra and
|
||||
* other code depend on that. They should be probably be fixed, but for
|
||||
* now reserve the extra byte. */
|
||||
string = malloc(len + 2);
|
||||
if (string == NULL)
|
||||
return NULL;
|
||||
|
||||
/* do the real work */
|
||||
vsnprintf(string, len + 1, fmt, ap);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
char *alloc_printf(const char *format, ...)
|
||||
{
|
||||
char *string;
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
string = alloc_vprintf(format, ap);
|
||||
va_end(ap);
|
||||
return string;
|
||||
}
|
||||
|
||||
/* Code must return to the server loop before 1000ms has returned or invoke
|
||||
* this function.
|
||||
*
|
||||
* The GDB connection will time out if it spends >2000ms and you'll get nasty
|
||||
* error messages from GDB:
|
||||
*
|
||||
* Ignoring packet error, continuing...
|
||||
* Reply contains invalid hex digit 116
|
||||
*
|
||||
* While it is possible use "set remotetimeout" to more than the default 2000ms
|
||||
* in GDB, OpenOCD guarantees that it sends keep-alive packages on the
|
||||
* GDB protocol and it is a bug in OpenOCD not to either return to the server
|
||||
* loop or invoke keep_alive() every 1000ms.
|
||||
*
|
||||
* This function will send a keep alive packet if >500ms has passed since last time
|
||||
* it was invoked.
|
||||
*
|
||||
* Note that this function can be invoked often, so it needs to be relatively
|
||||
* fast when invoked more often than every 500ms.
|
||||
*
|
||||
*/
|
||||
void keep_alive()
|
||||
{
|
||||
current_time = timeval_ms();
|
||||
if (current_time-last_time > 1000) {
|
||||
extern int gdb_actual_connections;
|
||||
|
||||
if (gdb_actual_connections)
|
||||
LOG_WARNING("keep_alive() was not invoked in the "
|
||||
"1000ms timelimit. GDB alive packet not "
|
||||
"sent! (%lld). Workaround: increase "
|
||||
"\"set remotetimeout\" in GDB",
|
||||
current_time-last_time);
|
||||
else
|
||||
LOG_DEBUG("keep_alive() was not invoked in the "
|
||||
"1000ms timelimit (%lld). This may cause "
|
||||
"trouble with GDB connections.",
|
||||
current_time-last_time);
|
||||
}
|
||||
if (current_time-last_time > 500) {
|
||||
/* this will keep the GDB connection alive */
|
||||
LOG_USER_N("%s", "");
|
||||
|
||||
/* DANGER!!!! do not add code to invoke e.g. target event processing,
|
||||
* jim timer processing, etc. it can cause infinite recursion +
|
||||
* jim event callbacks need to happen at a well defined time,
|
||||
* not anywhere keep_alive() is invoked.
|
||||
*
|
||||
* These functions should be invoked at a well defined spot in server.c
|
||||
*/
|
||||
|
||||
last_time = current_time;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset keep alive timer without sending message */
|
||||
void kept_alive()
|
||||
{
|
||||
current_time = timeval_ms();
|
||||
last_time = current_time;
|
||||
}
|
||||
|
||||
/* if we sleep for extended periods of time, we must invoke keep_alive() intermittantly */
|
||||
void alive_sleep(uint64_t ms)
|
||||
{
|
||||
uint64_t napTime = 10;
|
||||
for (uint64_t i = 0; i < ms; i += napTime) {
|
||||
uint64_t sleep_a_bit = ms - i;
|
||||
if (sleep_a_bit > napTime)
|
||||
sleep_a_bit = napTime;
|
||||
|
||||
usleep(sleep_a_bit * 1000);
|
||||
keep_alive();
|
||||
}
|
||||
}
|
||||
|
||||
void busy_sleep(uint64_t ms)
|
||||
{
|
||||
uint64_t then = timeval_ms();
|
||||
while (timeval_ms() - then < ms) {
|
||||
/*
|
||||
* busy wait
|
||||
*/
|
||||
}
|
||||
}
|
||||
142
debuggers/openocd/src/helper/log.h
Normal file
142
debuggers/openocd/src/helper/log.h
Normal file
@ -0,0 +1,142 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
* spen@spen-soft.co.uk *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef ERROR_H
|
||||
#define ERROR_H
|
||||
|
||||
#include <helper/command.h>
|
||||
|
||||
/* To achieve C99 printf compatibility in MinGW, gnu_printf should be
|
||||
* used for __attribute__((format( ... ))), with GCC v4.4 or later
|
||||
*/
|
||||
#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004))
|
||||
#define PRINTF_ATTRIBUTE_FORMAT gnu_printf
|
||||
#else
|
||||
#define PRINTF_ATTRIBUTE_FORMAT printf
|
||||
#endif
|
||||
|
||||
/* logging priorities
|
||||
* LOG_LVL_SILENT - turn off all output. In lieu of try + catch this can be used as a
|
||||
* feeble ersatz.
|
||||
* LOG_LVL_USER - user messages. Could be anything from information
|
||||
* to progress messags. These messages do not represent
|
||||
* incorrect or unexpected behaviour, just normal execution.
|
||||
* LOG_LVL_ERROR - fatal errors, that are likely to cause program abort
|
||||
* LOG_LVL_WARNING - non-fatal errors, that may be resolved later
|
||||
* LOG_LVL_INFO - state information, etc.
|
||||
* LOG_LVL_DEBUG - debug statements, execution trace
|
||||
*/
|
||||
enum log_levels {
|
||||
LOG_LVL_SILENT = -3,
|
||||
LOG_LVL_OUTPUT = -2,
|
||||
LOG_LVL_USER = -1,
|
||||
LOG_LVL_ERROR = 0,
|
||||
LOG_LVL_WARNING = 1,
|
||||
LOG_LVL_INFO = 2,
|
||||
LOG_LVL_DEBUG = 3
|
||||
};
|
||||
|
||||
void log_printf(enum log_levels level, const char *file, unsigned line,
|
||||
const char *function, const char *format, ...)
|
||||
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6)));
|
||||
void log_printf_lf(enum log_levels level, const char *file, unsigned line,
|
||||
const char *function, const char *format, ...)
|
||||
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6)));
|
||||
|
||||
/**
|
||||
* Initialize logging module. Call during program startup.
|
||||
*/
|
||||
void log_init(void);
|
||||
int set_log_output(struct command_context *cmd_ctx, FILE *output);
|
||||
|
||||
int log_register_commands(struct command_context *cmd_ctx);
|
||||
|
||||
void keep_alive(void);
|
||||
void kept_alive(void);
|
||||
|
||||
void alive_sleep(uint64_t ms);
|
||||
void busy_sleep(uint64_t ms);
|
||||
|
||||
typedef void (*log_callback_fn)(void *priv, const char *file, unsigned line,
|
||||
const char *function, const char *string);
|
||||
|
||||
struct log_callback {
|
||||
log_callback_fn fn;
|
||||
void *priv;
|
||||
struct log_callback *next;
|
||||
};
|
||||
|
||||
int log_add_callback(log_callback_fn fn, void *priv);
|
||||
int log_remove_callback(log_callback_fn fn, void *priv);
|
||||
|
||||
char *alloc_vprintf(const char *fmt, va_list ap);
|
||||
char *alloc_printf(const char *fmt, ...);
|
||||
|
||||
extern int debug_level;
|
||||
|
||||
/* Avoid fn call and building parameter list if we're not outputting the information.
|
||||
* Matters on feeble CPUs for DEBUG/INFO statements that are involved frequently */
|
||||
|
||||
#define LOG_LEVEL_IS(FOO) ((debug_level) >= (FOO))
|
||||
|
||||
#define LOG_DEBUG(expr ...) \
|
||||
do { \
|
||||
if (debug_level >= LOG_LVL_DEBUG) \
|
||||
log_printf_lf(LOG_LVL_DEBUG, \
|
||||
__FILE__, __LINE__, __func__, \
|
||||
expr); \
|
||||
} while (0)
|
||||
|
||||
#define LOG_INFO(expr ...) \
|
||||
log_printf_lf(LOG_LVL_INFO, __FILE__, __LINE__, __func__, expr)
|
||||
|
||||
#define LOG_WARNING(expr ...) \
|
||||
log_printf_lf(LOG_LVL_WARNING, __FILE__, __LINE__, __func__, expr)
|
||||
|
||||
#define LOG_ERROR(expr ...) \
|
||||
log_printf_lf(LOG_LVL_ERROR, __FILE__, __LINE__, __func__, expr)
|
||||
|
||||
#define LOG_USER(expr ...) \
|
||||
log_printf_lf(LOG_LVL_USER, __FILE__, __LINE__, __func__, expr)
|
||||
|
||||
#define LOG_USER_N(expr ...) \
|
||||
log_printf(LOG_LVL_USER, __FILE__, __LINE__, __func__, expr)
|
||||
|
||||
#define LOG_OUTPUT(expr ...) \
|
||||
log_printf(LOG_LVL_OUTPUT, __FILE__, __LINE__, __func__, expr)
|
||||
|
||||
/* general failures
|
||||
* error codes < 100
|
||||
*/
|
||||
#define ERROR_OK (0)
|
||||
#define ERROR_NO_CONFIG_FILE (-2)
|
||||
#define ERROR_BUF_TOO_SMALL (-3)
|
||||
/* see "Error:" log entry for meaningful message to the user. The caller should
|
||||
* make no assumptions about what went wrong and try to handle the problem.
|
||||
*/
|
||||
#define ERROR_FAIL (-4)
|
||||
|
||||
#endif /* LOG_H */
|
||||
214
debuggers/openocd/src/helper/options.c
Normal file
214
debuggers/openocd/src/helper/options.c
Normal file
@ -0,0 +1,214 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007-2010 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "configuration.h"
|
||||
/* @todo the inclusion of server.h here is a layering violation */
|
||||
#include <server/server.h>
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
static int help_flag, version_flag;
|
||||
|
||||
static const struct option long_options[] = {
|
||||
{"help", no_argument, &help_flag, 1},
|
||||
{"version", no_argument, &version_flag, 1},
|
||||
{"debug", optional_argument, 0, 'd'},
|
||||
{"file", required_argument, 0, 'f'},
|
||||
{"search", required_argument, 0, 's'},
|
||||
{"log_output", required_argument, 0, 'l'},
|
||||
{"command", required_argument, 0, 'c'},
|
||||
{"pipe", no_argument, 0, 'p'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int configuration_output_handler(struct command_context *context, const char *line)
|
||||
{
|
||||
LOG_USER_N("%s", line);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static void add_default_dirs(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
char strExePath[MAX_PATH];
|
||||
char *path;
|
||||
GetModuleFileName(NULL, strExePath, MAX_PATH);
|
||||
|
||||
/* Strip executable file name, leaving path */
|
||||
*strrchr(strExePath, '\\') = '\0';
|
||||
|
||||
/* Convert path separators to UNIX style, should work on Windows also. */
|
||||
for (char *p = strExePath; *p; p++) {
|
||||
if (*p == '\\')
|
||||
*p = '/';
|
||||
}
|
||||
|
||||
/* Add the parent of the directory where openocd.exe resides to the
|
||||
* config script search path.
|
||||
*
|
||||
* bin/openocd.exe
|
||||
* interface/dummy.cfg
|
||||
* target/at91eb40a.cfg
|
||||
*/
|
||||
path = alloc_printf("%s%s", strExePath, "/..");
|
||||
if (path) {
|
||||
add_script_search_dir(path);
|
||||
free(path);
|
||||
}
|
||||
/* Add support for the directory layout resulting from a 'make install'.
|
||||
*
|
||||
* bin/openocd.exe
|
||||
* share/openocd/scripts/interface/dummy.cfg
|
||||
* share/openocd/scripts/target/at91eb40a.cfg
|
||||
*/
|
||||
path = alloc_printf("%s%s", strExePath, "/../share/" PACKAGE "/scripts");
|
||||
if (path) {
|
||||
add_script_search_dir(path);
|
||||
free(path);
|
||||
}
|
||||
/* Add single "scripts" folder to search path for Windows OpenOCD builds that don't use cygwin
|
||||
*
|
||||
* bin/openocd.exe
|
||||
* scripts/interface/dummy.cfg
|
||||
* scripts/target/at91eb40a.cfg
|
||||
*/
|
||||
path = alloc_printf("%s%s", strExePath, "/../scripts");
|
||||
if (path) {
|
||||
add_script_search_dir(path);
|
||||
free(path);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* The directory containing OpenOCD-supplied scripts should be
|
||||
* listed last in the built-in search order, so the user can
|
||||
* override these scripts with site-specific customizations.
|
||||
*/
|
||||
|
||||
const char *home = getenv("HOME");
|
||||
|
||||
if (home) {
|
||||
char *path;
|
||||
|
||||
path = alloc_printf("%s/.openocd", home);
|
||||
|
||||
if (path) {
|
||||
add_script_search_dir(path);
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
|
||||
add_script_search_dir(PKGDATADIR "/site");
|
||||
add_script_search_dir(PKGDATADIR "/scripts");
|
||||
#endif
|
||||
}
|
||||
|
||||
int parse_cmdline_args(struct command_context *cmd_ctx, int argc, char *argv[])
|
||||
{
|
||||
int c;
|
||||
char command_buffer[128];
|
||||
|
||||
while (1) {
|
||||
/* getopt_long stores the option index here. */
|
||||
int option_index = 0;
|
||||
|
||||
c = getopt_long(argc, argv, "hvd::l:f:s:c:p", long_options, &option_index);
|
||||
|
||||
/* Detect the end of the options. */
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 0:
|
||||
break;
|
||||
case 'h': /* --help | -h */
|
||||
help_flag = 1;
|
||||
break;
|
||||
case 'v': /* --version | -v */
|
||||
version_flag = 1;
|
||||
break;
|
||||
case 'f': /* --file | -f */
|
||||
{
|
||||
snprintf(command_buffer, 128, "script {%s}", optarg);
|
||||
add_config_command(command_buffer);
|
||||
break;
|
||||
}
|
||||
case 's': /* --search | -s */
|
||||
add_script_search_dir(optarg);
|
||||
break;
|
||||
case 'd': /* --debug | -d */
|
||||
if (optarg)
|
||||
snprintf(command_buffer, 128, "debug_level %s", optarg);
|
||||
else
|
||||
snprintf(command_buffer, 128, "debug_level 3");
|
||||
command_run_line(cmd_ctx, command_buffer);
|
||||
break;
|
||||
case 'l': /* --log_output | -l */
|
||||
if (optarg) {
|
||||
snprintf(command_buffer, 128, "log_output %s", optarg);
|
||||
command_run_line(cmd_ctx, command_buffer);
|
||||
}
|
||||
break;
|
||||
case 'c': /* --command | -c */
|
||||
if (optarg)
|
||||
add_config_command(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
/* to replicate the old syntax this needs to be synchronous
|
||||
* otherwise the gdb stdin will overflow with the warning message */
|
||||
command_run_line(cmd_ctx, "gdb_port pipe; log_output openocd.log");
|
||||
LOG_WARNING("deprecated option: -p/--pipe. Use '-c \"gdb_port pipe; "
|
||||
"log_output openocd.log\"' instead.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (help_flag) {
|
||||
LOG_OUTPUT("Open On-Chip Debugger\nLicensed under GNU GPL v2\n");
|
||||
LOG_OUTPUT("--help | -h\tdisplay this help\n");
|
||||
LOG_OUTPUT("--version | -v\tdisplay OpenOCD version\n");
|
||||
LOG_OUTPUT("--file | -f\tuse configuration file <name>\n");
|
||||
LOG_OUTPUT("--search | -s\tdir to search for config files and scripts\n");
|
||||
LOG_OUTPUT("--debug | -d\tset debug level <0-3>\n");
|
||||
LOG_OUTPUT("--log_output | -l\tredirect log output to file <name>\n");
|
||||
LOG_OUTPUT("--command | -c\trun <command>\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (version_flag) {
|
||||
/* Nothing to do, version gets printed automatically. */
|
||||
/* It is not an error to request the VERSION number. */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* paths specified on the command line take precedence over these
|
||||
* built-in paths
|
||||
*/
|
||||
add_default_dirs();
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
278
debuggers/openocd/src/helper/replacements.c
Normal file
278
debuggers/openocd/src/helper/replacements.c
Normal file
@ -0,0 +1,278 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
* spen@spen-soft.co.uk *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
/* DANGER!!!! These must be defined *BEFORE* replacements.h and the malloc() macro!!!! */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
/*
|
||||
* clear_malloc
|
||||
*
|
||||
* will alloc memory and clear it
|
||||
*/
|
||||
void *clear_malloc(size_t size)
|
||||
{
|
||||
void *t = malloc(size);
|
||||
if (t != NULL)
|
||||
memset(t, 0x00, size);
|
||||
return t;
|
||||
}
|
||||
|
||||
void *fill_malloc(size_t size)
|
||||
{
|
||||
void *t = malloc(size);
|
||||
if (t != NULL) {
|
||||
/* We want to initialize memory to some known bad state.
|
||||
* 0 and 0xff yields 0 and -1 as integers, which often
|
||||
* have meaningful values. 0x5555... is not often a valid
|
||||
* integer and is quite easily spotted in the debugger
|
||||
* also it is almost certainly an invalid address */
|
||||
memset(t, 0x55, size);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
#define IN_REPLACEMENTS_C
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
/* replacements for gettimeofday */
|
||||
#ifndef HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Windows */
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define EPOCHFILETIME (116444736000000000i64)
|
||||
#else
|
||||
#define EPOCHFILETIME (116444736000000000LL)
|
||||
#endif
|
||||
|
||||
int gettimeofday(struct timeval *tv, struct timezone *tz)
|
||||
{
|
||||
FILETIME ft;
|
||||
LARGE_INTEGER li;
|
||||
__int64 t;
|
||||
static int tzflag;
|
||||
|
||||
if (tv) {
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
li.LowPart = ft.dwLowDateTime;
|
||||
li.HighPart = ft.dwHighDateTime;
|
||||
t = li.QuadPart; /* In 100-nanosecond intervals */
|
||||
t -= EPOCHFILETIME; /* Offset to the Epoch time */
|
||||
t /= 10; /* In microseconds */
|
||||
tv->tv_sec = (long)(t / 1000000);
|
||||
tv->tv_usec = (long)(t % 1000000);
|
||||
}
|
||||
|
||||
if (tz) {
|
||||
if (!tzflag) {
|
||||
_tzset();
|
||||
tzflag++;
|
||||
}
|
||||
tz->tz_minuteswest = _timezone / 60;
|
||||
tz->tz_dsttime = _daylight;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* HAVE_GETTIMEOFDAY */
|
||||
|
||||
#ifndef HAVE_STRNLEN
|
||||
size_t strnlen(const char *s, size_t maxlen)
|
||||
{
|
||||
const char *end = (const char *)memchr(s, '\0', maxlen);
|
||||
return end ? (size_t) (end - s) : maxlen;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRNDUP
|
||||
char *strndup(const char *s, size_t n)
|
||||
{
|
||||
size_t len = strnlen(s, n);
|
||||
char *new = (char *) malloc(len + 1);
|
||||
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
|
||||
new[len] = '\0';
|
||||
return (char *) memcpy(new, s, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
int win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
|
||||
{
|
||||
DWORD ms_total, limit;
|
||||
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
|
||||
int handle_slot_to_fd[MAXIMUM_WAIT_OBJECTS];
|
||||
int n_handles = 0, i;
|
||||
fd_set sock_read, sock_write, sock_except;
|
||||
fd_set aread, awrite, aexcept;
|
||||
int sock_max_fd = -1;
|
||||
struct timeval tvslice;
|
||||
int retcode;
|
||||
|
||||
#define SAFE_FD_ISSET(fd, set) (set != NULL && FD_ISSET(fd, set))
|
||||
|
||||
/* calculate how long we need to wait in milliseconds */
|
||||
if (tv == NULL)
|
||||
ms_total = INFINITE;
|
||||
else {
|
||||
ms_total = tv->tv_sec * 1000;
|
||||
ms_total += tv->tv_usec / 1000;
|
||||
}
|
||||
|
||||
FD_ZERO(&sock_read);
|
||||
FD_ZERO(&sock_write);
|
||||
FD_ZERO(&sock_except);
|
||||
|
||||
/* build an array of handles for non-sockets */
|
||||
for (i = 0; i < max_fd; i++) {
|
||||
if (SAFE_FD_ISSET(i, rfds) || SAFE_FD_ISSET(i, wfds) || SAFE_FD_ISSET(i, efds)) {
|
||||
intptr_t handle = (intptr_t) _get_osfhandle(i);
|
||||
handles[n_handles] = (HANDLE)handle;
|
||||
if (handles[n_handles] == INVALID_HANDLE_VALUE) {
|
||||
/* socket */
|
||||
if (SAFE_FD_ISSET(i, rfds))
|
||||
FD_SET(i, &sock_read);
|
||||
if (SAFE_FD_ISSET(i, wfds))
|
||||
FD_SET(i, &sock_write);
|
||||
if (SAFE_FD_ISSET(i, efds))
|
||||
FD_SET(i, &sock_except);
|
||||
if (i > sock_max_fd)
|
||||
sock_max_fd = i;
|
||||
} else {
|
||||
handle_slot_to_fd[n_handles] = i;
|
||||
n_handles++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (n_handles == 0) {
|
||||
/* plain sockets only - let winsock handle the whole thing */
|
||||
return select(max_fd, rfds, wfds, efds, tv);
|
||||
}
|
||||
|
||||
/* mixture of handles and sockets; lets multiplex between
|
||||
* winsock and waiting on the handles */
|
||||
|
||||
FD_ZERO(&aread);
|
||||
FD_ZERO(&awrite);
|
||||
FD_ZERO(&aexcept);
|
||||
|
||||
limit = GetTickCount() + ms_total;
|
||||
do {
|
||||
retcode = 0;
|
||||
|
||||
if (sock_max_fd >= 0) {
|
||||
/* overwrite the zero'd sets here; the select call
|
||||
* will clear those that are not active */
|
||||
aread = sock_read;
|
||||
awrite = sock_write;
|
||||
aexcept = sock_except;
|
||||
|
||||
tvslice.tv_sec = 0;
|
||||
tvslice.tv_usec = 1000;
|
||||
|
||||
retcode = select(sock_max_fd + 1, &aread, &awrite, &aexcept, &tvslice);
|
||||
}
|
||||
|
||||
if (n_handles > 0) {
|
||||
/* check handles */
|
||||
DWORD wret;
|
||||
|
||||
wret = MsgWaitForMultipleObjects(n_handles,
|
||||
handles,
|
||||
FALSE,
|
||||
retcode > 0 ? 0 : 1,
|
||||
QS_ALLEVENTS);
|
||||
|
||||
if (wret == WAIT_TIMEOUT) {
|
||||
/* set retcode to 0; this is the default.
|
||||
* select() may have set it to something else,
|
||||
* in which case we leave it alone, so this branch
|
||||
* does nothing */
|
||||
;
|
||||
} else if (wret == WAIT_FAILED) {
|
||||
if (retcode == 0)
|
||||
retcode = -1;
|
||||
} else {
|
||||
if (retcode < 0)
|
||||
retcode = 0;
|
||||
for (i = 0; i < n_handles; i++) {
|
||||
if (WAIT_OBJECT_0 == WaitForSingleObject(handles[i], 0)) {
|
||||
if (SAFE_FD_ISSET(handle_slot_to_fd[i], rfds)) {
|
||||
DWORD dwBytes;
|
||||
intptr_t handle = (intptr_t) _get_osfhandle(
|
||||
handle_slot_to_fd[i]);
|
||||
|
||||
if (PeekNamedPipe((HANDLE)handle, NULL, 0,
|
||||
NULL, &dwBytes, NULL)) {
|
||||
/* check to see if gdb pipe has data available */
|
||||
if (dwBytes) {
|
||||
FD_SET(handle_slot_to_fd[i], &aread);
|
||||
retcode++;
|
||||
}
|
||||
} else {
|
||||
FD_SET(handle_slot_to_fd[i], &aread);
|
||||
retcode++;
|
||||
}
|
||||
}
|
||||
if (SAFE_FD_ISSET(handle_slot_to_fd[i], wfds)) {
|
||||
FD_SET(handle_slot_to_fd[i], &awrite);
|
||||
retcode++;
|
||||
}
|
||||
if (SAFE_FD_ISSET(handle_slot_to_fd[i], efds)) {
|
||||
FD_SET(handle_slot_to_fd[i], &aexcept);
|
||||
retcode++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (retcode == 0 && (ms_total == INFINITE || GetTickCount() < limit));
|
||||
|
||||
if (rfds)
|
||||
*rfds = aread;
|
||||
if (wfds)
|
||||
*wfds = awrite;
|
||||
if (efds)
|
||||
*efds = aexcept;
|
||||
|
||||
return retcode;
|
||||
}
|
||||
#endif
|
||||
282
debuggers/openocd/src/helper/replacements.h
Normal file
282
debuggers/openocd/src/helper/replacements.h
Normal file
@ -0,0 +1,282 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
* spen@spen-soft.co.uk *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef REPLACEMENTS_H
|
||||
#define REPLACEMENTS_H
|
||||
|
||||
/* MIN,MAX macros */
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/* for systems that do not support ENOTSUP
|
||||
* win32 being one of them */
|
||||
#ifndef ENOTSUP
|
||||
#define ENOTSUP 134 /* Not supported */
|
||||
#endif
|
||||
|
||||
/* for systems that do not support O_BINARY
|
||||
* linux being one of them */
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SYS_TIME_H
|
||||
|
||||
#ifndef _TIMEVAL_DEFINED
|
||||
#define _TIMEVAL_DEFINED
|
||||
|
||||
struct timeval {
|
||||
long tv_sec;
|
||||
long tv_usec;
|
||||
};
|
||||
|
||||
#endif /* _TIMEVAL_DEFINED */
|
||||
|
||||
#endif
|
||||
|
||||
/* gettimeofday() */
|
||||
#ifndef HAVE_GETTIMEOFDAY
|
||||
|
||||
#ifdef _WIN32
|
||||
struct timezone {
|
||||
int tz_minuteswest;
|
||||
int tz_dsttime;
|
||||
};
|
||||
#endif
|
||||
struct timezone;
|
||||
|
||||
int gettimeofday(struct timeval *tv, struct timezone *tz);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef IN_REPLACEMENTS_C
|
||||
/**** clear_malloc & fill_malloc ****/
|
||||
void *clear_malloc(size_t size);
|
||||
void *fill_malloc(size_t size);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Now you have 3 ways for the malloc function:
|
||||
*
|
||||
* 1. Do not change anything, use the original malloc
|
||||
*
|
||||
* 2. Use the clear_malloc function instead of the original malloc.
|
||||
* In this case you must use the following define:
|
||||
* #define malloc((_a)) clear_malloc((_a))
|
||||
*
|
||||
* 3. Use the fill_malloc function instead of the original malloc.
|
||||
* In this case you must use the following define:
|
||||
* #define malloc((_a)) fill_malloc((_a))
|
||||
*
|
||||
* We have figured out that there could exist some malloc problems
|
||||
* where variables are using without to be initialise. To find this
|
||||
* places, use the fill_malloc function. With this function we want
|
||||
* to initialize memory to some known bad state. This is quite easily
|
||||
* spotted in the debugger and will trap to an invalid address.
|
||||
*
|
||||
* clear_malloc can be used if you want to set not initialise
|
||||
* variable to 0.
|
||||
*
|
||||
* If you do not want to change the malloc function, to not use one of
|
||||
* the following macros. Which is the default way.
|
||||
*/
|
||||
|
||||
/* #define malloc(_a) clear_malloc(_a)
|
||||
* #define malloc(_a) fill_malloc(_a) */
|
||||
|
||||
/* GNU extensions to the C library that may be missing on some systems */
|
||||
#ifndef HAVE_STRNDUP
|
||||
char *strndup(const char *s, size_t n);
|
||||
#endif /* HAVE_STRNDUP */
|
||||
|
||||
#ifndef HAVE_STRNLEN
|
||||
size_t strnlen(const char *s, size_t maxlen);
|
||||
#endif /* HAVE_STRNLEN */
|
||||
|
||||
#ifndef HAVE_USLEEP
|
||||
#ifdef _WIN32
|
||||
static inline unsigned usleep(unsigned int usecs)
|
||||
{
|
||||
Sleep((usecs/1000));
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#error no usleep defined for your platform
|
||||
#endif
|
||||
#endif /* HAVE_USLEEP */
|
||||
|
||||
/* Windows specific */
|
||||
#ifdef _WIN32
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
|
||||
/* Windows does not declare sockaddr_un */
|
||||
#define UNIX_PATH_LEN 108
|
||||
struct sockaddr_un {
|
||||
uint16_t sun_family;
|
||||
char sun_path[UNIX_PATH_LEN];
|
||||
};
|
||||
|
||||
/* win32 systems do not support ETIMEDOUT */
|
||||
|
||||
#ifndef ETIMEDOUT
|
||||
#define ETIMEDOUT WSAETIMEDOUT
|
||||
#endif
|
||||
|
||||
#if IS_MINGW == 1
|
||||
static inline unsigned char inb(unsigned short int port)
|
||||
{
|
||||
unsigned char _v;
|
||||
__asm__ __volatile__ ("inb %w1,%0" : "=a" (_v) : "Nd" (port));
|
||||
return _v;
|
||||
}
|
||||
|
||||
static inline void outb(unsigned char value, unsigned short int port)
|
||||
{
|
||||
__asm__ __volatile__ ("outb %b0,%w1" : : "a" (value), "Nd" (port));
|
||||
}
|
||||
|
||||
/* mingw does not have ffs, so use gcc builtin types */
|
||||
#define ffs __builtin_ffs
|
||||
|
||||
#endif /* IS_MINGW */
|
||||
|
||||
int win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv);
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* generic socket functions for Windows and Posix */
|
||||
static inline int write_socket(int handle, const void *buffer, unsigned int count)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return send(handle, buffer, count, 0);
|
||||
#else
|
||||
return write(handle, buffer, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int read_socket(int handle, void *buffer, unsigned int count)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return recv(handle, buffer, count, 0);
|
||||
#else
|
||||
return read(handle, buffer, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int close_socket(int sock)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return closesocket(sock);
|
||||
#else
|
||||
return close(sock);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void socket_nonblock(int fd)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
unsigned long nonblock = 1;
|
||||
ioctlsocket(fd, FIONBIO, &nonblock);
|
||||
#else
|
||||
int oldopts = fcntl(fd, F_GETFL, 0);
|
||||
fcntl(fd, F_SETFL, oldopts | O_NONBLOCK);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int socket_select(int max_fd,
|
||||
fd_set *rfds,
|
||||
fd_set *wfds,
|
||||
fd_set *efds,
|
||||
struct timeval *tv)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return win_select(max_fd, rfds, wfds, efds, tv);
|
||||
#else
|
||||
return select(max_fd, rfds, wfds, efds, tv);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE_ELF_H
|
||||
|
||||
typedef uint32_t Elf32_Addr;
|
||||
typedef uint16_t Elf32_Half;
|
||||
typedef uint32_t Elf32_Off;
|
||||
typedef int32_t Elf32_Sword;
|
||||
typedef uint32_t Elf32_Word;
|
||||
typedef uint32_t Elf32_Size;
|
||||
typedef Elf32_Off Elf32_Hashelt;
|
||||
|
||||
typedef struct {
|
||||
unsigned char e_ident[16]; /* Magic number and other info */
|
||||
Elf32_Half e_type; /* Object file type */
|
||||
Elf32_Half e_machine; /* Architecture */
|
||||
Elf32_Word e_version; /* Object file version */
|
||||
Elf32_Addr e_entry; /* Entry point virtual address */
|
||||
Elf32_Off e_phoff; /* Program header table file offset */
|
||||
Elf32_Off e_shoff; /* Section header table file offset */
|
||||
Elf32_Word e_flags; /* Processor-specific flags */
|
||||
Elf32_Half e_ehsize; /* ELF header size in bytes */
|
||||
Elf32_Half e_phentsize; /* Program header table entry size */
|
||||
Elf32_Half e_phnum; /* Program header table entry count */
|
||||
Elf32_Half e_shentsize; /* Section header table entry size */
|
||||
Elf32_Half e_shnum; /* Section header table entry count */
|
||||
Elf32_Half e_shstrndx; /* Section header string table index */
|
||||
} Elf32_Ehdr;
|
||||
|
||||
#define ELFMAG "\177ELF"
|
||||
#define SELFMAG 4
|
||||
|
||||
#define EI_CLASS 4 /* File class byte index */
|
||||
#define ELFCLASS32 1 /* 32-bit objects */
|
||||
#define ELFCLASS64 2 /* 64-bit objects */
|
||||
|
||||
#define EI_DATA 5 /* Data encoding byte index */
|
||||
#define ELFDATA2LSB 1 /* 2's complement, little endian */
|
||||
#define ELFDATA2MSB 2 /* 2's complement, big endian */
|
||||
|
||||
typedef struct {
|
||||
Elf32_Word p_type; /* Segment type */
|
||||
Elf32_Off p_offset; /* Segment file offset */
|
||||
Elf32_Addr p_vaddr; /* Segment virtual address */
|
||||
Elf32_Addr p_paddr; /* Segment physical address */
|
||||
Elf32_Size p_filesz; /* Segment size in file */
|
||||
Elf32_Size p_memsz; /* Segment size in memory */
|
||||
Elf32_Word p_flags; /* Segment flags */
|
||||
Elf32_Size p_align; /* Segment alignment */
|
||||
} Elf32_Phdr;
|
||||
|
||||
#define PT_LOAD 1 /* Loadable program segment */
|
||||
|
||||
#endif /* HAVE_ELF_H */
|
||||
|
||||
#endif /* REPLACEMENTS_H */
|
||||
64
debuggers/openocd/src/helper/startup.tcl
Normal file
64
debuggers/openocd/src/helper/startup.tcl
Normal file
@ -0,0 +1,64 @@
|
||||
# Defines basic Tcl procs that must exist for OpenOCD scripts to work.
|
||||
#
|
||||
# Embedded into OpenOCD executable
|
||||
#
|
||||
|
||||
|
||||
# We need to explicitly redirect this to the OpenOCD command
|
||||
# as Tcl defines the exit proc
|
||||
proc exit {} {
|
||||
ocd_throw exit
|
||||
}
|
||||
|
||||
# All commands are registered with an 'ocd_' prefix, while the "real"
|
||||
# command is a wrapper that calls this function. Its primary purpose is
|
||||
# to discard 'handler' command output,
|
||||
proc ocd_bouncer {name args} {
|
||||
set cmd [format "ocd_%s" $name]
|
||||
set type [eval ocd_command type $cmd $args]
|
||||
if {$type == "native"} {
|
||||
return [eval $cmd $args]
|
||||
} else {if {$type == "simple"} {
|
||||
if {[catch {eval $cmd $args}] == 0} {
|
||||
return ""
|
||||
} else {
|
||||
# 'classic' commands output error message as part of progress output
|
||||
set errmsg ""
|
||||
}
|
||||
} else {if {$type == "group"} {
|
||||
catch {eval ocd_usage $name $args}
|
||||
set errmsg [format "%s: command requires more arguments" \
|
||||
[concat $name " " $args]]
|
||||
} else {
|
||||
set errmsg [format "Unknown command type: %s" $type]
|
||||
}}}
|
||||
return -code error $errmsg
|
||||
}
|
||||
|
||||
# Try flipping / and \ to find file if the filename does not
|
||||
# match the precise spelling
|
||||
proc find {filename} {
|
||||
if {[catch {ocd_find $filename} t]==0} {
|
||||
return $t
|
||||
}
|
||||
if {[catch {ocd_find [string map {\ /} $filename} t]==0} {
|
||||
return $t
|
||||
}
|
||||
if {[catch {ocd_find [string map {/ \\} $filename} t]==0} {
|
||||
return $t
|
||||
}
|
||||
# make sure error message matches original input string
|
||||
return -code error "Can't find $filename"
|
||||
}
|
||||
add_usage_text find "<file>"
|
||||
add_help_text find "print full path to file according to OpenOCD search rules"
|
||||
|
||||
# Find and run a script
|
||||
proc script {filename} {
|
||||
uplevel #0 [list source [find $filename]]
|
||||
}
|
||||
add_help_text script "filename of OpenOCD script (tcl) to run"
|
||||
add_usage_text script "<file>"
|
||||
|
||||
#########
|
||||
|
||||
91
debuggers/openocd/src/helper/system.h
Normal file
91
debuggers/openocd/src/helper/system.h
Normal file
@ -0,0 +1,91 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Dominic Rath <Dominic.Rath@gmx.de> *
|
||||
* Copyright (C) 2007-2008 by Øyvind Harboe <oyvind.harboe@zylin.com> *
|
||||
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
|
||||
* Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SYSTEM_H
|
||||
#define SYSTEM_H
|
||||
|
||||
/* standard C library header files */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* +++ AC_HEADER_TIME +++ */
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
/* --- AC_HEADER_TIME --- */
|
||||
|
||||
/* +++ platform specific headers +++ */
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
/* --- platform specific headers --- */
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_POLL_H
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
|
||||
#ifdef __ECOS
|
||||
/* missing from eCos */
|
||||
#ifndef EFAULT
|
||||
#define EFAULT 14 /* Bad address */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h> /* select, FD_SET and friends (POSIX.1-2001) */
|
||||
#endif
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h> /* for MIN/MAX macros */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifndef true
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_H */
|
||||
91
debuggers/openocd/src/helper/time_support.c
Normal file
91
debuggers/openocd/src/helper/time_support.c
Normal file
@ -0,0 +1,91 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
* spen@spen-soft.co.uk *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "time_support.h"
|
||||
|
||||
/* calculate difference between two struct timeval values */
|
||||
int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y)
|
||||
{
|
||||
if (x->tv_usec < y->tv_usec) {
|
||||
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
|
||||
y->tv_usec -= 1000000 * nsec;
|
||||
y->tv_sec += nsec;
|
||||
}
|
||||
if (x->tv_usec - y->tv_usec > 1000000) {
|
||||
int nsec = (x->tv_usec - y->tv_usec) / 1000000;
|
||||
y->tv_usec += 1000000 * nsec;
|
||||
y->tv_sec -= nsec;
|
||||
}
|
||||
|
||||
result->tv_sec = x->tv_sec - y->tv_sec;
|
||||
result->tv_usec = x->tv_usec - y->tv_usec;
|
||||
|
||||
/* Return 1 if result is negative. */
|
||||
return x->tv_sec < y->tv_sec;
|
||||
}
|
||||
|
||||
int timeval_add_time(struct timeval *result, long sec, long usec)
|
||||
{
|
||||
result->tv_sec += sec;
|
||||
result->tv_usec += usec;
|
||||
|
||||
while (result->tv_usec > 1000000) {
|
||||
result->tv_usec -= 1000000;
|
||||
result->tv_sec++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int duration_start(struct duration *duration)
|
||||
{
|
||||
return gettimeofday(&duration->start, NULL);
|
||||
}
|
||||
|
||||
int duration_measure(struct duration *duration)
|
||||
{
|
||||
struct timeval end;
|
||||
int retval = gettimeofday(&end, NULL);
|
||||
if (0 == retval)
|
||||
timeval_subtract(&duration->elapsed, &end, &duration->start);
|
||||
return retval;
|
||||
}
|
||||
|
||||
float duration_elapsed(struct duration *duration)
|
||||
{
|
||||
float t = duration->elapsed.tv_sec;
|
||||
t += (float)duration->elapsed.tv_usec / 1000000.0;
|
||||
return t;
|
||||
}
|
||||
|
||||
float duration_kbps(struct duration *duration, size_t count)
|
||||
{
|
||||
return count / (1024.0 * duration_elapsed(duration));
|
||||
}
|
||||
62
debuggers/openocd/src/helper/time_support.h
Normal file
62
debuggers/openocd/src/helper/time_support.h
Normal file
@ -0,0 +1,62 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
* spen@spen-soft.co.uk *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TIME_SUPPORT_H
|
||||
#define TIME_SUPPORT_H
|
||||
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y);
|
||||
int timeval_add_time(struct timeval *result, long sec, long usec);
|
||||
|
||||
/** @returns gettimeofday() timeval as 64-bit in ms */
|
||||
int64_t timeval_ms(void);
|
||||
|
||||
struct duration {
|
||||
struct timeval start;
|
||||
struct timeval elapsed;
|
||||
};
|
||||
|
||||
/** Update the duration->start field to start the @a duration measurement. */
|
||||
int duration_start(struct duration *duration);
|
||||
/** Update the duration->elapsed field to finish the @a duration measurment. */
|
||||
int duration_measure(struct duration *duration);
|
||||
|
||||
/** @returns Elapsed time in seconds. */
|
||||
float duration_elapsed(struct duration *duration);
|
||||
/** @returns KB/sec for the elapsed @a duration and @a count bytes. */
|
||||
float duration_kbps(struct duration *duration, size_t count);
|
||||
|
||||
#endif /* TIME_SUPPORT_H */
|
||||
43
debuggers/openocd/src/helper/time_support_common.c
Normal file
43
debuggers/openocd/src/helper/time_support_common.c
Normal file
@ -0,0 +1,43 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
* spen@spen-soft.co.uk *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "time_support.h"
|
||||
|
||||
/* simple and low overhead fetching of ms counter. Use only
|
||||
* the difference between ms counters returned from this fn.
|
||||
*/
|
||||
int64_t timeval_ms()
|
||||
{
|
||||
struct timeval now;
|
||||
int retval = gettimeofday(&now, NULL);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
return (int64_t)now.tv_sec * 1000 + now.tv_usec / 1000;
|
||||
}
|
||||
235
debuggers/openocd/src/helper/types.h
Normal file
235
debuggers/openocd/src/helper/types.h
Normal file
@ -0,0 +1,235 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#include <stddef.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
#include <stdbool.h>
|
||||
#else /* HAVE_STDBOOL_H */
|
||||
#define __bool_true_false_are_defined 1
|
||||
|
||||
#ifndef HAVE__BOOL
|
||||
#ifndef __cplusplus
|
||||
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
typedef int _Bool;
|
||||
#else
|
||||
typedef bool _Bool;
|
||||
#endif /* __cplusplus */
|
||||
#endif /* HAVE__BOOL */
|
||||
|
||||
#define bool _Bool
|
||||
|
||||
#endif /* HAVE_STDBOOL_H */
|
||||
|
||||
/// turns a macro argument into a string constant
|
||||
#define stringify(s) __stringify(s)
|
||||
#define __stringify(s) #s
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of elements of a variable length array.
|
||||
* <code>
|
||||
* const char *strs[] = { "a", "b", "c" };
|
||||
* unsigned num_strs = ARRAY_SIZE(strs);
|
||||
* </code>
|
||||
*/
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
|
||||
|
||||
|
||||
/**
|
||||
* Cast a member of a structure out to the containing structure.
|
||||
* @param ptr The pointer to the member.
|
||||
* @param type The type of the container struct this is embedded in.
|
||||
* @param member The name of the member within the struct.
|
||||
*
|
||||
* This is a mechanism which is used throughout the Linux kernel.
|
||||
*/
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (void *) ( (char *)__mptr - offsetof(type,member) ) );})
|
||||
|
||||
|
||||
/**
|
||||
* Rounds @c m up to the nearest multiple of @c n using division.
|
||||
* @param m The value to round up to @c n.
|
||||
* @param n Round @c m up to a multiple of this number.
|
||||
* @returns The rounded integer value.
|
||||
*/
|
||||
#define DIV_ROUND_UP(m, n) (((m) + (n) - 1) / (n))
|
||||
|
||||
|
||||
/* DANGER!!!! here be dragons!
|
||||
*
|
||||
* Leave these fn's as byte accesses because it is safe
|
||||
* across architectures. Clever usage of 32 bit access
|
||||
* will create problems on some hosts.
|
||||
*
|
||||
* Note that the "buf" pointer in memory is probably unaligned.
|
||||
*
|
||||
* Were these functions to be re-written to take a 32 bit wide or 16 bit wide
|
||||
* memory access shortcut, then on some CPU's, i.e. ARM7, the 2 lsbytes of the address are
|
||||
* ignored for 32 bit access, whereas on other CPU's a 32 bit wide unaligned memory access
|
||||
* will cause an exception, and lastly on x86, an unaligned "greater than bytewide"
|
||||
* memory access works as if aligned. So what follows below will work for all
|
||||
* platforms and gives the compiler leeway to do its own platform specific optimizations.
|
||||
*
|
||||
* Again, note that the "buf" pointer in memory is probably unaligned.
|
||||
*/
|
||||
|
||||
|
||||
static inline uint32_t le_to_h_u32(const uint8_t* buf)
|
||||
{
|
||||
return (uint32_t)(buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24);
|
||||
}
|
||||
|
||||
static inline uint32_t le_to_h_u24(const uint8_t* buf)
|
||||
{
|
||||
return (uint32_t)(buf[0] | buf[1] << 8 | buf[2] << 16);
|
||||
}
|
||||
|
||||
static inline uint16_t le_to_h_u16(const uint8_t* buf)
|
||||
{
|
||||
return (uint16_t)(buf[0] | buf[1] << 8);
|
||||
}
|
||||
|
||||
static inline uint32_t be_to_h_u32(const uint8_t* buf)
|
||||
{
|
||||
return (uint32_t)(buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24);
|
||||
}
|
||||
|
||||
static inline uint32_t be_to_h_u24(const uint8_t* buf)
|
||||
{
|
||||
return (uint32_t)(buf[2] | buf[1] << 8 | buf[0] << 16);
|
||||
}
|
||||
|
||||
static inline uint16_t be_to_h_u16(const uint8_t* buf)
|
||||
{
|
||||
return (uint16_t)(buf[1] | buf[0] << 8);
|
||||
}
|
||||
|
||||
static inline void h_u32_to_le(uint8_t* buf, int val)
|
||||
{
|
||||
buf[3] = (uint8_t) (val >> 24);
|
||||
buf[2] = (uint8_t) (val >> 16);
|
||||
buf[1] = (uint8_t) (val >> 8);
|
||||
buf[0] = (uint8_t) (val >> 0);
|
||||
}
|
||||
|
||||
static inline void h_u32_to_be(uint8_t* buf, int val)
|
||||
{
|
||||
buf[0] = (uint8_t) (val >> 24);
|
||||
buf[1] = (uint8_t) (val >> 16);
|
||||
buf[2] = (uint8_t) (val >> 8);
|
||||
buf[3] = (uint8_t) (val >> 0);
|
||||
}
|
||||
|
||||
static inline void h_u24_to_le(uint8_t* buf, int val)
|
||||
{
|
||||
buf[2] = (uint8_t) (val >> 16);
|
||||
buf[1] = (uint8_t) (val >> 8);
|
||||
buf[0] = (uint8_t) (val >> 0);
|
||||
}
|
||||
|
||||
static inline void h_u24_to_be(uint8_t* buf, int val)
|
||||
{
|
||||
buf[0] = (uint8_t) (val >> 16);
|
||||
buf[1] = (uint8_t) (val >> 8);
|
||||
buf[2] = (uint8_t) (val >> 0);
|
||||
}
|
||||
|
||||
static inline void h_u16_to_le(uint8_t* buf, int val)
|
||||
{
|
||||
buf[1] = (uint8_t) (val >> 8);
|
||||
buf[0] = (uint8_t) (val >> 0);
|
||||
}
|
||||
|
||||
static inline void h_u16_to_be(uint8_t* buf, int val)
|
||||
{
|
||||
buf[0] = (uint8_t) (val >> 8);
|
||||
buf[1] = (uint8_t) (val >> 0);
|
||||
}
|
||||
|
||||
#if defined(__ECOS)
|
||||
|
||||
/* eCos plain lacks these definition... A series of upstream patches
|
||||
* could probably repair it, but it seems like too much work to be
|
||||
* worth it.
|
||||
*/
|
||||
|
||||
#if !defined(_STDINT_H)
|
||||
#define PRIx32 "x"
|
||||
#define PRId32 "d"
|
||||
#define SCNx32 "x"
|
||||
#define PRIi32 "i"
|
||||
#define PRIu32 "u"
|
||||
#define PRId8 PRId32
|
||||
#define SCNx64 "llx"
|
||||
#define PRIx64 "llx"
|
||||
|
||||
typedef CYG_ADDRWORD intptr_t;
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
#define INT8_MAX 0x7f
|
||||
#define INT8_MIN (-INT8_MAX - 1)
|
||||
# define UINT8_MAX (255)
|
||||
#define INT16_MAX 0x7fff
|
||||
#define INT16_MIN (-INT16_MAX - 1)
|
||||
# define UINT16_MAX (65535)
|
||||
#define INT32_MAX 0x7fffffffL
|
||||
#define INT32_MIN (-INT32_MAX - 1L)
|
||||
# define UINT32_MAX (4294967295U)
|
||||
#define INT64_MAX 0x7fffffffffffffffLL
|
||||
#define INT64_MIN (-INT64_MAX - 1LL)
|
||||
#define UINT64_MAX (__CONCAT(INT64_MAX, U) * 2ULL + 1ULL)
|
||||
#endif
|
||||
|
||||
#ifndef LLONG_MAX
|
||||
#define ULLONG_MAX UINT64_C(0xFFFFFFFFFFFFFFFF)
|
||||
#define LLONG_MAX INT64_C(0x7FFFFFFFFFFFFFFF)
|
||||
#define LLONG_MIN ULLONG_MAX
|
||||
#endif
|
||||
|
||||
|
||||
#define ULLONG_MAX 18446744073709551615
|
||||
|
||||
/* C99, eCos is C90 compliant (with bits of C99) */
|
||||
#define isblank(c) ((c) == ' ' || (c) == '\t')
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* TYPES_H */
|
||||
61
debuggers/openocd/src/helper/util.c
Normal file
61
debuggers/openocd/src/helper/util.c
Normal file
@ -0,0 +1,61 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2010 by Øyvind Harboe *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
/* this file contains various functionality useful to standalone systems */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "time_support.h"
|
||||
|
||||
static int util_Jim_Command_ms(Jim_Interp *interp,
|
||||
int argc,
|
||||
Jim_Obj * const *argv)
|
||||
{
|
||||
if (argc != 1) {
|
||||
Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
/* Cast from 64 to 32 bit int works for 2's-compliment
|
||||
* when calculating differences*/
|
||||
Jim_SetResult(interp, Jim_NewIntObj(interp, (int)timeval_ms()));
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
static const struct command_registration util_command_handlers[] = {
|
||||
/* jim handlers */
|
||||
{
|
||||
.name = "ms",
|
||||
.mode = COMMAND_ANY,
|
||||
.jim_handler = util_Jim_Command_ms,
|
||||
.help =
|
||||
"Returns ever increasing milliseconds. Used to calculuate differences in time.",
|
||||
.usage = "",
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
int util_init(struct command_context *cmd_ctx)
|
||||
{
|
||||
return register_commands(cmd_ctx, NULL, util_command_handlers);
|
||||
}
|
||||
27
debuggers/openocd/src/helper/util.h
Normal file
27
debuggers/openocd/src/helper/util.h
Normal file
@ -0,0 +1,27 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2010 by Øyvind Harboe *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef HELPER_UTILS_H
|
||||
#define HELPER_UTILS_H
|
||||
|
||||
struct command_context;
|
||||
|
||||
int util_init(struct command_context *cmd_ctx);
|
||||
|
||||
#endif /* HELPER_UTILS_H */
|
||||
Reference in New Issue
Block a user