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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
/*
* Copyright (c) 2022 Egor Tensin <egor@tensin.name>
* This file is part of the "cimple" project.
* For details, see https://github.com/egor-tensin/cimple.
* Distributed under the MIT License.
*/
#include "run_queue.h"
#include "json.h"
#include "log.h"
#include <json-c/json_object.h>
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
struct run {
int id;
char *repo_url;
char *repo_rev;
int status;
int exit_code;
SIMPLEQ_ENTRY(run) entries;
};
int run_new(struct run **_entry, int id, const char *_repo_url, const char *_repo_rev,
enum run_status status, int exit_code)
{
struct run *entry = malloc(sizeof(struct run));
if (!entry) {
log_errno("malloc");
goto fail;
}
char *repo_url = strdup(_repo_url);
if (!repo_url) {
log_errno("strdup");
goto free_entry;
}
char *repo_rev = strdup(_repo_rev);
if (!repo_rev) {
log_errno("strdup");
goto free_repo_url;
}
entry->id = id;
entry->repo_url = repo_url;
entry->repo_rev = repo_rev;
entry->status = status;
entry->exit_code = exit_code;
*_entry = entry;
return 0;
free_repo_url:
free(repo_url);
free_entry:
free(entry);
fail:
return -1;
}
void run_destroy(struct run *entry)
{
free(entry->repo_rev);
free(entry->repo_url);
free(entry);
}
int run_queued(struct run **entry, const char *repo_url, const char *repo_rev)
{
return run_new(entry, -1, repo_url, repo_rev, RUN_STATUS_CREATED, -1);
}
int run_created(struct run **entry, int id, const char *repo_url, const char *repo_rev)
{
return run_new(entry, id, repo_url, repo_rev, RUN_STATUS_CREATED, -1);
}
int run_to_json(const struct run *entry, struct json_object **_json)
{
struct json_object *json = NULL;
int ret = 0;
ret = libjson_new_object(&json);
if (ret < 0)
return -1;
ret = libjson_set_int_const_key(json, "id", entry->id);
if (ret < 0)
goto free;
ret = libjson_set_int_const_key(json, "exit_code", entry->exit_code);
if (ret < 0)
goto free;
ret = libjson_set_string_const_key(json, "repo_url", entry->repo_url);
if (ret < 0)
goto free;
ret = libjson_set_string_const_key(json, "repo_rev", entry->repo_rev);
if (ret < 0)
goto free;
*_json = json;
return ret;
free:
libjson_free(json);
return ret;
}
int run_get_id(const struct run *entry)
{
return entry->id;
}
const char *run_get_repo_url(const struct run *entry)
{
return entry->repo_url;
}
const char *run_get_repo_rev(const struct run *entry)
{
return entry->repo_rev;
}
void run_set_id(struct run *entry, int id)
{
entry->id = id;
}
void run_queue_create(struct run_queue *queue)
{
SIMPLEQ_INIT(queue);
}
void run_queue_destroy(struct run_queue *queue)
{
struct run *entry1 = SIMPLEQ_FIRST(queue);
while (entry1) {
struct run *entry2 = SIMPLEQ_NEXT(entry1, entries);
run_destroy(entry1);
entry1 = entry2;
}
SIMPLEQ_INIT(queue);
}
int run_queue_to_json(const struct run_queue *queue, struct json_object **_json)
{
struct json_object *json = NULL;
int ret = 0;
ret = libjson_new_array(&json);
if (ret < 0)
return ret;
struct run *entry = NULL;
SIMPLEQ_FOREACH(entry, queue, entries)
{
struct json_object *entry_json = NULL;
ret = run_to_json(entry, &entry_json);
if (ret < 0)
goto free;
ret = libjson_append(json, entry_json);
if (ret < 0) {
libjson_free(entry_json);
goto free;
}
}
*_json = json;
return ret;
free:
libjson_free(json);
return ret;
}
int run_queue_is_empty(const struct run_queue *queue)
{
return SIMPLEQ_EMPTY(queue);
}
void run_queue_add_first(struct run_queue *queue, struct run *entry)
{
SIMPLEQ_INSERT_HEAD(queue, entry, entries);
}
void run_queue_add_last(struct run_queue *queue, struct run *entry)
{
SIMPLEQ_INSERT_TAIL(queue, entry, entries);
}
struct run *run_queue_remove_first(struct run_queue *queue)
{
struct run *entry = SIMPLEQ_FIRST(queue);
SIMPLEQ_REMOVE_HEAD(queue, entries);
return entry;
}
|