intl/icu/source/common/ubidiimp.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/intl/icu/source/common/ubidiimp.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,481 @@
     1.4 +/*
     1.5 +******************************************************************************
     1.6 +*
     1.7 +*   Copyright (C) 1999-2013, International Business Machines
     1.8 +*   Corporation and others.  All Rights Reserved.
     1.9 +*
    1.10 +******************************************************************************
    1.11 +*   file name:  ubidiimp.h
    1.12 +*   encoding:   US-ASCII
    1.13 +*   tab size:   8 (not used)
    1.14 +*   indentation:4
    1.15 +*
    1.16 +*   created on: 1999aug06
    1.17 +*   created by: Markus W. Scherer, updated by Matitiahu Allouche
    1.18 +*/
    1.19 +
    1.20 +#ifndef UBIDIIMP_H
    1.21 +#define UBIDIIMP_H
    1.22 +
    1.23 +/* set import/export definitions */
    1.24 +#ifdef U_COMMON_IMPLEMENTATION
    1.25 +
    1.26 +#include "unicode/utypes.h"
    1.27 +#include "unicode/uchar.h"
    1.28 +#include "ubidi_props.h"
    1.29 +
    1.30 +/* miscellaneous definitions ---------------------------------------------- */
    1.31 +
    1.32 +typedef uint8_t DirProp;
    1.33 +typedef uint32_t Flags;
    1.34 +
    1.35 +/*  Comparing the description of the BiDi algorithm with this implementation
    1.36 +    is easier with the same names for the BiDi types in the code as there.
    1.37 +    See UCharDirection in uchar.h .
    1.38 +*/
    1.39 +enum {
    1.40 +    L=  U_LEFT_TO_RIGHT,                /*  0 */
    1.41 +    R=  U_RIGHT_TO_LEFT,                /*  1 */
    1.42 +    EN= U_EUROPEAN_NUMBER,              /*  2 */
    1.43 +    ES= U_EUROPEAN_NUMBER_SEPARATOR,    /*  3 */
    1.44 +    ET= U_EUROPEAN_NUMBER_TERMINATOR,   /*  4 */
    1.45 +    AN= U_ARABIC_NUMBER,                /*  5 */
    1.46 +    CS= U_COMMON_NUMBER_SEPARATOR,      /*  6 */
    1.47 +    B=  U_BLOCK_SEPARATOR,              /*  7 */
    1.48 +    S=  U_SEGMENT_SEPARATOR,            /*  8 */
    1.49 +    WS= U_WHITE_SPACE_NEUTRAL,          /*  9 */
    1.50 +    ON= U_OTHER_NEUTRAL,                /* 10 */
    1.51 +    LRE=U_LEFT_TO_RIGHT_EMBEDDING,      /* 11 */
    1.52 +    LRO=U_LEFT_TO_RIGHT_OVERRIDE,       /* 12 */
    1.53 +    AL= U_RIGHT_TO_LEFT_ARABIC,         /* 13 */
    1.54 +    RLE=U_RIGHT_TO_LEFT_EMBEDDING,      /* 14 */
    1.55 +    RLO=U_RIGHT_TO_LEFT_OVERRIDE,       /* 15 */
    1.56 +    PDF=U_POP_DIRECTIONAL_FORMAT,       /* 16 */
    1.57 +    NSM=U_DIR_NON_SPACING_MARK,         /* 17 */
    1.58 +    BN= U_BOUNDARY_NEUTRAL,             /* 18 */
    1.59 +    FSI=U_FIRST_STRONG_ISOLATE,         /* 19 */
    1.60 +    LRI=U_LEFT_TO_RIGHT_ISOLATE,        /* 20 */
    1.61 +    RLI=U_RIGHT_TO_LEFT_ISOLATE,        /* 21 */
    1.62 +    PDI=U_POP_DIRECTIONAL_ISOLATE,      /* 22 */
    1.63 +    ENL,                                /* 23 */
    1.64 +    ENR,                                /* 24 */
    1.65 +    dirPropCount
    1.66 +};
    1.67 +
    1.68 +/*
    1.69 + * Sometimes, bit values are more appropriate
    1.70 + * to deal with directionality properties.
    1.71 + * Abbreviations in these macro names refer to names
    1.72 + * used in the BiDi algorithm.
    1.73 + */
    1.74 +#define DIRPROP_FLAG(dir) (1UL<<(dir))
    1.75 +
    1.76 +/* special flag for multiple runs from explicit embedding codes */
    1.77 +#define DIRPROP_FLAG_MULTI_RUNS (1UL<<31)
    1.78 +
    1.79 +/* are there any characters that are LTR or RTL? */
    1.80 +#define MASK_LTR (DIRPROP_FLAG(L)|DIRPROP_FLAG(EN)|DIRPROP_FLAG(AN)|DIRPROP_FLAG(LRE)|DIRPROP_FLAG(LRO)|DIRPROP_FLAG(LRI))
    1.81 +#define MASK_RTL (DIRPROP_FLAG(R)|DIRPROP_FLAG(AL)|DIRPROP_FLAG(RLE)|DIRPROP_FLAG(RLO)|DIRPROP_FLAG(RLI))
    1.82 +#define MASK_R_AL (DIRPROP_FLAG(R)|DIRPROP_FLAG(AL))
    1.83 +#define MASK_STRONG_EN_AN (DIRPROP_FLAG(L)|DIRPROP_FLAG(R)|DIRPROP_FLAG(AL)|DIRPROP_FLAG(EN)|DIRPROP_FLAG(AN))
    1.84 +
    1.85 +/* explicit embedding codes */
    1.86 +#define MASK_EXPLICIT (DIRPROP_FLAG(LRE)|DIRPROP_FLAG(LRO)|DIRPROP_FLAG(RLE)|DIRPROP_FLAG(RLO)|DIRPROP_FLAG(PDF))
    1.87 +
    1.88 +/* explicit isolate codes */
    1.89 +#define MASK_ISO (DIRPROP_FLAG(LRI)|DIRPROP_FLAG(RLI)|DIRPROP_FLAG(FSI)|DIRPROP_FLAG(PDI))
    1.90 +
    1.91 +#define MASK_BN_EXPLICIT (DIRPROP_FLAG(BN)|MASK_EXPLICIT)
    1.92 +
    1.93 +/* paragraph and segment separators */
    1.94 +#define MASK_B_S (DIRPROP_FLAG(B)|DIRPROP_FLAG(S))
    1.95 +
    1.96 +/* all types that are counted as White Space or Neutral in some steps */
    1.97 +#define MASK_WS (MASK_B_S|DIRPROP_FLAG(WS)|MASK_BN_EXPLICIT|MASK_ISO)
    1.98 +
    1.99 +/* types that are neutrals or could becomes neutrals in (Wn) */
   1.100 +#define MASK_POSSIBLE_N (DIRPROP_FLAG(ON)|DIRPROP_FLAG(CS)|DIRPROP_FLAG(ES)|DIRPROP_FLAG(ET)|MASK_WS)
   1.101 +
   1.102 +/*
   1.103 + * These types may be changed to "e",
   1.104 + * the embedding type (L or R) of the run,
   1.105 + * in the BiDi algorithm (N2)
   1.106 + */
   1.107 +#define MASK_EMBEDDING (DIRPROP_FLAG(NSM)|MASK_POSSIBLE_N)
   1.108 +
   1.109 +/* the dirProp's L and R are defined to 0 and 1 values in UCharDirection */
   1.110 +#define GET_LR_FROM_LEVEL(level) ((DirProp)((level)&1))
   1.111 +
   1.112 +#define IS_DEFAULT_LEVEL(level) ((level)>=0xfe)
   1.113 +
   1.114 +/*
   1.115 + * The following bit is ORed to the property of directional control
   1.116 + * characters which are ignored: unmatched PDF or PDI; LRx, RLx or FSI
   1.117 + * which would exceed the maximum explicit bidi level.
   1.118 + */
   1.119 +#define IGNORE_CC   0x40
   1.120 +
   1.121 +#define PURE_DIRPROP(prop)  ((prop)&~IGNORE_CC)
   1.122 +
   1.123 +/*
   1.124 + * The following bit is used for the directional isolate status.
   1.125 + * Stack entries corresponding to isolate sequences are greater than ISOLATE.
   1.126 + */
   1.127 +#define ISOLATE  0x0100
   1.128 +
   1.129 +U_CFUNC UBiDiLevel
   1.130 +ubidi_getParaLevelAtIndex(const UBiDi *pBiDi, int32_t index);
   1.131 +
   1.132 +#define GET_PARALEVEL(ubidi, index) \
   1.133 +            ((UBiDiLevel)(!(ubidi)->defaultParaLevel || (index)<(ubidi)->paras[0].limit ? \
   1.134 +                         (ubidi)->paraLevel : ubidi_getParaLevelAtIndex((ubidi), (index))))
   1.135 +
   1.136 +/* number of paras entries allocated initially without malloc */
   1.137 +#define SIMPLE_PARAS_SIZE   10
   1.138 +/* number of isolate entries allocated initially without malloc */
   1.139 +#define SIMPLE_ISOLATES_SIZE 5
   1.140 +/* number of isolate run entries for paired brackets allocated initially without malloc */
   1.141 +#define SIMPLE_OPENINGS_SIZE 20
   1.142 +
   1.143 +#define CR  0x000D
   1.144 +#define LF  0x000A
   1.145 +
   1.146 +/* Run structure for reordering --------------------------------------------- */
   1.147 +enum {
   1.148 +    LRM_BEFORE=1,
   1.149 +    LRM_AFTER=2,
   1.150 +    RLM_BEFORE=4,
   1.151 +    RLM_AFTER=8
   1.152 +};
   1.153 +
   1.154 +typedef struct Para {
   1.155 +    int32_t limit;
   1.156 +    int32_t level;
   1.157 +} Para;
   1.158 +
   1.159 +enum {                                  /* flags for Opening.flags */
   1.160 +    FOUND_L=DIRPROP_FLAG(L),
   1.161 +    FOUND_R=DIRPROP_FLAG(R)
   1.162 +};
   1.163 +
   1.164 +typedef struct Opening {
   1.165 +    int32_t position;                   /* position of opening bracket */
   1.166 +    int32_t match;                      /* matching char or -position of closing bracket */
   1.167 +    int32_t contextPos;                 /* position of last strong char found before opening */
   1.168 +    uint16_t flags;                     /* bits for L or R/AL found within the pair */
   1.169 +    UBiDiDirection contextDir;          /* L or R according to last strong char before opening */
   1.170 +    uint8_t filler;                     /* to complete a nice multiple of 4 chars */
   1.171 +} Opening;
   1.172 +
   1.173 +typedef struct IsoRun {
   1.174 +    int32_t  lastStrongPos;             /* position of last strong char found in this run */
   1.175 +    int32_t  contextPos;                /* position of last char defining context */
   1.176 +    uint16_t start;                     /* index of first opening entry for this run */
   1.177 +    uint16_t limit;                     /* index after last opening entry for this run */
   1.178 +    UBiDiLevel level;                   /* level of this run */
   1.179 +    DirProp lastStrong;                 /* bidi class of last strong char found in this run */
   1.180 +    UBiDiDirection contextDir;          /* L or R to use as context for following openings */
   1.181 +    uint8_t filler;                     /* to complete a nice multiple of 4 chars */
   1.182 +} IsoRun;
   1.183 +
   1.184 +typedef struct BracketData {
   1.185 +    UBiDi   *pBiDi;
   1.186 +    /* array of opening entries which should be enough in most cases; no malloc() */
   1.187 +    Opening simpleOpenings[SIMPLE_OPENINGS_SIZE];
   1.188 +    Opening *openings;                  /* pointer to current array of entries */
   1.189 +    int32_t openingsSize;               /* number of allocated entries */
   1.190 +    int32_t isoRunLast;                 /* index of last used entry */
   1.191 +    /* array of nested isolated sequence entries; can never excess UBIDI_MAX_EXPLICIT_LEVEL
   1.192 +       + 1 for index 0, + 1 for before the first isolated sequence */
   1.193 +    IsoRun  isoRuns[UBIDI_MAX_EXPLICIT_LEVEL+2];
   1.194 +    UBool isNumbersSpecial;             /* reordering mode for NUMBERS_SPECIAL */
   1.195 +} BracketData;
   1.196 +
   1.197 +typedef struct Isolate {
   1.198 +    int32_t start1;
   1.199 +    int16_t stateImp;
   1.200 +    int16_t state;
   1.201 +} Isolate;
   1.202 +
   1.203 +typedef struct Run {
   1.204 +    int32_t logicalStart,   /* first character of the run; b31 indicates even/odd level */
   1.205 +            visualLimit,    /* last visual position of the run +1 */
   1.206 +            insertRemove;   /* if >0, flags for inserting LRM/RLM before/after run,
   1.207 +                               if <0, count of bidi controls within run            */
   1.208 +} Run;
   1.209 +
   1.210 +/* in a Run, logicalStart will get this bit set if the run level is odd */
   1.211 +#define INDEX_ODD_BIT (1UL<<31)
   1.212 +
   1.213 +#define MAKE_INDEX_ODD_PAIR(index, level) ((index)|((int32_t)(level)<<31))
   1.214 +#define ADD_ODD_BIT_FROM_LEVEL(x, level)  ((x)|=((int32_t)(level)<<31))
   1.215 +#define REMOVE_ODD_BIT(x)                 ((x)&=~INDEX_ODD_BIT)
   1.216 +
   1.217 +#define GET_INDEX(x)   ((x)&~INDEX_ODD_BIT)
   1.218 +#define GET_ODD_BIT(x) ((uint32_t)(x)>>31)
   1.219 +#define IS_ODD_RUN(x)  ((UBool)(((x)&INDEX_ODD_BIT)!=0))
   1.220 +#define IS_EVEN_RUN(x) ((UBool)(((x)&INDEX_ODD_BIT)==0))
   1.221 +
   1.222 +U_CFUNC UBool
   1.223 +ubidi_getRuns(UBiDi *pBiDi, UErrorCode *pErrorCode);
   1.224 +
   1.225 +/** BiDi control code points */
   1.226 +enum {
   1.227 +    ZWNJ_CHAR=0x200c,
   1.228 +    ZWJ_CHAR,
   1.229 +    LRM_CHAR,
   1.230 +    RLM_CHAR,
   1.231 +    LRE_CHAR=0x202a,
   1.232 +    RLE_CHAR,
   1.233 +    PDF_CHAR,
   1.234 +    LRO_CHAR,
   1.235 +    RLO_CHAR,
   1.236 +    LRI_CHAR=0x2066,
   1.237 +    RLI_CHAR,
   1.238 +    FSI_CHAR,
   1.239 +    PDI_CHAR
   1.240 +};
   1.241 +
   1.242 +#define IS_BIDI_CONTROL_CHAR(c) (((uint32_t)(c)&0xfffffffc)==ZWNJ_CHAR || (uint32_t)((c)-LRE_CHAR)<5 || (uint32_t)((c)-LRI_CHAR)<4)
   1.243 +
   1.244 +/* InsertPoints structure for noting where to put BiDi marks ---------------- */
   1.245 +
   1.246 +typedef struct Point {
   1.247 +    int32_t pos;            /* position in text */
   1.248 +    int32_t flag;           /* flag for LRM/RLM, before/after */
   1.249 +} Point;
   1.250 +
   1.251 +typedef struct InsertPoints {
   1.252 +    int32_t capacity;       /* number of points allocated */
   1.253 +    int32_t size;           /* number of points used */
   1.254 +    int32_t confirmed;      /* number of points confirmed */
   1.255 +    UErrorCode errorCode;   /* for eventual memory shortage */
   1.256 +    Point *points;          /* pointer to array of points */
   1.257 +} InsertPoints;
   1.258 +
   1.259 +
   1.260 +/* UBiDi structure ----------------------------------------------------------- */
   1.261 +
   1.262 +struct UBiDi {
   1.263 +    /* pointer to parent paragraph object (pointer to self if this object is
   1.264 +     * a paragraph object); set to NULL in a newly opened object; set to a
   1.265 +     * real value after a successful execution of ubidi_setPara or ubidi_setLine
   1.266 +     */
   1.267 +    const UBiDi * pParaBiDi;
   1.268 +
   1.269 +    const UBiDiProps *bdp;
   1.270 +
   1.271 +    /* alias pointer to the current text */
   1.272 +    const UChar *text;
   1.273 +
   1.274 +    /* length of the current text */
   1.275 +    int32_t originalLength;
   1.276 +
   1.277 +    /* if the UBIDI_OPTION_STREAMING option is set, this is the length
   1.278 +     * of text actually processed by ubidi_setPara, which may be shorter than
   1.279 +     * the original length.
   1.280 +     * Otherwise, it is identical to the original length.
   1.281 +     */
   1.282 +    int32_t length;
   1.283 +
   1.284 +    /* if the UBIDI_OPTION_REMOVE_CONTROLS option is set, and/or
   1.285 +     * marks are allowed to be inserted in one of the reordering mode, the
   1.286 +     * length of the result string may be different from the processed length.
   1.287 +     */
   1.288 +    int32_t resultLength;
   1.289 +
   1.290 +    /* memory sizes in bytes */
   1.291 +    int32_t dirPropsSize, levelsSize, openingsSize, parasSize, runsSize, isolatesSize;
   1.292 +
   1.293 +    /* allocated memory */
   1.294 +    DirProp *dirPropsMemory;
   1.295 +    UBiDiLevel *levelsMemory;
   1.296 +    Opening *openingsMemory;
   1.297 +    Para *parasMemory;
   1.298 +    Run *runsMemory;
   1.299 +    Isolate *isolatesMemory;
   1.300 +
   1.301 +    /* indicators for whether memory may be allocated after ubidi_open() */
   1.302 +    UBool mayAllocateText, mayAllocateRuns;
   1.303 +
   1.304 +    /* arrays with one value per text-character */
   1.305 +    DirProp *dirProps;
   1.306 +    UBiDiLevel *levels;
   1.307 +
   1.308 +    /* are we performing an approximation of the "inverse BiDi" algorithm? */
   1.309 +    UBool isInverse;
   1.310 +
   1.311 +    /* are we using the basic algorithm or its variation? */
   1.312 +    UBiDiReorderingMode reorderingMode;
   1.313 +
   1.314 +    /* UBIDI_REORDER_xxx values must be ordered so that all the regular
   1.315 +     * logical to visual modes come first, and all inverse BiDi modes
   1.316 +     * come last.
   1.317 +     */
   1.318 +    #define UBIDI_REORDER_LAST_LOGICAL_TO_VISUAL    UBIDI_REORDER_NUMBERS_SPECIAL
   1.319 +
   1.320 +    /* bitmask for reordering options */
   1.321 +    uint32_t reorderingOptions;
   1.322 +
   1.323 +    /* must block separators receive level 0? */
   1.324 +    UBool orderParagraphsLTR;
   1.325 +
   1.326 +    /* the paragraph level */
   1.327 +    UBiDiLevel paraLevel;
   1.328 +    /* original paraLevel when contextual */
   1.329 +    /* must be one of UBIDI_DEFAULT_xxx or 0 if not contextual */
   1.330 +    UBiDiLevel defaultParaLevel;
   1.331 +
   1.332 +    /* context data */
   1.333 +    const UChar *prologue;
   1.334 +    int32_t proLength;
   1.335 +    const UChar *epilogue;
   1.336 +    int32_t epiLength;
   1.337 +
   1.338 +    /* the following is set in ubidi_setPara, used in processPropertySeq */
   1.339 +    const struct ImpTabPair * pImpTabPair;  /* pointer to levels state table pair */
   1.340 +
   1.341 +    /* the overall paragraph or line directionality - see UBiDiDirection */
   1.342 +    UBiDiDirection direction;
   1.343 +
   1.344 +    /* flags is a bit set for which directional properties are in the text */
   1.345 +    Flags flags;
   1.346 +
   1.347 +    /* lastArabicPos is index to the last AL in the text, -1 if none */
   1.348 +    int32_t lastArabicPos;
   1.349 +
   1.350 +    /* characters after trailingWSStart are WS and are */
   1.351 +    /* implicitly at the paraLevel (rule (L1)) - levels may not reflect that */
   1.352 +    int32_t trailingWSStart;
   1.353 +
   1.354 +    /* fields for paragraph handling */
   1.355 +    int32_t paraCount;                  /* set in getDirProps() */
   1.356 +    /* filled in getDirProps() */
   1.357 +    Para *paras;
   1.358 +
   1.359 +    /* for relatively short text, we only need a tiny array of paras (no malloc()) */
   1.360 +    Para simpleParas[SIMPLE_PARAS_SIZE];
   1.361 +
   1.362 +    /* fields for line reordering */
   1.363 +    int32_t runCount;     /* ==-1: runs not set up yet */
   1.364 +    Run *runs;
   1.365 +
   1.366 +    /* for non-mixed text, we only need a tiny array of runs (no malloc()) */
   1.367 +    Run simpleRuns[1];
   1.368 +
   1.369 +    /* maximum or current nesting depth of isolate sequences */
   1.370 +    /* Within resolveExplicitLevels() and checkExplicitLevels(), this is the maximal
   1.371 +       nesting encountered.
   1.372 +       Within resolveImplicitLevels(), this is the index of the current isolates
   1.373 +       stack entry. */
   1.374 +    int32_t isolateCount;
   1.375 +    Isolate *isolates;
   1.376 +
   1.377 +    /* for simple text, have a small stack (no malloc()) */
   1.378 +    Isolate simpleIsolates[SIMPLE_ISOLATES_SIZE];
   1.379 +
   1.380 +    /* for inverse Bidi with insertion of directional marks */
   1.381 +    InsertPoints insertPoints;
   1.382 +
   1.383 +    /* for option UBIDI_OPTION_REMOVE_CONTROLS */
   1.384 +    int32_t controlCount;
   1.385 +
   1.386 +    /* for Bidi class callback */
   1.387 +    UBiDiClassCallback *fnClassCallback;    /* action pointer */
   1.388 +    const void *coClassCallback;            /* context pointer */
   1.389 +};
   1.390 +
   1.391 +#define IS_VALID_PARA(x) ((x) && ((x)->pParaBiDi==(x)))
   1.392 +#define IS_VALID_PARA_OR_LINE(x) ((x) && ((x)->pParaBiDi==(x) || (((x)->pParaBiDi) && (x)->pParaBiDi->pParaBiDi==(x)->pParaBiDi)))
   1.393 +
   1.394 +typedef union {
   1.395 +    DirProp *dirPropsMemory;
   1.396 +    UBiDiLevel *levelsMemory;
   1.397 +    Opening *openingsMemory;
   1.398 +    Para *parasMemory;
   1.399 +    Run *runsMemory;
   1.400 +    Isolate *isolatesMemory;
   1.401 +} BidiMemoryForAllocation;
   1.402 +
   1.403 +/* Macros for initial checks at function entry */
   1.404 +#define RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrcode, retvalue)   \
   1.405 +        if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return retvalue
   1.406 +#define RETURN_IF_NOT_VALID_PARA(bidi, errcode, retvalue)   \
   1.407 +        if(!IS_VALID_PARA(bidi)) {  \
   1.408 +            errcode=U_INVALID_STATE_ERROR;  \
   1.409 +            return retvalue;                \
   1.410 +        }
   1.411 +#define RETURN_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode, retvalue)   \
   1.412 +        if(!IS_VALID_PARA_OR_LINE(bidi)) {  \
   1.413 +            errcode=U_INVALID_STATE_ERROR;  \
   1.414 +            return retvalue;                \
   1.415 +        }
   1.416 +#define RETURN_IF_BAD_RANGE(arg, start, limit, errcode, retvalue)   \
   1.417 +        if((arg)<(start) || (arg)>=(limit)) {       \
   1.418 +            (errcode)=U_ILLEGAL_ARGUMENT_ERROR;     \
   1.419 +            return retvalue;                        \
   1.420 +        }
   1.421 +
   1.422 +#define RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrcode)   \
   1.423 +        if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return
   1.424 +#define RETURN_VOID_IF_NOT_VALID_PARA(bidi, errcode)   \
   1.425 +        if(!IS_VALID_PARA(bidi)) {  \
   1.426 +            errcode=U_INVALID_STATE_ERROR;  \
   1.427 +            return;                \
   1.428 +        }
   1.429 +#define RETURN_VOID_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode)   \
   1.430 +        if(!IS_VALID_PARA_OR_LINE(bidi)) {  \
   1.431 +            errcode=U_INVALID_STATE_ERROR;  \
   1.432 +            return;                \
   1.433 +        }
   1.434 +#define RETURN_VOID_IF_BAD_RANGE(arg, start, limit, errcode)   \
   1.435 +        if((arg)<(start) || (arg)>=(limit)) {       \
   1.436 +            (errcode)=U_ILLEGAL_ARGUMENT_ERROR;     \
   1.437 +            return;                        \
   1.438 +        }
   1.439 +
   1.440 +/* helper function to (re)allocate memory if allowed */
   1.441 +U_CFUNC UBool
   1.442 +ubidi_getMemory(BidiMemoryForAllocation *pMemory, int32_t *pSize, UBool mayAllocate, int32_t sizeNeeded);
   1.443 +
   1.444 +/* helper macros for each allocated array in UBiDi */
   1.445 +#define getDirPropsMemory(pBiDi, length) \
   1.446 +        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->dirPropsMemory, &(pBiDi)->dirPropsSize, \
   1.447 +                        (pBiDi)->mayAllocateText, (length))
   1.448 +
   1.449 +#define getLevelsMemory(pBiDi, length) \
   1.450 +        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->levelsMemory, &(pBiDi)->levelsSize, \
   1.451 +                        (pBiDi)->mayAllocateText, (length))
   1.452 +
   1.453 +#define getRunsMemory(pBiDi, length) \
   1.454 +        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->runsMemory, &(pBiDi)->runsSize, \
   1.455 +                        (pBiDi)->mayAllocateRuns, (length)*sizeof(Run))
   1.456 +
   1.457 +/* additional macros used by ubidi_open() - always allow allocation */
   1.458 +#define getInitialDirPropsMemory(pBiDi, length) \
   1.459 +        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->dirPropsMemory, &(pBiDi)->dirPropsSize, \
   1.460 +                        TRUE, (length))
   1.461 +
   1.462 +#define getInitialLevelsMemory(pBiDi, length) \
   1.463 +        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->levelsMemory, &(pBiDi)->levelsSize, \
   1.464 +                        TRUE, (length))
   1.465 +
   1.466 +#define getInitialOpeningsMemory(pBiDi, length) \
   1.467 +        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->openingsMemory, &(pBiDi)->openingsSize, \
   1.468 +                        TRUE, (length)*sizeof(Opening))
   1.469 +
   1.470 +#define getInitialParasMemory(pBiDi, length) \
   1.471 +        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->parasMemory, &(pBiDi)->parasSize, \
   1.472 +                        TRUE, (length)*sizeof(Para))
   1.473 +
   1.474 +#define getInitialRunsMemory(pBiDi, length) \
   1.475 +        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->runsMemory, &(pBiDi)->runsSize, \
   1.476 +                        TRUE, (length)*sizeof(Run))
   1.477 +
   1.478 +#define getInitialIsolatesMemory(pBiDi, length) \
   1.479 +        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->isolatesMemory, &(pBiDi)->isolatesSize, \
   1.480 +                        TRUE, (length)*sizeof(Isolate))
   1.481 +
   1.482 +#endif
   1.483 +
   1.484 +#endif

mercurial