mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-20 15:13:34 +08:00
Merge NuttX r5527
This commit is contained in:
+36
-17
@@ -37,31 +37,41 @@ TOPDIR ?= ${shell pwd}/..
|
||||
-include $(TOPDIR)/Make.defs
|
||||
include ${TOPDIR}/tools/Config.mk
|
||||
|
||||
# Define HOSTCC on the make command line if it differs from these defaults
|
||||
# Define HOSTCFLAGS with -g on the make command line to build debug versions
|
||||
|
||||
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||
|
||||
# In the Windows native environment, the MinGW GCC compiler is assumed
|
||||
|
||||
HOSTCC ?= mingw-gcc.exe
|
||||
HOSTCFLAGS ?= -O2 -Wall -Wstrict-prototypes -Wshadow -I. -DCONFIG_WINDOWS_NATIVE=y
|
||||
|
||||
else
|
||||
|
||||
# GCC is assumed in the POSIX environment.
|
||||
# strtok_r is used in some tools, but does not seem to be available in
|
||||
# the MinGW environment.
|
||||
|
||||
ifneq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||
HOSTCFLAGS += -D HAVE_STRTOK_C
|
||||
HOSTCC ?= gcc
|
||||
HOSTCFLAGS ?= -O2 -Wall -Wstrict-prototypes -Wshadow -I. -DHAVE_STRTOK_C
|
||||
|
||||
endif
|
||||
|
||||
# Targets
|
||||
|
||||
all: b16$(HOSTEXEEXT) bdf-converter$(HOSTEXEEXT) cmpconfig$(HOSTEXEEXT) \
|
||||
mkconfig$(HOSTEXEEXT) mkdeps$(HOSTEXEEXT) mksymtab$(HOSTEXEEXT) \
|
||||
configure$(HOSTEXEEXT) mkconfig$(HOSTEXEEXT) mkdeps$(HOSTEXEEXT) mksymtab$(HOSTEXEEXT) \
|
||||
mksyscall$(HOSTEXEEXT) mkversion$(HOSTEXEEXT)
|
||||
default: mkconfig$(HOSTEXEEXT) mksyscall$(HOSTEXEEXT) mkdeps$(HOSTEXEEXT)
|
||||
|
||||
ifdef HOSTEXEEXT
|
||||
.PHONY: b16 bdf-converter cmpconfig clean mkconfig mkdeps mksymtab \
|
||||
mksyscall mkversion
|
||||
.PHONY: b16 bdf-converter cmpconfig clean configure mkconfig mkdeps mksymtab mksyscall mkversion
|
||||
else
|
||||
.PHONY: clean
|
||||
endif
|
||||
|
||||
# Add HOSTCFLAGS=-g on the make command line build debug versions
|
||||
|
||||
HOSTCFLAGS ?= -O2 -Wall -I.
|
||||
HOSTCC ?= gcc
|
||||
|
||||
# b16 - Fixed precision math converstion tool
|
||||
# b16 - Fixed precision math conversion tool
|
||||
|
||||
b16$(HOSTEXEEXT): b16.c
|
||||
$(Q) $(HOSTCC) $(HOSTCFLAGS) -o b16$(HOSTEXEEXT) b16.c
|
||||
@@ -70,10 +80,19 @@ ifdef HOSTEXEEXT
|
||||
b16: b16$(HOSTEXEEXT)
|
||||
endif
|
||||
|
||||
# configure - Instantiate a canned NuttX configuration
|
||||
|
||||
configure$(HOSTEXEEXT): configure.c cfgparser.c
|
||||
$(Q) $(HOSTCC) $(HOSTCFLAGS) -o configure$(HOSTEXEEXT) configure.c cfgparser.c
|
||||
|
||||
ifdef HOSTEXEEXT
|
||||
configure: configure$(HOSTEXEEXT)
|
||||
endif
|
||||
|
||||
# mkconfig - Convert a .config file into a C config.h file
|
||||
|
||||
mkconfig$(HOSTEXEEXT): mkconfig.c cfgparser.c
|
||||
$(Q) $(HOSTCC) $(HOSTCFLAGS) -o mkconfig$(HOSTEXEEXT) mkconfig.c cfgparser.c
|
||||
mkconfig$(HOSTEXEEXT): mkconfig.c cfgdefine.c
|
||||
$(Q) $(HOSTCC) $(HOSTCFLAGS) -o mkconfig$(HOSTEXEEXT) mkconfig.c cfgdefine.c
|
||||
|
||||
ifdef HOSTEXEEXT
|
||||
mkconfig: mkconfig$(HOSTEXEEXT)
|
||||
@@ -81,8 +100,8 @@ endif
|
||||
|
||||
# cmpconfig - Compare the contents of two configuration files
|
||||
|
||||
cmpconfig$(HOSTEXEEXT): cmpconfig.c
|
||||
$(Q) $(HOSTCC) $(HOSTCFLAGS) -o cmpconfig$(HOSTEXEEXT) cmpconfig.c
|
||||
cmpconfig$(HOSTEXEEXT): cmpconfig.c cfgparser.c
|
||||
$(Q) $(HOSTCC) $(HOSTCFLAGS) -o cmpconfig$(HOSTEXEEXT) cmpconfig.c cfgparser.c
|
||||
|
||||
ifdef HOSTEXEEXT
|
||||
cmpconfig: cmpconfig$(HOSTEXEEXT)
|
||||
@@ -90,8 +109,8 @@ endif
|
||||
|
||||
# mkversion - Convert a .version file into a C version.h file
|
||||
|
||||
mkversion$(HOSTEXEEXT): mkconfig.c cfgparser.c
|
||||
$(Q) $(HOSTCC) $(HOSTCFLAGS) -o mkversion$(HOSTEXEEXT) mkversion.c cfgparser.c
|
||||
mkversion$(HOSTEXEEXT): mkconfig.c cfgdefine.c
|
||||
$(Q) $(HOSTCC) $(HOSTCFLAGS) -o mkversion$(HOSTEXEEXT) mkversion.c cfgdefine.c
|
||||
|
||||
ifdef HOSTEXEEXT
|
||||
mkversion: mkversion$(HOSTEXEEXT)
|
||||
|
||||
+57
-4
@@ -26,19 +26,42 @@ Config.mk
|
||||
override these default definitions as necessary.
|
||||
|
||||
configure.sh
|
||||
configure.bat
|
||||
configure.c, cfgparser.c, and cfgparser.h
|
||||
------------
|
||||
|
||||
This is a bash script that is used to configure NuttX for a given
|
||||
target board. See configs/README.txt or Documentation/NuttxPortingGuide.html
|
||||
configure.sh is a bash script that is used to configure NuttX for a given
|
||||
target board in a environment that supports POSIX paths (Linux, Cygwin,
|
||||
OSX, or similar). See configs/README.txt or Documentation/NuttxPortingGuide.html
|
||||
for a description of how to configure NuttX with this script.
|
||||
|
||||
configure.c, cfgparser.c, and cfgparser.h can be used to build a work-alike
|
||||
program as a replacement for configure.sh. This work-alike program would be
|
||||
used in environments that do not support Bash scripting (such as the Windows
|
||||
native environment).
|
||||
|
||||
configure.bat is a small Windows batch file that can be used as a replacement
|
||||
for configure.sh in a Windows native environment. configure.bat is actually
|
||||
just a thin layer that execuates configure.exe if it is available. If
|
||||
configure.exe is not available, then configure.bat will attempt to build it
|
||||
first.
|
||||
|
||||
In order two build configure.exe from configure.c in the Windows native
|
||||
environment, two assumptions are made:
|
||||
|
||||
1) You have installed the MinGW GCC toolchain. This toolchain can be
|
||||
downloaded from http://www.mingw.org/. Tt is recommended the you not
|
||||
install the optional MSYS components as there may be conflicts.
|
||||
2) That path to bin bin/ directory containing mingw-gcc.exe must be
|
||||
included in the PATH variable.
|
||||
|
||||
discover.py
|
||||
-----------
|
||||
|
||||
Example script for discovering devices in the local network.
|
||||
It is the counter part to apps/netutils/discover
|
||||
|
||||
mkconfig.c, cfgparser.c, and cfgparser.h
|
||||
mkconfig.c, cfgdefine.c, and cfgdefine.h
|
||||
----------------------------------------
|
||||
|
||||
These are Cs file that are used to build mkconfig program. The mkconfig
|
||||
@@ -79,7 +102,7 @@ mkfsdata.pl
|
||||
NOTE: This perl script comes from uIP and was (probably) written
|
||||
by Adam Dunkels. uIP has a license that is compatible with NuttX.
|
||||
|
||||
mkversion.c, cfgparser.c, and cfgparser.h
|
||||
mkversion.c, cfgdefine.c, and cfgdefine.h
|
||||
-----------------------------------------
|
||||
|
||||
This is C file that is used to build mkversion program. The mkversion
|
||||
@@ -413,6 +436,36 @@ unlink.bat
|
||||
NTFS mklink.exe command instead of copying files. That logic, however,
|
||||
has not been verified as of this writing.
|
||||
|
||||
kconfig.bat
|
||||
-----------
|
||||
|
||||
Recent versions of NuttX support building NuttX from a native Windows
|
||||
CMD.exe shell. But kconfig-frontends is a Linux tool and is not yet
|
||||
available in the pure CMD.exe environment. At this point, there are
|
||||
only a few options for the Windows user (see the top-level README.txt
|
||||
file).
|
||||
|
||||
You can, with some effort, run the the Cygwin kconfig-mconf tool directly
|
||||
in the CMD.exe shell. In this case, you do not have to modify the
|
||||
.config file, but there are other complexities: You need to
|
||||
temporarily set the Cgywin directories in the PATH variable and
|
||||
then run kconfig-mconf outside of the Make system.
|
||||
|
||||
kconfig.bat is a Windows batch file at tools/kconfig.bat that automates
|
||||
these steps. It is used from the top-level NuttX directory like:
|
||||
|
||||
tools/kconfig menuconfig
|
||||
|
||||
NOTE: There is an currently an issue with accessing DOS environment
|
||||
variables from the Cygwin kconfig-mconf running in the CMD.exe shell.
|
||||
The following change to the top-level Kconfig file seems to work around
|
||||
these problems:
|
||||
|
||||
config APPSDIR
|
||||
string
|
||||
- option env="APPSDIR"
|
||||
+ default "../apps"
|
||||
|
||||
mkimage.sh
|
||||
----------
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
/****************************************************************************
|
||||
* tools/cfgdefine.c
|
||||
*
|
||||
* Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "cfgdefine.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
char line[LINESIZE+1];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* These are configuration variable name that are quoted by configuration tool
|
||||
* but which must be unquoted when used in C code.
|
||||
*/
|
||||
|
||||
static const char *dequote_list[] =
|
||||
{
|
||||
/* NuttX */
|
||||
|
||||
"CONFIG_USER_ENTRYPOINT", /* Name of entry point function */
|
||||
"CONFIG_EXECFUNCS_SYMTAB", /* Symbol table used by exec[l|v] */
|
||||
|
||||
/* NxWidgets/NxWM */
|
||||
|
||||
"CONFIG_NXWM_BACKGROUND_IMAGE", /* Name of bitmap image class */
|
||||
"CONFIG_NXWM_STARTWINDOW_ICON", /* Name of bitmap image class */
|
||||
"CONFIG_NXWM_NXCONSOLE_ICON", /* Name of bitmap image class */
|
||||
"CONFIG_NXWM_CALIBRATION_ICON", /* Name of bitmap image class */
|
||||
"CONFIG_NXWM_HEXCALCULATOR_ICON", /* Name of bitmap image class */
|
||||
|
||||
NULL /* Marks the end of the list */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Skip over any spaces */
|
||||
|
||||
static char *skip_space(char *ptr)
|
||||
{
|
||||
while (*ptr && isspace((int)*ptr)) ptr++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Find the end of a variable string */
|
||||
|
||||
static char *find_name_end(char *ptr)
|
||||
{
|
||||
while (*ptr && (isalnum((int)*ptr) || *ptr == '_')) ptr++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Find the end of a value string */
|
||||
|
||||
static char *find_value_end(char *ptr)
|
||||
{
|
||||
while (*ptr && !isspace((int)*ptr))
|
||||
{
|
||||
if (*ptr == '"')
|
||||
{
|
||||
do ptr++; while (*ptr && *ptr != '"');
|
||||
if (*ptr) ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
do ptr++; while (*ptr && !isspace((int)*ptr) && *ptr != '"');
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Read the next line from the configuration file */
|
||||
|
||||
static char *read_line(FILE *stream)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
line[LINESIZE] = '\0';
|
||||
if (!fgets(line, LINESIZE, stream))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = skip_space(line);
|
||||
if (*ptr && *ptr != '#' && *ptr != '\n')
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the line from the configuration file into a variable name
|
||||
* string and a value string.
|
||||
*/
|
||||
|
||||
static void parse_line(char *ptr, char **varname, char **varval)
|
||||
{
|
||||
/* Skip over any leading spaces */
|
||||
|
||||
ptr = skip_space(ptr);
|
||||
|
||||
/* The first no-space is the beginning of the variable name */
|
||||
|
||||
*varname = skip_space(ptr);
|
||||
*varval = NULL;
|
||||
|
||||
/* Parse to the end of the variable name */
|
||||
|
||||
ptr = find_name_end(ptr);
|
||||
|
||||
/* An equal sign is expected next, perhaps after some white space */
|
||||
|
||||
if (*ptr && *ptr != '=')
|
||||
{
|
||||
/* Some else follows the variable name. Terminate the variable
|
||||
* name and skip over any spaces.
|
||||
*/
|
||||
|
||||
*ptr = '\0';
|
||||
ptr = skip_space(ptr + 1);
|
||||
}
|
||||
|
||||
/* Verify that the equal sign is present */
|
||||
|
||||
if (*ptr == '=')
|
||||
{
|
||||
/* Make sure that the variable name is terminated (this was already
|
||||
* done if the name was followed by white space.
|
||||
*/
|
||||
|
||||
*ptr = '\0';
|
||||
|
||||
/* The variable value should follow =, perhaps separated by some
|
||||
* white space.
|
||||
*/
|
||||
|
||||
ptr = skip_space(ptr + 1);
|
||||
if (*ptr)
|
||||
{
|
||||
/* Yes.. a variable follows. Save the pointer to the start
|
||||
* of the variable string.
|
||||
*/
|
||||
|
||||
*varval = ptr;
|
||||
|
||||
/* Find the end of the variable string and make sure that it
|
||||
* is terminated.
|
||||
*/
|
||||
|
||||
ptr = find_value_end(ptr);
|
||||
*ptr = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *dequote_value(const char *varname, char *varval)
|
||||
{
|
||||
const char **dqnam;
|
||||
char *dqval = varval;
|
||||
int len;
|
||||
|
||||
if (dqval)
|
||||
{
|
||||
/* Check if the variable name is in the list of strings to be dequoated */
|
||||
|
||||
for (dqnam = dequote_list; *dqnam; dqnam++)
|
||||
{
|
||||
if (strcmp(*dqnam, varname) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we find the variable name in the list of configuration variables
|
||||
* to be dequoated?
|
||||
*/
|
||||
|
||||
if (*dqnam)
|
||||
{
|
||||
/* Yes... Check if there is a traiing quote */
|
||||
|
||||
len = strlen(dqval);
|
||||
if (dqval[len-1] == '"')
|
||||
{
|
||||
/* Yes... replace it with a terminator */
|
||||
|
||||
dqval[len-1] = '\0';
|
||||
len--;
|
||||
}
|
||||
|
||||
/* Is there a leading quote? */
|
||||
|
||||
if (dqval[0] == '"')
|
||||
{
|
||||
/* Yes.. skip over the leading quote */
|
||||
|
||||
dqval++;
|
||||
len--;
|
||||
}
|
||||
|
||||
/* Handle the case where nothing is left after dequoting */
|
||||
|
||||
if (len <= 0)
|
||||
{
|
||||
dqval = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dqval;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
void generate_definitions(FILE *stream)
|
||||
{
|
||||
char *varname;
|
||||
char *varval;
|
||||
char *ptr;
|
||||
|
||||
/* Loop until the entire file has been parsed. */
|
||||
|
||||
do
|
||||
{
|
||||
/* Read the next line from the file */
|
||||
|
||||
ptr = read_line(stream);
|
||||
if (ptr)
|
||||
{
|
||||
/* Parse the line into a variable and a value field */
|
||||
|
||||
parse_line(ptr, &varname, &varval);
|
||||
|
||||
/* Was a variable name found? */
|
||||
|
||||
if (varname)
|
||||
{
|
||||
/* Yes.. dequote the value if necessary */
|
||||
|
||||
varval = dequote_value(varname, varval);
|
||||
|
||||
/* If no value was provided or if the special value 'n' was provided,
|
||||
* then undefine the configuration variable.
|
||||
*/
|
||||
|
||||
if (!varval || strcmp(varval, "n") == 0)
|
||||
{
|
||||
printf("#undef %s\n", varname);
|
||||
}
|
||||
|
||||
/* Simply define the configuration variable if it has the special
|
||||
* value "y"
|
||||
*/
|
||||
|
||||
else if (strcmp(varval, "y") == 0)
|
||||
{
|
||||
printf("#define %s 1\n", varname);
|
||||
}
|
||||
|
||||
/* Otherwise, use the value as provided */
|
||||
|
||||
else
|
||||
{
|
||||
printf("#define %s %s\n", varname, varval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (ptr);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
* tools/cfgdefine.h
|
||||
*
|
||||
* Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __TOOLS_CFGDEFINE_H
|
||||
#define __TOOLS_CFGDEFINE_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define LINESIZE ( PATH_MAX > 256 ? PATH_MAX : 256 )
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
extern char line[LINESIZE+1];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
void generate_definitions(FILE *stream);
|
||||
|
||||
#endif /* __TOOLS_CFGDEFINE_H */
|
||||
+68
-94
@@ -38,7 +38,9 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "cfgparser.h"
|
||||
|
||||
/****************************************************************************
|
||||
@@ -55,28 +57,7 @@ char line[LINESIZE+1];
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* These are configuration variable name that are quoted by configuration tool
|
||||
* but which must be unquoted when used in C code.
|
||||
*/
|
||||
|
||||
static const char *dequote_list[] =
|
||||
{
|
||||
/* NuttX */
|
||||
|
||||
"CONFIG_USER_ENTRYPOINT", /* Name of entry point function */
|
||||
|
||||
/* NxWidgets/NxWM */
|
||||
|
||||
"CONFIG_NXWM_BACKGROUND_IMAGE", /* Name of bitmap image class */
|
||||
"CONFIG_NXWM_STARTWINDOW_ICON", /* Name of bitmap image class */
|
||||
"CONFIG_NXWM_NXCONSOLE_ICON", /* Name of bitmap image class */
|
||||
"CONFIG_NXWM_CALIBRATION_ICON", /* Name of bitmap image class */
|
||||
"CONFIG_NXWM_HEXCALCULATOR_ICON", /* Name of bitmap image class */
|
||||
|
||||
NULL /* Marks the end of the list */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
@@ -203,69 +184,15 @@ static void parse_line(char *ptr, char **varname, char **varval)
|
||||
}
|
||||
}
|
||||
|
||||
static char *dequote_value(const char *varname, char *varval)
|
||||
{
|
||||
const char **dqnam;
|
||||
char *dqval = varval;
|
||||
int len;
|
||||
|
||||
if (dqval)
|
||||
{
|
||||
/* Check if the variable name is in the list of strings to be dequoated */
|
||||
|
||||
for (dqnam = dequote_list; *dqnam; dqnam++)
|
||||
{
|
||||
if (strcmp(*dqnam, varname) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we find the variable name in the list of configuration variables
|
||||
* to be dequoated?
|
||||
*/
|
||||
|
||||
if (*dqnam)
|
||||
{
|
||||
/* Yes... Check if there is a traiing quote */
|
||||
|
||||
len = strlen(dqval);
|
||||
if (dqval[len-1] == '"')
|
||||
{
|
||||
/* Yes... replace it with a terminator */
|
||||
|
||||
dqval[len-1] = '\0';
|
||||
len--;
|
||||
}
|
||||
|
||||
/* Is there a leading quote? */
|
||||
|
||||
if (dqval[0] == '"')
|
||||
{
|
||||
/* Yes.. skip over the leading quote */
|
||||
|
||||
dqval++;
|
||||
len--;
|
||||
}
|
||||
|
||||
/* Handle the case where nothing is left after dequoting */
|
||||
|
||||
if (len <= 0)
|
||||
{
|
||||
dqval = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dqval;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
void parse_file(FILE *stream)
|
||||
void parse_file(FILE *stream, struct variable_s **list)
|
||||
{
|
||||
struct variable_s *curr;
|
||||
struct variable_s *prev;
|
||||
struct variable_s *next;
|
||||
char *varname;
|
||||
char *varval;
|
||||
char *ptr;
|
||||
@@ -283,40 +210,87 @@ void parse_file(FILE *stream)
|
||||
|
||||
parse_line(ptr, &varname, &varval);
|
||||
|
||||
/* Was a variable name found? */
|
||||
/* If the variable has not value (or the special value 'n'), then
|
||||
* ignore it.
|
||||
*/
|
||||
|
||||
if (!varval || strcmp(varval, "n") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Make sure that a variable name was found. */
|
||||
|
||||
if (varname)
|
||||
{
|
||||
/* Yes.. dequote the value if necessary */
|
||||
int varlen = strlen(varname) + 1;
|
||||
int vallen = 0;
|
||||
|
||||
varval = dequote_value(varname, varval);
|
||||
|
||||
/* If no value was provided or if the special value 'n' was provided,
|
||||
* then undefine the configuration variable.
|
||||
/* Get the size of the value, including the NUL terminating
|
||||
* character.
|
||||
*/
|
||||
|
||||
if (!varval || strcmp(varval, "n") == 0)
|
||||
if (varval)
|
||||
{
|
||||
printf("#undef %s\n", varname);
|
||||
vallen = strlen(varval) + 1;
|
||||
}
|
||||
|
||||
/* Simply define the configuration variable if it has the special
|
||||
* value "y"
|
||||
/* Allocate memory to hold the struct variable_s with the
|
||||
* variable name and the value.
|
||||
*/
|
||||
|
||||
else if (strcmp(varval, "y") == 0)
|
||||
curr = (struct variable_s *)malloc(sizeof(struct variable_s) + varlen + vallen - 1);
|
||||
if (curr)
|
||||
{
|
||||
printf("#define %s 1\n", varname);
|
||||
/* Add the variable to the list */
|
||||
|
||||
curr->var = &curr->storage[0];
|
||||
strcpy(curr->var, varname);
|
||||
|
||||
curr->val = NULL;
|
||||
if (varval)
|
||||
{
|
||||
curr->val = &curr->storage[varlen];
|
||||
strcpy(curr->val, varval);
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, use the value as provided */
|
||||
prev = 0;
|
||||
next = *list;
|
||||
while (next && strcmp(next->var, curr->var) <= 0)
|
||||
{
|
||||
prev = next;
|
||||
next = next->flink;
|
||||
}
|
||||
|
||||
if (prev)
|
||||
{
|
||||
prev->flink = curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("#define %s %s\n", varname, varval);
|
||||
*list = curr;
|
||||
}
|
||||
|
||||
curr->flink = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (ptr);
|
||||
}
|
||||
|
||||
struct variable_s *find_variable(const char *varname, struct variable_s *list)
|
||||
{
|
||||
while (list)
|
||||
{
|
||||
if (strcmp(varname, list->var) == 0)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
list = list->flink;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -49,6 +49,18 @@
|
||||
|
||||
#define LINESIZE ( PATH_MAX > 256 ? PATH_MAX : 256 )
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct variable_s
|
||||
{
|
||||
struct variable_s *flink;
|
||||
char *var;
|
||||
char *val;
|
||||
char storage[1];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
@@ -59,6 +71,7 @@ extern char line[LINESIZE+1];
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
extern void parse_file(FILE *stream);
|
||||
void parse_file(FILE *stream, struct variable_s **list);
|
||||
struct variable_s *find_variable(const char *varname, struct variable_s *list);
|
||||
|
||||
#endif /* __TOOLS_CFGPARSER_H */
|
||||
|
||||
+6
-155
@@ -43,6 +43,8 @@
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "cfgparser.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
@@ -51,14 +53,6 @@
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct variable_s
|
||||
{
|
||||
struct variable_s *flink;
|
||||
char *var;
|
||||
char *val;
|
||||
char storage[1];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@@ -69,154 +63,11 @@ static void show_usage(const char *progname)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static char *skip_space(char *ptr)
|
||||
{
|
||||
while (*ptr && isspace((int)*ptr)) ptr++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char *read_line(FILE *stream, char *line, int len)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
line[len-1] = '\0';
|
||||
if (!fgets(line, len, stream))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = skip_space(line);
|
||||
if (*ptr && *ptr != '#' && *ptr != '\n')
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *find_name_end(char *ptr)
|
||||
{
|
||||
while (*ptr && (isalnum((int)*ptr) || *ptr == '_')) ptr++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char *find_value_end(char *ptr)
|
||||
{
|
||||
while (*ptr && !isspace((int)*ptr))
|
||||
{
|
||||
if (*ptr == '"')
|
||||
{
|
||||
do ptr++; while (*ptr && *ptr != '"');
|
||||
if (*ptr) ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
do ptr++; while (*ptr && !isspace((int)*ptr) && *ptr != '"');
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void parse_line(char *ptr, char **varname, char **varval)
|
||||
{
|
||||
*varname = ptr;
|
||||
*varval = NULL;
|
||||
|
||||
ptr = find_name_end(ptr);
|
||||
if (*ptr && *ptr != '=')
|
||||
{
|
||||
*ptr = '\0';
|
||||
ptr = skip_space(ptr + 1);
|
||||
}
|
||||
|
||||
if (*ptr == '=')
|
||||
{
|
||||
*ptr = '\0';
|
||||
ptr = skip_space(ptr + 1);
|
||||
if (*ptr)
|
||||
{
|
||||
*varval = ptr;
|
||||
ptr = find_value_end(ptr);
|
||||
*ptr = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_file(FILE *stream, struct variable_s **list)
|
||||
{
|
||||
char line[10242];
|
||||
struct variable_s *curr;
|
||||
struct variable_s *prev;
|
||||
struct variable_s *next;
|
||||
char *varname;
|
||||
char *varval;
|
||||
char *ptr;
|
||||
|
||||
do
|
||||
{
|
||||
ptr = read_line(stream, line, 1024);
|
||||
if (ptr)
|
||||
{
|
||||
parse_line(ptr, &varname, &varval);
|
||||
if (!varval || strcmp(varval, "n") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (varname)
|
||||
{
|
||||
int varlen = strlen(varname) + 1;
|
||||
int vallen = 0;
|
||||
|
||||
if (varval)
|
||||
{
|
||||
vallen = strlen(varval) + 1;
|
||||
}
|
||||
|
||||
curr = (struct variable_s *)malloc(sizeof(struct variable_s) + varlen + vallen - 1);
|
||||
if (curr)
|
||||
{
|
||||
curr->var = &curr->storage[0];
|
||||
strcpy(curr->var, varname);
|
||||
|
||||
curr->val = NULL;
|
||||
if (varval)
|
||||
{
|
||||
curr->val = &curr->storage[varlen];
|
||||
strcpy(curr->val, varval);
|
||||
}
|
||||
}
|
||||
|
||||
prev = 0;
|
||||
next = *list;
|
||||
while (next && strcmp(next->var, curr->var) <= 0)
|
||||
{
|
||||
prev = next;
|
||||
next = next->flink;
|
||||
}
|
||||
|
||||
if (prev)
|
||||
{
|
||||
prev->flink = curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
*list = curr;
|
||||
}
|
||||
curr->flink = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (ptr);
|
||||
}
|
||||
|
||||
static void compare_variables(struct variable_s *list1, struct variable_s *list2)
|
||||
{
|
||||
char *varval1;
|
||||
char *varval2;
|
||||
int result;
|
||||
|
||||
while (list1 || list2)
|
||||
{
|
||||
@@ -252,7 +103,7 @@ static void compare_variables(struct variable_s *list1, struct variable_s *list2
|
||||
}
|
||||
else
|
||||
{
|
||||
int result = strcmp(list1->var, list2->var);
|
||||
result = strcmp(list1->var, list2->var);
|
||||
if (result < 0)
|
||||
{
|
||||
printf("file1: %s=%s\n", list1->var, varval1);
|
||||
@@ -265,9 +116,9 @@ static void compare_variables(struct variable_s *list1, struct variable_s *list2
|
||||
printf("file2: %s=%s\n\n", list2->var, varval2);
|
||||
list2 = list2->flink;
|
||||
}
|
||||
else
|
||||
else /* if (result == 0) */
|
||||
{
|
||||
int result = strcmp(varval1, varval2);
|
||||
result = strcmp(varval1, varval2);
|
||||
if (result != 0)
|
||||
{
|
||||
printf("file1: %s=%s\n", list1->var, varval1);
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
@echo off
|
||||
|
||||
rem tools/configure.bat
|
||||
rem
|
||||
rem Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
rem Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
rem
|
||||
rem Redistribution and use in source and binary forms, with or without
|
||||
rem modification, are permitted provided that the following conditions
|
||||
rem are met:
|
||||
rem
|
||||
rem 1. Redistributions of source code must retain the above copyright
|
||||
rem notice, this list of conditions and the following disclaimer.
|
||||
rem 2. Redistributions in binary form must reproduce the above copyright
|
||||
rem notice, this list of conditions and the following disclaimer in
|
||||
rem the documentation and/or other materials provided with the
|
||||
rem distribution.
|
||||
rem 3. Neither the name NuttX nor the names of its contributors may be
|
||||
rem used to endorse or promote products derived from this software
|
||||
rem without specific prior written permission.
|
||||
rem
|
||||
rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
rem FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
rem COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
rem INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
rem BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
rem OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
rem AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
rem LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
rem ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
rem POSSIBILITY OF SUCH DAMAGE.
|
||||
rem
|
||||
|
||||
rem Parse command line arguments
|
||||
|
||||
set debug=
|
||||
set fmt=-w
|
||||
set posix=
|
||||
set help=
|
||||
set appdir=
|
||||
set config=
|
||||
|
||||
:ArgLoop
|
||||
if "%1"=="" goto :NoConfig
|
||||
if "%1"=="-h" goto :ShowUsage
|
||||
if "%1"=="-d" goto :SetDebug
|
||||
if "%1"=="-w" goto :SetWindows
|
||||
if "%1"=="-l" goto :SetPosix
|
||||
if "%1"=="-a" goto :SetAppDir
|
||||
|
||||
set config=%1
|
||||
goto EndOfLoop
|
||||
|
||||
:SetDebug
|
||||
set debug=-d
|
||||
goto :NextArg
|
||||
|
||||
:SetWindows
|
||||
set fmt=-w
|
||||
goto :NextArg
|
||||
|
||||
:SetWindows
|
||||
set fmt=-l
|
||||
goto :NextArg
|
||||
|
||||
:SetAppDir
|
||||
shift
|
||||
set appdir=-a %1
|
||||
|
||||
:NextArg
|
||||
shift
|
||||
goto :ArgLoop
|
||||
|
||||
:EndOfLoop
|
||||
|
||||
rem Check if we have to build configure.exe
|
||||
|
||||
if exist configure.exe goto :HaveConfigureExe
|
||||
|
||||
set cc=mingw32-gcc.exe
|
||||
set cflags=-Wall -Wstrict-prototypes -Wshadow -g -pipe -I. -DCONFIG_WINDOWS_NATIVE=y
|
||||
%cc% %cflags% -o configure.exe configure.c cfgparser.c
|
||||
if errorlevel 1 (
|
||||
echo ERROR: %cc% failed
|
||||
echo Is ming32-gcc.exe installed? Is it in the PATH variable?
|
||||
goto End
|
||||
)
|
||||
|
||||
:HaveConfigureExe
|
||||
configure.exe %debug% %fmt% %appdir% %config%
|
||||
if errorlevel 1 echo configure.exe failed
|
||||
goto End
|
||||
|
||||
:NoConfig
|
||||
echo Missing ^<board-name^>/^<config-name^> argument
|
||||
|
||||
:ShowUsage
|
||||
echo USAGE: %0 [-d] [-w] [-l] [-h] [-a ^<app-dir^>] ^<board-name^>\^<config-name^>
|
||||
echo\nWhere:
|
||||
echo ^<board-name^>:
|
||||
echo Identifies the board. This must correspond to a board directory
|
||||
echo under nuttx/configs/.
|
||||
echo ^<config-name^>:
|
||||
echo Identifies the specific configuratin for the selected ^<board-name^>.
|
||||
echo This must correspond to a sub-directory under the board directory at
|
||||
echo under nuttx/configs/^<board-name^>/.
|
||||
echo ^<-d^>:
|
||||
echo Enables debug output
|
||||
echo ^<-w^>:
|
||||
echo Informs the tool that it should use Windows style paths like C:\\Program Files
|
||||
echo instead of POSIX style paths are used like /usr/local/bin. Windows
|
||||
echo style paths are used by default.
|
||||
echo ^<-l^>:
|
||||
echo Informs the tool that it should use POSIX style paths like /usr/local/bin.
|
||||
echo By default, Windows style paths like C:\\Program Files are used.
|
||||
echo -a ^<app-dir^>:
|
||||
echo Informs the configuration tool where the application build
|
||||
echo directory. This is a relative path from the top-level NuttX
|
||||
echo build directory. But default, this tool will look in the usual
|
||||
echo places to try to locate the application directory: ../apps or
|
||||
echo ../apps-xx.yy where xx.yy is the NuttX version number.
|
||||
echo ^<-h^>:
|
||||
echo Prints this message and exits.
|
||||
|
||||
:End
|
||||
@@ -0,0 +1,890 @@
|
||||
/****************************************************************************
|
||||
* tools/configure.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <libgen.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "cfgparser.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_WINDOWS_NATIVE
|
||||
static char g_delim = '\\'; /* Delimiter to use when forming paths */
|
||||
static bool g_winpaths = true; /* True: Windows style paths */
|
||||
#else
|
||||
static char g_delim = '/'; /* Delimiter to use when forming paths */
|
||||
static bool g_winpaths = false; /* False: POSIX style paths */
|
||||
#endif
|
||||
static bool g_debug = false; /* Enable debug output */
|
||||
|
||||
static const char *g_appdir = NULL; /* Relative path to the applicatin directory */
|
||||
static const char *g_boarddir = NULL; /* Name of board subdirectory */
|
||||
static char *g_configdir = NULL; /* Name of configuration subdirectory */
|
||||
|
||||
static char *g_topdir = NULL; /* Full path to top-level NuttX build directory */
|
||||
static char *g_apppath = NULL; /* Full path to the applicatino directory */
|
||||
static char *g_configtop = NULL; /* Full path to the top-level configuration directory */
|
||||
static char *g_configpath = NULL; /* Full path to the configuration sub-directory */
|
||||
static char *g_verstring = "0.0"; /* Version String */
|
||||
|
||||
static char *g_srcdefconfig = NULL; /* Source defconfig file */
|
||||
static char *g_srcmakedefs = NULL; /* Source Make.defs file */
|
||||
static char *g_srcappconfig = NULL ; /* Source appconfig file (optional) */
|
||||
static char *g_srcsetenvsh = NULL; /* Source setenv.sh file (optional) */
|
||||
static char *g_srcsetenvbat = NULL; /* Source setenv.bat file (optional) */
|
||||
|
||||
static bool g_newconfig = false; /* True: New style configuration */
|
||||
static bool g_winnative = false; /* True: Windows native configuration */
|
||||
static bool g_needapppath = true; /* Need to add app path to the .config file */
|
||||
|
||||
static char g_buffer[BUFFER_SIZE]; /* Scratch buffer for forming full paths */
|
||||
|
||||
static struct variable_s *g_configvars = NULL;
|
||||
static struct variable_s *g_versionvars = NULL;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void show_usage(const char *progname, int exitcode)
|
||||
{
|
||||
fprintf(stderr, "\nUSAGE: %s [-d] [-w] [-l] [-h] [-a <app-dir>] <board-name>[%c<config-name>]\n", progname, g_delim);
|
||||
fprintf(stderr, "\nWhere:\n");
|
||||
fprintf(stderr, " <board-name>:\n");
|
||||
fprintf(stderr, " Identifies the board. This must correspond to a board directory\n");
|
||||
fprintf(stderr, " under nuttx%cconfigs%c.\n", g_delim, g_delim);
|
||||
fprintf(stderr, " <config-name>:\n");
|
||||
fprintf(stderr, " Identifies the specific configuration for the selected <board-name>.\n");
|
||||
fprintf(stderr, " This must correspond to a sub-directory under the board directory at\n");
|
||||
fprintf(stderr, " under nuttx%cconfigs%c<board-name>%c.\n", g_delim, g_delim, g_delim);
|
||||
fprintf(stderr, " <-d>:\n");
|
||||
fprintf(stderr, " Enables debug output\n");
|
||||
fprintf(stderr, " <-w>:\n");
|
||||
#ifdef CONFIG_WINDOWS_NATIVE
|
||||
fprintf(stderr, " Informs the tool that it should use Windows style paths like C:\\Program Files\n");
|
||||
fprintf(stderr, " instead of POSIX style paths are used like /usr/local/bin. Windows\n");
|
||||
fprintf(stderr, " style paths are used by default.\n");
|
||||
#else
|
||||
fprintf(stderr, " Informs the tool that it should use Windows style paths like C:\\Program Files.\n");
|
||||
fprintf(stderr, " By default, POSIX style paths like /usr/local/bin are used.\n");
|
||||
#endif
|
||||
fprintf(stderr, " <-l>:\n");
|
||||
#ifdef CONFIG_WINDOWS_NATIVE
|
||||
fprintf(stderr, " Informs the tool that it should use POSIX style paths like /usr/local/bin.\n");
|
||||
fprintf(stderr, " By default, Windows style paths like C:\\Program Files are used.\n");
|
||||
#else
|
||||
fprintf(stderr, " Informs the tool that it should use POSIX style paths like /usr/local/bin\n");
|
||||
fprintf(stderr, " instead of Windows style paths like C:\\Program Files are used. POSIX\n");
|
||||
fprintf(stderr, " style paths are used by default.\n");
|
||||
#endif
|
||||
fprintf(stderr, " -a <app-dir>:\n");
|
||||
fprintf(stderr, " Informs the configuration tool where the application build\n");
|
||||
fprintf(stderr, " directory. This is a relative path from the top-level NuttX\n");
|
||||
fprintf(stderr, " build directory. But default, this tool will look in the usual\n");
|
||||
fprintf(stderr, " places to try to locate the application directory: ..%capps or\n", g_delim);
|
||||
fprintf(stderr, " ..%capps-xx.yy where xx.yy is the NuttX version number.\n", g_delim);
|
||||
fprintf(stderr, " <-h>:\n");
|
||||
fprintf(stderr, " Prints this message and exits.\n");
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
static void debug(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (g_debug)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
(void)vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_args(int argc, char **argv)
|
||||
{
|
||||
char *ptr;
|
||||
int ch;
|
||||
|
||||
/* Parse command line options */
|
||||
|
||||
g_debug = false;
|
||||
|
||||
while ((ch = getopt(argc, argv, ":a:dwlh")) > 0)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case 'a' :
|
||||
g_appdir = optarg;
|
||||
break;
|
||||
|
||||
case 'd' :
|
||||
g_debug = true;
|
||||
break;
|
||||
|
||||
case 'w' :
|
||||
g_delim = '/';
|
||||
g_winpaths = true;
|
||||
break;
|
||||
|
||||
case 'l' :
|
||||
g_delim = '\\';
|
||||
g_winpaths = false;
|
||||
break;
|
||||
|
||||
case 'h' :
|
||||
show_usage(argv[0], EXIT_SUCCESS);
|
||||
|
||||
case '?' :
|
||||
fprintf(stderr, "ERROR: Unrecognized option: %c\n", optopt);
|
||||
show_usage(argv[0], EXIT_FAILURE);
|
||||
|
||||
case ':' :
|
||||
fprintf(stderr, "ERROR: Missing option argument, option: %c\n", optopt);
|
||||
show_usage(argv[0], EXIT_FAILURE);
|
||||
|
||||
break;
|
||||
fprintf(stderr, "ERROR: Unexpected option: %c\n", ch);
|
||||
show_usage(argv[0], EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* There should be exactly one argument following the options */
|
||||
|
||||
if (optind >= argc)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Missing <board-name>%c<config-name>\n", g_delim);
|
||||
show_usage(argv[0], EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* The required option should be the board directory name and the
|
||||
* configuration directory name separated by '/' or '\'. Either is
|
||||
* acceptable in this context.
|
||||
*/
|
||||
|
||||
g_boarddir = argv[optind];
|
||||
optind++;
|
||||
|
||||
ptr = strchr(g_boarddir, '/');
|
||||
if (!ptr)
|
||||
{
|
||||
ptr = strchr(g_boarddir, '\\');
|
||||
}
|
||||
|
||||
if (!ptr)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Invalid <board-name>%c<config-name>\n", g_delim);
|
||||
show_usage(argv[0], EXIT_FAILURE);
|
||||
}
|
||||
|
||||
*ptr++ = '\0';
|
||||
g_configdir = ptr;
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
fprintf(stderr, "Unexpected garbage at the end of the line\n");
|
||||
show_usage(argv[0], EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static void verify_directory(const char *directory)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
if (stat(directory, &buf) < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: stat of %s failed: %s\n", directory, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!S_ISDIR(buf.st_mode))
|
||||
{
|
||||
fprintf(stderr, "ERROR: %s exists but is not a directory\n", directory);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static bool verify_optiondir(const char *directory)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
if (stat(directory, &buf) < 0)
|
||||
{
|
||||
/* It may be okay if the dirctory does not exist */
|
||||
|
||||
/* It may be okay if the file does not exist */
|
||||
|
||||
int errcode = errno;
|
||||
if (errcode == ENOENT)
|
||||
{
|
||||
debug("verify_optiondir: stat of %s failed: %s\n", directory, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "ERROR: stat of %s failed: %s\n", directory, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!S_ISDIR(buf.st_mode))
|
||||
{
|
||||
fprintf(stderr, "ERROR: %s exists but is not a directory\n", directory);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool verify_file(const char *path)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
if (stat(path, &buf) < 0)
|
||||
{
|
||||
/* It may be okay if the file does not exist */
|
||||
|
||||
int errcode = errno;
|
||||
if (errcode == ENOENT)
|
||||
{
|
||||
debug("verify_file: stat of %s failed: %s\n", path, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "ERROR: stat of %s failed: %s\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!S_ISREG(buf.st_mode))
|
||||
{
|
||||
fprintf(stderr, "ERROR: %s exists but is not a regular file\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void get_topdir(void)
|
||||
{
|
||||
/* Get and verify the top-level NuttX directory */
|
||||
|
||||
if (getcwd(g_buffer, BUFFER_SIZE) == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: getcwd failed: %s\n", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
g_topdir = strdup(dirname(g_buffer));
|
||||
debug("get_topdir: Checking topdir=%s\n", g_topdir);
|
||||
verify_directory(g_topdir);
|
||||
}
|
||||
|
||||
static void config_search(const char *boarddir)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *dp;
|
||||
struct stat buf;
|
||||
char *parent;
|
||||
char *child;
|
||||
|
||||
/* Skip over any leading '/' or '\\'. This happens on the first second
|
||||
* call because the starting boarddir is ""
|
||||
*/
|
||||
|
||||
if (boarddir[0] == g_delim)
|
||||
{
|
||||
boarddir++;
|
||||
}
|
||||
|
||||
/* Get the full directory path and open it */
|
||||
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%c%s", g_configtop, g_delim, boarddir);
|
||||
dir = opendir(g_buffer);
|
||||
if (!dir)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Could not open %s: %s\n",
|
||||
g_buffer, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make a copy of the path to the directory */
|
||||
|
||||
parent = strdup(g_buffer);
|
||||
|
||||
/* Vist each entry in the directory */
|
||||
|
||||
while ((dp = readdir (dir)) != NULL)
|
||||
{
|
||||
/* Ignore directory entries that start with '.' */
|
||||
|
||||
if (dp->d_name[0] == '.')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get a properly terminated copy of d_name (if d_name is long it may
|
||||
* not include a NUL terminator.\ */
|
||||
|
||||
child = strndup(dp->d_name, NAME_MAX);
|
||||
|
||||
/* Get the full path to d_name and stat the file/directory */
|
||||
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%c%s", parent, g_delim, child);
|
||||
if (stat(g_buffer, &buf) < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: stat of %s failed: %s\n",
|
||||
g_buffer, strerror(errno));
|
||||
free(child);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If it is a directory, the recurse */
|
||||
|
||||
if (S_ISDIR(buf.st_mode))
|
||||
{
|
||||
char *tmppath;
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%c%s", boarddir, g_delim, child);
|
||||
tmppath = strdup(g_buffer);
|
||||
config_search(tmppath);
|
||||
free(tmppath);
|
||||
}
|
||||
|
||||
/* If it is a regular file named 'defconfig' then we have found a
|
||||
* configuration directory. We could terminate the serach in this case
|
||||
* because we do not expect sub-directories within configuration
|
||||
* directories.
|
||||
*/
|
||||
|
||||
else if (S_ISREG(buf.st_mode) && strcmp("defconfig", child) == 0)
|
||||
{
|
||||
fprintf(stderr, " %s\n", boarddir);
|
||||
}
|
||||
|
||||
free(child);
|
||||
}
|
||||
|
||||
free(parent);
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
static void enumerate_configs(void)
|
||||
{
|
||||
fprintf(stderr, "Options for <board-name>[%c<config-name>] include:\n\n", g_delim);
|
||||
config_search("");
|
||||
}
|
||||
|
||||
static void check_configdir(void)
|
||||
{
|
||||
/* Get the path to the top level configuration directory */
|
||||
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%cconfigs", g_topdir, g_delim);
|
||||
debug("check_configdir: Checking configtop=%s\n", g_buffer);
|
||||
|
||||
verify_directory(g_buffer);
|
||||
g_configtop = strdup(g_buffer);
|
||||
|
||||
/* Get and verify the path to the selected configuration */
|
||||
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%cconfigs%c%s%c%s",
|
||||
g_topdir, g_delim, g_delim, g_boarddir, g_delim, g_configdir);
|
||||
debug("check_configdir: Checking configpath=%s\n", g_buffer);
|
||||
|
||||
if (!verify_optiondir(g_buffer))
|
||||
{
|
||||
fprintf(stderr, "ERROR: No configuration at %s\n", g_buffer);
|
||||
enumerate_configs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
g_configpath = strdup(g_buffer);
|
||||
}
|
||||
|
||||
static void read_configfile(void)
|
||||
{
|
||||
FILE *stream;
|
||||
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%cdefconfig", g_configpath, g_delim);
|
||||
stream = fopen(g_buffer, "r");
|
||||
if (!stream)
|
||||
{
|
||||
fprintf(stderr, "ERROR: failed to open %s for reading: %s\n",
|
||||
g_buffer, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
parse_file(stream, &g_configvars);
|
||||
fclose(stream);
|
||||
}
|
||||
|
||||
static void read_versionfile(void)
|
||||
{
|
||||
FILE *stream;
|
||||
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%c.version", g_topdir, g_delim);
|
||||
stream = fopen(g_buffer, "r");
|
||||
if (!stream)
|
||||
{
|
||||
/* It may not be an error if there is no .version file */
|
||||
|
||||
debug("Failed to open %s for reading: %s\n",
|
||||
g_buffer, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
parse_file(stream, &g_versionvars);
|
||||
fclose(stream);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_verstring(void)
|
||||
{
|
||||
struct variable_s *var;
|
||||
|
||||
if (g_versionvars)
|
||||
{
|
||||
var = find_variable("CONFIG_VERSION_STRING", g_versionvars);
|
||||
if (var && var->val)
|
||||
{
|
||||
g_verstring = strdup(var->val);
|
||||
}
|
||||
}
|
||||
|
||||
debug("get_verstring: Version string=%s\n", g_verstring);
|
||||
}
|
||||
|
||||
static bool verify_appdir(const char *appdir)
|
||||
{
|
||||
/* Does this directory exist? */
|
||||
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%c%s", g_topdir, g_delim, appdir);
|
||||
debug("verify_appdir: Checking apppath=%s\n", g_buffer);
|
||||
if (verify_optiondir(g_buffer))
|
||||
{
|
||||
/* Yes.. Use this application directory path */
|
||||
|
||||
g_appdir = strdup(appdir);
|
||||
g_apppath = strdup(g_buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
debug("verify_appdir: apppath=%s does not exist\n", g_buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void check_appdir(void)
|
||||
{
|
||||
char tmp[16];
|
||||
|
||||
/* Get and verify the full path to the application directory */
|
||||
/* Was the appdir provided on the command line? */
|
||||
|
||||
debug("check_appdir: Command line appdir=%s\n",
|
||||
g_appdir ? g_appdir : "<null>");
|
||||
|
||||
if (!g_appdir)
|
||||
{
|
||||
/* No, was the path provided in the configuration? */
|
||||
|
||||
struct variable_s *var = find_variable("CONFIG_APP_DIR", g_configvars);
|
||||
if (var)
|
||||
{
|
||||
debug("check_appdir: Config file appdir=%s\n",
|
||||
var->val ? var->val : "<null>");
|
||||
|
||||
/* Yes.. does this directory exist? */
|
||||
|
||||
if (var->val && verify_appdir(var->val))
|
||||
{
|
||||
/* We are using the CONFIG_APP_DIR setting already
|
||||
* in the defconfig file.
|
||||
*/
|
||||
|
||||
g_needapppath = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now try some canned locations */
|
||||
|
||||
/* Try ../apps-xx.yy where xx.yy is the version string */
|
||||
|
||||
snprintf(tmp, 16, ".%capps-%s", g_delim, g_verstring);
|
||||
debug("check_appdir: Try appdir=%s\n", tmp);
|
||||
if (verify_appdir(tmp))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Try ../apps with no version */
|
||||
|
||||
snprintf(tmp, 16, "..%capps", g_delim);
|
||||
debug("check_appdir: Try appdir=%s\n", tmp);
|
||||
if (verify_appdir(tmp))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Try ../apps-xx.yy where xx.yy are the NuttX version number */
|
||||
|
||||
fprintf(stderr, "ERROR: Could not find the path to the application directory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%c%s", g_topdir, g_delim, g_appdir);
|
||||
if (!verify_appdir(g_buffer))
|
||||
{
|
||||
fprintf(stderr, "ERROR: Command line path to application directory does not exist\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void check_configuration(void)
|
||||
{
|
||||
struct variable_s *var;
|
||||
|
||||
/* Check if this the new style configuration based on kconfig-fontends */
|
||||
|
||||
var = find_variable("CONFIG_NUTTX_NEWCONFIG", g_configvars);
|
||||
if (var && var->val && strcmp("y", var->val) == 0)
|
||||
{
|
||||
debug("check_configuration: New style configuration\n");
|
||||
g_newconfig = true;
|
||||
}
|
||||
|
||||
/* Check if this is a Windows native configuration */
|
||||
|
||||
var = find_variable("CONFIG_WINDOWS_NATIVE", g_configvars);
|
||||
if (var && var->val && strcmp("y", var->val) == 0)
|
||||
{
|
||||
debug("check_configuration: Windows native configuration\n");
|
||||
g_winnative = true;
|
||||
}
|
||||
|
||||
/* All configurations must provide a defconfig and Make.defs file */
|
||||
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%cdefconfig", g_configpath, g_delim);
|
||||
debug("check_configuration: Checking %s\n", g_buffer);
|
||||
if (!verify_file(g_buffer))
|
||||
{
|
||||
fprintf(stderr, "ERROR: No configuration in %s\n", g_configpath);
|
||||
fprintf(stderr, " No defconfig file found.\n");
|
||||
enumerate_configs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
g_srcdefconfig = strdup(g_buffer);
|
||||
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%cMake.defs", g_configpath, g_delim);
|
||||
debug("check_configuration: Checking %s\n", g_buffer);
|
||||
if (!verify_file(g_buffer))
|
||||
{
|
||||
fprintf(stderr, "ERROR: Configuration corrupted in %s\n", g_configpath);
|
||||
fprintf(stderr, " No Make.defs file found.\n");
|
||||
enumerate_configs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
g_srcmakedefs = strdup(g_buffer);
|
||||
|
||||
/* Windows native configurations may provide setenv.bat; POSIX
|
||||
* configurations may provide a setenv.sh.
|
||||
*/
|
||||
|
||||
if (g_winnative)
|
||||
{
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%csetenv.bat", g_configpath, g_delim);
|
||||
debug("check_configuration: Checking %s\n", g_buffer);
|
||||
if (verify_file(g_buffer))
|
||||
{
|
||||
g_srcsetenvbat = strdup(g_buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%csetenv.sh", g_configpath, g_delim);
|
||||
debug("check_configuration: Checking %s\n", g_buffer);
|
||||
if (verify_file(g_buffer))
|
||||
{
|
||||
g_srcsetenvsh = strdup(g_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/* Old style configurations MUST provide an appconfig file */
|
||||
|
||||
if (!g_newconfig)
|
||||
{
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%cappconfig", g_configpath, g_delim);
|
||||
debug("check_configuration: Checking %s\n", g_buffer);
|
||||
if (!verify_file(g_buffer))
|
||||
{
|
||||
fprintf(stderr, "ERROR: Configuration corrupted in %s\n", g_configpath);
|
||||
fprintf(stderr, " Required appconfig file not found.\n");
|
||||
enumerate_configs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
g_srcappconfig = strdup(g_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_file(const char *srcpath, const char *destpath, mode_t mode)
|
||||
{
|
||||
int nbytesread;
|
||||
int nbyteswritten;
|
||||
int rdfd;
|
||||
int wrfd;
|
||||
|
||||
/* Open the source file for reading */
|
||||
|
||||
rdfd = open(srcpath, O_RDONLY);
|
||||
if (rdfd < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to open %s for reading: %s\n", srcpath, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Now open the destination for writing*/
|
||||
|
||||
wrfd = open(destpath, O_WRONLY|O_CREAT|O_TRUNC, mode);
|
||||
if (wrfd < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to open %s for writing: %s\n", destpath, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Now copy the file */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
do
|
||||
{
|
||||
nbytesread = read(rdfd, g_buffer, BUFFER_SIZE);
|
||||
if (nbytesread == 0)
|
||||
{
|
||||
/* End of file */
|
||||
|
||||
close(rdfd);
|
||||
close(wrfd);
|
||||
return;
|
||||
}
|
||||
else if (nbytesread < 0)
|
||||
{
|
||||
/* EINTR is not an error (but will still stop the copy) */
|
||||
|
||||
fprintf(stderr, "ERROR: Read failure: %s\n", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
while (nbytesread <= 0);
|
||||
|
||||
do
|
||||
{
|
||||
nbyteswritten = write(wrfd, g_buffer, nbytesread);
|
||||
if (nbyteswritten >= 0)
|
||||
{
|
||||
nbytesread -= nbyteswritten;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* EINTR is not an error (but will still stop the copy) */
|
||||
|
||||
fprintf(stderr, "ERROR: Write failure: %s\n", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
while (nbytesread > 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void substitute(char *str, int ch1, int ch2)
|
||||
{
|
||||
for (; *str; str++)
|
||||
{
|
||||
if (*str == ch1)
|
||||
{
|
||||
*str = ch2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void configure(void)
|
||||
{
|
||||
char *destconfig;
|
||||
|
||||
/* Copy the defconfig file as .config */
|
||||
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%c.config", g_topdir, g_delim);
|
||||
destconfig = strdup(g_buffer);
|
||||
debug("configure: Copying from %s to %s\n", g_srcdefconfig, destconfig);
|
||||
copy_file(g_srcdefconfig, destconfig, 0644);
|
||||
|
||||
/* Copy the Make.defs file as Make.defs */
|
||||
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%cMake.defs", g_topdir, g_delim);
|
||||
debug("configure: Copying from %s to %s\n", g_srcmakedefs, g_buffer);
|
||||
copy_file(g_srcmakedefs, g_buffer, 0644);
|
||||
|
||||
/* Copy the setenv.sh file if have one and need one */
|
||||
|
||||
if (g_srcsetenvsh)
|
||||
{
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%csetenv.sh", g_topdir, g_delim);
|
||||
debug("configure: Copying from %s to %s\n", g_srcsetenvsh, g_buffer);
|
||||
copy_file(g_srcsetenvsh, g_buffer, 0755);
|
||||
}
|
||||
|
||||
/* Copy the setenv.bat file if have one and need one */
|
||||
|
||||
if (g_srcsetenvbat)
|
||||
{
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%csetenv.bat", g_topdir, g_delim);
|
||||
debug("configure: Copying from %s to %s\n", g_srcsetenvbat, g_buffer);
|
||||
copy_file(g_srcsetenvbat, g_buffer, 0644);
|
||||
}
|
||||
|
||||
/* Copy the appconfig file to ../apps/.config if have one and need one */
|
||||
|
||||
if (g_srcappconfig)
|
||||
{
|
||||
snprintf(g_buffer, BUFFER_SIZE, "%s%c.config", g_apppath, g_delim);
|
||||
debug("configure: Copying from %s to %s\n", g_srcappconfig, g_buffer);
|
||||
copy_file(g_srcappconfig, g_buffer, 0644);
|
||||
}
|
||||
|
||||
/* If we did not use the CONFIG_APPS_DIR that was in the defconfig config file,
|
||||
* then append the correct application information to the tail of the .config
|
||||
* file
|
||||
*/
|
||||
|
||||
if (g_needapppath)
|
||||
{
|
||||
FILE *stream;
|
||||
char *appdir = strdup(g_appdir);
|
||||
|
||||
/* One complexity is if we are using Windows paths, but the configuration
|
||||
* needs POSIX paths (or vice versa).
|
||||
*/
|
||||
|
||||
if (g_winpaths != g_winnative)
|
||||
{
|
||||
/* Not the same */
|
||||
|
||||
if (g_winpaths)
|
||||
{
|
||||
/* Using Windows paths, but the configuration wants POSIX paths */
|
||||
|
||||
substitute(appdir, '\\', '/');
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Using POSIX paths, but the configuration wants Windows paths */
|
||||
|
||||
substitute(appdir, '/', '\\');
|
||||
}
|
||||
}
|
||||
|
||||
/* Open the file for appending */
|
||||
|
||||
stream = fopen(destconfig, "a");
|
||||
if (!stream)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to open %s for append mode mode: %s\n",
|
||||
destconfig, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fprintf(stream, "\n# Application configuration\n\n");
|
||||
fprintf(stream, "CONFIG_APPS_DIR=\"%s\"\n", appdir);
|
||||
fclose(stream);
|
||||
free(appdir);
|
||||
}
|
||||
|
||||
free(destconfig);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
debug("main: Checking arguments\n");
|
||||
parse_args(argc, argv);
|
||||
|
||||
debug("main: Checking Nuttx Directories\n");
|
||||
get_topdir();
|
||||
check_configdir();
|
||||
|
||||
debug("main: Reading the configuration/version files\n");
|
||||
read_configfile();
|
||||
read_versionfile();
|
||||
get_verstring();
|
||||
|
||||
debug("main: Checking Configuration Directory\n");
|
||||
check_configuration();
|
||||
|
||||
debug("main: Checking Application Directories\n");
|
||||
check_appdir();
|
||||
debug("main: Using apppath=%s\n", g_apppath ? g_apppath : "<null>");
|
||||
|
||||
debug("main: Configuring\n");
|
||||
configure();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -125,7 +125,6 @@ else
|
||||
fi
|
||||
|
||||
src_config="${configpath}/defconfig"
|
||||
tmp_config="${TOPDIR}/.configX"
|
||||
dest_config="${TOPDIR}/.config"
|
||||
|
||||
if [ ! -r "${src_config}" ]; then
|
||||
@@ -201,7 +200,7 @@ if [ "X${have_setenv}" = "Xy" ]; then
|
||||
{ echo "Failed to copy ${src_setenv}" ; exit 8 ; }
|
||||
chmod 755 "${dest_setenv}"
|
||||
fi
|
||||
install "${src_config}" "${tmp_config}" || \
|
||||
install "${src_config}" "${dest_config}" || \
|
||||
{ echo "Failed to copy \"${src_config}\"" ; exit 9 ; }
|
||||
|
||||
# If we did not use the CONFIG_APPS_DIR that was in the defconfig config file,
|
||||
@@ -209,14 +208,14 @@ install "${src_config}" "${tmp_config}" || \
|
||||
# file
|
||||
|
||||
if [ "X${defappdir}" = "Xy" ]; then
|
||||
sed -i -e "/^CONFIG_APPS_DIR/d" "${tmp_config}"
|
||||
echo "" >> "${tmp_config}"
|
||||
echo "# Application configuration" >> "${tmp_config}"
|
||||
echo "" >> "${tmp_config}"
|
||||
sed -i -e "/^CONFIG_APPS_DIR/d" "${dest_config}"
|
||||
echo "" >> "${dest_config}"
|
||||
echo "# Application configuration" >> "${dest_config}"
|
||||
echo "" >> "${dest_config}"
|
||||
if [ "X${winnative}" = "Xy" ]; then
|
||||
echo "CONFIG_APPS_DIR=\"$winappdir\"" >> "${tmp_config}"
|
||||
echo "CONFIG_APPS_DIR=\"$winappdir\"" >> "${dest_config}"
|
||||
else
|
||||
echo "CONFIG_APPS_DIR=\"$posappdir\"" >> "${tmp_config}"
|
||||
echo "CONFIG_APPS_DIR=\"$posappdir\"" >> "${dest_config}"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -232,9 +231,3 @@ if [ ! -z "${appdir}" -a "X${newconfig}" != "Xy" ]; then
|
||||
{ echo "Failed to copy ${configpath}/appconfig" ; exit 10 ; }
|
||||
fi
|
||||
fi
|
||||
|
||||
# install the final .configX only if it differs from any existing
|
||||
# .config file.
|
||||
|
||||
install "${tmp_config}" "${dest_config}"
|
||||
rm -f "${tmp_config}"
|
||||
|
||||
Executable
+131
@@ -0,0 +1,131 @@
|
||||
@echo off
|
||||
|
||||
rem tools/kconfig.bat
|
||||
rem
|
||||
rem Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
rem Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
rem
|
||||
rem Redistribution and use in source and binary forms, with or without
|
||||
rem modification, are permitted provided that the following conditions
|
||||
rem are met:
|
||||
rem
|
||||
rem 1. Redistributions of source code must retain the above copyright
|
||||
rem notice, this list of conditions and the following disclaimer.
|
||||
rem 2. Redistributions in binary form must reproduce the above copyright
|
||||
rem notice, this list of conditions and the following disclaimer in
|
||||
rem the documentation and/or other materials provided with the
|
||||
rem distribution.
|
||||
rem 3. Neither the name NuttX nor the names of its contributors may be
|
||||
rem used to endorse or promote products derived from this software
|
||||
rem without specific prior written permission.
|
||||
rem
|
||||
rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
rem FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
rem COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
rem INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
rem BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
rem OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
rem AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
rem LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
rem ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
rem POSSIBILITY OF SUCH DAMAGE.
|
||||
rem
|
||||
|
||||
rem Remember the state of the PATH variable on entry
|
||||
|
||||
set oldpath=%PATH%
|
||||
|
||||
rem Handle command line options
|
||||
|
||||
set action=%1
|
||||
shift
|
||||
if "%action%"=="" goto :MissingArgument
|
||||
|
||||
set appsdir=..\apps
|
||||
set cygwindir=C:\Cygwin
|
||||
|
||||
:ArgLoop
|
||||
|
||||
if "%1"=="" goto :CheckArguments
|
||||
|
||||
if "%1"=="-a" (
|
||||
shift
|
||||
set appsdir=%1
|
||||
goto :NextArg
|
||||
)
|
||||
|
||||
if "%1"=="-c" (
|
||||
shift
|
||||
set cygwindir=%1
|
||||
goto :NextArg
|
||||
)
|
||||
|
||||
echo ERROR: Unrecognized option: %1
|
||||
goto :ShowUsage
|
||||
|
||||
:NextArg
|
||||
shift
|
||||
goto :ArgLoop
|
||||
|
||||
rem Verify that all of the paths are valid
|
||||
|
||||
:CheckArguments
|
||||
if exist "%appsdir%" goto :CheckCygwinDir
|
||||
|
||||
echo ERROR: %appsdir% does not exist
|
||||
goto :ShowUsage
|
||||
|
||||
:CheckCygwinDir
|
||||
|
||||
if exist "%cygwindir%" goto :SetPath
|
||||
|
||||
echo ERROR: %cygwindir% does not exist
|
||||
goto :ShowUsage
|
||||
|
||||
rem Setup some required environment variables and PATH settings
|
||||
|
||||
:SetPath
|
||||
set PATH=%cygwindir%\usr\local\bin;%cygwindir%\usr\bin;%cygwindir%\bin;%PATH%
|
||||
set APPSDIR=%appsdir%
|
||||
|
||||
rem Execute the requested action
|
||||
|
||||
if "%action%"=="config" goto :DoConfig
|
||||
if "%action%"=="oldconfig" goto :DoOldConfig
|
||||
if "%action%"=="menuconfig" goto :DoMenuConfig
|
||||
|
||||
echo ERROR: Unrecognized action: %action%
|
||||
goto :ShowUsage
|
||||
|
||||
:DoConfig
|
||||
kconfig-conf Kconfig
|
||||
goto End
|
||||
|
||||
:DoOldConfig
|
||||
kconfig-conf --oldconfig Kconfig
|
||||
goto End
|
||||
|
||||
:DoMenuConfig
|
||||
kconfig-mconf Kconfig
|
||||
goto End
|
||||
|
||||
:MissingArgument
|
||||
|
||||
echo ERROR: Missing required argument
|
||||
|
||||
:ShowUsage
|
||||
echo USAGE: %0 ^<action^> [-a ^<appsdir^>] [-c ^<cygwindir^>]
|
||||
echo Where:
|
||||
echo ^<action^> is one of config, oldconf, or menuconfig
|
||||
echo ^<appsdir^> is the relative path to the apps\ directory.
|
||||
echo This defaults to ..\apps
|
||||
echo ^<cygwindir^> is the relative path to the Cygwin installation
|
||||
echo directory. This defaults to C:\Cygwin
|
||||
|
||||
rem Restore the original PATH settings
|
||||
|
||||
:End
|
||||
set PATH=%oldpath%
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* tools/mkconfig.c
|
||||
*
|
||||
* Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -41,7 +41,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "cfgparser.h"
|
||||
#include "cfgdefine.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
@@ -99,7 +99,7 @@ int main(int argc, char **argv, char **envp)
|
||||
printf("#ifndef __INCLUDE_NUTTX_CONFIG_H\n");
|
||||
printf("#define __INCLUDE_NUTTX_CONFIG_H\n\n");
|
||||
printf("/* Architecture-specific options *************************/\n\n");
|
||||
parse_file(stream);
|
||||
generate_definitions(stream);
|
||||
printf("\n/* Sanity Checks *****************************************/\n\n");
|
||||
printf("/* If this is an NXFLAT, external build, then make sure that\n");
|
||||
printf(" * NXFLAT support is enabled in the base code.\n");
|
||||
@@ -213,14 +213,14 @@ int main(int argc, char **argv, char **envp)
|
||||
printf("# undef CONFIG_FS_FAT\n");
|
||||
printf("# undef CONFIG_FS_ROMFS\n");
|
||||
printf("# undef CONFIG_FS_NXFFS\n");
|
||||
printf("# undef CONFIG_APPS_BINDIR\n");
|
||||
printf("# undef CONFIG_FS_BINFS\n");
|
||||
printf("# undef CONFIG_NFS\n");
|
||||
printf("#endif\n\n");
|
||||
printf("/* Check if any readable and writable filesystem (OR USB storage) is supported */\n\n");
|
||||
printf("#undef CONFIG_FS_READABLE\n");
|
||||
printf("#undef CONFIG_FS_WRITABLE\n");
|
||||
printf("#if defined(CONFIG_FS_FAT) || defined(CONFIG_FS_ROMFS) || defined(CONFIG_USBMSC) || \\\n");
|
||||
printf(" defined(CONFIG_FS_NXFFS) || defined(CONFIG_APPS_BINDIR) || defined(CONFIG_NFS)\n");
|
||||
printf(" defined(CONFIG_FS_NXFFS) || defined(CONFIG_FS_BINFS) || defined(CONFIG_NFS)\n");
|
||||
printf("# define CONFIG_FS_READABLE 1\n");
|
||||
printf("#endif\n\n");
|
||||
printf("#if defined(CONFIG_FS_FAT) || defined(CONFIG_USBMSC) || defined(CONFIG_FS_NXFFS) || \\\n");
|
||||
|
||||
@@ -61,11 +61,11 @@ static FILE *g_stubstream;
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static bool is_vararg(const char *type, int index, int nparms)
|
||||
static bool is_vararg(const char *type, int ndx, int nparms)
|
||||
{
|
||||
if (strcmp(type,"...") == 0)
|
||||
{
|
||||
if (index != (nparms-1))
|
||||
if (ndx != (nparms-1))
|
||||
{
|
||||
fprintf(stderr, "%d: ... is not the last in the argument list\n", g_lineno);
|
||||
exit(11);
|
||||
@@ -75,8 +75,10 @@ static bool is_vararg(const char *type, int index, int nparms)
|
||||
fprintf(stderr, "%d: Need one parameter before ...\n", g_lineno);
|
||||
exit(14);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "cfgparser.h"
|
||||
#include "cfgdefine.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
@@ -98,7 +98,7 @@ int main(int argc, char **argv, char **envp)
|
||||
printf("/* version.h -- Autogenerated! Do not edit. */\n\n");
|
||||
printf("#ifndef __INCLUDE_NUTTX_VERSION_H\n");
|
||||
printf("#define __INCLUDE_NUTTX_VERSION_H\n\n");
|
||||
parse_file(stream);
|
||||
generate_definitions(stream);
|
||||
printf("\n#define CONFIG_VERSION ((CONFIG_VERSION_MAJOR << 8) | (CONFIG_VERSION_MINOR))\n\n");
|
||||
printf("#endif /* __INCLUDE_NUTTX_VERSION_H */\n");
|
||||
fclose(stream);
|
||||
|
||||
Reference in New Issue
Block a user