AM_CONDITIONAL(HAVE_PYTHON_PEXPECT, 0)
fi
-# libesmtp
-esmtp=0
-AC_MSG_CHECKING([for libesmtp])
-AC_ARG_WITH(esmtp,
- [ --with-esmtp=PFX base of libesmtp installation],
- [AC_MSG_RESULT([$with_esmtp])
- case $with_esmtp in
- no)
- ;;
- yes)
- AC_CHECK_HEADERS(libesmtp.h,
- AC_CHECK_LIB([esmtp], [smtp_start_session],
- esmtp=1))
- ;;
- *)
- LDFLAGS="-L$with_esmtp/lib $LDFLAGS"
- CPPFLAGS="-I$with_esmtp/include $CPPFLAGS"
- AC_CHECK_HEADERS(libesmtp.h,
- AC_CHECK_LIB([esmtp], [smtp_start_session],
- EXT_LIB_PATH="-L$with_esmtp/lib $EXT_LIB_PATH"
- esmtp=1))
- ;;
- esac
- ],
- [AC_MSG_RESULT([--with-esmtp not specified])
- AC_CHECK_HEADERS(libesmtp.h,
- AC_CHECK_LIB([esmtp], [smtp_start_session],
- esmtp=1))])
-AM_CONDITIONAL(HAVE_ESMTP, test x$esmtp = x1)
-AC_DEFINE_UNQUOTED([HAVE_ESMTP], $esmtp, [We have libesmtp])
-# restore LIBS
-LIBS=$SAVE_LIBS
-
-
# check for gettext
AM_GNU_GETTEXT([external])
src/include/gnunet_directories.h
src/hostlist/Makefile
src/mesh/Makefile
-src/monkey/Makefile
src/nat/Makefile
src/peerinfo/Makefile
src/peerinfo-tool/Makefile
PORT = 2086
ADVERTISED_PORT = 2086
-TIMEOUT = 300000
+# Maximum number of open TCP connections allowed
+MAX_CONNECTIONS = 128
+
+# After how long do we drop inactive connections?
+TIMEOUT = 5000
# Allow use of loopback address
USE_LOCALADDR = NO
ACCEPT_FROM6 = ::1;
UNIXPATH = /tmp/gnunet-service-dns.sock
PROVIDE_EXIT = NO
+
# INTLEMU_SUBDIRS = intlemu
#endif
-if HAVE_ESMTP
-if HAVE_OPENSSL
-if HAVE_EXPERIMENTAL
- MONKEY_DIR = monkey
-endif
-endif
-endif
-
if HAVE_EXPERIMENTAL
EXP_DIR = fragmentation mesh vpn chat
endif
block \
statistics \
arm \
- $(MONKEY_DIR) \
peerinfo \
datacache \
datastore \
+++ /dev/null
-INCLUDES = -I$(top_srcdir)/src/include
-
-if MINGW
- WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
-endif
-
-if USE_COVERAGE
- AM_CFLAGS = --coverage -O0
- XLIB = -lgcov
-endif
-
-
-if !MINGW
-if HAVE_ESMTP
-if HAVE_OPENSSL
-
-
-lib_LTLIBRARIES = libmonkeyedb.la \
- libmonkeyaction.la
-
-libmonkeyedb_la_SOURCES = \
- edb_api.c \
- gnunet_monkey_edb.h
-
-libmonkeyedb_la_LIBADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- -lsqlite3 \
- $(GN_LIBINTL) $(XLIB)
-
-libmonkeyaction_la_SOURCES = \
- action_api.c \
- gnunet_monkey_action.h
-
-libmonkeyaction_la_LIBADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(GN_LIBINTL) $(XLIB)
-
-bin_PROGRAMS = \
- gnunet-monkey \
- gnunet-service-monkey
-
-noinst_PROGRAMS = \
- bug_null_pointer_exception \
- bug_bad_memory_access \
- bug_assertion_failure \
- bug_crypto_crc
-
-gnunet_monkey_SOURCES = \
- gdbmi.h \
- gdbmi_alloc.c \
- gdbmi_breakpoint.c \
- gdbmi_connect.c \
- gdbmi_data_man.c \
- gdbmi_error.c \
- gdbmi_get_free_pty.c \
- gdbmi_get_free_vt.c \
- gdbmi_misc.c \
- gdbmi_parse.c \
- gdbmi_prg_control.c \
- gdbmi_stack_man.c \
- gdbmi_symbol_query.c \
- gdbmi_target_man.c \
- gdbmi_thread.c \
- gdbmi_var_obj.c \
- gnunet-monkey.c \
- mail_sender.c
-
-gnunet_monkey_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/monkey/libmonkeyedb.la \
- $(top_builddir)/src/monkey/libmonkeyaction.la \
- -lesmtp \
- $(GN_LIBINTL)
-
-
-gnunet_service_monkey_SOURCES = \
- gnunet-service-monkey.c
-gnunet_service_monkey_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(GN_LIBINTL)
-
-
-bug_null_pointer_exception:
- gcc -g -O0 -o bug_null_pointer_exception bug_null_pointer_exception.c
-
-bug_bad_memory_access:
- gcc -g -O0 -o bug_bad_memory_access bug_bad_memory_access.c
-
-bug_assertion_failure:
- gcc -g -O0 -o bug_assertion_failure bug_assertion_failure.c
-
-bug_crypto_crc:
- gcc -g -O0 -o bug_crypto_crc bug_crypto_crc.c
-
-check_PROGRAMS = \
- test_monkey_edb
- #test_gnunet_monkey
-
-if ENABLE_TEST_RUN
-# TESTS = $(check_SCRIPTS)
-TESTS = $(check_PROGRAMS)
-endif
-
-test_monkey_edb_SOURCES = \
- test_monkey_edb.c
-test_monkey_edb_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/monkey/libmonkeyedb.la
-
-#test_gnunet_monkey_SOURCES = \
- #test_gnunet_monkey.c
-#test_gnunet_monkey_LDADD = \
- #$(top_builddir)/src/arm/libgnunetarm.la \
- #$(top_builddir)/src/util/libgnunetutil.la
-
-
-check_SCRIPTS = \
- #test_gnunet_monkey.sh \
- #test_monkey_npe.sh
-
-EXTRA_DIST = \
- test_gnunet_monkey_data.conf \
- test.db
-#$(check_SCRIPTS)
-
-endif
-endif
-endif
+++ /dev/null
-/*
- This file is part of GNUnet.
- (C) 2010, 2011 Christian Grothoff (and other contributing authors)
-
- GNUnet 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 3, or (at your
- option) any later version.
-
- GNUnet 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 GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file monkey/action_api.c
- * @brief Monkey API for actions taken by Monkey while debugging
- */
-
-#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_monkey_action.h"
-#include "gnunet_monkey_edb.h"
-#include "gnunet_container_lib.h"
-#include <libesmtp.h>
-
-extern void sendMail (const char *messageContents, const char *emailAddress);
-
-
-static int async_c = 0;
-static struct Expression *expressionListHead = NULL;
-static struct Expression *expressionListTail = NULL;
-static struct WatchInfo *watchInfoListHead = NULL;
-static struct WatchInfo *watchInfoListTail = NULL;
-static struct Expression *faultyExpression = NULL;
-
-struct Expression
-{
- struct Expression *next;
- struct Expression *prev;
- const char *expressionSyntax;
- const char *expressionValue;
- int lineNo;
-};
-
-struct WatchInfo
-{
- struct WatchInfo *next;
- struct WatchInfo *prev;
- int hitNumber;
- const char *value;
-};
-
-
-static void
-cb_console (const char *str, void *data)
-{
- printf ("CONSOLE> %s\n", str);
-}
-
-
-/* Note that unlike what's documented in gdb docs it isn't usable. */
-static void
-cb_target (const char *str, void *data)
-{
- printf ("TARGET> %s\n", str);
-}
-
-
-static void
-cb_log (const char *str, void *data)
-{
- printf ("LOG> %s\n", str);
-}
-
-
-static void
-cb_to (const char *str, void *data)
-{
- printf (">> %s", str);
-}
-
-
-static void
-cb_from (const char *str, void *data)
-{
- printf ("<< %s\n", str);
-}
-
-
-static void
-cb_async (mi_output * o, void *data)
-{
- printf ("ASYNC\n");
- async_c++;
-}
-
-
-static int
-wait_for_stop (struct GNUNET_MONKEY_ACTION_Context *cntxt)
-{
- while (!mi_get_response (cntxt->gdb_handle))
- usleep (1000);
- /* The end of the async. */
- cntxt->gdb_stop_reason = mi_res_stop (cntxt->gdb_handle);
- if (cntxt->gdb_stop_reason)
- {
- if (cntxt->gdb_stop_reason->reason == sr_exited_normally)
- return GDB_STATE_EXIT_NORMALLY;
- else if (cntxt->gdb_stop_reason->reason == sr_bkpt_hit) {
- /* We want to inspect an expression */
- /* Set hardware watch at the expression to inspect */
- mi_wp *wp = gmi_break_watch(cntxt->gdb_handle, wm_write, cntxt->inspect_expression);
- if (NULL == wp)
- {
- printf("Error in setting a watchpoint at expression:%s\n", cntxt->inspect_expression);
- return GDB_STATE_ERROR;
- }
- mi_free_wp(wp);
- /* continue execution */
- gmi_exec_continue(cntxt->gdb_handle);
- return wait_for_stop (cntxt);
- }
- else if (cntxt->gdb_stop_reason->reason == sr_wp_trigger) {
- static int watchPointHitNumber = 0;
- struct WatchInfo *watchInfo = GNUNET_malloc(sizeof(struct WatchInfo));
- watchInfo->hitNumber = ++watchPointHitNumber;
- watchInfo->value = cntxt->gdb_stop_reason->wp_val;
- GNUNET_CONTAINER_DLL_insert(watchInfoListHead, watchInfoListTail, watchInfo);
- if (watchPointHitNumber == 1023)
- printf("HEY! 1023! WE ARE GETTING OUT OF THE LOOP!\n");
- gmi_exec_continue(cntxt->gdb_handle);
- return wait_for_stop (cntxt);
- }
- else if (cntxt->gdb_stop_reason->reason == sr_wp_scope) {
- gmi_exec_continue(cntxt->gdb_handle);
- return wait_for_stop (cntxt);
- }
- cntxt->gdb_frames = gmi_stack_info_frame (cntxt->gdb_handle);
- if (NULL == cntxt->gdb_frames)
- GNUNET_break (0);
-
- if (0 == cntxt->gdb_frames->line)
- {
- /*
- * This happens if the program stops in a shared library (inner frames)
- * We will move to outer frames until reaching the faulty line in the source code
- */
- cntxt->gdb_frames = gmi_stack_list_frames (cntxt->gdb_handle);
- do
- {
- cntxt->gdb_frames = cntxt->gdb_frames->next;
- }
- while (0 == cntxt->gdb_frames->line);
- }
- /* Change current GDB frame to the one containing source code */
- gmi_stack_select_frame(cntxt->gdb_handle, cntxt->gdb_frames->level);
-
- return GDB_STATE_STOPPED;
- }
- return GDB_STATE_ERROR;
-}
-
-
-int
-GNUNET_MONKEY_ACTION_report_file (struct GNUNET_MONKEY_ACTION_Context *cntxt,
- const char *dumpFileName)
-{
- FILE *file = fopen (dumpFileName, "w");
- GNUNET_assert (NULL != file);
- fprintf (file, "%s", cntxt->debug_report);
- fclose (file);
- return GNUNET_OK;
-}
-
-
-int
-GNUNET_MONKEY_ACTION_report_email (struct GNUNET_MONKEY_ACTION_Context *cntxt)
-{
- if (cntxt->debug_mode == DEBUG_MODE_REPORT_READY)
- sendMail (cntxt->debug_report, cntxt->email_address);
-
- return GNUNET_OK;
-}
-
-
-static int
-iterateExpressions (void *cls, int numColumns, char **colValues,
- char **colNames)
-{
- struct Expression *expression;
-
- if (NULL == colValues[0] || NULL == colValues[1])
- return 1; /* Error */
-
- expression = GNUNET_malloc (sizeof (struct Expression));
- expression->expressionSyntax = strdup (colValues[0]);
- expression->lineNo = atoi (colValues[1]);
-
- GNUNET_CONTAINER_DLL_insert (expressionListHead, expressionListTail,
- expression);
-
- return 0; /* OK */
-}
-
-
-static int
-scopeEndCallback (void *cls, int numColumns, char **colValues,
- char **colNames)
-{
- int *scopeEnd = (int *) cls;
-
- *scopeEnd = atoi (colValues[0]);
- if (*scopeEnd < 0)
- return 1; /* Error */
- return 0;
-}
-
-
-static struct Expression *
-getFaultyExpression (struct GNUNET_MONKEY_ACTION_Context *cntxt)
-{
- struct Expression *faultyExpression = NULL;
- struct Expression *tmp = NULL;
- int expressionLength = 0;
-
- tmp = expressionListHead;
- while (NULL != tmp)
- {
- if ((tmp->lineNo == cntxt->gdb_frames->line)
- && (strlen (tmp->expressionSyntax) > expressionLength))
- {
- expressionLength = strlen (tmp->expressionSyntax);
- faultyExpression = tmp;
- }
- tmp = tmp->next;
- }
-
- return faultyExpression;
-}
-
-static int
-analyzeSegmentationFault (struct GNUNET_MONKEY_ACTION_Context *cntxt)
-{
- struct Expression *tmp;
-
-
- faultyExpression = getFaultyExpression (cntxt);
-
- if (NULL != faultyExpression)
- {
- tmp = expressionListHead;
- while (NULL != tmp)
- {
- const char *eval;
- if (tmp != faultyExpression)
- {
- eval =
- gmi_data_evaluate_expression (cntxt->gdb_handle,
- tmp->expressionSyntax);
- if (NULL != eval
- && (strcmp (eval, "0x0") == 0
- || strcmp (eval, "NULL") == 0))
- {
- cntxt->gdb_null_variable = tmp->expressionSyntax;
- return GNUNET_OK;
- }
- }
- tmp = tmp->next;
- }
- }
- /* Set watch points on the faulty-expression's subexpressions */
-// if (NULL != faultyExpression) {
-// tmp = expressionListHead;
-// while (NULL != tmp) {
-// if (tmp != faultyExpression) {
-// /* Only subexpressions are interesting */
-// watchPoint = gmi_break_watch(cntxt->gdb_handle, wm_write, tmp->expressionSyntax);
-// if (!watchPoint)
-// {
-// printf("Error in setting watchpoint\n");
-// return 1;
-// }
-// printf("Watchpoint %d for expression: %s\n", watchPoint->number, watchPoint->exp);
-// mi_free_wp(watchPoint);
-// }
-// tmp = tmp->next;
-// }
-// return GNUNET_OK;
-// }
- return GDB_STATE_ERROR;
-}
-
-
-
-static int
-analyzeCustomFault (struct GNUNET_MONKEY_ACTION_Context *cntxt)
-{
- struct Expression *tmp;
- faultyExpression = getFaultyExpression (cntxt);
-
-
- if (NULL != faultyExpression)
- {
- tmp = expressionListHead;
- while (NULL != tmp)
- {
- const char *eval;
- eval =
- gmi_data_evaluate_expression (cntxt->gdb_handle,
- tmp->expressionSyntax);
- if (NULL != eval) {
- tmp->expressionValue = eval;
- }
- tmp = tmp->next;
- }
- }
- return GNUNET_OK;
-}
-
-
-int
-GNUNET_MONKEY_ACTION_inspect_expression_database (struct
- GNUNET_MONKEY_ACTION_Context
- *cntxt)
-{
- struct GNUNET_MONKEY_EDB_Context *edbCntxt;
- int ret = GNUNET_OK;
- int endScope;
- const char *signalMeaning = cntxt->gdb_stop_reason->signal_meaning;
-
- edbCntxt = GNUNET_MONKEY_EDB_connect (cntxt->expression_database_path);
- if (NULL == edbCntxt)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unable to connect to Expression Database file!\n");
- return GNUNET_NO;
- }
-
- ret = GNUNET_MONKEY_EDB_get_expression_scope_end (edbCntxt,
- cntxt->gdb_frames->file,
- cntxt->gdb_frames->line,
- &scopeEndCallback,
- &endScope);
- if (endScope < 0)
- return GNUNET_NO;
-
-
- if (strcasecmp (signalMeaning, "Segmentation fault") == 0)
- {
- cntxt->bug_detected = BUG_NULL_POINTER;
- GNUNET_MONKEY_EDB_get_expressions (edbCntxt,
- cntxt->gdb_frames->file,
- cntxt->gdb_frames->line, endScope,
- &iterateExpressions, NULL);
- ret = analyzeSegmentationFault (cntxt);
- }
- else if (strcasecmp (signalMeaning, "Aborted") == 0)
- {
- cntxt->bug_detected = BUG_CUSTOM;
- GNUNET_MONKEY_EDB_get_sub_expressions (edbCntxt,
- cntxt->gdb_frames->file,
- cntxt->gdb_frames->line, endScope,
- &iterateExpressions, NULL);
- ret = analyzeCustomFault (cntxt);
- }
-
- GNUNET_MONKEY_EDB_disconnect (edbCntxt);
- mi_disconnect (cntxt->gdb_handle);
- return ret;
-}
-
-
-int
-GNUNET_MONKEY_ACTION_rerun_with_valgrind (struct GNUNET_MONKEY_ACTION_Context
- *cntxt)
-{
- char *valgrindCommand;
- FILE *valgrindPipe;
-
- GNUNET_asprintf(&cntxt->valgrind_output_tmp_file_name, "%d", rand());
- cntxt->debug_mode = DEBUG_MODE_VALGRIND;
- GNUNET_asprintf (&valgrindCommand, "valgrind --leak-check=yes --log-file=%s %s",
- cntxt->valgrind_output_tmp_file_name, cntxt->binary_name);
- valgrindPipe = popen (valgrindCommand, "r");
- if (NULL == valgrindPipe)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error in running Valgrind!\n");
- GNUNET_free (valgrindCommand);
- return GNUNET_NO;
- }
-
- pclose(valgrindPipe);
- GNUNET_free(valgrindCommand);
- return GNUNET_OK;
-}
-
-
-int
-GNUNET_MONKEY_ACTION_rerun_with_gdb (struct GNUNET_MONKEY_ACTION_Context
- *cntxt)
-{
- cntxt->debug_mode = DEBUG_MODE_GDB;
- /* This is like a file-handle for fopen.
- Here we have all the state of gdb "connection". */
- if (NULL != cntxt->gdb_binary_path)
- mi_set_gdb_exe (cntxt->gdb_binary_path);
- int ret;
-
- /* Connect to gdb child. */
- cntxt->gdb_handle = mi_connect_local ();
- if (!cntxt->gdb_handle)
- {
- printf ("Connect failed\n");
- return GNUNET_NO;
- }
- printf ("Connected to gdb!\n");
-
- /* Set all callbacks. */
- mi_set_console_cb (cntxt->gdb_handle, cb_console, NULL);
- mi_set_target_cb (cntxt->gdb_handle, cb_target, NULL);
- mi_set_log_cb (cntxt->gdb_handle, cb_log, NULL);
- mi_set_async_cb (cntxt->gdb_handle, cb_async, NULL);
- mi_set_to_gdb_cb (cntxt->gdb_handle, cb_to, NULL);
- mi_set_from_gdb_cb (cntxt->gdb_handle, cb_from, NULL);
-
- /* Set the name of the child and the command line arguments. */
- if (!gmi_set_exec (cntxt->gdb_handle, cntxt->binary_name, NULL))
- {
- printf ("Error setting exec y args\n");
- mi_disconnect (cntxt->gdb_handle);
- return GNUNET_NO;
- }
-
- /* Tell gdb to attach the child to a terminal. */
- if (!gmi_target_terminal (cntxt->gdb_handle, ttyname (STDIN_FILENO)))
- {
- printf ("Error selecting target terminal\n");
- mi_disconnect (cntxt->gdb_handle);
- return GNUNET_NO;
- }
-
- if ((NULL != cntxt->inspect_expression) && (NULL != cntxt->inspect_function))
- {
- /* Setting a breakpoint at the function containing the expression to inspect */
- mi_bkpt *bp = gmi_break_insert_full(cntxt->gdb_handle, 0, 0, NULL, -1, -1, cntxt->inspect_function);
- if (NULL == bp)
- {
- printf("Error setting breakpoint at function:%s\n", cntxt->inspect_function);
- mi_disconnect(cntxt->gdb_handle);
- return GNUNET_NO;
- }
- mi_free_bkpt(bp);
- }
-
- /* Run the program. */
- if (!gmi_exec_run (cntxt->gdb_handle))
- {
- printf ("Error in run!\n");
- mi_disconnect (cntxt->gdb_handle);
- return GNUNET_NO;
- }
- /* Here we should be stopped when the program crashes */
- ret = wait_for_stop (cntxt);
- if (ret == GDB_STATE_ERROR)
- mi_disconnect (cntxt->gdb_handle);
-
- return ret;
-}
-
-
-static int
-getExpressionListSize(struct Expression *head)
-{
- int size, count = 0;
- struct Expression *tmp = head;
-
- while (NULL != tmp) {
- count++;
- tmp = tmp->next;
- }
- /* Since the faulty expression is the longest in the expression list */
- size = count * strlen(faultyExpression->expressionSyntax) * sizeof(char);
- return size;
-}
-
-
-static const char *
-expressionListToString (struct Expression *head)
-{
- char *string = GNUNET_malloc (getExpressionListSize(head));
- char *strTmp;
- struct Expression *tmp = head;
-
- GNUNET_asprintf (&strTmp, "%s = %s\n", tmp->expressionSyntax, NULL == tmp->expressionValue ? "Not evaluated" : tmp->expressionValue);
- strcpy (string, strTmp);
- GNUNET_free (strTmp);
- tmp = tmp->next;
-
- while (NULL != tmp)
- {
- GNUNET_asprintf (&strTmp, "%s = %s\n", tmp->expressionSyntax, NULL == tmp->expressionValue ? "Not evaluated" : tmp->expressionValue);
- strcat (string, strTmp);
- GNUNET_free (strTmp);
- tmp = tmp->next;
- }
- return string;
-}
-
-#if 0
-static int
-getWatchInfoListSize(struct WatchInfo *head)
-{
- int count = 0;
- int largestStr = 0;
- struct WatchInfo *tmp = head;
-
- while (NULL != tmp) {
- if (largestStr < strlen(tmp->value))
- largestStr = strlen(tmp->value);
- tmp = tmp->next;
- count++;
- }
-
- return count * largestStr;
-}
-
-static const char*
-watchInfoListToString(struct WatchInfo *head)
-{
- char *string = GNUNET_malloc(getWatchInfoListSize(head));
- char *strTmp;
- struct WatchInfo *tmp = head;
-
- GNUNET_asprintf (&strTmp, "%s\t \t%s\n", tmp->hitNumber, tmp->value);
- strcpy (string, strTmp);
- GNUNET_free (strTmp);
- tmp = tmp->next;
-
- while (NULL != tmp) {
- GNUNET_asprintf (&strTmp, "%s\t \t%s\n", tmp->hitNumber, tmp->value);
- strcat (string, strTmp);
- GNUNET_free(strTmp);
- tmp = tmp->next;
- }
-
- return string;
-}
-#endif
-
-static const char* getValgrindOutput(struct GNUNET_MONKEY_ACTION_Context *cntxt)
-{
- char* valgrindOutput;
- int size;
- FILE *valgrindFile = fopen(cntxt->valgrind_output_tmp_file_name, "r");
- fseek(valgrindFile, 0L, SEEK_END);
- size = ftell(valgrindFile);
- fseek(valgrindFile, 0L, SEEK_SET);
-
- valgrindOutput = GNUNET_malloc(size);
- fread(valgrindOutput, size - 1, 1, valgrindFile);
- fclose(valgrindFile);
- return valgrindOutput;
-}
-
-
-int
-GNUNET_MONKEY_ACTION_format_report (struct GNUNET_MONKEY_ACTION_Context
- *cntxt)
-{
- switch (cntxt->debug_mode)
- {
- case DEBUG_MODE_GDB:
- if (cntxt->bug_detected == BUG_NULL_POINTER)
- {
- GNUNET_asprintf (&(cntxt->debug_report),
- "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n Details:\n Expression:%s is NULL\n",
- cntxt->gdb_frames->file, cntxt->gdb_frames->func,
- cntxt->gdb_frames->line,
- mi_reason_enum_to_str (cntxt->gdb_stop_reason->
- reason),
- cntxt->gdb_stop_reason->signal_name,
- cntxt->gdb_stop_reason->signal_meaning,
- cntxt->gdb_null_variable);
- }
- else if (cntxt->bug_detected == BUG_CUSTOM)
- {
- if (NULL == cntxt->inspect_expression)
- {
- /* Assertion Failure */
- const char *expToString = expressionListToString(expressionListHead);
- GNUNET_asprintf (&(cntxt->debug_report),
- "Bug detected in file:%s\nfunction:%s\nline:%d\nreceived signal:%s\n%s\nDetails:\nAssertion Failure\nExpression evaluation:\n%s\n",
- cntxt->gdb_frames->file,
- cntxt->gdb_frames->func,
- cntxt->gdb_frames->line,
- cntxt->gdb_stop_reason->signal_name,
- cntxt->gdb_stop_reason->signal_meaning,
- expToString);
- }
- else
- {
- /* Inspection of user-defined expression */
- /*
- GNUNET_asprintf(&(cntxt->debug_report),
- "Inspection of expression: %s in function: %s, file:%s\nHit Number: \t \tValue:\n%s",
- cntxt->inspect_expression, cntxt->inspect_function, cntxt->binary_name, watchInfoListToString(watchInfoListHead));
- */
- }
- }
- break;
- case DEBUG_MODE_VALGRIND:
- GNUNET_asprintf (&(cntxt->debug_report),
- "Bug detected in file:%s\nfunction:%s\nline:%d\nreceived signal:%s\n%s\n Details:\n Memory Check from Valgrind:\n%s",
- cntxt->gdb_frames->file, cntxt->gdb_frames->func,
- cntxt->gdb_frames->line,
- cntxt->gdb_stop_reason->signal_name,
- cntxt->gdb_stop_reason->signal_meaning,
- getValgrindOutput(cntxt));
- break;
- default:
- break;
- }
-
- cntxt->debug_mode = DEBUG_MODE_REPORT_READY;
- return GNUNET_OK;
-}
-
-
-int
-GNUNET_MONKEY_ACTION_delete_context(struct GNUNET_MONKEY_ACTION_Context *cntxt)
-{
- if (NULL != cntxt->debug_report)
- GNUNET_free(cntxt->debug_report);
- if (NULL != cntxt->valgrind_output_tmp_file_name) {
- remove(cntxt->valgrind_output_tmp_file_name);
- GNUNET_free(cntxt->valgrind_output_tmp_file_name);
- }
-
- GNUNET_free(cntxt);
- return GNUNET_OK;
-}
-
-
-int
-GNUNET_MONKEY_ACTION_check_bug_redundancy ()
-{
- return GNUNET_OK;
-}
+++ /dev/null
-#include <stdio.h>
-#include <assert.h>
-
-void assertionFailure()
-{
- int x = 5;
- printf("Assertion Failure Now!\n");
- assert(x < 4);
-}
-
-int main(int argc, char *argv[])
-{
- assertionFailure();
- return 0;
-}
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-
-
-void badMemoryAccess()
-{
- int *p = (int*) 0x4252352;
- printf("Bad memory access now!\n");
- *p = 5;
-}
-
-int main(int argc, char *argv[])
-{
- badMemoryAccess();
- return 0;
-}
+++ /dev/null
-/*
- This file is part of GNUnet.
- (C) 2001, 2002, 2003, 2004, 2006 Christian Grothoff (and other contributing authors)
-
- GNUnet 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, or (at your
- option) any later version.
-
- GNUnet 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 GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- For the actual CRC code:
- Copyright abandoned; this code is in the public domain.
- Provided to GNUnet by peter@horizon.com
-*/
-
-/**
- * @file monkey/bug_crypto_crc.c
- * @brief implementation of CRC32 (this code has been copied from GNUnet util source directory, and modified to be Seaspider friendly)
- * @author Christian Grothoff, Safey A.Halim
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-
-#define Z_NULL 0
-
-
-#define POLYNOMIAL (unsigned long)0xedb88320
-static unsigned long crc_table[256];
-
-/*
- * This routine writes each crc_table entry exactly once,
- * with the ccorrect final value. Thus, it is safe to call
- * even on a table that someone else is using concurrently.
- */
-static void
-crc_init ()
-{
- static int once;
- unsigned int i, j;
- unsigned long h = 1;
-
- if (once)
- return;
- once = 1;
- crc_table[0] = 0;
- for (i = 128; i; i >>= 1)
- {
- h = (h >> 1) ^ ((h & 1) ? POLYNOMIAL : 0);
- /* h is now crc_table[i] */
- for (j = 0; j < 256; j += 2 * i)
- crc_table[i + j] = crc_table[j] ^ h;
- }
-}
-
-/*
- * This computes the standard preset and inverted CRC, as used
- * by most networking standards. Start by passing in an initial
- * chaining value of 0, and then pass in the return value from the
- * previous crc32() call. The final return value is the CRC.
- * Note that this is a little-endian CRC, which is best used with
- * data transmitted lsbit-first, and it should, itself, be appended
- * to data in little-endian byte and bit order to preserve the
- * property of detecting all burst errors of length 32 bits or less.
- */
-static unsigned long
-crc_go (unsigned long crc, const char *buf, size_t len)
-{
- crc_init ();
- assert (crc_table[255] != 0);
- crc ^= 0xffffffff;
- while (len--)
- crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
- return crc ^ 0xffffffff;
-}
-
-
-/**
- * Compute the CRC32 checksum for the first len bytes of the buffer.
- *
- * @param buf the data over which we're taking the CRC
- * @param len the length of the buffer
- * @return the resulting CRC32 checksum
- */
-int32_t
-crc32_n (const void *buf, size_t len)
-{
- unsigned long crc;
- crc = crc_go (0L, Z_NULL, 0);
- crc = crc_go (crc, (char *) buf, len);
- return crc;
-}
-
-
-int main ()
-{
- char buf[1024];
- int i;
- for (i = 0; i < 1024; i++)
- {
- buf[i] = (char) i;
- }
- for (i = 0; i < 1024; i++)
- {
- printf("%d\n", crc32_n (&buf[i], 1024 - i));
- }
- return 0;
-}
-
-/* end of bug_crypto_crc.c */
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-
-
-struct CrashStruct {
- const char *crashValue;
-};
-
-void crashFunction()
-{
- struct CrashStruct *crashStruct;
- crashStruct = NULL;
- printf("Now the program will crash!\n");
- crashStruct->crashValue = "hello!";
-}
-
-int main(int argc, char *argv[])
-{
- crashFunction();
- return 0;
-}
+++ /dev/null
-/*
- This file is part of GNUnet.
- (C) 2009, 2010 Christian Grothoff (and other contributing authors)
-
- GNUnet 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 3, or (at your
- option) any later version.
-
- GNUnet 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 GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file monkey/edb_api.c
- * @brief Monkey API for accessing the Expression Database (edb)
- */
-
-#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_monkey_edb.h"
-#include <sqlite3.h>
-
-
-/**
- * Context for Database connection and Expressions
- */
-struct GNUNET_MONKEY_EDB_Context
-{
- /**
- * Database connection
- */
- sqlite3 *db_handle;
-};
-
-
-/**
- * Establish a connection to the Expression Database
- *
- * @param db_file_name path the Expression Database file
- * @return context to use for Accessing the Expression Database, NULL on error
- */
-struct GNUNET_MONKEY_EDB_Context *
-GNUNET_MONKEY_EDB_connect (const char *db_file_name)
-{
- int err;
- struct GNUNET_MONKEY_EDB_Context *ctxt =
- GNUNET_malloc (sizeof (struct GNUNET_MONKEY_EDB_Context));
-
- err = sqlite3_open (db_file_name, &ctxt->db_handle);
- if (err)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Cannot open Expression Database. `%s'\n",
- sqlite3_errmsg (ctxt->db_handle));
- return NULL;
- }
- return ctxt;
-}
-
-
-/**
- * Disconnect from Database, and cleanup resources
- *
- * @param context context containing the Expression Database handle
- * @return GNUNET_OK on success, GNUNET_NO on failure
- */
-int
-GNUNET_MONKEY_EDB_disconnect (struct GNUNET_MONKEY_EDB_Context *cntxt)
-{
- sqlite3_close (cntxt->db_handle);
- GNUNET_free (cntxt);
- return GNUNET_OK;
-}
-
-
-/**
- * Return the line number of the end-of-scope for the expression indicated by start_line_no
- *
- * @param cntxt context containing the Expression Database handle
- * @param file_name path to the file in which the expression in question exists
- * @param start_line_no expression's line
- * @param iter callback function, iterator for values returned from the Database
- * @param iter_cls closure for the expression iterator, will contain the scope-end line number
- * @return GNUNET_OK on success, GNUNET_NO on failure
- */
-int
-GNUNET_MONKEY_EDB_get_expression_scope_end(struct GNUNET_MONKEY_EDB_Context *cntxt,
- const char *file_name, int start_line_no,
- GNUNET_MONKEY_ExpressionIterator iter,
- void *iter_cls)
-{
- int err;
- char *errMsg;
- char *query;
-
- if (asprintf(&query, "select end_lineno from Expression where file_name LIKE \'%%/%s\' and start_lineno = %d", file_name, start_line_no) == -1) {
- GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Memory allocation problem occurred during creating database query!\n");
- return GNUNET_NO;
- }
-
- err = sqlite3_exec(cntxt->db_handle, query, iter, iter_cls, &errMsg);
- if (err) {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Error occurred while executing Database query. `%s'",
- errMsg);
- return GNUNET_NO;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Run an SQLite query to retrieve those expressions that are previous to
- * given expression and are in the same scope of the given expression
- *
- * @param cntxt context containing the Expression Database handle
- * @param file_name path to the file in which the expression in question exists
- * @param start_line_no expression beginning line
- * @param end_line_no line number for the expression's scope end
- * @param iter callback function, iterator for expressions returned from the Database
- * @param iter_cls closure for the expression iterator
- * @return GNUNET_OK success, GNUNET_NO failure
- */
-int
-GNUNET_MONKEY_EDB_get_expressions (struct GNUNET_MONKEY_EDB_Context *cntxt,
- const char *file_name, int start_line_no,
- int end_line_no,
- GNUNET_MONKEY_ExpressionIterator iter,
- void *iter_cls)
-{
- int err;
- char *errMsg;
- char *query;
- if (asprintf
- (&query,
- "select expr_syntax, start_lineno from Expression where file_name LIKE \'%%/%s\' and start_lineno <= %d and end_lineno = %d",
- file_name, start_line_no, end_line_no) == -1)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Memory allocation problem occurred!\n");
- return GNUNET_NO;
- }
-
- err = sqlite3_exec (cntxt->db_handle, query, iter, iter_cls, &errMsg);
- if (err)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Error occurred while executing Database query. `%s'",
- errMsg);
- return GNUNET_NO;
- }
- return GNUNET_OK;
-}
-
-
-int
-GNUNET_MONKEY_EDB_get_sub_expressions (struct GNUNET_MONKEY_EDB_Context *cntxt,
- const char *file_name, int start_line_no,
- int end_line_no,
- GNUNET_MONKEY_ExpressionIterator iter,
- void *iter_cls)
-{
- int err;
- char *errMsg;
- char *query;
- if (asprintf
- (&query,
- "select expr_syntax, start_lineno from Expression where file_name LIKE \'%%/%s\' and start_lineno = %d and end_lineno = %d",
- file_name, start_line_no, end_line_no) == -1)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Memory allocation problem occurred!\n");
- return GNUNET_NO;
- }
-
- err = sqlite3_exec (cntxt->db_handle, query, iter, iter_cls, &errMsg);
- if (err)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Error occurred while executing Database query. `%s'",
- errMsg);
- return GNUNET_NO;
- }
- return GNUNET_OK;
-}
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004-2009 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Comments:
- Main header for libmigdb.
-
-***************************************************************************/
-
-#ifndef GDBMI_H
-#define GDBMI_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0 /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h> /* pid_t */
-
-#define MI_OK 0
-#define MI_OUT_OF_MEMORY 1
-#define MI_PIPE_CREATE 2
-#define MI_FORK 3
-#define MI_DEBUGGER_RUN 4
-#define MI_PARSER 5
-#define MI_UNKNOWN_ASYNC 6
-#define MI_UNKNOWN_RESULT 7
-#define MI_FROM_GDB 8
-#define MI_GDB_TIME_OUT 9
-#define MI_GDB_DIED 10
-#define MI_MISSING_XTERM 11
-#define MI_CREATE_TEMPORAL 12
-#define MI_MISSING_GDB 13
-#define MI_LAST_ERROR 13
-
-#define MI_R_NONE 0 /* We are no waiting any response. */
-#define MI_R_SKIP 1 /* We want to discard it. */
-#define MI_R_FE_AND_S 2 /* Wait for done. */
-#define MI_R_E_ARGS 3
-
-enum mi_val_type { t_const, t_tuple, t_list };
-
-/* Types and subtypes. */
-/* Type. */
-#define MI_T_OUT_OF_BAND 0
-#define MI_T_RESULT_RECORD 1
-/* Out of band subtypes. */
-#define MI_ST_ASYNC 0
-#define MI_ST_STREAM 1
-/* Async sub-subtypes. */
-#define MI_SST_EXEC 0
-#define MI_SST_STATUS 1
-#define MI_SST_NOTIFY 2
-/* Stream sub-subtypes. */
-#define MI_SST_CONSOLE 3
-#define MI_SST_TARGET 4
-#define MI_SST_LOG 5
-/* Classes. */
-/* Async classes. */
-#define MI_CL_UNKNOWN 0
-#define MI_CL_STOPPED 1
-#define MI_CL_DOWNLOAD 2
-/* Result classes. */
-#define MI_CL_DONE 2
-#define MI_CL_RUNNING 3
-#define MI_CL_CONNECTED 4
-#define MI_CL_ERROR 5
-#define MI_CL_EXIT 6
-
-#define MI_DEFAULT_TIME_OUT 10
-
-#define MI_DIS_ASM 0
-#define MI_DIS_SRC_ASM 1
-
-/* Implemented workaround for gdb bugs that we can dis/enable. */
-/* At least gdb<=6.1.1 fails to find a source file with absolute path if the
- name is for a psym instead of a sym. psym==partially loaded symbol table. */
-#define MI_PSYM_SEARCH 0
-
-#define MI_VERSION_STR "0.8.12"
-#define MI_VERSION_MAJOR 0
-#define MI_VERSION_MIDDLE 8
-#define MI_VERSION_MINOR 12
-
-struct mi_results_struct
-{
- char *var; /* Result name or NULL if just a value. */
- enum mi_val_type type;
- union
- {
- char *cstr;
- struct mi_results_struct *rs;
- } v;
- struct mi_results_struct *next;
-};
-typedef struct mi_results_struct mi_results;
-
-struct mi_output_struct
-{
- /* Type of output. */
- char type;
- char stype;
- char sstype;
- char tclass;
- /* Content. */
- mi_results *c;
- /* Always modeled as a list. */
- struct mi_output_struct *next;
-};
-typedef struct mi_output_struct mi_output;
-
-typedef void (*stream_cb)(const char *, void *);
-typedef void (*async_cb)(mi_output *o, void *);
-typedef int (*tm_cb)(void *);
-
-/* Values of this structure shouldn't be manipulated by the user. */
-struct mi_h_struct
-{
- /* Pipes connected to gdb. */
- int to_gdb[2];
- int from_gdb[2];
- /* Streams for the pipes. */
- FILE *to, *from;
- /* PID of child gdb. */
- pid_t pid;
- char died;
- /* Which rensponse we are waiting for. */
- /*int response;*/
- /* The line we are reading. */
- char *line;
- int llen, lread;
- /* Parsed output. */
- mi_output *po, *last;
- /* Tunneled streams callbacks. */
- stream_cb console;
- void *console_data;
- stream_cb target;
- void *target_data;
- stream_cb log;
- void *log_data;
- /* Async responses callback. */
- async_cb async;
- void *async_data;
- /* Callbacks to get echo of gdb dialog. */
- stream_cb to_gdb_echo;
- void *to_gdb_echo_data;
- stream_cb from_gdb_echo;
- void *from_gdb_echo_data;
- /* Time out */
- tm_cb time_out_cb;
- void *time_out_cb_data;
- int time_out;
- /* Ugly workaround for some of the show responses :-( */
- int catch_console;
- char *catched_console;
- /* MI version, currently unknown but the user can force v2 */
- unsigned version;
-};
-typedef struct mi_h_struct mi_h;
-
-#define MI_TO(a) ((a)->to_gdb[1])
-
-enum mi_bkp_type { t_unknown=0, t_breakpoint=1, t_hw=2 };
-enum mi_bkp_disp { d_unknown=0, d_keep=1, d_del=2 };
-enum mi_bkp_mode { m_file_line=0, m_function=1, m_file_function=2, m_address=3 };
-
-struct mi_bkpt_struct
-{
- int number;
- enum mi_bkp_type type;
- enum mi_bkp_disp disp; /* keep or del if temporal */
- char enabled;
- void *addr;
- char *func;
- char *file;
- int line;
- int ignore;
- int times;
-
- /* For the user: */
- char *cond;
- char *file_abs;
- int thread;
- enum mi_bkp_mode mode;
- struct mi_bkpt_struct *next;
-};
-typedef struct mi_bkpt_struct mi_bkpt;
-
-enum mi_wp_mode { wm_unknown=0, wm_write=1, wm_read=2, wm_rw=3 };
-
-struct mi_wp_struct
-{
- int number;
- char *exp;
- enum mi_wp_mode mode;
-
- /* For the user: */
- struct mi_wp_struct *next;
- char enabled;
-};
-typedef struct mi_wp_struct mi_wp;
-
-struct mi_frames_struct
-{
- int level; /* The frame number, 0 being the topmost frame, i.e. the innermost
- function. */
- void *addr; /* The `$pc' value for that frame. */
- char *func; /* Function name. */
- char *file; /* File name of the source file where the function lives. */
- char *from;
- int line; /* Line number corresponding to the `$pc'. */
- /* When arguments are available: */
- mi_results *args;
- int thread_id;
- /* When more than one is provided: */
- struct mi_frames_struct *next;
-};
-typedef struct mi_frames_struct mi_frames;
-
-struct mi_aux_term_struct
-{
- pid_t pid;
- char *tty;
-};
-typedef struct mi_aux_term_struct mi_aux_term;
-
-struct mi_pty_struct
-{
- char *slave;
- int master;
-};
-typedef struct mi_pty_struct mi_pty;
-
-enum mi_gvar_fmt { fm_natural=0, fm_binary=1, fm_decimal=2, fm_hexadecimal=3,
- fm_octal=4,
- /* Only for registers format: */
- fm_raw=5 };
-enum mi_gvar_lang { lg_unknown=0, lg_c, lg_cpp, lg_java };
-
-#define MI_ATTR_DONT_KNOW 0
-#define MI_ATTR_NONEDITABLE 1
-#define MI_ATTR_EDITABLE 2
-
-struct mi_gvar_struct
-{
- char *name;
- int numchild;
- char *type;
- enum mi_gvar_fmt format;
- enum mi_gvar_lang lang;
- char *exp;
- int attr;
-
- /* MI v2 fills it, not yet implemented here. */
- /* Use gmi_var_evaluate_expression. */
- char *value;
-
- /* Pointer to the parent. NULL if none. */
- struct mi_gvar_struct *parent;
- /* List containing the children.
- Filled by gmi_var_list_children.
- NULL if numchild==0 or not yet filled. */
- struct mi_gvar_struct *child;
- /* Next var in the list. */
- struct mi_gvar_struct *next;
-
- /* For the user: */
- char opened; /* We will show its children. 1 when we fill "child" */
- char changed; /* Needs to be updated. 0 when created. */
- int vischild; /* How many items visible. numchild when we fill "child" */
- int depth; /* How deep is this var. */
- char ispointer;
-};
-typedef struct mi_gvar_struct mi_gvar;
-
-struct mi_gvar_chg_struct
-{
- char *name;
- int in_scope; /* if true the other fields apply. */
- char *new_type; /* NULL if type_changed==false */
- int new_num_children; /* only when new_type!=NULL */
-
- struct mi_gvar_chg_struct *next;
-};
-typedef struct mi_gvar_chg_struct mi_gvar_chg;
-
-
-/* A list of assembler instructions. */
-struct mi_asm_insn_struct
-{
- void *addr;
- char *func;
- unsigned offset;
- char *inst;
-
- struct mi_asm_insn_struct *next;
-};
-typedef struct mi_asm_insn_struct mi_asm_insn;
-
-/* A list of source lines containing assembler instructions. */
-struct mi_asm_insns_struct
-{
- char *file;
- int line;
- mi_asm_insn *ins;
-
- struct mi_asm_insns_struct *next;
-};
-typedef struct mi_asm_insns_struct mi_asm_insns;
-
-/* Changed register. */
-struct mi_chg_reg_struct
-{
- int reg;
- char *val;
- char *name;
- char updated;
-
- struct mi_chg_reg_struct *next;
-};
-typedef struct mi_chg_reg_struct mi_chg_reg;
-
-/*
- Examining gdb sources and looking at docs I can see the following "stop"
-reasons:
-
-Breakpoints:
-a) breakpoint-hit (bkptno) + frame
-Also: without reason for temporal breakpoints.
-
-Watchpoints:
-b) watchpoint-trigger (wpt={number,exp};value={old,new}) + frame
-c) read-watchpoint-trigger (hw-rwpt{number,exp};value={value}) + frame
-d) access-watchpoint-trigger (hw-awpt{number,exp};value={[old,]new}) + frame
-e) watchpoint-scope (wpnum) + frame
-
-Movement:
-f) function-finished ([gdb-result-var,return-value]) + frame
-g) location-reached + frame
-h) end-stepping-range + frame
-
-Exit:
-i) exited-signalled (signal-name,signal-meaning)
-j) exited (exit-code)
-k) exited-normally
-
-Signal:
-l) signal-received (signal-name,signal-meaning) + frame
-
-Plus: thread-id
-*/
-enum mi_stop_reason
-{
- sr_unknown=0,
- sr_bkpt_hit,
- sr_wp_trigger, sr_read_wp_trigger, sr_access_wp_trigger, sr_wp_scope,
- sr_function_finished, sr_location_reached, sr_end_stepping_range,
- sr_exited_signalled, sr_exited, sr_exited_normally,
- sr_signal_received
-};
-
-struct mi_stop_struct
-{
- enum mi_stop_reason reason; /* If more than one reason just the last. */
- /* Flags indicating if non-pointer fields are filled. */
- char have_thread_id;
- char have_bkptno;
- char have_exit_code;
- char have_wpno;
- /* Where stopped. Doesn't exist for sr_exited*. */
- int thread_id;
- mi_frames *frame;
- /* sr_bkpt_hit */
- int bkptno;
- /* sr_*wp_* no scope */
- mi_wp *wp;
- char *wp_old;
- char *wp_val;
- /* sr_wp_scope */
- int wpno;
- /* sr_function_finished. Not for void func. */
- char *gdb_result_var;
- char *return_value;
- /* sr_exited_signalled, sr_signal_received */
- char *signal_name;
- char *signal_meaning;
- /* sr_exited */
- int exit_code;
-};
-typedef struct mi_stop_struct mi_stop;
-
-/* Variable containing the last error. */
-extern int mi_error;
-extern char *mi_error_from_gdb;
-const char *mi_get_error_str();
-
-/* Indicate the name of gdb exe. Default is /usr/bin/gdb */
-void mi_set_gdb_exe(const char *name);
-const char *mi_get_gdb_exe();
-/* Indicate the name of a file containing commands to send at start-up */
-void mi_set_gdb_start(const char *name);
-const char *mi_get_gdb_start();
-/* Indicate the name of a file containing commands to send after connection */
-void mi_set_gdb_conn(const char *name);
-const char *mi_get_gdb_conn();
-void mi_send_target_commands(mi_h *h);
-/* Connect to a local copy of gdb. */
-mi_h *mi_connect_local();
-/* Close connection. You should ask gdb to quit first. */
-void mi_disconnect(mi_h *h);
-/* Force MI version. */
-#define MI_VERSION2U(maj,mid,min) (maj*0x1000000+mid*0x10000+min)
-void mi_force_version(mi_h *h, unsigned vMajor, unsigned vMiddle,
- unsigned vMinor);
-void mi_set_workaround(unsigned wa, int enable);
-int mi_get_workaround(unsigned wa);
-/* Parse gdb output. */
-mi_output *mi_parse_gdb_output(const char *str);
-/* Functions to set/get the tunneled streams callbacks. */
-void mi_set_console_cb(mi_h *h, stream_cb cb, void *data);
-void mi_set_target_cb(mi_h *h, stream_cb cb, void *data);
-void mi_set_log_cb(mi_h *h, stream_cb cb, void *data);
-stream_cb mi_get_console_cb(mi_h *h, void **data);
-stream_cb mi_get_target_cb(mi_h *h, void **data);
-stream_cb mi_get_log_cb(mi_h *h, void **data);
-/* The callback to deal with async events. */
-void mi_set_async_cb(mi_h *h, async_cb cb, void *data);
-async_cb mi_get_async_cb(mi_h *h, void **data);
-/* Time out in gdb responses. */
-void mi_set_time_out_cb(mi_h *h, tm_cb cb, void *data);
-tm_cb mi_get_time_out_cb(mi_h *h, void **data);
-void mi_set_time_out(mi_h *h, int to);
-int mi_get_time_out(mi_h *h);
-/* Callbacks to "see" the dialog with gdb. */
-void mi_set_to_gdb_cb(mi_h *h, stream_cb cb, void *data);
-void mi_set_from_gdb_cb(mi_h *h, stream_cb cb, void *data);
-stream_cb mi_get_to_gdb_cb(mi_h *h, void **data);
-stream_cb mi_get_from_gdb_cb(mi_h *h, void **data);
-/* Sends a message to gdb. */
-int mi_send(mi_h *h, const char *format, ...);
-/* Wait until gdb sends a response. */
-mi_output *mi_get_response_blk(mi_h *h);
-/* Check if gdb sent a complete response. Use with mi_retire_response. */
-int mi_get_response(mi_h *h);
-/* Get the last response. Use with mi_get_response. */
-mi_output *mi_retire_response(mi_h *h);
-/* Look for a result record in gdb output. */
-mi_output *mi_get_rrecord(mi_output *r);
-/* Look if the output contains an async stop.
- If that's the case return the reason for the stop.
- If the output contains an error the description is returned in reason. */
-int mi_get_async_stop_reason(mi_output *r, char **reason);
-mi_stop *mi_get_stopped(mi_results *r);
-mi_frames *mi_get_async_frame(mi_output *r);
-/* Wait until gdb sends a response.
- Then check if the response is of the desired type. */
-int mi_res_simple_exit(mi_h *h);
-int mi_res_simple_done(mi_h *h);
-int mi_res_simple_running(mi_h *h);
-int mi_res_simple_connected(mi_h *h);
-/* It additionally extracts an specified variable. */
-mi_results *mi_res_done_var(mi_h *h, const char *var);
-/* Extract a frames list from the response. */
-mi_frames *mi_res_frames_array(mi_h *h, const char *var);
-mi_frames *mi_res_frames_list(mi_h *h);
-mi_frames *mi_parse_frame(mi_results *c);
-mi_frames *mi_res_frame(mi_h *h);
-/* Create an auxiliar terminal using xterm. */
-mi_aux_term *gmi_start_xterm();
-/* Indicate the name of xterm exe. Default is /usr/bin/X11/xterm */
-void mi_set_xterm_exe(const char *name);
-const char *mi_get_xterm_exe();
-/* Kill the auxiliar terminal and release the structure. */
-void gmi_end_aux_term(mi_aux_term *t);
-/* Look for a free Linux VT for the child. */
-mi_aux_term *gmi_look_for_free_vt();
-/* Look for a free and usable Linux VT. */
-int mi_look_for_free_vt();
-/* Close master and release the structure. */
-void gmi_end_pty(mi_pty *p);
-/* Look for a free pseudo terminal. */
-mi_pty *gmi_look_for_free_pty();
-/* Extract a list of thread IDs from response. */
-int mi_res_thread_ids(mi_h *h, int **list);
-int mi_get_thread_ids(mi_output *res, int **list);
-/* A variable response. */
-mi_gvar *mi_res_gvar(mi_h *h, mi_gvar *cur, const char *expression);
-enum mi_gvar_fmt mi_format_str_to_enum(const char *format);
-const char *mi_format_enum_to_str(enum mi_gvar_fmt format);
-char mi_format_enum_to_char(enum mi_gvar_fmt format);
-enum mi_gvar_lang mi_lang_str_to_enum(const char *lang);
-const char *mi_lang_enum_to_str(enum mi_gvar_lang lang);
-int mi_res_changelist(mi_h *h, mi_gvar_chg **changed);
-int mi_res_children(mi_h *h, mi_gvar *v);
-mi_bkpt *mi_res_bkpt(mi_h *h);
-mi_wp *mi_res_wp(mi_h *h);
-char *mi_res_value(mi_h *h);
-mi_stop *mi_res_stop(mi_h *h);
-enum mi_stop_reason mi_reason_str_to_enum(const char *s);
-const char *mi_reason_enum_to_str(enum mi_stop_reason r);
-int mi_get_read_memory(mi_h *h, unsigned char *dest, unsigned ws, int *na,
- unsigned long *addr);
-mi_asm_insns *mi_get_asm_insns(mi_h *h);
-/* Starting point of the program. */
-void mi_set_main_func(const char *name);
-const char *mi_get_main_func();
-mi_chg_reg *mi_get_list_registers(mi_h *h, int *how_many);
-int mi_get_list_registers_l(mi_h *h, mi_chg_reg *l);
-mi_chg_reg *mi_get_list_changed_regs(mi_h *h);
-int mi_get_reg_values(mi_h *h, mi_chg_reg *l);
-mi_chg_reg *mi_get_reg_values_l(mi_h *h, int *how_many);
-int gmi_target_download(mi_h *h);
-
-/* Allocation functions: */
-void *mi_calloc(size_t count, size_t sz);
-void *mi_calloc1(size_t sz);
-char *mi_malloc(size_t sz);
-mi_results *mi_alloc_results(void);
-mi_output *mi_alloc_output(void);
-mi_frames *mi_alloc_frames(void);
-mi_gvar *mi_alloc_gvar(void);
-mi_gvar_chg *mi_alloc_gvar_chg(void);
-mi_bkpt *mi_alloc_bkpt(void);
-mi_wp *mi_alloc_wp(void);
-mi_stop *mi_alloc_stop(void);
-mi_asm_insns *mi_alloc_asm_insns(void);
-mi_asm_insn *mi_alloc_asm_insn(void);
-mi_chg_reg *mi_alloc_chg_reg(void);
-void mi_free_output(mi_output *r);
-void mi_free_output_but(mi_output *r, mi_output *no, mi_results *no_r);
-void mi_free_frames(mi_frames *f);
-void mi_free_aux_term(mi_aux_term *t);
-void mi_free_results(mi_results *r);
-void mi_free_results_but(mi_results *r, mi_results *no);
-void mi_free_gvar(mi_gvar *v);
-void mi_free_gvar_chg(mi_gvar_chg *p);
-void mi_free_wp(mi_wp *wp);
-void mi_free_stop(mi_stop *s);
-void mi_free_asm_insns(mi_asm_insns *i);
-void mi_free_asm_insn(mi_asm_insn *i);
-void mi_free_charp_list(char **l);
-void mi_free_chg_reg(mi_chg_reg *r);
-
-/* Porgram control: */
-/* Specify the executable and arguments for local debug. */
-int gmi_set_exec(mi_h *h, const char *file, const char *args);
-/* Start running the executable. Remote sessions starts running. */
-int gmi_exec_run(mi_h *h);
-/* Continue the execution after a "stop". */
-int gmi_exec_continue(mi_h *h);
-/* Indicate which terminal will use the target program. For local sessions. */
-int gmi_target_terminal(mi_h *h, const char *tty_name);
-/* Specify what's the local copy that have debug info. For remote sessions. */
-int gmi_file_symbol_file(mi_h *h, const char *file);
-/* Continue until function return, the return value is included in the async
- response. */
-int gmi_exec_finish(mi_h *h);
-/* Stop the program using SIGINT. */
-int gmi_exec_interrupt(mi_h *h);
-/* Next line of code. */
-int gmi_exec_next(mi_h *h);
-/* Next count lines of code. */
-int gmi_exec_next_cnt(mi_h *h, int count);
-/* Next line of assembler code. */
-int gmi_exec_next_instruction(mi_h *h);
-/* Next line of code. Get inside functions. */
-int gmi_exec_step(mi_h *h);
-/* Next count lines of code. Get inside functions. */
-int gmi_exec_step_cnt(mi_h *h, int count);
-/* Next line of assembler code. Get inside calls. */
-int gmi_exec_step_instruction(mi_h *h);
-/* Execute until location is reached. If file is NULL then is until next line. */
-int gmi_exec_until(mi_h *h, const char *file, int line);
-int gmi_exec_until_addr(mi_h *h, void *addr);
-/* Return to previous frame inmediatly. */
-mi_frames *gmi_exec_return(mi_h *h);
-/* Just kill the program. Please read the notes in prg_control.c. */
-int gmi_exec_kill(mi_h *h);
-
-/* Target manipulation: */
-/* Connect to a remote gdbserver using the specified methode. */
-int gmi_target_select(mi_h *h, const char *type, const char *params);
-/* Attach to an already running process. */
-mi_frames *gmi_target_attach(mi_h *h, pid_t pid);
-/* Detach from an attached process. */
-int gmi_target_detach(mi_h *h);
-
-/* Miscellaneous commands: */
-/* Exit gdb killing the child is it is running. */
-void gmi_gdb_exit(mi_h *h);
-/* Send the version to the console. */
-int gmi_gdb_version(mi_h *h);
-/* Set a gdb variable. */
-int gmi_gdb_set(mi_h *h, const char *var, const char *val);
-/* Get a gdb variable. */
-char *gmi_gdb_show(mi_h *h, const char *var);
-
-/* Breakpoints manipulation: */
-/* Insert a breakpoint at file:line. */
-mi_bkpt *gmi_break_insert(mi_h *h, const char *file, int line);
-/* Insert a breakpoint, all available options. */
-mi_bkpt *gmi_break_insert_full(mi_h *h, int temporary, int hard_assist,
- const char *cond, int count, int thread,
- const char *where);
-mi_bkpt *gmi_break_insert_full_fl(mi_h *h, const char *file, int line,
- int temporary, int hard_assist,
- const char *cond, int count, int thread);
-/* Remove a breakpoint. */
-int gmi_break_delete(mi_h *h, int number);
-/* Free the memory used for a breakpoint description. */
-void mi_free_bkpt(mi_bkpt *b);
-/* Modify the "ignore" count for a breakpoint. */
-int gmi_break_set_times(mi_h *h, int number, int count);
-/* Associate a condition with the breakpoint. */
-int gmi_break_set_condition(mi_h *h, int number, const char *condition);
-/* Enable or disable a breakpoint. */
-int gmi_break_state(mi_h *h, int number, int enable);
-/* Set a watchpoint. It doesn't work for remote targets! */
-mi_wp *gmi_break_watch(mi_h *h, enum mi_wp_mode mode, const char *exp);
-
-/* Data Manipulation. */
-/* Evaluate an expression. Returns a parsed tree. */
-char *gmi_data_evaluate_expression(mi_h *h, const char *expression);
-/* Path for sources. */
-int gmi_dir(mi_h *h, const char *path);
-/* A very limited "data read memory" implementation. */
-int gmi_read_memory(mi_h *h, const char *exp, unsigned size,
- unsigned char *dest, int *na, int convAddr,
- unsigned long *addr);
-mi_asm_insns *gmi_data_disassemble_se(mi_h *h, const char *start,
- const char *end, int mode);
-mi_asm_insns *gmi_data_disassemble_fl(mi_h *h, const char *file, int line,
- int lines, int mode);
-mi_chg_reg *gmi_data_list_register_names(mi_h *h, int *how_many);
-int gmi_data_list_register_names_l(mi_h *h, mi_chg_reg *l);
-mi_chg_reg *gmi_data_list_changed_registers(mi_h *h);
-int gmi_data_list_register_values(mi_h *h, enum mi_gvar_fmt fmt, mi_chg_reg *l);
-mi_chg_reg *gmi_data_list_all_register_values(mi_h *h, enum mi_gvar_fmt fmt, int *how_many);
-
-/* Stack manipulation. */
-/* List of frames. Arguments aren't filled. */
-mi_frames *gmi_stack_list_frames(mi_h *h);
-/* List of frames. Indicating a range. */
-mi_frames *gmi_stack_list_frames_r(mi_h *h, int from, int to);
-/* List arguments. Only level and args filled. */
-mi_frames *gmi_stack_list_arguments(mi_h *h, int show);
-/* List arguments. Indicating a range. Only level and args filled. */
-mi_frames *gmi_stack_list_arguments_r(mi_h *h, int show, int from, int to);
-/* Information about the current frame, including args. */
-mi_frames *gmi_stack_info_frame(mi_h *h);
-/* Stack info depth. error => -1 */
-int gmi_stack_info_depth_get(mi_h *h);
-/* Set stack info depth. error => -1 */
-int gmi_stack_info_depth(mi_h *h, int max_depth);
-/* Change current frame. */
-int gmi_stack_select_frame(mi_h *h, int framenum);
-/* List of local vars. */
-mi_results *gmi_stack_list_locals(mi_h *h, int show);
-
-/* Thread. */
-/* List available thread ids. */
-int gmi_thread_list_ids(mi_h *h, int **list);
-/* Select a thread. */
-mi_frames *gmi_thread_select(mi_h *h, int id);
-/* List available threads. */
-mi_frames *gmi_thread_list_all_threads(mi_h *h);
-
-/* Variable objects. */
-/* Create a variable object. */
-mi_gvar *gmi_var_create_nm(mi_h *h, const char *name, int frame, const char *exp);
-mi_gvar *gmi_var_create(mi_h *h, int frame, const char *exp);
-/* Create the variable and also fill the lang and attr fields. */
-mi_gvar *gmi_full_var_create(mi_h *h, int frame, const char *exp);
-/* Delete a variable object. Doesn't free the mi_gvar data. */
-int gmi_var_delete(mi_h *h, mi_gvar *var);
-/* Set the format used to represent the result. */
-int gmi_var_set_format(mi_h *h, mi_gvar *var, enum mi_gvar_fmt format);
-/* Fill the format field with info from gdb. */
-int gmi_var_show_format(mi_h *h, mi_gvar *var);
-/* Fill the numchild field with info from gdb. */
-int gmi_var_info_num_children(mi_h *h, mi_gvar *var);
-/* Fill the type field with info from gdb. */
-int gmi_var_info_type(mi_h *h, mi_gvar *var);
-/* Fill the expression and lang fields with info from gdb.
- Note that lang isn't filled during creation. */
-int gmi_var_info_expression(mi_h *h, mi_gvar *var);
-/* Fill the attr field with info from gdb.
- Note that attr isn't filled during creation. */
-int gmi_var_show_attributes(mi_h *h, mi_gvar *var);
-/* Update variable. Use NULL for all.
- Note that *changed can be NULL if none updated. */
-int gmi_var_update(mi_h *h, mi_gvar *var, mi_gvar_chg **changed);
-/* Change variable. Fills the value field. */
-int gmi_var_assign(mi_h *h, mi_gvar *var, const char *expression);
-/* Get current value for a variable. */
-int gmi_var_evaluate_expression(mi_h *h, mi_gvar *var);
-/* List children. It ONLY returns the first level information. :-( */
-int gmi_var_list_children(mi_h *h, mi_gvar *var);
-
-
-
-
-#if 0 /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Allocator.
- Comments:
- Most alloc/free routines are here. Free routines must accept NULL
-pointers. Alloc functions must set mi_error. @<p>
-
-***************************************************************************/
-
-#include "gdbmi.h"
-
-void *mi_calloc(size_t count, size_t sz)
-{
- void *res=calloc(count,sz);
- if (!res)
- mi_error=MI_OUT_OF_MEMORY;
- return res;
-}
-
-void *mi_calloc1(size_t sz)
-{
- return mi_calloc(1,sz);
-}
-
-char *mi_malloc(size_t sz)
-{
- char *res=malloc(sz);
- if (!res)
- mi_error=MI_OUT_OF_MEMORY;
- return res;
-}
-
-mi_results *mi_alloc_results(void)
-{
- return (mi_results *)mi_calloc1(sizeof(mi_results));
-}
-
-mi_output *mi_alloc_output(void)
-{
- return (mi_output *)mi_calloc1(sizeof(mi_output));
-}
-
-mi_frames *mi_alloc_frames(void)
-{
- return (mi_frames *)mi_calloc1(sizeof(mi_frames));
-}
-
-mi_gvar *mi_alloc_gvar(void)
-{
- return (mi_gvar *)mi_calloc1(sizeof(mi_gvar));
-}
-
-mi_gvar_chg *mi_alloc_gvar_chg(void)
-{
- return (mi_gvar_chg *)mi_calloc1(sizeof(mi_gvar_chg));
-}
-
-mi_bkpt *mi_alloc_bkpt(void)
-{
- mi_bkpt *b=(mi_bkpt *)mi_calloc1(sizeof(mi_bkpt));
- if (b)
- {
- b->thread=-1;
- b->ignore=-1;
- }
- return b;
-}
-
-mi_wp *mi_alloc_wp(void)
-{
- return (mi_wp *)mi_calloc1(sizeof(mi_wp));
-}
-
-mi_stop *mi_alloc_stop(void)
-{
- return (mi_stop *)mi_calloc1(sizeof(mi_stop));
-}
-
-mi_asm_insns *mi_alloc_asm_insns(void)
-{
- return (mi_asm_insns *)mi_calloc1(sizeof(mi_asm_insns));
-}
-
-mi_asm_insn *mi_alloc_asm_insn(void)
-{
- return (mi_asm_insn *)mi_calloc1(sizeof(mi_asm_insn));
-}
-
-mi_chg_reg *mi_alloc_chg_reg(void)
-{
- return (mi_chg_reg *)mi_calloc1(sizeof(mi_chg_reg));
-}
-
-/*****************************************************************************
- Free functions
-*****************************************************************************/
-
-void mi_free_frames(mi_frames *f)
-{
- mi_frames *aux;
-
- while (f)
- {
- free(f->func);
- free(f->file);
- free(f->from);
- mi_free_results(f->args);
- aux=f->next;
- free(f);
- f=aux;
- }
-}
-
-void mi_free_bkpt(mi_bkpt *b)
-{
- mi_bkpt *aux;
-
- while (b)
- {
- free(b->func);
- free(b->file);
- free(b->file_abs);
- free(b->cond);
- aux=b->next;
- free(b);
- b=aux;
- }
-}
-
-void mi_free_gvar(mi_gvar *v)
-{
- mi_gvar *aux;
-
- while (v)
- {
- free(v->name);
- free(v->type);
- free(v->exp);
- free(v->value);
- if (v->numchild && v->child)
- mi_free_gvar(v->child);
- aux=v->next;
- free(v);
- v=aux;
- }
-}
-
-void mi_free_gvar_chg(mi_gvar_chg *p)
-{
- mi_gvar_chg *aux;
-
- while (p)
- {
- free(p->name);
- free(p->new_type);
- aux=p->next;
- free(p);
- p=aux;
- }
-}
-
-void mi_free_results_but(mi_results *r, mi_results *no)
-{
- mi_results *aux;
-
- while (r)
- {
- if (r==no)
- {
- aux=r->next;
- r->next=NULL;
- r=aux;
- }
- else
- {
- free(r->var);
- switch (r->type)
- {
- case t_const:
- free(r->v.cstr);
- break;
- case t_tuple:
- case t_list:
- mi_free_results_but(r->v.rs,no);
- break;
- }
- aux=r->next;
- free(r);
- r=aux;
- }
- }
-}
-
-void mi_free_results(mi_results *r)
-{
- mi_free_results_but(r,NULL);
-}
-
-void mi_free_output_but(mi_output *r, mi_output *no, mi_results *no_r)
-{
- mi_output *aux;
-
- while (r)
- {
- if (r==no)
- {
- aux=r->next;
- r->next=NULL;
- r=aux;
- }
- else
- {
- if (r->c)
- mi_free_results_but(r->c,no_r);
- aux=r->next;
- free(r);
- r=aux;
- }
- }
-}
-
-void mi_free_output(mi_output *r)
-{
- mi_free_output_but(r,NULL,NULL);
-}
-
-void mi_free_stop(mi_stop *s)
-{
- if (!s)
- return;
- mi_free_frames(s->frame);
- mi_free_wp(s->wp);
- free(s->wp_old);
- free(s->wp_val);
- free(s->gdb_result_var);
- free(s->return_value);
- free(s->signal_name);
- free(s->signal_meaning);
- free(s);
-}
-
-void mi_free_wp(mi_wp *wp)
-{
- mi_wp *aux;
- while (wp)
- {
- free(wp->exp);
- aux=wp->next;
- free(wp);
- wp=aux;
- }
-}
-
-void mi_free_asm_insns(mi_asm_insns *i)
-{
- mi_asm_insns *aux;
-
- while (i)
- {
- free(i->file);
- mi_free_asm_insn(i->ins);
- aux=i->next;
- free(i);
- i=aux;
- }
-}
-
-void mi_free_asm_insn(mi_asm_insn *i)
-{
- mi_asm_insn *aux;
-
- while (i)
- {
- free(i->func);
- free(i->inst);
- aux=i->next;
- free(i);
- i=aux;
- }
-}
-
-/*void mi_free_charp_list(char **l)
-{
- char **c=l;
- while (c)
- {
- free(*c);
- c++;
- }
- free(l);
-}*/
-
-void mi_free_chg_reg(mi_chg_reg *r)
-{
- mi_chg_reg *aux;
- while (r)
- {
- free(r->val);
- free(r->name);
- aux=r->next;
- free(r);
- r=aux;
- }
-}
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Breakpoint table commands.
- Comments:
- GDB/MI commands for the "Breakpoint Table Commands" section.
- @<p>
-@<pre>
-gdb command: Implemented?
-
--break-after Yes
--break-condition Yes
--break-delete Yes
--break-disable Yes
--break-enable Yes
--break-info N.A. (info break NUMBER) (*)
--break-insert Yes
--break-list No (*)
--break-watch Yes
-@</pre>
-
-(*) I think the program should keep track of the breakpoints, so it will
-be implemented when I have more time. @<p>
-
-***************************************************************************/
-
-#include "gdbmi.h"
-
-/* Low level versions. */
-
-void mi_break_insert_fl(mi_h *h, const char *file, int line)
-{
- mi_send(h,"-break-insert %s:%d\n",file,line);
-}
-
-void mi_break_insert(mi_h *h, int temporary, int hard_assist,
- const char *cond, int count, int thread,
- const char *where)
-{
- char s_count[32];
- char s_thread[32];
-
- if (count>=0)
- snprintf(s_count,32,"%d",count);
- if (thread>=0)
- snprintf(s_thread,32,"%d",thread);
- if (cond)
- // Conditions may contain spaces, in fact, if they don't gdb will add
- // them after parsing. Enclosing the expression with "" solves the
- // problem.
- mi_send(h,"-break-insert %s %s -c \"%s\" %s %s %s %s %s\n",
- temporary ? "-t" : "",
- hard_assist ? "-h" : "",
- cond,
- count>=0 ? "-i" : "", count>=0 ? s_count : "",
- thread>=0 ? "-p" : "", thread>=0 ? s_thread : "",
- where);
- else
- mi_send(h,"-break-insert %s %s %s %s %s %s %s\n",
- temporary ? "-t" : "",
- hard_assist ? "-h" : "",
- count>=0 ? "-i" : "", count>=0 ? s_count : "",
- thread>=0 ? "-p" : "", thread>=0 ? s_thread : "",
- where);
-}
-
-void mi_break_insert_flf(mi_h *h, const char *file, int line, int temporary,
- int hard_assist, const char *cond, int count,
- int thread)
-{
- char s_count[32];
- char s_thread[32];
-
- if (count>=0)
- snprintf(s_count,32,"%d",count);
- if (thread>=0)
- snprintf(s_thread,32,"%d",thread);
- mi_send(h,"-break-insert %s %s %s %s %s %s %s %s %s:%d\n",
- temporary ? "-t" : "",
- hard_assist ? "-h" : "",
- cond ? "-c" : "", cond ? cond : "",
- count>=0 ? "-i" : "", count>=0 ? s_count : "",
- thread>=0 ? "-p" : "", thread>=0 ? s_thread : "",
- file,line);
-}
-
-void mi_break_delete(mi_h *h, int number)
-{
- mi_send(h,"-break-delete %d\n",number);
-}
-
-void mi_break_after(mi_h *h, int number, int count)
-{
- mi_send(h,"-break-after %d %d\n",number,count);
-}
-
-void mi_break_condition(mi_h *h, int number, const char *condition)
-{
- mi_send(h,"-break-condition %d %s\n",number,condition);
-}
-
-void mi_break_enable(mi_h *h, int number)
-{
- mi_send(h,"-break-enable %d\n",number);
-}
-
-void mi_break_disable(mi_h *h, int number)
-{
- mi_send(h,"-break-disable %d\n",number);
-}
-
-void mi_break_watch(mi_h *h, enum mi_wp_mode mode, const char *exp)
-{
- if (mode==wm_write)
- mi_send(h,"-break-watch \"%s\"\n",exp);
- else
- mi_send(h,"-break-watch -%c \"%s\"\n",mode==wm_rw ? 'a' : 'r',exp);
-}
-
-/* High level versions. */
-
-/**[txh]********************************************************************
-
- Description:
- Insert a breakpoint at file:line.
-
- Command: -break-insert file:line
- Return: A new mi_bkpt structure with info about the breakpoint. NULL on
-error.
-
-***************************************************************************/
-
-mi_bkpt *gmi_break_insert(mi_h *h, const char *file, int line)
-{
- mi_break_insert_fl(h,file,line);
- return mi_res_bkpt(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Insert a breakpoint, all available options.
-
- Command: -break-insert
- Return: A new mi_bkpt structure with info about the breakpoint. NULL on
-error.
-
-***************************************************************************/
-
-mi_bkpt *gmi_break_insert_full(mi_h *h, int temporary, int hard_assist,
- const char *cond, int count, int thread,
- const char *where)
-{
- mi_break_insert(h,temporary,hard_assist,cond,count,thread,where);
- return mi_res_bkpt(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Insert a breakpoint, all available options.
-
- Command: -break-insert [ops] file:line
- Return: A new mi_bkpt structure with info about the breakpoint. NULL on
-error.
-
-***************************************************************************/
-
-mi_bkpt *gmi_break_insert_full_fl(mi_h *h, const char *file, int line,
- int temporary, int hard_assist,
- const char *cond, int count, int thread)
-{
- mi_break_insert_flf(h,file,line,temporary,hard_assist,cond,count,thread);
- return mi_res_bkpt(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Remove a breakpoint.
-
- Command: -break-delete
- Return: !=0 OK. Note that gdb always says OK, but errors can be sent to the
-console.
-
-***************************************************************************/
-
-int gmi_break_delete(mi_h *h, int number)
-{
- mi_break_delete(h,number);
- return mi_res_simple_done(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Modify the "ignore" count for a breakpoint.
-
- Command: -break-after
- Return: !=0 OK. Note that gdb always says OK, but errors can be sent to the
-console.
-
-***************************************************************************/
-
-int gmi_break_set_times(mi_h *h, int number, int count)
-{
- mi_break_after(h,number,count);
- return mi_res_simple_done(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Associate a condition with the breakpoint.
-
- Command: -break-condition
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_break_set_condition(mi_h *h, int number, const char *condition)
-{
- mi_break_condition(h,number,condition);
- return mi_res_simple_done(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Enable or disable a breakpoint.
-
- Command: -break-enable + -break-disable
- Return: !=0 OK. Note that gdb always says OK, but errors can be sent to the
-console.
-
-***************************************************************************/
-
-int gmi_break_state(mi_h *h, int number, int enable)
-{
- if (enable)
- mi_break_enable(h,number);
- else
- mi_break_disable(h,number);
- return mi_res_simple_done(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Set a watchpoint. It doesn't work for remote targets!
-
- Command: -break-watch
- Return: A new mi_wp structure with info about the watchpoint. NULL on
-error.
-
-***************************************************************************/
-
-mi_wp *gmi_break_watch(mi_h *h, enum mi_wp_mode mode, const char *exp)
-{
- mi_break_watch(h,mode,exp);
- return mi_res_wp(h);
-}
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004-2009 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Connect.
- Comments:
- This module handles the dialog with gdb, including starting and stopping
-gdb.
- @<p>
-
-GDB Bug workaround for "file -readnow": I tried to workaround a bug using
-it but looks like this option also have bugs!!!! so I have to use the
-command line option --readnow.
-It also have a bug!!!! when the binary is changed and gdb must reload it
-this option is ignored. So it looks like we have no solution but 3 gdb bugs
-in a row.
-
-***************************************************************************/
-
-#include "platform.h"
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdarg.h>
-#include <limits.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include "gdbmi.h"
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#ifndef TEMP_FAILURE_RETRY
- #define TEMP_FAILURE_RETRY(a) (a)
-#endif
-
-int mi_error=MI_OK;
-char *mi_error_from_gdb=NULL;
-static char *gdb_exe=NULL;
-static char *xterm_exe=NULL;
-static char *gdb_start=NULL;
-static char *gdb_conn=NULL;
-static char *main_func=NULL;
-static char disable_psym_search_workaround=0;
-
-mi_h *mi_alloc_h()
-{
- mi_h *h=(mi_h *)calloc(1,sizeof(mi_h));
- if (!h)
- {
- mi_error=MI_OUT_OF_MEMORY;
- return NULL;
- }
- h->to_gdb[0]=h->to_gdb[1]=h->from_gdb[0]=h->from_gdb[1]=-1;
- h->pid=-1;
- return h;
-}
-
-int mi_check_running_pid(pid_t pid)
-{
- int status;
-
- if (pid<=0)
- return 0;
- /* If waitpid returns the number of our child means it communicated
- to as a termination status. */
- if (waitpid(pid,&status,WNOHANG)==pid)
- {
- pid=0;
- return 0;
- }
- return 1;
-}
-
-int mi_check_running(mi_h *h)
-{
- return !h->died && mi_check_running_pid(h->pid);
-}
-
-void mi_kill_child(pid_t pid)
-{
- kill(pid,SIGTERM);
- usleep(100000);
- if (mi_check_running_pid(pid))
- {
- int status;
- kill(pid,SIGKILL);
- waitpid(pid,&status,0);
- }
-}
-
-void mi_free_h(mi_h **handle)
-{
- mi_h *h=*handle;
- if (h->to_gdb[0]>=0)
- close(h->to_gdb[0]);
- if (h->to)
- fclose(h->to);
- else if (h->to_gdb[1]>=0)
- close(h->to_gdb[1]);
- if (h->from)
- fclose(h->from);
- else if (h->from_gdb[0]>=0)
- close(h->from_gdb[0]);
- if (h->from_gdb[1]>=0)
- close(h->from_gdb[1]);
- if (mi_check_running(h))
- {/* GDB is running! */
- mi_kill_child(h->pid);
- }
- if (h->line)
- free(h->line);
- mi_free_output(h->po);
- free(h->catched_console);
- free(h);
- *handle=NULL;
-}
-
-void mi_set_nonblk(int h)
-{
- int flf;
- flf=fcntl(h,F_GETFL,0);
- flf=flf | O_NONBLOCK;
- fcntl(h,F_SETFL,flf);
-}
-
-int mi_getline(mi_h *h)
-{
- char c;
-
- while (read(h->from_gdb[0],&c,1)==1)
- {
- if (h->lread>=h->llen)
- {
- h->llen=h->lread+128;
- h->line=(char *)realloc(h->line,h->llen);
- if (!h->line)
- {
- h->llen=0;
- h->lread=0;
- return -1;
- }
- }
- if (c=='\n')
- {
- int ret=h->lread;
- h->line[ret]=0;
- h->lread=0;
- return ret;
- }
- h->line[h->lread]=c;
- h->lread++;
- }
- return 0;
-}
-
-char *get_cstr(mi_output *o)
-{
- if (!o->c || o->c->type!=t_const)
- return NULL;
- return o->c->v.cstr;
-}
-
-int mi_get_response(mi_h *h)
-{
- int l=mi_getline(h);
- if (!l)
- return 0;
-
- if (h->from_gdb_echo)
- h->from_gdb_echo(h->line,h->from_gdb_echo_data);
- if (strncmp(h->line,"(gdb)",5)==0)
- {/* End of response. */
- return 1;
- }
- else
- {/* Add to the response. */
- mi_output *o;
- int add=1, is_exit=0;
- o=mi_parse_gdb_output(h->line);
-
- if (!o)
- return 0;
- /* Tunneled streams callbacks. */
- if (o->type==MI_T_OUT_OF_BAND && o->stype==MI_ST_STREAM)
- {
- char *aux;
- add=0;
- switch (o->sstype)
- {
- case MI_SST_CONSOLE:
- aux=get_cstr(o);
- if (h->console)
- h->console(aux,h->console_data);
- if (h->catch_console && aux)
- {
- h->catch_console--;
- if (!h->catch_console)
- {
- free(h->catched_console);
- h->catched_console=strdup(aux);
- }
- }
- break;
- case MI_SST_TARGET:
- /* This one seems to be useless. */
- if (h->target)
- h->target(get_cstr(o),h->target_data);
- break;
- case MI_SST_LOG:
- if (h->log)
- h->log(get_cstr(o),h->log_data);
- break;
- }
- }
- else if (o->type==MI_T_OUT_OF_BAND && o->stype==MI_ST_ASYNC)
- {
- if (h->async)
- h->async(o,h->async_data);
- }
- else if (o->type==MI_T_RESULT_RECORD && o->tclass==MI_CL_ERROR)
- {/* Error from gdb, record it. */
- mi_error=MI_FROM_GDB;
- free(mi_error_from_gdb);
- mi_error_from_gdb=NULL;
- if (o->c && strcmp(o->c->var,"msg")==0 && o->c->type==t_const)
- mi_error_from_gdb=strdup(o->c->v.cstr);
- }
- is_exit=(o->type==MI_T_RESULT_RECORD && o->tclass==MI_CL_EXIT);
- /* Add to the list of responses. */
- if (add)
- {
- if (h->last)
- h->last->next=o;
- else
- h->po=o;
- h->last=o;
- }
- else
- mi_free_output(o);
- /* Exit RR means gdb exited, we won't get a new prompt ;-) */
- if (is_exit)
- return 1;
- }
-
- return 0;
-}
-
-mi_output *mi_retire_response(mi_h *h)
-{
- mi_output *ret=h->po;
- h->po=h->last=NULL;
- return ret;
-}
-
-mi_output *mi_get_response_blk(mi_h *h)
-{
- int r;
- /* Sometimes gdb dies. */
- if (!mi_check_running(h))
- {
- h->died=1;
- mi_error=MI_GDB_DIED;
- return NULL;
- }
- do
- {
- /*
- That's a must. If we just keep trying to read and failing things
- become really sloooowwww. Instead we try and if it fails we wait
- until something is available.
- TODO: Implement something with the time out, a callback to ask the
- application is we have to wait or not could be a good thing.
- */
- fd_set set;
- struct timeval timeout;
- int ret;
-
- r=mi_get_response(h);
- if (r)
- return mi_retire_response(h);
-
- FD_ZERO(&set);
- FD_SET(h->from_gdb[0],&set);
- timeout.tv_sec=h->time_out;
- timeout.tv_usec=0;
- ret=TEMP_FAILURE_RETRY(select(FD_SETSIZE,&set,NULL,NULL,&timeout));
- if (!ret)
- {
- if (!mi_check_running(h))
- {
- h->died=1;
- mi_error=MI_GDB_DIED;
- return NULL;
- }
- if (h->time_out_cb)
- ret=h->time_out_cb(h->time_out_cb_data);
- if (!ret)
- {
- mi_error=MI_GDB_TIME_OUT;
- return NULL;
- }
- }
- }
- while (!r);
-
- return NULL;
-}
-
-void mi_send_commands(mi_h *h, const char *file)
-{
- FILE *f;
- char b[PATH_MAX];
-
- //printf("File: %s\n",file);
- if (!file)
- return;
- f=fopen(file,"rt");
- if (!f)
- return;
- while (!feof(f))
- {
- if (fgets(b,PATH_MAX,f))
- {
- //printf("Send: %s\n",b);
- mi_send (h, "%s", b);
- mi_res_simple_done(h);
- }
- }
- fclose(f);
-}
-
-void mi_send_target_commands(mi_h *h)
-{
- mi_send_commands(h,gdb_conn);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Connect to a local copy of gdb. Note that the mi_h structure is something
-similar to a "FILE *" for stdio.
-
- Return: A new mi_h structure or NULL on error.
-
-***************************************************************************/
-
-mi_h *mi_connect_local()
-{
- mi_h *h;
- const char *gdb=mi_get_gdb_exe();
-
- /* Start without error. */
- mi_error=MI_OK;
- /* Verify we have a GDB binary. */
- if (access(gdb,X_OK))
- {
- mi_error=MI_MISSING_GDB;
- return NULL;
- }
- /* Alloc the handle structure. */
- h=mi_alloc_h();
- if (!h)
- return h;
- h->time_out=MI_DEFAULT_TIME_OUT;
- /* Create the pipes to connect with the child. */
- if (pipe(h->to_gdb) || pipe(h->from_gdb))
- {
- mi_error=MI_PIPE_CREATE;
- mi_free_h(&h);
- return NULL;
- }
- mi_set_nonblk(h->to_gdb[1]);
- mi_set_nonblk(h->from_gdb[0]);
- /* Associate streams to the file handles. */
- h->to=fdopen(h->to_gdb[1],"w");
- h->from=fdopen(h->from_gdb[0],"r");
- if (!h->to || !h->from)
- {
- mi_error=MI_PIPE_CREATE;
- mi_free_h(&h);
- return NULL;
- }
- /* Create the child. */
- h->pid=fork();
- if (h->pid==0)
- {/* We are the child. */
- char *argv[5];
- /* Connect stdin/out to the pipes. */
- dup2(h->to_gdb[0],STDIN_FILENO);
- dup2(h->from_gdb[1],STDOUT_FILENO);
- /* Pass the control to gdb. */
- argv[0]=(char *)gdb; /* Is that OK? */
- argv[1]="--interpreter=mi";
- argv[2]="--quiet";
- argv[3]=disable_psym_search_workaround ? 0 : "--readnow";
- argv[4]=0;
- execvp(argv[0],argv);
- /* We get here only if exec failed. */
- _exit(127);
- }
- /* We are the parent. */
- if (h->pid==-1)
- {/* Fork failed. */
- mi_error=MI_FORK;
- mi_free_h(&h);
- return NULL;
- }
- if (!mi_check_running(h))
- {
- mi_error=MI_DEBUGGER_RUN;
- mi_free_h(&h);
- return NULL;
- }
- /* Wait for the prompt. */
- mi_get_response_blk(h);
- /* Send the start-up commands */
- mi_send_commands(h,gdb_start);
-
- return h;
-}
-
-/**[txh]********************************************************************
-
- Description:
- Close connection. You should ask gdb to quit first gmi_gdb_exit.
-
-***************************************************************************/
-
-void mi_disconnect(mi_h *h)
-{
- mi_free_h(&h);
- free(mi_error_from_gdb);
- mi_error_from_gdb=NULL;
-}
-
-void mi_set_console_cb(mi_h *h, stream_cb cb, void *data)
-{
- h->console=cb;
- h->console_data=data;
-}
-
-void mi_set_target_cb(mi_h *h, stream_cb cb, void *data)
-{
- h->target=cb;
- h->target_data=data;
-}
-
-void mi_set_log_cb(mi_h *h, stream_cb cb, void *data)
-{
- h->log=cb;
- h->log_data=data;
-}
-
-stream_cb mi_get_console_cb(mi_h *h, void **data)
-{
- if (data)
- *data=h->console_data;
- return h->console;
-}
-
-stream_cb mi_get_target_cb(mi_h *h, void **data)
-{
- if (data)
- *data=h->target_data;
- return h->target;
-}
-
-stream_cb mi_get_log_cb(mi_h *h, void **data)
-{
- if (data)
- *data=h->log_data;
- return h->log;
-}
-
-void mi_set_async_cb(mi_h *h, async_cb cb, void *data)
-{
- h->async=cb;
- h->async_data=data;
-}
-
-async_cb mi_get_async_cb(mi_h *h, void **data)
-{
- if (data)
- *data=h->async_data;
- return h->async;
-}
-
-void mi_set_to_gdb_cb(mi_h *h, stream_cb cb, void *data)
-{
- h->to_gdb_echo=cb;
- h->to_gdb_echo_data=data;
-}
-
-void mi_set_from_gdb_cb(mi_h *h, stream_cb cb, void *data)
-{
- h->from_gdb_echo=cb;
- h->from_gdb_echo_data=data;
-}
-
-stream_cb mi_get_to_gdb_cb(mi_h *h, void **data)
-{
- if (data)
- *data=h->to_gdb_echo_data;
- return h->to_gdb_echo;
-}
-
-stream_cb mi_get_from_gdb_cb(mi_h *h, void **data)
-{
- if (data)
- *data=h->from_gdb_echo_data;
- return h->from_gdb_echo;
-}
-
-void mi_set_time_out_cb(mi_h *h, tm_cb cb, void *data)
-{
- h->time_out_cb=cb;
- h->time_out_cb_data=data;
-}
-
-tm_cb mi_get_time_out_cb(mi_h *h, void **data)
-{
- if (data)
- *data=h->time_out_cb_data;
- return h->time_out_cb;
-}
-
-void mi_set_time_out(mi_h *h, int to)
-{
- h->time_out=to;
-}
-
-int mi_get_time_out(mi_h *h)
-{
- return h->time_out;
-}
-
-int mi_send(mi_h *h, const char *format, ...)
-{
- int ret;
- char *str;
- va_list argptr;
-
- if (h->died)
- return 0;
-
- va_start(argptr,format);
- ret=vasprintf(&str,format,argptr);
- va_end(argptr);
- if (-1 != ret)
- {
- fputs(str,h->to);
- fflush(h->to);
- if (h->to_gdb_echo)
- h->to_gdb_echo(str,h->to_gdb_echo_data);
- free(str);
- }
- else
- {
- abort ();
- }
-
- return ret;
-}
-
-void mi_clean_up_globals()
-{
- free(gdb_exe);
- gdb_exe=NULL;
- free(xterm_exe);
- xterm_exe=NULL;
- free(gdb_start);
- gdb_start=NULL;
- free(gdb_conn);
- gdb_conn=NULL;
- free(main_func);
- main_func=NULL;
-}
-
-void mi_register_exit()
-{
- static int registered=0;
- if (!registered)
- {
- registered=1;
- atexit(mi_clean_up_globals);
- }
-}
-
-void mi_set_gdb_exe(const char *name)
-{
- free(gdb_exe);
- gdb_exe=name ? strdup(name) : NULL;
- mi_register_exit();
-}
-
-void mi_set_gdb_start(const char *name)
-{
- free(gdb_start);
- gdb_start=name ? strdup(name) : NULL;
- mi_register_exit();
-}
-
-void mi_set_gdb_conn(const char *name)
-{
- free(gdb_conn);
- gdb_conn=name ? strdup(name) : NULL;
- mi_register_exit();
-}
-
-static
-char *mi_search_in_path(const char *file)
-{
- char *path, *pt, *r;
- char test[PATH_MAX];
- struct stat st;
-
- path=getenv("PATH");
- if (!path)
- return NULL;
- pt=strdup(path);
- r=strtok(pt,PATH_SEPARATOR_STR);
- while (r)
- {
- strcpy(test,r);
- strcat(test,"/");
- strcat(test,file);
- if (stat(test,&st)==0 && S_ISREG(st.st_mode))
- {
- free(pt);
- return strdup(test);
- }
- r=strtok(NULL,PATH_SEPARATOR_STR);
- }
- free(pt);
- return NULL;
-}
-
-const char *mi_get_gdb_exe()
-{
- if (!gdb_exe)
- {/* Look for gdb in path */
- gdb_exe=mi_search_in_path("gdb");
- if (!gdb_exe)
- return "/usr/bin/gdb";
- }
- return gdb_exe;
-}
-
-const char *mi_get_gdb_start()
-{
- return gdb_start;
-}
-
-const char *mi_get_gdb_conn()
-{
- return gdb_conn;
-}
-
-void mi_set_xterm_exe(const char *name)
-{
- free(xterm_exe);
- xterm_exe=name ? strdup(name) : NULL;
- mi_register_exit();
-}
-
-const char *mi_get_xterm_exe()
-{
- if (!xterm_exe)
- {/* Look for xterm in path */
- xterm_exe=mi_search_in_path("xterm");
- if (!xterm_exe)
- return "/usr/bin/X11/xterm";
- }
- return xterm_exe;
-}
-
-void mi_set_main_func(const char *name)
-{
- free(main_func);
- main_func=name ? strdup(name) : NULL;
- mi_register_exit();
-}
-
-const char *mi_get_main_func()
-{
- if (main_func)
- return main_func;
- return "main";
-}
-
-/**[txh]********************************************************************
-
- Description:
- Opens a new xterm to be used by the child process to debug.
-
- Return: A new mi_aux_term structure, you can use gmi_end_aux_term to
-release it.
-
-***************************************************************************/
-
-mi_aux_term *gmi_start_xterm()
-{
- char nsh[14]="/tmp/shXXXXXX";
- char ntt[14]="/tmp/ttXXXXXX";
- const char *xterm;
- struct stat st;
- int hsh, htt=-1;
- mi_aux_term *res=NULL;
- FILE *f;
- pid_t pid;
- char buf[PATH_MAX];
-
- /* Verify we have an X terminal. */
- xterm=mi_get_xterm_exe();
- if (access(xterm,X_OK))
- {
- mi_error=MI_MISSING_XTERM;
- return NULL;
- }
-
- /* Create 2 temporals. */
- hsh=mkstemp(nsh);
- if (hsh==-1)
- {
- mi_error=MI_CREATE_TEMPORAL;
- return NULL;
- }
- htt=mkstemp(ntt);
- if (htt==-1)
- {
- close(hsh);
- unlink(nsh);
- mi_error=MI_CREATE_TEMPORAL;
- return NULL;
- }
- close(htt);
- /* Create the script. */
- f=fdopen(hsh,"w");
- if (!f)
- {
- close(hsh);
- unlink(nsh);
- unlink(ntt);
- mi_error=MI_CREATE_TEMPORAL;
- return NULL;
- }
- fprintf(f,"#!/bin/sh\n");
- fprintf(f,"tty > %s\n",ntt);
- fprintf(f,"rm %s\n",nsh);
- fprintf(f,"sleep 365d\n");
- fclose(f);
- /* Spawn xterm. */
- /* Create the child. */
- pid=fork();
- if (pid==0)
- {/* We are the child. */
- char *argv[5];
- /* Pass the control to gdb. */
- argv[0]=(char *)mi_get_xterm_exe(); /* Is that ok? */
- argv[1]="-e";
- argv[2]="/bin/sh";
- argv[3]=nsh;
- argv[4]=0;
- execvp(argv[0],argv);
- /* We get here only if exec failed. */
- unlink(nsh);
- unlink(ntt);
- _exit(127);
- }
- /* We are the parent. */
- if (pid==-1)
- {/* Fork failed. */
- unlink(nsh);
- unlink(ntt);
- mi_error=MI_FORK;
- return NULL;
- }
- /* Wait until the shell is deleted. */
- while (stat(nsh,&st)==0)
- usleep(1000);
- /* Try to read the tty name. */
- f=fopen(ntt,"rt");
- if (f)
- {
- if (fgets(buf,PATH_MAX,f))
- {
- char *s; /* Strip the \n. */
- for (s=buf; *s && *s!='\n'; s++);
- *s=0;
- res=(mi_aux_term *)malloc(sizeof(mi_aux_term));
- if (res)
- {
- res->pid=pid;
- res->tty=strdup(buf);
- }
- }
- fclose(f);
- }
- unlink(ntt);
- return res;
-}
-
-void mi_free_aux_term(mi_aux_term *t)
-{
- if (!t)
- return;
- free(t->tty);
- free(t);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Closes the auxiliar terminal and releases the allocated memory.
-
-***************************************************************************/
-
-void gmi_end_aux_term(mi_aux_term *t)
-{
- if (!t)
- return;
- if (t->pid!=-1 && mi_check_running_pid(t->pid))
- mi_kill_child(t->pid);
- mi_free_aux_term(t);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Forces the MI version. Currently the library can't detect it so you must
-force it manually. GDB 5.x implemented MI v1 and 6.x v2.
-
-***************************************************************************/
-
-void mi_force_version(mi_h *h, unsigned vMajor, unsigned vMiddle,
- unsigned vMinor)
-{
- h->version=MI_VERSION2U(vMajor,vMiddle,vMinor);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Dis/Enables the workaround for a bug in gdb.
-
-***************************************************************************/
-
-void mi_set_workaround(unsigned wa, int enable)
-{
- switch (wa)
- {
- case MI_PSYM_SEARCH:
- disable_psym_search_workaround=enable ? 0 : 1;
- break;
- }
-}
-
-/**[txh]********************************************************************
-
- Description:
- Finds if the workaround for a bug in gdb is enabled.
-
- Return: !=0 if enabled.
-
-***************************************************************************/
-
-int mi_get_workaround(unsigned wa)
-{
- switch (wa)
- {
- case MI_PSYM_SEARCH:
- return disable_psym_search_workaround==0;
- }
- return 0;
-}
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Data manipulation.
- Comments:
- GDB/MI commands for the "Data manipulation" section.
-
- @<p>
-
-@<pre>
-gdb command: Implemented?
-
--data-disassemble Yes
--data-evaluate-expression Yes
--data-list-changed-registers No
--data-list-register-names Yes
--data-list-register-values No
--data-read-memory No
--display-delete N.A. (delete display)
--display-disable N.A. (disable display)
--display-enable N.A. (enable display)
--display-insert N.A. (display)
--display-list N.A. (info display)
--environment-cd No
--environment-directory Yes, MI v1 implementation
--environment-path No
-@</pre>
-
-Notes: @<p>
-
-1) -display* aren't implemented. You can use CLI command display, but the
-results are sent to the console. So it looks like the best is to manually
-use -data-evaluate-expression to emulate it. @<p>
-
-2) GDB bug mi/1770: Affects gdb<=6.2, when you ask for the names of the
-registers you get it plus the name of the "pseudo-registers", but if you
-try to get the value of a pseudo-register you get an error saying the
-register number is invalid. I reported to gdb-patches@sources.redhat.com
-on 2004/08/25 and as I didn't get any answer I filled a bug report on
-2004/09/02. The patch to fix this annoying bug is:
-
-Index: gdb/mi/mi-main.c
-===================================================================
-RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
-retrieving revision 1.64
-diff -u -r1.64 mi-main.c
---- gdb/mi/mi-main.c 3 Aug 2004 00:57:27 -0000 1.64
-+++ gdb/mi/mi-main.c 25 Aug 2004 14:12:50 -0000
-@@ -423,7 +423,7 @@
- case, some entries of REGISTER_NAME will change depending upon
- the particular processor being debugged.
-
-- numregs = NUM_REGS;
-+ numregs = NUM_REGS + NUM_PSEUDO_REGS;
-
- if (argc == 0)
- {
-----
-
-Note I had to remove an end of comment in the patch to include it here.
-This bug forced me to create another set of functions. The only way is to
-first get the values and then the names.
-Fixed by Changelog entry:
-
-2004-09-12 Salvador E. Tropea <set@users.sf.net>
- Andrew Cagney <cagney@gnu.org>
-
- * mi/mi-main.c (mi_cmd_data_list_changed_registers)
- (mi_cmd_data_list_register_values)
- (mi_cmd_data_write_register_values): Include the PSEUDO_REGS in
- the register number computation.
-
-***************************************************************************/
-
-#include "gdbmi.h"
-
-/* Low level versions. */
-
-void mi_data_evaluate_expression(mi_h *h, const char *expression)
-{
- mi_send(h,"-data-evaluate-expression \"%s\"\n",expression);
-}
-
-void mi_dir(mi_h *h, const char *path)
-{
- if (h->version>=MI_VERSION2U(2,0,0))
- {// MI v2
- if (path)
- mi_send(h,"-environment-directory \"%s\"\n",path);
- else
- mi_send(h,"-environment-directory -r\n");
- }
- else
- {
- mi_send(h,"-environment-directory %s\n",path ? path : "");
- }
-}
-
-void mi_data_read_memory_hx(mi_h *h, const char *exp, unsigned ws,
- unsigned c, int convAddr)
-{
- if (convAddr)
- mi_send(h,"-data-read-memory \"&%s\" x %d 1 %d\n",exp,ws,c);
- else
- mi_send(h,"-data-read-memory \"%s\" x %d 1 %d\n",exp,ws,c);
-}
-
-void mi_data_disassemble_se(mi_h *h, const char *start, const char *end,
- int mode)
-{
- mi_send(h,"-data-disassemble -s \"%s\" -e \"%s\" -- %d\n",start,end,mode);
-}
-
-void mi_data_disassemble_fl(mi_h *h, const char *file, int line, int lines,
- int mode)
-{
- mi_send(h,"-data-disassemble -f \"%s\" -l %d -n %d -- %d\n",file,line,lines,
- mode);
-}
-
-void mi_data_list_register_names(mi_h *h)
-{
- mi_send(h,"-data-list-register-names\n");
-}
-
-void mi_data_list_register_names_l(mi_h *h, mi_chg_reg *l)
-{
- mi_send(h,"-data-list-register-names ");
- while (l)
- {
- mi_send(h,"%d ",l->reg);
- l=l->next;
- }
- mi_send(h,"\n");
-}
-
-void mi_data_list_changed_registers(mi_h *h)
-{
- mi_send(h,"-data-list-changed-registers\n");
-}
-
-void mi_data_list_register_values(mi_h *h, enum mi_gvar_fmt fmt, mi_chg_reg *l)
-{
- mi_send(h,"-data-list-register-values %c ",mi_format_enum_to_char(fmt));
- while (l)
- {
- mi_send(h,"%d ",l->reg);
- l=l->next;
- }
- mi_send(h,"\n");
-}
-
-/* High level versions. */
-
-/**[txh]********************************************************************
-
- Description:
- Evaluate an expression. Returns a parsed tree.
-
- Command: -data-evaluate-expression
- Return: The resulting value (as plain text) or NULL on error.
-
-***************************************************************************/
-
-char *gmi_data_evaluate_expression(mi_h *h, const char *expression)
-{
- mi_data_evaluate_expression(h,expression);
- return mi_res_value(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Path for sources. You must use it to indicate where are the sources for
-the program to debug. Only the MI v1 implementation is available.
-
- Command: -environment-directory
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_dir(mi_h *h, const char *path)
-{
- mi_dir(h,path);
- return mi_res_simple_done(h);
-}
-
-int gmi_read_memory(mi_h *h, const char *exp, unsigned size,
- unsigned char *dest, int *na, int convAddr,
- unsigned long *addr)
-{
- mi_data_read_memory_hx(h,exp,1,size,convAddr);
- return mi_get_read_memory(h,dest,1,na,addr);
-}
-
-mi_asm_insns *gmi_data_disassemble_se(mi_h *h, const char *start,
- const char *end, int mode)
-{
- mi_data_disassemble_se(h,start,end,mode);
- return mi_get_asm_insns(h);
-}
-
-mi_asm_insns *gmi_data_disassemble_fl(mi_h *h, const char *file, int line,
- int lines, int mode)
-{
- mi_data_disassemble_fl(h,file,line,lines,mode);
- return mi_get_asm_insns(h);
-}
-
-// Affected by gdb bug mi/1770
-mi_chg_reg *gmi_data_list_register_names(mi_h *h, int *how_many)
-{
- mi_data_list_register_names(h);
- return mi_get_list_registers(h,how_many);
-}
-
-int gmi_data_list_register_names_l(mi_h *h, mi_chg_reg *l)
-{
- mi_data_list_register_names_l(h,l);
- return mi_get_list_registers_l(h,l);
-}
-
-mi_chg_reg *gmi_data_list_changed_registers(mi_h *h)
-{
- mi_error=MI_OK;
- mi_data_list_changed_registers(h);
- return mi_get_list_changed_regs(h);
-}
-
-int gmi_data_list_register_values(mi_h *h, enum mi_gvar_fmt fmt, mi_chg_reg *l)
-{
- mi_data_list_register_values(h,fmt,l);
- return mi_get_reg_values(h,l);
-}
-
-mi_chg_reg *gmi_data_list_all_register_values(mi_h *h, enum mi_gvar_fmt fmt, int *how_many)
-{
- mi_data_list_register_values(h,fmt,NULL);
- return mi_get_reg_values_l(h,how_many);
-}
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Error.
- Comment:
- Translates error numbers into messages.
-
-***************************************************************************/
-
-#include "gdbmi.h"
-
-static
-const char *error_strs[]=
-{
- "Ok",
- "Out of memory",
- "Pipe creation",
- "Fork failed",
- "GDB not running",
- "Parser failed",
- "Unknown asyn response",
- "Unknown result response",
- "Error from gdb",
- "Time out in gdb response",
- "GDB suddenly died",
- "Can't execute X terminal",
- "Failed to create temporal",
- "Can't execute the debugger"
-};
-
-const char *mi_get_error_str()
-{
- if (mi_error<0 || mi_error>MI_LAST_ERROR)
- return "Unknown";
- return error_strs[mi_error];
-}
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: pseudo terminal
- Comments:
- Helper to find a free pseudo terminal. Use this if you need to manage
- input *and* output to the target process. If you just need output then
- define a handler for target output stream records (assuming that this
- is working for your particular version of gdb).
- Usage:
-
- mi_pty *pty = gmi_look_for_free_pty();
- if (pty) gmi_target_terminal(mih, pty->slave);
- ...
- * reading from pty->master will get stdout from target *
- * writing to pty->master will send to target stdin *
-
- Note: Contributed by Greg Watson (gwatson lanl gov)
-
-***************************************************************************/
-
-#define _GNU_SOURCE
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#include "gdbmi.h"
-
-/**[txh]********************************************************************
-
- Description:
- Look for a free and usable pseudo terminal. Low level, use
- gmi_look_for_free_pty().
-
- Return: A file descriptor connected to the master pty and the name of the slave device, or <0 on error.
-
-***************************************************************************/
-
-#ifdef __APPLE__
-
-#include <util.h>
-
-int mi_look_for_free_pty(int *master, char **slave)
-{
- int fdmaster;
- int fdslave;
- static char name[BUFSIZ];
-
- if (openpty(&fdmaster,&fdslave,name,NULL,NULL)<0)
- return -1;
-
- (void)close(fdslave); /* this will be reopened by gdb */
- *master=fdmaster;
- *slave =name;
-
- return 0;
-}
-
-#elif defined(__linux__)
-
-int mi_look_for_free_pty(int *master, char **slave)
-{
- if ((*master=open("/dev/ptmx",O_RDWR))<0)
- return -1;
- if (grantpt(*master)<0 || unlockpt(*master)<0)
- return -1;
- *slave = ptsname(*master);
-
- return 0;
-}
-
-#else /* undefined o/s */
-
-int mi_look_for_free_pty(int *master, char **slave)
-{
- return -1;
-}
-#endif
-
-/**[txh]********************************************************************
-
- Description:
- Look for a free and usable pseudo terminal to be used by the child.
-
- Return: A new mi_pty structure, you can use gmi_end_pty to
-release it.
-
-***************************************************************************/
-
-mi_pty *gmi_look_for_free_pty()
-{
- int master;
- char *slave;
- int pty=mi_look_for_free_pty(&master,&slave);
- mi_pty *res;
-
- if (pty<0)
- return NULL;
- res=(mi_pty *)malloc(sizeof(mi_pty));
- if (!res)
- return NULL;
- res->slave=strdup(slave);
- res->master=master;
- return res;
-}
-
-void mi_free_pty(mi_pty *p)
-{
- if (!p)
- return;
- free(p->slave);
- free(p);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Closes the pseudo termial master and releases the allocated memory.
-
-***************************************************************************/
-
-void gmi_end_pty(mi_pty *p)
-{
- if (!p)
- return;
- close(p->master);
- mi_free_pty(p);
-}
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Linux VT.
- Comments:
- Helper to find a free VT. That's 100% Linux specific.@p
- The code comes from "lconsole.c" from Allegro project and was originally
-created by Marek Habersack and then modified by George Foot. I addapted it
-to my needs and changed license from giftware to GPL.@p
-
-***************************************************************************/
-
-#define _GNU_SOURCE
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#ifdef __APPLE__
-#include <util.h>
-#endif /* __APPLE__ */
-
-#include "gdbmi.h"
-
-#if !defined(__linux__)
-
-int mi_look_for_free_vt()
-{
- return -1;
-}
-
-mi_aux_term *gmi_look_for_free_vt()
-{
- return NULL;
-}
-
-#else
-
-#include <linux/vt.h>
-
-/**[txh]********************************************************************
-
- Description:
- Look for a free and usable Linux VT. Low level, use
-@x{gmi_look_for_free_vt}.
-
- Return: The VT number or <0 on error.
-
-***************************************************************************/
-
-int mi_look_for_free_vt()
-{/* Code from Allegro. */
- int tty, console_fd, fd;
- unsigned short mask;
- char tty_name[16];
- struct vt_stat vts;
-
- /* Now we need to find a VT we can use. It must be readable and
- * writable by us, if we're not setuid root. VT_OPENQRY itself
- * isn't too useful because it'll only ever come up with one
- * suggestion, with no guarrantee that we actually have access
- * to it.
- *
- * At some stage I think this is a candidate for config
- * file overriding, but for now we'll stat the first N consoles
- * to see which ones we can write to (hopefully at least one!),
- * so that we can use that one to do ioctls. We used to use
- * /dev/console for that purpose but it looks like it's not
- * always writable by enough people.
- *
- * Having found and opened a writable device, we query the state
- * of the first sixteen (fifteen really) consoles, and try
- * opening each unused one in turn.
- */
-
- console_fd=open("/dev/console",O_WRONLY);
- if (console_fd<0)
- {
- int n;
- /* Try some ttys instead... */
- for (n=1; n<=24; n++)
- {
- snprintf(tty_name,sizeof(tty_name),"/dev/tty%d",n);
- console_fd=open(tty_name,O_WRONLY);
- if (console_fd>=0)
- break;
- }
- if (n>24)
- return -1;
- }
-
- /* Get the state of the console -- in particular, the free VT field */
- if (ioctl(console_fd,VT_GETSTATE,&vts)) {
- close(console_fd);
- return -2;
- }
- close(console_fd);
-
- /* We attempt to set our euid to 0; if we were run with euid 0 to
- * start with, we'll be able to do this now. Otherwise, we'll just
- * ignore the error returned since it might not be a problem if the
- * ttys we look at are owned by the user running the program. */
- seteuid(0);
-
- /* tty0 is not really a console, so start counting at 2. */
- fd=-1;
- for (tty=1, mask=2; mask; tty++, mask<<=1)
- if (!(vts.v_state & mask))
- {
- snprintf(tty_name,sizeof(tty_name),"/dev/tty%d",tty);
- fd=open(tty_name,O_RDWR);
- if (fd!=-1)
- {
- close(fd);
- break;
- }
- }
-
- seteuid(getuid());
-
- if (!mask)
- return -3;
-
- return tty;
-}
-
-/**[txh]********************************************************************
-
- Description:
- Look for a free and usable Linux VT to be used by the child.
-
- Return: A new mi_aux_term structure, you can use @x{gmi_end_aux_term} to
-release it.
-
-***************************************************************************/
-
-mi_aux_term *gmi_look_for_free_vt()
-{
- int ret;
- int vt=mi_look_for_free_vt();
- mi_aux_term *res;
-
- if (vt<0)
- return NULL;
- res=(mi_aux_term *)malloc(sizeof(mi_aux_term));
- if (!res)
- return NULL;
- res->pid=-1;
- ret = asprintf(&res->tty,"/dev/tty%d",vt);
- return res;
-}
-
-#endif
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Miscellaneous commands.
- Comments:
- GDB/MI commands for the "Miscellaneous Commands" section. @<p>
-
-@<pre>
-gdb command: Implemented?
-
--gdb-exit Yes
--gdb-set Yes
--gdb-show Yes
--gdb-version Yes
-@</pre>
-
-GDB Bug workaround for "-gdb-show architecture": gdb 6.1 and olders doesn't
-report it in "value", but they give the output of "show architecture". In
-6.4 we observed that not even a clue is reported. So now we always use
-"show architecture".
-
-***************************************************************************/
-
-#include <string.h>
-#include "gdbmi.h"
-
-/* Low level versions. */
-
-void mi_gdb_exit(mi_h *h)
-{
- mi_send(h,"-gdb-exit\n");
-}
-
-void mi_gdb_version(mi_h *h)
-{
- mi_send(h,"-gdb-version\n");
-}
-
-void mi_gdb_set(mi_h *h, const char *var, const char *val)
-{
- mi_send(h,"-gdb-set %s %s\n",var,val);
-}
-
-void mi_gdb_show(mi_h *h, const char *var)
-{
- if (strcmp(var,"architecture")==0)
- mi_send(h,"show %s\n",var);
- else
- mi_send(h,"-gdb-show %s\n",var);
-}
-
-/* High level versions. */
-
-/**[txh]********************************************************************
-
- Description:
- Exit gdb killing the child is it is running.
-
- Command: -gdb-exit
-
-***************************************************************************/
-
-void gmi_gdb_exit(mi_h *h)
-{
- mi_gdb_exit(h);
- mi_res_simple_exit(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Send the version to the console.
-
- Command: -gdb-version
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_gdb_version(mi_h *h)
-{
- mi_gdb_version(h);
- return mi_res_simple_done(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Set a gdb variable.
-
- Command: -gdb-set
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_gdb_set(mi_h *h, const char *var, const char *val)
-{
- mi_gdb_set(h,var,val);
- return mi_res_simple_done(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Get a gdb variable.
-
- Command: -gdb-show
- Return: The current value of the variable or NULL on error.
-
-***************************************************************************/
-
-char *gmi_gdb_show(mi_h *h, const char *var)
-{
- mi_gdb_show(h,var);
- return mi_res_value(h);
-}
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004-2007 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Parser.
- Comments:
- Parses the output of gdb. It basically converts the text from gdb into a
-tree (could be a complex one) that we can easily interpret using C code.
-
-***************************************************************************/
-
-#include <ctype.h>
-#include <string.h>
-#include <assert.h>
-#include "gdbmi.h"
-
-mi_results *mi_get_result(const char *str, const char **end);
-int mi_get_value(mi_results *r, const char *str, const char **end);
-
-
-/* GDB BUG!!!! I got:
-^error,msg="Problem parsing arguments: data-evaluate-expression ""1+2"""
-Afects gdb 2002-04-01-cvs and 6.1.1 for sure.
-That's an heuristical workaround.
-*/
-static inline
-int EndOfStr(const char *s)
-{
- if (*s=='"')
- {
- s++;
- return !*s || *s==',' || *s==']' || *s=='}';
- }
- return 0;
-}
-
-int mi_get_cstring_r(mi_results *r, const char *str, const char **end)
-{
- const char *s;
- char *d;
- int len;
-
- if (*str!='"')
- {
- mi_error=MI_PARSER;
- return 0;
- }
- str++;
- /* Meassure. */
- for (s=str, len=0; *s && !EndOfStr(s); s++)
- {
- if (!*s) {
- mi_error = MI_PARSER;
- return 0;
- }
- if (*s=='\\')
- s++;
- len++;
- }
- /* Copy. */
- r->type=t_const;
- d=r->v.cstr=mi_malloc(len+1);
- if (!r->v.cstr)
- return 0;
- for (s=str; *s && !EndOfStr(s); s++, d++)
- {
- if (*s=='\\')
- {
- s++;
- switch (*s)
- {
- case 'n':
- *d='\n';
- break;
- case 't':
- *d='\t';
- break;
- default:
- *d=*s;
- }
- }
- else
- *d=*s;
- }
- *d=0;
- if (end)
- *end=s+1;
-
- return 1;
-}
-
-/* TODO: What's a valid variable name?
- I'll assume a-zA-Z0-9_- */
-inline
-int mi_is_var_name_char(char c)
-{
- return isalnum(c) || c=='-' || c=='_';
-}
-
-char *mi_get_var_name(const char *str, const char **end)
-{
- const char *s;
- char *r;
- int l;
- /* Meassure. */
- for (s=str; *s && mi_is_var_name_char(*s); s++);
- if (*s!='=')
- {
- mi_error=MI_PARSER;
- return NULL;
- }
- /* Allocate. */
- l=s-str;
- r=mi_malloc(l+1);
- /* Copy. */
- if (NULL != r) {
- memcpy(r,str,l);
- r[l]=0;
- }
- if (end)
- *end=s+1;
- return r;
-}
-
-
-int mi_get_list_res(mi_results *r, const char *str, const char **end, char closeC)
-{
- mi_results *last_r, *rs;
-
- last_r=NULL;
- do
- {
- rs=mi_get_result(str,&str);
- if (last_r)
- last_r->next=rs;
- else
- r->v.rs=rs;
- last_r=rs;
- if (*str==closeC)
- {
- *end=str+1;
- return 1;
- }
- if (*str!=',')
- break;
- str++;
- }
- while (1);
-
- mi_error=MI_PARSER;
- return 0;
-}
-
-#ifdef __APPLE__
-int mi_get_tuple_val(mi_results *r, const char *str, const char **end)
-{
- mi_results *last_r, *rs;
-
- last_r=NULL;
- do
- {
- rs=mi_alloc_results();
- if (!rs || !mi_get_value(rs,str,&str))
- {
- mi_free_results(rs);
- return 0;
- }
- /* Note that rs->var is NULL, that indicates that's just a value and not
- a result. */
- if (last_r)
- last_r->next=rs;
- else
- r->v.rs=rs;
- last_r=rs;
- if (*str=='}')
- {
- *end=str+1;
- return 1;
- }
- if (*str!=',')
- break;
- str++;
- }
- while (1);
-
- mi_error=MI_PARSER;
- return 0;
-}
-#endif /* __APPLE__ */
-
-int mi_get_tuple(mi_results *r, const char *str, const char **end)
-{
- if (*str!='{')
- {
- mi_error=MI_PARSER;
- return 0;
- }
- r->type=t_tuple;
- str++;
- if (*str=='}')
- {/* Special case: empty tuple */
- *end=str+1;
- return 1;
- }
- #ifdef __APPLE__
- if (mi_is_var_name_char(*str))
- return mi_get_list_res(r,str,end,'}');
- return mi_get_tuple_val(r,str,end);
- #else /* __APPLE__ */
- return mi_get_list_res(r,str,end,'}');
- #endif /* __APPLE__ */
-}
-
-int mi_get_list_val(mi_results *r, const char *str, const char **end)
-{
- mi_results *last_r, *rs;
-
- last_r=NULL;
- do
- {
- rs=mi_alloc_results();
- if (!rs || !mi_get_value(rs,str,&str))
- {
- mi_free_results(rs);
- return 0;
- }
- /* Note that rs->var is NULL, that indicates that's just a value and not
- a result. */
- if (last_r)
- last_r->next=rs;
- else
- r->v.rs=rs;
- last_r=rs;
- if (*str==']')
- {
- *end=str+1;
- return 1;
- }
- if (*str!=',')
- break;
- str++;
- }
- while (1);
-
- mi_error=MI_PARSER;
- return 0;
-}
-
-int mi_get_list(mi_results *r, const char *str, const char **end)
-{
- if (*str!='[')
- {
- mi_error=MI_PARSER;
- return 0;
- }
- r->type=t_list;
- str++;
- if (*str==']')
- {/* Special case: empty list */
- *end=str+1;
- return 1;
- }
- /* Comment: I think they could choose () for values. Is confusing in this way. */
- if (mi_is_var_name_char(*str))
- return mi_get_list_res(r,str,end,']');
- return mi_get_list_val(r,str,end);
-}
-
-int mi_get_value(mi_results *r, const char *str, const char **end)
-{
- switch (str[0])
- {
- case '"':
- return mi_get_cstring_r(r,str,end);
- case '{':
- return mi_get_tuple(r,str,end);
- case '[':
- return mi_get_list(r,str,end);
- }
- mi_error=MI_PARSER;
- return 0;
-}
-
-mi_results *mi_get_result(const char *str, const char **end)
-{
- char *var;
- mi_results *r;
-
- var=mi_get_var_name(str,&str);
- if (!var)
- return NULL;
-
- r=mi_alloc_results();
- if (!r)
- {
- free(var);
- return NULL;
- }
- r->var=var;
-
- if (!mi_get_value(r,str,end))
- {
- mi_free_results(r);
- return NULL;
- }
-
- return r;
-}
-
-mi_output *mi_get_results_alone(mi_output *r,const char *str)
-{
- mi_results *last_r, *rs;
-
- /* * results */
- last_r=NULL;
- do
- {
- if (!*str)
- return r;
- if (*str!=',')
- {
- mi_error=MI_PARSER;
- break;
- }
- str++;
- rs=mi_get_result(str,&str);
- if (!rs)
- break;
- if (!last_r)
- r->c=rs;
- else
- last_r->next=rs;
- last_r=rs;
- }
- while (1);
- mi_free_output(r);
- return NULL;
-}
-
-mi_output *mi_parse_result_record(mi_output *r,const char *str)
-{
- r->type=MI_T_RESULT_RECORD;
-
- /* Solve the result-class. */
- if (strncmp(str,"done",4)==0)
- {
- str+=4;
- r->tclass=MI_CL_DONE;
- }
- else if (strncmp(str,"running",7)==0)
- {
- str+=7;
- r->tclass=MI_CL_RUNNING;
- }
- else if (strncmp(str,"connected",9)==0)
- {
- str+=9;
- r->tclass=MI_CL_CONNECTED;
- }
- else if (strncmp(str,"error",5)==0)
- {
- str+=5;
- r->tclass=MI_CL_ERROR;
- }
- else if (strncmp(str,"exit",4)==0)
- {
- str+=4;
- r->tclass=MI_CL_EXIT;
- }
- else
- {
- mi_error=MI_UNKNOWN_RESULT;
- return NULL;
- }
-
- return mi_get_results_alone(r,str);
-}
-
-mi_output *mi_parse_asyn(mi_output *r,const char *str)
-{
- r->type=MI_T_OUT_OF_BAND;
- r->stype=MI_ST_ASYNC;
- /* async-class. */
- if (strncmp(str,"stopped",7)==0)
- {
- r->tclass=MI_CL_STOPPED;
- str+=7;
- return mi_get_results_alone(r,str);
- }
- if (strncmp(str,"download",8)==0)
- {
- r->tclass=MI_CL_DOWNLOAD;
- str+=8;
- return mi_get_results_alone(r,str);
- }
- mi_error=MI_UNKNOWN_ASYNC;
- mi_free_output(r);
- return NULL;
-}
-
-mi_output *mi_parse_exec_asyn(mi_output *r,const char *str)
-{
- r->sstype=MI_SST_EXEC;
- return mi_parse_asyn(r,str);
-}
-
-mi_output *mi_parse_status_asyn(mi_output *r,const char *str)
-{
- r->sstype=MI_SST_STATUS;
- return mi_parse_asyn(r,str);
-}
-
-mi_output *mi_parse_notify_asyn(mi_output *r,const char *str)
-{
- r->sstype=MI_SST_NOTIFY;
- return mi_parse_asyn(r,str);
-}
-
-mi_output *mi_console(mi_output *r,const char *str)
-{
- r->type=MI_T_OUT_OF_BAND;
- r->stype=MI_ST_STREAM;
- r->c=mi_alloc_results();
- if (!r->c || !mi_get_cstring_r(r->c,str,NULL))
- {
- mi_free_output(r);
- return NULL;
- }
- return r;
-}
-
-mi_output *mi_console_stream(mi_output *r,const char *str)
-{
- r->sstype=MI_SST_CONSOLE;
- return mi_console(r,str);
-}
-
-mi_output *mi_target_stream(mi_output *r,const char *str)
-{
- r->sstype=MI_SST_TARGET;
- return mi_console(r,str);
-}
-
-mi_output *mi_log_stream(mi_output *r,const char *str)
-{
- r->sstype=MI_SST_LOG;
- return mi_console(r,str);
-}
-
-mi_output *mi_parse_gdb_output(const char *str)
-{
- char type=str[0];
-
- mi_output *r=mi_alloc_output();
- if (!r)
- {
- mi_error=MI_OUT_OF_MEMORY;
- return NULL;
- }
- str++;
- switch (type)
- {
- case '^':
- return mi_parse_result_record(r,str);
- case '*':
- return mi_parse_exec_asyn(r,str);
- case '+':
- return mi_parse_status_asyn(r,str);
- case '=':
- return mi_parse_notify_asyn(r,str);
- case '~':
- return mi_console_stream(r,str);
- case '@':
- return mi_target_stream(r,str);
- case '&':
- return mi_log_stream(r,str);
- }
- mi_error=MI_PARSER;
- return NULL;
-}
-
-mi_output *mi_get_rrecord(mi_output *r)
-{
- if (!r)
- return NULL;
- while (r)
- {
- if (r->type==MI_T_RESULT_RECORD)
- return r;
- r=r->next;
- }
- return r;
-}
-
-mi_results *mi_get_var_r(mi_results *r, const char *var)
-{
- while (r)
- {
- if (strcmp(r->var,var)==0)
- return r;
- r=r->next;
- }
- return NULL;
-}
-
-mi_results *mi_get_var(mi_output *res, const char *var)
-{
- if (!res)
- return NULL;
- return mi_get_var_r(res->c,var);
-}
-
-int mi_get_async_stop_reason(mi_output *r, char **reason)
-{
- int found_stopped=0;
-
- *reason=NULL;
- while (r)
- {
- if (r->type==MI_T_RESULT_RECORD && r->tclass==MI_CL_ERROR)
- {
- if (r->c->type==t_const)
- *reason=r->c->v.cstr;
- return 0;
- }
- if (r->type==MI_T_OUT_OF_BAND && r->stype==MI_ST_ASYNC &&
- r->sstype==MI_SST_EXEC && r->tclass==MI_CL_STOPPED)
- {
- mi_results *p=r->c;
- found_stopped=1;
- while (p)
- {
- if (strcmp(p->var,"reason")==0)
- {
- *reason=p->v.cstr;
- return 1;
- }
- p=p->next;
- }
- }
- r=r->next;
- }
- if (*reason==NULL && found_stopped)
- {
- *reason=strdup("unknown (temp bkpt?)");
- return 1;
- }
- return 0;
-}
-
-mi_frames *mi_get_async_frame(mi_output *r)
-{
- while (r)
- {
- if (r->type==MI_T_OUT_OF_BAND && r->stype==MI_ST_ASYNC &&
- r->sstype==MI_SST_EXEC && r->tclass==MI_CL_STOPPED)
- {
- mi_results *p=r->c;
- while (p)
- {
- if (strcmp(p->var,"frame")==0)
- return mi_parse_frame(p->v.rs);
- p=p->next;
- }
- }
- r=r->next;
- }
- return NULL;
-}
-
-int mi_res_simple(mi_h *h, int tclass, int accert_ret)
-{
- mi_output *r, *res;
- int ret=0;
-
- r=mi_get_response_blk(h);
- res=mi_get_rrecord(r);
-
- if (res)
- ret=res->tclass==tclass;
- mi_free_output(r);
-
- return ret;
-}
-
-
-int mi_res_simple_done(mi_h *h)
-{
- return mi_res_simple(h,MI_CL_DONE,0);
-}
-
-int mi_res_simple_exit(mi_h *h)
-{
- return mi_res_simple(h,MI_CL_EXIT,1);
-}
-
-int mi_res_simple_running(mi_h *h)
-{
- return mi_res_simple(h,MI_CL_RUNNING,0);
-}
-
-int mi_res_simple_connected(mi_h *h)
-{
- return mi_res_simple(h,MI_CL_CONNECTED,0);
-}
-
-mi_results *mi_res_var(mi_h *h, const char *var, int tclass)
-{
- mi_output *r, *res;
- mi_results *the_var=NULL;
-
- r=mi_get_response_blk(h);
- /* All the code that follows is "NULL" tolerant. */
- /* Look for the result-record. */
- res=mi_get_rrecord(r);
- /* Look for the desired var. */
- if (res && res->tclass==tclass)
- the_var=mi_get_var(res,var);
- /* Release all but the one we want. */
- mi_free_output_but(r,NULL,the_var);
- return the_var;
-}
-
-mi_results *mi_res_done_var(mi_h *h, const char *var)
-{
- return mi_res_var(h,var,MI_CL_DONE);
-}
-
-mi_frames *mi_parse_frame(mi_results *c)
-{
- mi_frames *res=mi_alloc_frames();
- char *end;
-
- if (res)
- {
- while (c)
- {
- if (c->type==t_const)
- {
- if (strcmp(c->var,"level")==0)
- res->level=atoi(c->v.cstr);
- else if (strcmp(c->var,"addr")==0)
- res->addr=(void *)strtoul(c->v.cstr,&end,0);
- else if (strcmp(c->var,"func")==0)
- {
- res->func=c->v.cstr;
- c->v.cstr=NULL;
- }
- else if (strcmp(c->var,"file")==0)
- {
- res->file=c->v.cstr;
- c->v.cstr=NULL;
- }
- else if (strcmp(c->var,"from")==0)
- {
- res->from=c->v.cstr;
- c->v.cstr=NULL;
- }
- else if (strcmp(c->var,"line")==0)
- res->line=atoi(c->v.cstr);
- }
- else if (c->type==t_list && strcmp(c->var,"args")==0)
- {
- res->args=c->v.rs;
- c->v.rs=NULL;
- }
- c=c->next;
- }
- }
- return res;
-}
-
-mi_frames *mi_res_frame(mi_h *h)
-{
- mi_results *r=mi_res_done_var(h,"frame");
- mi_frames *f=NULL;
-
- if (r && r->type==t_tuple)
- f=mi_parse_frame(r->v.rs);
- mi_free_results(r);
- return f;
-}
-
-mi_frames *mi_res_frames_array(mi_h *h, const char *var)
-{
- mi_results *r=mi_res_done_var(h,var), *c;
- mi_frames *res=NULL, *nframe, *last=NULL;
-
- if (!r)
- return NULL;
-#ifdef __APPLE__
- if (r->type!=t_list && r->type!=t_tuple)
-#else
- if (r->type!=t_list)
-#endif
- {
- mi_free_results(r);
- return NULL;
- }
- c=r->v.rs;
- while (c)
- {
- if (strcmp(c->var,"frame")==0 && c->type==t_tuple)
- {
- nframe=mi_parse_frame(c->v.rs);
- if (nframe)
- {
- if (!last)
- res=nframe;
- else
- last->next=nframe;
- last=nframe;
- }
- }
- c=c->next;
- }
- mi_free_results(r);
- return res;
-}
-
-mi_frames *mi_res_frames_list(mi_h *h)
-{
- mi_output *r, *res;
- mi_frames *ret=NULL, *nframe, *last=NULL;
- mi_results *c;
-
- r=mi_get_response_blk(h);
- res=mi_get_rrecord(r);
- if (res && res->tclass==MI_CL_DONE)
- {
- c=res->c;
- while (c)
- {
- if (strcmp(c->var,"frame")==0 && c->type==t_tuple)
- {
- nframe=mi_parse_frame(c->v.rs);
- if (nframe)
- {
- if (!last)
- ret=nframe;
- else
- last->next=nframe;
- last=nframe;
- }
- }
- c=c->next;
- }
- }
- mi_free_output(r);
- return ret;
-}
-
-int mi_get_thread_ids(mi_output *res, int **list)
-{
- mi_results *vids, *lids;
- int ids=-1, i;
-
- *list=NULL;
- vids=mi_get_var(res,"number-of-threads");
- lids=mi_get_var(res,"thread-ids");
- if (vids && vids->type==t_const &&
- lids && lids->type==t_tuple)
- {
- ids=atoi(vids->v.cstr);
- if (ids)
- {
- int *lst;
- lst=(int *)mi_calloc(ids,sizeof(int));
- if (lst)
- {
- lids=lids->v.rs;
- i=0;
- while (lids)
- {
- if (strcmp(lids->var,"thread-id")==0 && lids->type==t_const)
- lst[i++]=atoi(lids->v.cstr);
- lids=lids->next;
- }
- *list=lst;
- }
- else
- ids=-1;
- }
- }
- return ids;
-}
-
-int mi_res_thread_ids(mi_h *h, int **list)
-{
- mi_output *r, *res;
- int ids=-1;
-
- r=mi_get_response_blk(h);
- res=mi_get_rrecord(r);
- if (res && res->tclass==MI_CL_DONE)
- ids=mi_get_thread_ids(res,list);
- mi_free_output(r);
- return ids;
-}
-
-enum mi_gvar_lang mi_lang_str_to_enum(const char *lang)
-{
- enum mi_gvar_lang lg=lg_unknown;
-
- if (strcmp(lang,"C")==0)
- lg=lg_c;
- else if (strcmp(lang,"C++")==0)
- lg=lg_cpp;
- else if (strcmp(lang,"Java")==0)
- lg=lg_java;
-
- return lg;
-}
-
-const char *mi_lang_enum_to_str(enum mi_gvar_lang lang)
-{
- const char *lg;
-
- switch (lang)
- {
- case lg_c:
- lg="C";
- break;
- case lg_cpp:
- lg="C++";
- break;
- case lg_java:
- lg="Java";
- break;
- /*case lg_unknown:*/
- default:
- lg="unknown";
- break;
- }
- return lg;
-}
-
-enum mi_gvar_fmt mi_format_str_to_enum(const char *format)
-{
- enum mi_gvar_fmt fmt=fm_natural;
-
- if (strcmp(format,"binary")==0)
- fmt=fm_binary;
- else if (strcmp(format,"decimal")==0)
- fmt=fm_decimal;
- else if (strcmp(format,"hexadecimal")==0)
- fmt=fm_hexadecimal;
- else if (strcmp(format,"octal")==0)
- fmt=fm_octal;
-
- return fmt;
-}
-
-const char *mi_format_enum_to_str(enum mi_gvar_fmt format)
-{
- const char *fmt;
-
- switch (format)
- {
- case fm_natural:
- fmt="natural";
- break;
- case fm_binary:
- fmt="binary";
- break;
- case fm_decimal:
- fmt="decimal";
- break;
- case fm_hexadecimal:
- fmt="hexadecimal";
- break;
- case fm_octal:
- fmt="octal";
- break;
- case fm_raw:
- fmt="raw";
- break;
- default:
- fmt="unknown";
- }
- return fmt;
-}
-
-char mi_format_enum_to_char(enum mi_gvar_fmt format)
-{
- char fmt;
-
- switch (format)
- {
- case fm_natural:
- fmt='N';
- break;
- case fm_binary:
- fmt='t';
- break;
- case fm_decimal:
- fmt='d';
- break;
- case fm_hexadecimal:
- fmt='x';
- break;
- case fm_octal:
- fmt='o';
- break;
- case fm_raw:
- fmt='r';
- break;
- default:
- fmt=' ';
- }
- return fmt;
-}
-
-mi_gvar *mi_get_gvar(mi_output *o, mi_gvar *cur, const char *expression)
-{
- mi_results *r;
- mi_gvar *res=cur ? cur : mi_alloc_gvar();
- int l;
-
- if (!res)
- return res;
- r=o->c;
- if (expression)
- res->exp=strdup(expression);
- while (r)
- {
- if (r->type==t_const)
- {
- if (strcmp(r->var,"name")==0)
- {
- free(res->name);
- res->name=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if (strcmp(r->var,"numchild")==0)
- {
- res->numchild=atoi(r->v.cstr);
- }
- else if (strcmp(r->var,"type")==0)
- {
- free(res->type);
- res->type=r->v.cstr;
- r->v.cstr=NULL;
- l=strlen(res->type);
- if (l && res->type[l-1]=='*')
- res->ispointer=1;
- }
- else if (strcmp(r->var,"lang")==0)
- {
- res->lang=mi_lang_str_to_enum(r->v.cstr);
- }
- else if (strcmp(r->var,"exp")==0)
- {
- free(res->exp);
- res->exp=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if (strcmp(r->var,"format")==0)
- {
- res->format=mi_format_str_to_enum(r->v.cstr);
- }
- else if (strcmp(r->var,"attr")==0)
- { /* Note: gdb 6.1.1 have only this: */
- if (strcmp(r->v.cstr,"editable")==0)
- res->attr=MI_ATTR_EDITABLE;
- else /* noneditable */
- res->attr=MI_ATTR_NONEDITABLE;
- }
- }
- r=r->next;
- }
- return res;
-}
-
-mi_gvar *mi_res_gvar(mi_h *h, mi_gvar *cur, const char *expression)
-{
- mi_output *r, *res;
- mi_gvar *gvar=NULL;
-
- r=mi_get_response_blk(h);
- res=mi_get_rrecord(r);
- if (res && res->tclass==MI_CL_DONE)
- gvar=mi_get_gvar(res,cur,expression);
- mi_free_output(r);
- return gvar;
-}
-
-mi_gvar_chg *mi_get_gvar_chg(mi_results *r)
-{
- mi_gvar_chg *n;
-
- if (r->type!=t_const)
- return NULL;
- n=mi_alloc_gvar_chg();
- if (n)
- {
- while (r)
- {
- if (r->type==t_const)
- {
- if (strcmp(r->var,"name")==0)
- {
- n->name=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if (strcmp(r->var,"in_scope")==0)
- {
- n->in_scope=strcmp(r->v.cstr,"true")==0;
- }
- else if (strcmp(r->var,"new_type")==0)
- {
- n->new_type=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if (strcmp(r->var,"new_num_children")==0)
- {
- n->new_num_children=atoi(r->v.cstr);
- }
- // type_changed="false" is the default
- }
- r=r->next;
- }
- }
- return n;
-}
-
-int mi_res_changelist(mi_h *h, mi_gvar_chg **changed)
-{
- mi_gvar_chg *last, *n;
- mi_results *res=mi_res_done_var(h,"changelist"), *r;
- int count=0;
-
- *changed=NULL;
- if (!res)
- return 0;
- last=NULL;
- count=1;
- n=NULL;
- r=res->v.rs;
-
- if (res->type==t_list)
- {// MI v2 a list of tuples
- while (r)
- {
- if (r->type==t_tuple)
- {
- n=mi_get_gvar_chg(r->v.rs);
- if (n)
- {
- if (last)
- last->next=n;
- else
- *changed=n;
- last=n;
- count++;
- }
- }
- r=r->next;
- }
- }
- else if (res->type==t_tuple)
- {// MI v1 a tuple with all together *8-P
- while (r)
- {
- if (r->type==t_const) /* Just in case. */
- {/* Get one var. */
- if (strcmp(r->var,"name")==0)
- {
- if (n)
- {/* Add to the list*/
- if (last)
- last->next=n;
- else
- *changed=n;
- last=n;
- count++;
- }
- n=mi_alloc_gvar_chg();
- if (!n)
- {
- mi_free_gvar_chg(*changed);
- return 0;
- }
- n->name=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if ((NULL != n) && (strcmp(r->var,"in_scope")==0))
- {
- n->in_scope=strcmp(r->v.cstr,"true")==0;
- }
- else if ((NULL != n) && (strcmp(r->var,"new_type")==0))
- {
- n->new_type=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if ((NULL != n) && (strcmp(r->var,"new_num_children")==0))
- {
- n->new_num_children=atoi(r->v.cstr);
- }
- // type_changed="false" is the default
- }
- r=r->next;
- }
- if (n)
- {/* Add to the list*/
- if (last)
- last->next=n;
- else
- *changed=n;
- last=n;
- count++;
- }
- }
- mi_free_results(res);
-
- return count;
-}
-
-int mi_get_children(mi_results *ch, mi_gvar *v)
-{
- mi_gvar *cur=NULL, *aux;
- int i=0, count=v->numchild, l;
-
- while (ch)
- {
- if (strcmp(ch->var,"child")==0 && ch->type==t_tuple && i<count)
- {
- mi_results *r=ch->v.rs;
- aux=mi_alloc_gvar();
- if (!aux)
- return 0;
- if (!v->child)
- v->child=aux;
- else if (NULL != cur)
- cur->next=aux;
- cur=aux;
- cur->parent=v;
- cur->depth=v->depth+1;
-
- while (r)
- {
- if (r->type==t_const)
- {
- if (strcmp(r->var,"name")==0)
- {
- cur->name=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if (strcmp(r->var,"exp")==0)
- {
- cur->exp=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if (strcmp(r->var,"type")==0)
- {
- cur->type=r->v.cstr;
- r->v.cstr=NULL;
- l=strlen(cur->type);
- if (l && cur->type[l-1]=='*')
- cur->ispointer=1;
- }
- else if (strcmp(r->var,"value")==0)
- {
- cur->value=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if (strcmp(r->var,"numchild")==0)
- {
- cur->numchild=atoi(r->v.cstr);
- }
- }
- r=r->next;
- }
- i++;
- }
- ch=ch->next;
- }
- v->vischild=i;
- v->opened=1;
- return i==v->numchild;
-}
-
-int mi_res_children(mi_h *h, mi_gvar *v)
-{
- mi_output *r, *res;
- int ok=0;
-
- r=mi_get_response_blk(h);
- res=mi_get_rrecord(r);
- if (res && res->tclass==MI_CL_DONE)
- {
- mi_results *num=mi_get_var(res,"numchild");
- if (num && num->type==t_const)
- {
- v->numchild=atoi(num->v.cstr);
- if (v->child)
- {
- mi_free_gvar(v->child);
- v->child=NULL;
- }
- if (v->numchild)
- {
- mi_results *ch =mi_get_var(res,"children");
- if (ch && ch->type!=t_const) /* MI v1 tuple, MI v2 list */
- ok=mi_get_children(ch->v.rs,v);
- }
- else
- ok=1;
- }
- }
- mi_free_output(r);
- return ok;
-}
-
-mi_bkpt *mi_get_bkpt(mi_results *p)
-{
- mi_bkpt *res;
- char *end;
-
- res=mi_alloc_bkpt();
- if (!res)
- return NULL;
- while (p)
- {
- if (p->type==t_const && p->var)
- {
- if (strcmp(p->var,"number")==0)
- res->number=atoi(p->v.cstr);
- else if (strcmp(p->var,"type")==0)
- {
- if (strcmp(p->v.cstr,"breakpoint")==0)
- res->type=t_breakpoint;
- else
- res->type=t_unknown;
- }
- else if (strcmp(p->var,"disp")==0)
- {
- if (strcmp(p->v.cstr,"keep")==0)
- res->disp=d_keep;
- else if (strcmp(p->v.cstr,"del")==0)
- res->disp=d_del;
- else
- res->disp=d_unknown;
- }
- else if (strcmp(p->var,"enabled")==0)
- res->enabled=p->v.cstr[0]=='y';
- else if (strcmp(p->var,"addr")==0)
- res->addr=(void *)strtoul(p->v.cstr,&end,0);
- else if (strcmp(p->var,"func")==0)
- {
- res->func=p->v.cstr;
- p->v.cstr=NULL;
- }
- else if (strcmp(p->var,"file")==0)
- {
- res->file=p->v.cstr;
- p->v.cstr=NULL;
- }
- else if (strcmp(p->var,"line")==0)
- res->line=atoi(p->v.cstr);
- else if (strcmp(p->var,"times")==0)
- res->times=atoi(p->v.cstr);
- else if (strcmp(p->var,"ignore")==0)
- res->ignore=atoi(p->v.cstr);
- else if (strcmp(p->var,"cond")==0)
- {
- res->cond=p->v.cstr;
- p->v.cstr=NULL;
- }
- }
- p=p->next;
- }
- return res;
-}
-
-mi_bkpt *mi_res_bkpt(mi_h *h)
-{
- mi_results *r=mi_res_done_var(h,"bkpt");
- mi_bkpt *b=NULL;
-
- if (r && r->type==t_tuple)
- b=mi_get_bkpt(r->v.rs);
- mi_free_results(r);
- return b;
-}
-
-mi_wp *mi_get_wp(mi_results *p, enum mi_wp_mode m)
-{
- mi_wp *res=mi_alloc_wp();
-
- if (res)
- {
- res->mode=m;
- while (p)
- {
- if (p->type==t_const && p->var)
- {
- if (strcmp(p->var,"number")==0)
- {
- res->number=atoi(p->v.cstr);
- res->enabled=1;
- }
- else if (strcmp(p->var,"exp")==0)
- {
- res->exp=p->v.cstr;
- p->v.cstr=NULL;
- }
- }
- p=p->next;
- }
- }
- return res;
-}
-
-mi_wp *mi_parse_wp_res(mi_output *r)
-{
- mi_results *p;
- enum mi_wp_mode m=wm_unknown;
-
- /* The info is in a result wpt=... */
- p=r->c;
- while (p)
- {
- if (p->var)
- {
- if (strcmp(p->var,"wpt")==0)
- m=wm_write;
- else if (strcmp(p->var,"hw-rwpt")==0)
- m=wm_read;
- else if (strcmp(p->var,"hw-awpt")==0)
- m=wm_rw;
- if (m!=wm_unknown)
- break;
- }
- p=p->next;
- }
- if (!p || p->type!=t_tuple)
- return NULL;
- /* Scan the values inside it. */
- return mi_get_wp(p->v.rs,m);
-}
-
-mi_wp *mi_res_wp(mi_h *h)
-{
- mi_output *r, *res;
- mi_wp *ret=NULL;
-
- r=mi_get_response_blk(h);
- res=mi_get_rrecord(r);
-
- if (res)
- ret=mi_parse_wp_res(res);
-
- mi_free_output(r);
- return ret;
-}
-
-char *mi_res_value(mi_h *h)
-{
- mi_results *r=mi_res_done_var(h,"value");
- char *s=NULL;
-
- if (r && r->type==t_const)
- {
- s=r->v.cstr;
- r->v.rs=NULL;
- }
- mi_free_results(r);
- return s;
-}
-
-mi_output *mi_get_stop_record(mi_output *r)
-{
- while (r)
- {
- if (r->type==MI_T_OUT_OF_BAND && r->stype==MI_ST_ASYNC &&
- r->sstype==MI_SST_EXEC && r->tclass==MI_CL_STOPPED)
- return r;
- r=r->next;
- }
- return r;
-}
-
-static
-char *reason_names[]=
-{
- "breakpoint-hit",
- "watchpoint-trigger",
- "read-watchpoint-trigger",
- "access-watchpoint-trigger",
- "watchpoint-scope",
- "function-finished",
- "location-reached",
- "end-stepping-range",
- "exited-signalled",
- "exited",
- "exited-normally",
- "signal-received"
-};
-
-static
-enum mi_stop_reason reason_values[]=
-{
- sr_bkpt_hit,
- sr_wp_trigger, sr_read_wp_trigger, sr_access_wp_trigger, sr_wp_scope,
- sr_function_finished, sr_location_reached, sr_end_stepping_range,
- sr_exited_signalled, sr_exited, sr_exited_normally,
- sr_signal_received
-};
-
-static
-char *reason_expl[]=
-{
- "Hit a breakpoint",
- "Write watchpoint",
- "Read watchpoint",
- "Access watchpoint",
- "Watchpoint out of scope",
- "Function finished",
- "Location reached",
- "End of stepping",
- "Exited signalled",
- "Exited with error",
- "Exited normally",
- "Signal received"
-};
-
-enum mi_stop_reason mi_reason_str_to_enum(const char *s)
-{
- int i;
-
- for (i=0; i<sizeof(reason_names)/sizeof(char *); i++)
- if (strcmp(reason_names[i],s)==0)
- return reason_values[i];
- return sr_unknown;
-}
-
-const char *mi_reason_enum_to_str(enum mi_stop_reason r)
-{
- int i;
-
- if (r==sr_unknown)
- return "Unknown (temp bkp?)";
- for (i=0; i<sizeof(reason_values)/sizeof(char *); i++)
- if (reason_values[i]==r)
- return reason_expl[i];
- return NULL;
-}
-
-mi_stop *mi_get_stopped(mi_results *r)
-{
- mi_stop *res=mi_alloc_stop();
-
- if (res)
- {
- while (r)
- {
- if (r->type==t_const)
- {
- if (strcmp(r->var,"reason")==0)
- res->reason=mi_reason_str_to_enum(r->v.cstr);
- else if (!res->have_thread_id && strcmp(r->var,"thread-id")==0)
- {
- res->have_thread_id=1;
- res->thread_id=atoi(r->v.cstr);
- }
- else if (!res->have_bkptno && strcmp(r->var,"bkptno")==0)
- {
- res->have_bkptno=1;
- res->bkptno=atoi(r->v.cstr);
- }
- else if (!res->have_bkptno && strcmp(r->var,"wpnum")==0)
- {
- res->have_wpno=1;
- res->wpno=atoi(r->v.cstr);
- }
- else if (strcmp(r->var,"gdb-result-var")==0)
- {
- res->gdb_result_var=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if (strcmp(r->var,"return-value")==0)
- {
- res->return_value=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if (strcmp(r->var,"signal-name")==0)
- {
- res->signal_name=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if (strcmp(r->var,"signal-meaning")==0)
- {
- res->signal_meaning=r->v.cstr;
- r->v.cstr=NULL;
- }
- else if (!res->have_exit_code && strcmp(r->var,"exit-code")==0)
- {
- res->have_exit_code=1;
- res->exit_code=atoi(r->v.cstr);
- }
- }
- else // tuple or list
- {
- if (strcmp(r->var,"frame")==0)
- res->frame=mi_parse_frame(r->v.rs);
- else if (!res->wp && strcmp(r->var,"wpt")==0)
- res->wp=mi_get_wp(r->v.rs,wm_write);
- else if (!res->wp && strcmp(r->var,"hw-rwpt")==0)
- res->wp=mi_get_wp(r->v.rs,wm_read);
- else if (!res->wp && strcmp(r->var,"hw-awpt")==0)
- res->wp=mi_get_wp(r->v.rs,wm_rw);
- else if (!(res->wp_old || res->wp_val) && strcmp(r->var,"value")==0)
- {
- mi_results *p=r->v.rs;
- while (p)
- {
- if (strcmp(p->var,"value")==0 || strcmp(p->var,"new")==0)
- {
- res->wp_val=p->v.cstr;
- p->v.cstr=NULL;
- }
- else if (strcmp(p->var,"old")==0)
- {
- res->wp_old=p->v.cstr;
- p->v.cstr=NULL;
- }
- p=p->next;
- }
- }
- }
- r=r->next;
- }
- }
- return res;
-}
-
-mi_stop *mi_res_stop(mi_h *h)
-{
- mi_output *o=mi_retire_response(h);
- mi_stop *stop=NULL;
-
- if (o)
- {
- mi_output *sr=mi_get_stop_record(o);
- if (sr)
- stop=mi_get_stopped(sr->c);
- }
- mi_free_output(o);
-
- return stop;
-}
-
-int mi_get_read_memory(mi_h *h, unsigned char *dest, unsigned ws, int *na,
- unsigned long *addr)
-{
- char *end;
- mi_results *res=mi_res_done_var(h,"memory"), *r;
- int ok=0;
-
- *na=0;
- r=res;
- if (r && r->type==t_list && ws==1)
- {
- r=r->v.rs;
- if (r->type!=t_tuple)
- {
- mi_free_results(res);
- return 0;
- }
- r=r->v.rs;
- while (r)
- {
- if (r->type==t_list && strcmp(r->var,"data")==0)
- {
- mi_results *data=r->v.rs;
- ok++;
- if (data && data->type==t_const &&
- strcmp(data->v.cstr,"N/A")==0)
- *na=1;
- else
- while (data)
- {
- if (data->type==t_const)
- *(dest++)=strtol(data->v.cstr,&end,0);
- data=data->next;
- }
- }
- else if (r->type==t_const && strcmp(r->var,"addr")==0)
- {
- ok++;
- if (addr)
- *addr=strtoul(r->v.cstr,&end,0);
- }
- r=r->next;
- }
-
- }
- mi_free_results(res);
- return ok==2;
-}
-
-mi_asm_insn *mi_parse_insn(mi_results *c)
-{
- mi_asm_insn *res=NULL, *cur=NULL;
- mi_results *sub;
- char *end;
-
- while (c)
- {
- if (c->type==t_tuple)
- {
- if (!res)
- res=cur=mi_alloc_asm_insn();
- else
- {
- cur->next=mi_alloc_asm_insn();
- cur=cur->next;
- }
- if (!cur)
- {
- mi_free_asm_insn(res);
- return NULL;
- }
- sub=c->v.rs;
- while (sub)
- {
- if (sub->type==t_const)
- {
- if (strcmp(sub->var,"address")==0)
- cur->addr=(void *)strtoul(sub->v.cstr,&end,0);
- else if (strcmp(sub->var,"func-name")==0)
- {
- cur->func=sub->v.cstr;
- sub->v.cstr=NULL;
- }
- else if (strcmp(sub->var,"offset")==0)
- cur->offset=atoi(sub->v.cstr);
- else if (strcmp(sub->var,"inst")==0)
- {
- cur->inst=sub->v.cstr;
- sub->v.cstr=NULL;
- }
- }
- sub=sub->next;
- }
- }
- c=c->next;
- }
- return res;
-}
-
-mi_asm_insns *mi_parse_insns(mi_results *c)
-{
- mi_asm_insns *res=NULL, *cur=NULL;
- mi_results *sub;
-
- while (c)
- {
- if (c->var)
- {
- if (strcmp(c->var,"src_and_asm_line")==0 && c->type==t_tuple)
- {
- if (!res)
- res=cur=mi_alloc_asm_insns();
- else
- {
- cur->next=mi_alloc_asm_insns();
- cur=cur->next;
- }
- if (!cur)
- {
- mi_free_asm_insns(res);
- return NULL;
- }
- sub=c->v.rs;
- while (sub)
- {
- if (sub->var)
- {
- if (sub->type==t_const)
- {
- if (strcmp(sub->var,"line")==0)
- cur->line=atoi(sub->v.cstr);
- else if (strcmp(sub->var,"file")==0)
- {
- cur->file=sub->v.cstr;
- sub->v.cstr=NULL;
- }
- }
- else if (sub->type==t_list)
- {
- if (strcmp(sub->var,"line_asm_insn")==0)
- cur->ins=mi_parse_insn(sub->v.rs);
- }
- }
- sub=sub->next;
- }
- }
- }
- else
- {/* No source line, just instructions */
- res=mi_alloc_asm_insns();
- res->ins=mi_parse_insn(c);
- break;
- }
- c=c->next;
- }
- return res;
-}
-
-
-mi_asm_insns *mi_get_asm_insns(mi_h *h)
-{
- mi_results *r=mi_res_done_var(h,"asm_insns");
- mi_asm_insns *f=NULL;
-
- if (r && r->type==t_list)
- f=mi_parse_insns(r->v.rs);
- mi_free_results(r);
- return f;
-}
-
-mi_chg_reg *mi_parse_list_regs(mi_results *r, int *how_many)
-{
- mi_results *c=r;
- int cregs=0;
- mi_chg_reg *first=NULL, *cur=NULL;
-
- /* Create the list. */
- while (c)
- {
- if (c->type==t_const && !c->var)
- {
- if (first)
- cur=cur->next=mi_alloc_chg_reg();
- else
- first=cur=mi_alloc_chg_reg();
-
- if (NULL != cur) {
- cur->name=c->v.cstr;
- cur->reg=cregs++;
- c->v.cstr=NULL;
- }
- }
- c=c->next;
- }
- if (how_many)
- *how_many=cregs;
-
- return first;
-}
-
-mi_chg_reg *mi_get_list_registers(mi_h *h, int *how_many)
-{
- mi_results *r=mi_res_done_var(h,"register-names");
- mi_chg_reg *l=NULL;
-
- if (r && r->type==t_list)
- l=mi_parse_list_regs(r->v.rs,how_many);
- mi_free_results(r);
- return l;
-}
-
-mi_chg_reg *mi_parse_list_changed_regs(mi_results *r)
-{
- mi_results *c=r;
- mi_chg_reg *first=NULL, *cur=NULL;
-
- /* Create the list. */
- while (c)
- {
- if (c->type==t_const && !c->var)
- {
- if (first)
- cur=cur->next=mi_alloc_chg_reg();
- else
- first=cur=mi_alloc_chg_reg();
- cur->reg=atoi(c->v.cstr);
- }
- c=c->next;
- }
-
- return first;
-}
-
-mi_chg_reg *mi_get_list_changed_regs(mi_h *h)
-{
- mi_results *r=mi_res_done_var(h,"changed-registers");
- mi_chg_reg *changed=NULL;
-
- if (r && r->type==t_list)
- changed=mi_parse_list_changed_regs(r->v.rs);
- mi_free_results(r);
- return changed;
-}
-
-int mi_parse_reg_values(mi_results *r, mi_chg_reg *l)
-{
- mi_results *c;
-
- while (r && l)
- {
- if (r->type==t_tuple && !r->var)
- {
- c=r->v.rs;
- while (c)
- {
- if (c->type==t_const && c->var)
- {
- if (strcmp(c->var,"number")==0)
- {
- if (atoi(c->v.cstr)!=l->reg)
- {
- mi_error=MI_PARSER;
- return 0;
- }
- }
- else if (strcmp(c->var,"value")==0)
- {
- l->val=c->v.cstr;
- c->v.cstr=NULL;
- }
- }
- c=c->next;
- }
- }
- r=r->next;
- l=l->next;
- }
-
- return !l && !r;
-}
-
-int mi_get_reg_values(mi_h *h, mi_chg_reg *l)
-{
- mi_results *r=mi_res_done_var(h,"register-values");
- int ok=0;
-
- if (r && r->type==t_list)
- ok=mi_parse_reg_values(r->v.rs,l);
- mi_free_results(r);
- return ok;
-}
-
-int mi_parse_list_regs_l(mi_results *r, mi_chg_reg *l)
-{
- while (r && l)
- {
- if (r->type==t_const && !r->var)
- {
- free(l->name);
- l->name=r->v.cstr;
- r->v.cstr=NULL;
- l=l->next;
- }
- r=r->next;
- }
-
- return !l && !r;
-}
-
-int mi_get_list_registers_l(mi_h *h, mi_chg_reg *l)
-{
- mi_results *r=mi_res_done_var(h,"register-names");
- int ok=0;
-
- if (r && r->type==t_list)
- ok=mi_parse_list_regs_l(r->v.rs,l);
- mi_free_results(r);
- return ok;
-}
-
-mi_chg_reg *mi_parse_reg_values_l(mi_results *r, int *how_many)
-{
- mi_results *c;
- mi_chg_reg *first=NULL, *cur=NULL;
- *how_many=0;
-
- while (r)
- {
- if (r->type==t_tuple && !r->var)
- {
- c=r->v.rs;
- if (first)
- cur=cur->next=mi_alloc_chg_reg();
- else
- first=cur=mi_alloc_chg_reg();
- while (c)
- {
- if (c->type==t_const && c->var)
- {
- if (strcmp(c->var,"number")==0)
- {
- if (NULL != cur)
- cur->reg=atoi(c->v.cstr);
- (*how_many)++;
- }
- else if (strcmp(c->var,"value")==0)
- {
- if (NULL != cur)
- cur->val=c->v.cstr;
- c->v.cstr=NULL;
- }
- }
- c=c->next;
- }
- }
- r=r->next;
- }
-
- return first;
-}
-
-mi_chg_reg *mi_get_reg_values_l(mi_h *h, int *how_many)
-{
- mi_results *r=mi_res_done_var(h,"register-values");
- mi_chg_reg *rgs=NULL;
-
- if (r && r->type==t_list)
- rgs=mi_parse_reg_values_l(r->v.rs,how_many);
- mi_free_results(r);
- return rgs;
-}
-
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Program control.
- Comments:
- GDB/MI commands for the "Program Control" section. @<p>
-
-@<pre>
-gdb command: Implemented?
-
--exec-abort N.A. (*) (kill, but with non-interactive options)
--exec-arguments Yes
--exec-continue Yes ASYNC
--exec-finish Yes ASYNC
--exec-interrupt Yes ASYNC
--exec-next Yes ASYNC
--exec-next-instruction Yes ASYNC
--exec-return Yes
--exec-run Yes ASYNC
--exec-show-arguments N.A. (show args) see gmi_stack_info_frame
--exec-step Yes ASYNC
--exec-step-instruction Yes ASYNC
--exec-until Yes ASYNC
--file-exec-and-symbols Yes
--file-exec-file No
--file-list-exec-sections N.A. (info file)
--file-list-exec-source-files N.A.
--file-list-shared-libraries N.A.
--file-list-symbol-files N.A.
--file-symbol-file Yes
-@</pre>
-
-(*) gmi_exec_kill implements it, but you should ensure that
-gmi_gdb_set("confirm","off") was called. @<p>
-
-GDB Bug workaround for -file-exec-and-symbols and -file-symbol-file: This
-is complex, but a real bug. When you set a breakpoint you never know the
-name of the file as it appears in the debug info. So you can be specifying
-an absolute file name or a relative file name. The reference point could be
-different than the one used in the debug info. To solve all the combinations
-gdb does a search trying various combinations. GDB isn't very smart so you
-must at least specify the working directory and the directory where the
-binary is located to get a good chance (+ user options to solve the rest).
-Once you did it gdb can find the file by doing transformations to the
-"canonical" filename. This search works OK for already loaded symtabs
-(symbol tables), but it have a bug when the search is done for psymtabs
-(partial symtabs). The bug is in the use of source_full_path_of (source.c).
-This function calls openp indicating try_cwd_first. It makes the search file
-if the psymtab file name have at least one dirseparator. It means that
-psymtabs for files compiled with relative paths will fail. The search for
-symtabs uses symtab_to_filename, it calls open_source_file which finally
-calls openp without try_cwd_first.@*
-To workaround this bug we must ensure gdb loads *all* the symtabs to memory.
-And here comes another problem -file-exec-and-symbols doesn't support it
-according to docs. In real life that's a wrapper for "file", but as nobody
-can say it won't change we must use the CLI command.
-
-***************************************************************************/
-
-#include <signal.h>
-#include "gdbmi.h"
-
-/* Low level versions. */
-
-void mi_file_exec_and_symbols(mi_h *h, const char *file)
-{
- if (mi_get_workaround(MI_PSYM_SEARCH))
- mi_send(h,"file %s -readnow\n",file);
- else
- mi_send(h,"-file-exec-and-symbols %s\n",file);
-}
-
-void mi_exec_arguments(mi_h *h, const char *args)
-{
- mi_send(h,"-exec-arguments %s\n",args);
-}
-
-void mi_exec_run(mi_h *h)
-{
- mi_send(h,"-exec-run\n");
-}
-
-void mi_exec_continue(mi_h *h)
-{
- mi_send(h,"-exec-continue\n");
-}
-
-void mi_target_terminal(mi_h *h, const char *tty_name)
-{
- mi_send(h,"tty %s\n",tty_name);
-}
-
-void mi_file_symbol_file(mi_h *h, const char *file)
-{
- if (mi_get_workaround(MI_PSYM_SEARCH))
- mi_send(h,"symbol-file %s -readnow\n",file);
- else
- mi_send(h,"-file-symbol-file %s\n",file);
-}
-
-void mi_exec_finish(mi_h *h)
-{
- mi_send(h,"-exec-finish\n");
-}
-
-void mi_exec_interrupt(mi_h *h)
-{
- mi_send(h,"-exec-interrupt\n");
-}
-
-void mi_exec_next(mi_h *h, int count)
-{
- if (count>1)
- mi_send(h,"-exec-next %d\n",count);
- else
- mi_send(h,"-exec-next\n");
-}
-
-void mi_exec_next_instruction(mi_h *h)
-{
- mi_send(h,"-exec-next-instruction\n");
-}
-
-void mi_exec_step(mi_h *h, int count)
-{
- if (count>1)
- mi_send(h,"-exec-step %d\n",count);
- else
- mi_send(h,"-exec-step\n");
-}
-
-void mi_exec_step_instruction(mi_h *h)
-{
- mi_send(h,"-exec-step-instruction\n");
-}
-
-void mi_exec_until(mi_h *h, const char *file, int line)
-{
- if (!file)
- mi_send(h,"-exec-until\n");
- else
- mi_send(h,"-exec-until %s:%d\n",file,line);
-}
-
-void mi_exec_until_addr(mi_h *h, void *addr)
-{
- mi_send(h,"-exec-until *%p\n",addr);
-}
-
-void mi_exec_return(mi_h *h)
-{
- mi_send(h,"-exec-return\n");
-}
-
-void mi_exec_kill(mi_h *h)
-{
- mi_send(h,"kill\n");
-}
-
-/* High level versions. */
-
-/**[txh]********************************************************************
-
- Description:
- Specify the executable and arguments for local debug.
-
- Command: -file-exec-and-symbols + -exec-arguments
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_set_exec(mi_h *h, const char *file, const char *args)
-{
- mi_file_exec_and_symbols(h,file);
- if (!mi_res_simple_done(h))
- return 0;
- if (!args)
- return 1;
- mi_exec_arguments(h,args);
- return mi_res_simple_done(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Start running the executable. Remote sessions starts running.
-
- Command: -exec-run
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_exec_run(mi_h *h)
-{
- mi_exec_run(h);
- return mi_res_simple_running(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Continue the execution after a "stop".
-
- Command: -exec-continue
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_exec_continue(mi_h *h)
-{
- mi_exec_continue(h);
- return mi_res_simple_running(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Indicate which terminal will use the target program. For local sessions.
-
- Command: tty
- Return: !=0 OK
- Example:
-
-***************************************************************************/
-
-int gmi_target_terminal(mi_h *h, const char *tty_name)
-{
- mi_target_terminal(h,tty_name);
- return mi_res_simple_done(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Specify what's the local copy that have debug info. For remote sessions.
-
- Command: -file-symbol-file
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_file_symbol_file(mi_h *h, const char *file)
-{
- mi_file_symbol_file(h,file);
- return mi_res_simple_done(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Continue until function return, the return value is included in the async
-response.
-
- Command: -exec-finish
- Return: !=0 OK.
-
-***************************************************************************/
-
-int gmi_exec_finish(mi_h *h)
-{
- mi_exec_finish(h);
- return mi_res_simple_running(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Stop the program using SIGINT. The corresponding command should be
--exec-interrupt but not even gdb 6.1.1 can do it because the "async" mode
-isn't really working.
-
- Command: -exec-interrupt [replacement]
- Return: Always 1
- Example:
-
-***************************************************************************/
-
-int gmi_exec_interrupt(mi_h *h)
-{
- // **** IMPORTANT!!! **** Not even gdb 6.1.1 can do it because the "async"
- // mode isn't really working.
- //mi_exec_interrupt(h);
- //return mi_res_simple_running(h);
-
- kill(h->pid,SIGINT);
- return 1; // How can I know?
-}
-
-/**[txh]********************************************************************
-
- Description:
- Next line of code.
-
- Command: -exec-next
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_exec_next(mi_h *h)
-{
- mi_exec_next(h,1);
- return mi_res_simple_running(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Skip count lines of code.
-
- Command: -exec-next count
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_exec_next_cnt(mi_h *h, int count)
-{
- mi_exec_next(h,count);
- return mi_res_simple_running(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Next line of assembler code.
-
- Command: -exec-next-instruction
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_exec_next_instruction(mi_h *h)
-{
- mi_exec_next_instruction(h);
- return mi_res_simple_running(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Next line of code. Get inside functions.
-
- Command: -exec-step
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_exec_step(mi_h *h)
-{
- mi_exec_step(h,1);
- return mi_res_simple_running(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Next count lines of code. Get inside functions.
-
- Command: -exec-step count
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_exec_step_cnt(mi_h *h, int count)
-{
- mi_exec_step(h,count);
- return mi_res_simple_running(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Next line of assembler code. Get inside calls.
-
- Command: -exec-step-instruction
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_exec_step_instruction(mi_h *h)
-{
- mi_exec_step_instruction(h);
- return mi_res_simple_running(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Execute until location is reached. If file is NULL then is until next
-line.
-
- Command: -exec-until
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_exec_until(mi_h *h, const char *file, int line)
-{
- mi_exec_until(h,file,line);
- return mi_res_simple_running(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Execute until location is reached.
-
- Command: -exec-until (using *address)
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_exec_until_addr(mi_h *h, void *addr)
-{
- mi_exec_until_addr(h,addr);
- return mi_res_simple_running(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Return to previous frame inmediatly.
-
- Command: -exec-return
- Return: A pointer to a new mi_frames structure indicating the current
-location. NULL on error.
-
-***************************************************************************/
-
-mi_frames *gmi_exec_return(mi_h *h)
-{
- mi_exec_return(h);
- return mi_res_frame(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Just kill the program. That's what -exec-abort should do, but it isn't
-implemented by gdb. This implementation only works if the interactive mode
-is disabled (gmi_gdb_set("confirm","off")).
-
- Command: -exec-abort [using kill]
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_exec_kill(mi_h *h)
-{
- mi_exec_kill(h);
- return mi_res_simple_done(h);
-}
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Stack manipulation.
- Comments:
- GDB/MI commands for the "Stack Manipulation" section. @<p>
-
-@<pre>
-gdb command: Implemented?
-
--stack-info-frame Yes, implemented as "frame"
--stack-info-depth Yes
--stack-list-arguments Yes
--stack-list-frames Yes
--stack-list-locals Yes
--stack-select-frame Yes
-@</pre>
-
-***************************************************************************/
-
-#include "gdbmi.h"
-
-/* Low level versions. */
-
-void mi_stack_list_frames(mi_h *h, int from, int to)
-{
- if (from<0)
- mi_send(h,"-stack-list-frames\n");
- else
- mi_send(h,"-stack-list-frames %d %d\n",from,to);
-}
-
-void mi_stack_list_arguments(mi_h *h, int show, int from, int to)
-{
- if (from<0)
- mi_send(h,"-stack-list-arguments %d\n",show);
- else
- mi_send(h,"-stack-list-arguments %d %d %d\n",show,from,to);
-}
-
-void mi_stack_info_frame(mi_h *h)
-{
- mi_send(h,"frame\n");
-}
-
-void mi_stack_info_depth(mi_h *h, int depth)
-{
- if (depth<0)
- mi_send(h,"-stack-info-depth\n");
- else
- mi_send(h,"-stack-info-depth %d\n",depth);
-}
-
-void mi_stack_select_frame(mi_h *h, int framenum)
-{
- mi_send(h,"-stack-select-frame %d\n",framenum);
-}
-
-void mi_stack_list_locals(mi_h *h, int show)
-{
- mi_send(h,"-stack-list-locals %d\n",show);
-}
-
-/* High level versions. */
-
-/**[txh]********************************************************************
-
- Description:
- List of frames. Arguments aren't filled.
-
- Command: -stack-list-frames
- Return: A new list of mi_frames or NULL on error.
-
-***************************************************************************/
-
-mi_frames *gmi_stack_list_frames(mi_h *h)
-{
- mi_stack_list_frames(h,-1,-1);
- return mi_res_frames_array(h,"stack");
-}
-
-/**[txh]********************************************************************
-
- Description:
- List of frames. Arguments aren't filled. Only the frames in the from
- - to range are returned.
-
- Command: -stack-list-frames
- Return: A new list of mi_frames or NULL on error.
-
-***************************************************************************/
-
-mi_frames *gmi_stack_list_frames_r(mi_h *h, int from, int to)
-{
- mi_stack_list_frames(h,from,to);
- return mi_res_frames_array(h,"stack");
-}
-
-/**[txh]********************************************************************
-
- Description:
- List arguments. Only level and args filled.
-
- Command: -stack-list-arguments
- Return: A new list of mi_frames or NULL on error.
-
-***************************************************************************/
-
-mi_frames *gmi_stack_list_arguments(mi_h *h, int show)
-{
- mi_stack_list_arguments(h,show,-1,-1);
- return mi_res_frames_array(h,"stack-args");
-}
-
-/**[txh]********************************************************************
-
- Description:
- List arguments. Only level and args filled. Only for the
-frames in the from - to range.
-
- Command: -stack-list-arguments
- Return: A new list of mi_frames or NULL on error.
-
-***************************************************************************/
-
-mi_frames *gmi_stack_list_arguments_r(mi_h *h, int show, int from, int to)
-{
- mi_stack_list_arguments(h,show,from,to);
- return mi_res_frames_array(h,"stack-args");
-}
-
-/**[txh]********************************************************************
-
- Description:
- Information about the current frame, including args.
-
- Command: -stack-info-frame [using frame]
- Return: A new mi_frames or NULL on error.
-
-***************************************************************************/
-
-mi_frames *gmi_stack_info_frame(mi_h *h)
-{
- mi_stack_info_frame(h);
- return mi_res_frame(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Stack info depth.
-
- Command: -stack-info-depth
- Return: The depth or -1 on error.
-
-***************************************************************************/
-
-int gmi_stack_info_depth(mi_h *h, int max_depth)
-{
- mi_results *r;
- int ret=-1;
-
- mi_stack_info_depth(h,max_depth);
- r=mi_res_done_var(h,"depth");
- if (r && r->type==t_const)
- {
- ret=atoi(r->v.cstr);
- mi_free_results(r);
- }
- return ret;
-}
-
-/**[txh]********************************************************************
-
- Description:
- Set stack info depth.
-
- Command: -stack-info-depth [no args]
- Return: The depth or -1 on error.
- Example:
-
-***************************************************************************/
-
-int gmi_stack_info_depth_get(mi_h *h)
-{
- return gmi_stack_info_depth(h,-1);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Change current frame.
-
- Command: -stack-select-frame
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_stack_select_frame(mi_h *h, int framenum)
-{
- mi_stack_select_frame(h,framenum);
- return mi_res_simple_done(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- List of local vars.
-
- Command: -stack-list-locals
- Return: A new mi_results tree containing the variables or NULL on error.
-
-***************************************************************************/
-
-mi_results *gmi_stack_list_locals(mi_h *h, int show)
-{
- mi_stack_list_locals(h,show);
- return mi_res_done_var(h,"locals");
-}
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Symbol query.
- Comments:
- GDB/MI commands for the "Symbol Query" section.@p
-
-@<pre>
-gdb command: Implemented?
--symbol-info-address N.A. (info address, human readable)
--symbol-info-file N.A.
--symbol-info-function N.A.
--symbol-info-line N.A. (info line, human readable)
--symbol-info-symbol N.A. (info symbol, human readable)
--symbol-list-functions N.A. (info functions, human readable)
--symbol-list-types N.A. (info types, human readable)
--symbol-list-variables N.A. (info variables, human readable)
--symbol-list-lines No (gdb 6.x)
--symbol-locate N.A.
--symbol-type N.A. (ptype, human readable)
-@</pre>
-
-Note:@p
-
-Only one is implemented and not in gdb 5.x.@p
-
-***************************************************************************/
-
-#include "gdbmi.h"
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004-2007 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Target manipulation.
- Comments:
- GDB/MI commands for the "Target Manipulation" section. @<p>
-
-@<pre>
--target-attach Yes (implemented using attach)
--target-compare-sections N.A. (compare-sections)
--target-detach Yes
--target-download Yes
--target-exec-status N.A.
--target-list-available-targets N.A. (help target)
--target-list-current-targets N.A. (info file among other things)
--target-list-parameters N.A.
--target-select Yes
-@</pre>
-
-***************************************************************************/
-
-#include "gdbmi.h"
-
-/* Low level versions. */
-
-void mi_target_select(mi_h *h, const char *type, const char *params)
-{
- mi_send(h,"-target-select %s %s\n",type,params);
-}
-
-/* Note: -target-attach isn't currently implemented :-( (gdb 6.1.1) */
-void mi_target_attach(mi_h *h, pid_t pid)
-{
- mi_send(h,"attach %d\n",pid);
-}
-
-void mi_target_detach(mi_h *h)
-{
- mi_send(h,"-target-detach\n");
-}
-
-void mi_target_download(mi_h *h)
-{
- mi_send(h,"-target-download\n");
-}
-
-/* High level versions. */
-
-/**[txh]********************************************************************
-
- Description:
- Connect to a remote gdbserver using the specified methode.
-
- Command: -target-select
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_target_select(mi_h *h, const char *type, const char *params)
-{
- mi_target_select(h,type,params);
- if (!mi_res_simple_connected(h))
- return 0;
- mi_send_target_commands(h);
- return 1;
-}
-
-/**[txh]********************************************************************
-
- Description:
- Attach to an already running process.
-
- Command: -target-attach [using attach]
- Return: The frame of the current location, NULL on error.
-
-***************************************************************************/
-
-mi_frames *gmi_target_attach(mi_h *h, pid_t pid)
-{
- mi_target_attach(h,pid);
- //return mi_res_simple_done(h);
- return mi_res_frame(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Detach from an attached process.
-
- Command: -target-detach
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_target_detach(mi_h *h)
-{
- mi_target_detach(h);
- return mi_res_simple_done(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Loads the executable onto the remote target.
-
- Command: -target-download
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_target_download(mi_h *h)
-{
- mi_target_download(h);
- // TODO: this response have some data
- return mi_res_simple_done(h);
-}
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Thread commands.
- Comments:
- GDB/MI commands for the "Thread Commands" section. @<p>
-
-@<pre>
-gdb command: Implemented?
--thread-info N.A.
--thread-list-all-threads Yes, implemented as "info threads"
--thread-list-ids Yes
--thread-select Yes
-@</pre>
-
-***************************************************************************/
-
-#include "gdbmi.h"
-
-/* Low level versions. */
-
-void mi_thread_list_ids(mi_h *h)
-{
- mi_send(h,"-thread-list-ids\n");
-}
-
-void mi_thread_select(mi_h *h, int id)
-{
- mi_send(h,"-thread-select %d\n",id);
-}
-
-void mi_thread_list_all_threads(mi_h *h)
-{
- mi_send(h,"info threads\n");
-}
-
-/* High level versions. */
-
-/**[txh]********************************************************************
-
- Description:
- List available thread ids.
-
- Command: -thread-list-ids
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_thread_list_ids(mi_h *h, int **list)
-{
- mi_thread_list_ids(h);
- return mi_res_thread_ids(h,list);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Select a thread.
-
- Command: -thread-select
- Return: A new mi_frames or NULL on error.
-
-***************************************************************************/
-
-mi_frames *gmi_thread_select(mi_h *h, int id)
-{
- mi_thread_select(h,id);
- return mi_res_frame(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Get a list of frames for each available thread. Implemented using "info
-thread".
-
- Command: -thread-list-all-threads
- Return: A kist of frames, NULL on error
-
-***************************************************************************/
-
-mi_frames *gmi_thread_list_all_threads(mi_h *h)
-{
- mi_thread_list_all_threads(h);
- return mi_res_frames_list(h);
-}
-
+++ /dev/null
-/**[txh]********************************************************************
-
- Copyright (c) 2004 by Salvador E. Tropea.
- Covered by the GPL license.
-
- Module: Variable objects.
- Comments:
- GDB/MI commands for the "Variable Objects" section.
- @<p>
-
-@<pre>
-gdb command: Imp? Description:
--var-create Yes create a variable object
--var-delete Yes delete the variable object and its children
--var-set-format Yes set the display format of this variable
--var-show-format Yes show the display format of this variable
--var-info-num-children Yes tells how many children this object has
--var-list-children Yes* return a list of the object's children
--var-info-type Yes show the type of this variable object
--var-info-expression Yes print what this variable object represents
--var-show-attributes Yes is this variable editable?
--var-evaluate-expression Yes get the value of this variable
--var-assign Yes set the value of this variable
--var-update Yes* update the variable and its children
-@</pre>
-
-Notes: @<p>
-1) I suggest letting gdb to choose the names for the variables.@*
-2) -var-list-children supports an optional "show values" argument in MI v2.
-It isn't implemented.@*
-
- @<p>
-
-* MI v1 and v2 result formats supported. @<p>
-
-***************************************************************************/
-
-#include "gdbmi.h"
-
-/* Low level versions. */
-
-void mi_var_create(mi_h *h, const char *name, int frame, const char *exp)
-{
- const char *n=name ? name : "-";
-
- if (frame<0)
- mi_send(h,"-var-create %s * %s\n",n,exp);
- else
- mi_send(h,"-var-create %s %d %s\n",n,frame,exp);
-}
-
-void mi_var_delete(mi_h *h, const char *name)
-{
- mi_send(h,"-var-delete %s\n",name);
-}
-
-void mi_var_set_format(mi_h *h, const char *name, const char *format)
-{
- mi_send(h,"-var-set-format \"%s\" %s\n",name,format);
-}
-
-void mi_var_show_format(mi_h *h, const char *name)
-{
- mi_send(h,"-var-show-format \"%s\"\n",name);
-}
-
-void mi_var_info_num_children(mi_h *h, const char *name)
-{
- mi_send(h,"-var-info-num-children \"%s\"\n",name);
-}
-
-void mi_var_info_type(mi_h *h, const char *name)
-{
- mi_send(h,"-var-info-type \"%s\"\n",name);
-}
-
-void mi_var_info_expression(mi_h *h, const char *name)
-{
- mi_send(h,"-var-info-expression \"%s\"\n",name);
-}
-
-void mi_var_show_attributes(mi_h *h, const char *name)
-{
- mi_send(h,"-var-show-attributes \"%s\"\n",name);
-}
-
-void mi_var_update(mi_h *h, const char *name)
-{
- if (name)
- mi_send(h,"-var-update %s\n",name);
- else
- mi_send(h,"-var-update *\n");
-}
-
-void mi_var_assign(mi_h *h, const char *name, const char *expression)
-{
- mi_send(h,"-var-assign \"%s\" \"%s\"\n",name,expression);
-}
-
-void mi_var_evaluate_expression(mi_h *h, const char *name)
-{
- mi_send(h,"-var-evaluate-expression \"%s\"\n",name);
-}
-
-void mi_var_list_children(mi_h *h, const char *name)
-{
- if (h->version>=MI_VERSION2U(2,0,0))
- mi_send(h,"-var-list-children --all-values \"%s\"\n",name);
- else
- mi_send(h,"-var-list-children \"%s\"\n",name);
-}
-
-/* High level versions. */
-
-/**[txh]********************************************************************
-
- Description:
- Create a variable object. I recommend using gmi_var_create and letting
-gdb choose the names.
-
- Command: -var-create
- Return: A new mi_gvar strcture or NULL on error.
-
-***************************************************************************/
-
-mi_gvar *gmi_var_create_nm(mi_h *h, const char *name, int frame, const char *exp)
-{
- mi_var_create(h,name,frame,exp);
- return mi_res_gvar(h,NULL,exp);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Create a variable object. The name is selected by gdb. Alternative:
- gmi_full_var_create.
-
- Command: -var-create [auto name]
- Return: A new mi_gvar strcture or NULL on error.
-
-***************************************************************************/
-
-mi_gvar *gmi_var_create(mi_h *h, int frame, const char *exp)
-{
- return gmi_var_create_nm(h,NULL,frame,exp);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Delete a variable object. Doesn't free the mi_gvar data.
-
- Command: -var-delete
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_var_delete(mi_h *h, mi_gvar *var)
-{
- mi_var_delete(h,var->name);
- return mi_res_simple_done(h);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Set the format used to represent the result.
-
- Command: -var-set-format
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_var_set_format(mi_h *h, mi_gvar *var, enum mi_gvar_fmt format)
-{
- int ret;
-
- mi_var_set_format(h,var->name,mi_format_enum_to_str(format));
- ret=mi_res_simple_done(h);
- if (ret)
- var->format=format;
- return ret;
-}
-
-/**[txh]********************************************************************
-
- Description:
- Fill the format field with info from gdb.
-
- Command: -var-show-format
- Return: !=0 OK.
-
-***************************************************************************/
-
-int gmi_var_show_format(mi_h *h, mi_gvar *var)
-{
- mi_var_show_format(h,var->name);
- return mi_res_gvar(h,var,NULL)!=NULL;
-}
-
-/**[txh]********************************************************************
-
- Description:
- Fill the numchild field with info from gdb.
-
- Command: -var-info-num-children
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_var_info_num_children(mi_h *h, mi_gvar *var)
-{
- mi_var_info_num_children(h,var->name);
- return mi_res_gvar(h,var,NULL)!=NULL;
-}
-
-/**[txh]********************************************************************
-
- Description:
- Fill the type field with info from gdb.
-
- Command: -var-info-type
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_var_info_type(mi_h *h, mi_gvar *var)
-{
- mi_var_info_type(h,var->name);
- return mi_res_gvar(h,var,NULL)!=NULL;
-}
-
-/**[txh]********************************************************************
-
- Description:
- Fill the expression and lang fields with info from gdb. Note that lang
-isn't filled during creation.
-
- Command: -var-info-expression
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_var_info_expression(mi_h *h, mi_gvar *var)
-{
- mi_var_info_expression(h,var->name);
- return mi_res_gvar(h,var,NULL)!=NULL;
-}
-
-
-/**[txh]********************************************************************
-
- Description:
- Fill the attr field with info from gdb. Note that attr isn't filled
-during creation.
-
- Command: -var-show-attributes
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_var_show_attributes(mi_h *h, mi_gvar *var)
-{
- mi_var_show_attributes(h,var->name);
- return mi_res_gvar(h,var,NULL)!=NULL;
-}
-
-/**[txh]********************************************************************
-
- Description:
- Create the variable and also fill the lang and attr fields. The name is
-selected by gdb.
-
- Command: -var-create + -var-info-expression + -var-show-attributes
- Return: A new mi_gvar strcture or NULL on error.
-
-***************************************************************************/
-
-mi_gvar *gmi_full_var_create(mi_h *h, int frame, const char *exp)
-{
- mi_gvar *var=gmi_var_create_nm(h,NULL,frame,exp);
- if (var)
- {/* What if it fails? */
- gmi_var_info_expression(h,var);
- gmi_var_show_attributes(h,var);
- }
- return var;
-}
-
-/**[txh]********************************************************************
-
- Description:
- Update variable. Use NULL for all. Note that *changed can be NULL if none
-updated.
-
- Command: -var-update
- Return: !=0 OK. The changed list contains the list of changed vars.
-
-***************************************************************************/
-
-int gmi_var_update(mi_h *h, mi_gvar *var, mi_gvar_chg **changed)
-{
- mi_var_update(h,var ? var->name : NULL);
- return mi_res_changelist(h,changed);
-}
-
-/**[txh]********************************************************************
-
- Description:
- Change variable. The new value replaces the value field.
-
- Command: -var-assign
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_var_assign(mi_h *h, mi_gvar *var, const char *expression)
-{
- char *res;
- mi_var_assign(h,var->name,expression);
- res=mi_res_value(h);
- if (res)
- {
- free(var->value);
- var->value=res;
- return 1;
- }
- return 0;
-}
-
-/**[txh]********************************************************************
-
- Description:
- Fill the value field getting the current value for a variable.
-
- Command: -var-evaluate-expression
- Return: !=0 OK, value contains the result.
-
-***************************************************************************/
-
-int gmi_var_evaluate_expression(mi_h *h, mi_gvar *var)
-{
- char *s;
-
- mi_var_evaluate_expression(h,var->name);
- s=mi_res_value(h);
- if (s)
- {
- free(var->value);
- var->value=s;
- }
- return s!=NULL;
-}
-
-/**[txh]********************************************************************
-
- Description:
- List children. It ONLY returns the first level information. :-(@*
- On success the child field contains the list of children.
-
- Command: -var-list-children
- Return: !=0 OK
-
-***************************************************************************/
-
-int gmi_var_list_children(mi_h *h, mi_gvar *var)
-{
- mi_var_list_children(h,var->name);
- return mi_res_children(h,var);
-}
-
+++ /dev/null
-/*
- This file is part of GNUnet.
- (C) 2010, 2011 Christian Grothoff (and other contributing authors)
-
- GNUnet 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 3, or (at your
- option) any later version.
-
- GNUnet 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 GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file monkey/gnunet-monkey.c
- * @brief Monkey: gnunet automated debugging tool
- */
-
-#include <stdio.h>
-#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_getopt_lib.h"
-#include "gnunet_program_lib.h"
-#include "gnunet_monkey_action.h"
-
-static const char *mode;
-static const char *dumpFileName;
-static const char *binaryName;
-static const char *emailAddress;
-static const char *edbFilePath;
-static const char *gdbBinaryPath;
-static const char *inspectExpression;
-static const char *inspectFunction;
-static int ret = 0;
-
-/**
- * Main function that will launch the action api.
- *
- * @param cls closure
- * @param args remaining command-line arguments
- * @param cfgfile name of the configuration file used (for saving, can be NULL!)
- * @param c configuration
- */
-static void
-run (void *cls,
- char *const *args,
- const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
-{
- int result;
- struct GNUNET_MONKEY_ACTION_Context *cntxt;
-
- if (strcasecmp (mode, "email") == 0)
- {
- if (NULL == emailAddress)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Working in email mode requires an email address!\n");
- ret = 1;
- return;
- }
- }
- else if (strcasecmp (mode, "text") == 0)
- {
- if (NULL == dumpFileName)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Working in text mode requires a path for the dump file!\n");
- ret = 1;
- return;
- }
- }
-
- /* Initialize context for the Action API */
- cntxt = GNUNET_malloc (sizeof (struct GNUNET_MONKEY_ACTION_Context));
- cntxt->binary_name = binaryName;
- cntxt->expression_database_path = edbFilePath;
- cntxt->gdb_binary_path = gdbBinaryPath;
- cntxt->inspect_expression = inspectExpression;
- cntxt->inspect_function = inspectFunction;
-
- result = GNUNET_MONKEY_ACTION_rerun_with_gdb (cntxt);
- switch (result)
- {
- int retVal;
- case GDB_STATE_ERROR:
- break;
- case GDB_STATE_EXIT_NORMALLY:
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Debug with gdb, program exited normally!\n");
- /*FIXME: Valgrind should be launched here */
- break;
- case GDB_STATE_STOPPED:
- /*FIXME: Expression Database should be inspected here (before writing the report) */
- retVal = GNUNET_MONKEY_ACTION_inspect_expression_database (cntxt);
- if (GNUNET_NO == retVal)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Error using Expression Database!\n");
- ret = 1;
- break;
- }
- else if (GDB_STATE_ERROR == retVal)
- {
- /* GDB could not locate a NULL value expression, launch Valgrind */
- retVal = GNUNET_MONKEY_ACTION_rerun_with_valgrind (cntxt);
- if (GNUNET_NO == retVal)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error using Valgrind!\n");
- ret = 1;
- break;
- }
- }
- if (GNUNET_OK != GNUNET_MONKEY_ACTION_format_report (cntxt))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Error in generating debug report!\n");
- ret = 1;
- }
- if (strcasecmp (mode, "email") == 0)
- {
- if (GNUNET_OK != GNUNET_MONKEY_ACTION_report_email (cntxt))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error sending email!\n");
- ret = 1;
- }
- }
- else
- {
- /* text mode */
- if (GNUNET_OK !=
- GNUNET_MONKEY_ACTION_report_file (cntxt, dumpFileName))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Error in saving debug file!\n");
- ret = 1;
- }
- }
- break;
- default:
- break;
- }
- GNUNET_MONKEY_ACTION_delete_context(cntxt);
-}
-
-
-int
-main (int argc, char *argv[])
-{
- static const struct GNUNET_GETOPT_CommandLineOption options[] = {
- {'m', "mode", NULL,
- gettext_noop
- ("monkey's mode of operation: options are \"text\" or \"email\""),
- GNUNET_YES, &GNUNET_GETOPT_set_string, &mode},
- {'b', "binary", NULL,
- gettext_noop ("binary for program to debug with monkey"),
- GNUNET_YES, &GNUNET_GETOPT_set_string, &binaryName},
- {'o', "output", NULL,
- gettext_noop
- ("path to file to dump monkey's output in case of text mode"),
- GNUNET_YES, &GNUNET_GETOPT_set_string, &dumpFileName},
- {'a', "address", NULL,
- gettext_noop ("address to send email to in case of email mode"),
- GNUNET_YES, &GNUNET_GETOPT_set_string, &emailAddress},
- {'d', "database", NULL, gettext_noop ("path to Expression Database file"),
- GNUNET_YES, &GNUNET_GETOPT_set_string, &edbFilePath},
- {'g', "gdb", NULL,
- gettext_noop ("path to gdb binary in use; default is /usr/bin/gdb"),
- GNUNET_YES, &GNUNET_GETOPT_set_string, &gdbBinaryPath},
- {'f', "function", NULL, gettext_noop ("Monkey will set a breakpoint on this function"),
- GNUNET_YES, &GNUNET_GETOPT_set_string, &inspectFunction},
- {'i', "inspect", NULL, gettext_noop ("An expression to inspect in the function specified after the argument f"),
- GNUNET_YES, &GNUNET_GETOPT_set_string, &inspectExpression},
- GNUNET_GETOPT_OPTION_END
- };
-
- if (argc < 2)
- {
- printf ("%s",
- "Monkey should take arguments: Use --help to get a list of options.\n");
- return 1;
- }
-
- if (GNUNET_OK == GNUNET_PROGRAM_run (argc,
- argv,
- "gnunet-monkey",
- gettext_noop
- ("Automatically debug a service"),
- options, &run, NULL))
- {
- return ret;
- }
-
- return 1;
-}
+++ /dev/null
-
-
-int main(int argc, char *argv[])
-{
- return 0;
-}
+++ /dev/null
-/*
- This file is part of GNUnet
- (C) 2010, 2011 Christian Grothoff (and other contributing authors)
-
- GNUnet 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 3, or (at your
- option) any later version.
-
- GNUnet 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 GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
- */
-
-/**
- * @file monkey/gnunet_monkey_action.h
- * @brief Monkey API for actions taken by Monkey while debugging
- */
-
-#ifndef GNUNET_MONKEY_ACTION_H
-#define GNUNET_MONKEY_ACTION_H
-
-#include "gdbmi.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0 /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-
-/* Debug constants */
-#define DEBUG_MODE_GDB 0
-#define GDB_STATE_STOPPED 1
-#define GDB_STATE_EXIT_NORMALLY 2
-#define GDB_STATE_ERROR 3
-#define DEBUG_MODE_VALGRIND 4
-#define DEBUG_MODE_REPORT_READY 5
-#define BUG_NULL_POINTER 6
-#define BUG_CUSTOM 7
-
-
-/**
- * Context for the Action API
- */
-struct GNUNET_MONKEY_ACTION_Context
-{
- const char *binary_name;
- const char *email_address;
- const char *expression_database_path;
- const char *gdb_binary_path;
- const char *inspect_expression;
- const char *inspect_function;
- int debug_mode;
- int bug_detected;
- char *debug_report;
-
- /* gdb debugging attributes */
- mi_h *gdb_handle;
- const char *gdb_in_use;
- mi_stop *gdb_stop_reason;
- mi_frames *gdb_frames;
- const char *gdb_null_variable;
-
- /* Valgrind memcheck attributes */
- char* valgrind_output_tmp_file_name;
-};
-
-
-int GNUNET_MONKEY_ACTION_report_file (struct GNUNET_MONKEY_ACTION_Context
- *cntxt, const char *dumpFileName);
-int GNUNET_MONKEY_ACTION_report_email (struct GNUNET_MONKEY_ACTION_Context
- *cntxt);
-int GNUNET_MONKEY_ACTION_inspect_expression_database (struct
- GNUNET_MONKEY_ACTION_Context
- *cntxt);
-int GNUNET_MONKEY_ACTION_rerun_with_gdb (struct GNUNET_MONKEY_ACTION_Context
- *cntxt);
-int GNUNET_MONKEY_ACTION_rerun_with_valgrind (struct
- GNUNET_MONKEY_ACTION_Context
- *cntxt);
-int GNUNET_MONKEY_ACTION_format_report (struct GNUNET_MONKEY_ACTION_Context
- *cntxt);
-int GNUNET_MONKEY_ACTION_delete_context(struct GNUNET_MONKEY_ACTION_Context *cntxt);
-
-int GNUNET_MONKEY_ACTION_check_bug_redundancy (void);
-
-
-#if 0 /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
+++ /dev/null
-/*
- This file is part of GNUnet
- (C) 2009, 2010 Christian Grothoff (and other contributing authors)
-
- GNUnet 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 3, or (at your
- option) any later version.
-
- GNUnet 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 GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
- */
-
-/**
- * @file monkey/gnunet_monkey_edb.h
- * @brief Monkey API for accessing the Expression Database (edb)
- */
-
-#ifndef GNUNET_MONKEY_EDB_H
-#define GNUNET_MONKEY_EDB_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0 /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-
-struct GNUNET_MONKEY_EDB_Context;
-
-/**
- * Establish a connection to the Expression Database
- *
- * @param db_file_name path the Expression Database file
- * @return context to use for Accessing the Expression Database, NULL on error
- */
-struct GNUNET_MONKEY_EDB_Context *GNUNET_MONKEY_EDB_connect (const char
- *db_file_name);
-
-
-/**
- * Disconnect from Database, and cleanup resources
- *
- * @param context context
- * @return GNUNET_OK on success, GNUNET_NO on failure
- */
-int GNUNET_MONKEY_EDB_disconnect (struct GNUNET_MONKEY_EDB_Context *cntxt);
-
-
-typedef int (*GNUNET_MONKEY_ExpressionIterator) (void *, int, char **,
- char **);
-
-
-
-/**
- * Return the line number of the end-of-scope for the expression indicated by start_line_no
- *
- * @param cntxt context containing the Expression Database handle
- * @param file_name path to the file in which the expression in question exists
- * @param start_line_no expression's line
- * @param iter callback function, iterator for values returned from the Database
- * @param iter_cls closure for the expression iterator, will contain the scope-end line number
- * @return GNUNET_OK on success, GNUNET_NO on failure
- */
-int
-GNUNET_MONKEY_EDB_get_expression_scope_end(struct GNUNET_MONKEY_EDB_Context *cntxt,
- const char *file_name, int start_line_no,
- GNUNET_MONKEY_ExpressionIterator iter,
- void *iter_cls);
-
-
-/**
- * Run an SQLite query to retrieve those expressions that are previous to
- * given expression and are in the same scope of the given expression
- * For example, consider the following code snippet:
- *
- * {
- * struct Something whole; // line no.1
- * struct SomethingElse part; // line no.2
- * whole.part = ∂ // line no.3
- * whole.part->member = 1; // line no.4
- * }
- *
- * If the expression supplied to the function is that of line no.4 "whole.part->member = 1;"
- * The returned list of expressions will be: whole.part (line no.4), whole.part->member (line no.4),
- * whole (line no.3), whole.part (line no.3), &part (line no.3), whole.part = &part (line no.3)
- *
- * @param cntxt context containing the Expression Database handle.
- * @param file_name path to the file in which the expression in question exists
- * @param start_line_no expression beginning line
- * @param end_line_no line number for the expression's scope end
- * @param iter callback function, iterator for expressions returned from the Database
- * @param iter_cls closure for the expression iterator
- * @return GNUNET_OK success, GNUNET_NO failure
- */
-int
-GNUNET_MONKEY_EDB_get_expressions (struct GNUNET_MONKEY_EDB_Context *cntxt,
- const char *file_name, int start_line_no,
- int end_line_no,
- GNUNET_MONKEY_ExpressionIterator iter,
- void *iter_cls);
-
-
-int
-GNUNET_MONKEY_EDB_get_sub_expressions (struct GNUNET_MONKEY_EDB_Context *cntxt,
- const char *file_name, int start_line_no,
- int end_line_no,
- GNUNET_MONKEY_ExpressionIterator iter,
- void *iter_cls);
-
-
-
-#if 0 /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <string.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdarg.h>
-
-#include <openssl/ssl.h>
-#include <auth-client.h>
-#include <libesmtp.h>
-
-#if !defined (__GNUC__) || __GNUC__ < 2
-# define __attribute__(x)
-#endif
-
-
-int
-handle_invalid_peer_certificate(long vfy_result)
-{
- const char *k ="rare error";
- switch(vfy_result) {
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- k="X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT"; break;
- case X509_V_ERR_UNABLE_TO_GET_CRL:
- k="X509_V_ERR_UNABLE_TO_GET_CRL"; break;
- case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
- k="X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE"; break;
- case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
- k="X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE"; break;
- case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
- k="X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY"; break;
- case X509_V_ERR_CERT_SIGNATURE_FAILURE:
- k="X509_V_ERR_CERT_SIGNATURE_FAILURE"; break;
- case X509_V_ERR_CRL_SIGNATURE_FAILURE:
- k="X509_V_ERR_CRL_SIGNATURE_FAILURE"; break;
- case X509_V_ERR_CERT_NOT_YET_VALID:
- k="X509_V_ERR_CERT_NOT_YET_VALID"; break;
- case X509_V_ERR_CERT_HAS_EXPIRED:
- k="X509_V_ERR_CERT_HAS_EXPIRED"; break;
- case X509_V_ERR_CRL_NOT_YET_VALID:
- k="X509_V_ERR_CRL_NOT_YET_VALID"; break;
- case X509_V_ERR_CRL_HAS_EXPIRED:
- k="X509_V_ERR_CRL_HAS_EXPIRED"; break;
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- k="X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD"; break;
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- k="X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD"; break;
- case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
- k="X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD"; break;
- case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
- k="X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD"; break;
- case X509_V_ERR_OUT_OF_MEM:
- k="X509_V_ERR_OUT_OF_MEM"; break;
- case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
- k="X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT"; break;
- case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
- k="X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN"; break;
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
- k="X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY"; break;
- case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
- k="X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE"; break;
- case X509_V_ERR_CERT_CHAIN_TOO_LONG:
- k="X509_V_ERR_CERT_CHAIN_TOO_LONG"; break;
- case X509_V_ERR_CERT_REVOKED:
- k="X509_V_ERR_CERT_REVOKED"; break;
- case X509_V_ERR_INVALID_CA:
- k="X509_V_ERR_INVALID_CA"; break;
- case X509_V_ERR_PATH_LENGTH_EXCEEDED:
- k="X509_V_ERR_PATH_LENGTH_EXCEEDED"; break;
- case X509_V_ERR_INVALID_PURPOSE:
- k="X509_V_ERR_INVALID_PURPOSE"; break;
- case X509_V_ERR_CERT_UNTRUSTED:
- k="X509_V_ERR_CERT_UNTRUSTED"; break;
- case X509_V_ERR_CERT_REJECTED:
- k="X509_V_ERR_CERT_REJECTED"; break;
- }
- printf("SMTP_EV_INVALID_PEER_CERTIFICATE: %ld: %s\n", vfy_result, k);
- return 1; /* Accept the problem */
-}
-
-
-void event_cb (smtp_session_t session, int event_no, void *arg,...)
-{
- va_list alist;
- int *ok;
-
- va_start(alist, arg);
- switch(event_no) {
- case SMTP_EV_CONNECT:
- case SMTP_EV_MAILSTATUS:
- case SMTP_EV_RCPTSTATUS:
- case SMTP_EV_MESSAGEDATA:
- case SMTP_EV_MESSAGESENT:
- case SMTP_EV_DISCONNECT: break;
- case SMTP_EV_WEAK_CIPHER: {
- int bits;
- bits = va_arg(alist, long); ok = va_arg(alist, int*);
- printf("SMTP_EV_WEAK_CIPHER, bits=%d - accepted.\n", bits);
- *ok = 1; break;
- }
- case SMTP_EV_STARTTLS_OK:
- puts("SMTP_EV_STARTTLS_OK - TLS started here."); break;
- case SMTP_EV_INVALID_PEER_CERTIFICATE: {
- long vfy_result;
- vfy_result = va_arg(alist, long); ok = va_arg(alist, int*);
- *ok = handle_invalid_peer_certificate(vfy_result);
- break;
- }
- case SMTP_EV_NO_PEER_CERTIFICATE: {
- ok = va_arg(alist, int*);
- puts("SMTP_EV_NO_PEER_CERTIFICATE - accepted.");
- *ok = 1; break;
- }
- case SMTP_EV_WRONG_PEER_CERTIFICATE: {
- ok = va_arg(alist, int*);
- puts("SMTP_EV_WRONG_PEER_CERTIFICATE - accepted.");
- *ok = 1; break;
- }
- case SMTP_EV_NO_CLIENT_CERTIFICATE: {
- ok = va_arg(alist, int*);
- puts("SMTP_EV_NO_CLIENT_CERTIFICATE - accepted.");
- *ok = 1; break;
- }
- default:
- printf("Got event: %d - ignored.\n", event_no);
- }
- va_end(alist);
-}
-
-
-/* Callback to prnt the recipient status */
-void
-print_recipient_status (smtp_recipient_t recipient,
- const char *mailbox, void *arg)
-{
- const smtp_status_t *status;
-
- status = smtp_recipient_status (recipient);
- printf ("%s: %d %s", mailbox, status->code, status->text);
-}
-
-
-void sendMail(const char *messageContents, const char *emailAddress)
-{
- smtp_session_t session;
- smtp_message_t message;
- smtp_recipient_t recipient;
- const smtp_status_t *status;
- struct sigaction sa;
- char *host = "localhost:25";
- char *from = "gnunet-monkey";
- char *subject = "e-mail from Libesmtp!";
- const char *recipient_address = emailAddress;
- char tempFileName[1000];
- int tempFd;
- FILE *fp;
- enum notify_flags notify = Notify_SUCCESS | Notify_FAILURE;
-
- auth_client_init();
- session = smtp_create_session();
- message = smtp_add_message(session);
-
- /* Ignore sigpipe */
- sa.sa_handler = SIG_IGN;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sigaction(SIGPIPE, &sa, NULL);
-
-
- smtp_set_server(session, host);
- smtp_set_eventcb(session, event_cb, NULL);
-
- /* Set the reverse path for the mail envelope. (NULL is ok)
- */
- smtp_set_reverse_path(message, from);
-
- /* Set the Subject: header. For no reason, we want the supplied subject
- to override any subject line in the message headers. */
- if (subject != NULL) {
- smtp_set_header(message, "Subject", subject);
- smtp_set_header_option(message, "Subject", Hdr_OVERRIDE, 1);
- }
-
-
- /* Prepare message */
- memset(tempFileName, 0, sizeof(tempFileName));
- sprintf(tempFileName, "/tmp/messageXXXXXX");
- tempFd = mkstemp(tempFileName);
- fp = fdopen(tempFd, "w");
- fprintf(fp, "%s", messageContents);
- fclose(fp);
- fp = fopen(tempFileName, "r");
- smtp_set_message_fp(message, fp);
-
-
- recipient = smtp_add_recipient(message, recipient_address);
-
- smtp_dsn_set_notify (recipient, notify);
-
- /* Initiate a connection to the SMTP server and transfer the
- message. */
- if (!smtp_start_session(session)) {
- char buf[128];
-
- fprintf(stderr, "SMTP server problem %s\n", smtp_strerror(smtp_errno(),
- buf, sizeof buf));
- } else {
- /* Report on the success or otherwise of the mail transfer.
- */
- status = smtp_message_transfer_status(message);
- printf("%d %s", status->code, (status->text != NULL) ? status->text
- : "\n");
- smtp_enumerate_recipients(message, print_recipient_status, NULL);
- }
-
- /* Free resources consumed by the program.
- */
- smtp_destroy_session(session);
- fclose(fp);
- auth_client_exit();
-}
-
+++ /dev/null
-/*
-
- C grammar defintion for use with JavaCC
- Contributed by Doug South (dsouth@squirrel.com.au) 21/3/97
-
- This parser assumes that the C source file has been preprocessed : all
- #includes have been included and all macros have been expanded. I accomplish
- this with "gcc -P -E <source file> > <output file>".
-
- There is a problem with compiler specific types, such as __signed, __const,
- __inline__, etc. These types can be added as typedef types before the parser
- is run on a file. See main() for an example. I have also found a strange little
- compiler specific "type" if you can call it that. It is __attribute__, but it
- does not seem to be used as a type. I found that just deleting the __attribute__
- and the following "offensive" code works.
-
- This grammar also prints out all the types defined while parsing the file. This
- is done via a call to printTypes() when the parser is complete. If you do not want
- this, just comment out the printTypes() method call in the production rule
- TranslationUnit(), which BTW is the root node for parsing a C source file.
-
- I have not in anyway extensively tested this grammar, in fact it is barely tested,
- but I imagine it is better to have a starting point for a C grammar other than from
- scratch. It has not been optimized in anyway, my main aim was to get a parser that
- works. Lookahead may not be optimum at choice points and may even be insufficient at
- times. I choose to err on the side of not optimum if I made a choice at all.
-
- If you use this grammar, I would appreciate hearing from you. I will try to maintain
- this grammar to the best of my ability, but at this point in time, this is only a side
- hobby (unless someone wants to pay me for doing JavaCC work!). In that regards, I am
- interested in hearing bugs and comments.
-
- TODO:
-
- Insert the appropriate code to enable C source trees from this grammar.
-
-=============================================
-3/2/06: Modified by Tom Copeland
-- STRING_LITERAL now handles embedded escaped newlines, thanks to J.Chris Findlay for the patch
-- Works with JavaCC 4.0
-- Preprocessor directives are now simply SKIP'd, so no need to run C files through GCC first
-
-31/8/10: Modified heavily by Christian Grothoff
-- No more tracking of type names (so we can run without preprocessing)
-- Support certain gcc-isms (unsigned long long, 33LL, etc.)
-- No support for certain older C constructs
-- Support for magic "GNUNET_PACKED" construct (extra "IDENTIFIER" in struct)
-
-8/11/10: Modified some more by Christian Grothoff
-- support for arguments without variable names (in particular, just 'void')
-- support for string concatenations
-*/
-
-PARSER_BEGIN(CParser)
-
-import java.util.*;
-
- public class CParser{
-
- // Run the parser
- public static void main ( String args [ ] ) {
- CParser parser ;
-
- if(args.length == 0){
- System.out.println("C Parser Version 0.1Alpha: Reading from standard input . . .");
- parser = new CParser(System.in);
- }
- else if(args.length == 1){
- System.out.println("C Parser Version 0.1Alpha: Reading from file " + args[0] + " . . ." );
- try {
- parser = new CParser(new java.io.FileInputStream(args[0]));
- }
- catch(java.io.FileNotFoundException e){
- System.out.println("C Parser Version 0.1: File " + args[0] + " not found.");
- return ;
- }
- }
- else {
- System.out.println("C Parser Version 0.1Alpha: Usage is one of:");
- System.out.println(" java CParser < inputfile");
- System.out.println("OR");
- System.out.println(" java CParser inputfile");
- return ;
- }
- try {
- parser.TranslationUnit();
- System.out.println("C Parser Version 0.1Alpha: Java program parsed successfully.");
- }
- catch(ParseException e){
- System.out.println("C Parser Version 0.1Alpha: Encountered errors during parse.");
- e.printStackTrace();
- }
- }
- }
-
-PARSER_END(CParser)
-
-SKIP : {
- " "
-| "\t"
-| "\n"
-| "\r"
-| <"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")>
-| <"/*" (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/">
-| "#" : PREPROCESSOR_OUTPUT
-}
-
-<PREPROCESSOR_OUTPUT> SKIP:
-{
- "\n" : DEFAULT
-}
-
-<PREPROCESSOR_OUTPUT> MORE:
-{
- "\\\n"
- |
- "\\\r\n"
- |
- < ~[] >
-}
-
-
-TOKEN : {
- <INTEGER_LITERAL: <DECIMAL_LITERAL> (["l","L"])? (["l","L"])? | <HEX_LITERAL> (["l","L"])? (["l","L"])? | <OCTAL_LITERAL> (["l","L"])? (["l","L"])?>
-| <#DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
-| <#HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+>
-| <#OCTAL_LITERAL: "0" (["0"-"7"])*>
-| <FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])? | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]>
-| <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+>
-|
- < CHARACTER_LITERAL:
- "'"
- ( (~["'","\\","\n","\r"])
- | ("\\"
- ( ["n","t","b","r","f","\\","'","\""]
- | ["0"-"7"] ( ["0"-"7"] )?
- | ["0"-"3"] ["0"-"7"] ["0"-"7"]
- )
- )
- )
- "'"
- >
-| < STRING_LITERAL:
- ("\""
- ( (~["\"","\\","\n","\r"])
- | ("\\"
- ( ["n","t","b","r","f","\\","'","\""]
- | ["0"-"7"] ( ["0"-"7"] )?
- | ["0"-"3"] ["0"-"7"] ["0"-"7"]
- )
- )
- )*
- "\"")+
- >
-}
-
-TOKEN : {
- <CONTINUE: "continue"> |
- <VOLATILE: "volatile"> |
- <REGISTER: "register"> |
- <UNSIGNED: "unsigned"> |
- <TYPEDEF: "typedef"> |
- <DFLT: "default"> |
- <DOUBLE: "double"> |
- <SIZEOF: "sizeof"> |
- <SWITCH: "switch"> |
- <RETURN: "return"> |
- <EXTERN: "extern"> |
- <STRUCT: "struct"> |
- <STATIC: "static"> |
- <SIGNED: "signed"> |
- <WHILE: "while"> |
- <BREAK: "break"> |
- <UNION: "union"> |
- <CONST: "const"> |
- <FLOAT: "float"> |
- <SHORT: "short"> |
- <ELSE: "else"> |
- <CASE: "case"> |
- <LONG: "long"> |
- <ENUM: "enum"> |
- <AUTO: "auto"> |
- <VOID: "void"> |
- <CHAR: "char"> |
- <GOTO: "goto"> |
- <FOR: "for"> |
- <INT: "int"> |
- <IF: "if"> |
- <DO: "do">
-}
-
-TOKEN : {
- <IDENTIFIER: <LETTER> (<LETTER> | <DIGIT>)*>
-| <#LETTER: ["$","A"-"Z","_","a"-"z"]>
-| <#DIGIT: ["0"-"9"]>
-}
-
-void TranslationUnit() : {}
-{
- (ExternalDeclaration())+
- <EOF>
-}
-
-void ExternalDeclaration() : {}
-{
- (StorageClassSpecifier())*
- (
- LOOKAHEAD (FunctionDeclaration()) FunctionDeclaration() |
- LOOKAHEAD (StructOrUnionSpecifier() ";") StructOrUnionSpecifier() ";" |
- LOOKAHEAD (EnumSpecifier() ";") EnumSpecifier() ";" |
- LOOKAHEAD (VariableDeclaration()) VariableDeclaration() |
- LOOKAHEAD (TypeDeclaration()) TypeDeclaration ()
- )
-}
-
-void FunctionDeclaration() : {}
-{
- TypeSpecifier ()
- <IDENTIFIER>
- "(" [ ParameterList () ] ")"
- ( ";" | CompoundStatement() )
-}
-
-void StorageClassSpecifier() : {}
-{
- ( <STATIC> | <EXTERN> )
-}
-
-void TypeDeclaration() : {}
-{
- <TYPEDEF>
- ( LOOKAHEAD (DataType() ";") DataType () | FunctionType() ) ";"
-}
-
-void DataType() : {}
-{
- StructOrUnionSpecifier () <IDENTIFIER>
-}
-
-void FunctionType() : {}
-{
- TypeSpecifier () "(" "*" <IDENTIFIER> ")" "(" [ ParameterList() ] ")"
-}
-
-void ParameterList() : {}
-{
- ParameterDeclaration() ( LOOKAHEAD (2) "," ParameterDeclaration() )* [ "," "..." ]
-}
-
-void ParameterDeclaration() : {}
-{
- TypeSpecifier() [<IDENTIFIER> [ Array () ]]
-}
-
-void VariableDeclaration() : {}
-{
- VariableClassSpecifier ()
- TypeSpecifier ()
- InitDeclaratorList() ";"
-}
-
-void LocalVariableDeclaration() : {}
-{
- [ <STATIC> ] VariableDeclaration ()
-}
-
-void VariableClassSpecifier() : {}
-{
- ( <AUTO> | <REGISTER> )*
-}
-
-void TypeSpecifier() : {}
-{
- [ <CONST> ]
- ( <VOID>
- | <CHAR>
- | <SHORT> [ <INT> ]
- | <INT>
- | <LONG> [ <LONG> ]
- | <FLOAT> | <DOUBLE>
- | (<SIGNED> | <UNSIGNED>) [ <CHAR>
- | <SHORT> [ <INT> ]
- | <INT>
- | <LONG> [ <LONG> ] ]
- | StructOrUnionSpecifier()
- | EnumSpecifier()
- | <IDENTIFIER>
- )
- [ Pointer () ]
- [ Array () ]
-}
-
-/* this is needed for 'va_arg' where a type is an argument
- -- and we cannot disambiguate the use of 'FOO'
- after a 'typedef int FOO' from the variable 'FOO';
- hence this hack */
-void NoIdentifierTypeSpecifier() : {}
-{
- [ <CONST> ]
- ( <VOID>
- | <CHAR>
- | <SHORT> [ <INT> ]
- | <INT>
- | <LONG> [ <LONG> ]
- | <FLOAT> | <DOUBLE>
- | (<SIGNED> | <UNSIGNED>) [ <CHAR>
- | <SHORT> [ <INT> ]
- | <INT>
- | <LONG> [ <LONG> ] ]
- | StructOrUnionSpecifier()
- | EnumSpecifier()
- )
- [ Pointer () ]
- [ Array () ]
-}
-
-void StructOrUnionSpecifier() : {}
-{
- LOOKAHEAD (3)
- StructOrUnion() [ <IDENTIFIER> ] "{" StructDeclarationList() "}" |
- StructOrUnion() <IDENTIFIER>
-}
-
-void StructOrUnion() : {}
-{
- ( <STRUCT> | <UNION> )
-}
-
-void StructDeclarationList() : {}
-{
- (StructDeclaration())*
-}
-
-void InitDeclaratorList() : {}
-{
- InitDeclarator() ("," InitDeclarator())*
-}
-
-void InitDeclarator() : {}
-{
- <IDENTIFIER> [ Array () ] [ "=" Initializer() ]
-}
-
-void StructDeclaration() : {}
-{
- TypeSpecifier() <IDENTIFIER> [ Array() | ":" ConstantExpression() ] [ <IDENTIFIER> ] ";"
-}
-
-void EnumSpecifier() : {}
-{
- <ENUM> ( LOOKAHEAD(3) [ <IDENTIFIER> ] "{" EnumeratorList() "}" | <IDENTIFIER> )
-}
-
-void EnumeratorList() : {}
-{
- Enumerator() ("," Enumerator())*
-}
-
-void Enumerator() : {}
-{
- <IDENTIFIER> [ "=" ConstantExpression() ]
-}
-
-void Pointer() : {}
-{
- "*" [ <CONST> ] [ Pointer() ]
-}
-
-void Initializer() : {}
-{
- ( AssignmentExpression() |
- "{" InitializerList() [","] "}" )
-}
-
-void InitializerList() : {}
-{
- Initializer() (LOOKAHEAD(2) "," Initializer())*
-}
-
-
-void Array() : {}
-{
- ("[" [ConstantExpression()] "]" )+
-}
-
-void Statement() : {}
-{
- ( LOOKAHEAD(2) LabeledStatement() |
- ExpressionStatement() |
- CompoundStatement() |
- SelectionStatement() |
- IterationStatement() |
- JumpStatement() )
-}
-
-void LabeledStatement() : {}
-{
- ( <IDENTIFIER> ":" Statement() |
- <CASE> ConstantExpression() ":" Statement() |
- <DFLT> ":" Statement() )
-}
-
-void ExpressionStatement() : {}
-{
- [ Expression() ] ";"
-}
-
-void CompoundStatement() : {}
-{
- "{" ( LOOKAHEAD (LocalVariableDeclaration()) LocalVariableDeclaration () |
- Statement() )*
- "}"
-}
-
-void SelectionStatement() : {}
-{
- ( IfStatement() | SwitchStatement() )
-}
-
-void IfStatement() : {}
-{
- <IF> "(" Expression() ")" Statement() [ LOOKAHEAD(2) <ELSE> Statement() ]
-}
-
-void SwitchStatement() : {}
-{
- <SWITCH> "(" Expression() ")" Statement()
-}
-
-void IterationStatement() : {}
-{
- ( WhileStatement() | DoWhileStatement() | ForStatement() )
-}
-void WhileStatement() : {}
-{
- <WHILE> "(" Expression() ")" Statement()
-}
-void DoWhileStatement() : {}
-{
- <DO> Statement() <WHILE> "(" Expression() ")" ";"
-}
-void ForStatement() : {}
-{
- <FOR> "(" [ Expression() ] ";" [ Expression() ] ";" [ Expression() ] ")" Statement()
-}
-
-void JumpStatement() : {}
-{
- ( <GOTO> <IDENTIFIER> ";" |
- <CONTINUE> ";" |
- <BREAK> ";" |
- <RETURN> [ Expression() ] ";" )
-}
-
-void Expression() : {}
-{
- AssignmentExpression() ( "," AssignmentExpression() )*
-}
-
-void AssignmentExpression() : {}
-{
- LOOKAHEAD(UnaryExpression() AssignmentOperator()) UnaryExpression() AssignmentOperator() AssignmentExpression() |
- LOOKAHEAD(3) ConditionalExpression()
-}
-
-void AssignmentOperator() : {}
-{
- ( "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" )
-}
-
-void ConditionalExpression() : {}
-{
- LogicalORExpression() [ "?" Expression() ":" ConditionalExpression() ]
-}
-
-void ConstantExpression() : {}
-{
- ConditionalExpression()
-}
-
-void LogicalORExpression() : {}
-{
- LogicalANDExpression() [ "||" LogicalORExpression() ]
-}
-
-void LogicalANDExpression() : {}
-{
- InclusiveORExpression() [ "&&" LogicalANDExpression() ]
-}
-
-void InclusiveORExpression() : {}
-{
- ExclusiveORExpression() [ "|" InclusiveORExpression() ]
-}
-
-void ExclusiveORExpression() : {}
-{
- ANDExpression() [ "^" ExclusiveORExpression() ]
-}
-
-void ANDExpression() : {}
-{
- EqualityExpression() [ "&" ANDExpression() ]
-}
-
-void EqualityExpression() : {}
-{
- RelationalExpression() [ ( "==" | "!=" ) EqualityExpression() ]
-}
-
-void RelationalExpression() : {}
-{
- ShiftExpression() [ ( "<" | ">" | "<=" | ">=" ) RelationalExpression() ]
-}
-
-void ShiftExpression() : {}
-{
- AdditiveExpression() [ ( "<<" | ">>" ) ShiftExpression() ]
-}
-
-void AdditiveExpression() : {}
-{
- MultiplicativeExpression() [ ( "+" | "-" ) AdditiveExpression() ]
-}
-
-void MultiplicativeExpression() : {}
-{
- CastExpression() [ ( "*" | "/" | "%" ) MultiplicativeExpression() ]
-}
-
-void CastExpression() : {}
-{
- ( LOOKAHEAD("(" TypeSpecifier() ")" CastExpression() ) "(" TypeSpecifier() ")" CastExpression() |
- UnaryExpression() )
-}
-
-void UnaryExpression() : {}
-{
- ( LOOKAHEAD(3) PostfixExpression() |
- "++" UnaryExpression() |
- "--" UnaryExpression() |
- UnaryOperator() CastExpression() |
- <SIZEOF> ( LOOKAHEAD(UnaryExpression() ) UnaryExpression() | "(" TypeSpecifier() ")" ) )
-}
-
-void UnaryOperator() : {}
-{
- ( "&" | "*" | "+" | "-" | "~" | "!" )
-}
-
-void PostfixExpression() : {}
-{
- PrimaryExpression() ( "[" Expression() "]" |
- "(" [ LOOKAHEAD(ArgumentExpressionList() ) ArgumentExpressionList() ] ")" |
- "." <IDENTIFIER> |
- "->" <IDENTIFIER> |
- "++" |
- "--" )*
-}
-
-void PrimaryExpression() : {}
-{
- <IDENTIFIER> |
- Constant() |
- "(" Expression() ")"
-}
-
-void ArgumentExpressionList() : {}
-{
- AssignmentOrTypeExpression() ( "," AssignmentOrTypeExpression() )*
-}
-
-
-void AssignmentOrTypeExpression() : {}
-{
- NoIdentifierTypeSpecifier() |
- AssignmentExpression()
-}
-
-void Constant() : {}
-{
- <INTEGER_LITERAL> |
- <FLOATING_POINT_LITERAL> |
- <CHARACTER_LITERAL> |
- (<STRING_LITERAL>)+
-}
-
+++ /dev/null
-all:
- jtb C.jj
- javacc C.out.jj
- javac -nowarn -classpath ../../../contrib/antlr-runtime-3.1.3.jariantlr-runtime-3.1.3.jarantlr-runtime-3.1.3.jar:../../../contrib/sqljet.1.0.3.b914.jar `find * -name "*.java"`
- jar -cvf seaspider.jar `find * -name "*.class"`
+++ /dev/null
-/**
- * @file src/monkey/seaspider/SeaspiderTest.c
- * @brief C file to test Seaspider's parsing
- */
-
-/* include */
-#include <stdio.h>
-
-
-#define PRE_PROC_DIR 0
-#define MACRO_fun(arg1, arg2) (arg1 + arg2)
-
-struct MyStruct {
- int member;
- struct MyStruct *part;
-};
-
-
-enum MyEnum{
- enumMember1,
- enumMember2,
- enumMember3
-};
-
-
-static int fun(int arg1, int arg2)
-{
- return arg1 + arg2;
-}
-
-
-int main(int args, const char * argv[])
-{
- /* variables declarations */
- struct MyStruct whole;
- struct MyStruct part;
- enum MyEnum myEnum;
- int i;
- int x, y;
-
- /* Allocations and assignments */
- whole.member = 1;
- whole.part = ∂
- whole.part->member = 2;
- myEnum = enumMember3;
- x = 0, y = 1;
-
- /* block */
- {
- /* arithmetic and logic operations */
- float f = 20.0;
- whole.part->member = (int)(whole.part->member + 5) - 6; // cast - multilevel assignment
- }
-
- /* for loop */
- for (i = 0; i < 2; i++) {
- /* conditional expressions */
- if ( x > 0) {
- while (y < 5) {
- y++;
- }
- } else if (x > 0 || y == 4) {
- do {
- y--;
- } while (y != 1);
- }
- else {
- switch (myEnum) {
- case enumMember1:
- fun(enumMember1, enumMember2);
- break;
- case enumMember2:
- fun(enumMember1, enumMember2 ? enumMember2 : enumMember1); // ternary operator
- break;
- default:
- MACRO_fun(enumMember1, PRE_PROC_DIR); // preprocessing directive
- break;
- }
- }
- }
-
- return 1;
-}
+++ /dev/null
-package org.gnunet.seaspider;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Stack;
-import org.tmatesoft.sqljet.core.SqlJetException;
-import org.tmatesoft.sqljet.core.SqlJetTransactionMode;
-import org.tmatesoft.sqljet.core.table.ISqlJetTable;
-import org.tmatesoft.sqljet.core.table.SqlJetDb;
-
-/**
- * ExpressionDatabaseHandler is fed by expressions from the C code parser, and
- * inserts them into SQLite Expression database using SQLJet API. Before
- * inserting an expression into the database, ExpressionDatabaseHandler makes
- * sure it's not redundant.
- * For example:
- * int x = 0;
- * int y = 1;
- * int z = x + y // line 3
- * The parser input for line 3 is: z, x, y, x + y, and z = x + y The
- * expressions to be committed to the database will be only: z, and z = x + y
- */
-public class ExpressionDatabaseHandler {
-
- private static final boolean DEBUG = false;
-
- private static final boolean PRINT_STACK = false;
-
- private static SqlJetDb db;
-
- private static ISqlJetTable table;
-
- private static String currentFileName = null;
-
- private static int currentScopeEnd = 0;
-
- private static Stack<HashMap<String, Integer>> expressionStack = new Stack<HashMap<String, Integer>>();
-
- public static void createExpressionDatabase(String databasePath) {
- String createTableQuery = "CREATE TABLE Expression ( expr_ID INTEGER PRIMARY KEY AUTOINCREMENT, "
- + "file_name TEXT NOT NULL , expr_syntax TEXT NOT NULL ,"
- + " start_lineno INT, end_lineno INT)";
-
- File dbFile = new File(databasePath);
- dbFile.delete();/* Delete it if already existent */
-
- /* Create Expressions database */
- try {
- db = SqlJetDb.open(dbFile, true);
- db.getOptions().setAutovacuum(true);
- db.beginTransaction(SqlJetTransactionMode.WRITE);
- try {
- db.getOptions().setUserVersion(1);/* Sets the user's cookie */
- } finally {
- db.commit();
- }
- /* Create table Expression */
- db.createTable(createTableQuery);
- db.beginTransaction(SqlJetTransactionMode.WRITE);
- table = db.getTable("Expression");
- } catch (SqlJetException e) {
- e.printStackTrace();
- }
- }
-
- public static void closeDatabase() {
- try {
- db.commit();
- db.close();
- } catch (SqlJetException e) {
- e.printStackTrace();
- }
- }
-
- private static void doInsertExpression(String fileName,
- String expressionSyntax, int startLineNo, int endLineNo) {
- try {
- if (DEBUG)
- System.out.println(fileName + ":[" + startLineNo + "-"
- + endLineNo + "]: " + expressionSyntax);
- table.insert(null, currentFileName, expressionSyntax, startLineNo,
- endLineNo);
- } catch (SqlJetException e) {
- e.printStackTrace();
- }
- }
-
- private static boolean isRedundant(String expressionSyntax) {
- Iterator<HashMap<String, Integer>> itr = expressionStack.iterator();
- HashMap<String, Integer> scope;
-
- while (itr.hasNext()) {
- scope = itr.next();
- if (null != scope.get(expressionSyntax))
- return true;
- }
-
- return false;
- }
-
- private static int getScopeEnd(HashMap<String, Integer> scope) {
- Iterator<Integer> itr = scope.values().iterator();
- return itr.next();
- }
-
- private static HashMap<String, Integer> pushNewScope(int endLineNo) {
- HashMap<String, Integer> scope = new HashMap<String, Integer>();
- currentScopeEnd = endLineNo;
- expressionStack.push(scope);
-
- return scope;
- }
-
- private static void printExpressionStack(String expressionSyntax,
- int startLineNo, int endLineNo) {
- HashMap<String, Integer> hashMap;
- Iterator<String> itr;
- System.out.println("Commit call for expression: " + expressionSyntax
- + " start:" + startLineNo + " end:" + endLineNo);
- for (int i = 0; i < expressionStack.size(); i++) {
- hashMap = expressionStack.get(i);
- itr = hashMap.keySet().iterator();
- System.out.println("Printing expressions of scope " + i + ":");
- while (itr.hasNext()) {
- System.out.println(itr.next());
- }
- }
- System.out.println("");
- }
-
- private static void insertExpression(String fileName,
- String expressionSyntax, int startLineNo, int endLineNo) {
-
- HashMap<String, Integer> currentScopeExpressions = null;
-
- if (PRINT_STACK)
- printExpressionStack(expressionSyntax, startLineNo, endLineNo);
-
- if (null == currentFileName || !currentFileName.equals(fileName)) {
- /* First time, or new file */
- currentFileName = fileName;
- if (!expressionStack.empty())
- expressionStack.clear();
- currentScopeExpressions = pushNewScope(endLineNo);
- } else {
- if (endLineNo > currentScopeEnd) {
- /*
- * We are either in a new function or back to an outer scope
- */
- expressionStack.pop();
- if (expressionStack.empty()) {
- /* We are in a new function */
- currentScopeExpressions = pushNewScope(endLineNo);
- } else {
- /* We just left an inner scope to an outer one */
- currentScopeExpressions = expressionStack.lastElement();
- currentScopeEnd = getScopeEnd(currentScopeExpressions);
- if (isRedundant(expressionSyntax))
- return;
- }
- } else {
- /* Either we delved into a sub-scope or we are in the same scope */
- if (isRedundant(expressionSyntax))
- return;
- if (endLineNo == currentScopeEnd) // same scope
- currentScopeExpressions = expressionStack.lastElement();
- else
- // new sub-scope
- currentScopeExpressions = pushNewScope(endLineNo);
- }
- }
-
- /* Add the new expression */
- currentScopeExpressions.put(expressionSyntax, endLineNo);
- doInsertExpression(fileName, expressionSyntax, startLineNo, endLineNo);
- }
-
- /**
- * Inserts expression into the Expression Database
- *
- * @param fileName source file the expression comes from
- * @param expressionSyntax string of the expression
- * @param startLineNo line number of the expression
- * @param endLineNo end line of the expression scope
- */
- public static void insertIntoExpressionTable(String fileName,
- String expressionSyntax, int startLineNo, int endLineNo) {
- if (expressionSyntax.matches("[0-9]*"))
- return;
- if (expressionSyntax.startsWith("\""))
- return;
- if (db == null) {
- System.out
- .println("Error:Database handle is not initialized. Program will exit now!");
- System.exit(1);
- }
-
- String[] fileNameArr = fileName.split("src/");
- if (fileNameArr.length > 1)
- fileName = fileNameArr[1];
- insertExpression(fileName, expressionSyntax, startLineNo, endLineNo);
- }
-}
+++ /dev/null
-package org.gnunet.seaspider;
-
-import org.gnunet.seaspider.parser.nodes.ANDExpression;
-import org.gnunet.seaspider.parser.nodes.AdditiveExpression;
-import org.gnunet.seaspider.parser.nodes.ArgumentExpressionList;
-import org.gnunet.seaspider.parser.nodes.AssignmentExpression;
-import org.gnunet.seaspider.parser.nodes.AssignmentOperator;
-import org.gnunet.seaspider.parser.nodes.CastExpression;
-import org.gnunet.seaspider.parser.nodes.CompoundStatement;
-import org.gnunet.seaspider.parser.nodes.ConditionalExpression;
-import org.gnunet.seaspider.parser.nodes.ConstantExpression;
-import org.gnunet.seaspider.parser.nodes.DoWhileStatement;
-import org.gnunet.seaspider.parser.nodes.EqualityExpression;
-import org.gnunet.seaspider.parser.nodes.ExclusiveORExpression;
-import org.gnunet.seaspider.parser.nodes.Expression;
-import org.gnunet.seaspider.parser.nodes.ExpressionStatement;
-import org.gnunet.seaspider.parser.nodes.ForStatement;
-import org.gnunet.seaspider.parser.nodes.FunctionDeclaration;
-import org.gnunet.seaspider.parser.nodes.IfStatement;
-import org.gnunet.seaspider.parser.nodes.InclusiveORExpression;
-import org.gnunet.seaspider.parser.nodes.InitDeclarator;
-import org.gnunet.seaspider.parser.nodes.InitDeclaratorList;
-import org.gnunet.seaspider.parser.nodes.Initializer;
-import org.gnunet.seaspider.parser.nodes.InitializerList;
-import org.gnunet.seaspider.parser.nodes.JumpStatement;
-import org.gnunet.seaspider.parser.nodes.LogicalANDExpression;
-import org.gnunet.seaspider.parser.nodes.LogicalORExpression;
-import org.gnunet.seaspider.parser.nodes.MultiplicativeExpression;
-import org.gnunet.seaspider.parser.nodes.Node;
-import org.gnunet.seaspider.parser.nodes.NodeChoice;
-import org.gnunet.seaspider.parser.nodes.NodeSequence;
-import org.gnunet.seaspider.parser.nodes.NodeToken;
-import org.gnunet.seaspider.parser.nodes.ParameterDeclaration;
-import org.gnunet.seaspider.parser.nodes.PostfixExpression;
-import org.gnunet.seaspider.parser.nodes.PrimaryExpression;
-import org.gnunet.seaspider.parser.nodes.RelationalExpression;
-import org.gnunet.seaspider.parser.nodes.ShiftExpression;
-import org.gnunet.seaspider.parser.nodes.StructOrUnionSpecifier;
-import org.gnunet.seaspider.parser.nodes.SwitchStatement;
-import org.gnunet.seaspider.parser.nodes.TranslationUnit;
-import org.gnunet.seaspider.parser.nodes.TypeDeclaration;
-import org.gnunet.seaspider.parser.nodes.UnaryExpression;
-import org.gnunet.seaspider.parser.nodes.UnaryOperator;
-import org.gnunet.seaspider.parser.nodes.VariableDeclaration;
-import org.gnunet.seaspider.parser.nodes.WhileStatement;
-import org.gnunet.seaspider.parser.visitors.DepthFirstVisitor;
-import org.grothoff.LineNumberInfo;
-
-/**
- * @author grothoff
- *
- */
-public class ExpressionExtractorVisitor extends DepthFirstVisitor {
-
- class ExpressionBuilder {
- String expression = "";
-
- void push(String token) {
- expression = expression + token;
- }
-
- void commit(int line) {
- ExpressionDatabaseHandler.insertIntoExpressionTable(filename,
- expression, line, scope_end_line);
- }
-
- }
-
- final String filename;
-
- ExpressionBuilder current_expression;
-
- int scope_end_line;
-
- boolean operator;
-
- boolean skip_mode = true;
-
- /**
- *
- */
- public ExpressionExtractorVisitor(String filename) {
- this.filename = filename;
- }
-
- public void visit(TranslationUnit n) {
- LineNumberInfo lin = LineNumberInfo.get(n);
- scope_end_line = lin.lineEnd;
- n.f0.accept(this);
- assert scope_end_line == lin.lineEnd;
- }
-
- public void visit(NodeToken n) {
- if (skip_mode)
- return;
- current_expression.push(n.tokenImage);
- }
-
- public void visit(StructOrUnionSpecifier n) {
- // do nothing -- skip!
- }
-
- public void visit(TypeDeclaration n) {
- // do nothing -- skip!
- }
-
- public void visit(InitDeclaratorList n) {
- assert skip_mode == true;
- super.visit(n);
- assert skip_mode == true;
- }
-
- public void visit(Initializer n) {
- assert skip_mode == true;
- if (n.f0.which == 0) {
- boolean old_mode = skip_mode;
- skip_mode = false;
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- LineNumberInfo lin = LineNumberInfo.get(n);
- if (old != null) {
- old.push(current_expression.expression);
- old.commit(lin.lineEnd);
- } else {
- current_expression.commit(lin.lineEnd);
- }
- current_expression = old;
- skip_mode = old_mode;
- } else {
- super.visit(n);
- }
- assert skip_mode == true;
- }
-
- public void visit(InitializerList n) {
- assert skip_mode == true;
- super.visit(n);
- assert skip_mode == true;
- }
-
- public void visit(VariableDeclaration n) {
- assert skip_mode == true;
- super.visit(n);
- }
-
- public void visit(FunctionDeclaration n) {
- if (n.f5.which == 0)
- return; // no body
- int old_scope = scope_end_line;
- LineNumberInfo lin = LineNumberInfo.get(n);
- scope_end_line = lin.lineEnd;
- n.f3.accept(this);
- n.f5.accept(this);
- assert scope_end_line == lin.lineEnd;
- scope_end_line = old_scope;
- }
-
- public void visit(ParameterDeclaration n) {
- skip_mode = false;
- assert current_expression == null;
- if (n.f1.present()) {
- NodeSequence ns = (NodeSequence) n.f1.node;
- Node var = ns.elementAt(0);
- current_expression = new ExpressionBuilder();
- var.accept(this);
- LineNumberInfo lin = LineNumberInfo.get(var);
- current_expression.commit(lin.lineEnd);
- }
- current_expression = null;
- skip_mode = true;
- }
-
- public void visit(InitDeclarator n) {
- skip_mode = false;
- assert current_expression == null;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- current_expression = null;
- skip_mode = true;
- n.f2.accept(this);
- }
-
- public void visit(ExpressionStatement n) {
- if (!n.f0.present())
- return;
- assert current_expression == null;
- skip_mode = false;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- LineNumberInfo lin = LineNumberInfo.get(n);
- current_expression.commit(lin.lineEnd);
- current_expression = null;
- skip_mode = true;
- }
-
- public void visit(CompoundStatement n) {
- assert current_expression == null;
- assert skip_mode == true;
- int old_end = scope_end_line;
- scope_end_line = n.f2.endLine;
- n.f1.accept(this);
- scope_end_line = old_end;
- }
-
- public void visit(SwitchStatement n) {
- assert current_expression == null;
- skip_mode = false;
- current_expression = new ExpressionBuilder();
- n.f2.accept(this);
- current_expression.commit(n.f0.endLine);
- skip_mode = true;
- current_expression = null;
- n.f4.accept(this);
- }
-
- public void visit(IfStatement n) {
- assert current_expression == null;
- skip_mode = false;
- current_expression = new ExpressionBuilder();
- n.f2.accept(this);
- current_expression.commit(n.f0.endLine);
- skip_mode = true;
- current_expression = null;
- n.f4.accept(this);
- n.f5.accept(this);
- }
-
- public void visit(WhileStatement n) {
- assert current_expression == null;
- skip_mode = false;
- current_expression = new ExpressionBuilder();
- n.f2.accept(this);
- current_expression.commit(n.f0.endLine);
- skip_mode = true;
- current_expression = null;
- n.f4.accept(this);
- }
-
- public void visit(DoWhileStatement n) {
- assert current_expression == null;
- skip_mode = false;
- current_expression = new ExpressionBuilder();
- n.f4.accept(this);
- current_expression.commit(n.f6.endLine);
- skip_mode = true;
- current_expression = null;
- n.f1.accept(this);
- }
-
- public void visit(ForStatement n) {
- assert current_expression == null;
- skip_mode = false;
- int old_scope = scope_end_line;
- LineNumberInfo lin = LineNumberInfo.get(n);
- scope_end_line = lin.lineEnd;
- if (n.f2.present()) {
- current_expression = new ExpressionBuilder();
- n.f2.accept(this);
- current_expression.commit(n.f3.endLine);
- }
- if (n.f4.present()) {
- current_expression = new ExpressionBuilder();
- n.f4.accept(this);
- current_expression.commit(n.f5.endLine);
- }
- if (n.f6.present()) {
- current_expression = new ExpressionBuilder();
- n.f6.accept(this);
- current_expression.commit(n.f7.endLine);
- }
- skip_mode = true;
- current_expression = null;
- n.f8.accept(this);
- scope_end_line = old_scope;
- }
-
- public void visit(JumpStatement n) {
- if (n.f0.which != 3)
- return;
- NodeSequence ns = (NodeSequence) n.f0.choice;
- assert current_expression == null;
- skip_mode = false;
- current_expression = new ExpressionBuilder();
- ns.elementAt(1).accept(this);
- LineNumberInfo lin = LineNumberInfo.get(n);
- current_expression.commit(lin.lineEnd);
- current_expression = null;
- skip_mode = true;
- }
-
- public void visit(Expression n) {
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- for (int i = 0; i < n.f1.size(); i++) {
- NodeSequence ns = (NodeSequence) n.f1.elementAt(i);
- current_expression = new ExpressionBuilder();
- ns.elementAt(1).accept(this);
- }
- old.push(current_expression.expression);
- current_expression = old;
- }
-
- public void visit(AssignmentOperator n) {
- operator = true;
- super.visit(n);
- operator = false;
- }
-
- public void visit(AssignmentExpression n)
- {
- if (0 == n.f0.which)
- {
- NodeSequence ns = (NodeSequence) n.f0.choice;
- UnaryExpression u = (UnaryExpression) ns.elementAt(0);
- AssignmentOperator ao = (AssignmentOperator) ns.elementAt(1);
- AssignmentExpression ae = (AssignmentExpression) ns.elementAt(2);
- LineNumberInfo lin = LineNumberInfo.get(n);
-
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- u.accept(this);
- current_expression.commit(lin.lineEnd);
- ao.accept (this);
- old.push(current_expression.expression);
- current_expression = new ExpressionBuilder();
- ae.accept(this);
- current_expression.commit(lin.lineEnd);
- old.push(current_expression.expression);
- current_expression = old;
- }
- else
- {
- n.f0.choice.accept (this);
- }
- }
-
- public void visit(ConditionalExpression n) {
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- old.push(current_expression.expression);
- if (n.f1.present()) {
- LineNumberInfo lin = LineNumberInfo.get(n);
- NodeSequence ns = (NodeSequence) n.f1.node;
- current_expression = new ExpressionBuilder();
- ns.elementAt(1).accept(this);
- current_expression.commit(lin.lineEnd);
- old.push("?");
- old.push(current_expression.expression);
- current_expression = new ExpressionBuilder();
- ns.elementAt(3).accept(this);
- current_expression.commit(lin.lineEnd);
- old.push(":");
- old.push(current_expression.expression);
- old.commit(lin.lineEnd);
- }
- current_expression = old;
- }
-
- public void visit(ConstantExpression n) {
- /* skip */
- }
-
- public void visit(LogicalORExpression n) {
- assert skip_mode == false;
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- if (n.f1.present()) {
- LineNumberInfo lin = LineNumberInfo.get(n);
- current_expression.commit(lin.lineEnd);
- operator = true;
- NodeSequence ns = (NodeSequence) n.f1.node;
- ns.nodes.get(0).accept(this);
- operator = false;
- old.push(current_expression.expression);
- current_expression = new ExpressionBuilder();
- ns.nodes.get(1).accept(this);
- current_expression.commit(lin.lineEnd);
- }
- old.push(current_expression.expression);
- current_expression = old;
- }
-
- public void visit(LogicalANDExpression n) {
- assert skip_mode == false;
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- if (n.f1.present()) {
- LineNumberInfo lin = LineNumberInfo.get(n);
- current_expression.commit(lin.lineEnd);
- operator = true;
- NodeSequence ns = (NodeSequence) n.f1.node;
- ns.nodes.get(0).accept(this);
- operator = false;
- old.push(current_expression.expression);
- current_expression = new ExpressionBuilder();
- ns.nodes.get(1).accept(this);
- current_expression.commit(lin.lineEnd);
- }
- old.push(current_expression.expression);
- current_expression = old;
- }
-
- public void visit(InclusiveORExpression n) {
- assert skip_mode == false;
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- if (n.f1.present()) {
- LineNumberInfo lin = LineNumberInfo.get(n.f0);
- current_expression.commit(lin.lineEnd);
- operator = true;
- NodeSequence ns = (NodeSequence) n.f1.node;
- ns.nodes.get(0).accept(this);
- operator = false;
- ExpressionBuilder tmp = current_expression;
- current_expression = new ExpressionBuilder();
- ns.nodes.get(1).accept(this);
- lin = LineNumberInfo.get(ns.nodes.get(1));
- current_expression.commit(lin.lineEnd);
- tmp.push (current_expression.expression);
- current_expression = tmp;
- }
- old.push(current_expression.expression);
- current_expression = old;
- }
-
- public void visit(ExclusiveORExpression n) {
- assert skip_mode == false;
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- if (n.f1.present()) {
- LineNumberInfo lin = LineNumberInfo.get(n.f0);
- current_expression.commit(lin.lineEnd);
- operator = true;
- NodeSequence ns = (NodeSequence) n.f1.node;
- ns.nodes.get(0).accept(this);
- operator = false;
- ExpressionBuilder tmp = current_expression;
- current_expression = new ExpressionBuilder();
- ns.nodes.get(1).accept(this);
- lin = LineNumberInfo.get(ns.nodes.get(1));
- current_expression.commit(lin.lineEnd);
- tmp.push (current_expression.expression);
- current_expression = tmp;
- }
- old.push(current_expression.expression);
- current_expression = old;
- }
-
- public void visit(ANDExpression n) {
- assert skip_mode == false;
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- if (n.f1.present()) {
- LineNumberInfo lin = LineNumberInfo.get(n.f0);
- current_expression.commit(lin.lineEnd);
- operator = true;
- NodeSequence ns = (NodeSequence) n.f1.node;
- ns.nodes.get(0).accept(this);
- operator = false;
- ExpressionBuilder tmp = current_expression;
- current_expression = new ExpressionBuilder();
- ns.nodes.get(1).accept(this);
- lin = LineNumberInfo.get(ns.nodes.get(1));
- current_expression.commit(lin.lineEnd);
- tmp.push (current_expression.expression);
- current_expression = tmp;
- }
- old.push(current_expression.expression);
- current_expression = old;
- }
-
- // Safey: this function was fixed to commit the right hand side, the
- // other similar functions still need to be updated accordingly...
- public void visit(EqualityExpression n) {
- assert skip_mode == false;
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- if (n.f1.present()) {
- LineNumberInfo lin = LineNumberInfo.get(n);
- current_expression.commit(lin.lineEnd);
- operator = true;
- NodeSequence ns = (NodeSequence) n.f1.node;
- ns.nodes.get(0).accept(this);
- operator = false;
- old.push(current_expression.expression);
- current_expression = new ExpressionBuilder();
- ns.nodes.get(1).accept(this);
- current_expression.commit(lin.lineEnd);
- }
- old.push(current_expression.expression);
- current_expression = old;
- }
-
- public void visit(RelationalExpression n) {
- assert skip_mode == false;
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- if (n.f1.present()) {
- LineNumberInfo lin = LineNumberInfo.get(n);
- current_expression.commit(lin.lineEnd);
- operator = true;
- NodeSequence ns = (NodeSequence) n.f1.node;
- ns.nodes.get(0).accept(this);
- operator = false;
- old.push(current_expression.expression);
- current_expression = new ExpressionBuilder();
- ns.nodes.get(1).accept(this);
- current_expression.commit(lin.lineEnd);
- }
- old.push(current_expression.expression);
- current_expression = old;
- }
-
- public void visit(ShiftExpression n) {
- assert skip_mode == false;
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- if (n.f1.present()) {
- LineNumberInfo lin = LineNumberInfo.get(n.f0);
- current_expression.commit(lin.lineEnd);
- operator = true;
- NodeSequence ns = (NodeSequence) n.f1.node;
- ns.nodes.get(0).accept(this);
- operator = false;
- ExpressionBuilder tmp = current_expression;
- current_expression = new ExpressionBuilder();
- ns.nodes.get(1).accept(this);
- lin = LineNumberInfo.get(ns.nodes.get(1));
- current_expression.commit(lin.lineEnd);
- tmp.push (current_expression.expression);
- current_expression = tmp;
- }
- old.push(current_expression.expression);
- current_expression = old;
- }
-
- public void visit(AdditiveExpression n) {
- assert skip_mode == false;
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- if (n.f1.present()) {
- LineNumberInfo lin = LineNumberInfo.get(n.f0);
- current_expression.commit(lin.lineEnd);
- operator = true;
- NodeSequence ns = (NodeSequence) n.f1.node;
- ns.nodes.get(0).accept(this);
- operator = false;
- ExpressionBuilder tmp = current_expression;
- current_expression = new ExpressionBuilder();
- ns.nodes.get(1).accept(this);
- lin = LineNumberInfo.get(ns.nodes.get(1));
- current_expression.commit(lin.lineEnd);
- tmp.push (current_expression.expression);
- current_expression = tmp;
- }
- old.push(current_expression.expression);
- current_expression = old;
- }
-
- public void visit(MultiplicativeExpression n) {
- assert skip_mode == false;
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- if (n.f1.present()) {
- LineNumberInfo lin = LineNumberInfo.get(n.f0);
- current_expression.commit(lin.lineEnd);
- operator = true;
- NodeSequence ns = (NodeSequence) n.f1.node;
- ns.nodes.get(0).accept(this);
- operator = false;
- ExpressionBuilder tmp = current_expression;
- current_expression = new ExpressionBuilder();
- ns.nodes.get(1).accept(this);
- lin = LineNumberInfo.get(ns.nodes.get(1));
- current_expression.commit(lin.lineEnd);
- tmp.push (current_expression.expression);
- current_expression = tmp;
- }
- old.push(current_expression.expression);
- current_expression = old;
- }
-
- public void visit(CastExpression n) {
- if (n.f0.which == 1) {
- n.f0.accept(this);
- return;
- }
- NodeSequence ns = (NodeSequence) n.f0.choice;
- ns.nodes.get(3).accept(this);
- }
-
- public void visit(UnaryExpression n) {
- if ((n.f0.which == 1) || (n.f0.which == 2)) {
- NodeSequence ns = (NodeSequence) n.f0.choice;
- ns.nodes.get(1).accept(this);
- } else
- n.f0.accept(this);
-
- }
-
- public void visit(UnaryOperator n) {
- operator = true;
- n.f0.accept(this);
- operator = false;
- }
-
- public void visit(PostfixExpression n) {
- n.f0.accept(this);
- for (int i = 0; i < n.f1.size(); i++) {
- NodeChoice nc = (NodeChoice) n.f1.elementAt(i);
- switch (nc.which) {
- case 0: // []
- {
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- NodeSequence ns = (NodeSequence) nc.choice;
- ns.elementAt(1).accept(this);
- LineNumberInfo lin = LineNumberInfo.get(n);
- current_expression.commit(lin.lineEnd);
- old.push("[");
- old.push(current_expression.expression);
- old.push("]");
- current_expression = old;
- }
- case 1: // ()
- {
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- NodeSequence ns = (NodeSequence) nc.choice;
- ns.elementAt(1).accept(this);
- LineNumberInfo lin = LineNumberInfo.get (ns.elementAt(1));
- if (! current_expression.expression.isEmpty())
- current_expression.commit(lin.lineEnd);
- old.push("(");
- old.push(current_expression.expression);
- old.push(")");
- current_expression = old;
- }
- break;
- case 2: // .
- case 3: // ->
- {
- ExpressionBuilder old = current_expression;
- LineNumberInfo lin = LineNumberInfo.get(n);
- old.commit(lin.lineEnd);
- current_expression = new ExpressionBuilder();
- NodeSequence ns = (NodeSequence) nc.choice;
- ns.elementAt(1).accept(this);
- if (nc.which == 2)
- old.push(".");
- else
- old.push("->");
- old.push(current_expression.expression);
- current_expression = old;
- }
- break;
- case 4: // ++
- case 5: // --
- /* skip */
- break;
- default:
- throw new Error("Oops!");
- }
- }
- }
-
- public void visit(PrimaryExpression n) {
- if (n.f0.which == 2) {
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- NodeSequence ns = (NodeSequence) n.f0.choice;
- ns.elementAt(1).accept(this);
- LineNumberInfo lin1 = LineNumberInfo.get (ns.elementAt(1));
- current_expression.commit(lin1.lineEnd);
- old.push("(");
- old.push(current_expression.expression);
- old.push(")");
- LineNumberInfo lin = LineNumberInfo.get(n);
- old.commit(lin.lineEnd);
- current_expression = old;
- } else
- n.f0.accept(this);
- }
-
- public void visit(ArgumentExpressionList n) {
- ExpressionBuilder old = current_expression;
- current_expression = new ExpressionBuilder();
- n.f0.accept(this);
- old.push(current_expression.expression);
- for (int i = 0; i < n.f1.size(); i++) {
- NodeSequence ns = (NodeSequence) n.f1.elementAt(i);
- current_expression = new ExpressionBuilder();
- ns.elementAt(1).accept(this);
- old.push(",");
- old.push(current_expression.expression);
- }
- current_expression = old;
- }
-
-}
+++ /dev/null
-package org.gnunet.seaspider;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FilenameFilter;
-
-import org.gnunet.seaspider.parser.CParser;
-import org.gnunet.seaspider.parser.ParseException;
-import org.gnunet.seaspider.parser.TokenMgrError;
-import org.gnunet.seaspider.parser.nodes.Node;
-
-public class Seaspider {
-
- private static final boolean DEBUG = true;
- private static CParser parser = null;
- private static boolean isFirstFile = true;
- private static int successCount = 0;
- private static int failureCount = 0;
- private static FilenameFilter filter = new FilenameFilter() {
- public boolean accept(File dir, String fileName) {
- File file = new File(dir.getPath() + "/" + fileName);
- if ((file.isDirectory() && !fileName.startsWith(".")) || (fileName.endsWith(".c") && !fileName.startsWith("test_")))
- /* directories like .svn are of no interest */
- return true;
- return false;
- }
- };
-
-
- private static void doParseFile(String filePath)
- {
- try {
- if (isFirstFile) {
- parser = new CParser(new FileInputStream(filePath));
- isFirstFile = false;
- }
- else
- parser.ReInit(new FileInputStream(filePath));
- }
- catch (FileNotFoundException e) {
- /* This should never happen */
- System.err.println("File not found!");
- e.printStackTrace();
- System.exit(1);
- }
- try {
- System.out.println("Parsing file: " + filePath);
- Node root = parser.TranslationUnit();
- root.accept(new ExpressionExtractorVisitor(filePath));
- System.out.println("File " + filePath + " parsed successfully.");
- successCount++;
- }
- catch (ParseException e) {
- System.out.println("Encountered errors during parsing file " + filePath);
- failureCount++;
- if (DEBUG)
- e.printStackTrace();
- } catch (TokenMgrError e) {
- System.err.println("Encountered errors during parsing file " + filePath + ":" + e.getMessage());
- failureCount++;
- if (DEBUG)
- e.printStackTrace();
- }
- }
-
-
- private static void parseRecursively(String path)
- {
- File file = new File(path);
-
- if (!file.isDirectory()) {
- if (path.endsWith(".db"))
- return;
- /* A source file */
- doParseFile(path);
- return;
- }
-
- /* A source directory */
- System.out.println("Reading from: " + path + " source directory...");
- String[] dirContents = file.list(filter);/* Only directories and .c files */
- for (int i = 0; i < dirContents.length; i++) {
- String fullPath = path + "/" + dirContents[i];
- parseRecursively(fullPath);
- }
- }
-
- public static void main(String args[])
- {
- String dbFilePath = null;
-
- if (args.length < 2)
- {
- System.err.println("Invoke seaspider with database filename and source path!");
- System.exit(1);
- }
- System.out.println("Seaspider 0.0\n");
-
-
- for (int i = 0; i < args.length; i++) {
- if (args[i].endsWith(".db"))
- dbFilePath = args[i];
- else {
- /* Should be a valid path for a file or a directory */
- File file = new File(args[i]);
- if (!file.exists()) {
- System.err.println("\"" + args[i] + "\" is an invalid file or directory location");
- System.exit(1);
- } else if (!file.isDirectory() && !args[i].endsWith(".c")) {
- System.err.println("\"" + args[i] + "\" only source files can be parsed");
- }
- }
- }
- if (null == dbFilePath) {
- System.err.println("Missing database file path");
- System.exit(1);
- }
-
- /* Create the Expressions Database */
- ExpressionDatabaseHandler.createExpressionDatabase(dbFilePath);
-
- for (int i = 0; i < args.length; i++)
- parseRecursively(args[i]);
-
- /* We're done with the Expression Database, close it */
- ExpressionDatabaseHandler.closeDatabase();
-
- System.out.println(successCount + " parsed successfully.");
- System.out.println("Failed to parse " + failureCount + " files.");
- }
-}
+++ /dev/null
-package org.grothoff;
-
-import java.lang.reflect.Field;
-import java.util.Enumeration;
-import java.util.WeakHashMap;
-
-/**
- * Obtain line number information for any JTB node. Note that
- * "any" really means any -- we use reflection to overcome the
- * problem that we do not know the full name of the AST root
- * (in particular, there maybe multiple AST hierarchies in the
- * project with multiple root "Node" classes).<p>
- *
- * Essentially, pass a JTB node to the static "get" method
- * and (if it is a JTB node and there is source corresponding
- * to it), a LineNumberInfo object with the scope of the
- * subtree is returned. Otherwise null.<p>
- *
- *
- * Minimal example:
- * <code>
- * void semanticError(String message, Node n) {
- * throw new Error(message + " at " + LineNumberInfo.get(n));
- * }
- * </code>
- *<p>
- *
- * This code is dual licensed under both BSD and LGPL.
- *
- * @author Christian Grothoff
- */
-public class LineNumberInfo {
-
- private static final Object NULL = new Object();
- private static final Object SELF = new Object();
- private static final WeakHashMap<Object, Object> cacheF_ = new WeakHashMap<Object,Object>();
- private static final WeakHashMap<Object, Object> cacheL_ = new WeakHashMap<Object,Object>();
-
- public final int lineStart;
- public final int lineEnd;
- public final int colStart;
- public final int colEnd;
-
- public LineNumberInfo(int s, int e, int cs, int ce) {
- lineStart = s;
- lineEnd = e;
- colStart = cs;
- colEnd = ce;
- }
-
- public String toString() {
- return "["+lineStart+":"+colStart+","+lineEnd+":"+colEnd+"]";
- }
-
- /**
- * Compute line number information for the given JTB node.
- *
- * @param o any JTB node (the type should be node, but since this
- * code handles any JTB AST we cannot hardwire the
- * type ("Node" -- but which package?)
- * @return
- */
- public static LineNumberInfo get(Object o) {
- if (o == null)
- return null; // fail!
- Object p = firstMatch(o);
- Object q = lastMatch(o);
- try {
- int lstart = ((Integer)p.getClass().getField("beginLine").get(p)).intValue();
- int cstart = ((Integer)p.getClass().getField("beginColumn").get(p)).intValue();
- int lend = ((Integer)p.getClass().getField("endLine").get(q)).intValue();
- int cend = ((Integer)p.getClass().getField("endColumn").get(q)).intValue();
- return new LineNumberInfo(lstart, lend, cstart, cend);
- } catch (Throwable t) {
- return null; // failed
- }
- }
-
- private static Object firstMatch(Object o) {
- synchronized(cacheF_) {
- Object r = cacheF_.get(o);
- if (r != null)
- return (r == SELF) ? o : (r == NULL) ? null : r;
- }
- Object r = firstMatch_(o);
- synchronized(cacheF_) {
- cacheF_.put(o, r == o ? SELF : r == null ? NULL : r);
- }
- return r;
- }
-
-
- private static Object lastMatch(Object o) {
- synchronized(cacheL_) {
- Object r = cacheL_.get(o);
- if (r != null)
- return (r == SELF) ? o : (r == NULL) ? null : r;
- }
- Object r = lastMatch_(o);
- synchronized(cacheL_) {
- cacheL_.put(o, r == o ? SELF : r == null ? NULL : r);
- }
- return r;
- }
-
- private static Object firstMatch_(Object o) {
- if (o == null)
- return null;
- Class c = o.getClass();
- if (c.getName().endsWith("NodeToken"))
- return o;
- try {
- int i=0;
- while (true) {
- Field f = null;
- try {
- f = c.getField("f" + i);
- } catch (Throwable t) {
- }
- if ( (f == null) && (i == 0) && (c.getName().endsWith("NodeChoice")) ) {
- f = c.getField("choice");
- } else if ( (f == null) && (i == 0) && (c.getName().endsWith("NodeOptional")) ) {
- f = c.getField("node");
- } else if ( (f == null) && (i == 0) ) {
- // special cases: node sequence, etc.
- Enumeration e = (Enumeration) c.getMethod("elements").invoke(o);
- while (e.hasMoreElements()) {
- Object x = firstMatch(e.nextElement());
- if (x != null)
- return x;
- }
- }
- if (f != null) {
- Object r = firstMatch(f.get(o));
- if (r != null)
- return r;
- } else {
- return null;
- }
- i++;
- }
- } catch (Throwable t) {
- }
- return null;
- }
-
- private static Object lastMatch_(Object o) {
- if (o == null)
- return null;
- Class c = o.getClass();
- if (c.getName().endsWith("NodeToken"))
- return o;
-
- Object ret = null;
- try {
- int i=0;
- while (true) {
- Field f = null;
- try {
- f = c.getField("f" + i);
- } catch (Throwable t) {
- }
- if ( (f == null) && (i == 0) && (c.getName().endsWith("NodeChoice")) ) {
- f = c.getField("choice");
- } else if ( (f == null) && (i == 0) && (c.getName().endsWith("NodeOptional")) ) {
- f = c.getField("node");
- } else if ( (f == null) && (i == 0) ) {
- // special cases: node sequence, etc.
- Enumeration e = (Enumeration) o.getClass().getMethod("elements").invoke(o);
- while (e.hasMoreElements()) {
- Object x = lastMatch(e.nextElement());
- if (x != null)
- ret = x;
- }
- return ret;
- }
- if (f != null) {
- Object r = lastMatch(f.get(o));
- if (r != null)
- ret = r;
- } else {
- return ret;
- }
- i++;
- }
- } catch (Throwable t) {
- }
- return ret;
- }
-
-}
-
+++ /dev/null
-/*
- This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
-
- GNUnet 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 3, or (at your
- option) any later version.
-
- GNUnet 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 GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file monkey/test_gnunet_monkey.c
- * @brief Testcase for Monkey
- * @author Safey Abdel Halim
- */
-
-/**
- * Test case for Monkey Automatic Debugger.
- * It launches Monkey to run binaries having
- * known bugs (e.g. Null Pointer Exception)
- * Monkey should be able to detect the problem and send an e-mail
- * containing the problem description.
- */
-
-
-#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_program_lib.h"
-
-
-static int
-check ()
-{
- GNUNET_OS_process_close (GNUNET_OS_start_process (NULL, NULL,
- "gnunet-monkey",
- "gnunet-monkey",
- "./bug_null_pointer_exception",
- NULL));
-
- return 0;
-}
-
-
-int
-main (int argc, char *argv[])
-{
- int ret;
-
- GNUNET_log_setup ("test-gnunet-monkey",
-#if VERBOSE
- "DEBUG",
-#else
- "WARNING",
-#endif
- NULL);
- ret = check ();
- return ret;
-}
-
-/* end of test_gnunet_monkey.c */
-
+++ /dev/null
-#!/bin/sh
-
-rm -rf /tmp/test-gnunetd-monkey/
-exe="./gnunet-monkey -c test_monkey_api_data.conf"
-out=`mktemp /tmp/test-gnunet-monkey-logXXXXXXXX`
-arm="gnunet-arm -c test_monkey_api_data.conf $DEBUG"
-#DEBUG="-L DEBUG"
-# -----------------------------------
-echo -n "Preparing: Starting service..."
-
-$arm -s > /dev/null
-sleep 1
-$arm -i monkey > /dev/null
-sleep 1
-echo "DONE"
-
-# ----------------------------------------------------------------------------------
-echo -n "TEST: Bad argument checking..."
-
-if $exe -x 2> /dev/null; then
- echo "FAIL: error running $exe"
- $arm -e
- exit 1
-fi
-echo "PASS"
-
-# ----------------------------------------------------------------------------------
-echo -n "TEST: Set value..."
-
-if ! $exe $DEBUG -n test -s subsystem 42 ; then
- echo "FAIL: error running $exe"
- $arm -e
- exit 1
-fi
-echo "PASS"
-
-# ----------------------------------------------------------------------------------
-echo -n "TEST: Set another value..."
-
-if ! $exe $DEBUG -n other -s osystem 43 ; then
- echo "FAIL: error running $exe"
- $arm -e
- exit 1
-fi
-echo "PASS"
-
-# ----------------------------------------------------------------------------------
-echo -n "TEST: viewing all stats..."
-
-if ! $exe $DEBUG > $out; then
- echo "FAIL: error running $exe"
- $arm -e
- exit 1
-fi
-LINES=`cat $out | wc -l`
-if test $LINES -ne 2; then
- echo "FAIL: unexpected output"
- $arm -e
- exit 1
-fi
-echo "PASS"
-
-# ----------------------------------------------------------------------------------
-echo -n "TEST: viewing stats by name..."
-
-if ! $exe $DEBUG -n other > $out; then
- echo "FAIL: error running $exe"
- $arm -e
- exit 1
-fi
-LINES=`cat $out | grep 43 | wc -l`
-if test $LINES -ne 1; then
- echo "FAIL: unexpected output"
- $arm -e
- exit 1
-fi
-echo "PASS"
-
-# ----------------------------------------------------------------------------------
-echo -n "TEST: viewing stats by subsystem..."
-
-if ! $exe $DEBUG -s subsystem > $out; then
- echo "FAIL: error running $exe"
- $arm -e
- exit 1
-fi
-LINES=`cat $out | grep 42 | wc -l`
-if test $LINES -ne 1; then
- echo "FAIL: unexpected output"
- $arm -e
- exit 1
-fi
-echo "PASS"
-
-
-# ----------------------------------------------------------------------------------
-echo -n "TEST: Set persistent value..."
-
-if ! $exe $DEBUG -n lasting -s subsystem 40 -p; then
- echo "FAIL: error running $exe"
- $arm -e
- exit 1
-fi
-if ! $exe $DEBUG > $out; then
- echo "FAIL: error running $exe"
- $arm -e
- exit 1
-fi
-LINES=`cat $out | grep 40 | wc -l`
-if test $LINES -ne 1; then
- echo "FAIL: unexpected output"
- cat $out
- $arm -e
- exit 1
-fi
-echo "PASS"
-
-# -----------------------------------
-echo -n "Restarting service..."
-$arm -k monkey > /dev/null
-sleep 1
-$arm -i monkey > /dev/null
-sleep 1
-echo "DONE"
-
-# ----------------------------------------------------------------------------------
-echo -n "TEST: checking persistence..."
-
-if ! $exe $DEBUG > $out; then
- echo "FAIL: error running $exe"
- $arm -e
- exit 1
-fi
-LINES=`cat $out | grep 40 | wc -l`
-if test $LINES -ne 1; then
- echo "FAIL: unexpected output"
- cat $out
- $arm -e
- exit 1
-fi
-echo "PASS"
-
-
-
-# ----------------------------------------------------------------------------------
-echo -n "TEST: Removing persistence..."
-
-if ! $exe $DEBUG -n lasting -s subsystem 40; then
- echo "FAIL: error running $exe"
- $arm -e
- exit 1
-fi
-if ! $exe $DEBUG > $out; then
- echo "FAIL: error running $exe"
- $arm -e
- exit 1
-fi
-LINES=`cat $out | grep \! | wc -l`
-if test $LINES -ne 0; then
- echo "FAIL: unexpected output"
- cat $out
- $arm -e
- exit 1
-fi
-echo "PASS"
-
-
-# -----------------------------------
-echo -n "Restarting service..."
-$arm -k monkey > /dev/null
-sleep 1
-$arm -i monkey > /dev/null
-sleep 1
-echo "DONE"
-
-# ----------------------------------------------------------------------------------
-echo -n "TEST: checking removed persistence..."
-
-if ! $exe $DEBUG > $out; then
- echo "FAIL: error running $exe"
- $arm -e
- exit 1
-fi
-LINES=`cat $out | grep 40 | wc -l`
-if test $LINES -ne 0; then
- echo "FAIL: unexpected output"
- cat $out
- $arm -e
- exit 1
-fi
-echo "PASS"
-
-# -----------------------------------
-echo -n "Stopping service..."
-$arm -e > /dev/null
-sleep 1
-echo "DONE"
-rm -f $out
-rm -rf /tmp/test-gnunetd-monkey/
+++ /dev/null
-[PATHS]
-SERVICEHOME = /tmp/test-gnunetd-arm/
-DEFAULTCONFIG = test_arm_api_data.conf
-
-[arm]
-PORT = 23354
-DEFAULTSERVICES =
-BINARY = gnunet-service-arm
-OPTIONS = -L ERROR
-# DEBUG = YES
-#PREFIX = valgrind --tool=memcheck --leak-check=yes
-
-[gnunet-monkey]
-# DEBUG = YES
-PORT = 23355
-BINARY = gnunet-monkey
-# PREFIX = valgrind
-
-
-[fs]
-AUTOSTART = NO
-
-[datastore]
-AUTOSTART = NO
-
-[core]
-AUTOSTART = NO
-
-[transport]
-AUTOSTART = NO
-
-[peerinfo]
-AUTOSTART = NO
-
-[statistics]
-AUTOSTART = YES
-# DEBUG = NO
-
-
-[dns]
-AUTOSTART = NO
-
-
+++ /dev/null
-/*
- This file is part of GNUnet.
- (C) 2010 Christian Grothoff (and other contributing authors)
-
- GNUnet 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 3, or (at your
- option) any later version.
-
- GNUnet 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 GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-/**
- * @file monkey/test_monkey_edb.c
- * @brief testcase for edb_api.c
- */
-#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_monkey_edb.h"
-
-
-static const char *ref[16] =
- { "args", "32", "argv", "32", "whole", "42", "whole.member", "42",
- "whole.member=1", "42", "whole.part", "43", "&part", "43",
- "whole.part=&part", "43"
-};
-
-static int refCount = 0;
-static int ret = 1;
-
-int
-expressionIterator (void *cls, int colNum, char **colValues, char **colNames)
-{
- int i;
- for (i = 0; i < colNum; i++)
- {
- if (strcmp (colValues[i], ref[refCount]) != 0)
- return 1;
- refCount++;
- }
-
- return 0;
-}
-
-
-int
-main (int args, const char *argv[])
-{
- struct GNUNET_MONKEY_EDB_Context *cntxt;
- cntxt = GNUNET_MONKEY_EDB_connect ("test.db");
- ret =
- GNUNET_MONKEY_EDB_get_expressions (cntxt,
- "monkey/seaspider/SeaspiderTest.c", 44,
- 83, &expressionIterator, NULL);
- GNUNET_MONKEY_EDB_disconnect (cntxt);
-
- if (ret == GNUNET_OK)
- {
- return 0;
- }
- return 1;
-}
+++ /dev/null
-#!/bin/sh
-echo -n "Test Monkey with Bug - Null Pointer Exception -"
-gnunet-monkey --mode text --binary bug_null_pointer_exception --output npe.out && exit 0
-grep "Bug detected in file:bug_null_pointer_exception.c" npe.out > /dev/null || exit 1
-grep "function:crashFunction" npe.out > /dev/null || exit 1
-grep "line:8" npe.out > /dev/null || exit 1
-grep "reason:Signal received" npe.out > /dev/null || exit 1
-grep "received signal:EXC_BAD_ACCESS" npe.out > /dev/null || exit 1
-grep "Could not access memory" npe.out > /dev/null || exit 1
-rm -f npe.out
-echo "PASS"
\ No newline at end of file
+++ /dev/null
-==1277== Memcheck, a memory error detector
-==1277== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
-==1277== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
-==1277== Command: ./bug_bad_memory_access
-==1277== Parent PID: 1666
-==1277==
-==1277== Invalid write of size 4
-==1277== at 0x400512: badMemoryAccess (bug_bad_memory_access.c:9)
-==1277== by 0x400532: main (bug_bad_memory_access.c:14)
-==1277== Address 0x4252352 is not stack'd, malloc'd or (recently) free'd
-==1277==
-==1277==
-==1277== Process terminating with default action of signal 11 (SIGSEGV)
-==1277== Access not within mapped region at address 0x4252352
-==1277== at 0x400512: badMemoryAccess (bug_bad_memory_access.c:9)
-==1277== by 0x400532: main (bug_bad_memory_access.c:14)
-==1277== If you believe this happened as a result of a stack
-==1277== overflow in your program's main thread (unlikely but
-==1277== possible), you can try to increase the size of the
-==1277== main thread stack using the --main-stacksize= flag.
-==1277== The main thread stack size used in this run was 8388608.
-==1277==
-==1277== HEAP SUMMARY:
-==1277== in use at exit: 0 bytes in 0 blocks
-==1277== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
-==1277==
-==1277== All heap blocks were freed -- no leaks are possible
-==1277==
-==1277== For counts of detected and suppressed errors, rerun with: -v
-==1277== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)