Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consider this printf implementation with stdio fopencookie function #4713

Closed
JAndrassy opened this issue May 8, 2018 · 4 comments
Closed

Comments

@JAndrassy
Copy link
Contributor

ssize_t adapterWrite(void* p, const char *buf, size_t n) {
  return ((Print*) p) -> write(buf, n);
}

FILE* openAdapter(void *p) {
  cookie_io_functions_t fncs; 
  fncs.write = adapterWrite; 
  fncs.close = NULL; 
  return fopencookie(p, "w", fncs); 
}

size_t Print::printf(const char *fmt, ...) {
  va_list args;
  va_start(args, fmt);
  FILE* adapter = openAdapter(this);
  size_t len = vfprintf(adapter, fmt, args);
  fclose(adapter);
  va_end(args);
  return len;
}

size_t Print::printf(const __FlashStringHelper *fmt, ...) {
  size_t fmtLen = strlen_P((PGM_P) fmt);
  char format[fmtLen + 1];
  strcpy_P(format, (PGM_P) fmt);
  va_list args;
  va_start(args, fmt);
  FILE* adapter = openAdapter(this);
  size_t len = vfprintf(adapter, format, args);
  fclose(adapter);
  va_end(args);
  return len;
}
@earlephilhower
Copy link
Collaborator

The suggested code snippet doesn't have any explanation or context. Nothing to do here. If you have a need for this, I suggest making a PR with an example or some explanation. Closing as an issue.

@devyte
Copy link
Collaborator

devyte commented Jan 17, 2019

@JAndrassy I also don't understand the intent here. If you provide a more detailed explanation and examples we can discus it.

@JAndrassy
Copy link
Contributor Author

JAndrassy commented Jan 17, 2019

current implementation of printf in Print in esp8266 core calls vsnprintf twice and uses dynamic allocation of buffer, if the resulting string doesn't fit into 64 bytes. I would guess that a lot of printf uses have the result larger then 64 characters.

the proposed implementation writes to output the result of formatting directly with write(byte).

I use this implementation in StreamLib , a library for all architectures. This printf implementation works for xtensa and for ARM. For AVR the implementation with the same concept is slightly different. I use the StreamLib in my project with many different printfs. The project ran months on esp8266. Now it is on M0.

In AVR core this way of implementation of printf was proposed but not merged yet.

@u48
Copy link

u48 commented Feb 9, 2019

Hi.

The solution is correct, it will work fine.

I have already added a completely similar way of printf() in arduino STM32.
Works on STM32, ESP8266, DUE, Raspbery.

In my profile there is a fork Arduino Stm32. In the branch for Stm32F1 there is already a ready source print.с

Bonus, for Arduino Uno, too, there is a similar solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants