⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 partime.c

📁 制作2.6内核的CLFS时 patch包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Parse a string, yielding a struct partime that describes it.  *//* Copyright (C) 1993, 1994, 1995, 1997, 2002 Paul Eggert   Distributed under license by the Free Software Foundation, Inc.   This file is part of RCS.   RCS 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 2, or (at your option)   any later version.   RCS 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 RCS; see the file COPYING.   If not, write to the Free Software Foundation,   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   Report problems and direct all questions to:	rcs-bugs@cs.purdue.edu */#if has_conf_h# include <conf.h>#else# if HAVE_CONFIG_H#  include <config.h># else#  ifndef __STDC__#   define const#  endif# endif# if HAVE_LIMITS_H#  include <limits.h># endif# ifndef LONG_MIN# define LONG_MIN (-1-2147483647L)# endif# if HAVE_STDDEF_H#  include <stddef.h># endif# if STDC_HEADERS#  include <stdlib.h># endif# include <time.h># ifdef __STDC__#  define P(x) x# else#  define P(x) ()# endif#endif#ifndef offsetof#define offsetof(aggregate, member) ((size_t) &((aggregate *) 0)->member)#endif#include <ctype.h>#if STDC_HEADERS# define CTYPE_DOMAIN(c) 1#else# define CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177)#endif#define ISALNUM(c)	(CTYPE_DOMAIN (c) && isalnum (c))#define ISALPHA(c)	(CTYPE_DOMAIN (c) && isalpha (c))#define ISSPACE(c)	(CTYPE_DOMAIN (c) && isspace (c))#define ISUPPER(c)	(CTYPE_DOMAIN (c) && isupper (c))#define ISDIGIT(c)	((unsigned) (c) - '0' <= 9)#include <partime.h>char const partime_id[] =  "$Id: partime.c,v 1.2 2002/02/18 07:42:58 eggert Exp $";/* Lookup tables for names of months, weekdays, time zones.  */#define NAME_LENGTH_MAXIMUM 4struct name_val  {    char name[NAME_LENGTH_MAXIMUM];    int val;  };static char const *parse_decimal P ((char const *, int, int, int, int, int *, int *));static char const *parse_fixed P ((char const *, int, int *));static char const *parse_pattern_letter P ((char const *, int, struct partime *));static char const *parse_prefix P ((char const *, char const **, struct partime *));static char const *parse_ranged P ((char const *, int, int, int, int *));static char const *parse_varying P ((char const *, int *));static int lookup P ((char const *, struct name_val const[]));static int merge_partime P ((struct partime *, struct partime const *));static void undefine P ((struct partime *));static struct name_val const month_names[] ={  {"jan", 0},  {"feb", 1},  {"mar", 2},  {"apr", 3},  {"may", 4},  {"jun", 5},  {"jul", 6},  {"aug", 7},  {"sep", 8},  {"oct", 9},  {"nov", 10},  {"dec", 11},  {"", TM_UNDEFINED}};static struct name_val const weekday_names[] ={  {"sun", 0},  {"mon", 1},  {"tue", 2},  {"wed", 3},  {"thu", 4},  {"fri", 5},  {"sat", 6},  {"", TM_UNDEFINED}};#define RELATIVE_CONS(member, multiplier)	\	(offsetof (struct tm, member) + (multiplier) * sizeof (struct tm))#define RELATIVE_OFFSET(c)	((c) % sizeof (struct tm))#define RELATIVE_MULTIPLIER(c)	((c) / sizeof (struct tm))static struct name_val const relative_units[] ={  {"year", RELATIVE_CONS (tm_year,  1) },  {"mont", RELATIVE_CONS (tm_mon ,  1) },  {"fort", RELATIVE_CONS (tm_mday, 14) },  {"week", RELATIVE_CONS (tm_mday,  7) },  {"day" , RELATIVE_CONS (tm_mday,  1) },  {"hour", RELATIVE_CONS (tm_hour,  1) },  {"min" , RELATIVE_CONS (tm_min ,  1) },  {"sec" , RELATIVE_CONS (tm_sec ,  1) },  {"", TM_UNDEFINED}};static struct name_val const ago[] ={  {"ago", 0},  {"", TM_UNDEFINED}};static struct name_val const dst_names[] ={  {"dst", 1},  {"", 0}};#define hr60nonnegative(t)	((t)/100 * 60  +  (t)%100)#define hr60(t)	((t) < 0 ? - hr60nonnegative (-(t)) : hr60nonnegative (t))#define zs(t, s)	{s, hr60 (t)}#define zd(t, s, d)	zs (t, s),  zs ((t) + 100, d)static struct name_val const zone_names[] ={  zs (-1000, "hst"),		/* Hawaii */  zd (-1000, "hast", "hadt"),	/* Hawaii-Aleutian */  zd (- 900, "akst", "akdt"),	/* Alaska */  zd (- 800, "pst" , "pdt" ),	/* Pacific */  zd (- 700, "mst" , "mdt" ),	/* Mountain */  zd (- 600, "cst" , "cdt" ),	/* Central */  zd (- 500, "est" , "edt" ),	/* Eastern */  zd (- 400, "ast" , "adt" ),	/* Atlantic */  zd (- 330, "nst" , "ndt" ),	/* Newfoundland */  zs (  000, "utc" ),		/* Coordinated Universal */  zs (  000, "uct" ),		/* " */  zs (  000, "cut" ),		/* " */  zs (  000, "ut"),		/* Universal */  zs (  000, "z"),		/* Zulu (required by ISO 8601) */  zd (  000, "gmt" , "bst" ),	/* Greenwich Mean, British Summer */  zd (  000, "wet" , "west"),	/* Western European */  zd (  100, "cet" , "cest"),	/* Central European */  zd (  100, "met" , "mest"),	/* Middle European (bug in old tz versions) */  zd (  100, "mez" , "mesz"),	/* Mittel-Europaeische Zeit */  zd (  200, "eet" , "eest"),	/* Eastern European */  zs (  530, "ist" ),		/* India */  zd (  900, "jst" , "jdt" ),	/* Japan */  zd (  900, "kst" , "kdt" ),	/* Korea */  zd ( 1200, "nzst", "nzdt"),	/* New Zealand */  {"lt", 1},#if 0  /* The following names are duplicates or are not well attested.     It's not worth keeping a complete list, since alphabetic time zone names     are deprecated and there are lots more where these came from.  */  zs (-1100, "sst" ),		/* Samoan */  zd (- 900, "yst" , "ydt" ),	/* Yukon - name is no longer used */  zd (- 500, "ast" , "adt" ),	/* Acre */  zd (- 400, "wst" , "wdt" ),	/* Western Brazil */  zd (- 400, "cst" , "cdt" ),	/* Chile */  zd (- 200, "fst" , "fdt" ),	/* Fernando de Noronha */  zs (  000, "wat" ),		/* West African */  zs (  100, "cat" ),		/* Central African */  zs (  200, "sat" ),		/* South African */  zd (  200, "ist" , "idt" ),	/* Israel */  zs (  300, "eat" ),		/* East African */  zd (  300, "msk" , "msd" ),	/* Moscow */  zd (  330, "ist" , "idt" ),	/* Iran */  zs (  800, "hkt" ),		/* Hong Kong */  zs (  800, "sgt" ),		/* Singapore */  zd (  800, "cst" , "cdt" ),	/* China */  zd (  800, "wst" , "wst" ),	/* Western Australia */  zd (  930, "cst" , "cst" ),	/* Central Australia */  zs ( 1000, "gst" ),		/* Guam */  zd ( 1000, "est" , "est" ),	/* Eastern Australia */#endif  {"", -1}};/* Look for a prefix of S in TABLE, returning val for first matching entry.  */static intlookup (s, table)     char const *s;     struct name_val const table[];{  int j;  char buf[NAME_LENGTH_MAXIMUM];  for (j = 0; j < NAME_LENGTH_MAXIMUM; j++)    {      unsigned char c = *s;      if (! ISALPHA (c))	{	  buf[j] = '\0';	  break;	}      buf[j] = ISUPPER (c) ? tolower (c) : c;      s++;      s += *s == '.';    }  for (;; table++)    for (j = 0; ; j++)      if (j == NAME_LENGTH_MAXIMUM  ||  ! table[0].name[j])	return table[0].val;      else if (buf[j] != table[0].name[j])	break;}/* Set *T to ``undefined'' values.  */static voidundefine (t)     struct partime *t;{  t->tm.tm_sec = t->tm.tm_min = t->tm.tm_hour = t->tm.tm_mday = t->tm.tm_mon    = t->tm.tm_year = t->tm.tm_wday = t->tm.tm_yday    = t->wday_ordinal = t->ymodulus = t->yweek    = TM_UNDEFINED;  t->tmr.tm_sec = t->tmr.tm_min = t->tmr.tm_hour =    t->tmr.tm_mday = t->tmr.tm_mon = t->tmr.tm_year = 0;  t->zone = TM_UNDEFINED_ZONE;}/* Patterns to look for in a time string.   Order is important: we look for the first matching pattern   whose values do not contradict values that we already know about.   See `parse_pattern_letter' below for the meaning of the pattern codes.  */static char const time_patterns[] ={  /* Traditional patterns come first,     to prevent an ISO 8601 format from misinterpreting their prefixes.  */  /* RFC 822, extended */  'E', '_', 'N', '_', 'y', '$', 0,  'x', 0,  /* traditional */  '4', '_', 'M', '_', 'D', '_', 'h', '_', 'm', '_', 's', '$', 0,  'R', '_', 'M', '_', 'D', '_', 'h', '_', 'm', '_', 's', '$', 0,  'E', '_', 'N', 0,  'N', '_', 'E', '_', 'y', ';', 0,  'N', '_', 'E', ';', 0,  'N', 0,  't', ':', 'm', ':', 's', '_', 'A', 0,  't', ':', 'm', '_', 'A', 0,  't', '_', 'A', 0,  /* traditional get_date */  'i', '_', 'x', 0,  'Y', '/', 'n', '/', 'E', ';', 0,  'n', '/', 'E', '/', 'y', ';', 0,  'n', '/', 'E', ';', 0,  'u', 0,  /* ISO 8601:1988 formats, generalized a bit.  */  'y', '-', 'M', '-', 'D', '$', 0,  '4', 'M', 'D', '$', 0,  'Y', '-', 'M', '$', 0,  'R', 'M', 'D', '$', 0,  '-', 'R', '=', 'M', '$', 0,  '-', 'R', '$', 0,  '-', '-', 'M', '=', 'D', '$', 0,  'M', '=', 'D', 'T', 0,  '-', '-', 'M', '$', 0,  '-', '-', '-', 'D', '$', 0,  'D', 'T', 0,  'Y', '-', 'd', '$', 0,  '4', 'd', '$', 0,  'R', '=', 'd', '$', 0,  '-', 'd', '$', 0,  'd', 'T', 0,  'y', '-', 'W', '-', 'X', 0,  'y', 'W', 'X', 0,  'y', '=', 'W', 0,  '-', 'r', '-', 'W', '-', 'X', 0,  'r', '-', 'W', '-', 'X', 'T', 0,  '-', 'r', 'W', 'X', 0,  'r', 'W', 'X', 'T', 0,  '-', 'W', '=', 'X', 0,  'W', '=', 'X', 'T', 0,  '-', 'W', 0,  '-', 'w', '-', 'X', 0,  'w', '-', 'X', 'T', 0,  '-', '-', '-', 'X', '$', 0,  'X', 'T', 0,  '4', '$', 0,  'T', 0,  'h', ':', 'm', ':', 's', '$', 0,  'h', 'm', 's', '$', 0,  'h', ':', 'L', '$', 0,  'h', 'L', '$', 0,  'H', '$', 0,  '-', 'm', ':', 's', '$', 0,  '-', 'm', 's', '$', 0,  '-', 'L', '$', 0,  '-', '-', 's', '$', 0,  'Y', 0,  'Z', 0,  0};/* Parse an initial prefix of STR according to *PATTERNS, setting *T.   Return the first character after the prefix, or 0 if it couldn't be parsed.   *PATTERNS is a character array containing one pattern string after another;   it is terminated by an empty string.   If success, set *PATTERNS to the next pattern to try.   Set *PATTERNS to 0 if we know there are no more patterns to try;   if *PATTERNS is initially 0, give up immediately.  */static char const *parse_prefix (str, patterns, t)     char const *str;     char const **patterns;     struct partime *t;{  char const *pat = *patterns;  unsigned char c;  if (! pat)    return 0;  /* Remove initial noise.  */  while (! ISALNUM (c = *str) && c != '-' && c != '+')    {      if (! c)	{	  undefine (t);	  *patterns = 0;	  return str;	}      str++;    }  /* Try a pattern until one succeeds.  */  while (*pat)    {      char const *s = str;      undefine (t);      do	{	  if (! (c = *pat++))	    {	      *patterns = pat;	      return s;	    }	}      while ((s = parse_pattern_letter (s, c, t)) != 0);      while (*pat++)	continue;    }  return 0;}/* Parse an initial prefix of S of length DIGITS; it must be a number.   Store the parsed number into *RES.   Return the first character after the prefix, or 0 if it wasn't parsed.  */static char const *parse_fixed (s, digits, res)     char const *s;     int digits, *res;{  int n = 0;  char const *lim = s + digits;  while (s < lim)    {      unsigned d = *s++ - '0';      if (9 < d)	return 0;      n = 10 * n + d;    }  *res = n;  return s;}/* Parse a possibly empty initial prefix of S.   Store the parsed number into *RES.   Return the first character after the prefix.  */static char const *parse_varying (s, res)     char const *s;     int *res;{  int n = 0;  for (;;)    {      unsigned d = *s - '0';      if (9 < d)	break;      s++;      n = 10 * n + d;    }  *res = n;  return s;}/* Parse an initial prefix of S of length DIGITS;   it must be a number in the range LO through HI.   Store the parsed number into *RES.   Return the first character after the prefix, or 0 if it wasn't parsed.  */static char const *parse_ranged (s, digits, lo, hi, res)     char const *s;     int digits, lo, hi, *res;{  s = parse_fixed (s, digits, res);  return s && lo <= *res && *res <= hi ? s : 0;}/* Parse an initial prefix of S of length DIGITS;   it must be a number in the range LO through HI   and it may be followed by a fraction to be computed using RESOLUTION.   Store the parsed number into *RES; store the fraction times RESOLUTION,   rounded to the nearest integer, into *FRES.   Return the first character after the prefix, or 0 if it wasn't parsed.  */static char const *parse_decimal (s, digits, lo, hi, resolution, res, fres)     char const *s;     int digits, lo, hi, resolution, *res, *fres;{  s = parse_fixed (s, digits, res);  if (s && lo <= *res && *res <= hi)    {      int f = 0;      if ((s[0] == ',' || s[0] == '.') && ISDIGIT (s[1]))	{	  char const *s1 = ++s;	  int num10 = 0, denom10 = 10, product;	  while (ISDIGIT (*++s))	    {	      int d = denom10 * 10;	      if (d / 10  !=  denom10)		return 0; /* overflow */	      denom10 = d;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -