1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
48 typedef struct _HashEntry
52 struct _HashEntry* next;
57 HashEntry keyword_storage[100];
59 #define HASHTABLE_SIZE 17
60 HashEntry* keyword_table[HASHTABLE_SIZE];
61 static int hash_init = 0;
63 const char* keywords[] =
65 "break", "case", "char", "const",
66 "continue", "default", "do", "double",
67 "else", "enum", "extern", "float",
68 "for", "goto", "if", "int",
69 "long", "register", "return", "short",
70 "signed", "sizeof", "static", "struct",
71 "switch", "typedef", "union", "unsigned",
72 "void", "volatile", "while", 0
76 inline unsigned calc_hash( const char* text, int len )
80 for( j = 0; j < len; j++ )
83 if( shift >= 32 ) shift -= 32;
84 hash ^= ((unsigned char*)text)[j] << shift;
90 void InitLexer( Lexer* lexer, const char* text )
98 int count[HASHTABLE_SIZE];
99 memset( count, 0, sizeof(count));
100 memset( keyword_table, 0, sizeof( keyword_table));
102 for( i = 0; keywords[i] != 0; i++ )
105 keyword_storage[i].len = len = strlen( keywords[i] );
106 keyword_storage[i].hash = calc_hash( keywords[i], len );
107 keyword_storage[i].str = keywords[i];
108 idx = keyword_storage[i].hash % HASHTABLE_SIZE;
109 keyword_storage[i].next = keyword_table[idx];
110 keyword_table[idx] = keyword_storage + i;
118 HashEntry* find_text( const char* str, int len )
120 unsigned hash = calc_hash( str, len );
121 int idx = hash % HASHTABLE_SIZE;
122 HashEntry* entry = keyword_table[idx];
126 if( entry->hash == hash &&
128 !strncmp( entry->str, str, len )) break;
135 void GetToken( Lexer* lexer, Token* token )
137 const char* text = lexer->text;
138 int pos = lexer->pos;
139 token->type = TOKEN_NORMAL;
141 while( isspace(text[pos])) pos++;
149 case '/': /* end-line comment */
150 token->type = TOKEN_COMMENT;
151 ++pos; while( text[pos] != '\n' && text[pos] != '\0' ) pos++;
154 token->type = TOKEN_COMMENT;
156 while( text[pos] != '\0' )
158 if( text[pos] == '*' && text[pos+1] == '/')
168 case '\0': token->type = TOKEN_END;
171 case '\"': token->type = TOKEN_STRING;
175 if( text[pos] == '\0' || text[pos] == '\"' || text[pos] == '\n' )
177 if( text[pos] == '\\' )
180 if( text[pos] == '\n' ) pos++;
187 if( text[pos] == '\"') pos++;
190 case '\'': token->type = TOKEN_STRING;
194 if( text[pos] == '\0' || text[pos] == '\'' || text[pos] == '\n' )
196 pos += text[pos] == '\\' ? 2 : 1;
198 if( text[pos] == '\'') pos++;
201 if( isalpha( text[pos] ) || text[pos] == '_' )
204 while( isalnum( text[pos] ) || text[pos] == '_' ) pos++;
206 if( find_text( text + token->start, pos - token->start ))
208 token->type = TOKEN_KEYWORD;
211 else if( isdigit(text[pos]) || (text[pos] == '.' && isdigit(text[pos+1])))
214 token->type = TOKEN_NUMBER;
215 pos++; while( isalnum( text[pos])) pos++;
216 if( (text[pos] == '+' || text[pos] == '-') && text[pos-1] == 'e')
218 while( isdigit(text[pos1]) || text[pos1] == '.') pos1++;
219 if( pos1 == pos - 1 )
222 while( isdigit(text[pos])) pos++;
235 ///////////////////////////////////////////////////////////////////////////////
239 int GetTokenFromPos(int pos, Token* tokens, int num)
242 for(i = 1; i < num; i++)
243 if(pos < tokens[i].start) return i -1;
247 int SetMap(char* map, Token* tokens, int num)
250 for(int i = 0; i < num - 1; i++)
251 for(int j = 0; j < tokens[i + 1].start - tokens[i].start; j++)
252 map[tokens[i].start + j] = (char)tokens[i].type;
253 map[tokens[max(0, num - 1)].start] = TOKEN_END;
257 static char* old_text = 0;
258 static char* old_map = 0;
260 int ParseTextBegin(ClientData, Tcl_Interp *interp,
263 Token tokens__[MAX_TOKNS] = { TOKEN_END, 0 };
264 Token* tokens_ = tokens__;
266 int max_num = MAX_TOKNS;
268 Tcl_Eval(interp, "$CVEnv::curframe get 1.0 end");
270 if(old_text) delete old_text;
271 if(old_map) delete old_map;
273 int len = strlen(interp->result);
275 old_text = new char[len + 1];
277 old_map = new char[len + 1];
280 strcpy(old_text, interp->result);
284 Token prev_token = { TOKEN_END, 0 };
286 InitLexer( &lexer, old_text );
291 GetToken( &lexer, &token );
292 if( token.type != prev_token.type )
294 tokens_[num] = token;
300 Token* tokens_tmp = new Token[max_num];
302 for(int i = 0; i < num; i++) tokens_tmp[i] = tokens_[i];
303 if(tokens_ != tokens__) delete tokens_;
304 tokens_ = tokens_tmp;
307 if( token.type == TOKEN_END ) break;
310 SetMap(old_map, tokens_, num);
312 assert(*old_map <= TOKEN_END);
314 if(tokens_ != tokens__) delete tokens_;
319 int ParseTextEnd(ClientData, Tcl_Interp *interp,
322 Token tokens__[MAX_TOKNS] = { TOKEN_END, 0 };
323 Token* tokens_ = tokens__;
325 int max_num = MAX_TOKNS;
327 Tcl_Eval(interp, "$CVEnv::curframe get 1.0 end");
329 int len = strlen(interp->result);
331 char* text = new char[len + 1];
333 char* map = new char[len + 1];
336 strcpy(text, interp->result);
338 if(old_text && !strcmp(text, old_text)) goto end;
341 if(!old_text) {old_text = new char[1]; *old_text = 0;}
342 if(!old_map) {old_map = new char[1]; *old_map = TOKEN_END;}
344 assert(*old_map <= TOKEN_END);
347 Token* tokens = tokens_;
349 Token prev_token = { TOKEN_END, 0 };
351 InitLexer( &lexer, text );
356 GetToken( &lexer, &token );
357 if( token.type != prev_token.type )
359 tokens_[num] = token;
365 Token* tokens_tmp = new Token[max_num];
367 for(int i = 0; i < num; i++) tokens_tmp[i] = tokens_[i];
368 if(tokens_ != tokens__) delete tokens_;
369 tokens_ = tokens_tmp;
372 if( token.type == TOKEN_END ) break;
375 assert(*old_map <= TOKEN_END);
377 int len = strlen(text);
378 int old_len = strlen(old_text);
380 SetMap(map, tokens_, num);
381 // finding first & last changed tokens
384 for(first = 0; map[first] == old_map[first]; first++);
385 for(last = len - 1; map[last] == old_map[max(0, last + (old_len - len))]; last--);
387 if(first > last) swap(first, last);
389 int first_t = GetTokenFromPos(first, tokens_, num);
390 int last_t = GetTokenFromPos(last, tokens_, num);
397 char* normal = new char[len * strlen("\"0.0 + 0000000 chars\" \"0.0 + 0000000 chars\" ")];
398 char* comment = new char[len * strlen("\"0.0 + 0000000 chars\" \"0.0 + 0000000 chars\" ")];
399 char* strng = new char[len * strlen("\"0.0 + 0000000 chars\" \"0.0 + 0000000 chars\" ")];
400 char* keyword = new char[len * strlen("\"0.0 + 0000000 chars\" \"0.0 + 0000000 chars\" ")];
401 char* number = new char[len * strlen("\"0.0 + 0000000 chars\" \"0.0 + 0000000 chars\" ")];
403 assert( normal && comment && strng && keyword && number );
404 strcpy( normal, "$CVEnv::curframe tag add normal " );
405 strcpy( comment, "$CVEnv::curframe tag add comment " );
406 strcpy( strng, "$CVEnv::curframe tag add string " );
407 strcpy( keyword, "$CVEnv::curframe tag add keyword " );
408 strcpy( number, "$CVEnv::curframe tag add number " );
410 sprintf(command, "ClearColors %d %d $CVEnv::curframe", first, last);
411 Tcl_Eval(interp, command);
412 assert(*interp->result == 0);
415 for( int t = first_t; t <=last_t; t++ )
418 sprintf(pos, "\"0.0 + %d chars\" \"0.0 + %d chars\" ", tokens[t].start, tokens[t + 1].start);
419 switch(tokens[t].type)
422 strcat(comment, pos);
428 strcat(keyword, pos);
441 if(strlen(normal) > 34)
443 Tcl_Eval(interp, normal);
444 assert(*interp->result == 0);
446 if(strlen(comment) > 34)
448 Tcl_Eval(interp, comment);
449 assert(*interp->result == 0);
451 if(strlen(strng) > 34)
453 Tcl_Eval(interp, strng);
454 assert(*interp->result == 0);
456 if(strlen(number) > 34)
458 Tcl_Eval(interp, number);
459 assert(*interp->result == 0);
461 if(strlen(keyword) > 34)
463 Tcl_Eval(interp, keyword);
464 assert(*interp->result == 0);
474 if(old_map) delete old_map;
477 if(old_text) delete old_text;
479 if(tokens_ != tokens__) delete tokens_;
483 ///////////////////////////////////////////////////////////////////////////////
487 bool LoadColors(Tcl_Interp *pinterp, const char* colorsfile)
489 int code = Tcl_EvalFile(pinterp, (char*)colorsfile);
496 bool SaveColors(Tcl_Interp *pinterp, const char* colorsfile)
498 FILE* pfile = fopen(colorsfile, "w");
502 fprintf( pfile, "# Custom Colors\n");
503 fprintf( pfile, "set ::EditorTextbg ");
504 fprintf( pfile, "%s\n",Tcl_GetVar(pinterp, "EditorTextbg", TCL_GLOBAL_ONLY));
505 fprintf( pfile, "set ::EditorTextfg ");
506 fprintf( pfile, "%s\n",Tcl_GetVar(pinterp, "EditorTextfg", TCL_GLOBAL_ONLY));
507 fprintf( pfile, "set ::EditorStringfg ");
508 fprintf( pfile, "%s\n",Tcl_GetVar(pinterp, "EditorStringfg", TCL_GLOBAL_ONLY));
509 fprintf( pfile, "set ::EditorNumberfg ");
510 fprintf( pfile, "%s\n",Tcl_GetVar(pinterp, "EditorNumberfg", TCL_GLOBAL_ONLY));
511 fprintf( pfile, "set ::EditorCommentfg ");
512 fprintf( pfile, "%s\n",Tcl_GetVar(pinterp, "EditorCommentfg", TCL_GLOBAL_ONLY));
513 fprintf( pfile, "set ::EditorKeywordfg ");
514 fprintf( pfile, "%s\n",Tcl_GetVar(pinterp, "EditorKeywordfg", TCL_GLOBAL_ONLY));
515 fprintf( pfile, "set ::EditorSelectbg ");
516 fprintf( pfile, "%s\n",Tcl_GetVar(pinterp, "EditorSelectbg", TCL_GLOBAL_ONLY));
517 fprintf( pfile, "set ::EditorSelectfg ");
518 fprintf( pfile, "%s\n",Tcl_GetVar(pinterp, "EditorSelectfg", TCL_GLOBAL_ONLY));
519 fprintf( pfile, "set ::EditorCursorbg ");
520 fprintf( pfile, "%s\n",Tcl_GetVar(pinterp, "EditorCursorbg", TCL_GLOBAL_ONLY));
522 fprintf( pfile, "# Custom Fonts\n");
523 fprintf( pfile, "set ::EditorTextfont \"");
524 fprintf( pfile, "%s\"\n",Tcl_GetVar(pinterp, "EditorTextfont", TCL_GLOBAL_ONLY));
525 fprintf( pfile, "set ::EditorStringfont \"");
526 fprintf( pfile, "%s\"\n",Tcl_GetVar(pinterp, "EditorStringfont", TCL_GLOBAL_ONLY));
527 fprintf( pfile, "set ::EditorNumberfont \"");
528 fprintf( pfile, "%s\"\n",Tcl_GetVar(pinterp, "EditorNumberfont", TCL_GLOBAL_ONLY));
529 fprintf( pfile, "set ::EditorCommentfont \"");
530 fprintf( pfile, "%s\"\n",Tcl_GetVar(pinterp, "EditorCommentfont", TCL_GLOBAL_ONLY));
531 fprintf( pfile, "set ::EditorKeywordfont \"");
532 fprintf( pfile, "%s\"\n",Tcl_GetVar(pinterp, "EditorKeywordfont", TCL_GLOBAL_ONLY));