diff options
Diffstat (limited to 'backends/platform/symbian/src/vsnprintf.h')
| -rw-r--r-- | backends/platform/symbian/src/vsnprintf.h | 805 | 
1 files changed, 432 insertions, 373 deletions
diff --git a/backends/platform/symbian/src/vsnprintf.h b/backends/platform/symbian/src/vsnprintf.h index 5a9c836ea3..6e75719d55 100644 --- a/backends/platform/symbian/src/vsnprintf.h +++ b/backends/platform/symbian/src/vsnprintf.h @@ -1,8 +1,11 @@  /* - * This is the vsnprintf for scummvm/symbian implementation from the original snprintf.c, - * all support functions has been removed and vsnprintf renamed to symbian_vsnprintf + * This is the vsnprintf for scummvm/symbian implementation from the original + * snprintf.c, all support functions has been removed and vsnprintf renamed to + * symbian_vsnprintf + * According to the homepage this function may be licensed under either the + * Frontier Artistic License or the GPL. + *   * snprintf.c - a portable implementation of snprintf - * According to the homepage this function could be licensed as either Frontier Aritistic or GPL.   *   * AUTHOR   *   Mark Martinec <mark.martinec@ijs.si>, April 1999. @@ -244,13 +247,14 @@ int symbian_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) {  			/* if (str_l < str_m) str[str_l++] = *p++;    -- this would be sufficient */  			/* but the following code achieves better performance for cases  			* where format string is long and contains few conversions */ -			const char *q = strchr(p+1,'%'); -			size_t n = !q ? strlen(p) : (q-p); +			const char *q = strchr(p + 1, '%'); +			size_t n = !q ? strlen(p) : (q - p);  			if (str_l < str_m) { -				size_t avail = str_m-str_l; -				fast_memcpy(str+str_l, p, (n>avail?avail:n)); +				size_t avail = str_m - str_l; +				fast_memcpy(str + str_l, p, (n > avail ? avail : n));  			} -			p += n; str_l += n; +			p += n; +			str_l += n;  		} else {  			const char *starting_p;  			size_t min_field_width = 0, precision = 0; @@ -262,398 +266,453 @@ int symbian_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) {  			char tmp[32];/* temporary buffer for simple numeric->string conversion */  			const char *str_arg;      /* string address in case of string argument */ -									  size_t str_arg_l;         /* natural field width of arg without padding +			size_t str_arg_l;         /* natural field width of arg without padding  									  and sign */ -									  unsigned char uchar_arg; -									  /* unsigned char argument value - only defined for c conversion. -									  N.B. standard explicitly states the char argument for -									  the c conversion is unsigned */ +			unsigned char uchar_arg; +			/* unsigned char argument value - only defined for c conversion. +			N.B. standard explicitly states the char argument for +			the c conversion is unsigned */ -									  size_t number_of_zeros_to_pad = 0; -									  /* number of zeros to be inserted for numeric conversions -									  as required by the precision or minimal field width */ +			size_t number_of_zeros_to_pad = 0; +			/* number of zeros to be inserted for numeric conversions +			as required by the precision or minimal field width */ -									  size_t zero_padding_insertion_ind = 0; -									  /* index into tmp where zero padding is to be inserted */ +			size_t zero_padding_insertion_ind = 0; +			/* index into tmp where zero padding is to be inserted */ -									  char fmt_spec = '\0'; -									  /* current conversion specifier character */ +			char fmt_spec = '\0'; +			/* current conversion specifier character */ -									  str_arg = credits;/* just to make compiler happy (defined but not used)*/ -									  str_arg = NULL; -									  starting_p = p; p++;  /* skip '%' */ -									  /* parse flags */ -									  while (*p == '0' || *p == '-' || *p == '+' || -										  *p == ' ' || *p == '#' || *p == '\'') { -										  switch (*p) { -										  case '0': zero_padding = 1; break; -										  case '-': justify_left = 1; break; -										  case '+': force_sign = 1; space_for_positive = 0; break; -										  case ' ': force_sign = 1; -											  /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */ -											  break; -										  case '#': alternate_form = 1; break; -										  case '\'': break; -										  } -										  p++; -									  } -									  /* If the '0' and '-' flags both appear, the '0' flag should be ignored. */ +			str_arg = credits;/* just to make compiler happy (defined but not used)*/ +			str_arg = NULL; +			starting_p = p; +			p++;  /* skip '%' */ +			/* parse flags */ +			while (*p == '0' || *p == '-' || *p == '+' || +			       *p == ' ' || *p == '#' || *p == '\'') { +				switch (*p) { +				case '0': +					zero_padding = 1; +					break; +				case '-': +					justify_left = 1; +					break; +				case '+': +					force_sign = 1; +					space_for_positive = 0; +					break; +				case ' ': +					force_sign = 1; +					/* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */ +					break; +				case '#': +					alternate_form = 1; +					break; +				case '\'': +					break; +				} +				p++; +			} +			/* If the '0' and '-' flags both appear, the '0' flag should be ignored. */ -									  /* parse field width */ -									  if (*p == '*') { -										  int j; -										  p++; j = va_arg(ap, int); -										  if (j >= 0) min_field_width = j; -										  else { min_field_width = -j; justify_left = 1; } -									  } else if (isdigit((int)(*p))) { -									  /* size_t could be wider than unsigned int; -										  make sure we treat argument like common implementations do */ -										  unsigned int uj = *p++ - '0'; -										  while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0'); -										  min_field_width = uj; -									  } -									  /* parse precision */ -									  if (*p == '.') { -										  p++; precision_specified = 1; -										  if (*p == '*') { -											  int j = va_arg(ap, int); -											  p++; -											  if (j >= 0) precision = j; -											  else { -												  precision_specified = 0; precision = 0; -												  /* NOTE: -												  *   Solaris 2.6 man page claims that in this case the precision -												  *   should be set to 0.  Digital Unix 4.0, HPUX 10 and BSD man page -												  *   claim that this case should be treated as unspecified precision, -												  *   which is what we do here. -												  */ -											  } -										  } else if (isdigit((int)(*p))) { -										  /* size_t could be wider than unsigned int; -											  make sure we treat argument like common implementations do */ -											  unsigned int uj = *p++ - '0'; -											  while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0'); -											  precision = uj; -										  } -									  } -									  /* parse 'h', 'l' and 'll' length modifiers */ -									  if (*p == 'h' || *p == 'l') { -										  length_modifier = *p; p++; -										  if (length_modifier == 'l' && *p == 'l') {   /* double l = long long */ +			/* parse field width */ +			if (*p == '*') { +				int j; +				p++; +				j = va_arg(ap, int); +				if (j >= 0) min_field_width = j; +				else { min_field_width = -j; justify_left = 1; } +			} else if (isdigit((int)(*p))) { +				/* size_t could be wider than unsigned int; +				    make sure we treat argument like common implementations do */ +				unsigned int uj = *p++ - '0'; +				while (isdigit((int)(*p))) uj = 10 * uj + (unsigned int)(*p++ - '0'); +				min_field_width = uj; +			} +			/* parse precision */ +			if (*p == '.') { +				p++; +				precision_specified = 1; +				if (*p == '*') { +					int j = va_arg(ap, int); +					p++; +					if (j >= 0) precision = j; +					else { +						precision_specified = 0; +						precision = 0; +						/* NOTE: +						*   Solaris 2.6 man page claims that in this case the precision +						*   should be set to 0.  Digital Unix 4.0, HPUX 10 and BSD man page +						*   claim that this case should be treated as unspecified precision, +						*   which is what we do here. +						*/ +					} +				} else if (isdigit((int)(*p))) { +					/* size_t could be wider than unsigned int; +					    make sure we treat argument like common implementations do */ +					unsigned int uj = *p++ - '0'; +					while (isdigit((int)(*p))) uj = 10 * uj + (unsigned int)(*p++ - '0'); +					precision = uj; +				} +			} +			/* parse 'h', 'l' and 'll' length modifiers */ +			if (*p == 'h' || *p == 'l') { +				length_modifier = *p; +				p++; +				if (length_modifier == 'l' && *p == 'l') {   /* double l = long long */  #ifdef SNPRINTF_LONGLONG_SUPPORT -											  length_modifier = '2';                  /* double l encoded as '2' */ +					length_modifier = '2';                  /* double l encoded as '2' */  #else -											  length_modifier = 'l';                 /* treat it as a single 'l' */ +					length_modifier = 'l';                 /* treat it as a single 'l' */  #endif -											  p++; -										  } -									  } -									  fmt_spec = *p; -									  /* common synonyms: */ -									  switch (fmt_spec) { -									  case 'i': fmt_spec = 'd'; break; -									  case 'D': fmt_spec = 'd'; length_modifier = 'l'; break; -									  case 'U': fmt_spec = 'u'; length_modifier = 'l'; break; -									  case 'O': fmt_spec = 'o'; length_modifier = 'l'; break; -									  default: break; -									  } -									  /* get parameter value, do initial processing */ -									  switch (fmt_spec) { -									  case '%': /* % behaves similar to 's' regarding flags and field widths */ -									  case 'c': /* c behaves similar to 's' regarding flags and field widths */ -									  case 's': -										  length_modifier = '\0';          /* wint_t and wchar_t not supported */ -										  /* the result of zero padding flag with non-numeric conversion specifier*/ -										  /* is undefined. Solaris and HPUX 10 does zero padding in this case,    */ -										  /* Digital Unix and Linux does not. */ -										  zero_padding = 0;    /* turn zero padding off for string conversions */ -										  str_arg_l = 1; -										  switch (fmt_spec) { -										  case '%': -											  str_arg = p; break; -										  case 'c': { -											  int j = va_arg(ap, int); -											  uchar_arg = (unsigned char) j;   /* standard demands unsigned char */ -											  str_arg = (const char *) &uchar_arg; -											  break; -													} -										  case 's': -											  str_arg = va_arg(ap, const char *); -											  if (!str_arg) str_arg_l = 0; -											  /* make sure not to address string beyond the specified precision !!! */ -											  else if (!precision_specified) str_arg_l = strlen(str_arg); -											  /* truncate string if necessary as requested by precision */ -											  else if (precision == 0) str_arg_l = 0; -											  else { -												  /* memchr on HP does not like n > 2^31  !!! */ -												  const char *q = (const char*) memchr(str_arg, '\0', -													  precision <= 0x7fffffff ? precision : 0x7fffffff); -												  str_arg_l = !q ? precision : (q-str_arg); -											  } -											  break; -										  default: break; -										  } -										  break; -										  case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': { -										  /* NOTE: the u, o, x, X and p conversion specifiers imply -											  the value is unsigned;  d implies a signed value */ +					p++; +				} +			} +			fmt_spec = *p; +			/* common synonyms: */ +			switch (fmt_spec) { +			case 'i': +				fmt_spec = 'd'; +				break; +			case 'D': +				fmt_spec = 'd'; +				length_modifier = 'l'; +				break; +			case 'U': +				fmt_spec = 'u'; +				length_modifier = 'l'; +				break; +			case 'O': +				fmt_spec = 'o'; +				length_modifier = 'l'; +				break; +			default: +				break; +			} +			/* get parameter value, do initial processing */ +			switch (fmt_spec) { +			case '%': /* % behaves similar to 's' regarding flags and field widths */ +			case 'c': /* c behaves similar to 's' regarding flags and field widths */ +			case 's': +				length_modifier = '\0';          /* wint_t and wchar_t not supported */ +				/* the result of zero padding flag with non-numeric conversion specifier*/ +				/* is undefined. Solaris and HPUX 10 does zero padding in this case,    */ +				/* Digital Unix and Linux does not. */ +				zero_padding = 0;    /* turn zero padding off for string conversions */ +				str_arg_l = 1; +				switch (fmt_spec) { +				case '%': +					str_arg = p; +					break; +				case 'c': { +					int j = va_arg(ap, int); +					uchar_arg = (unsigned char) j;   /* standard demands unsigned char */ +					str_arg = (const char *) & uchar_arg; +					break; +				} +				case 's': +					str_arg = va_arg(ap, const char *); +					if (!str_arg) str_arg_l = 0; +					/* make sure not to address string beyond the specified precision !!! */ +					else if (!precision_specified) str_arg_l = strlen(str_arg); +					/* truncate string if necessary as requested by precision */ +					else if (precision == 0) str_arg_l = 0; +					else { +						/* memchr on HP does not like n > 2^31  !!! */ +						const char *q = (const char*) memchr(str_arg, '\0', +						                                     precision <= 0x7fffffff ? precision : 0x7fffffff); +						str_arg_l = !q ? precision : (q - str_arg); +					} +					break; +				default: +					break; +				} +				break; +			case 'd': +			case 'u': +			case 'o': +			case 'x': +			case 'X': +			case 'p': { +				/* NOTE: the u, o, x, X and p conversion specifiers imply +				    the value is unsigned;  d implies a signed value */ -											  int arg_sign = 0; -											  /* 0 if numeric argument is zero (or if pointer is NULL for 'p'), -											  +1 if greater than zero (or nonzero for unsigned arguments), -											  -1 if negative (unsigned argument is never negative) */ +				int arg_sign = 0; +				/* 0 if numeric argument is zero (or if pointer is NULL for 'p'), +				+1 if greater than zero (or nonzero for unsigned arguments), +				-1 if negative (unsigned argument is never negative) */ -											  int int_arg = 0;  unsigned int uint_arg = 0; -											  /* only defined for length modifier h, or for no length modifiers */ +				int int_arg = 0; +				unsigned int uint_arg = 0; +				/* only defined for length modifier h, or for no length modifiers */ -											  long int long_arg = 0;  unsigned long int ulong_arg = 0; -											  /* only defined for length modifier l */ +				long int long_arg = 0; +				unsigned long int ulong_arg = 0; +				/* only defined for length modifier l */ -											  void *ptr_arg = NULL; -											  /* pointer argument value -only defined for p conversion */ +				void *ptr_arg = NULL; +				/* pointer argument value -only defined for p conversion */  #ifdef SNPRINTF_LONGLONG_SUPPORT -											  long long int long_long_arg = 0; -											  unsigned long long int ulong_long_arg = 0; -											  /* only defined for length modifier ll */ +				long long int long_long_arg = 0; +				unsigned long long int ulong_long_arg = 0; +				/* only defined for length modifier ll */  #endif -											  if (fmt_spec == 'p') { -											  /* HPUX 10: An l, h, ll or L before any other conversion character -											  *   (other than d, i, u, o, x, or X) is ignored. -											  * Digital Unix: -											  *   not specified, but seems to behave as HPUX does. -											  * Solaris: If an h, l, or L appears before any other conversion -											  *   specifier (other than d, i, u, o, x, or X), the behavior -											  *   is undefined. (Actually %hp converts only 16-bits of address -											  *   and %llp treats address as 64-bit data which is incompatible -											  *   with (void *) argument on a 32-bit system). -												  */ -												  length_modifier = '\0'; -												  ptr_arg = va_arg(ap, void *); -												  if (ptr_arg != NULL) arg_sign = 1; -											  } else if (fmt_spec == 'd') {  /* signed */ -												  switch (length_modifier) { -												  case '\0': -												  case 'h': -												  /* It is non-portable to specify a second argument of char or short -												  * to va_arg, because arguments seen by the called function -												  * are not char or short.  C converts char and short arguments -												  * to int before passing them to a function. -													  */ -													  int_arg = va_arg(ap, int); -													  if      (int_arg > 0) arg_sign =  1; -													  else if (int_arg < 0) arg_sign = -1; -													  break; -												  case 'l': -													  long_arg = va_arg(ap, long int); -													  if      (long_arg > 0) arg_sign =  1; -													  else if (long_arg < 0) arg_sign = -1; -													  break; +				if (fmt_spec == 'p') { +					/* HPUX 10: An l, h, ll or L before any other conversion character +					*   (other than d, i, u, o, x, or X) is ignored. +					* Digital Unix: +					*   not specified, but seems to behave as HPUX does. +					* Solaris: If an h, l, or L appears before any other conversion +					*   specifier (other than d, i, u, o, x, or X), the behavior +					*   is undefined. (Actually %hp converts only 16-bits of address +					*   and %llp treats address as 64-bit data which is incompatible +					*   with (void *) argument on a 32-bit system). +					    */ +					length_modifier = '\0'; +					ptr_arg = va_arg(ap, void *); +					if (ptr_arg != NULL) arg_sign = 1; +				} else if (fmt_spec == 'd') {  /* signed */ +					switch (length_modifier) { +					case '\0': +					case 'h': +						/* It is non-portable to specify a second argument of char or short +						* to va_arg, because arguments seen by the called function +						* are not char or short.  C converts char and short arguments +						* to int before passing them to a function. +						    */ +						int_arg = va_arg(ap, int); +						if (int_arg > 0) arg_sign =  1; +						else if (int_arg < 0) arg_sign = -1; +						break; +					case 'l': +						long_arg = va_arg(ap, long int); +						if (long_arg > 0) arg_sign =  1; +						else if (long_arg < 0) arg_sign = -1; +						break;  #ifdef SNPRINTF_LONGLONG_SUPPORT -												  case '2': -													  long_long_arg = va_arg(ap, long long int); -													  if      (long_long_arg > 0) arg_sign =  1; -													  else if (long_long_arg < 0) arg_sign = -1; -													  break; +					case '2': +						long_long_arg = va_arg(ap, long long int); +						if (long_long_arg > 0) arg_sign =  1; +						else if (long_long_arg < 0) arg_sign = -1; +						break;  #endif -												  } -											  } else {  /* unsigned */ -												  switch (length_modifier) { -												  case '\0': -												  case 'h': -													  uint_arg = va_arg(ap, unsigned int); -													  if (uint_arg) arg_sign = 1; -													  break; -												  case 'l': -													  ulong_arg = va_arg(ap, unsigned long int); -													  if (ulong_arg) arg_sign = 1; -													  break; +					} +				} else {  /* unsigned */ +					switch (length_modifier) { +					case '\0': +					case 'h': +						uint_arg = va_arg(ap, unsigned int); +						if (uint_arg) arg_sign = 1; +						break; +					case 'l': +						ulong_arg = va_arg(ap, unsigned long int); +						if (ulong_arg) arg_sign = 1; +						break;  #ifdef SNPRINTF_LONGLONG_SUPPORT -												  case '2': -													  ulong_long_arg = va_arg(ap, unsigned long long int); -													  if (ulong_long_arg) arg_sign = 1; -													  break; +					case '2': +						ulong_long_arg = va_arg(ap, unsigned long long int); +						if (ulong_long_arg) arg_sign = 1; +						break;  #endif -												  } -											  } -											  str_arg = tmp; str_arg_l = 0; -											  /* NOTE: -											  *   For d, i, u, o, x, and X conversions, if precision is specified, -											  *   the '0' flag should be ignored. This is so with Solaris 2.6, -											  *   Digital UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl. -											  */ -											  if (precision_specified) zero_padding = 0; -											  if (fmt_spec == 'd') { -												  if (force_sign && arg_sign >= 0) -													  tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; -													  /* leave negative numbers for sprintf to handle, -												  to avoid handling tricky cases like (short int)(-32768) */ -											  } else if (alternate_form) { -												  if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X') ) -												  { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = fmt_spec; } -												  /* alternate form should have no effect for p conversion, but ... */ -											  } -											  zero_padding_insertion_ind = str_arg_l; -											  if (!precision_specified) precision = 1;   /* default precision is 1 */ -											  if (precision == 0 && arg_sign == 0 -												  ) { -												  /* converted to null string */ -												  /* When zero value is formatted with an explicit precision 0, -												  the resulting formatted string is empty (d, i, u, o, x, X, p).   */ -											  } else { -												  char f[5]; int f_l = 0; -												  f[f_l++] = '%';    /* construct a simple format string for sprintf */ -												  if (!length_modifier) { } -												  else if (length_modifier=='2') { f[f_l++] = 'l'; f[f_l++] = 'l'; } -												  else f[f_l++] = length_modifier; -												  f[f_l++] = fmt_spec; f[f_l++] = '\0'; -												  if (fmt_spec == 'p') str_arg_l += sprintf(tmp+str_arg_l, f, ptr_arg); -												  else if (fmt_spec == 'd') {  /* signed */ -													  switch (length_modifier) { -													  case '\0': -													  case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, int_arg);  break; -													  case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, long_arg); break; +					} +				} +				str_arg = tmp; +				str_arg_l = 0; +				/* NOTE: +				*   For d, i, u, o, x, and X conversions, if precision is specified, +				*   the '0' flag should be ignored. This is so with Solaris 2.6, +				*   Digital UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl. +				*/ +				if (precision_specified) zero_padding = 0; +				if (fmt_spec == 'd') { +					if (force_sign && arg_sign >= 0) +						tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; +					/* leave negative numbers for sprintf to handle, +					to avoid handling tricky cases like (short int)(-32768) */ +				} else if (alternate_form) { +					if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X')) +						{ tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = fmt_spec; } +					/* alternate form should have no effect for p conversion, but ... */ +				} +				zero_padding_insertion_ind = str_arg_l; +				if (!precision_specified) precision = 1;   /* default precision is 1 */ +				if (precision == 0 && arg_sign == 0 +				   ) { +					/* converted to null string */ +					/* When zero value is formatted with an explicit precision 0, +					the resulting formatted string is empty (d, i, u, o, x, X, p).   */ +				} else { +					char f[5]; +					int f_l = 0; +					f[f_l++] = '%';    /* construct a simple format string for sprintf */ +					if (!length_modifier) { } else if (length_modifier == '2') { f[f_l++] = 'l'; f[f_l++] = 'l'; } else f[f_l++] = length_modifier; +					f[f_l++] = fmt_spec; +					f[f_l++] = '\0'; +					if (fmt_spec == 'p') str_arg_l += sprintf(tmp + str_arg_l, f, ptr_arg); +					else if (fmt_spec == 'd') {  /* signed */ +						switch (length_modifier) { +						case '\0': +						case 'h': +							str_arg_l += sprintf(tmp + str_arg_l, f, int_arg); +							break; +						case 'l': +							str_arg_l += sprintf(tmp + str_arg_l, f, long_arg); +							break;  #ifdef SNPRINTF_LONGLONG_SUPPORT -													  case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,long_long_arg); break; +						case '2': +							str_arg_l += sprintf(tmp + str_arg_l, f, long_long_arg); +							break;  #endif -													  } -												  } else {  /* unsigned */ -													  switch (length_modifier) { -													  case '\0': -													  case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, uint_arg);  break; -													  case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, ulong_arg); break; +						} +					} else {  /* unsigned */ +						switch (length_modifier) { +						case '\0': +						case 'h': +							str_arg_l += sprintf(tmp + str_arg_l, f, uint_arg); +							break; +						case 'l': +							str_arg_l += sprintf(tmp + str_arg_l, f, ulong_arg); +							break;  #ifdef SNPRINTF_LONGLONG_SUPPORT -													  case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,ulong_long_arg);break; +						case '2': +							str_arg_l += sprintf(tmp + str_arg_l, f, ulong_long_arg); +							break;  #endif -													  } -												  } -												  /* include the optional minus sign and possible "0x" -												  in the region before the zero padding insertion point */ -												  if (zero_padding_insertion_ind < str_arg_l && -													  tmp[zero_padding_insertion_ind] == '-') { -													  zero_padding_insertion_ind++; -												  } -												  if (zero_padding_insertion_ind+1 < str_arg_l && -													  tmp[zero_padding_insertion_ind]   == '0' && -													  (tmp[zero_padding_insertion_ind+1] == 'x' || -													  tmp[zero_padding_insertion_ind+1] == 'X') ) { -													  zero_padding_insertion_ind += 2; -												  } -											  } -											  { size_t num_of_digits = str_arg_l - zero_padding_insertion_ind; -											  if (alternate_form && fmt_spec == 'o' -												  /* unless zero is already the first character */ -												  && !(zero_padding_insertion_ind < str_arg_l -												  && tmp[zero_padding_insertion_ind] == '0') -												  ) {        /* assure leading zero for alternate-form octal numbers */ -												  if (!precision_specified || precision < num_of_digits+1) { -												  /* precision is increased to force the first character to be zero, -												  except if a zero value is formatted with an explicit precision -													  of zero */ -													  precision = num_of_digits+1; precision_specified = 1; -												  } -											  } -											  /* zero padding to specified precision? */ -											  if (num_of_digits < precision) -												  number_of_zeros_to_pad = precision - num_of_digits; -											  } -											  /* zero padding to specified minimal field width? */ -											  if (!justify_left && zero_padding) { -												  int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); -												  if (n > 0) number_of_zeros_to_pad += n; -											  } -											  break; -      } -      default: /* unrecognized conversion specifier, keep format string as-is*/ -		  zero_padding = 0;  /* turn zero padding off for non-numeric convers. */ -		  justify_left = 1; min_field_width = 0;                /* reset flags */ -																/* discard the unrecognized conversion, just keep * -		  * the unrecognized conversion character          */ -		  str_arg = p; str_arg_l = 0; -		  if (*p) str_arg_l++;  /* include invalid conversion specifier unchanged +						} +					} +					/* include the optional minus sign and possible "0x" +					in the region before the zero padding insertion point */ +					if (zero_padding_insertion_ind < str_arg_l && +					        tmp[zero_padding_insertion_ind] == '-') { +						zero_padding_insertion_ind++; +					} +					if (zero_padding_insertion_ind + 1 < str_arg_l && +					        tmp[zero_padding_insertion_ind]   == '0' && +					        (tmp[zero_padding_insertion_ind+1] == 'x' || +					         tmp[zero_padding_insertion_ind+1] == 'X')) { +						zero_padding_insertion_ind += 2; +					} +				} +				{ +					size_t num_of_digits = str_arg_l - zero_padding_insertion_ind; +					if (alternate_form && fmt_spec == 'o' +					        /* unless zero is already the first character */ +					        && !(zero_padding_insertion_ind < str_arg_l +					             && tmp[zero_padding_insertion_ind] == '0') +					   ) {        /* assure leading zero for alternate-form octal numbers */ +						if (!precision_specified || precision < num_of_digits + 1) { +							/* precision is increased to force the first character to be zero, +							except if a zero value is formatted with an explicit precision +							    of zero */ +							precision = num_of_digits + 1; +							precision_specified = 1; +						} +					} +					/* zero padding to specified precision? */ +					if (num_of_digits < precision) +						number_of_zeros_to_pad = precision - num_of_digits; +				} +				/* zero padding to specified minimal field width? */ +				if (!justify_left && zero_padding) { +					int n = min_field_width - (str_arg_l + number_of_zeros_to_pad); +					if (n > 0) number_of_zeros_to_pad += n; +				} +				break; +			} +			default: /* unrecognized conversion specifier, keep format string as-is*/ +				zero_padding = 0;  /* turn zero padding off for non-numeric convers. */ +				justify_left = 1; +				min_field_width = 0;                /* reset flags */ +				/* discard the unrecognized conversion, just keep * +				* the unrecognized conversion character          */ +				str_arg = p; +				str_arg_l = 0; +				if (*p) str_arg_l++;  /* include invalid conversion specifier unchanged  		  if not at end-of-string */ -		  break; -      } -      if (*p) p++;      /* step over the just processed conversion specifier */ -						/* insert padding to the left as requested by min_field_width; -      this does not include the zero padding in case of numerical conversions*/ -      if (!justify_left) {                /* left padding with blank or zero */ -		  int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); -		  if (n > 0) { -			  if (str_l < str_m) { -				  size_t avail = str_m-str_l; -				  fast_memset(str+str_l, (zero_padding?'0':' '), (n>avail?avail:n)); -			  } -			  str_l += n; -		  } -      } -	  /* zero padding as requested by the precision or by the minimal field width -	  * for numeric conversions required? */ -      if (number_of_zeros_to_pad <= 0) { -	  /* will not copy first part of numeric right now, * -		  * force it to be copied later in its entirety    */ -		  zero_padding_insertion_ind = 0; -      } else { -		  /* insert first part of numerics (sign or '0x') before zero padding */ -		  int n = zero_padding_insertion_ind; -		  if (n > 0) { -			  if (str_l < str_m) { -				  size_t avail = str_m-str_l; -				  fast_memcpy(str+str_l, str_arg, (n>avail?avail:n)); -			  } -			  str_l += n; -		  } -		  /* insert zero padding as requested by the precision or min field width */ -		  n = number_of_zeros_to_pad; -		  if (n > 0) { -			  if (str_l < str_m) { -				  size_t avail = str_m-str_l; -				  fast_memset(str+str_l, '0', (n>avail?avail:n)); -			  } -			  str_l += n; -		  } -      } -	  /* insert formatted string -	  * (or as-is conversion specifier for unknown conversions) */ -      { int n = str_arg_l - zero_padding_insertion_ind; -	  if (n > 0) { -          if (str_l < str_m) { -			  size_t avail = str_m-str_l; -			  fast_memcpy(str+str_l, str_arg+zero_padding_insertion_ind, -				  (n>avail?avail:n)); -          } -          str_l += n; -	  } -      } -	  /* insert right padding */ -      if (justify_left) {          /* right blank padding to the field width */ -		  int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); -		  if (n > 0) { -			  if (str_l < str_m) { -				  size_t avail = str_m-str_l; -				  fast_memset(str+str_l, ' ', (n>avail?avail:n)); -			  } -			  str_l += n; -		  } -      } -    } -  } -  if (str_m > 0) { /* make sure the string is null-terminated +				break; +			} +			if (*p) p++;      /* step over the just processed conversion specifier */ +			/* insert padding to the left as requested by min_field_width; +			this does not include the zero padding in case of numerical conversions*/ +			if (!justify_left) {                /* left padding with blank or zero */ +				int n = min_field_width - (str_arg_l + number_of_zeros_to_pad); +				if (n > 0) { +					if (str_l < str_m) { +						size_t avail = str_m - str_l; +						fast_memset(str + str_l, (zero_padding ? '0' : ' '), (n > avail ? avail : n)); +					} +					str_l += n; +				} +			} +			/* zero padding as requested by the precision or by the minimal field width +			* for numeric conversions required? */ +			if (number_of_zeros_to_pad <= 0) { +				/* will not copy first part of numeric right now, * +				    * force it to be copied later in its entirety    */ +				zero_padding_insertion_ind = 0; +			} else { +				/* insert first part of numerics (sign or '0x') before zero padding */ +				int n = zero_padding_insertion_ind; +				if (n > 0) { +					if (str_l < str_m) { +						size_t avail = str_m - str_l; +						fast_memcpy(str + str_l, str_arg, (n > avail ? avail : n)); +					} +					str_l += n; +				} +				/* insert zero padding as requested by the precision or min field width */ +				n = number_of_zeros_to_pad; +				if (n > 0) { +					if (str_l < str_m) { +						size_t avail = str_m - str_l; +						fast_memset(str + str_l, '0', (n > avail ? avail : n)); +					} +					str_l += n; +				} +			} +			/* insert formatted string +			* (or as-is conversion specifier for unknown conversions) */ +			{ +				int n = str_arg_l - zero_padding_insertion_ind; +				if (n > 0) { +					if (str_l < str_m) { +						size_t avail = str_m - str_l; +						fast_memcpy(str + str_l, str_arg + zero_padding_insertion_ind, +						            (n > avail ? avail : n)); +					} +					str_l += n; +				} +			} +			/* insert right padding */ +			if (justify_left) {          /* right blank padding to the field width */ +				int n = min_field_width - (str_arg_l + number_of_zeros_to_pad); +				if (n > 0) { +					if (str_l < str_m) { +						size_t avail = str_m - str_l; +						fast_memset(str + str_l, ' ', (n > avail ? avail : n)); +					} +					str_l += n; +				} +			} +		} +	} +	if (str_m > 0) { /* make sure the string is null-terminated  				   even at the expense of overwriting the last character  	  (shouldn't happen, but just in case) */ -	  str[str_l <= str_m-1 ? str_l : str_m-1] = '\0'; -  } -  /* Return the number of characters formatted (excluding trailing null -  * character), that is, the number of characters that would have been -  * written to the buffer if it were large enough. -  * -  * The value of str_l should be returned, but str_l is of unsigned type -  * size_t, and snprintf is int, possibly leading to an undetected -  * integer overflow, resulting in a negative return value, which is illegal. -  * Both XSH5 and ISO C99 (at least the draft) are silent on this issue. -  * Should errno be set to EOVERFLOW and EOF returned in this case??? -  */ -  return (int) str_l; +		str[str_l <= str_m-1 ? str_l : str_m-1] = '\0'; +	} +	/* Return the number of characters formatted (excluding trailing null +	 * character), that is, the number of characters that would have been +	 * written to the buffer if it were large enough. +	 * +	 * The value of str_l should be returned, but str_l is of unsigned type +	 * size_t, and snprintf is int, possibly leading to an undetected +	 * integer overflow, resulting in a negative return value, which is illegal. +	 * Both XSH5 and ISO C99 (at least the draft) are silent on this issue. +	 * Should errno be set to EOVERFLOW and EOF returned in this case??? +	 */ +	return (int) str_l;  }  int symbian_snprintf(char *text, size_t maxlen, const char *fmt, ...) {  | 
