File src/filetype.c changed (mode: 100644) (index 0aaba1863..968ffd009) |
... |
... |
static assoc_records_t parse_command_list(const char cmds[], int with_descr); |
41 |
41 |
static assoc_records_t clone_all_matching_records(const char file[], |
static assoc_records_t clone_all_matching_records(const char file[], |
42 |
42 |
const assoc_list_t *record_list); |
const assoc_list_t *record_list); |
43 |
43 |
static int add_assoc(assoc_list_t *assoc_list, assoc_t assoc); |
static int add_assoc(assoc_list_t *assoc_list, assoc_t assoc); |
44 |
|
static assoc_records_t clone_assoc_records(const assoc_records_t *records, |
|
45 |
|
const char pattern[], const assoc_list_t *dst); |
|
|
44 |
|
static int is_assoc_equal(const assoc_t *a, const assoc_t *b); |
46 |
45 |
static void reset_all_lists(void); |
static void reset_all_lists(void); |
47 |
46 |
static void add_defaults(int in_x); |
static void add_defaults(int in_x); |
48 |
47 |
static void reset_list(assoc_list_t *assoc_list); |
static void reset_list(assoc_list_t *assoc_list); |
|
... |
... |
void |
194 |
193 |
ft_set_programs(matchers_t *matchers, const char programs[], int for_x, |
ft_set_programs(matchers_t *matchers, const char programs[], int for_x, |
195 |
194 |
int in_x) |
int in_x) |
196 |
195 |
{ |
{ |
197 |
|
assoc_records_t prog_records = parse_command_list(programs, 1); |
|
198 |
|
|
|
199 |
196 |
const assoc_t assoc = { |
const assoc_t assoc = { |
200 |
197 |
.matchers = matchers, |
.matchers = matchers, |
201 |
|
.records = clone_assoc_records(&prog_records, matchers_get_expr(matchers), |
|
202 |
|
for_x ? &xfiletypes : &filetypes), |
|
|
198 |
|
.records = parse_command_list(programs, 1), |
203 |
199 |
}; |
}; |
204 |
|
ft_assoc_records_free(&prog_records); |
|
205 |
200 |
|
|
206 |
201 |
/* On error, add_assoc() frees assoc, so just exit then. */ |
/* On error, add_assoc() frees assoc, so just exit then. */ |
207 |
202 |
if(add_assoc(for_x ? &xfiletypes : &filetypes, assoc) == 0) |
if(add_assoc(for_x ? &xfiletypes : &filetypes, assoc) == 0) |
|
... |
... |
clone_all_matching_records(const char file[], const assoc_list_t *record_list) |
278 |
273 |
void |
void |
279 |
274 |
ft_set_viewers(matchers_t *matchers, const char viewers[]) |
ft_set_viewers(matchers_t *matchers, const char viewers[]) |
280 |
275 |
{ |
{ |
281 |
|
assoc_records_t view_records = parse_command_list(viewers, 0); |
|
282 |
|
|
|
283 |
276 |
const assoc_t assoc = { |
const assoc_t assoc = { |
284 |
277 |
.matchers = matchers, |
.matchers = matchers, |
285 |
|
.records = clone_assoc_records(&view_records, matchers_get_expr(matchers), |
|
286 |
|
&fileviewers), |
|
|
278 |
|
.records = parse_command_list(viewers, 0), |
287 |
279 |
}; |
}; |
288 |
|
ft_assoc_records_free(&view_records); |
|
289 |
|
|
|
290 |
280 |
/* On error, add_assoc() frees assoc, so just exit then. */ |
/* On error, add_assoc() frees assoc, so just exit then. */ |
291 |
281 |
(void)add_assoc(&fileviewers, assoc); |
(void)add_assoc(&fileviewers, assoc); |
292 |
282 |
} |
} |
293 |
283 |
|
|
294 |
|
/* Clones list of association records. Returns the clone. */ |
|
295 |
|
static assoc_records_t |
|
296 |
|
clone_assoc_records(const assoc_records_t *records, const char pattern[], |
|
297 |
|
const assoc_list_t *dst) |
|
|
284 |
|
/* Adds association to the list of associations, takes ownership of it |
|
285 |
|
* regardless of the outcome. Returns non-zero on out of memory error, |
|
286 |
|
* otherwise zero is returned. */ |
|
287 |
|
static int |
|
288 |
|
add_assoc(assoc_list_t *assoc_list, assoc_t assoc) |
298 |
289 |
{ |
{ |
299 |
290 |
int i; |
int i; |
300 |
|
assoc_records_t list = {}; |
|
301 |
|
|
|
302 |
|
for(i = 0; i < records->count; ++i) |
|
|
291 |
|
for(i = 0; i < assoc_list->count; ++i) |
303 |
292 |
{ |
{ |
304 |
|
if(!ft_assoc_exists(dst, pattern, records->list[i].command)) |
|
|
293 |
|
if(is_assoc_equal(&assoc_list->list[i], &assoc)) |
305 |
294 |
{ |
{ |
306 |
|
ft_assoc_record_add(&list, records->list[i].command, |
|
307 |
|
records->list[i].description); |
|
|
295 |
|
/* Not adding duplicates. */ |
|
296 |
|
free_assoc(&assoc); |
|
297 |
|
return 0; |
308 |
298 |
} |
} |
309 |
299 |
} |
} |
310 |
300 |
|
|
311 |
|
return list; |
|
312 |
|
} |
|
313 |
|
|
|
314 |
|
/* Adds association to the list of associations. Returns non-zero on |
|
315 |
|
* out of memory error, otherwise zero is returned. Frees resources of assoc |
|
316 |
|
* on error. */ |
|
317 |
|
static int |
|
318 |
|
add_assoc(assoc_list_t *assoc_list, assoc_t assoc) |
|
319 |
|
{ |
|
320 |
301 |
void *p; |
void *p; |
321 |
302 |
p = reallocarray(assoc_list->list, assoc_list->count + 1, sizeof(assoc_t)); |
p = reallocarray(assoc_list->list, assoc_list->count + 1, sizeof(assoc_t)); |
322 |
303 |
if(p == NULL) |
if(p == NULL) |
|
... |
... |
add_assoc(assoc_list_t *assoc_list, assoc_t assoc) |
332 |
313 |
return 0; |
return 0; |
333 |
314 |
} |
} |
334 |
315 |
|
|
|
316 |
|
/* Compares two associations for equality. Returns non-zero if they are equal, |
|
317 |
|
* otherwise zero is returned. */ |
|
318 |
|
static int |
|
319 |
|
is_assoc_equal(const assoc_t *a, const assoc_t *b) |
|
320 |
|
{ |
|
321 |
|
if(a->records.count != b->records.count) |
|
322 |
|
{ |
|
323 |
|
return 0; |
|
324 |
|
} |
|
325 |
|
|
|
326 |
|
if(strcmp(matchers_get_expr(a->matchers), |
|
327 |
|
matchers_get_expr(b->matchers)) != 0) |
|
328 |
|
{ |
|
329 |
|
return 0; |
|
330 |
|
} |
|
331 |
|
|
|
332 |
|
int i; |
|
333 |
|
for(i = 0; i < a->records.count; ++i) |
|
334 |
|
{ |
|
335 |
|
if(strcmp(a->records.list[i].command, b->records.list[i].command) != 0) |
|
336 |
|
{ |
|
337 |
|
return 0; |
|
338 |
|
} |
|
339 |
|
} |
|
340 |
|
return 1; |
|
341 |
|
} |
|
342 |
|
|
335 |
343 |
ViewerKind |
ViewerKind |
336 |
344 |
ft_viewer_kind(const char viewer[]) |
ft_viewer_kind(const char viewer[]) |
337 |
345 |
{ |
{ |