📄 option.c
字号:
/* * mpatrol * A library for controlling and tracing dynamic memory allocations. * Copyright (C) 1997-2002 Graeme S. Roy <graeme.roy@analog.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307, USA. *//* * Option handling. Run-time modifiable flags are set here by parsing * an option string read from an environment variable. Any warnings * or errors that occurred during parsing will be reported. */#include "option.h"#include "diag.h"#include "utils.h"#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <limits.h>#include <time.h>#if MP_IDENT_SUPPORT#ident "$Id: option.c,v 1.43 2002/01/08 20:13:59 graeme Exp $"#else /* MP_IDENT_SUPPORT */static MP_CONST MP_VOLATILE char *option_id = "$Id: option.c,v 1.43 2002/01/08 20:13:59 graeme Exp $";#endif /* MP_IDENT_SUPPORT */#ifdef __cplusplusextern "C"{#endif /* __cplusplus *//* The temporary buffer used to parse the configuration environment variable, * since if we change the variable directly then we change the environment. * This should not really be a file scope variable as it prevents this module * from being re-entrant. */static char options[1024];/* The table describing a summary of all recognised options. */static char *options_help[] ={ "ALLOCBYTE", "unsigned integer", "", "Specifies an 8-bit byte pattern with which to prefill newly-allocated", "", "memory.", "ALLOCSTOP", "unsigned integer", "", "Specifies an allocation index at which to stop the program when it is", "", "being allocated.", "ALLOWOFLOW", NULL, "", "Specifies that a warning rather than an error should be produced if", "", "any memory operation function overflows the boundaries of a memory", "", "allocation, and that the operation should still be performed.", "AUTOSAVE", "unsigned integer", "", "Specifies the frequency at which to periodically write the profiling", "", "data to the profiling output file.", "CHECK", "unsigned range", "", "Specifies a range of allocation indices at which to check the", "", "integrity of free memory and overflow buffers.", "CHECKALL", NULL, "", "Equivalent to the CHECKALLOCS, CHECKREALLOCS, CHECKFREES and", "", "CHECKMEMORY options specified together.", "CHECKALLOCS", NULL, "", "Checks that no attempt is made to allocate a block of memory of size", "", "zero.", "CHECKFORK", NULL, "", "Checks at every call to see if the process has been forked in case", "", "new log, profiling and tracing output files need to be started.", "CHECKFREES", NULL, "", "Checks that no attempt is made to deallocate a NULL pointer.", "CHECKMEMORY", NULL, "", "Checks that no attempt is made to perform a zero-length memory", "", "operation on a NULL pointer.", "CHECKREALLOCS", NULL, "", "Checks that no attempt is made to reallocate a NULL pointer or resize", "", "an existing block of memory to size zero.", "DEFALIGN", "unsigned integer", "", "Specifies the default alignment for general-purpose memory", "", "allocations, which must be a power of two.", "EDIT", NULL, "", "Specifies that a text editor should be invoked to edit any relevant", "", "source files that are associated with any warnings or errors when", "", "they occur.", "FAILFREQ", "unsigned integer", "", "Specifies the frequency at which all memory allocations will randomly", "", "fail.", "FAILSEED", "unsigned integer", "", "Specifies the random number seed which will be used when determining", "", "which memory allocations will randomly fail.", "FREEBYTE", "unsigned integer", "", "Specifies an 8-bit byte pattern with which to prefill newly-freed", "", "memory.", "FREESTOP", "unsigned integer", "", "Specifies an allocation index at which to stop the program when it is", "", "being freed.", "HELP", NULL, "", "Displays this quick-reference option summary.", "HTML", NULL, "", "Specifies that the log file should be formatted in HTML.", "LARGEBOUND", "unsigned integer", "", "Specifies the limit in bytes up to which memory allocations should be", "", "classified as large allocations for profiling purposes.", "LEAKTABLE", NULL, "", "Specifies that the leak table should be automatically used and a leak", "", "table summary should be displayed at the end of program execution.", "LIMIT", "unsigned integer", "", "Specifies the limit in bytes at which all memory allocations should", "", "fail if the total allocated memory should increase beyond this.", "LIST", NULL, "", "Specifies that a context listing should be shown for any relevant", "", "source files that are associated with any warnings or errors when", "", "they occur.", "LOGALL", NULL, "", "Equivalent to the LOGALLOCS, LOGREALLOCS, LOGFREES and LOGMEMORY", "", "options specified together.", "LOGALLOCS", NULL, "", "Specifies that all memory allocations are to be logged and sent to", "", "the log file.", "LOGFILE", "string", "", "Specifies an alternative file in which to place all diagnostics from", "", "the mpatrol library.", "LOGFREES", NULL, "", "Specifies that all memory deallocations are to be logged and sent to", "", "the log file.", "LOGMEMORY", NULL, "", "Specifies that all memory operations are to be logged and sent to the", "", "log file.", "LOGREALLOCS", NULL, "", "Specifies that all memory reallocations are to be logged and sent to", "", "the log file.", "MEDIUMBOUND", "unsigned integer", "", "Specifies the limit in bytes up to which memory allocations should be", "", "classified as medium allocations for profiling purposes.", "NOFREE", "unsigned integer", "", "Specifies that a number of recently-freed memory allocations should", "", "be prevented from being returned to the free memory pool.", "NOPROTECT", NULL, "", "Specifies that the mpatrol library's internal data structures should", "", "not be made read-only after every memory allocation, reallocation or", "", "deallocation.", "OFLOWBYTE", "unsigned integer", "", "Specifies an 8-bit byte pattern with which to fill the overflow", "", "buffers of all memory allocations.", "OFLOWSIZE", "unsigned integer", "", "Specifies the size in bytes to use for all overflow buffers, which", "", "must be a power of two.", "OFLOWWATCH", NULL, "", "Specifies that watch point areas should be used for overflow buffers", "", "rather than filling with the overflow byte.", "PAGEALLOC", "LOWER|UPPER", "", "Specifies that each individual memory allocation should occupy at", "", "least one page of virtual memory and should be placed at the lowest", "", "or highest point within these pages.", "PRESERVE", NULL, "", "Specifies that any reallocated or freed memory allocations should", "", "preserve their original contents.", "PROF", NULL, "", "Specifies that all memory allocations are to be profiled and sent to", "", "the profiling output file.", "PROFFILE", "string", "", "Specifies an alternative file in which to place all memory allocation", "", "profiling information from the mpatrol library.", "PROGFILE", "string", "", "Specifies an alternative filename with which to locate the executable", "", "file containing the program's symbols.", "REALLOCSTOP", "unsigned integer", "", "Specifies an allocation index at which to stop the program when a", "", "memory allocation is being reallocated.", "SAFESIGNALS", NULL, "", "Instructs the library to save and replace certain signal handlers", "", "during the execution of library code and to restore them afterwards.", "SHOWALL", NULL, "", "Equivalent to the SHOWFREE, SHOWFREED, SHOWUNFREED, SHOWMAP and", "", "SHOWSYMBOLS options specified together.", "SHOWFREE", NULL, "", "Specifies that a summary of all of the free memory blocks should be", "", "displayed at the end of program execution.", "SHOWFREED", NULL, "", "Specifies that a summary of all of the freed memory allocations", "", "should be displayed at the end of program execution.", "SHOWMAP", NULL, "", "Specifies that a memory map of the entire heap should be displayed at", "", "the end of program execution.", "SHOWSYMBOLS", NULL, "", "Specifies that a summary of all of the function symbols read from the", "", "program's executable file should be displayed at the end of program", "", "execution.", "SHOWUNFREED", NULL, "", "Specifies that a summary of all of the unfreed memory allocations", "", "should be displayed at the end of program execution.", "SMALLBOUND", "unsigned integer", "", "Specifies the limit in bytes up to which memory allocations should be", "", "classified as small allocations for profiling purposes.", "TRACE", NULL, "", "Specifies that all memory allocations are to be traced and sent to", "", "the tracing output file.", "TRACEFILE", "string", "", "Specifies an alternative file in which to place all memory allocation", "", "tracing information from the mpatrol library.", "UNFREEDABORT", "unsigned integer", "", "Specifies the minimum number of unfreed allocations at which to abort", "", "the program just before program termination.", "USEDEBUG", NULL, "", "Specifies that any debugging information in the executable file", "", "should be used to obtain additional source-level information.", "USEMMAP", NULL, "", "Specifies that the library should use mmap() instead of sbrk() to", "", "allocate user memory on UNIX platforms.", NULL};/* Perform a case-insensitive comparison between two option keywords. */staticintmatchoption(char *s, char *t){#if TARGET != TARGET_AMIGA && TARGET != TARGET_WINDOWS && \ TARGET != TARGET_NETWARE int d;#endif /* TARGET */#if TARGET == TARGET_AMIGA || TARGET == TARGET_WINDOWS || \ TARGET == TARGET_NETWARE return !stricmp(s, t);#else /* TARGET */ while (((d = toupper(*s) - toupper(*t)) == 0) && (*s != '\0')) { s++; t++; } return (d == 0);#endif /* TARGET */}/* Convert a string representation of a number to an integer, * reporting any errors that occur during the conversion. */staticsize_treadnumber(char *s, long *n, int u){ char *t; int e; e = errno; errno = 0; while (isspace(*s)) s++; if ((u == 1) && (*s == '-')) { __mp_error(ET_MAX, AT_MAX, NULL, 0, "ignoring negative number `%s'\n", s); t = s; } else if ((u == 0) && (*s == '-') && (s[1] == '0') && ((s[2] == 'b') || (s[2] == 'B'))) /* This is a negative binary number. */ *n = -strtol(s + 3, &t, 2); else if ((*s == '0') && ((s[1] == 'b') || (s[1] == 'B'))) { /* This is a positive binary number. */ if (u == 0) *n = strtol(s + 2, &t, 2); else *n = strtoul(s + 2, &t, 2); } /* Otherwise let the conversion function work out the number base * from the prefix. */ else if (u == 0) *n = strtol(s, &t, 0); else *n = strtoul(s, &t, 0); if (errno == ERANGE) __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s number overflow in `%s'\n", ((u == 0) && (*n == LONG_MIN)) ? "negative" : "positive", s); errno = e; return (size_t) (t - s);}/* Convert a string representation of a numeric range to two unsigned integers, * ensuring that the first integer is less than or equal to the second. An * open range at either end is represented by -1. */staticintreadrange(char *s, unsigned long *l, unsigned long *u, unsigned long *d){ char *p, *t; unsigned long n; int w; char b, c; w = 0; *l = *u = (unsigned long) -1; *d = 1; for (p = s; (*p != '/') && (*p != '\0'); p++); b = *p; *p = '\0'; for (t = s; (*t != '-') && (*t != '\0'); t++); c = *t; *t = '\0'; /* If there was a number before the minus sign then read it. */ if ((*s != '\0') && (s[readnumber(s, (long *) l, 1)] != '\0')) { *l = (unsigned long) -1; w = 1; } else if (c == '\0') *u = *l; else { s = t + 1; /* If there was a number after the minus sign then read it too. */ if ((*s != '\0') && (s[readnumber(s, (long *) u, 1)] != '\0')) { *u = (unsigned long) -1; w = 1; } } if ((w == 0) && (b == '/')) { s = p + 1; /* If there was a forward slash then read the number after it as well. */ if ((*s != '\0') && (s[readnumber(s, (long *) d, 1)] != '\0')) { *d = 1; w = 1; } } if (w != 0) return 0; /* If one or the other of the integers was zero (but not both) then convert * it to an open range. */ if ((*l == 0) && (*u != 0)) *l = (unsigned long) -1; else if ((*l != 0) && (*u == 0)) *u = (unsigned long) -1; /* If the frequency was zero then convert it to one. */ if (*d == 0) *d = 1; /* Swap the integers if the first number is greater than the second. */ if ((*l != (unsigned long) -1) && (*u != (unsigned long) -1) && (*l > *u)) { n = *l; *l = *u; *u = n; } return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -