/*
    General.c
*/

/// Includes
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdarg.h>
#include "protos.h"
#include "config.h"
#include "macros.h"
///
/// External variables
///
/// Prototypes
Prototype void fail (int rc, char *msg, ...);
Prototype void fail_io (int rc, char *msg);
Prototype void c_fwrite (void *obj, int objsize, int numobjs, FILE *file);
Prototype int RandomNumber (int limit);
Prototype char *ReadLine (FILE *f);
Prototype char *ReadLineFromMemory (char **buf);
///
/// Global variables
///

/// "fail"
/* ----------------------------------- fail ------------------------------------

 Comment: prints an error message then exit()s

*/

void
fail(int rc, char *msg, ...)
{
    va_list va;
    FILE *log;
    time_t t = time(NULL);
    struct tm *tp = localtime(&t);
    char buf[256], bigbuf[1024];

    va_start (va, msg);

    if (msg) {
        vsprintf (bigbuf, msg, va);
        if (!Config.NoReq)
                        AlertUser ("Tag-o-Miga: %s", "OK", bigbuf);

        log = fopen (Config.LogFile, "a");
        if (log) {
            strftime(buf, sizeof(buf) - 1, "%d/%m/%y %H:%M:%S", tp);
            fprintf (log, "%s  %s\n", buf, bigbuf);
            fclose (log);
        }
    }

    va_end (va);
    exit (rc);
}
///
/// fail_io
/* ---------------------------------- fail_io ----------------------------------

 Comment: fail, but check IoErr() and return an appropriate message

*/

void
fail_io(int rc, char *msg)
{
    char msg1[256];

    sprintf (msg1, "%s\n%s", msg, ErrorMessage ());
    fail (rc, msg1);
}
///
/// "c_fwrite"
/* -------------------------------- c_fwrite -----------------------------------

 Comment: fwrite() with automatic error checking

*/

void
c_fwrite(void *obj, int objsize, int numobjs, FILE *file)
{
    int ret;

    ret = fwrite (obj, objsize, numobjs, file);
    if (ret != numobjs) fail_io (20, "Error while writing (c_fwrite)");
}
///
/// RandomNumber
/* ---------------------------------- RandomNumber -----------------------------------

 Comment:

*/

int RandomNumber (int limit)
{
    static seeded = 0;

    if (!seeded) {
        //srand (clock ());
        srand (time (NULL));
        seeded = 1;
    }

    return ((rand () + clock ()) % limit);
}
///
/// ReadLine
/* --------------------------------- ReadLine ----------------------------------

 Comment: Read a line from a given filehandle.  Handles EOF and EOL.

*/

char *ReadLine(FILE *f)
{
    static char linebuf[256];
    char c;
    int n = 0;

    for (;;) {
        c = fgetc (f);
        if (c == 0x0D || c == 0x0A || c == EOF) break;
        linebuf[n++] = c;
    }
    linebuf[n] = 0;

    if (n == 0 && c == EOF) return NULL;

    return linebuf;
}
///
/// ReadLineFromMemory
/* ----------------------- ReadLineFromMemory ----------------------------------

 Comment: Read a line from a given memory address.

*/

char *ReadLineFromMemory(char **buf)
{
    static char linebuf[256];
    char c, *ptr;
    int n = 0;

    ptr = *buf;

    for (;;) {
#ifdef AMIGA
        chkabort ();
#endif
        c = *ptr; ptr++;
        if (c == 0x0D || c == 0x0A || c == 0) break;
        linebuf[n++] = c;
    }
    linebuf[n] = 0;

    if (c == 0) ptr--;
    if (n == 0 && *ptr == 0) return NULL;

    *buf = ptr;

    return linebuf;
}
///

