int getNextElem(char *str, int *pos, char *token) { int i; token[0] = '\0'; i=0; while (str[*pos]!='\0') { /*bracelet*/ if (str[*pos]=='(') { *pos = *pos+1; strcpy(token,"("); return 1; } else if (str[*pos]==')') { *pos = *pos+1; strcpy(token,")"); return 1; } /*induction register*/ else if (str[*pos]=='$') { token[i++]=str[*pos]; *pos = *pos+1; while (isDecNum(str[*pos])) { token[i++]=str[*pos]; *pos = *pos+1; if (str[*pos]=='\0') break; } token[i]='\0'; return 1; } /*numerical value, 0x1234abcdef*/ else if ( isHexNum(str[*pos]) ) { while( isHexNum(str[*pos]) ) { token[i++]=str[*pos]; *pos = *pos+1; if (str[*pos]=='\0') break; } token[i]='\0'; return 1; } else if (str[*pos]=='T') {//unknown var token[i++]=str[*pos]; token[i]='\0'; *pos = *pos+1; return 1; } /*oprator, hopefully*/ else if (str[*pos]!=' ') { while (str[*pos]!='$' && !isHexNum(str[*pos]) && str[*pos]!='T' && str[*pos]!='(' && str[*pos]!=')' && str[*pos]!=' ') { token[i++]=str[*pos]; *pos = *pos+1; if (str[*pos]=='\0') break; } token[i]='\0'; return 1; } //blank space else *pos = *pos + 1; } return 0; }
int checkColor(const char * arg) { string check = arg; //can take format 0xNUMBER or NUMBER if (arg[0] == '0' && arg[1] == 'x') { check = check.substr(2); } if (! isHexNum(check) ) { cout << "color must be a postive hexadecimal number: [" << arg << "]" << endl; exit(1); } int color = (int) strtol(arg,NULL,16); if (color < 0 || color > 0xFFFFFF) { cout << "color must be a postitive integer between 0x0 and 0xFFFFFF: [" << arg << "]" << endl; exit(1); } return color; }
_EXPORT void ColorLine(CLanguageProxy& proxy, int& state) { const char *text = proxy.Text(); int size = proxy.Size(); int i = 0, s = 0, kws = 0, cc_cnt = 0, esc = 0; char c; bool leave = false; // floating point flag, true when the NUMERIC: label finds a . inside a number, and checks to make sure that a number with two '.' is invalid. (and not highlighted as numeric) bool floating_point = false; // same flag, only for hex numbers. allows proper highlighting only for 1 x per number. (0x21 is ok. 0x023x31 is not. will look wierd.) bool hex_num = false; int ifZeroCounter = state >> STATE_SHIFT; state = state & STATE_MASK; if (state == COMMENT || state == LCOMMENT) proxy.SetColor(0, kColorComment1); else proxy.SetColor(0, kColorText); if (size <= 0) return; while (!leave) { GETCHAR; switch (state) { case START: s = i - 1; proxy.SetColor(s, kColorText); if (c == '#') { kws = proxy.Move(c, 1); state = PRAGMA1; } else if (isalpha(c) || c == '_') { kws = proxy.Move(c, 1); state = IDENT; } else if (c == '/' && text[i] == '*') { i++; state = COMMENT; } else if (c == '/' && text[i] == '/') { i++; state = LCOMMENT; } else if (c == '"') state = STRING; else if (c == '\'') { state = CHAR_CONST; cc_cnt = 0; } // m7m: here are the 3 magic IFs. else if (isNumeric(c)) { state = NUMERIC; } else if (isOperator(c)) { state = OPERATOR; } else if (isSymbol(c)) { state = SYMBOL; } else if (c == '\n' || c == 0) leave = true; break; case COMMENT: if ((s == 0 || i > s + 1) && c == '*' && text[i] == '/') { proxy.SetColor(s, kColorComment1); i++; state = START; } else if (c == 0 || c == '\n') { proxy.SetColor(s, kColorComment1); leave = true; } break; case LCOMMENT: proxy.SetColor(s, kColorComment1); leave = true; if (text[size - 1] == '\n') state = START; break; case IDENT: if (!isalnum(c) && c != '_') { int kwc; if (i > s + 1 && (kwc = proxy.IsKeyword(kws)) != 0) { switch (kwc) { case 1: proxy.SetColor(s, kColorKeyword1); break; case 2: proxy.SetColor(s, kColorUserSet1); break; case 3: proxy.SetColor(s, kColorUserSet2); break; case 4: proxy.SetColor(s, kColorUserSet3); break; case 5: proxy.SetColor(s, kColorUserSet4); break; // default: ASSERT(false); } } else proxy.SetColor(s, kColorText); i--; state = START; } else if (kws) kws = proxy.Move((int)(unsigned char)c, kws); break; case PRAGMA1: if (c == ' ' || c == '\t') ; else if (islower(c)) { kws = proxy.Move((int)(unsigned char)c, kws); state = PRAGMA2; } else { proxy.SetColor(s, kColorText); i--; state = START; } break; case PRAGMA2: if (!islower(c)) { int kwc; if (i > s + 2 && (kwc = proxy.IsKeyword(kws)) != 0) { switch (kwc) { case 1: proxy.SetColor(s, kColorKeyword1); break; case 2: proxy.SetColor(s, kColorUserSet1); break; case 3: proxy.SetColor(s, kColorUserSet2); break; case 4: proxy.SetColor(s, kColorUserSet3); break; case 5: proxy.SetColor(s, kColorUserSet4); break; // default: ASSERT(false); } // check for "#if 0" or "elif 0" bool ifZero = false; int k = s + 1; while (text[k] == ' ' || text[k] == '\t') k++; int len = i - 1 - k; if (strings_equal(text + k, "if", len, 2) || strings_equal(text + k, "elif", len, 4)) { k = i - 1; while (text[k] == ' ' || text[k] == '\t') k++; if (text[k] == '0' && (k + 1 == size || text[k + 1] == 0 || isspace(text[k + 1]))) { proxy.SetColor(s, kColorComment1); state = IF_ZERO; ifZeroCounter = 1; leave = true; } } } else { proxy.SetColor(s, kColorText); } if (state != IF_ZERO) { state = strncmp(text+i-8, "include", 7) ? START : INCL1; s = --i; } } else if (kws) kws = proxy.Move((int)(unsigned char)c, kws); break; case INCL1: if (c == '"') state = INCL2; else if (c == '<') state = INCL3; else if (c != ' ' && c != '\t') { state = START; i--; } break; case INCL2: if (c == '"') { proxy.SetColor(s, kColorString1); state = START; } else if (c == '\n' || c == 0) { proxy.SetColor(s, kColorText); leave = true; state = START; } break; case INCL3: if (c == '>') { proxy.SetColor(s, kColorString1); state = START; } else if (c == '\n' || c == 0) { proxy.SetColor(s, kColorText); leave = true; state = START; } break; case STRING: if (c == '"' && !esc) { proxy.SetColor(s, kColorString1); state = START; } else if (c == '\n' || c == 0) { if (text[i - 2] == '\\' && text[i - 3] != '\\') { proxy.SetColor(s, kColorString1); } else { proxy.SetColor(s, kColorText); state = START; } leave = true; } else esc = !esc && (c == '\\'); break; case CHAR_CONST: if (c == '\t' || c == '\n' || c == 0 || (c == '\'' && !esc && (cc_cnt == 0 || cc_cnt > 5))) { // invalid char constant - either invalid char or too short/long proxy.SetColor(s, kColorText); state = START; } else if (c == '\'' && !esc) { proxy.SetColor(s, kColorCharConst); state = START; } else { if (!esc) cc_cnt++; esc = !esc && (c == '\\'); } break; case NUMERIC: { proxy.SetColor(s, kColorNumber1); if (isNumeric(text[i-1]) || (hex_num && isHexNum(text[i - 1]))) ; else if (text[i-1]=='.' && floating_point==false && hex_num==false) floating_point = true; else if (text[i-1]=='x' && hex_num==false && floating_point==false) hex_num = true; else { i--; hex_num = false; state = START; } } break; case OPERATOR: { proxy.SetColor(s, kColorOperator1); if (isOperator(text[i-1])) ; else { i--; state = START; } } break; case SYMBOL: { proxy.SetColor(s, kColorSeparator1); if (isSymbol(text[i-1])) ; else { i--; state = START; } } break; case IF_ZERO: { if (isspace(c)) break; proxy.SetColor(i - 1, kColorComment1); if (c == '#') { // get the preprocessor keyword while (isspace(GETCHAR)); int s = i - 1; int end = s; while (end < size && text[end] != 0 && !isspace(text[end])) end++; int len = end - s; // on "#if", "#ifdef", "#ifndef" increment the nesting // counter if (strings_equal(text + s, "if", len, 2) || strings_equal(text + s, "ifdef", len, 5) || strings_equal(text + s, "ifndef", len, 6)) { ifZeroCounter++; i = end + 1; } // on "endif" decrement the nesting counter else if (strings_equal(text + s, "endif", len, 5)) { ifZeroCounter--; i = end + 1; // if the counter drops to zero, we fall be to normal // parsing if (ifZeroCounter == 0) { state = START; leave = true; break; } } // on "else" or "elif" and nest count 1, fall back to normal // parsing: else if (ifZeroCounter == 1 && (strings_equal(text + s, "else", len, 4) || strings_equal(text + s, "elif", len, 4))) { i = end + 1; ifZeroCounter == 0; state = START; leave = true; break; } } // we need to check for C style comments int commentOffset; if (find_comment_start(text + i - 1, size - i + 1, commentOffset)) { state = IF_ZERO_COMMENT; i += commentOffset + 1; } else leave = true; } break; case IF_ZERO_COMMENT: { proxy.SetColor(i - 1, kColorComment1); int commentEnd; if (find_comment_end(text + i - 1, size - i + 1, commentEnd)) { i += commentEnd + 1; state = IF_ZERO; } else leave = true; } break; default: // error condition, gracefully leave the loop leave = true; break; } } state |= ifZeroCounter << STATE_SHIFT; } /* ColorLine */
_EXPORT void ColorLine(CLanguageProxy& proxy, int32& state) { const char *text = proxy.Text(); int32 size = proxy.Size(); int32 i = 0, s = 0, kws = 0, esc = 0; char c; bool leave = false; bool floating_point = false; bool hex_num = false; // int sqrBraquetStrCount = 0; if (state == LCOMMENT) proxy.SetColor(0, kColorComment1); else proxy.SetColor(0, kColorText); if (size <= 0) return; while (!leave) { GETCHAR; switch (state) { case START: if (isalpha(c) || c == '_') { kws = proxy.Move(tolower(c), 1); state = IDENT; } else if (c == '-' && text[i] == '-') { i++; state = LCOMMENT; } else if (c == '"') state = STRING; else if (c == '\'') state = STRING2; /* else if (c == '[' && text[i] == '[') { sqrBraquetStrCount++; state = STRING3; } */ else if (isNumeric(c) || (c == '$' && isHexNum(text[i]))) { state = NUMERIC; } else if (isOperator(c)) { state = OPERATOR; } else if (isSymbol(c)) { state = SYMBOL; } else if (c == '\n' || c == 0) leave = true; if (leave || (state != START && s < i)) { proxy.SetColor(s, kColorText); s = i - 1; } break; // -- format comments case LCOMMENT: proxy.SetColor(s - 1, kColorComment1); leave = true; if (text[size - 1] == '\n') state = START; break; case IDENT: if (!isalnum(c) && c != '_') { int32 kwc; if (i > s + 1 && (kwc = proxy.IsKeyword(kws)) != 0) { switch (kwc) { case 1: proxy.SetColor(s, kColorKeyword1); break; case 2: proxy.SetColor(s, kColorUserSet1); break; case 3: proxy.SetColor(s, kColorUserSet2); break; case 4: proxy.SetColor(s, kColorUserSet3); break; case 5: proxy.SetColor(s, kColorUserSet4); break; } s = --i; state = START; } else { proxy.SetColor(s, kColorText); s = --i; state = START; } } else if (kws) kws = proxy.Move((int)(unsigned char) c, kws); break; case STRING: if (c == '"' && !esc) { proxy.SetColor(s, kColorString1); s = i; state = START; } else if (c == '\n' || c == 0) { if (text[i - 2] == '\\' && text[i - 3] != '\\') { proxy.SetColor(s, kColorString1); } else { proxy.SetColor(s, kColorText); state = START; } s = size; leave = true; } else esc = !esc && (c == '\\'); break; case STRING2: if (c == '\'' && !esc) { proxy.SetColor(s, kColorString1); s = i; state = START; } else if (c == '\n' || c == 0) { if (text[i - 2] == '\\' && text[i - 3] != '\\') { proxy.SetColor(s, kColorString1); } else { proxy.SetColor(s, kColorText); state = START; } s = size; leave = true; } else esc = !esc && (c == '\\'); break; /* case STRING3: break; */ case NUMERIC: proxy.SetColor(s, kColorNumber1); if (isNumeric(text[i - 1]) || (hex_num && isHexNum(text[i - 1]))) ; else if (text[i - 1] == '.' && floating_point == false) floating_point = true; else if (isHexNum(text[i - 1]) && hex_num == false) hex_num = true; else { s = i - 1; i--; state = START; } break; case OPERATOR: proxy.SetColor(s, kColorOperator1); if (isOperator(text[i - 1])) ; else { s = i - 1; i--; state = START; } break; case SYMBOL: proxy.SetColor(s, kColorSeparator1); if (isSymbol(text[i - 1])) ; else { s = i - 1; i--; state = START; } break; default: leave = true; break; } } }