| top | | | ^ | | | | | | section top | | 10. Symbol string type ::
The symbol strings manipulated by these commands have the characteristics
-
Once a string is created (by sym ensym, by interpretting
the string interpretation, or by concatenation sym concat)
it is not thereafter modified by adding symbols, modifying symbols,
or removing symbols from the interior.
-
The string will need to be traversed front to back or back to front
efficiently.
Internally a symbol string is a shared vector of UTF-8 strings. The original Tcl
object for the string and all substrings refer back to the same vector, with
pointers which identify which substring the Tcl object refers to. The shared
vector has its own reference count. The UTF-8 strings are unescaped; escaping
is only done when converting the internal representation to the string
representation; unescaping when converting string to internal.
This makes extracting deescaped symbols easy: just put the UTF-8 string
into a Tcl string. Traversing with first, rest, front, and last involve merely
adjusting an index and length field without any copying.
Angle marks are used to enclose nested symbol sets.
The SymbolString has reference count and then a start of string
pointer for each symbol, with one last pointer pointing after the last string.
All symbol strings are stored contiguously in one vector. The SymbolString
does not maintain the string length; that is stored in each Tcl object. The first
Tcl object has the entire length; substrings derive their length from that
object (or another substring object).
Strings may be labeled, the label being on one symbol of the string
or the entire string. When the string is copied or substringed, the copy
has a copy of the labels. A symbol label is identified by the
symbol offset; a substring symbol will need to use its new offset to get
the same label. An label is property-value pair of a property
(of the string or symbol) name with the property value. If an label
value is requested but does not exist, an empty Tcl string is returned.
Labels are preserved in set operations. In a concatenation, each
symbol retains its own labels. String labels for the each original
string are combined into a list of labels of the concatenated string.
- type struct SymbolString—Shared symbol string vector.
| - int refCount—Number of Tcl objects referring to this symbol string.
| - chars symbol—Pointer to symbol string; symbol[i] is the first byte address of the ith symbol; its length is symbol[i+1]-symbol[i].
| - chars (strings)—The strings are stored in the same memory block, after the pointers.
|
|
|
struct SymbolString {
int refCount;
chars symbol[1];
};
| ^ | Definition continued at: 11. | | | | | section top | | - type struct SymbolStringRef—Symbol string reference and size.
| - SymbolString symbols—The actual symbols.
| - int first—First symbol in this substring.
| - int length—Number of symbols in this substring.
| - bool Reversed—If the string has been reversed.
|
|
|
struct SymbolStringRef {
SymbolString *symbols;
int first;
int length;
Obj labels;
bool reversed;
};
| ^ | | | | | | section top | |
typedef struct SymbolString SymbolString;
typedef struct SymbolStringRef SymbolStringRef;
| ^ | | | | | | section top | |
#define refReverse(ref) ((ref)->reversed = !(ref)->reversed)
#define refIndex(ref,i) ((ref)->first+((ref)->reversed ? (ref)->length-(i)-1 : (i)))
#define origIndex(ref,p) ((ref)->reversed ? (ref)->first + (ref)->length + 1 - (p) : (p) - (ref)->first)
#define symbolString(ref,i) ((ref)->symbols->symbol[refIndex(ref,i)])
#define symbolLength(ref,i) ((ref)->symbols->symbol[refIndex(ref,i)+1]-(ref)->symbols->symbol[refIndex(ref,i)])
#define substringAdvance(ref,o) ( \
((ref)->reversed ? 0 : ((ref)->first += (o))), \
(ref)->length -= (o), \
((ref)->length<0 ? ((ref)->length = 0) : 0), \
0)
#define substringLength(ref,n) ( \
((ref)->reversed && (n)<(ref)->length ? ((ref)->first += (ref)->length-(n)) : 0), \
(ref)->length>(n) ? ((ref)->length = (n)) : 0, \
((ref)->length<0 ? ((ref)->length = 0) : 0), \
0)
static int symcmp(Obj x,Obj y) {
SymbolStringRef *rx; Obj X = extractSymbolString(x,&rx);
SymbolStringRef *ry; Obj Y = extractSymbolString(y,&ry);
int i,cc;
for (i=0,cc=0; cc==0; i++)
if (i>=rx->length && i>=ry->length) break;
else if (i>=rx->length) cc = -1;
else if (i>=ry->length) cc = 1;
else {
chars rxfca = symbolString(rx,i); int rxlen = symbolLength(rx,i);
chars ryfca = symbolString(ry,i); int rylen = symbolLength(ry,i);
cc = memcmp(rxfca,ryfca,rxlen<rylen?rxlen:rylen);
if (cc==0) cc = rxlen-rylen;
}
decr(X);
decr(Y);
return cc;
}
static int symcmpq(const void *x, const void *y) {
Obj *X = x,*Y = y; return symcmp(*X,*Y);
}
static int symcmpb(const void *x, const void *y) {
Obj X = x,*Y = y; return symcmp(X,*Y);
}
| ^ | | | | | | section top | | - protocol Create a SymbolString
| - input int nsymbols—Number of symbols.
| - input int ncharacters—Total number of characters.
| - output SymbolStringRef* ref—String reference.
| - input Obj labels—Labels to copy in or NULL..
|
|
|
ref = heap(SymbolStringRef); ref->first = 0; ref->length = nsymbols; ref->reversed = false;
ref->labels = incr(labels);
if (nsymbols==0) {
ref->symbols = 0;
}else {
chars p = allocate(sizeof(SymbolString) + nsymbols*sizeof(chars) + ncharacters+1);
SymbolString *symbolString = (SymbolString*)p;
symbolString->refCount = 1;
symbolString->symbol[0] = p + sizeof(SymbolString) + nsymbols*sizeof(chars);
ref->symbols = symbolString;
}
| ^ | | | | | | section top | | - protocol Append to SymbolString
| - io SymbolStringRef* ref—Reference to string appended to.
| - input int i—The ith symbol added.
| - input chars symbol—Symbol characters.
| - input int length—Number of characters; if -1, to zero byte.
|
|
|
SymbolString *symbolString = ref->symbols;
if (length<0) length = symbol ? strlen(symbol) : 0;
memcpy(symbolString->symbol[i],symbol,length);
symbolString->symbol[i+1] = symbolString->symbol[i]+length;
| ^ | | | | | | section top | | - protocol Duplicate a SymbolString
| - input SymbolStringRef* ref—Previous reference.
| - output SymbolStringRef* newref—New reference.
|
|
|
newref = heap(SymbolStringRef);
*newref = *ref;
incr(newref->labels);
if (newref->symbols) newref->symbols->refCount += 1;
| ^ | | | | | | section top | | - protocol Free a SymbolString reference
| - io SymbolStringRef* ref—The reference.
|
|
|
SymbolString *symbolString = ref->symbols;
if (symbolString) {
symbolString->refCount -= 1;
if (symbolString->refCount==0) {
dispose(symbolString);
}
}
decr(ref->labels);
dispose(ref);
| ^ | | | | | | section top | | 18. Symbol string encoding ::
The reserved characters are comma ",", vertical bar "|",
full stop ".",
open brace "{", close brace "}",
quote """, backslash "\",
at sign "@",
colon ":",
white space,
or a hash "#" followed by "NS" or two hexidecimal digits.
Angle marks are reserved to enclose nested symbol sets.
A reserved character is escaped by replacing it with "#" followed
by the two hexidecimal digit ASCII code of the character. However unless the string
representations are directly manipulated, it should not be necessary to worry about
escaping; commands are provided to convert between Tcl lists of strings and symbol
set strings, and escaping is removed when individual symbols are returned.
- protocol Encode a string
| - io chars s—Beginning of the string to encode; incremented by n.
| - io int n—Length of the string to encode (to zero byte if -1); decremented to zero.
| - output Tcl_DString* DS—Encoded string.
|
|
|
if (n<0) n = strlen(s);
for (; n>0; n--,s++) {
if (isspace(*s) || *s==',' || *s=='|' || *s=='.' || *s=='@'
|| *s=='{' || *s=='}' || *s==042 || *s=='\\' || *s==':'
|| n>=3 && s[0]==043 && isxdigit(s[1]) && isxdigit(s[2])
|| n>=3 && s[0]==043 && s[1]=='N' && s[2]=='S'
) {
char T[3];
T[0] = 043;
T[1] = "0123456789abcdef"[(*s>>4)&0xF];
T[2] = "0123456789abcdef"[(*s )&0xF];
Tcl_DStringAppend(DS,T,3);
}else if (*s=='<') {
int d = 0;
for (; n>0; n--,s++) {
if (*s=='<') d++;
else if (*s=='>' && --d==0) break;
Tcl_DStringAppend(DS,s,1);
}
Tcl_DStringAppend(DS,s,1);
}else {
Tcl_DStringAppend(DS,s,1);
}
}
| ^ | | | | | | section top | | - protocol Decode a string
| - io chars s—Beginning of the string to decode; incremented by n.
| - io int n—Length of the string to decode (to zero byte if -1); decremented to zero.
| - output Tcl_DString* DS—Decoded string.
|
|
|
if (n<0) n = strlen(s);
for (; n>0; n--,s++) {
if (n>=3 && s[0]==043 && isxdigit(s[1]) && isxdigit(s[2])) {
char T[3],S[1];
T[0] = s[1]; T[1] = s[2]; T[2] = 0;
*S = strtol(T,0,16);
Tcl_DStringAppend(DS,S,1);
n -= 2; s += 2;
}else if (*s=='<') {
int d = 0;
for (; n>0; n--,s++) {
if (*s=='<') d++;
else if (*s=='>' && --d==0) break;
Tcl_DStringAppend(DS,s,1);
}
Tcl_DStringAppend(DS,s,1);
}else {
Tcl_DStringAppend(DS,s,1);
}
}
| ^ | | | | | | section top | |
int NE; Obj *PE; bool set = true;
if (N<3) {
Tcl_WrongNumArgs(intr,2,P,"[string|set] tcl-value"); return TCL_ERROR;
}else if (N>4) {
Tcl_WrongNumArgs(intr,4,P,": too many parameters"); return TCL_ERROR;
}else if (N==4 && (strbegins("st",Tcl_GetString(P[2])) || strbegins("-st",Tcl_GetString(P[2])))) {
if (Tcl_ListObjGetElements(intr,P[3],&NE,&PE)!=TCL_OK) return TCL_ERROR;
set = false;
}else if (N==4 && (strbegins("se",Tcl_GetString(P[2])) || strbegins("-se",Tcl_GetString(P[2])))) {
if (Tcl_ListObjGetElements(intr,P[3],&NE,&PE)!=TCL_OK) return TCL_ERROR;
set = true;
}else if (N==4) {
rprintf(intr,"expected 'string' or 'set': %{y}s",P[2]);
return TCL_ERROR;
}else {
if (Tcl_ListObjGetElements(intr,P[2],&NE,&PE)!=TCL_OK) return TCL_ERROR;
set = true;
}
| ^ | | | | | | section top | | 21. sym encode :: - sym encode
-
Encode Tcl list values into escaped and delimited strings expected
by the symbol string operators. The Tcl list form of a symbol string
is a list of the unescaped symbol names; the empty string is an empty
list. The Tcl list form of a symbol string set is a list of Tcl symbol string
lists; the empty set is the empty list.
-
If the type string is specified, the Tcl-list-representation
is the one deep Tcl list form of a symbol string. If the type set
is specified or no type is specified, the Tcl-list-representation
is the two deep Tcl list form of a symbol string set.
-
For example
- wyrm::sym encode {{} a {b c} {d e f} {{g h i}} xyz {abc def} {a,b c|d e.f}}
returns
- #NS|a|b,c|d,e,f|g#20h#20i|xyz|abc,def|a#2cb,c#7cd,e#2ef
And
- wyrm::sym encode set {}
returns
- ""
And
- wyrm::sym encode string {abc def xyz {p q r}}
returns
- abc,def,xyz,p#20q#20r
And
- wyrm::sym encode string {}
returns
- #NS
if (set) {
Obj *elem = NE ? nheap(NE,Obj) : 0; int i,rc;
zero(NE,Obj,elem);
for (i=0,rc=TCL_OK; i<NE && rc==TCL_OK; i++) {
int n; Obj *p;
rc = Tcl_ListObjGetElements(intr,PE[i],&n,&p);
if (rc==TCL_OK) elem[i] = incr(newSymbolStringObj(n,p));
}
if (rc==TCL_OK) {
Tcl_SetObjResult(intr,newSymbolSetObj(0,elem,NE,0,true));
}else {
for (i=0; i<NE; i++) decr(elem[i]); dispose(elem);
}
return rc;
}else {
Tcl_SetObjResult(intr,newSymbolStringObj(NE,PE));
return TCL_OK;
}
| ^ | | | | | | section top | |
Obj ss; bool set = true;
if (N<3 || N>4) {
Tcl_WrongNumArgs(intr,2,P,"[string|set] tcl-value"); return TCL_ERROR;
}else if (N==4 && (strbegins("st",Tcl_GetString(P[2])) || strbegins("-st",Tcl_GetString(P[2])))) {
ss = P[3]; set = false;
}else if (N==4 && (strbegins("se",Tcl_GetString(P[2])) || strbegins("-se",Tcl_GetString(P[2])))) {
ss = P[3]; set = true;
}else if (N==4) {
rprintf(intr,"expected 'string' or 'set': %{y}s",P[2]);
return TCL_ERROR;
}else {
ss = P[2]; set = true;
}
| ^ | | | | | | section top | |
if (set) {
int e; SymbolSet *S = extractSymbolSet(ss); Obj L = incr(Tcl_NewObj());
for (e=0; e<S->card; e++) {
SymbolStringRef *ref; Obj string = extractSymbolString(S->elem[e],&ref);
if (string) {
int i; Obj E = incr(Tcl_NewObj());
for (i=0; i<ref->length; i++) {
Tcl_ListObjAppendElement(0,E,Tcl_NewStringObj(symbolString(ref,i),symbolLength(ref,i)));
}
Tcl_ListObjAppendElement(0,L,E); decr(E); decr(string);
}
}
Tcl_SetObjResult(intr,L); decr(L);
}else {
SymbolStringRef *ref; Obj string = extractSymbolString(ss,&ref);
if (string) {
int i; Obj E = incr(Tcl_NewObj());
for (i=0; i<ref->length; i++) {
Tcl_ListObjAppendElement(0,E,Tcl_NewStringObj(symbolString(ref,i),symbolLength(ref,i)));
}
Tcl_SetObjResult(intr,E); decr(E); decr(string);
}else {
return TCL_ERROR;
}
}
return TCL_OK;
| ^ | | | | | | section top | |
static Tcl_ObjType SymbolsType = {
"wyrm.sym.symbols",
freeSymbolString,
dupSymbolString,
updateFromSymbolString,
convertToSymbolString
};
| ^ | | | | | | section top | | - proc freeSymbolString—Free the symbol string internal representation.
| - output obj—Reference to internal symbol string is removed.
|
|
|
static void freeSymbolString(Obj obj) {
SymbolStringRef *ref = obj->internalRep.otherValuePtr;
<Free a SymbolString reference>
obj->typePtr = 0;
obj->internalRep.otherValuePtr = 0;
}
| ^ | Definition continued at: 27, 29, 31. | | | | | section top | |
static void freeSymbolString(Obj obj);
| ^ | Definition continued at: 28, 30, 32, 34, 36, 38, 40, 72, 74, 76, 78, 80, 82, 130, 135, 137, 139, 141, 144, 146, 148, 150, 174, 193, 194, 219. | | | | | section top | | - proc dupSymbolString—Duplicate the symbol string internal representation.
| - input ss—Original internal symbol string.
| - output dd—Refers to the same internal symbol string.
|
|
|
static void dupSymbolString(Obj ss,Obj dd) {
SymbolStringRef *ref = ss->internalRep.otherValuePtr;
SymbolStringRef *newref;
<Duplicate a SymbolString>
dd->typePtr = &SymbolsType;
dd->internalRep.otherValuePtr = newref;
}
| ^ | Definition continued at: 29, 31. | | | | | section top | |
static void dupSymbolString(Obj ss,Obj dd);
| ^ | Definition continued at: 30, 32, 34, 36, 38, 40, 72, 74, 76, 78, 80, 82, 130, 135, 137, 139, 141, 144, 146, 148, 150, 174, 193, 194, 219. | | | | | section top | | - proc updateFromSymbolString—Create the string representation from the internal.
| - io obj—Internal symbol string converted to string representation.
|
|
|
static void updateFromSymbolString(Obj obj) {
SymbolStringRef *ref = obj->internalRep.otherValuePtr;
Tcl_DString DS0,*DS=&DS0;
Tcl_DStringInit(DS);
if (ref->length==0) {
Tcl_DStringAppend(DS,"#NS",3);
}else {
int i; chars sep;
for (i=0,sep=""; i<ref->length; i++,sep=",") {
chars s = symbolString(ref,i);
int n = symbolLength(ref,i);
Tcl_DStringAppend(DS,sep,-1);
<Symbol string encoding>
}
}
if (ref->labels) {
Obj L = incr(Tcl_NewObj()); int n; chars s;
Obj R,*P; int N;
Tcl_DStringAppend(DS,"@P",2);
for (wyrm_assocFilter(0,ref->labels,false,0,&R,&N,&P); N>0; N-=2,P+=2) {
Obj key = P[0];
Obj data = P[1];
int n,x; chars s,q;
s = Tcl_GetStringFromObj(key,&n);
x = strtol(s,&q,10);
if (s!=q) {
Obj t = oprintf("%d%.*s",origIndex(ref,x),n-(q-s),q);
Tcl_ListObjAppendElement(0,L,t); decr(t);
Tcl_ListObjAppendElement(0,L,data);
}else {
Tcl_ListObjAppendElement(0,L,key);
Tcl_ListObjAppendElement(0,L,data);
}
}
decr(R);
s = Tcl_GetStringFromObj(L,&n);
<Symbol string encoding>
decr(L);
}
obj->length = Tcl_DStringLength(DS);
obj->bytes = nheap(obj->length+1,char);
memcpy(obj->bytes,Tcl_DStringValue(DS),obj->length);
obj->bytes[obj->length] = 0;
Tcl_DStringFree(DS);
}
| ^ | Definition continued at: 31. | | | | | section top | |
static void updateFromSymbolString(Obj obj);
| ^ | Definition continued at: 32, 34, 36, 38, 40, 72, 74, 76, 78, 80, 82, 130, 135, 137, 139, 141, 144, 146, 148, 150, 174, 193, 194, 219. | | | | | section top | | - proc convertToSymbolString—Create the internal symbol string from the string; returns TCL_OK.
| - output obj—Created internal symbol string.
|
|
|
static Obj stripLabels(chars p,int *l0,char level) {
int r = *l0,l = 0;
text:
if (r==0) return 0;
else if (*p=='@') {p++,r--; goto at;}
else {p++; r--; l++; goto text;}
at:
if (r==0) return 0;
else if (!isupper(*p)) {l++; goto text;}
else if (*p<level) {l++; goto text;}
else if (*p==level) {
chars s= p+1; int n = r-1; Obj labels = 0;
if (n>0) {
Tcl_DString DS0,*DS=&DS0;
Tcl_DStringInit(DS);
<Symbol string decoding>
labels = Tcl_NewStringObj(Tcl_DStringValue(DS),Tcl_DStringLength(DS));
Tcl_DStringFree(DS);
}
*l0 = l;
return labels;
}else return 0;
}
static int convertToSymbolString(Intr intr,Obj obj) {
if (obj && obj->typePtr==&SetType) {
SymbolSet *set = obj->internalRep.otherValuePtr;
if (set->card>0 && set->elem[0]->typePtr==&SymbolsType) {
SymbolStringRef *ref = set->elem[0]->internalRep.otherValuePtr,*newref;
<Duplicate a SymbolString>
if (set->card>1) Tcl_InvalidateStringRep(obj);
obj->typePtr = &SymbolsType;
obj->internalRep.otherValuePtr = newref;
return TCL_OK;
}
}
if (obj->typePtr!=&SymbolsType) {
int msymbols=1,nsymbols=0,*offsymbol = heap(int),i,ncharacters;
int m; chars s = Tcl_GetStringFromObj(obj,&m);
SymbolStringRef *ref;
Obj labels = stripLabels(s,&m,'P');
chars bar = memchr(s,'|',m);
Tcl_DString DS0,*DS=&DS0;
Tcl_DStringInit(DS);
if (bar) m = bar-s;
while (m>0) {
chars comma = memchr(s,',',m);
int n = comma ? comma-s : m;
m -= n;
if (n>0 && (n!=3 || memcmp(s,"#NS",3)!=0)) {
if (nsymbols+2>=msymbols) {msymbols = 2*(nsymbols+2); offsymbol = reheap(msymbols,int,offsymbol);}
offsymbol[nsymbols++] = Tcl_DStringLength(DS);
<Symbol string decoding>
}
if (comma) {m--; s++;}
}
ncharacters = offsymbol[nsymbols] = Tcl_DStringLength(DS);
<Create a SymbolString>
for (i=0; i<nsymbols; i++) {
chars symbol = Tcl_DStringValue(DS)+offsymbol[i];
int length = offsymbol[i+1]-offsymbol[i];
<Append to a SymbolString during creation>
}
dispose(offsymbol); Tcl_DStringFree(DS);
if (obj->typePtr && obj->typePtr->freeIntRepProc)
obj->typePtr->freeIntRepProc(obj);
obj->typePtr = &SymbolsType;
obj->internalRep.otherValuePtr = ref;
}
return TCL_OK;
}
| ^ | | | | | | section top | |
static int convertToSymbolString(Intr intr,Obj obj);
| ^ | Definition continued at: 34, 36, 38, 40, 72, 74, 76, 78, 80, 82, 130, 135, 137, 139, 141, 144, 146, 148, 150, 174, 193, 194, 219. | | | | | section top | | - proc newSymbolStringObj—New symbol string.
| - input nsymbols—Array size.
| - input symbolobj—Array of symbols.
|
|
|
static Obj newSymbolStringObj(int nsymbols,Obj *symbolobj) {
Obj obj = heap(Tcl_Obj);
SymbolStringRef *ref;
int i,ncharacters = 0;
Obj labels = 0;
for (i=0; i<nsymbols; i++) {
int n; Tcl_GetStringFromObj(symbolobj[i],&n); ncharacters += n;
}
<Create a SymbolString>
for (i=0; i<nsymbols; i++) {
int length; chars symbol = Tcl_GetStringFromObj(symbolobj[i],&length);
<Append to a SymbolString during creation>
}
obj->refCount = 0; obj->bytes = 0; obj->length = 0;
obj->typePtr = &SymbolsType;
obj->internalRep.otherValuePtr = ref;
return obj;
}
| ^ | | | | | | section top | |
static Obj newSymbolStringObj(int nsymbols,Obj *symbolobj);
| ^ | Definition continued at: 36, 38, 40, 72, 74, 76, 78, 80, 82, 130, 135, 137, 139, 141, 144, 146, 148, 150, 174, 193, 194, 219. | | | | | section top | | - proc newSymbolSubstringObj—Symbol substring.
| - input ref—Reference to the symbol string.
| - input o—Offset of the substring from the reference.
| - input n—Length of the substring.
|
|
|
static Obj newSymbolSubstringObj(SymbolStringRef *ref,int o,int n) {
Obj obj = heap(Tcl_Obj);
SymbolStringRef *newref;
<Duplicate a SymbolString>
substringAdvance(newref,o);
substringLength(newref,n);
obj->refCount = 0; obj->bytes = 0; obj->length = 0;
obj->typePtr = &SymbolsType;
obj->internalRep.otherValuePtr = newref;
return obj;
}
| ^ | | | | | | section top | |
static Obj newSymbolSubstringObj(SymbolStringRef *ref,int o,int n);
| ^ | Definition continued at: 38, 40, 72, 74, 76, 78, 80, 82, 130, 135, 137, 139, 141, 144, 146, 148, 150, 174, 193, 194, 219. | | | | | section top | | - proc newReversedSymbolStringObj—Symbol substring.
| - input ref—Reference to the symbol string.
|
|
|
static Obj newReversedSymbolStringObj(SymbolStringRef *ref) {
Obj obj = heap(Tcl_Obj);
SymbolStringRef *newref;
<Duplicate a SymbolString>
refReverse(newref);
obj->refCount = 0; obj->bytes = 0; obj->length = 0;
obj->typePtr = &SymbolsType;
obj->internalRep.otherValuePtr = newref;
return obj;
}
| ^ | | | | | | section top | |
static Obj newReversedSymbolStringObj(SymbolStringRef *ref);
| ^ | Definition continued at: 40, 72, 74, 76, 78, 80, 82, 130, 135, 137, 139, 141, 144, 146, 148, 150, 174, 193, 194, 219. | | | | | section top | | - proc extractSymbolString—Coerce an object to a symbol string; returns the symbol string object.
- Memory. Caller decrements reference count when done.
| - output Intr intr—Receives error messages; may be NULL.
| - io Obj obj—Coerced object.
| - output SymbolStringRef** ref—String reference or NULL if error.
|
|
|
static Obj extractSymbolString(Obj obj,SymbolStringRef **ref) {
if (!obj) {
;
}else if (obj->typePtr==&SymbolsType) {
incr(obj);
}else if (obj->typePtr==&SetType) {
SymbolSet *set = obj->internalRep.otherValuePtr;
obj = set->card ? incr(set->elem[0]) : 0;
}else if (strchr(Tcl_GetString(obj),'|')) {
SymbolSet *set = extractSymbolSet(obj);
obj = set->card ? incr(set->elem[0]) : 0;
}else {
incr(obj);
}
if (!obj) obj = incr(newSymbolStringObj(0,0));
convertToSymbolString(0,obj);
*ref = obj->internalRep.otherValuePtr;
return obj;
}
| ^ | | | | | | section top | |
static Obj extractSymbolString(Obj obj,SymbolStringRef **ref);
| ^ | Definition continued at: 72, 74, 76, 78, 80, 82, 130, 135, 137, 139, 141, 144, 146, 148, 150, 174, 193, 194, 219. | | | | | section top | |
Obj string; SymbolStringRef *ref;
if (N!=3) {
Tcl_WrongNumArgs(intr,2,P,"string"); return TCL_ERROR;
}
string = extractSymbolString(P[2],&ref);
| ^ | | | | | | section top | | | ^ | | | | | | section top | |
Tcl_SetObjResult(intr,Tcl_NewBooleanObj(ref->length==0));
decr(string);
return TCL_OK;
| ^ | | | | | | section top | | | ^ | | | | | | section top | |
Tcl_SetObjResult(intr,Tcl_NewIntObj(ref->length));
decr(string);
return TCL_OK;
| ^ | | | | | | section top | | | ^ | | | | | | section top | |
if (ref->length>0) {
Tcl_SetObjResult(intr,newSymbolSubstringObj(ref,0,1));
decr(string);
return TCL_OK;
}else {
Tcl_SetResult(intr,"empty string",TCL_STATIC);
decr(string);
return TCL_ERROR;
}
| ^ | | | | | | section top | | | ^ | | | | | | section top | |
Tcl_SetObjResult(intr,ref->length>0 ? newSymbolSubstringObj(ref,1,ref->length-1) : newSymbolStringObj(0,0));
decr(string);
return TCL_OK;
| ^ | | | | | | section top | | | ^ | | | | | | section top | |
if (ref->length>0) {
int last = ref->length-1;
Tcl_SetObjResult(intr,newSymbolSubstringObj(ref,ref->length-1,1));
decr(string);
return TCL_OK;
}else {
Tcl_SetResult(intr,"empty string",TCL_STATIC);
decr(string);
return TCL_ERROR;
}
| ^ | | | | | | section top | | | ^ | | | | | | section top | |
Tcl_SetObjResult(intr,ref->length>0 ? newSymbolSubstringObj(ref,0,ref->length-1) : newSymbolStringObj(0,0));
decr(string);
return TCL_OK;
| ^ | | | | | | section top | |
Obj string; SymbolStringRef *ref; Obj pos; long num;
if (N |
|