Skip to content

Commit 57fbd34

Browse files
author
H. Peter Anvin
committed
preproc: implement %str() and %strcat() functions
Add function equivalents of the %defstr and %strcat directives. Signed-off-by: H. Peter Anvin <[email protected]>
1 parent a5d0284 commit 57fbd34

File tree

1 file changed

+57
-30
lines changed

1 file changed

+57
-30
lines changed

asm/preproc.c

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3567,6 +3567,47 @@ static void assign_smacro(const char *mname, bool casesense,
35673567
}
35683568
}
35693569

3570+
/*
3571+
* Implement string concatenation as used by the %strcat directive
3572+
* and function.
3573+
*/
3574+
static Token *pp_strcat(Token *tline, const char *dname)
3575+
{
3576+
3577+
size_t len;
3578+
Token *t;
3579+
char *q, *qbuf;
3580+
3581+
len = 0;
3582+
list_for_each(t, tline) {
3583+
switch (t->type) {
3584+
case TOKEN_WHITESPACE:
3585+
case TOKEN_COMMA:
3586+
break;
3587+
case TOKEN_STR:
3588+
unquote_token(t);
3589+
len += t->len;
3590+
break;
3591+
default:
3592+
nasm_nonfatal("non-string passed to `%s': %s", dname,
3593+
tok_text(t));
3594+
free_tlist(tline);
3595+
return NULL;
3596+
}
3597+
}
3598+
3599+
q = qbuf = nasm_malloc(len+1);
3600+
list_for_each(t, tline) {
3601+
if (t->type == TOKEN_INTERNAL_STR)
3602+
q = mempcpy(q, tok_text(t), t->len);
3603+
}
3604+
*q = '\0';
3605+
3606+
return make_tok_qstr_len(NULL, qbuf, len);
3607+
nasm_free(qbuf);
3608+
return t;
3609+
}
3610+
35703611
/**
35713612
* find and process preprocessor directive in passed line
35723613
* Find out if a line contains a preprocessor directive, and deal
@@ -3588,7 +3629,7 @@ static int do_directive(Token *tline, Token **output)
35883629
bool casesense;
35893630
int offset;
35903631
const char *p;
3591-
char *q, *qbuf;
3632+
char *q;
35923633
const char *found_path;
35933634
const char *mname;
35943635
struct ppscan pps;
@@ -3601,7 +3642,6 @@ static int do_directive(Token *tline, Token **output)
36013642
struct tokenval tokval;
36023643
expr *evalresult;
36033644
int64_t count;
3604-
size_t len;
36053645
errflags severity;
36063646
const char *dname; /* Name of directive, for messages */
36073647

@@ -4717,38 +4757,12 @@ static int do_directive(Token *tline, Token **output)
47174757
tline = expand_smacro(tline->next);
47184758
last->next = NULL;
47194759

4720-
len = 0;
4721-
list_for_each(t, tline) {
4722-
switch (t->type) {
4723-
case TOKEN_WHITESPACE:
4724-
case TOKEN_COMMA:
4725-
break;
4726-
case TOKEN_STR:
4727-
unquote_token(t);
4728-
len += t->len;
4729-
break;
4730-
default:
4731-
nasm_nonfatal("non-string passed to `%s': %s", dname,
4732-
tok_text(t));
4733-
free_tlist(tline);
4734-
goto done;
4735-
}
4736-
}
4737-
4738-
q = qbuf = nasm_malloc(len+1);
4739-
list_for_each(t, tline) {
4740-
if (t->type == TOKEN_INTERNAL_STR)
4741-
q = mempcpy(q, tok_text(t), t->len);
4742-
}
4743-
*q = '\0';
4744-
4760+
macro_start = pp_strcat(tline, dname);
47454761
/*
47464762
* We now have a macro name, an implicit parameter count of
4747-
* zero, and a numeric token to use as an expansion. Create
4763+
* zero, and a string token to use as an expansion. Create
47484764
* and store an SMacro.
47494765
*/
4750-
macro_start = make_tok_qstr_len(NULL, qbuf, len);
4751-
nasm_free(qbuf);
47524766
define_smacro(mname, casesense, macro_start, NULL);
47534767
free_tlist(tline);
47544768
break;
@@ -6838,6 +6852,9 @@ stdmac_is(const SMacro *s, Token **params, int nparams)
68386852
/*
68396853
* Join all expanded macro arguments with commas, e.g. %eval().
68406854
* Remember that this needs to output the tokens in reverse order.
6855+
*
6856+
* This can also be used when only single argument is already ready
6857+
* to be emitted, e.g. %str().
68416858
*/
68426859
static Token *
68436860
stdmac_join(const SMacro *s, Token **params, int nparams)
@@ -6865,6 +6882,14 @@ stdmac_join(const SMacro *s, Token **params, int nparams)
68656882
return tline;
68666883
}
68676884

6885+
/* %strcat() function */
6886+
static Token *
6887+
stdmac_strcat(const SMacro *s, Token **params, int nparams)
6888+
{
6889+
nasm_assert(nparams == 1);
6890+
return pp_strcat(expand_smacro_noreset(params[0]), s->name);
6891+
}
6892+
68686893
/* Add magic standard macros */
68696894
struct magic_macros {
68706895
const char *name;
@@ -6881,6 +6906,8 @@ static void pp_add_magic_stdmac(void)
68816906
{ "__?BITS?__", true, 0, 0, stdmac_bits },
68826907
{ "__?PTR?__", true, 0, 0, stdmac_ptr },
68836908
{ "%eval", false, 1, SPARM_EVAL|SPARM_VARADIC, stdmac_join },
6909+
{ "%str", false, 1, SPARM_GREEDY|SPARM_STR, stdmac_join },
6910+
{ "%strcat", false, 1, SPARM_GREEDY, stdmac_strcat },
68846911
{ NULL, false, 0, 0, NULL }
68856912
};
68866913
const struct magic_macros *m;

0 commit comments

Comments
 (0)