You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2020/05/29 20:17:47 UTC
[incubator-nuttx] branch master updated: tools/incdir.c: Add faster,
C version of incdir.sh
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new b111e13 tools/incdir.c: Add faster, C version of incdir.sh
b111e13 is described below
commit b111e135e049e561122b3ec41cd19c4ad8417c44
Author: Gregory Nutt <gn...@nuttx.org>
AuthorDate: Fri May 29 13:19:32 2020 -0600
tools/incdir.c: Add faster, C version of incdir.sh
---
tools/Makefile.host | 15 +-
tools/README.txt | 6 +-
tools/incdir.c | 484 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 500 insertions(+), 5 deletions(-)
diff --git a/tools/Makefile.host b/tools/Makefile.host
index 0b12bec..2531c20 100644
--- a/tools/Makefile.host
+++ b/tools/Makefile.host
@@ -63,14 +63,14 @@ all: b16$(HOSTEXEEXT) bdf-converter$(HOSTEXEEXT) cmpconfig$(HOSTEXEEXT) \
mksymtab$(HOSTEXEEXT) mksyscall$(HOSTEXEEXT) mkversion$(HOSTEXEEXT) \
cnvwindeps$(HOSTEXEEXT) nxstyle$(HOSTEXEEXT) initialconfig$(HOSTEXEEXT) \
gencromfs$(HOSTEXEEXT) convert-comments$(HOSTEXEEXT) lowhex$(HOSTEXEEXT) \
- detab$(HOSTEXEEXT) rmcr$(HOSTEXEEXT)
+ detab$(HOSTEXEEXT) rmcr$(HOSTEXEEXT) incdir$(HOSTEXEEXT)
default: mkconfig$(HOSTEXEEXT) mksyscall$(HOSTEXEEXT) mkdeps$(HOSTEXEEXT) \
- cnvwindeps$(HOSTEXEEXT)
+ cnvwindeps$(HOSTEXEEXT) incdir$(HOSTEXEEXT)
ifdef HOSTEXEEXT
.PHONY: b16 bdf-converter cmpconfig clean configure kconfig2html mkconfig \
mkdeps mksymtab mksyscall mkversion cnvwindeps nxstyle initialconfig \
- gencromfs convert-comments lowhex detab rmcr
+ gencromfs convert-comments lowhex detab rmcr incdir
else
.PHONY: clean
endif
@@ -221,6 +221,15 @@ ifdef HOSTEXEEXT
rmcr: rmcr$(HOSTEXEEXT)
endif
+# incdir - Generate compiler-specific include paths
+
+incdir$(HOSTEXEEXT): incdir.c
+ $(Q) $(HOSTCC) $(HOSTCFLAGS) -o incdir$(HOSTEXEEXT) incdir.c
+
+ifdef HOSTEXEEXT
+incdir: incdir$(HOSTEXEEXT)
+endif
+
# cnvwindeps - Convert dependences generated by a Windows native toolchain
# for use in a Cygwin/POSIX build environment
diff --git a/tools/README.txt b/tools/README.txt
index e824a4e..3a70e56 100644
--- a/tools/README.txt
+++ b/tools/README.txt
@@ -605,8 +605,8 @@ ide_exporter.py
Obsoleted/stm32f429i_disco/ltcd/template and at
Obsoleted/stm3220g-eval/template.
-incdir.sh and incdir.bat
-------------------------
+incdir.sh, incdir.bat, and incdir.c
+-----------------------------------
Different compilers have different conventions for specifying lists
of include file paths on the compiler command line. This incdir.sh
@@ -617,6 +617,8 @@ incdir.sh and incdir.bat
build. However, there is currently only one compiler supported in
that context: MinGW-GCC.
+ incdir.c is a higher performance version of incdir.sh, converted to C.
+
indent.sh
---------
diff --git a/tools/incdir.c b/tools/incdir.c
new file mode 100644
index 0000000..0eaaf43
--- /dev/null
+++ b/tools/incdir.c
@@ -0,0 +1,484 @@
+/****************************************************************************
+ * tools/incdir.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/utsname.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef HOST_CYGWIN
+# include <sys/cygwin.h>
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+enum pathtype_e
+{
+ USER_PATH = 0,
+ SYSTEM_PATH
+};
+
+enum os_e
+{
+ OS_UNKNOWN = 0,
+ OS_LINUX,
+ OS_WINDOWS,
+ OS_CYGWIN,
+ OS_MSYS,
+ OS_WSL,
+ OS_MACOS,
+ OS_BSD
+};
+
+enum compiler_e
+{
+ COMPILER_UNKNOWN = 0,
+ COMPILER_GCC,
+ COMPILER_CLANG,
+ COMPILER_MINGW,
+ COMPILER_SDCC,
+ COMPILER_ZDSII
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void show_advice(const char *progname, int exitcode)
+{
+ fprintf(stderr, "\nUSAGE: %s [-h] [-w] [-s] <compiler-path> "
+ "<dir1> [<dir2> [<dir3> ...]]\n",
+ progname);
+ fprintf(stderr, "Try '%s -h' for more information\n", progname);
+
+ exit(exitcode);
+}
+
+static void show_help(const char *progname, int exitcode)
+{
+ fprintf(stderr, "%s is a tool for flexible generation of include path "
+ "arguments for a\n",
+ progname);
+ fprintf(stderr, "variety of different compilers in a variety of "
+ "compilation environments\n");
+ fprintf(stderr, "\nUSAGE: %s [-w] [-s] <compiler-path> "
+ "<dir1> [<dir2> [<dir3> ...]]\n",
+ progname);
+ fprintf(stderr, " %s -h\n\n", progname);
+
+ fprintf(stderr, "Where:\n");
+ fprintf(stderr, " <compiler-path>\n");
+ fprintf(stderr, " The full path to your compiler\n");
+ fprintf(stderr, " <dir1> [<dir2> [<dir3> ...]]\n");
+ fprintf(stderr, " A list of include directories\n");
+ fprintf(stderr, " -w\n");
+ fprintf(stderr, " The compiler is a Windows native tool and requires "
+ "Windows\n");
+ fprintf(stderr, " style pathnames like C:\\Program Files\n");
+ fprintf(stderr, " -s\n");
+ fprintf(stderr, " Generate standard, system header file paths instead "
+ "of normal user\n");
+ fprintf(stderr, " header file paths.\n");
+ fprintf(stderr, " -h\n");
+ fprintf(stderr, " Shows this help text and exits.\n");
+
+ exit(exitcode);
+}
+
+static enum os_e get_os(const char *ccpath)
+{
+ struct utsname buf;
+ int ret;
+
+ /* Check for MinGW which implies a Windows native environment */
+
+ if (strstr(ccpath, "mingw") != NULL)
+ {
+ return OS_WINDOWS;
+ }
+
+ /* Get the context names */
+
+ ret = uname(&buf);
+ if (ret < 0)
+ {
+ int errcode = errno;
+ fprintf(stderr, "ERROR: uname failed: %s\n", strerror(errcode));
+ exit(EXIT_FAILURE);
+ }
+
+ if (strcmp(buf.sysname, "Linux") == 0)
+ {
+ return OS_LINUX; /* Or OS_WSL */
+ }
+ else if (strncmp(buf.sysname, "CYGWIN", 6) == 0)
+ {
+ return OS_CYGWIN;
+ }
+ else if (strncmp(buf.sysname, "MINGW", 5) == 0)
+ {
+ return OS_CYGWIN;
+ }
+ else if (strncmp(buf.sysname, "MSYS", 4) == 0)
+ {
+ return OS_CYGWIN;
+ }
+ else if (strcmp(buf.sysname, "Darwin") == 0)
+ {
+ return OS_MACOS;
+ }
+ else if (strcmp(buf.sysname, "FreeBSD") == 0 ||
+ strcmp(buf.sysname, "OpenBSD") == 0 ||
+ strcmp(buf.sysname, "GNU/kFreeBSD") == 0)
+ {
+ return OS_BSD;
+ }
+ else
+ {
+ return OS_UNKNOWN;
+ }
+}
+
+static enum compiler_e get_compiler(const char *ccpath, enum os_e os)
+{
+ /* Let's assume that all GCC compiler paths contain the string gcc or
+ * g++ and no non-GCC compiler paths include these substrings
+ */
+
+ if (strstr(ccpath, "gcc") != NULL ||
+ strstr(ccpath, "g++") != NULL)
+ {
+ return COMPILER_GCC;
+ }
+ else if (strstr(ccpath, "clang") != NULL)
+ {
+ return COMPILER_CLANG;
+ }
+ else if (strstr(ccpath, "sdcc") != NULL)
+ {
+ return COMPILER_SDCC;
+ }
+ else if (strstr(ccpath, "mingw") != NULL)
+ {
+ return COMPILER_MINGW;
+ }
+ else if (strstr(ccpath, "ez8cc") != NULL ||
+ strstr(ccpath, "zneocc") != NULL ||
+ strstr(ccpath, "ez80cc") != NULL)
+ {
+ return COMPILER_ZDSII;
+ }
+ else
+ {
+ return COMPILER_UNKNOWN;
+ }
+}
+
+static int my_asprintf(char **strp, const char *fmt, ...)
+{
+ va_list ap;
+ ssize_t bufsize;
+ char *buffer;
+
+ /* Get the size of the buffer */
+
+ va_start(ap, fmt);
+ bufsize = vsnprintf(NULL, 0, fmt, ap);
+ va_end(ap);
+
+ if (bufsize <= 0)
+ {
+ fprintf(stderr, "ERROR: vsnprintf() failed.\n");
+ exit (EXIT_FAILURE);
+ }
+
+ buffer = malloc(bufsize + 1);
+ if (buffer == NULL)
+ {
+ fprintf(stderr, "ERROR: Failed allocated vsnprintf() buffer.\n");
+ exit (EXIT_FAILURE);
+ }
+
+ va_start(ap, fmt);
+ vsnprintf(buffer, bufsize + 1, fmt, ap);
+ va_end(ap);
+
+ *strp = buffer;
+ return bufsize;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, char **argv, char **envp)
+{
+#ifdef HOST_CYGWIN
+ char *convpath = NULL;
+#endif
+ enum pathtype_e pathtype = USER_PATH;
+ enum os_e os;
+ enum compiler_e compiler;
+ const char *progname = argv[0];
+ const char *ccpath;
+ const char *cmdarg;
+ char * const *dirlist;
+ size_t respsize = 0;
+ char *response = NULL;
+ bool wintool = false;
+ int ndirs;
+ int ret;
+ int ch;
+ int i;
+
+ /* Handle command line options */
+
+ while ((ch = getopt(argc, argv, "wsh")) >= 0)
+ {
+ switch (ch)
+ {
+ case 'w':
+ wintool = true;
+ break;
+
+ case 's':
+ pathtype = SYSTEM_PATH;
+ break;
+
+ case 'h':
+ show_help(progname, EXIT_SUCCESS);
+ }
+ }
+
+ if (optind >= argc)
+ {
+ fprintf(stderr, "ERROR: Missing <compiler-path>\n");
+ show_advice(progname, EXIT_FAILURE);
+ }
+
+ ccpath = argv[optind];
+ optind++;
+
+ if (optind >= argc)
+ {
+ fprintf(stderr, "ERROR: At least one directory must be supplied\n");
+ show_advice(progname, EXIT_FAILURE);
+ }
+
+ dirlist = &argv[optind];
+ ndirs = argc - optind;
+
+ /* Most compilers support CFLAG options like '-I<dir>' to add include
+ * file header paths. Some (like the Zilog tools), do not. This script
+ * makes the selection of header file paths compiler independent.
+ *
+ * Below are all known compiler names (as found in the board/ Make.defs
+ * files). If a new compiler is used that has some unusual syntax, then
+ * additional logic needs to be added to this file.
+ *
+ * NAME Syntax
+ * $(CROSSDEV)gcc -I<dir1> -I<dir2> -I<dir3> ...
+ * sdcc -I<dir2> -I<dir2> -I<dir3> ...
+ * $(ZDSBINDIR)/ez8cc.exe -usrinc:'<dir1>:<dir2>:<dir3>:...`
+ * $(ZDSBINDIR)/zneocc.exe -usrinc:'<dir1>:<dir2>:<dir3>:...`
+ * $(ZDSBINDIR)/ez80cc.exe -usrinc:'<dir1>:<dir2>:<dir3>:...`
+ *
+ * Furthermore, just to make matters more difficult, with Windows based
+ * toolchains, we have to use the full windows-style paths to the header
+ * files.
+ */
+
+ os = get_os(ccpath);
+ if (os == OS_UNKNOWN)
+ {
+ fprintf(stderr, "ERROR: Operating system not recognized.\n");
+ show_advice(progname, EXIT_FAILURE);
+ }
+
+ compiler = get_compiler(ccpath, os);
+ if (compiler == COMPILER_UNKNOWN)
+ {
+ fprintf(stderr, "ERROR: Compiler not recognized.\n");
+ show_advice(progname, EXIT_FAILURE);
+ }
+
+ /* Select system or user header file path command line option */
+
+ if (compiler == COMPILER_ZDSII)
+ {
+ cmdarg = (pathtype == SYSTEM_PATH) ? "-stdinc:" : "-usrinc:";
+ wintool = true;
+ }
+ else
+ {
+ cmdarg = (pathtype == SYSTEM_PATH) ? "-isystem" : "-I";
+ }
+
+ /* Now process each directory in the directory list */
+
+ for (i = 0; i < ndirs; i++)
+ {
+ const char *dirname;
+ const char *incpath;
+ char *saveresp;
+ char *segment = NULL;
+ size_t segsize;
+
+ dirname = dirlist[i];
+
+#ifdef HOST_CYGWIN
+ /* Check if the path needs to be extended for Windows-based tools under
+ * Cygwin:
+ *
+ * wintool == true: The platform is Cygwin and we are using a windows
+ * native tool
+ */
+
+ if (os == OS_CYGWIN && wintool)
+ {
+ ssize_t bufsize;
+
+ bufsize = cygwin_conv_path(CCP_POSIX_TO_WIN_A, dirname, NULL, 0);
+ convpath = (char *)malloc(bufsize);
+ if (convpath == NULL)
+ {
+ fprintf(stderr, "ERROR: Faile to allocate buffer.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ (void)cygwin_conv_path(CCP_POSIX_TO_WIN_A, dirname, convpath,
+ bufsize);
+ incpath = convpath;
+ }
+ else
+#endif
+ {
+ incpath = dirname;
+ }
+
+ /* Handle the output using the selected format */
+
+ if (compiler == COMPILER_ZDSII)
+ {
+ /* FORM: -stdinc: 'dir1;dir2;...;dirN'
+ * -usrinc: 'dir1;dir2;...;dirN'
+ */
+
+ /* Treat the first directory differently */
+
+ if (response == NULL)
+ {
+ if (i == ndirs - 1)
+ {
+ ret = my_asprintf(&segment, "%s '%s'", cmdarg, incpath);
+ }
+ else
+ {
+ ret = my_asprintf(&segment, "%s '%s", cmdarg, incpath);
+ }
+ }
+ else
+ {
+ if (i == ndirs - 1)
+ {
+ ret = my_asprintf(&segment, ";%s'", incpath);
+ }
+ else
+ {
+ ret = my_asprintf(&segment, ";%s", incpath);
+ }
+ }
+ }
+ else
+ {
+ /* FORM: -isystem: "dir1" -isystem "dir2" ... -isystem "dirN"
+ * -I: "dir1" -I "dir2" ... -I "dirN"
+ */
+
+ /* Treat the first directory differently */
+
+ if (response == NULL)
+ {
+ ret = my_asprintf(&segment, "%s \"%s\"", cmdarg, incpath);
+ }
+ else
+ {
+ ret = my_asprintf(&segment, " %s \"%s\"", cmdarg, incpath);
+ }
+ }
+
+ if (ret < 0)
+ {
+ fprintf(stderr, "ERROR: my_asprintf failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Append the new response segment */
+
+ saveresp = response;
+ segsize = ret;
+ respsize += (response == NULL) ? segsize + 1 : segsize;
+
+ response = (char *)malloc(respsize);
+ if (response == NULL)
+ {
+ fprintf(stderr, "ERROR: Failed to allocate response.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (saveresp == NULL)
+ {
+ strncpy(response, segment, respsize);
+ }
+ else
+ {
+ snprintf(response, respsize, "%s%s", saveresp, segment);
+ }
+
+ /* Clean up for the next pass */
+
+ if (segment != NULL)
+ {
+ free(segment);
+ segment = NULL;
+ }
+
+#ifdef HOST_CYGWIN
+ if (convpath != NULL)
+ {
+ free(convpath);
+ convpath = NULL;
+ }
+#endif
+ }
+
+ fputs(response, stdout);
+ return EXIT_SUCCESS;
+}