Advertisement
GeeckoDev

fat-2

Aug 25th, 2011
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.62 KB | None | 0 0
  1. // Financial Account Tracker (FAT) v0.0
  2. // Geecko, 2011
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <time.h>
  8.  
  9. typedef struct
  10. {
  11.   char name[16];
  12.   int (*f)();
  13. } Command;
  14.  
  15. typedef struct
  16. {
  17.   int c, i;
  18.   char** v;
  19. } Argument;
  20.  
  21. typedef struct
  22. {
  23.   int day, month, year;
  24.   char desc[31];
  25.   float balance;
  26. } Operation;
  27.  
  28. char file_path[128];
  29. Argument arg;
  30. Operation *op = NULL;
  31. int op_size = 0;
  32.  
  33. // Common
  34.  
  35. int checkCommand(Command cmd[], int size, char name[])
  36. {
  37.   int i;
  38.   for (i=0; i<size; i++)
  39.   {
  40.     if (!strcmp(cmd[i].name,name)) return i;
  41.   }
  42.   return -1;
  43. }
  44.  
  45.  
  46. int remainingArg()
  47. {
  48.   return arg.c - arg.i;
  49. }
  50.  
  51.  
  52. int exec(Command cmd[], int size)
  53. {
  54.   int err;
  55.  
  56.   if (arg.i >= arg.c) return -1;
  57.  
  58.   err = checkCommand(cmd,size,arg.v[arg.i]);
  59.   if (err < 0)
  60.   {
  61.     printf("Invalid command (%s)\n",arg.v[arg.i]);
  62.     return 1;
  63.   }
  64.   arg.i++;
  65.  
  66.   err = cmd[err].f();
  67.   if (err > 0) printf("Error arg #%d\n",arg.i+err-1);
  68.   arg.i--;
  69.  
  70.   return 0;
  71. }
  72.  
  73.  
  74. void push(Operation t)
  75. {
  76.   op = realloc(op,(++op_size) * sizeof(Operation));
  77.   op[op_size-1] = t;
  78. }
  79.  
  80.  
  81. void pop()
  82. {
  83.   op = realloc(op,(--op_size) * sizeof(Operation));
  84. }
  85.  
  86.  
  87. void getDCB(float* debit, float* credit, float* balance, int id)
  88. {
  89.   *balance = (id>0 ? op[id-1].balance : 0.f);
  90.   *debit = 0.f;
  91.   *credit = 0.f;
  92.  
  93.   if (op[id].balance - *balance > 0.f)
  94.   {
  95.     *credit = op[id].balance - *balance;
  96.   }
  97.   else
  98.   {
  99.     *debit = *balance - op[id].balance;
  100.   }
  101.  
  102.   *balance = op[id].balance;
  103. }
  104.  
  105.  
  106. void getDMY(int* day, int* month, int* year)
  107. {
  108.   time_t rawTime;
  109.   struct tm* timeInfo;
  110.   time(&rawTime);
  111.   timeInfo = localtime(&rawTime);
  112.  
  113.   *day = timeInfo->tm_mday;
  114.   *month = timeInfo->tm_mon + 1;
  115.   *year = timeInfo->tm_year + 1900;
  116. }
  117.  
  118.  
  119. void tableJoint()
  120. {
  121.   printf("+-------+----------+-----------------------------+---------+---------+---------+\n");
  122. }
  123.  
  124. void tableHead()
  125. {
  126.   tableJoint();
  127.   printf("|ID     |Date      |Description                  |Debit    |Credit   |Balance  |\n");
  128.   tableJoint();
  129. }
  130.  
  131. void tableElement(int id)
  132. {
  133.   float balance, credit, debit;
  134.  
  135.   if (id < 0 || id >= op_size) return;
  136.   getDCB(&debit,&credit,&balance,id);
  137.  
  138.   printf("|%7d|%02d/%02d/%4d|%29s|",id+1,
  139.          op[id].day,op[id].month,op[id].year,op[id].desc);
  140.          
  141.   if (credit > 0.f) printf("         |%9.2f|",credit);
  142.   else if (debit > 0.f) printf("%9.2f|         |",debit);
  143.  
  144.   printf("%9.2f|\n",balance);
  145. }
  146.  
  147. // File management
  148.  
  149. void load()
  150. {
  151.   op = NULL;
  152.   op_size = 0;
  153.  
  154.   FILE* file = fopen(file_path,"r");
  155.   if (file == NULL)
  156.   {
  157.     printf("Error opening file for reading\n");
  158.     return;
  159.   }
  160.  
  161.   Operation t;
  162.   for (;;)
  163.   {
  164.     if (fscanf(file,"%*d %2d%2d%4d \"%[^\"]\" %f\n",
  165.                &t.day,&t.month,&t.year,t.desc,&t.balance) <= 0) break;
  166.                
  167.     op = realloc(op,(++op_size) * sizeof(Operation));
  168.     op[op_size-1] = t;
  169.   }
  170.  
  171.   fclose(file);
  172. }
  173.  
  174.  
  175. void write()
  176. {
  177.   int i;
  178.  
  179.   FILE* file = fopen(file_path,"w");
  180.   if (file == NULL)
  181.   {
  182.     printf("Error opening file for writing\n");
  183.     return;
  184.   }
  185.  
  186.   Operation t;
  187.   for (i=0; i<op_size; i++)
  188.   {
  189.     t = op[i];
  190.     if (fprintf(file,"%d %02d%02d%4d \"%s\" %.2f\n",
  191.                 i+1,t.day,t.month,t.year,t.desc,t.balance) <= 0) break;
  192.   }
  193.  
  194.   fclose(file);
  195. }
  196.  
  197. // Commands
  198.  
  199. int add()
  200. {
  201.   float amount;
  202.   char desc[31] = {0};
  203.  
  204.   if (remainingArg() < 2) return remainingArg() + 1;
  205.   if (strncpy(desc,arg.v[arg.i+0],29) <= 0) return 1;
  206.   if (sscanf(arg.v[arg.i+1],"%f",&amount) <= 0) return 2;
  207.   if (amount == 0.f) return 2;
  208.  
  209.   Operation t;
  210.   getDMY(&t.day,&t.month,&t.year);
  211.   t.balance = amount + (op_size>0 ? op[op_size-1].balance : 0);
  212.   strcpy(t.desc,desc);
  213.   push(t);
  214.   write();
  215.  
  216.   printf("Adding an operation (%02d/%02d/%4d):\n",t.day,t.month,t.year);
  217.   printf(" - ID is #%d\n",op_size);
  218.   printf(" - Description is \"%s\"\n",desc);
  219.   printf(" - Amount is %+.2f euro(s)\n",amount);
  220.   printf(" - Current balance is %+.2f euro(s)\n",op[op_size-1].balance);
  221.  
  222.   return 0;
  223. }
  224.  
  225.  
  226. int delete()
  227. {
  228.   float old_amount, old_balance;
  229.   char* old_desc;
  230.  
  231.   if (op_size <= 0)
  232.   {
  233.     printf("Nothing to delete\n");
  234.     return 0;
  235.   }
  236.  
  237.   old_desc = op[op_size-1].desc;
  238.   old_balance = (op_size>1 ? op[op_size-2].balance : 0);
  239.   old_amount = op[op_size-1].balance - old_balance;
  240.  
  241.   printf("Deleting the last operation (%02d/%02d/%4d):\n",
  242.          op[op_size-1].day,op[op_size-1].month,op[op_size-1].year);
  243.   printf(" - ID was #%d\n",op_size);
  244.   printf(" - Description was \"%s\"\n",old_desc);
  245.   printf(" - Amount was %+.2f euro(s)\n",old_amount);
  246.   printf(" - Balance is back to %+.2f euro(s)\n",old_balance);
  247.  
  248.   pop();
  249.   write();  
  250.  
  251.   return 0;
  252. }
  253.  
  254. int view_recap()
  255. {
  256.   int i;
  257.   float balance, debit, credit, acc_debit=0.f, acc_credit=0.f;
  258.  
  259.   for (i=0; i<op_size; i++)
  260.   {
  261.     getDCB(&debit,&credit,&balance,i);
  262.     acc_debit += debit;
  263.     acc_credit += credit;
  264.   }
  265.  
  266.   printf("Total credit: %.2f\n",acc_credit);
  267.   printf("Total debit: %.2f\n",acc_debit);
  268.   printf("Current balance: %.2f\n",balance);
  269.  
  270.   return 0;
  271. }
  272.  
  273.  
  274. int view_last()
  275. {
  276.   int i, n;
  277.  
  278.   n = 20;
  279.   if (remainingArg() > 0)
  280.   {
  281.     if (sscanf(arg.v[arg.i],"%d",&n) <= 0) return 1;
  282.   }
  283.   if (op_size < n) n = op_size;
  284.  
  285.   if (n < 1)
  286.   {
  287.     printf("Nothing to print\n");
  288.     return 0;
  289.   }
  290.  
  291.   tableHead();
  292.   for (i=op_size-n; i<op_size; i++) tableElement(i);
  293.   tableJoint();
  294.  
  295.   return 0;
  296. }
  297.  
  298.  
  299. int view_id()
  300. {
  301.   int id;
  302.  
  303.   if (remainingArg() <= 0) return 1;
  304.   if (sscanf(arg.v[arg.i],"%d",&id) <= 0) return 1;
  305.   if (id < 1 || id > op_size) return 1;
  306.  
  307.   tableHead();
  308.   tableElement(id-1);
  309.   tableJoint();
  310.  
  311.   return 0;
  312. }
  313.  
  314.  
  315. int view_day()
  316. {
  317.   int i, day, month, year;
  318.  
  319.   if (remainingArg() < 3) getDMY(&day,&month,&year);
  320.   else
  321.   {
  322.     if (sscanf(arg.v[arg.i+0],"%d",&day) <= 0) return 1;
  323.     if (sscanf(arg.v[arg.i+1],"%d",&month) <= 0) return 2;
  324.     if (sscanf(arg.v[arg.i+2],"%d",&year) <= 0) return 3;
  325.   }
  326.  
  327.   for (i=0; i<op_size; i++)
  328.   {
  329.     if (op[i].day == day && op[i].month == month && op[i].year == year) break;
  330.   }
  331.   if (i >= op_size)
  332.   {
  333.     printf("Nothing to print\n");
  334.     return 0;
  335.   }
  336.  
  337.   tableHead();
  338.   for (i=0; i<op_size; i++)
  339.   {
  340.     if (op[i].day == day && op[i].month == month && op[i].year == year)
  341.     {
  342.       tableElement(i);
  343.     }
  344.   }
  345.   tableJoint();
  346.  
  347.   return 0;
  348. }
  349.  
  350.  
  351. int view_month()
  352. {
  353.   int i, day, month, year;
  354.  
  355.   if (remainingArg() < 2) getDMY(&day,&month,&year);
  356.   else
  357.   {
  358.     if (sscanf(arg.v[arg.i+0],"%d",&month) <= 0) return 1;
  359.     if (sscanf(arg.v[arg.i+1],"%d",&year) <= 0) return 2;
  360.   }
  361.  
  362.   for (i=0; i<op_size; i++)
  363.   {
  364.     if (op[i].month == month && op[i].year == year) break;
  365.   }
  366.   if (i >= op_size)
  367.   {
  368.     printf("Nothing to print\n");
  369.     return 0;
  370.   }
  371.  
  372.   tableHead();
  373.   for (i=0; i<op_size; i++)
  374.   {
  375.     if (op[i].month == month && op[i].year == year) tableElement(i);
  376.   }
  377.   tableJoint();
  378.  
  379.   return 0;
  380. }
  381.  
  382.  
  383. int view_year()
  384. {
  385.   int i, day, month, year;
  386.  
  387.   if (remainingArg() < 1) getDMY(&day,&month,&year);
  388.   else
  389.   {
  390.     if (sscanf(arg.v[arg.i+0],"%d",&year) <= 0) return 1;
  391.   }
  392.  
  393.   for (i=0; i<op_size; i++)
  394.   {
  395.     if (op[i].year == year) break;
  396.   }
  397.   if (i >= op_size)
  398.   {
  399.     printf("Nothing to print\n");
  400.     return 0;
  401.   }
  402.  
  403.   tableHead();
  404.   for (i=0; i<op_size; i++)
  405.   {
  406.     if (op[i].year == year) tableElement(i);
  407.   }
  408.   tableJoint();
  409.  
  410.   return 0;
  411. }
  412.  
  413.  
  414. Command cmd_view[6] =
  415. {
  416.   {"recap",view_recap},
  417.   {"last",view_last},
  418.   {"id",view_id},
  419.   {"day",view_day},
  420.   {"month",view_month},
  421.   {"year",view_year}
  422. };
  423.  
  424. int view()
  425. {
  426.   if (exec(cmd_view,6) < 0)
  427.   {
  428.     printf("Financial account tracker (FAT) v0.0\n");
  429.     printf("Usage: fat view COMMAND [ARGS]\n\n");
  430.     printf("Commands available:\n");
  431.     printf("   recap\n");
  432.     printf("   last [n]\n");
  433.     printf("   id num\n");
  434.     printf("   day [dd mm yyyy]\n");
  435.     printf("   month [mm yyyy]\n");
  436.     printf("   year [yyyy]\n");
  437.   }
  438.  
  439.   return 0;
  440. }
  441.  
  442. // Main
  443.  
  444. Command cmd_main[3] =
  445. {
  446.   {"add",add},
  447.   {"delete",delete},
  448.   {"view",view}
  449. };
  450.  
  451. int main(int argc, char **argv)
  452. {
  453.   arg.c = argc;
  454.   arg.v = argv;
  455.   arg.i = 1;
  456.  
  457.   strcpy(file_path,argv[0]);
  458.   strcpy(strrchr(file_path,'/')+1,"facc");
  459.  
  460.   load();  
  461.   if (exec(cmd_main,3) < 0)
  462.   {
  463.     printf("Financial account tracker (FAT) v0.0\n");
  464.     printf("Usage: fat COMMAND [ARGS]\n\n");
  465.     printf("Commands available:\n");
  466.     printf("   add \"desc\" amount\n");
  467.     printf("   delete\n");
  468.     printf("   view COMMAND [ARGS]\n");
  469.   }
  470.  
  471.   return 0;
  472. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement