src/compat/gnu_strftime.c File Reference

#include <ctype.h>
#include <sys/types.h>
#include <time.h>
Include dependency graph for gnu_strftime.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define DO_MULTIBYTE   (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
#define memcpy(d, s, n)   bcopy ((s), (d), (n))
#define MEMPCPY(d, s, n)   ((void *) ((char *) memcpy (d, s, n) + (n)))
#define __P(args)   ()
#define PTR   char *
#define CHAR_BIT   8
#define NULL   0
#define TYPE_SIGNED(t)   ((t) -1 < 0)
#define INT_STRLEN_BOUND(t)   ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
#define TM_YEAR_BASE   1900
#define __isleap(year)   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
#define memset_space(P, Len)
#define memset_zero(P, Len)
#define add(n, f)
#define cpy(n, s)
#define TOUPPER(Ch)   (islower (Ch) ? toupper (Ch) : (Ch))
#define TOLOWER(Ch)   (isupper (Ch) ? tolower (Ch) : (Ch))
#define ISDIGIT(Ch)   ((unsigned int) (Ch) - '0' <= 9)
#define tm_diff   ftime_tm_diff
#define ISO_WEEK_START_WDAY   1
#define ISO_WEEK1_WDAY   4
#define YDAY_MINIMUM   (-366)
#define my_strftime   strftime
#define ut_argument
#define ut_argument_spec
#define ut_argument_spec_iso
#define ut   0
#define f_wkday   (weekday_name[tp->tm_wday])
#define f_month   (month_name[tp->tm_mon])
#define a_wkday   f_wkday
#define a_month   f_month
#define ampm   ("AMPM" + 2 * (tp->tm_hour > 11))
#define DO_NUMBER(d, v)
#define DO_NUMBER_SPACEPAD(d, v)

Functions

static struct tm * my_strftime_gmtime_r ()
static struct tm * my_strftime_gmtime_r (time_t *t, struct tm *tp) const
static struct tm * my_strftime_localtime_r ()
static struct tm * my_strftime_localtime_r (time_t *t, struct tm *tp) const
static char * memcpy_lowcase ()
static char * memcpy_lowcase (char *dest, const char *src, size_t len)
static char * memcpy_uppcase ()
static char * memcpy_uppcase (char *dest, const char *src, size_t len)
static int ftime_tm_diff ()
static int ftime_tm_diff (struct tm *a, const struct tm *b) const
static int iso_week_days ()
static int iso_week_days (int yday, int wday)
size_t strftime (char *s, size_t maxsize, const char *format, const struct tm *tp)

Variables

static const char spaces [16]
static const char zeroes [16]
static char const weekday_name [][10]
static char const month_name [][10]

Define Documentation

#define __isleap ( year   )     ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))

Definition at line 139 of file gnu_strftime.c.

Referenced by strftime().

#define __P ( args   )     ()

Definition at line 104 of file gnu_strftime.c.

#define a_month   f_month

Referenced by strftime().

#define a_wkday   f_wkday

Referenced by strftime().

#define add ( n,
 ) 
Value:
do                                        \
    {                                         \
      int _n = (n);                               \
      int _delta = width - _n;                            \
      int _incr = _n + (_delta > 0 ? _delta : 0);                 \
      if (i + _incr >= maxsize)                           \
    return 0;                                 \
      if (p)                                      \
    {                                     \
      if (_delta > 0)                             \
        {                                     \
          if (pad == '0')                             \
        memset_zero (p, _delta);                      \
          else                                \
        memset_space (p, _delta);                     \
        }                                     \
      f;                                      \
      p += _n;                                \
    }                                     \
      i += _incr;                                 \
    } while (0)

Definition at line 225 of file gnu_strftime.c.

Referenced by strftime().

#define ampm   ("AMPM" + 2 * (tp->tm_hour > 11))

Referenced by strftime().

#define CHAR_BIT   8

Definition at line 117 of file gnu_strftime.c.

#define cpy ( n,
 ) 
Value:
add ((n),                                     \
     if (to_lowcase)                              \
       memcpy_lowcase (p, (s), _n);                       \
     else if (to_uppcase)                             \
       memcpy_uppcase (p, (s), _n);                       \
     else                                     \
       memcpy ((PTR) p, (PTR) (s), _n))

Definition at line 248 of file gnu_strftime.c.

Referenced by strftime().

#define DO_MULTIBYTE   (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)

Definition at line 64 of file gnu_strftime.c.

#define DO_NUMBER ( d,
 ) 
Value:
digits = width == -1 ? d : width;                     \
      number_value = v; goto do_number

Referenced by strftime().

#define DO_NUMBER_SPACEPAD ( d,
 ) 
Value:
digits = width == -1 ? d : width;                     \
      number_value = v; goto do_number_spacepad

Referenced by strftime().

#define f_month   (month_name[tp->tm_mon])

Referenced by strftime().

#define f_wkday   (weekday_name[tp->tm_wday])

Referenced by strftime().

#define INT_STRLEN_BOUND (  )     ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))

Definition at line 131 of file gnu_strftime.c.

Referenced by strftime().

#define ISDIGIT ( Ch   )     ((unsigned int) (Ch) - '0' <= 9)

Definition at line 270 of file gnu_strftime.c.

Referenced by strftime().

#define ISO_WEEK1_WDAY   4

Definition at line 335 of file gnu_strftime.c.

Referenced by iso_week_days().

#define ISO_WEEK_START_WDAY   1

Definition at line 334 of file gnu_strftime.c.

Referenced by iso_week_days().

#define memcpy ( d,
s,
 )     bcopy ((s), (d), (n))

Definition at line 88 of file gnu_strftime.c.

#define MEMPCPY ( d,
s,
 )     ((void *) ((char *) memcpy (d, s, n) + (n)))

Definition at line 96 of file gnu_strftime.c.

#define memset_space ( P,
Len   ) 
Value:
do {                                          \
    int _len = (Len);                                 \
                                          \
    do                                        \
      {                                       \
    int _this = _len > 16 ? 16 : _len;                    \
    (P) = MEMPCPY ((P), spaces, _this);                   \
    _len -= _this;                                \
      }                                       \
    while (_len > 0);                                 \
  } while (0)

Definition at line 195 of file gnu_strftime.c.

#define memset_zero ( P,
Len   ) 
Value:
do {                                          \
    int _len = (Len);                                 \
                                          \
    do                                        \
      {                                       \
    int _this = _len > 16 ? 16 : _len;                    \
    (P) = MEMPCPY ((P), zeroes, _this);                   \
    _len -= _this;                                \
      }                                       \
    while (_len > 0);                                 \
  } while (0)

Definition at line 208 of file gnu_strftime.c.

#define my_strftime   strftime

Definition at line 374 of file gnu_strftime.c.

Referenced by strftime().

#define NULL   0

Definition at line 121 of file gnu_strftime.c.

Referenced by _dcc_send(), _filedb_getfile(), _filedb_matchfile(), _malloc_fdbe(), _wild_match_per(), add_assoc(), add_cd_tcl_cmds(), add_chanrec(), add_delay(), add_help_reference(), add_lang(), add_lang_section(), add_note(), answer_local_whom(), append_line(), assoc_close(), assoc_start(), bg_do_detach(), bgtclcallback(), bind_bind_entry(), block_dns_hostbyip(), blowfish_expmem(), blowfish_init(), blowfish_report(), blowfish_start(), bot_actchan(), bot_chan2(), bot_chat(), bot_filereject(), bot_filereq(), bot_filesend(), bot_infoq(), bot_link(), bot_motd(), bot_nlinked(), bot_priv(), bot_reject(), bot_traced(), bot_unlink(), botaddr_pack(), botaddr_set(), botaddr_tcl_get(), botfl_display(), botfl_pack(), botfl_tcl_get(), botfl_tcl_set(), botfl_unpack(), botfl_write_userfile(), call_hostbyip(), call_ipbyhost(), call_tcl_func(), changeover_dcc(), channels_chon(), channels_close(), channels_start(), chanprog(), chanset_unlink(), charp_func(), check_botnet_pings(), check_chanlist(), check_chanlist_hand(), check_dcclist_hand(), check_delay(), check_expired_bans(), check_expired_exempts(), check_expired_invites(), check_expired_tbufs(), check_logsize(), check_secondly(), check_tcl_ctcpr(), check_tcl_msg(), check_tcl_msgm(), check_tcl_notc(), check_this_member(), check_this_user(), chof_wire(), clear_chanlist(), clear_chanlist_member(), clear_masks(), cmd_act(), cmd_adduser(), cmd_assoc(), cmd_boot(), cmd_botattr(), cmd_channel(), cmd_chanset(), cmd_chat(), cmd_chattr(), cmd_chdir(), cmd_chhandle(), cmd_chinfo(), cmd_chpass(), cmd_comment(), cmd_deluser(), cmd_desc(), cmd_filestats(), cmd_fwd(), cmd_handle(), cmd_hide(), cmd_info(), cmd_kick(), cmd_kickban(), cmd_languagedump(), cmd_ln(), cmd_match(), cmd_me(), cmd_mkdir(), cmd_mns_ban(), cmd_mns_chrec(), cmd_mns_exempt(), cmd_mns_host(), cmd_mns_invite(), cmd_mns_user(), cmd_module(), cmd_mv_cp(), cmd_optimize(), cmd_pls_ban(), cmd_pls_bot(), cmd_pls_chan(), cmd_pls_exempt(), cmd_pls_host(), cmd_pls_ignore(), cmd_pls_invite(), cmd_pls_user(), cmd_reget_get(), cmd_rm(), cmd_rmdir(), cmd_say(), cmd_set(), cmd_share(), cmd_status(), cmd_stick_yn(), cmd_su(), cmd_tcl(), cmd_topic(), cmd_unhide(), cmd_unshare(), cmd_whom(), compress_close(), compress_start(), console_chon(), console_close(), console_dostore(), console_pack(), console_start(), console_tcl_get(), cont_tandem_relay(), convert_old_files(), core_secondly(), correct_handle(), ctcp_CLIENTINFO(), ctcp_close(), ctcp_start(), dcc_chat(), dcc_chat_pass(), dcc_chatter(), dcc_remove_lost(), dcc_script(), dcc_telnet_got_ident(), dcc_telnet_id(), dcc_telnet_new(), dcc_telnet_pass(), debug_mem_to_dcc(), def_pack(), def_set(), def_tcl_get(), def_unpack(), del_chanrec(), del_lang(), del_lang_section(), del_tbuf(), delay_expmem(), delay_free_mem(), deq_kick(), deq_msg(), deq_this(), detect_telnet_flood(), display_tellhelp(), dns_change(), dns_close(), dns_free_cache(), dns_start(), do_channel_part(), do_check_timers(), do_dcc_send(), do_seen(), dorequest(), dump_assoc(), dump_bind_tables(), dup_userlist(), expire_notes(), expmem_net(), expmem_tclmisc(), expmem_users(), filedb_add(), filedb_change(), filedb_cleanup(), filedb_findempty(), filedb_getdesc(), filedb_getdirs(), filedb_getentry(), filedb_getfiles(), filedb_getgots(), filedb_getlink(), filedb_getowner(), filedb_ls(), filedb_mergeempty(), filedb_open(), filedb_setdesc(), filedb_setlink(), filedb_setowner(), filedb_timestamp(), filedb_update(), filelist_add(), filelist_new(), fileq_cancel(), files_ls(), files_reget(), filesys_close(), filesys_dcc_send(), filesys_dcc_send_hostresolved(), filesys_start(), findbot(), findchan(), findchan_by_dname(), findhost(), findid(), findip(), finish_share(), flush_fileq(), flush_lines(), flush_mode(), flush_tbuf(), flushlogs(), freeuser(), fstat_gotshare(), fstat_pack(), fstat_set(), fstat_tcl_get(), fstat_tcl_set(), garbage_collect_tclhash(), get_assoc_name(), get_chanrec(), get_handle_chaninfo(), get_ip(), get_langfile(), get_specific_langfile(), get_user_by_equal_host(), get_user_flagrec(), getnick(), global(), got324(), got331(), got332(), got352or4(), got354(), got437(), got_ban(), got_exempt(), got_invite(), got_unban(), got_unexempt(), got_uninvite(), gotfake433(), gotjoin(), gotmode(), gotmsg(), gotnick(), gotnotice(), gotquit(), gottopic(), help_subst(), hosts_set(), incr_file_gots(), init_bind(), init_bots(), init_dns_core(), init_mem(), init_misc(), init_modules(), init_tcl(), init_threaddata(), init_uptime(), initudef(), int(), IP(), irc_close(), irc_report(), irc_start(), ismember(), isowner(), kill_all_assoc(), kill_assoc(), kill_bind(), killmember(), killtransfer(), laston_pack(), laston_tcl_get(), linkresolve(), linkresolvehost(), linkresolveid(), linkresolveip(), logsuffix_change(), main(), mainloop(), make_point_path(), match_trigger(), me_halfop(), me_op(), modebind_refresh(), msg_addhost(), msg_hello(), msg_ident(), msg_info(), msgq_clear(), n_free(), n_malloc(), n_realloc(), new_tbuf(), newmask(), newmember(), next_server(), not_away(), notes_change(), notes_close(), notes_start(), num_notes(), parse_q(), pass_set(), pass_tcl_set(), pub_seen(), punish_badguy(), purge_kicks(), putlog(), q_addmsg(), queue_server(), raw_dcc_resend_send(), read_lang(), real_add_mode(), rehash(), reload(), reload_help_data(), rem_help_reference(), rembot(), remote_filereq(), remote_tell_who(), remove_channel(), remove_crlf(), replace_spaces(), resetmasks(), resolve_dir(), resolve_help(), rmspace(), seen_close(), seen_start(), send_next_file(), send_uptime(), sendrequest(), server_close(), server_die(), server_postrehash(), server_start(), set_away(), set_handle_chaninfo(), set_key(), set_topic(), set_user_flagrec(), setudef(), share_change(), share_chhand(), share_close(), share_killuser(), share_mns_ban(), share_mns_exempt(), share_mns_host(), share_mns_ignore(), share_mns_invite(), share_newuser(), share_pls_ban(), share_pls_bothost(), share_pls_exempt(), share_pls_host(), share_pls_ignore(), share_pls_invite(), share_start(), share_stick_ban(), share_stick_exempt(), share_stick_invite(), share_ufsend(), show_banner(), show_motd(), show_queued_files(), showhelp(), splitc(), splitcn(), start_sending_users(), status_log(), str_escape(), strchr_unescape(), strftime(), sub_lang(), subst_addcol(), tandem_relay_resolve_success(), tcl_addbot(), tcl_adduser(), tcl_bind(), tcl_binds(), tcl_botattr(), tcl_chattr(), tcl_chhandle(), tcl_countusers(), tcl_ctime(), tcl_dccdumpfile(), tcl_delhost(), tcl_deluser(), tcl_dnshostbyip(), tcl_dnsipbyhost(), tcl_dumpfile(), tcl_duration(), tcl_eggcouplet(), tcl_eggint(), tcl_eggserver(), tcl_eggstr(), tcl_finduser(), tcl_getting_users(), tcl_getuser(), tcl_isignore(), tcl_killignore(), tcl_killtimer(), tcl_killutimer(), tcl_loadmodule(), tcl_logfile(), tcl_matchaddr(), tcl_matchattr(), tcl_matchcidr(), tcl_matchstr(), tcl_md5(), tcl_myip(), tcl_passwdOk(), tcl_putloglev(), tcl_rand(), tcl_resultint(), tcl_sendnote(), tcl_setuser(), tcl_strftime(), tcl_stripcodes(), tcl_timer(), tcl_unames(), tcl_unixtime(), tcl_unloadmodule(), tcl_userlist(), tcl_utimer(), tcl_validuser(), tell_bans(), tell_bottree(), tell_exempts(), tell_file_stats(), tell_invites(), tell_settings(), tell_who(), traced_globchanset(), traced_nettype(), traced_rfccompliant(), transfer_close(), transfer_start(), u_addban(), u_addexempt(), u_addinvite(), u_delban(), u_delexempt(), u_delinvite(), uf_features_check(), uf_features_dump(), uf_features_parse(), uff_findentry_byflag(), uff_findentry_byname(), uff_insert_entry(), uptime_report(), uptime_start(), void(), welcome_to_files(), wipe_timers(), wire_close(), wire_start(), woobie_close(), woobie_start(), and write_channels().

#define PTR   char *

Definition at line 112 of file gnu_strftime.c.

#define tm_diff   ftime_tm_diff

Definition at line 302 of file gnu_strftime.c.

Referenced by strftime().

#define TM_YEAR_BASE   1900

Definition at line 134 of file gnu_strftime.c.

Referenced by ftime_tm_diff(), and strftime().

#define TOLOWER ( Ch   )     (isupper (Ch) ? tolower (Ch) : (Ch))

Definition at line 264 of file gnu_strftime.c.

Referenced by memcpy_lowcase().

#define TOUPPER ( Ch   )     (islower (Ch) ? toupper (Ch) : (Ch))

Definition at line 263 of file gnu_strftime.c.

Referenced by memcpy_uppcase(), and strftime().

#define TYPE_SIGNED (  )     ((t) -1 < 0)

Definition at line 124 of file gnu_strftime.c.

#define ut   0

Definition at line 379 of file gnu_strftime.c.

Referenced by freeuser(), and strftime().

#define ut_argument

Definition at line 375 of file gnu_strftime.c.

#define ut_argument_spec

Definition at line 376 of file gnu_strftime.c.

#define ut_argument_spec_iso

Definition at line 377 of file gnu_strftime.c.

#define YDAY_MINIMUM   (-366)

Definition at line 336 of file gnu_strftime.c.

Referenced by iso_week_days().


Function Documentation

static int ftime_tm_diff ( struct tm *  a,
const struct tm *  b 
) const [static]

Definition at line 305 of file gnu_strftime.c.

References days, and TM_YEAR_BASE.

00308 {
00309   /* Compute intervening leap days correctly even if year is negative.
00310      Take care to avoid int overflow in leap day calculations,
00311      but it's OK to assume that A and B are close to each other.  */
00312   int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
00313   int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
00314   int a100 = a4 / 25 - (a4 % 25 < 0);
00315   int b100 = b4 / 25 - (b4 % 25 < 0);
00316   int a400 = a100 >> 2;
00317   int b400 = b100 >> 2;
00318   int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
00319   int years = a->tm_year - b->tm_year;
00320   int days = (365 * years + intervening_leap_days
00321           + (a->tm_yday - b->tm_yday));
00322   return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
00323         + (a->tm_min - b->tm_min))
00324       + (a->tm_sec - b->tm_sec));
00325 }

static int ftime_tm_diff (  )  [static]
static int iso_week_days ( int  yday,
int  wday 
) [static]

Definition at line 342 of file gnu_strftime.c.

References ISO_WEEK1_WDAY, ISO_WEEK_START_WDAY, and YDAY_MINIMUM.

00345 {
00346   /* Add enough to the first operand of % to make it nonnegative.  */
00347   int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
00348   return (yday
00349       - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
00350       + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
00351 }

static int iso_week_days (  )  [static]

Referenced by strftime().

Here is the caller graph for this function:

static char* memcpy_lowcase ( char *  dest,
const char *  src,
size_t  len 
) [static]

Definition at line 275 of file gnu_strftime.c.

References TOLOWER.

00279 {
00280   while (len-- > 0)
00281     dest[len] = TOLOWER ((unsigned char) src[len]);
00282   return dest;
00283 }

static char* memcpy_lowcase (  )  [static]
static char* memcpy_uppcase ( char *  dest,
const char *  src,
size_t  len 
) [static]

Definition at line 288 of file gnu_strftime.c.

References TOUPPER.

00292 {
00293   while (len-- > 0)
00294     dest[len] = TOUPPER ((unsigned char) src[len]);
00295   return dest;
00296 }

static char* memcpy_uppcase (  )  [static]
static struct tm* my_strftime_gmtime_r ( time_t t,
struct tm *  tp 
) const [static, read]

Definition at line 158 of file gnu_strftime.c.

00161 {
00162   struct tm *l = gmtime (t);
00163   if (! l)
00164     return 0;
00165   *tp = *l;
00166   return tp;
00167 }

static struct tm* my_strftime_gmtime_r (  )  [static, read]

Referenced by strftime().

Here is the caller graph for this function:

static struct tm* my_strftime_localtime_r ( time_t t,
struct tm *  tp 
) const [static, read]

Definition at line 172 of file gnu_strftime.c.

00175 {
00176   struct tm *l = localtime (t);
00177   if (! l)
00178     return 0;
00179   *tp = *l;
00180   return tp;
00181 }

static struct tm* my_strftime_localtime_r (  )  [static, read]

Referenced by strftime().

Here is the caller graph for this function:

size_t strftime ( char *  s,
size_t  maxsize,
const char *  format,
const struct tm *  tp 
)

Definition at line 412 of file gnu_strftime.c.

References __isleap, a_month, a_wkday, add, ampm, cpy, days, DO_NUMBER, DO_NUMBER_SPACEPAD, f_month, f_wkday, int, INT_STRLEN_BOUND, ISDIGIT, iso_week_days(), my_strftime, my_strftime_gmtime_r(), my_strftime_localtime_r(), NULL, strftime, time_t, tm_diff, TM_YEAR_BASE, TOUPPER, and ut.

00418 {
00419   int hour12 = tp->tm_hour;
00420 #ifdef _NL_CURRENT
00421   /* We cannot make the following values variables since we must delay
00422      the evaluation of these values until really needed since some
00423      expressions might not be valid in every situation.  The `struct tm'
00424      might be generated by a strptime() call that initialized
00425      only a few elements.  Dereference the pointers only if the format
00426      requires this.  Then it is ok to fail if the pointers are invalid.  */
00427 # define a_wkday _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday)
00428 # define f_wkday _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday)
00429 # define a_month _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon)
00430 # define f_month _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon)
00431 # define ampm _NL_CURRENT (LC_TIME, tp->tm_hour > 11 ? PM_STR : AM_STR)
00432 
00433 # define aw_len strlen (a_wkday)
00434 # define am_len strlen (a_month)
00435 # define ap_len strlen (ampm)
00436 #else
00437 # if !HAVE_STRFTIME
00438 # define f_wkday (weekday_name[tp->tm_wday])
00439 # define f_month (month_name[tp->tm_mon])
00440 # define a_wkday f_wkday
00441 # define a_month f_month
00442 # define ampm ("AMPM" + 2 * (tp->tm_hour > 11))
00443 
00444   size_t aw_len = 3;
00445   size_t am_len = 3;
00446   size_t ap_len = 2;
00447 # endif
00448 #endif
00449   const char *zone;
00450   size_t i = 0;
00451   char *p = s;
00452   const char *f;
00453 
00454   zone = NULL;
00455 #if HAVE_TM_ZONE
00456   /* The POSIX test suite assumes that setting
00457      the environment variable TZ to a new value before calling strftime()
00458      will influence the result (the %Z format) even if the information in
00459      TP is computed with a totally different time zone.
00460      This is bogus: though POSIX allows bad behavior like this,
00461      POSIX does not require it.  Do the right thing instead.  */
00462   zone = (const char *) tp->tm_zone;
00463 #endif
00464 #if HAVE_TZNAME
00465   if (ut)
00466     {
00467       if (! (zone && *zone))
00468     zone = "GMT";
00469     }
00470   else
00471     {
00472       /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
00473      time zone names contained in the external variable `tzname' shall
00474      be set as if the tzset() function had been called.  */
00475 # if HAVE_TZSET
00476       tzset ();
00477 # endif
00478     }
00479 #endif
00480 
00481   if (hour12 > 12)
00482     hour12 -= 12;
00483   else
00484     if (hour12 == 0)
00485       hour12 = 12;
00486 
00487   for (f = format; *f != '\0'; ++f)
00488     {
00489       int pad = 0;      /* Padding for number ('-', '_', or 0).  */
00490       int modifier;     /* Field modifier ('E', 'O', or 0).  */
00491       int digits;       /* Max digits for numeric format.  */
00492       int number_value;     /* Numeric value to be printed.  */
00493       int negative_number;  /* 1 if the number is negative.  */
00494       const char *subfmt;
00495       char *bufp;
00496       char buf[1 + (sizeof (int) < sizeof (time_t)
00497             ? INT_STRLEN_BOUND (time_t)
00498             : INT_STRLEN_BOUND (int))];
00499       int width = -1;
00500       int to_lowcase = 0;
00501       int to_uppcase = 0;
00502       int change_case = 0;
00503       int format_char;
00504 
00505 #if DO_MULTIBYTE
00506 
00507        switch (*f)
00508     {
00509     case '%':
00510       break;
00511 
00512     case '\a': case '\b': case '\t': case '\n':
00513     case '\v': case '\f': case '\r':
00514     case ' ': case '!': case '"': case '#': case '&': case'\'':
00515     case '(': case ')': case '*': case '+': case ',': case '-':
00516     case '.': case '/': case '0': case '1': case '2': case '3':
00517     case '4': case '5': case '6': case '7': case '8': case '9':
00518     case ':': case ';': case '<': case '=': case '>': case '?':
00519     case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
00520     case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
00521     case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
00522     case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
00523     case 'Y': case 'Z': case '[': case'\\': case ']': case '^':
00524     case '_': case 'a': case 'b': case 'c': case 'd': case 'e':
00525     case 'f': case 'g': case 'h': case 'i': case 'j': case 'k':
00526     case 'l': case 'm': case 'n': case 'o': case 'p': case 'q':
00527     case 'r': case 's': case 't': case 'u': case 'v': case 'w':
00528     case 'x': case 'y': case 'z': case '{': case '|': case '}':
00529     case '~':
00530       /* The C Standard requires these 98 characters (plus '%') to
00531          be in the basic execution character set.  None of these
00532          characters can start a multibyte sequence, so they need
00533          not be analyzed further.  */
00534       add (1, *p = *f);
00535       continue;
00536 
00537     default:
00538       /* Copy this multibyte sequence until we reach its end, find
00539          an error, or come back to the initial shift state.  */
00540       {
00541         mbstate_t mbstate = mbstate_zero;
00542         size_t len = 0;
00543 
00544         do
00545           {
00546         size_t bytes = mbrlen (f + len, (size_t) -1, &mbstate);
00547 
00548         if (bytes == 0)
00549           break;
00550 
00551         if (bytes == (size_t) -2)
00552           {
00553             len += strlen (f + len);
00554             break;
00555           }
00556 
00557         if (bytes == (size_t) -1)
00558           {
00559             len++;
00560             break;
00561           }
00562 
00563         len += bytes;
00564           }
00565         while (! mbsinit (&mbstate));
00566 
00567         cpy (len, f);
00568         f += len - 1;
00569         continue;
00570       }
00571     }
00572 
00573 #else /* ! DO_MULTIBYTE */
00574 
00575       /* Either multibyte encodings are not supported, or they are
00576      safe for formats, so any non-'%' byte can be copied through.  */
00577       if (*f != '%')
00578     {
00579       add (1, *p = *f);
00580       continue;
00581     }
00582 
00583 #endif /* ! DO_MULTIBYTE */
00584 
00585       /* Check for flags that can modify a format.  */
00586       while (1)
00587     {
00588       switch (*++f)
00589         {
00590           /* This influences the number formats.  */
00591         case '_':
00592         case '-':
00593         case '0':
00594           pad = *f;
00595           continue;
00596 
00597           /* This changes textual output.  */
00598         case '^':
00599           to_uppcase = 1;
00600           continue;
00601         case '#':
00602           change_case = 1;
00603           continue;
00604 
00605         default:
00606           break;
00607         }
00608       break;
00609     }
00610 
00611       /* As a GNU extension we allow to specify the field width.  */
00612       if (ISDIGIT (*f))
00613     {
00614       width = 0;
00615       do
00616         {
00617           width *= 10;
00618           width += *f - '0';
00619           ++f;
00620         }
00621       while (ISDIGIT (*f));
00622     }
00623 
00624       /* Check for modifiers.  */
00625       switch (*f)
00626     {
00627     case 'E':
00628     case 'O':
00629       modifier = *f++;
00630       break;
00631 
00632     default:
00633       modifier = 0;
00634       break;
00635     }
00636 
00637       /* Now do the specified format.  */
00638       format_char = *f;
00639       switch (format_char)
00640     {
00641 #define DO_NUMBER(d, v) \
00642       digits = width == -1 ? d : width;                   \
00643       number_value = v; goto do_number
00644 #define DO_NUMBER_SPACEPAD(d, v) \
00645       digits = width == -1 ? d : width;                   \
00646       number_value = v; goto do_number_spacepad
00647 
00648     case '%':
00649       if (modifier != 0)
00650         goto bad_format;
00651       add (1, *p = *f);
00652       break;
00653 
00654     case 'a':
00655       if (modifier != 0)
00656         goto bad_format;
00657       if (change_case)
00658         {
00659           to_uppcase = 1;
00660           to_lowcase = 0;
00661         }
00662 #if defined _NL_CURRENT || !HAVE_STRFTIME
00663       cpy (aw_len, a_wkday);
00664       break;
00665 #else
00666       goto underlying_strftime;
00667 #endif
00668 
00669     case 'A':
00670       if (modifier != 0)
00671         goto bad_format;
00672       if (change_case)
00673         {
00674           to_uppcase = 1;
00675           to_lowcase = 0;
00676         }
00677 #if defined _NL_CURRENT || !HAVE_STRFTIME
00678       cpy (strlen (f_wkday), f_wkday);
00679       break;
00680 #else
00681       goto underlying_strftime;
00682 #endif
00683 
00684     case 'b':
00685     case 'h':       /* POSIX.2 extension.  */
00686       if (modifier != 0)
00687         goto bad_format;
00688 #if defined _NL_CURRENT || !HAVE_STRFTIME
00689       cpy (am_len, a_month);
00690       break;
00691 #else
00692       goto underlying_strftime;
00693 #endif
00694 
00695     case 'B':
00696       if (modifier != 0)
00697         goto bad_format;
00698       if (change_case)
00699         {
00700           to_uppcase = 1;
00701           to_lowcase = 0;
00702         }
00703 #if defined _NL_CURRENT || !HAVE_STRFTIME
00704       cpy (strlen (f_month), f_month);
00705       break;
00706 #else
00707       goto underlying_strftime;
00708 #endif
00709 
00710     case 'c':
00711       if (modifier == 'O')
00712         goto bad_format;
00713 #ifdef _NL_CURRENT
00714       if (! (modifier == 'E'
00715          && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0'))
00716         subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);
00717 #else
00718 # if HAVE_STRFTIME
00719       goto underlying_strftime;
00720 # else
00721       subfmt = "%a %b %e %H:%M:%S %Y";
00722 # endif
00723 #endif
00724 
00725     subformat:
00726       {
00727         char *old_start = p;
00728         size_t len = my_strftime (NULL, (size_t) -1, subfmt, tp);
00729         add (len, my_strftime (p, maxsize - i, subfmt, tp));
00730 
00731         if (to_uppcase)
00732           while (old_start < p)
00733         {
00734           *old_start = TOUPPER ((unsigned char) *old_start);
00735           ++old_start;
00736         }
00737       }
00738       break;
00739 
00740 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
00741     underlying_strftime:
00742       {
00743         /* The relevant information is available only via the
00744            underlying strftime implementation, so use that.  */
00745         char ufmt[4];
00746         char *u = ufmt;
00747         char ubuf[1024]; /* enough for any single format in practice */
00748         size_t len;
00749         *u++ = '%';
00750         if (modifier != 0)
00751           *u++ = modifier;
00752         *u++ = format_char;
00753         *u = '\0';
00754         len = strftime (ubuf, sizeof ubuf, ufmt, tp);
00755         if (len == 0 && ubuf[0] != '\0')
00756           return 0;
00757         cpy (len, ubuf);
00758       }
00759       break;
00760 #endif
00761 
00762     case 'C':       /* POSIX.2 extension.  */
00763       if (modifier == 'O')
00764         goto bad_format;
00765       if (modifier == 'E')
00766         {
00767 #if HAVE_STRUCT_ERA_ENTRY
00768           struct era_entry *era = _nl_get_era_entry (tp);
00769           if (era)
00770         {
00771           size_t len = strlen (era->name_fmt);
00772           cpy (len, era->name_fmt);
00773           break;
00774         }
00775 #else
00776 # if HAVE_STRFTIME
00777           goto underlying_strftime;
00778 # endif
00779 #endif
00780         }
00781 
00782       {
00783         int year = tp->tm_year + TM_YEAR_BASE;
00784         DO_NUMBER (1, year / 100 - (year % 100 < 0));
00785       }
00786 
00787     case 'x':
00788       if (modifier == 'O')
00789         goto bad_format;
00790 #ifdef _NL_CURRENT
00791       if (! (modifier == 'E'
00792          && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0'))
00793         subfmt = _NL_CURRENT (LC_TIME, D_FMT);
00794       goto subformat;
00795 #else
00796 # if HAVE_STRFTIME
00797       goto underlying_strftime;
00798 # else
00799       /* Fall through.  */
00800 # endif
00801 #endif
00802     case 'D':       /* POSIX.2 extension.  */
00803       if (modifier != 0)
00804         goto bad_format;
00805       subfmt = "%m/%d/%y";
00806       goto subformat;
00807 
00808     case 'd':
00809       if (modifier == 'E')
00810         goto bad_format;
00811 
00812       DO_NUMBER (2, tp->tm_mday);
00813 
00814     case 'e':       /* POSIX.2 extension.  */
00815       if (modifier == 'E')
00816         goto bad_format;
00817 
00818       DO_NUMBER_SPACEPAD (2, tp->tm_mday);
00819 
00820       /* All numeric formats set DIGITS and NUMBER_VALUE and then
00821          jump to one of these two labels.  */
00822 
00823     do_number_spacepad:
00824       /* Force `_' flag unless overwritten by `0' flag.  */
00825       if (pad != '0')
00826         pad = '_';
00827 
00828     do_number:
00829       /* Format the number according to the MODIFIER flag.  */
00830 
00831       if (modifier == 'O' && 0 <= number_value)
00832         {
00833 #ifdef _NL_CURRENT
00834           /* Get the locale specific alternate representation of
00835          the number NUMBER_VALUE.  If none exist NULL is returned.  */
00836           const char *cp = _nl_get_alt_digit (number_value);
00837 
00838           if (cp != NULL)
00839         {
00840           size_t digitlen = strlen (cp);
00841           if (digitlen != 0)
00842             {
00843               cpy (digitlen, cp);
00844               break;
00845             }
00846         }
00847 #else
00848 # if HAVE_STRFTIME
00849           goto underlying_strftime;
00850 # endif
00851 #endif
00852         }
00853       {
00854         unsigned int u = number_value;
00855 
00856         bufp = buf + sizeof (buf);
00857         negative_number = number_value < 0;
00858 
00859         if (negative_number)
00860           u = -u;
00861 
00862         do
00863           *--bufp = u % 10 + '0';
00864         while ((u /= 10) != 0);
00865       }
00866 
00867     do_number_sign_and_padding:
00868       if (negative_number)
00869         *--bufp = '-';
00870 
00871       if (pad != '-')
00872         {
00873           int padding = digits - (buf + sizeof (buf) - bufp);
00874 
00875           if (pad == '_')
00876         {
00877           while (0 < padding--)
00878             *--bufp = ' ';
00879         }
00880           else
00881         {
00882           bufp += negative_number;
00883           while (0 < padding--)
00884             *--bufp = '0';
00885           if (negative_number)
00886             *--bufp = '-';
00887         }
00888         }
00889 
00890       cpy (buf + sizeof (buf) - bufp, bufp);
00891       break;
00892 
00893     case 'F':
00894       if (modifier != 0)
00895         goto bad_format;
00896       subfmt = "%Y-%m-%d";
00897       goto subformat;
00898 
00899     case 'H':
00900       if (modifier == 'E')
00901         goto bad_format;
00902 
00903       DO_NUMBER (2, tp->tm_hour);
00904 
00905     case 'I':
00906       if (modifier == 'E')
00907         goto bad_format;
00908 
00909       DO_NUMBER (2, hour12);
00910 
00911     case 'k':       /* GNU extension.  */
00912       if (modifier == 'E')
00913         goto bad_format;
00914 
00915       DO_NUMBER_SPACEPAD (2, tp->tm_hour);
00916 
00917     case 'l':       /* GNU extension.  */
00918       if (modifier == 'E')
00919         goto bad_format;
00920 
00921       DO_NUMBER_SPACEPAD (2, hour12);
00922 
00923     case 'j':
00924       if (modifier == 'E')
00925         goto bad_format;
00926 
00927       DO_NUMBER (3, 1 + tp->tm_yday);
00928 
00929     case 'M':
00930       if (modifier == 'E')
00931         goto bad_format;
00932 
00933       DO_NUMBER (2, tp->tm_min);
00934 
00935     case 'm':
00936       if (modifier == 'E')
00937         goto bad_format;
00938 
00939       DO_NUMBER (2, tp->tm_mon + 1);
00940 
00941     case 'n':       /* POSIX.2 extension.  */
00942       add (1, *p = '\n');
00943       break;
00944 
00945     case 'P':
00946       to_lowcase = 1;
00947 #if !defined _NL_CURRENT && HAVE_STRFTIME
00948       format_char = 'p';
00949 #endif
00950       /* FALLTHROUGH */
00951 
00952     case 'p':
00953       if (change_case)
00954         {
00955           to_uppcase = 0;
00956           to_lowcase = 1;
00957         }
00958 #if defined _NL_CURRENT || !HAVE_STRFTIME
00959       cpy (ap_len, ampm);
00960       break;
00961 #else
00962       goto underlying_strftime;
00963 #endif
00964 
00965     case 'R':       /* GNU extension.  */
00966       subfmt = "%H:%M";
00967       goto subformat;
00968 
00969     case 'r':       /* POSIX.2 extension.  */
00970 #ifdef _NL_CURRENT
00971       if (*(subfmt = _NL_CURRENT (LC_TIME, T_FMT_AMPM)) == '\0')
00972 #endif
00973         subfmt = "%I:%M:%S %p";
00974       goto subformat;
00975 
00976     case 'S':
00977       if (modifier == 'E')
00978         goto bad_format;
00979 
00980       DO_NUMBER (2, tp->tm_sec);
00981 
00982     case 's':       /* GNU extension.  */
00983       {
00984         struct tm ltm;
00985         time_t t;
00986 
00987         ltm = *tp;
00988         t = mktime (&ltm);
00989 
00990         /* Generate string value for T using time_t arithmetic;
00991            this works even if sizeof (long) < sizeof (time_t).  */
00992 
00993         bufp = buf + sizeof (buf);
00994         negative_number = t < 0;
00995 
00996         do
00997           {
00998         int d = t % 10;
00999         t /= 10;
01000 
01001         if (negative_number)
01002           {
01003             d = -d;
01004 
01005             /* Adjust if division truncates to minus infinity.  */
01006             if (0 < -1 % 10 && d < 0)
01007               {
01008             t++;
01009             d += 10;
01010               }
01011           }
01012 
01013         *--bufp = d + '0';
01014           }
01015         while (t != 0);
01016 
01017         digits = 1;
01018         goto do_number_sign_and_padding;
01019       }
01020 
01021     case 'X':
01022       if (modifier == 'O')
01023         goto bad_format;
01024 #ifdef _NL_CURRENT
01025       if (! (modifier == 'E'
01026          && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0'))
01027         subfmt = _NL_CURRENT (LC_TIME, T_FMT);
01028       goto subformat;
01029 #else
01030 # if HAVE_STRFTIME
01031       goto underlying_strftime;
01032 # else
01033       /* Fall through.  */
01034 # endif
01035 #endif
01036     case 'T':       /* POSIX.2 extension.  */
01037       subfmt = "%H:%M:%S";
01038       goto subformat;
01039 
01040     case 't':       /* POSIX.2 extension.  */
01041       add (1, *p = '\t');
01042       break;
01043 
01044     case 'u':       /* POSIX.2 extension.  */
01045       DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
01046 
01047     case 'U':
01048       if (modifier == 'E')
01049         goto bad_format;
01050 
01051       DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
01052 
01053     case 'V':
01054     case 'g':       /* GNU extension.  */
01055     case 'G':       /* GNU extension.  */
01056       if (modifier == 'E')
01057         goto bad_format;
01058       {
01059         int year = tp->tm_year + TM_YEAR_BASE;
01060         int days = iso_week_days (tp->tm_yday, tp->tm_wday);
01061 
01062         if (days < 0)
01063           {
01064         /* This ISO week belongs to the previous year.  */
01065         year--;
01066         days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
01067                       tp->tm_wday);
01068           }
01069         else
01070           {
01071         int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
01072                        tp->tm_wday);
01073         if (0 <= d)
01074           {
01075             /* This ISO week belongs to the next year.  */
01076             year++;
01077             days = d;
01078           }
01079           }
01080 
01081         switch (*f)
01082           {
01083           case 'g':
01084         DO_NUMBER (2, (year % 100 + 100) % 100);
01085 
01086           case 'G':
01087         DO_NUMBER (1, year);
01088 
01089           default:
01090         DO_NUMBER (2, days / 7 + 1);
01091           }
01092       }
01093 
01094     case 'W':
01095       if (modifier == 'E')
01096         goto bad_format;
01097 
01098       DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
01099 
01100     case 'w':
01101       if (modifier == 'E')
01102         goto bad_format;
01103 
01104       DO_NUMBER (1, tp->tm_wday);
01105 
01106     case 'Y':
01107       if (modifier == 'E')
01108         {
01109 #if HAVE_STRUCT_ERA_ENTRY
01110           struct era_entry *era = _nl_get_era_entry (tp);
01111           if (era)
01112         {
01113           subfmt = strchr (era->name_fmt, '\0') + 1;
01114           goto subformat;
01115         }
01116 #else
01117 # if HAVE_STRFTIME
01118           goto underlying_strftime;
01119 # endif
01120 #endif
01121         }
01122       if (modifier == 'O')
01123         goto bad_format;
01124       else
01125         DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
01126 
01127     case 'y':
01128       if (modifier == 'E')
01129         {
01130 #if HAVE_STRUCT_ERA_ENTRY
01131           struct era_entry *era = _nl_get_era_entry (tp);
01132           if (era)
01133         {
01134           int delta = tp->tm_year - era->start_date[0];
01135           DO_NUMBER (1, (era->offset
01136                  + (era->direction == '-' ? -delta : delta)));
01137         }
01138 #else
01139 # if HAVE_STRFTIME
01140           goto underlying_strftime;
01141 # endif
01142 #endif
01143         }
01144       DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
01145 
01146     case 'Z':
01147       if (change_case)
01148         {
01149           to_uppcase = 0;
01150           to_lowcase = 1;
01151         }
01152 
01153 #if HAVE_TZNAME
01154       /* The tzset() call might have changed the value.  */
01155       if (!(zone && *zone) && tp->tm_isdst >= 0)
01156         zone = tzname[tp->tm_isdst];
01157 #endif
01158       if (! zone)
01159         zone = "";      /* POSIX.2 requires the empty string here.  */
01160 
01161       cpy (strlen (zone), zone);
01162       break;
01163 
01164     case 'z':       /* GNU extension.  */
01165       if (tp->tm_isdst < 0)
01166         break;
01167 
01168       {
01169         int diff;
01170 #if HAVE_TM_GMTOFF
01171         diff = tp->tm_gmtoff;
01172 #else
01173         if (ut)
01174           diff = 0;
01175         else
01176           {
01177         struct tm gtm;
01178         struct tm ltm;
01179         time_t lt;
01180 
01181         ltm = *tp;
01182         lt = mktime (&ltm);
01183 
01184         if (lt == (time_t) -1)
01185           {
01186             /* mktime returns -1 for errors, but -1 is also a
01187                valid time_t value.  Check whether an error really
01188                occurred.  */
01189             struct tm tm;
01190 
01191             if (! my_strftime_localtime_r (&lt, &tm)
01192             || ((ltm.tm_sec ^ tm.tm_sec)
01193                 | (ltm.tm_min ^ tm.tm_min)
01194                 | (ltm.tm_hour ^ tm.tm_hour)
01195                 | (ltm.tm_mday ^ tm.tm_mday)
01196                 | (ltm.tm_mon ^ tm.tm_mon)
01197                 | (ltm.tm_year ^ tm.tm_year)))
01198               break;
01199           }
01200 
01201         if (! my_strftime_gmtime_r (&lt, &gtm))
01202           break;
01203 
01204         diff = tm_diff (&ltm, &gtm);
01205           }
01206 #endif
01207 
01208         if (diff < 0)
01209           {
01210         add (1, *p = '-');
01211         diff = -diff;
01212           }
01213         else
01214           add (1, *p = '+');
01215 
01216         diff /= 60;
01217         DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
01218       }
01219 
01220     case '\0':      /* GNU extension: % at end of format.  */
01221         --f;
01222         /* Fall through.  */
01223     default:
01224       /* Unknown format; output the format, including the '%',
01225          since this is most likely the right thing to do if a
01226          multibyte string has been misparsed.  */
01227     bad_format:
01228       {
01229         int flen;
01230         for (flen = 1; f[1 - flen] != '%'; flen++)
01231           continue;
01232         cpy (flen, &f[1 - flen]);
01233       }
01234       break;
01235     }
01236     }
01237 
01238   if (p && maxsize != 0)
01239     *p = '\0';
01240   return i;
01241 }

Here is the call graph for this function:


Variable Documentation

char const month_name[][10] [static]
Initial value:
  {
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
  }

Definition at line 360 of file gnu_strftime.c.

const char spaces[16] [static]
Initial value:
 
  { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' }

Definition at line 190 of file gnu_strftime.c.

Referenced by show_queued_files().

char const weekday_name[][10] [static]
Initial value:
  {
    "Sunday", "Monday", "Tuesday", "Wednesday",
    "Thursday", "Friday", "Saturday"
  }

Definition at line 355 of file gnu_strftime.c.

const char zeroes[16] [static]
Initial value:
 
  { '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' }

Definition at line 192 of file gnu_strftime.c.


Generated on 7 Sep 2016 for Eggdrop by  doxygen 1.6.1