Um pequeno programa de teste para obter alguns campos de uma declaração.
[cascardo/libreceita.git] / decfile.c
index bfaf1ee..26ef3bc 100644 (file)
--- a/decfile.c
+++ b/decfile.c
@@ -1,5 +1,6 @@
 /*
- *  Copyright (C) 2012-2013  Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
+ *  Copyright (C) 2012-2014  Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
+ *  Copyright (C) 2014  Alexandre Oliva <lxoliva@fsfla.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -83,9 +84,9 @@ static int decfile_parse_header(struct rnet_decfile *decfile)
        if (!buffer)
                return -EINVAL;
        switch (strlen(buffer)) {
-       case 765:
+       case RNET_HEADER_SIZE_2013:
                return parse_header_2013(decfile->header, buffer);
-       case 793:
+       case RNET_HEADER_SIZE_2014:
                return parse_header_2014(decfile->header, buffer);
        default:
                return -EINVAL;
@@ -176,6 +177,7 @@ static int parse_header_2014(struct pmhash *hash, char *buffer)
        char *p = buffer;
        char *key;
        char *val;
+       char *tail;
 
 #define parse(field, sz) \
        r = -ENOMEM; \
@@ -207,6 +209,12 @@ static int parse_header_2014(struct pmhash *hash, char *buffer)
        parse("nome", 60);
        parse("uf", 2);
        parse("hash", 10);
+
+       if (p - buffer != RNET_HEADER_HEAD_2014) {
+               fprintf(stderr, "RNET_HEADER_HEAD_2014 in decfile.h needs to be adjusted to %ti\n", p - buffer);
+               goto out_val;
+       }
+
        parse("in_cert", 1);
        parse("dt_nasc", 8);
        parse("in_comp", 1);
@@ -279,9 +287,35 @@ static int parse_header_2014(struct pmhash *hash, char *buffer)
        parse("nr_conta", 13);
        parse("nr_dv_conta", 2);
        parse("in_dv_conta", 1);
+
+       tail = p;
+
        parse("versaotestpgd", 3);
        parse("controle", 10);
 
+       if (*p++ != '\r') {
+               fprintf(stderr,
+                       "missing CR at the %tith header character\n",
+                       p - buffer);
+               goto out_val;
+       } else if (*p++ != '\n') {
+               fprintf(stderr,
+                       "missing LF at the %tith header character\n",
+                       p - buffer);
+               goto out_val;
+       } else if (*p != 0) {
+               fprintf(stderr,
+                       "missing NUL at the %tith header character\n",
+                       p - buffer);
+               goto out_val;
+       } else if (p - buffer != RNET_HEADER_SIZE_2014) {
+               fprintf(stderr, "RNET_HEADER_SIZE_2014 in decfile.h needs to be adjusted to %ti,\nor parse_header in decfile.c needs updating\n", p - buffer);
+               goto out_val;
+       } else if (p - tail != RNET_HEADER_TAIL_2014) {
+               fprintf(stderr, "RNET_HEADER_TAIL_2014 in decfile.h needs to be adjusted to %ti\n", p - tail);
+               goto out_val;
+       }
+
        return 0;
 out_add:
        free(key);
@@ -297,6 +331,7 @@ static int parse_header_2013(struct pmhash *hash, char *buffer)
        char *p = buffer;
        char *key;
        char *val;
+       char *tail;
 
 #define parse(field, sz) \
        r = -ENOMEM; \
@@ -328,6 +363,12 @@ static int parse_header_2013(struct pmhash *hash, char *buffer)
        parse("nome", 60);
        parse("uf", 2);
        parse("hash", 10);
+
+       if (p - buffer != RNET_HEADER_HEAD_2013) {
+               fprintf(stderr, "RNET_HEADER_HEAD_2013 in decfile.h needs to be adjusted to %ti\n", p - buffer);
+               goto out_val;
+       }
+
        parse("in_cert", 1);
        parse("dt_nasc", 8);
        parse("in_comp", 1);
@@ -395,9 +436,35 @@ static int parse_header_2013(struct pmhash *hash, char *buffer)
        parse("vr_totisentos", 13);
        parse("vr_totexclusivo", 13);
        parse("vr_totpagamentos", 13);
+
+       tail = p;
+
        parse("versaotestpgd", 3);
        parse("controle", 10);
 
+       if (*p++ != '\r') {
+               fprintf(stderr,
+                       "missing CR at the %tith header character\n",
+                       p - buffer);
+               goto out_val;
+       } else if (*p++ != '\n') {
+               fprintf(stderr,
+                       "missing LF at the %tith header character\n",
+                       p - buffer);
+               goto out_val;
+       } else if (*p != 0) {
+               fprintf(stderr,
+                       "missing NUL at the %tith header character\n",
+                       p - buffer);
+               goto out_val;
+       } else if (p - buffer != RNET_HEADER_SIZE_2013) {
+               fprintf(stderr, "RNET_HEADER_SIZE_2013 in decfile.h needs to be adjusted to %ti,\nor parse_header in decfile.c needs updating\n", p - buffer);
+               goto out_val;
+       } else if (p - tail != RNET_HEADER_TAIL_2013) {
+               fprintf(stderr, "RNET_HEADER_TAIL_2013 in decfile.h needs to be adjusted to %ti\n", p - tail);
+               goto out_val;
+       }
+
        return 0;
 out_add:
        free(key);
@@ -430,13 +497,15 @@ static int append_stripped_reg_ctrl(struct rnet_message **message, char *line)
 {
        size_t len;
        struct rnet_message *msg = *message;
+       int growth;
        if (!decfile_reg_is_dec(line))
                return 0;
        len = strlen(line);
        if (len < 12)
                return -EINVAL;
-       if (msg->alen - msg->len < len) {
-               if (rnet_message_expand(message, MAX(msg->len, len)))
+       growth = msg->len + len - 10 - msg->alen;
+       if (growth > 0) {
+               if (rnet_message_expand(message, growth))
                        return -ENOMEM;
                msg = *message;
        }
@@ -484,3 +553,10 @@ char * rnet_decfile_get_header(struct rnet_decfile *decfile)
 {
        return get_header(decfile);
 }
+
+char * rnet_decfile_get_line(struct rnet_decfile *decfile, int i)
+{
+       if (i < decfile->lines_len)
+               return decfile->lines[i];
+       return NULL;
+}