aboutsummaryrefslogtreecommitdiff
path: root/src/lib/process.c
blob: e927bd3fbaf228ad5af0082ad3f69a91bd20e8c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <stdlib.h>
#include <string.h>

#include "types.h"
#include "util.h"

void appendline(struct filedata *f, char *data, size_t len) {
  f->lines = realloc(f->lines, sizeof(struct line) * (f->lc + 1));

  size_t loc = f->lc;

  f->lines[loc].len = len;
  f->lines[loc].buf = malloc(len + 1);
  memcpy(f->lines[loc].buf, data, len);
  f->lines[loc].buf[len] = '\0';
}

void loadlines(struct filedata *f) {
  f->lc = 0;

  size_t offset = 0;
  size_t linelen = 4096;
  char *line = malloc(linelen);
  if (line == NULL)
    die("malloc");

  for (size_t i = 0; i < f->buflen; i++) {
    char c = f->buf[i];
    if (c == '\n') {
      if (offset < linelen) { // shrink
        char *new_line = realloc(line, offset);
        if (new_line == NULL)
          die("realloc");
        line = new_line;
      }

      appendline(f, line, offset);
      f->lc++;

      free(line);
      offset = 0;
      line = malloc(linelen);
      if (line == NULL)
        die("malloc");
    } else {
      if (offset == linelen) {
        linelen *= 2;

        char *new_line = realloc(line, linelen);
        if (new_line == NULL)
          die("realloc");

        line = new_line;
      }

      line[offset++] = c;
    }
  }

  // capture last line
  if (offset < linelen) { // shrink
    char *new_line = realloc(line, offset);
    if (new_line == NULL)
      die("realloc");
    line = new_line;
  }

  appendline(f, line, offset);
  f->lc++;

  free(line);
}

char *linepad(int lc, int total) {
  int padlen = intlen(total) - intlen(lc);
  char *padding = malloc(padlen + 1);
  if (padding == NULL)
    die("malloc");

  if (padlen)
    memset(padding, ' ', padlen);
  padding[padlen] = '\0';

  return padding;
}