-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpwla_filter.c
127 lines (103 loc) · 3.28 KB
/
pwla_filter.c
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
/* -*- mode: c -*- */
#include "pwla.h"
#include <stdio.h>
#include "ate_handle.h"
#include "ate_utilities.h"
#include "ate_errors.h"
#include "word_list_stack.h"
/**
* @brief Create new handle with subset of source table
* @param "alist" Stack-based simple linked list of argument values
* @return EXECUTION_SUCCESS or one of the failure codes
*
* see man ate(1)
*/
int pwla_filter(ARG_LIST *alist)
{
const char *handle_name = NULL;
const char *function_name = NULL;
const char *new_handle_name = NULL;
ARG_TARGET filter_targets[] = {
{ "handle_name", AL_ARG, &handle_name},
{ "callback_name", AL_ARG, &function_name},
{ "new_handle_name", AL_ARG, &new_handle_name},
{ NULL }
};
int retval;
if ((retval = process_word_list_args(filter_targets, alist, AL_NO_OPTIONS)))
goto early_exit;
SHELL_VAR *handle_var;
if ((retval = get_handle_var_by_name_or_fail(&handle_var,
handle_name,
"filter")))
goto early_exit;
SHELL_VAR *callback_var;
if ((retval = get_function_by_name_or_fail(&callback_var,
function_name,
"filter")))
goto early_exit;
retval = EX_USAGE;
if (new_handle_name == NULL)
{
ate_register_missing_argument("new handle name", "filter");
goto early_exit;
}
// For actions that create an array for callback functions
SHELL_VAR *new_array = NULL;
if ((retval = create_array_var_by_stem(&new_array, "ATE_FILTER_ARRAY_", "template")))
goto early_exit;
// Make WORD_LIST of args for each call
WORD_LIST *args = NULL, *tail = NULL;
WL_APPEND(tail, new_array->name);
args = tail;
ARG_LIST *argptr = alist->next;
while (argptr)
{
WL_APPEND(tail, argptr->value);
argptr = argptr->next;
}
// Use the values aquired above
AHEAD *ahead = ahead_cell(handle_var);
ARRAY_ELEMENT **ptr = ahead->rows;
ARRAY_ELEMENT **end = ptr + ahead->row_count;
// Run the filter
AEL *ael_list = NULL, *ael_tail = NULL, *ael_cur = NULL;
int count = 0;
while (ptr < end)
{
// Update new_array with current row contents:
if ((retval = update_row_array(new_array, *ptr, ahead->row_size)))
goto early_exit;
if (EXECUTION_SUCCESS == invoke_shell_function_word_list(callback_var, args))
{
++count;
ael_cur = (AEL*)alloca(sizeof(AEL));
ael_cur->element = *ptr;
ael_cur->next = NULL;
if (ael_tail)
ael_tail->next = ael_cur;
else
ael_list = ael_cur;
ael_tail = ael_cur;
}
++ptr;
}
AHEAD *new_head = NULL;
retval = EXECUTION_FAILURE;
if (ate_create_head_with_ael(&new_head,
ahead->array,
ahead->row_size,
count,
ael_list))
{
SHELL_VAR *var = NULL;
if (ate_create_handle_with_head(&var,
new_handle_name,
new_head))
retval = EXECUTION_SUCCESS;
else
xfree(new_head);
}
early_exit:
return retval;
}