2 * db: functions to retrieve data from the database file.
4 * The database is a CSV list, each line has the following format
7 * CEP;UF;Cidade;Bairro;Rua
9 * A line is called an entry, each value in the line is called
12 * This file is licensed under the GPLv2 license.
14 * Luiz Fernando N. Capitulino
15 * <lcapitulino@gmail.com>
24 /* eof_info(): return 1 if 'c' is an end of info character,
25 * otherwise return 0. */
26 static int eof_info(FILE *db
, char c
)
28 if (c
== ';' || c
== '\n')
32 /* remove trailing '\n' */
35 fatal("DOS file seems corrupted");
42 /* read_info(): Return the next info from the 'db' file,
43 * aborts program execution on error. */
44 static char *read_info(FILE *db
)
48 info
= read_chars(db
, eof_info
);
50 fatal("didn't read expected EOF from db file");
56 /* read_buf(): read 'len' characters from 'db' file into 'buf',
57 * the characters have to be part of an info (ie, they're
58 * terminated by ';' or '\n') otherwise program execution is
60 static void read_buf(FILE *db
, char *buf
, size_t len
)
65 for (i
= 0; i
< (len
- 1); i
++)
72 fatal("db file is corrupted");
75 /* read_cep(): read CEP info from the 'db' file. */
76 static unsigned int read_cep(FILE *db
)
78 char cep_str
[DB_CEP_LEN
+ 1];
80 read_buf(db
, cep_str
, sizeof(cep_str
));
82 /* XXX: error check */
83 return strtol(cep_str
, NULL
, 10);
86 /* read_uf(): read UF info from the 'db' file. */
87 static void read_uf(FILE *db
, char *uf
)
89 read_buf(db
, uf
, DB_UF_LEN
);
92 /* file_eof(): return 1 if next character from 'db' is EOF,
93 * otherwise return 0. */
94 static int file_eof(FILE *db
)
106 /* db_next_entry(): return the next entry from 'db' file, if
107 * EOF is found return NULL. */
108 struct db_entry
*db_next_entry(FILE *db
)
110 struct db_entry
*entry
;
115 entry
= malloc(sizeof(*entry
));
117 fatal("cannot allocate memory");
119 entry
->cep
= read_cep(db
);
120 read_uf(db
, entry
->uf
);
121 entry
->cidade
= read_info(db
);
122 entry
->bairro
= read_info(db
);
123 entry
->desc
= read_info(db
);
128 /* db_free_entry(): free all the memory allocated by 'entry */
129 void db_free_entry(struct db_entry
**entry
)
131 free((*entry
)->cidade
);
132 free((*entry
)->bairro
);
133 free((*entry
)->desc
);
137 /* db_dump_entry(): dump 'entry' info in CSV format to stdout */
138 void db_dump_entry(const struct db_entry
*entry
)
140 printf("%u;%s;%s;%s;%s\n", entry
->cep
, entry
->uf
,
141 entry
->cidade
, entry
->bairro
, entry
->desc
);
144 /* db_print_entry(): print 'entry' info in human readable format
146 void db_print_entry(const struct db_entry
*entry
)
156 entry
->cep
, entry
->uf
, entry
->cidade
,
157 entry
->bairro
, entry
->desc
);
162 /* db_dump_csv(): dump all entries in 'db' file in CSV format
164 void db_dump_csv(FILE *db
)
166 struct db_entry
*entry
;
169 entry
= db_next_entry(db
);
173 db_dump_entry(entry
);
174 db_free_entry(&entry
);
178 /* db_entries_match(): return 1 if ent1 == ent2, return
180 int db_entries_match(const struct db_entry
*ent1
,
181 const struct db_entry
*ent2
)
183 if (ent1
->cep
!= ent2
->cep
)
186 if (strcmp(ent1
->uf
, ent2
->uf
))
189 if (strcmp(ent1
->cidade
, ent2
->cidade
))
192 if (strcmp(ent1
->bairro
, ent2
->bairro
))
195 if (strcmp(ent1
->desc
, ent2
->desc
))