Macros, PROGMEM and such.

Code:

#define MAKE_STR(x) _MAKE_STR(x)
#define _MAKE_STR(x) #x
const uint8_t PROGMEM buff[] = {MAKE_STR(hello)};

const uint8_t PROGMEM test1[] = {"test text"};
const uint8_t PROGMEM test2[] = {"Sketch uses 1508 bytes (4%) of program storage space."};

#define prtmem(x)   for(volatile uint16_t i = 0; i < sizeof(x); i++)\
                    {Serial.print((char)pgm_read_byte(x + i));}

void setup()
{
    Serial.begin(38400);
    prtmem(test1);
    Serial.println("");
    prtmem(test2);
    Serial.println("");
    prtmem(buff);
    Serial.println("");
}

void loop() 
{
    
}

Explanation:
The first three lines expand to

const uint8_t PROGMEM text_test[] = {"hello"};

The functions in setup result in,

test text
Sketch uses 1508 bytes (4%) of program storage space.
hello

being printed.

What I'm failing to do is to convert

const uint8_t PROGMEM buff[] = {MAKE_STR(hello)};

into a macro such that

#define new_macro(x) const uint8_t PROGMEM buff[] = {MAKE_STR(x)}; (or equivalent)

results in the same expansion as the first three lines.

Ultimately, this new_macro would then be joined with the prtmem macro so that prtmem(x) will print the string stored in PROGMEM. And please don't suggest using the F() macro as this is intended to replace it, using only GCC compiler functions. The issue involves stringifying the x parameter from prtmem(x) through all the subsequent macro calls.

Are you trying to create a cruder version of this?

http://arduiniana.org/libraries/flash/

No. That bit's easy. The tough part is in doing the macros. The whole point of the exercise is to have it embedded in the code as external libraries are not permitted. The concept of monolithic code is to remove dependencies on third party libraries and use only what gets distributed with the compiler. Also, C only, no C++ templates, etc.

So, what actual problem does this solve?

Solving another pre-processor mystery. For more, have a look here.

PSTR() ?

IIRC, the only thing wrong with it is that PSTR(“FOO”) is the same type as “FOO”, so you can’t overload a function to handle both ram strings and flash string...

I've tried playing with PSTR but must confess that I haven't as yet got working syntax. I bailed and asked for help. Still working on it. When I get the solution I will post.

Don't you have extra braces in there? I don't know whether that's a problem.
I don't think that you'll be able to have a single macro that can used with both string literals (like PROGMEM) AND variable initializations (like F() or PSTR()) That's true in the C++/Arduino world as well.

This sketch produces:

  test text
  Sketch uses 1508 bytes (4%) of program storage space.
  hello
  HELPME
#define MAKE_STR(x) _MAKE_STR(x)
#define _MAKE_STR(x) #x
const uint8_t PROGMEM buff[] = MAKE_STR(hello);
#define new_macro(var, x) const uint8_t PROGMEM var[] = MAKE_STR(x);

const uint8_t PROGMEM test1[] = "test text";
const uint8_t PROGMEM test2[] = "Sketch uses 1508 bytes (4%) of program storage space.";

#define prtmem(x)   for(volatile uint16_t i = 0; i < sizeof(x); i++)\
  {Serial.print((char)pgm_read_byte(x + i));}

new_macro(foo, HELPME);

void setup()
{
  Serial.begin(38400);
  prtmem(test1);
  Serial.println("");
  prtmem(test2);
  Serial.println("");
  prtmem(buff);
  Serial.println("");
  prtmem(foo);
  Serial.println("");
}

foo, test1, test2, and buf, are all in flash.
That sort-of looks like what you asked for, but It's not a replacement for F(), which you also asked for...

Thanks for that. It may be as close as I get. It's not so much a replacement for F() as it is an abstraction of the PROGMEM write/read process. Having a few unused pre-processor directives hanging around, if needed, as opposed to referring to the library manual for syntax when you do want it. Cheers. K+.