@@ -882,6 +882,8 @@ struct iovec
882882#define WTERMSIG (status ) ((status) & 0x7F)
883883#define WIFSIGNALED (status ) (WTERMSIG(status) != 0)
884884#define WIFEXITED (status ) (WTERMSIG(status) == 0)
885+ #define EXIT_SUCCESS 0
886+ #define EXIT_FAILURE 1
885887
886888typedef size_t socklen_t ;
887889#define AF_UNSPEC 0
@@ -2481,6 +2483,11 @@ static int isxdigit(int c)
24812483 (c >= '0' && c <= '9' );
24822484}
24832485
2486+ static int isodigit (int c )
2487+ {
2488+ return (c >= '0' && c <= '7' );
2489+ }
2490+
24842491static int toupper (int c )
24852492{
24862493 if (c >= 'a' && c <= 'z' )
@@ -3731,18 +3738,19 @@ static long ftell(FILE *stream)
37313738/* PRINTF */
37323739/****************************************************************************/
37333740
3734- #define PRINTF_FLAG_NEG 0x0001
3735- #define PRINTF_FLAG_UPPER 0x0002
3736- #define PRINTF_FLAG_HEX 0x0004
3737- #define PRINTF_FLAG_PLUS 0x0008
3738- #define PRINTF_FLAG_HASH 0x0010
3739- #define PRINTF_FLAG_SPACE 0x0020
3740- #define PRINTF_FLAG_RIGHT 0x0040
3741- #define PRINTF_FLAG_ZERO 0x0080
3742- #define PRINTF_FLAG_PRECISION 0x0100
3743- #define PRINTF_FLAG_8 0x0200
3744- #define PRINTF_FLAG_16 0x0400
3745- #define PRINTF_FLAG_64 0x0800
3741+ #define PRINTF_FLAG_NEG 0x0001
3742+ #define PRINTF_FLAG_UPPER 0x0002
3743+ #define PRINTF_FLAG_OCTAL 0x0004
3744+ #define PRINTF_FLAG_HEX 0x0008
3745+ #define PRINTF_FLAG_PLUS 0x0010
3746+ #define PRINTF_FLAG_HASH 0x0020
3747+ #define PRINTF_FLAG_SPACE 0x0040
3748+ #define PRINTF_FLAG_RIGHT 0x0080
3749+ #define PRINTF_FLAG_ZERO 0x0100
3750+ #define PRINTF_FLAG_PRECISION 0x0200
3751+ #define PRINTF_FLAG_8 0x0400
3752+ #define PRINTF_FLAG_16 0x0800
3753+ #define PRINTF_FLAG_64 0x1000
37463754
37473755static __attribute__((__noinline__ )) size_t printf_put_char (char * str ,
37483756 size_t size , size_t idx , char c )
@@ -3760,22 +3768,25 @@ static __attribute__((__noinline__)) size_t printf_put_num(char *str,
37603768 char prefix [2 ] = {'\0' , '\0' };
37613769 char buf [32 ];
37623770 size_t i = 0 ;
3763- if (flags & PRINTF_FLAG_HEX )
3771+ bool seen = false;
3772+ if (flags & (PRINTF_FLAG_HEX | PRINTF_FLAG_OCTAL ))
37643773 {
37653774 if (flags & PRINTF_FLAG_HASH )
37663775 {
37673776 prefix [0 ] = '0' ;
3768- prefix [1 ] = (flags & PRINTF_FLAG_UPPER ? 'X' : 'x' );
3777+ if (flags & PRINTF_FLAG_HEX )
3778+ prefix [1 ] = (flags & PRINTF_FLAG_UPPER ? 'X' : 'x' );
37693779 }
37703780 const char digs [] = "0123456789abcdef" ;
37713781 const char DIGS [] = "0123456789ABCDEF" ;
37723782 const char * ds = (flags & PRINTF_FLAG_UPPER ? DIGS : digs );
3773- int shift = (15 * 4 );
3774- bool seen = false;
3783+ int shift = (flags & PRINTF_FLAG_HEX ? 60 : 63 ),
3784+ dec = (flags & PRINTF_FLAG_HEX ? 4 : 3 ),
3785+ mask = (flags & PRINTF_FLAG_HEX ? 0xF : 0x7 );
37753786 while (shift >= 0 )
37763787 {
3777- char c = ds [(x >> shift ) & 0xF ];
3778- shift -= 4 ;
3788+ char c = ds [(x >> shift ) & mask ];
3789+ shift -= dec ;
37793790 if (!seen && c == '0' )
37803791 continue ;
37813792 seen = true;
@@ -3793,7 +3804,6 @@ static __attribute__((__noinline__)) size_t printf_put_num(char *str,
37933804 else if (flags & PRINTF_FLAG_SPACE )
37943805 prefix [0 ] = ' ' ;
37953806 unsigned long long r = 10000000000000000000ull ;
3796- bool seen = false;
37973807 while (r != 0 )
37983808 {
37993809 char c = '0' + x / r ;
@@ -3980,13 +3990,16 @@ static int vsnprintf(char *str, size_t size, const char *format, va_list ap)
39803990 idx = printf_put_num (str , size , idx , flags , width ,
39813991 precision , (uint64_t )x );
39823992 break ;
3993+ case 'o' :
3994+ flags |= PRINTF_FLAG_OCTAL ;
3995+ goto uint ;
39833996 case 'X' :
39843997 flags |= PRINTF_FLAG_UPPER ;
39853998 // Fallthrough
39863999 case 'x' :
39874000 flags |= PRINTF_FLAG_HEX ;
39884001 // Fallthrough
3989- case 'u' :
4002+ case 'u' : uint :
39904003 if (flags & PRINTF_FLAG_8 )
39914004 y = (uint64_t )(uint8_t )va_arg (ap , unsigned );
39924005 else if (flags & PRINTF_FLAG_16 )
@@ -4122,11 +4135,12 @@ static int printf_unlocked(const char *format, ...)
41224135
41234136#define SCANF_FLAG_NEG 0x0001
41244137#define SCANF_FLAG_DEC 0x0002
4125- #define SCANF_FLAG_HEX 0x0004
4126- #define SCANF_FLAG_8 0x0008
4127- #define SCANF_FLAG_16 0x0010
4128- #define SCANF_FLAG_64 0x0020
4129- #define SCANF_FLAG_SIGNED 0x0040
4138+ #define SCANF_FLAG_OCT 0x0004
4139+ #define SCANF_FLAG_HEX 0x0008
4140+ #define SCANF_FLAG_8 0x0010
4141+ #define SCANF_FLAG_16 0x0020
4142+ #define SCANF_FLAG_64 0x0040
4143+ #define SCANF_FLAG_SIGNED 0x0080
41304144
41314145struct scanf_stream_s
41324146{
@@ -4209,6 +4223,30 @@ static __attribute__((__noinline__)) bool scanf_get_dec(
42094223 return true;
42104224}
42114225
4226+ static __attribute__((__noinline__ )) bool scanf_get_oct (
4227+ struct scanf_stream_s * in , size_t * width , uint64_t * p , bool * r )
4228+ {
4229+ char c = scanf_get_char_n (in , width );
4230+ if (!isodigit (c ))
4231+ {
4232+ scanf_unget_char_n (c , in , width );
4233+ return false;
4234+ }
4235+ uint64_t i = 0 ;
4236+ do
4237+ {
4238+ i *= 8 ;
4239+ uint64_t d = (c - '0' );
4240+ if (UINT64_MAX - i < d )
4241+ * r = true;
4242+ i = (UINT64_MAX - i < d ? UINT64_MAX : i + d );
4243+ }
4244+ while (isodigit (c = scanf_get_char_n (in , width )));
4245+ scanf_unget_char_n (c , in , width );
4246+ * p = i ;
4247+ return true;
4248+ }
4249+
42124250static __attribute__((__noinline__ )) bool scanf_get_hex (
42134251 struct scanf_stream_s * in , size_t * width , uint64_t * p , bool * r )
42144252{
@@ -4251,24 +4289,22 @@ static __attribute__((__noinline__)) bool scanf_get_num(
42514289 c = scanf_get_char_n (in , & width );
42524290 uint64_t i = 0 ;
42534291 bool overflow = false;
4254- if (c == '0' && (flags & SCANF_FLAG_HEX ))
4292+ if (c == '0' && (flags & ( SCANF_FLAG_OCT | SCANF_FLAG_HEX ) ))
42554293 {
42564294 c = scanf_get_char_n (in , & width );
4257- if (c == 'x' || c == 'X' )
4295+ if (( flags & SCANF_FLAG_HEX ) && ( c == 'x' || c == 'X' ) )
42584296 {
42594297 if (!scanf_get_hex (in , & width , & i , & overflow ))
42604298 return false;
42614299 }
4262- else if (flags & SCANF_FLAG_DEC )
4300+ else if (flags & SCANF_FLAG_OCT )
42634301 {
4264- c = scanf_get_char_n (in , & width );
4265- if (!isdigit (c ))
4266- i = 0 ;
4267- else if (!scanf_get_dec (in , & width , & i , & overflow ))
4302+ scanf_unget_char_n (c , in , & width );
4303+ if (!scanf_get_oct (in , & width , & i , & overflow ))
42684304 return false;
42694305 }
42704306 else
4271- return false ;
4307+ scanf_unget_char_n ( c , in , & width ) ;
42724308 }
42734309 else if (flags & SCANF_FLAG_DEC )
42744310 {
@@ -4410,7 +4446,8 @@ static int scanf_impl(struct scanf_stream_s *in, const char *format, va_list ap)
44104446 while (isspace (c = scanf_get_char_n (in , & width )))
44114447 ;
44124448 * ptr8 ++ = c ;
4413- while ((c = scanf_get_char_n (in , & width )) != EOF && !isspace (c ))
4449+ while ((c = scanf_get_char_n (in , & width )) != EOF &&
4450+ !isspace (c ))
44144451 * ptr8 ++ = c ;
44154452 scanf_unget_char_n (c , in , & width );
44164453 * ptr8 ++ = '\0' ;
@@ -4425,13 +4462,19 @@ static int scanf_impl(struct scanf_stream_s *in, const char *format, va_list ap)
44254462 if (!scanf_get_num (in , width , flags , ptr ))
44264463 return num ;
44274464 break ;
4465+ case 'o' :
4466+ flags |= SCANF_FLAG_OCT ;
4467+ if (!scanf_get_num (in , width , flags , ptr ))
4468+ return num ;
4469+ break ;
44284470 case 'x' : case 'X' :
44294471 flags |= SCANF_FLAG_HEX ;
44304472 if (!scanf_get_num (in , width , flags , ptr ))
44314473 return num ;
44324474 break ;
44334475 case 'i' :
4434- flags |= SCANF_FLAG_DEC | SCANF_FLAG_HEX | SCANF_FLAG_SIGNED ;
4476+ flags |= SCANF_FLAG_DEC | SCANF_FLAG_OCT | SCANF_FLAG_HEX |
4477+ SCANF_FLAG_SIGNED ;
44354478 if (!scanf_get_num (in , width , flags , ptr ))
44364479 return num ;
44374480 break ;
0 commit comments