This is MOStringParsing.m in view mode; [Download] [Up]
// MOStringParsing.m
//
// by Mike Ferris
// Part of MOKit
// Copyright 1993, all rights reserved.
// ABOUT MOKit
// by Mike Ferris (mike@lorax.com)
//
// MOKit is a collection of useful and general objects. Permission is
// granted by the author to use MOKit in your own programs in any way
// you see fit. All other rights pertaining to the kit are reserved by the
// author including the right to sell these objects as objects, as part
// of a LIBRARY, or as SOURCE CODE. In plain English, I wish to retain
// rights to these objects as objects, but allow the use of the objects
// as pieces in a fully functional program. Permission is also granted to
// redistribute the source code of MOKit for FREE as long as this copyright
// notice is left intact and unchanged. NO WARRANTY is expressed or implied.
// The author will under no circumstances be held responsible for ANY
// consequences from the use of these objects. Since you don't have to pay
// for them, and full source is provided, I think this is perfectly fair.
#import "MOKit/MOString.h"
extern char *MOBuildStringFromFormatV(const char *formatStr,
va_list param_list);
@implementation MOString(Parsing)
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// =-=-=-=-=-=-=-=-=-=-=-=-=-= Parsing MOStrings =-=-=-=-=-=-=-=-=-=-=-=-=-=
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- (char)charAt:(int)index
// Returns the character at index. Returns '\0' if str is NULL or index
// is beyond the end of the str.
{
if ((index<0) || (isUnique?!uStr:!str) || (index>=len)) {
return '\0';
}
return (isUnique?uStr[index]:str[index]);
}
- substringFrom:(int)start to:(int)end
// Returns a new String object containing the specified substring of the
// receiver's contents. Returns nil if the indexes are bad or the receiving
// String is empty. The new string is NOT unique regardless of whether the
// receiver is or not.
//
// Note that the string object returned is always the receiving object's
// class even if the receiving object is a subclass!
{
id newStr;
char *buf;
int i,j;
if ((start<0) || (end<0) || (start>end) || (isUnique?!uStr:!str) ||
(end>len)) {
return nil;
}
NX_MALLOC(buf, char, end-start+2);
for (i=start, j=0; i<=end; i++, j++) {
buf[j]=(isUnique?uStr[i]:str[i]);
}
buf[j]='\0';
newStr = [[[self class] allocFromZone:[self zone]]
initStringValueNoCopy:buf shouldFree:YES];
return newStr;
}
- (int)positionOf:(char)aChar nthOccurrence:(int)n
// Returns the index of the nth occurrence of aChar in the string.
// If n is negative it counts backwards from the end of the string.
// If there is no nth occurrence of aChar or the string is NULL this
// returns -1. This won't work for aChar=='\0' unless n==1.
{
int numFound=0, i;
BOOL fromBack = (n<0);
if ((isUnique?!uStr:!str) || (n==0)) {
return -1;
}
n = abs(n);
for (i=(fromBack?len:0); (fromBack?i>=0:i<=len); (fromBack?i--:i++)) {
if ((isUnique?uStr[i]:str[i])==aChar) {
numFound++;
if (numFound==n) {
return i;
}
}
}
return -1;
}
- (int)countOccurrencesOf:(char)aChar
{
int i;
int count = 0;
for (i=0; i<len; i++) {
if ((isUnique?uStr:str)[i] == aChar) {
count++;
}
}
return count;
}
- tokenize:(const char *)breakChars into:aList
// Uses strtok() on a COPY of the strings contents to break the string
// into tokens. Fills aList with MOString objects containing (in order)
// the tokens from strtok. If aList is nil a list is allocated, but the
// caller is still responsible for freeing it. This is a "safe" usage of
// strtok() (although not "thread-safe"). strtok() relies on static
// variables to keep track of where it is in between calls. This is "safe"
// in that we parse the whole damn thing before returning, so no one
// in this thread will start parsing another string with strtok() while
// we're in the middle of ours.
//
// Note that the string object returned is always the receiving object's
// class even if the receiving object is a subclass!
{
char *toker, *token;
// Allocate the list if we need to.
if (aList == nil) {
aList = [[List allocFromZone:[self zone]] init];
}
// Copy our contents into a scratch buffer.
NX_MALLOC(toker, char, len+1);
strcpy(toker, (isUnique?uStr:str));
// Start toking on it.
token = strtok(toker, breakChars);
while (token) {
[aList addObject:[[[self class] allocFromZone:[self zone]]
initStringValue:token]];
token = strtok(NULL, breakChars);
}
// As you allocate, so shall ye free.
NX_FREE(toker);
return aList;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.