== Registrando alterações

* Comando "svn log": registro técnico/detalhado, por revisão.
* ChangeLog: uma cópia do anterior, mas por data.
* LEIAME: resumo para usuários, limitado às revisões que alteram
  alguma funcionalidade que o usuário interage diretamente (seja no
  programa ou nos arquivos usados).


== Estrutura de caminhos

* aplicacao: dados particulares das declarações ou da lista de
  declarações.
* contrib: scripts ou ferramentas para facilitar contribuições ao
  projeto.
* src/org/fsfla: código fonte principal do projeto IRPF-Livre ou com
  base na versão inicial.
* src/serpro: idem.
* src/srf: idem.
* src/*: outros códigos fonte, geralmente das dependências do
  IRPF-Livre, todos embutidos no projeto do IRPF-Livre.
* jode: código e documentação históricos, que foram usados para obter
  a primeira versão do IRPF-Livre.
* list: listas de arquivos monitorados pelo Makefile.
* res: recursos a serem carregados durante a execução, incluindo as
  tabelas de códigos.


== Atualizando os valores dos percentuais, limites e descontos

Procure pelo texto "NOTE:" no código fonte principal para encontrar os
arquivos que sabemos que geralmente mudam, bem como as referências.
Exemplo usando o GNU Grep:

  grep --exclude-dir='.svn' -R 'NOTE:' 'src/org/fsfla' 'src/serpro' 'src/srf'


== Encontrando partes que talvez precisem de correção

Procure pelo texto "FIXME:" no código fonte principal.  Exemplo usando
o GNU Grep:

  grep --exclude-dir='.svn' -R 'FIXME:' 'src/org/fsfla' 'src/serpro' 'src/srf'


== Atualizando os registros e campos no mapeamento da declaração

1. Extraia o arquivo mapeamentoTxt.xml de dentro do programa
   privativo.

2. Use o script contrib/tirar_ano_anterior_do_mapeamentoTxt.xslt
   contra os mapeamentos do IRPF-Livre e do privativo, mas mande os
   resultados para arquivos novos e diferentes.  Segue um exemplo
   usando o xsltproc e trocando @PRIVATIVO@ pelo caminho do
   mapeamentoTxt.xml do programa privativo, que manda os resultados
   para os arquvios atual-livre.xml e atual-privativo.xml,
   respectivamente:

   xsltproc --output 'atual-livre.xml' 'contrib/tirar_ano_anterior_do_mapeamentoTxt.xslt' 'res/mapeamentoTxt.xml'

   xsltproc --output 'atual-privativo.xml' 'contrib/tirar_ano_anterior_do_mapeamentoTxt.xslt' @PRIVATIVO@

3. Use qualquer comparador de sua escolha, por exemplo, xmldiff:

   xmldiff -f xml -p 'atual-livre.xml' 'atual-privativo.xml' | less -IN +'/diff:'

4. Perceba as diferenças e implemente as mudanças na forma de
   funcionamento do IRPF-Livre, *SEM ALTERAR* o arquivo
   res/mapemeantoTxt.xml (isso será feito mais tarde).

5. Agora use xmllint para pegar apenas o "ano anterior" usando uma
   consulta XPath 1.0 que pega os elementos DeclaracaoTxt com
   "TipoArquivo" igual a "ARQ_IRPFANOANTERIOR". No exemplo a seguir,
   os do mapeamento do IRPF-Livre e do privativo são salvos
   respectivamente em anterior-livre.xml e anterior-privativo.xml,
   novamente trocando @PRIVATIVO@ pelo caminho do mapeamentoTxt.xml do
   programa privativo:

   xmllint --xpath '/Mapeamento/DeclaracaoTXT[@TipoArquivo = "ARQ_IRPFANOANTERIOR"]' --output 'anterior-livre.xml' 'res/mapeamentoTxt.xml'

   xmllint --xpath '/Mapeamento/DeclaracaoTXT[@TipoArquivo = "ARQ_IRPFANOANTERIOR"]' --output 'anterior-privativo.xml' @PRIVATIVO@

6. Perceba as diferenças e implemente as mudanças na forma de
   funcionamento do IRPF-Livre, *SEM ALTERAR* o arquivo
   res/mapemeantoTxt.xml (isso será feito mais tarde).

7. Finalmente, altere o arquivo res/mapeamentoTxt.xml do IRPF-Livre.


== Dicas para encontrar/depurar erros

1. Instale o JDK-headless equivalente ao JRE que você possui, para
   obter o depurador jdb.

2. Adicione ao final da variável JAVAC no arquivo Makefile a opção
   "-g", salve o arquivo e depois recompile o IRPF-Livre.

3. Para facilitar repetir tudo que seja necessário antes da depuração
   real, crie um arquivo ~/.jdbrc.

4. Coloque no arquivo a linha abaixo começando com "sourcepath",
   trocando o caminho ao lado pelo ABSOLUTO/COMPLETO correspondente ao
   diretório "src" do IRPF-Livre.

   sourcepath /caminho/completo/irpf-livre/src

5. Para economizar tempo, aproveite para colocar nas próximas linhas
   quaisquer outros comandos necessários para preparar o jdb, depois
   disso salve o arquivo.

6. Para depurar o IRPF-Livre troque o/a função/alias/script do shell
   criada inicialmente (irpf) por algo parecido com (troque gij pelo
   interpretador Java de sua preferência e @CPF@ pelo do declarante):

   irpf () { gij -agentlib:jdwp=transport=dt_socket,server=y,suspend=y -jar irpf-livre-cl.jar $1 @CPF@; }

7. Para testar, use 'irpf ajuda'. Se tudo deu certo o IRPF-Livre vai
   parar e uma mensagem similar à esta vai aparecer:

   Listening for transport dt_socket at address: @PORTA@

8. Agora o IRPF-Livre está ESPERANDO que você conecte o jdb na porta
   @PORTA@, por isso, em outro terminal, repita o comando abaixo,
   trocando @PORTA@ pelo número na direita da mensagem acima:

   jdb -attach @PORTA@

9. Se na última linha aparecer algo como "main[1]", então você está
   dentro do IRPF-Livre através do jdb. Assumindo que ~/.jdbrc possui
   todos os comandos internos do jdb necessários para preparar o
   ambiente de depuração, rode 'run' para fazer o IRPF-Livre
   funcionar.

O jdb possui comandos internos cuja documentação infelizmente está em
inglês. O "help" é a ajuda que mostra eles, cito alguns exemplos:

* Sair do jdb imediatamente com execução normal do IRPF-Livre:

  exit
  quit

* Parar antes de executar a linha 67 da classe
  serpro.ppgd.irpf.ModeloSimplificado (arquivo
  src/serpro/ppgd/irpf/ModeloSimplificado.java):

  stop at serpro.ppgd.irpf.ModeloDeclaracao:65

* Lista paradas registradas:

  stop

* Mostra em que parte do arquivo fonte o depurador está (só funciona
  se sourcepath estiver corretamente configurado):

  list

* Executar/avaliar/imprimir resultado de algo qualquer em Java:

  eval algo-qualquer-em-java
  print algo-qualquer-em-java

  Dica: se aparecer a mensagem de "Name unknown" ou algo similar, use
  o nome INTEIRO, que inclui todo o caminho da classe

* Outras informações:

  locals (lista variáveis locais)
  classes (lista todas as classes conhecidas)
  dump variavel (mostra algumas propriedades da variável)
  fields classe (campos da classe)
  methods classe (métodos)
  class classe (informações de herança)

* Repete um comando interno do jdb em todas as paradas:

  monitor eval algo-qualquer-em-java

* Dar passos na execução:

  step (executa uma linha inteira sem parar nas funções)
  stepi (idem, mas para nas funções)
  step up (faz tudo sem parar até voltar ao invocador da função)
  next (NÃO EXECUTA uma linha inteira)
  cont (faz tudo até a próxima parada)

* Repetir o comando anterior:

  !!


== Imprimindo

Em tese, tem código que poderia permitir a impressão da declaração e
do recibo, mas não conseguimos fazer funcionar :-(

Acreditamos que o problema seja causado por diferenças de versão entre
as bibliotecas utilizadas no programa original e as que baixamos para
substituí-las.  Infelizmente a Receita Federal se recusa a informar
sequer quais versões dessas bibliotecas Livres foram utilizadas, e
por ora desistimos de descobrir por conta própria.

Se alguma boa alma se animar a arrumar isso (quem sabe nós mesmos),
vamos poder imprimir as declarações e os recibos, se bem que uma
porção de coisas terá de ser atualizada, pois o código de impressão
ainda é de 2007!  Se não, quando alguém pedir a declaração ou o
recibo, a gente imprime o xml ou o par .DEC/.REC mesmo.  Certo?
Afinal, os formatos são (parcialmente) públicos :-)


== Considerações finais sobre o código fonte

Como visto nas seções anteriores, pode ser que algumas partes não
sejam mais utilizadas.  Todavia, estas ainda precisam ser
identificadas.


== Dúvidas sobre como implementar as mudanças

O programa privativo já divergiu bastante do que era em 2007, a base
do nosso, mas ainda há semelhanças importantes na estrutura, então às
vezes é o caso de dar uma espiada no código privativo pra entender o
que precisa ser feito, sem muito receio de infração de direito
autoral, até porque o código reflete e implementa o que está na lei e
nas instruções normativas, e isso é tudo público, como o código
deveria ser.  Pelo que manda a lei, era pra ser Livre também:
https://www.planalto.gov.br/ccivil_03/_ato2019-2022/2020/lei/l14063.htm#art16

Mas enfim, enquanto não cumprem a lei, vamos dando jeito.

Há basicamente duas formas de investigar o código:

- usando javap [-cp @JAR@] -c @CLASSNAME@ e compreendendo o bytecode

- usando procyon e olhando para código Java bastante legível, ainda
que não seja propriamente código fonte:
  PATH=/usr/lib/jvm/java-11-openjdk-amd64/bin:$PATH \
  procyon -o @JAR@.src @JAR@

O IRPF2026, como nos últimos anos e como num aparente acidente em
2007, não tem mais usado ofuscamento do código objeto, como fazia
antes do IRPF-Livre começar e se manteve fazendo por muitos anos.  Tem
trazido até informação de debugging, como nomes de variáveis, linhas
do código fonte.

Com isso, um descompilador como o procyon-decompiler (esse é o nome do
pacote no Trisquel GNU/Linux-libre) tem resultados bastante bons, que
facilitam entender o que precisa ser feito no IRPF-Livre para que se
comporte de maneira equivalente ao privativo.

Todos os arquivos .jar do IRPF2026 são descompilados com sucesso
usando o procyon-decompiler 0.5.36-1 com openjdk-11-jre (mas com
openjdk-25-jre, ele não está funcionando, um método utilizado pelo
procyon foi removido da classe sun.misc.Unsafe).

Até o lib/receitanet-pro-1.32.jar, que ainda usa ofuscamento, é
descompilado quase que integralmente, só o método
'serpro.receitanet.z.a(java.io.RandomAcessFile)', que verifica
assinaturas digitais, não descompila direito e acaba com o bytecode em
comentários e uma exceção em tempo de execução.

Não me surpreenderia se alguém aparecesse com uma versão descompilada
e recompilada, como fizemos em 2007, só que plenamente funcional,
porque agora identificam as versões dos componentes livres de
terceiros que usam, coisa que não conseguimos fizemos em 2007 e que
causou algumas dificuldades, e com licença Livre, não por terem dado
alguma brecha com as licenças, como em 2007, mas porque hoje é o que a
lei manda, só falta cumprirem.
