/*static char *SCCSID = "@(#)lprintf.c	6.1 90/11/17";*/
/*static char *SCCSID = "@(#)lprintf.c      13.5 90/02/08";*/
#include <os2def.h>
#include <fsh.h>

#include "const.h"
#include "misc.h"
#include "buf.h"
#include "chain.h"
#include "dir.h"
#include "volume.h"
#include "frame.h"
#include "lw.h"
#include "storage.h"
#include "fsdata.h"
#include "tables.h"
#include "log.h"

#ifndef LOG_PRINT
#   define LOG_PRINT
#endif

#include "lprintf.h"


#include "pr_misc.h"
#include "pr_debug.h"




#define CH_LOG_CONT	' '
#define CH_LOG_NEWL	'>'

#define ACH_LOG_NOTIFY	( 'N' + 'Y' * 256 )	 /* 'NY' */

#define CH_LOG_FILL	'\0'

#define CCH_LOG_LINE	16
#define CCH_LOG_BUFFER 65536


CHAR FAR pchLogBase[ CCH_LOG_BUFFER ] = {0};
PCHAR pchLogCursor = &pchLogBase[0];

PCHAR near lputc( USHORT usPid, PCHAR pch, CHAR ch );
PCHAR near lputl (USHORT usPid, PCHAR pch, ULONG ul, USHORT base);
PCHAR near NextLog( USHORT usPid );
void near lformat (USHORT usPid, PSZ fmt, PVOID pv);

#define LPUTC( usPid, pch, ch ) 	(pch = lputc(usPid,pch,ch))
#define LPUTL( usPid, pch, ul, base )	(pch = lputl(usPid,pch,ul,base))


USHORT far InitLPrnt() {
    PVOID pv = pchLogBase;
    return FSH_FORCENOSWAP (SELECTOROF (pv));
}

void far cdecl lprintf (USHORT usMode, char *fmt, ...)
{

    USHORT usPid;

    switch( usMode ) {

    case LMOD_NTFY:
	usPid = ACH_LOG_NOTIFY;
	break;


    default:
	usPid = pfrm->usID;
	break;

    }


    lformat( usPid, fmt, (PVOID)(&fmt + 1) );

}


PCHAR near lputc( USHORT usPid, PCHAR pch, CHAR ch )
{
    if( (OFFSETOF( pch ) % CCH_LOG_LINE) == 0 ) {
	/* continue line */
	pch = NextLog( usPid );
	*pch++ = CH_LOG_CONT;

    }

    *pch++ = ch;

    return pch;
}


PCHAR near lputl (USHORT usPid, PCHAR pch, ULONG ul, USHORT base)
{
    if (ul / base != 0)
	pch = lputl (usPid, pch, ul / base, base);

    return lputc (usPid, pch, "0123456789ABCDEF"[ul % base]);
}

PCHAR near NextLog( USHORT usPid )
{
    PCHAR pch;

    if( usPid != ACH_LOG_NOTIFY )
	_disable();

    pch = pchLogCursor;

    pchLogCursor += CCH_LOG_LINE;

    if (OFFSETOF (pchLogCursor) > (USHORT)(CCH_LOG_BUFFER - CCH_LOG_LINE)) {
	pchLogCursor = pchLogBase;
    }

    memset( pchLogCursor, CH_LOG_FILL, CCH_LOG_LINE );


    if( usPid != ACH_LOG_NOTIFY )
	_enable();

    *(PUSHORT)pch = usPid;
    return pch + ( sizeof(USHORT) / sizeof(CHAR) );
}


/*  lformat - formats strings for lprintf
 *
 *  lformat is a dependent function of lprintf.
 *
 *  fmt 	formatting string.  Formats currently understood are:
 *		    %c single character
 *		    %[l]d %[l]x
 *		    %[F]s
 *		    %p
 *		      * may be used to copy in values for m and n from arg
 *			list.
 *		    %%
 *  arg 	is a list of arguments
 */
void near lformat (usPid, fmt, pv)
USHORT usPid;
PSZ fmt;
PVOID pv;
{
    char c;
    PSZ psz;
    USHORT base;
    PCHAR pch;

    pch = NextLog( usPid );
    *pch++ = CH_LOG_NEWL;

    while (c = *fmt++) {
	if (c != '%')
	    LPUTC ( usPid, pch, c);
	else {
	    BOOL fLong = FALSE;
	    BOOL fFar = FALSE;

	    base = 10;
	    if (*fmt == 'l') {
		fLong = TRUE;
		fmt++;
	    }
	    if (*fmt == 'F') {
		fFar = TRUE;
		fmt++;
	    }

	    switch (*fmt++) {
	    case 'c':
		LPUTC ( usPid, pch, (char) * MAKETYPE (pv, PUSHORT));
		++ MAKETYPE (pv, PUSHORT);
		break;
	    case 'x':
		base = 16;
	    case 'd':
	    case 'u':
		if (fLong) {
		    LPUTL (usPid, pch, (ULONG) * MAKETYPE (pv, PULONG), base);
		    ++ MAKETYPE (pv, PULONG);
		} else {
		    LPUTL (usPid, pch, (ULONG) * MAKETYPE (pv, PUSHORT), base);
		    ++ MAKETYPE (pv, PUSHORT);
		}
		break;
	    case 's':
		if (fFar) {
		    psz = * MAKETYPE (pv, PSZ far *);
		    ++ MAKETYPE (pv, PSZ far *);
		} else {
		    psz = * MAKETYPE (pv, NPSZ far *);
		    ++ MAKETYPE (pv, NPSZ far *);
		}
		while (*psz != 0)
		    LPUTC ( usPid, pch, *psz++);
		break;
	    case '%':
		LPUTC ( usPid, pch, '%');
		break;
	    case 'p':
		psz = * MAKETYPE (pv, PSZ far *);
		++ MAKETYPE (pv, PSZ far *);
		LPUTL (usPid, pch, (LONG)SELECTOROF (psz), 16);
		LPUTC ( usPid, pch, ':');
		LPUTL (usPid, pch, (LONG)OFFSETOF (psz), 16);
		break;
	    default:
		LPUTC ( usPid, pch, '?');
		LPUTC ( usPid, pch, '\'');
		LPUTC ( usPid, pch, fmt[-1]);
		LPUTC( usPid, pch, '\'');
	    }
	}
    }
}
