title: va_start va_end with fatfs f_printf
body: <p>i'm trying to implement a function, which will write to an sdcard. it should be called just like printf with the additional optional arguments:</p>
  
  <pre><code>    void writeDataToFiles(int anything,
          const TCHAR* fmt, ...){
               ....
              va_list args;
              va_start(args, fmt);
              f_printf(file, fmt, args); //this doesnt work
              vPrintf(fmt, args); //this works
              va_end(args);
              f_sync(file);
  ...
  }
  </code></pre>
  
  <p>i try to call it like this</p>
  
  <pre><code>int m=5
  writeDataToFiles(0,"my int value %i\n", m);
  </code></pre>
  
  <p>vPrintf will work, but f_printf is saving the String just with a "i" instead of replacing it with the actual value</p>
  
  <p>this is the f_printf implementation</p>
  
  <pre><code>    /*-----------------------------------------------------------------------*/
  /* Put a formatted string to the file                                    */
  /*-----------------------------------------------------------------------*/
  int f_printf(FIL* fil, /* Pointer to the file object */
  const TCHAR* str, /* Pointer to the format string */
  ... /* Optional arguments... */
  ) {
      va_list arp;
      BYTE f, r;
      UINT i, j, w;
      ULONG v;
      TCHAR c, d, s[16], *p;
      int res, cc;
  
      va_start(arp, str);
  
      for (cc = res = 0; cc != EOF; res += cc) {
          c = *str++;
          if (c == 0)
              break; /* End of string */
          if (c != '%') { /* Non escape character */
              cc = f_putc(c, fil);
              if (cc != EOF)
                  cc = 1;
              continue;
          }
          w = f = 0;
          c = *str++;
          if (c == '0') { /* Flag: '0' padding */
              f = 1;
              c = *str++;
          } else {
              if (c == '-') { /* Flag: left justified */
                  f = 2;
                  c = *str++;
              }
          }
          while (IsDigit(c)) { /* Precision */
              w = w * 10 + c - '0';
              c = *str++;
          }
          if (c == 'l' || c == 'L') { /* Prefix: Size is long int */
              f |= 4;
              c = *str++;
          }
          if (!c)
              break;
          d = c;
          if (IsLower(d))
              d -= 0x20;
          switch (d) { /* Type is... */
              case 'S': /* String */
                  p = va_arg(arp, TCHAR*);
                  for (j = 0; p[j]; j++)
                      ;
                  res = 0;
                  while (!(f &amp; 2) &amp;&amp; j++ &lt; w)
                      res += (cc = f_putc(' ', fil));
                  res += (cc = f_puts(p, fil));
                  while (j++ &lt; w)
                      res += (cc = f_putc(' ', fil));
                  if (cc != EOF)
                      cc = res;
                  continue;
              case 'C': /* Character */
                  cc = f_putc((TCHAR) va_arg(arp, int), fil);
                  continue;
              case 'B': /* Binary */
                  r = 2;
                  break;
              case 'O': /* Octal */
                  r = 8;
                  break;
              case 'D': /* Signed decimal */
              case 'U': /* Unsigned decimal */
                  r = 10;
                  break;
              case 'X': /* Hexdecimal */
                  r = 16;
                  break;
              default: /* Unknown type (passthrough) */
                  cc = f_putc(c, fil);
                  continue;
          }
  
          /* Get an argument and put it in numeral */
          v = (f &amp; 4) ? va_arg(arp, long) : ((d == 'D') ? (long) va_arg(arp, int)
                  : va_arg(arp, unsigned int));
          if (d == 'D' &amp;&amp; (v &amp; 0x80000000)) {
              v = 0 - v;
              f |= 8;
          }
          i = 0;
          do {
              d = (TCHAR) (v % r);
              v /= r;
              if (d &gt; 9)
                  d += (c == 'x') ? 0x27 : 0x07;
              s[i++] = d + '0';
          } while (v &amp;&amp; i &lt; sizeof(s) / sizeof(s[0]));
          if (f &amp; 8)
              s[i++] = '-';
          j = i;
          d = (f &amp; 1) ? '0' : ' ';
          res = 0;
          while (!(f &amp; 2) &amp;&amp; j++ &lt; w)
              res += (cc = f_putc(d, fil));
          do
              res += (cc = f_putc(s[--i], fil));
          while (i);
          while (j++ &lt; w)
              res += (cc = f_putc(' ', fil));
          if (cc != EOF)
              cc = res;
      }
  
      va_end(arp);
      return (cc == EOF) ? cc : res;
  }
  </code></pre>
  
  <p>edit:
  i tried to use the va_list as a Parameter for the f_print method, but it still doesnt work:</p>
  
  <pre><code>int f_printf(FIL* fil, /* Pointer to the file object */
  const TCHAR* str, /* Pointer to the format string */
  va_list arp /* Optional arguments... */
  ) {
      BYTE f, r;
      UINT i, j, w;
      ULONG v;
      TCHAR c, d, s[16], *p;
      int res, cc;
      for (cc = res = 0; cc != EOF; res += cc) {
          c = *str++;
          if (c == 0)
              break; /* End of string */
          if (c != '%') { /* Non escape character */
              cc = f_putc(c, fil);
              if (cc != EOF)
                  cc = 1;
              continue;
          }
          w = f = 0;
          c = *str++;
          if (c == '0') { /* Flag: '0' padding */
              f = 1;
              c = *str++;
          } else {
              if (c == '-') { /* Flag: left justified */
                  f = 2;
                  c = *str++;
              }
          }
          while (IsDigit(c)) { /* Precision */
              w = w * 10 + c - '0';
              c = *str++;
          }
          if (c == 'l' || c == 'L') { /* Prefix: Size is long int */
              f |= 4;
              c = *str++;
          }
          if (!c)
              break;
          d = c;
          if (IsLower(d))
              d -= 0x20;
          switch (d) { /* Type is... */
              case 'S': /* String */
                  p = va_arg(arp, TCHAR*);
                  for (j = 0; p[j]; j++)
                      ;
                  res = 0;
                  while (!(f &amp; 2) &amp;&amp; j++ &lt; w)
                      res += (cc = f_putc(' ', fil));
                  res += (cc = f_puts(p, fil));
                  while (j++ &lt; w)
                      res += (cc = f_putc(' ', fil));
                  if (cc != EOF)
                      cc = res;
                  continue;
              case 'C': /* Character */
                  cc = f_putc((TCHAR) va_arg(arp, int), fil);
                  continue;
              case 'B': /* Binary */
                  r = 2;
                  break;
              case 'O': /* Octal */
                  r = 8;
                  break;
              case 'D': /* Signed decimal */
              case 'U': /* Unsigned decimal */
                  r = 10;
                  break;
              case 'X': /* Hexdecimal */
                  r = 16;
                  break;
              default: /* Unknown type (passthrough) */
                  cc = f_putc(c, fil);
                  continue;
          }
  
          /* Get an argument and put it in numeral */
          v = (f &amp; 4) ? va_arg(arp, long) : ((d == 'D') ? (long) va_arg(arp, int)
                  : va_arg(arp, unsigned int));
          if (d == 'D' &amp;&amp; (v &amp; 0x80000000)) {
              v = 0 - v;
              f |= 8;
          }
          i = 0;
          do {
              d = (TCHAR) (v % r);
              v /= r;
              if (d &gt; 9)
                  d += (c == 'x') ? 0x27 : 0x07;
              s[i++] = d + '0';
          } while (v &amp;&amp; i &lt; sizeof(s) / sizeof(s[0]));
          if (f &amp; 8)
              s[i++] = '-';
          j = i;
          d = (f &amp; 1) ? '0' : ' ';
          res = 0;
          while (!(f &amp; 2) &amp;&amp; j++ &lt; w)
              res += (cc = f_putc(d, fil));
          do
              res += (cc = f_putc(s[--i], fil));
          while (i);
          while (j++ &lt; w)
              res += (cc = f_putc(' ', fil));
          if (cc != EOF)
              cc = res;
      }
  
      return (cc == EOF) ? cc : res;
  }
  </code></pre>