Imprime o hash do cabeçalho.
authorThadeu Lima de Souza Cascardo <cascardo@cascardo.eti.br>
Sun, 9 Aug 2015 00:43:35 +0000 (21:43 -0300)
committerThadeu Lima de Souza Cascardo <cascardo@cascardo.eti.br>
Sun, 9 Aug 2015 00:43:35 +0000 (21:43 -0300)
Utiliza uma lista para guardar as linhas temporariamente, altera o
cabeçalho para incluir o hash e recalcula o campo de controle, com o
prefixo do nome de arquivo em formato DOS (8.3), e imprime as linhas no
arquivo.

lib/gera.c

index 828c9ed..0bf0304 100644 (file)
@@ -558,7 +558,7 @@ static void update_hash(struct declaracao *dec, char *buf, size_t len)
        }
 }
 
-static int wrap(gera_linha fn, struct declaracao *dec, FILE *f)
+static int wrap(gera_linha fn, struct declaracao *dec, struct list *l)
 {
        FILE *m;
        char *buf = NULL;
@@ -584,9 +584,21 @@ static int wrap(gera_linha fn, struct declaracao *dec, FILE *f)
                dec->linhas[linha]++;
        }
        update_hash(dec, buf, bsize);
-       fwrite(buf, bsize, 1, f);
-       free(buf);
-       return 0;
+       return list_add(&l, buf);
+}
+
+static void insert_hash(struct declaracao *dec, char *irpf)
+{
+       uLong c = crc32(0L, NULL, 0);
+       char cpf[13];
+       char crc[11];
+       snprintf(cpf, 13, "%-8.8s.DEC", dec->cpf);
+       c = crc32(c, cpf, 12);
+       snprintf(crc, 11, "%010ld", dec->hash);
+       memcpy(irpf + 101, crc, 10);
+       c = crc32(c, irpf, strlen(irpf) - 12);
+       snprintf(crc, 11, "%010ld", c);
+       memcpy(irpf + strlen(irpf) - 12, crc, 10);
 }
 
 static int gera(struct declaracao *dec, char *filename)
@@ -598,42 +610,48 @@ static int gera(struct declaracao *dec, char *filename)
        struct isento *isento;
        struct pagamento *pagamento;
        struct bem *bem;
+       struct list *linhas;
+       char *buf;
+
+       linhas = list_new();
+       if (!linhas)
+               return -ENOMEM;
 
        dec->hash = crc32(0L, NULL, 0);
        dec->rhash = crc32(0L, NULL, 0);
 
-#define W(fn, dec, f) \
+#define W(fn) \
        do { \
-               r = wrap(fn, dec, f); \
+               r = wrap(fn, dec, linhas); \
                if (r < 0) \
                        goto out; \
        } while (0);
 
        f = fopen(filename, "w");
        if (!f)
-               return -errno;
+               goto out_file;
        memset(dec->linhas, 0, sizeof(dec->linhas));
-       W(gera_header, dec, f);
-       W(gera_contribuinte, dec, f);
+       W(gera_header);
+       W(gera_contribuinte);
        if (dec->tipo == COMPLETA) {
-               W(gera_completa, dec, f);
-               W(gera_totais_completa, dec, f);
+               W(gera_completa);
+               W(gera_totais_completa);
        } else {
-               W(gera_simples, dec, f);
-               W(gera_totais_simples, dec, f);
+               W(gera_simples);
+               W(gera_totais_simples);
        }
        for (i = 0; rendimento = list_get(dec->rendimento, i); i++) {
-               W(gera_rendimento, dec, f);
+               W(gera_rendimento);
        }
 
-       W(gera_isentos, dec, f);
-       W(gera_exclusivos, dec, f);
+       W(gera_isentos);
+       W(gera_exclusivos);
 
        for (i = 0; (pagamento = list_get(dec->pagamentos, i)); i++) {
-               W(gera_pagamento, dec, f);
+               W(gera_pagamento);
        }
        for (i = 0; (bem = list_get(dec->bens, i)); i++) {
-               W(gera_bem, dec, f);
+               W(gera_bem);
        }
 
        /* Rendimentos isentos e com tributação exclusiva */
@@ -643,20 +661,28 @@ static int gera(struct declaracao *dec, char *filename)
                isento = isento_get(dec, codigo, i); \
                if (!isento) \
                        break; \
-               W(fn, dec, f); \
+               W(fn); \
        }
        IW(gera_plr, 96);
        IW(gera_poupanca, 98);
 
-       W(gera_trailler, dec, f);
-       W(gera_reciboheader, dec, f);
-       W(gera_recibodetalhe, dec, f);
-       W(gera_recibotrailler, dec, f);
+       W(gera_trailler);
+       W(gera_reciboheader);
+       W(gera_recibodetalhe);
+       W(gera_recibotrailler);
+
+       insert_hash(dec, list_get(linhas, 0));
+       for (i = 0; (buf = list_get(linhas, i)); i++) {
+               fwrite(buf, strlen(buf), 1, f);
+       }
 
        fclose(f);
+       list_free(linhas, free);
        return 0;
 out:
        fclose(f);
+out_file:
+       list_free(linhas, free);
        return r;
 }