Skip to content

Commit 68c5065

Browse files
authored
Do set-diff for bash state in C (#346)
Signed-off-by: Konstantinos Kallas <[email protected]>
1 parent 2e5bb76 commit 68c5065

File tree

5 files changed

+115
-6
lines changed

5 files changed

+115
-6
lines changed

compiler/pash_init_setup.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export distro=$(printf '%s\n' "$distro" | LC_ALL=C tr '[:upper:]' '[:lower:]')
1111

1212
## File directory
1313
export RUNTIME_DIR=$(dirname "${BASH_SOURCE[0]}")
14+
## TODO: Is there a better way to do this?
15+
export RUNTIME_LIBRARY_DIR="$RUNTIME_DIR/../runtime/"
1416
export PASH_REDIR="&2"
1517
export PASH_DEBUG_LEVEL=0
1618

compiler/pash_set_from_to.sh

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ from_set=${1?From set not given}
44
to_set=${2?To set not given}
55

66
## Finds the difference of set variables (removing the c, s one since it cannot be actually set and unset)
7-
##
8-
## TODO: This is very inefficient! It can probably happen in a single C command.
9-
pash_set_to_add="$(comm -23 <(echo $to_set | sed -E 's/(.)/\1\n/g' | sort) <(echo $from_set | sed -E 's/(.)/\1\n/g' | sort) | grep -v 'c' | grep -v 's' || true )"
10-
pash_set_to_remove="$(comm -13 <(echo $to_set | sed -E 's/(.)/\1\n/g' | sort) <(echo $from_set | sed -E 's/(.)/\1\n/g' | sort) | grep -v 'c' | grep -v 's' || true )"
7+
pash_redir_output echo "From set: $from_set"
8+
pash_redir_output echo "To set: $to_set"
9+
IFS=',' read -r pash_set_to_remove pash_set_to_add <<< "$($RUNTIME_LIBRARY_DIR/set-diff $from_set $to_set)"
1110
pash_redir_output echo "To add: $pash_set_to_add"
1211
pash_redir_output echo "To remove: $pash_set_to_remove"
1312
pash_redir_all_output_always_execute set "-$pash_set_to_add"

runtime/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ r_split
44
r_merge
55
r_unwrap
66
r_wrap
7+
set-diff
78
tests/perf*
8-
tests/*out
9+
tests/*out

runtime/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.PHONY: all eager-debug split-debug clean agg
22

3-
all: eager split r-merge r-wrap r-split r-unwrap dgsh-tee agg
3+
all: eager split r-merge r-wrap r-split r-unwrap dgsh-tee agg set-diff
44

55
CFLAGS=-Wall
66

@@ -50,6 +50,9 @@ r-wrap: r_wrap.c r_split.h
5050
r-unwrap: r_unwrap.c r_split.h
5151
gcc ${CFLAGS} r_unwrap.c -o r_unwrap
5252

53+
set-diff: set-diff.c
54+
gcc ${CFLAGS} set-diff.c -o set-diff
55+
5356

5457
libdgsh_a_SOURCES = negotiate.c $(DGSH_ASSEMBLY_FILE)
5558
dgsh_tee_SOURCES = dgsh-tee.c

runtime/set-diff.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
int comp (const void * elem1, const void * elem2)
6+
{
7+
char f = *((char*)elem1);
8+
char s = *((char*)elem2);
9+
if (f > s) return 1;
10+
if (f < s) return -1;
11+
return 0;
12+
}
13+
14+
int main(int argc, char* argv[]) {
15+
// arg#1 -> old set
16+
// arg#2 -> new set
17+
if (argc != 3) {
18+
printf("ERROR: wrong input!\n");
19+
exit(1);
20+
}
21+
22+
// Returns the - and + difference of the two sets of sorted characters.
23+
//
24+
// First ensures that characters are already sorted
25+
//
26+
// It requires that there are no duplicates
27+
int fromLen = strlen(argv[1]);
28+
int toLen = strlen(argv[2]);
29+
30+
qsort(argv[1], fromLen, sizeof(char), comp);
31+
qsort(argv[2], toLen, sizeof(char), comp);
32+
33+
int maxLen = (fromLen < toLen) ? toLen : fromLen;
34+
35+
char* toRemove = malloc((maxLen + 1) * sizeof(char));
36+
char* toAdd = malloc((maxLen + 1) * sizeof(char));
37+
38+
int iFrom = 0;
39+
int iTo = 0;
40+
int iRemove = 0;
41+
int iAdd = 0;
42+
43+
while (iFrom < fromLen && iTo < toLen )
44+
{
45+
// We do not add or remove -s and -c
46+
if (argv[1][iFrom] == 'c' || argv[1][iFrom] == 's')
47+
{
48+
iFrom++;
49+
}
50+
else if (argv[2][iTo] == 'c' || argv[2][iTo] == 's')
51+
{
52+
iTo++;
53+
}
54+
else if (argv[1][iFrom] < argv[2][iTo])
55+
{
56+
// Only exists in iFrom, therefore we need to remove
57+
toRemove[iRemove] = argv[1][iFrom];
58+
iRemove ++;
59+
iFrom ++;
60+
}
61+
else if (argv[1][iFrom] == argv[2][iTo])
62+
{
63+
// Don't add or remove anything!
64+
iFrom ++;
65+
iTo ++;
66+
}
67+
else
68+
{
69+
// Only exists in iTo, therefore we need to add
70+
toAdd[iAdd] = argv[2][iTo];
71+
iAdd ++;
72+
iTo ++;
73+
}
74+
}
75+
76+
// If there is something left in iFrom
77+
while (iFrom < fromLen)
78+
{
79+
if (argv[1][iFrom] != 'c' && argv[1][iFrom] != 's')
80+
{
81+
toRemove[iRemove] = argv[1][iFrom];
82+
iRemove ++;
83+
}
84+
iFrom ++;
85+
}
86+
87+
// If there is something left in iTo
88+
while (iTo < toLen)
89+
{
90+
if (argv[2][iTo] != 'c' && argv[2][iTo] != 's')
91+
{
92+
toAdd[iAdd] = argv[2][iTo];
93+
iAdd ++;
94+
}
95+
iTo ++;
96+
}
97+
98+
toRemove[iRemove] = '\0';
99+
toAdd[iAdd] = '\0';
100+
101+
printf("%s,%s\n", toRemove, toAdd);
102+
103+
return 0;
104+
}

0 commit comments

Comments
 (0)