~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to misc-utils/cal.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2011-05-11 08:38:31 UTC
  • mfrom: (1.3.10 upstream)
  • mto: (1.6.3 upstream) (4.5.5 sid)
  • mto: This revision was merged to the branch mainline in revision 82.
  • Revision ID: james.westby@ubuntu.com-20110511083831-tty7wnezw55fmrn4
ImportĀ upstreamĀ versionĀ 2.19.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
64
64
#include <time.h>
65
65
#include <unistd.h>
66
66
#include <err.h>
 
67
#include <errno.h>
67
68
 
68
69
#include "c.h"
69
70
#include "nls.h"
 
71
#include "mbsalign.h"
70
72
 
71
73
#if defined(HAVE_LIBNCURSES) || defined(HAVE_LIBNCURSESW)
72
74
 
139
141
int             Slen;           /* strlen of Senter+Sexit */
140
142
char            *Hrow;          /* pointer to highlighted row in month */
141
143
 
142
 
#ifdef HAVE_LANGINFO_H
143
 
# include <langinfo.h>
144
 
#endif
145
 
 
146
144
#include "widechar.h"
147
145
 
148
146
/* allow compile-time define to over-ride default */
243
241
};
244
242
 
245
243
char * ascii_day(char *, int);
246
 
int center_str(const char* src, char* dest, size_t dest_size, int width);
247
 
void center(const char *, int, int);
 
244
int center_str(const char* src, char* dest, size_t dest_size, size_t width);
 
245
void center(const char *, size_t, int);
248
246
void day_array(int, int, int, int *);
249
247
int day_in_week(int, int, int);
250
248
int day_in_year(int, int, int);
256
254
void trim_trailing_spaces(char *);
257
255
void usage(void);
258
256
void headers_init(void);
259
 
extern char *__progname;
260
257
 
261
258
int
262
259
main(int argc, char **argv) {
263
260
        struct tm *local_time;
264
261
        time_t now;
265
262
        int ch, day, month, year, yflag;
266
 
        char *progname, *p;
267
263
        int num_months = NUM_MONTHS;
268
264
 
269
 
        progname = argv[0];
270
 
        if ((p = strrchr(progname, '/')) != NULL)
271
 
                progname = p+1;
272
 
        __progname = progname;
273
 
 
274
265
        setlocale(LC_ALL, "");
275
266
        bindtextdomain(PACKAGE, LOCALEDIR);
276
267
        textdomain(PACKAGE);
312
303
         POSIX:  19971201 + 7 -1 = 0
313
304
         */
314
305
        {
315
 
                int wfd = (int)(intptr_t) nl_langinfo(_NL_TIME_WEEK_1STDAY);
 
306
                int wfd;
 
307
                union { unsigned int word; char *string; } val;
 
308
                val.string = nl_langinfo(_NL_TIME_WEEK_1STDAY);
 
309
 
 
310
                wfd = val.word;
316
311
                wfd = day_in_week(wfd % 100, (wfd / 100) % 100, wfd / (100 * 100));
317
312
                weekstart = (wfd + *nl_langinfo(_NL_TIME_FIRST_WEEKDAY) - 1) % 7;
318
313
        }
340
335
                        yflag = 1;
341
336
                        break;
342
337
                case 'V':
343
 
                        printf(_("%s from %s\n"),
344
 
                               progname, PACKAGE_STRING);
345
 
                        return 0;
 
338
                        printf(_("%s from %s\n"), program_invocation_short_name,
 
339
                               PACKAGE_STRING);
 
340
                        return EXIT_SUCCESS;
346
341
                case '?':
347
342
                default:
348
343
                        usage();
398
393
                monthly(day, month, year);
399
394
        else if (num_months == 3)
400
395
                monthly3(day, month, year);
401
 
        exit(0);
 
396
 
 
397
        return EXIT_SUCCESS;
402
398
}
403
399
 
404
400
void headers_init(void)
409
405
  strcpy(day_headings,"");
410
406
  strcpy(j_day_headings,"");
411
407
 
412
 
#ifdef HAVE_LANGINFO_H
413
 
# define weekday(wd)    nl_langinfo(ABDAY_1+wd)
414
 
#else
415
 
# define weekday(wd)    _time_info->abbrev_wkday[wd]
416
 
#endif
417
 
 
418
408
  for(i = 0 ; i < 7 ; i++ ) {
419
409
     ssize_t space_left;
420
410
     wd = (i + weekstart) % 7;
424
414
     space_left = sizeof(day_headings) - (cur_dh - day_headings);
425
415
     if(space_left <= 2)
426
416
        break;
427
 
     cur_dh += center_str(weekday(wd), cur_dh, space_left, 2);
 
417
     cur_dh += center_str(nl_langinfo(ABDAY_1+wd), cur_dh, space_left, 2);
428
418
 
429
419
     if (i)
430
420
        strcat(cur_j_dh++, " ");
431
421
     space_left = sizeof(j_day_headings) - (cur_j_dh - j_day_headings);
432
422
     if(space_left <= 3)
433
423
        break;
434
 
     cur_j_dh += center_str(weekday(wd), cur_j_dh, space_left, 3);
 
424
     cur_j_dh += center_str(nl_langinfo(ABDAY_1+wd), cur_j_dh, space_left, 3);
435
425
  }
436
426
 
437
 
#undef weekday
438
 
 
439
 
  for (i = 0; i < 12; i++) {
440
 
#ifdef HAVE_LANGINFO_H
 
427
  for (i = 0; i < 12; i++)
441
428
     full_month[i] = nl_langinfo(MON_1+i);
442
 
#else
443
 
     full_month[i] = _time_info->full_month[i];
444
 
#endif
445
 
  }
446
429
}
447
430
 
448
431
void
749
732
        *p = '\0';
750
733
}
751
734
 
752
 
#ifdef HAVE_WIDECHAR
753
 
/* replace non printable chars.
754
 
 * return 1 if replacement made, 0 otherwise */
755
 
int wc_ensure_printable(wchar_t* wchars)
756
 
{
757
 
        int replaced=0;
758
 
        wchar_t* wc = wchars;
759
 
        while (*wc) {
760
 
                if (!iswprint((wint_t) *wc)) {
761
 
                        *wc=L'\uFFFD';
762
 
                        replaced=1;
763
 
                }
764
 
                wc++;
765
 
        }
766
 
        return replaced;
767
 
}
768
 
 
769
 
/* truncate wchar string to width cells.
770
 
 * returns number of cells used. */
771
 
size_t wc_truncate(wchar_t* wchars, size_t width, size_t minchars)
772
 
{
773
 
        int wc=0;
774
 
        int cells=0;
775
 
        while (*(wchars+wc)) {
776
 
                cells = wcswidth(wchars, wc+1);
777
 
                if (cells > width) {
778
 
                        if (wc >= minchars) {
779
 
                                break;
780
 
                        }
781
 
                }
782
 
                wc++;
783
 
        }
784
 
        wchars[wc]=L'\0';
785
 
        return cells;
786
 
}
787
 
#endif
788
 
 
789
735
/*
790
736
 * Center string, handling multibyte characters appropriately.
791
737
 * In addition if the string is too large for the width it's truncated.
792
738
 * The number of trailing spaces may be 1 less than the number of leading spaces.
793
739
 */
794
740
int
795
 
center_str(const char* src, char* dest, size_t dest_size, int width)
 
741
center_str(const char* src, char* dest, size_t dest_size, size_t width)
796
742
{
797
 
#ifdef HAVE_WIDECHAR
798
 
        wchar_t str_wc[FMT_ST_CHARS];
799
 
#endif
800
 
        char str[FMT_ST_CHARS];
801
 
        const char* str_to_print=src;
802
 
        int used, spaces, wc_conversion=0, wc_enabled=0;
803
 
 
804
 
#ifdef HAVE_WIDECHAR
805
 
        if (mbstowcs(str_wc, src, ARRAY_SIZE(str_wc)) > 0) {
806
 
                str_wc[ARRAY_SIZE(str_wc)-1]=L'\0';
807
 
                wc_enabled=1;
808
 
                wc_conversion = wc_ensure_printable(str_wc);
809
 
                used = wcswidth(str_wc, ARRAY_SIZE(str_wc));
810
 
        }
811
 
        else
812
 
#endif
813
 
                used = strlen(src);
814
 
 
815
 
        if (wc_conversion || used > width) {
816
 
                str_to_print=str;
817
 
                if (wc_enabled) {
818
 
#ifdef HAVE_WIDECHAR
819
 
                        used = wc_truncate(str_wc, width, 1);
820
 
                        wcstombs(str, str_wc, ARRAY_SIZE(str));
821
 
#endif
822
 
                } else {
823
 
                        memcpy(str, src, width);
824
 
                        str[width]='\0';
825
 
                }
826
 
        }
827
 
 
828
 
        spaces = width - used;
829
 
        spaces = ( spaces < 0 ? 0 : spaces );
830
 
 
831
 
        return snprintf(dest, dest_size, "%*s%s%*s",
832
 
                spaces / 2 + spaces % 2, "",
833
 
                str_to_print,
834
 
                spaces / 2, "" );
 
743
        return mbsalign(src, dest, dest_size, &width,
 
744
                        MBS_ALIGN_CENTER, MBA_UNIBYTE_FALLBACK);
835
745
}
836
746
 
837
747
void
838
748
center(str, len, separate)
839
749
        const char *str;
840
 
        int len;
 
750
        size_t len;
841
751
        int separate;
842
752
{
843
753
        char lineout[FMT_ST_CHARS];
851
761
usage()
852
762
{
853
763
 
854
 
        fprintf(stderr, _("usage: cal [-13smjyV] [[[day] month] year]\n"));
855
 
        exit(1);
 
764
        fprintf(stderr, _("usage: %s [-13smjyV] [[[day] month] year]\n"),
 
765
                        program_invocation_short_name);
 
766
        exit(EXIT_FAILURE);
856
767
}