Commit 0fe8634c60cc6cac589951c0b8b8d802f40efbdd

Authored by perry.werneck@gmail.com
1 parent 57ededa0

Atualizando plugin rexx para usar a biblioteca de classes

src/classlib/session.cc
@@ -284,6 +284,102 @@ @@ -284,6 +284,102 @@
284 return str; 284 return str;
285 } 285 }
286 286
  287 + string * session::get_string_at(int row, int col, size_t sz)
  288 + {
  289 + string *str = this->get_text_at(row,col,sz);
  290 +
  291 + if(str)
  292 + return this->get_local_text(str);
  293 +
  294 + return 0;
  295 + }
  296 +
  297 + int session::set_string_at(int row, int col, const char *str)
  298 + {
  299 + if(!str)
  300 + return -1;
  301 +
  302 +#ifdef HAVE_ICONV
  303 + if(conv2Host != (iconv_t)(-1))
  304 + {
  305 + size_t in = strlen(str);
  306 + size_t out = (in << 1);
  307 + char * ptr;
  308 + char * outBuffer = (char *) malloc(out);
  309 + ICONV_CONST char * inBuffer = (ICONV_CONST char *) str;
  310 +
  311 + memset(ptr=outBuffer,0,out);
  312 +
  313 + iconv(conv2Host,NULL,NULL,NULL,NULL); // Reset state
  314 +
  315 + if(iconv(conv2Host,&inBuffer,&in,&ptr,&out) != ((size_t) -1))
  316 + {
  317 + int rc = this->set_text_at(row,col,outBuffer);
  318 + free(outBuffer);
  319 + return rc;
  320 + }
  321 +
  322 + free(outBuffer);
  323 + }
  324 +#endif // HAVE_ICONV
  325 +
  326 + return this->set_text_at(row,col,str);
  327 +
  328 + }
  329 +
  330 + int session::input_string(const char *str)
  331 + {
  332 + if(!str)
  333 + return -1;
  334 +
  335 +#ifdef HAVE_ICONV
  336 + if(conv2Host != (iconv_t)(-1))
  337 + {
  338 + size_t in = strlen(str);
  339 + size_t out = (in << 1);
  340 + char * ptr;
  341 + char * outBuffer = (char *) malloc(out);
  342 + ICONV_CONST char * inBuffer = (ICONV_CONST char *) str;
  343 +
  344 + memset(ptr=outBuffer,0,out);
  345 +
  346 + iconv(conv2Host,NULL,NULL,NULL,NULL); // Reset state
  347 +
  348 + if(iconv(conv2Host,&inBuffer,&in,&ptr,&out) != ((size_t) -1))
  349 + {
  350 + int rc = this->emulate_input(outBuffer);
  351 + free(outBuffer);
  352 + return rc;
  353 + }
  354 +
  355 + free(outBuffer);
  356 + }
  357 +#endif // HAVE_ICONV
  358 +
  359 + return this->emulate_input(str);
  360 +
  361 + }
  362 +
  363 + int session::cmp_string_at(int row, int col, const char *text)
  364 + {
  365 + string * str = get_3270_text(new string(text));
  366 + int rc = cmp_text_at(row,col,str->c_str());
  367 + delete str;
  368 + return rc;
  369 + }
  370 +
  371 + int session::wait_for_string_at(int row, int col, const char *key, int timeout)
  372 + {
  373 + string * str = get_3270_text(new string(key));
  374 + int rc = wait_for_text_at(row,col,str->c_str(),timeout);
  375 + delete str;
  376 + return rc;
  377 + }
  378 +
  379 + string * session::get_string(int baddr, size_t len)
  380 + {
  381 + return get_local_text(get_text(baddr,len));
  382 + }
287 383
288 } 384 }
289 385
src/include/pw3270/class.h
@@ -112,12 +112,18 @@ @@ -112,12 +112,18 @@
112 virtual int wait(int seconds) = 0; 112 virtual int wait(int seconds) = 0;
113 virtual int iterate(bool wait = true) = 0; 113 virtual int iterate(bool wait = true) = 0;
114 114
  115 + virtual string * get_text(int baddr, size_t len) = 0;
115 virtual string * get_text_at(int row, int col, size_t sz) = 0; 116 virtual string * get_text_at(int row, int col, size_t sz) = 0;
116 virtual int set_text_at(int row, int col, const char *str) = 0; 117 virtual int set_text_at(int row, int col, const char *str) = 0;
117 - virtual string * get_text(int baddr, size_t len) = 0;  
118 virtual int cmp_text_at(int row, int col, const char *text) = 0; 118 virtual int cmp_text_at(int row, int col, const char *text) = 0;
119 virtual int wait_for_text_at(int row, int col, const char *key, int timeout); 119 virtual int wait_for_text_at(int row, int col, const char *key, int timeout);
120 120
  121 + string * get_string(int baddr, size_t len);
  122 + string * get_string_at(int row, int col, size_t sz);
  123 + int set_string_at(int row, int col, const char *str);
  124 + int cmp_string_at(int row, int col, const char *text);
  125 + int wait_for_string_at(int row, int col, const char *key, int timeout);
  126 +
121 virtual int set_cursor_position(int row, int col) = 0; 127 virtual int set_cursor_position(int row, int col) = 0;
122 virtual int set_cursor_addr(int addr) = 0; 128 virtual int set_cursor_addr(int addr) = 0;
123 virtual int get_cursor_addr(void) = 0; 129 virtual int get_cursor_addr(void) = 0;
@@ -129,6 +135,7 @@ @@ -129,6 +135,7 @@
129 virtual int pakey(int key) = 0; 135 virtual int pakey(int key) = 0;
130 136
131 virtual int emulate_input(const char *str) = 0; 137 virtual int emulate_input(const char *str) = 0;
  138 + int input_string(const char *str);
132 139
133 virtual int get_field_start(int baddr = -1) = 0; 140 virtual int get_field_start(int baddr = -1) = 0;
134 virtual int get_field_len(int baddr = -1) = 0; 141 virtual int get_field_len(int baddr = -1) = 0;
src/plugins/rx3270/Makefile.in
@@ -56,10 +56,10 @@ $(BINDBG)/$(PLUGIN_NAME): $(foreach SRC, $(basename $(PLUGIN_SRC)), $(OBJDBG)/$( @@ -56,10 +56,10 @@ $(BINDBG)/$(PLUGIN_NAME): $(foreach SRC, $(basename $(PLUGIN_SRC)), $(OBJDBG)/$(
56 @$(MKDIR) `dirname $@` 56 @$(MKDIR) `dirname $@`
57 @$(CXX) $(DLL_FLAGS) @LDSOFLAGS@ @DBGRPATH@ $(LDFLAGS) -o $@ $^ $(LIBS) $(LIB3270_LIBS) $(GTK_LIBS) $(GLIB_LIBS) $(PW3270_LIBS) 57 @$(CXX) $(DLL_FLAGS) @LDSOFLAGS@ @DBGRPATH@ $(LDFLAGS) -o $@ $^ $(LIBS) $(LIB3270_LIBS) $(GTK_LIBS) $(GLIB_LIBS) $(PW3270_LIBS)
58 58
59 -$(BINDBG)$(DLL_NAME).$(VERSION): $(foreach SRC, $(basename $(EXTAPI_SRC) $(CLASS_SRC)), $(OBJDBG)/$(SRC)@OBJEXT@) 59 +$(BINDBG)$(DLL_NAME).$(VERSION): $(foreach SRC, $(basename $(EXTAPI_SRC)), $(OBJDBG)/$(SRC)@OBJEXT@) $(CLASS_DEBUG_OBJECTS)
60 @echo " CCLD `basename $@`" 60 @echo " CCLD `basename $@`"
61 @$(MKDIR) `dirname $@` 61 @$(MKDIR) `dirname $@`
62 - @$(CXX) $(DLL_FLAGS) $(LDFLAGS) @LDSOFLAGS@ @DBGRPATH@ -o $@ $^ $(LIBS) $(LIB3270_LIBS) 62 + @$(CXX) $(DLL_FLAGS) $(LDFLAGS) @LDSOFLAGS@ @DBGRPATH@ -o $@ $^ $(LIBS) $(LIB3270_LIBS) $(CLASS_LIBS)
63 63
64 #---[ Release Targets ]-------------------------------------------------------- 64 #---[ Release Targets ]--------------------------------------------------------
65 65
@@ -68,10 +68,10 @@ $(BINRLS)/$(PLUGIN_NAME): $(foreach SRC, $(basename $(PLUGIN_SRC)), $(OBJRLS)/$( @@ -68,10 +68,10 @@ $(BINRLS)/$(PLUGIN_NAME): $(foreach SRC, $(basename $(PLUGIN_SRC)), $(OBJRLS)/$(
68 @$(MKDIR) `dirname $@` 68 @$(MKDIR) `dirname $@`
69 $(CXX) $(DLL_FLAGS) @LDSOFLAGS@ $(LDFLAGS) @RLS_LDFLAGS@ -o $@ $^ $(LIBS) $(LIB3270_LIBS) $(GTK_LIBS) $(GLIB_LIBS) $(PW3270_LIBS) 69 $(CXX) $(DLL_FLAGS) @LDSOFLAGS@ $(LDFLAGS) @RLS_LDFLAGS@ -o $@ $^ $(LIBS) $(LIB3270_LIBS) $(GTK_LIBS) $(GLIB_LIBS) $(PW3270_LIBS)
70 70
71 -$(BINRLS)$(DLL_NAME).$(VERSION): $(foreach SRC, $(basename $(EXTAPI_SRC)), $(OBJRLS)/$(SRC).o) 71 +$(BINRLS)$(DLL_NAME).$(VERSION): $(foreach SRC, $(basename $(EXTAPI_SRC)), $(OBJRLS)/$(SRC).o) $(CLASS_RELEASE_OBJECTS)
72 @echo " CCLD `basename $@`" 72 @echo " CCLD `basename $@`"
73 @$(MKDIR) `dirname $@` 73 @$(MKDIR) `dirname $@`
74 - $(CXX) $(DLL_FLAGS) @LDSOFLAGS@ $(LDFLAGS) @RLS_LDFLAGS@ -o $@ $^ $(LIBS) $(LIB3270_LIBS) 74 + $(CXX) $(DLL_FLAGS) @LDSOFLAGS@ $(LDFLAGS) @RLS_LDFLAGS@ -o $@ $^ $(LIBS) $(LIB3270_LIBS) $(CLASS_LIBS)
75 75
76 install: 76 install:
77 @$(MKDIR) $(DESTDIR)$(libdir)/$(PACKAGE_NAME)-plugin 77 @$(MKDIR) $(DESTDIR)$(libdir)/$(PACKAGE_NAME)-plugin
@@ -84,7 +84,3 @@ install: @@ -84,7 +84,3 @@ install:
84 @$(MKDIR) $(DESTDIR)$(REXX_HOME) 84 @$(MKDIR) $(DESTDIR)$(REXX_HOME)
85 @$(INSTALL_DATA) rx3270.cls $(DESTDIR)$(REXX_HOME) 85 @$(INSTALL_DATA) rx3270.cls $(DESTDIR)$(REXX_HOME)
86 86
87 -$(DEBDIR)/$(MODULE_NAME).install: Makefile  
88 - @$(MKDIR) `dirname $@`  
89 - @rm -f $@  
90 - @echo $(libdir)/$(PACKAGE_NAME)-plugins/$(MODULE_NAME).so > $@  
src/plugins/rx3270/rexx_methods.cc
@@ -126,7 +126,7 @@ RexxMethod1(logical_t, rx3270_method_is_connected, CSELF, sessionPtr) @@ -126,7 +126,7 @@ RexxMethod1(logical_t, rx3270_method_is_connected, CSELF, sessionPtr)
126 return false; 126 return false;
127 return hSession->is_connected(); 127 return hSession->is_connected();
128 } 128 }
129 - catch(std::exception e) 129 + catch(std::exception &e)
130 { 130 {
131 context->RaiseException1(Rexx_Error_Application_error,context->NewStringFromAsciiz(e.what())); 131 context->RaiseException1(Rexx_Error_Application_error,context->NewStringFromAsciiz(e.what()));
132 } 132 }
@@ -200,84 +200,71 @@ RexxMethod2(int, rx3270_method_pakey, CSELF, sessionPtr, int, key) @@ -200,84 +200,71 @@ RexxMethod2(int, rx3270_method_pakey, CSELF, sessionPtr, int, key)
200 200
201 RexxMethod4(RexxStringObject, rx3270_method_get_text_at, CSELF, sessionPtr, int, row, int, col, int, sz) 201 RexxMethod4(RexxStringObject, rx3270_method_get_text_at, CSELF, sessionPtr, int, row, int, col, int, sz)
202 { 202 {
203 - #warning Reimplementar  
204 -/*  
205 - session * hSession = (session *) sessionPtr;  
206 203
207 - if(hSession) 204 + try
208 { 205 {
209 - char * str = session->get_text_at(row,col,sz); 206 + session * hSession = (session *) sessionPtr;
  207 + string * str = hSession->get_string_at(row,col,sz);
210 208
211 if(str) 209 if(str)
212 { 210 {
213 - char * text = session->get_local_string(str);  
214 - RexxStringObject ret = context->String((CSTRING) text);  
215 - free(str);  
216 - free(text); 211 + RexxStringObject ret = context->String((CSTRING) str->c_str());
  212 + delete str;
217 return ret; 213 return ret;
218 } 214 }
  215 +
219 } 216 }
220 -*/ 217 + catch(std::exception &e)
  218 + {
  219 + context->RaiseException1(Rexx_Error_Application_error,context->NewStringFromAsciiz(e.what()));
  220 + }
  221 +
221 return context->String(""); 222 return context->String("");
222 } 223 }
223 224
224 225
225 RexxMethod4(int, rx3270_method_set_text_at, CSELF, sessionPtr, int, row, int, col, CSTRING, text) 226 RexxMethod4(int, rx3270_method_set_text_at, CSELF, sessionPtr, int, row, int, col, CSTRING, text)
226 { 227 {
227 - #warning Reimplementar  
228 -/*  
229 - rx3270 * session = (rx3270 *) sessionPtr;  
230 -  
231 - if(session) 228 + try
232 { 229 {
233 - char * str = session->get_3270_string(text);  
234 - int rc;  
235 - rc = session->set_text_at(row,col,str);  
236 - free(str);  
237 - return rc; 230 + session * hSession = (session *) sessionPtr;
  231 + return hSession->set_string_at(row,col,text);
238 } 232 }
239 -*/ 233 + catch(std::exception &e)
  234 + {
  235 + context->RaiseException1(Rexx_Error_Application_error,context->NewStringFromAsciiz(e.what()));
  236 + }
  237 +
240 return -1; 238 return -1;
241 } 239 }
242 240
243 RexxMethod2(int, rx3270_method_input_text, CSELF, sessionPtr, CSTRING, text) 241 RexxMethod2(int, rx3270_method_input_text, CSELF, sessionPtr, CSTRING, text)
244 { 242 {
245 -#warning Reimplementar  
246 -/*  
247 - rx3270 * session = (rx3270 *) sessionPtr;  
248 -  
249 - if(session) 243 + try
  244 + {
  245 + session * hSession = (session *) sessionPtr;
  246 + return hSession->input_string(text);
  247 + }
  248 + catch(std::exception &e)
250 { 249 {
251 - char * str = session->get_3270_string(text);  
252 - int rc = session->emulate_input(str);  
253 - free(str);  
254 - return rc; 250 + context->RaiseException1(Rexx_Error_Application_error,context->NewStringFromAsciiz(e.what()));
255 } 251 }
256 -*/ 252 +
257 return -1; 253 return -1;
  254 +
258 } 255 }
259 256
260 RexxMethod4(int, rx3270_method_cmp_text_at, CSELF, sessionPtr, int, row, int, col, CSTRING, key) 257 RexxMethod4(int, rx3270_method_cmp_text_at, CSELF, sessionPtr, int, row, int, col, CSTRING, key)
261 { 258 {
262 - #warning Reimplementar  
263 -/*  
264 - int rc = 0;  
265 - rx3270 * session = (rx3270 *) sessionPtr;  
266 -  
267 - if(session) 259 + try
268 { 260 {
269 - char * str = session->get_text_at(row,col,strlen(key));  
270 - if(str)  
271 - {  
272 - char * text = session->get_3270_string(key);  
273 - rc = strcasecmp(str,text);  
274 - free(text);  
275 - }  
276 - free(str); 261 + session * hSession = (session *) sessionPtr;
  262 + return hSession->cmp_string_at(row,col,key);
  263 + }
  264 + catch(std::exception &e)
  265 + {
  266 + context->RaiseException1(Rexx_Error_Application_error,context->NewStringFromAsciiz(e.what()));
277 } 267 }
278 - return rc;  
279 -*/  
280 -  
281 return -1; 268 return -1;
282 } 269 }
283 270
@@ -363,64 +350,67 @@ RexxMethod3(int, rx3270_method_set_option, CSELF, sessionPtr, CSTRING, name, int @@ -363,64 +350,67 @@ RexxMethod3(int, rx3270_method_set_option, CSELF, sessionPtr, CSTRING, name, int
363 350
364 RexxMethod4(logical_t, rx3270_method_test, CSELF, sessionPtr, CSTRING, key, int, row, int, col) 351 RexxMethod4(logical_t, rx3270_method_test, CSELF, sessionPtr, CSTRING, key, int, row, int, col)
365 { 352 {
366 - #warning Reimplementar  
367 -/*  
368 - session * hSession = (session *) sessionPtr;  
369 -  
370 - if(!hSession)  
371 - return false; 353 + try
  354 + {
  355 + session * hSession = (session *) sessionPtr;
372 356
373 - if(!hSession->is_ready())  
374 - hSession->iterate(false); 357 + if(!hSession->is_ready())
  358 + hSession->iterate(false);
375 359
376 - if(hSession->is_ready())  
377 - {  
378 - bool rc = false;  
379 - char * str = hSession->get_text_at(row,col,strlen(key));  
380 - if(str) 360 + if(hSession->is_ready())
381 { 361 {
382 - char * text = hSession->get_3270_string(key);  
383 - rc = (strcasecmp(str,text) == 0);  
384 - free(text); 362 + bool rc = false;
  363 + string * str = hSession->get_string_at(row,col,strlen(key));
  364 + if(str)
  365 + rc = (strcasecmp(str->c_str(),key) == 0);
  366 + delete str;
  367 + return rc;
385 } 368 }
386 - free(str);  
387 - return rc; 369 +
  370 + }
  371 + catch(std::exception &e)
  372 + {
  373 + context->RaiseException1(Rexx_Error_Application_error,context->NewStringFromAsciiz(e.what()));
388 } 374 }
389 -*/ 375 +
390 return false; 376 return false;
391 } 377 }
392 378
393 RexxMethod5(int, rx3270_method_wait_for_text_at, CSELF, sessionPtr, int, row, int, col, CSTRING, key, int, timeout) 379 RexxMethod5(int, rx3270_method_wait_for_text_at, CSELF, sessionPtr, int, row, int, col, CSTRING, key, int, timeout)
394 { 380 {
395 - #warning Reimplementar  
396 -/*  
397 - rx3270 * hSession = (rx3270 *) sessionPtr; 381 + try
  382 + {
  383 + session * hSession = (session *) sessionPtr;
  384 + return hSession->wait_for_string_at(row,col,key,timeout);
  385 +
  386 + }
  387 + catch(std::exception &e)
  388 + {
  389 + context->RaiseException1(Rexx_Error_Application_error,context->NewStringFromAsciiz(e.what()));
  390 + }
398 391
399 - if(hSession)  
400 - return hSession->wait_for_text_at(row,col,key,timeout);  
401 -*/  
402 return -1; 392 return -1;
403 } 393 }
404 394
405 RexxMethod3(RexxStringObject, rx3270_method_get_text, CSELF, sessionPtr, OPTIONAL_int, baddr, OPTIONAL_int, sz) 395 RexxMethod3(RexxStringObject, rx3270_method_get_text, CSELF, sessionPtr, OPTIONAL_int, baddr, OPTIONAL_int, sz)
406 { 396 {
407 - #warning Reimplementar  
408 -/*  
409 - rx3270 * hSession = (rx3270 *) sessionPtr;  
410 -  
411 - if(hSession) 397 + try
412 { 398 {
413 - char *str = hSession->get_text(baddr,sz > 0 ? sz : -1); 399 + session * hSession = (session *) sessionPtr;
  400 + string * str = hSession->get_string(baddr,sz > 0 ? sz : -1);
  401 +
414 if(str) 402 if(str)
415 { 403 {
416 - char * text = hSession->get_local_string(str);  
417 - RexxStringObject ret = context->String((CSTRING) text);  
418 - free(str);  
419 - free(text); 404 + RexxStringObject ret = context->String((CSTRING) str->c_str());
  405 + delete str;
420 return ret; 406 return ret;
421 } 407 }
422 } 408 }
423 -*/ 409 + catch(std::exception &e)
  410 + {
  411 + context->RaiseException1(Rexx_Error_Application_error,context->NewStringFromAsciiz(e.what()));
  412 + }
  413 +
424 return context->String(""); 414 return context->String("");
425 } 415 }
426 416
@@ -456,41 +446,37 @@ RexxMethod2(int, rx3270_method_get_next_unprotected, CSELF, sessionPtr, OPTIONAL @@ -456,41 +446,37 @@ RexxMethod2(int, rx3270_method_get_next_unprotected, CSELF, sessionPtr, OPTIONAL
456 446
457 RexxMethod1(RexxStringObject, rx3270_method_get_selection, CSELF, sessionPtr) 447 RexxMethod1(RexxStringObject, rx3270_method_get_selection, CSELF, sessionPtr)
458 { 448 {
459 - #warning Reimplementar  
460 -/*  
461 - session * hSession = (session *) sessionPtr;  
462 -  
463 - if(hSession) 449 + try
464 { 450 {
465 - char *str = hSession->get_copy(); 451 + string *str = ((session *) sessionPtr)->get_copy();
  452 +
466 if(str) 453 if(str)
467 { 454 {
468 - char * text = hSession->get_local_string(str);  
469 - RexxStringObject ret = context->String((CSTRING) text);  
470 - free(str);  
471 - free(text); 455 + RexxStringObject ret = context->String((CSTRING) str->c_str());
  456 + delete str;
472 return ret; 457 return ret;
473 } 458 }
  459 +
474 } 460 }
475 -*/ 461 + catch(std::exception &e)
  462 + {
  463 + context->RaiseException1(Rexx_Error_Application_error,context->NewStringFromAsciiz(e.what()));
  464 + }
  465 +
476 return context->String(""); 466 return context->String("");
477 } 467 }
478 468
479 RexxMethod2(int, rx3270_method_set_selection, CSELF, sessionPtr, CSTRING, text) 469 RexxMethod2(int, rx3270_method_set_selection, CSELF, sessionPtr, CSTRING, text)
480 { 470 {
481 - #warning Reimplementar  
482 -/*  
483 - rx3270 * session = (rx3270 *) sessionPtr;  
484 -  
485 - if(session) 471 + try
486 { 472 {
487 - char * str = session->get_3270_string(text);  
488 - int rc;  
489 - rc = session->set_copy(str);  
490 - free(str);  
491 - return rc; 473 + return ((session *) sessionPtr)->set_copy(text);
492 } 474 }
493 -*/ 475 + catch(std::exception &e)
  476 + {
  477 + context->RaiseException1(Rexx_Error_Application_error,context->NewStringFromAsciiz(e.what()));
  478 + }
  479 +
494 return -1; 480 return -1;
495 } 481 }
496 482
@@ -516,15 +502,9 @@ RexxMethod1(RexxStringObject, rx3270_method_get_clipboard, CSELF, sessionPtr) @@ -516,15 +502,9 @@ RexxMethod1(RexxStringObject, rx3270_method_get_clipboard, CSELF, sessionPtr)
516 502
517 RexxMethod2(int, rx3270_method_set_clipboard, CSELF, sessionPtr, CSTRING, text) 503 RexxMethod2(int, rx3270_method_set_clipboard, CSELF, sessionPtr, CSTRING, text)
518 { 504 {
519 - session * hSession = (session *) sessionPtr;  
520 -  
521 - if(hSession)  
522 - return hSession->set_clipboard(text);  
523 -  
524 - return -1; 505 + return ((session *) sessionPtr)->set_clipboard(text);
525 } 506 }
526 507
527 -  
528 RexxMethod5(int, rx3270_method_popup, CSELF, sessionPtr, CSTRING, s_id, CSTRING, title, CSTRING, message, OPTIONAL_CSTRING, det) 508 RexxMethod5(int, rx3270_method_popup, CSELF, sessionPtr, CSTRING, s_id, CSTRING, title, CSTRING, message, OPTIONAL_CSTRING, det)
529 { 509 {
530 LIB3270_NOTIFY id = LIB3270_NOTIFY_INFO; 510 LIB3270_NOTIFY id = LIB3270_NOTIFY_INFO;