Merge NuttX r5527

This commit is contained in:
px4dev
2013-01-17 01:00:46 -08:00
228 changed files with 15512 additions and 1913 deletions
+36 -17
View File
@@ -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
View File
@@ -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
----------
+1
View File
@@ -43,6 +43,7 @@
* Included Files
****************************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
+323
View File
@@ -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);
}
+64
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+127
View File
@@ -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
+890
View File
@@ -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;
}
+7 -14
View File
@@ -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}"
+131
View File
@@ -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%
+5 -5
View File
@@ -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");
+4 -2
View File
@@ -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;
}
+2 -2
View File
@@ -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);