EmbDev.net

Forum: ARM programming with GCC/GNU tools modified rprintf, please comment


von outer_space (Guest)


Rate this post
useful
not useful
This might be a little off topic.  I took rprintf.c and rprintf.h from
mthomas' latest demo and modified them to prntf.c and prntf.h.  There
are 2 parts, a prntf macro and a sprntf function.  Is it correct to
include a temporary string in the macro or should I define this
somewhere else?  I would have made prntf a function if I knew how to
pass the ... on to the sprntf function, can this be done?  In the .c
part, the 'i' case of the switch statement has parse errors unless the
curley braces encapsulate the entire case.  In my C book it shows cases
all without curley braces, what should I do about these curley braces?
Any comments or suggestions appreciated.  Below is the .h file and below
that is the .c file.

#ifndef PRNTF_H_
#define PRNTF_H_

#include <string.h> //for strlen()

#define SPRNTF_LENGTH 50

void sprntf(char* dest,char const *format, ...);

#define prntf(format, ...) char temp [SPRNTF_LENGTH];\
  sprntf(temp, format, ## _VA_ARGS_);\
  AT91F_US_SendFrame((AT91S_USART*)AT91C_BASE_DBGU,\
  temp, strlen(temp), 0,0);
//only this sendstring function should be changed for use in other
platforms

#endif /*PRNTF_H_*/


/* compact formatting code based on rprintf by martin thomas
 * Changes made by outer_space:
 * -Renamed functions with prnt instead of print to note abbreviated
nature
 * -Changed from putchar function to dma putstring function
 * -DMA serial specific to sam7s
 * -Reduced size and functionality
 * -Added %f
 * -All output via prntf, change only the header for different platforms
 */

#include "prntf.h"
#include <stdarg.h>

void sprntf(char* dest,char const *format, ...)
{
  char format_flag;
  char *ptr;
  char hold [32];
  double fval;
  long int digit, ival;
  va_list ap;
  va_start(ap, format);

  for (;;){
    while ((format_flag = *(format++)) != '%')
    {
      if (!format_flag)
      {
        va_end(ap);
        *dest = 0; //
        return;
      }
      *dest++ = format_flag;
    }
    format_flag = *format++;
    switch (format_flag)
    {
      case 'c':
        format_flag = va_arg(ap,int);
        *dest = format_flag;
        dest++;
        break;

      case 'i': {
        ival = va_arg(ap,int);
        if(ival<0)
        {
          ival = -ival;
          *dest++ = '-';
        }
        ptr = hold;
        for(digit = 10000; digit >0; digit/=10)
        {
          *ptr++ = ival / digit + '0';
          ival %= digit;
        }
        *ptr = 0; //mark end of string
        ptr = hold; //set pointer back to beginning
        while(*ptr == '0'){ptr++;}
        if(!*ptr){*--ptr = '0';} //if number is zero, must have 1 
leading
'0'
        while( (*dest++ = *ptr++) ); //strcopy into dest
        dest--; //negate \0
        break;  //*/
      }
      case 's':
        ptr = va_arg(ap,char *);
        while( (*dest++ = *ptr++) ); //strcopy
        dest--; //negate \0
        break;
///*
      case 'f':
        ptr=hold;
        fval = va_arg(ap,double);

        ival = fval*100000;
        for(digit = 1000000000; digit > 0; digit /= 10)
        {
          if(digit == 10000){*ptr++ = '.';} //decimal point here
          *ptr++ = ival / digit + '0';
          ival %= digit;
        }
        while(*--ptr == '0'); //erase trailing zeros
        if(*ptr == '.'){ptr--;} //erase decimal if nothing is after it
        *++ptr = 0; //mark end of string
        ptr = hold; //set pointer back to beginning
        while(*ptr == '0'){ptr++;} //strip leading zeros
        if(*ptr == '.'){*--ptr = '0';} //if nothing to left of '.' must 
put
'0'
        while( (*dest++ = *ptr++) ); //strcopy into dest
        dest--; //negate \0, added before return
        break;
      default:
        *dest++ = '%';
        *dest++ = format_flag;
        break;
    }
  }
}

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.