⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbug.c

📁 MySQL的ODBC接口程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
  new_str = StrDup (control);  PushState ();  state=code_state();  scan = static_strtok (new_str, ':');  for (; scan != NULL; scan = static_strtok ((char *)NULL, ':')) {    switch (*scan++) {    case 'd':      _db_on_ = TRUE;      stack -> flags |= DEBUG_ON;      if (*scan++ == ',') {	stack -> keywords = ListParse (scan);      }      break;    case 'D':      stack -> delay = 0;      if (*scan++ == ',') {	temp = ListParse (scan);	stack -> delay = DelayArg (atoi (temp -> str));	FreeList (temp);      }      break;    case 'f':      if (*scan++ == ',') {	stack -> functions = ListParse (scan);      }      break;    case 'F':      stack -> flags |= FILE_ON;      break;    case 'i':      stack -> flags |= PID_ON;      break;#ifndef THREAD    case 'g':      _db_pon_ = TRUE;      if (OpenProfile(PROF_FILE))      {	stack -> flags |= PROFILE_ON;	if (*scan++ == ',')	  stack -> p_functions = ListParse (scan);      }      break;#endif    case 'L':      stack -> flags |= LINE_ON;      break;    case 'n':      stack -> flags |= DEPTH_ON;      break;    case 'N':      stack -> flags |= NUMBER_ON;      break;    case 'O':      stack -> flags |= FLUSH_ON_WRITE;    case 'o':      if (*scan++ == ',') {	temp = ListParse (scan);	DBUGOpenFile (temp -> str);	FreeList (temp);      } else {	DBUGOpenFile ("-");      }      break;    case 'p':      if (*scan++ == ',') {	stack -> processes = ListParse (scan);      }      break;    case 'P':      stack -> flags |= PROCESS_ON;      break;    case 'r':      stack->sub_level= state->level;      break;    case 't':      stack -> flags |= TRACE_ON;      if (*scan++ == ',') {	temp = ListParse (scan);	stack -> maxdepth = atoi (temp -> str);	FreeList (temp);      }      break;    case 'S':      stack -> flags |= SANITY_CHECK_ON;      break;    }  }  free (new_str);}/* *  FUNCTION * *	_db_pop_    pop the debug stack * *  DESCRIPTION * *	Pops the debug stack, returning the debug state to its *	condition prior to the most recent _db_push_ invocation. *	Note that the pop will fail if it would remove the last *	valid state 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_ (){  reg1 struct state *discard;  discard = stack;  if (discard != NULL && discard -> next_state != NULL) {    stack = discard -> next_state;    _db_fp_ = stack -> out_file;    _db_pfp_ = stack -> prof_file;    if (discard -> keywords != NULL) {      FreeList (discard -> keywords);    }    if (discard -> functions != NULL) {      FreeList (discard -> functions);    }    if (discard -> processes != NULL) {      FreeList (discard -> processes);    }    if (discard -> p_functions != NULL) {      FreeList (discard -> p_functions);    }    CloseFile (discard -> out_file);    if (discard -> prof_file)      CloseFile (discard -> prof_file);    free ((char *) discard);  }}/* *  FUNCTION * *	_db_enter_    process entry point to user function * *  SYNOPSIS * *	VOID _db_enter_ (_func_, _file_, _line_, *			 _sfunc_, _sfile_, _slevel_, _sframep_) *	char *_func_;		points to current function name *	char *_file_;		points to current file name *	int _line_;		called from source line number *	char **_sfunc_;		save previous _func_ *	char **_sfile_;		save previous _file_ *	int *_slevel_;		save previous nesting level *	char ***_sframep_;	save previous frame pointer * *  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_ (_func_, _file_, _line_, _sfunc_, _sfile_, _slevel_,		 _sframep_)const char *_func_;const char *_file_;uint _line_;char **_sfunc_;char **_sfile_;uint *_slevel_;char ***_sframep_ __attribute__((unused));{  reg1 CODE_STATE *state;  if (!_no_db_)  {    if (!init_done)      _db_push_ (_DBUG_START_CONDITION_);    state=code_state();    *_sfunc_ = (char*) state->func;    *_sfile_ = state->file;    state->func =(char*)  _func_;    state->file = (char*) _file_;		/* BaseName takes time !! */    *_slevel_ =  ++state->level;#ifndef THREAD    *_sframep_ = state->framep;    state->framep = (char **) _sframep_;    if (DoProfile ())    {      long stackused;      if (*state->framep == NULL) {	stackused = 0;      } else {	stackused = ((long)(*state->framep)) - ((long)(state->framep));	stackused = stackused > 0 ? stackused : -stackused;      }      (void) fprintf (_db_pfp_, PROF_EFMT , Clock (), state->func);#ifdef AUTOS_REVERSE      (void) fprintf (_db_pfp_, PROF_SFMT, state->framep, stackused, *_sfunc_);#else      (void) fprintf (_db_pfp_, PROF_SFMT, state->framep, stackused,		      state->func);#endif      (void) fflush (_db_pfp_);    }#endif    if (DoTrace (state))    {      pthread_mutex_lock(&THR_LOCK_dbug);      DoPrefix (_line_);      Indent (state -> level);      (void) fprintf (_db_fp_, ">%s\n", state->func);      dbug_flush ();				/* This does a unlock */    }#ifdef SAFEMALLOC    if (stack -> flags & SANITY_CHECK_ON)      if (_sanity(_file_,_line_))		/* Check of safemalloc */	stack -> flags &= ~SANITY_CHECK_ON;#endif  }}/* *  FUNCTION * *	_db_return_    process exit from user function * *  SYNOPSIS * *	VOID _db_return_ (_line_, _sfunc_, _sfile_, _slevel_) *	int _line_;		current source line number *	char **_sfunc_;		where previous _func_ is to be retrieved *	char **_sfile_;		where previous _file_ is to be retrieved *	int *_slevel_;		where previous level was stashed * *  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. * */void _db_return_ (_line_, _sfunc_, _sfile_, _slevel_)uint _line_;char **_sfunc_;char **_sfile_;uint *_slevel_;{  CODE_STATE *state;  if (!_no_db_)  {    if (!init_done)      _db_push_ ("");    state=code_state();    if (stack->flags & (TRACE_ON | DEBUG_ON | PROFILE_ON))    {      pthread_mutex_lock(&THR_LOCK_dbug);      if (state->level != (int) *_slevel_)	(void) fprintf (_db_fp_, ERR_MISSING_RETURN, _db_process_,			state->func);      else      {#ifdef SAFEMALLOC	if (stack -> flags & SANITY_CHECK_ON)	  if (_sanity(*_sfile_,_line_))	    stack->flags &= ~SANITY_CHECK_ON;#endif#ifndef THREAD	if (DoProfile ())	  (void) fprintf (_db_pfp_, PROF_XFMT, Clock(), state->func);#endif	if (DoTrace (state))	{	  DoPrefix (_line_);	  Indent (state->level);	  (void) fprintf (_db_fp_, "<%s\n", state->func);	}      }      dbug_flush();    }    state->level = *_slevel_-1;    state->func = *_sfunc_;    state->file = *_sfile_;#ifndef THREAD    if (state->framep != NULL)      state->framep = (char **) *state->framep;#endif  }}/* *  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_ (_line_, keyword)uint _line_;const char *keyword;{  CODE_STATE *state=code_state();  state->u_line = _line_;  state->u_keyword = (char*) 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 *state;  state=code_state();  va_start(args,format);  if (_db_keyword_ (state->u_keyword)) {    pthread_mutex_lock(&THR_LOCK_dbug);    DoPrefix (state->u_line);    if (TRACING) {      Indent (state->level + 1);    } else {      (void) fprintf (_db_fp_, "%s: ", state->func);    }    (void) fprintf (_db_fp_, "%s: ", state->u_keyword);    (void) vfprintf (_db_fp_, format, args);    va_end(args);    (void) fputc('\n',_db_fp_);    dbug_flush();  }  va_end(args);}/* *  FUNCTION * *	      _db_dump_    dump a string until '\0' is found * *  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_(_line_,keyword,memory,length)uint _line_,length;const char *keyword;const char *memory;{  int pos;  char dbuff[90],*strpos;  CODE_STATE *state;  state=code_state();  if (_db_keyword_ ((char*) keyword))  {    pthread_mutex_lock(&THR_LOCK_dbug);    DoPrefix (_line_);    if (TRACING)    {      Indent (state->level + 1);      pos= min(max(state->level-stack->sub_level,0)*INDENT,80);    }    else    {      pos=fprintf (_db_fp_, "%s: ", state->func);    }    sprintf(dbuff,"%s: Memory: %lx  Bytes: ",keyword,memory);    pos+= strlen(dbuff);    (void) fputs(dbuff,_db_fp_);    while (length-- > 0)    {      strpos=int2str((long) *((unsigned char*) memory++),dbuff,10);      *strpos++=' '; *strpos=0;      if ((pos+= (int) (strpos-dbuff)) >= 80)      {	pos=(int) (strpos-dbuff);	fputc('\n',_db_fp_);      }      (void) fputs(dbuff,_db_fp_);    }    (void) fputc('\n',_db_fp_);    dbug_flush();  }}/* *  FUNCTION * *	ListParse    parse list of modifiers in debug control string * *  SYNOPSIS * *	static struct link *ListParse (ctlp) *	char *ctlp; * *  DESCRIPTION * *	Given pointer to a comma separated list of strings in "cltp", *	parses the list, building a list and returning a pointer to it. *	The original comma separated list is destroyed in the process of *	building the linked list, thus it had better be a duplicate *	if it is important. * *	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 *ListParse (ctlp)char *ctlp;{  REGISTER char *start;  REGISTER struct link *new;  REGISTER struct link *head;  head = NULL;  while (*ctlp != EOS) {    start = ctlp;    while (*ctlp != EOS && *ctlp != ',') {      ctlp++;    }    if (*ctlp == ',') {      *ctlp++ = EOS;    }    new = (struct link *) DbugMalloc (sizeof (struct link));    new -> str = StrDup (start);    new -> next_link = head;    head = new;  }  return (head);}/* *  FUNCTION * *	InList	  test a given string for member of a given list * *  SYNOPSIS * *	static BOOLEAN InList (linkp, cp) *	struct link *linkp; *	char *cp; * *  DESCRIPTION

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -