X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=ioctlsort.c;h=079f21e59c907c2cd93a269abc013b1a2029d400;hb=3fb78d7305cd5b38bbed2d91b328c3181207b4e9;hp=7881a918c4e2685c543884d93afd50702ee7f077;hpb=30145dda9d7ff70df1d5ad750a183572c73e8963;p=strace diff --git a/ioctlsort.c b/ioctlsort.c index 7881a918..079f21e5 100644 --- a/ioctlsort.c +++ b/ioctlsort.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1991, 1992 Paul Kranenburg - * Copyright (c) 1993, 1994, 1995 Rick Sladkey + * Copyright (c) 2001 Wichert Akkerman + * Copyright (c) 2004-2015 Dmitry V. Levin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,46 +24,141 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $Id$ */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif #include - -#ifdef STDC_HEADERS #include -#endif +#include + +#include "ioctl_iocdef.h" struct ioctlent { - const char *doth; - const char *symbol; - unsigned long code; + const char *info; + const char *name; + unsigned int dir; + unsigned int type_nr; + unsigned int size; }; -#include "ioctlent.raw" +static int +is_prefix(const char *s1, const char *s2) +{ + size_t len = strlen(s1); -int nioctlents = sizeof ioctlent / sizeof ioctlent[0]; + if (len > strlen(s2)) + return 0; + return !memcmp(s1, s2, len); +} -int -compare(a, b) -const void *a; -const void *b; +static int +compare_name_info(const void* a, const void* b) { - unsigned long code1 = ((struct ioctlent *) a)->code; - unsigned long code2 = ((struct ioctlent *) b)->code; - return (code1 > code2) ? 1 : (code1 < code2) ? -1 : 0; + int rc; + + const char *name1 = ((struct ioctlent *) a)->name; + const char *name2 = ((struct ioctlent *) b)->name; + const char *info1 = ((struct ioctlent *) a)->info; + const char *info2 = ((struct ioctlent *) b)->info; + + rc = strcmp(name1, name2); + if (rc) + return rc; + + /* + * exception from lexicographical order: + * "asm/" < "asm-generic/" + */ + if (is_prefix("asm/", info1) && + is_prefix("asm-generic/", info2)) + return -1; + + if (is_prefix("asm/", info2) && + is_prefix("asm-generic/", info1)) + return 1; + + return strcmp(info1, info2); } -int -main(int argc, const char *argv[]) +static unsigned int +code(const struct ioctlent *e) { - int i; + return e->type_nr | + (e->size << _IOC_SIZESHIFT) | + (e->dir << _IOC_DIRSHIFT); +} - qsort(ioctlent, nioctlents, sizeof ioctlent[0], compare); - for (i = 0; i < nioctlents; i++) { - printf("{\"%s\", \"%s\", %#lx},\n", - ioctlent[i].doth, ioctlent[i].symbol, ioctlent[i].code); +static int +compare_code_name(const void* a, const void* b) +{ + unsigned int code1 = code((struct ioctlent *) a); + unsigned int code2 = code((struct ioctlent *) b); + const char *name1 = ((struct ioctlent *) a)->name; + const char *name2 = ((struct ioctlent *) b)->name; + return (code1 > code2) ? + 1 : (code1 < code2) ? -1 : strcmp(name1, name2); +} + +static void +ioctlsort(struct ioctlent *ioctls, size_t nioctls) +{ + size_t i; + + qsort(ioctls, nioctls, sizeof(ioctls[0]), compare_name_info); + + for (i = 1; i < nioctls; ++i) + if (!strcmp(ioctls[i-1].name, ioctls[i].name)) { + /* + * If there are multiple definitions for the same + * name, keep the first one and mark all the rest + * for deletion. + */ + ioctls[i].info = NULL; + } + + for (i = 1; i < nioctls; ++i) + if (!ioctls[i].info) { + /* + * Change ioctl code of marked elements + * to make them sorted to the end of array. + */ + ioctls[i].dir = + ioctls[i].type_nr = + ioctls[i].size = 0xffffffffu; + } + + qsort(ioctls, nioctls, sizeof(ioctls[0]), compare_code_name); + + puts("/* Generated by ioctlsort. */"); + for (i = 0; i < nioctls; ++i) { + if (!ioctls[i].info) { + /* + * We've reached the first element marked for deletion. + */ + break; + } + if (i == 0 || code(&ioctls[i-1]) != code(&ioctls[i]) || + !is_prefix(ioctls[i-1].name, ioctls[i].name)) + printf("{ \"%s\", %#010x },\n", + ioctls[i].name, code(ioctls+i)); } +} + +static struct ioctlent ioctls[] = { +#ifdef IOCTLSORT_INC +# include IOCTLSORT_INC +#else +# include "ioctls_arch.h" +# include "ioctls_inc.h" +#endif +}; + +int +main(void) +{ + ioctlsort(ioctls, sizeof(ioctls) / sizeof(ioctls[0])); return 0; }