Hello Rob, List,
An implementation of __printf__ is attached.
Would love to have your inputs on the same.
__PATCH__:
An issue in ifconfig while verifying the HW Address, which is assumed
to be of the format __C2:79:38:95:CD:AB__ but can be of form
__C2:79:38:95:D:A__. In this case the HW address is reported as bad.
if (*hw_addr == ':') hw_addr++;
sscanf(hw_addr, %2x%n, val, len);
-if (len != 2) break;
+if (!len || len 2) break; // 1 nibble can be set e.g.
C2:79:38:95:D:A
hw_addr += len;
*p++ = val;
patch for same is attached.
regards,
Ashwini
PS: A reminder again!! about the commands lost in mailing list.
__getty__ and __modprobe__ implementations are still hanging around in
there.
/* printf.c - Format and Print the data.
*
* Copyright 2014 Sandeep Sharma sandeep.jack2...@gmail.com
* Copyright 2014 Kyungwan Han asura...@gmail.com
*
* See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html
USE_PRINTF(NEWTOY(printf, 1, TOYFLAG_USR|TOYFLAG_BIN))
config PRINTF
bool printf
default n
help
usage: printf Format [Arguments..]
Format and print ARGUMENT(s) according to FORMAT.
Format is 'C' control output as 'C' printf.
*/
#define FOR_printf
#include toys.h
GLOBALS(
char *hv_w;
char *hv_p;
int encountered;
)
// Calculate width and precision from format string
static int get_w_p()
{
char *ptr, *str = *toys.optargs;
errno = 0;
if (*str == '-') str++;
long value = strtol(str, ptr, 10);
if (errno || (ptr (*ptr != '\0' || ptr == str)))
perror_msg(Invalid num %s, *toys.optargs);
if (*--str == '-') return (int)(-1 * value);
return value;
}
// Add ll and L to Interger and floating point formats respectively.
static char *get_format(char *f)
{
int len = strlen(f);
char last = f[--len], *post = ;
f[len] = '\0';
if (strchr(diouxX, last)) post = ll; // add ll to integer modifier.
else if (strchr(feEgG, last)) post = L; // add L to float modifier.
return xmprintf(%s%s%c, f, post, last);
}
// Print arguments with corresponding conversion and width and precision.
static void print(char *fmt, int w, int p, int l)
{
char *ptr = (fmt+l-1), *ep = NULL, *format = NULL;
long long val;
long double dval;
errno = 0;
switch (*ptr) {
case 'd': /*FALL_THROUGH*/
case 'i': /*FALL_THROUGH*/
case 'o': /*FALL_THROUGH*/
case 'u': /*FALL_THROUGH*/
case 'x': /*FALL_THROUGH*/
case 'X':
if (!*toys.optargs) val = 0;
else {
if (**toys.optargs == '\'' || **toys.optargs == '')
val = *((*toys.optargs) + 1);
else {
val = strtoll(*toys.optargs, ep, 0);
if (errno || (ep (*ep != '\0' || ep == *toys.optargs))) {
perror_msg(Invalid num %s, *toys.optargs);
val = 0;
}
}
}
format = get_format(fmt);
TT.hv_w ? (TT.hv_p ? printf(format, w, p, val) : printf(format, w, val))
: (TT.hv_p ? printf(format, p, val) : printf(format, val));
break;
case 'g': /*FALL_THROUGH*/
case 'e': /*FALL_THROUGH*/
case 'E': /*FALL_THROUGH*/
case 'G': /*FALL_THROUGH*/
case 'f':
if (*toys.optargs) {
dval = strtold(*toys.optargs, ep);
if (errno || (ep (*ep != '\0' || ep == *toys.optargs))) {
perror_msg(Invalid num %s, *toys.optargs);
dval = 0;
}
} else dval = 0;
format = get_format(fmt);
TT.hv_w ? (TT.hv_p ? printf(format, w, p, dval):printf(format, w, dval))
: (TT.hv_p ? printf(format, p, dval) : printf(format, dval));
break;
case 's':
{
char *str = (*toys.optargs ? *toys.optargs : );
TT.hv_w ? (TT.hv_p ? printf(fmt,w,p,str): printf(fmt, w, str))
: (TT.hv_p ? printf(fmt, p, str) : printf(fmt, str));
}
break;
case 'c':
printf(fmt, (*toys.optargs ? **toys.optargs : '\0'));
break;
}
if (format) free(format);
}
// Handle the escape sequences.
static int handle_slash(char **esc_val)
{
char *ptr = *esc_val;
int esc_length = 0;
unsigned base = 0, num = 0, result = 0, count = 0;
/*
* Hex escape sequence have only 1 or 2 digits, xHH. Oct escape sequence
* have 1,2 or 3 digits, xHHH. Leading 0 (\0HHH) we are ignoring.
*/
if (*ptr == 'x') {
ptr++;
esc_length++;
base = 16;
} else if (isdigit(*ptr)) base = 8;
while (esc_length 3 base) {
num = tolower(*ptr) - '0';
if (num 10) num += ('0' - 'a' + 10);
if (num = base) {
if (base == 16) {
esc_length--;
if (!esc_length) {// Invalid hex value eg. /xvd, print as it is /xvd
result = '\\';
ptr--;
}
}
break;
}
esc_length++;
count = result = (count * base) + num;
ptr++;
}
if (base) {
ptr--;
*esc_val = ptr;
return (char)result;
} else {
switch (*ptr) {
case 'n': result = '\n'; break;
case 't': result =