1#!/usr/bin/env bash
2
3# Small script to test fpc to system error numbers
4
5addtoerrno=0
6errnonew=./errno-new.inc
7
8temps="check_errno_list.sh check_reverse_errno_list.sh test-errno* $errnonew"
9
10if [ "$1" == "clean" ] ; then
11  echo "Deleting $temps"
12  rm -f $temps
13  exit
14fi
15
16if [ "$1" == "verbose" ] ; then
17  verbose=1
18  echo "Being verbose"
19  shift
20else
21  verbose=0
22fi
23
24if [ "$1" == "addall" ] ; then
25  addall=1
26  echo "Adding all entries to errno-new.inc"
27  shift
28else
29  addall=0
30fi
31
32# Location of error number in system header
33
34errno_headers="/usr/include/asm-generic/errno-base.h /usr/include/asm-generic/errno.h"
35
36if [ "$1" != "" ] ; then
37  errno_include=$1
38  echo "Using $errno_include file"
39else
40  errno_include=./errno.inc
41fi
42
43# Sustitution made to pass from fpc syscall number
44# to system define
45fpc_errno_prefix=ESysE
46errno_prefix=E
47
48# Test C file to grab all loaded headers
49cat > test-errno.c <<EOF
50#include <errno.h>
51
52int
53dummy ()
54{
55  return 0;
56}
57EOF
58
59# Default C compiler is gcc
60# Can be overwritten by setting CC variable
61# But I don't know if other compilers also generate
62# .i files with --save-temps option
63if [ "$CC" == "" ] ; then
64  CC=gcc
65fi
66
67# Use gcc with --save-temps option to create .i file
68$CC --save-temps -c ./test-errno.c
69# list of errno.h headers listed
70errno_headers_CC=` sed -n "s:.*\"\(.*\.h\)\".*:\1:p" test-errno.i |sort | uniq`
71echo "Headers found are \"$errno_headers_CC\""
72
73if [ "$errno_headers_CC" != "" ] ; then
74  errno_headers="$errno_headers_CC"
75fi
76
77
78# You should only need to change the variables above
79
80sed -n "s:^[[:space:]]*${fpc_errno_prefix}\\([_a-zA-Z0-9]*\\)[[:space:]]*=[[:space:]]*\\([0-9][0-9]*\\).*:check_errno_number ${errno_prefix}\1 \2:p" ${errno_include} > check_errno_list.sh
81sed -n "s:#define[[:space:]]*${errno_prefix}\\([_a-zA-Z0-9]*\\)[[:space:]][[:space:]]*\\(-*[0-9A-Za-z_]*\\)[[:space:]]*\(.*\):check_reverse_errno_number ${fpc_errno_prefix}\1 \2 \"\3\":p" ${errno_headers} > check_reverse_errno_list.sh
82
83function rpad {
84  word="$1"
85  while [ ${#word} -lt $2 ]; do
86    word="$word$3";
87  done;
88  echo "$word";
89}
90
91function compile_errno ()
92{
93  errname=$1
94  errvalue=$2
95# Test C file to grab all loaded headers
96cat > test-errno.c <<EOF
97#include <errno.h>
98#include <stdio.h>
99
100int
101main ()
102{
103  printf ("$errname=%d\n",$errname);
104  return 0;
105}
106EOF
107$CC -o ./test-errno ./test-errno.c
108compiledvalue=`./test-errno`
109if [ "$compiledvalue" == "$errname=$errvalue" ] ; then
110  if [ $verbose -ne 0 ]; then
111    echo "GCC reports $compiledvalue OK"
112  fi
113else
114  echo "GCC reports $compiledvalue, but $errvalue is expected"
115fi
116}
117
118function check_errno_number ()
119{
120  sys=$1
121  value=$2
122  if [ $verbose -ne 0 ] ; then
123    echo Testing $sys value $value
124  fi
125  # Remember value of this constant
126  eval ${sys}=${value}
127  compile_errno $sys $value
128
129  found=`sed -n "/#define[[:space:]][[:space:]]*${sys}[^A-Za-z0-9_]/p" ${errno_headers}`
130  val=`sed -n "s:#define[[:space:]][[:space:]]*${sys}[^A-Za-z0-9_][^A-Za-z0-9_]*\([0-9]*\).*:\1:p" ${errno_headers}`
131  extval=`sed -n "s:#define[[:space:]][[:space:]]*${sys}[^A-Za-z0-9_][^A-Za-z0-9_]*\([0-9A-Za-z_]*\).*:\1:p" ${errno_headers}`
132  if [ $verbose -ne 0 ] ; then
133    echo Test for $sys found \"${found}\" \"${value}\" \"${val}\"
134  fi
135  if [ "${val}" == "${value}" ] ; then
136    if [ $verbose -ne 0 ] ; then
137      echo ${sys} value ${val} is correct
138    fi
139  else
140    if [ $verbose -ne 0 ] ; then
141      echo "${sys} val=\"$val\", extval=\"$extval\""
142    fi
143    if [ "${val}" == "" ] ; then
144      foundvalue=`sed -n "/#define.*[^A-Za-z0-9_]${value}$/p" ${errno_headers}`
145      if [ "${foundvalue}" == "" ] ; then
146        foundvalue=`sed -n "s:\/\* ${value} is compa: ${value} is compa:p" ${errno_headers}`
147      fi
148    fi
149    if [ "$extval" != "$val" ] ; then
150      eval indirectval=\$$extval
151      echo "indirectval =\"$indirectval\" for \"$extval\""
152      if [ "$indirectval" != "$value" ] ; then
153        echo problem for ${sys} expected ${value}, line is \"${found}\", val found is \"${indirectval}\"
154      else
155        echo "$sys is defined as $extval which is $indirectval as expected $value"
156      fi
157    else
158      echo "problem for ${sys} expected ${value}, line is \"${found}\", val found is \"${val}\""
159    fi
160  fi
161}
162
163function write_errno_new_head ()
164{
165  echo "{ File generated by $0" > $errnonew
166  uname_info=`uname -s -r -m`
167  echo " generated on \"$uname_info\" machine" >> $errnonew
168  echo "List of missing system error number found in" >> $errnonew
169  echo "$errno_headers" >> $errnonew
170  echo "}" >> $errnonew
171}
172
173function check_reverse_errno_number ()
174{
175  errname=$1
176  errvalue=$2
177  rpaderrname=$(rpad $errname 20 " ")
178  if ! [[ "$errvalue" =~ ^[0-9]+$ ]] ; then
179    eval errvalue=\$$errvalue
180  fi
181
182  printf -v padd "%s = %4d" "$rpaderrname" $errvalue
183
184  found=`grep -i -w $1 ${errno_include}`
185  comment="$3"
186  comment=${comment##\/\*}
187  comment=${comment%%\*\/}
188  if [ "${found}" == "" ] ; then
189    echo "Error ${errname}, value ${errvalue}, not in ${errno_include} file"
190    if [ $addtoerrno -eq 0 ] ; then
191      addtoerrno=1
192      write_errno_new_head
193    fi
194    echo "        $padd; { $comment }" >> $errnonew
195  else
196    if [ $addall -eq 1 ] ; then
197      if [ $addtoerrno -eq 0 ] ; then
198        addtoerrno=1
199        write_errno_new_head
200      fi
201      echo "        $padd; { $comment }" >> $errnonew
202    fi
203  fi
204}
205
206set -f
207echo "Checking all entries of ${errno_include} file"
208source ./check_errno_list.sh
209
210echo "Checking all defines from \"$errno_header\""
211source ./check_reverse_errno_list.sh
212
213if [ $addtoerrno -eq 1 ] ; then
214  echo " Missing error number found"
215  echo " New values are in \"$errnonew\"
216  echo You might want to add these lines to \"$errno_include\""
217fi
218
219