1 /* (C) Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 Stijn van Dongen 2 * (C) Copyright 2006, 2007, 2008, 2009 Stijn van Dongen 3 * 4 * This file is part of tingea. You can redistribute and/or modify tingea 5 * under the terms of the GNU General Public License; either version 3 of the 6 * License or (at your option) any later version. You should have received a 7 * copy of the GPL along with tingea, in the file COPYING. 8 */ 9 10 #ifndef tingea_ting 11 #define tingea_ting 12 13 #include "types.h" 14 15 typedef struct 16 { char *str 17 ; dim len 18 ; dim mxl 19 ; 20 } mcxTing ; 21 22 23 /* ************************************************************************** 24 * * 25 ** Implementation notes (a few). 26 * 27 * 28 29 Synopsis 30 * This little module provides an objectified C-string compatible interface 31 * to strings. 32 33 * Some philosophy 34 * Do not mind the overhead of 2*sizeof(int) bytes per ting. 35 * If you have humongous amounts of small strings, use C-strings. Optionally 36 * you can do the needed char manipulation in a ting used as scratch-space 37 * using the ting interface, then create a normal string once you are done. 38 * Use mcxTinguish to avoid copying if needed. 39 40 * Feel free to use the str member with routines from <string.h> 41 * or perhaps from ding.h. Just remember to treat it as a const object 42 * when doing so. 43 44 * Applications 45 * Zoem is the macro processor that processes the zoem language. It is very 46 * string-heavy and its string operations are entirely based on the ting 47 * module. 48 49 * Caveat 50 * Nearly all routines return a NULL pointer to indicate malloc failure. 51 52 * Data structure 53 * str: array of chars 54 * 55 * len: length of string in str (excluding '\0') 56 * *(str+len) == '\0' 57 * 58 * mxl: current allocated number of writable char's (excluding '\0') 59 * Allocated amount is mxl+1 60 * *(str+mxl) == '\0' - but don't count on that. 61 62 * Notes 63 * mcxTingEnsure is the only routine allowed to fiddle with mxl. 64 * (apart from mcxTingInit which sets it to zero). 65 * 66 * Future idea 67 * mcxTingFinalize, (realloc to length) 68 * 69 * Routines marked `!' will NOT accept ting==NULL argument. 70 * Routines marked `#' should not be called other than by ting routines 71 * 72 * _ #Init _ 73 * / \ 74 * Ensure <--- #Instantiate 75 * / \ \ 76 * Empty !Splice New,Write,Print,PrintAfter 77 * NWrite | 78 * | 79 * Append,Insert,Delete,PrintSplice 80 81 * TODO 82 * the library should be able to deal with embedded \0's. Really. 83 */ 84 85 86 87 /* ************************************************************************** 88 * * 89 ** Various instantiation routines. 90 */ 91 92 /* Accepts NULL argument. 93 * void arguments so that it can be used 94 * as callback. 95 * 96 * Should ordinarily *not* be used, unless 97 * you want to initialize a ting allocated 98 * on the frame stack. 99 */ 100 void* mcxTingInit 101 ( void* ting 102 ) ; 103 /* Accepts NULL argument. 104 * Should ordinarily *not* be used. 105 */ 106 mcxTing* mcxTingInstantiate 107 ( mcxTing* dst_ting 108 , const char* str 109 ) ; 110 /* Accepts NULL argument. Does not affect 111 * ting->str. used for preallocing, e.g. to 112 * prepare for successive calls of Append. (see 113 * also Empty). 114 */ 115 mcxTing* mcxTingEnsure 116 ( mcxTing* ting 117 , dim length 118 ) ; 119 /* Accepts NULL argument. The string part is 120 * set to the empty string. 121 * Can be used for preallocing. 122 */ 123 mcxTing* mcxTingEmpty 124 ( mcxTing* ting 125 , dim length 126 ) ; 127 128 129 130 /* ************************************************************************** 131 * * 132 ** Some freeing routines. 133 */ 134 /* Free members and shell struct 135 * You pass the address of a variable, 136 * loosely speaking. 137 */ 138 void mcxTingFree 139 ( mcxTing **tingpp 140 ) ; 141 /* Free members and shell struct 142 * Use with callbacks, e.g. 143 * for freeing hash with tings in one go. 144 */ 145 void mcxTingFree_v 146 ( void *tingpp 147 ) ; 148 /* Free members 149 * Use for freeing array of ting; 150 * e.g. as callback in mcxNFree. 151 */ 152 void mcxTingRelease 153 ( void *ting 154 ) ; 155 156 157 158 /* ************************************************************************** 159 * * 160 ** A bunch of user-land creation routines. 161 */ 162 163 /* accepts NULL argument, maps to empty string. 164 */ 165 mcxTing* mcxTingNew 166 ( const char* str 167 ) ; 168 /* accepts NULL argument, maps to empty string. 169 */ 170 mcxTing* mcxTingNNew 171 ( const char* str 172 , dim n 173 ) ; 174 /* accepts NULL argument. 175 */ 176 mcxTing* mcxTingWrite 177 ( mcxTing* ting 178 , const char* str 179 ) ; 180 /* accepts NULL argument. 181 */ 182 mcxTing* mcxTingNWrite 183 ( mcxTing* ting 184 , const char* str 185 , dim n 186 ) ; 187 188 189 /* usurps argument. 190 */ 191 mcxTing* mcxTingify 192 ( char* str 193 ) ; 194 195 196 /* destroys argument, returns str member. 197 */ 198 char* mcxTinguish 199 ( mcxTing* ting 200 ) ; 201 202 203 /* ************************************************************************** 204 * * 205 ** Appending, inserting, deleting, shrinking. 206 * Some can be used as creation routine (e.g. append). 207 */ 208 209 210 #define TING_INS_CENTER -3 211 #define TING_INS_OVERRUN -4 212 #define TING_INS_OVERWRITE -5 213 214 /* 215 * The offset argument can be negative, for subscripting from the end. 216 * 217 * The n_delete argument can be nonnegative, or one of 218 * TING_INS_CENTER center, (try to) overwrite without changing length. 219 * TING_INS_OVERRUN overwrite till the end. 220 * TING_INS_OVERWRITE (try to) overwrite without changing length. 221 * 222 * The n_copy argument is not magical like the previous two. 223 * 224 */ 225 /* does NOT accept NULL argument. 226 */ 227 mcxstatus mcxTingSplice 228 ( mcxTing* ting 229 , const char* pstr 230 , ofs d_offset /* negative offset refers to end */ 231 , ofs n_delete /* special modes as documented above */ 232 , dim n_copy 233 ) ; 234 /* accepts NULL argument. 235 */ 236 mcxTing* mcxTingInsert 237 ( mcxTing* ting 238 , const char* str 239 , ofs offset 240 ) ; 241 /* accepts NULL argument. 242 */ 243 mcxTing* mcxTingNInsert 244 ( mcxTing* ting 245 , const char* str 246 , ofs offset /* of ting->str */ 247 , dim length /* of str */ 248 ) ; 249 250 /* accepts NULL argument. 251 */ 252 mcxTing* mcxTingAppend 253 ( mcxTing* ting 254 , const char* str 255 ) ; 256 257 /* accepts NULL argument. 258 */ 259 mcxTing* mcxTingKAppend 260 ( mcxTing* ting 261 , const char* str 262 , dim n 263 ) ; 264 /* accepts NULL argument. 265 */ 266 mcxTing* mcxTingNAppend 267 ( mcxTing* ting 268 , const char* str 269 , dim n 270 ) ; 271 /* accepts NULL argument. 272 */ 273 mcxTing* mcxTingDelete 274 ( mcxTing* ting 275 , ofs offset 276 , dim width 277 ) ; 278 /* accepts NULL argument. 279 */ 280 mcxTing* mcxTingShrink 281 ( mcxTing* ting 282 , ofs length 283 ) ; 284 285 286 287 /* Fails only for memory reason */ 288 289 mcxstatus mcxTingTackc 290 ( mcxTing* ting 291 , unsigned char c 292 ) ; 293 294 295 /* Fails if last char is not the same as c */ 296 297 mcxstatus mcxTingTickc 298 ( mcxTing* ting 299 , unsigned char c 300 ) ; 301 302 303 /* ************************************************************************** 304 * * 305 ** A bunch of printf like routines. 306 */ 307 308 /* Accepts NULL argument. 309 */ 310 mcxTing* mcxTingPrint 311 ( mcxTing* ting 312 , const char* fmt 313 , ... 314 ) 315 #ifdef __GNUC__ 316 __attribute__ ((format (printf, 2, 3))) 317 #endif 318 ; 319 /* Accepts NULL argument. 320 */ 321 mcxTing* mcxTingPrintAfter 322 ( mcxTing* dst 323 , const char* fmt 324 , ... 325 ) 326 #ifdef __GNUC__ 327 __attribute__ ((format (printf, 2, 3))) 328 #endif 329 ; 330 /* Accepts NULL argument. 331 * same offset and delete interface as 332 * mcxTingSplice. 333 */ 334 mcxTing* mcxTingPrintSplice 335 ( mcxTing* dst 336 , ofs offset 337 , ofs n_delete /* count of chars to delete, special modes */ 338 , const char* fmt 339 , ... 340 ) 341 #ifdef __GNUC__ 342 __attribute__ ((format (printf, 4, 5))) 343 #endif 344 ; 345 346 347 /* ************************************************************************** 348 * * 349 ** Miscellaneous. 350 */ 351 352 char* mcxTingStr 353 ( const mcxTing* ting 354 ) ; 355 356 357 char* mcxTingSubStr 358 ( const mcxTing* ting 359 , ofs offset 360 , ofs length /* use -1 to indicate remainder of string */ 361 ) ; 362 363 /* accepts NULL argument. 364 */ 365 mcxTing* mcxTingRoman 366 ( mcxTing* dst 367 , long x 368 , mcxbool ucase 369 ) ; 370 /* accepts NULL argument. 371 */ 372 mcxTing* mcxTingInteger 373 ( mcxTing* dst 374 , long x 375 ) ; 376 /* accepts NULL argument. 377 */ 378 mcxTing* mcxTingDouble 379 ( mcxTing* dst 380 , double x 381 , int decimals 382 ) ; 383 384 385 /* ************************************************************************** 386 * * 387 ** Comparing. 388 */ 389 390 /* compare two mcxTing* pointers */ 391 int mcxTingCmp 392 ( const void* t1 393 , const void* t2 394 ) ; 395 396 /* compare two mcxTing* pointers */ 397 int mcxTingRevCmp 398 ( const void* t1 399 , const void* t2 400 ) ; 401 402 /* compare two mcxTing** pointers */ 403 int mcxTingPCmp 404 ( const void* t1 405 , const void* t2 406 ) ; 407 408 /* compare two mcxTing** pointers */ 409 int mcxTingPRevCmp 410 ( const void* t1 411 , const void* t2 412 ) ; 413 414 /* compare two mcxKV** pointers by key as mcxTing* */ 415 int mcxPKeyTingCmp 416 ( const void* k1 417 , const void* k2 418 ) ; 419 420 /* compare two mcxKV** pointers by key as mcxTing* */ 421 int mcxPKeyTingRevCmp 422 ( const void* k1 423 , const void* k2 424 ) ; 425 426 427 /* ************************************************************************** 428 * * 429 ** Hashing. 430 */ 431 432 u32 (*mcxTingHFieByName(const char* id))(const void* ting) ; 433 434 435 u32 mcxTingELFhash 436 ( const void* ting 437 ) ; 438 439 u32 mcxTingHash 440 ( const void* ting 441 ) ; 442 443 u32 mcxTingBJhash 444 ( const void* ting 445 ) ; 446 447 u32 mcxTingCThash 448 ( const void* ting 449 ) ; 450 451 u32 mcxTingDPhash 452 ( const void* ting 453 ) ; 454 455 u32 mcxTingBDBhash 456 ( const void* ting 457 ) ; 458 459 u32 mcxTingGEhash 460 ( const void* ting 461 ) ; 462 463 u32 mcxTingOAThash 464 ( const void* ting 465 ) ; 466 467 u32 mcxTingFNVhash 468 ( const void* ting 469 ) ; 470 471 u32 mcxTingSvDhash 472 ( const void* ting 473 ) ; 474 475 u32 mcxTingSvD2hash 476 ( const void* ting 477 ) ; 478 479 u32 mcxTingSvD1hash 480 ( const void* ting 481 ) ; 482 483 u32 mcxTingDJBhash 484 ( const void* ting 485 ) ; 486 487 #endif 488 489