| 1 | #ifndef _JUDY_INCLUDED |
| 2 | #define _JUDY_INCLUDED |
| 3 | // _________________ |
| 4 | // |
| 5 | // Copyright (C) 2000 - 2002 Hewlett-Packard Company |
| 6 | // |
| 7 | // This program is free software; you can redistribute it and/or modify it |
| 8 | // under the term of the GNU Lesser General Public License as published by the |
| 9 | // Free Software Foundation; either version 2 of the License, or (at your |
| 10 | // option) any later version. |
| 11 | // |
| 12 | // This program is distributed in the hope that it will be useful, but WITHOUT |
| 13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 14 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License |
| 15 | // for more details. |
| 16 | // |
| 17 | // You should have received a copy of the GNU Lesser General Public License |
| 18 | // along with this program; if not, write to the Free Software Foundation, |
| 19 | // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 20 | // _________________ |
| 21 | |
| 22 | // @(#) $Revision: 4.52 $ $Source: /judy/src/Judy.h $ |
| 23 | // |
| 24 | // HEADER FILE FOR EXPORTED FEATURES IN JUDY LIBRARY, libJudy.* |
| 25 | // |
| 26 | // See the manual entries for details. |
| 27 | // |
| 28 | // Note: This header file uses old-style comments on #-directive lines and |
| 29 | // avoids "()" on macro names in comments for compatibility with older cc -Aa |
| 30 | // and some tools on some platforms. |
| 31 | |
| 32 | |
| 33 | // PLATFORM-SPECIFIC |
| 34 | |
| 35 | #ifdef JU_WIN /* =============================================== */ |
| 36 | |
| 37 | typedef __int8 int8_t; |
| 38 | typedef __int16 int16_t; |
| 39 | typedef __int32 int32_t; |
| 40 | typedef __int64 int64_t; |
| 41 | |
| 42 | typedef unsigned __int8 uint8_t; |
| 43 | typedef unsigned __int16 uint16_t; |
| 44 | typedef unsigned __int32 uint32_t; |
| 45 | typedef unsigned __int64 uint64_t; |
| 46 | |
| 47 | #else /* ================ ! JU_WIN ============================= */ |
| 48 | |
| 49 | // ISO C99: 7.8 Format conversion of integer types <inttypes.h> |
| 50 | #include <inttypes.h> /* if this FAILS, try #include <stdint.h> */ |
| 51 | |
| 52 | // ISO C99: 7.18 Integer types uint*_t |
| 53 | //#include <stdint.h> |
| 54 | |
| 55 | #endif /* ================ ! JU_WIN ============================= */ |
| 56 | |
| 57 | // ISO C99 Standard: 7.20 General utilities |
| 58 | #include <stdlib.h> |
| 59 | |
| 60 | // ISO C99 Standard: 7.10/5.2.4.2.1 Sizes of integer types |
| 61 | #include <limits.h> |
| 62 | |
| 63 | #ifdef __cplusplus /* support use by C++ code */ |
| 64 | extern "C" { |
| 65 | #endif |
| 66 | |
| 67 | |
| 68 | // **************************************************************************** |
| 69 | // DECLARE SOME BASE TYPES IN CASE THEY ARE MISSING: |
| 70 | // |
| 71 | // These base types include "const" where appropriate, but only where of |
| 72 | // interest to the caller. For example, a caller cares that a variable passed |
| 73 | // by reference will not be modified, such as, "const void * Pindex", but not |
| 74 | // that the called function internally does not modify the pointer itself, such |
| 75 | // as, "void * const Pindex". |
| 76 | // |
| 77 | // Note that its OK to pass a Pvoid_t to a Pcvoid_t; the latter is the same, |
| 78 | // only constant. Callers need to do this so they can also pass & Pvoid_t to |
| 79 | // PPvoid_t (non-constant). |
| 80 | |
| 81 | #ifndef _PCVOID_T |
| 82 | #define _PCVOID_T |
| 83 | typedef const void * Pcvoid_t; |
| 84 | #endif |
| 85 | |
| 86 | #ifndef _PVOID_T |
| 87 | #define _PVOID_T |
| 88 | typedef void * Pvoid_t; |
| 89 | typedef void ** PPvoid_t; |
| 90 | #endif |
| 91 | |
| 92 | #ifndef _WORD_T |
| 93 | #define _WORD_T |
| 94 | typedef unsigned long Word_t, * PWord_t; // expect 32-bit or 64-bit words. |
| 95 | #endif |
| 96 | |
| 97 | #ifndef NULL |
| 98 | #define NULL 0 |
| 99 | #endif |
| 100 | |
| 101 | |
| 102 | // **************************************************************************** |
| 103 | // SUPPORT FOR ERROR HANDLING: |
| 104 | // |
| 105 | // Judy error numbers: |
| 106 | // |
| 107 | // Note: These are an enum so theres a related typedef, but the numbers are |
| 108 | // spelled out so you can map a number back to its name. |
| 109 | |
| 110 | typedef enum // uint8_t -- but C does not support this type of enum. |
| 111 | { |
| 112 | |
| 113 | // Note: JU_ERRNO_NONE and JU_ERRNO_FULL are not real errors. They specify |
| 114 | // conditions which are otherwise impossible return values from 32-bit |
| 115 | // Judy1Count, which has 2^32 + 1 valid returns (0..2^32) plus one error |
| 116 | // return. These pseudo-errors support the return values that cannot otherwise |
| 117 | // be unambiguously represented in a 32-bit word, and will never occur on a |
| 118 | // 64-bit system. |
| 119 | |
| 120 | JU_ERRNO_NONE = 0, |
| 121 | JU_ERRNO_FULL = 1, |
| 122 | JU_ERRNO_NFMAX = JU_ERRNO_FULL, |
| 123 | |
| 124 | // JU_ERRNO_NOMEM comes from malloc(3C) when Judy cannot obtain needed memory. |
| 125 | // The system errno value is also set to ENOMEM. This error can be recoverable |
| 126 | // if the calling application frees other memory. |
| 127 | // |
| 128 | // TBD: Currently there is no guarantee the Judy array has no memory leaks |
| 129 | // upon JU_ERRNO_NOMEM. |
| 130 | |
| 131 | JU_ERRNO_NOMEM = 2, |
| 132 | |
| 133 | // Problems with parameters from the calling program: |
| 134 | // |
| 135 | // JU_ERRNO_NULLPPARRAY means PPArray was null; perhaps PArray was passed where |
| 136 | // &PArray was intended. Similarly, JU_ERRNO_NULLPINDEX means PIndex was null; |
| 137 | // perhaps &Index was intended. Also, JU_ERRNO_NONNULLPARRAY, |
| 138 | // JU_ERRNO_NULLPVALUE, and JU_ERRNO_UNSORTED, all added later (hence with |
| 139 | // higher numbers), mean: A non-null array was passed in where a null pointer |
| 140 | // was required; PValue was null; and unsorted indexes were detected. |
| 141 | |
| 142 | JU_ERRNO_NULLPPARRAY = 3, // see above. |
| 143 | JU_ERRNO_NONNULLPARRAY = 10, // see above. |
| 144 | JU_ERRNO_NULLPINDEX = 4, // see above. |
| 145 | JU_ERRNO_NULLPVALUE = 11, // see above. |
| 146 | JU_ERRNO_NOTJUDY1 = 5, // PArray is not to a Judy1 array. |
| 147 | JU_ERRNO_NOTJUDYL = 6, // PArray is not to a JudyL array. |
| 148 | JU_ERRNO_NOTJUDYSL = 7, // PArray is not to a JudySL array. |
| 149 | JU_ERRNO_UNSORTED = 12, // see above. |
| 150 | |
| 151 | // Errors below this point are not recoverable; further tries to access the |
| 152 | // Judy array might result in EFAULT and a core dump: |
| 153 | // |
| 154 | // JU_ERRNO_OVERRUN occurs when Judy detects, upon reallocation, that a block |
| 155 | // of memory in its own freelist was modified since being freed. |
| 156 | |
| 157 | JU_ERRNO_OVERRUN = 8, |
| 158 | |
| 159 | // JU_ERRNO_CORRUPT occurs when Judy detects an impossible value in a Judy data |
| 160 | // structure: |
| 161 | // |
| 162 | // Note: The Judy data structure contains some redundant elements that support |
| 163 | // this type of checking. |
| 164 | |
| 165 | JU_ERRNO_CORRUPT = 9 |
| 166 | |
| 167 | // Warning: At least some C or C++ compilers do not tolerate a trailing comma |
| 168 | // above here. At least we know of one case, in aCC; see JAGad58928. |
| 169 | |
| 170 | } JU_Errno_t; |
| 171 | |
| 172 | |
| 173 | // Judy errno structure: |
| 174 | // |
| 175 | // WARNING: For compatibility with possible future changes, the fields of this |
| 176 | // struct should not be referenced directly. Instead use the macros supplied |
| 177 | // below. |
| 178 | |
| 179 | // This structure should be declared on the stack in a threaded process. |
| 180 | |
| 181 | typedef struct J_UDY_ERROR_STRUCT |
| 182 | { |
| 183 | JU_Errno_t je_Errno; // one of the enums above. |
| 184 | int je_ErrID; // often an internal source line number. |
| 185 | Word_t je_reserved[4]; // for future backward compatibility. |
| 186 | |
| 187 | } JError_t, * PJError_t; |
| 188 | |
| 189 | |
| 190 | // Related macros: |
| 191 | // |
| 192 | // Fields from error struct: |
| 193 | |
| 194 | #define JU_ERRNO(PJError) ((PJError)->je_Errno) |
| 195 | #define JU_ERRID(PJError) ((PJError)->je_ErrID) |
| 196 | |
| 197 | // For checking return values from various Judy functions: |
| 198 | // |
| 199 | // Note: Define JERR as -1, not as the seemingly more portable (Word_t) |
| 200 | // (~0UL), to avoid a compiler "overflow in implicit constant conversion" |
| 201 | // warning. |
| 202 | |
| 203 | #define JERR (-1) /* functions returning int or Word_t */ |
| 204 | #define PJERR ((Pvoid_t) (~0UL)) /* mainly for use here, see below */ |
| 205 | #define PPJERR ((PPvoid_t) (~0UL)) /* functions that return PPvoid_t */ |
| 206 | |
| 207 | // Convenience macro for when detailed error information (PJError_t) is not |
| 208 | // desired by the caller; a purposely short name: |
| 209 | |
| 210 | #define PJE0 ((PJError_t) NULL) |
| 211 | |
| 212 | |
| 213 | // **************************************************************************** |
| 214 | // JUDY FUNCTIONS: |
| 215 | // |
| 216 | // P_JE is a shorthand for use below: |
| 217 | |
| 218 | #define P_JE PJError_t PJError |
| 219 | |
| 220 | // **************************************************************************** |
| 221 | // JUDY1 FUNCTIONS: |
| 222 | |
| 223 | extern int Judy1Test( Pcvoid_t PArray, Word_t Index, P_JE); |
| 224 | extern int Judy1Set( PPvoid_t PPArray, Word_t Index, P_JE); |
| 225 | extern int Judy1SetArray( PPvoid_t PPArray, Word_t Count, |
| 226 | const Word_t * const PIndex, |
| 227 | P_JE); |
| 228 | extern int Judy1Unset( PPvoid_t PPArray, Word_t Index, P_JE); |
| 229 | extern Word_t Judy1Count( Pcvoid_t PArray, Word_t Index1, |
| 230 | Word_t Index2, P_JE); |
| 231 | extern int Judy1ByCount( Pcvoid_t PArray, Word_t Count, |
| 232 | Word_t * PIndex, P_JE); |
| 233 | extern Word_t Judy1FreeArray( PPvoid_t PPArray, P_JE); |
| 234 | extern Word_t Judy1MemUsed( Pcvoid_t PArray); |
| 235 | extern Word_t Judy1MemActive( Pcvoid_t PArray); |
| 236 | extern int Judy1First( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 237 | extern int Judy1Next( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 238 | extern int Judy1Last( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 239 | extern int Judy1Prev( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 240 | extern int Judy1FirstEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 241 | extern int Judy1NextEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 242 | extern int Judy1LastEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 243 | extern int Judy1PrevEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 244 | |
| 245 | extern PPvoid_t JudyLGet( Pcvoid_t PArray, Word_t Index, P_JE); |
| 246 | extern PPvoid_t JudyLIns( PPvoid_t PPArray, Word_t Index, P_JE); |
| 247 | extern int JudyLInsArray( PPvoid_t PPArray, Word_t Count, |
| 248 | const Word_t * const PIndex, |
| 249 | const Word_t * const PValue, |
| 250 | |
| 251 | // **************************************************************************** |
| 252 | // JUDYL FUNCTIONS: |
| 253 | P_JE); |
| 254 | extern int JudyLDel( PPvoid_t PPArray, Word_t Index, P_JE); |
| 255 | extern Word_t JudyLCount( Pcvoid_t PArray, Word_t Index1, |
| 256 | Word_t Index2, P_JE); |
| 257 | extern PPvoid_t JudyLByCount( Pcvoid_t PArray, Word_t Count, |
| 258 | Word_t * PIndex, P_JE); |
| 259 | extern Word_t JudyLFreeArray( PPvoid_t PPArray, P_JE); |
| 260 | extern Word_t JudyLMemUsed( Pcvoid_t PArray); |
| 261 | extern Word_t JudyLMemActive( Pcvoid_t PArray); |
| 262 | extern PPvoid_t JudyLFirst( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 263 | extern PPvoid_t JudyLNext( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 264 | extern PPvoid_t JudyLLast( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 265 | extern PPvoid_t JudyLPrev( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 266 | extern int JudyLFirstEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 267 | extern int JudyLNextEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 268 | extern int JudyLLastEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 269 | extern int JudyLPrevEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); |
| 270 | |
| 271 | // **************************************************************************** |
| 272 | // JUDYSL FUNCTIONS: |
| 273 | |
| 274 | extern PPvoid_t JudySLGet( Pcvoid_t, const uint8_t * Index, P_JE); |
| 275 | extern PPvoid_t JudySLIns( PPvoid_t, const uint8_t * Index, P_JE); |
| 276 | extern int JudySLDel( PPvoid_t, const uint8_t * Index, P_JE); |
| 277 | extern Word_t JudySLFreeArray( PPvoid_t, P_JE); |
| 278 | extern PPvoid_t JudySLFirst( Pcvoid_t, uint8_t * Index, P_JE); |
| 279 | extern PPvoid_t JudySLNext( Pcvoid_t, uint8_t * Index, P_JE); |
| 280 | extern PPvoid_t JudySLLast( Pcvoid_t, uint8_t * Index, P_JE); |
| 281 | extern PPvoid_t JudySLPrev( Pcvoid_t, uint8_t * Index, P_JE); |
| 282 | |
| 283 | // **************************************************************************** |
| 284 | // JUDYHSL FUNCTIONS: |
| 285 | |
| 286 | extern PPvoid_t JudyHSGet( Pcvoid_t, void *, Word_t); |
| 287 | extern PPvoid_t JudyHSIns( PPvoid_t, void *, Word_t, P_JE); |
| 288 | extern int JudyHSDel( PPvoid_t, void *, Word_t, P_JE); |
| 289 | extern Word_t JudyHSFreeArray( PPvoid_t, P_JE); |
| 290 | |
| 291 | extern const char *Judy1MallocSizes; |
| 292 | extern const char *JudyLMallocSizes; |
| 293 | |
| 294 | // **************************************************************************** |
| 295 | // JUDY memory interface to malloc() FUNCTIONS: |
| 296 | |
| 297 | extern Word_t JudyMalloc(Word_t); // words reqd => words allocd. |
| 298 | extern Word_t JudyMallocVirtual(Word_t); // words reqd => words allocd. |
| 299 | extern void JudyFree(Pvoid_t, Word_t); // free, size in words. |
| 300 | extern void JudyFreeVirtual(Pvoid_t, Word_t); // free, size in words. |
| 301 | |
| 302 | #define JLAP_INVALID 0x1 /* flag to mark pointer "not a Judy array" */ |
| 303 | |
| 304 | // **************************************************************************** |
| 305 | // MACRO EQUIVALENTS FOR JUDY FUNCTIONS: |
| 306 | // |
| 307 | // The following macros, such as J1T, are shorthands for calling Judy functions |
| 308 | // with parameter address-of and detailed error checking included. Since they |
| 309 | // are macros, the error checking code is replicated each time the macro is |
| 310 | // used, but it runs fast in the normal case of no error. |
| 311 | // |
| 312 | // If the caller does not like the way the default JUDYERROR macro handles |
| 313 | // errors (such as an exit(1) call when out of memory), they may define their |
| 314 | // own before the "#include <Judy.h>". A routine such as HandleJudyError |
| 315 | // could do checking on specific error numbers and print a different message |
| 316 | // dependent on the error. The following is one example: |
| 317 | // |
| 318 | // Note: the back-slashes are removed because some compilers will not accept |
| 319 | // them in comments. |
| 320 | // |
| 321 | // void HandleJudyError(uint8_t *, int, uint8_t *, int, int); |
| 322 | // #define JUDYERROR(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID) |
| 323 | // { |
| 324 | // HandleJudyError(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID); |
| 325 | // } |
| 326 | // |
| 327 | // The routine HandleJudyError could do checking on specific error numbers and |
| 328 | // print a different message dependent on the error. |
| 329 | // |
| 330 | // The macro receives five parameters that are: |
| 331 | // |
| 332 | // 1. CallerFile: Source filename where a Judy call returned a serious error. |
| 333 | // 2. CallerLine: Line number in that source file. |
| 334 | // 3. JudyFunc: Name of Judy function reporting the error. |
| 335 | // 4. JudyErrno: One of the JU_ERRNO* values enumerated above. |
| 336 | // 5. JudyErrID: The je_ErrID field described above. |
| 337 | |
| 338 | #ifndef JUDYERROR_NOTEST |
| 339 | #ifndef JUDYERROR /* supply a default error macro */ |
| 340 | #include <stdio.h> |
| 341 | |
| 342 | #define JUDYERROR(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID) \ |
| 343 | { \ |
| 344 | (void) fprintf(stderr, "File '%s', line %d: %s(), " \ |
| 345 | "JU_ERRNO_* == %d, ID == %d\n", \ |
| 346 | CallerFile, CallerLine, \ |
| 347 | JudyFunc, JudyErrno, JudyErrID); \ |
| 348 | exit(1); \ |
| 349 | } |
| 350 | |
| 351 | #endif /* JUDYERROR */ |
| 352 | #endif /* JUDYERROR_NOTEST */ |
| 353 | |
| 354 | // If the JUDYERROR macro is not desired at all, then the following eliminates |
| 355 | // it. However, the return code from each Judy function (that is, the first |
| 356 | // parameter of each macro) must be checked by the caller to assure that an |
| 357 | // error did not occur. |
| 358 | // |
| 359 | // Example: |
| 360 | // |
| 361 | // #define JUDYERROR_NOTEST 1 |
| 362 | // #include <Judy.h> |
| 363 | // |
| 364 | // or use this cc option at compile time: |
| 365 | // |
| 366 | // cc -DJUDYERROR_NOTEST ... |
| 367 | // |
| 368 | // Example code: |
| 369 | // |
| 370 | // J1S(Rc, PArray, Index); |
| 371 | // if (Rc == JERR) goto ...error |
| 372 | // |
| 373 | // or: |
| 374 | // |
| 375 | // JLI(PValue, PArray, Index); |
| 376 | // if (PValue == PJERR) goto ...error |
| 377 | |
| 378 | |
| 379 | // Internal shorthand macros for writing the J1S, etc. macros: |
| 380 | |
| 381 | #ifdef JUDYERROR_NOTEST /* ============================================ */ |
| 382 | |
| 383 | // "Judy Set Error": |
| 384 | |
| 385 | #define J_SE(FuncName,Errno) ((void) 0) |
| 386 | |
| 387 | // Note: In each J_*() case below, the digit is the number of key parameters |
| 388 | // to the Judy*() call. Just assign the Func result to the callers Rc value |
| 389 | // without a cast because none is required, and this keeps the API simpler. |
| 390 | // However, a family of different J_*() macros is needed to support the |
| 391 | // different numbers of key parameters (0,1,2) and the Func return type. |
| 392 | // |
| 393 | // In the names below, "I" = integer result; "P" = pointer result. Note, the |
| 394 | // Funcs for J_*P() return PPvoid_t, but cast this to a Pvoid_t for flexible, |
| 395 | // error-free assignment, and then compare to PJERR. |
| 396 | |
| 397 | #define J_0I(Rc,PArray,Func,FuncName) \ |
| 398 | { (Rc) = Func(PArray, PJE0); } |
| 399 | |
| 400 | #define J_1I(Rc,PArray,Index,Func,FuncName) \ |
| 401 | { (Rc) = Func(PArray, Index, PJE0); } |
| 402 | |
| 403 | #define J_1P(PV,PArray,Index,Func,FuncName) \ |
| 404 | { (PV) = (Pvoid_t) Func(PArray, Index, PJE0); } |
| 405 | |
| 406 | #define J_2I(Rc,PArray,Index,Arg2,Func,FuncName) \ |
| 407 | { (Rc) = Func(PArray, Index, Arg2, PJE0); } |
| 408 | |
| 409 | #define J_2C(Rc,PArray,Index1,Index2,Func,FuncName) \ |
| 410 | { (Rc) = Func(PArray, Index1, Index2, PJE0); } |
| 411 | |
| 412 | #define J_2P(PV,PArray,Index,Arg2,Func,FuncName) \ |
| 413 | { (PV) = (Pvoid_t) Func(PArray, Index, Arg2, PJE0); } |
| 414 | |
| 415 | // Variations for Judy*Set/InsArray functions: |
| 416 | |
| 417 | #define J_2AI(Rc,PArray,Count,PIndex,Func,FuncName) \ |
| 418 | { (Rc) = Func(PArray, Count, PIndex, PJE0); } |
| 419 | #define J_3AI(Rc,PArray,Count,PIndex,PValue,Func,FuncName) \ |
| 420 | { (Rc) = Func(PArray, Count, PIndex, PValue, PJE0); } |
| 421 | |
| 422 | #else /* ================ ! JUDYERROR_NOTEST ============================= */ |
| 423 | |
| 424 | #define J_E(FuncName,PJE) \ |
| 425 | JUDYERROR(__FILE__, __LINE__, FuncName, JU_ERRNO(PJE), JU_ERRID(PJE)) |
| 426 | |
| 427 | #define J_SE(FuncName,Errno) \ |
| 428 | { \ |
| 429 | JError_t J_Error; \ |
| 430 | JU_ERRNO(&J_Error) = (Errno); \ |
| 431 | JU_ERRID(&J_Error) = __LINE__; \ |
| 432 | J_E(FuncName, &J_Error); \ |
| 433 | } |
| 434 | |
| 435 | // Note: In each J_*() case below, the digit is the number of key parameters |
| 436 | // to the Judy*() call. Just assign the Func result to the callers Rc value |
| 437 | // without a cast because none is required, and this keeps the API simpler. |
| 438 | // However, a family of different J_*() macros is needed to support the |
| 439 | // different numbers of key parameters (0,1,2) and the Func return type. |
| 440 | // |
| 441 | // In the names below, "I" = integer result; "P" = pointer result. Note, the |
| 442 | // Funcs for J_*P() return PPvoid_t, but cast this to a Pvoid_t for flexible, |
| 443 | // error-free assignment, and then compare to PJERR. |
| 444 | |
| 445 | #define J_0I(Rc,PArray,Func,FuncName) \ |
| 446 | { \ |
| 447 | JError_t J_Error; \ |
| 448 | if (((Rc) = Func(PArray, &J_Error)) == JERR) \ |
| 449 | J_E(FuncName, &J_Error); \ |
| 450 | } |
| 451 | |
| 452 | #define J_1I(Rc,PArray,Index,Func,FuncName) \ |
| 453 | { \ |
| 454 | JError_t J_Error; \ |
| 455 | if (((Rc) = Func(PArray, Index, &J_Error)) == JERR) \ |
| 456 | J_E(FuncName, &J_Error); \ |
| 457 | } |
| 458 | |
| 459 | #define J_1P(Rc,PArray,Index,Func,FuncName) \ |
| 460 | { \ |
| 461 | JError_t J_Error; \ |
| 462 | if (((Rc) = (Pvoid_t) Func(PArray, Index, &J_Error)) == PJERR) \ |
| 463 | J_E(FuncName, &J_Error); \ |
| 464 | } |
| 465 | |
| 466 | #define J_2I(Rc,PArray,Index,Arg2,Func,FuncName) \ |
| 467 | { \ |
| 468 | JError_t J_Error; \ |
| 469 | if (((Rc) = Func(PArray, Index, Arg2, &J_Error)) == JERR) \ |
| 470 | J_E(FuncName, &J_Error); \ |
| 471 | } |
| 472 | |
| 473 | // Variation for Judy*Count functions, which return 0, not JERR, for error (and |
| 474 | // also for other non-error cases): |
| 475 | // |
| 476 | // Note: JU_ERRNO_NFMAX should only apply to 32-bit Judy1, but this header |
| 477 | // file lacks the necessary ifdefs to make it go away otherwise, so always |
| 478 | // check against it. |
| 479 | |
| 480 | #define J_2C(Rc,PArray,Index1,Index2,Func,FuncName) \ |
| 481 | { \ |
| 482 | JError_t J_Error; \ |
| 483 | if ((((Rc) = Func(PArray, Index1, Index2, &J_Error)) == 0) \ |
| 484 | && (JU_ERRNO(&J_Error) > JU_ERRNO_NFMAX)) \ |
| 485 | { \ |
| 486 | J_E(FuncName, &J_Error); \ |
| 487 | } \ |
| 488 | } |
| 489 | |
| 490 | #define J_2P(PV,PArray,Index,Arg2,Func,FuncName) \ |
| 491 | { \ |
| 492 | JError_t J_Error; \ |
| 493 | if (((PV) = (Pvoid_t) Func(PArray, Index, Arg2, &J_Error)) \ |
| 494 | == PJERR) J_E(FuncName, &J_Error); \ |
| 495 | } |
| 496 | |
| 497 | // Variations for Judy*Set/InsArray functions: |
| 498 | |
| 499 | #define J_2AI(Rc,PArray,Count,PIndex,Func,FuncName) \ |
| 500 | { \ |
| 501 | JError_t J_Error; \ |
| 502 | if (((Rc) = Func(PArray, Count, PIndex, &J_Error)) == JERR) \ |
| 503 | J_E(FuncName, &J_Error); \ |
| 504 | } |
| 505 | |
| 506 | #define J_3AI(Rc,PArray,Count,PIndex,PValue,Func,FuncName) \ |
| 507 | { \ |
| 508 | JError_t J_Error; \ |
| 509 | if (((Rc) = Func(PArray, Count, PIndex, PValue, &J_Error)) \ |
| 510 | == JERR) J_E(FuncName, &J_Error); \ |
| 511 | } |
| 512 | |
| 513 | #endif /* ================ ! JUDYERROR_NOTEST ============================= */ |
| 514 | |
| 515 | // Some of the macros are special cases that use inlined shortcuts for speed |
| 516 | // with root-level leaves: |
| 517 | |
| 518 | // This is a slower version with current processors, but in the future... |
| 519 | |
| 520 | #define J1T(Rc,PArray,Index) \ |
| 521 | (Rc) = Judy1Test((Pvoid_t)(PArray), Index, PJE0) |
| 522 | |
| 523 | #define J1S( Rc, PArray, Index) \ |
| 524 | J_1I(Rc, (&(PArray)), Index, Judy1Set, "Judy1Set") |
| 525 | #define J1SA(Rc, PArray, Count, PIndex) \ |
| 526 | J_2AI(Rc,(&(PArray)), Count, PIndex, Judy1SetArray, "Judy1SetArray") |
| 527 | #define J1U( Rc, PArray, Index) \ |
| 528 | J_1I(Rc, (&(PArray)), Index, Judy1Unset, "Judy1Unset") |
| 529 | #define J1F( Rc, PArray, Index) \ |
| 530 | J_1I(Rc, PArray, &(Index), Judy1First, "Judy1First") |
| 531 | #define J1N( Rc, PArray, Index) \ |
| 532 | J_1I(Rc, PArray, &(Index), Judy1Next, "Judy1Next") |
| 533 | #define J1L( Rc, PArray, Index) \ |
| 534 | J_1I(Rc, PArray, &(Index), Judy1Last, "Judy1Last") |
| 535 | #define J1P( Rc, PArray, Index) \ |
| 536 | J_1I(Rc, PArray, &(Index), Judy1Prev, "Judy1Prev") |
| 537 | #define J1FE(Rc, PArray, Index) \ |
| 538 | J_1I(Rc, PArray, &(Index), Judy1FirstEmpty, "Judy1FirstEmpty") |
| 539 | #define J1NE(Rc, PArray, Index) \ |
| 540 | J_1I(Rc, PArray, &(Index), Judy1NextEmpty, "Judy1NextEmpty") |
| 541 | #define J1LE(Rc, PArray, Index) \ |
| 542 | J_1I(Rc, PArray, &(Index), Judy1LastEmpty, "Judy1LastEmpty") |
| 543 | #define J1PE(Rc, PArray, Index) \ |
| 544 | J_1I(Rc, PArray, &(Index), Judy1PrevEmpty, "Judy1PrevEmpty") |
| 545 | #define J1C( Rc, PArray, Index1, Index2) \ |
| 546 | J_2C(Rc, PArray, Index1, Index2, Judy1Count, "Judy1Count") |
| 547 | #define J1BC(Rc, PArray, Count, Index) \ |
| 548 | J_2I(Rc, PArray, Count, &(Index), Judy1ByCount, "Judy1ByCount") |
| 549 | #define J1FA(Rc, PArray) \ |
| 550 | J_0I(Rc, (&(PArray)), Judy1FreeArray, "Judy1FreeArray") |
| 551 | #define J1MU(Rc, PArray) \ |
| 552 | (Rc) = Judy1MemUsed(PArray) |
| 553 | |
| 554 | #define JLG(PV,PArray,Index) \ |
| 555 | (PV) = (Pvoid_t)JudyLGet((Pvoid_t)PArray, Index, PJE0) |
| 556 | |
| 557 | #define JLI( PV, PArray, Index) \ |
| 558 | J_1P(PV, (&(PArray)), Index, JudyLIns, "JudyLIns") |
| 559 | |
| 560 | #define JLIA(Rc, PArray, Count, PIndex, PValue) \ |
| 561 | J_3AI(Rc,(&(PArray)), Count, PIndex, PValue, JudyLInsArray, \ |
| 562 | "JudyLInsArray") |
| 563 | #define JLD( Rc, PArray, Index) \ |
| 564 | J_1I(Rc, (&(PArray)), Index, JudyLDel, "JudyLDel") |
| 565 | |
| 566 | #define JLF( PV, PArray, Index) \ |
| 567 | J_1P(PV, PArray, &(Index), JudyLFirst, "JudyLFirst") |
| 568 | |
| 569 | #define JLN( PV, PArray, Index) \ |
| 570 | J_1P(PV, PArray, &(Index), JudyLNext, "JudyLNext") |
| 571 | |
| 572 | #define JLL( PV, PArray, Index) \ |
| 573 | J_1P(PV, PArray, &(Index), JudyLLast, "JudyLLast") |
| 574 | #define JLP( PV, PArray, Index) \ |
| 575 | J_1P(PV, PArray, &(Index), JudyLPrev, "JudyLPrev") |
| 576 | #define JLFE(Rc, PArray, Index) \ |
| 577 | J_1I(Rc, PArray, &(Index), JudyLFirstEmpty, "JudyLFirstEmpty") |
| 578 | #define JLNE(Rc, PArray, Index) \ |
| 579 | J_1I(Rc, PArray, &(Index), JudyLNextEmpty, "JudyLNextEmpty") |
| 580 | #define JLLE(Rc, PArray, Index) \ |
| 581 | J_1I(Rc, PArray, &(Index), JudyLLastEmpty, "JudyLLastEmpty") |
| 582 | #define JLPE(Rc, PArray, Index) \ |
| 583 | J_1I(Rc, PArray, &(Index), JudyLPrevEmpty, "JudyLPrevEmpty") |
| 584 | #define JLC( Rc, PArray, Index1, Index2) \ |
| 585 | J_2C(Rc, PArray, Index1, Index2, JudyLCount, "JudyLCount") |
| 586 | #define JLBC(PV, PArray, Count, Index) \ |
| 587 | J_2P(PV, PArray, Count, &(Index), JudyLByCount, "JudyLByCount") |
| 588 | #define JLFA(Rc, PArray) \ |
| 589 | J_0I(Rc, (&(PArray)), JudyLFreeArray, "JudyLFreeArray") |
| 590 | #define JLMU(Rc, PArray) \ |
| 591 | (Rc) = JudyLMemUsed(PArray) |
| 592 | |
| 593 | #define JHSI(PV, PArray, PIndex, Count) \ |
| 594 | J_2P(PV, (&(PArray)), PIndex, Count, JudyHSIns, "JudyHSIns") |
| 595 | #define JHSG(PV, PArray, PIndex, Count) \ |
| 596 | (PV) = (Pvoid_t) JudyHSGet(PArray, PIndex, Count) |
| 597 | #define JHSD(Rc, PArray, PIndex, Count) \ |
| 598 | J_2I(Rc, (&(PArray)), PIndex, Count, JudyHSDel, "JudyHSDel") |
| 599 | #define JHSFA(Rc, PArray) \ |
| 600 | J_0I(Rc, (&(PArray)), JudyHSFreeArray, "JudyHSFreeArray") |
| 601 | |
| 602 | #define JSLG( PV, PArray, Index) \ |
| 603 | J_1P( PV, PArray, Index, JudySLGet, "JudySLGet") |
| 604 | #define JSLI( PV, PArray, Index) \ |
| 605 | J_1P( PV, (&(PArray)), Index, JudySLIns, "JudySLIns") |
| 606 | #define JSLD( Rc, PArray, Index) \ |
| 607 | J_1I( Rc, (&(PArray)), Index, JudySLDel, "JudySLDel") |
| 608 | #define JSLF( PV, PArray, Index) \ |
| 609 | J_1P( PV, PArray, Index, JudySLFirst, "JudySLFirst") |
| 610 | #define JSLN( PV, PArray, Index) \ |
| 611 | J_1P( PV, PArray, Index, JudySLNext, "JudySLNext") |
| 612 | #define JSLL( PV, PArray, Index) \ |
| 613 | J_1P( PV, PArray, Index, JudySLLast, "JudySLLast") |
| 614 | #define JSLP( PV, PArray, Index) \ |
| 615 | J_1P( PV, PArray, Index, JudySLPrev, "JudySLPrev") |
| 616 | #define JSLFA(Rc, PArray) \ |
| 617 | J_0I( Rc, (&(PArray)), JudySLFreeArray, "JudySLFreeArray") |
| 618 | |
| 619 | #ifdef __cplusplus |
| 620 | } |
| 621 | #endif |
| 622 | #endif /* ! _JUDY_INCLUDED */ |