diff options
Diffstat (limited to 'externals/mysql/extlib/dbug')
| -rw-r--r-- | externals/mysql/extlib/dbug/dbug.c | 2583 | ||||
| -rw-r--r-- | externals/mysql/extlib/dbug/dbug_analyze.c | 726 | ||||
| -rw-r--r-- | externals/mysql/extlib/dbug/dbug_long.h | 160 | ||||
| -rw-r--r-- | externals/mysql/extlib/dbug/example1.c | 10 | ||||
| -rw-r--r-- | externals/mysql/extlib/dbug/example2.c | 15 | ||||
| -rw-r--r-- | externals/mysql/extlib/dbug/example3.c | 14 | ||||
| -rw-r--r-- | externals/mysql/extlib/dbug/factorial.c | 27 | ||||
| -rw-r--r-- | externals/mysql/extlib/dbug/main.c | 24 | ||||
| -rw-r--r-- | externals/mysql/extlib/dbug/my_main.c | 42 | ||||
| -rw-r--r-- | externals/mysql/extlib/dbug/sanity.c | 13 | ||||
| -rw-r--r-- | externals/mysql/extlib/dbug/tests.c | 87 | 
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); -  } -}  | 
