diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt index 8cd30ae830..1bb2a08b55 100755 --- a/apps/ChangeLog.txt +++ b/apps/ChangeLog.txt @@ -270,3 +270,7 @@ are provided, then the current mountpoints are enumerated. * apps/nshlib/nsh_mntcmds.c: Add an NSH df command to list the properties of mounted file systems. + * apps/nshlib/nsh_parse.c: Extend help command options. 'help' with + no arguments outputs a short list of commands. With -v lists all + command line details. And command name can be added to just get + help on one command. diff --git a/apps/README.txt b/apps/README.txt index 6a78da4b54..4266585726 100644 --- a/apps/README.txt +++ b/apps/README.txt @@ -25,7 +25,7 @@ Directory Location ------------------ The default application directory used by the NuttX build should be named apps/ (or apps-x.y/ where x.y is the NuttX version number). This apps/ -directory should appear in the directory tree at the same level as the +directoy should appear in the directory tree at the same level as the NuttX directory. Like: . diff --git a/apps/nshlib/README.txt b/apps/nshlib/README.txt index 543b9a448d..7dbae8e63e 100644 --- a/apps/nshlib/README.txt +++ b/apps/nshlib/README.txt @@ -310,7 +310,7 @@ o dd if= of= [bs=] [count=] [skip=] o df - Show the state of each mounted volume + Show the state of each mounted volume. Example: diff --git a/apps/nshlib/nsh_parse.c b/apps/nshlib/nsh_parse.c index 00319a98b9..b79461bba6 100644 --- a/apps/nshlib/nsh_parse.c +++ b/apps/nshlib/nsh_parse.c @@ -88,6 +88,14 @@ # define MAX_ARGV_ENTRIES (NSH_MAX_ARGUMENTS+4) #endif +/* Help layout */ + +#define MAX_CMDLEN 12 +#define CMDS_PER_LINE 5 + +#define NUM_CMDS (sizeof(g_cmdmap)/sizeof(struct cmdmap_s)) +#define NUM_CMD_ROWS ((NUM_CMDS + (CMDS_PER_LINE-1)) / CMDS_PER_LINE) + /**************************************************************************** * Private Types ****************************************************************************/ @@ -116,13 +124,13 @@ struct cmdarg_s ****************************************************************************/ #ifndef CONFIG_NSH_DISABLE_HELP - static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif #ifndef CONFIG_NSH_DISABLE_EXIT - static int cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +static int cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif -static int cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +static int cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); /**************************************************************************** * Private Data @@ -203,7 +211,7 @@ static const struct cmdmap_s g_cmdmap[] = #endif #ifndef CONFIG_NSH_DISABLE_HELP - { "help", cmd_help, 1, 1, NULL }, + { "help", cmd_help, 1, 3, "[-v] [cmd]" }, #endif #ifdef CONFIG_NET @@ -414,18 +422,40 @@ const char g_fmtsignalrecvd[] = "nsh: %s: Interrupted by signal\n"; ****************************************************************************/ /**************************************************************************** - * Name: cmd_help + * Name: help_cmdlist ****************************************************************************/ #ifndef CONFIG_NSH_DISABLE_HELP -static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +static inline void help_cmdlist(FAR struct nsh_vtbl_s *vtbl) { - const struct cmdmap_s *ptr; -#ifdef CONFIG_NSH_BUILTIN_APPS - FAR const char * name; - int i; + int i; + int j; + int k; + + /* Print the command name in NUM_CMD_ROWS rows with CMDS_PER_LINE commands + * on each line. + */ + + for (i = 0; i < NUM_CMD_ROWS; i++) + { + nsh_output(vtbl, " "); + for (j = 0, k = i; j < CMDS_PER_LINE && k < NUM_CMDS; j++, k += CMDS_PER_LINE) + { + nsh_output(vtbl, "%-12s", g_cmdmap[k].cmd); + } + + nsh_output(vtbl, "\n"); + } +} #endif +/**************************************************************************** + * Name: help_usage + ****************************************************************************/ + +#ifndef CONFIG_NSH_DISABLE_HELP +static inline void help_usage(FAR struct nsh_vtbl_s *vtbl) +{ nsh_output(vtbl, "NSH command forms:\n"); #ifndef CONFIG_NSH_DISABLEBG nsh_output(vtbl, " [nice [-d >]] [> |>> ] [&]\n"); @@ -439,30 +469,169 @@ static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) nsh_output(vtbl, " [sequence of ]\n"); nsh_output(vtbl, " else\n"); nsh_output(vtbl, " [sequence of ]\n"); - nsh_output(vtbl, " fi\n"); + nsh_output(vtbl, " fi\n\n"); #endif - nsh_output(vtbl, "Where is one of:\n"); - for (ptr = g_cmdmap; ptr->cmd; ptr++) +} +#endif + +/**************************************************************************** + * Name: help_showcmd + ****************************************************************************/ + +#ifndef CONFIG_NSH_DISABLE_HELP +static void help_showcmd(FAR struct nsh_vtbl_s *vtbl, + FAR const struct cmdmap_s *cmdmap) +{ + if (cmdmap->usage) { - if (ptr->usage) + nsh_output(vtbl, " %s %s\n", cmdmap->cmd, cmdmap->usage); + } + else + { + nsh_output(vtbl, " %s\n", cmdmap->cmd); + } +} +#endif + +/**************************************************************************** + * Name: help_cmd + ****************************************************************************/ + +#ifndef CONFIG_NSH_DISABLE_HELP +static int help_cmd(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd) +{ + FAR const struct cmdmap_s *cmdmap; + + /* Find the command in the command table */ + + for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++) + { + /* Is this the one we are looking for? */ + + if (strcmp(cmdmap->cmd, cmd) == 0) { - nsh_output(vtbl, " %s %s\n", ptr->cmd, ptr->usage); - } - else - { - nsh_output(vtbl, " %s\n", ptr->cmd); + /* Yes... show it */ + + help_showcmd(vtbl, cmdmap); + return OK; } } + nsh_output(vtbl, g_fmtcmdnotfound, cmd); + return ERROR; +} +#endif + +/**************************************************************************** + * Name: help_allcmds + ****************************************************************************/ + +#ifndef CONFIG_NSH_DISABLE_HELP +static inline void help_allcmds(FAR struct nsh_vtbl_s *vtbl) +{ + FAR const struct cmdmap_s *cmdmap; + + /* Show all of the commands in the command table */ + + for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++) + { + help_showcmd(vtbl, cmdmap); + } +} +#endif + +/**************************************************************************** + * Name: help_builtins + ****************************************************************************/ + +#ifndef CONFIG_NSH_DISABLE_HELP +static inline void help_builtins(FAR struct nsh_vtbl_s *vtbl) +{ +#ifdef CONFIG_NSH_BUILTIN_APPS + FAR const char *name; + int i; + /* List the set of available built-in commands */ -#ifdef CONFIG_NSH_BUILTIN_APPS - nsh_output(vtbl, "\nBuiltin Apps:\n"); - for (i = 0; (name = namedapp_getname(i)) != NULL; i++) - { - nsh_output(vtbl, " %s\n", name); - } + nsh_output(vtbl, "\nBuiltin Apps:\n"); + for (i = 0; (name = namedapp_getname(i)) != NULL; i++) + { + nsh_output(vtbl, " %s\n", name); + } #endif +} +#endif + +/**************************************************************************** + * Name: cmd_help + ****************************************************************************/ + +#ifndef CONFIG_NSH_DISABLE_HELP +static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + bool verbose = false; + FAR const char *cmd = NULL; + int i; + + /* The command may be followed by a verbose option */ + + i = 1; + if (argc > i) + { + if (strcmp(argv[i], "-v") == 0) + { + verbose = true; + i++; + } + } + + /* The command line may end with a command name */ + + if (argc > i) + { + cmd = argv[i]; + } + + /* Show the generic usage if verbose is requested */ + + if (verbose) + { + help_usage(vtbl); + } + + /* Are we showing help on a single command? */ + + if (cmd) + { + /* Yes.. show the single command */ + + nsh_output(vtbl, "%s usage:", cmd); + help_cmd(vtbl, cmd); + } + else + { + /* In verbose mode, show detailed help for all commands */ + + if (verbose) + { + nsh_output(vtbl, "Where is one of:\n"); + help_allcmds(vtbl); + } + + /* Otherwise, just show the list of command names */ + + else + { + nsh_output(vtbl, "help usage:"); + help_cmd(vtbl, "help"); + nsh_output(vtbl, "\n"); + help_cmdlist(vtbl); + } + + /* And show the list of built-in applications */ + + help_builtins(vtbl); + } return OK; } @@ -508,72 +677,72 @@ static int cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) static int nsh_execute(FAR struct nsh_vtbl_s *vtbl, int argc, char *argv[]) { - const struct cmdmap_s *cmdmap; - const char *cmd; - cmd_t handler = cmd_unrecognized; - int ret; + const struct cmdmap_s *cmdmap; + const char *cmd; + cmd_t handler = cmd_unrecognized; + int ret; - /* The form of argv is: - * - * argv[0]: The command name. This is argv[0] when the arguments - * are, finally, received by the command vtblr - * argv[1]: The beginning of argument (up to NSH_MAX_ARGUMENTS) - * argv[argc]: NULL terminating pointer - */ + /* The form of argv is: + * + * argv[0]: The command name. This is argv[0] when the arguments + * are, finally, received by the command vtblr + * argv[1]: The beginning of argument (up to NSH_MAX_ARGUMENTS) + * argv[argc]: NULL terminating pointer + */ - cmd = argv[0]; + cmd = argv[0]; - /* Try to find a command in the application library. */ + /* Try to find a command in the application library. */ #ifdef CONFIG_NSH_BUILTIN_APPS - ret = nsh_execapp(vtbl, cmd, argv); + ret = nsh_execapp(vtbl, cmd, argv); - /* If the built-in application was successfully started, return OK - * or 1 (if the application returned a non-zero exit status). - */ + /* If the built-in application was successfully started, return OK + * or 1 (if the application returned a non-zero exit status). + */ - if (ret >= 0) + if (ret >= 0) { return ret; } #endif - /* See if the command is one that we understand */ + /* See if the command is one that we understand */ - for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++) - { - if (strcmp(cmdmap->cmd, cmd) == 0) - { - /* Check if a valid number of arguments was provided. We - * do this simple, imperfect checking here so that it does - * not have to be performed in each command. - */ + for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++) + { + if (strcmp(cmdmap->cmd, cmd) == 0) + { + /* Check if a valid number of arguments was provided. We + * do this simple, imperfect checking here so that it does + * not have to be performed in each command. + */ - if (argc < cmdmap->minargs) - { - /* Fewer than the minimum number were provided */ + if (argc < cmdmap->minargs) + { + /* Fewer than the minimum number were provided */ - nsh_output(vtbl, g_fmtargrequired, cmd); - return ERROR; - } - else if (argc > cmdmap->maxargs) - { - /* More than the maximum number were provided */ + nsh_output(vtbl, g_fmtargrequired, cmd); + return ERROR; + } + else if (argc > cmdmap->maxargs) + { + /* More than the maximum number were provided */ - nsh_output(vtbl, g_fmttoomanyargs, cmd); - return ERROR; - } - else - { - /* A valid number of arguments were provided (this does - * not mean they are right). - */ + nsh_output(vtbl, g_fmttoomanyargs, cmd); + return ERROR; + } + else + { + /* A valid number of arguments were provided (this does + * not mean they are right). + */ - handler = cmdmap->handler; - break; - } - } - } + handler = cmdmap->handler; + break; + } + } + } ret = handler(vtbl, argc, argv); return ret; diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 9d2f5ea6b0..1061f39ae5 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -3120,4 +3120,8 @@ the PLL after re-awakening from deep sleep modes. * fs/fs_foreachinode.c and fs/fs_foreachmountpoint.c: All logic to traverse inodes and mountpoints in the NuttX psuedo-file system. - + * fs/fat/fs_fat32.c: Max. filename length reported by statfs() was wrong + if FAT long file names were enabled. + * lib/stdio/lib_libvsprintf.c: Fieldwidth and justification were not + supported for the %s format. As a result, %s, %12s, and %-12s all + produced the same output. diff --git a/nuttx/TODO b/nuttx/TODO index 303950a088..a4bad193ec 100644 --- a/nuttx/TODO +++ b/nuttx/TODO @@ -15,7 +15,7 @@ nuttx/ (5) Binary loaders (binfmt/) (17) Network (net/, drivers/net) (3) USB (drivers/usbdev, drivers/usbhost) - (8) Libraries (lib/) + (9) Libraries (lib/) (10) File system/Generic drivers (fs/, drivers/) (5) Graphics subystem (graphics/) (1) Pascal add-on (pcode/) @@ -29,6 +29,7 @@ nuttx/ (3) ARM/LPC17xx (arch/arm/src/lpc17xx/) (7) ARM/LPC214x (arch/arm/src/lpc214x/) (2) ARM/LPC313x (arch/arm/src/lpc313x/) + (0) ARM/LPC43x (arch/arm/src/lpc43xx/) (3) ARM/STR71x (arch/arm/src/str71x/) (3) ARM/LM3S6918 (arch/arm/src/lm3s/) (7) ARM/STM32 (arch/arm/src/stm32/) @@ -671,6 +672,19 @@ o Libraries (lib/) Status: Open Priority: ?? + Title: SYSLOG INTEGRATION + Description: There are the beginnings of some system logging capabilities (see + drivers/syslog, fs/fs_syslog.c, and lib/stdio/lib_librawprintf.c and + lib_liblowprintf.c. For NuttX, SYSLOG is a concept and includes, + extends, and replaces the legacy NuttX debug ouput. Some additional + integration is required to formalized this. For example: + + o lib_rawprintf() shjould be renamed syslog(). + o debug.h should be renamed syslog.h + o And what about lib_lowprintf()? llsyslog? + Status: Open + Priority: Low -- more of a roadmap + o File system / Generic drivers (fs/, drivers/) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1197,7 +1211,7 @@ o ARM/LPC214x (arch/arm/src/lpc214x/) I am not aware of anyone using LPC2148 now so I think the priority has to be low. -o ARM/LPC313x (arch/arm/src/lpc313x/) +o ARM/LPC31xx (arch/arm/src/lpc31xx/) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Title: PLATFORM-SPECIFIC LOGIC @@ -1221,6 +1235,9 @@ o ARM/LPC313x (arch/arm/src/lpc313x/) Status: Open Priority: High if you need to use SPI. +o ARM/LPC43x (arch/arm/src/lpc43xx/) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + o ARM/STR71x (arch/arm/src/str71x/) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1338,7 +1355,7 @@ o ARM/STM32 (arch/arm/src/stm32/) Status: Open Priority: Low (I am not even sure if this is a problem yet). - Status: Unfinished STM32 F4 OTG FS Host Driver + Status: UNFINISHED STM32 F4 OTG FS HOST DRIVER Description: A quick-n-dirty leverage of the the LPC17xx host driver was put into the STM32 source to support development of the STM32 F4 OTG FS host driver. It is non-functional and still waiting for STM32 F4 logic @@ -1843,27 +1860,6 @@ o NuttShell (NSH) (apps/nshlib) Status: Open Priority: Low (enhancement) - Title: MOUNT w/NO PARAMETERS - Description: Feature request: "A 'mount' without arguments should probably list - mounted filesystems as in Linux. - - nsh> mount - nsh_romfsimg on /etc type romfs (ro) - /dev/mtdblock0 on /home type vfat (rw) - Status: Open - Priority: Low (enhancement) - - Title: DF COMMAND - Description: Feature request: "It would be convenient to list the free space - on a filesystem with something like 'df'. - - nsh> df - Filesystem 1K-blocks Used Available Use% Mounted on - nsh_romfsimg 8 8 0 100% /etc - /dev/mtdblock0 3584 16 3568 1% /home - Status: Open - Priority: Low (enhancement) - o System libraries apps/system (apps/system) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1871,7 +1867,8 @@ o System libraries apps/system (apps/system) Description: readline implementation does not use C-buffered I/O, but rather talks to serial driver directly via read(). It includes VT-100 specific editting commands. A more generic readline() should be - implemented. + implemented using termios' tcsetattr() to put the serial driver + into a "raw" mode. Status: Open Priority: Low (unless you are using mixed C-buffered I/O with readline and fgetc, for example). @@ -1894,7 +1891,7 @@ o Other Applications & Tests (apps/examples/) Title: EXAMPLES/SENDMAIL UNTESTED Description: examples/sendmail is untested on the target (it has been tested - on the host, but not on the target. + on the host, but not on the target). Status: Open Priority: Med diff --git a/nuttx/fs/fat/fs_fat32.c b/nuttx/fs/fat/fs_fat32.c index f0845070ba..7b7ce1f5f7 100644 --- a/nuttx/fs/fat/fs_fat32.c +++ b/nuttx/fs/fat/fs_fat32.c @@ -1705,7 +1705,11 @@ static int fat_statfs(struct inode *mountpt, struct statfs *buf) { buf->f_blocks = fs->fs_nclusters; /* Total data blocks in the file system */ buf->f_bavail = buf->f_bfree; /* Free blocks avail to non-superuser */ +#ifdef CONFIG_FAT_LFN + buf->f_namelen = LDIR_MAXFNAME; /* Maximum length of filenames */ +#else buf->f_namelen = (8+1+3); /* Maximum length of filenames */ +#endif } errout_with_semaphore: diff --git a/nuttx/lib/stdio/lib_libvsprintf.c b/nuttx/lib/stdio/lib_libvsprintf.c index 8d521c35e8..1fb0376a9a 100644 --- a/nuttx/lib/stdio/lib_libvsprintf.c +++ b/nuttx/lib/stdio/lib_libvsprintf.c @@ -197,9 +197,9 @@ static int getllusize(uint8_t fmt, FAR uint8_t flags, FAR unsigned long long ll #ifndef CONFIG_NOPRINTF_FIELDWIDTH static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt, - uint8_t flags, int fieldwidth, int numwidth); + uint8_t flags, int fieldwidth, int valwidth); static void postjustify(FAR struct lib_outstream_s *obj, uint8_t fmt, - uint8_t flags, int fieldwidth, int numwidth); + uint8_t flags, int fieldwidth, int valwidth); #endif /**************************************************************************** @@ -1062,7 +1062,7 @@ static int getllusize(uint8_t fmt, uint8_t flags, unsigned long long lln) #ifndef CONFIG_NOPRINTF_FIELDWIDTH static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt, - uint8_t flags, int fieldwidth, int numwidth) + uint8_t flags, int fieldwidth, int valwidth) { int i; @@ -1072,10 +1072,10 @@ static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt, case FMT_RJUST: if (IS_SIGNED(flags)) { - numwidth++; + valwidth++; } - for (i = fieldwidth - numwidth; i > 0; i--) + for (i = fieldwidth - valwidth; i > 0; i--) { obj->put(obj, ' '); } @@ -1094,15 +1094,15 @@ static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt, if (IS_NEGATE(flags)) { obj->put(obj, '-'); - numwidth++; + valwidth++; } else if (IS_SHOWPLUS(flags)) { obj->put(obj, '+'); - numwidth++; + valwidth++; } - for (i = fieldwidth - numwidth; i > 0; i--) + for (i = fieldwidth - valwidth; i > 0; i--) { obj->put(obj, '0'); } @@ -1128,7 +1128,7 @@ static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt, #ifndef CONFIG_NOPRINTF_FIELDWIDTH static void postjustify(FAR struct lib_outstream_s *obj, uint8_t fmt, - uint8_t flags, int fieldwidth, int numwidth) + uint8_t flags, int fieldwidth, int valwidth) { int i; @@ -1144,10 +1144,10 @@ static void postjustify(FAR struct lib_outstream_s *obj, uint8_t fmt, case FMT_LJUST: if (IS_SIGNED(flags)) { - numwidth++; + valwidth++; } - for (i = fieldwidth - numwidth; i > 0; i--) + for (i = fieldwidth - valwidth; i > 0; i--) { obj->put(obj, ' '); } @@ -1350,7 +1350,10 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list a if (FMT_CHAR == 's') { - /* Just concatenate the string into the output */ +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + int swidth; +#endif + /* Get the string to output */ ptmp = va_arg(ap, char *); if (!ptmp) @@ -1358,11 +1361,27 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list a ptmp = (char*)g_nullstring; } - while(*ptmp) + /* Get the widith of the string and perform right-justification + * operations. + */ + +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + swidth = strlen(ptmp); + prejustify(obj, fmt, 0, width, swidth); +#endif + /* Concatenate the string into the output */ + + while (*ptmp) { obj->put(obj, *ptmp); ptmp++; } + + /* Perform left-justification operations. */ + +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + postjustify(obj, fmt, 0, width, swidth); +#endif continue; } diff --git a/nuttx/sched/clock_dow.c b/nuttx/sched/clock_dow.c new file mode 100644 index 0000000000..93bcfc2d94 --- /dev/null +++ b/nuttx/sched/clock_dow.c @@ -0,0 +1,88 @@ +/**************************************************************************** + * sched/clock_dow.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include + +#include + +#include "clock_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* 23 * (month + 1) / 9, month = 0..11 */ + +static const uint8_t g_lookup[12] = {2, 5, 7, 10, 12, 15, 17, 20, 23, 25, 28, 30}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: clock_dow + * + * Description: + * Calculate the day of week (DOW) from they year month and day. Based on + * an algorithm pubished in 1990 by Michael Keith and Tom Craver with some + * tweaks to handle months in the range 0-11. + * + * Parameters: + * year - year (e.g., 1988) + * month - 0 through 11 + * day - 1 through 31 + * + * Return Value: + * The day of the week as days since Sunday: 0 = Sunday, 1 = Monday, etc. + * + * Assumptions: + * + ****************************************************************************/ + +int clock_dow(int year, int month, int day) +{ + day += month < 2 ? year-- : year - 2; + return ((int)g_lookup[month] + day + 4 + year/4 - year/100 + year/400) % 7; +}