STATIC WB_enum
S_backup_one_WB(pTHX_ WB_enum * previous, const U8 * const strbeg, U8 ** curpos, const bool utf8_target)
{
    WB_enum wb;

    PERL_ARGS_ASSERT_BACKUP_ONE_WB;

    /* If we know what the previous character's break value is, don't have
        * to look it up */
    if (*previous != WB_UNKNOWN) {
        wb = *previous;
        *previous = WB_UNKNOWN;
        /* XXX Note that doesn't change curpos, and maybe should */

        /* But we always back up over these two types */
        if (wb != WB_Extend && wb != WB_Format) {
            return wb;
        }
    }

    if (*curpos < strbeg) {
        return WB_EDGE;
    }

    if (utf8_target) {
        U8 * prev_char_pos = reghopmaybe3(*curpos, -1, strbeg);
        if (! prev_char_pos) {
            return WB_EDGE;
        }

        /* Back up over Extend and Format.  curpos is always just to the right
         * of the characater whose value we are getting */
        do {
            U8 * prev_prev_char_pos;
            if ((prev_prev_char_pos = reghopmaybe3((U8 *) prev_char_pos,
                                                   -1,
                                                   strbeg)))
            {
                wb = getWB_VAL_UTF8(prev_prev_char_pos, prev_char_pos);
                *curpos = prev_char_pos;
                prev_char_pos = prev_prev_char_pos;
            }
            else {
                *curpos = (U8 *) strbeg;
                return WB_EDGE;
            }
        } while (wb == WB_Extend || wb == WB_Format);
    }
    else {
        do {
            if (*curpos - 2 < strbeg) {
                *curpos = (U8 *) strbeg;
                return WB_EDGE;
            }
            (*curpos)--;
            wb = getWB_VAL_CP(*(*curpos - 1));
        } while (wb == WB_Extend || wb == WB_Format);
    }

    return wb;
STATIC WB_enum
S_backup_one_WB(pTHX_ WB_enum * previous, const U8 * const strbeg, U8 ** curpos, const bool utf8_target)
{
    WB_enum wb;

    PERL_ARGS_ASSERT_BACKUP_ONE_WB;

     
    if (*previous != WB_UNKNOWN) {
        wb = *previous;
        *previous = WB_UNKNOWN;
         

         
        if (wb != WB_Extend && wb != WB_Format) {
            return wb;
        }
    }

    if (*curpos < strbeg) {
        return WB_EDGE;
    }

    if (utf8_target) {
        U8 * prev_char_pos = reghopmaybe3(*curpos, -1, strbeg);
        if (! prev_char_pos) {
            return WB_EDGE;
        }

         
        do {
            U8 * prev_prev_char_pos;
            if ((prev_prev_char_pos = reghopmaybe3((U8 *) prev_char_pos,
                                                   -1,
                                                   strbeg)))
            {
                wb = getWB_VAL_UTF8(prev_prev_char_pos, prev_char_pos);
                *curpos = prev_char_pos;
                prev_char_pos = prev_prev_char_pos;
            }
            else {
                *curpos = (U8 *) strbeg;
                return WB_EDGE;
            }
        } while (wb == WB_Extend || wb == WB_Format);
    }
    else {
        do {
            if (*curpos - 2 < strbeg) {
                *curpos = (U8 *) strbeg;
                return WB_EDGE;
            }
            (*curpos)--;
            wb = getWB_VAL_CP(*(*curpos - 1));
        } while (wb == WB_Extend || wb == WB_Format);
    }

    return wb;