Annotation of objc/NXStringTable.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.0 (the 'License').  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License."
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: /*
                     25:        NXStringTable.m
                     26:        Copyright 1990 NeXT, Inc.
                     27:        Written by Bertrand Serlet, Jan 89
                     28:        Responsibility: Bertrand Serlet
                     29: */
                     30: 
                     31: #ifndef KERNEL
                     32: #ifdef SHLIB
                     33: #import "shlib.h"
                     34: #endif SHLIB
                     35: 
                     36: #import <stdlib.h>
                     37: #import <stdio.h>
                     38: #import <string.h>
                     39: #import "NXStringTable.h"
                     40: 
                     41: @implementation NXStringTable
                     42: + new {
                     43:     return [self newKeyDesc:"%" valueDesc:"*"];
                     44: }
                     45: 
                     46: - init {
                     47:     return [self initKeyDesc:"%" valueDesc:"*"];
                     48: }
                     49: 
                     50: static void noFree (void *item) {}
                     51: static void freeString(void *string) { free(string);}
                     52: - free {
                     53:     [self freeKeys:noFree values:freeString];
                     54:     return [super free];
                     55: }
                     56:     
                     57: - (const char *)valueForStringKey:(const char *)aString {
                     58:     return (const char *) [super valueForKey:NXUniqueString(aString)];
                     59: }
                     60: 
                     61: static int skipSpace(NXStream *stream) {
                     62:     /* return first significant character */
                     63:     int        ch;
                     64:     while ((ch = NXGetc(stream)) != EOF) {
                     65:        if ((ch != ' ') && (ch != '\n') && (ch != '\t')) return ch;
                     66:     }
                     67:     return ch;
                     68: }
                     69: 
                     70: static int parseWord(NXStream *stream, char *word) {
                     71:     /* return '"', that is read, or EOF */
                     72:     int        length = 0;
                     73:     int        ch;
                     74:     while (((ch = NXGetc(stream)) != EOF) && (ch != '"') && (length < MAX_NXSTRINGTABLE_LENGTH)) {
                     75:        word[length++] = ch;
                     76:        if (ch == '\\') {
                     77:            switch (ch = NXGetc(stream)) {
                     78:                case 'a':       word[length-1] = '\a'; break;
                     79:                case 'b':       word[length-1] = '\b'; break;
                     80:                case 'f':       word[length-1] = '\f'; break;
                     81:                case 'n':       word[length-1] = '\n'; break;
                     82:                case 'r':       word[length-1] = '\r'; break;
                     83:                case 't':       word[length-1] = '\t'; break;
                     84:                case 'v':       word[length-1] = '\v'; break;
                     85:                case '"':       word[length-1] = '\"'; break;
                     86:                case EOF:       break;
                     87:                case '\'':      word[length-1] = '\''; break;
                     88:                case '?':       word[length-1] = '?'; break;
                     89:                case '\\':      word[length-1] = '\\'; break;
                     90:                case 'x':
                     91:                    {
                     92:                      unsigned char c2 = 0;
                     93:                      
                     94:                      while (1)
                     95:                        {
                     96:                          ch = NXGetc (stream);
                     97:                          
                     98:                          if ('0' <= ch && ch <= '7')
                     99:                            c2 = (16 * c2) + (ch - '0');
                    100:                          else if ('a' <= ch && ch <= 'f')
                    101:                            c2 = (16 * c2) + (ch - 'a' + 0xa);
                    102:                          else if ('A' <= ch && ch <= 'F')
                    103:                            c2 = (16 * c2) + (ch - 'A' + 0xa);
                    104:                          else
                    105:                            {
                    106:                              NXUngetc (stream);
                    107:                              break;
                    108:                            }
                    109:                        }
                    110:                      
                    111:                      word[length-1] = c2;
                    112:                      break;
                    113:                    }
                    114:                  
                    115:                default:
                    116:                  if ('0' <= ch && ch <= '7')
                    117:                    {
                    118:                      unsigned char c2 = ch - '0';
                    119:                      unsigned int i;
                    120:                      
                    121:                      for (i = 0; i < 2; i++)
                    122:                        {
                    123:                          ch = NXGetc (stream);
                    124:                          
                    125:                          if ('0' <= ch && ch <= '7')
                    126:                            c2 = (8 * c2) + (ch - '0');
                    127:                          else
                    128:                            {
                    129:                              NXUngetc (stream);
                    130:                              break;
                    131:                            }
                    132:                        }
                    133:                      
                    134:                      word[length-1] = c2;
                    135:                    }
                    136:                  else
                    137:                    /* unknown escape sequence */
                    138:                    word[length-1] = ch;
                    139:                  
                    140:                  break;
                    141:            }
                    142:        }
                    143:     }
                    144:     word[length] = 0;
                    145:     return ch;
                    146: }
                    147: 
                    148: static void writeWord(NXStream *stream, const char *word) {
                    149:     int        ch;
                    150:     NXPutc(stream, '"');
                    151:     while ((ch = *(word++))) {
                    152:        switch (ch) {
                    153:            case '\a':  NXPutc(stream, '\\'); NXPutc(stream, 'a'); break;
                    154:            case '\b':  NXPutc(stream, '\\'); NXPutc(stream, 'b'); break;
                    155:            case '\f':  NXPutc(stream, '\\'); NXPutc(stream, 'f'); break;
                    156:            case '\n':  NXPutc(stream, '\\'); NXPutc(stream, 'n'); break;
                    157:            case '\r':  NXPutc(stream, '\\'); NXPutc(stream, 'r'); break;
                    158:            case '\t':  NXPutc(stream, '\\'); NXPutc(stream, 't'); break;
                    159:            case '\v':  NXPutc(stream, '\\'); NXPutc(stream, 'v'); break;
                    160:            case '\"':  NXPutc(stream, '\\'); NXPutc(stream, '"'); break;
                    161:            case '\\':  NXPutc(stream, '\\'); NXPutc(stream, '\\'); break;
                    162:            default: NXPutc(stream, ch);
                    163:        }
                    164:     }
                    165:     NXPutc(stream, '"');
                    166: }
                    167: 
                    168:     
                    169: - readFromStream:(NXStream *)stream {
                    170:     int        ch;
                    171:     NXZone *zone = [self zone];
                    172:     if (!stream) return nil;
                    173:     while ((ch = skipSpace(stream)) != EOF) {
                    174:        switch (ch) {
                    175:            case '/':
                    176:                ch = NXGetc(stream);
                    177:                if (ch != '*') goto nope;
                    178:                while ((ch = NXGetc(stream)) != EOF) {
                    179:                    if (ch == '*') {
                    180:                        ch = NXGetc(stream);
                    181:                        if (ch == '/') break;
                    182:                        NXUngetc(stream);
                    183:                    }
                    184:                }
                    185:                if (ch == EOF) goto nope;
                    186:                break;
                    187:            case '"': {
                    188:                char    key[MAX_NXSTRINGTABLE_LENGTH+1];
                    189:                char    value[MAX_NXSTRINGTABLE_LENGTH+1];
                    190:                ch = parseWord(stream, key);
                    191:                if (ch != '"') goto nope;
                    192:                ch = skipSpace(stream);
                    193:                if (ch == '=') {
                    194:                    ch = skipSpace(stream);
                    195:                    if (ch != '"') goto nope;
                    196:                    ch = parseWord(stream, value);
                    197:                    if (ch != '"') goto nope;
                    198:                    ch = skipSpace(stream);
                    199:                } else {
                    200:                    strcpy(value, key);
                    201:                }
                    202:                if (ch != ';') goto nope;
                    203:                free([self insertKey:NXUniqueString(key) 
                    204:                    value:NXCopyStringBufferFromZone(value, zone)]);
                    205:                break;
                    206:            }
                    207:            default:    goto nope;
                    208:        }
                    209:     }
                    210:     return self;
                    211:   nope:
                    212:     {
                    213:         extern void _NXLogError(const char *format, ...);
                    214:         if (ch == EOF)
                    215:             _NXLogError ("NXStringTable: parse error before end of stream");
                    216:         else
                    217:             _NXLogError ("NXStringTable: parse error before '%c'", ch);
                    218:         return nil;
                    219:     }
                    220: }
                    221: 
                    222: - readFromFile:(const char *)fileName {
                    223:     NXStream   *stream = NXMapFile(fileName, NX_READONLY);
                    224:     id retval = [self readFromStream:stream];
                    225:     if (stream) NXCloseMemory(stream, NX_FREEBUFFER);
                    226:     return retval;
                    227: }
                    228: 
                    229: + newFromStream:(NXStream *)stream {
                    230:     id table;
                    231:     if (! stream) return nil;
                    232:     table = [self new];
                    233:     if (![table readFromStream:stream])
                    234:        table = [table free];
                    235:     return table;
                    236: }
                    237:     
                    238: + newFromFile:(const char *)fileName {
                    239:     id table;
                    240:     table = [self new];
                    241:     if (![table readFromFile:fileName])
                    242:        table = [table free];
                    243:     return table;
                    244: }
                    245: 
                    246: - writeToStream:(NXStream *)stream {
                    247:     NXHashState                state = [self initState];
                    248:     NXAtom             key;
                    249:     const char         *value;
                    250:     while ([self nextState:&state key:(const void **)&key value:(void **)&value]) {
                    251:        writeWord(stream, key);
                    252:        if (strcmp(key, value)) {
                    253:            NXPrintf(stream, "\t= ");
                    254:            writeWord(stream, value);
                    255:        }
                    256:        NXPrintf(stream, ";\n");
                    257:     }
                    258:     return self;
                    259: }
                    260:     
                    261: - writeToFile:(const char *)fileName {
                    262:     NXStream   *stream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
                    263:     int                res;
                    264:     [self writeToStream:stream];
                    265:     res = NXSaveToFile(stream, fileName);
                    266:     NXCloseMemory(stream, NX_FREEBUFFER);
                    267:     return (res) ? nil : self;
                    268: }
                    269: 
                    270: @end
                    271: #endif /* KERNEL */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.