"====================================================================== | | C preprocessor string literal unquoter layer | | $Revision: 1.7.5$ | $Date: 2000/05/28 16:56:52$ | $Author: pb$ | ======================================================================" "====================================================================== | | Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc. | Written by Steve Byrne. | | This file is part of GNU Smalltalk. | | GNU Smalltalk 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, or (at your option) any later version. | | GNU Smalltalk 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 | GNU Smalltalk; see the file COPYING. If not, write to the Free Software | Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ======================================================================" " | Change Log | ============================================================================ | Author Date Change | " FileStream fileIn: 'CToken.st' ifMissing: #CToken ! PushBackStream subclass: #StringUnquoteStream instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: nil ! StringUnquoteStream comment: 'I process a sequence of tokens, looking for strings or character literals. When I find them, I scan them for any occurance of quoted characters, and remove the quoting character, converting any special characters (such as "\n") into their internal representation. I yield a stream of tokens where strings and chars are "fixed"'! !StringUnquoteStream methodsFor: 'accessing'! next | result nextTok | result _ super next. ((result isKindOf: StringTok) or: [ result isKindOf: CharLiteralTok ]) ifTrue: [ ^self processQuotedChars: result ] ifFalse: [ ^result ] ! ! !StringUnquoteStream methodsFor: 'private'! processQuotedChars: aLiteral "Note that characters are also represented as strings" | string changed rStream wStream ch | string _ aLiteral value. changed _ false. rStream _ ReadStream on: string. wStream _ WriteStream on: (String new: string size). [ rStream atEnd ] whileFalse: [ ch _ rStream next. ch == $\ ifTrue: [ changed _ true. ch _ self parseEscapedChar: rStream. ]. wStream nextPut: ch. ]. changed ifTrue: [ ^(aLiteral class) value: wStream contents ] ifFalse: [ ^aLiteral ] ! parseEscapedChar: aStream "called right after \ in a string or a character literal" | ch num count | ch _ aStream next. ch == $b ifTrue: [ ^Character value: 8 ]. ch == $n ifTrue: [ ^Character value: 10 ]. ch == $r ifTrue: [ ^Character value: 13 ]. ch == $f ifTrue: [ ^Character value: 12 ]. ch == $t ifTrue: [ ^Character value: 9 ]. ch == $v ifTrue: [ ^Character value: 11 ]. " this should probably go away " ch == (Character nl) ifTrue: [ ch _ aStream next. ch == $\ ifTrue: [ ^self parseEscapedChar: aStream ] ifFalse: [ ^ch ] ]. ch == $\ ifTrue: [ ^$\ ]. ch == $' ifTrue: [ ^$' ]. ch == $" ifTrue: [ ^$" ]. ch == $x ifTrue: [ "have \xhhh" ch _ aStream next. num _ 0. count _ 0. [ (self isDigit: ch base: 16) and: [ count < 3 ] ] whileTrue: [ num _ num * 16 + ch digitValue. aStream next. ch _ aStream peek. count _ count + 1 ]. ^Character value: num ]. (self isDigit: ch base: 8) ifTrue: [ "have \ooo" num _ 0. count _ 0. [ (self isDigit: ch base: 8) and: [ count < 3 ] ] whileTrue: [ num _ num * 8 + ch digitValue. aStream next. ch _ aStream peek. count _ count + 1 ]. ^Character value: num ]. self error: 'Illegal quoted character' ! !