/*                                             -*- mode:C++; fill-column:100 -*-
  SFBPrintf.h - Crappy cheapo knockoff printf-like routines
  Copyright (C) 2009 The Regents of the University of New Mexico
 
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
  USA

  $Id$
 */

/**
  \file SFBPrintf.h Support for simple packet-customized printf- and scanf-like functions.
  \author David H. Ackley.  
  \date (C) 2009 All rights reserved.
  \lgpl
 */
#ifndef SFBPRINTF_H
#define SFBPRINTF_H

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

enum { LOGLEVEL_NONE, LOGLEVEL_QUIET, LOGLEVEL_NORMAL, LOGLEVEL_VERBOSE, LOGLEVEL_DEBUG };
extern void setLogLevel(int n) ;
extern int getLogLevel() ;

extern void setLogFace(u8 face) ;
extern u8 getLogFace() ;

/**
 Convenience shorthand for printing to all available physical faces.  Equivalent to
 #facePrintf(ALL_FACES, format, ...), which see for details of the possible format codes.
 */
extern void pprintf(const char * format, ...) ;

extern void facePrintf(u8 face, const char * format, ...) ;
extern void vfacePrintf(u8 face, const char * format, va_list & ap) ;

/**
 Formatted reading from a packet into individual variables.  Scanning starts at the \e current
 #packetCursor() of \a packet, \e not necessarily at the beginning, and the #packetCursor() of \a
 packet is advanced as scanning proceeds.

 \param packet The packet that is to be scanned.  

 \param format a null-terminated string controlling what is to be printed; see below.

 \param ... a variable sequence of pointer arguments of sufficient number and appropriate types
            through which to store values for all the "% codes" in \a format that require arguments.

 With the exceptions of \%s, \%f, and \%p, which are not supported, #packetScanf supports the same format
 codes as #facePrintf prints, which see for further description of the format conversions.  Note
 that the pointed-to variables must be appropriate (sizes at least) for the converted type!  For
 example,
 \code
  void MyBHandler(u8 * packet) {
    u32 fourBytes; u16 twoBytes; u8 oneByte;
    if (packetScanf(packet,"b%c%d%h",&oneByte,&fourBytes,&twoBytes) != 4) 
       return;
    ..
  }
 \endcode
 is correct since the sizes of the \c oneByte, \c fourBytes, and \c twoBytes variables match the
 specified sizes of \%c, \%d, and \%h, respectively.

 Since 0.9.9, there is some support for field widths, limited to the \%b, \%o, \%d, \%x, and \%t
 conversions only.  

 packetScanf returns the number of successful matches it made, where a 'match' counts as either a
 successful '\% conversion' \e or a successful match of a \e single literal byte of the format
 string.  E.g., given a packet containing "fg123h", \c packetScanf(packet,"fg%dh",&u32var) will
 return 4 -- one for the 'f', one for the 'g', one for the '\%d', and one for the 'h'.  (But watch
 out!  Given the same packet, \c packetScanf(packet,"fg%dh\n",&u32var) will return 5 -- including
 one for the successful matching of the end-of-packet!)

 XXX Still need formatting details; examples.

 \since 0.9.9 for field widths
 
 */
extern u32 packetScanf(u8 * packet, const char * format, ...) ;

extern u32 vPacketScanf(u8 * packet, const char * format, va_list & ap) ;

extern void vfaceLogf(int includeTimestamp, int level, u8 face, const char * format, va_list & ap) ;

/* The 'log*' functions output a timestamp first */
extern void logf(int level, const char * format, ...) ;
extern void logNormal(const char * format, ...) ;
extern void logVerbose(const char * format, ...) ;
extern void logDebug(const char * format, ...) ;
extern void logQuiet(const char * format, ...) ;

/* The 'msg*' functions print only what you say */
extern void msgf(int level, const char * format, ...) ;
extern void msgNormal(const char * format, ...) ;
extern void msgVerbose(const char * format, ...) ;
extern void msgDebug(const char * format, ...) ;
extern void msgQuiet(const char * format, ...) ;

#endif /* SFBPRINTF_H */
