home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / deskaccs / cal.arc / CAL.C < prev    next >
C/C++ Source or Header  |  1987-01-25  |  9KB  |  499 lines

  1. /* #define LATTICE */
  2. #ifndef LATTICE
  3. #include <sys/time.h>            /* structures for time system calls */
  4. #endif
  5. #include <stdio.h>            /* buffered i/o package */
  6. #include <ctype.h>            /* upper/lower case macros */
  7.  
  8. #ifdef LATTICE
  9. struct tm {
  10.     int    tm_sec;
  11.     int    tm_min;
  12.     int    tm_hour;
  13.     int    tm_mday;
  14.     int    tm_mon;
  15.     int    tm_year;
  16.     int    tm_wday;
  17.     int    tm_yday;
  18.     int    tm_isdst;
  19. };
  20. #endif
  21.  
  22. char    string[432];
  23.     
  24. /*
  25.  *    Day of week headers.
  26.  */
  27.  
  28. static    char    dayw[] = { " S  M Tu  W Th  F  S" };
  29.  
  30. /*
  31.  *    Month of year headers.
  32.  */
  33.  
  34. static    char    *smon[]= {
  35.     "January",    "February",    "March",    "April",
  36.     "May",        "June",        "July",        "August",
  37.     "September",    "October",    "November",    "December",
  38. };
  39.  
  40. main(argc, argv)
  41. int    argc;                    /* argument count */
  42. char    *argv[];                /* argument vector */
  43. {
  44.     extern    int        exit();        /* terminate our process */
  45.     extern    int        fprintf();    /* print formatted to file */
  46.     extern    int        printf();    /* print formatted */
  47.     extern    long        time();        /* get current system time */
  48.     extern    struct    tm    *localtime();    /* convert sys to local time */
  49.  
  50.     extern    pstr();                /* print calendar string */
  51.  
  52.     register int    m;            /* month */
  53.     register int    y;            /* year */
  54.     register int    i;
  55.     register int    j;
  56.  
  57.     long        systime;        /* system time */
  58.     struct    tm    *local;            /* local time */
  59.  
  60.     /**
  61.      *    Get the system time.
  62.     **/
  63.     
  64.     time(&systime);
  65.     
  66.     /**
  67.      *    Convert it to local time.
  68.     **/
  69.     
  70.     local = localtime(&systime);
  71.     
  72.     /**
  73.      *    Print the whole year if there was exactly one argument other
  74.      *    than the invocation name, and that argument is a number greater
  75.      *    than 13, or if there was no argument.
  76.     **/
  77.  
  78.     if (argc == 1 || (argc == 2 && (y = number(argv[1])) > 12)) {
  79.  
  80.         /**
  81.          *    Print out the current year if
  82.          *    no arguments are specified.
  83.         **/
  84.  
  85.         if (argc == 1) {
  86.         
  87.             /**
  88.              *    Extract the year and adjust it for this century.
  89.             **/
  90.  
  91.             y = local->tm_year + 1900;
  92.  
  93.         }
  94.     
  95.         /**
  96.          *    Get the year from the command line.
  97.         **/
  98.  
  99.         else {
  100.  
  101.             /**
  102.              *    Check for allowable years
  103.             **/
  104.  
  105.             if (y < 1 || y > 9999) {
  106.                 usage();
  107.             }
  108.  
  109.             /**
  110.              *    Allow abbreviations: 86 --> 1986.
  111.             **/
  112.  
  113.             if (y < 100) {
  114.                 y += 1900;
  115.             }
  116.         }
  117.  
  118.         /**
  119.          *    Print the year header.
  120.         **/
  121.  
  122.         printf("\n\n\n                %u\n\n", y);
  123.  
  124.         /**
  125.          *    Cycle through the months.
  126.         **/
  127.  
  128.         for (i = 0; i < 12; i += 3) {
  129.             for (j = 0; j < 6 * 72; j++)
  130.                 string[j] = '\0';
  131.  
  132.             printf("         %.3s", smon[i]);
  133.             printf("                    %.3s", smon[i + 1]);
  134.             printf("                    %.3s\n", smon[i + 2]);
  135.             printf("%s   %s   %s\n", dayw, dayw, dayw);
  136.  
  137.             cal(i + 1, y, string, 72);
  138.             cal(i + 2, y, string + 23, 72);
  139.             cal(i + 3, y, string + 46, 72);
  140.  
  141.             for (j = 0; j < 6 * 72; j += 72)
  142.                 pstr(string + j, 72);
  143.         }
  144.         printf("\n\n\n");
  145.     }
  146.  
  147.     else {
  148.  
  149.         /**
  150.          *    Print the current month if there was exactly one
  151.          *    argument other than the invocation name, and that
  152.          *    argument is a number less than 13.
  153.         **/
  154.  
  155.         if (argc == 2 && (y = number(argv[1])) <= 12) {
  156.         
  157.             /**
  158.              *    Extract the year and adjust it for this century.
  159.             **/
  160.  
  161.             y = local->tm_year + 1900;
  162.  
  163.             /**
  164.              *    Get the month from the command line.
  165.             **/
  166.  
  167.             m = number(argv[1]);
  168.  
  169.             /**
  170.              *    If the month has already passed, use
  171.              *    next year.
  172.             **/
  173.  
  174.             if (m < local->tm_mon+1) {
  175.                 y++;
  176.             }
  177.  
  178.         }
  179.  
  180.         /**
  181.          *    Print a specific month from the specified year if
  182.          *    there was more than one argument other than the
  183.          *    invocation name.
  184.         **/
  185.  
  186.         else {
  187.             /**
  188.              *    Get the month from the command line.
  189.             **/
  190.  
  191.             m = number(argv[1]);
  192.     
  193.             /**
  194.              *    Get the year from the command line.  Allow
  195.              *    abbreviations of form nn -> 19nn.
  196.             **/
  197.  
  198.             y = number(argv[2]);
  199.             if (y >0 && y < 100) {
  200.                 y += 1900;
  201.             }
  202.         }
  203.  
  204.         /**
  205.          *    Generate an error if the month is illegal.
  206.         **/
  207.  
  208.         if (m < 1 || m > 12) {
  209.             fprintf(stderr,
  210.                 "cal:  month must be between 1 and 12.\n");
  211.             usage();
  212.         }
  213.  
  214.         /**
  215.          *    Generate an error if the year is illegal.
  216.         **/
  217.  
  218.         if (y < 1 || y > 9999) {
  219.             fprintf(stderr,
  220.                 "cal:  year must be between 1 and 9999.\n");
  221.             usage();
  222.         }
  223.  
  224.         /**
  225.          *    Print the month and year header.
  226.         **/
  227.  
  228.         printf("   %s %u\n", smon[m - 1], y);
  229.  
  230.         /**
  231.          *    Print the day of week header.
  232.         **/
  233.  
  234.         printf("%s\n", dayw);
  235.  
  236.         /**
  237.          *    Generate the calendar for the month and year.
  238.         **/
  239.  
  240.         cal(m, y, string, 24);
  241.  
  242.         /**
  243.          *    Print out the month.
  244.         **/
  245.  
  246.         for (i = 0; i < 6 * 24; i += 24)
  247.             pstr(string + i, 24);
  248.     }
  249.  
  250.     /**
  251.      *    All done.
  252.     **/
  253.  
  254.     exit(0);
  255. }
  256.  
  257. int
  258. number(str)
  259. register char    *str;                /* string to convert */
  260. {
  261.     int        cicmp();        /* case-insensitive compare */
  262.  
  263.     register int    n;            /* number value of string */
  264.     register char    *s,*p;            /* loop pointers */
  265.  
  266.     /**
  267.      *    Convert the string to a number.
  268.     **/
  269.  
  270.     for (n = 0, s = str; *s >= '0' && *s <= '9'; s++) {
  271.         n = n * 10 + *s - '0';
  272.     }
  273.     
  274.     if (*s == '\0') {
  275.         return (n);
  276.     }
  277.  
  278.     /**
  279.      *    If it's not a number, check if it's a month.
  280.     **/
  281.  
  282.     for (n=0; n<12; n++) {
  283.         if (cicmp(str,smon[n]) == 0) {
  284.             return (n+1);
  285.         }
  286.     }
  287.  
  288.     /**
  289.      *    Otherwise, give up and return zero.
  290.     **/
  291.     
  292.     return (0);
  293. }
  294.  
  295. pstr(str, n)
  296. char    *str;
  297. int    n;
  298. {
  299.     register int    i;
  300.     register char    *s;
  301.  
  302.     s = str;
  303.     i = n;
  304.  
  305.     while (i--)
  306.         if (*s++ == '\0')
  307.             s[-1] = ' ';
  308.  
  309.     i = n + 1;
  310.  
  311.     while (i--)
  312.         if (*--s != ' ')
  313.             break;
  314.  
  315.     s[1] = '\0';
  316.     printf("%s\n", str);
  317.  
  318.     return;
  319. }
  320.  
  321. cal(m, y, p, w)
  322. int    m;                        /* month */
  323. int    y;                        /* year */
  324. char    *p;
  325. int    w;
  326. {
  327.     register int    d;
  328.     register int    i;
  329.     register char    *s;
  330.  
  331.     /*
  332.      *    Number of days per month table.
  333.      */
  334.  
  335.     static    char    mon[] = {
  336.         0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
  337.     };
  338.  
  339.     s = p;
  340.  
  341.     /**
  342.      *    Get the day of the week for January 1 of this `y`ear.
  343.     **/
  344.  
  345.     d = jan1(y);
  346.  
  347.     /**
  348.      *    Restore the days-per-month for February and September because
  349.      *    they may have been fiddled with.
  350.     **/
  351.  
  352.     mon[2] = 29;
  353.     mon[9] = 30;
  354.  
  355.     switch ((jan1(y + 1) + 7 - d) % 7) {
  356.  
  357.         /*
  358.          *    non-leap year
  359.          */
  360.     case 1:
  361.         mon[2] = 28;
  362.         break;
  363.  
  364.         /*
  365.          *    1752
  366.          */
  367.     default:
  368.         mon[9] = 19;
  369.         break;
  370.  
  371.         /*
  372.          *    leap year
  373.          */
  374.     case 2:
  375.         ;
  376.     }
  377.  
  378.     for (i = 1; i < m; i++)
  379.         d += mon[i];
  380.     d %= 7;
  381.     s += 3 * d;
  382.     for (i = 1; i <= mon[m]; i++) {
  383.         if (i == 3 && mon[m] == 19) {
  384.             i += 11;
  385.             mon[m] += 11;
  386.         }
  387.         if (i > 9)
  388.             *s = i / 10 + '0';
  389.         s++;
  390.         *s++ = i % 10 + '0';
  391.         s++;
  392.         if (++d == 7) {
  393.             d = 0;
  394.             s = p + w;
  395.             p = s;
  396.         }
  397.     }
  398. }
  399.  
  400. jan1(y)
  401. register int    y;                    /* year */
  402. {
  403.     register int    d;                /* day */
  404.  
  405.     /**
  406.      *    Compute the number of days until the first of this year using
  407.      *    the normal Gregorian calendar which has one extra day per four
  408.      *    years.
  409.     **/
  410.  
  411.     d = 4 + y + (y + 3) / 4;
  412.  
  413.     /**
  414.      *    Adjust for the Julian and Regular Gregorian calendars which
  415.      *    have three less days per each 400.
  416.     **/
  417.  
  418.     if (y > 1800) {
  419.         d -= (y - 1701) / 100;
  420.         d += (y - 1601) / 400;
  421.     }
  422.  
  423.     /**
  424.      *    Add three days if necessary to account for the great
  425.      *    calendar changeover instant.
  426.     **/
  427.  
  428.     if (y > 1752)
  429.         d += 3;
  430.     
  431.     /**
  432.      *    Get the day of the week from the day count.
  433.     **/
  434.  
  435.     return (d % 7);
  436. }
  437.  
  438. usage()
  439. {
  440.     fprintf(stderr,"Usage:\tcal [m] [y]\n");
  441.     fprintf(stderr,"\t'm' is 1 thru 12 or any reasonable month name.\n");
  442.     fprintf(stderr,"\t'y' is a year between 100 and 9999.\n");
  443.     fprintf(stderr,"\tYears 13-99 are abbreviations for 1913-1999.\n");
  444.     fprintf(stderr,"\tWith no arguments, the current year is printed.\n");
  445.     fprintf(stderr,"\tWith only a month given, the next instance of\n");
  446.     fprintf(stderr,"\t\tthat month (this year or next) is printed.\n");
  447.     fprintf(stderr,"\tYear as a single argument gives that whole year.\n");
  448.  
  449.     exit(-1);
  450. }
  451.  
  452. int cicmp(s,pat)
  453. char *s,*pat;
  454. {
  455.     char    c1,c2;
  456.     while (*s) {
  457.         c1 = *s++;
  458.         c2 = *pat++;
  459.         if (isupper(c1)) {
  460.             c1 = tolower(c1);
  461.         }
  462.         if (isupper(c2)) {
  463.             c2 = tolower(c2);
  464.         }
  465.         if (c1 != c2) {
  466.             return (1);
  467.         }
  468.     }
  469.     return (0);
  470. }
  471.  
  472. #ifdef LATTICE
  473. long time()
  474. {
  475. }
  476.  
  477. struct tm *localtime()
  478. {
  479.     extern long time_bin(),date_bin();
  480.     long date,time;
  481.     static struct tm t;
  482.  
  483.     time=time_bin();
  484.     date=date_bin();
  485.  
  486.     t.tm_year=(date >> 16) & 0x0000FFFFL;
  487.     t.tm_year -= 1900;    /* conform to unix */
  488.     t.tm_mon=(date >> 8) & 0x000000FFL;
  489.     t.tm_mon -= 1;        /* unix months start at zero */
  490.     t.tm_day=date & 0x000000FFL;
  491.     t.tm_hr=(time >> 24) & 0x000000FFL;
  492.     t.tm_min=(time >> 16) & 0x000000FFL;
  493.     t.tm_sec=(time >> 8) & 0x000000FFL;
  494.  
  495.     return (&t);
  496. }
  497. #endif
  498.  
  499.