// Rowley C Compiler, runtime support.
//
// Copyright (c) 2001, 2002 Rowley Associates Limited.
//
// This file may be distributed under the terms of the License Agreement
// provided with this software.
//
// THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

#ifndef __vfprintf_H
#define __vfprintf_H

#if defined(__CROSSWORKS) || defined(__CROSSWORKS_ARM)
#include "__argtype.h"
#else
#include "../../lib/hosted__argtype.h"
#endif

#ifndef __MEMSPACE
#define __MEMSPACE
#endif

#ifndef __CODE
#define __CODE
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct __printf_tag
{
  size_t charcount;
  size_t maxchars;
  char *string;
  int (*output_fn)(int, struct __printf_tag *ctx);
} __printf_t;

typedef struct
{
  char is_string;
} __scanf_t;

typedef struct
{
  char is_string;
  char *string;
}  __string_scanf_t;

typedef struct
{
  char is_string;
  int (*getc_fn)(void);
  int (*ungetc_fn)(int);
} __stream_scanf_t;

int __putc_to_string(int c, __printf_t *ctx);

// Printer formatting flags.
#define FORMAT_LONG                 (1<<0)
#define FORMAT_LONG_LONG            (1<<1)
#define FORMAT_SHORT                (1<<2)
#define FORMAT_CHAR                 (1<<3)
#define FORMAT_LEFT_JUSTIFY         (1<<4)
#define FORMAT_SIGNED               (1<<5)
#define FORMAT_SPACE                (1<<6)
#define FORMAT_ALTERNATIVE          (1<<7)
#define FORMAT_HAVE_PRECISION       (1<<8)
#define FORMAT_ZERO_FILL            (1<<9)
#define FORMAT_FLOAT_E              (1<<10)
#define FORMAT_FLOAT_F              (1<<11)
#define FORMAT_FLOAT_A              (1<<12)
#define FORMAT_CAPITALS             (1<<13)
#define FORMAT_INPUT_SIGNED         (1<<14)
#define FORMAT_TICK                 (1<<15)   // POSIX.1 extension

// Combinations of flags used internally...
#define FORMAT_NEGATIVE             (FORMAT_SIGNED | FORMAT_SPACE)
#define FORMAT_FLOAT_G              (FORMAT_FLOAT_E | FORMAT_FLOAT_F)

// Helper variables.
extern __CODE const char __hex_uc[16];
extern __CODE const char __hex_lc[16];

// Standard formatting routine.
#ifdef __VFxxxxx_C 
int __vfprintf_c(__printf_t *p, __MEMSPACE const char *fmt, ARGTYPE args);
int __vfscanf_c(__scanf_t *p, __MEMSPACE const unsigned char *fmt, ARGTYPE argv);
#else
int __vfprintf(__printf_t *p, __MEMSPACE const char *fmt, ARGTYPE args);
int __vfscanf(__scanf_t *p, __MEMSPACE const unsigned char *fmt, ARGTYPE argv);
#endif

extern void (*__format_extender)(char ch, __printf_t *ctx, int flags, int width, int precision, ARGTYPE *args);

void __print_padding(int ch, int n, __printf_t *ctx);
void __pre_padding(int flags, int width, __printf_t *ctx);
void __putc(__printf_t *ctx, char ch);

#ifdef __cplusplus
}
#endif

#endif