From 003728be02514976de3b2847c921b16913aec6e3 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 4 Aug 2012 22:00:18 +0000 Subject: [PATCH] Fix max filename size report by FAT statfs with long file names; Add missing logic to support fieldwidth and justification for %s format; Add extended help options. Default help command just shows a short list of commands. Verbose and single command help options git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@5008 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- apps/ChangeLog.txt | 4 + apps/nshlib/README.txt | 2 +- apps/nshlib/nsh_parse.c | 317 ++++++++++++++++++++++------- nuttx/ChangeLog | 6 +- nuttx/Documentation/NuttShell.html | 2 +- nuttx/TODO | 49 +++-- nuttx/fs/fat/fs_fat32.c | 4 + nuttx/lib/stdio/lib_libvsprintf.c | 45 ++-- nuttx/sched/clock_dow.c | 88 ++++++++ 9 files changed, 401 insertions(+), 116 deletions(-) create mode 100644 nuttx/sched/clock_dow.c diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt index 8cd30ae83..1bb2a08b5 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/nshlib/README.txt b/apps/nshlib/README.txt index 543b9a448..7dbae8e63 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 00319a98b..b79461bba 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 9d2f5ea6b..1061f39ae 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/Documentation/NuttShell.html b/nuttx/Documentation/NuttShell.html index e561a9bb3..249bf2636 100644 --- a/nuttx/Documentation/NuttShell.html +++ b/nuttx/Documentation/NuttShell.html @@ -893,7 +893,7 @@ df

     nsh> mount
    - /etc type romfs
    +  /etc type romfs
       /tmp type vfat
     nsh> df
       Block  Number
    diff --git a/nuttx/TODO b/nuttx/TODO
    index 303950a08..a4bad193e 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 f0845070b..7b7ce1f5f 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 8d521c35e..1fb0376a9 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 000000000..93bcfc2d9
    --- /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;
    +}