#help_index "DolDoc/Misc"

CColorROPU32 highlight_hash_type_colors[HTt_TYPES_NUM] =
                                DOC_COLOR_EXPORT_SYS_SYM, 0, DOC_COLOR_DEFINE_STR, DOC_COLOR_GLOBAL_VAR, 
                                DOC_COLOR_CLASS, DOC_COLOR_KEYWORD, DOC_COLOR_FUN, 0, 0, DOC_COLOR_KEYWORD, 
                                DOC_COLOR_KEYWORD, DOC_COLOR_KEYWORD, DOC_COLOR_REG, 0, 0, 0, 0};

U32 *DocHighlight(CDocEntry *doc_e, U8 *src, I64 len, I64 _tmp_u32_attr)
{//Be aware of ::/Demo/ToHtmlToTXTDemo/ToHtml.CC.
        U32                             *res = MAlloc((len + 1) * sizeof(U32)), *dst = res;
        U8                              *ptr;
        CDocSettings    *s = &doc_e->settings;
        I64                              count, ch, ch1, ch2, last_ch, tmp_u32_attr, mask_tmp_u32_attr = _tmp_u32_attr & 0xFFFFF000, 
                                         comment_depth, brace_depth = s->brace_depth, paren_depth = s->paren_depth;
        CHash                   *tmph;

        switch [s->state]
        {
                case DOCSS_NORMAL:
hl_normal:
                        while (len)
                        {
                                while (len && !Bt(char_bmp_alpha_numeric, *src))
                                {
                                        tmp_u32_attr = _tmp_u32_attr;
                                        ch1 = *src++;
                                        switch (ch1)
                                        {
                                                case '/':
                                                        if (len >= 2)
                                                        {
                                                                if (*src == '/')
                                                                {
                                                                        tmp_u32_attr = DOC_COLOR_COMMENT << 8 | mask_tmp_u32_attr;
                                                                        *dst++ = ch1 + tmp_u32_attr;
                                                                        *dst++ = *src++ + tmp_u32_attr;
                                                                        len -= 2;
                                                                        goto hl_cpp_comment;
                                                                }
                                                                else if (*src == '*')
                                                                {
                                                                        tmp_u32_attr = DOC_COLOR_COMMENT << 8 | mask_tmp_u32_attr;
                                                                        *dst++ = ch1 + tmp_u32_attr;
                                                                        *dst++ = *src++ + tmp_u32_attr;
                                                                        len -= 2;
                                                                        comment_depth = 1;
                                                                        goto hl_comment;
                                                                }
                                                        }
                                                        break;

                                                case '\'':
                                                        tmp_u32_attr = DOC_COLOR_CHAR_CONST << 8 | mask_tmp_u32_attr;
                                                        *dst++ = ch1 + tmp_u32_attr;
                                                        len--;
                                                        goto hl_single_quote;

                                                case '\"':
                                                        tmp_u32_attr = DOC_COLOR_STR << 8 | mask_tmp_u32_attr;
                                                        *dst++ = ch1 + tmp_u32_attr;
                                                        len--;
                                                        goto hl_dbl_quote;

                                                case '(':
                                                        if (paren_depth++ & 1)
                                                                tmp_u32_attr = DOC_COLOR_ALT_TEXT << 8 | mask_tmp_u32_attr;
                                                        break;

                                                case ')':
                                                        if (--paren_depth & 1)
                                                                tmp_u32_attr = DOC_COLOR_ALT_TEXT << 8 | mask_tmp_u32_attr;
                                                        break;

                                                case '{':
                                                        if (brace_depth++ & 1)
                                                                tmp_u32_attr = DOC_COLOR_ALT_TEXT << 8 | mask_tmp_u32_attr;
                                                        break;

                                                case '}':
                                                        if (--brace_depth & 1)
                                                                tmp_u32_attr = DOC_COLOR_ALT_TEXT << 8 | mask_tmp_u32_attr;
                                                        break;
                                        }
                                        *dst++ = ch1 + tmp_u32_attr;
                                        if (!--len)
                                                goto hl_normal_done;
                                }

                                ptr = src;
                                if (*ptr++ == '0')
                                {
                                        ch2 = *ptr--;
                                        if (ch2 == 'x' || ch2 == 'b')
                                        {
                                                count = 0;
                                                while (len && (Bt(char_bmp_hex_numeric, *src) || *src == ch2 && count < 2))
                                                {
                                                        count++;
                                                        src++;
                                                        len--;
                                                }
                                                ch = *src;
                                                *src = '\0';
                                                tmp_u32_attr = DOC_COLOR_NUMBER << 8 | mask_tmp_u32_attr;
                                                while (ch1 = *ptr++)
                                                        *dst++ = ch1 + tmp_u32_attr;
                                                *src = ch;
                                                if (!len)
                                                        goto hl_normal_done;
                                        }
                                }

                                ptr = src;
                                while (len && Bt(char_bmp_dec_numeric, *src))
                                {
                                        src++;
                                        len--;
                                }
                                ch = *src;
                                *src = '\0';
                                tmp_u32_attr = DOC_COLOR_NUMBER << 8 | mask_tmp_u32_attr;
                                while (ch1 = *ptr++)
                                        *dst++ = ch1 + tmp_u32_attr;
                                *src = ch;
                                if (!len)
                                        goto hl_normal_done;

                                ptr = src;
                                while (len && Bt(char_bmp_alpha_numeric, *src))
                                {
                                        src++;
                                        len--;
                                }
                                ch = *src;
                                *src = 0;
                                if (tmph=HashFind(ptr, sys_task->hash_table,
                                                        HTT_EXPORT_SYS_SYM | HTT_DEFINE_STR | HTT_GLOBAL_VAR|HTT_CLASS |
                                                        HTT_INTERNAL_TYPE | HTT_FUN | HTT_KEYWORD | HTT_ASM_KEYWORD |
                                                        HTT_OPCODE | HTT_REG))
                                        tmp_u32_attr = highlight_hash_type_colors[HashTypeNum(tmph)] << 8 | mask_tmp_u32_attr;
                                else
                                        tmp_u32_attr = _tmp_u32_attr;
                                while (ch1 = *ptr++)
                                        *dst++ = ch1 + tmp_u32_attr;
                                *src = ch;
                        }
hl_normal_done:
                        s->state                 = DOCSS_NORMAL;
                        s->comment_depth = 0;
                        break;

                case DOCSS_SINGLE_QUOTE:
                        tmp_u32_attr = DOC_COLOR_CHAR_CONST << 8 | mask_tmp_u32_attr;
hl_single_quote:
                        last_ch = 0;
                        while (len--)
                        {
                                ch1 = *src++;
                                *dst++ = ch1 + tmp_u32_attr;
                                if (last_ch != '\\' && ch1 == '\'')
                                        goto hl_normal;
                                if (last_ch == '\\' && ch1 == '\\')
                                        last_ch = 0;
                                else
                                        last_ch = ch1;
                        }
                        s->state                 = DOCSS_SINGLE_QUOTE;
                        s->comment_depth = 0;
                        break;

                case DOCSS_DBL_QUOTE:
                        tmp_u32_attr = DOC_COLOR_CHAR_CONST << 8 | mask_tmp_u32_attr;
hl_dbl_quote:
                        last_ch = 0;
                        while (len--)
                        {
                                ch1 = *src++;
                                *dst++ = ch1 + tmp_u32_attr;
                                if (last_ch != '\\' && ch1 == '\"')
                                        goto hl_normal;
                                if (last_ch == '\\' && ch1 == '\\')
                                        last_ch = 0;
                                else
                                        last_ch = ch1;
                        }
                        s->state                 = DOCSS_DBL_QUOTE;
                        s->comment_depth = 0;
                        break;

                case DOCSS_COMMENT:
                        tmp_u32_attr = DOC_COLOR_COMMENT << 8 | mask_tmp_u32_attr;
                        comment_depth = s->comment_depth;
hl_comment:
                        last_ch = 0;
                        while (len--)
                        {
                                ch1 = *src++;
                                *dst++ = ch1 + tmp_u32_attr;
                                if (last_ch == '*' && ch1 == '/')
                                {
                                        if (!--comment_depth)
                                                goto hl_normal;
                                }
                                else if (last_ch == '/' && ch1 == '*')
                                        comment_depth++;
                                last_ch = ch1;
                        }
                        s->state                 = DOCSS_COMMENT;
                        s->comment_depth = comment_depth;
                        break;

                case DOCSS_CPP_Z_COMMENT:
                        tmp_u32_attr = DOC_COLOR_COMMENT << 8 | mask_tmp_u32_attr;
hl_cpp_comment:
                        while (len--)
                                *dst++ = *src++ + tmp_u32_attr;
                        s->state                 = DOCSS_CPP_Z_COMMENT;
                        s->comment_depth = 0;
                        break;
        }
        s->paren_depth = paren_depth;
        s->brace_depth = brace_depth;
        *dst = 0;

        return res;
}