Exemplo n.º 1
0
int Hilit_SIMPLE(EBuffer *BF,
                 int      LN,
                 PCell    B,
                 int      Pos,
                 int      Width,
                 ELine   *Line,
                 hlState& State,
                 hsState *StateMap,
                 int     *ECol) {
  EColorize *col = BF->Mode->fColorize;
  HMachine  *hm  = col->hm;

  HILIT_VARS(col->Colors, Line);
  HState *st = 0;
  HTrans *tr = 0;
  int     t, cc;
  int     quotech = 0;
  int     matchFlags;
  int     matchLen;
  int     nextState;
  char   *match;
  int     lastPos = -1;
  hlState entryState;
  int     iterCount;
  bool    reportError = true;

  if ((hm == 0) || (hm->stateCount == 0)) return 0;

  if (State >= hm->stateCount) State = 0;
  st    = hm->state + State;
  Color = st->color;

  /*{
      fprintf(stderr, "ColMode:%s, State:%d\n", col->Name, State);
      for (int s = 0; s < hm->stateCount; s++) {
          fprintf(stderr,
                  "State:%d, transCount:%d, firstTrans:%d, options:%d, color:%d,
                     nextState:%d\n",
                  s,
                  hm->state[s].transCount,
                  hm->state[s].firstTrans,
                  hm->state[s].options,
                  hm->state[s].color,
                  hm->state[s].nextState);
      }
      for (int t = 0; t < hm->transCount; t++) {
          fprintf(stderr,
                  "Trans:%d, matchLen:%d, matchFlags:%d, nextState:%d,
                     color:%d\n",
                  t,
                  hm->trans[t].matchLen,
                  hm->trans[t].matchFlags,
                  hm->trans[t].nextState,
                  hm->trans[t].color);
      }
      //exit(1);
      sleep(5);
     }*/

  for (i = 0; i < Line->Count;) {
    // Check for infinite loops
    if (i == lastPos) {
      if (++iterCount > hm->stateCount) {
        // Passed the same position more times than number of states -> must be
        // looping
        if (reportError) {
          // Report only once per line since other errors may be false alarms
          // caused by hiliter restart
          reportError = false;
          BF->Msg(S_INFO,
                  "Hiliter looping at line %d, column %d, entry state %d",
                  LN + 1,
                  i + 1,
                  entryState);
        } else {
          // Already reported - advance by one character
          Color = hm->state[entryState].color;
            IF_TAB()
          else ColorNext();
        }

        // Restart with state 0
        State     = 0;
        st        = hm->state;
        iterCount = 1;
        goto next_state;
      }
    } else {
      lastPos    = i;
      entryState = State;
      iterCount  = 1;
    }

    if (quotech) {
      quotech = 0;
    } else {
      for (t = 0; t < st->transCount; t++) {
        tr         = hm->trans + st->firstTrans + t;
        matchLen   = tr->matchLen;
        matchFlags = tr->matchFlags;
        match      = tr->match;
        nextState  = tr->nextState;

        // fprintf(stderr,
        //        "line:%d, char:%d (%c), len:%d, state:%d, tr:%d,
        // st->transCount:%d, st->firstTrans:%d, nextState:%d,
        // matchFlags:%08x\n",
        //        LN, i, *p, len, State, t, st->transCount, st->firstTrans,
        // nextState, matchFlags);

        if (len < matchLen) continue;

        if ((i > 0) && (matchFlags & MATCH_MUST_BOL)) continue;

        if ((matchFlags & (MATCH_SET | MATCH_NOTSET)) == 0) {
          if (matchFlags & MATCH_REGEXP) {
            RxMatchRes b;

            if (!RxExecMatch(tr->regexp, Line->Chars, Line->Count, p, &b,
                             (matchFlags &
                              MATCH_NO_CASE) ? 0 : RX_CASE)) continue;

            if ((b.Open[1] != -1) && (b.Close[1] != -1)) matchLen = b.Open[1] - i;
            else matchLen = b.Close[0] - i;
          } else if (matchFlags & MATCH_NO_CASE) {
            if (memicmp(match, p, matchLen)) continue;
          } else {
            for (cc = 0; cc < matchLen; cc++)
              if (p[cc] != match[cc]) goto next_trans;
          }
        } else if (matchFlags & MATCH_SET) {
          if (!WGETBIT(match, *p)) continue;
        } else if (matchFlags & MATCH_NOTSET) {
          if (WGETBIT(match, *p)) continue;
        }

        if ((len != matchLen) && (matchFlags & MATCH_MUST_EOL)) continue;

        if (matchFlags & MATCH_NOGRAB) {
          State = nextState;

          if (State >= hm->stateCount) State = 0;
          st = hm->state + State;

          // fprintf(stderr, "nograb\n");
        } else {
          if (matchFlags & MATCH_TAGASNEXT) {
            State = nextState;

            if (State >= hm->stateCount) State = 0;
            st = hm->state + State;
          }
          Color = tr->color;

          for (cc = 0; cc < matchLen; cc++)
            IF_TAB()
            else ColorNext();

          if (!(matchFlags & MATCH_TAGASNEXT)) {
            State = nextState;

            if (State >= hm->stateCount) State = 0;
            st = hm->state + State;
          }

          if (len > 0) {
            if (matchFlags & MATCH_QUOTECH) quotech = 1;
          } else if (len == 0) {
            if (matchFlags & MATCH_QUOTEEOL) goto end_parse;  /* see note below
                                                                !! */
          }
        }

        // fprintf(stderr, "next state\n");
        goto next_state;
next_trans: /* */
        ;
      }

      if (st->wordChars != 0) {
        int j;
        hlState MState = State;

        j = 0;

        while (((i + j) < Line->Count) &&
               (WGETBIT(st->wordChars, Line->Chars[i + j]))) j++;

        // GP (fix)
        Color = st->color;

        if (j == 0) {
          if (st->nextKwdNoCharState != -1) {
            State = st->nextKwdNoCharState;

            if (State >= hm->stateCount) State = 0;
            st    = hm->state + State;
            Color = st->color;
            goto next_state;
          }
        } else {
          if (st->GetHilitWord(j, &Line->Chars[i], Color) ||
              BF->GetHilitWord(j, &Line->Chars[i], Color,
                               BFI(BF, BFI_MatchCase) ? 0 : 1)) {
            if (st->nextKwdMatchedState != -1) State = st->nextKwdMatchedState;
          } else {
            if (st->nextKwdNotMatchedState != -1) {
              State = st->nextKwdNotMatchedState;

              if (st->options & STATE_NOGRAB) {
                if (State >= hm->stateCount) State = 0;
                st    = hm->state + State;
                Color = st->color;
                goto next_state;
              }
            }
          }

          if (State >= hm->stateCount) State = 0;

          // highlight/tag as next state
          if (st->options & STATE_TAGASNEXT) {
            MState = State;
            st     = hm->state + State;
            Color  = st->color;
          }

          if (StateMap) memset(StateMap + i, MState, j);

          if (B) MoveMem(B, C - Pos, Width, Line->Chars + i, HILIT_CLRD(), j);
          i   += j;
          len -= j;
          p   += j;
          C   += j;

          if (!(st->options & STATE_TAGASNEXT)) {
            st    = hm->state + State;
            Color = st->color;
          }
          goto next_state;
        }
      }
    }
    Color = st->color;
    IF_TAB()
    else ColorNext();
next_state: /* */
    ;
  }
Exemplo n.º 2
0
static int ReadColorize(CurPos &cp, EColorize *Colorize, const char *ModeName) {
    unsigned char obj;
    unsigned short len;

    long LastState = -1;

    while ((obj = GetObj(cp, len)) != 0xFF) {
        switch (obj) {
        case CF_COLOR:
            if (ReadHilitColors(cp, Colorize, ModeName) == -1) return -1;
            break;

        case CF_KEYWORD:
            {
                const char *colorstr;

                if ((colorstr = GetCharStr(cp, len)) == 0) return -1;

                unsigned int Col;
                unsigned int ColBg, ColFg;

                if (sscanf(colorstr, "%1X %1X", &ColFg, &ColBg) != 2)
                    return 0;

                Col = ColFg | (ColBg << 4);

                int color = ChColor(Col);
                if (ReadKeywords(cp, &Colorize->Keywords, color) == -1) return -1;
            }
            break;

        case CF_HSTATE:
            {
                long stateno;
                long color;

                if (Colorize->hm == 0)
                    Colorize->hm = new HMachine();

                assert(Colorize->hm != 0);

                if (GetNum(cp, stateno) == 0)
                    return -1;

                assert(stateno == LastState + 1);

                obj = GetObj(cp, len);
                assert(obj == CF_INT);

                if (GetNum(cp, color) == 0)
                    return -1;

                HState newState;

                newState.InitState();

                newState.color = color;

                Colorize->hm->AddState(newState);
                LastState = stateno;
            }
            break;

        case CF_HTRANS:
            {
                HTrans newTrans;
                long nextState;
                long matchFlags;
                const char *match;
                long color;

                if (GetNum(cp, nextState) == 0)
                    return -1;
                obj = GetObj(cp, len);
                assert(obj == CF_INT);
                if (GetNum(cp, matchFlags) == 0)
                    return -1;
                obj = GetObj(cp, len);
                assert(obj == CF_INT);
                if (GetNum(cp, color) == 0)
                    return -1;
                obj = GetObj(cp, len);
                assert(matchFlags & MATCH_REGEXP ? obj == CF_REGEXP : obj == CF_STRING);
                if ((match = GetCharStr(cp, len)) == 0)
                    return -1;

                newTrans.InitTrans();

                newTrans.matchFlags = matchFlags;
                newTrans.nextState = nextState;
                newTrans.color = color;

                if (newTrans.matchFlags & MATCH_REGEXP) {
                    newTrans.regexp = RxCompile(match);
                    newTrans.matchLen = 0;
                } else if ((newTrans.matchFlags & MATCH_SET) ||
                           (newTrans.matchFlags & MATCH_NOTSET))
                {
                    newTrans.matchLen = 1;
                    newTrans.match = (char *)malloc(256/8);
                    assert(newTrans.match != NULL);
                    SetWordChars(newTrans.match, match);
                } else {
                    newTrans.match = strdup(match);
                    newTrans.matchLen = strlen(match);
                }

                Colorize->hm->AddTrans(newTrans);
            }
            break;

        case CF_HWTYPE:
            {
                long nextKwdMatchedState;
                long nextKwdNotMatchedState;
                long nextKwdNoCharState;
                long options;
                const char *wordChars;

                obj = GetObj(cp, len);
                assert(obj == CF_INT);
                if (GetNum(cp, nextKwdMatchedState) == 0)
                    return -1;

                obj = GetObj(cp, len);
                assert(obj == CF_INT);
                if (GetNum(cp, nextKwdNotMatchedState) == 0)
                    return -1;

                obj = GetObj(cp, len);
                assert(obj == CF_INT);
                if (GetNum(cp, nextKwdNoCharState) == 0)
                    return -1;

                obj = GetObj(cp, len);
                assert(obj == CF_INT);
                if (GetNum(cp, options) == 0)
                    return -1;

                obj = GetObj(cp, len);
                assert(obj == CF_STRING);
                if ((wordChars = GetCharStr(cp, len)) == 0)
                    return -1;

                Colorize->hm->LastState()->options = options;
                Colorize->hm->LastState()->nextKwdMatchedState = nextKwdMatchedState;
                Colorize->hm->LastState()->nextKwdNotMatchedState = nextKwdNotMatchedState;
                Colorize->hm->LastState()->nextKwdNoCharState = nextKwdNoCharState;

                if (wordChars && *wordChars) {
                    Colorize->hm->LastState()->wordChars = (char *)malloc(256/8);
                    assert(Colorize->hm->LastState()->wordChars != NULL);
                    SetWordChars(Colorize->hm->LastState()->wordChars, wordChars);
                }
            }
            break;

        case CF_HWORDS:
            {
                const char *colorstr;
                int color;

                if ((colorstr = GetCharStr(cp, len)) == 0) return -1;

                color = hcPlain_Keyword;

                if (strcmp(colorstr, "-") != 0) {
                    const char *Value = colorstr;
                    int Col;

                    if (*Value == '-') {
                        Value++;
                        if (sscanf(Value, "%1X", &Col) != 1) return -1;
                        Col |= (hcPlain_Background & 0xF0);
                    } else if (Value[1] == '-') {
                        if (sscanf(Value, "%1X", &Col) != 1) return -1;
                        Col <<= 4;
                        Col |= (hcPlain_Background & 0x0F);
                    } else {
                        unsigned int ColBg, ColFg;

                        if (sscanf(colorstr, "%1X %1X", &ColFg, &ColBg) != 2)
                            return 0;

                        Col = ColFg | (ColBg << 4);
                    }
                    color = Col;
                }
                if (ReadKeywords(cp, &Colorize->hm->LastState()->keywords, color) == -1) return -1;
            }
            break;

        case CF_SETVAR:
            {
                long what;

                if (GetNum(cp, what) == 0) return -1;
                switch (GetObj(cp, len)) {
                case CF_STRING:
                    {
                        const char *val = GetCharStr(cp, len);
                        if (len == 0) return -1;
                        if (SetColorizeString(Colorize, what, val) != 0) return -1;
                    }
                    break;
                    /*                case CF_INT:
                     {
                     long num;

                     if (GetNum(cp, num) == 0) return -1;
                     if (SetModeNumber(Mode, what, num) != 0) return -1;
                     }
                     break;*/
                default:
                    return -1;
                }
            }
            break;
        case CF_END:
            return 0;
        default:
            return -1;
        }
    }
    return -1;
}
Exemplo n.º 3
0
int Hilit_SIMPLE(EBuffer *BF, int /*LN*/, PCell B, int Pos, int Width, ELine *Line, hlState &State, hsState *StateMap, int *ECol) {
    EColorize *col = BF->Mode->fColorize;
    HMachine *hm = col->hm;
    HILIT_VARS(col->Colors, Line);
    HState *st = 0;
    HTrans *tr = 0;
    int t, cc;
    int quotech = 0;
    int matchFlags;
    int matchLen;
    int nextState;
    char *match;

    if (hm == 0 || hm->stateCount == 0)
        return 0;

    if (State >= hm->stateCount)
        State = 0;
    st = hm->state + State;
    Color = st->color;

    /*{
        fprintf(stderr, "ColMode:%s, State:%d\n", col->Name, State);
        for (int s = 0; s < hm->stateCount; s++) {
            fprintf(stderr,
                    "State:%d, transCount:%d, firstTrans:%d, options:%d, color:%d, nextState:%d\n",
                    s,
                    hm->state[s].transCount,
                    hm->state[s].firstTrans,
                    hm->state[s].options,
                    hm->state[s].color,
                    hm->state[s].nextState);
        }
        for (int t = 0; t < hm->transCount; t++) {
            fprintf(stderr,
                    "Trans:%d, matchLen:%d, matchFlags:%d, nextState:%d, color:%d\n",
                    t,
                    hm->trans[t].matchLen,
                    hm->trans[t].matchFlags,
                    hm->trans[t].nextState,
                    hm->trans[t].color);
        }
        //exit(1);
        sleep(5);
    }*/

    for (i = 0; i < Line->Count; ) {
        if (quotech) {
            quotech = 0;
        } else {
            for (t = 0; t < st->transCount; t++) {
                tr = hm->trans + st->firstTrans + t;
                matchLen = tr->matchLen;
                matchFlags = tr->matchFlags;
                match = tr->match;
                nextState = tr->nextState;

                //fprintf(stderr,
                //        "line:%d, char:%d (%c), len:%d, state:%d, tr:%d, st->transCount:%d, st->firstTrans:%d, nextState:%d, matchFlags:%08x\n",
                //        LN, i, *p, len, State, t, st->transCount, st->firstTrans, nextState, matchFlags);

                if (len < matchLen)
                    continue;

                if ((i > 0) && (matchFlags & MATCH_MUST_BOL))
                    continue;

                if ((matchFlags & (MATCH_SET | MATCH_NOTSET)) == 0) {
                    if (matchFlags & MATCH_REGEXP) {
                        RxMatchRes b;
                        if (!RxExecMatch(tr->regexp, Line->Chars, Line->Count, p, &b, (matchFlags & MATCH_NO_CASE) ? 0 : RX_CASE)) continue;
                        if (b.Open[1] != -1 && b.Close[1] != -1) matchLen = b.Open[1] - i;
                        else matchLen = b.Close[0] - i;
                    } else if (matchFlags & MATCH_NO_CASE) {
                        if (memicmp(match, p, matchLen))
                            continue;
                    } else {
                        for (cc = 0; cc < matchLen; cc++)
                            if (p[cc] != match[cc])
                                goto next_trans;
                    }
                } else if (matchFlags & MATCH_SET) {
                    if (!WGETBIT(match, *p))
                        continue;
                } else if (matchFlags & MATCH_NOTSET) {
                    if (WGETBIT(match, *p))
                        continue;
                }

                if ((len != matchLen) && (matchFlags & MATCH_MUST_EOL))
                    continue;

                if (matchFlags & MATCH_NOGRAB) {
                    State = nextState;
                    if (State >= hm->stateCount)
                        State = 0;
                    st = hm->state + State;
                    //fprintf(stderr, "nograb\n");
                } else {
                    if (matchFlags & MATCH_TAGASNEXT) {
                        State = nextState;
                        if (State >= hm->stateCount)
                            State = 0;
                        st = hm->state + State;
                    }
                    Color = tr->color;
                    for (cc = 0; cc < matchLen; cc++)
                        IF_TAB()
                        else
                            ColorNext();
                    if (!(matchFlags & MATCH_TAGASNEXT)) {
                        State = nextState;
                        if (State >= hm->stateCount)
                            State = 0;
                        st = hm->state + State;
                    }
                    if (len > 0) {
                        if (matchFlags & MATCH_QUOTECH)
                            quotech = 1;
                    } else if (len == 0) {
                        if (matchFlags & MATCH_QUOTEEOL)
                            goto end_parse; /* see note below !! */
                    }
                }
                //fprintf(stderr, "next state\n");
                goto next_state;
            next_trans: /* */;
            }
            if (st->wordChars != 0) {
                int j;
                hlState MState = State;

                j = 0;
                while (((i + j) < Line->Count) &&
                       (WGETBIT(st->wordChars, Line->Chars[i + j]))) j++;

                //GP (fix)
                Color = st->color;

                if (j == 0) {
                    if (st->nextKwdNoCharState != -1) {
                        State = st->nextKwdNoCharState;
                        if (State >= hm->stateCount)
                            State = 0;
                        st = hm->state + State;
                        Color = st->color;
                        goto next_state;
                    }
                } else {
                    if (st->GetHilitWord(j, &Line->Chars[i], Color ) ||
                        BF->GetHilitWord(j, &Line->Chars[i], Color,  BFI( BF, BFI_MatchCase ) ? 0 : 1))
                    {
                        if (st->nextKwdMatchedState != -1)
                            State = st->nextKwdMatchedState;
                    } else {
                        if (st->nextKwdNotMatchedState != -1) {
                            State = st->nextKwdNotMatchedState;
                            if (st->options & STATE_NOGRAB) {
                                if (State >= hm->stateCount)
                                    State = 0;
                                st = hm->state + State;
                                Color = st->color;
                                goto next_state;
                            }
                        }
                    }
                    
                    if (State >= hm->stateCount)
                        State = 0;
                    
                    // highlight/tag as next state
                    if (st->options & STATE_TAGASNEXT) {
                        MState = State;
                        st = hm->state + State;
                        Color = st->color;
                    }
                    
                    if (StateMap)
                        memset(StateMap + i, MState, j);
                    if (B)
                        MoveMem(B, C - Pos, Width, Line->Chars + i, HILIT_CLRD(), j);
                    i += j;
                    len -= j;
                    p += j;
                    C += j;

                    if (!(st->options & STATE_TAGASNEXT)) {
                        st = hm->state + State;
                        Color = st->color;
                    }
                    goto next_state;
                }
            }
        }
        Color = st->color;
        IF_TAB()
        else
            ColorNext();
    next_state: /* */;
    }

    /* check if there are any matches for EOL */
    /* NOTE: this is skipped when Q option is used above. !! */
    for (t = 0; t < st->transCount; t++) {
        tr = hm->trans + st->firstTrans + t;
        matchLen = tr->matchLen;
        matchFlags = tr->matchFlags;
        match = tr->match;
        nextState = tr->nextState;
        
        if (((i > 0) && (matchFlags & MATCH_MUST_BOL)) || (matchFlags & MATCH_REGEXP))
            continue;

        //cant match eol beyond eol.
        //if ((len != matchLen) && (matchFlags & MATCH_MUST_EOL))
        //continue;

        if (matchLen == 0) {
            State = nextState;
            if (State >= hm->stateCount)
                State = 0;
            break;
        }
    }
end_parse: ;
    *ECol = C;
    return 0;
}