aboutsummaryrefslogtreecommitdiff
path: root/externals/mysql/extlib/dbug
diff options
context:
space:
mode:
Diffstat (limited to 'externals/mysql/extlib/dbug')
-rw-r--r--externals/mysql/extlib/dbug/dbug.c2583
-rw-r--r--externals/mysql/extlib/dbug/dbug_analyze.c726
-rw-r--r--externals/mysql/extlib/dbug/dbug_long.h160
-rw-r--r--externals/mysql/extlib/dbug/example1.c10
-rw-r--r--externals/mysql/extlib/dbug/example2.c15
-rw-r--r--externals/mysql/extlib/dbug/example3.c14
-rw-r--r--externals/mysql/extlib/dbug/factorial.c27
-rw-r--r--externals/mysql/extlib/dbug/main.c24
-rw-r--r--externals/mysql/extlib/dbug/my_main.c42
-rw-r--r--externals/mysql/extlib/dbug/sanity.c13
-rw-r--r--externals/mysql/extlib/dbug/tests.c87
11 files changed, 0 insertions, 3701 deletions
diff --git a/externals/mysql/extlib/dbug/dbug.c b/externals/mysql/extlib/dbug/dbug.c
deleted file mode 100644
index 68932adf1e1..00000000000
--- a/externals/mysql/extlib/dbug/dbug.c
+++ /dev/null
@@ -1,2583 +0,0 @@
-/******************************************************************************
- * *
- * N O T I C E *
- * *
- * Copyright Abandoned, 1987, Fred Fish *
- * *
- * *
- * This previously copyrighted work has been placed into the public *
- * domain by the author and may be freely used for any purpose, *
- * private or commercial. *
- * *
- * Because of the number of inquiries I was receiving about the use *
- * of this product in commercially developed works I have decided to *
- * simply make it public domain to further its unrestricted use. I *
- * specifically would be most happy to see this material become a *
- * part of the standard Unix distributions by AT&T and the Berkeley *
- * Computer Science Research Group, and a standard part of the GNU *
- * system from the Free Software Foundation. *
- * *
- * I would appreciate it, as a courtesy, if this notice is left in *
- * all copies and derivative works. Thank you. *
- * *
- * The author makes no warranty of any kind with respect to this *
- * product and explicitly disclaims any implied warranties of mer- *
- * chantability or fitness for any particular purpose. *
- * *
- ******************************************************************************
- */
-
-/*
- * FILE
- *
- * dbug.c runtime support routines for dbug package
- *
- * SCCS
- *
- * @(#)dbug.c 1.25 7/25/89
- *
- * DESCRIPTION
- *
- * These are the runtime support routines for the dbug package.
- * The dbug package has two main components; the user include
- * file containing various macro definitions, and the runtime
- * support routines which are called from the macro expansions.
- *
- * Externally visible functions in the runtime support module
- * use the naming convention pattern "_db_xx...xx_", thus
- * they are unlikely to collide with user defined function names.
- *
- * AUTHOR(S)
- *
- * Fred Fish (base code)
- * Enhanced Software Technologies, Tempe, AZ
- * asuvax!mcdphx!estinc!fnf
- *
- * Binayak Banerjee (profiling enhancements)
- * seismo!bpa!sjuvax!bbanerje
- *
- * Michael Widenius:
- * DBUG_DUMP - To dump a block of memory.
- * PUSH_FLAG "O" - To be used insted of "o" if we
- * want flushing after each write
- * PUSH_FLAG "A" - as 'O', but we will append to the out file instead
- * of creating a new one.
- * Check of malloc on entry/exit (option "S")
- *
- * Sergei Golubchik:
- * DBUG_EXECUTE_IF
- * incremental mode (-#+t:-d,info ...)
- * DBUG_SET, _db_explain_
- * thread-local settings
- * negative lists (-#-d,info => everything but "info")
- *
- * function/ syntax
- * (the logic is - think of a call stack as of a path.
- * "function" means only this function, "function/" means the hierarchy.
- * in the future, filters like function1/function2 could be supported.
- * following this logic glob(7) wildcards are supported.)
- *
- */
-
-/*
- We can't have SAFE_MUTEX defined here as this will cause recursion
- in pthread_mutex_lock
-*/
-
-#undef SAFE_MUTEX
-#include <my_global.h>
-#include <m_string.h>
-#include <errno.h>
-
-#ifdef HAVE_FNMATCH_H
-#include <fnmatch.h>
-#else
-#define fnmatch(A,B,C) strcmp(A,B)
-#endif
-
-#if defined(MSDOS) || defined(__WIN__)
-#include <process.h>
-#endif
-
-#ifndef DBUG_OFF
-
-
-/*
- * Manifest constants which may be "tuned" if desired.
- */
-
-#define PRINTBUF 1024 /* Print buffer size */
-#define INDENT 2 /* Indentation per trace level */
-#define MAXDEPTH 200 /* Maximum trace depth default */
-
-/*
- * The following flags are used to determine which
- * capabilities the user has enabled with the settings
- * push macro.
- *
- * TRACE_ON is also used in _db_stack_frame_->level
- * (until we add flags to _db_stack_frame_, increasing it by 4 bytes)
- */
-
-#define DEBUG_ON (1 << 1) /* Debug enabled */
-#define FILE_ON (1 << 2) /* File name print enabled */
-#define LINE_ON (1 << 3) /* Line number print enabled */
-#define DEPTH_ON (1 << 4) /* Function nest level print enabled */
-#define PROCESS_ON (1 << 5) /* Process name print enabled */
-#define NUMBER_ON (1 << 6) /* Number each line of output */
-#define PROFILE_ON (1 << 7) /* Print out profiling code */
-#define PID_ON (1 << 8) /* Identify each line with process id */
-#define TIMESTAMP_ON (1 << 9) /* timestamp every line of output */
-#define SANITY_CHECK_ON (1 << 10) /* Check safemalloc on DBUG_ENTER */
-#define FLUSH_ON_WRITE (1 << 11) /* Flush on every write */
-#define OPEN_APPEND (1 << 12) /* Open for append */
-#define TRACE_ON ((uint)1 << 31) /* Trace enabled. MUST be the highest bit!*/
-
-#define TRACING (cs->stack->flags & TRACE_ON)
-#define DEBUGGING (cs->stack->flags & DEBUG_ON)
-#define PROFILING (cs->stack->flags & PROFILE_ON)
-
-/*
- * Typedefs to make things more obvious.
- */
-
-#define BOOLEAN my_bool
-
-/*
- * Make it easy to change storage classes if necessary.
- */
-
-#define IMPORT extern /* Names defined externally */
-#define EXPORT /* Allocated here, available globally */
-#define AUTO auto /* Names to be allocated on stack */
-#define REGISTER register /* Names to be placed in registers */
-
-/*
- * The default file for profiling. Could also add another flag
- * (G?) which allowed the user to specify this.
- *
- * If the automatic variables get allocated on the stack in
- * reverse order from their declarations, then define AUTOS_REVERSE to 1.
- * This is used by the code that keeps track of stack usage. For
- * forward allocation, the difference in the dbug frame pointers
- * represents stack used by the callee function. For reverse allocation,
- * the difference represents stack used by the caller function.
- *
- */
-
-#define PROF_FILE "dbugmon.out"
-#define PROF_EFMT "E\t%ld\t%s\n"
-#define PROF_SFMT "S\t%lx\t%lx\t%s\n"
-#define PROF_XFMT "X\t%ld\t%s\n"
-
-#ifdef M_I386 /* predefined by xenix 386 compiler */
-#define AUTOS_REVERSE 1
-#else
-#define AUTOS_REVERSE 0
-#endif
-
-/*
- * Externally supplied functions.
- */
-
-#ifndef HAVE_PERROR
-static void perror(); /* Fake system/library error print routine */
-#endif
-
-#ifdef SAFEMALLOC
-IMPORT int _sanity(const char *file,uint line); /* safemalloc sanity checker */
-#else
-#define _sanity(X,Y) (1)
-#endif
-
-/*
- * The user may specify a list of functions to trace or
- * debug. These lists are kept in a linear linked list,
- * a very simple implementation.
- */
-
-struct link {
- struct link *next_link; /* Pointer to the next link */
- char flags;
- char str[1]; /* Pointer to link's contents */
-};
-
-/* flags for struct link and return flags of InList */
-#define SUBDIR 1 /* this MUST be 1 */
-#define INCLUDE 2
-#define EXCLUDE 4
-/* this is not a struct link flag, but only a return flags of InList */
-#define MATCHED 65536
-#define NOT_MATCHED 0
-
-/*
- * Debugging settings can be pushed or popped off of a
- * stack which is implemented as a linked list. Note
- * that the head of the list is the current settings and the
- * stack is pushed by adding a new settings to the head of the
- * list or popped by removing the first link.
- *
- * Note: if out_file is NULL, the other fields are not initialized at all!
- */
-
-struct settings {
- uint flags; /* Current settings flags */
- uint maxdepth; /* Current maximum trace depth */
- uint delay; /* Delay after each output line */
- uint sub_level; /* Sub this from code_state->level */
- FILE *out_file; /* Current output stream */
- FILE *prof_file; /* Current profiling stream */
- char name[FN_REFLEN]; /* Name of output file */
- struct link *functions; /* List of functions */
- struct link *p_functions; /* List of profiled functions */
- struct link *keywords; /* List of debug keywords */
- struct link *processes; /* List of process names */
- struct settings *next; /* Next settings in the list */
-};
-
-#define is_shared(S, V) ((S)->next && (S)->next->V == (S)->V)
-
-/*
- * Local variables not seen by user.
- */
-
-
-static BOOLEAN init_done= FALSE; /* Set to TRUE when initialization done */
-static struct settings init_settings;
-static const char *db_process= 0;/* Pointer to process name; argv[0] */
-my_bool _dbug_on_= TRUE; /* FALSE if no debugging at all */
-
-typedef struct _db_code_state_ {
- const char *process; /* Pointer to process name; usually argv[0] */
- const char *func; /* Name of current user function */
- const char *file; /* Name of current user file */
- struct _db_stack_frame_ *framep; /* Pointer to current frame */
- struct settings *stack; /* debugging settings */
- const char *jmpfunc; /* Remember current function for setjmp */
- const char *jmpfile; /* Remember current file for setjmp */
- int lineno; /* Current debugger output line number */
- uint level; /* Current function nesting level */
- int jmplevel; /* Remember nesting level at setjmp() */
-
-/*
- * The following variables are used to hold the state information
- * between the call to _db_pargs_() and _db_doprnt_(), during
- * expansion of the DBUG_PRINT macro. This is the only macro
- * that currently uses these variables.
- *
- * These variables are currently used only by _db_pargs_() and
- * _db_doprnt_().
- */
-
- uint u_line; /* User source code line number */
- int locked; /* If locked with _db_lock_file_ */
- const char *u_keyword; /* Keyword for current macro */
-} CODE_STATE;
-
-/*
- The test below is so we could call functions with DBUG_ENTER before
- my_thread_init().
-*/
-#define get_code_state_if_not_set_or_return if (!cs && !((cs=code_state()))) return
-#define get_code_state_or_return if (!((cs=code_state()))) return
-
- /* Handling lists */
-#define ListAdd(A,B,C) ListAddDel(A,B,C,INCLUDE)
-#define ListDel(A,B,C) ListAddDel(A,B,C,EXCLUDE)
-static struct link *ListAddDel(struct link *, const char *, const char *, int);
-static struct link *ListCopy(struct link *);
-static int InList(struct link *linkp,const char *cp);
-static uint ListFlags(struct link *linkp);
-static void FreeList(struct link *linkp);
-
- /* OpenClose debug output stream */
-static void DBUGOpenFile(CODE_STATE *,const char *, const char *, int);
-static void DBUGCloseFile(CODE_STATE *cs, FILE *fp);
- /* Push current debug settings */
-static void PushState(CODE_STATE *cs);
- /* Free memory associated with debug state. */
-static void FreeState (CODE_STATE *cs, struct settings *state, int free_state);
- /* Test for tracing enabled */
-static int DoTrace(CODE_STATE *cs);
-/*
- return values of DoTrace.
- Can also be used as bitmask: ret & DO_TRACE
-*/
-#define DO_TRACE 1
-#define DONT_TRACE 2
-#define ENABLE_TRACE 3
-#define DISABLE_TRACE 4
-
- /* Test to see if file is writable */
-#if defined(HAVE_ACCESS) && !defined(MSDOS)
-static BOOLEAN Writable(const char *pathname);
- /* Change file owner and group */
-static void ChangeOwner(CODE_STATE *cs, char *pathname);
- /* Allocate memory for runtime support */
-#endif
-
-static void DoPrefix(CODE_STATE *cs, uint line);
-
-static char *DbugMalloc(size_t size);
-static const char *BaseName(const char *pathname);
-static void Indent(CODE_STATE *cs, int indent);
-static void DbugFlush(CODE_STATE *);
-static void DbugExit(const char *why);
-static const char *DbugStrTok(const char *s);
-static void DbugFprintf(FILE *stream, const char* format, va_list args);
-
-#ifndef THREAD
- /* Open profile output stream */
-static FILE *OpenProfile(CODE_STATE *cs, const char *name);
- /* Profile if asked for it */
-static BOOLEAN DoProfile(CODE_STATE *);
- /* Return current user time (ms) */
-static unsigned long Clock(void);
-#endif
-
-/*
- * Miscellaneous printf format strings.
- */
-
-#define ERR_MISSING_RETURN "%s: missing DBUG_RETURN or DBUG_VOID_RETURN macro in function \"%s\"\n"
-#define ERR_OPEN "%s: can't open debug output stream \"%s\": "
-#define ERR_CLOSE "%s: can't close debug file: "
-#define ERR_ABORT "%s: debugger aborting because %s\n"
-#define ERR_CHOWN "%s: can't change owner/group of \"%s\": "
-
-/*
- * Macros and defines for testing file accessibility under UNIX and MSDOS.
- */
-
-#undef EXISTS
-#if !defined(HAVE_ACCESS) || defined(MSDOS)
-#define EXISTS(pathname) (FALSE) /* Assume no existance */
-#define Writable(name) (TRUE)
-#else
-#define EXISTS(pathname) (access(pathname, F_OK) == 0)
-#define WRITABLE(pathname) (access(pathname, W_OK) == 0)
-#endif
-#ifndef MSDOS
-#define ChangeOwner(cs,name)
-#endif
-
-
-/*
-** Macros to allow dbugging with threads
-*/
-
-#ifdef THREAD
-#include <my_pthread.h>
-static pthread_mutex_t THR_LOCK_dbug;
-
-static CODE_STATE *code_state(void)
-{
- CODE_STATE *cs, **cs_ptr;
-
- /*
- _dbug_on_ is reset if we don't plan to use any debug commands at all and
- we want to run on maximum speed
- */
- if (!_dbug_on_)
- return 0;
-
- if (!init_done)
- {
- init_done=TRUE;
- pthread_mutex_init(&THR_LOCK_dbug,MY_MUTEX_INIT_FAST);
- bzero(&init_settings, sizeof(init_settings));
- init_settings.out_file=stderr;
- init_settings.flags=OPEN_APPEND;
- }
-
- if (!(cs_ptr= (CODE_STATE**) my_thread_var_dbug()))
- return 0; /* Thread not initialised */
- if (!(cs= *cs_ptr))
- {
- cs=(CODE_STATE*) DbugMalloc(sizeof(*cs));
- bzero((uchar*) cs,sizeof(*cs));
- cs->process= db_process ? db_process : "dbug";
- cs->func="?func";
- cs->file="?file";
- cs->stack=&init_settings;
- *cs_ptr= cs;
- }
- return cs;
-}
-
-#else /* !THREAD */
-
-static CODE_STATE static_code_state=
-{
- "dbug", "?func", "?file", NULL, &init_settings,
- NullS, NullS, 0,0,0,0,0,NullS
-};
-
-static CODE_STATE *code_state(void)
-{
- if (!init_done)
- {
- bzero(&init_settings, sizeof(init_settings));
- init_settings.out_file=stderr;
- init_settings.flags=OPEN_APPEND;
- init_done=TRUE;
- }
- return &static_code_state;
-}
-
-#define pthread_mutex_lock(A) {}
-#define pthread_mutex_unlock(A) {}
-#endif
-
-/*
- * Translate some calls among different systems.
- */
-
-#ifdef HAVE_SLEEP
-/* sleep() wants seconds */
-#define Delay(A) sleep(((uint) A)/10)
-#else
-#define Delay(A) (0)
-#endif
-
-/*
- * FUNCTION
- *
- * _db_process_ give the name to the current process/thread
- *
- * SYNOPSIS
- *
- * VOID _process_(name)
- * char *name;
- *
- */
-
-void _db_process_(const char *name)
-{
- CODE_STATE *cs;
-
- if (!db_process)
- db_process= name;
-
- get_code_state_or_return;
- cs->process= name;
-}
-
-/*
- * FUNCTION
- *
- * DbugParse parse control string and set current debugger settings
- *
- * DESCRIPTION
- *
- * Given pointer to a debug control string in "control",
- * parses the control string, and sets
- * up a current debug settings.
- *
- * The debug control string is a sequence of colon separated fields
- * as follows:
- *
- * [+]<field_1>:<field_2>:...:<field_N>
- *
- * Each field consists of a mandatory flag character followed by
- * an optional "," and comma separated list of modifiers:
- *
- * [sign]flag[,modifier,modifier,...,modifier]
- *
- * See the manual for the list of supported signs, flags, and modifiers
- *
- * For convenience, any leading "-#" is stripped off.
- *
- * RETURN
- * 1 - a list of functions ("f" flag) was possibly changed
- * 0 - a list of functions was not changed
- */
-
-int DbugParse(CODE_STATE *cs, const char *control)
-{
- const char *end;
- int rel, f_used=0;
- struct settings *stack;
-
- stack= cs->stack;
-
- if (control[0] == '-' && control[1] == '#')
- control+=2;
-
- rel= control[0] == '+' || control[0] == '-';
- if ((!rel || (!stack->out_file && !stack->next)))
- {
- FreeState(cs, stack, 0);
- stack->flags= 0;
- stack->delay= 0;
- stack->maxdepth= 0;
- stack->sub_level= 0;
- stack->out_file= stderr;
- stack->prof_file= NULL;
- stack->functions= NULL;
- stack->p_functions= NULL;
- stack->keywords= NULL;
- stack->processes= NULL;
- }
- else if (!stack->out_file)
- {
- stack->flags= stack->next->flags;
- stack->delay= stack->next->delay;
- stack->maxdepth= stack->next->maxdepth;
- stack->sub_level= stack->next->sub_level;
- strcpy(stack->name, stack->next->name);
- stack->out_file= stack->next->out_file;
- stack->prof_file= stack->next->prof_file;
- if (stack->next == &init_settings)
- {
- /* never share with the global parent - it can change under your feet */
- stack->functions= ListCopy(init_settings.functions);
- stack->p_functions= ListCopy(init_settings.p_functions);
- stack->keywords= ListCopy(init_settings.keywords);
- stack->processes= ListCopy(init_settings.processes);
- }
- else
- {
- stack->functions= stack->next->functions;
- stack->p_functions= stack->next->p_functions;
- stack->keywords= stack->next->keywords;
- stack->processes= stack->next->processes;
- }
- }
-
- end= DbugStrTok(control);
- while (control < end)
- {
- int c, sign= (*control == '+') ? 1 : (*control == '-') ? -1 : 0;
- if (sign) control++;
- c= *control++;
- if (*control == ',') control++;
- /* XXX when adding new cases here, don't forget _db_explain_ ! */
- switch (c) {
- case 'd':
- if (sign < 0 && control == end)
- {
- if (!is_shared(stack, keywords))
- FreeList(stack->keywords);
- stack->keywords=NULL;
- stack->flags &= ~DEBUG_ON;
- break;
- }
- if (rel && is_shared(stack, keywords))
- stack->keywords= ListCopy(stack->keywords);
- if (sign < 0)
- {
- if (DEBUGGING)
- stack->keywords= ListDel(stack->keywords, control, end);
- break;
- }
- stack->keywords= ListAdd(stack->keywords, control, end);
- stack->flags |= DEBUG_ON;
- break;
- case 'D':
- stack->delay= atoi(control);
- break;
- case 'f':
- f_used= 1;
- if (sign < 0 && control == end)
- {
- if (!is_shared(stack,functions))
- FreeList(stack->functions);
- stack->functions=NULL;
- break;
- }
- if (rel && is_shared(stack,functions))
- stack->functions= ListCopy(stack->functions);
- if (sign < 0)
- stack->functions= ListDel(stack->functions, control, end);
- else
- stack->functions= ListAdd(stack->functions, control, end);
- break;
- case 'F':
- if (sign < 0)
- stack->flags &= ~FILE_ON;
- else
- stack->flags |= FILE_ON;
- break;
- case 'i':
- if (sign < 0)
- stack->flags &= ~PID_ON;
- else
- stack->flags |= PID_ON;
- break;
-#ifndef THREAD
- case 'g':
- if (OpenProfile(cs, PROF_FILE))
- {
- stack->flags |= PROFILE_ON;
- stack->p_functions= ListAdd(stack->p_functions, control, end);
- }
- break;
-#endif
- case 'L':
- if (sign < 0)
- stack->flags &= ~LINE_ON;
- else
- stack->flags |= LINE_ON;
- break;
- case 'n':
- if (sign < 0)
- stack->flags &= ~DEPTH_ON;
- else
- stack->flags |= DEPTH_ON;
- break;
- case 'N':
- if (sign < 0)
- stack->flags &= ~NUMBER_ON;
- else
- stack->flags |= NUMBER_ON;
- break;
- case 'A':
- case 'O':
- stack->flags |= FLUSH_ON_WRITE;
- /* fall through */
- case 'a':
- case 'o':
- if (sign < 0)
- {
- if (!is_shared(stack, out_file))
- DBUGCloseFile(cs, stack->out_file);
- stack->flags &= ~FLUSH_ON_WRITE;
- stack->out_file= stderr;
- break;
- }
- if (c == 'a' || c == 'A')
- stack->flags |= OPEN_APPEND;
- else
- stack->flags &= ~OPEN_APPEND;
- if (control != end)
- DBUGOpenFile(cs, control, end, stack->flags & OPEN_APPEND);
- else
- DBUGOpenFile(cs, "-",0,0);
- break;
- case 'p':
- if (sign < 0 && control == end)
- {
- if (!is_shared(stack,processes))
- FreeList(stack->processes);
- stack->processes=NULL;
- break;
- }
- if (rel && is_shared(stack, processes))
- stack->processes= ListCopy(stack->processes);
- if (sign < 0)
- stack->processes= ListDel(stack->processes, control, end);
- else
- stack->processes= ListAdd(stack->processes, control, end);
- break;
- case 'P':
- if (sign < 0)
- stack->flags &= ~PROCESS_ON;
- else
- stack->flags |= PROCESS_ON;
- break;
- case 'r':
- stack->sub_level= cs->level;
- break;
- case 't':
- if (sign < 0)
- {
- if (control != end)
- stack->maxdepth-= atoi(control);
- else
- stack->maxdepth= 0;
- }
- else
- {
- if (control != end)
- stack->maxdepth+= atoi(control);
- else
- stack->maxdepth= MAXDEPTH;
- }
- if (stack->maxdepth > 0)
- stack->flags |= TRACE_ON;
- else
- stack->flags &= ~TRACE_ON;
- break;
- case 'T':
- if (sign < 0)
- stack->flags &= ~TIMESTAMP_ON;
- else
- stack->flags |= TIMESTAMP_ON;
- break;
- case 'S':
- if (sign < 0)
- stack->flags &= ~SANITY_CHECK_ON;
- else
- stack->flags |= SANITY_CHECK_ON;
- break;
- }
- if (!*end)
- break;
- control=end+1;
- end= DbugStrTok(control);
- }
- return !rel || f_used;
-}
-
-#define framep_trace_flag(cs, frp) (frp ? \
- frp->level & TRACE_ON : \
- (ListFlags(cs->stack->functions) & INCLUDE) ? \
- 0 : (uint)TRACE_ON)
-
-void FixTraceFlags_helper(CODE_STATE *cs, const char *func,
- struct _db_stack_frame_ *framep)
-{
- if (framep->prev)
- FixTraceFlags_helper(cs, framep->func, framep->prev);
-
- cs->func= func;
- cs->level= framep->level & ~TRACE_ON;
- framep->level= cs->level | framep_trace_flag(cs, framep->prev);
- /*
- we don't set cs->framep correctly, even though DoTrace uses it.
- It's ok, because cs->framep may only affect DO_TRACE/DONT_TRACE return
- values, but we ignore them here anyway
- */
- switch(DoTrace(cs)) {
- case ENABLE_TRACE:
- framep->level|= TRACE_ON;
- break;
- case DISABLE_TRACE:
- framep->level&= ~TRACE_ON;
- break;
- }
-}
-
-#define fflags(cs) cs->stack->out_file ? ListFlags(cs->stack->functions) : TRACE_ON;
-
-void FixTraceFlags(uint old_fflags, CODE_STATE *cs)
-{
- const char *func;
- uint new_fflags, traceon, level;
- struct _db_stack_frame_ *framep;
-
- /*
- first (a.k.a. safety) check:
- if we haven't started tracing yet, no call stack at all - we're safe.
- */
- framep=cs->framep;
- if (framep == 0)
- return;
-
- /*
- Ok, the tracing has started, call stack isn't empty.
-
- second check: does the new list have a SUBDIR rule ?
- */
- new_fflags=fflags(cs);
- if (new_fflags & SUBDIR)
- goto yuck;
-
- /*
- Ok, new list doesn't use SUBDIR.
-
- third check: we do NOT need to re-scan if
- neither old nor new lists used SUBDIR flag and if a default behavior
- (whether an unlisted function is traced) hasn't changed.
- Default behavior depends on whether there're INCLUDE elements in the list.
- */
- if (!(old_fflags & SUBDIR) && !((new_fflags^old_fflags) & INCLUDE))
- return;
-
- /*
- Ok, old list may've used SUBDIR, or defaults could've changed.
-
- fourth check: are we inside a currently active SUBDIR rule ?
- go up the call stack, if TRACE_ON flag ever changes its value - we are.
- */
- for (traceon=framep->level; framep; framep=framep->prev)
- if ((traceon ^ framep->level) & TRACE_ON)
- goto yuck;
-
- /*
- Ok, TRACE_ON flag doesn't change in the call stack.
-
- fifth check: but is the top-most value equal to a default one ?
- */
- if (((traceon & TRACE_ON) != 0) == ((new_fflags & INCLUDE) == 0))
- return;
-
-yuck:
- /*
- Yuck! function list was changed, and one of the currently active rules
- was possibly affected. For example, a tracing could've been enabled or
- disabled for a function somewhere up the call stack.
- To react correctly, we must go up the call stack all the way to
- the top and re-match rules to set TRACE_ON bit correctly.
-
- We must traverse the stack forwards, not backwards.
- That's what a recursive helper is doing.
- It'll destroy two CODE_STATE fields, save them now.
- */
- func= cs->func;
- level= cs->level;
- FixTraceFlags_helper(cs, func, cs->framep);
- /* now we only need to restore CODE_STATE fields, and we're done */
- cs->func= func;
- cs->level= level;
-}
-
-/*
- * FUNCTION
- *
- * _db_set_ set current debugger settings
- *
- * SYNOPSIS
- *
- * VOID _db_set_(control)
- * char *control;
- *
- * DESCRIPTION
- *
- * Given pointer to a debug control string in "control",
- * parses the control string, and sets up a current debug
- * settings. Pushes a new debug settings if the current is
- * set to the initial debugger settings.
- *
- */
-
-void _db_set_(const char *control)
-{
- CODE_STATE *cs;
- uint old_fflags;
- get_code_state_or_return;
- old_fflags=fflags(cs);
- if (cs->stack == &init_settings)
- PushState(cs);
- if (DbugParse(cs, control))
- FixTraceFlags(old_fflags, cs);
-}
-
-/*
- * FUNCTION
- *
- * _db_push_ push current debugger settings and set up new one
- *
- * SYNOPSIS
- *
- * VOID _db_push_(control)
- * char *control;
- *
- * DESCRIPTION
- *
- * Given pointer to a debug control string in "control", pushes
- * the current debug settings, parses the control string, and sets
- * up a new debug settings with DbugParse()
- *
- */
-
-void _db_push_(const char *control)
-{
- CODE_STATE *cs;
- uint old_fflags;
- get_code_state_or_return;
- old_fflags=fflags(cs);
- PushState(cs);
- if (DbugParse(cs, control))
- FixTraceFlags(old_fflags, cs);
-}
-
-
-/**
- Returns TRUE if session-local settings have been set.
-*/
-
-int _db_is_pushed_()
-{
- CODE_STATE *cs= NULL;
- get_code_state_or_return FALSE;
- return (cs->stack != &init_settings);
-}
-
-/*
- * FUNCTION
- *
- * _db_set_init_ set initial debugger settings
- *
- * SYNOPSIS
- *
- * VOID _db_set_init_(control)
- * char *control;
- *
- * DESCRIPTION
- * see _db_set_
- *
- */
-
-void _db_set_init_(const char *control)
-{
- CODE_STATE tmp_cs;
- bzero((uchar*) &tmp_cs, sizeof(tmp_cs));
- tmp_cs.stack= &init_settings;
- DbugParse(&tmp_cs, control);
-}
-
-/*
- * FUNCTION
- *
- * _db_pop_ pop the debug stack
- *
- * DESCRIPTION
- *
- * Pops the debug stack, returning the debug settings to its
- * condition prior to the most recent _db_push_ invocation.
- * Note that the pop will fail if it would remove the last
- * valid settings from the stack. This prevents user errors
- * in the push/pop sequence from screwing up the debugger.
- * Maybe there should be some kind of warning printed if the
- * user tries to pop too many states.
- *
- */
-
-void _db_pop_()
-{
- struct settings *discard;
- uint old_fflags;
- CODE_STATE *cs;
-
- get_code_state_or_return;
-
- discard= cs->stack;
- if (discard != &init_settings)
- {
- old_fflags=fflags(cs);
- cs->stack= discard->next;
- FreeState(cs, discard, 1);
- FixTraceFlags(old_fflags, cs);
- }
-}
-
-/*
- * FUNCTION
- *
- * _db_explain_ generates 'control' string for the current settings
- *
- * RETURN
- * 0 - ok
- * 1 - buffer too short, output truncated
- *
- */
-
-/* helper macros */
-#define char_to_buf(C) do { \
- *buf++=(C); \
- if (buf >= end) goto overflow; \
- } while (0)
-#define str_to_buf(S) do { \
- char_to_buf(','); \
- buf=strnmov(buf, (S), len+1); \
- if (buf >= end) goto overflow; \
- } while (0)
-#define list_to_buf(l, f) do { \
- struct link *listp=(l); \
- while (listp) \
- { \
- if (listp->flags & (f)) \
- { \
- str_to_buf(listp->str); \
- if (listp->flags & SUBDIR) \
- char_to_buf('/'); \
- } \
- listp=listp->next_link; \
- } \
- } while (0)
-#define int_to_buf(i) do { \
- char b[50]; \
- int10_to_str((i), b, 10); \
- str_to_buf(b); \
- } while (0)
-#define colon_to_buf do { \
- if (buf != start) char_to_buf(':'); \
- } while(0)
-#define op_int_to_buf(C, val, def) do { \
- if ((val) != (def)) \
- { \
- colon_to_buf; \
- char_to_buf((C)); \
- int_to_buf(val); \
- } \
- } while (0)
-#define op_intf_to_buf(C, val, def, cond) do { \
- if ((cond)) \
- { \
- colon_to_buf; \
- char_to_buf((C)); \
- if ((val) != (def)) int_to_buf(val); \
- } \
- } while (0)
-#define op_str_to_buf(C, val, cond) do { \
- if ((cond)) \
- { \
- char *s=(val); \
- colon_to_buf; \
- char_to_buf((C)); \
- if (*s) str_to_buf(s); \
- } \
- } while (0)
-#define op_list_to_buf(C, val, cond) do { \
- if ((cond)) \
- { \
- int f=ListFlags(val); \
- colon_to_buf; \
- char_to_buf((C)); \
- if (f & INCLUDE) \
- list_to_buf(val, INCLUDE); \
- if (f & EXCLUDE) \
- { \
- colon_to_buf; \
- char_to_buf('-'); \
- char_to_buf((C)); \
- list_to_buf(val, EXCLUDE); \
- } \
- } \
- } while (0)
-#define op_bool_to_buf(C, cond) do { \
- if ((cond)) \
- { \
- colon_to_buf; \
- char_to_buf((C)); \
- } \
- } while (0)
-
-int _db_explain_ (CODE_STATE *cs, char *buf, size_t len)
-{
- char *start=buf, *end=buf+len-4;
-
- get_code_state_if_not_set_or_return *buf=0;
-
- op_list_to_buf('d', cs->stack->keywords, DEBUGGING);
- op_int_to_buf ('D', cs->stack->delay, 0);
- op_list_to_buf('f', cs->stack->functions, cs->stack->functions);
- op_bool_to_buf('F', cs->stack->flags & FILE_ON);
- op_bool_to_buf('i', cs->stack->flags & PID_ON);
- op_list_to_buf('g', cs->stack->p_functions, PROFILING);
- op_bool_to_buf('L', cs->stack->flags & LINE_ON);
- op_bool_to_buf('n', cs->stack->flags & DEPTH_ON);
- op_bool_to_buf('N', cs->stack->flags & NUMBER_ON);
- op_str_to_buf(
- ((cs->stack->flags & FLUSH_ON_WRITE ? 0 : 32) |
- (cs->stack->flags & OPEN_APPEND ? 'A' : 'O')),
- cs->stack->name, cs->stack->out_file != stderr);
- op_list_to_buf('p', cs->stack->processes, cs->stack->processes);
- op_bool_to_buf('P', cs->stack->flags & PROCESS_ON);
- op_bool_to_buf('r', cs->stack->sub_level != 0);
- op_intf_to_buf('t', cs->stack->maxdepth, MAXDEPTH, TRACING);
- op_bool_to_buf('T', cs->stack->flags & TIMESTAMP_ON);
- op_bool_to_buf('S', cs->stack->flags & SANITY_CHECK_ON);
-
- *buf= '\0';
- return 0;
-
-overflow:
- *end++= '.';
- *end++= '.';
- *end++= '.';
- *end= '\0';
- return 1;
-}
-
-#undef char_to_buf
-#undef str_to_buf
-#undef list_to_buf
-#undef int_to_buf
-#undef colon_to_buf
-#undef op_int_to_buf
-#undef op_intf_to_buf
-#undef op_str_to_buf
-#undef op_list_to_buf
-#undef op_bool_to_buf
-
-/*
- * FUNCTION
- *
- * _db_explain_init_ explain initial debugger settings
- *
- * DESCRIPTION
- * see _db_explain_
- */
-
-int _db_explain_init_(char *buf, size_t len)
-{
- CODE_STATE cs;
- bzero((uchar*) &cs,sizeof(cs));
- cs.stack=&init_settings;
- return _db_explain_(&cs, buf, len);
-}
-
-/*
- * FUNCTION
- *
- * _db_enter_ process entry point to user function
- *
- * SYNOPSIS
- *
- * VOID _db_enter_(_func_, _file_, _line_, _stack_frame_)
- * char *_func_; points to current function name
- * char *_file_; points to current file name
- * int _line_; called from source line number
- * struct _db_stack_frame_ allocated on the caller's stack
- *
- * DESCRIPTION
- *
- * Called at the beginning of each user function to tell
- * the debugger that a new function has been entered.
- * Note that the pointers to the previous user function
- * name and previous user file name are stored on the
- * caller's stack (this is why the ENTER macro must be
- * the first "executable" code in a function, since it
- * allocates these storage locations). The previous nesting
- * level is also stored on the callers stack for internal
- * self consistency checks.
- *
- * Also prints a trace line if tracing is enabled and
- * increments the current function nesting depth.
- *
- * Note that this mechanism allows the debugger to know
- * what the current user function is at all times, without
- * maintaining an internal stack for the function names.
- *
- */
-
-void _db_enter_(const char *_func_, const char *_file_,
- uint _line_, struct _db_stack_frame_ *_stack_frame_)
-{
- int save_errno;
- CODE_STATE *cs;
- if (!((cs=code_state())))
- {
- _stack_frame_->level= 0; /* Set to avoid valgrind warnings if dbug is enabled later */
- _stack_frame_->prev= 0;
- return;
- }
- save_errno= errno;
-
- _stack_frame_->func= cs->func;
- _stack_frame_->file= cs->file;
- cs->func= _func_;
- cs->file= _file_;
- _stack_frame_->prev= cs->framep;
- _stack_frame_->level= ++cs->level | framep_trace_flag(cs, cs->framep);
- cs->framep= _stack_frame_;
-#ifndef THREAD
- if (DoProfile(cs))
- {
- long stackused;
- if (cs->framep->prev == NULL)
- stackused= 0;
- else
- {
- stackused= (char*)(cs->framep->prev) - (char*)(cs->framep);
- stackused= stackused > 0 ? stackused : -stackused;
- }
- (void) fprintf(cs->stack->prof_file, PROF_EFMT , Clock(), cs->func);
- (void) fprintf(cs->stack->prof_file, PROF_SFMT, (ulong) cs->framep, stackused,
- AUTOS_REVERSE ? _stack_frame_->func : cs->func);
- (void) fflush(cs->stack->prof_file);
- }
-#endif
- switch (DoTrace(cs)) {
- case ENABLE_TRACE:
- cs->framep->level|= TRACE_ON;
- if (!TRACING) break;
- /* fall through */
- case DO_TRACE:
- if ((cs->stack->flags & SANITY_CHECK_ON) && _sanity(_file_,_line_))
- cs->stack->flags &= ~SANITY_CHECK_ON;
- if (TRACING)
- {
- if (!cs->locked)
- pthread_mutex_lock(&THR_LOCK_dbug);
- DoPrefix(cs, _line_);
- Indent(cs, cs->level);
- (void) fprintf(cs->stack->out_file, ">%s\n", cs->func);
- DbugFlush(cs); /* This does a unlock */
- }
- break;
- case DISABLE_TRACE:
- cs->framep->level&= ~TRACE_ON;
- /* fall through */
- case DONT_TRACE:
- break;
- }
- errno=save_errno;
-}
-
-/*
- * FUNCTION
- *
- * _db_return_ process exit from user function
- *
- * SYNOPSIS
- *
- * VOID _db_return_(_line_, _stack_frame_)
- * int _line_; current source line number
- * struct _db_stack_frame_ allocated on the caller's stack
- *
- * DESCRIPTION
- *
- * Called just before user function executes an explicit or implicit
- * return. Prints a trace line if trace is enabled, decrements
- * the current nesting level, and restores the current function and
- * file names from the defunct function's stack.
- *
- */
-
-/* helper macro */
-void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_)
-{
- int save_errno=errno;
- uint _slevel_= _stack_frame_->level & ~TRACE_ON;
- CODE_STATE *cs;
- get_code_state_or_return;
-
- if (cs->level != _slevel_)
- {
- if (!cs->locked)
- pthread_mutex_lock(&THR_LOCK_dbug);
- (void) fprintf(cs->stack->out_file, ERR_MISSING_RETURN, cs->process,
- cs->func);
- DbugFlush(cs);
- }
- else
- {
-#ifndef THREAD
- if (DoProfile(cs))
- (void) fprintf(cs->stack->prof_file, PROF_XFMT, Clock(), cs->func);
-#endif
- if (DoTrace(cs) & DO_TRACE)
- {
- if ((cs->stack->flags & SANITY_CHECK_ON) &&
- _sanity(_stack_frame_->file,_line_))
- cs->stack->flags &= ~SANITY_CHECK_ON;
- if (TRACING)
- {
- if (!cs->locked)
- pthread_mutex_lock(&THR_LOCK_dbug);
- DoPrefix(cs, _line_);
- Indent(cs, cs->level);
- (void) fprintf(cs->stack->out_file, "<%s\n", cs->func);
- DbugFlush(cs);
- }
- }
- }
- /*
- Check to not set level < 0. This can happen if DBUG was disabled when
- function was entered and enabled in function.
- */
- cs->level= _slevel_ != 0 ? _slevel_ - 1 : 0;
- cs->func= _stack_frame_->func;
- cs->file= _stack_frame_->file;
- if (cs->framep != NULL)
- cs->framep= cs->framep->prev;
- errno=save_errno;
-}
-
-
-/*
- * FUNCTION
- *
- * _db_pargs_ log arguments for subsequent use by _db_doprnt_()
- *
- * SYNOPSIS
- *
- * VOID _db_pargs_(_line_, keyword)
- * int _line_;
- * char *keyword;
- *
- * DESCRIPTION
- *
- * The new universal printing macro DBUG_PRINT, which replaces
- * all forms of the DBUG_N macros, needs two calls to runtime
- * support routines. The first, this function, remembers arguments
- * that are used by the subsequent call to _db_doprnt_().
- *
- */
-
-void _db_pargs_(uint _line_, const char *keyword)
-{
- CODE_STATE *cs;
- get_code_state_or_return;
- cs->u_line= _line_;
- cs->u_keyword= keyword;
-}
-
-
-/*
- * FUNCTION
- *
- * _db_doprnt_ handle print of debug lines
- *
- * SYNOPSIS
- *
- * VOID _db_doprnt_(format, va_alist)
- * char *format;
- * va_dcl;
- *
- * DESCRIPTION
- *
- * When invoked via one of the DBUG macros, tests the current keyword
- * set by calling _db_pargs_() to see if that macro has been selected
- * for processing via the debugger control string, and if so, handles
- * printing of the arguments via the format string. The line number
- * of the DBUG macro in the source is found in u_line.
- *
- * Note that the format string SHOULD NOT include a terminating
- * newline, this is supplied automatically.
- *
- */
-
-#include <stdarg.h>
-
-void _db_doprnt_(const char *format,...)
-{
- va_list args;
- CODE_STATE *cs;
- get_code_state_or_return;
-
- va_start(args,format);
-
- if (_db_keyword_(cs, cs->u_keyword, 0))
- {
- int save_errno=errno;
- if (!cs->locked)
- pthread_mutex_lock(&THR_LOCK_dbug);
- DoPrefix(cs, cs->u_line);
- if (TRACING)
- Indent(cs, cs->level + 1);
- else
- (void) fprintf(cs->stack->out_file, "%s: ", cs->func);
- (void) fprintf(cs->stack->out_file, "%s: ", cs->u_keyword);
- DbugFprintf(cs->stack->out_file, format, args);
- DbugFlush(cs);
- errno=save_errno;
- }
- va_end(args);
-}
-
-/*
- * fprintf clone with consistent, platform independent output for
- * problematic formats like %p, %zd and %lld.
- */
-static void DbugFprintf(FILE *stream, const char* format, va_list args)
-{
- char cvtbuf[1024];
- size_t len;
- len = my_vsnprintf(cvtbuf, sizeof(cvtbuf), format, args);
- (void) fprintf(stream, "%s\n", cvtbuf);
-}
-
-
-/*
- * FUNCTION
- *
- * _db_dump_ dump a string in hex
- *
- * SYNOPSIS
- *
- * void _db_dump_(_line_,keyword,memory,length)
- * int _line_; current source line number
- * char *keyword;
- * char *memory; Memory to print
- * int length; Bytes to print
- *
- * DESCRIPTION
- * Dump N characters in a binary array.
- * Is used to examine corrputed memory or arrays.
- */
-
-void _db_dump_(uint _line_, const char *keyword,
- const unsigned char *memory, size_t length)
-{
- int pos;
- char dbuff[90];
- CODE_STATE *cs;
- get_code_state_or_return;
-
- if (_db_keyword_(cs, keyword, 0))
- {
- if (!cs->locked)
- pthread_mutex_lock(&THR_LOCK_dbug);
- DoPrefix(cs, _line_);
- if (TRACING)
- {
- Indent(cs, cs->level + 1);
- pos= min(max(cs->level-cs->stack->sub_level,0)*INDENT,80);
- }
- else
- {
- fprintf(cs->stack->out_file, "%s: ", cs->func);
- }
- sprintf(dbuff,"%s: Memory: 0x%lx Bytes: (%ld)\n",
- keyword, (ulong) memory, (long) length);
- (void) fputs(dbuff,cs->stack->out_file);
-
- pos=0;
- while (length-- > 0)
- {
- uint tmp= *((unsigned char*) memory++);
- if ((pos+=3) >= 80)
- {
- fputc('\n',cs->stack->out_file);
- pos=3;
- }
- fputc(_dig_vec_upper[((tmp >> 4) & 15)], cs->stack->out_file);
- fputc(_dig_vec_upper[tmp & 15], cs->stack->out_file);
- fputc(' ',cs->stack->out_file);
- }
- (void) fputc('\n',cs->stack->out_file);
- DbugFlush(cs);
- }
-}
-
-
-/*
- * FUNCTION
- *
- * ListAddDel modify the list according to debug control string
- *
- * DESCRIPTION
- *
- * Given pointer to a comma separated list of strings in "cltp",
- * parses the list, and modifies "listp", returning a pointer
- * to the new list.
- *
- * The mode of operation is defined by "todo" parameter.
- *
- * If it is INCLUDE, elements (strings from "cltp") are added to the
- * list, they will have INCLUDE flag set. If the list already contains
- * the string in question, new element is not added, but a flag of
- * the existing element is adjusted (INCLUDE bit is set, EXCLUDE bit
- * is removed).
- *
- * If it is EXCLUDE, elements are added to the list with the EXCLUDE
- * flag set. If the list already contains the string in question,
- * it is removed, new element is not added.
- */
-
-static struct link *ListAddDel(struct link *head, const char *ctlp,
- const char *end, int todo)
-{
- const char *start;
- struct link **cur;
- size_t len;
- int subdir;
-
- ctlp--;
-next:
- while (++ctlp < end)
- {
- start= ctlp;
- subdir=0;
- while (ctlp < end && *ctlp != ',')
- ctlp++;
- len=ctlp-start;
- if (start[len-1] == '/')
- {
- len--;
- subdir=SUBDIR;
- }
- if (len == 0) continue;
- for (cur=&head; *cur; cur=&((*cur)->next_link))
- {
- if (!strncmp((*cur)->str, start, len))
- {
- if ((*cur)->flags & todo) /* same action ? */
- (*cur)->flags|= subdir; /* just merge the SUBDIR flag */
- else if (todo == EXCLUDE)
- {
- struct link *delme=*cur;
- *cur=(*cur)->next_link;
- free((void*) delme);
- }
- else
- {
- (*cur)->flags&=~(EXCLUDE & SUBDIR);
- (*cur)->flags|=INCLUDE | subdir;
- }
- goto next;
- }
- }
- *cur= (struct link *) DbugMalloc(sizeof(struct link)+len);
- memcpy((*cur)->str, start, len);
- (*cur)->str[len]=0;
- (*cur)->flags=todo | subdir;
- (*cur)->next_link=0;
- }
- return head;
-}
-
-/*
- * FUNCTION
- *
- * ListCopy make a copy of the list
- *
- * SYNOPSIS
- *
- * static struct link *ListCopy(orig)
- * struct link *orig;
- *
- * DESCRIPTION
- *
- * Given pointer to list, which contains a copy of every element from
- * the original list.
- *
- * the orig pointer can be NULL
- *
- * Note that since each link is added at the head of the list,
- * the final list will be in "reverse order", which is not
- * significant for our usage here.
- *
- */
-
-static struct link *ListCopy(struct link *orig)
-{
- struct link *new_malloc;
- struct link *head;
- size_t len;
-
- head= NULL;
- while (orig != NULL)
- {
- len= strlen(orig->str);
- new_malloc= (struct link *) DbugMalloc(sizeof(struct link)+len);
- memcpy(new_malloc->str, orig->str, len);
- new_malloc->str[len]= 0;
- new_malloc->flags=orig->flags;
- new_malloc->next_link= head;
- head= new_malloc;
- orig= orig->next_link;
- }
- return head;
-}
-
-/*
- * FUNCTION
- *
- * InList test a given string for member of a given list
- *
- * DESCRIPTION
- *
- * Tests the string pointed to by "cp" to determine if it is in
- * the list pointed to by "linkp". Linkp points to the first
- * link in the list. If linkp is NULL or contains only EXCLUDE
- * elements then the string is treated as if it is in the list.
- * This may seem rather strange at first but leads to the desired
- * operation if no list is given. The net effect is that all
- * strings will be accepted when there is no list, and when there
- * is a list, only those strings in the list will be accepted.
- *
- * RETURN
- * combination of SUBDIR, INCLUDE, EXCLUDE, MATCHED flags
- *
- */
-
-static int InList(struct link *linkp, const char *cp)
-{
- int result;
-
- for (result=MATCHED; linkp != NULL; linkp= linkp->next_link)
- {
- if (!fnmatch(linkp->str, cp, 0))
- return linkp->flags;
- if (!(linkp->flags & EXCLUDE))
- result=NOT_MATCHED;
- if (linkp->flags & SUBDIR)
- result|=SUBDIR;
- }
- return result;
-}
-
-/*
- * FUNCTION
- *
- * ListFlags returns aggregated list flags (ORed over all elements)
- *
- */
-
-static uint ListFlags(struct link *linkp)
-{
- uint f;
- for (f=0; linkp != NULL; linkp= linkp->next_link)
- f|= linkp->flags;
- return f;
-}
-
-/*
- * FUNCTION
- *
- * PushState push current settings onto stack and set up new one
- *
- * SYNOPSIS
- *
- * static VOID PushState()
- *
- * DESCRIPTION
- *
- * Pushes the current settings on the settings stack, and creates
- * a new settings. The new settings is NOT initialized
- *
- * The settings stack is a linked list of settings, with the new
- * settings added at the head. This allows the stack to grow
- * to the limits of memory if necessary.
- *
- */
-
-static void PushState(CODE_STATE *cs)
-{
- struct settings *new_malloc;
-
- new_malloc= (struct settings *) DbugMalloc(sizeof(struct settings));
- bzero(new_malloc, sizeof(*new_malloc));
- new_malloc->next= cs->stack;
- cs->stack= new_malloc;
-}
-
-/*
- * FUNCTION
- *
- * FreeState Free memory associated with a struct state.
- *
- * SYNOPSIS
- *
- * static void FreeState (state)
- * struct state *state;
- * int free_state;
- *
- * DESCRIPTION
- *
- * Deallocates the memory allocated for various information in a
- * state. If free_state is set, also free 'state'
- *
- */
-static void FreeState(CODE_STATE *cs, struct settings *state, int free_state)
-{
- if (!is_shared(state, keywords))
- FreeList(state->keywords);
- if (!is_shared(state, functions))
- FreeList(state->functions);
- if (!is_shared(state, processes))
- FreeList(state->processes);
- if (!is_shared(state, p_functions))
- FreeList(state->p_functions);
-
- if (!is_shared(state, out_file))
- DBUGCloseFile(cs, state->out_file);
- else
- (void) fflush(state->out_file);
-
- if (!is_shared(state, prof_file))
- DBUGCloseFile(cs, state->prof_file);
- else
- (void) fflush(state->prof_file);
-
- if (free_state)
- free((void*) state);
-}
-
-
-/*
- * FUNCTION
- *
- * _db_end_ End debugging, freeing state stack memory.
- *
- * SYNOPSIS
- *
- * static VOID _db_end_ ()
- *
- * DESCRIPTION
- *
- * Ends debugging, de-allocating the memory allocated to the
- * state stack.
- *
- * To be called at the very end of the program.
- *
- */
-void _db_end_()
-{
- struct settings *discard;
- static struct settings tmp;
- CODE_STATE *cs;
- /*
- Set _dbug_on_ to be able to do full reset even when DEBUGGER_OFF was
- called after dbug was initialized
- */
- _dbug_on_= 1;
- get_code_state_or_return;
-
- while ((discard= cs->stack))
- {
- if (discard == &init_settings)
- break;
- cs->stack= discard->next;
- FreeState(cs, discard, 1);
- }
- tmp= init_settings;
-
- /* Use mutex lock to make it less likely anyone access out_file */
- pthread_mutex_lock(&THR_LOCK_dbug);
- init_settings.flags= OPEN_APPEND;
- init_settings.out_file= stderr;
- init_settings.prof_file= stderr;
- init_settings.maxdepth= 0;
- init_settings.delay= 0;
- init_settings.sub_level= 0;
- init_settings.functions= 0;
- init_settings.p_functions= 0;
- init_settings.keywords= 0;
- init_settings.processes= 0;
- pthread_mutex_unlock(&THR_LOCK_dbug);
- FreeState(cs, &tmp, 0);
-}
-
-
-/*
- * FUNCTION
- *
- * DoTrace check to see if tracing is current enabled
- *
- * DESCRIPTION
- *
- * Checks to see if dbug in this function is enabled based on
- * whether the maximum trace depth has been reached, the current
- * function is selected, and the current process is selected.
- *
- */
-
-static int DoTrace(CODE_STATE *cs)
-{
- if ((cs->stack->maxdepth == 0 || cs->level <= cs->stack->maxdepth) &&
- InList(cs->stack->processes, cs->process) & (MATCHED|INCLUDE))
- switch(InList(cs->stack->functions, cs->func)) {
- case INCLUDE|SUBDIR: return ENABLE_TRACE;
- case INCLUDE: return DO_TRACE;
- case MATCHED|SUBDIR:
- case NOT_MATCHED|SUBDIR:
- case MATCHED: return framep_trace_flag(cs, cs->framep) ?
- DO_TRACE : DONT_TRACE;
- case EXCLUDE:
- case NOT_MATCHED: return DONT_TRACE;
- case EXCLUDE|SUBDIR: return DISABLE_TRACE;
- }
- return DONT_TRACE;
-}
-
-
-/*
- * FUNCTION
- *
- * DoProfile check to see if profiling is current enabled
- *
- * SYNOPSIS
- *
- * static BOOLEAN DoProfile()
- *
- * DESCRIPTION
- *
- * Checks to see if profiling is enabled based on whether the
- * user has specified profiling, the maximum trace depth has
- * not yet been reached, the current function is selected,
- * and the current process is selected. Returns TRUE if
- * profiling is enabled, FALSE otherwise.
- *
- */
-
-#ifndef THREAD
-static BOOLEAN DoProfile(CODE_STATE *cs)
-{
- return PROFILING &&
- cs->level <= cs->stack->maxdepth &&
- InList(cs->stack->p_functions, cs->func) & (INCLUDE|MATCHED) &&
- InList(cs->stack->processes, cs->process) & (INCLUDE|MATCHED);
-}
-#endif
-
-FILE *_db_fp_(void)
-{
- CODE_STATE *cs;
- get_code_state_or_return NULL;
- return cs->stack->out_file;
-}
-
-/*
- * FUNCTION
- *
- * _db_keyword_ test keyword for member of keyword list
- *
- * DESCRIPTION
- *
- * Test a keyword to determine if it is in the currently active
- * keyword list. If strict=0, a keyword is accepted
- * if the list is null, otherwise it must match one of the list
- * members. When debugging is not on, no keywords are accepted.
- * After the maximum trace level is exceeded, no keywords are
- * accepted (this behavior subject to change). Additionally,
- * the current function and process must be accepted based on
- * their respective lists.
- *
- * Returns TRUE if keyword accepted, FALSE otherwise.
- *
- */
-
-BOOLEAN _db_keyword_(CODE_STATE *cs, const char *keyword, int strict)
-{
- get_code_state_if_not_set_or_return FALSE;
- strict=strict ? INCLUDE : INCLUDE|MATCHED;
-
- return DEBUGGING && DoTrace(cs) & DO_TRACE &&
- InList(cs->stack->keywords, keyword) & strict;
-}
-
-/*
- * FUNCTION
- *
- * Indent indent a line to the given indentation level
- *
- * SYNOPSIS
- *
- * static VOID Indent(indent)
- * int indent;
- *
- * DESCRIPTION
- *
- * Indent a line to the given level. Note that this is
- * a simple minded but portable implementation.
- * There are better ways.
- *
- * Also, the indent must be scaled by the compile time option
- * of character positions per nesting level.
- *
- */
-
-static void Indent(CODE_STATE *cs, int indent)
-{
- REGISTER int count;
-
- indent= max(indent-1-cs->stack->sub_level,0)*INDENT;
- for (count= 0; count < indent ; count++)
- {
- if ((count % INDENT) == 0)
- fputc('|',cs->stack->out_file);
- else
- fputc(' ',cs->stack->out_file);
- }
-}
-
-
-/*
- * FUNCTION
- *
- * FreeList free all memory associated with a linked list
- *
- * SYNOPSIS
- *
- * static VOID FreeList(linkp)
- * struct link *linkp;
- *
- * DESCRIPTION
- *
- * Given pointer to the head of a linked list, frees all
- * memory held by the list and the members of the list.
- *
- */
-
-static void FreeList(struct link *linkp)
-{
- REGISTER struct link *old;
-
- while (linkp != NULL)
- {
- old= linkp;
- linkp= linkp->next_link;
- free((void*) old);
- }
-}
-
-
-/*
- * FUNCTION
- *
- * DoPrefix print debugger line prefix prior to indentation
- *
- * SYNOPSIS
- *
- * static VOID DoPrefix(_line_)
- * int _line_;
- *
- * DESCRIPTION
- *
- * Print prefix common to all debugger output lines, prior to
- * doing indentation if necessary. Print such information as
- * current process name, current source file name and line number,
- * and current function nesting depth.
- *
- */
-
-static void DoPrefix(CODE_STATE *cs, uint _line_)
-{
- cs->lineno++;
- if (cs->stack->flags & PID_ON)
- {
-#ifdef THREAD
- (void) fprintf(cs->stack->out_file, "%-7s: ", my_thread_name());
-#else
- (void) fprintf(cs->stack->out_file, "%5d: ", (int) getpid());
-#endif
- }
- if (cs->stack->flags & NUMBER_ON)
- (void) fprintf(cs->stack->out_file, "%5d: ", cs->lineno);
- if (cs->stack->flags & TIMESTAMP_ON)
- {
-#ifdef __WIN__
- /* FIXME This doesn't give microseconds as in Unix case, and the resolution is
- in system ticks, 10 ms intervals. See my_getsystime.c for high res */
- SYSTEMTIME loc_t;
- GetLocalTime(&loc_t);
- (void) fprintf (cs->stack->out_file,
- /* "%04d-%02d-%02d " */
- "%02d:%02d:%02d.%06d ",
- /*tm_p->tm_year + 1900, tm_p->tm_mon + 1, tm_p->tm_mday,*/
- loc_t.wHour, loc_t.wMinute, loc_t.wSecond, loc_t.wMilliseconds);
-#else
- struct timeval tv;
- struct tm *tm_p;
- if (gettimeofday(&tv, NULL) != -1)
- {
- if ((tm_p= localtime((const time_t *)&tv.tv_sec)))
- {
- (void) fprintf (cs->stack->out_file,
- /* "%04d-%02d-%02d " */
- "%02d:%02d:%02d.%06d ",
- /*tm_p->tm_year + 1900, tm_p->tm_mon + 1, tm_p->tm_mday,*/
- tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec,
- (int) (tv.tv_usec));
- }
- }
-#endif
- }
- if (cs->stack->flags & PROCESS_ON)
- (void) fprintf(cs->stack->out_file, "%s: ", cs->process);
- if (cs->stack->flags & FILE_ON)
- (void) fprintf(cs->stack->out_file, "%14s: ", BaseName(cs->file));
- if (cs->stack->flags & LINE_ON)
- (void) fprintf(cs->stack->out_file, "%5d: ", _line_);
- if (cs->stack->flags & DEPTH_ON)
- (void) fprintf(cs->stack->out_file, "%4d: ", cs->level);
-}
-
-
-/*
- * FUNCTION
- *
- * DBUGOpenFile open new output stream for debugger output
- *
- * SYNOPSIS
- *
- * static VOID DBUGOpenFile(name)
- * char *name;
- *
- * DESCRIPTION
- *
- * Given name of a new file (or "-" for stdout) opens the file
- * and sets the output stream to the new file.
- *
- */
-
-static void DBUGOpenFile(CODE_STATE *cs,
- const char *name,const char *end,int append)
-{
- REGISTER FILE *fp;
- REGISTER BOOLEAN newfile;
-
- if (name != NULL)
- {
- if (end)
- {
- size_t len=end-name;
- memcpy(cs->stack->name, name, len);
- cs->stack->name[len]=0;
- }
- else
- strmov(cs->stack->name,name);
- name=cs->stack->name;
- if (strcmp(name, "-") == 0)
- {
- cs->stack->out_file= stdout;
- cs->stack->flags |= FLUSH_ON_WRITE;
- cs->stack->name[0]=0;
- }
- else
- {
- if (!Writable(name))
- {
- (void) fprintf(stderr, ERR_OPEN, cs->process, name);
- perror("");
- fflush(stderr);
- }
- else
- {
- newfile= !EXISTS(name);
- if (!(fp= fopen(name, append ? "a+" : "w")))
- {
- (void) fprintf(stderr, ERR_OPEN, cs->process, name);
- perror("");
- fflush(stderr);
- }
- else
- {
- cs->stack->out_file= fp;
- if (newfile)
- {
- ChangeOwner(cs, name);
- }
- }
- }
- }
- }
-}
-
-
-/*
- * FUNCTION
- *
- * OpenProfile open new output stream for profiler output
- *
- * SYNOPSIS
- *
- * static FILE *OpenProfile(name)
- * char *name;
- *
- * DESCRIPTION
- *
- * Given name of a new file, opens the file
- * and sets the profiler output stream to the new file.
- *
- * It is currently unclear whether the prefered behavior is
- * to truncate any existing file, or simply append to it.
- * The latter behavior would be desirable for collecting
- * accumulated runtime history over a number of separate
- * runs. It might take some changes to the analyzer program
- * though, and the notes that Binayak sent with the profiling
- * diffs indicated that append was the normal mode, but this
- * does not appear to agree with the actual code. I haven't
- * investigated at this time [fnf; 24-Jul-87].
- */
-
-#ifndef THREAD
-static FILE *OpenProfile(CODE_STATE *cs, const char *name)
-{
- REGISTER FILE *fp;
- REGISTER BOOLEAN newfile;
-
- fp=0;
- if (!Writable(name))
- {
- (void) fprintf(cs->stack->out_file, ERR_OPEN, cs->process, name);
- perror("");
- (void) Delay(cs->stack->delay);
- }
- else
- {
- newfile= !EXISTS(name);
- if (!(fp= fopen(name, "w")))
- {
- (void) fprintf(cs->stack->out_file, ERR_OPEN, cs->process, name);
- perror("");
- }
- else
- {
- cs->stack->prof_file= fp;
- if (newfile)
- {
- ChangeOwner(cs, name);
- }
- }
- }
- return fp;
-}
-#endif
-
-/*
- * FUNCTION
- *
- * DBUGCloseFile close the debug output stream
- *
- * SYNOPSIS
- *
- * static VOID DBUGCloseFile(fp)
- * FILE *fp;
- *
- * DESCRIPTION
- *
- * Closes the debug output stream unless it is standard output
- * or standard error.
- *
- */
-
-static void DBUGCloseFile(CODE_STATE *cs, FILE *fp)
-{
- if (fp && fp != stderr && fp != stdout && fclose(fp) == EOF)
- {
- pthread_mutex_lock(&THR_LOCK_dbug);
- (void) fprintf(cs->stack->out_file, ERR_CLOSE, cs->process);
- perror("");
- DbugFlush(cs);
- }
-}
-
-
-/*
- * FUNCTION
- *
- * DbugExit print error message and exit
- *
- * SYNOPSIS
- *
- * static VOID DbugExit(why)
- * char *why;
- *
- * DESCRIPTION
- *
- * Prints error message using current process name, the reason for
- * aborting (typically out of memory), and exits with status 1.
- * This should probably be changed to use a status code
- * defined in the user's debugger include file.
- *
- */
-
-static void DbugExit(const char *why)
-{
- CODE_STATE *cs=code_state();
- (void) fprintf(stderr, ERR_ABORT, cs ? cs->process : "(null)", why);
- (void) fflush(stderr);
- exit(1);
-}
-
-
-/*
- * FUNCTION
- *
- * DbugMalloc allocate memory for debugger runtime support
- *
- * SYNOPSIS
- *
- * static long *DbugMalloc(size)
- * int size;
- *
- * DESCRIPTION
- *
- * Allocate more memory for debugger runtime support functions.
- * Failure to to allocate the requested number of bytes is
- * immediately fatal to the current process. This may be
- * rather unfriendly behavior. It might be better to simply
- * print a warning message, freeze the current debugger cs,
- * and continue execution.
- *
- */
-
-static char *DbugMalloc(size_t size)
-{
- register char *new_malloc;
-
- if (!(new_malloc= (char*) malloc(size)))
- DbugExit("out of memory");
- return new_malloc;
-}
-
-
-/*
- * strtok lookalike - splits on ':', magically handles ::, :\ and :/
- */
-
-static const char *DbugStrTok(const char *s)
-{
- while (s[0] && (s[0] != ':' ||
- (s[1] == '\\' || s[1] == '/' || (s[1] == ':' && s++))))
- s++;
- return s;
-}
-
-
-/*
- * FUNCTION
- *
- * BaseName strip leading pathname components from name
- *
- * SYNOPSIS
- *
- * static char *BaseName(pathname)
- * char *pathname;
- *
- * DESCRIPTION
- *
- * Given pointer to a complete pathname, locates the base file
- * name at the end of the pathname and returns a pointer to
- * it.
- *
- */
-
-static const char *BaseName(const char *pathname)
-{
- register const char *base;
-
- base= strrchr(pathname, FN_LIBCHAR);
- if (base++ == NullS)
- base= pathname;
- return base;
-}
-
-
-/*
- * FUNCTION
- *
- * Writable test to see if a pathname is writable/creatable
- *
- * SYNOPSIS
- *
- * static BOOLEAN Writable(pathname)
- * char *pathname;
- *
- * DESCRIPTION
- *
- * Because the debugger might be linked in with a program that
- * runs with the set-uid-bit (suid) set, we have to be careful
- * about opening a user named file for debug output. This consists
- * of checking the file for write access with the real user id,
- * or checking the directory where the file will be created.
- *
- * Returns TRUE if the user would normally be allowed write or
- * create access to the named file. Returns FALSE otherwise.
- *
- */
-
-
-#ifndef Writable
-
-static BOOLEAN Writable(const char *pathname)
-{
- REGISTER BOOLEAN granted;
- REGISTER char *lastslash;
-
- granted= FALSE;
- if (EXISTS(pathname))
- {
- if (WRITABLE(pathname))
- granted= TRUE;
- }
- else
- {
- lastslash= strrchr(pathname, '/');
- if (lastslash != NULL)
- *lastslash= '\0';
- else
- pathname= ".";
- if (WRITABLE(pathname))
- granted= TRUE;
- if (lastslash != NULL)
- *lastslash= '/';
- }
- return granted;
-}
-#endif
-
-
-/*
- * FUNCTION
- *
- * ChangeOwner change owner to real user for suid programs
- *
- * SYNOPSIS
- *
- * static VOID ChangeOwner(pathname)
- *
- * DESCRIPTION
- *
- * For unix systems, change the owner of the newly created debug
- * file to the real owner. This is strictly for the benefit of
- * programs that are running with the set-user-id bit set.
- *
- * Note that at this point, the fact that pathname represents
- * a newly created file has already been established. If the
- * program that the debugger is linked to is not running with
- * the suid bit set, then this operation is redundant (but
- * harmless).
- *
- */
-
-#ifndef ChangeOwner
-static void ChangeOwner(CODE_STATE *cs, char *pathname)
-{
- if (chown(pathname, getuid(), getgid()) == -1)
- {
- (void) fprintf(stderr, ERR_CHOWN, cs->process, pathname);
- perror("");
- (void) fflush(stderr);
- }
-}
-#endif
-
-
-/*
- * FUNCTION
- *
- * _db_setjmp_ save debugger environment
- *
- * SYNOPSIS
- *
- * VOID _db_setjmp_()
- *
- * DESCRIPTION
- *
- * Invoked as part of the user's DBUG_SETJMP macro to save
- * the debugger environment in parallel with saving the user's
- * environment.
- *
- */
-
-#ifdef HAVE_LONGJMP
-
-EXPORT void _db_setjmp_()
-{
- CODE_STATE *cs;
- get_code_state_or_return;
-
- cs->jmplevel= cs->level;
- cs->jmpfunc= cs->func;
- cs->jmpfile= cs->file;
-}
-
-/*
- * FUNCTION
- *
- * _db_longjmp_ restore previously saved debugger environment
- *
- * SYNOPSIS
- *
- * VOID _db_longjmp_()
- *
- * DESCRIPTION
- *
- * Invoked as part of the user's DBUG_LONGJMP macro to restore
- * the debugger environment in parallel with restoring the user's
- * previously saved environment.
- *
- */
-
-EXPORT void _db_longjmp_()
-{
- CODE_STATE *cs;
- get_code_state_or_return;
-
- cs->level= cs->jmplevel;
- if (cs->jmpfunc)
- cs->func= cs->jmpfunc;
- if (cs->jmpfile)
- cs->file= cs->jmpfile;
-}
-#endif
-
-/*
- * FUNCTION
- *
- * perror perror simulation for systems that don't have it
- *
- * SYNOPSIS
- *
- * static VOID perror(s)
- * char *s;
- *
- * DESCRIPTION
- *
- * Perror produces a message on the standard error stream which
- * provides more information about the library or system error
- * just encountered. The argument string s is printed, followed
- * by a ':', a blank, and then a message and a newline.
- *
- * An undocumented feature of the unix perror is that if the string
- * 's' is a null string (NOT a NULL pointer!), then the ':' and
- * blank are not printed.
- *
- * This version just complains about an "unknown system error".
- *
- */
-
-#ifndef HAVE_PERROR
-static void perror(s)
-char *s;
-{
- if (s && *s != '\0')
- (void) fprintf(stderr, "%s: ", s);
- (void) fprintf(stderr, "<unknown system error>\n");
-}
-#endif /* HAVE_PERROR */
-
-
- /* flush dbug-stream, free mutex lock & wait delay */
- /* This is because some systems (MSDOS!!) dosn't flush fileheader */
- /* and dbug-file isn't readable after a system crash !! */
-
-static void DbugFlush(CODE_STATE *cs)
-{
- if (cs->stack->flags & FLUSH_ON_WRITE)
- {
- (void) fflush(cs->stack->out_file);
- if (cs->stack->delay)
- (void) Delay(cs->stack->delay);
- }
- if (!cs->locked)
- pthread_mutex_unlock(&THR_LOCK_dbug);
-} /* DbugFlush */
-
-
-/* For debugging */
-
-void _db_flush_()
-{
- CODE_STATE *cs;
- get_code_state_or_return;
- (void) fflush(cs->stack->out_file);
-}
-
-
-void _db_lock_file_()
-{
- CODE_STATE *cs;
- get_code_state_or_return;
- pthread_mutex_lock(&THR_LOCK_dbug);
- cs->locked=1;
-}
-
-void _db_unlock_file_()
-{
- CODE_STATE *cs;
- get_code_state_or_return;
- cs->locked=0;
- pthread_mutex_unlock(&THR_LOCK_dbug);
-}
-
-/*
- * Here we need the definitions of the clock routine. Add your
- * own for whatever system that you have.
- */
-
-#ifndef THREAD
-#if defined(HAVE_GETRUSAGE)
-
-#include <sys/param.h>
-#include <sys/resource.h>
-
-/* extern int getrusage(int, struct rusage *); */
-
-/*
- * Returns the user time in milliseconds used by this process so
- * far.
- */
-
-static unsigned long Clock()
-{
- struct rusage ru;
-
- (void) getrusage(RUSAGE_SELF, &ru);
- return ru.ru_utime.tv_sec*1000 + ru.ru_utime.tv_usec/1000;
-}
-
-#elif defined(MSDOS) || defined(__WIN__)
-
-static ulong Clock()
-{
- return clock()*(1000/CLOCKS_PER_SEC);
-}
-#elif defined(amiga)
-
-struct DateStamp { /* Yes, this is a hack, but doing it right */
- long ds_Days; /* is incredibly ugly without splitting this */
- long ds_Minute; /* off into a separate file */
- long ds_Tick;
-};
-
-static int first_clock= TRUE;
-static struct DateStamp begin;
-static struct DateStamp elapsed;
-
-static unsigned long Clock()
-{
- register struct DateStamp *now;
- register unsigned long millisec= 0;
- extern VOID *AllocMem();
-
- now= (struct DateStamp *) AllocMem((long) sizeof(struct DateStamp), 0L);
- if (now != NULL)
- {
- if (first_clock == TRUE)
- {
- first_clock= FALSE;
- (void) DateStamp(now);
- begin= *now;
- }
- (void) DateStamp(now);
- millisec= 24 * 3600 * (1000 / HZ) * (now->ds_Days - begin.ds_Days);
- millisec += 60 * (1000 / HZ) * (now->ds_Minute - begin.ds_Minute);
- millisec += (1000 / HZ) * (now->ds_Tick - begin.ds_Tick);
- (void) FreeMem(now, (long) sizeof(struct DateStamp));
- }
- return millisec;
-}
-#else
-static unsigned long Clock()
-{
- return 0;
-}
-#endif /* RUSAGE */
-#endif /* THREADS */
-
-#ifdef NO_VARARGS
-
-/*
- * Fake vfprintf for systems that don't support it. If this
- * doesn't work, you are probably SOL...
- */
-
-static int vfprintf(stream, format, ap)
-FILE *stream;
-char *format;
-va_list ap;
-{
- int rtnval;
- ARGS_DCL;
-
- ARG0= va_arg(ap, ARGS_TYPE);
- ARG1= va_arg(ap, ARGS_TYPE);
- ARG2= va_arg(ap, ARGS_TYPE);
- ARG3= va_arg(ap, ARGS_TYPE);
- ARG4= va_arg(ap, ARGS_TYPE);
- ARG5= va_arg(ap, ARGS_TYPE);
- ARG6= va_arg(ap, ARGS_TYPE);
- ARG7= va_arg(ap, ARGS_TYPE);
- ARG8= va_arg(ap, ARGS_TYPE);
- ARG9= va_arg(ap, ARGS_TYPE);
- rtnval= fprintf(stream, format, ARGS_LIST);
- return rtnval;
-}
-
-#endif /* NO_VARARGS */
-
-#else
-
-/*
- * Dummy function, workaround for MySQL bug#14420 related
- * build failure on a platform where linking with an empty
- * archive fails.
- *
- * This block can be removed as soon as a fix for bug#14420
- * is implemented.
- */
-int i_am_a_dummy_function() {
- return 0;
-}
-
-#endif
diff --git a/externals/mysql/extlib/dbug/dbug_analyze.c b/externals/mysql/extlib/dbug/dbug_analyze.c
deleted file mode 100644
index 3263b2ccc59..00000000000
--- a/externals/mysql/extlib/dbug/dbug_analyze.c
+++ /dev/null
@@ -1,726 +0,0 @@
-/*
- * Analyze the profile file (cmon.out) written out by the dbug
- * routines with profiling enabled.
- *
- * Copyright June 1987, Binayak Banerjee
- * All rights reserved.
- *
- * This program may be freely distributed under the same terms and
- * conditions as Fred Fish's Dbug package.
- *
- * Compile with -- cc -O -s -o %s analyze.c
- *
- * Analyze will read an trace file created by the dbug package
- * (when run with traceing enabled). It will then produce a
- * summary on standard output listing the name of each traced
- * function, the number of times it was called, the percentage
- * of total calls, the time spent executing the function, the
- * proportion of the total time and the 'importance'. The last
- * is a metric which is obtained by multiplying the proportions
- * of calls and the proportions of time for each function. The
- * greater the importance, the more likely it is that a speedup
- * could be obtained by reducing the time taken by that function.
- *
- * Note that the timing values that you obtain are only rough
- * measures. The overhead of the dbug package is included
- * within. However, there is no need to link in special profiled
- * libraries and the like.
- *
- * CHANGES:
- *
- * 2-Mar-89: fnf
- * Changes to support tracking of stack usage. This required
- * reordering the fields in the profile log file to make
- * parsing of different record types easier. Corresponding
- * changes made in dbug runtime library. Also used this
- * opportunity to reformat the code more to my liking (my
- * apologies to Binayak Banerjee for "uglifying" his code).
- *
- * 24-Jul-87: fnf
- * Because I tend to use functions names like
- * "ExternalFunctionDoingSomething", I've rearranged the
- * printout to put the function name last in each line, so
- * long names don't screw up the formatting unless they are
- * *very* long and wrap around the screen width...
- *
- * 24-Jul-87: fnf
- * Modified to put out table very similar to Unix profiler
- * by default, but also puts out original verbose table
- * if invoked with -v flag.
- */
-
-#include <my_global.h>
-#include <m_string.h>
-#include <my_pthread.h>
-
-static char *my_name;
-static int verbose;
-
-/*
- * Structure of the stack.
- */
-
-#define PRO_FILE "dbugmon.out" /* Default output file name */
-#define STACKSIZ 100 /* Maximum function nesting */
-#define MAXPROCS 10000 /* Maximum number of function calls */
-
-# ifdef BSD
-# include <sysexits.h>
-# else
-# define EX_SOFTWARE 1
-# define EX_DATAERR 1
-# define EX_USAGE 1
-# define EX_OSERR 1
-# define EX_IOERR 1
-#ifndef EX_OK
-# define EX_OK 0
-#endif
-# endif
-
-#define __MERF_OO_ "%s: Malloc Failed in %s: %d\n"
-
-#define MALLOC(Ptr,Num,Typ) do /* Malloc w/error checking & exit */ \
- if (!(Ptr = (Typ *)malloc((Num)*(sizeof(Typ))))) \
- {fprintf(stderr,__MERF_OO_,my_name,__FILE__,__LINE__);\
- exit(EX_OSERR);} while(0)
-
-#define Malloc(Ptr,Num,Typ) do /* Weaker version of above */\
- if (!(Ptr = (Typ *)malloc((Num)*(sizeof(Typ))))) \
- fprintf(stderr,__MERF_OO_,my_name,__FILE__,__LINE__);\
- while(0)
-
-#define FILEOPEN(Fp,Fn,Mod) do /* File open with error exit */ \
- if (!(Fp = fopen(Fn,Mod)))\
- {fprintf(stderr,"%s: Couldn't open %s\n",my_name,Fn);\
- exit(EX_IOERR);} while(0)
-
-#define Fileopen(Fp,Fn,Mod) do /* Weaker version of above */ \
- if(!(Fp = fopen(Fn,Mod))) \
- fprintf(stderr,"%s: Couldn't open %s\n",my_name,Fn);\
- while(0)
-
-
-struct stack_t {
- unsigned int pos; /* which function? */
- unsigned long time; /* Time that this was entered */
- unsigned long children; /* Time spent in called funcs */
-};
-
-static struct stack_t fn_stack[STACKSIZ+1];
-
-static unsigned int stacktop = 0; /* Lowest stack position is a dummy */
-
-static unsigned long tot_time = 0;
-static unsigned long tot_calls = 0;
-static unsigned long highstack = 0;
-static unsigned long lowstack = (ulong) ~0;
-
-/*
- * top() returns a pointer to the top item on the stack.
- * (was a function, now a macro)
- */
-
-#define top() &fn_stack[stacktop]
-
-/*
- * Push - Push the given record on the stack.
- */
-
-void push (name_pos, time_entered)
-register unsigned int name_pos;
-register unsigned long time_entered;
-{
- register struct stack_t *t;
-
- DBUG_ENTER("push");
- if (++stacktop > STACKSIZ) {
- fprintf (DBUG_FILE,"%s: stack overflow (%s:%d)\n",
- my_name, __FILE__, __LINE__);
- exit (EX_SOFTWARE);
- }
- DBUG_PRINT ("push", ("%d %ld",name_pos,time_entered));
- t = &fn_stack[stacktop];
- t -> pos = name_pos;
- t -> time = time_entered;
- t -> children = 0;
- DBUG_VOID_RETURN;
-}
-
-/*
- * Pop - pop the top item off the stack, assigning the field values
- * to the arguments. Returns 0 on stack underflow, or on popping first
- * item off stack.
- */
-
-unsigned int pop (name_pos, time_entered, child_time)
-register unsigned int *name_pos;
-register unsigned long *time_entered;
-register unsigned long *child_time;
-{
- register struct stack_t *temp;
- register unsigned int rtnval;
-
- DBUG_ENTER ("pop");
-
- if (stacktop < 1) {
- rtnval = 0;
- } else {
- temp = &fn_stack[stacktop];
- *name_pos = temp->pos;
- *time_entered = temp->time;
- *child_time = temp->children;
- DBUG_PRINT ("pop", ("%d %lu %lu",*name_pos,*time_entered,*child_time));
- rtnval = stacktop--;
- }
- DBUG_RETURN (rtnval);
-}
-
-/*
- * We keep the function info in another array (serves as a simple
- * symbol table)
- */
-
-struct module_t {
- char *name;
- unsigned long m_time;
- unsigned long m_calls;
- unsigned long m_stkuse;
-};
-
-static struct module_t modules[MAXPROCS];
-
-/*
- * We keep a binary search tree in order to look up function names
- * quickly (and sort them at the end.
- */
-
-struct bnode {
- unsigned int lchild; /* Index of left subtree */
- unsigned int rchild; /* Index of right subtree */
- unsigned int pos; /* Index of module_name entry */
-};
-
-static struct bnode s_table[MAXPROCS];
-
-static unsigned int n_items = 0; /* No. of items in the array so far */
-
-/*
- * Need a function to allocate space for a string and squirrel it away.
- */
-
-char *strsave (s)
-char *s;
-{
- register char *retval;
- register unsigned int len;
-
- DBUG_ENTER ("strsave");
- DBUG_PRINT ("strsave", ("%s",s));
- if (!s || (len = strlen (s)) == 0) {
- DBUG_RETURN (0);
- }
- MALLOC (retval, ++len, char);
- strcpy (retval, s);
- DBUG_RETURN (retval);
-}
-
-/*
- * add() - adds m_name to the table (if not already there), and returns
- * the index of its location in the table. Checks s_table (which is a
- * binary search tree) to see whether or not it should be added.
- */
-
-unsigned int add (m_name)
-char *m_name;
-{
- register unsigned int ind = 0;
- register int cmp;
-
- DBUG_ENTER ("add");
- if (n_items == 0) { /* First item to be added */
- s_table[0].pos = ind;
- s_table[0].lchild = s_table[0].rchild = MAXPROCS;
- addit:
- modules[n_items].name = strsave (m_name);
- modules[n_items].m_time = 0;
- modules[n_items].m_calls = 0;
- modules[n_items].m_stkuse = 0;
- DBUG_RETURN (n_items++);
- }
- while ((cmp = strcmp (m_name,modules[ind].name))) {
- if (cmp < 0) { /* In left subtree */
- if (s_table[ind].lchild == MAXPROCS) {
- /* Add as left child */
- if (n_items >= MAXPROCS) {
- fprintf (DBUG_FILE,
- "%s: Too many functions being profiled\n",
- my_name);
- exit (EX_SOFTWARE);
- }
- s_table[n_items].pos = s_table[ind].lchild = n_items;
- s_table[n_items].lchild = s_table[n_items].rchild = MAXPROCS;
-#ifdef notdef
- modules[n_items].name = strsave (m_name);
- modules[n_items].m_time = modules[n_items].m_calls = 0;
- DBUG_RETURN (n_items++);
-#else
- goto addit;
-#endif
-
- }
- ind = s_table[ind].lchild; /* else traverse l-tree */
- } else {
- if (s_table[ind].rchild == MAXPROCS) {
- /* Add as right child */
- if (n_items >= MAXPROCS) {
- fprintf (DBUG_FILE,
- "%s: Too many functions being profiled\n",
- my_name);
- exit (EX_SOFTWARE);
- }
- s_table[n_items].pos = s_table[ind].rchild = n_items;
- s_table[n_items].lchild = s_table[n_items].rchild = MAXPROCS;
-#ifdef notdef
- modules[n_items].name = strsave (m_name);
- modules[n_items].m_time = modules[n_items].m_calls = 0;
- DBUG_RETURN (n_items++);
-#else
- goto addit;
-#endif
-
- }
- ind = s_table[ind].rchild; /* else traverse r-tree */
- }
- }
- DBUG_RETURN (ind);
-}
-
-/*
- * process() - process the input file, filling in the modules table.
- */
-
-void process (inf)
-FILE *inf;
-{
- char buf[BUFSIZ];
- char fn_name[64]; /* Max length of fn_name */
- unsigned long fn_time;
- unsigned long fn_sbot;
- unsigned long fn_ssz;
- unsigned long lastuse;
- unsigned int pos;
- unsigned long local_time;
- unsigned int oldpos;
- unsigned long oldtime;
- unsigned long oldchild;
- struct stack_t *t;
-
- DBUG_ENTER ("process");
- while (fgets (buf,BUFSIZ,inf) != NULL) {
- switch (buf[0]) {
- case 'E':
- sscanf (buf+2, "%ld %64s", &fn_time, fn_name);
- DBUG_PRINT ("erec", ("%ld %s", fn_time, fn_name));
- pos = add (fn_name);
- push (pos, fn_time);
- break;
- case 'X':
- sscanf (buf+2, "%ld %64s", &fn_time, fn_name);
- DBUG_PRINT ("xrec", ("%ld %s", fn_time, fn_name));
- pos = add (fn_name);
- /*
- * An exited function implies that all stacked
- * functions are also exited, until the matching
- * function is found on the stack.
- */
- while (pop (&oldpos, &oldtime, &oldchild)) {
- DBUG_PRINT ("popped", ("%lu %lu", oldtime, oldchild));
- local_time = fn_time - oldtime;
- t = top ();
- t -> children += local_time;
- DBUG_PRINT ("update", ("%s", modules[t -> pos].name));
- DBUG_PRINT ("update", ("%lu", t -> children));
- local_time -= oldchild;
- modules[oldpos].m_time += local_time;
- modules[oldpos].m_calls++;
- tot_time += local_time;
- tot_calls++;
- if (pos == oldpos) {
- goto next_line; /* Should be a break2 */
- }
- }
- /*
- * Assume that item seen started at time 0.
- * (True for function main). But initialize
- * it so that it works the next time too.
- */
- t = top ();
- local_time = fn_time - t -> time - t -> children;
- t -> time = fn_time; t -> children = 0;
- modules[pos].m_time += local_time;
- modules[pos].m_calls++;
- tot_time += local_time;
- tot_calls++;
- break;
- case 'S':
- sscanf (buf+2, "%lx %lx %64s", &fn_sbot, &fn_ssz, fn_name);
- DBUG_PRINT ("srec", ("%lx %lx %s", fn_sbot, fn_ssz, fn_name));
- pos = add (fn_name);
- lastuse = modules[pos].m_stkuse;
-#if 0
- /*
- * Needs further thought. Stack use is determined by
- * difference in stack between two functions with DBUG_ENTER
- * macros. If A calls B calls C, where A and C have the
- * macros, and B doesn't, then B's stack use will be lumped
- * in with either A's or C's. If somewhere else A calls
- * C directly, the stack use will seem to change. Just
- * take the biggest for now...
- */
- if (lastuse > 0 && lastuse != fn_ssz) {
- fprintf (stderr,
- "warning - %s stack use changed (%lx to %lx)\n",
- fn_name, lastuse, fn_ssz);
- }
-#endif
- if (fn_ssz > lastuse) {
- modules[pos].m_stkuse = fn_ssz;
- }
- if (fn_sbot > highstack) {
- highstack = fn_sbot;
- } else if (fn_sbot < lowstack) {
- lowstack = fn_sbot;
- }
- break;
- default:
- fprintf (stderr, "unknown record type '%c'\n", buf[0]);
- break;
- }
- next_line:;
- }
-
- /*
- * Now, we've hit eof. If we still have stuff stacked, then we
- * assume that the user called exit, so give everything the exited
- * time of fn_time.
- */
- while (pop (&oldpos,&oldtime,&oldchild)) {
- local_time = fn_time - oldtime;
- t = top ();
- t -> children += local_time;
- local_time -= oldchild;
- modules[oldpos].m_time += local_time;
- modules[oldpos].m_calls++;
- tot_time += local_time;
- tot_calls++;
- }
- DBUG_VOID_RETURN;
-}
-
-/*
- * out_header () -- print out the header of the report.
- */
-
-void out_header (outf)
-FILE *outf;
-{
- DBUG_ENTER ("out_header");
- if (verbose) {
- fprintf (outf, "Profile of Execution\n");
- fprintf (outf, "Execution times are in milliseconds\n\n");
- fprintf (outf, " Calls\t\t\t Time\n");
- fprintf (outf, " -----\t\t\t ----\n");
- fprintf (outf, "Times\tPercentage\tTime Spent\tPercentage\n");
- fprintf (outf, "Called\tof total\tin Function\tof total Importance\tFunction\n");
- fprintf (outf, "======\t==========\t===========\t========== ==========\t========\t\n");
- } else {
- fprintf (outf, "%ld bytes of stack used, from %lx down to %lx\n\n",
- highstack - lowstack, highstack, lowstack);
- fprintf (outf,
- " %%time sec #call ms/call %%calls weight stack name\n");
- }
- DBUG_VOID_RETURN;
-}
-
-/*
- * out_trailer () - writes out the summary line of the report.
- */
-
-void out_trailer (outf,sum_calls,sum_time)
-FILE *outf;
-unsigned long int sum_calls, sum_time;
-{
- DBUG_ENTER ("out_trailer");
- if (verbose)
- {
- fprintf(outf, "======\t==========\t===========\t==========\t========\n");
- fprintf(outf, "%6ld\t%10.2f\t%11ld\t%10.2f\t\t%-15s\n",
- sum_calls, 100.0, sum_time, 100.0, "Totals");
- }
- DBUG_VOID_RETURN;
-}
-
-/*
- * out_item () - prints out the output line for a single entry,
- * and sets the calls and time fields appropriately.
- */
-
-void out_item (outf, m,called,timed)
-FILE *outf;
-register struct module_t *m;
-unsigned long int *called, *timed;
-{
- char *name = m -> name;
- register unsigned int calls = m -> m_calls;
- register unsigned long local_time = m -> m_time;
- register unsigned long stkuse = m -> m_stkuse;
- unsigned int import;
- double per_time = 0.0;
- double per_calls = 0.0;
- double ms_per_call, local_ftime;
-
- DBUG_ENTER ("out_item");
-
- if (tot_time > 0) {
- per_time = (double) (local_time * 100) / (double) tot_time;
- }
- if (tot_calls > 0) {
- per_calls = (double) (calls * 100) / (double) tot_calls;
- }
- import = (unsigned int) (per_time * per_calls);
-
- if (verbose) {
- fprintf (outf, "%6d\t%10.2f\t%11ld\t%10.2f %10d\t%-15s\n",
- calls, per_calls, local_time, per_time, import, name);
- } else {
- ms_per_call = local_time;
- ms_per_call /= calls;
- local_ftime = local_time;
- local_ftime /= 1000;
- fprintf(outf, "%8.2f%8.3f%8u%8.3f%8.2f%8u%8lu %-s\n",
- per_time, local_ftime, calls, ms_per_call, per_calls, import,
- stkuse, name);
- }
- *called = calls;
- *timed = local_time;
- DBUG_VOID_RETURN;
-}
-
-/*
- * out_body (outf, root,s_calls,s_time) -- Performs an inorder traversal
- * on the binary search tree (root). Calls out_item to actually print
- * the item out.
- */
-
-void out_body (outf, root,s_calls,s_time)
-FILE *outf;
-register unsigned int root;
-register unsigned long int *s_calls, *s_time;
-{
- unsigned long int calls, local_time;
-
- DBUG_ENTER ("out_body");
- DBUG_PRINT ("out_body", ("%lu,%lu",*s_calls,*s_time));
- if (root == MAXPROCS) {
- DBUG_PRINT ("out_body", ("%lu,%lu",*s_calls,*s_time));
- } else {
- while (root != MAXPROCS) {
- out_body (outf, s_table[root].lchild,s_calls,s_time);
- out_item (outf, &modules[s_table[root].pos],&calls,&local_time);
- DBUG_PRINT ("out_body", ("-- %lu -- %lu --", calls, local_time));
- *s_calls += calls;
- *s_time += local_time;
- root = s_table[root].rchild;
- }
- DBUG_PRINT ("out_body", ("%lu,%lu", *s_calls, *s_time));
- }
- DBUG_VOID_RETURN;
-}
-
-/*
- * output () - print out a nice sorted output report on outf.
- */
-
-void output (outf)
-FILE *outf;
-{
- unsigned long int sum_calls = 0;
- unsigned long int sum_time = 0;
-
- DBUG_ENTER ("output");
- if (n_items == 0) {
- fprintf (outf, "%s: No functions to trace\n", my_name);
- exit (EX_DATAERR);
- }
- out_header (outf);
- out_body (outf, 0,&sum_calls,&sum_time);
- out_trailer (outf, sum_calls,sum_time);
- DBUG_VOID_RETURN;
-}
-
-
-#define usage() fprintf (DBUG_FILE,"Usage: %s [-v] [prof-file]\n",my_name)
-
-#ifdef MSDOS
-extern int getopt(int argc, char **argv, char *opts);
-#endif
-extern int optind;
-extern char *optarg;
-
-int main (int argc, char **argv)
-{
- register int c;
- int badflg = 0;
- FILE *infile;
- FILE *outfile = {stdout};
-
-#ifdef THREAD
-#if defined(HAVE_PTHREAD_INIT)
- pthread_init(); /* Must be called before DBUG_ENTER */
-#endif
- my_thread_global_init();
-#endif /* THREAD */
- {
- DBUG_ENTER ("main");
- DBUG_PROCESS (argv[0]);
- my_name = argv[0];
- while ((c = getopt (argc,argv,"#:v")) != EOF) {
- switch (c) {
- case '#': /* Debugging Macro enable */
- DBUG_PUSH (optarg);
- break;
- case 'v': /* Verbose mode */
- verbose++;
- break;
- default:
- badflg++;
- break;
- }
- }
- if (badflg) {
- usage ();
- DBUG_RETURN (EX_USAGE);
- }
- if (optind < argc) {
- FILEOPEN (infile, argv[optind], "r");
- } else {
- FILEOPEN (infile, PRO_FILE, "r");
- }
- process (infile);
- output (outfile);
- DBUG_RETURN (EX_OK);
-}
-}
-
-#ifdef MSDOS
-
-/*
- * From std-unix@ut-sally.UUCP (Moderator, John Quarterman) Sun Nov 3 14:34:15 1985
- * Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site gatech.CSNET
- * Posting-Version: version B 2.10.2 9/18/84; site ut-sally.UUCP
- * Path: gatech!akgua!mhuxv!mhuxt!mhuxr!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!ut-sally!std-unix
- * From: std-unix@ut-sally.UUCP (Moderator, John Quarterman)
- * Newsgroups: mod.std.unix
- * Subject: public domain AT&T getopt source
- * Message-ID: <3352@ut-sally.UUCP>
- * Date: 3 Nov 85 19:34:15 GMT
- * Date-Received: 4 Nov 85 12:25:09 GMT
- * Organization: IEEE/P1003 Portable Operating System Environment Committee
- * Lines: 91
- * Approved: jsq@ut-sally.UUCP
- *
- * Here's something you've all been waiting for: the AT&T public domain
- * source for getopt(3). It is the code which was given out at the 1985
- * UNIFORUM conference in Dallas. I obtained it by electronic mail
- * directly from AT&T. The people there assure me that it is indeed
- * in the public domain.
- *
- * There is no manual page. That is because the one they gave out at
- * UNIFORUM was slightly different from the current System V Release 2
- * manual page. The difference apparently involved a note about the
- * famous rules 5 and 6, recommending using white space between an option
- * and its first argument, and not grouping options that have arguments.
- * Getopt itself is currently lenient about both of these things White
- * space is allowed, but not mandatory, and the last option in a group can
- * have an argument. That particular version of the man page evidently
- * has no official existence, and my source at AT&T did not send a copy.
- * The current SVR2 man page reflects the actual behavor of this getopt.
- * However, I am not about to post a copy of anything licensed by AT&T.
- *
- * I will submit this source to Berkeley as a bug fix.
- *
- * I, personally, make no claims or guarantees of any kind about the
- * following source. I did compile it to get some confidence that
- * it arrived whole, but beyond that you're on your own.
- *
- */
-
-/*LINTLIBRARY*/
-
-int opterr = 1;
-int optind = 1;
-int optopt;
-char *optarg;
-
-static void _ERR(s,c,argv)
-char *s;
-int c;
-char *argv[];
-{
- char errbuf[3];
-
- if (opterr) {
- errbuf[0] = c;
- errbuf[1] = '\n';
- (void) fprintf(stderr, "%s", argv[0]);
- (void) fprintf(stderr, "%s", s);
- (void) fprintf(stderr, "%s", errbuf);
- }
-}
-
-int getopt(argc, argv, opts)
-int argc;
-char **argv, *opts;
-{
- static int sp = 1;
- register int c;
- register char *cp;
-
- if(sp == 1)
- if(optind >= argc ||
- argv[optind][0] != '-' || argv[optind][1] == '\0')
- return(EOF);
- else if(strcmp(argv[optind], "--") == 0) {
- optind++;
- return(EOF);
- }
- optopt = c = argv[optind][sp];
- if(c == ':' || (cp=strchr(opts, c)) == NULL) {
- _ERR(": illegal option -- ", c, argv);
- if(argv[optind][++sp] == '\0') {
- optind++;
- sp = 1;
- }
- return('?');
- }
- if(*++cp == ':') {
- if(argv[optind][sp+1] != '\0')
- optarg = &argv[optind++][sp+1];
- else if(++optind >= argc) {
- _ERR(": option requires an argument -- ", c, argv);
- sp = 1;
- return('?');
- } else
- optarg = argv[optind++];
- sp = 1;
- } else {
- if(argv[optind][++sp] == '\0') {
- sp = 1;
- optind++;
- }
- optarg = NULL;
- }
- return(c);
-}
-
-#endif /* !unix && !xenix */
diff --git a/externals/mysql/extlib/dbug/dbug_long.h b/externals/mysql/extlib/dbug/dbug_long.h
deleted file mode 100644
index 829df181ef1..00000000000
--- a/externals/mysql/extlib/dbug/dbug_long.h
+++ /dev/null
@@ -1,160 +0,0 @@
-#error This file is not used in MySQL - see ../include/my_dbug.h instead
-/******************************************************************************
- * *
- * N O T I C E *
- * *
- * Copyright Abandoned, 1987, Fred Fish *
- * *
- * *
- * This previously copyrighted work has been placed into the public *
- * domain by the author and may be freely used for any purpose, *
- * private or commercial. *
- * *
- * Because of the number of inquiries I was receiving about the use *
- * of this product in commercially developed works I have decided to *
- * simply make it public domain to further its unrestricted use. I *
- * specifically would be most happy to see this material become a *
- * part of the standard Unix distributions by AT&T and the Berkeley *
- * Computer Science Research Group, and a standard part of the GNU *
- * system from the Free Software Foundation. *
- * *
- * I would appreciate it, as a courtesy, if this notice is left in *
- * all copies and derivative works. Thank you. *
- * *
- * The author makes no warranty of any kind with respect to this *
- * product and explicitly disclaims any implied warranties of mer- *
- * chantability or fitness for any particular purpose. *
- * *
- ******************************************************************************
- */
-
-/*
- * FILE
- *
- * dbug.h user include file for programs using the dbug package
- *
- * SYNOPSIS
- *
- * #include <local/dbug.h>
- *
- * SCCS ID
- *
- * @(#)dbug.h 1.13 7/17/89
- *
- * DESCRIPTION
- *
- * Programs which use the dbug package must include this file.
- * It contains the appropriate macros to call support routines
- * in the dbug runtime library.
- *
- * To disable compilation of the macro expansions define the
- * preprocessor symbol "DBUG_OFF". This will result in null
- * macros expansions so that the resulting code will be smaller
- * and faster. (The difference may be smaller than you think
- * so this step is recommended only when absolutely necessary).
- * In general, tradeoffs between space and efficiency are
- * decided in favor of efficiency since space is seldom a
- * problem on the new machines).
- *
- * All externally visible symbol names follow the pattern
- * "_db_xxx..xx_" to minimize the possibility of a dbug package
- * symbol colliding with a user defined symbol.
- *
- * The DBUG_<N> style macros are obsolete and should not be used
- * in new code. Macros to map them to instances of DBUG_PRINT
- * are provided for compatibility with older code. They may go
- * away completely in subsequent releases.
- *
- * AUTHOR
- *
- * Fred Fish
- * (Currently employed by Motorola Computer Division, Tempe, Az.)
- * hao!noao!mcdsun!fnf
- * (602) 438-3614
- *
- */
-
-/*
- * Internally used dbug variables which must be global.
- */
-
-#ifndef DBUG_OFF
- extern int _db_on_; /* TRUE if debug currently enabled */
- extern FILE *_db_fp_; /* Current debug output stream */
- extern char *_db_process_; /* Name of current process */
- extern int _db_keyword_ (); /* Accept/reject keyword */
- extern void _db_push_ (); /* Push state, set up new state */
- extern void _db_pop_ (); /* Pop previous debug state */
- extern void _db_enter_ (); /* New user function entered */
- extern void _db_return_ (); /* User function return */
- extern void _db_pargs_ (); /* Remember args for line */
- extern void _db_doprnt_ (); /* Print debug output */
- extern void _db_setjmp_ (); /* Save debugger environment */
- extern void _db_longjmp_ (); /* Restore debugger environment */
- extern void _db_dump_(); /* Dump memory */
-# endif
-
-
-/*
- * These macros provide a user interface into functions in the
- * dbug runtime support library. They isolate users from changes
- * in the MACROS and/or runtime support.
- *
- * The symbols "__LINE__" and "__FILE__" are expanded by the
- * preprocessor to the current source file line number and file
- * name respectively.
- *
- * WARNING --- Because the DBUG_ENTER macro allocates space on
- * the user function's stack, it must precede any executable
- * statements in the user function.
- *
- */
-
-# ifdef DBUG_OFF
-# define DBUG_ENTER(a1)
-# define DBUG_RETURN(a1) return(a1)
-# define DBUG_VOID_RETURN return
-# define DBUG_EXECUTE(keyword,a1)
-# define DBUG_PRINT(keyword,arglist)
-# define DBUG_2(keyword,format) /* Obsolete */
-# define DBUG_3(keyword,format,a1) /* Obsolete */
-# define DBUG_4(keyword,format,a1,a2) /* Obsolete */
-# define DBUG_5(keyword,format,a1,a2,a3) /* Obsolete */
-# define DBUG_PUSH(a1)
-# define DBUG_POP()
-# define DBUG_PROCESS(a1)
-# define DBUG_FILE (stderr)
-# define DBUG_SETJMP setjmp
-# define DBUG_LONGJMP longjmp
-# define DBUG_DUMP(keyword,a1)
-# else
-# define DBUG_ENTER(a) \
- auto char *_db_func_; auto char *_db_file_; auto int _db_level_; \
- auto char **_db_framep_; \
- _db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \
- &_db_framep_)
-# define DBUG_LEAVE \
- (_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_))
-# define DBUG_RETURN(a1) return (DBUG_LEAVE, (a1))
-/* define DBUG_RETURN(a1) {DBUG_LEAVE; return(a1);} Alternate form */
-# define DBUG_VOID_RETURN {DBUG_LEAVE; return;}
-# define DBUG_EXECUTE(keyword,a1) \
- {if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}}
-# define DBUG_PRINT(keyword,arglist) \
- {if (_db_on_) {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;}}
-# define DBUG_2(keyword,format) \
- DBUG_PRINT(keyword,(format)) /* Obsolete */
-# define DBUG_3(keyword,format,a1) \
- DBUG_PRINT(keyword,(format,a1)) /* Obsolete */
-# define DBUG_4(keyword,format,a1,a2) \
- DBUG_PRINT(keyword,(format,a1,a2)) /* Obsolete */
-# define DBUG_5(keyword,format,a1,a2,a3) \
- DBUG_PRINT(keyword,(format,a1,a2,a3)) /* Obsolete */
-# define DBUG_PUSH(a1) _db_push_ (a1)
-# define DBUG_POP() _db_pop_ ()
-# define DBUG_PROCESS(a1) (_db_process_ = a1)
-# define DBUG_FILE (_db_fp_)
-# define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1))
-# define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2))
-# define DBUG_DUMP(keyword,a1,a2) _db_dump_(__LINE__,keyword,a1,a2)
-# endif
diff --git a/externals/mysql/extlib/dbug/example1.c b/externals/mysql/extlib/dbug/example1.c
deleted file mode 100644
index 7b3c3fcd63d..00000000000
--- a/externals/mysql/extlib/dbug/example1.c
+++ /dev/null
@@ -1,10 +0,0 @@
-main (argc, argv)
-int argc;
-char *argv[];
-{
- printf ("argv[0] = %d\n", argv[0]);
- /*
- * Rest of program
- */
- printf ("== done ==\n");
-}
diff --git a/externals/mysql/extlib/dbug/example2.c b/externals/mysql/extlib/dbug/example2.c
deleted file mode 100644
index 75fc1321b13..00000000000
--- a/externals/mysql/extlib/dbug/example2.c
+++ /dev/null
@@ -1,15 +0,0 @@
-int debug = 0;
-
-main (argc, argv)
-int argc;
-char *argv[];
-{
- /* printf ("argv = %x\n", argv) */
- if (debug) printf ("argv[0] = %d\n", argv[0]);
- /*
- * Rest of program
- */
-#ifdef DEBUG
- printf ("== done ==\n");
-#endif
-}
diff --git a/externals/mysql/extlib/dbug/example3.c b/externals/mysql/extlib/dbug/example3.c
deleted file mode 100644
index c035cdfffa0..00000000000
--- a/externals/mysql/extlib/dbug/example3.c
+++ /dev/null
@@ -1,14 +0,0 @@
-main (argc, argv)
-int argc;
-char *argv[];
-{
-# ifdef DEBUG
- printf ("argv[0] = %d\n", argv[0]);
-# endif
- /*
- * Rest of program
- */
-# ifdef DEBUG
- printf ("== done ==\n");
-# endif
-}
diff --git a/externals/mysql/extlib/dbug/factorial.c b/externals/mysql/extlib/dbug/factorial.c
deleted file mode 100644
index 7b190ea8d8e..00000000000
--- a/externals/mysql/extlib/dbug/factorial.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifdef DBUG_OFF /* We are testing dbug */
-
-int factorial(register int value) {
- if(value > 1) {
- value *= factorial(value-1);
- }
- return value;
-}
-
-#else
-
-#include <my_global.h>
-
-int factorial (
-register int value)
-{
- DBUG_ENTER ("factorial");
- DBUG_PRINT ("find", ("find %d factorial", value));
- if (value > 1) {
- value *= factorial (value - 1);
- }
- DBUG_PRINT ("result", ("result is %d", value));
- DBUG_RETURN (value);
-}
-
-#endif
-
diff --git a/externals/mysql/extlib/dbug/main.c b/externals/mysql/extlib/dbug/main.c
deleted file mode 100644
index 00e80c8ba31..00000000000
--- a/externals/mysql/extlib/dbug/main.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <dbug.h>
-
-int main (argc, argv)
-int argc;
-char *argv[];
-{
- int result, ix;
- extern int factorial(int);
- DBUG_ENTER ("main");
- DBUG_PROCESS (argv[0]);
- for (ix = 1; ix < argc && argv[ix][0] == '-'; ix++) {
- switch (argv[ix][1]) {
- case '#':
- DBUG_PUSH (&(argv[ix][2]));
- break;
- }
- }
- for (; ix < argc; ix++) {
- DBUG_PRINT ("args", ("argv[%d] = %s", ix, argv[ix]));
- result = factorial (atoi(argv[ix]));
- printf ("%d\n", result);
- }
- DBUG_RETURN (0);
-}
diff --git a/externals/mysql/extlib/dbug/my_main.c b/externals/mysql/extlib/dbug/my_main.c
deleted file mode 100644
index 31c15aa67aa..00000000000
--- a/externals/mysql/extlib/dbug/my_main.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- this is modified version of the original example main.c
- fixed so that it could compile and run in MySQL source tree
-*/
-
-#ifdef DBUG_OFF /* We are testing dbug */
-#undef DBUG_OFF
-#endif
-
-#include <my_global.h> /* This includes dbug.h */
-#include <my_pthread.h>
-
-int main (argc, argv)
-int argc;
-char *argv[];
-{
- register int result, ix;
- extern int factorial(int);
-#if defined(HAVE_PTHREAD_INIT) && defined(THREAD)
- pthread_init(); /* Must be called before DBUG_ENTER */
-#endif
-#ifdef THREAD
- my_thread_global_init();
-#endif
- {
- DBUG_ENTER ("main");
- DBUG_PROCESS (argv[0]);
- for (ix = 1; ix < argc && argv[ix][0] == '-'; ix++) {
- switch (argv[ix][1]) {
- case '#':
- DBUG_PUSH (&(argv[ix][2]));
- break;
- }
- }
- for (; ix < argc; ix++) {
- DBUG_PRINT ("args", ("argv[%d] = %s", ix, argv[ix]));
- result = factorial (atoi(argv[ix]));
- printf ("%d\n", result);
- }
- DBUG_RETURN (0);
- }
-}
diff --git a/externals/mysql/extlib/dbug/sanity.c b/externals/mysql/extlib/dbug/sanity.c
deleted file mode 100644
index df43fc14ba9..00000000000
--- a/externals/mysql/extlib/dbug/sanity.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Declarate _sanity() if not declared in main program */
-
-#include <my_global.h>
-
-extern int _sanity(const char *file,uint line);
-
-#if defined(SAFEMALLOC) && !defined(MASTER) /* Avoid errors in MySQL */
-int _sanity(const char * file __attribute__((unused)),
- uint line __attribute__((unused)))
-{
- return 0;
-}
-#endif
diff --git a/externals/mysql/extlib/dbug/tests.c b/externals/mysql/extlib/dbug/tests.c
deleted file mode 100644
index d76266d34a3..00000000000
--- a/externals/mysql/extlib/dbug/tests.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- A program to test DBUG features. Used by tests-t.pl
-*/
-
-char *push1=0;
-
-#include <my_global.h> /* This includes dbug.h */
-#include <my_pthread.h>
-#include <string.h>
-
-const char *func3()
-{
- DBUG_ENTER("func3");
- DBUG_RETURN(DBUG_EVALUATE("ret3", "ok", "ko"));
-}
-
-void func2()
-{
- const char *s;
- DBUG_ENTER("func2");
- s=func3();
- DBUG_PRINT("info", ("s=%s", s));
- DBUG_VOID_RETURN;
-}
-
-int func1()
-{
- DBUG_ENTER("func1");
- func2();
- if (push1)
- {
- DBUG_PUSH(push1);
- fprintf(DBUG_FILE, "=> push1\n");
- }
- DBUG_RETURN(10);
-}
-
-int main (int argc, char *argv[])
-{
- int i;
-#ifdef DBUG_OFF
- return 1;
-#endif
- if (argc == 1)
- return 0;
-
-#if defined(HAVE_PTHREAD_INIT) && defined(THREAD)
- pthread_init(); /* Must be called before DBUG_ENTER */
-#endif
-#ifdef THREAD
- my_thread_global_init();
-#endif
- dup2(1, 2);
- for (i = 1; i < argc; i++)
- {
- if (strncmp(argv[i], "--push1=", 8) == 0)
- push1=argv[i]+8;
- else
- DBUG_PUSH (argv[i]);
- }
- {
- DBUG_ENTER ("main");
- DBUG_PROCESS ("dbug-tests");
- func1();
- DBUG_EXECUTE_IF("dump",
- {
- char s[1000];
- DBUG_EXPLAIN(s, sizeof(s)-1);
- DBUG_DUMP("dump", (uchar*)s, strlen(s));
- });
- DBUG_EXECUTE_IF("push", DBUG_PUSH("+t"); );
- DBUG_EXECUTE("execute", fprintf(DBUG_FILE, "=> execute\n"); );
- DBUG_EXECUTE_IF("set", DBUG_SET("+F"); );
- fprintf(DBUG_FILE, "=> evaluate: %s\n",
- DBUG_EVALUATE("evaluate", "ON", "OFF"));
- fprintf(DBUG_FILE, "=> evaluate_if: %s\n",
- DBUG_EVALUATE_IF("evaluate_if", "ON", "OFF"));
- DBUG_EXECUTE_IF("pop", DBUG_POP(); );
- {
- char s[1000] __attribute__((unused));
- DBUG_EXPLAIN(s, sizeof(s)-1);
- DBUG_PRINT("explain", ("dbug explained: %s", s));
- }
- func2();
- DBUG_RETURN (0);
- }
-}