Hello and Hey,

Steffen Nurpmeso wrote in
<20200604235757.jxtge%stef...@sdaoden.eu>:
 |Steffen Nurpmeso wrote in
 |<20200603135346.rbmv5%stef...@sdaoden.eu>:
 ||Roberto Ricci wrote in
 ||<20200603132131.GA19797@ricci>:
 |||I'm trying to cross-compile s-nail version 14.9.19 on a Void Linux host.
 |||
 |||I run the command:
 |||    make CC=name_of_cross_compiler OPT_CROSS_BUILD=yes config
 |||but I get the following error:
 |||    [...]
 |||     . OS error mapping table generated ... no
 |||    make: *** [makefile:23: config] Error 1
 |||
 |||This probably happens because the config script needs to compile \
 |||a program
 |||and then run it. Obviously it fails if I am cross-compiling.
 | ...
 ||What a mess ;-))
 | ...
 ||moment, i think i will have to create something that uses the
 ||preprocessor to dump out data, and then a portable (awk?) parser
 ||has to parse that.  Alternatively we need to add support for an
 | ...
 |
 |So i have done exactly this, and it seems to work just fine.
 |I hope CROSS_BUILD now works.  Sorry for that inconvenience!
 |I have pushed it to [master] and the [stable/] series.

I forgot to add the patch directly, sorry.
Please find it attached.

Ciao, and a nice Weekend everybody,

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)
diff --git a/mk/make-config.sh b/mk/make-config.sh
index ffe1614a..b281877d 100644
--- a/mk/make-config.sh
+++ b/mk/make-config.sh
@@ -1631,13 +1631,14 @@ fi
 printf '#define su_PAGE_SIZE %su\n' "${i}" >> ${h}
 
 # Generate SU <> OS error number mappings
-dump_test_program=0
-(
-   feat_yes DEVEL && NV= || NV=noverbose
-   SRCDIR="${SRCDIR}" TARGET="${h}" awk="${awk}" \
-      ${SHELL} "${TOPDIR}"mk/su-make-errors.sh ${NV} config
-) | xrun_check oserrno 'OS error mapping table generated' || config_exit 1
-dump_test_program=1
+msg_nonl ' . OS error mapping table generated ... '
+feat_yes DEVEL && NV= || NV=noverbose
+SRCDIR="${SRCDIR}" TARGET="${h}" awk="${awk}" rm="${rm}" sort="${sort}" \
+      ${SHELL} "${TOPDIR}"mk/su-make-errors.sh ${NV} compile_time || {
+   msg 'no'
+   config_exit 1
+}
+msg 'yes'
 
 ## /SU
 
diff --git a/mk/su-make-errors.sh b/mk/su-make-errors.sh
index bc03944b..4ef84c4d 100644
--- a/mk/su-make-errors.sh
+++ b/mk/su-make-errors.sh
@@ -20,6 +20,9 @@ LC_ALL=C
 export LC_ALL MAXDISTANCE_PENALTY VERB MAILX IN XOUT
 
 : ${awk:=awk}
+# Compile-time only
+: ${rm:=rm}
+: ${sort:=sort}
 
 # The set of errors we support
 ERRORS="\
@@ -122,7 +125,7 @@ error_parse() {
                d = substr(v, doff + 2, length(v) - doff - 1)
                v = substr(v, 1, doff - 1)
             }
-            if(!incnone && v == "NONE")
+            if(!incnone && (v == "NONE" || v == "NOTOBACCO"))
                continue
             print dodoc ? d : v
          }
@@ -130,162 +133,169 @@ error_parse() {
    '
 }
 
-config() {
+compile_time() {
    [ -n "${TARGET}" ] || {
       echo >&2 'Invalid usage'
       exit 1
    }
-   # Note this may be ISO C89, so we cannot
-   cat <<__EOT__
-   #include <ctype.h>
-   #include <errno.h>
-   #include <limits.h>
-   #include <stdio.h>
-   #include <stdlib.h>
-   #include <string.h>
-   #if defined __STDC_VERSION__ && __STDC_VERSION__ + 0 >= 199901L
-   # include <stdint.h>
-   #else
-   # include <inttypes.h>
-   #endif
-   #include <${IN}>
-   #ifdef UINT32_MAX
-   typedef uint32_t u32;
-   typedef int32_t s32;
-   #elif ULONG_MAX == 0xFFFFFFFFu
-   typedef unsigned long int u32;
-   typedef signed long int s32;
-   #else
-   typedef unsigned int u32;
-   typedef signed int s32;
-   #endif
-   struct a_in {struct a_in *next; char const *name; s32 no; u32 uno;};
-   static int a_sortin(void const *a, void const *b){
-      return (*(struct a_in const* const *)a)->uno -
-         (*(struct a_in const* const *)b)->uno;
-   }
-   int main(void){
-      struct a_in *head, *tail, *np, **nap;
-      u32 maxsub, umax;
-      s32 xavail = 0, total = 1, imin = 0, imax = 0, voidoff = 0, i, j;
-      FILE *ofp = fopen("${TARGET}", "a");
-      if(ofp == NULL){
-         fprintf(stderr, "ERROR: cannot open output\n");
-         return 1;
-      }
 
-      /* Create a list of all errors */
-      head = tail = (struct a_in*)malloc(sizeof *head);
-      head->next = NULL; head->name = "su_ERR_NONE"; head->no = 0;
-__EOT__
-   for n in `error_parse 0 0`; do
-      cat <<__EOT__
-      ++total;
-      #ifdef E${n}
-      i = E${n};
-      #else
-      i = --xavail;
-      #endif
-      if(imin > i) {imin = i;} if(imax < i) {imax = i;}
-      np = (struct a_in*)malloc(sizeof *np);
-      np->next = NULL; np->name = "su_ERR_${n}"; np->no = i;
-      tail->next = np; tail = np;
-__EOT__
-   done
-   cat <<__EOT__
-      /* The unsigned type used for storage */
-
-      fputs("#define su__ERR_NUMBER_TYPE ", ofp);
-      if((u32)imax <= 0xFFu && (u32)-imin <= 0xFFu){
-         fputs("u8\n", ofp);
-         maxsub = 0xFFu;
-      }else if(((u32)imax <= 0xFFFFu && (u32)-imin <= 0xFFFFu)){
-         fputs("u16\n", ofp);
-         maxsub = 0xFFFFu;
-      }else{
-         fputs("u32\n", ofp);
-         maxsub = 0xFFFFFFFFu;
-      }
+   {
+      printf '#include <errno.h>\nsu_ERROR_START\n'
+      for n in `error_parse 0 0`; do
+         printf '#ifdef E%s\nE%s %s\n#else\n-1 %s\n#endif\n' $n $n $n $n
+      done
+   } > "${TARGET}".c
+
+   # The problem is that at least (some versions of) gcc mangle output.
+   # Ensure we get both arguments on one line.
+   # While here sort numerically.
+   "${CC}" -E "${TARGET}".c |
+      ${awk} '
+         BEGIN{hot=0; conti=0}
+         /^[ 	]*$/{next}
+         /^[ 	]*#/{next}
+         /^su_ERROR_START$/{hot=1; next}
+         {
+            if(!hot)
+               next
+            printf "%s ", $1
+            if(conti){
+               printf "\n"
+               conti = 0
+            }else if($2 != "")
+               printf $2 "\n"
+            else
+               conti = 1
+         }
+      ' |
+      ${sort} -n > "${TARGET}".txt
 
-      /* Now that we know the storage type, create the unsigned numbers */
-      for(umax = 0, np = head; np != NULL; np = np->next){
-         if(np->no < 0)
-            np->uno = maxsub + np->no + 1;
-         else
-            np->uno = np->no;
-         if(np->uno > umax)
-            umax = np->uno;
-      }
-      if(umax <= (u32)imax){
-         fprintf(stderr, "ERROR: errno ranges overlap\n");
-         return 1;
-      }
+   # EBCDIC/ASCII: we use \134 for \
+   j=\'
+   ${awk} -v verb="${VERB}" -v input="${ERRORS}" -v dat="${TARGET}.txt" '
+      BEGIN{
+         verb = verb ? "   " : ""
 
-      /* Sort this list */
+         # Read in our OS data
 
-      nap = (struct a_in**)malloc(sizeof(*nap) * (unsigned)total);
-      for(i = 0, np = head; np != NULL; ++i, np = np->next)
-         nap[i] = np;
-      if(i != total){
-         fprintf(stderr, "ERROR: implementation error i != total\n");
-         return 1;
-      }
-      qsort(nap, (u32)i, sizeof *nap, &a_sortin);
-
-      /* The enumeration of numbers */
-
-      fputs("#define su__ERR_NUMBER_ENUM_C \\\\\\n", ofp);
-      for(i = 0; i < total; ++i)
-         fprintf(ofp, "   %s = %lu,\\\\\\n",
-            nap[i]->name, (unsigned long)nap[i]->uno);
-      fprintf(ofp, "   su__ERR_NUMBER = %ld\\n", (long)total);
-
-      fputs("#ifdef __cplusplus\n# define su__CXX_ERR_NUMBER_ENUM \\\\\\n",
-         ofp);
-      for(i = 0; i < total; ++i){
-         char b[64], *cbp = b;
-         char const *cp;
-         cp = &nap[i]->name[sizeof("su_") -1];
-         *cbp++ = 'e';
-         for(cp += sizeof("ERR_") -1; *cp != '\0'; ++cp)
-            *cbp++ = tolower(*cp);
-         *cbp = '\0';
-         fprintf(ofp, "   %s = %s,\\\\\\n", b, nap[i]->name);
-      }
-      fprintf(ofp,
-         "   e__number = su__ERR_NUMBER\\n#endif /* __cplusplus */\n");
-
-      /* The binary search mapping table from OS error value to our internal
-       * a_corerr_map[] error description table */
-      fprintf(ofp, "#define su__ERR_NUMBER_TO_MAPOFF \\\\\\n");
-      for(xavail = 0, i = 0; i < total; ++i){
-         if(i == 0 || nap[i]->no != nap[i - 1]->no){
-            for(j = 0; a_names_alphasort[j] != NULL; ++j){
-               if(!strcmp(&nap[i]->name[sizeof("su_ERR_") -1],
-                     a_names_alphasort[j]))
-                  break;
+         unavail = 0
+         max = 0
+         oscnt = 0
+         while(getline dl < dat){
+            split(dl, ia)
+
+            ++oscnt
+            osnoa[oscnt] = osonoa[oscnt] = ia[1]
+            osnaa[oscnt] = ia[2]
+
+            if(ia[1] < 0)
+               ++unavail
+            else{
+               if(ia[1] > max)
+                  max = ia[1]
             }
-            fprintf(ofp, "\ta_X(%lu, %lu) %s%s%s\\\\\\n",
-               (unsigned long)nap[i]->uno, (long)(u32)j,
-               ((${VERB}) ? "/* " : ""), ((${VERB}) ? nap[i]->name : ""),
-                  ((${VERB}) ? " */ " : ""));
-            if(!strcmp("su_ERR_NOTOBACCO", nap[i]->name))
-               voidoff = j;
-            ++xavail;
          }
-      }
-      fprintf(ofp, "\\t/* %ld unique members */\\n", (long)xavail);
-      fprintf(ofp, "#define su__ERR_NUMBER_VOIDOFF %ld\\n", (long)voidoff);
-      fclose(ofp);
+         close(dat)
+
+         # Maximum error number defines the datatype to use.
+         # We need a value for NOTOBACCO, we warp all non-available errors to
+         # numbers too high to be regular errors, counting backwards
+
+         i = max + unavail + 1
+         if(i >= 65535){
+            t = "u32"
+            max = "0xFFFFFFFFu"
+         }else if(i >= 255){
+            t = "u16"
+            max = "0xFFFFu"
+         }else{
+            t = "u8"
+            max = "0xFFu"
+         }
+         print "#define su__ERR_NUMBER_TYPE " t
+         print "#define su__ERR_NUMBER_MAX " max
+
+         # Dump C table
+
+         unavail = 0
+         cnt = 0
+         print "#define su__ERR_NUMBER_ENUM_C \134"
+
+         print verb "su_ERR_NONE = 0,\134"
+         ++cnt
+
+         for(i = 1; i <= oscnt; ++i){
+            if(osnoa[i] < 0){
+               ++unavail
+               osnoa[i] = "(su__ERR_NUMBER_MAX - " unavail ")"
+            }
+            map[osnaa[i]] = osnoa[i]
+            print verb "su_ERR_" osnaa[i] " = " osnoa[i] ",\134"
+            ++cnt
+         }
+
+         print verb "su_ERR_NOTOBACCO = su__ERR_NUMBER_MAX,\134"
+         ++cnt
+
+         print verb "su__ERR_NUMBER = " cnt
+
+         # The C++ mapping table
+
+         print "#ifdef __cplusplus"
+         print "# define su__CXX_ERR_NUMBER_ENUM \134"
+         print verb "enone = su_ERR_NONE,\134"
+         for(i = 1; i <= oscnt; ++i)
+            print verb "e" tolower(osnaa[i]) " = su_ERR_" osnaa[i] ",\134"
+         print verb "enotobacco = su_ERR_NOTOBACCO,\134"
+         print verb "e__number = su__ERR_NUMBER"
+         print "#endif /* __cplusplus */"
+
+         # And our OS errno -> name map offset table
+
+         voidoff = 0
+         for(mapoff = 0;; ++mapoff){
+            voff = match(input, /[0-9a-zA-Z_]+(='${j}'[^'${j}']+)?/)
+            if(voff == 0)
+               break
+
+            v = substr(input, voff, RLENGTH)
+            input = substr(input, voff + RLENGTH)
+            doff = index(v, "=")
+            if(doff > 0){
+               d = substr(v, doff + 2, length(v) - doff - 1)
+               v = substr(v, 1, doff - 1)
+            }
+
+            mapo[v] = mapoff
+            if(v == "NOTOBACCO")
+               voidoff = mapoff
+         }
 
-      while((np = head) != NULL){
-         head = np->next;
-         free(np);
+         uniq = 0
+         print "#define su__ERR_NUMBER_TO_MAPOFF \134"
+
+         print verb "a_X(0, 0) \134"
+         ++uniq
+
+         mapx[0] = 1
+         for(i = 1; i <= oscnt; ++i){
+            if(osonoa[i] < 0)
+               continue
+            if(mapx[osnoa[i]])
+               continue
+            mapx[osnoa[i]] = 1
+            ++uniq
+            print verb "a_X(" osnoa[i] ", " mapo[osnaa[i]] ") \134"
+         }
+
+         print verb "a_X(su__ERR_NUMBER_MAX, " voidoff ") \134"
+         ++uniq
+         print verb "/* " uniq " unique members */"
+         print "#define su__ERR_NUMBER_VOIDOFF " voidoff
       }
-      free(nap);
-      return 0;
-   }
-__EOT__
+   ' >> "${TARGET}"
+
+   ${rm} "${TARGET}".*
    exit 0
 }
 
@@ -298,7 +308,7 @@ if [ ${#} -ne 0 ]; then
 fi
 
 if [ ${#} -eq 1 ]; then
-   [ "${1}" = config ] && config
+   [ "${1}" = compile_time ] && compile_time
 elif [ ${#} -eq 0 ]; then
    # Now start perl(1) without PERL5OPT set to avoid multibyte sequence errors
    PERL5OPT= PERL5LIB= exec perl -x "${0}"
@@ -493,23 +503,6 @@ sub dump_map{
    print F '/*@ ', scalar basen($ENV{XOUT}), ', generated by ',
       scalar basen($0), ".\n *@ See core-errors.c for more */\n\n";
 
-   print F '#ifndef su_SOURCE /* For compile-time tools only */', "\n",
-      'static char const * const a_names_alphasort[] = {';
-   ($i, $alen) = (0, 0);
-   foreach my $e (@ENTS){
-      $i = 1 + 3 + length $e->{name};
-      if($alen == 0 || $alen + $i > 75){
-         print F "\n${S}";
-         $alen = length $S
-      }else{
-         print F ' ';
-         ++$i
-      }
-      $alen += $i;
-      print F "\"$e->{name}\","
-   }
-   print F " NULL\n};\n#endif /* !su_SOURCE */\n\n";
-
    ($i, $alen) = (0, 0);
    print F '#ifdef su_SOURCE', "\n",
       'static char const a_corerr_names[] = {', "\n";

Reply via email to