/* function definition to parse a string instead of a file
*/
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <time.h>
#include <glib.h>
#include "types.h"
/* static lifetime but only accessible here and through get and set functions below */
static BotExpenseEntry * g_lastExpenseEntry = NULL;
static GString *g_filename = NULL;
BotExpenseEntry *bot_get_last_expense()
{
return g_lastExpenseEntry;
}
void bot_set_last_expense(BotExpenseEntry *entry)
{
if(g_lastExpenseEntry) {
free_bot_expense_entry(g_lastExpenseEntry);
}
g_lastExpenseEntry = entry;
}
GString *bot_get_filename()
{
return g_filename;
}
void bot_set_filename(GString *fn)
{
if(g_filename) {
g_string_free(g_filename, true);
}
g_filename = fn;
}
/* Create a BotExpenseEntry with data fed from the parser.
* Returns NULL if error getting local time.
*/
BotExpenseEntry *create_bot_expense_entry
(
const BotExpenseEntry *previous,
const unsigned int id,
const BotCommand cmd,
const double value,
GString* user,
GString* notes
)
{
double signedValue = value;
BotExpenseEntry *entry = malloc(sizeof *entry); // TODO this should be freed once it's written to registry
struct tm *lt = malloc(sizeof *lt);
time_t t = time(NULL);
/* get the local time */
localtime_r(&t, lt);
if(lt == NULL) {
fprintf(stderr, "Unable to get localtime.\n");
return NULL;
}
if(cmd == BOT_CMD_OUT) {
signedValue = -value;
}
entry->id = id;
entry->time = *lt;
entry->value = signedValue;
entry->user = user;
entry->notes = notes;
entry->_serialized = false;
return entry;
}
/* FP should not be null. This assumes that it has been initialized with an header line as well
* Returns NULL in case 'entry' is uninitialized.
*/
GString *serialize_bot_expense_entry_csv
(
BotExpenseEntry *entry
)
{
/* will be automatically expanded by g_string_printf */
GString *tstr = g_string_new(NULL);
GString *result = g_string_new(NULL);
if(entry == NULL) {
fprintf(stderr, "BotExpenseEntry 'entry' is NULL. Initialize it before calling 'serialize_bot_expense_entry_csv'\n");
return NULL;
}
/* Time in ISO 8061 */
g_string_printf(tstr,
"%d-%02d-%02d %02d:%02d:%02d",
entry->time.tm_year + 1900,
entry->time.tm_mon + 1,
entry->time.tm_mday,
entry->time.tm_hour,
entry->time.tm_min,
entry->time.tm_sec);
g_string_printf(result,
"%u,%s,%.2f,%s,%s\n",
entry->id,
tstr->str,
entry->value,
entry->user->str,
entry->notes->str
);
entry->_serialized = true;
return result;
}
/* To be called after it has been serialized */
void free_bot_expense_entry
(
BotExpenseEntry *entry
)
{
if(!entry->_serialized) {
/* TODO could fail here instead */
fprintf(stderr, "WARNING: freeing an entry that wasn't serialized!\n");
}
/* Also free underlying string, we don't need it anymore */
g_string_free(entry->user, TRUE);
g_string_free(entry->notes, TRUE);
free(entry);
}
void free_bot_reminder
(
BotReminder *reminder
)
{
g_string_free(reminder->from, true);
free(reminder);
}