/*-*-c++-*-
 * $Id: osdep.h,v 1.1 2002/01/28 15:38:33 holzheu Exp $
 *
 * This file is part of qlcrash, a GUI for the dump-analysis tool lcrash.
 *
 * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *
 * Authors:
 * Michael Geselbracht (let@users.sourceforge.net)
 * Fritz Elfert (elfert@de.ibm.com)
 * Michael Holzheu (holzheu@de.ibm.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version. See the file COPYING for more
 * information.
 */
#ifndef _OSDEP_H_
#define _OSDEP_H_

#ifdef WIN32
// Windows ...

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// Exclude rarely-used stuff from Windows headers
#define WIN32_LEAN_AND_MEAN

// Disable warnings about undebuggable huge identifiers (due to STL templates)
#pragma warning(disable:4786)

#include <windows.h>
#include <io.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

typedef int pid_t;

// return directory of executable
static inline char *execdir() {
	char *p;
	static char myPath[_MAX_PATH];
	GetModuleFileName(GetModuleHandle(NULL), myPath, sizeof(myPath));
	while (p = strchr(myPath, '\\'))
		*p = '/';
	if (p = strrchr(myPath,'/'))
		*p = 0;
	return myPath;
}

static inline int isblank(const char c) {
	return (c == ' ') || (c == 9);
}

struct utsname {
	char sysname[20];
	char release[20];
	char machine[20];
};

static inline int uname(struct utsname *uts) {
	OSVERSIONINFO vi;

	::strcpy(uts->machine, "Unknown CPU");
	::strcpy(uts->sysname, "Windows");
	vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	if (GetVersionEx(&vi)) {
		switch (vi.dwPlatformId) {
			case VER_PLATFORM_WIN32_WINDOWS:
				switch (vi.dwMinorVersion) {
					case 0:
						::sprintf(uts->release, "95");
						break;
					case 9:
						::sprintf(uts->release, "ME");
						break;
					default:
						::sprintf(uts->release, "98");
						break;
				}
				break;
			case VER_PLATFORM_WIN32_NT:
				::sprintf(uts->release, "NT %d.%d", vi.dwMajorVersion, vi.dwMinorVersion);
				break;
			case VER_PLATFORM_WIN32s:
				::sprintf(uts->release, "3.1");
				break;
		}
	} else
		::sprintf(uts->release, "Unknown Version");
	return 0;
}

#define ULONG_LONG_MAX ((UINT64)(0xffffffffffffffffi64))

static inline UINT64 strtoull(const char *str, char **eptr, int base) {
	UINT64 ret;
	char *fmt = "";
	switch (base) {
		case 8:
			fmt = "%I64o";
			break;
		case 10:
			fmt = "%I64u";
			break;
		case 16:
			fmt = "%I64x";
			break;
		default:
			fmt = "%I64i";
	}
	if (sscanf(str, fmt, &ret) == 1) {
		if (eptr)
			*eptr = (char *)(str + strlen(str));
	} else {
		if (eptr)
			*eptr = (char *)str;
	}
	return ret;
}

#define CHUNK 4096
static inline size_t getline(char **bufptr, size_t *buflen, FILE *f) {
	char *lfptr;
	char *readptr;
	size_t l = *buflen;

	if ((!*bufptr) || (l < CHUNK)) {
		l = CHUNK;
		*bufptr = (char *)realloc(*bufptr, l);
	}
	do {
		if (!*bufptr)
			return -1;

		readptr = *bufptr + l - CHUNK;
		*buflen = l;
		if (!fgets(readptr, CHUNK, f))
			return -1;
		if (!(lfptr = strrchr(readptr, '\n'))) {
			l += CHUNK;
			*bufptr = (char *)realloc(*bufptr, l);
		}
	} while (!lfptr);
	return strlen(*bufptr);
}
#undef CHUNK

#else
// Real OS'es ...

typedef unsigned long long UINT64;
typedef long long INT64;

#endif

#endif
