#include "assert.h" #include "errors/errors.h" #include "errors/exceptions.h" #include "files/files.h" #include "interpreter/parameters/actions.h" #include "interpreter/parameters/globalised.h" #include "memory/virtualmemory.h" #include "object.h" #include "stacks.h" #include "types/composites/composites.h" #include "types/composites/load.h" #include "types/equality.h" #include "types/typestrings.h" static object read_(const object parameter[const pair]) { object *value = valuefrom(parameter); assert(value); return *value; } static void write_(const object thing, object parameter[const pair]) { object * const value = valuefrom(parameter); assert(value); if (thing.type != value->type) throw (typecheck); *value = global((object){.type = arraytype, .array = value, .access = none}) ? globalised(thing) : copied(thing); } static object readWriteonly(const object parameter[const pair]) { (void)valuefrom(parameter); return null; } static void writeReadonly(const object thing, object parameter[const pair]) { (void)thing; (void)valuefrom(parameter); } static accessattribute FileAccessfrom(object string) { if (string.type != stringtype) throw (typecheck); if (string.access > readonly) throw (invalidaccess); return fileaccessfrom(string.length ? string : string("unlimited")); } static object readFileAccess(const object parameter[const pair]) { return accessattributestring(FileAccessfrom(read_(parameter))); } static void writeFileAccess(const object thing, object parameter[const pair]) { const accessattribute access = FileAccessfrom(thing); if (access < FileAccessfrom(read_(parameter))) throw (invalidfileaccess); write_(accessattributestring(access), parameter); } static object readJobName(const object parameter[const pair]) { if (count(dictionarystack)) { const object systemdict = bottomof(dictionarystack); assert(systemdict.type == dicttype); const object * const statusdict = known(string("statusdict"), systemdict); if (statusdict && statusdict->type == dicttype) { const object * const jobname = known(string("jobname"), *statusdict); if (jobname && jobname->type == stringtype) return *jobname; } } return read_(parameter); } static void writeJobName(const object thing, object parameter[const pair]) { if (thing.type != stringtype) throw (typecheck); if (thing.length) assert(thing.string); if (count(dictionarystack)) { const object systemdict = bottomof(dictionarystack); assert(systemdict.type == dicttype); const object * const statusdict = known(string("statusdict"), systemdict); if (statusdict && statusdict->type == dicttype) { if (known(string("jobname"), *statusdict)) put[dicttype](string("jobname"), thing, *statusdict); } } write_(thing, parameter); } static struct stack *selectstack(const object parameter[const pair]) { assert(parameter); return ( eq(parameter[key], string("MaxOpStack")) ? operandstack : eq(parameter[key], string("MaxExecStack")) ? executionstack : eq(parameter[key], string("MaxDictStack")) ? dictionarystack : (throw (undefined), (struct stack *)0) ); } static object readMaxStack(const object parameter[const pair]) { const natural limit = selectstack(parameter)->limit; return integer((assert(limit <= largestinteger), (integer)limit)); } static void writeMaxStack(const object thing, object parameter[const pair]) { if (thing.type != integertype) throw (typecheck); if (thing.integer < 0) throw (rangecheck); limit(selectstack(parameter), (natural)thing.integer); } static object readPrinterName(const object parameter[const pair]) { object PrinterName = read_(parameter); if (eq(PrinterName, string(""))) { const object systemdict = bottomof(dictionarystack); assert(systemdict.type == dicttype); PrinterName = get[dicttype](string("product"), systemdict); } return PrinterName; } static object readVMReclaim(const object parameter[const pair]) { assert(parameter); (void)parameter; if (vm.global->collection.enabled) { return integer(vm.local->collection.enabled ? 0 : -1); } else { assert(vm.local->collection.enabled == false); return integer(-2); } } static void writeVMReclaim(const object thing, object parameter[const pair]) { assert(parameter); (void)parameter; if (thing.type != integertype) throw (typecheck); if (thing.integer > 0) throw (rangecheck); vmreclaim(thing.integer); } static object readVMThreshold(const object parameter[const pair]) { assert(parameter); (void)parameter; return integer(vm.threshold); } static void writeVMThreshold(const object thing, object parameter[const pair]) { assert(parameter); (void)parameter; if (thing.type != integertype) throw (typecheck); setvmthreshold(thing.integer); } object (* const readaction[allactions])(const object[pair]) = { [Array] = read_, [FileAccess] = readFileAccess, [JobName] = readJobName, [MaxStack] = readMaxStack, [PrinterName] = readPrinterName, [Readonly] = read_, [VMReclaim] = readVMReclaim, [VMThreshold] = readVMThreshold, [Writeonly] = readWriteonly }; void (* const writeaction[allactions])(object, object[pair]) = { [Array] = write_, [FileAccess] = writeFileAccess, [JobName] = writeJobName, [MaxStack] = writeMaxStack, [PrinterName] = write_, [Readonly] = writeReadonly, [VMReclaim] = writeVMReclaim, [VMThreshold] = writeVMThreshold, [Writeonly] = write_ };