home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / calgen / part1 / calndr.c next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  22.9 KB  |  1,055 lines

  1. /*******************************************************
  2.  *
  3.  *          Calendar Generation Program
  4.  *        Copyright 1986 David H. Brierley
  5.  *
  6.  * Permission is granted to anyone to use this software for any
  7.  * purpose on any computer system, and to redistribute it freely,
  8.  * subject to the following restrictions:
  9.  * 1. The author is not responsible for the consequences of use of
  10.  *    this software, no matter how awful, even if they arise
  11.  *    from defects in it.
  12.  * 2. The origin of this software must not be misrepresented, either
  13.  *    by explicit claim or by omission.
  14.  * 3. Altered versions must be plainly marked as such, and must not
  15.  *    be misrepresented as being the original software.
  16.  *
  17.  * David H. Brierley
  18.  * Portsmouth, RI
  19.  * {allegra,ihnp4,linus}!rayssd!dhb
  20.  *
  21.  ********************************************************/
  22.  
  23. #include <stdio.h>
  24.  
  25. #define TRUE    1
  26. #define FALSE    0
  27.  
  28. #ifndef PICDATA
  29. #define PICDATA "/staff/dhb/data/picdata"
  30. #endif
  31.  
  32. struct holiday_data
  33. {
  34.     int     h_month;
  35.     int     h_day;
  36.     char    h_name[14];
  37.     struct holiday_data *h_link;
  38. };
  39. typedef struct holiday_data HDATA;
  40.  
  41. int     month1;
  42. int     year1;
  43. int     month2;
  44. int     year2;
  45. int     this_day;
  46. int     this_year;
  47. int     this_month;
  48. int     copies;
  49. int     points[13];
  50. int     days[42];
  51. int     julian_days[42];
  52. int     first;
  53. int     rawdata;
  54. int     daycnt[] =
  55. {
  56.     31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  57. };
  58. int     pic_flag;
  59. int     std_flag;
  60. int     hday_flag;
  61.  
  62. int     easter[100] =
  63. {
  64.     3, 25, 4, 13, 4, 5, 4, 18, 4, 10, 4, 1, 4, 21, 4, 6, 3, 29, 4, 17,
  65.     4, 2, 4, 22, 4, 14, 3, 29, 4, 18, 4, 10, 3, 26, 4, 14, 4, 6, 3, 29,
  66.     4, 11, 4, 2, 4, 22, 4, 14, 3, 30, 4, 18, 4, 10, 3, 26, 4, 15, 4, 6,
  67.     4, 19, 4, 11, 4, 3, 4, 22, 4, 7, 3, 30, 4, 19, 4, 3, 3, 26, 4, 15,
  68.     3, 31, 4, 19, 4, 11, 4, 3, 4, 16, 4, 7, 3, 30, 4, 12, 4, 4, 4, 23
  69. };
  70.  
  71. char    sday_file[1024];
  72. char    hday_file[1024];
  73. char    output_file[1024];
  74. char    input_file[1024];
  75.  
  76. char  **line;
  77. char   *monames[12][7];
  78. char   *nums[10][5];
  79. char   *holidays[12][32];
  80. char   *special[4][12][32];
  81.  
  82. HDATA * hday_head = NULL;
  83.  
  84. FILE   *calout;
  85.  
  86. extern  FILE   *popen ();
  87. extern  char   *index ();
  88. extern  char   *strcpy ();
  89. extern  char   *strncpy ();
  90. extern  char   *gets ();
  91. extern  char   *calloc ();
  92. extern  char   *malloc ();
  93. extern  char   *optarg;
  94. extern  int     optind;
  95.  
  96. #define alloc_3d(base, x, y, z, size) {\
  97.     register unsigned  total; register int i, j, k; register char *area;\
  98.     total = (x * y * z) * size; area = malloc (total);\
  99.     if (area == NULL) { perror ("calndr"); exit (1); }\
  100.     for (i = 0; i < x; i++) for (j = 0; j < y; j++) for (k = 0; k < z; k++) { base[i][j][k] = area; area += size; }\
  101. }
  102.  
  103. #define alloc_2d(base, x, y, size) {\
  104.     register unsigned  total; register int i, j; register char   *area;\
  105.     total = (x * y) * size; area = malloc (total);\
  106.     if (area == NULL) { perror ("calndr"); exit (1); }\
  107.     for (i = 0; i < x; i++) for (j = 0; j < y; j++) { base[i][j] = area; area += size; }\
  108. }
  109.  
  110. #define alloc_1d(base, x, size) {\
  111.     register unsigned total; register int i; register char *area;\
  112.     total = x * size; area = malloc (total);\
  113.     if (area == NULL) { perror ("calndr"); exit (1); }\
  114.     for (i = 0; i < x; i++) { base[i] = area; area += size; }\
  115. }
  116.  
  117. #define zap3(base, x, y, z) {\
  118.     register int i, j, k;\
  119.     for (i = 0; i < x; i++) for (j = 0; j < y; j++) for (k = 0; k < z; k++) *base[i][j][k] = '\0';\
  120. }
  121.  
  122. #define zap2(base, x, y) {\
  123.     register int i, j;\
  124.     for (i = 0; i < x; i++) for (j = 0; j < y; j++) *base[i][j] = '\0';\
  125. }
  126.  
  127. main (argc, argv)
  128. int     argc;
  129. char   *argv[];
  130. {
  131.     int     optch;
  132.     int     rc;
  133.  
  134.     calout = NULL;
  135.     rawdata = 0;
  136.     (void) strcpy (input_file, PICDATA);
  137.     while ((optch = getopt (argc, argv, "r:f:o:P:")) != EOF) {
  138.     switch (optch) {
  139.     case 'r':
  140.         (void) sprintf (input_file, "pic_h2m %s /tmp/picdata%d",
  141.                 optarg, getpid ());
  142.         fprintf (stderr, "Please wait while raw data file is transformed\n");
  143.         rc = system (input_file);
  144.         if (rc != 0) {
  145.         fprintf (stderr, "Unable to transform raw data file\n");
  146.         exit (1);
  147.         }
  148.         (void) sprintf (input_file, "/tmp/picdata%d", getpid ());
  149.         rawdata = 1;
  150.         break;
  151.     case 'f':
  152.         (void) strcpy (input_file, optarg);
  153.         rawdata = 0;
  154.         break;
  155.     case 'o':
  156.         calout = fopen (optarg, "w");
  157.         if (calout == NULL) {
  158.         fprintf (stderr, "Unable to open output file %s\n", optarg);
  159.         exit (1);
  160.         }
  161.         break;
  162.     case 'P':
  163.         (void) sprintf (output_file, "lpr -P%s", optarg);
  164.         calout = popen (output_file, "w");
  165.         if (calout == NULL) {
  166.         fprintf (stderr, "Unable to open pipe to printer %s\n", optarg);
  167.         exit (1);
  168.         }
  169.         break;
  170.     default:
  171.         exit (1);
  172.     }
  173.     }
  174.     if (calout == NULL) {
  175.     fprintf (stderr, "Usage: %s [-r rawdatafile] [-f datafile]\n", argv[0]);
  176.     fprintf (stderr, "       [-o outputfile] [-P printer]\n");
  177.     exit (1);
  178.     }
  179.  
  180.     alloc_2d (monames, 12, 7, 81);
  181.     alloc_2d (nums, 10, 5, 6);
  182.     alloc_2d (holidays, 12, 32, 14);
  183.     alloc_3d (special, 4, 12, 32, 17);
  184.     read_picdata ();
  185.  
  186.     while (cardscan () == TRUE) {
  187.     while (copies-- > 0) {
  188.         make_calndr ();
  189.     }
  190.     }
  191.  
  192.     if (rawdata == 1) {
  193.     (void) unlink (input_file);
  194.     }
  195.  
  196. }
  197.  
  198. make_calndr ()
  199. {
  200.     int     i;
  201.     int     j;
  202.  
  203.     this_year = year1;
  204.     this_month = month1 - 1;
  205.     daycnt[1] = 28 + leap ();
  206.     gen_hdays ();
  207.     this_day = 0;
  208.     for (i = 0; i < this_month; i++) {
  209.     this_day += daycnt[i];
  210.     }
  211.  
  212.     while (this_year < year2 || (this_year == year2 && this_month < month2)) {
  213.     this_month++;
  214.     if (this_month < 1) {
  215.         this_month = 1;
  216.     }
  217.     if (this_month > 12) {
  218.         this_month = 1;
  219.         this_year++;
  220.         this_day = 0;
  221.         daycnt[1] = 28 + leap ();
  222.         gen_hdays ();
  223.     }
  224.     if (pic_flag) {
  225.         print_picture (this_month);
  226.     }
  227.     caltop ();
  228.     first = zeller (this_month, this_year);
  229.     for (i = 0; i < 42; i++) {
  230.         days[i] = 0;
  231.         julian_days[i] = 0;
  232.     }
  233.     for (i = 0; i < daycnt[this_month - 1]; i++) {
  234.         days[i + first] = i + 1;
  235.         julian_days[i + first] = (i + 1) + this_day;
  236.     }
  237.     this_day += daycnt[this_month - 1];
  238.     dash_line (1);
  239.  
  240.     for (i = 0; i < 6; i++) {
  241.         vbar_line ();
  242.         date_line (i);
  243.         for (j = 0; j < 4; j++) {
  244.         special_line (j, this_month, i);
  245.         }
  246.         jdate_line (this_month, i);
  247.         dash_line (0);
  248.     }
  249.     }
  250. }
  251.  
  252. leap ()
  253. {
  254.     int     yr;
  255.  
  256.     yr = this_year;
  257.  
  258.     if ((yr / 4) * 4 != yr) {
  259.     return 0;
  260.     }
  261.     if ((yr / 100) * 100 != yr) {
  262.     return 1;
  263.     }
  264.     if ((yr / 400) * 400 != yr) {
  265.     return 0;
  266.     }
  267.     return 1;
  268.  
  269. }
  270.  
  271. zeller (month, year)
  272. int     month;
  273. int     year;
  274. {
  275.     int     result;
  276.     int     m,
  277.             c,
  278.             y,
  279.             f;
  280.  
  281.     y = year;
  282.     m = month - 2;
  283.     if (m <= 0) {
  284.     m += 12;
  285.     y--;
  286.     }
  287.  
  288.     c = y / 100;
  289.     y -= (c * 100);
  290.  
  291.     f = ((26 * m - 2) / 10) + 1 + ((5 * y) / 4) + (c / 4) - (2 * c);
  292.  
  293.     result = f % 7;
  294.     return result;
  295.  
  296. }
  297.  
  298. cardscan ()
  299. {
  300.     char    input_line[80];
  301.     char   *ptr;
  302.     int     plus_minus;
  303.     int     n;
  304.  
  305.     if (isatty (0)) {
  306.     printf ("Enter command line, enter '?' for help, 'q' to quit\n");
  307.     printf (">> ");
  308.     (void) fflush (stdout);
  309.     }
  310.  
  311.     if (getline (0, input_line) == -1) {
  312.     if (isatty (0)) {
  313.         printf ("\n");
  314.     }
  315.     return FALSE;
  316.     }
  317.  
  318.     if (input_line[0] == 'q') {
  319.     return FALSE;
  320.     }
  321.  
  322.     if (input_line[0] == '?') {
  323.     help ();
  324.     return cardscan ();
  325.     }
  326.  
  327.     n = sscanf (input_line, "%d/%d,%d/%d", &month1, &year1, &month2, &year2);
  328.     if (n != 4) {
  329.     printf ("Error: badly formed input line\n");
  330.     return cardscan ();
  331.     }
  332.     ptr = index (input_line, ' ');
  333.     ptr++;
  334.     zap3 (special, 4, 12, 32);
  335.     plus_minus = TRUE;
  336.     copies = 1;
  337.     pic_flag = TRUE;
  338.     std_flag = TRUE;
  339.     hday_flag = TRUE;
  340.     (void) strcpy (sday_file, "");
  341.  
  342.     while (*ptr) {
  343.     switch (*ptr) {
  344.     case '+': 
  345.         plus_minus = TRUE;
  346.         break;
  347.     case '-': 
  348.         plus_minus = FALSE;
  349.         break;
  350.     case 'p': 
  351.         pic_flag = plus_minus;
  352.         break;
  353.     case 'h': 
  354.         hday_flag = plus_minus;
  355.         if (hday_flag) {
  356.         read_holidays (ptr + 1);
  357.         }
  358.         if (hday_file[0] == '\0') {
  359.         hday_flag = FALSE;
  360.         }
  361.         ptr = index (ptr, ' ');
  362.         break;
  363.     case 's': 
  364.         std_flag = plus_minus;
  365.         break;
  366.     case 'x': 
  367.         if (plus_minus) {
  368.         read_sdays (ptr + 1);
  369.         }
  370.         ptr = index (ptr, ' ');
  371.         break;
  372.     case 'c': 
  373.         copies = atoi (ptr + 1);
  374.         if (copies < 1) {
  375.         copies = 1;
  376.         }
  377.         ptr = index (ptr, ' ');
  378.         break;
  379.     }
  380.     ptr++;
  381.     }
  382.  
  383.     printf ("options: begin = %02d/%d, end = %02d/%d, copies = %d\n",
  384.         month1, year1, month2, year2, copies);
  385.  
  386.     if (pic_flag) {
  387.     printf ("\t\tpictures");
  388.     }
  389.     else {
  390.     printf ("\t\tnopictures");
  391.     }
  392.  
  393.     if (std_flag) {
  394.     printf (", standard");
  395.     }
  396.     else {
  397.     printf (", nostandard");
  398.     }
  399.  
  400.     if (hday_flag) {
  401.     printf (", holidays(%s)", hday_file);
  402.     }
  403.     else {
  404.     printf (", noholidays");
  405.     }
  406.  
  407.     if (sday_file[0] != '\0') {
  408.     printf (", specialdays(%s)", sday_file);
  409.     }
  410.     else {
  411.     printf (", nospecialdays");
  412.     }
  413.  
  414.     printf ("\n");
  415.  
  416.     return TRUE;
  417. }
  418.  
  419. read_sdays (ptr)
  420. char   *ptr;
  421. {
  422.     char    sd_line[256];
  423.     char   *line_ptr;
  424.     char   *msg;
  425.     int     fd_sday;
  426.     int     sp_indx;
  427.     int     month;
  428.     int     day;
  429.     int     i,
  430.             j,
  431.             k,
  432.             n;
  433.  
  434.     (void) strcpy (sd_line, ptr);
  435.     msg = index (sd_line, ' ');
  436.     if (msg != NULL) {
  437.     *msg = '\0';
  438.     }
  439.     fd_sday = open (sd_line, 0);
  440.     if (fd_sday == -1) {
  441.     return;
  442.     }
  443.     (void) strcpy (sday_file, sd_line);
  444.  
  445.     while (getline (fd_sday, sd_line) != -1) {
  446.     line_ptr = sd_line;
  447.     while (*line_ptr && (*line_ptr == ' ')) {
  448.         line_ptr++;
  449.     }
  450.     if (!*line_ptr) {
  451.         continue;
  452.     }
  453.     n = sscanf (line_ptr, "%d%*c%d%*c%d", &i, &j, &k);
  454.     switch (n) {
  455.     case 3: 
  456.         if ((i < 1) || (i > 4)) {
  457.         printf ("ignoring special day line '%s'\n", sd_line);
  458.         continue;
  459.         }
  460.         if (i == 4) {
  461.         printf ("Warning: special day '%s' ", sd_line);
  462.         printf ("might be overwritten by two line holiday\n");
  463.         }
  464.         sp_indx = i - 1;
  465.         month = j - 1;
  466.         day = k;
  467.         break;
  468.     case 2: 
  469.         sp_indx = 1;
  470.         month = i - 1;
  471.         day = j;
  472.         break;
  473.     default: 
  474.         printf ("ignoring special day line '%s'\n", sd_line);
  475.         continue;
  476.     }
  477.     if (*special[sp_indx][month][day] != '\0') {
  478.         printf ("Warning: special day conflicts with previous entry\n");
  479.         printf ("currently processing file %s\n", sday_file);
  480.         printf ("input line = '%s'\n", sd_line);
  481.         printf ("previous entry = '%s'\n", special[sp_indx][month][day]);
  482.     }
  483.     msg = index (line_ptr, ' ');
  484.     while (*msg == ' ') {
  485.         msg++;
  486.     }
  487.     (void) strcpy (special[sp_indx][month][day], msg);
  488.     }
  489.     (void) close (fd_sday);
  490. }
  491.  
  492. special_line (indx, month, week)
  493. int     indx;
  494. int     month;
  495. int     week;
  496. {
  497.     int     day;
  498.  
  499.     fprintf (calout, "  ");
  500.     month--;
  501.     for (day = week * 7; day < (week + 1) * 7; day++) {
  502.     fprintf (calout, "| %-16s", special[indx][month][days[day]]);
  503.     }
  504.     fprintf (calout, "|\n");
  505. }
  506.  
  507. date_line (week)
  508. int     week;
  509. {
  510.     int     day;
  511.  
  512.     fprintf (calout, "  |");
  513.     for (day = week * 7; day < (week + 1) * 7; day++) {
  514.     if (days[day] != 0) {
  515.         fprintf (calout, "%16d |", days[day]);
  516.     }
  517.     else {
  518.         fprintf (calout, "%16s |", " ");
  519.     }
  520.     }
  521.     fprintf (calout, "\n");
  522. }
  523.  
  524. jdate_line (month, week)
  525. int     month;
  526. int     week;
  527. {
  528.     int     day;
  529.  
  530.     fprintf (calout, "  ");
  531.     month--;
  532.     for (day = week * 7; day < (week + 1) * 7; day++) {
  533.     if (days[day] != 0) {
  534.         fprintf (calout, "|%03d %-13s", julian_days[day],
  535.             holidays[month][days[day]]);
  536.     }
  537.     else {
  538.         fprintf (calout, "|%17s", " ");
  539.     }
  540.     }
  541.     fprintf (calout, "|\n");
  542. }
  543.  
  544. dash_line (n)
  545. int     n;
  546. {
  547.     while (n-- > 0) {
  548.     fprintf (calout, "\n");
  549.     }
  550.  
  551.     fprintf (calout, "  ");
  552.     for (n = 0; n < 7; n++) {
  553.     fprintf (calout, "+-----------------");
  554.     }
  555.     fprintf (calout, "+\n");
  556. }
  557.  
  558. vbar_line ()
  559. {
  560.     int     n;
  561.  
  562.     fprintf (calout, "  ");
  563.     for (n = 0; n < 7; n++) {
  564.     fprintf (calout, "%-18s", "|");
  565.     }
  566.     fprintf (calout, "|\n");
  567. }
  568.  
  569. caltop ()
  570. {
  571.     int     i;
  572.     int     y_thou;
  573.     int     y_hund;
  574.     int     y_ten;
  575.     int     y_one;
  576.  
  577.     y_thou = this_year / 1000;
  578.     y_hund = (this_year % 1000) / 100;
  579.     y_ten = (this_year % 100) / 10;
  580.     y_one = (this_year % 10);
  581.  
  582.     fprintf (calout, "\f");
  583.  
  584.     for (i = 0; i < 8; i++) {
  585.     switch (i) {
  586.     case 0: 
  587.     case 1: 
  588.         fprintf (calout, "%26s%s\n", " ", monames[this_month - 1][i]);
  589.         break;
  590.     case 2: 
  591.         fprintf (calout, "%6s%-20s%-94s%s\n", " ",
  592.             nums[y_hund][i - 2], monames[this_month - 1][i],
  593.             nums[y_ten][i - 2]);
  594.         break;
  595.     default: 
  596.         fprintf (calout, "%-6s%-20s%-94s%-6s%s\n",
  597.             nums[y_thou][i - 3], nums[y_hund][i - 2],
  598.             monames[this_month - 1][i],
  599.             nums[y_ten][i - 2], nums[y_one][i - 3]);
  600.         break;
  601.     case 7: 
  602.         fprintf (calout, "%-126s%s\n",
  603.             nums[y_thou][i - 3], nums[y_one][i - 3]);
  604.         break;
  605.     }
  606.     }
  607.     fprintf (calout, "\n%-9s%-18s%-18s%-18s%-18s%-18s%-18s%s\n",
  608.         " ", "Sunday", "Monday", "Tuesday", "Wednesday",
  609.         "Thursday", "Friday", "Saturday");
  610.  
  611. }
  612.  
  613.  
  614.  
  615. print_picture (month)
  616. int     month;
  617. {
  618.     int     i;
  619.     char   *outline;
  620.  
  621.     for (i = points[month - 1]; i < points[month]; i++) {
  622.     outline = line[i];
  623.     switch (*outline) {
  624.     case '1': 
  625.         fprintf (calout, "\f");
  626.         break;
  627.     case '-': 
  628.         fprintf (calout, "\n\n\n");
  629.         break;
  630.     case '0': 
  631.         fprintf (calout, "\n\n");
  632.         break;
  633.     case ' ': 
  634.         fprintf (calout, "\n");
  635.         break;
  636.     case '+': 
  637.         fprintf (calout, "\r");
  638.         break;
  639.     default: 
  640.         fprintf (calout, "\n");
  641.         break;
  642.     }
  643.     fprintf (calout, "%s", ++outline);
  644.     }
  645.     fprintf (calout, "\r");
  646. }
  647.  
  648. read_picdata ()
  649. {
  650.     int     picdata;
  651.     unsigned    numlines;
  652.  
  653.     picdata = open (input_file, 0);
  654.     if (picdata == -1) {
  655.     perror ("calndr");
  656.     fprintf (stderr, "Unable to open data file\n");
  657.     exit (1);
  658.     }
  659.  
  660.     if (read (picdata, monames[0][0], 12 * 7 * 81) != (12 * 7 * 81)) {
  661.     fprintf (stderr, "Incomplete read on data file while reading sss\n");
  662.     exit (1);
  663.     }
  664.     if (read (picdata, nums[0][0], 10 * 5 * 6) != (10 * 5 * 6)) {
  665.     fprintf (stderr, "Incomplete read on data file while reading sss\n");
  666.     exit (1);
  667.     }
  668.     if (read (picdata, (char *) points, sizeof points) != sizeof points) {
  669.     fprintf (stderr, "Incomplete read on data file while reading sss\n");
  670.     exit (1);
  671.     }
  672.     numlines = (unsigned) points[12];
  673.     line = (char **) calloc (numlines, sizeof (char *));
  674.     alloc_1d (line, numlines, 134);
  675.     if (read (picdata, line[0], (int) (numlines * 134)) != (numlines * 134)) {
  676.     fprintf (stderr, "Incomplete read on data file while reading sss\n");
  677.     exit (1);
  678.     }
  679.     (void) close (picdata);
  680.     return;
  681.  
  682. }
  683.  
  684. /*----- subroutine get_line                    -----*/
  685.  
  686. #define BUFFSIZE 4096
  687. #define BUFCOUNT 6
  688.  
  689. getline (fd, buf)
  690. int     fd;
  691. char   *buf;
  692. {
  693.  
  694.     static char buffer[BUFCOUNT][BUFFSIZE];
  695.     static int  buf_pos[BUFCOUNT];
  696.     static int  buf_size[BUFCOUNT];
  697.     static int  init_flag = 1;
  698.     int     i;
  699.  
  700.  
  701.     if (init_flag) {
  702.     for (i = 0; i < BUFCOUNT; i++) {
  703.         buf_pos[i] = BUFFSIZE;
  704.         buf_size[i] = BUFFSIZE;
  705.     }
  706.     init_flag = 0;
  707.     }
  708.  
  709.     if (fd >= BUFCOUNT) {
  710.     printf ("Error: get_line: fd = %d\n", fd);
  711.     exit (1);
  712.     }
  713.  
  714.  
  715.     i = 0;
  716.  
  717.     while (1) {
  718.     if (buf_pos[fd] >= buf_size[fd]) {
  719.         buf_size[fd] = read (fd, buffer[fd], BUFFSIZE);
  720.         buf_pos[fd] = 0;
  721.         if (buf_size[fd] == 0) {
  722.         break;
  723.         }
  724.     }
  725.  
  726.     if (buffer[fd][buf_pos[fd]] == '\n')
  727.         break;
  728.     if (buffer[fd][buf_pos[fd]] == 12) {
  729.         buf_pos[fd]++;
  730.         continue;
  731.     }
  732.     *buf = buffer[fd][buf_pos[fd]++];
  733.     if (*buf == '\t') {
  734.         *buf = ' ';
  735.         while (i % 8 != 7) {
  736.         *++buf = ' ';
  737.         i++;
  738.         }
  739.     }
  740.     buf++;
  741.     i++;
  742.  
  743.     }
  744.  
  745.     *buf = '\0';
  746.     if (i == 0 && buf_size[fd] == 0 && buf_pos[fd] == 0) {
  747.     i = -1;
  748.     }
  749.     buf_pos[fd]++;
  750.  
  751.     return (i);
  752.  
  753. }
  754.  
  755. #define    VU(s)    fprintf(vu, s)
  756.  
  757. help ()
  758. {
  759.     FILE   *vu;
  760.     FILE   *popen ();
  761.     char    junk[256];
  762.  
  763. #ifdef PAGER
  764.     if ((vu = popen (PAGER, "w")) == NULL)
  765. #endif
  766.     vu = stdout;
  767.  
  768.     VU ("The format of a command input line is as follows:\n");
  769.     VU (" mm/yyyy,mm/yyyy [options]\n\n");
  770.     VU ("The first mm/yyyy specifies the month and year the\n");
  771.     VU ("calendar is to begin with and the second mm/yyyy specifies\n");
  772.     VU ("the ending month and year.  The options that may be given\n");
  773.     VU ("are as follows:\n");
  774.     VU ("\n");
  775.     VU ("   +p        = print pictures\n");
  776.     VU ("   -p        = dont print pictures\n");
  777.     VU ("   +hFILE    = read list of special holidays from FILE\n");
  778.     VU ("   -h        = no special holidays\n");
  779.     VU ("   +s        = include standard holidays on calendar\n");
  780.     VU ("   -s        = dont include standard holidays\n");
  781.     VU ("   +xFILE    = read list of special days from FILE\n");
  782.     VU ("   +cNN      = print NN copies of calendar\n");
  783.     VU ("\n");
  784. #ifndef PAGER
  785.     VU ("Type RETURN for more help\n");
  786.     (void) getline (0, junk);
  787. #endif
  788.     VU ("The special day notations are written on the four lines\n");
  789.     VU ("in the center of the block for the specified day.\n");
  790.     VU ("The format of the special day entries is as follows:\n");
  791.     VU ("\n");
  792.     VU ("   n:mm/dd descriptive text\n");
  793.     VU ("\n");
  794.     VU ("The 'n:' at the beginning of the line specifies which\n");
  795.     VU ("of the four lines in the block to print the descriptive\n");
  796.     VU ("text on.  If the 'n:' is omitted, the default is to print\n");
  797.     VU ("the text on the third line.  The format of the holiday\n");
  798.     VU ("entries is the same except that the 'n:' is always omitted.\n");
  799.     VU ("The text of a holiday entry is printed on the bottom line\n");
  800.     VU ("of the block, next to the julian date.\n\n");
  801.     VU ("The descriptive text can be up to 16 characters for a\n");
  802.     VU ("special day entry and up to 13 characters for a holiday.\n");
  803.  
  804.     if (vu != stdout) {
  805.     (void) pclose (vu);
  806.     }
  807.  
  808. }
  809.  
  810. gen_hdays ()
  811. {
  812.     HDATA * ptr;
  813.  
  814.     if ((this_year == year2) && (month2 == 1)) {
  815.     return;
  816.     }
  817.  
  818.     zap2 (holidays, 12, 32);
  819.  
  820.     if (std_flag) {
  821.     std_hdays ();
  822.     }
  823.  
  824.     if (!hday_flag) {
  825.     return;
  826.     }
  827.     if (hday_head == NULL) {
  828.     return;
  829.     }
  830.  
  831.     ptr = hday_head;
  832.     while (ptr) {
  833.     if (*holidays[ptr -> h_month][ptr -> h_day] != '\0') {
  834.         printf ("User specified holiday conflicts with standard holiday\n");
  835.         printf ("\tstandard holiday = '%s', user holiday = '%s'\n",
  836.             holidays[ptr -> h_month][ptr -> h_day], ptr -> h_name);
  837.         (void) fflush (stdout);
  838.     }
  839.     (void) strcpy (holidays[ptr -> h_month][ptr -> h_day], ptr -> h_name);
  840.     ptr = ptr -> h_link;
  841.     }
  842.  
  843. }
  844.  
  845. std_hdays ()
  846. {
  847.     int     temp;
  848.     int     month;
  849.  
  850.     /* fixed holidays */
  851.     (void) strcpy (holidays[0][1], "New Years Day");
  852.     (void) strcpy (special[3][0][15], "   Martin Luther");
  853.     (void) strcpy (holidays[0][15], " King Jr. Day");
  854.     (void) strcpy (holidays[1][2], "Groundhog Day");
  855.     (void) strcpy (holidays[1][14], "Valentine Day");
  856.     (void) strcpy (special[3][1][12], "       Lincoln's");
  857.     (void) strcpy (holidays[1][12], "    Birthday ");
  858.     (void) strcpy (special[3][1][22], "    Washington's");
  859.     (void) strcpy (holidays[1][22], "   Birthday  ");
  860.     (void) strcpy (special[3][2][17], " Saint Patrick's");
  861.     (void) strcpy (holidays[2][17], "    Day      ");
  862.     (void) strcpy (holidays[5][14], "Flag Day     ");
  863.     (void) strcpy (special[3][6][4], "     Independence");
  864.     (void) strcpy (holidays[6][4], "      Day    ");
  865.     (void) strcpy (special[3][9][24], "  United Nations");
  866.     (void) strcpy (holidays[9][24], "    Day      ");
  867.     (void) strcpy (holidays[9][31], "Halloween    ");
  868.     (void) strcpy (holidays[10][11], "Veterans Day ");
  869.     (void) strcpy (holidays[11][25], "Christmas    ");
  870.  
  871.     /* Armed Forces Day */
  872.     temp = 21 - zeller (5, this_year);
  873.     (void) strcpy (special[3][4][temp], "    Armed Forces");
  874.     (void) strcpy (holidays[4][temp], "     Day     ");
  875.  
  876.     /* Labor Day */
  877.     temp = 9 - zeller (9, this_year);
  878.     if (temp > 7) {
  879.     temp -= 7;
  880.     }
  881.     (void) strcpy (holidays[8][temp], "Labor Day");
  882.  
  883.     /* Thanksgiving */
  884.     temp = 26 - zeller (11, this_year);
  885.     if (temp < 22) {
  886.     temp += 7;
  887.     }
  888.     (void) strcpy (holidays[10][temp], "Thanksgiving");
  889.  
  890.     /* Memorial Day */
  891.     temp = 30 - zeller (5, this_year);
  892.     if (temp < 25) {
  893.     temp += 7;
  894.     }
  895.     (void) strcpy (holidays[4][temp], "Memorial Day");
  896.  
  897.     /* Mothers Day */
  898.     temp = 15 - zeller (5, this_year);
  899.     if (temp > 14) {
  900.     temp -= 7;
  901.     }
  902.     (void) strcpy (holidays[4][temp], "Mother's Day");
  903.  
  904.     /* Fathers Day */
  905.     temp = 22 - zeller (6, this_year);
  906.     if (temp > 21) {
  907.     temp -= 7;
  908.     }
  909.     (void) strcpy (holidays[5][temp], "Father's Day");
  910.  
  911.     /* Columbus Day */
  912.     temp = 16 - zeller (10, this_year);
  913.     if (temp > 12) {
  914.     temp -= 7;
  915.     }
  916.     (void) strcpy (holidays[9][temp], "Columbus Day");
  917.  
  918.     /* generate a couple of Canadian holidays */
  919.     temp = 23 - zeller (5, this_year);
  920.     (void) strcpy (special[3][4][temp], "     Canadian   ");
  921.     (void) strcpy (holidays[4][temp], "Victoria Day ");
  922.  
  923.     temp = zeller (7, this_year);
  924.     switch (temp) {
  925.     case 0: 
  926.     temp = 2;
  927.     break;
  928.     case 6: 
  929.     temp = 3;
  930.     break;
  931.     default: 
  932.     temp = 1;
  933.     break;
  934.     }
  935.     (void) strcpy (special[3][6][temp], "     Canadian   ");
  936.     (void) strcpy (holidays[6][temp], "Dominion Day ");
  937.  
  938.     /* if year is withing range, generate easter etc. */
  939.     temp = this_year - 1950;
  940.     if ((temp < 1) || (temp > 50)) {
  941.     printf ("Warning: requested year is not within the bounds for\n");
  942.     printf ("generating Easter and related holidays.\n");
  943.     return;
  944.     }
  945.  
  946.     temp--;
  947.     temp *= 2;
  948.     month = easter[temp];
  949.     temp = easter[++temp];
  950.     (void) strcpy (holidays[--month][temp], "Easter");
  951.  
  952.     temp -= 2;
  953.     if (temp < 1) {
  954.     month--;
  955.     temp += daycnt[month];
  956.     }
  957.     (void) strcpy (holidays[month][temp], "Good Friday");
  958.  
  959.     temp -= 5;
  960.     if (temp < 1) {
  961.     month--;
  962.     temp += daycnt[month];
  963.     }
  964.     (void) strcpy (holidays[month][temp], "Palm Sunday");
  965.  
  966.     temp -= 39;
  967.     while (temp < 1) {
  968.     month--;
  969.     temp += daycnt[month];
  970.     }
  971.     (void) strcpy (holidays[month][temp], "Ash Wednesday");
  972.  
  973. }
  974.  
  975. read_holidays (sptr)
  976. char   *sptr;
  977. {
  978.     char    file[1024];
  979.     char    input_line[80];
  980.     char   *temp;
  981.     int     fd;
  982.     int     i,
  983.             j,
  984.             n;
  985.     HDATA  *ptr;
  986.     HDATA  *next;
  987.  
  988.     if (*sptr == ' ') {
  989.     return;
  990.     }
  991.  
  992.     if (hday_head != NULL) {
  993.     ptr = hday_head;
  994.     while (ptr) {
  995.         next = ptr -> h_link;
  996.         free ((char *) ptr);
  997.         ptr = next;
  998.     }
  999.     }
  1000.  
  1001.     hday_head = NULL;
  1002.     (void) strcpy (hday_file, "");
  1003.     (void) strcpy (file, sptr);
  1004.     if ((temp = index (file, ' ')) != NULL) {
  1005.     *temp = '\0';
  1006.     }
  1007.  
  1008.     if ((fd = open (file, 0)) == -1) {
  1009.     printf ("** warning ** - unable to open file %s\n", file);
  1010.     printf ("                +h option ignored\n");
  1011.     hday_flag = FALSE;
  1012.     return;
  1013.     }
  1014.     (void) strcpy (hday_file, file);
  1015.  
  1016.     while (getline (fd, input_line) != -1) {
  1017.     temp = input_line;
  1018.     while (*temp && (*temp == ' ')) {
  1019.         temp++;
  1020.     }
  1021.     if (!*temp) {
  1022.         continue;
  1023.     }
  1024.     n = sscanf (temp, "%d%*c%d", &i, &j);
  1025.     if (n != 2) {
  1026.         continue;
  1027.     }
  1028.     next = (HDATA *) malloc (sizeof (HDATA));
  1029.     if (next == NULL) {
  1030.         perror ("calndr");
  1031.         printf ("Unable to alocate space for holiday_data\n");
  1032.         return;
  1033.     }
  1034.     if (hday_head == NULL) {
  1035.         hday_head = next;
  1036.     }
  1037.     else {
  1038.         ptr -> h_link = next;
  1039.     }
  1040.     ptr = next;
  1041.     ptr -> h_link = NULL;
  1042.     i--;
  1043.     temp = index (temp, ' ');
  1044.     while (*temp && (*temp == ' ')) {
  1045.         temp++;
  1046.     }
  1047.     ptr -> h_month = i;
  1048.     ptr -> h_day = j;
  1049.     (void) strncpy (ptr -> h_name, temp, 13);
  1050.     }
  1051.  
  1052.     (void) close (fd);
  1053.  
  1054. }
  1055.