/* impl.c.mpsliban: HARLEQUIN MEMORY POOL SYSTEM LIBRARY INTERFACE (DYLAN)
*
*
* PURPOSE
*
* .purpose: The purpose of this code is
* 1. to connect the MPS Library Interface to the Dylan runtime
* with no dependency on the C runtime.
*/
#include "mpslib.h"
#include <windows.h>
#include <stdio.h>
#include <time.h>
/* First some simple stream buffer management */
#define BUFFER_SIZE 200
#define BUFFER_LIMIT (BUFFER_SIZE + 1)
typedef struct message_buffer_s *message_buffer_t;
typedef struct message_buffer_s {
int buf_index;
char buf_data [BUFFER_LIMIT];
} message_buffer_s;
static message_buffer_s err_buf_struct = {0, ""};
static message_buffer_s out_buf_struct = {0, ""};
static message_buffer_t err_buf = &err_buf_struct;
static message_buffer_t out_buf = &out_buf_struct;
extern BOOL dylan_streamQ;
extern char *dylan_buffer;
extern int dylan_buffer_pos;
extern int dylan_buffer_size;
int buffer_add (message_buffer_t buf, char c)
{
int res = 0;
if (dylan_streamQ)
{
if (dylan_buffer_pos < dylan_buffer_size)
dylan_buffer[dylan_buffer_pos++] = c;
else {
/* HACK -- delete last line in dylan buffer on overflow */
int pos = dylan_buffer_pos - 1;
if (dylan_buffer[pos] != '\n') {
while (dylan_buffer[--pos] != '\n');
while (pos < dylan_buffer_pos)
dylan_buffer[++pos] = ' ';
dylan_buffer[pos - 1] = '\n'; }
}
}
else
{
buf->buf_data[buf->buf_index++] = c;
if ((c == '\n') || (c == '\0') || (buf->buf_index >= BUFFER_SIZE))
res = buf->buf_index;
};
return(res);
}
char *buffer_contents (message_buffer_t buf)
{
buf->buf_data[buf->buf_index] = '\0';
return(buf->buf_data);
}
void buffer_reset (message_buffer_t buf)
{
buf->buf_index = 0;
}
static HANDLE current_log_file = 0;
HANDLE ensure_log_file (void)
{
if (current_log_file == 0)
{
current_log_file = CreateFile("dylan-runtime.log",
GENERIC_WRITE,
FILE_SHARE_READ,
0,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
}
return(current_log_file);
}
void ensure_log_file_closed (void)
{
if (current_log_file != 0)
{
if (CloseHandle(current_log_file))
current_log_file = 0;
}
}
void plinth_flush_string_to_file (char *string, int length)
{
int written;
HANDLE log_file = ensure_log_file();
if (log_file != 0)
WriteFile(log_file, string, length, &written, 0);
}
void plinth_flush_string_to_debugger (char *string, int length)
{
OutputDebugString(string);
}
void plinth_flush_string (char *string, int length)
{
plinth_flush_string_to_debugger(string, length);
plinth_flush_string_to_file(string, length);
}
int plinth_putc (message_buffer_t buf, int c)
{
int num_to_flush = buffer_add(buf, (char)c);
if (num_to_flush > 0)
{
plinth_flush_string(buffer_contents(buf), num_to_flush);
buffer_reset(buf);
};
return(c);
}
/* Now the plinth implementation itself */
void mps_lib_abort(void)
{
ensure_log_file_closed();
DebugBreak();
}
int mps_lib_get_EOF(void)
{
return 0;
}
mps_lib_FILE *mps_lib_get_stderr(void)
{
return (mps_lib_FILE *)err_buf;
}
mps_lib_FILE *mps_lib_get_stdout(void)
{
return (mps_lib_FILE *)out_buf;
}
int mps_lib_fputc(int c, mps_lib_FILE *stream)
{
return plinth_putc((message_buffer_t)stream, c);
}
int mps_lib_fputs(const char *s, mps_lib_FILE *stream)
{
int i = 0;
char c;
while (c = s[i++])
{
plinth_putc((message_buffer_t)stream, c);
};
return 1;
}
int mps_lib_fputs_(const char *s, int end, mps_lib_FILE *stream)
{
int i = 0;
char c;
while ((i < end) && (c = s[i++]))
{
plinth_putc((message_buffer_t)stream, c);
};
return 1;
}
void mps_lib_assert_fail(const char *message)
{
mps_lib_FILE *err = mps_lib_get_stderr();
mps_lib_fputs("\nMPS ASSERTION FAILURE: ", err);
mps_lib_fputs(message, err);
mps_lib_fputs("\n", err);
mps_lib_abort();
}
mps_clock_t mps_clock(void)
{
return (unsigned long)clock();
}
mps_clock_t mps_clocks_per_sec(void)
{
return (unsigned long)CLOCKS_PER_SEC;
}
unsigned long mps_lib_telemetry_control(void)
{
return 0;
}
void *mps_lib_memset( void *dest, int c, size_t count )
{
return memset(dest, c, count);
}
void *mps_lib_memcpy( void *dest, const void *src, size_t count )
{
return memcpy(dest, src, count);
}
int mps_lib_memcmp(const void *s1, const void *s2, size_t n)
{
return memcmp(s1, s2, n);
}
syntax highlighted by Code2HTML, v. 0.9.1