mirror of
https://github.com/DerekK19/PDP-8-E-Simulator.git
synced 2024-10-31 14:08:29 +00:00
160 lines
4.6 KiB
Mathematica
160 lines
4.6 KiB
Mathematica
|
/*
|
||
|
* PDP-8/E Simulator
|
||
|
*
|
||
|
* Copyright © 1994-2015 Bernhard Baehr
|
||
|
*
|
||
|
* OctalFormatter.m - Formatter for octal numbers
|
||
|
*
|
||
|
* This file is part of PDP-8/E Simulator.
|
||
|
*
|
||
|
* PDP-8/E Simulator 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 3 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, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
|
||
|
#import <Cocoa/Cocoa.h>
|
||
|
|
||
|
#import "OctalFormatter.h"
|
||
|
|
||
|
|
||
|
@implementation OctalFormatter
|
||
|
|
||
|
|
||
|
+ (OctalFormatter *) formatterWithBitMask:(unsigned)mask wildcardAllowed:(BOOL)withWildcard
|
||
|
{
|
||
|
return [[[OctalFormatter alloc] initWithBitMask:mask wildcardAllowed:withWildcard] autorelease];
|
||
|
}
|
||
|
|
||
|
|
||
|
- (OctalFormatter *) initWithBitMask:(unsigned)mask wildcardAllowed:(BOOL)withWildcard
|
||
|
{
|
||
|
if ((self = [super init])) {
|
||
|
wildcardAllowed = withWildcard;
|
||
|
bitMask = mask;
|
||
|
int digits = 0;
|
||
|
while (mask) {
|
||
|
digits++;
|
||
|
mask >>= 3;
|
||
|
}
|
||
|
outputFormat = [[NSString alloc] initWithFormat:@"%%%d.%do", digits, digits];
|
||
|
numberOfWords = 1;
|
||
|
}
|
||
|
return self;
|
||
|
}
|
||
|
|
||
|
|
||
|
- (void) setNumberOfWords:(unsigned)n
|
||
|
{
|
||
|
numberOfWords = n;
|
||
|
}
|
||
|
|
||
|
|
||
|
- (NSString *) stringForObjectValue:(id)value
|
||
|
{
|
||
|
unsigned i;
|
||
|
|
||
|
NSMutableString *string = nil;
|
||
|
if ([value isKindOfClass:[NSNumber class]])
|
||
|
string = [NSString stringWithFormat:outputFormat, [value intValue]];
|
||
|
else if ([value isKindOfClass:[NSArray class]]) {
|
||
|
unsigned count = [value count];
|
||
|
if (numberOfWords < count)
|
||
|
count = numberOfWords;
|
||
|
string = [NSMutableString stringWithCapacity:5 * count];
|
||
|
for (i = 0; i < count; i++) {
|
||
|
if (i > 0)
|
||
|
[string appendString:@" "];
|
||
|
[string appendFormat:outputFormat, [[value objectAtIndex:i] intValue]];
|
||
|
}
|
||
|
}
|
||
|
return string;
|
||
|
}
|
||
|
|
||
|
|
||
|
- (BOOL) getObjectValue:(id *)value forString:(NSString *)string errorDescription:(NSString **)error
|
||
|
/* For string without placeholder, value becomes a NSNumber (for numberOfWords == 1) or an
|
||
|
NSArray of NSNumbers (for numberOfWords > 1). For strings with placeholder, values becomes
|
||
|
an asencding sorted NSArray of NSNumbers (for numberOfWords == 1) or an NSArray of such NSArrays
|
||
|
(for numberOfWords > 1). */
|
||
|
{
|
||
|
char buf[128];
|
||
|
char *bp = buf;
|
||
|
NSMutableArray *values = [NSMutableArray arrayWithCapacity:numberOfWords];
|
||
|
if (! [string getCString:buf maxLength:(sizeof(buf) - 1) encoding:NSMacOSRomanStringEncoding]) {
|
||
|
if (error)
|
||
|
*error = [string canBeConvertedToEncoding:NSMacOSRomanStringEncoding] ?
|
||
|
NSLocalizedString(@"Input too long.", @"") :
|
||
|
NSLocalizedString(@"Input contains invalid characters.", @"");
|
||
|
return FALSE;
|
||
|
}
|
||
|
while (*bp == ' ')
|
||
|
bp++;
|
||
|
while (('0' <= *bp && *bp < '8') || (wildcardAllowed && *bp == '#')) {
|
||
|
unsigned val = 0;
|
||
|
unsigned pattern = 0;
|
||
|
while (('0' <= *bp && *bp < '8') || (wildcardAllowed && *bp == '#')) {
|
||
|
pattern <<= 3;
|
||
|
if ('0' <= *bp && *bp < '8')
|
||
|
val = val * 8 + (*bp - '0');
|
||
|
else {
|
||
|
val *= 8;
|
||
|
pattern |= 7;
|
||
|
}
|
||
|
bp++;
|
||
|
}
|
||
|
while (*bp == ' ')
|
||
|
bp++;
|
||
|
if ((val | pattern) & ~bitMask) {
|
||
|
if (error)
|
||
|
*error = [NSString stringWithFormat:NSLocalizedString(
|
||
|
@"The octal number is of range. The largest allowed number is %o.",
|
||
|
@""), bitMask];
|
||
|
return FALSE;
|
||
|
}
|
||
|
if (pattern) {
|
||
|
unsigned long mask = pattern;
|
||
|
NSMutableArray *patternValues = [NSMutableArray arrayWithCapacity:8];
|
||
|
do {
|
||
|
[patternValues insertObject:[NSNumber numberWithInt:val + pattern]
|
||
|
atIndex:0];
|
||
|
pattern = (pattern - 1) & mask;
|
||
|
} while (pattern != mask);
|
||
|
[values addObject:patternValues];
|
||
|
} else
|
||
|
[values addObject:[NSNumber numberWithInt:val]];
|
||
|
}
|
||
|
if (*bp || [values count] != numberOfWords) {
|
||
|
if (error)
|
||
|
*error = (numberOfWords == 1) ?
|
||
|
(wildcardAllowed ?
|
||
|
NSLocalizedString(
|
||
|
@"Invalid input. An octal number is expected. "
|
||
|
@"The wildcard character # is allowed.", @"") :
|
||
|
NSLocalizedString(
|
||
|
@"Invalid input. An octal number is expected.", @"")) :
|
||
|
[NSString stringWithFormat:wildcardAllowed ?
|
||
|
NSLocalizedString(
|
||
|
@"Invalid input. %d octal numbers are expected. "
|
||
|
@"The wildcard character # is allowed.", @"") :
|
||
|
NSLocalizedString(
|
||
|
@"Invalid input. %d octal numbers are expected.", @""),
|
||
|
numberOfWords];
|
||
|
return FALSE;
|
||
|
}
|
||
|
*value = (numberOfWords == 1) ? [values objectAtIndex:0] : values;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
@end
|