From 3cd180b262db4490f811aaa2f19ef7a4d00ce24f Mon Sep 17 00:00:00 2001 From: jaortega Date: Thu, 1 Mar 2001 23:56:08 +0000 Subject: mix device operations handled via a vtable --- mixlib/Makefile.am | 2 +- mixlib/mix_device.c | 168 +++++++++++++++++---------------------------------- mixlib/mix_device.h | 28 +++++++-- mixlib/mix_vm.c | 19 ++++++ mixlib/mix_vm.h | 5 ++ mixlib/xmix_device.h | 77 +++++++++++++++++++++++ mixlib/xmix_device.o | Bin 0 -> 30132 bytes 7 files changed, 181 insertions(+), 118 deletions(-) create mode 100644 mixlib/xmix_device.h create mode 100644 mixlib/xmix_device.o (limited to 'mixlib') diff --git a/mixlib/Makefile.am b/mixlib/Makefile.am index 38c475a..5091e88 100644 --- a/mixlib/Makefile.am +++ b/mixlib/Makefile.am @@ -24,7 +24,7 @@ libmix_a_SOURCES = mix.h mix.c \ mix_file.h mix_file.c \ mix_code_file.h mix_code_file.c \ mix_parser.h xmix_parser.h mix_parser.c mix_scanner.l \ - mix_device.h mix_device.c \ + mix_device.h mix_device.c xmix_device.h xmix_device.c \ mix_eval.h mix_eval.c xmix_eval.h mix_eval_scanner.l \ mix_src_file.c mix_src_file.h \ mix_vm_clock.c mix_vm_clock.h \ diff --git a/mixlib/mix_device.c b/mixlib/mix_device.c index 624702b..13e7150 100644 --- a/mixlib/mix_device.c +++ b/mixlib/mix_device.c @@ -1,7 +1,7 @@ /* -*-c-*- -------------- mix_device.c : * Implementation of the functions declared in mix_device.h * ------------------------------------------------------------------ - * Copyright (C) 2000 Free Software Foundation, Inc. + * Copyright (C) 2000, 2001 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,56 +21,14 @@ #include "mix_file.h" -#include "mix_device.h" - -/* - Actual definition of a mix device, which can be cast to - a mix file. -*/ -struct mix_device_t -{ - mix_iochannel_t *file; - mix_device_type_t type; -}; - - -static const char *DEV_EXT_ = ".dev"; - -static const char *DEF_NAMES_[] = { - "tape0", "tape1", "tape2", "tape3", "tape4", "tape5", "tape6", "tape7", - "disk0", "disk1", "disk2", "disk3", "disk4", "disk5", "disk6", "disk7", - "cardrd", "cardwr", "printer", "console", "paper" -}; - -static const size_t SIZES_[] = { - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 16, 16, 24, 14, 14 -}; - -static const mix_device_mode_t MODES_[] = { - mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, - mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, - mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, - mix_dev_BIN, mix_dev_CHAR, mix_dev_CHAR, mix_dev_CHAR, mix_dev_CHAR, - mix_dev_CHAR -}; - -static const mix_fmode_t FMODES_[] = { - mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, - mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, - mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, - mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, - mix_io_READ, mix_io_WRITE, mix_io_WRITE, mix_io_RDWRT, mix_io_WRITE -}; - -#define GET_CHANNEL_(dev) (dev->file) -#define GET_FILE_(dev) ((mix_file_t *)(dev->file)) +#include "xmix_device.h" mix_device_t * mix_device_new (mix_device_type_t type) { - mix_device_t *result = g_new (mix_device_t, 1); + mix_device_t *result = NULL; + g_return_val_if_fail (type < mix_dev_INVALID, NULL); + result = g_new (mix_device_t, 1); result->type = type; if (type != mix_dev_CONSOLE) { result->file = MIX_IOCHANNEL(mix_file_new_with_def_ext (DEF_NAMES_[type], @@ -78,26 +36,18 @@ mix_device_new (mix_device_type_t type) DEV_EXT_)); } else result->file = mix_io_new (stdout); - + result->vtable = DEF_DEV_VTABLE_; return result; } -void -mix_device_delete (mix_device_t *dev) -{ - if (dev != NULL) - { - if (dev->type != mix_dev_CONSOLE && GET_FILE_(dev) != NULL) - mix_file_delete (GET_FILE_(dev)); - g_free (dev); - } -} + mix_device_t * mix_device_new_with_name (mix_device_type_t type, const gchar *name) { mix_device_t *result = NULL; - g_return_val_if_fail (name != NULL, result); + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (type < mix_dev_INVALID, NULL); result = g_new (mix_device_t, 1); result->type = type; if (type != mix_dev_CONSOLE) @@ -110,11 +60,46 @@ mix_device_new_with_name (mix_device_type_t type, const gchar *name) { result->file = mix_io_new (stdout); } + result->vtable = DEF_DEV_VTABLE_; return result; } +/* + Create a new device with a given type and stream +*/ +mix_device_t * +mix_device_new_with_file (mix_device_type_t type, FILE *file) +{ + mix_device_t *result = NULL; + g_return_val_if_fail (file != NULL, NULL); + g_return_val_if_fail (type < mix_dev_INVALID, NULL); + result = g_new (mix_device_t, 1); + result->type = type; + result->file = mix_io_new (file); + result->vtable = DEF_DEV_VTABLE_; + return result; +} + +void +mix_device_delete (mix_device_t *dev) +{ + if (dev != NULL) + { + if (dev->type != mix_dev_CONSOLE && GET_FILE_(dev) != NULL) + mix_file_delete (GET_FILE_(dev)); + g_free (dev); + } +} + +mix_device_type_t +mix_device_type (const mix_device_t *dev) +{ + g_return_val_if_fail (dev != NULL, mix_dev_INVALID); + return dev->type; +} + const char * -mix_device_get_name (mix_device_t *dev) +mix_device_get_name (const mix_device_t *dev) { g_return_val_if_fail (dev != NULL, NULL); return mix_file_base_name(GET_FILE_(dev)); @@ -124,7 +109,7 @@ mix_device_get_name (mix_device_t *dev) Get the device block size */ size_t -mix_device_block_size (mix_device_t *dev) +mix_device_block_size (const mix_device_t *dev) { g_return_val_if_fail (dev != NULL, 0); return SIZES_[dev->type]; @@ -134,7 +119,7 @@ mix_device_block_size (mix_device_t *dev) Get the device io mode */ mix_device_mode_t -mix_device_mode (mix_device_t *dev) +mix_device_mode (const mix_device_t *dev) { g_return_val_if_fail (dev != NULL, 0); return MODES_[dev->type]; @@ -146,23 +131,10 @@ mix_device_mode (mix_device_t *dev) gboolean mix_device_write (mix_device_t *dev, const mix_word_t *block) { - gboolean result; - g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (block != NULL, FALSE); - if (FMODES_[dev->type] == mix_io_READ) return FALSE; - if (MODES_[dev->type] == mix_dev_CHAR) - result = mix_io_write_word_array_as_char (GET_CHANNEL_ (dev), - block, SIZES_[dev->type]); - else - result = mix_io_write_word_array (GET_CHANNEL_ (dev), - block, SIZES_[dev->type]); - if (result && mix_device_mode(dev) == mix_dev_CHAR) - putc ('\n', mix_io_to_FILE (GET_CHANNEL_ (dev))); - - fflush (mix_io_to_FILE (GET_CHANNEL_ (dev))); - - return result; + g_assert (dev->vtable != NULL); + return (dev->vtable->write) (dev, block); } gboolean @@ -170,48 +142,22 @@ mix_device_read (mix_device_t *dev, mix_word_t *block) { g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (block != NULL, FALSE); - if (FMODES_[dev->type] == mix_io_WRITE) return FALSE; - if (MODES_[dev->type] == mix_dev_CHAR) - return mix_io_read_word_array_as_char (GET_CHANNEL_ (dev), - block, SIZES_[dev->type]); - else - return mix_io_read_word_array (GET_CHANNEL_ (dev), - block, SIZES_[dev->type]); + g_assert (dev->vtable != NULL); + return (dev->vtable->read) (dev, block); } gboolean mix_device_ioc (mix_device_t *dev, mix_short_t arg) { - int m; - FILE *file; - g_return_val_if_fail (dev != NULL, FALSE); - - m = mix_short_magnitude(arg); - if (mix_short_is_negative(arg)) m = -m; - m *= sizeof (mix_word_t) * SIZES_[dev->type]; - file = mix_io_to_FILE (GET_CHANNEL_(dev)); - - if (dev->type >= mix_dev_TAPE_0 && dev->type <= mix_dev_TAPE_7) - { - if (m == 0) rewind (file); - else fseek (file, m, SEEK_CUR); - } - if (dev->type >= mix_dev_DISK_0 && dev->type <= mix_dev_DISK_7) - { - g_return_val_if_fail (m == 0, FALSE); - // position disk - } - if (dev->type == mix_dev_PAPER_TAPE) - { - g_return_val_if_fail (m == 0, FALSE); - rewind (file); - } - return TRUE; + g_assert (dev->vtable != NULL); + return (dev->vtable->ioc) (dev, arg); } gboolean -mix_device_busy (mix_device_t *dev) +mix_device_busy (const mix_device_t *dev) { - return (dev != NULL && !mix_io_is_ready(GET_CHANNEL_(dev))); + g_return_val_if_fail (dev != NULL, FALSE); + return (dev->vtable->busy) (dev); + } diff --git a/mixlib/mix_device.h b/mixlib/mix_device.h index 73f16af..7248d72 100644 --- a/mixlib/mix_device.h +++ b/mixlib/mix_device.h @@ -1,7 +1,7 @@ /* -*-c-*- ---------------- mix_device.h : * Declaration of mix_device_t and associated methods. * ------------------------------------------------------------------ - * Copyright (C) 2000 Free Software Foundation, Inc. + * Copyright (C) 2000, 2001 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +24,7 @@ #define MIX_DEVICE_H #include +#include #include "mix.h" #include "mix_types.h" @@ -56,7 +57,8 @@ typedef enum { mix_dev_CARD_WR, mix_dev_PRINTER, mix_dev_CONSOLE, - mix_dev_PAPER_TAPE + mix_dev_PAPER_TAPE, + mix_dev_INVALID } mix_device_type_t; /* @@ -79,29 +81,43 @@ mix_device_new (mix_device_type_t type); extern mix_device_t * mix_device_new_with_name (mix_device_type_t type, const gchar *name); +/* + Create a new device with a given type and stream +*/ +extern mix_device_t * +mix_device_new_with_file (mix_device_type_t type, FILE *file); + /* Delete a device. */ extern void mix_device_delete(mix_device_t *dev); + +/* + Get a device type +*/ +extern mix_device_type_t +mix_device_type (const mix_device_t *dev); + + /* Get a device name */ extern const char * -mix_device_get_name (mix_device_t *dev); +mix_device_get_name (const mix_device_t *dev); /* Get the device block size */ extern size_t -mix_device_block_size (mix_device_t *dev); +mix_device_block_size (const mix_device_t *dev); /* Get the device io mode */ extern mix_device_mode_t -mix_device_mode (mix_device_t *dev); +mix_device_mode (const mix_device_t *dev); /* Write a block to the device. @@ -129,7 +145,7 @@ mix_device_ioc (mix_device_t *dev, mix_short_t arg); Check if a device is busy */ extern gboolean -mix_device_busy (mix_device_t *dev); +mix_device_busy (const mix_device_t *dev); #endif /* MIX_DEVICE_H */ diff --git a/mixlib/mix_vm.c b/mixlib/mix_vm.c index 979d558..6da21e2 100644 --- a/mixlib/mix_vm.c +++ b/mixlib/mix_vm.c @@ -87,6 +87,8 @@ mix_vm_delete (mix_vm_t * vm) { int i; + g_return_if_fail (vm != NULL); + if (vm->line_table != NULL) g_tree_destroy (vm->line_table); if (vm->address_table != NULL) g_tree_destroy (vm->address_table); if (vm->symbol_table != NULL) mix_symbol_table_delete (vm->symbol_table); @@ -97,6 +99,23 @@ mix_vm_delete (mix_vm_t * vm) g_free (vm); } +/* connect devices to a virtual machine */ +mix_device_t * +mix_vm_connect_device (mix_vm_t *vm, mix_device_t *device) +{ + mix_device_t *old; + mix_device_type_t type; + + g_return_val_if_fail (vm != NULL, NULL); + g_return_val_if_fail (device != NULL, NULL); + + type = mix_device_type (device); + old = vm->devices[type]; + vm->devices[type] = device; + + return old; +} + /* Reset a vm (set state as of a newly created one) */ void mix_vm_reset (mix_vm_t * vm) diff --git a/mixlib/mix_vm.h b/mixlib/mix_vm.h index ac734d7..b4b408c 100644 --- a/mixlib/mix_vm.h +++ b/mixlib/mix_vm.h @@ -25,6 +25,7 @@ #include "mix_types.h" #include "mix_ins.h" +#include "mix_device.h" #include "mix_code_file.h" #include "mix_src_file.h" #include "mix_symbol_table.h" @@ -46,6 +47,10 @@ mix_vm_new(void); extern void mix_vm_delete(mix_vm_t * vm); +/* connect devices to a virtual machine */ +extern mix_device_t * /* previously connected device */ +mix_vm_connect_device (mix_vm_t *vm, mix_device_t *device); + /* Reset a vm (set state as of a newly created one) */ extern void mix_vm_reset(mix_vm_t * vm); diff --git a/mixlib/xmix_device.h b/mixlib/xmix_device.h new file mode 100644 index 0000000..c3e8a88 --- /dev/null +++ b/mixlib/xmix_device.h @@ -0,0 +1,77 @@ +/* -*-c-*- ---------------- xmix_device.h : + * Protected declarations for mix_device_t + * ------------------------------------------------------------------ + * Last change: Time-stamp: <01/03/02 00:30:56 jose> + * ------------------------------------------------------------------ + * Copyright (C) 2001 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + + +#ifndef XMIX_DEVICE_H +#define XMIX_DEVICE_H + +#include "mix_file.h" +#include "mix_device.h" + +/* table of overridable device operations */ +typedef gboolean (*mix_dev_write_func_t) (mix_device_t *, const mix_word_t *); +typedef gboolean (*mix_dev_read_func_t) (mix_device_t *, mix_word_t *); +typedef gboolean (*mix_dev_ioc_func_t) (mix_device_t *, mix_short_t); +typedef gboolean (*mix_dev_busy_func_t) (const mix_device_t *); + +typedef struct mix_device_vtable_t +{ + mix_dev_write_func_t write; + mix_dev_read_func_t read; + mix_dev_ioc_func_t ioc; + mix_dev_busy_func_t busy; +} mix_device_vtable_t; + +/* default vtable */ +extern const mix_device_vtable_t *DEF_DEV_VTABLE_; + +/* + Actual definition of a mix device, which can be cast to + a mix file. +*/ +struct mix_device_t +{ + mix_iochannel_t *file; + mix_device_type_t type; + const mix_device_vtable_t *vtable; +}; + +#define GET_CHANNEL_(dev) (dev->file) +#define GET_FILE_(dev) ((mix_file_t *)(dev->file)) + +/* default extension for device files */ +extern const char *DEV_EXT_; +/* default names for device files */ +extern const char *DEF_NAMES_[]; +/* block sizes for devices */ +extern const size_t SIZES_[]; +/* modes for devices */ +extern const mix_device_mode_t MODES_[]; +/* files modes for devices */ +extern const mix_fmode_t FMODES_[]; + + + + +#endif /* XMIX_DEVICE_H */ + diff --git a/mixlib/xmix_device.o b/mixlib/xmix_device.o new file mode 100644 index 0000000..7a5526f Binary files /dev/null and b/mixlib/xmix_device.o differ -- cgit v1.2.3