Advertisement
Guest User

Untitled

a guest
Feb 10th, 2020
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.38 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdint.h>
  5.  
  6. enum { Cmd, Itm, Val };
  7.  
  8. void *items_new();
  9. void *items_load(const char *);
  10. void items_save(void *, const char *);
  11. int items_do(void **, const char **);
  12. int bsrch(const void *, const void *, size_t, size_t,
  13.           int (*)(const void *, const void *));
  14.  
  15. int main(int argc, char **argv)
  16. {
  17.     void *items = items_load(argv[1]);
  18.  
  19.     if (argv[2+Cmd][0] == 'i')
  20.     {
  21.         while (1)
  22.         {
  23.             char cmd[0x40],
  24.                  itm[0x40],
  25.                  val[0x40],
  26.                  *args[] = {cmd, itm, val};
  27.  
  28.             scanf("%s", cmd);
  29.             if (cmd[0] == '+' || cmd[0] == '-') {
  30.                 scanf("%s", itm);
  31.                 scanf("%s", val);
  32.             }
  33.             if (items_do(&items, args)) break;
  34.         }
  35.     }
  36.     else items_do(&items, argv + 2);
  37.  
  38.     items_save(items, argv[1]);
  39. }
  40.  
  41. #define SZREALLOC 0x40
  42.  
  43. typedef struct {
  44.     char name[0x40];
  45.     int32_t val;
  46. } item_t;
  47.  
  48. typedef struct {
  49.     int32_t num;
  50.     item_t item[];
  51. } items_t;
  52.  
  53. void *items_new()
  54. {
  55.     return calloc(1, sizeof(items_t));
  56. }
  57.  
  58. void *items_load(const char *path)
  59. {
  60.     FILE *file = fopen(path, "r");
  61.  
  62.     if (!file) return items_new();
  63.  
  64.     int32_t nitems;
  65.     fread(&nitems, sizeof(int32_t), 1, file);
  66.  
  67.     int nalloc = nitems + (-nitems % SZREALLOC);
  68.     items_t *items = malloc(sizeof(items_t) + nalloc * sizeof(item_t));
  69.  
  70.     items->num = nitems;
  71.     fread(items->item, sizeof(item_t), nitems, file);
  72.  
  73.     fclose(file);
  74.  
  75.     return items;
  76. }
  77.  
  78. void items_save(void *_items, const char *path)
  79. {
  80.     items_t *items = _items;
  81.  
  82.     FILE *file = fopen(path, "w");
  83.     fwrite(&items->num, sizeof(int32_t), 1, file);
  84.     fwrite(items->item, sizeof(item_t), items->num, file);
  85.     fclose(file);
  86. }
  87.  
  88. int items_do(void **pitems, const char **args)
  89. {
  90.     items_t *items = *pitems;
  91.  
  92.     const char *cmd = args[Cmd],
  93.                *itm = args[Itm],
  94.                *val = args[Val];
  95.  
  96.     switch (cmd[0]) {
  97.     case '+': case '-': {
  98.         int idx = bsrch(itm, items->item, items->num, sizeof(item_t), strcmp);
  99.         if (strcmp(items->item[idx].name, itm))
  100.         {
  101.             if (items->num % SZREALLOC == 0)
  102.             {
  103.                 int nalloc = items->num + SZREALLOC;
  104.                 items = realloc(items,
  105.                                 sizeof(items_t) + nalloc * sizeof(item_t));
  106.                 *pitems = items;
  107.             }
  108.             size_t nbytes = (items->num++ - idx) * sizeof(item_t);
  109.             memmove(items->item + idx + 1, items->item + idx, nbytes);
  110.             strcpy(items->item[idx].name, itm);
  111.             items->item[idx].val = 0;
  112.         }
  113.         items->item[idx].val += cmd[0] == '+' ? atoi(val) : -atoi(val);
  114.         return 0;
  115.     }
  116.     case 'l':
  117.         for (int i = 0; i < items->num; ++i)
  118.             printf("%-64s - %12d\n", items->item[i].name, items->item[i].val);
  119.         return 0;
  120.     default:
  121.         return -1;
  122.     }
  123. }
  124.  
  125. int bsrch(const void *key, const void *_base,
  126.            size_t num, size_t sz, int (*cmp)(const void *, const void *))
  127. {
  128.     const char (*base)[sz] = _base;
  129.  
  130.     int l = 0, r = num, m, c;
  131.     while (l < r) {
  132.         m = (l + r) / 2;
  133.         c = cmp(key, base[m]);
  134.         if (c == 0) return m;
  135.         if (c < 0) r = m;
  136.               else l = m + 1;
  137.     }
  138.     return l;
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement