@@ -7143,6 +7143,80 @@ stdmac_count(const SMacro *s, Token **params, int nparams)
7143
7143
return make_tok_num (NULL , nparams );
7144
7144
}
7145
7145
7146
+ /* %num() */
7147
+ static Token *
7148
+ stdmac_num (const SMacro * s , Token * * params , int nparams )
7149
+ {
7150
+ static const char num_digits [] =
7151
+ "0123456789"
7152
+ "abcdefghijklmnopqrstuvwxyz"
7153
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
7154
+ "@_" ; /* Compatible with bash */
7155
+ int64_t parm [3 ];
7156
+ uint64_t n ;
7157
+ int64_t dparm , bparm ;
7158
+ int i , nd ;
7159
+ unsigned int base ;
7160
+ char numstr [256 ];
7161
+ char * const endstr = numstr + sizeof numstr - 1 ;
7162
+ const int maxlen = sizeof numstr - 3 ;
7163
+ const int maxbase = sizeof num_digits - 1 ;
7164
+ char * p ;
7165
+ bool moredigits ;
7166
+
7167
+ if (nparams < 1 || nparams > (int )ARRAY_SIZE (parm )) {
7168
+ nasm_nonfatal ("invalid number of parameters to %s()" , s -> name );
7169
+ return NULL ;
7170
+ }
7171
+
7172
+ parm [1 ] = 10 ; /* Default base */
7173
+ parm [2 ] = -1 ; /* Default digits */
7174
+
7175
+ for (i = 0 ; i < nparams ; i ++ ) {
7176
+ bool err ;
7177
+ parm [i ] = get_tok_num (params [i ], & err );
7178
+ if (err )
7179
+ return NULL ;
7180
+ }
7181
+
7182
+ n = parm [0 ];
7183
+ bparm = parm [1 ];
7184
+ dparm = parm [2 ];
7185
+
7186
+ if (bparm < 2 || bparm > maxbase ) {
7187
+ nasm_nonfatal ("invalid base %" PRId64 " given to %s()" ,
7188
+ bparm , s -> name );
7189
+ return NULL ;
7190
+ }
7191
+
7192
+ base = bparm ;
7193
+
7194
+ if (dparm < - maxlen || dparm > maxlen ) {
7195
+ nasm_nonfatal ("digit count %" PRId64 " specified to %s() too large" ,
7196
+ dparm , s -> name );
7197
+ moredigits = true;
7198
+ nd = 1 ;
7199
+ } else if (dparm <= 0 ) {
7200
+ moredigits = true;
7201
+ nd = - dparm ;
7202
+ } else {
7203
+ moredigits = false;
7204
+ nd = dparm ;
7205
+ }
7206
+
7207
+ p = endstr ;
7208
+ * p = '\0' ;
7209
+ * -- p = '\'' ;
7210
+
7211
+ while (nd -- > 0 || (moredigits && n )) {
7212
+ * -- p = num_digits [n % base ];
7213
+ n /= base ;
7214
+ }
7215
+ * -- p = '\'' ;
7216
+
7217
+ return new_Token (NULL , TOKEN_STR , p , endstr - p );
7218
+ }
7219
+
7146
7220
/* Add magic standard macros */
7147
7221
struct magic_macros {
7148
7222
const char * name ;
@@ -7151,6 +7225,13 @@ struct magic_macros {
7151
7225
enum sparmflags flags ;
7152
7226
ExpandSMacro func ;
7153
7227
};
7228
+
7229
+ struct num_macros {
7230
+ const char name [6 ];
7231
+ uint8_t base ;
7232
+ char prefix ;
7233
+ };
7234
+
7154
7235
static void pp_add_magic_stdmac (void )
7155
7236
{
7156
7237
static const struct magic_macros magic_macros [] = {
@@ -7160,6 +7241,7 @@ static void pp_add_magic_stdmac(void)
7160
7241
{ "__?PTR?__" , true, 0 , 0 , stdmac_ptr },
7161
7242
{ "%count" , false, 1 , SPARM_VARADIC , stdmac_count },
7162
7243
{ "%eval" , false, 1 , SPARM_EVAL |SPARM_VARADIC , stdmac_join },
7244
+ { "%num" , false, 1 , SPARM_EVAL |SPARM_VARADIC , stdmac_num },
7163
7245
{ "%str" , false, 1 , SPARM_GREEDY |SPARM_STR , stdmac_join },
7164
7246
{ "%strcat" , false, 1 , SPARM_GREEDY , stdmac_strcat },
7165
7247
{ "%strlen" , false, 1 , 0 , stdmac_strlen },
0 commit comments