intl/icu/source/common/ubidiimp.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 ******************************************************************************
michael@0 3 *
michael@0 4 * Copyright (C) 1999-2013, International Business Machines
michael@0 5 * Corporation and others. All Rights Reserved.
michael@0 6 *
michael@0 7 ******************************************************************************
michael@0 8 * file name: ubidiimp.h
michael@0 9 * encoding: US-ASCII
michael@0 10 * tab size: 8 (not used)
michael@0 11 * indentation:4
michael@0 12 *
michael@0 13 * created on: 1999aug06
michael@0 14 * created by: Markus W. Scherer, updated by Matitiahu Allouche
michael@0 15 */
michael@0 16
michael@0 17 #ifndef UBIDIIMP_H
michael@0 18 #define UBIDIIMP_H
michael@0 19
michael@0 20 /* set import/export definitions */
michael@0 21 #ifdef U_COMMON_IMPLEMENTATION
michael@0 22
michael@0 23 #include "unicode/utypes.h"
michael@0 24 #include "unicode/uchar.h"
michael@0 25 #include "ubidi_props.h"
michael@0 26
michael@0 27 /* miscellaneous definitions ---------------------------------------------- */
michael@0 28
michael@0 29 typedef uint8_t DirProp;
michael@0 30 typedef uint32_t Flags;
michael@0 31
michael@0 32 /* Comparing the description of the BiDi algorithm with this implementation
michael@0 33 is easier with the same names for the BiDi types in the code as there.
michael@0 34 See UCharDirection in uchar.h .
michael@0 35 */
michael@0 36 enum {
michael@0 37 L= U_LEFT_TO_RIGHT, /* 0 */
michael@0 38 R= U_RIGHT_TO_LEFT, /* 1 */
michael@0 39 EN= U_EUROPEAN_NUMBER, /* 2 */
michael@0 40 ES= U_EUROPEAN_NUMBER_SEPARATOR, /* 3 */
michael@0 41 ET= U_EUROPEAN_NUMBER_TERMINATOR, /* 4 */
michael@0 42 AN= U_ARABIC_NUMBER, /* 5 */
michael@0 43 CS= U_COMMON_NUMBER_SEPARATOR, /* 6 */
michael@0 44 B= U_BLOCK_SEPARATOR, /* 7 */
michael@0 45 S= U_SEGMENT_SEPARATOR, /* 8 */
michael@0 46 WS= U_WHITE_SPACE_NEUTRAL, /* 9 */
michael@0 47 ON= U_OTHER_NEUTRAL, /* 10 */
michael@0 48 LRE=U_LEFT_TO_RIGHT_EMBEDDING, /* 11 */
michael@0 49 LRO=U_LEFT_TO_RIGHT_OVERRIDE, /* 12 */
michael@0 50 AL= U_RIGHT_TO_LEFT_ARABIC, /* 13 */
michael@0 51 RLE=U_RIGHT_TO_LEFT_EMBEDDING, /* 14 */
michael@0 52 RLO=U_RIGHT_TO_LEFT_OVERRIDE, /* 15 */
michael@0 53 PDF=U_POP_DIRECTIONAL_FORMAT, /* 16 */
michael@0 54 NSM=U_DIR_NON_SPACING_MARK, /* 17 */
michael@0 55 BN= U_BOUNDARY_NEUTRAL, /* 18 */
michael@0 56 FSI=U_FIRST_STRONG_ISOLATE, /* 19 */
michael@0 57 LRI=U_LEFT_TO_RIGHT_ISOLATE, /* 20 */
michael@0 58 RLI=U_RIGHT_TO_LEFT_ISOLATE, /* 21 */
michael@0 59 PDI=U_POP_DIRECTIONAL_ISOLATE, /* 22 */
michael@0 60 ENL, /* 23 */
michael@0 61 ENR, /* 24 */
michael@0 62 dirPropCount
michael@0 63 };
michael@0 64
michael@0 65 /*
michael@0 66 * Sometimes, bit values are more appropriate
michael@0 67 * to deal with directionality properties.
michael@0 68 * Abbreviations in these macro names refer to names
michael@0 69 * used in the BiDi algorithm.
michael@0 70 */
michael@0 71 #define DIRPROP_FLAG(dir) (1UL<<(dir))
michael@0 72
michael@0 73 /* special flag for multiple runs from explicit embedding codes */
michael@0 74 #define DIRPROP_FLAG_MULTI_RUNS (1UL<<31)
michael@0 75
michael@0 76 /* are there any characters that are LTR or RTL? */
michael@0 77 #define MASK_LTR (DIRPROP_FLAG(L)|DIRPROP_FLAG(EN)|DIRPROP_FLAG(AN)|DIRPROP_FLAG(LRE)|DIRPROP_FLAG(LRO)|DIRPROP_FLAG(LRI))
michael@0 78 #define MASK_RTL (DIRPROP_FLAG(R)|DIRPROP_FLAG(AL)|DIRPROP_FLAG(RLE)|DIRPROP_FLAG(RLO)|DIRPROP_FLAG(RLI))
michael@0 79 #define MASK_R_AL (DIRPROP_FLAG(R)|DIRPROP_FLAG(AL))
michael@0 80 #define MASK_STRONG_EN_AN (DIRPROP_FLAG(L)|DIRPROP_FLAG(R)|DIRPROP_FLAG(AL)|DIRPROP_FLAG(EN)|DIRPROP_FLAG(AN))
michael@0 81
michael@0 82 /* explicit embedding codes */
michael@0 83 #define MASK_EXPLICIT (DIRPROP_FLAG(LRE)|DIRPROP_FLAG(LRO)|DIRPROP_FLAG(RLE)|DIRPROP_FLAG(RLO)|DIRPROP_FLAG(PDF))
michael@0 84
michael@0 85 /* explicit isolate codes */
michael@0 86 #define MASK_ISO (DIRPROP_FLAG(LRI)|DIRPROP_FLAG(RLI)|DIRPROP_FLAG(FSI)|DIRPROP_FLAG(PDI))
michael@0 87
michael@0 88 #define MASK_BN_EXPLICIT (DIRPROP_FLAG(BN)|MASK_EXPLICIT)
michael@0 89
michael@0 90 /* paragraph and segment separators */
michael@0 91 #define MASK_B_S (DIRPROP_FLAG(B)|DIRPROP_FLAG(S))
michael@0 92
michael@0 93 /* all types that are counted as White Space or Neutral in some steps */
michael@0 94 #define MASK_WS (MASK_B_S|DIRPROP_FLAG(WS)|MASK_BN_EXPLICIT|MASK_ISO)
michael@0 95
michael@0 96 /* types that are neutrals or could becomes neutrals in (Wn) */
michael@0 97 #define MASK_POSSIBLE_N (DIRPROP_FLAG(ON)|DIRPROP_FLAG(CS)|DIRPROP_FLAG(ES)|DIRPROP_FLAG(ET)|MASK_WS)
michael@0 98
michael@0 99 /*
michael@0 100 * These types may be changed to "e",
michael@0 101 * the embedding type (L or R) of the run,
michael@0 102 * in the BiDi algorithm (N2)
michael@0 103 */
michael@0 104 #define MASK_EMBEDDING (DIRPROP_FLAG(NSM)|MASK_POSSIBLE_N)
michael@0 105
michael@0 106 /* the dirProp's L and R are defined to 0 and 1 values in UCharDirection */
michael@0 107 #define GET_LR_FROM_LEVEL(level) ((DirProp)((level)&1))
michael@0 108
michael@0 109 #define IS_DEFAULT_LEVEL(level) ((level)>=0xfe)
michael@0 110
michael@0 111 /*
michael@0 112 * The following bit is ORed to the property of directional control
michael@0 113 * characters which are ignored: unmatched PDF or PDI; LRx, RLx or FSI
michael@0 114 * which would exceed the maximum explicit bidi level.
michael@0 115 */
michael@0 116 #define IGNORE_CC 0x40
michael@0 117
michael@0 118 #define PURE_DIRPROP(prop) ((prop)&~IGNORE_CC)
michael@0 119
michael@0 120 /*
michael@0 121 * The following bit is used for the directional isolate status.
michael@0 122 * Stack entries corresponding to isolate sequences are greater than ISOLATE.
michael@0 123 */
michael@0 124 #define ISOLATE 0x0100
michael@0 125
michael@0 126 U_CFUNC UBiDiLevel
michael@0 127 ubidi_getParaLevelAtIndex(const UBiDi *pBiDi, int32_t index);
michael@0 128
michael@0 129 #define GET_PARALEVEL(ubidi, index) \
michael@0 130 ((UBiDiLevel)(!(ubidi)->defaultParaLevel || (index)<(ubidi)->paras[0].limit ? \
michael@0 131 (ubidi)->paraLevel : ubidi_getParaLevelAtIndex((ubidi), (index))))
michael@0 132
michael@0 133 /* number of paras entries allocated initially without malloc */
michael@0 134 #define SIMPLE_PARAS_SIZE 10
michael@0 135 /* number of isolate entries allocated initially without malloc */
michael@0 136 #define SIMPLE_ISOLATES_SIZE 5
michael@0 137 /* number of isolate run entries for paired brackets allocated initially without malloc */
michael@0 138 #define SIMPLE_OPENINGS_SIZE 20
michael@0 139
michael@0 140 #define CR 0x000D
michael@0 141 #define LF 0x000A
michael@0 142
michael@0 143 /* Run structure for reordering --------------------------------------------- */
michael@0 144 enum {
michael@0 145 LRM_BEFORE=1,
michael@0 146 LRM_AFTER=2,
michael@0 147 RLM_BEFORE=4,
michael@0 148 RLM_AFTER=8
michael@0 149 };
michael@0 150
michael@0 151 typedef struct Para {
michael@0 152 int32_t limit;
michael@0 153 int32_t level;
michael@0 154 } Para;
michael@0 155
michael@0 156 enum { /* flags for Opening.flags */
michael@0 157 FOUND_L=DIRPROP_FLAG(L),
michael@0 158 FOUND_R=DIRPROP_FLAG(R)
michael@0 159 };
michael@0 160
michael@0 161 typedef struct Opening {
michael@0 162 int32_t position; /* position of opening bracket */
michael@0 163 int32_t match; /* matching char or -position of closing bracket */
michael@0 164 int32_t contextPos; /* position of last strong char found before opening */
michael@0 165 uint16_t flags; /* bits for L or R/AL found within the pair */
michael@0 166 UBiDiDirection contextDir; /* L or R according to last strong char before opening */
michael@0 167 uint8_t filler; /* to complete a nice multiple of 4 chars */
michael@0 168 } Opening;
michael@0 169
michael@0 170 typedef struct IsoRun {
michael@0 171 int32_t lastStrongPos; /* position of last strong char found in this run */
michael@0 172 int32_t contextPos; /* position of last char defining context */
michael@0 173 uint16_t start; /* index of first opening entry for this run */
michael@0 174 uint16_t limit; /* index after last opening entry for this run */
michael@0 175 UBiDiLevel level; /* level of this run */
michael@0 176 DirProp lastStrong; /* bidi class of last strong char found in this run */
michael@0 177 UBiDiDirection contextDir; /* L or R to use as context for following openings */
michael@0 178 uint8_t filler; /* to complete a nice multiple of 4 chars */
michael@0 179 } IsoRun;
michael@0 180
michael@0 181 typedef struct BracketData {
michael@0 182 UBiDi *pBiDi;
michael@0 183 /* array of opening entries which should be enough in most cases; no malloc() */
michael@0 184 Opening simpleOpenings[SIMPLE_OPENINGS_SIZE];
michael@0 185 Opening *openings; /* pointer to current array of entries */
michael@0 186 int32_t openingsSize; /* number of allocated entries */
michael@0 187 int32_t isoRunLast; /* index of last used entry */
michael@0 188 /* array of nested isolated sequence entries; can never excess UBIDI_MAX_EXPLICIT_LEVEL
michael@0 189 + 1 for index 0, + 1 for before the first isolated sequence */
michael@0 190 IsoRun isoRuns[UBIDI_MAX_EXPLICIT_LEVEL+2];
michael@0 191 UBool isNumbersSpecial; /* reordering mode for NUMBERS_SPECIAL */
michael@0 192 } BracketData;
michael@0 193
michael@0 194 typedef struct Isolate {
michael@0 195 int32_t start1;
michael@0 196 int16_t stateImp;
michael@0 197 int16_t state;
michael@0 198 } Isolate;
michael@0 199
michael@0 200 typedef struct Run {
michael@0 201 int32_t logicalStart, /* first character of the run; b31 indicates even/odd level */
michael@0 202 visualLimit, /* last visual position of the run +1 */
michael@0 203 insertRemove; /* if >0, flags for inserting LRM/RLM before/after run,
michael@0 204 if <0, count of bidi controls within run */
michael@0 205 } Run;
michael@0 206
michael@0 207 /* in a Run, logicalStart will get this bit set if the run level is odd */
michael@0 208 #define INDEX_ODD_BIT (1UL<<31)
michael@0 209
michael@0 210 #define MAKE_INDEX_ODD_PAIR(index, level) ((index)|((int32_t)(level)<<31))
michael@0 211 #define ADD_ODD_BIT_FROM_LEVEL(x, level) ((x)|=((int32_t)(level)<<31))
michael@0 212 #define REMOVE_ODD_BIT(x) ((x)&=~INDEX_ODD_BIT)
michael@0 213
michael@0 214 #define GET_INDEX(x) ((x)&~INDEX_ODD_BIT)
michael@0 215 #define GET_ODD_BIT(x) ((uint32_t)(x)>>31)
michael@0 216 #define IS_ODD_RUN(x) ((UBool)(((x)&INDEX_ODD_BIT)!=0))
michael@0 217 #define IS_EVEN_RUN(x) ((UBool)(((x)&INDEX_ODD_BIT)==0))
michael@0 218
michael@0 219 U_CFUNC UBool
michael@0 220 ubidi_getRuns(UBiDi *pBiDi, UErrorCode *pErrorCode);
michael@0 221
michael@0 222 /** BiDi control code points */
michael@0 223 enum {
michael@0 224 ZWNJ_CHAR=0x200c,
michael@0 225 ZWJ_CHAR,
michael@0 226 LRM_CHAR,
michael@0 227 RLM_CHAR,
michael@0 228 LRE_CHAR=0x202a,
michael@0 229 RLE_CHAR,
michael@0 230 PDF_CHAR,
michael@0 231 LRO_CHAR,
michael@0 232 RLO_CHAR,
michael@0 233 LRI_CHAR=0x2066,
michael@0 234 RLI_CHAR,
michael@0 235 FSI_CHAR,
michael@0 236 PDI_CHAR
michael@0 237 };
michael@0 238
michael@0 239 #define IS_BIDI_CONTROL_CHAR(c) (((uint32_t)(c)&0xfffffffc)==ZWNJ_CHAR || (uint32_t)((c)-LRE_CHAR)<5 || (uint32_t)((c)-LRI_CHAR)<4)
michael@0 240
michael@0 241 /* InsertPoints structure for noting where to put BiDi marks ---------------- */
michael@0 242
michael@0 243 typedef struct Point {
michael@0 244 int32_t pos; /* position in text */
michael@0 245 int32_t flag; /* flag for LRM/RLM, before/after */
michael@0 246 } Point;
michael@0 247
michael@0 248 typedef struct InsertPoints {
michael@0 249 int32_t capacity; /* number of points allocated */
michael@0 250 int32_t size; /* number of points used */
michael@0 251 int32_t confirmed; /* number of points confirmed */
michael@0 252 UErrorCode errorCode; /* for eventual memory shortage */
michael@0 253 Point *points; /* pointer to array of points */
michael@0 254 } InsertPoints;
michael@0 255
michael@0 256
michael@0 257 /* UBiDi structure ----------------------------------------------------------- */
michael@0 258
michael@0 259 struct UBiDi {
michael@0 260 /* pointer to parent paragraph object (pointer to self if this object is
michael@0 261 * a paragraph object); set to NULL in a newly opened object; set to a
michael@0 262 * real value after a successful execution of ubidi_setPara or ubidi_setLine
michael@0 263 */
michael@0 264 const UBiDi * pParaBiDi;
michael@0 265
michael@0 266 const UBiDiProps *bdp;
michael@0 267
michael@0 268 /* alias pointer to the current text */
michael@0 269 const UChar *text;
michael@0 270
michael@0 271 /* length of the current text */
michael@0 272 int32_t originalLength;
michael@0 273
michael@0 274 /* if the UBIDI_OPTION_STREAMING option is set, this is the length
michael@0 275 * of text actually processed by ubidi_setPara, which may be shorter than
michael@0 276 * the original length.
michael@0 277 * Otherwise, it is identical to the original length.
michael@0 278 */
michael@0 279 int32_t length;
michael@0 280
michael@0 281 /* if the UBIDI_OPTION_REMOVE_CONTROLS option is set, and/or
michael@0 282 * marks are allowed to be inserted in one of the reordering mode, the
michael@0 283 * length of the result string may be different from the processed length.
michael@0 284 */
michael@0 285 int32_t resultLength;
michael@0 286
michael@0 287 /* memory sizes in bytes */
michael@0 288 int32_t dirPropsSize, levelsSize, openingsSize, parasSize, runsSize, isolatesSize;
michael@0 289
michael@0 290 /* allocated memory */
michael@0 291 DirProp *dirPropsMemory;
michael@0 292 UBiDiLevel *levelsMemory;
michael@0 293 Opening *openingsMemory;
michael@0 294 Para *parasMemory;
michael@0 295 Run *runsMemory;
michael@0 296 Isolate *isolatesMemory;
michael@0 297
michael@0 298 /* indicators for whether memory may be allocated after ubidi_open() */
michael@0 299 UBool mayAllocateText, mayAllocateRuns;
michael@0 300
michael@0 301 /* arrays with one value per text-character */
michael@0 302 DirProp *dirProps;
michael@0 303 UBiDiLevel *levels;
michael@0 304
michael@0 305 /* are we performing an approximation of the "inverse BiDi" algorithm? */
michael@0 306 UBool isInverse;
michael@0 307
michael@0 308 /* are we using the basic algorithm or its variation? */
michael@0 309 UBiDiReorderingMode reorderingMode;
michael@0 310
michael@0 311 /* UBIDI_REORDER_xxx values must be ordered so that all the regular
michael@0 312 * logical to visual modes come first, and all inverse BiDi modes
michael@0 313 * come last.
michael@0 314 */
michael@0 315 #define UBIDI_REORDER_LAST_LOGICAL_TO_VISUAL UBIDI_REORDER_NUMBERS_SPECIAL
michael@0 316
michael@0 317 /* bitmask for reordering options */
michael@0 318 uint32_t reorderingOptions;
michael@0 319
michael@0 320 /* must block separators receive level 0? */
michael@0 321 UBool orderParagraphsLTR;
michael@0 322
michael@0 323 /* the paragraph level */
michael@0 324 UBiDiLevel paraLevel;
michael@0 325 /* original paraLevel when contextual */
michael@0 326 /* must be one of UBIDI_DEFAULT_xxx or 0 if not contextual */
michael@0 327 UBiDiLevel defaultParaLevel;
michael@0 328
michael@0 329 /* context data */
michael@0 330 const UChar *prologue;
michael@0 331 int32_t proLength;
michael@0 332 const UChar *epilogue;
michael@0 333 int32_t epiLength;
michael@0 334
michael@0 335 /* the following is set in ubidi_setPara, used in processPropertySeq */
michael@0 336 const struct ImpTabPair * pImpTabPair; /* pointer to levels state table pair */
michael@0 337
michael@0 338 /* the overall paragraph or line directionality - see UBiDiDirection */
michael@0 339 UBiDiDirection direction;
michael@0 340
michael@0 341 /* flags is a bit set for which directional properties are in the text */
michael@0 342 Flags flags;
michael@0 343
michael@0 344 /* lastArabicPos is index to the last AL in the text, -1 if none */
michael@0 345 int32_t lastArabicPos;
michael@0 346
michael@0 347 /* characters after trailingWSStart are WS and are */
michael@0 348 /* implicitly at the paraLevel (rule (L1)) - levels may not reflect that */
michael@0 349 int32_t trailingWSStart;
michael@0 350
michael@0 351 /* fields for paragraph handling */
michael@0 352 int32_t paraCount; /* set in getDirProps() */
michael@0 353 /* filled in getDirProps() */
michael@0 354 Para *paras;
michael@0 355
michael@0 356 /* for relatively short text, we only need a tiny array of paras (no malloc()) */
michael@0 357 Para simpleParas[SIMPLE_PARAS_SIZE];
michael@0 358
michael@0 359 /* fields for line reordering */
michael@0 360 int32_t runCount; /* ==-1: runs not set up yet */
michael@0 361 Run *runs;
michael@0 362
michael@0 363 /* for non-mixed text, we only need a tiny array of runs (no malloc()) */
michael@0 364 Run simpleRuns[1];
michael@0 365
michael@0 366 /* maximum or current nesting depth of isolate sequences */
michael@0 367 /* Within resolveExplicitLevels() and checkExplicitLevels(), this is the maximal
michael@0 368 nesting encountered.
michael@0 369 Within resolveImplicitLevels(), this is the index of the current isolates
michael@0 370 stack entry. */
michael@0 371 int32_t isolateCount;
michael@0 372 Isolate *isolates;
michael@0 373
michael@0 374 /* for simple text, have a small stack (no malloc()) */
michael@0 375 Isolate simpleIsolates[SIMPLE_ISOLATES_SIZE];
michael@0 376
michael@0 377 /* for inverse Bidi with insertion of directional marks */
michael@0 378 InsertPoints insertPoints;
michael@0 379
michael@0 380 /* for option UBIDI_OPTION_REMOVE_CONTROLS */
michael@0 381 int32_t controlCount;
michael@0 382
michael@0 383 /* for Bidi class callback */
michael@0 384 UBiDiClassCallback *fnClassCallback; /* action pointer */
michael@0 385 const void *coClassCallback; /* context pointer */
michael@0 386 };
michael@0 387
michael@0 388 #define IS_VALID_PARA(x) ((x) && ((x)->pParaBiDi==(x)))
michael@0 389 #define IS_VALID_PARA_OR_LINE(x) ((x) && ((x)->pParaBiDi==(x) || (((x)->pParaBiDi) && (x)->pParaBiDi->pParaBiDi==(x)->pParaBiDi)))
michael@0 390
michael@0 391 typedef union {
michael@0 392 DirProp *dirPropsMemory;
michael@0 393 UBiDiLevel *levelsMemory;
michael@0 394 Opening *openingsMemory;
michael@0 395 Para *parasMemory;
michael@0 396 Run *runsMemory;
michael@0 397 Isolate *isolatesMemory;
michael@0 398 } BidiMemoryForAllocation;
michael@0 399
michael@0 400 /* Macros for initial checks at function entry */
michael@0 401 #define RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrcode, retvalue) \
michael@0 402 if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return retvalue
michael@0 403 #define RETURN_IF_NOT_VALID_PARA(bidi, errcode, retvalue) \
michael@0 404 if(!IS_VALID_PARA(bidi)) { \
michael@0 405 errcode=U_INVALID_STATE_ERROR; \
michael@0 406 return retvalue; \
michael@0 407 }
michael@0 408 #define RETURN_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode, retvalue) \
michael@0 409 if(!IS_VALID_PARA_OR_LINE(bidi)) { \
michael@0 410 errcode=U_INVALID_STATE_ERROR; \
michael@0 411 return retvalue; \
michael@0 412 }
michael@0 413 #define RETURN_IF_BAD_RANGE(arg, start, limit, errcode, retvalue) \
michael@0 414 if((arg)<(start) || (arg)>=(limit)) { \
michael@0 415 (errcode)=U_ILLEGAL_ARGUMENT_ERROR; \
michael@0 416 return retvalue; \
michael@0 417 }
michael@0 418
michael@0 419 #define RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrcode) \
michael@0 420 if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return
michael@0 421 #define RETURN_VOID_IF_NOT_VALID_PARA(bidi, errcode) \
michael@0 422 if(!IS_VALID_PARA(bidi)) { \
michael@0 423 errcode=U_INVALID_STATE_ERROR; \
michael@0 424 return; \
michael@0 425 }
michael@0 426 #define RETURN_VOID_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode) \
michael@0 427 if(!IS_VALID_PARA_OR_LINE(bidi)) { \
michael@0 428 errcode=U_INVALID_STATE_ERROR; \
michael@0 429 return; \
michael@0 430 }
michael@0 431 #define RETURN_VOID_IF_BAD_RANGE(arg, start, limit, errcode) \
michael@0 432 if((arg)<(start) || (arg)>=(limit)) { \
michael@0 433 (errcode)=U_ILLEGAL_ARGUMENT_ERROR; \
michael@0 434 return; \
michael@0 435 }
michael@0 436
michael@0 437 /* helper function to (re)allocate memory if allowed */
michael@0 438 U_CFUNC UBool
michael@0 439 ubidi_getMemory(BidiMemoryForAllocation *pMemory, int32_t *pSize, UBool mayAllocate, int32_t sizeNeeded);
michael@0 440
michael@0 441 /* helper macros for each allocated array in UBiDi */
michael@0 442 #define getDirPropsMemory(pBiDi, length) \
michael@0 443 ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->dirPropsMemory, &(pBiDi)->dirPropsSize, \
michael@0 444 (pBiDi)->mayAllocateText, (length))
michael@0 445
michael@0 446 #define getLevelsMemory(pBiDi, length) \
michael@0 447 ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->levelsMemory, &(pBiDi)->levelsSize, \
michael@0 448 (pBiDi)->mayAllocateText, (length))
michael@0 449
michael@0 450 #define getRunsMemory(pBiDi, length) \
michael@0 451 ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->runsMemory, &(pBiDi)->runsSize, \
michael@0 452 (pBiDi)->mayAllocateRuns, (length)*sizeof(Run))
michael@0 453
michael@0 454 /* additional macros used by ubidi_open() - always allow allocation */
michael@0 455 #define getInitialDirPropsMemory(pBiDi, length) \
michael@0 456 ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->dirPropsMemory, &(pBiDi)->dirPropsSize, \
michael@0 457 TRUE, (length))
michael@0 458
michael@0 459 #define getInitialLevelsMemory(pBiDi, length) \
michael@0 460 ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->levelsMemory, &(pBiDi)->levelsSize, \
michael@0 461 TRUE, (length))
michael@0 462
michael@0 463 #define getInitialOpeningsMemory(pBiDi, length) \
michael@0 464 ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->openingsMemory, &(pBiDi)->openingsSize, \
michael@0 465 TRUE, (length)*sizeof(Opening))
michael@0 466
michael@0 467 #define getInitialParasMemory(pBiDi, length) \
michael@0 468 ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->parasMemory, &(pBiDi)->parasSize, \
michael@0 469 TRUE, (length)*sizeof(Para))
michael@0 470
michael@0 471 #define getInitialRunsMemory(pBiDi, length) \
michael@0 472 ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->runsMemory, &(pBiDi)->runsSize, \
michael@0 473 TRUE, (length)*sizeof(Run))
michael@0 474
michael@0 475 #define getInitialIsolatesMemory(pBiDi, length) \
michael@0 476 ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->isolatesMemory, &(pBiDi)->isolatesSize, \
michael@0 477 TRUE, (length)*sizeof(Isolate))
michael@0 478
michael@0 479 #endif
michael@0 480
michael@0 481 #endif

mercurial