Pessoal,
Estamos convertendo um sistema clipper para harbour e nesse sistema acontece aquele problema do nome de variável estar declarada com mais de 10 caracteres e ser usado parte ou todo nome declarado.
Só que no harbour "vê" o nome variável como ela foi declarada, se parte dela foi truncada acontece o erro de variável não encontrada.
Pergunto:
Existe algum utillitário que liste essas variáveis ou todas variáveis que existem nos prg de uma aplicação?
[]´s
Tamanho de Nome de Variável
Moderador: Moderadores
Tamanho de Nome de Variável
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
Tamanho de Nome de Variável
Eu acho que na hora do erro (através do ERRORSYS.PRG) poderia ser gravado em arquivo texto, todas as variáveis através de SAVE TO e depois ler o arquivo .mem e passá-lo para o arquivo txt. Veja um trecho do exemplo que eu utilizo:
Código: Selecionar todos
FWriteLine( nFhandle, 'Vari veis de Mem¢ria:' )
FWriteLine( nFhandle, '--------------------' )
FWriteLine( nFhandle, '' )
Save All Like * to ErrorMem
nMemHandle := Fopen( 'Errormem.mem', 2 )
nMemLength := Fseek( nMemHandle, 0, 2)
Fseek(nMemHandle,0)
nCount := 1
While Fseek(nMemHandle, 0, 1)+1 < nMemLength
nMemWidth:= space(18)
Fread( nMemHandle, @nMemWidth, 18 )
cVarName := Left( nMemWidth, At( Chr(0) , nMemWidth ) -1 )
cVartype := Substr( nMemWidth, 12, 1 )
cVarRec := Bin2w( Right( nMemWidth, 2 ) )
nMemCount:= If( cVarType $ Chr(195)+Chr(204), 14+cVarRec, 22 )
Fseek(nMemHandle, nMemCount, 1)
cTemp := Left(cVarName + Space(10), 10)
cTemp += ' Tipo ' + Type(cVarName)
IF "TELA" $ ALLTRIM(cVarName)
cTemp += ' < Tela > '
ELSE
cTemp += ' ' + If( Type(cVarName) == 'C', ['] + &cVarName + ['], StrValue( &cVarName ))
ENDIF
nBytes := 0
Do Case
Case Type(cVarName) == 'C'
nBytes += ( nLenTemp := Len( &cVarName. ) )
Case Type(cVarName) == 'N'
nBytes += ( nLenTemp := 9 )
Case Type(cVarName) == 'L'
nBytes += ( nLenTemp := 2 )
Case Type(cVarName) == 'D'
nBytes += ( nLenTemp := 9 )
EndCase
Fwrite( nFhandle, Transform(nLenTemp, '9999999') + ' Bytes -> ')
FWriteLine( nFhandle, cTemp )
EndDoUm clip-abraço !
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
-
alxsts
- Colaborador

- Mensagens: 3092
- Registrado em: 12 Ago 2008 15:50
- Localização: São Paulo-SP-Brasil
Tamanho de Nome de Variável
Olá!
Geralmente os linkeditores tem a opção de geração de um mapa de linkedição do aplicativo.
Não sei se vai te servir mas veja este documento dobre o ILink32. Veja a opção /m. Não sei se vai listar todas os símbolos ou somente os considerados públicos.
Geralmente os linkeditores tem a opção de geração de um mapa de linkedição do aplicativo.
Não sei se vai te servir mas veja este documento dobre o ILink32. Veja a opção /m. Não sei se vai listar todas os símbolos ou somente os considerados públicos.
[]´s
Alexandre Santos (AlxSts)
Alexandre Santos (AlxSts)
-
alxsts
- Colaborador

- Mensagens: 3092
- Registrado em: 12 Ago 2008 15:50
- Localização: São Paulo-SP-Brasil
Tamanho de Nome de Variável
Olá!
Lembrando que Save To e Restore From só funcionam com variáveis Public e Private.
Lembrando que Save To e Restore From só funcionam com variáveis Public e Private.
[]´s
Alexandre Santos (AlxSts)
Alexandre Santos (AlxSts)
Tamanho de Nome de Variável
Obrigado,
Pablo e AlxSts,
Na verdade eu queria evitar de enviar para o usuário a aplicação com este tipo erro.
Pensei em um utilitário que varre-se todos os prgs listando todas a variáveis utilizadas em algum txt ou dbf
e analizando este arquivo, rapidamente detectaria o problema evitando transtorno para o usuário.
Porque a grande questão com usuário é o comentário dele: "Mas estava tudo funcionando antes de você mexer!?"
O usuário nem sempre entende as melhorias envolvidas do clipper para harbour ou xharbour.
Pablo e AlxSts,
Na verdade eu queria evitar de enviar para o usuário a aplicação com este tipo erro.
Pensei em um utilitário que varre-se todos os prgs listando todas a variáveis utilizadas em algum txt ou dbf
e analizando este arquivo, rapidamente detectaria o problema evitando transtorno para o usuário.
Porque a grande questão com usuário é o comentário dele: "Mas estava tudo funcionando antes de você mexer!?"
O usuário nem sempre entende as melhorias envolvidas do clipper para harbour ou xharbour.
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Tamanho de Nome de Variável
Pessoal,
Construi um utilitário para listar variáveis em prg com o objetivo de procurar possíveis problemas na migração de clipper para harbour com relação ao tamanho do nome declarado das variáveis (>10) e seu uso.
O utilitário que eu fiz gera um banco com todas variáveis encontradas em um prg e depois lista estas variáveis em um arquivo de saída txt.
O trabalho ainda não é conclusivo e aguarda sugestões de melhorias.
[]´s
BAT COMPILAÇÃO
SCRIPT COMPILAÇÃO
LISTVAR.PRG
Construi um utilitário para listar variáveis em prg com o objetivo de procurar possíveis problemas na migração de clipper para harbour com relação ao tamanho do nome declarado das variáveis (>10) e seu uso.
O utilitário que eu fiz gera um banco com todas variáveis encontradas em um prg e depois lista estas variáveis em um arquivo de saída txt.
O trabalho ainda não é conclusivo e aguarda sugestões de melhorias.
[]´s
BAT COMPILAÇÃO
Código: Selecionar todos
@echo off
set path=d:\harbour32\bin
set hb_compiler=mingw
set HB_DBG_PATH=.\
hbmk2 listvar.hbp -rebuild
Código: Selecionar todos
# ---------------------------------------------------------------------------------
# Script de constru‡Æo do LISTVAR
# ---------------------------------------------------------------------------------
# Autor : Alexandre Simäes
# VersÆo : 1.0
# Data : 30/03/2012
# Harbour : Harbour 3.1.0dev (Rev. 17207) Copyright (c) 1999-2012,
# http://harbour-project.org/
# Compilador: MinGW GNU C 4.6.1 (32-bit)
# ---------------------------------------------------------------------------------
# Nome do Execut vel
# ---------------------------------------------------------------------------------
# -o<outname> Diretiva para nome de arquivo de sa¡da
-olistvar
# ---------------------------------------------------------------------------------
# Bibliotecas
# ---------------------------------------------------------------------------------
# l<libname> Diretiva para linkar com a biblioteca <libname>. <libname> deve omitir
# path, extensÆo e o prefixo 'lib' (… menos que fa‡a parte do nome-de-arquivo).
-lhwgui
-lprocmisc
-lhbgt
-lgtwvg
-lgtwvt
-lhbct
-lhbwin
-lhbnf
-lxhb
-lhbblink
# ---------------------------------------------------------------------------------
# Caminhos dos Includes
# ---------------------------------------------------------------------------------
# -i<p>|-incpath=<p> paths adicionais para pesquisa de arquivos headers
-incpath=D:\HARBOUR32\hwgui\include;
# ---------------------------------------------------------------------------------
# Caminho da Lib HPROC E HGAC
# ---------------------------------------------------------------------------------
# -L<libpath> path adicional para pesquisar por bibliotecas
-Ld:\HARBOUR32\hwgui\lib;
# ---------------------------------------------------------------------------------
# Outros Parƒmetros
# ---------------------------------------------------------------------------------
# .\OBJ\ Grava os arquivos .c e .o na subpasta OBJ
# ---------------------------------------------------------------------------------
# -workdir=<dir> Working directory
# Diretiva para diret¢rio de trabalho da compila‡Æo.
# (default: .hbmk/plat/comp in incremental mode, OS temp
# directory otherwise).
-workdir=.\OBJ\
-gtgui
# ---------------------------------------------------------------------------------
# -[no]head[=<m>] Control source header parsing (in incremental build mode)
# <m> can be: native (uses compiler to extract
# dependencies), full (default, uses simple text parser on
# the whole file), dep, off.
-head=full
# ---------------------------------------------------------------------------------
# /n[<type>] No implicit starting procedure
# <type>: 0=no implicit starting procedure
# 1=no starting procedure at all
# 2=add starting procedure if necessary
-n
# ---------------------------------------------------------------------------------
# -[no]warn[=lev] Define o n¡vel de avisos (warnings) do compilador C
# <lev> pode ser: max, yes, low, no, def (padrão: yes).
-nowarn
# ---------------------------------------------------------------------------------
# -inc Habilita o modo de compilaçao incremental.
-inc
# ---------------------------------------------------------------------------------
# -[no]debug Adicionar/excluir informa‡äes de debug do compilador C.
# Para compilar com Harbour utilize a op‡Æo -b como de
# costume.
-b
# ---------------------------------------------------------------------------------
# -d<diretiva> Diretiva de compila‡Æo para ifdef
-dHARBOUR
# ---------------------------------------------------------------------------------
# -icon=<file> Seta o ícone para o aplicativo. <file> deve possuir um
# formato compat¡vel com a plataforma de destino.
# Diretiva para informar o icone da aplicação.
# ---------------------------------------------------------------------------------
# /u[<file>] Usa comando def set em <arquivo> (ou nenhum)
# Diretiva para carregar arquivo header (.ch) para toda
# aplicação.
#-uE:\Corporativo\Lib\HInclude\stdsmf.ch
#-mt
# ---------------------------------------------------------------------------------
# Prg(s) e Rc(s)
# ---------------------------------------------------------------------------------
listvar.prg
Código: Selecionar todos
#include "inkey.ch"
#include "wvtwin.ch"
#include "hbcompat.ch"
#include "hbgtinfo.ch"
#include "hbgtwvg.ch"
#include "wvgparts.ch"
#include "dbinfo.ch"
#include "fileio.ch"
#include "hbdyn.ch"
#include "common.ch"
#include "directry.ch"
FUNCTION MAIN
TRY
USE LISTVAR ALIAS LISTVAR EXCLUSIVE NEW
ZAP
INDEX ON FONTE+STRZERO(LINHA,6) TAG TESTE TO LISTVAR
SET INDEX TO LISTVAR
USE LISTVARX ALIAS LISTVARX EXCLUSIVE NEW
ZAP
INDEX ON FONTE+STRZERO(LINHA,6) TAG TESTE TO LISTVARX
SET INDEX TO LISTVARX
CATCH
MsgInfo("O dbf LISTVAR.DBF est em uso.")
QUIT
END
DO WHILE .T.
//X1234567890:=""
@00,00 SAY PADC(cTituloJanela,MaxCol()+1) COLOR "B/W*"
@01,00 TO 01,MaxCol() COLOR "B+/N"
aPRG:={}
aDir:=Directory("*.PRG")
ASort( aDir ,,, {|x,y| y[1] > x[1] } )
IF Len(aDir) > 0
AEval(aDir,{|f| AAdd(aPRG,Upper(f[F_NAME]))})
ASort(aPRG)
ENDIF
FOR X:=1 TO Len(aPRG)
FT_FUSE( aPrg[X], FO_READWRITE + FO_SHARED )
FT_FGOTOP()
@02,00 SAY PADR("Processando PRG",40)+": " COLOR "W+/N"
@02,42 SAY PADL(aPRG[X],MaxCol()-42) COLOR "W+/N"
@03,00 SAY PADR("Total de Linhas",40)+": " COLOR "W+/N"
@03,42 SAY PADL(Transform(FT_FLASTRE(),"999999999"),MaxCol()-42) COLOR "W+/N"
aVar:={}
DO WHILE !FT_FEOF()
FT_FSKIP()
ENDDO
FT_FGOTOP()
DO WHILE !FT_FEOF()
cLinha:=Upper(FT_FREADLN())
LISTVARX->(DbAppend())
LISTVARX->Fonte :=aPrg[X]
LISTVARX->Variavel:=cLinha
LISTVARX->Linha :=FT_FRECNO()
lSkip:=.F.
//Retirar coment rios
IF Left(cLinha,2) == "//" .OR. ;
Right(cLinha,2) == "//" .OR. ;
Left(cLinha,1) == "*" .OR. ;
Right(cLinha,1) == "*" .OR. ;
Left(cLinha,1) == "."
FT_FSKIP()
LOOP
ENDIF
cLinha:=LTRIM(cLinha)
cLinha:=RTRIM(cLinha)
cCaracterEspecial:=',+-=:"'
IF HB_AT("FILTER",cLinha) > 0
FT_FSKIP()
LOOP
ENDIF
IF HB_AT("INDEX",cLinha) > 0
FT_FSKIP()
LOOP
ENDIF
IF HB_AT("SET INDEX",cLinha) > 0
FT_FSKIP()
LOOP
ENDIF
IF HB_AT("@",cLinha) > 0
IF HB_AT("SAY",cLinha) > 0
FT_FSKIP()
LOOP
ENDIF
ENDIF
lSkip:=.T.
FOR I:=1 TO Len(cLinha)
IF SubStr(cLinha,I,2) == ":=" .OR. SubStr(cLinha,I,1) == "="
lSkip:=.F.
ENDIF
NEXT
IF lSkip
FT_FSKIP()
LOOP
ENDIF
cCaracterNormal:=""
FOR A:=65 TO 90
cCaracterNormal+=CHR(A)
NEXT
lSair:=.F.
nPosI:=0
nPosF:=0
lPorVirgula:=.T.
IF HB_AT("FOR",cLinha) > 0 .AND. HB_AT("TO",cLinha) > 0
FOR L:=1 TO Len(cLinha)
IF SubStr(cLinha,L,3) == "FOR"
cLinha:=SubStr(cLinha,L+4)
ENDIF
IF SubStr(cLinha,L,1) == "="
cLinha:=SubStr(cLinha,1,L)
ENDIF
NEXT
ENDIF
IF HB_AT("-",cLinha) > 0
FOR L:=1 TO Len(cLinha)
IF SubStr(cLinha,L,1) == "-" .AND. ! SubStr(cLinha,L+1,1) == ">"
cLinha:=SubStr(cLinha,1,L-1)+","+SubStr(cLinha,L+1)
ENDIF
NEXT
ENDIF
IF HB_AT("+",cLinha) > 0
FOR L:=1 TO Len(cLinha)
IF SubStr(cLinha,L,1) == "+"
cLinha:=SubStr(cLinha,1,L-1)+" "+SubStr(cLinha,L+1)
ENDIF
NEXT
ENDIF
nPos:=HB_AT("/",cLinha)
IF nPos > 0
FOR C:=nPos-1 TO 1 STEP -1
IF SubStr(cLinha,C,1) == '"' .OR.;
SubStr(cLinha,C,1) == "'" .OR.;
SubStr(cLinha,C,1) == "="
nPos:=0
EXIT
ENDIF
NEXT
IF nPos > 0
cLinha:=SubStr(cLinha,1,nPos-1)
ENDIF
ENDIF
nPos:=HB_AT("{",cLinha)
IF nPos > 0
IF !SubStr(cLinha,nPos-1,1) == '"' .OR. !SubStr(cLinha,nPos-1,1) == "'"
cLinha:=SubStr(cLinha,1,nPos-1)
ENDIF
ENDIF
FOR K:=Len(cLinha) TO 1 STEP -1
IF RIGHT(cLinha,K) == ";"
lPorVirgula:=.F.
EXIT
ENDIF
NEXT
cVar:=""
//Retirar fun‡Æo ()
nPosIni:=0
nPosFim:=0
I:=1
DO WHILE I < LEN(cLinha)
IF SubStr(cLinha,I,1) == '('
FOR C:=I TO 1 STEP -1
IF SubStr(cLinha,C,1) == '='
nPosIni:=C
EXIT
ENDIF
NEXT
ENDIF
IF SubStr(cLinha,I,1) == ')'
nPosFim:=I
ENDIF
IF nPosIni > 0 .AND. nPosFim > 0
cLinha:=SubStr(cLinha,1,nPosIni)+SubStr(cLinha,nPosFim+1)
nPosIni:=0
nPosFim:=0
ENDIF
I++
ENDDO
I:=1
DO WHILE I < LEN(cLinha)
IF SubStr(cLinha,I,1) == '"' .OR. SubStr(cLinha,I,1) == "'"
nPosFim:=0
nPosIni:=0
FOR C:=1 TO Len(cLinha)
IF SubStr(cLinha,C,1) == '"' .OR. SubStr(cLinha,C,1) == "'"
IF nPosIni = 0
nPosIni:= C
ENDIF
nPosFim:=C
ENDIF
NEXT
IF nPosIni > 1 .AND. nPosFim > 0
cLinha:=SubStr(cLinha,1,nPosIni-1)+SubStr(cLinha,nPosFim+1)
ENDIF
ENDIF
I++
ENDDO
cLinha:=StrTran(cLinha," ")
cLinha+=IF(lPorVirgula,", ","")
I:=1
DO WHILE I < LEN(cLinha)
IF SubStr(cLinha,1,1) $ ',:=()0123456789'
cVar:=""
cLinha:=SubStr(cLinha,I+1)
cLinha:=LTRIM(cLinha)
IF SubStr(cLinha,1,1) == ","
cLinha:=SubStr(cLinha,2)
ENDIF
I:=1
ENDIF
IF SubStr(cLinha,I,1) == "," .AND. I > 1
cVar:=AllTrim(SubStr(cLinha,1,I-1))
cLinha:=SubStr(cLinha,I+1)
cLinha:=LTRIM(cLinha)
I:=1
ENDIF
IF SubStr(cLinha,I,1) == ":" .AND. I > 1
cVar:=AllTrim(SubStr(cLinha,1,I-1))
cLinha:=SubStr(cLinha,I+1)
cLinha:=LTRIM(cLinha)
I:=1
ENDIF
IF SubStr(cLinha,I,1) == "=" .AND. I > 1
cVar:=AllTrim(SubStr(cLinha,1,I-1))
cLinha:=SubStr(cLinha,I+1)
cLinha:=LTRIM(cLinha)
I:=1
ENDIF
IF SubStr(cLinha,I,1) == "(" .AND. I > 1
cVar:=""
cLinha:=SubStr(cLinha,I+1)
cLinha:=LTRIM(cLinha)
I:=1
ENDIF
IF SubStr(cLinha,I,1) == ")" .AND. I > 1
cVar:=""
cLinha:=SubStr(cLinha,I+1)
cLinha:=LTRIM(cLinha)
I:=1
ENDIF
IF !Empty(cVar) .AND. ASCAN(aVar,{|AVAL|AVAL[2] == AllTrim(cVar)}) < 1
AADD(aVar,{aPRG[X],AllTrim(cVar),FT_FRECNO()})
cVar:=""
I:=1
LOOP
ENDIF
I++
ENDDO
FT_FSKIP()
ENDDO
FT_FUSE()
IF Len(aVar) > 0
//aSort( aVar,,,{|x,y| x[1]+x[2] < y[1]+y[2] })
TRY
FOR A:=1 TO Len(aVar)
LISTVAR->(DbAppend())
LISTVAR->Fonte :=aVar[A,1]
LISTVAR->Variavel:=aVar[A,2]
LISTVAR->Linha :=aVar[A,3]
LISTVAR->Maior10 :=IF(Len(AllTrim(aVar[A,2]))>=10,"*",LISTVAR->Maior10)
NEXT
CATCH
MsgInfo("Erro na grava‡„o.","Aten‡„o")
MsgInfo()
END
ENDIF
NEXT
EXIT
ENDDO
SET FILTER TO LISTVAR->MAIOR10 = "*"
LISTVAR->(DbGoTop())
FERASE("Variavel.txt")
cFonte:=""
aVetor:={}
DO WHILE !LISTVAR->(Eof())
cVar:=AllTrim(LISTVAR->Variavel)
IF Len(cVar) >= 10
SELECT LISTVARX
LOCATE FOR HB_AT(cVar,LISTVARX->Variavel) > 0
IF Found()
DO WHILE !LISTVARX->(Eof()) .AND. HB_AT(cVar,LISTVARX->Variavel) > 0
AADD(aVetor,{PADR(LISTVAR->Fonte,15),StrZero(LISTVAR->Linha,6),PADR(cVar,20),PADR(LISTVARX->Fonte,15)+"("+StrZero(LISTVARX->Linha,6)+")",LISTVARX->Variavel})
CONTINUE
ENDDO
ENDIF
ENDIF
LISTVAR->(DbSkip())
ENDDO
IF Len(aVetor) > 0
StrFile("FONTE LINHA VARIAVEL OCORRENCIA","VARIAVEL.TXT",.T.)
StrFile(""+HB_EOL(),"VARIAVEL.TXT",.T.)
StrFile(REPLICATE("-",Len(aVetor[I,1]+" - "+aVetor[I,2]+" - "+aVetor[I,3]+" - "+aVetor[I,4]+" - "+aVetor[I,5])),"VARIAVEL.TXT",.T.)
StrFile(""+HB_EOL(),"VARIAVEL.TXT",.T.)
aSort( aVetor,,,{|a,b| a[1]+a[3] < b[1]+b[3] })
FOR I:=1 TO Len(aVetor)
StrFile(aVetor[I,1]+" - "+aVetor[I,2]+" - "+aVetor[I,3]+" - "+aVetor[I,4]+" - "+aVetor[I,5],"VARIAVEL.TXT",.T.)
StrFile(""+HB_EOL(),"VARIAVEL.TXT",.T.)
NEXT
ENDIF
RETURN Nil
INIT FUNCTION AppSetup()
REQUEST HB_LANG_PT
REQUEST HB_CODEPAGE_PT850
REQUEST HB_GT_GUI_DEFAULT
REQUEST HB_GT_WVG
REQUEST HB_GT_WVT
REQUEST HB_GT_WGU
HB_LANGSELECT("PT")
HB_CDPSELECT( "PT850" )
SET(_SET_DBFLOCKSCHEME,DB_DBFLOCK_DEFAULT)
SETMODE(25,80)
REQUEST DBFCDX
RddSetDefault("DBFCDX")
IniciaJanela()
RETURN Nil
FUNCTION IniciaJanela(nLi,nCi,nLf,nCf)
LOCAL oCrt
PUBLIC cTituloJanela:="ListVar - Listar Vari veis de PRG"
DEFAULT nLi TO 0,;
nCi TO 0,;
nLf TO MaxRow(),;
nCf TO MaxCol()
oCrt := WvgCrt():New( , , { nLi,nCi }, { nLf,nCf}, , .T. )
oCrt:lModal := .F.
oCrt:icon := "P:\GERAL\HARBOUR\HARB_WIN.ICO"
oCrt:create()
oCrt:resizable :=.F.
WVT_SetFont("Lucida Console")
WVT_SetTitle(cTituloJanela)
WVT_SetAltF4Close(.F. )
HB_gtInfo( HB_GTI_SPEC, HB_GTS_WNDSTATE, HB_GTS_WS_MAXIMIZED )
RETURN Nil
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)