Пример #1
0
static void print_direc(char *start, size_t length, int field_width, int precision,
		const char *argument)
{
	char *p;		/* Null-terminated copy of % directive. */

	p = xmalloc((unsigned) (length + 1));
	strncpy(p, start, length);
	p[length] = 0;

	switch (p[length - 1]) {
	case 'd':
	case 'i':
		if (field_width < 0) {
			if (precision < 0)
				printf(p, my_xstrtol(argument));
			else
				printf(p, precision, my_xstrtol(argument));
		} else {
			if (precision < 0)
				printf(p, field_width, my_xstrtol(argument));
			else
				printf(p, field_width, precision, my_xstrtol(argument));
		}
		break;
	case 'o':
	case 'u':
	case 'x':
	case 'X':
		if (field_width < 0) {
			if (precision < 0)
				printf(p, my_xstrtoul(argument));
			else
				printf(p, precision, my_xstrtoul(argument));
		} else {
			if (precision < 0)
				printf(p, field_width, my_xstrtoul(argument));
			else
				printf(p, field_width, precision, my_xstrtoul(argument));
		}
		break;
	case 'f':
	case 'e':
	case 'E':
	case 'g':
	case 'G':
		if (field_width < 0) {
			if (precision < 0)
				printf(p, my_xstrtod(argument));
			else
				printf(p, precision, my_xstrtod(argument));
		} else {
			if (precision < 0)
				printf(p, field_width, my_xstrtod(argument));
			else
				printf(p, field_width, precision, my_xstrtod(argument));
		}
		break;
	case 'c':
		printf(p, *argument);
		break;
	case 's':
		if (field_width < 0) {
			if (precision < 0)
				printf(p, argument);
			else
				printf(p, precision, argument);
		} else {
			if (precision < 0)
				printf(p, field_width, argument);
			else
				printf(p, field_width, precision, argument);
		}
		break;
	}

	free(p);
}
Пример #2
0
static int print_formatted(char *format, int argc, char **argv)
{
	int save_argc = argc;   /* Preserve original value.  */
	char *f;                /* Pointer into 'format'.  */
	char *direc_start;      /* Start of % directive.  */
	size_t direc_length;    /* Length of % directive.  */
	int field_width;        /* Arg to first '*', or -1 if none.  */
	int precision;          /* Arg to second '*', or -1 if none.  */

	for (f = format; *f; ++f) {
		switch (*f) {
		case '%':
			direc_start = f++;
			direc_length = 1;
			field_width = precision = -1;
			if (*f == '%') {
				bb_putchar('%');
				break;
			}
			if (*f == 'b') {
				if (argc > 0) {
					print_esc_string(*argv);
					++argv;
					--argc;
				}
				break;
			}
			if (strchr("-+ #", *f)) {
				++f;
				++direc_length;
			}
			if (*f == '*') {
				++f;
				++direc_length;
				if (argc > 0) {
					field_width = my_xstrtoul(*argv);
					++argv;
					--argc;
				} else
					field_width = 0;
			} else {
				while (isdigit(*f)) {
					++f;
					++direc_length;
				}
			}
			if (*f == '.') {
				++f;
				++direc_length;
				if (*f == '*') {
					++f;
					++direc_length;
					if (argc > 0) {
						precision = my_xstrtoul(*argv);
						++argv;
						--argc;
					} else
						precision = 0;
				} else
					while (isdigit(*f)) {
						++f;
						++direc_length;
					}
			}
			if (*f == 'l' || *f == 'L' || *f == 'h') {
				++f;
				++direc_length;
			}
			/*
			if (!strchr ("diouxXfeEgGcs", *f))
			fprintf(stderr, "%%%c: invalid directive", *f);
			*/
			++direc_length;
			if (argc > 0) {
				print_direc(direc_start, direc_length, field_width,
							precision, *argv);
				++argv;
				--argc;
			} else
				print_direc(direc_start, direc_length, field_width,
							precision, "");
			break;
		case '\\':
			if (*++f == 'c')
				exit(0);
			bb_putchar(bb_process_escape_sequence((const char **)&f));
			f--;
			break;
		default:
			bb_putchar(*f);
		}
	}

	return save_argc - argc;
}
Пример #3
0
static void print_direc(char *format, unsigned fmt_length,
		int field_width, int precision,
		const char *argument)
{
	long lv;
	double dv;
	char saved;
	char *have_prec, *have_width;

	have_prec = strstr(format, ".*");
	have_width = strchr(format, '*');
	if (have_width - 1 == have_prec)
		have_width = NULL;

	saved = format[fmt_length];
	format[fmt_length] = '\0';

	switch (format[fmt_length - 1]) {
	case 'c':
		printf(format, *argument);
		break;
	case 'd':
	case 'i':
		lv = my_xstrtol(argument);
 print_long:
		/* if (errno) return; - see comment at the top */
		if (!have_width) {
			if (!have_prec)
				printf(format, lv);
			else
				printf(format, precision, lv);
		} else {
			if (!have_prec)
				printf(format, field_width, lv);
			else
				printf(format, field_width, precision, lv);
		}
		break;
	case 'o':
	case 'u':
	case 'x':
	case 'X':
		lv = my_xstrtoul(argument);
		/* cheat: unsigned long and long have same width, so... */
		goto print_long;
	case 's':
		/* Are char* and long the same? (true for most arches) */
		if (sizeof(argument) == sizeof(lv)) {
			lv = (long)(ptrdiff_t)argument;
			goto print_long;
		} else { /* Hope compiler will optimize it out */
			if (!have_width) {
				if (!have_prec)
					printf(format, argument);
				else
					printf(format, precision, argument);
			} else {
				if (!have_prec)
					printf(format, field_width, argument);
				else
					printf(format, field_width, precision, argument);
			}
			break;
		}
	case 'f':
	case 'e':
	case 'E':
	case 'g':
	case 'G':
		dv = my_xstrtod(argument);
		/* if (errno) return; */
		if (!have_width) {
			if (!have_prec)
				printf(format, dv);
			else
				printf(format, precision, dv);
		} else {
			if (!have_prec)
				printf(format, field_width, dv);
			else
				printf(format, field_width, precision, dv);
		}
		break;
	} /* switch */

	format[fmt_length] = saved;
}