summaryrefslogtreecommitdiffstats
path: root/generic/tclStrIdxTree.h
blob: e80d3dbd17a0ee06570d8366f69268b2df45074c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * tclStrIdxTree.h --
 *
 *	Declarations of string index tries and other primitives currently 
 *  back-ported from tclSE.
 *
 * Copyright (c) 2016 Serg G. Brester (aka sebres)
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TCLSTRIDXTREE_H
#define _TCLSTRIDXTREE_H


/*
 * Main structures declarations of index tree and entry
 */

typedef struct TclStrIdxTree {
    struct TclStrIdx *firstPtr;
    struct TclStrIdx *lastPtr;
} TclStrIdxTree;

typedef struct TclStrIdx {
    struct TclStrIdxTree childTree;
    struct TclStrIdx *nextPtr;
    struct TclStrIdx *prevPtr;
    Tcl_Obj *key;
    int	     length;
    int	     value;
} TclStrIdx;


/*
 *----------------------------------------------------------------------
 *
 * TclUtfFindEqual, TclUtfFindEqualNC --
 *
 *  Find largest part of string cs in string cin (case sensitive and not). 
 *
 * Results:
 *  Return position of UTF character in cs after last equal character.
 *
 * Side effects:
 *  None.
 *
 *----------------------------------------------------------------------
 */

inline const char *
TclUtfFindEqual(
    register const char *cs,	/* UTF string to find in cin. */
    register const char *cse,	/* End of cs */
    register const char *cin,	/* UTF string will be browsed. */
    register const char *cine)	/* End of cin */
{
    register const char *ret = cs;
    Tcl_UniChar ch1, ch2;
    do {
	cs += TclUtfToUniChar(cs, &ch1);
	cin += TclUtfToUniChar(cin, &ch2);
	if (ch1 != ch2) break;
    } while ((ret = cs) < cse && cin < cine);
    return ret;
}

inline const char *
TclUtfFindEqualNC(
    register const char *cs,	/* UTF string to find in cin. */
    register const char *cse,	/* End of cs */
    register const char *cin,	/* UTF string will be browsed. */
    register const char *cine,	/* End of cin */
    const char	     **cinfnd)	/* Return position in cin */
{
    register const char *ret = cs;
    Tcl_UniChar ch1, ch2;
    do {
	cs += TclUtfToUniChar(cs, &ch1);
	cin += TclUtfToUniChar(cin, &ch2);
	if (ch1 != ch2) {
	    ch1 = Tcl_UniCharToLower(ch1);
	    ch2 = Tcl_UniCharToLower(ch2);
	    if (ch1 != ch2) break;
	}
	*cinfnd = cin;
    } while ((ret = cs) < cse && cin < cine);
    return ret;
}

/*
 * Primitives to safe set, reset and free references.
 */

#define Tcl_UnsetObjRef(obj) \
  if (obj != NULL) { Tcl_DecrRefCount(obj); obj = NULL; }
#define Tcl_InitObjRef(obj, val) \
  obj = val; if (obj) { Tcl_IncrRefCount(obj); }
#define Tcl_SetObjRef(obj, val) \
if (1) { \
  Tcl_Obj *nval = val; \
  if (obj != nval) { \
    Tcl_Obj *prev = obj; \
    Tcl_InitObjRef(obj, nval); \
    if (prev != NULL) { Tcl_DecrRefCount(prev); }; \
  } \
}

/*
 * Prototypes of module functions.
 */

MODULE_SCOPE const char*
		    TclStrIdxTreeSearch(TclStrIdxTree **foundParent,
			TclStrIdx **foundItem, TclStrIdxTree *tree, 
			const char *start, const char *end);

MODULE_SCOPE int    TclStrIdxTreeBuildFromList(TclStrIdxTree *idxTree,
			int lstc, Tcl_Obj **lstv);

MODULE_SCOPE Tcl_Obj* 
		    TclStrIdxTreeNewObj();

MODULE_SCOPE TclStrIdxTree*
		    TclStrIdxTreeGetFromObj(Tcl_Obj *objPtr);

#if 1

MODULE_SCOPE int    TclStrIdxTreeTestObjCmd(ClientData, Tcl_Interp *,
			int, Tcl_Obj *const objv[]);
#endif

#endif /* _TCLSTRIDXTREE_H */