void add_words(void) { char buf[40]; int z1=0,z2; while (input[z1]) { z2=0; while (xisalpha(input[z1]) && z2<39) { buf[z2++]=input[z1++]; } buf[z2]=0; add_word(buf); while (input[z1] && !xisalpha(input[z1])) z1++; } }
void complete_word(void) { int n=0,z,pos; char buf[40]; if (cur_pos<1) return; for (z=cur_pos-1; z>=0; z--) if (!xisalpha(input[z])) { z++; break; } if (z<0) z=0; while (z<cur_pos && n<39) buf[n++]=input[z++]; buf[n]=0; if (n<1) return; for (z=tabstart; z<MWORD; z++) { if (!strncmp(buf,words[z],n) && strlen(words[z])>(unsigned)n) { pos=cur_pos; while (pos<115 && words[z][n]) input[pos++]=words[z][n++]; if (pos<115) input[pos++]=' '; in_len=pos; tabmode=1; tabstart=z+1; return; } } tabmode=0; tabstart=0; in_len=cur_pos; }
static int parseBits(const char * s, const tokenBits tokbits, /*@out@*/ rpmsenseFlags * bp) /*@modifies *bp @*/ { tokenBits tb; const char * se; rpmsenseFlags bits = RPMSENSE_ANY; int c = 0; if (s) { while (*s != '\0') { while ((c = *s) && xisspace(c)) s++; se = s; while ((c = *se) && xisalpha(c)) se++; if (s == se) break; for (tb = tokbits; tb->name; tb++) { if (tb->name != NULL && strlen(tb->name) == (size_t)(se-s) && !strncmp(tb->name, s, (se-s))) /*@innerbreak@*/ break; } if (tb->name == NULL) break; bits |= tb->bits; while ((c = *se) && xisspace(c)) se++; if (c != ',') break; s = ++se; } } if (c == 0 && bp) *bp = bits; return (c ? RPMRC_FAIL : RPMRC_OK); }
void #line 366 "./cwebdir/ctang-w2c.ch" skip_limbo P1H(void) #line 1481 "./cwebdir/ctangle.w" { char c; while(1){ if(loc> limit&&get_line()==0)return; *(limit+1)= '@'; while(*loc!='@')loc++; if(loc++<=limit){ c= *loc++; if(ccode[(eight_bits)c]==new_section)break; switch(ccode[(eight_bits)c]){ case translit_code:/*93:*/ #line 1507 "./cwebdir/ctangle.w" while(xisspace(*loc)&&loc<limit)loc++; loc+= 3; if(loc> limit||!xisxdigit(*(loc-3))||!xisxdigit(*(loc-2)) ||(*(loc-3)>='0'&&*(loc-3)<='7')||!xisspace(*(loc-1))) err_print("! Improper hex number following @l"); else{ unsigned i; char*beg; sscanf(loc-3,"%x",&i); while(xisspace(*loc)&&loc<limit)loc++; beg= loc; while(loc<limit&&(xisalpha(*loc)||xisdigit(*loc)||*loc=='_'))loc++; if(loc-beg>=translit_length) err_print("! Replacement string in @l too long"); else{ strncpy(translit[i-0200],beg,loc-beg); translit[i-0200][loc-beg]= '\0'; } } /*:93*/ #line 1491 "./cwebdir/ctangle.w" ;break; case format_code:case'@':break; case control_text:if(c=='q'||c=='Q'){ while((c= skip_ahead())=='@'); if(*(loc-1)!='>') err_print("! Double @ should be used in control text"); break; } default:err_print("! Double @ should be used in limbo"); } } } }
/* assume ascii */ static inline int dpkgEVRctype(char x) /*@*/ { int c = (int)x; return ( x == '~' ? -1 : xisdigit(c) ? 0 : x == '\0' ? 0 \ : xisalpha(c) ? c : c + 256 ); }
static BINDING_FUNCTION(binding_word_rubout) { CHAR_T *p; int eaten = 0; if (!line_index) return; xfree(yanked); p = line + line_index; if (xisspace(*(p - 1))) { while (p > line && xisspace(*(p - 1))) { p--; eaten++; } } else { while (p > line && ! xisalpha(*(p - 1)) && ! xisspace(*(p - 1))) { p--; eaten++; } } if (p > line) { while (p > line && ! xisspace(*(p - 1)) && xisalpha(*(p - 1))) { p--; eaten++; } } yanked = xcalloc(eaten + 1, sizeof(CHAR_T)); xwcslcpy(yanked, p, eaten + 1); memmove(p, line + line_index, (xwcslen(line) - line_index + 1) * sizeof(CHAR_T)); line_index -= eaten; }
/* * returns a pointer to a field-value of the first matching field-name where * field-value matches prefix if any */ char * mime_get_header_field(const char *mime, const char *name, const char *prefix) { LOCAL_ARRAY(char, header, GET_HDR_SZ); const char *p = NULL; char *q = NULL; char got = 0; const int namelen = name ? strlen(name) : 0; const int preflen = prefix ? strlen(prefix) : 0; int l; if (NULL == mime) return NULL; assert(NULL != name); debug(25, 5) ("mime_get_header: looking for '%s'\n", name); for (p = mime; *p; p += strcspn(p, "\n\r")) { if (strcmp(p, "\r\n\r\n") == 0 || strcmp(p, "\n\n") == 0) return NULL; while (xisspace(*p)) p++; if (strncasecmp(p, name, namelen)) continue; if (!xisspace(p[namelen]) && p[namelen] != ':') continue; l = strcspn(p, "\n\r") + 1; if (l > GET_HDR_SZ) l = GET_HDR_SZ; xstrncpy(header, p, l); debug(25, 5) ("mime_get_header: checking '%s'\n", header); q = header; q += namelen; if (*q == ':') q++, got = 1; while (xisspace(*q)) q++, got = 1; if (got && prefix) { /* we could process list entries here if we had strcasestr(). */ /* make sure we did not match a part of another field-value */ got = !strncasecmp(q, prefix, preflen) && !xisalpha(q[preflen]); } if (got) { debug(25, 5) ("mime_get_header: returning '%s'\n", q); return q; } } return NULL; }
DWORD CCrystalTextView:: ParseLineVerilog (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) { int nLength = GetLineLength (nLineIndex); if (nLength == 0) return dwCookie & COOKIE_EXT_COMMENT; LPCTSTR pszChars = GetLineChars (nLineIndex); bool bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; bool bRedefineBlock = true; bool bWasCommentStart = false; bool bDecIndex = false; int nIdentBegin = -1; int nPrevI = -1; int I=0; for (I = 0;; nPrevI = I, I = static_cast<int>(::CharNext(pszChars+I) - pszChars)) { if (I == nPrevI) { // CharNext did not advance, so we're at the end of the string // and we already handled this character, so stop break; } if (bRedefineBlock) { int nPos = I; if (bDecIndex) nPos = nPrevI; if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) { DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); } else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) { DEFINE_BLOCK (nPos, COLORINDEX_STRING); } else if (dwCookie & COOKIE_PREPROCESSOR) { DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR); } else { if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '$' || (pszChars[nPos] == '\'' && nPos > 0 && (xisalpha (*::CharNext(pszChars + nPos))))) { DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); } else { DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); bRedefineBlock = true; bDecIndex = true; goto out; } } bRedefineBlock = false; bDecIndex = false; } out: // Can be bigger than length if there is binary data // See bug #1474782 Crash when comparing SQL with with binary data if (I >= nLength) break; if (dwCookie & COOKIE_COMMENT) { DEFINE_BLOCK (I, COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; break; } // String constant "..." if (dwCookie & COOKIE_STRING) { if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || pszChars[nPrevI] == '\\' && *::CharPrev(pszChars, pszChars + nPrevI) == '\\'))) { dwCookie &= ~COOKIE_STRING; bRedefineBlock = true; } continue; } // Extended comment /*...*/ if (dwCookie & COOKIE_EXT_COMMENT) { if ((I > 1 && pszChars[I] == '/' && pszChars[nPrevI] == '*' && !bWasCommentStart) || (I == 1 && pszChars[I] == '/' && pszChars[nPrevI] == '*')) { dwCookie &= ~COOKIE_EXT_COMMENT; bRedefineBlock = true; } bWasCommentStart = false; continue; } // Line comment //... if (I > 0 && pszChars[I] == '/' && pszChars[nPrevI] == '/') { DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; break; } // Preprocessor directive `... if (dwCookie & COOKIE_PREPROCESSOR) { if (I > 0 && pszChars[I] == '*' && pszChars[nPrevI] == '/') { DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT); dwCookie |= COOKIE_EXT_COMMENT; } continue; } // Normal text if (pszChars[I] == '"') { DEFINE_BLOCK (I, COLORINDEX_STRING); dwCookie |= COOKIE_STRING; continue; } if (I > 0 && pszChars[I] == '*' && pszChars[nPrevI] == '/') { DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT); dwCookie |= COOKIE_EXT_COMMENT; bWasCommentStart = true; continue; } bWasCommentStart = false; if (bFirstChar) { if (pszChars[I] == '`') { DEFINE_BLOCK (I, COLORINDEX_PREPROCESSOR); dwCookie |= COOKIE_PREPROCESSOR; continue; } if (!xisspace (pszChars[I])) bFirstChar = false; } if (pBuf == NULL) continue; // We don't need to extract keywords, // for faster parsing skip the rest of loop if (xisalnum (pszChars[I]) || pszChars[I] == '$' || pszChars[I] == '\'') { if (nIdentBegin == -1) nIdentBegin = I; } else { if (nIdentBegin >= 0) { if (IsVerilogKeyword (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); } else if (IsVerilogFunction (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); } else if (IsVerilogNumber (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); } bRedefineBlock = true; bDecIndex = true; nIdentBegin = -1; } } } if (nIdentBegin >= 0) { if (IsVerilogKeyword (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); } else if (IsVerilogFunction (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); } else if (IsVerilogNumber (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); } } dwCookie &= COOKIE_EXT_COMMENT; return dwCookie; }
/* * Convert a string to a int64 integer. * * Ignores `locale' stuff. Assumes that the upper and lower case * alphabets and digits are each contiguous. */ int64_t strtoll (const char *nptr, char **endptr, int base) { register const char *s = nptr; register u_int64_t acc; register int c; register u_int64_t cutoff; register int neg = 0, any, cutlim; /* * Skip white space and pick up leading +/- sign if any. * If base is 0, allow 0x for hex and 0 for octal, else * assume decimal; if base is already 16, allow 0x. */ do { c = *s++; } while (xisspace(c)); if (c == '-') { neg = 1; c = *s++; } else if (c == '+') c = *s++; if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; /* * Compute the cutoff value between legal numbers and illegal * numbers. That is the largest legal value, divided by the * base. An input number that is greater than this value, if * followed by a legal input character, is too big. One that * is equal to this value may be valid or not; the limit * between valid and invalid numbers is then based on the last * digit. For instance, if the range for longs is * [-2147483648..2147483647] and the input base is 10, * cutoff will be set to 214748364 and cutlim to either * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated * a value > 214748364, or equal but the next digit is > 7 (or 8), * the number is too big, and we will return a range error. * * Set any if any `digits' consumed; make it negative to indicate * overflow. */ cutoff = neg ? -(u_int64_t) INT64_MIN : INT64_MAX; cutlim = cutoff % (u_int64_t) base; cutoff /= (u_int64_t) base; for (acc = 0, any = 0;; c = *s++) { if (xisdigit(c)) c -= '0'; else if (xisalpha(c)) c -= xisupper(c) ? 'A' - 10 : 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = neg ? INT64_MIN : INT64_MAX; errno = ERANGE; } else if (neg) acc = -acc; if (endptr != 0) *endptr = (char *) (any ? s - 1 : nptr); return acc; }
/* * binding_key() * * analizuje nazwê klawisza i wpisuje akcjê do odpowiedniej mapy. * * 0/-1. */ static int binding_key(struct binding *b, const char *key, int add) { /* debug("Key: %s\n", key); */ if (!xstrncasecmp(key, ("Alt-"), 4)) { unsigned char ch; #define __key(x, y, z) \ if (!xstrcasecmp(key + 4, (x))) { \ b->key = saprintf("Alt-%s", (x)); \ if (add) { \ ncurses_binding_map_meta[y] = LIST_ADD2(&bindings, xmemdup(b, sizeof(struct binding))); \ if (z) \ ncurses_binding_map_meta[z] = ncurses_binding_map_meta[y]; \ } \ return 0; \ } __key("Enter", 13, 0); __key("Backspace", KEY_BACKSPACE, 127); __key("Home", KEY_HOME, KEY_FIND); __key("End", KEY_END, KEY_SELECT); __key("Delete", KEY_DC, 0); __key("Insert", KEY_IC, 0); __key("Left", KEY_LEFT, 0); __key("Right", KEY_RIGHT, 0); __key("Up", KEY_UP, 0); __key("Down", KEY_DOWN, 0); __key("PageUp", KEY_PPAGE, 0); __key("PageDown", KEY_NPAGE, 0); #undef __key if (xstrlen(key) != 5) return -1; ch = xtoupper(key[4]); b->key = saprintf(("Alt-%c"), ch); /* XXX Alt-Ó ??? */ if (add) { ncurses_binding_map_meta[ch] = LIST_ADD2(&bindings, xmemdup(b, sizeof(struct binding))); if (xisalpha(ch)) ncurses_binding_map_meta[xtolower(ch)] = ncurses_binding_map_meta[ch]; } return 0; } if (!xstrncasecmp(key, ("Ctrl-"), 5)) { unsigned char ch; // if (xstrlen(key) != 6) // return -1; #define __key(x, y, z) \ if (!xstrcasecmp(key + 5, (x))) { \ b->key = saprintf("Ctrl-%s", (x)); \ if (add) { \ ncurses_binding_map[y] = LIST_ADD2(&bindings, xmemdup(b, sizeof(struct binding))); \ if (z) \ ncurses_binding_map[z] = ncurses_binding_map[y]; \ } \ return 0; \ } __key("Enter", KEY_CTRL_ENTER, 0); __key("Escape", KEY_CTRL_ESCAPE, 0); __key("Delete", KEY_CTRL_DC, 0); __key("Backspace", KEY_CTRL_BACKSPACE, 0); __key("Tab", KEY_CTRL_TAB, 0); #undef __key ch = xtoupper(key[5]); b->key = saprintf(("Ctrl-%c"), ch); if (add) { if (xisalpha(ch)) ncurses_binding_map[ch - 64] = LIST_ADD2(&bindings, xmemdup(b, sizeof(struct binding))); else return -1; } return 0; } if (xtoupper(key[0]) == 'F' && atoi(key + 1)) { int f = atoi(key + 1); if (f < 1 || f > 63) return -1; b->key = saprintf(("F%d"), f); if (add) ncurses_binding_map[KEY_F(f)] = LIST_ADD2(&bindings, xmemdup(b, sizeof(struct binding))); return 0; } #define __key(x, y, z) \ if (!xstrcasecmp(key, (x))) { \ b->key = xstrdup((x)); \ if (add) { \ ncurses_binding_map[y] = LIST_ADD2(&bindings, xmemdup(b, sizeof(struct binding))); \ if (z) \ ncurses_binding_map[z] = ncurses_binding_map[y]; \ } \ return 0; \ } __key("Enter", 13, 0); __key("Escape", 27, 0); __key("Home", KEY_HOME, KEY_FIND); __key("End", KEY_END, KEY_SELECT); __key("Delete", KEY_DC, 0); __key("Insert", KEY_IC, 0); __key("Backspace", KEY_BACKSPACE, 127); __key("Tab", 9, 0); __key("Left", KEY_LEFT, 0); __key("Right", KEY_RIGHT, 0); __key("Up", KEY_UP, 0); __key("Down", KEY_DOWN, 0); __key("PageUp", KEY_PPAGE, 0); __key("PageDown", KEY_NPAGE, 0); #undef __key return -1; }
DWORD CrystalLineParser::ParseLineNsis (DWORD dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems) { if (nLength == 0) return dwCookie & COOKIE_EXT_COMMENT; bool bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; bool bRedefineBlock = true; bool bWasCommentStart = false; bool bDecIndex = false; int nIdentBegin = -1; int nPrevI = -1; int I=0; for (I = 0;; nPrevI = I, I = static_cast<int>(::CharNext(pszChars+I) - pszChars)) { if (I == nPrevI) { // CharNext did not advance, so we're at the end of the string // and we already handled this character, so stop break; } if (bRedefineBlock) { int nPos = I; if (bDecIndex) nPos = nPrevI; if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) { DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); } else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) { DEFINE_BLOCK (nPos, COLORINDEX_STRING); } else if (dwCookie & COOKIE_PREPROCESSOR) { DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR); } else { if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (*::CharPrev(pszChars, pszChars + nPos)) && !xisalpha (*::CharNext(pszChars + nPos)))) { DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); } else { DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); bRedefineBlock = true; bDecIndex = true; goto out; } } bRedefineBlock = false; bDecIndex = false; } out: // Can be bigger than length if there is binary data // See bug #1474782 Crash when comparing SQL with with binary data if (I >= nLength || pszChars[I] == 0) break; if (dwCookie & COOKIE_COMMENT) { DEFINE_BLOCK (I, COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; break; } // String constant "...." if (dwCookie & COOKIE_STRING) { if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\'))) { dwCookie &= ~COOKIE_STRING; bRedefineBlock = true; } continue; } // Char constant '..' if (dwCookie & COOKIE_CHAR) { if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\'))) { dwCookie &= ~COOKIE_CHAR; bRedefineBlock = true; } continue; } // Extended comment /*....*/ if (dwCookie & COOKIE_EXT_COMMENT) { // if (I > 0 && pszChars[I] == '/' && pszChars[nPrevI] == '*') if ((I > 1 && pszChars[I] == '/' && pszChars[nPrevI] == '*' /*&& *::CharPrev(pszChars, pszChars + nPrevI) != '/'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == '/' && pszChars[nPrevI] == '*')) { dwCookie &= ~COOKIE_EXT_COMMENT; bRedefineBlock = true; } bWasCommentStart = false; continue; } //if (I > 0 && pszChars[I] == '/' && pszChars[nPrevI] == '/') if (I > 0 && pszChars[nPrevI] == ';') { DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; break; } // Preprocessor directive #.... if (dwCookie & COOKIE_PREPROCESSOR) { if (I > 0 && pszChars[I] == '*' && pszChars[nPrevI] == '/') { DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT); dwCookie |= COOKIE_EXT_COMMENT; } continue; } // Normal text if (pszChars[I] == '"') { DEFINE_BLOCK (I, COLORINDEX_STRING); dwCookie |= COOKIE_STRING; continue; } if (pszChars[I] == '\'') { // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') if (!I || !xisalnum (pszChars[nPrevI])) { DEFINE_BLOCK (I, COLORINDEX_STRING); dwCookie |= COOKIE_CHAR; continue; } } if (I > 0 && pszChars[I] == '*' && pszChars[nPrevI] == '/') { DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT); dwCookie |= COOKIE_EXT_COMMENT; bWasCommentStart = true; continue; } bWasCommentStart = false; if (bFirstChar) { if (pszChars[I] == '!') { DEFINE_BLOCK (I, COLORINDEX_PREPROCESSOR); dwCookie |= COOKIE_PREPROCESSOR; continue; } if (!xisspace (pszChars[I])) bFirstChar = false; } if (pBuf == nullptr) continue; // We don't need to extract keywords, // for faster parsing skip the rest of loop if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[nPrevI]) && !xisalpha (pszChars[I + 1]))) { if (nIdentBegin == -1) nIdentBegin = I; } else { if (nIdentBegin >= 0) { if (IsNsisKeyword (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); } else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); } else if (IsNsisNumber (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); } else { bool bFunction = false; for (int j = I; j < nLength; j++) { if (!xisspace (pszChars[j])) { if (pszChars[j] == '(') { bFunction = true; } break; } } if (bFunction) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); } } bRedefineBlock = true; bDecIndex = true; nIdentBegin = -1; } } } if (nIdentBegin >= 0) { if (IsNsisKeyword (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); } else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); } else if (IsNsisNumber (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); } else { bool bFunction = false; for (int j = I; j < nLength; j++) { if (!xisspace (pszChars[j])) { if (pszChars[j] == '(') { bFunction = true; } break; } } if (bFunction) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); } } } if (pszChars[nLength - 1] != '\\' || IsMBSTrail(pszChars, nLength - 1)) dwCookie &= COOKIE_EXT_COMMENT; return dwCookie; }
DWORD CCrystalTextView:: ParseLineInnoSetup (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) { int nLength = GetLineLength (nLineIndex); if (nLength == 0) return dwCookie & (COOKIE_EXT_COMMENT | COOKIE_EXT_COMMENT2); LPCTSTR pszChars = GetLineChars (nLineIndex); BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; BOOL bRedefineBlock = TRUE; BOOL bDecIndex = FALSE; int nIdentBegin = -1; int nPrevI = -1; int I=0; for (I = 0;; nPrevI = I, I = CharNext(pszChars+I) - pszChars) { if (I == nPrevI) { // CharNext did not advance, so we're at the end of the string // and we already handled this character, so stop break; } if (bRedefineBlock) { int nPos = I; if (bDecIndex) nPos = nPrevI; if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT | COOKIE_EXT_COMMENT2)) { DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); } else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) { DEFINE_BLOCK (nPos, COLORINDEX_STRING); } else if (dwCookie & COOKIE_PREPROCESSOR) { DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR); } else if (dwCookie & COOKIE_SECTION) { DEFINE_BLOCK (nPos, COLORINDEX_FUNCNAME); } else { if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (*::CharPrev(pszChars, pszChars + nPos)) && !xisalpha (*::CharNext(pszChars + nPos)))) { DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); } else { DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); bRedefineBlock = TRUE; bDecIndex = TRUE; goto out; } } bRedefineBlock = FALSE; bDecIndex = FALSE; } out: // Can be bigger than length if there is binary data // See bug #1474782 Crash when comparing SQL with with binary data if (I >= nLength) break; if (dwCookie & COOKIE_COMMENT) { DEFINE_BLOCK (I, COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; break; } // String constant "...." if (dwCookie & COOKIE_STRING) { if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || pszChars[nPrevI] == '\\' && *::CharPrev(pszChars, pszChars + nPrevI) == '\\'))) { dwCookie &= ~COOKIE_STRING; bRedefineBlock = TRUE; } continue; } // Char constant '..' if (dwCookie & COOKIE_CHAR) { if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || pszChars[nPrevI] == '\\' && *::CharPrev(pszChars, pszChars + nPrevI) == '\\'))) { dwCookie &= ~COOKIE_CHAR; bRedefineBlock = TRUE; } continue; } // Extended comment (*....*) if (dwCookie & COOKIE_EXT_COMMENT) { // if (I > 0 && pszChars[I] == ')' && pszChars[nPrevI] == '*') if ((I > 1 && pszChars[I] == ')' && pszChars[nPrevI] == '*' && *::CharPrev(pszChars, pszChars + nPrevI) != '(') || (I == 1 && pszChars[I] == ')' && pszChars[nPrevI] == '*')) { dwCookie &= ~COOKIE_EXT_COMMENT; bRedefineBlock = TRUE; } continue; } // Extended comment {....} if (dwCookie & COOKIE_EXT_COMMENT2) { if (pszChars[I] == '}') { dwCookie &= ~COOKIE_EXT_COMMENT2; bRedefineBlock = TRUE; } continue; } if (I > 0 && pszChars[I] == '/' && pszChars[nPrevI] == '/') { DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; break; } // Section header [...] if (dwCookie & COOKIE_SECTION) { if (pszChars[I] == ']') { dwCookie &= ~COOKIE_SECTION; bRedefineBlock = TRUE; } continue; } // Normal text if (pszChars[I] == '"') { DEFINE_BLOCK (I, COLORINDEX_STRING); dwCookie |= COOKIE_STRING; continue; } if (pszChars[I] == '\'') { // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') if (!I || !xisalnum (pszChars[nPrevI])) { DEFINE_BLOCK (I, COLORINDEX_STRING); dwCookie |= COOKIE_CHAR; continue; } } if (I > 0 && pszChars[I] == '*' && pszChars[nPrevI] == '(') { DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT); dwCookie |= COOKIE_EXT_COMMENT; continue; } if (pszChars[I] == '{') { DEFINE_BLOCK (I, COLORINDEX_COMMENT); dwCookie |= COOKIE_EXT_COMMENT2; continue; } if (bFirstChar) { if (pszChars[I] == ';') { DEFINE_BLOCK (I, COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; continue; } if (pszChars[I] == '#') { DEFINE_BLOCK (I, COLORINDEX_PREPROCESSOR); dwCookie |= COOKIE_PREPROCESSOR; continue; } if (pszChars[I] == '[') { DEFINE_BLOCK (I, COLORINDEX_FUNCNAME); dwCookie |= COOKIE_SECTION; continue; } if (!xisspace (pszChars[I])) bFirstChar = FALSE; } if (pBuf == NULL) continue; // We don't need to extract keywords, // for faster parsing skip the rest of loop if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[nPrevI]) && !xisalpha (pszChars[I + 1]))) { if (nIdentBegin == -1) nIdentBegin = I; } else { if (nIdentBegin >= 0) { if (IsInnoSetupKeyword (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); } else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); } else if (IsInnoSetupNumber (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); } else { bool bFunction = FALSE; for (int j = I; j < nLength; j++) { if (!xisspace (pszChars[j])) { if (pszChars[j] == '(') { bFunction = TRUE; } break; } } if (bFunction) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); } } bRedefineBlock = TRUE; bDecIndex = TRUE; nIdentBegin = -1; } } } if (nIdentBegin >= 0) { if (IsInnoSetupKeyword (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); } else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); } else if (IsInnoSetupNumber (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); } else { bool bFunction = FALSE; for (int j = I; j < nLength; j++) { if (!xisspace (pszChars[j])) { if (pszChars[j] == '(') { bFunction = TRUE; } break; } } if (bFunction) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); } } } if (pszChars[nLength - 1] != '\\' || m_pTextBuffer->IsMBSTrail(nLineIndex, nLength - 1)) dwCookie &= (COOKIE_EXT_COMMENT | COOKIE_EXT_COMMENT2); return dwCookie; }
DWORD Edit_Syntax_ParseLineGeneric(LPEDITVIEW lpew, DWORD dwCookie, int nLineIndex, LPTEXTBLOCK pBuf, int *piActualItems) { int nLength = Edit_View_GetLineLength(lpew, nLineIndex); LPCTSTR pszChars = Edit_View_GetLineChars(lpew, nLineIndex); LPTEXTDEF lptd = lpew->lptdCurSourceDef; BOOL bFirstChar = (dwCookie & ~(COOKIE_EXT_COMMENT)) == 0; BOOL bRedefineBlock = TRUE; BOOL bWasCommentStart = FALSE; BOOL bDecIndex = FALSE; int nIdentBegin = -1; int i; int nCommentLen; if (nLength <= 0) return (dwCookie & COOKIE_EXT_COMMENT); for (i = 0; ; i++) { if (bRedefineBlock) { int nPos = i; if (bDecIndex) nPos--; if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) { DEFINE_BLOCK(nPos, COLORINDEX_COMMENT); } else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) { DEFINE_BLOCK(nPos, COLORINDEX_STRING); } else if (dwCookie & COOKIE_PREPROCESSOR) { DEFINE_BLOCK(nPos, COLORINDEX_PREPROCESSOR); } else if (dwCookie & COOKIE_PREFIXED) { DEFINE_BLOCK(nPos, COLORINDEX_PREFIXED); } else { if (Edit_Syntax_IsOperator(lptd, pszChars[nPos])) { DEFINE_BLOCK(nPos, COLORINDEX_OPERATOR); bRedefineBlock = TRUE; bDecIndex = TRUE; goto out; } else /* if ((xisalnum(pszChars[nPos]) || pszChars[nPos] == _T('.') && nPos > 0 && (!xisalfa(pszChars[nPos - 1]) && !xisalfa(pszChars[nPos + 1]))))*/ { DEFINE_BLOCK(nPos, COLORINDEX_NORMALTEXT); } /* else { DEFINE_BLOCK(nPos, COLORINDEX_OPERATOR); bRedefineBlock = TRUE; bDecIndex = TRUE; goto out; }*/ } bRedefineBlock = FALSE; bDecIndex = FALSE; } out: if (i >= nLength) break; // Line Comment ? [//] if (dwCookie & COOKIE_COMMENT) { if ((!lptd->bCommentFirstRealChar) || (lptd->bCommentFirstRealChar && bFirstChar)) { DEFINE_BLOCK(i, COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; break; } } // String constant ? ["..."] if (dwCookie & COOKIE_STRING) { if (pszChars[i] == lptd->cString && (i == 0 || i == 1 && pszChars[i - 1] != lptd->cEscape || i >= 2 && (pszChars[i - 1] != lptd->cEscape || pszChars[i - 1] == lptd->cEscape && pszChars[i - 2] == lptd->cEscape))) { dwCookie &= ~(COOKIE_STRING); bRedefineBlock = TRUE; } // Nasty but functions...just a good proof that // this whole function needs rewriting if (lptd->bPrefixesInStrings) { if (bRedefineBlock && (dwCookie & COOKIE_PREFIXED)) dwCookie |= COOKIE_STRING; if (dwCookie & COOKIE_PREFIXED) { if (!xisalnum(pszChars[i])) { dwCookie &= ~(COOKIE_PREFIXED); bRedefineBlock = TRUE; // We have to reevaluate the last char i--; } else { DEFINE_BLOCK(i, COLORINDEX_PREFIXED); } } else { if (Edit_Syntax_IsPrefix(lptd, pszChars + i)) { DEFINE_BLOCK(i, COLORINDEX_PREFIXED); dwCookie |= COOKIE_PREFIXED; } } } continue; } // Char constant ? ['...'] if (dwCookie & COOKIE_CHAR) { if (pszChars[i] == lptd->cChar && (i == 0 || i == 1 && pszChars[i - 1] != lptd->cEscape || i >= 2 && (pszChars[i - 1] != lptd->cEscape || pszChars[i - 1] == lptd->cEscape && pszChars[i - 2] == lptd->cEscape))) { dwCookie &= ~(COOKIE_CHAR); bRedefineBlock = TRUE; } continue; } // Extended comment End ? [*/] if (dwCookie & COOKIE_EXT_COMMENT) { if (((i > (lptd->nCloseCommentLen - 1) && lptd->nCloseCommentLen > 0 && String_NumEqual((pszChars + i - lptd->nCloseCommentLen), lptd->szCloseComment, lptd->nCloseCommentLen, lptd->bCase) && !bWasCommentStart) || (i >= (lptd->nCloseCommentLen - 1) && lptd->nCloseCommentLen > 0 && String_NumEqual((pszChars + i - (lptd->nCloseCommentLen - 1)), lptd->szCloseComment, lptd->nCloseCommentLen, lptd->bCase))) || ((i > (lptd->nCloseComment2Len - 1) && lptd->nCloseComment2Len > 0 && String_NumEqual((pszChars + i - lptd->nCloseComment2Len), lptd->szCloseComment2, lptd->nCloseComment2Len, lptd->bCase) && !bWasCommentStart) || (i >= (lptd->nCloseComment2Len - 1) && lptd->nCloseComment2Len > 0 && String_NumEqual((pszChars + i - (lptd->nCloseComment2Len - 1)), lptd->szCloseComment2, lptd->nCloseComment2Len, lptd->bCase)))) { dwCookie &= ~(COOKIE_EXT_COMMENT); bRedefineBlock = TRUE; } bWasCommentStart = FALSE; continue; } if (dwCookie & COOKIE_PREFIXED) { if (!xisalnum(pszChars[i])) { dwCookie &= ~(COOKIE_PREFIXED); bRedefineBlock = TRUE; // We have to reevaluate the last char i--; } else { DEFINE_BLOCK(i, COLORINDEX_PREFIXED); } continue; } if (dwCookie & COOKIE_DISABLED) { if (pszChars[i] == lptd->cEnable && (i == 0 || i == 1 && pszChars[i - 1] != lptd->cEscape || i >= 2 && (pszChars[i - 1] != lptd->cEscape || pszChars[i - 1] == lptd->cEscape && pszChars[i - 2] == lptd->cEscape))) { dwCookie &= ~(COOKIE_DISABLED); bRedefineBlock = TRUE; } continue; } // if the line end char is there than the next char will be the first // in that pseudoline if (pszChars[i] == lptd->cLineEnd) { bFirstChar = TRUE; goto ProcessWord; // continue; } // Start Processing // if the char is a linecontinuation char then assume error in user code // or already parsed from previous line // Just break because it does so in MSDEV damnit! =P if (pszChars[i] == lptd->cLineContinuation) { DEFINE_BLOCK(i, COLORINDEX_NORMALTEXT); break; } // Line Comment [//] if (((i >= ((nCommentLen = lptd->nLineCommentLen) - 1) && lptd->nLineCommentLen > 0 && String_NumEqual((pszChars + i - (lptd->nLineCommentLen - 1)), lptd->szLineComment, lptd->nLineCommentLen, lptd->bCase))) || (i >= ((nCommentLen = lptd->nLineComment2Len) - 1) && lptd->nLineComment2Len > 0 && String_NumEqual((pszChars + i - (lptd->nLineComment2Len - 1)), lptd->szLineComment2, lptd->nLineComment2Len, lptd->bCase))) { if ((!lptd->bCommentFirstRealChar) || (lptd->bCommentFirstRealChar && bFirstChar)) { DEFINE_BLOCK(i - (nCommentLen - 1), COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; break; } } // Preprocessor directive [#] if (dwCookie & COOKIE_PREPROCESSOR) { if (((i >= ((nCommentLen = lptd->nOpenCommentLen) - 1) && lptd->nOpenCommentLen > 0 && String_NumEqual((pszChars + i - (lptd->nOpenCommentLen - 1)), lptd->szOpenComment, lptd->nOpenCommentLen, lptd->bCase))) || (i >= ((nCommentLen = lptd->nOpenComment2Len) - 1) && lptd->nOpenComment2Len > 0 && String_NumEqual((pszChars + i - (lptd->nOpenComment2Len - 1)), lptd->szOpenComment2, lptd->nOpenComment2Len, lptd->bCase))) { DEFINE_BLOCK(i - (nCommentLen - 1), COLORINDEX_COMMENT); dwCookie |= COOKIE_EXT_COMMENT; } continue; } // Normal text // String ["..."] if (pszChars[i] == lptd->cString) { if (i > 0 && pszChars[i - 1] == lptd->cEscape) continue; DEFINE_BLOCK(i, COLORINDEX_STRING); dwCookie |= COOKIE_STRING; continue; } // Char ['...'] if (pszChars[i] == lptd->cChar) { if (i > 0 && pszChars[i - 1] == lptd->cEscape) continue; DEFINE_BLOCK(i, COLORINDEX_STRING); dwCookie |= COOKIE_CHAR; continue; } // Open Comment [/*] if (((i >= ((nCommentLen = lptd->nOpenCommentLen) - 1) && lptd->nOpenCommentLen > 0 && String_NumEqual((pszChars + i - (lptd->nOpenCommentLen - 1)), lptd->szOpenComment, lptd->nOpenCommentLen, lptd->bCase))) || (i >= ((nCommentLen = lptd->nOpenComment2Len) - 1) && lptd->nOpenComment2Len > 0 && String_NumEqual((pszChars + i - (lptd->nOpenComment2Len - 1)), lptd->szOpenComment2, lptd->nOpenComment2Len, lptd->bCase))) { if ((!lptd->bCommentFirstRealChar) || (lptd->bCommentFirstRealChar && bFirstChar)) { DEFINE_BLOCK(i - (nCommentLen - 1), COLORINDEX_COMMENT); dwCookie |= COOKIE_EXT_COMMENT; bWasCommentStart = TRUE; } continue; } bWasCommentStart = FALSE; if (bFirstChar) { // Preprocessor [#] if (pszChars[i] == lptd->cPreProcessor) { DEFINE_BLOCK(i, COLORINDEX_PREPROCESSOR); dwCookie |= COOKIE_PREPROCESSOR; continue; } // if it is whitespace then still available if (!_istspace(pszChars[i])) bFirstChar = FALSE; } // FIXME: does this work with lptd->cEscape? if (Edit_Syntax_IsPrefix(lptd, pszChars + i)) { DEFINE_BLOCK(i, COLORINDEX_PREFIXED); dwCookie |= COOKIE_PREFIXED; continue; } if (pszChars[i] == lptd->cDisable) { if (i > 0 && pszChars[i - 1] == lptd->cEscape) continue; DEFINE_BLOCK(i, COLORINDEX_NORMALTEXT); dwCookie |= COOKIE_DISABLED; continue; } // We don't need to extract keywords, // for faster parsing skip the rest of loop if (pBuf == NULL) continue; if (xisalnum(pszChars[i]) || pszChars[i] == _T('.') && i > 0 && (!xisalpha(pszChars[i - 1]) && !xisalpha(pszChars[i + 1]))) { if (nIdentBegin == -1) nIdentBegin = i; } else { ProcessWord: if (nIdentBegin >= 0) { if (Edit_Syntax_IsKeyword(lptd, pszChars + nIdentBegin, i - nIdentBegin)) { DEFINE_BLOCK(nIdentBegin, COLORINDEX_KEYWORD); } else if (Edit_Syntax_IsUser1Keyword(lptd, pszChars + nIdentBegin, i - nIdentBegin)) { DEFINE_BLOCK(nIdentBegin, COLORINDEX_USER1); } else if (Edit_Syntax_IsUser2Keyword(lptd, pszChars + nIdentBegin, i - nIdentBegin)) { DEFINE_BLOCK(nIdentBegin, COLORINDEX_USER2); } else if (Edit_Syntax_IsNumber(pszChars + nIdentBegin, i - nIdentBegin)) { DEFINE_BLOCK(nIdentBegin, COLORINDEX_NUMBER); } else { BOOL bFunction = FALSE; int j; for (j = i; j < nLength; j++) { if (!_istspace(pszChars[j])) { if (pszChars[j] == lptd->cFunctionBegin) bFunction = TRUE; break; } } if (bFunction) { DEFINE_BLOCK(nIdentBegin, COLORINDEX_FUNCNAME); } } bRedefineBlock = TRUE; bDecIndex = TRUE; nIdentBegin = -1; } else if (Edit_Syntax_IsOperator(lptd, pszChars[i])) { DEFINE_BLOCK(i, COLORINDEX_OPERATOR); bRedefineBlock = TRUE; bDecIndex = TRUE; } } } if (nIdentBegin >= 0) { if (Edit_Syntax_IsKeyword(lptd, pszChars + nIdentBegin, i - nIdentBegin)) { DEFINE_BLOCK(nIdentBegin, COLORINDEX_KEYWORD); } else if (Edit_Syntax_IsUser1Keyword(lptd, pszChars + nIdentBegin, i - nIdentBegin)) { DEFINE_BLOCK(nIdentBegin, COLORINDEX_USER1); } else if (Edit_Syntax_IsUser2Keyword(lptd, pszChars + nIdentBegin, i - nIdentBegin)) { DEFINE_BLOCK(nIdentBegin, COLORINDEX_USER2); } else if (Edit_Syntax_IsNumber(pszChars + nIdentBegin, i - nIdentBegin)) { DEFINE_BLOCK(nIdentBegin, COLORINDEX_NUMBER); } else { BOOL bFunction = FALSE; int j; for (j = i; j < nLength; j++) { if (!_istspace(pszChars[j])) { if (pszChars[j] == lptd->cFunctionBegin) bFunction = TRUE; break; } } if (bFunction) { DEFINE_BLOCK(nIdentBegin, COLORINDEX_FUNCNAME); } } } if (pszChars[nLength - 1] != lptd->cLineContinuation) { dwCookie &= ~(COOKIE_COMMENT); dwCookie &= ~(COOKIE_STRING); dwCookie &= ~(COOKIE_CHAR); dwCookie &= ~(COOKIE_PREFIXED); } return (dwCookie); }
void vmain(void) { int c, cnt, i; cell esave[TUBECOLS]; char *oglobp; short d; line *addr; int ind, nlput; int shouldpo = 0; int onumber = 0, olist = 0; void (*OPline)(int) = NULL; int (*OPutchar)(int) = NULL; CLOBBGRD(c); CLOBBGRD(cnt); CLOBBGRD(i); CLOBBGRD(oglobp); CLOBBGRD(addr); CLOBBGRD(shouldpo); CLOBBGRD(onumber); CLOBBGRD(olist); CLOBBGRD(OPline); CLOBBGRD(OPutchar); vch_mac = VC_NOTINMAC; /* * If we started as a vi command (on the command line) * then go process initial commands (recover, next or tag). */ if (initev) { oglobp = globp; globp = initev; hadcnt = cnt = 0; i = tchng; addr = dot; goto doinit; } /* * NB: * * The current line is always in the line buffer linebuf, * and the cursor at the position cursor. You should do * a vsave() before moving off the line to make sure the disk * copy is updated if it has changed, and a getDOT() to get * the line back if you mung linebuf. The motion * routines in ex_vwind.c handle most of this. */ for (;;) { /* * Decode a visual command. * First sync the temp file if there has been a reasonable * amount of change. Clear state for decoding of next * command. */ TSYNC(); vglobp = 0; vreg = 0; hold = 0; seenprompt = 1; wcursor = 0; Xhadcnt = hadcnt = 0; Xcnt = cnt = 1; splitw = 0; if (i = holdupd) { if (state == VISUAL) ignore(peekkey()); holdupd = 0; /* if (LINE(0) < ZERO) { vclear(); vcnt = 0; i = 3; } */ if (state != VISUAL) { vcnt = 0; vsave(); vrepaint(cursor); } else if (i == 3) vredraw(WTOP); else vsync(WTOP); vfixcurs(); } /* * Gobble up counts and named buffer specifications. */ for (;;) { looptop: #ifdef MDEBUG if (trace) fprintf(trace, "pc=%c",peekkey()); #endif if (xisdigit(peekkey()) && peekkey() != '0') { hadcnt = 1; cnt = vgetcnt(); forbid (cnt <= 0); } if (peekkey() != '"') break; ignore(getkey()), c = getkey(); /* * Buffer names be letters or digits. * But not '0' as that is the source of * an 'empty' named buffer spec in the routine * kshift (see ex_temp.c). */ forbid (c == '0' || !xisalpha(c) && !xisdigit(c)); vreg = c; } reread: /* * Come to reread from below after some macro expansions. * The call to map allows use of function key pads * by performing a terminal dependent mapping of inputs. */ #ifdef MDEBUG if (trace) fprintf(trace,"pcb=%c,",peekkey()); #endif op = getkey(); maphopcnt = 0; do { /* * Keep mapping the char as long as it changes. * This allows for double mappings, e.g., q to #, * #1 to something else. */ c = op; op = map(c,arrows); #ifdef MDEBUG if (trace) fprintf(trace,"pca=%c,",c); #endif /* * Maybe the mapped to char is a count. If so, we have * to go back to the "for" to interpret it. Likewise * for a buffer name. */ if ((xisdigit(c) && c!='0') || c == '"') { ungetkey(c); goto looptop; } if (!value(REMAP)) { c = op; break; } if (++maphopcnt > 256) error(catgets(catd, 1, 225, "Infinite macro loop")); } while (c != op); /* * Begin to build an image of this command for possible * later repeat in the buffer workcmd. It will be copied * to lastcmd by the routine setLAST * if/when completely specified. */ lastcp = workcmd; if (!vglobp) *lastcp++ = c; /* * First level command decode. */ if (c == ATTN) goto case_ATTN; switch (c) { /* * ^L Clear screen e.g. after transmission error. */ /* * ^R Retype screen, getting rid of @ lines. * If in open, equivalent to ^L. * On terminals where the right arrow key sends * ^L we make ^R act like ^L, since there is no * way to get ^L. These terminals (adm31, tvi) * are intelligent so ^R is useless. Soroc * will probably foul this up, but nobody has * one of them. */ case CTRL('l'): case CTRL('r'): if (c == CTRL('l') || (KR && *KR==CTRL('l'))) { vclear(); vdirty(0, vcnt); } if (state != VISUAL) { /* * Get a clean line, throw away the * memory of what is displayed now, * and move back onto the current line. */ vclean(); vcnt = 0; vmoveto(dot, cursor, 0); continue; } vredraw(WTOP); /* * Weird glitch -- when we enter visual * in a very small window we may end up with * no lines on the screen because the line * at the top is too long. This forces the screen * to be expanded to make room for it (after * we have printed @'s ick showing we goofed). */ if (vcnt == 0) vrepaint(cursor); vfixcurs(); continue; /* * $ Escape just cancels the current command * with a little feedback. */ case ESCAPE: beep(); continue; /* * @ Macros. Bring in the macro and put it * in vmacbuf, point vglobp there and punt. */ case '@': c = getesc(); if (c == 0) continue; if (c == '@') c = lastmac; if (xisupper(c)) c = xtolower(c); forbid(!xislower(c)); lastmac = c; vsave(); CATCH char tmpbuf[BUFSIZ]; regbuf(c,tmpbuf,sizeof(vmacbuf)); macpush(tmpbuf, 1); ONERR lastmac = 0; splitw = 0; getDOT(); vrepaint(cursor); continue; ENDCATCH vmacp = vmacbuf; goto reread; /* * . Repeat the last (modifying) open/visual command. */ case '.': /* * Check that there was a last command, and * take its count and named buffer unless they * were given anew. Special case if last command * referenced a numeric named buffer -- increment * the number and go to a named buffer again. * This allows a sequence like "1pu.u.u... * to successively look for stuff in the kill chain * much as one does in EMACS with C-Y and M-Y. */ forbid (lastcmd[0] == 0); if (hadcnt) lastcnt = cnt; if (vreg) lastreg = vreg; else if (xisdigit(lastreg) && lastreg < '9') lastreg++; vreg = lastreg; cnt = lastcnt; hadcnt = lasthad; vglobp = lastcmd; goto reread; /* * ^U Scroll up. A count sticks around for * future scrolls as the scroll amount. * Attempt to hold the indentation from the * top of the screen (in logical lines). * * BUG: A ^U near the bottom of the screen * on a dumb terminal (which can't roll back) * causes the screen to be cleared and then * redrawn almost as it was. In this case * one should simply move the cursor. */ case CTRL('u'): if (hadcnt) vSCROLL = cnt; cnt = vSCROLL; if (state == VISUAL) ind = vcline, cnt += ind; else ind = 0; vmoving = 0; vup(cnt, ind, 1); vnline(NOSTR); continue; /* * ^D Scroll down. Like scroll up. */ case CTRL('d'): #ifdef TRACE if (trace) fprintf(trace, "before vdown in ^D, dot=%d, wdot=%d, dol=%d\n", lineno(dot), lineno(wdot), lineno(dol)); #endif if (hadcnt) vSCROLL = cnt; cnt = vSCROLL; if (state == VISUAL) ind = vcnt - vcline - 1, cnt += ind; else ind = 0; vmoving = 0; vdown(cnt, ind, 1); #ifdef TRACE if (trace) fprintf(trace, "before vnline in ^D, dot=%d, wdot=%d, dol=%d\n", lineno(dot), lineno(wdot), lineno(dol)); #endif vnline(NOSTR); #ifdef TRACE if (trace) fprintf(trace, "after vnline in ^D, dot=%d, wdot=%d, dol=%d\n", lineno(dot), lineno(wdot), lineno(dol)); #endif continue; /* * ^E Glitch the screen down (one) line. * Cursor left on same line in file. */ case CTRL('e'): if (state != VISUAL) continue; if (!hadcnt) cnt = 1; /* Bottom line of file already on screen */ forbid(lineDOL()-lineDOT() <= vcnt-1-vcline); ind = vcnt - vcline - 1 + cnt; vdown(ind, ind, 1); vnline(cursor); continue; /* * ^Y Like ^E but up */ case CTRL('y'): if (state != VISUAL) continue; if (!hadcnt) cnt = 1; forbid(lineDOT()-1<=vcline); /* line 1 already there */ ind = vcline + cnt; vup(ind, ind, 1); vnline(cursor); continue; /* * m Mark position in mark register given * by following letter. Return is * accomplished via ' or `; former * to beginning of line where mark * was set, latter to column where marked. */ case 'm': /* * Getesc is generally used when a character * is read as a latter part of a command * to allow one to hit rubout/escape to cancel * what you have typed so far. These characters * are mapped to 0 by the subroutine. */ c = getesc(); if (c == 0) continue; /* * Markreg checks that argument is a letter * and also maps ' and ` to the end of the range * to allow '' or `` to reference the previous * context mark. */ c = markreg(c); forbid (c == 0); vsave(); names[c - 'a'] = (*dot &~ 01); ncols[c - 'a'] = cursor; anymarks = 1; continue; /* * ^F Window forwards, with 2 lines of continuity. * Count repeats. */ case CTRL('f'): vsave(); if (vcnt > 2) { addr = dot + (vcnt - vcline) - 2 + (cnt-1)*basWLINES; forbid(addr > dol); dot = (line*)addr; vcnt = vcline = 0; } vzop(0, 0, '+'); continue; /* * ^B Window backwards, with 2 lines of continuity. * Inverse of ^F. */ case CTRL('b'): vsave(); if (one + vcline != dot && vcnt > 2) { addr = dot - vcline + 2 - (cnt-1)*basWLINES; forbid (addr <= zero); dot = (line*)addr; vcnt = vcline = 0; } vzop(0, 0, '^'); continue; /* * z Screen adjustment, taking a following character: * z<CR> current line to top * z<NL> like z<CR> * z- current line to bottom * also z+, z^ like ^F and ^B. * A preceding count is line to use rather * than current line. A count between z and * specifier character changes the screen size * for the redraw. * */ case 'z': if (state == VISUAL) { i = vgetcnt(); if (i > 0) vsetsiz(i); c = getesc(); if (c == 0) continue; } vsave(); vzop(hadcnt, cnt, c); continue; /* * Y Yank lines, abbreviation for y_ or yy. * Yanked lines can be put later if no * changes intervene, or can be put in named * buffers and put anytime in this session. */ case 'Y': ungetkey('_'); c = 'y'; break; /* * J Join lines, 2 by default. Count is number * of lines to join (no join operator sorry.) */ case 'J': forbid (dot == dol); if (cnt == 1) cnt = 2; if (cnt > (i = dol - dot + 1)) cnt = i; vsave(); vmacchng(1); setLAST(); cursor = strend(linebuf); vremote(cnt, join, 0); notenam = "join"; vmoving = 0; killU(); vreplace(vcline, cnt, 1); if (!*cursor && cursor > linebuf) cursor += skipleft(linebuf, cursor); if (notecnt == 2) notecnt = 0; vrepaint(cursor); continue; /* * S Substitute text for whole lines, abbrev for c_. * Count is number of lines to change. */ case 'S': ungetkey('_'); c = 'c'; break; /* * O Create a new line above current and accept new * input text, to an escape, there. * A count specifies, for dumb terminals when * slowopen is not set, the number of physical * line space to open on the screen. * * o Like O, but opens lines below. */ case 'O': case 'o': vmacchng(1); voOpen(c, cnt); continue; /* * C Change text to end of line, short for c$. */ case 'C': if (*cursor) { ungetkey('$'), c = 'c'; break; } goto appnd; /* * ~ Switch case of letter under cursor */ case '~': vswitch(cnt); continue; /* * A Append at end of line, short for $a. */ case 'A': operate('$', 1); appnd: c = 'a'; /* fall into ... */ /* * a Appends text after cursor. Text can continue * through arbitrary number of lines. */ case 'a': if (*cursor) { if (state == HARDOPEN) { int c, n; nextc(c, cursor, n); putchar(c); cursor += n; } else cursor += skipright(linebuf, cursor); } goto insrt; /* * I Insert at beginning of whitespace of line, * short for ^i. */ case 'I': operate('^', 1); c = 'i'; /* fall into ... */ /* * R Replace characters, one for one, by input * (logically), like repeated r commands. * * BUG: This is like the typeover mode of many other * editors, and is only rarely useful. Its * implementation is a hack in a low level * routine and it doesn't work very well, e.g. * you can't move around within a R, etc. */ case 'R': /* fall into... */ /* * i Insert text to an escape in the buffer. * Text is arbitrary. This command reminds of * the i command in bare teco. */ case 'i': insrt: /* * Common code for all the insertion commands. * Save for redo, position cursor, prepare for append * at command and in visual undo. Note that nothing * is doomed, unless R when all is, and save the * current line in a the undo temporary buffer. */ vmacchng(1); setLAST(); vcursat(cursor); prepapp(); vnoapp(); doomed = c == 'R' ? 10000 : 0; if(FIXUNDO) vundkind = VCHNG; vmoving = 0; CP(vutmp, linebuf); /* * If this is a repeated command, then suppress * fake insert mode on dumb terminals which looks * ridiculous and wastes lots of time even at 9600B. */ if (vglobp) hold = HOLDQIK; vappend(c, cnt, 0); continue; /* * ^? An attention, normally a ^?, just beeps. * If you are a vi command within ex, then * two ATTN's will drop you back to command mode. */ case_ATTN: beep(); if (initev || peekkey() != ATTN) continue; /* fall into... */ /* * ^\ A quit always gets command mode. */ case QUIT: /* * Have to be careful if we were called * g/xxx/vi * since a return will just start up again. * So we simulate an interrupt. */ if (inglobal) onintr(SIGINT); /* fall into... */ #ifdef notdef /* * q Quit back to command mode, unless called as * vi on command line in which case dont do it */ case 'q': /* quit */ if (initev) { vsave(); CATCH error(catgets(catd, 1, 226, "Q gets ex command mode, :q leaves vi")); ENDCATCH splitw = 0; getDOT(); vrepaint(cursor); continue; } #endif /* fall into... */ /* * Q Is like q, but always gets to command mode * even if command line invocation was as vi. */ case 'Q': vsave(); /* * If we are in the middle of a macro, throw away * the rest and fix up undo. * This code copied from getbr(). */ if (vmacp) { vmacp = 0; if (inopen == -1) /* don't screw up undo for esc esc */ vundkind = VMANY; inopen = 1; /* restore old setting now that macro done */ } return; /* * ZZ Like :x */ case 'Z': forbid(getkey() != 'Z'); oglobp = globp; globp = "x"; vclrech(0); goto gogo; /* * P Put back text before cursor or before current * line. If text was whole lines goes back * as whole lines. If part of a single line * or parts of whole lines splits up current * line to form many new lines. * May specify a named buffer, or the delete * saving buffers 1-9. * * p Like P but after rather than before. */ case 'P': case 'p': vmoving = 0; #ifdef notdef forbid (!vreg && value(UNDOMACRO) && inopen < 0); #endif /* * If previous delete was partial line, use an * append or insert to put it back so as to * use insert mode on intelligent terminals. */ if (!vreg && DEL[0]) { forbid ((DEL[0] & (QUOTE|TRIM)) == OVERBUF); vglobp = DEL; ungetkey(c == 'p' ? 'a' : 'i'); goto reread; } /* * If a register wasn't specified, then make * sure there is something to put back. */ forbid (!vreg && unddol == dol); /* * If we just did a macro the whole buffer is in * the undo save area. We don't want to put THAT. */ forbid (vundkind == VMANY && undkind==UNDALL); vsave(); vmacchng(1); setLAST(); i = 0; if (vreg && partreg(vreg) || !vreg && pkill[0]) { /* * Restoring multiple lines which were partial * lines; will leave cursor in middle * of line after shoving restored text in to * split the current line. */ i++; if (c == 'p' && *cursor) cursor += skipright(linebuf, cursor); } else { /* * In whole line case, have to back up dot * for P; also want to clear cursor so * cursor will eventually be positioned * at the beginning of the first put line. */ cursor = 0; if (c == 'P') { dot--, vcline--; c = 'p'; } } killU(); /* * The call to putreg can potentially * bomb since there may be nothing in a named buffer. * We thus put a catch in here. If we didn't and * there was an error we would end up in command mode. */ addr = dol; /* old dol */ CATCH vremote(1, vreg ? putreg : put, vreg); ONERR if (vreg == -1) { splitw = 0; if (op == 'P') dot++, vcline++; goto pfixup; } ENDCATCH splitw = 0; nlput = dol - addr + 1; if (!i) { /* * Increment undap1, undap2 to make up * for their incorrect initialization in the * routine vremote before calling put/putreg. */ if (FIXUNDO) undap1++, undap2++; vcline++; nlput--; /* * After a put want current line first line, * and dot was made the last line put in code * run so far. This is why we increment vcline * above and decrease dot here. */ dot -= nlput - 1; } #ifdef TRACE if (trace) fprintf(trace, "vreplace(%d, %d, %d), undap1=%d, undap2=%d, dot=%d\n", vcline, i, nlput, lineno(undap1), lineno(undap2), lineno(dot)); #endif vreplace(vcline, i, nlput); if (state != VISUAL) { /* * Special case in open mode. * Force action on the screen when a single * line is put even if it is identical to * the current line, e.g. on YP; otherwise * you can't tell anything happened. */ vjumpto(dot, cursor, '.'); continue; } pfixup: vrepaint(cursor); vfixcurs(); continue; /* * ^^ Return to previous file. * Like a :e #, and thus can be used after a * "No Write" diagnostic. */ case CTRL('^'): forbid (hadcnt); vsave(); ckaw(); oglobp = globp; if (value(AUTOWRITE)) globp = "e! #"; else globp = "e #"; goto gogo; /* * ^] Takes word after cursor as tag, and then does * tag command. Read ``go right to''. */ case CTRL(']'): grabtag(); oglobp = globp; globp = "tag"; goto gogo; /* * & Like :& */ case '&': oglobp = globp; globp = "&"; goto gogo; /* * ^G Bring up a status line at the bottom of * the screen, like a :file command. * * BUG: Was ^S but doesn't work in cbreak mode */ case CTRL('g'): oglobp = globp; globp = "file"; gogo: addr = dot; vsave(); goto doinit; #ifdef SIGTSTP /* * ^Z: suspend editor session and temporarily return * to shell. Only works with Berkeley/IIASA process * control in kernel. */ case CTRL('z'): forbid(dosusp == 0 || !ldisc); vsave(); oglobp = globp; globp = "stop"; goto gogo; #endif /* * : Read a command from the echo area and * execute it in command mode. */ case ':': forbid (hadcnt); vsave(); i = tchng; addr = dot; if (readecho(c)) { esave[0] = 0; goto fixup; } getDOT(); /* * Use the visual undo buffer to store the global * string for command mode, since it is idle right now. */ oglobp = globp; CP(vutmp, genbuf+1); globp = vutmp; doinit: esave[0] = 0; fixech(); /* * Have to finagle around not to lose last * character after this command (when run from ex * command mode). This is clumsy. */ d = peekc; ungetchar(0); if (shouldpo) { /* * So after a "Hit return..." ":", we do * another "Hit return..." the next time */ pofix(); shouldpo = 0; } CATCH /* * Save old values of options so we can * notice when they change; switch into * cooked mode so we are interruptible. */ onumber = value(NUMBER); olist = value(LIST); OPline = Pline; OPutchar = Putchar; commands(1, 1); if (dot == zero && dol > zero) dot = one; ONERR copy(esave, vtube[WECHO], TUBECOLS * sizeof *esave); ENDCATCH fixol(); Pline = OPline; Putchar = OPutchar; ungetchar(d); if (globp && tflag < 0) { tflag = 0; goto doinit; } globp = oglobp; /* * If we ended up with no lines in the buffer, make * a line, and don't consider the buffer changed. */ if (dot == zero) { fixzero(); /*synced();*/ } splitw = 0; /* * Special case: did list/number options change? */ if (onumber != value(NUMBER)) setnumb(value(NUMBER)); if (olist != value(LIST)) setlist(value(LIST)); fixup: /* * If a change occurred, other than * a write which clears changes, then * we should allow an undo even if . * didn't move. * * BUG: You can make this wrong by * tricking around with multiple commands * on one line of : escape, and including * a write command there, but its not * worth worrying about. */ if (FIXUNDO && tchng && tchng != i) vundkind = VMANY, cursor = 0; /* * If we are about to do another :, hold off * updating of screen. */ if (vcnt < 0 && Peekkey == ':') { getDOT(); shouldpo = 1; continue; } shouldpo = 0; /* * In the case where the file being edited is * new; e.g. if the initial state hasn't been * saved yet, then do so now. */ if (unddol == truedol) { vundkind = VNONE; Vlines = lineDOL(); if (!inglobal) savevis(); addr = zero; vcnt = 0; if (esave[0] == 0) copy(esave, vtube[WECHO], TUBECOLS * sizeof *esave); } /* * If the current line moved reset the cursor position. */ if (dot != addr) { vmoving = 0; cursor = 0; } /* * If current line is not on screen or if we are * in open mode and . moved, then redraw. */ i = vcline + (dot - addr); if (i < 0 || i >= vcnt && i >= -vcnt || state != VISUAL && dot != addr) { if (state == CRTOPEN) vup1(); if (vcnt > 0) vcnt = 0; vjumpto(dot, (char *) 0, '.'); } else { /* * Current line IS on screen. * If we did a [Hit return...] then * restore vcnt and clear screen if in visual */ vcline = i; if (vcnt < 0) { vcnt = -vcnt; if (state == VISUAL) vclear(); else if (state == CRTOPEN) { vcnt = 0; } } /* * Limit max value of vcnt based on $ */ i = vcline + lineDOL() - lineDOT() + 1; if (i < vcnt) vcnt = i; /* * Dirty and repaint. */ vdirty(0, TLINES); vrepaint(cursor); } /* * If in visual, put back the echo area * if it was clobberred. */ if (state == VISUAL) { int sdc = destcol, sdl = destline; splitw++; vigoto(WECHO, 0); for (i = 0; i < TUBECOLS - 1; i++) { if (esave[i] == 0) break; vputchar(esave[i]); } splitw = 0; vgoto(sdl, sdc); } continue; /* * u undo the last changing command. */ case 'u': vundo(1); continue; /* * U restore current line to initial state. */ case 'U': vUndo(); continue; fonfon: beep(); vmacp = 0; inopen = 1; /* might have been -1 */ continue; } /* * Rest of commands are decoded by the operate * routine. */ operate(c, cnt); } }
DWORD CrystalLineParser::ParseLineIni (DWORD dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems) { if (nLength == 0) return dwCookie & COOKIE_EXT_COMMENT; bool bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; bool bRedefineBlock = true; bool bDecIndex = false; int nIdentBegin = -1; int nPrevI = -1; int I=0; for (I = 0;; nPrevI = I, I = static_cast<int>(::CharNext(pszChars+I) - pszChars)) { if (I == nPrevI) { // CharNext did not advance, so we're at the end of the string // and we already handled this character, so stop break; } if (bRedefineBlock) { int nPos = I; if (bDecIndex) nPos = nPrevI; if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) { DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); } else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) { DEFINE_BLOCK (nPos, COLORINDEX_STRING); } else if (dwCookie & COOKIE_SECTION) { DEFINE_BLOCK (nPos, COLORINDEX_FUNCNAME); } else if (dwCookie & COOKIE_KEY) { DEFINE_BLOCK (nPos, COLORINDEX_KEYWORD); } else { if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (*::CharPrev(pszChars, pszChars + nPos)) && !xisalpha (*::CharNext(pszChars + nPos)))) { DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); } else { DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); bRedefineBlock = true; bDecIndex = true; goto out; } } bRedefineBlock = false; bDecIndex = false; } out: // Can be bigger than length if there is binary data // See bug #1474782 Crash when comparing SQL with with binary data if (I >= nLength || pszChars[I] == 0) break; if (dwCookie & COOKIE_COMMENT) { DEFINE_BLOCK (I, COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; break; } // String constant "...." if (dwCookie & COOKIE_STRING) { if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\'))) { dwCookie &= ~COOKIE_STRING; bRedefineBlock = true; } continue; } // Char constant '..' if (dwCookie & COOKIE_CHAR) { if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\'))) { dwCookie &= ~COOKIE_CHAR; bRedefineBlock = true; } continue; } // Section header [...] if (dwCookie & COOKIE_SECTION) { if (pszChars[I] == ']') { dwCookie &= ~COOKIE_SECTION; bRedefineBlock = true; } continue; } // Key if (dwCookie & COOKIE_KEY) { if (I + 1 < nLength && pszChars[I + 1] == '=') { dwCookie &= ~COOKIE_KEY; bRedefineBlock = true; } continue; } // Normal text if (pszChars[I] == '"') { DEFINE_BLOCK (I, COLORINDEX_STRING); dwCookie |= COOKIE_STRING; continue; } if (pszChars[I] == '\'') { // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') if (!I || !xisalnum (pszChars[nPrevI])) { DEFINE_BLOCK (I, COLORINDEX_STRING); dwCookie |= COOKIE_CHAR; continue; } } if (bFirstChar) { if (pszChars[I] == ';') // Comment { DEFINE_BLOCK (I, COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; break; } else if (pszChars[I] == '[') // Section header [...] { DEFINE_BLOCK (I, COLORINDEX_FUNCNAME); dwCookie |= COOKIE_SECTION; continue; } else // Key { DEFINE_BLOCK (I, COLORINDEX_KEYWORD); dwCookie |= COOKIE_KEY; } if (!xisspace (pszChars[I])) bFirstChar = false; } if (pBuf == nullptr) continue; // We don't need to extract keywords, // for faster parsing skip the rest of loop if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[nPrevI]) && !xisalpha (pszChars[I + 1]))) { if (nIdentBegin == -1) nIdentBegin = I; } else { if (nIdentBegin >= 0) { if (IsIniNumber (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); } bRedefineBlock = true; bDecIndex = true; nIdentBegin = -1; } } } if (nIdentBegin >= 0) { if (IsIniNumber (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); } } dwCookie &= COOKIE_EXT_COMMENT; return dwCookie; }
DWORD CCrystalTextView:: ParseLineFortran (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) { int nLength = GetLineLength (nLineIndex); if (nLength == 0) return dwCookie & COOKIE_EXT_COMMENT; LPCTSTR pszChars = GetLineChars (nLineIndex); bool bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; bool bRedefineBlock = true; bool bDecIndex = false; int nIdentBegin = -1; int nPrevI = -1; int I=0; for (I = 0;; nPrevI = I, I = CharNext(pszChars+I) - pszChars) { if (I == nPrevI) { // CharNext did not advance, so we're at the end of the string // and we already handled this character, so stop break; } if (bRedefineBlock) { int nPos = I; if (bDecIndex) nPos = nPrevI; if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) { DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); } else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) { DEFINE_BLOCK (nPos, COLORINDEX_STRING); } else { if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (*::CharPrev(pszChars, pszChars + nPos)) && !xisalpha (*::CharNext(pszChars + nPos)))) { DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); } else { DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); bRedefineBlock = true; bDecIndex = true; goto out; } } bRedefineBlock = false; bDecIndex = false; } out: // Can be bigger than length if there is binary data // See bug #1474782 Crash when comparing SQL with with binary data if (I >= nLength) break; if (dwCookie & COOKIE_COMMENT) { DEFINE_BLOCK (I, COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; break; } // String constant "...." if (dwCookie & COOKIE_STRING) { if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || pszChars[nPrevI] == '\\' && *::CharPrev(pszChars, pszChars + nPrevI) == '\\'))) { dwCookie &= ~COOKIE_STRING; bRedefineBlock = true; } continue; } // Char constant '..' if (dwCookie & COOKIE_CHAR) { if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || pszChars[nPrevI] == '\\' && *::CharPrev(pszChars, pszChars + nPrevI) == '\\'))) { dwCookie &= ~COOKIE_CHAR; bRedefineBlock = true; } continue; } if (pszChars[I] == '!' || !I && (pszChars[I] == 'C' || pszChars[I] == 'c')) { DEFINE_BLOCK (I, COLORINDEX_COMMENT); dwCookie |= COOKIE_COMMENT; break; } // Normal text if (pszChars[I] == '"') { DEFINE_BLOCK (I, COLORINDEX_STRING); dwCookie |= COOKIE_STRING; continue; } if (pszChars[I] == '\'') { // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') if (!I || !xisalnum (pszChars[nPrevI])) { DEFINE_BLOCK (I, COLORINDEX_STRING); dwCookie |= COOKIE_CHAR; continue; } } if (bFirstChar) { if (!xisspace (pszChars[I])) bFirstChar = false; } if (pBuf == NULL) continue; // We don't need to extract keywords, // for faster parsing skip the rest of loop if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[nPrevI]) && !xisalpha (pszChars[I + 1]))) { if (nIdentBegin == -1) nIdentBegin = I; } else { if (nIdentBegin >= 0) { if (IsFortranKeyword (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); } else if (IsFortranNumber (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); } bRedefineBlock = true; bDecIndex = true; nIdentBegin = -1; } } } if (nIdentBegin >= 0) { if (IsFortranKeyword (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); } else if (IsFortranNumber (pszChars + nIdentBegin, I - nIdentBegin)) { DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); } } if (pszChars[nLength - 1] != '\\' || m_pTextBuffer->IsMBSTrail(nLineIndex, nLength - 1)) dwCookie &= COOKIE_EXT_COMMENT; return dwCookie; }
/* * Convert a floating point number to a string formats 'f', 'e' or 'E'. * The result is placed in buf, and len denotes the length of the string * The sign is returned in the is_negative argument (and is not placed * in buf). */ static char * conv_fp(register char format, register double num, boolean_e add_dp, int precision, bool_int * is_negative, char *buf, int *len) { register char *s = buf; register char *p; int decimal_point; if (format == 'f') p = ap_fcvt(num, precision, &decimal_point, is_negative); else /* either e or E format */ p = ap_ecvt(num, precision + 1, &decimal_point, is_negative); /* * Check for Infinity and NaN */ if (xisalpha(*p)) { *len = strlen(strcpy(buf, p)); *is_negative = FALSE; return (buf); } if (format == 'f') { if (decimal_point <= 0) { *s++ = '0'; if (precision > 0) { *s++ = '.'; while (decimal_point++ < 0) *s++ = '0'; } else if (add_dp) *s++ = '.'; } else { while (decimal_point-- > 0) *s++ = *p++; if (precision > 0 || add_dp) *s++ = '.'; } } else { *s++ = *p++; if (precision > 0 || add_dp) *s++ = '.'; } /* * copy the rest of p, the NUL is NOT copied */ while (*p) *s++ = *p++; if (format != 'f') { char temp[EXPONENT_LENGTH]; /* for exponent conversion */ int t_len; bool_int exponent_is_negative; *s++ = format; /* either e or E */ decimal_point--; if (decimal_point != 0) { p = conv_10((wide_int) decimal_point, FALSE, &exponent_is_negative, &temp[EXPONENT_LENGTH], &t_len); *s++ = exponent_is_negative ? '-' : '+'; /* * Make sure the exponent has at least 2 digits */ if (t_len == 1) *s++ = '0'; while (t_len--) *s++ = *p++; } else { *s++ = '+'; *s++ = '0'; *s++ = '0'; } } *len = s - buf; return (buf); }