aboutsummaryrefslogtreecommitdiff
path: root/src/package.c
blob: 98d6f004dc205a7676e6e309917ab08a625c04f7 (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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "package.h"

#include "lauxlib.h"
#include "lualib.h"
#include "malloc.h"
#include "pow_lua.h"
#include "stdio.h"
#include "string.h"

int extract_package_info(lua_State *L, pow_package *pkg) {
  lua_getfield(L, -1, "name");

  if (!lua_isstring(L, -1)) {
    printf("invalid package, name is not string (or doesn't exist)\n");

    return 1;
  }

  pkg->name = strdup(lua_tostring(L, -1));

  if (!pkg->name) {
    printf("strdup failed trying to get package name\n");

    return 1;
  }

  lua_pop(L, 1);

  lua_getfield(L, -1, "version");

  if (!lua_isstring(L, -1)) {
    printf("invalid package, version is not string (or doesn't exist)\n");

    return 1;
  }

  pkg->version = strdup(lua_tostring(L, -1));

  lua_pop(L, 1);

  if (!pkg->version) {
    printf("strdup failed trying to get package name\n");

    return 1;
  }

  return 0;
}

int pow_package_open(pow_package *pkg, const char *path) {
  FILE *fp;
  int c;
  int err;

  fp = fopen(path, "r");

  if (!fp) {
    printf("error opening package definition, doesn't exist?\n");

    return 1;
  }

  char *package_buffer = malloc(4096);

  size_t total = 0;
  size_t capacity = 4096;

  while ((c = fgetc(fp)) != EOF) {
    if (total + 1 >= capacity) {
      capacity *= 2;

      char *tmp = realloc(package_buffer, capacity);

      if (!tmp) {
        fclose(fp);

        printf("failed to realloc package buffer\n");

        return 1;
      }

      printf("reallocated package buffer due to size constraints\n");

      package_buffer = tmp;
    }

    package_buffer[total++] = c;
  }

  package_buffer[total] = '\0';

  lua_State *L = luaL_newstate();

  pkg->L = L;

  luaL_openlibs(L);
  pow_lua_load(L);

  luaL_loadstring(L, package_buffer);

  err = lua_pcall(L, 0, 1, 0);

  free(package_buffer);

  if (err) {
    printf("%s\n", lua_tostring(L, -1));

    return 1;
  }

  if (!lua_istable(L, -1)) {
    printf("invalid package, scripts must return table\n");

    return 1;
  }

  extract_package_info(L, pkg);

  pkg->path = path;
  pkg->pkg_ref = luaL_ref(L, LUA_REGISTRYINDEX);

  return 0;
}

int pow_package_close(pow_package *pkg) {
  free(pkg->name);
  free(pkg->version);

  lua_close(pkg->L);

  return 0;
}