From 8b15b45ecc58d84f9d4a6bd91fc0675b446103b8 Mon Sep 17 00:00:00 2001 From: Manuel Novoa III Date: Sat, 27 Jan 2001 18:51:26 +0000 Subject: Enable auto-generation of a size-optimized sysconf function (saves .5k on i386). --- libc/unistd/.cvsignore | 2 + libc/unistd/Makefile | 46 +++++- libc/unistd/sysconf.c | 415 ++++++++++++++++++++++++++++++++++++------------- 3 files changed, 349 insertions(+), 114 deletions(-) create mode 100644 libc/unistd/.cvsignore (limited to 'libc/unistd') diff --git a/libc/unistd/.cvsignore b/libc/unistd/.cvsignore new file mode 100644 index 000000000..dba071497 --- /dev/null +++ b/libc/unistd/.cvsignore @@ -0,0 +1,2 @@ +sysconf_*.c +gen_sysconf diff --git a/libc/unistd/Makefile b/libc/unistd/Makefile index c1ff28575..6873102b0 100644 --- a/libc/unistd/Makefile +++ b/libc/unistd/Makefile @@ -24,9 +24,16 @@ TOPDIR=../ include $(TOPDIR)Rules.mak LIBC=$(TOPDIR)libc.a - CSRC=execl.c execlp.c execv.c execvep.c execvp.c getcwd.c getopt.c \ - sleep.c sysconf.c getpass.c + sleep.c getpass.c sysconf_src.c + +# TESTING -- comment this out if it breaks for you +ifeq ($(TARGET_ARCH), $(NATIVE_ARCH)) + SYSCONF = sysconf_native +else + SYSCONF = sysconf_$(TARGET_ARCH).c +endif + COBJS=$(patsubst %.c,%.o, $(CSRC)) MSRC=gnu_getopt.c @@ -36,13 +43,44 @@ MOBJ=_gnu_getopt_internal.o gnu_getopt_long.o gnu_getopt_long_only.o # over gnu_getopt when appropriate. OBJS=$(COBJS) $(MOBJ) -all: $(OBJS) $(LIBC) +all: $(SYSCONF) $(OBJS) $(LIBC) $(LIBC): ar-target subdirs ar-target: $(OBJS) $(AR) $(ARFLAGS) $(LIBC) $(OBJS) +# We are cross-compiling so use the generic sysconf.c. +sysconf_$(TARGET_ARCH).c: sysconf.c + @echo warning: sysconf_$(NATIVE_ARCH).c is older then sysconf.c so using generic sysconf.c + @echo To build sysconf_$(NATIVE_ARCH).c run gen_sysconf \> sysconf_$(NATIVE_ARCH).c on + @echo your target platform, place in the unistd directory, and rebuild + cp -f sysconf.c sysconf_src.c + +# We are compiling for the native platform, so build an optimized sysconf.c. +sysconf_native: sysconf.c + $(CC) $(CFLAGS) -D_UCLIBC_GENERATE_SYSCONF_ARCH -c sysconf.c -o sysconf_tester.o + $(CC) $(CFLAGS) -D_UCLIBC_GENERATE_SYSCONF_ARCH -c ../sysdeps/linux/common/getpagesize.c -o getpagesize_tester.o + @ld -r -o gen_sysconf_tester.o sysconf_tester.o getpagesize_tester.o + @if nm -s gen_sysconf_tester.o | grep -v "U errno" | grep " U " ;\ + then \ + echo warning: missing symbols in gen_sysconf_tester.o so using generic sysconf.c ;\ + cp -f sysconf.c sysconf_src.c ;\ + else \ + if ../extra/gcc-uClibc/gcc-uClibc-$(NATIVE_ARCH) -static -D_UCLIBC_GENERATE_SYSCONF_MAIN sysconf.c sysconf_tester.o -o gen_sysconf && \ + ./gen_sysconf > sysconf_$(NATIVE_ARCH).c ;\ + then \ + echo successfully built sysconf_$(NATIVE_ARCH).c ;\ + else \ + echo warning: build of gen_sysconf failed so using generic sysconf.c ;\ + cp -f sysconf.c sysconf_$(NATIVE_ARCH).c ;\ + fi ;\ + fi + +sysconf_src.c: sysconf_$(TARGET_ARCH).c + cp -f sysconf_$(TARGET_ARCH).c sysconf_src.c + + $(COBJS): %.o : %.c $(CC) $(CFLAGS) -c $< -o $@ $(STRIPTOOL) -x -R .note -R .comment $*.o @@ -63,5 +101,5 @@ $(patsubst %, _dirclean_%, $(DIRS)) : dummy $(MAKE) -C $(patsubst _dirclean_%, %, $@) clean clean: - rm -f *.[oa] *~ core + rm -f *.[oa] *~ core gen_sysconf sysconf_*.c diff --git a/libc/unistd/sysconf.c b/libc/unistd/sysconf.c index 032311378..5d8c7fc4b 100644 --- a/libc/unistd/sysconf.c +++ b/libc/unistd/sysconf.c @@ -29,6 +29,36 @@ #include #include +/***********************************************************************/ +/* + * Manuel Novoa III Jan 2001 + * + * On i386, the switch-based implementation generates 796 bytes of code. + * However, many of the return values are repeats. By collecting these + * repeats and moving to a table-based implementation, we generate 283 + * bytes on i386 (-Os -fomit-frame-pointer). + */ +#ifndef _UCLIBC_GENERATE_SYSCONF_MAIN + +#ifdef _UCLIBC_GENERATE_SYSCONF_ARCH +/* + * Set some errno's so the auto-gen code knows what it is dealing with. + * 1) ENOSYS signifies that we're returning a default value. + * This is just extra info for development. + * 2) EISNAM signifies that the value returned varies at runtime. + * + * Option: GETPAGESIZE_IS_DYNAMIC + * The current implementation of getpagesize in uClibc returns + * a constant. The pagesize on the target arch should not vary, + * so it should be safe to set this as 0. + */ +#define RETURN_NEG_1 errno = ENOSYS; return -1 +#define RETURN_FUNCTION(f) errno = EISNAM ; return (long int) #f +#define GETPAGESIZE_IS_DYNAMIC 0 +#else +#define RETURN_NEG_1 return -1 +#define RETURN_FUNCTION(f) return f; +#endif /* _UCLIBC_GENERATE_SYSCONF_ARCH */ /* Get the value of the system variable NAME. */ long int sysconf(int name) @@ -43,14 +73,14 @@ long int sysconf(int name) #ifdef ARG_MAX return ARG_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_CHILD_MAX: #ifdef CHILD_MAX return CHILD_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_CLK_TCK: @@ -64,14 +94,14 @@ long int sysconf(int name) #ifdef NGROUPS_MAX return NGROUPS_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_OPEN_MAX: #if 0 - return getdtablesize (); + RETURN_FUNCTION(getdtablesize()); #else - return -1; + RETURN_NEG_1; #endif case _SC_STREAM_MAX: @@ -83,372 +113,376 @@ long int sysconf(int name) case _SC_TZNAME_MAX: #if 0 - return tzname_max (); + RETURN_FUNCTION(tzname_max ()); #else - return -1; + RETURN_NEG_1; #endif case _SC_JOB_CONTROL: #ifdef _POSIX_JOB_CONTROL return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_SAVED_IDS: #ifdef _POSIX_SAVED_IDS return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_REALTIME_SIGNALS: #ifdef _POSIX_REALTIME_SIGNALS return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_PRIORITY_SCHEDULING: #ifdef _POSIX_PRIORITY_SCHEDULING return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_TIMERS: #ifdef _POSIX_TIMERS return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_ASYNCHRONOUS_IO: #ifdef _POSIX_ASYNCHRONOUS_IO return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_PRIORITIZED_IO: #ifdef _POSIX_PRIORITIZED_IO return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_SYNCHRONIZED_IO: #ifdef _POSIX_SYNCHRONIZED_IO return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_FSYNC: #ifdef _POSIX_FSYNC return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_MAPPED_FILES: #ifdef _POSIX_MAPPED_FILES return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_MEMLOCK: #ifdef _POSIX_MEMLOCK return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_MEMLOCK_RANGE: #ifdef _POSIX_MEMLOCK_RANGE return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_MEMORY_PROTECTION: #ifdef _POSIX_MEMORY_PROTECTION return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_MESSAGE_PASSING: #ifdef _POSIX_MESSAGE_PASSING return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_SEMAPHORES: #ifdef _POSIX_SEMAPHORES return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_SHARED_MEMORY_OBJECTS: #ifdef _POSIX_SHARED_MEMORY_OBJECTS return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_VERSION: return _POSIX_VERSION; case _SC_PAGESIZE: - return getpagesize(); +#if defined(GETPAGESIZE_IS_DYNAMIC) && (GETPAGESIZE_IS_DYNAMIC == 1) + RETURN_FUNCTION(getpagesize()); +#else + return getpagesize(); /* note: currently this is not dynamic */ +#endif case _SC_AIO_LISTIO_MAX: #ifdef AIO_LISTIO_MAX return AIO_LISTIO_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_AIO_MAX: #ifdef AIO_MAX return AIO_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_AIO_PRIO_DELTA_MAX: #ifdef AIO_PRIO_DELTA_MAX return AIO_PRIO_DELTA_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_DELAYTIMER_MAX: #ifdef DELAYTIMER_MAX return DELAYTIMER_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_MQ_OPEN_MAX: #ifdef MQ_OPEN_MAX return MQ_OPEN_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_MQ_PRIO_MAX: #ifdef MQ_PRIO_MAX return MQ_PRIO_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_RTSIG_MAX: #ifdef RTSIG_MAX return RTSIG_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_SEM_NSEMS_MAX: #ifdef SEM_NSEMS_MAX return SEM_NSEMS_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_SEM_VALUE_MAX: #ifdef SEM_VALUE_MAX return SEM_VALUE_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_SIGQUEUE_MAX: #ifdef SIGQUEUE_MAX return SIGQUEUE_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_TIMER_MAX: #ifdef TIMER_MAX return TIMER_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_BC_BASE_MAX: #ifdef BC_BASE_MAX return BC_BASE_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_BC_DIM_MAX: #ifdef BC_DIM_MAX return BC_DIM_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_BC_SCALE_MAX: #ifdef BC_SCALE_MAX return BC_SCALE_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_BC_STRING_MAX: #ifdef BC_STRING_MAX return BC_STRING_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_COLL_WEIGHTS_MAX: #ifdef COLL_WEIGHTS_MAX return COLL_WEIGHTS_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_EQUIV_CLASS_MAX: #ifdef EQUIV_CLASS_MAX return EQUIV_CLASS_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_EXPR_NEST_MAX: #ifdef EXPR_NEST_MAX return EXPR_NEST_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_LINE_MAX: #ifdef LINE_MAX return LINE_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_RE_DUP_MAX: #ifdef RE_DUP_MAX return RE_DUP_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_CHARCLASS_NAME_MAX: #ifdef CHARCLASS_NAME_MAX return CHARCLASS_NAME_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_PII: #ifdef _POSIX_PII return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_PII_XTI: #ifdef _POSIX_PII_XTI return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_PII_SOCKET: #ifdef _POSIX_PII_SOCKET return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_PII_INTERNET: #ifdef _POSIX_PII_INTERNET return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_PII_OSI: #ifdef _POSIX_PII_OSI return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_POLL: #ifdef _POSIX_POLL return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_SELECT: #ifdef _POSIX_SELECT return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_UIO_MAXIOV: #ifdef UIO_MAXIOV return UIO_MAXIOV; #else - return -1; + RETURN_NEG_1; #endif case _SC_PII_INTERNET_STREAM: #ifdef _POSIX_PII_INTERNET_STREAM return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_PII_INTERNET_DGRAM: #ifdef _POSIX_PII_INTERNET_DGRAM return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_PII_OSI_COTS: #ifdef _POSIX_PII_OSI_COTS return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_PII_OSI_CLTS: #ifdef _POSIX_PII_OSI_CLTS return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_PII_OSI_M: #ifdef _POSIX_PII_OSI_M return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_T_IOV_MAX: #ifdef _T_IOV_MAX return _T_IOV_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_2_VERSION: @@ -458,63 +492,63 @@ long int sysconf(int name) #ifdef _POSIX2_C_BIND return _POSIX2_C_BIND; #else - return -1; + RETURN_NEG_1; #endif case _SC_2_C_DEV: #ifdef _POSIX2_C_DEV return _POSIX2_C_DEV; #else - return -1; + RETURN_NEG_1; #endif case _SC_2_C_VERSION: #ifdef _POSIX2_C_VERSION return _POSIX2_C_VERSION; #else - return -1; + RETURN_NEG_1; #endif case _SC_2_FORT_DEV: #ifdef _POSIX2_FORT_DEV return _POSIX2_FORT_DEV; #else - return -1; + RETURN_NEG_1; #endif case _SC_2_FORT_RUN: #ifdef _POSIX2_FORT_RUN return _POSIX2_FORT_RUN; #else - return -1; + RETURN_NEG_1; #endif case _SC_2_LOCALEDEF: #ifdef _POSIX2_LOCALEDEF return _POSIX2_LOCALEDEF; #else - return -1; + RETURN_NEG_1; #endif case _SC_2_SW_DEV: #ifdef _POSIX2_SW_DEV return _POSIX2_SW_DEV; #else - return -1; + RETURN_NEG_1; #endif case _SC_2_CHAR_TERM: #ifdef _POSIX2_CHAR_TERM return _POSIX2_CHAR_TERM; #else - return -1; + RETURN_NEG_1; #endif case _SC_2_UPE: #ifdef _POSIX2_UPE return _POSIX2_UPE; #else - return -1; + RETURN_NEG_1; #endif /* POSIX 1003.1c (POSIX Threads). */ @@ -522,140 +556,140 @@ long int sysconf(int name) #ifdef _POSIX_THREADS return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_THREAD_SAFE_FUNCTIONS: #ifdef _POSIX_THREAD_SAFE_FUNCTIONS return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_GETGR_R_SIZE_MAX: #ifdef NSS_BUFLEN_GROUP return NSS_BUFLEN_GROUP; #else - return -1; + RETURN_NEG_1; #endif case _SC_GETPW_R_SIZE_MAX: #ifdef NSS_BUFLEN_PASSWD return NSS_BUFLEN_PASSWD; #else - return -1; + RETURN_NEG_1; #endif case _SC_LOGIN_NAME_MAX: #ifdef _POSIX_LOGIN_NAME_MAX return _POSIX_LOGIN_NAME_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_TTY_NAME_MAX: #ifdef _POSIX_TTY_NAME_MAX return _POSIX_TTY_NAME_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_THREAD_DESTRUCTOR_ITERATIONS: #ifdef _POSIX_THREAD_DESTRUCTOR_ITERATIONS return _POSIX_THREAD_DESTRUCTOR_ITERATIONS; #else - return -1; + RETURN_NEG_1; #endif case _SC_THREAD_KEYS_MAX: #ifdef PTHREAD_KEYS_MAX return PTHREAD_KEYS_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_THREAD_STACK_MIN: #ifdef PTHREAD_STACK_MIN return PTHREAD_STACK_MIN; #else - return -1; + RETURN_NEG_1; #endif case _SC_THREAD_THREADS_MAX: #ifdef PTHREAD_THREADS_MAX return PTHREAD_THREADS_MAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_THREAD_ATTR_STACKADDR: #ifdef _POSIX_THREAD_ATTR_STACKADDR return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_THREAD_ATTR_STACKSIZE: #ifdef _POSIX_THREAD_ATTR_STACKSIZE return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_THREAD_PRIORITY_SCHEDULING: #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_THREAD_PRIO_INHERIT: #ifdef _POSIX_THREAD_PRIO_INHERIT return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_THREAD_PRIO_PROTECT: #ifdef _POSIX_THREAD_PRIO_PROTECT return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_THREAD_PROCESS_SHARED: #ifdef _POSIX_THREAD_PROCESS_SHARED return 1; #else - return -1; + RETURN_NEG_1; #endif case _SC_NPROCESSORS_CONF: #if 0 - return get_nprocs_conf (); + RETURN_FUNCTION(get_nprocs_conf()); #else - return -1; + RETURN_NEG_1; #endif case _SC_NPROCESSORS_ONLN: #if 0 - return get_nprocs (); + RETURN_FUNCTION(get_nprocs()); #else - return -1; + RETURN_NEG_1; #endif case _SC_PHYS_PAGES: #if 0 - return get_phys_pages (); + RETURN_FUNCTION(get_phys_pages()); #else - return -1; + RETURN_NEG_1; #endif case _SC_AVPHYS_PAGES: #if 0 - return get_avphys_pages (); + RETURN_FUNCTION(get_avphys_pages()); #else - return -1; + RETURN_NEG_1; #endif case _SC_ATEXIT_MAX: @@ -679,42 +713,42 @@ long int sysconf(int name) #ifdef _XOPEN_CRYPT return _XOPEN_CRYPT; #else - return -1; + RETURN_NEG_1; #endif case _SC_XOPEN_ENH_I18N: #ifdef _XOPEN_ENH_I18N return _XOPEN_ENH_I18N; #else - return -1; + RETURN_NEG_1; #endif case _SC_XOPEN_SHM: #ifdef _XOPEN_SHM return _XOPEN_SHM; #else - return -1; + RETURN_NEG_1; #endif case _SC_XOPEN_XPG2: #ifdef _XOPEN_XPG2 return _XOPEN_XPG2; #else - return -1; + RETURN_NEG_1; #endif case _SC_XOPEN_XPG3: #ifdef _XOPEN_XPG3 return _XOPEN_XPG3; #else - return -1; + RETURN_NEG_1; #endif case _SC_XOPEN_XPG4: #ifdef _XOPEN_XPG4 return _XOPEN_XPG4; #else - return -1; + RETURN_NEG_1; #endif case _SC_CHAR_BIT: @@ -775,67 +809,67 @@ long int sysconf(int name) #ifdef NL_ARGMAX return NL_ARGMAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_NL_LANGMAX: #ifdef NL_LANGMAX return NL_LANGMAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_NL_MSGMAX: #ifdef NL_MSGMAX return NL_MSGMAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_NL_NMAX: #ifdef NL_NMAX return NL_NMAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_NL_SETMAX: #ifdef NL_SETMAX return NL_SETMAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_NL_TEXTMAX: #ifdef NL_TEXTMAX return NL_TEXTMAX; #else - return -1; + RETURN_NEG_1; #endif case _SC_XBS5_ILP32_OFF32: #ifdef _XBS5_ILP32_OFF32 return _XBS5_ILP32_OFF32; #else - return -1; + RETURN_NEG_1; #endif case _SC_XBS5_ILP32_OFFBIG: #ifdef _XBS5_ILP32_OFFBIG return _XBS5_ILP32_OFFBIG; #else - return -1; + RETURN_NEG_1; #endif case _SC_XBS5_LP64_OFF64: #ifdef _XBS5_LP64_OFF64 return _XBS5_LP64_OFF64; #else - return -1; + RETURN_NEG_1; #endif case _SC_XBS5_LPBIG_OFFBIG: #ifdef _XBS5_LPBIG_OFFBIG return _XBS5_LPBIG_OFFBIG; #else - return -1; + RETURN_NEG_1; #endif case _SC_XOPEN_LEGACY: @@ -845,14 +879,175 @@ long int sysconf(int name) #ifdef _XOPEN_REALTIME return _XOPEN_REALTIME; #else - return -1; + RETURN_NEG_1; #endif case _SC_XOPEN_REALTIME_THREADS: #ifdef _XOPEN_REALTIME_THREADS return _XOPEN_REALTIME_THREADS; #else - return -1; + RETURN_NEG_1; #endif } } +#endif /* _UCLIBC_GENERATE_SYSCONF_MAIN */ +/***********************************************************************/ +#ifdef _UCLIBC_GENERATE_SYSCONF_MAIN + +static long int ret_vals[_UCLIBC_SYSCONF_NUM_VALID_ARGS]; + +static const char *type_str[] = { + "char", "short", "int", "long" +}; + +static const char *type_fmt[] = { " %4ld", " %6ld", " %8ld", " %8ld" }; +static const int type_mod[] = { 13, 9, 6, 6 }; + +static int find_or_add_in_table(int index, long int val, int *table, + int *num_in_table, int add_flag) +{ + int i; + + for (i=0 ; i<*num_in_table ; i++) { + if (ret_vals[table[i]] == val) { + return i; + } + } + if (add_flag) { + table[(*num_in_table)++] = index; + return i; + } else { + return -1; + } +} + + +int main(void) +{ + long int r; + int type_table[5][_UCLIBC_SYSCONF_NUM_VALID_ARGS]; + int ret_type[_UCLIBC_SYSCONF_NUM_VALID_ARGS]; + int num_type[5]; + int i, j, k, code; + + for (i=0 ; i<5 ; i++) { + num_type[i] = 0; + } + + for (i=0; i<_UCLIBC_SYSCONF_NUM_VALID_ARGS ; i++) { + errno = 0; + r = ret_vals[i] = sysconf(i); + switch(errno) { + case EINVAL: /* we're missing a case! */ + fprintf(stderr,"sysconf.c is broken! case %d missing!\n", i); + return EXIT_FAILURE; + case EISNAM: /* function */ + find_or_add_in_table(i,r,type_table[4],num_type+4,1); + ret_type[i] = 4; + break; + case ENOSYS: /* defaults to -1 */ + /* why does this break for shared???? */ + fprintf(stderr,"gen_sysconf advisory --" + "case %d defaults to -1\n", i); + /* fall through */ + case 0: + if ((r>=CHAR_MIN) && (r<=CHAR_MAX)) { + ret_type[i] = 0; + find_or_add_in_table(i,r,type_table[0],num_type+0,1); + } else if ((r>=SHRT_MIN) && (r<=SHRT_MAX)) { + ret_type[i] = 1; + find_or_add_in_table(i,r,type_table[1],num_type+1,1); + } else if ((r>=INT_MIN) && (r<=INT_MAX)) { + ret_type[i] = 2; + find_or_add_in_table(i,r,type_table[2],num_type+2,1); + } else { + ret_type[i] = 3; + find_or_add_in_table(i,r,type_table[3],num_type+3,1); + } + break; + default: + fprintf(stderr,"sysconf.c is broken! errno = %d!\n", errno); + break; + } + } + + printf("#include \n#include \n#include \n\n"); + + printf("static const unsigned char index[%d] = {", + _UCLIBC_SYSCONF_NUM_VALID_ARGS); + for (i=0 ; i<_UCLIBC_SYSCONF_NUM_VALID_ARGS ; i++) { + if (i) printf(","); + if (i%15 == 0) printf("\n"); + code = 0; + for (j=0 ; j<4 ; j++) { + k = find_or_add_in_table(i,ret_vals[i],type_table[j],num_type+j,0); + if (k>=0) { + code += k; + break; + } + code += num_type[j]; + } + printf(" %3d", code); + } + printf("\n};\n\n"); + + for (j=0 ; j < 4 ; j++) { + if (num_type[j]) { + printf("static const %s %s_vals[%d] = {", + type_str[j], type_str[j], num_type[j]); + for (i = 0 ; i= %d)) {\n" + "\t\terrno=EINVAL;\n" + "\t\treturn -1;\n" + "\t}\n\n", _UCLIBC_SYSCONF_NUM_VALID_ARGS); + + printf("\ti = index[name];\n\n"); + k = 0; + for (i=0 ; i<4 ; i++) { + if (num_type[i]) { + if (k>0) { + printf("\ti -= %d;\n", k); + } + printf("\tif (i < %d) {\n" + "\t\treturn %s_vals[i];\n" + "\t}\n\n", + num_type[i], type_str[i]); + k = num_type[i]; + } + } + + if (num_type[4]) { + if (k>0) { + printf("\ti -= %d;\n", k); + } + printf("\tswitch(i) {\n"); + for (i = 0 ; i