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

📄 snprintf.c

📁 wm PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
字号:
/* $Header: /usr/cvsroot/target/src/wrn/wm/common/lib/snprintf.c,v 1.3 2003/01/16 18:18:57 josh Exp $ *//* * Copyright (C) 1999-2005 Wind River Systems, Inc. * All rights reserved.  Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//**************************************************************************** *  Copyright 1999 Integrated Systems, Inc. *  All rights reserved. ****************************************************************************//* * Portable implementation of snprintf() and vsnprintf().  This is * derived from publicly-available code, modified to fit Epilogue * coding conventions and strip out the floating point support (which * we don't need). * * Original author's copyright notice: * * Copyright Patrick Powell 1995 * This code is based on code written by Patrick Powell (papowell@astart.com) * It may be used for any purpose as long as this notice remains intact * on all source code distributions *//* * $Log: snprintf.c,v $ * Revision 1.3  2003/01/16 18:18:57  josh * directory structure shifting * * Revision 1.2  2001/11/06 22:15:53  tneale * Fixed for newest file layout * * Revision 1.1.1.1  2001/11/05 17:48:39  tneale * Tornado shuffle * * Revision 1.5  2001/01/19 22:21:31  paul * Update copyright. * * Revision 1.4  2000/03/17 00:16:56  meister * Update copyright message * * Revision 1.3  1999/05/21 16:43:51  sra * Minor tweaks to debugging code. * * Revision 1.2  1999/05/20 22:15:12  wes * Call etc_vsnprintf from etc_snprintf * * Revision 1.1  1999/05/20 20:28:17  sra * Add etc_snprintf() and etc_vsnprintf(). * *//* [clearcase]modification history-------------------01b,20apr05,job  update copyright notices01a,11dec03,job  fix copyright statements*/#include <stdarg.h>#include <wrn/wm/common/config.h>#include <wrn/wm/common/snprintf.h>#include <wrn/wm/common/glue.h>#include <ctype.h>static void dopr (char *buffer, size_t maxlen, const char *format,                   va_list args);static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,		    char *value, int flags, int min, int max);static void fmtint (char *buffer, size_t *currlen, size_t maxlen,		    long value, int base, int min, int max, int flags);static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );/* * dopr(): poor man's version of doprintf *//* format read states */#define DP_S_DEFAULT 0#define DP_S_FLAGS   1#define DP_S_MIN     2#define DP_S_DOT     3#define DP_S_MAX     4#define DP_S_MOD     5#define DP_S_CONV    6#define DP_S_DONE    7/* format flags - Bits */#define DP_F_MINUS 	(1 << 0)#define DP_F_PLUS  	(1 << 1)#define DP_F_SPACE 	(1 << 2)#define DP_F_NUM   	(1 << 3)#define DP_F_ZERO  	(1 << 4)#define DP_F_UP    	(1 << 5)#define DP_F_UNSIGNED 	(1 << 6)/* Conversion Flags */#define DP_C_SHORT   1#define DP_C_LONG    2#define char_to_int(p) (p - '0')#define MAX(p,q) ((p >= q) ? p : q)static void dopr (char *buffer, size_t maxlen, const char *format, va_list args){  char ch;  long value;  char *strvalue;  int min;  int max;  int state;  int flags;  int cflags;  size_t currlen;    state = DP_S_DEFAULT;  currlen = flags = cflags = min = 0;  max = -1;  ch = *format++;  while (state != DP_S_DONE) {    if ((ch == '\0') || (currlen >= maxlen))       state = DP_S_DONE;    switch(state) {    case DP_S_DEFAULT:      if (ch == '%') 	state = DP_S_FLAGS;      else 	dopr_outch (buffer, &currlen, maxlen, ch);      ch = *format++;      break;    case DP_S_FLAGS:      switch (ch) {      case '-':	flags |= DP_F_MINUS;        ch = *format++;	break;      case '+':	flags |= DP_F_PLUS;        ch = *format++;	break;      case ' ':	flags |= DP_F_SPACE;        ch = *format++;	break;      case '#':	flags |= DP_F_NUM;        ch = *format++;	break;      case '0':	flags |= DP_F_ZERO;        ch = *format++;	break;      default:	state = DP_S_MIN;	break;      }      break;    case DP_S_MIN:      if (isdigit((int) ch)) {	min = 10*min + char_to_int (ch);	ch = *format++;      } else if (ch == '*') {	min = va_arg (args, int);	ch = *format++;	state = DP_S_DOT;      } else {	state = DP_S_DOT;      }      break;    case DP_S_DOT:      if (ch == '.') {	state = DP_S_MAX;	ch = *format++;      } else {	state = DP_S_MOD;      }      break;    case DP_S_MAX:      if (isdigit((int) ch)) {	if (max < 0)	  max = 0;	max = 10*max + char_to_int (ch);	ch = *format++;      } else if (ch == '*') {	max = va_arg (args, int);	ch = *format++;	state = DP_S_MOD;      } else {	state = DP_S_MOD;      }      break;    case DP_S_MOD:      /* Currently, we don't support Long Long, bummer */      switch (ch) {      case 'h':	cflags = DP_C_SHORT;	ch = *format++;	break;      case 'l':	cflags = DP_C_LONG;	ch = *format++;	break;      default:	break;      }      state = DP_S_CONV;      break;    case DP_S_CONV:      switch (ch) {      case 'd':      case 'i':	if (cflags == DP_C_SHORT) 	  value = va_arg (args, short int);	else if (cflags == DP_C_LONG)	  value = va_arg (args, long int);	else	  value = va_arg (args, int);	fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);	break;      case 'o':	flags |= DP_F_UNSIGNED;	if (cflags == DP_C_SHORT)	  value = va_arg (args, unsigned short int);	else if (cflags == DP_C_LONG)	  value = va_arg (args, unsigned long int);	else	  value = va_arg (args, unsigned int);	fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);	break;      case 'u':	flags |= DP_F_UNSIGNED;	if (cflags == DP_C_SHORT)	  value = va_arg (args, unsigned short int);	else if (cflags == DP_C_LONG)	  value = va_arg (args, unsigned long int);	else	  value = va_arg (args, unsigned int);	fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);	break;      case 'X':	flags |= DP_F_UP;      case 'x':	flags |= DP_F_UNSIGNED;	if (cflags == DP_C_SHORT)	  value = va_arg (args, unsigned short int);	else if (cflags == DP_C_LONG)	  value = va_arg (args, unsigned long int);	else	  value = va_arg (args, unsigned int);	fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);	break;      case 'c':	dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));	break;      case 's':	strvalue = va_arg (args, char *);	if (max < 0) 	  max = maxlen; /* ie, no max */	fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);	break;      case 'p':	strvalue = va_arg (args, void *);	fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);	break;      case 'n':	if (cflags == DP_C_SHORT) {	  short int *num;	  num = va_arg (args, short int *);	  *num = currlen;        } else if (cflags == DP_C_LONG) {	  long int *num;	  num = va_arg (args, long int *);	  *num = currlen;        } else {	  int *num;	  num = va_arg (args, int *);	  *num = currlen;        }	break;      case '%':	dopr_outch (buffer, &currlen, maxlen, ch);	break;      case 'w':	/* not supported yet, treat as next char */	ch = *format++;	break;      default:	/* Unknown, skip */	break;      }      ch = *format++;      state = DP_S_DEFAULT;      flags = cflags = min = 0;      max = -1;      break;    case DP_S_DONE:      break;    default:			/* hmm? */      break;			/* some picky compilers need this */    }  }  if (currlen < maxlen - 1)     buffer[currlen] = '\0';  else     buffer[maxlen - 1] = '\0';}static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,		    char *value, int flags, int min, int max){  int padlen;			/* amount to pad */  int cnt = 0;    if (value == 0)    value = "<NULL>";  padlen = min - STRLEN(value);  if (padlen < 0)     padlen = 0;  if (flags & DP_F_MINUS)     padlen = -padlen; /* Left Justify */  while ((padlen > 0) && (cnt < max)) {    dopr_outch (buffer, currlen, maxlen, ' ');    --padlen;    ++cnt;  }  while (*value && (cnt < max)) {    dopr_outch (buffer, currlen, maxlen, *value++);    ++cnt;  }  while ((padlen < 0) && (cnt < max)) {    dopr_outch (buffer, currlen, maxlen, ' ');    ++padlen;    ++cnt;  }}/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */static void fmtint (char *buffer, size_t *currlen, size_t maxlen,		    long value, int base, int min, int max, int flags){  int signvalue = 0;  unsigned long uvalue;  char convert[20];  int place = 0;  int spadlen = 0; /* amount to space pad */  int zpadlen = 0; /* amount to zero pad */  char *chars = ((flags & DP_F_UP)		 ? "0123456789ABCDEF"		 : "0123456789abcdef");  if (max < 0)    max = 0;  uvalue = value;  if (!(flags & DP_F_UNSIGNED)) {    if (value < 0) {      signvalue = '-';      uvalue = -value;    } else if (flags & DP_F_PLUS) {	/* Do a sign (+/i) */      signvalue = '+';    } else if (flags & DP_F_SPACE) {      signvalue = ' ';    }  }  do {    convert[place++] = chars[uvalue % (unsigned) base];    uvalue = (uvalue / (unsigned)base );  } while(uvalue && (place < 20));  if (place == 20)    place--;  convert[place] = 0;  zpadlen = max - place;  spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);  if (zpadlen < 0)    zpadlen = 0;  if (spadlen < 0)    spadlen = 0;  if (flags & DP_F_ZERO) {    zpadlen = MAX(zpadlen, spadlen);    spadlen = 0;  }  if (flags & DP_F_MINUS)     spadlen = -spadlen; /* Left Justifty */  /* Spaces */  while (spadlen > 0) {    dopr_outch (buffer, currlen, maxlen, ' ');    --spadlen;  }  /* Sign */  if (signvalue)     dopr_outch (buffer, currlen, maxlen, signvalue);  /* Zeros */  if (zpadlen > 0) {    while (zpadlen > 0) {      dopr_outch (buffer, currlen, maxlen, '0');      --zpadlen;    }  }  /* Digits */  while (place > 0)     dopr_outch (buffer, currlen, maxlen, convert[--place]);    /* Left Justified spaces */  while (spadlen < 0) {    dopr_outch (buffer, currlen, maxlen, ' ');    ++spadlen;  }}static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c){  if (*currlen < maxlen)    buffer[(*currlen)++] = c;}int etc_vsnprintf (char *str, size_t count, const char *fmt, va_list args){  str[0] = 0;  dopr(str, count, fmt, args);  return(STRLEN(str));}int etc_snprintf (char *str, size_t count, const char *fmt, ...){  va_list ap;  va_start(ap, fmt);  etc_vsnprintf(str, count, fmt, ap);  va_end(ap);  return(STRLEN(str));}#ifndef INSTALL_ETC_SNPRINTF_TEST#define INSTALL_ETC_SNPRINTF_TEST defined(ETC_SNPRINTF_TEST_OUTPUT)#endif#if INSTALL_ETC_SNPRINTF_TESTint main (int argc, char *argv[]){  char buf1[1024];  char buf2[1024];  char *int_fmt[] = { "%-1.5d", "%1.5d", "%123.9d", "%5.5d", "%10.5d",		      "% 10.5d", "%+22.33d", "%01.3d", "%4d", 0 };  long int_nums[] = { -1, 134, 91340, 341, 0203, 0};  int x, y;  int fail = 0;  int num = 0;  ETC_SNPRINTF_TEST_OUTPUT("Testing etc_snprintf() against sprintf()...");  for (x = 0; int_fmt[x] != 0; x++) {    for (y = 0; int_nums[y] != 0 ; y++) {      etc_snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);      sprintf      (buf2,                int_fmt[x], int_nums[y]);      if (STRCMP (buf1, buf2)) {	ETC_SNPRINTF_TEST_OUTPUT("\netc_snprintf() doesn't match format: ");	ETC_SNPRINTF_TEST_OUTPUT(int_fmt[x]);	ETC_SNPRINTF_TEST_OUTPUT("\n\tetc_snprintf() = ");	ETC_SNPRINTF_TEST_OUTPUT(buf1);	ETC_SNPRINTF_TEST_OUTPUT("\n\tsprintf() = ");	ETC_SNPRINTF_TEST_OUTPUT(buf2);	ETC_SNPRINTF_TEST_OUTPUT("\n");	fail++;      } else {	ETC_SNPRINTF_TEST_OUTPUT(".");      }      num++;    }  }  ETC_SNPRINTF_TEST_OUTPUT("\n");  return fail;}#endif /* INSTALL_ETC_SNPRINTF_TEST */

⌨️ 快捷键说明

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