Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/coreutils/cal.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 532 by niro, Sat Sep 1 22:45:15 2007 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 16  Line 16 
16   *   *
17   * Major size reduction... over 50% (>1.5k) on i386.   * Major size reduction... over 50% (>1.5k) on i386.
18   */   */
19    #include "libbb.h"
20    #include "unicode.h"
21    
22  #include "busybox.h"  /* We often use "unsigned" intead of "int", it's easier to div on most CPUs */
23    
24  #define THURSDAY 4 /* for reformation */  #define THURSDAY 4 /* for reformation */
25  #define SATURDAY 6 /* 1 Jan 1 was a Saturday */  #define SATURDAY 6 /* 1 Jan 1 was a Saturday */
# Line 28  Line 30 
30  #define MAXDAYS 42 /* max slots in a month array */  #define MAXDAYS 42 /* max slots in a month array */
31  #define SPACE -1 /* used in day array */  #define SPACE -1 /* used in day array */
32    
33  static const char days_in_month[] = {  static const unsigned char days_in_month[] ALIGN1 = {
34   0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31   0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
35  };  };
36    
37  static const char sep1752[] = {  static const unsigned char sep1752[] ALIGN1 = {
38   1, 2, 14, 15, 16,   1, 2, 14, 15, 16,
39   17, 18, 19, 20, 21, 22, 23,   17, 18, 19, 20, 21, 22, 23,
40   24, 25, 26, 27, 28, 29, 30   24, 25, 26, 27, 28, 29, 30
41  };  };
42    
43  static int julian;  /* Set to 0 or 1 in main */
44    #define julian ((unsigned)option_mask32)
45    
46  /* leap year -- account for Gregorian reformation in 1752 */  /* leap year -- account for Gregorian reformation in 1752 */
47  #define leap_year(yr) \  static int leap_year(unsigned yr)
  ((yr) <= 1752 ? !((yr) % 4) : \  
  (!((yr) % 4) && ((yr) % 100)) || !((yr) % 400))  
   
 static int is_leap_year(int year)  
48  {  {
49   return leap_year(year);   if (yr <= 1752)
50     return !(yr % 4);
51     return (!(yr % 4) && (yr % 100)) || !(yr % 400);
52  }  }
 #undef leap_year  
 #define leap_year(yr) is_leap_year(yr)  
53    
54  /* number of centuries since 1700, not inclusive */  /* number of centuries since 1700, not inclusive */
55  #define centuries_since_1700(yr) \  #define centuries_since_1700(yr) \
# Line 64  static int is_leap_year(int year) Line 63  static int is_leap_year(int year)
63  #define leap_years_since_year_1(yr) \  #define leap_years_since_year_1(yr) \
64   ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr))   ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr))
65    
66  static void center (char *, int, int);  static void center(char *, unsigned, unsigned);
67  static void day_array (int, int, int *);  static void day_array(unsigned, unsigned, unsigned *);
68  static void trim_trailing_spaces_and_print (char *);  static void trim_trailing_spaces_and_print(char *);
69    
70  static void blank_string(char *buf, size_t buflen);  static void blank_string(char *buf, size_t buflen);
71  static char *build_row(char *p, int *dp);  static char *build_row(char *p, unsigned *dp);
72    
73  #define DAY_LEN 3 /* 3 spaces per day */  #define DAY_LEN 3 /* 3 spaces per day */
74  #define J_DAY_LEN (DAY_LEN + 1)  #define J_DAY_LEN (DAY_LEN + 1)
# Line 77  static char *build_row(char *p, int *dp) Line 76  static char *build_row(char *p, int *dp)
76  #define J_WEEK_LEN (WEEK_LEN + 7)  #define J_WEEK_LEN (WEEK_LEN + 7)
77  #define HEAD_SEP 2 /* spaces between day headings */  #define HEAD_SEP 2 /* spaces between day headings */
78    
79  int cal_main(int argc, char **argv)  int cal_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
80    int cal_main(int argc UNUSED_PARAM, char **argv)
81  {  {
  struct tm *local_time;  
82   struct tm zero_tm;   struct tm zero_tm;
83   time_t now;   time_t now;
84   int month, year, flags, i;   unsigned month, year, flags, i;
85   char *month_names[12];   char *month_names[12];
86   char day_headings[28]; /* 28 for julian, 21 for nonjulian */   /* normal heading: */
87     /* "Su Mo Tu We Th Fr Sa" */
88     /* -j heading: */
89     /* " Su  Mo  Tu  We  Th  Fr  Sa" */
90     char day_headings[ENABLE_FEATURE_ASSUME_UNICODE ? 28 * 6 : 28];
91     IF_FEATURE_ASSUME_UNICODE(char *hp = day_headings;)
92   char buf[40];   char buf[40];
93    
94   flags = getopt32(argc, argv, "jy");   init_unicode();
   
  julian = flags & 1;  
   
  argv += optind;  
95    
96     flags = getopt32(argv, "jy");
97     /* This sets julian = flags & 1: */
98     option_mask32 &= 1;
99   month = 0;   month = 0;
100     argv += optind;
101    
102   if ((argc -= optind) > 2) {   if (!argv[0]) {
103   bb_show_usage();   struct tm *ptm;
  }  
104    
  if (!argc) {  
105   time(&now);   time(&now);
106   local_time = localtime(&now);   ptm = localtime(&now);
107   year = local_time->tm_year + 1900;   year = ptm->tm_year + 1900;
108   if (!(flags & 2)) {   if (!(flags & 2)) { /* no -y */
109   month = local_time->tm_mon + 1;   month = ptm->tm_mon + 1;
110   }   }
111   } else {   } else {
112   if (argc == 2) {   if (argv[1]) {
113   month = xatoul_range(*argv++, 1, 12);   if (argv[2]) {
114     bb_show_usage();
115     }
116     month = xatou_range(*argv++, 1, 12);
117   }   }
118   year = xatoul_range(*argv, 1, 9999);   year = xatou_range(*argv, 1, 9999);
119   }   }
120    
121   blank_string(day_headings, sizeof(day_headings) - 7 +  7*julian);   blank_string(day_headings, sizeof(day_headings) - 7 + 7*julian);
122    
123   i = 0;   i = 0;
124   do {   do {
125   zero_tm.tm_mon = i;   zero_tm.tm_mon = i;
126     /* full month name according to locale */
127   strftime(buf, sizeof(buf), "%B", &zero_tm);   strftime(buf, sizeof(buf), "%B", &zero_tm);
128   month_names[i] = xstrdup(buf);   month_names[i] = xstrdup(buf);
129    
130   if (i < 7) {   if (i < 7) {
131   zero_tm.tm_wday = i;   zero_tm.tm_wday = i;
132     /* abbreviated weekday name according to locale */
133   strftime(buf, sizeof(buf), "%a", &zero_tm);   strftime(buf, sizeof(buf), "%a", &zero_tm);
134    #if ENABLE_FEATURE_ASSUME_UNICODE
135     if (julian)
136     *hp++ = ' ';
137     {
138     char *two_wchars = unicode_cut_nchars(2, buf);
139     strcpy(hp, two_wchars);
140     free(two_wchars);
141     }
142     hp += strlen(hp);
143     *hp++ = ' ';
144    #else
145   strncpy(day_headings + i * (3+julian) + julian, buf, 2);   strncpy(day_headings + i * (3+julian) + julian, buf, 2);
146    #endif
147   }   }
148   } while (++i < 12);   } while (++i < 12);
149     IF_FEATURE_ASSUME_UNICODE(hp[-1] = '\0';)
150    
151   if (month) {   if (month) {
152   int row, len, days[MAXDAYS];   unsigned row, len, days[MAXDAYS];
153   int *dp = days;   unsigned *dp = days;
154   char lineout[30];   char lineout[30];
155    
156   day_array(month, year, dp);   day_array(month, year, dp);
# Line 144  int cal_main(int argc, char **argv) Line 164  int cal_main(int argc, char **argv)
164   trim_trailing_spaces_and_print(lineout);   trim_trailing_spaces_and_print(lineout);
165   }   }
166   } else {   } else {
167   int row, which_cal, week_len, days[12][MAXDAYS];   unsigned row, which_cal, week_len, days[12][MAXDAYS];
168   int *dp;   unsigned *dp;
169   char lineout[80];   char lineout[80];
170    
171   sprintf(lineout, "%d", year);   sprintf(lineout, "%u", year);
172   center(lineout,   center(lineout,
173     (WEEK_LEN * 3 + HEAD_SEP * 2)     (WEEK_LEN * 3 + HEAD_SEP * 2)
174     + julian * (J_WEEK_LEN * 2 + HEAD_SEP     + julian * (J_WEEK_LEN * 2 + HEAD_SEP
# Line 170  int cal_main(int argc, char **argv) Line 190  int cal_main(int argc, char **argv)
190   if (!julian) {   if (!julian) {
191   printf("%*s%s", HEAD_SEP, "", day_headings);   printf("%*s%s", HEAD_SEP, "", day_headings);
192   }   }
193   putchar('\n');   bb_putchar('\n');
194   for (row = 0; row < (6*7); row += 7) {   for (row = 0; row < (6*7); row += 7) {
195   for (which_cal = 0; which_cal < 3-julian; which_cal++) {   for (which_cal = 0; which_cal < 3-julian; which_cal++) {
196   dp = days[month + which_cal] + row;   dp = days[month + which_cal] + row;
# Line 182  int cal_main(int argc, char **argv) Line 202  int cal_main(int argc, char **argv)
202   }   }
203   }   }
204    
205   fflush_stdout_and_exit(0);   fflush_stdout_and_exit(EXIT_SUCCESS);
206  }  }
207    
208  /*  /*
# Line 192  int cal_main(int argc, char **argv) Line 212  int cal_main(int argc, char **argv)
212   * out end to end.  You would have 42 numbers or spaces.  This routine   * out end to end.  You would have 42 numbers or spaces.  This routine
213   * builds that array for any month from Jan. 1 through Dec. 9999.   * builds that array for any month from Jan. 1 through Dec. 9999.
214   */   */
215  static void day_array(int month, int year, int *days)  static void day_array(unsigned month, unsigned year, unsigned *days)
216  {  {
217   long temp;   unsigned long temp;
218   int i;   unsigned i;
219   int j_offset;   unsigned day, dw, dm;
  int day, dw, dm;  
220    
221   memset(days, SPACE, MAXDAYS * sizeof(int));   memset(days, SPACE, MAXDAYS * sizeof(int));
222    
223   if ((month == 9) && (year == 1752)) {   if ((month == 9) && (year == 1752)) {
224     /* Assumes the Gregorian reformation eliminates
225     * 3 Sep. 1752 through 13 Sep. 1752.
226     */
227     unsigned j_offset = julian * 244;
228   size_t oday = 0;   size_t oday = 0;
229    
  j_offset = julian * 244;  
230   do {   do {
231   days[oday+2] = sep1752[oday] + j_offset;   days[oday+2] = sep1752[oday] + j_offset;
232   } while (++oday < sizeof(sep1752));   } while (++oday < sizeof(sep1752));
# Line 213  static void day_array(int month, int yea Line 235  static void day_array(int month, int yea
235   }   }
236    
237   /* day_in_year   /* day_in_year
238   * return the 1 based day number within the year   * return the 1 based day number within the year
239   */   */
240   day = 1;   day = 1;
241   if ((month > 2) && leap_year(year)) {   if ((month > 2) && leap_year(year)) {
# Line 226  static void day_array(int month, int yea Line 248  static void day_array(int month, int yea
248   }   }
249    
250   /* day_in_week   /* day_in_week
251   * return the 0 based day number for any date from 1 Jan. 1 to   * return the 0 based day number for any date from 1 Jan. 1 to
252   * 31 Dec. 9999.  Assumes the Gregorian reformation eliminates   * 31 Dec. 9999.  Assumes the Gregorian reformation eliminates
253   * 3 Sep. 1752 through 13 Sep. 1752.  Returns Thursday for all   * 3 Sep. 1752 through 13 Sep. 1752.  Returns Thursday for all
254   * missing days.   * missing days.
255   */   */
256   dw = THURSDAY;   temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1) + day;
  temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1)  
  + day;  
257   if (temp < FIRST_MISSING_DAY) {   if (temp < FIRST_MISSING_DAY) {
258   dw = ((temp - 1 + SATURDAY) % 7);   dw = ((temp - 1 + SATURDAY) % 7);
259   } else if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS)) {   } else {
260   dw = (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7);   dw = (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7);
261   }   }
262    
# Line 249  static void day_array(int month, int yea Line 269  static void day_array(int month, int yea
269   ++dm;   ++dm;
270   }   }
271    
272   while (dm) {   do {
273   days[dw++] = day++;   days[dw++] = day++;
274   --dm;   } while (--dm);
  }  
275  }  }
276    
277  static void trim_trailing_spaces_and_print(char *s)  static void trim_trailing_spaces_and_print(char *s)
# Line 262  static void trim_trailing_spaces_and_pri Line 281  static void trim_trailing_spaces_and_pri
281   while (*p) {   while (*p) {
282   ++p;   ++p;
283   }   }
284   while (p > s) {   while (p != s) {
285   --p;   --p;
286   if (!(isspace)(*p)) { /* We want the function... not the inline. */   if (!isspace(*p)) {
287   p[1] = '\0';   p[1] = '\0';
288   break;   break;
289   }   }
# Line 273  static void trim_trailing_spaces_and_pri Line 292  static void trim_trailing_spaces_and_pri
292   puts(s);   puts(s);
293  }  }
294    
295  static void center(char *str, int len, int separate)  static void center(char *str, unsigned len, unsigned separate)
296  {  {
297   int n = strlen(str);   unsigned n = strlen(str);
298   len -= n;   len -= n;
299   printf("%*s%*s", (len/2) + n, str, (len/2) + (len % 2) + separate, "");   printf("%*s%*s", (len/2) + n, str, (len/2) + (len % 2) + separate, "");
300  }  }
# Line 286  static void blank_string(char *buf, size Line 305  static void blank_string(char *buf, size
305   buf[buflen-1] = '\0';   buf[buflen-1] = '\0';
306  }  }
307    
308  static char *build_row(char *p, int *dp)  static char *build_row(char *p, unsigned *dp)
309  {  {
310   int col, val, day;   unsigned col, val, day;
311    
312   memset(p, ' ', (julian + DAY_LEN) * 7);   memset(p, ' ', (julian + DAY_LEN) * 7);
313    
314   col = 0;   col = 0;
315   do {   do {
316   if ((day = *dp++) != SPACE) {   day = *dp++;
317     if (day != SPACE) {
318   if (julian) {   if (julian) {
319   ++p;   ++p;
320   if (day >= 100) {   if (day >= 100) {
# Line 303  static char *build_row(char *p, int *dp) Line 323  static char *build_row(char *p, int *dp)
323   day %= 100;   day %= 100;
324   }   }
325   }   }
326   if ((val = day / 10) > 0) {   val = day / 10;
327     if (val > 0) {
328   *p = val + '0';   *p = val + '0';
329   }   }
330   *++p = day % 10 + '0';   *++p = day % 10 + '0';
# Line 347  static char *build_row(char *p, int *dp) Line 368  static char *build_row(char *p, int *dp)
368   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
369   * SUCH DAMAGE.   * SUCH DAMAGE.
370   */   */
   
   

Legend:
Removed from v.532  
changed lines
  Added in v.984