home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-06-19 | 7.9 KB | 329 lines | [TEXT/CWIE] |
- /*
- Problem 04 - Text Processing
-
- const
- kMaxHandleSize = 1000000;
- const
- kActionMove = 1;
- kActionInsert = 2;
- kActionDelete = 3;
- kActionSearch = 4;
- kActionSearchAndReplace = 5;
- const
- kFlagCaseSensitiveBit = 0;
- kFlagGlobalBit = 1;
- kFlagBackwardsBit = 2;
- type
- ActionRecord = record
- action: UInt32;
- amount: SInt32;
- flags: UInt32;
- search: Str255;
- replace: Str255;
- end;
- ActionRecordArray = array[0..0] of ActionRecord;
- ActionRecordArrayPtr = ^ActionRecordArray;
-
- procedure TextProcess( data: Handle; action_count: UInt32; actions:
- ActionRecordArrayPtr );
-
- Given an unlocked handle to a block of text, you need to apply a sequence of
- actions to the data. You will be required to insert text, delete text, search
- for text, search for and replace text. All required actions take place at the
- position of the current selection pointer, which starts at zero, before the
- first character in the data. In response to each of the action commands you
- need to perform the following:
-
- kActionMove - move the internal position forward by the amount field (which may
- be negative). (Example, kActionMove with amount set to kMaxHandleSize will set
- the internal pointer to be GetHandleSize( data )).
-
- kActionInsert - Insert the replace string at the current location. (Example,
- if the internal pointer is GetHandleSize( data ), then the replace string will
- be appended to the handle.
-
- kActionDelete - Delete the number of characters specified by the amount field.
- The internal position pointer is never moved. If the amount field is greater
- than the number of characters after the internal pointer, then fewer characters
- are deleted such that the handle is truncated at the current value of the
- selection pointer.
-
- kActionSearch - search forward (backwards if the kFlagBackwardsBit is set in
- the flags field) for the search field (case sensitively if the
- kFlagCaseSenstitiveBit is set in the flags field). The position pointer should
- be set to point before the first character of the string if it is found, or at
- GetHandleSize (zero if backwards) if not found. If there is a match at the
- initial position, it is not counted (ie, kActionMove -kMaxHandleSize, kSearch
- 'hello', kSearch 'hello' finds the second occurance of 'hello').
-
- kActionSearchAndReplace - search forward (or backward if the kFlagBackwardsBit
- is set in the flags field), but when a match is found, replace it with the
- replace string, leaving the position pointer unmoved. If the kFlagGlobalBit is
- set in the flags field, continue searching as long matches continues to be
- found. Repeated searches begin after the previous replace string (i.e., never
- replace any characters of the replace string). For example, if you replace
- 'aaa' with 'ABA' (case insensitively) in 'aaaaaaaa' you will get 'ABAABAaa',
- not 'ABABABAa'. Replace never moves the internal position pointer.
-
- The internal selection pointer is constrained to be in the range of 0 and
- GetHandleSize(data), inclusive, at all times. Should any action cause the
- selection pointer to become less than zero (or greater than GetHandleSize),
- then you must reset it to zero (or GetHandleSize, respectively). The handle
- size will never exceed 1 Meg, and you will have plenty of memory to play with.
-
- Characters from chr(127)-chr(255) will never appear in the handle or any
- strings.
- */
-
- #include "Solution.h"
- #include <ctype.h>
-
- // Fill in your solution and then submit this folder
-
- // Team Name: Jager & Quinn
-
- enum {
- kFlagCaseSenstitiveMask = 0x0001,
- kFlagGlobalMask = 0x0002,
- kFlagBackwardsMask = 0x0004,
- };
-
- static void FixCursor(Handle data, long* cursor)
- {
- if (*cursor < 0)
- {
- *cursor = 0;
- }
- if (*cursor > GetHandleSize(data) )
- {
- *cursor = GetHandleSize(data);
- }
- }
-
- static void DoMove(Handle data, long* cursor, SInt32 amt)
- {
- *cursor += amt;
- FixCursor(data,cursor);
- }
-
- static void DoInsert(Handle data, long* cursor, Str255 str)
- {
- long strlen = str[0] & 0x00FF;
- long datalen = GetHandleSize(data);
-
- FixCursor(data,cursor);
- if (strlen > 0)
- {
-
- if (*cursor >= datalen)
- {
- PtrAndHand(&str[1],data,strlen);
- }
- else
- {
- SetHandleSize(data, datalen + strlen);
- BlockMoveData(&(*data)[*cursor],&(*data)[*cursor+strlen],datalen - *cursor);
- BlockMoveData(&str[1],&(*data)[*cursor],strlen);
- }
- }
- FixCursor(data,cursor);
- }
-
- static void DoDelete(Handle data, long* cursor, SInt32 amt)
- {
- FixCursor(data,cursor);
- if (amt > 0)
- {
- long datalen = GetHandleSize(data);
-
- if (*cursor + amt >= datalen)
- {
- SetHandleSize(data,*cursor);
- }
- else
- {
- BlockMoveData(&(*data)[*cursor+amt],&(*data)[*cursor],datalen - *cursor - amt);
- SetHandleSize(data,datalen - amt);
- }
- }
- FixCursor(data,cursor);
- }
-
- static Boolean DoMatch(UInt32 flags,char *s1,char *s2,long len)
- {
- if ((flags & kFlagCaseSenstitiveMask) == kFlagCaseSenstitiveMask)
- {
- while (len > 0)
- {
- if (*s1 != *s2)
- {
- break;
- }
- s1++;
- s2++;
- len--;
- }
- }
- else
- {
- while (len > 0)
- {
- if (toupper(*s1) != toupper(*s2))
- {
- break;
- }
- s1++;
- s2++;
- len--;
- }
- }
-
- return (len == 0);
- }
-
- static Boolean DoSearchForwards(Handle data, long* cursor, UInt32 flags, Str255 str)
- {
- long strlen = str[0] & 0x00FF;
- long datalen = GetHandleSize(data);
-
- *cursor += 1;
- while (*cursor + strlen <= datalen)
- {
- if (DoMatch(flags,&(*data)[*cursor],(char*) &str[1],strlen) )
- {
- return true;
- }
- *cursor += 1;
- }
- *cursor = datalen;
- return false;
- }
-
- static Boolean DoSearchBackwards(Handle data, long* cursor, UInt32 flags, Str255 str)
- {
- long strlen = str[0] & 0x00FF;
- long datalen = GetHandleSize(data);
-
- *cursor -= 1;
- if (*cursor + strlen > datalen)
- {
- *cursor = datalen - strlen;
- }
- while (*cursor >= 0)
- {
- if (DoMatch(flags,&(*data)[*cursor],(char*) &str[1],strlen) )
- {
- return true;
- }
- *cursor -= 1;
- }
- *cursor = 0;
- return false;
- }
-
- static Boolean DoSearch(Handle data, long* cursor, UInt32 flags, Str255 str)
- {
- if ((flags & kFlagBackwardsMask) == kFlagBackwardsMask)
- {
- return DoSearchBackwards(data,cursor,flags,str);
- }
- else
- {
- return DoSearchForwards(data,cursor,flags,str);
- }
- }
-
- static Boolean DoOneReplaceForwards(Handle data, long* cursor, UInt32 flags, Str255 str,Str255 rlpc)
- {
- if ( DoSearchForwards(data,cursor,flags,str) )
- {
- DoDelete(data,cursor,(str[0] & 0x00FF));
- DoInsert(data,cursor,rlpc);
- *cursor =+ (rlpc[0] & 0x00FF);
- FixCursor(data,cursor);
- return true;
- }
- return false;
- }
-
- static Boolean DoOneReplaceBackwards(Handle data, long* cursor, UInt32 flags, Str255 str,Str255 rlpc)
- {
- if ( DoSearchBackwards(data,cursor,flags,str) )
- {
- DoDelete(data,cursor,(str[0] & 0x00FF));
- DoInsert(data,cursor,rlpc);
- *cursor =- (str[0] & 0x00FF);
- FixCursor(data,cursor);
- return true;
- }
- return false;
- }
-
- static Boolean DoOneReplace(Handle data, long* cursor, UInt32 flags, Str255 str,Str255 rlpc)
- {
- if ((flags & kFlagBackwardsMask) == kFlagBackwardsMask)
- {
- return DoOneReplaceBackwards(data,cursor,flags,str,rlpc);
- }
- else
- {
- return DoOneReplaceForwards(data,cursor,flags,str,rlpc);
- }
- }
-
- static void DoReplace(Handle data, long* cursor, UInt32 flags, Str255 str,Str255 rlpc)
- {
- FixCursor(data,cursor);
-
- long cur = *cursor;
-
- if ( (flags & kFlagGlobalMask) == kFlagGlobalMask)
- {
- while (DoOneReplace(data,&cur,flags,str,rlpc)) {};
- }
- else
- {
- DoOneReplace(data,&cur,flags,str,rlpc);
- }
- FixCursor(data,cursor);
- }
-
- pascal void TextProcess( Handle data, UInt32 action_count, ActionRecord *actions )
- {
- long idx = 0;
- long cursor = 0;
-
- if ( (data == 0) || (actions == 0) )
- {
- return;
- }
-
- while (idx < action_count)
- {
- switch (actions[idx].action) {
- case kActionMove :
- DoMove(data,&cursor,actions[idx].amount);
- break;
-
- case kActionInsert :
- DoInsert(data,&cursor,actions[idx].search);
- break;
-
- case kActionDelete :
- DoDelete(data,&cursor,actions[idx].amount);
- break;
-
- case kActionSearch :
- DoSearch(data,&cursor,actions[idx].flags,actions[idx].search);
- break;
-
- case kActionSearchAndReplace :
- DoReplace(data,&cursor,actions[idx].flags,actions[idx].search,actions[idx].replace);
- break;
-
- }
- idx++;
- }
-
- return;
- }