Newsgroup: it.comp.lang.c
Titolo: preprocessore

io vorrei scrivere una (serie di) macro per cpp in modo da espandere
   MyCol(3)
in
   "honeydew3"
compresi i doppi apici, che senza doppi apici
   #define COLORE() honeydew
   #define MyCol(N) COLORE()N
funziona sufficientemente bene
grazie per la vostra attenzione,
                                                        gb
-- 
BOMBED BY SALESMEN. WEB PAGES. SINKING. U-188.

                                                         gb
mi ero dimenticato di dire che cpp e' quello di gcc, e viene invocato
con l'opzione --traditional
-- 
ANNOYED BY DESTROYER. LEAVE BOAT. U-112.

 gb
#define MyCol(N)  "honeydew"#N
ciao,
g.

Giovanni Resta <g.r...@iit.cnr.it.nospam> writes:

grazie Giovanni, la cosa di #N non la sapevo, ma ho ancora qualche
problema, anche perche' vorrei usare lo switch "--traditional" in
quanto senza mi metteva spazi bianchi dove non volevo (preprocesso dei
file di configurazione, oh yeah)
ecco i tre tentativi che ho fatto, nessuno dei quali da "honeydew3"
############################ 1: con --traditional mi lascia "#"
boffi95/../boffi Mon Apr 26 15:00:43: cpp --traditional
#define MyCol(N)  "honeydew"#N
MyCol(4)
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "<stdin>"
"honeydew"#4
############################ 2: senza --traditional mi mette troppe
############################    virgolette...
boffi95/../boffi Mon Apr 26 15:04:36: cpp              
#define MyCol(N)  "honeydew"#N
MyCol(4)
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "<stdin>"
"honeydew""4"
############################ 3: se metto #N tra virgolette non lo
############################    espande
boffi95/../boffi Mon Apr 26 15:04:48: cpp
#define MyCol(N)  "honeydew#N"
MyCol(4)
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "<stdin>"
"honeydew#N"
boffi95/../boffi Mon Apr 26 15:06:58: 
-- 
ATTACKED BY SALESMEN. DEPTH CHARGES. SINKING. U-838.

 "honeydew""4"
Questa per il compilatore C dovrebbe essere equivalente a "honeydew4".
Cioe' per il compilatore C delle costanti stringa consecutive sono
equivalenti alla loro concatenzazione.
Prova ad esempio a scrivere
printf("<%s>\n", "Ciao" ", pippo " "!");
ciao,
g.

Giovanni Resta <g.r...@iit.cnr.it.nospam> writes:

forse non l'ho detto prima, io preprocesso dei files di
configurazione, mica compilo dei files...
e nel, e.g., .twmrc alla fine deve andarci
    MenuTitleBackground   "honeydew4"
e non
    MenuTitleBackground   "honeydew" "
altrimenti twm si incazza...
-- 
SALESMEN. ANNOYED. SINKING. U-297.

 [snip]
Hai bisogno di una serie di macro e di *non* usare -traditional ;)
La macro suggerita  da Giovanni *funziona* _se_, pero`,  non utilizzi la
flag -traditional quando  invochi il preprocessore (con  quella flag cpp
ignora il token # perche` "e` ANSI").
L'unico intoppo, nel *tuo* caso (e  non in generale) di quella macro e`,
se immaginiamo di definirla cosi`:
#define wrong(x) "honeydew"#x
e di chiamarla con:
wrong(51)
che verrebbe espansa in:
"honeydew""51"
che non e` esattamente quello che ti serve.
Ti  occorre  necessariamente una  serie  di  macro  in quanto,  oltre  a
concatenare due stringhe (utilizzando il token ##), devi anche inserirle
tra doppi  apici (attraverso  il token  #) e, una  volta che  i suddetti
tokens vengono  espansi una  volta, se  ricomparissero in  una scansione
successiva, non sarebbero interpretati come direttiva  del prepocessore.
Capisci bene che se il contenuto della macro e` una costante non si pone
nessun problema, ma  se il contenuto e` un'altra macro  (che contiene un
token speciale) invece  di problemi ce ne sono. Quello che  devi fare e`
un prescan  degli argomenti. Una possibile risoluzione  del tuo problema
potrebbe essere (nomi a parte):
#define Create(x) honeydew ## x
#define UseLess(x) #x
#define Stringify(x) UseLess(x)
#define MyCol(x) Stringify(Create(x))
Quando vorrai usarla ti basta chiamare:
MyCol(51)
ed otterrai:
"honeydew51"
(che, se ho capito bene, e`  proprio quello che ti serve). Se non usassi
la UseLess (che tanto inutile poi  non e`) per eseguire il prescan degli
argomenti, ad esempio definendo le cose cosi`:
#define Create(x) honeydew ## x
#define Stringify(x) #x
#define MyCol(x) Stringify(Create(x))
il tutto verrebbe espanso in:
"Create(51)"
in virtu` di quello detto  prima. Sempre in virtu` di quello specificato
prima, e` ovvio che:
#define COLOR 33
MyCol(COLOR)
_funziona_  (COLOR  e`  una  costante  e non  una  macro)  ;)  Solo  per
curiosita`: che  spazi indesiderati ti aggiunge  cpp se non usi  la flag
-traditional?
Ciao.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 funziona sufficientemente bene
Soluzione veloce:
#define STR_1(x) #x
#define STR_2(x) STR_1(x)
#define CAT(x, y) x ## y
#define MYCOL(n) STR_2(CAT(honeydew, n))
Se invece vuoi che "honeydew" venga preso da una macro separata devi
aggiungere un livello ulteriore di valutazione:
#define STR_1(x) #x
#define STR_2(x) STR_1(x)
#define CAT(x, y) x ## y
#define FOO(x, y) CAT(x, y)
#define COLORE honeydew
#define MYCOL(n) STR_2(FOO(COLORE, n))
L'operatore ## e` definito nel C99, quindi devi avere un gcc abbastanza
recente (o meglio: non preistorico).
HTH,
Luca
-- 
Home: 
http://kronoz.cjb.net
Porc i' mond che cio' sott i piedi!
V. Catozzo

 flag -traditional?
nel caso specifico, cuttando da un diff -u
-    "xterm"    ("gray20":"honeydew1")  f.exec  "aterm &"
+    "xterm" ( "gray20" : "honeydew1" ) f.exec "aterm &"
che comunque twm sembra digerire...
il problema a monte e' un problema di ignoranza... dovendo far
concatenare dei simboli al preprocessore (sempre nel contesto di files
di configurazione), avevo sottocchio degli esempi in .Xdefaults che
usavano --traditional e tok1/**/tok2, e di contro non riuscivo
(ignorando ##) a fare la stessa cosa senza --traditional
ora conosco ##, # e le tecniche per convincere cpp ad espandere delle
macro annidate, e di questo ringrazio te, Luca e Giovanni (non e' che
tu te ti chiami Marco o Matteo?)
ancora, grazie a tutti
                                                                gb
-- 
TINY GNATS. ANNOYED. SINKING. U-451.

 Luca
ha helpato si, ha helpato!
grazie Luca
-- 
ATOMIC BOMB. TORPEDOED. LEAVE BOAT. U-273.

 tu te ti chiami Marco o Matteo?)
LOL! :)
