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

📄 dmalloc_argv.c

📁 减少内存碎片的malloc分配函数
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Generic argv processor... * * Copyright 1995 by Gray Watson * * This file is part of the argv library. * * Permission to use, copy, modify, and distribute this software for * any purpose and without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies, and that the name of Gray Watson not be used in advertising * or publicity pertaining to distribution of the document or software * without specific, written prior permission. * * Gray Watson makes no representations about the suitability of the * software described herein for any purpose.  It is provided "as is" * without express or implied warranty. * * The author may be contacted via http://dmalloc.com/ */#include <ctype.h>#include <stdio.h>#if HAVE_STRING_H# include <string.h>#endif#if HAVE_STDLIB_H# include <stdlib.h>#endif#include "conf.h"#include "dmalloc_argv.h"#include "dmalloc_argv_loc.h"#include "compat.h"/* internal routines */static	void	do_list(argv_t *grid, const int arg_c, char **argv,			argv_t **queue_list, int *queue_head_p,			int *queue_tail_p, int *okay_bp);/* * exported variables *//* This is a processed version of argv[0], pre-path removed: /bin/ls -> ls */char	argv_program[PROGRAM_NAME + 1] = "Unknown";/* A global value of argv from main after argv_process has been called */char	**argv_argv = NULL;/* A global value of argc from main after argv_process has been called */int	argv_argc = 0;/* This should be set externally to provide general program help to user */char	*argv_help_string = NULL;/* This should be set externally to provide version information to the user */char	*argv_version_string = NULL;/* * Are we running interactively?  This will exit on errors.  Set to * false to return error codes instead. */int 	argv_interactive = ARGV_TRUE;/* * The FILE stream that argv out_puts all its errors.  Set to NULL to * not dump any error messages.  Default is stderr. */FILE 	*argv_error_stream = ERROR_STREAM_INIT;/* * global settings *//* * Set to 1 (the default) to enable the handling of -l=foo or * --logfile=foo type of arguments.  Set to 0 to disable.  This allows * you to specifically assign a value to an argument. * * NOTE: this is set by argv_process automatically.  If you do not * want this behavior, you should use argv_process_no_env. */int	argv_close_enable_b = 1;/* * If the library sees a "--" argument, it will turn off further * argument process.  Set to 1 to enable the ability of specifying * additional "--" arguments to reenable (basically toggle on then * off) argument processing.  Set to 0 (the default) to disable this * behavior. * * NOTE: this is set by argv_process automatically.  If you do not * want this behavior, you should use argv_process_no_env. */int	argv_last_toggle_b = 0;/* * Set to 1 (the default) to have the library accept multiple usage of * the same argument.  Set to 0 to have the library generate an error * if you use an argument twice. * * NOTE: this is set by argv_process automatically.  If you do not * want this behavior, you should use argv_process_no_env. */int	argv_multi_accept_b = 1;/* * Set to one of the ARGV_USAGE_ defines in the argv.h file.  This * tell the library what usage information to display when --usage is * specified by the user.  Default is ARGV_USAGE_LONG. * * NOTE: this is set by argv_process automatically.  If you do not * want this behavior, you should use argv_process_no_env. */int	argv_usage_type = ARGV_USAGE_LONG;/* * Set to one of the ARGV_USAGE_ defines in the argv.h file.  This * tell the library what usage information to display when an error is * encountered.  The usage information accompanies the error message. * Default is ARGV_USAGE_SEE. * * NOTE: this is set by argv_process automatically.  If you do not * want this behavior, you should use argv_process_no_env. */int	argv_error_type = ARGV_USAGE_SEE;/* * Set to 1 (the default) if you want the library look for associated * arguments from the associated program's environmental variable.  If * set the 0 then no environmental variable will be used.  If you are * running program foo then the library will look for the * environmental variable ARGV_foo and will add those to the argument * list specified on the command line.  By default they will be * inserted in front of those on the command line unless the * argv_env_after_b is set to 1. * * NOTE: this is set by argv_process automatically.  If you do not * want this behavior, you should use argv_process_no_env. */int	argv_process_env_b = 1;/* * Set to 1 if you want the library to append the arguments from the * program's environmental variable after those specified on the * command line.  If set the 0 (the default) then they will be * inserted before those specified on the command line.  See * argv_process_env_b for more information. * * NOTE: this is set by argv_process automatically.  If you do not * want this behavior, you should use argv_process_no_env. */int	argv_env_after_b = 0;/* local variables */static	argv_t	empty[] = {{ ARGV_LAST }};	/* empty argument array */static	int	enabled_b = ARGV_FALSE;		/* are the lights on? *//****************************** startup routine ******************************//* * static void argv_startup * * DESCRIPTION: * * Turn on the lights. * * RETURNS: * * None. * * ARGUMENTS: * * None. */static	void	argv_startup(void){  if (enabled_b) {    return;  }  enabled_b = ARGV_TRUE;    /* ANSI says we cannot predefine this above */  if (argv_error_stream == ERROR_STREAM_INIT) {    argv_error_stream = stderr;  }}/***************************** general utilities *****************************//* * static int btoi * * DESCRIPTION: * * Binary string to integer translation. * * RETURNS: * * Integer converted from the string. * * ARGUMENTS: * * str - String of binary 0s and 1s that we are converting. */static	int	btoi(const char *str){  int		ret = 0;    /* strip off spaces */  for (; isspace(*str); str++) {  }    for (; *str == '0' || *str == '1'; str++) {    ret *= 2;    ret += *str - '0';  }    return ret;}/* * static int otoi * * DESCRIPTION: * * Octal string to integer translation. * * RETURNS: * * Integer converted from the string. * * ARGUMENTS: * * str - String of octal digits that we are converting. */static	int	otoi(const char *str){  int		ret = 0;    /* strip off spaces */  for (; isspace(*str); str++) {  }    for (; *str >= '0' && *str <= '7'; str++) {    ret *= 8;    ret += *str - '0';  }    return ret;}/* * static int htoi * * DESCRIPTION: * * Hexadecimal string to integer translation. * * RETURNS: * * Integer converted from the string. * * ARGUMENTS: * * str - String of hexadecimal characters and digits that we are * converting. */static	int	htoi(const char *str){  int		ret = 0;    /* strip off spaces */  for (; isspace(*str); str++) {  }    /* skip a leading 0[xX] */  if (*str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X')) {    str += 2;  }    for (; isdigit(*str) ||       (*str >= 'a' && *str <= 'f') || (*str >= 'A' && *str <= 'F');       str++) {    ret *= 16;    if (*str >= 'a' && *str <= 'f') {      ret += *str - 'a' + 10;    }    else if (*str >= 'A' && *str <= 'F') {      ret += *str - 'A' + 10;    }    else {      ret += *str - '0';    }  }    return ret;}/* * static char *string_copy * * DESCRIPTION: * * Basically a strdup for compatibility sake. * * RETURNS: * * Character pointer that must be freed later. * * ARGUMENTS: * * str - String we are copying. */static	char	*string_copy(const char *str){  const char	*str_p;  char		*copy, *copy_p;  int		len;    len = strlen(str);  copy = (char *)malloc(len + 1);  if (copy == NULL) {    if (argv_error_stream != NULL) {      (void)fprintf(argv_error_stream,		    "%s: memory error during argument processing\n",		    argv_program);    }    if (argv_interactive) {      (void)exit(EXIT_CODE);    }    return NULL;  }    for (str_p = str, copy_p = copy; *str_p != '\0';) {    *copy_p++ = *str_p++;  }  *copy_p = '\0';    return copy;}/* * static char **vectorize * * DESCRIPTION: * * Break a string up into its arguments separated by one of the * characters in a token string and return an array of char pointers. * * NOTE: the string argument should stay around until that time. * * RETURNS: * * Success - Allocated list of character poiners into the string * argument which must be freed later. * * Failure - NULL * * ARGUMENTS: * * str - String we are tokenizing. * * tok - List of token characters to look for in the string. * * num_tok_p - Pointer to an integer which will be set to the number * of tokens found in the string. */static	char	**vectorize(char *str, const char *tok, int *num_tok_p){  char	**vect_p;  char	*tmp, *str_p, *tok_p;  int	tok_c, tok_n;    /* count the tokens */  tmp = string_copy(str);  if (tmp == NULL) {    return NULL;  }    str_p = tmp;  tok_c = 0;  while (1) {    tok_p = strsep(&str_p, tok);    if (tok_p == NULL) {      break;    }    if (*tok_p != '\0') {      tok_c++;    }  }  tok_n = tok_c;  free(tmp);    *num_tok_p = tok_n;    if (tok_c == 0) {    return NULL;  }    /* allocate the pointer grid */  vect_p = (char **)malloc(sizeof(char *) * tok_c);  if (vect_p == NULL) {    if (argv_error_stream != NULL) {      (void)fprintf(argv_error_stream,		    "%s: memory error during argument processing\n",		    argv_program);    }    if (argv_interactive) {      (void)exit(EXIT_CODE);    }    return NULL;  }    /* load the tokens into the list */  str_p = str;  for (tok_c = 0; tok_c < tok_n;) {    tok_p = strsep(&str_p, tok);    if (tok_p == NULL) {      break;    }    if (*tok_p != '\0') {      vect_p[0] = tok_p;      tok_c++;    }  }    return vect_p;}/* * static int expand_buf * * DESCRIPTION: * * Translates a buffer of bytes into its printable version. * * NOTE: it does _not_ add a \0 at the end of OUT. * * RETURNS: * * Number of characters written in to the output buffer. * * ARGUMENTS: * * buf - Input buffer of bytes. * * buf_size - Size of the input buffer.  If < 0 then the routing will * translate up to the first \0. * * out - Output buffer for the translated characters. * * out_size - Maximum size of the output buffer. */static	int	expand_buf(const void *buf, const int buf_size,			   char *out, const int out_size){  int			buf_c;  const unsigned char	*buf_p, *spec_p;  char	 		*max_p, *out_p = out;    /* setup our max pointer */  max_p = out + out_size;    /* run through the input buffer, counting the characters as we go */  for (buf_c = 0, buf_p = (const unsigned char *)buf;; buf_c++, buf_p++) {        /* did we reach the end of the buffer? */    if (buf_size < 0) {      if (*buf_p == '\0') {	break;      }    }    else {      if (buf_c >= buf_size) {	break;      }    }        /* search for special characters */    for (spec_p = (unsigned char *)SPECIAL_CHARS + 1;	 *(spec_p - 1) != '\0';	 spec_p += 2) {      if (*spec_p == *buf_p) {	break;      }    }        /* did we find one? */    if (*(spec_p - 1) != '\0') {      if (out_p + 2 >= max_p) {	break;      }      (void)loc_snprintf(out_p, max_p - out_p, "\\%c", *(spec_p - 1));      out_p += 2;      continue;    }        /* print out any 7-bit printable characters */    if (*buf_p < 128 && isprint(*buf_p)) {      if (out_p + 1 >= max_p) {	break;      }      *out_p = *(char *)buf_p;      out_p += 1;    }    else {      if (out_p + 4 >= max_p) {	break;      }      (void)loc_snprintf(out_p, max_p - out_p, "\\%03o", *buf_p);      out_p += 4;    }  }    return out_p - out;}/****************************** usage routines *******************************//* * static void usage_short * * DESCRIPTION: * * Print a short-format usage message. * * RETURNS: * * None. * * ARGUMENTS: * * args - Array of argv_t structions whose usage messages you print. * * flags - User flags. */static	void	usage_short(const argv_t *args, const int flag){  const argv_t	*arg_p;  int		len, col_c = 0;  int		mark_b = ARGV_FALSE;  char		*prefix;    if (argv_error_stream == NULL) {

⌨️ 快捷键说明

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