@@ -3567,6 +3567,47 @@ static void assign_smacro(const char *mname, bool casesense,
3567
3567
}
3568
3568
}
3569
3569
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
+
3570
3611
/**
3571
3612
* find and process preprocessor directive in passed line
3572
3613
* Find out if a line contains a preprocessor directive, and deal
@@ -3588,7 +3629,7 @@ static int do_directive(Token *tline, Token **output)
3588
3629
bool casesense ;
3589
3630
int offset ;
3590
3631
const char * p ;
3591
- char * q , * qbuf ;
3632
+ char * q ;
3592
3633
const char * found_path ;
3593
3634
const char * mname ;
3594
3635
struct ppscan pps ;
@@ -3601,7 +3642,6 @@ static int do_directive(Token *tline, Token **output)
3601
3642
struct tokenval tokval ;
3602
3643
expr * evalresult ;
3603
3644
int64_t count ;
3604
- size_t len ;
3605
3645
errflags severity ;
3606
3646
const char * dname ; /* Name of directive, for messages */
3607
3647
@@ -4717,38 +4757,12 @@ static int do_directive(Token *tline, Token **output)
4717
4757
tline = expand_smacro (tline -> next );
4718
4758
last -> next = NULL ;
4719
4759
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 );
4745
4761
/*
4746
4762
* 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
4748
4764
* and store an SMacro.
4749
4765
*/
4750
- macro_start = make_tok_qstr_len (NULL , qbuf , len );
4751
- nasm_free (qbuf );
4752
4766
define_smacro (mname , casesense , macro_start , NULL );
4753
4767
free_tlist (tline );
4754
4768
break ;
@@ -6838,6 +6852,9 @@ stdmac_is(const SMacro *s, Token **params, int nparams)
6838
6852
/*
6839
6853
* Join all expanded macro arguments with commas, e.g. %eval().
6840
6854
* 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().
6841
6858
*/
6842
6859
static Token *
6843
6860
stdmac_join (const SMacro * s , Token * * params , int nparams )
@@ -6865,6 +6882,14 @@ stdmac_join(const SMacro *s, Token **params, int nparams)
6865
6882
return tline ;
6866
6883
}
6867
6884
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
+
6868
6893
/* Add magic standard macros */
6869
6894
struct magic_macros {
6870
6895
const char * name ;
@@ -6881,6 +6906,8 @@ static void pp_add_magic_stdmac(void)
6881
6906
{ "__?BITS?__" , true, 0 , 0 , stdmac_bits },
6882
6907
{ "__?PTR?__" , true, 0 , 0 , stdmac_ptr },
6883
6908
{ "%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 },
6884
6911
{ NULL , false, 0 , 0 , NULL }
6885
6912
};
6886
6913
const struct magic_macros * m ;
0 commit comments