summaryrefslogtreecommitdiff
path: root/gen-stubs.bash
blob: 0b9886b239a3bccf5c7283a009b193e67453a4a9 (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
#!/bin/bash

filter_classifiers()
{
   sed 's/static//;s/__inline__//;s/^[\t ]*//'
}

ret_type_for()
{
   filter_classifiers <<<"$1" | sed 's/^const[\t ]*//' | grep -Eo '^(struct|unsigned)? *[a-zA-Z_]+[\t \*]*'
}

fun_name_for()
{
   filter_classifiers <<<"$1" | sed 's/struct//;s/const//;s/unsigned//;s/^[\t ]*//;s/[a-zA-Z_]\+[\t \*]*//' | grep -Eo '^[a-zA-Z_]+'
}

should_error()
{
   # stubs that should return error value
   grep -Fqs "$(cat << EOF
_malloc
snd_config_
EOF
)" <<<"$1"
}

return_for()
{
   ret="$(ret_type_for "$1" | xargs)"
   case "$ret" in
      *\*|snd_config_iterator_t)
         printf 'return NULL;'
         ;;
      void)
         printf ''
         ;;
      snd_pcm_sync_id_t|snd_htimestamp_t)
         printf 'return (%s){0};' "$ret"
         ;;
      'unsigned char'|int|'unsigned int'|long|'unsigned long'|size_t|ssize_t|pid_t|snd_*)
         if should_error "$2"; then
            printf 'return -1;'
         else
            printf 'return 0;'
         fi
         ;;
      *)
         printf 'unhandled return type: %s\n' "$ret" 1>&2
         exit 1
         ;;
   esac
}

blacklist()
{
   grep -Fvs "$(cat << EOF
return
snd_dlsym_link
snd_pcm_hw_strategy
__SND_DLSYM_VERSION
EOF
)"
}

match()
{
   blacklist | grep -Eh '^(static|__inline__|const|struct|unsigned| )*[a-zA-Z_]+[\t \*]*[a-zA-Z_]+\(.*\);'
}

preprocess()
{
   # trim leading whitespace and turn function definitions oneline and remove attributes
   sed 's/^[\t ]*//;s/[\t ]*__attribute__((.*))[\t ]*//g' | sed -z 's/,[\t ]*\n/, /g'
}

cat include/alsa/*.h | preprocess | match | tr -d ';' | while read -r fun; do
   name="$(fun_name_for "$fun")"
   grep -Fqs "$name(" src/{libasound,pcm,mixer}.c || printf '%s { WARNX1("stub"); %s }\n' "$fun" "$(return_for "$fun" "$name")"
done