/* sleep - delay for a specified amount of time.                                This is the sleep utility
   Copyright (C) 1984-2018 Free Software Foundation, Inc.                       
                                                                                
   This program is free software: you can redistribute it and/or modify         
   it under the terms of the GNU General Public License as published by         
   the Free Software Foundation, either version 3 of the License, or            
   (at your option) any later version.                                          
                                                                                
   This program is distributed in the hope that it will be useful,              
   but WITHOUT ANY WARRANTY; without even the implied warranty of               
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                
   GNU General Public License for more details.                                 
                                                                                
   You should have received a copy of the GNU General Public License            
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */   The GNUv3 license
                                                                                
#include <config.h>                                                             Provides system specific information
#include <stdio.h>                                                              Provides standard I/O capability
#include <sys/types.h>                                                          Provides system data types
#include <getopt.h>                                                             ...!includes auto-comment...
                                                                                
#include "system.h"                                                             ...!includes auto-comment...
#include "c-strtod.h"                                                           ...!includes auto-comment...
#include "die.h"                                                                ...!includes auto-comment...
#include "error.h"                                                              ...!includes auto-comment...
#include "long-options.h"                                                       ...!includes auto-comment...
#include "quote.h"                                                              ...!includes auto-comment...
#include "xnanosleep.h"                                                         ...!includes auto-comment...
#include "xstrtod.h"                                                            ...!includes auto-comment...
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#define PROGRAM_NAME "sleep"                                                    Line 32
                                                                                
#define AUTHORS \                                                               Line 34
  proper_name ("Jim Meyering"), \                                               Line 35
  proper_name ("Paul Eggert")                                                   Line 36
                                                                                
static struct option const long_options[] =                                     Line 38
{                                                                               
  {NULL, 0, NULL, 0}                                                            Line 40
};                                                                              Block 1
                                                                                
void                                                                            Line 43
usage (int status)                                                              Line 44
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 46
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 48
    {                                                                           
      printf (_("\                                                              Line 50
Usage: %s NUMBER[SUFFIX]...\n\                                                  Line 51
  or:  %s OPTION\n\                                                             Line 52
Pause for NUMBER seconds.  SUFFIX may be 's' for seconds (the default),\n\      Line 53
'm' for minutes, 'h' for hours or 'd' for days.  Unlike most implementations\n\ Line 54
that require NUMBER be an integer, here NUMBER may be an arbitrary floating\n\  Line 55
point number.  Given two or more arguments, pause for the amount of time\n\     Line 56
specified by the sum of their values.\n\                                        Line 57
\n\                                                                             
"),                                                                             Line 59
              program_name, program_name);                                      Line 60
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 61
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 62
      emit_ancillary_info (PROGRAM_NAME);                                       Line 63
    }                                                                           
  exit (status);                                                                Line 65
}                                                                               Block 2
                                                                                
/* Given a floating point value *X, and a suffix character, SUFFIX_CHAR,        
   scale *X by the multiplier implied by SUFFIX_CHAR.  SUFFIX_CHAR may          
   be the NUL byte or 's' to denote seconds, 'm' for minutes, 'h' for           
   hours, or 'd' for days.  If SUFFIX_CHAR is invalid, don't modify *X          
   and return false.  Otherwise return true.  */                                
                                                                                
static bool                                                                     Line 74
apply_suffix (double *x, char suffix_char)                                      Line 75
{                                                                               
  int multiplier;                                                               Line 77
                                                                                
  switch (suffix_char)                                                          Line 79
    {                                                                           
    case 0:                                                                     Line 81
    case 's':                                                                   Line 82
      multiplier = 1;                                                           Line 83
      break;                                                                    Line 84
    case 'm':                                                                   Line 85
      multiplier = 60;                                                          Line 86
      break;                                                                    Line 87
    case 'h':                                                                   Line 88
      multiplier = 60 * 60;                                                     Line 89
      break;                                                                    Line 90
    case 'd':                                                                   Line 91
      multiplier = 60 * 60 * 24;                                                Line 92
      break;                                                                    Line 93
    default:                                                                    Line 94
      return false;                                                             Line 95
    }                                                                           
                                                                                
  *x *= multiplier;                                                             Line 98
                                                                                
  return true;                                                                  Line 100
}                                                                               Block 3
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 104
{                                                                               
  double seconds = 0.0;                                                         Line 106
  bool ok = true;                                                               Line 107
                                                                                
  initialize_main (&argc, &argv);                                               VMS-specific entry point handling wildcard expansion
  set_program_name (argv[0]);                                                   Retains program name and discards path
  setlocale (LC_ALL, "");                                                       Sets up internationalization (i18n)
  bindtextdomain (PACKAGE, LOCALEDIR);                                          Assigns i18n directorySets text domain for _() [gettext()] function
  textdomain (PACKAGE);                                                         Sets text domain for _() [gettext()] function
                                                                                
  atexit (close_stdout);                                                        Close stdout on exit (see gnulib)
                                                                                
  parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,          ...!common auto-comment...
                      usage, AUTHORS, (char const *) NULL);                     Line 118
  if (getopt_long (argc, argv, "", long_options, NULL) != -1)                   Line 119
    usage (EXIT_FAILURE);                                                       Line 120
                                                                                
  if (argc == 1)                                                                Line 122
    {                                                                           
      error (0, 0, _("missing operand"));                                       Line 124
      usage (EXIT_FAILURE);                                                     Line 125
    }                                                                           
                                                                                
  for (int i = optind; i < argc; i++)                                           Line 128
    {                                                                           
      double s;                                                                 Line 130
      const char *p;                                                            Line 131
      if (! (xstrtod (argv[i], &p, &s, c_strtod) || errno == ERANGE)            Line 132
          /* Nonnegative interval.  */                                          
          || ! (0 <= s)                                                         Line 134
          /* No extra chars after the number and an optional s,m,h,d char.  */  
          || (*p && *(p+1))                                                     Line 136
          /* Check any suffix char and update S based on the suffix.  */        
          || ! apply_suffix (&s, *p))                                           Line 138
        {                                                                       
          error (0, 0, _("invalid time interval %s"), quote (argv[i]));         Line 140
          ok = false;                                                           Line 141
        }                                                                       
                                                                                
      seconds += s;                                                             Line 144
    }                                                                           
                                                                                
  if (!ok)                                                                      Line 147
    usage (EXIT_FAILURE);                                                       Line 148
                                                                                
  if (xnanosleep (seconds))                                                     Line 150
    die (EXIT_FAILURE, errno, _("cannot read realtime clock"));                 Line 151
                                                                                
  return EXIT_SUCCESS;                                                          Line 153
}                                                                               Block 4