home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume39 / nhl / part01 / nhl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-16  |  21.3 KB  |  815 lines

  1. /*
  2.   NHL.C - Last modified on 6 Sep 1993 by ferguson.
  3.  
  4.   Schedule program for the NHL regular season.
  5.  
  6.   Reconstructed for 1993-94 by:
  7.     George Ferguson <ferguson@cs.rochester.edu>
  8.  
  9.     With any luck, you should never have to edit this file for a new
  10.     season. All the season-specific information is in schedule.c which
  11.     is included by this file. I also added head-to-head (team or division)
  12.     modes, the manpage, and put together the distribution kit.
  13.  
  14.   Maintained thorugh 1992-93 season by:
  15.     Valerie Hammerl (hammerl@acsu.buffalo.edu)
  16.     Rob Springall (rgs7077@ultb.isc.rit.edu, rgs7077@ritvax.bitnet)
  17.  
  18.   ----------------------------------------------------------------------
  19.  
  20.   Original program concept by Len Carr, used with permission.
  21.   All other features created by Rob Springall, except for neutral site 
  22.   games, assisted by Tom Wilson.
  23.  
  24.   Additional credit goes to the members of the USENET community who
  25.   contributed ideas and support for this project.
  26.  
  27.   This program is not copyrighted or registered in any form.  It does,
  28.   however, remain the intellectual property of its authors.
  29.  
  30.   ----------------------------------------------------------------------
  31. */
  32.  
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <time.h>
  36. #ifndef VMS
  37. #ifndef MSDOS
  38. #include <sys/time.h>
  39. #endif
  40. #endif
  41.  
  42. /*
  43.  * Load the season-specific code
  44.  */
  45. #include "schedule.c"
  46.  
  47. /*
  48.  * Include version control information for -v option
  49.  */
  50. #include "patchlevel.h"
  51.  
  52. /*    -    -    -    -    -    -    -    -    */
  53. /*
  54.  * Functions defined here:
  55.  */
  56. static void initialize(), parse_options(), set_team_arg();
  57. static int str_to_team(), str_to_division();
  58. static void error(), print_help();
  59. static void do_sched(), do_nhl_sched(), do_team_sched(), do_div_sched();
  60. static void do_team_vs_team(), do_team_vs_div(), do_div_vs_div();
  61. static int today(), parse_date(), md_to_nhlday(), nhlday_to_dow(), find_char();
  62. static void inc_date(), print_game();
  63.  
  64. /*
  65.  * Global variables:
  66.  */
  67. char *program;            /* Name of program for error messages */
  68. int nhl_start_day;        /* Date of start of season */
  69. int nhl_start_month;
  70. int nhl_start_year;
  71. int nhl_end_day;        /* Date of end of season */
  72. int nhl_end_month;
  73. int nhl_end_year;
  74. int nhl_start_dow;        /* Day of week of start of season (Sun == 0) */
  75. int nhl_old_year_offset;    /* Days in start year before season starts */
  76. int nhl_new_year_offset;    /* Days in start year after season starts */
  77.  
  78. int team1 = -1;            /* First team specified on cmd-line */
  79. int team2 = -1;            /* Second team specified on cmd-line */
  80. int team1_is_div = 0;        /* First team is actually a division */
  81. int team2_is_div = 0;        /* Second team is actually a division */
  82. int homeonlyflag = 0;        /* Only print home games */
  83. int awayonlyflag = 0;        /* Only print away games */
  84. #define DEFAULT_GAMES_TO_SHOW 3
  85. int num_games_to_show = DEFAULT_GAMES_TO_SHOW;    /* Value of -n option */
  86.  
  87. /*
  88.  * These array will be munged in initialize() to adjust for leap-years.
  89.  */
  90. /* Number of days in month in non-leap year, Jan == 1. */
  91. int month_len[] = {
  92.   0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  93. };
  94. /* Index of first day of month in non-leap year, Jan == 1. */
  95. int month_start[] = {
  96.   0,  0, 31, 59, 90,120,151,181,212,243,273,304,334
  97. };
  98.  
  99. /*
  100.  * String corresponding to weekday (0 == Sunday):
  101.  */
  102. char *weekday[] = {
  103.   "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday",
  104. };
  105.  
  106. /*    -    -    -    -    -    -    -    -    */
  107.  
  108. main(argc,argv)
  109. int argc;
  110. char *argv[];
  111. {
  112.     int month,day;
  113.  
  114.     program = argv[0];
  115.     argc -= 1;
  116.     argv += 1;
  117.     initialize();
  118.     parse_options(&argc,&argv);
  119.     if (argc == 0) {
  120.     today(&month,&day);
  121.     /* If today isn't in season, assume start of season */
  122.     if (md_to_nhlday(month,day) < 0) {
  123.         fprintf(stderr,
  124.             "%s: today not during season, assuming start of season\n",
  125.             program);
  126.         month = nhl_start_month;
  127.         day = nhl_start_day;
  128.     }
  129.     do_sched(month,day);
  130.     } else {
  131.     while (argc--) {
  132.         if (parse_date(argv[0],&month,&day) >= 0) {
  133.         do_sched(month,day);
  134.         }
  135.         argv += 1;
  136.     }
  137.     }
  138.     exit(0);
  139. }
  140.  
  141. /*
  142.  * initialize():
  143.  *  Initialize the program. This involves setting various "constants"
  144.  *  from the season-specific information.
  145.  */
  146. static void
  147. initialize()
  148. {
  149.     int div,team,i;
  150.  
  151.     /* Parse the start and end dates */
  152.     if (sscanf(NHL_START_DATE,"%d/%d/%d",
  153.            &nhl_start_month,&nhl_start_day,&nhl_start_year) != 3) {
  154.     fprintf(stderr,"%s: YOW! NHL_START_DATE not set correctly: %s\n",
  155.         program,NHL_START_DATE);
  156.     exit(1);
  157.     }
  158.     if (sscanf(NHL_END_DATE,"%d/%d/%d",
  159.            &nhl_end_month,&nhl_end_day,&nhl_end_year) != 3) {
  160.     fprintf(stderr,"%s: YOW! NHL_END_DATE not set correctly: %s\n",
  161.         program,NHL_END_DATE);
  162.     exit(1);
  163.     }
  164.     /* Parse the start dow */
  165.     for (i=0; i < 7; i++) {
  166.     if (strcmp(NHL_START_DOW,weekday[i]) == 0) {
  167.         nhl_start_dow = i;
  168.         break;
  169.     }
  170.     }
  171.     if (i == 7) {
  172.     fprintf(stderr,"%s: YOW! NHL_START_DOW not set correctly: %s\n",
  173.         program,NHL_START_DOW);
  174.     exit(1);
  175.     }
  176.     /* Adjust length of Feb for leap years */
  177.     if (nhl_end_year % 400 == 0 ||
  178.     (nhl_end_year % 100 != 0 && nhl_end_year % 4 == 0)) {
  179.     month_len[2] += 1;
  180.     for (i=3; i <= nhl_end_month; i++)
  181.         month_start[i] += 1;
  182.     }
  183.     /* Number of days in nhl_start_year before season starts: */
  184.     nhl_old_year_offset = month_start[nhl_start_month] + nhl_start_day;
  185.     /* Number of days in nhl_start_year after season starts: */
  186.     nhl_new_year_offset = month_start[12]+month_len[12]-nhl_old_year_offset;
  187.     /* Parse the division info */
  188.     for (div=0; div < NUM_DIVISIONS; div++) {
  189.     for (i=0; i < MAX_TEAMS_PER_DIVISION &&
  190.               divisions[div].teams[i] != NULL; i++) {
  191.         if ((team=str_to_team(divisions[div].teams[i])) < 0) {
  192.         fprintf(stderr,"%s: YOW! division \"%s\" has bogus team: \"%s\"\n",
  193.             program,divisions[div].name,divisions[div].teams[i]);
  194.         exit(1);
  195.         }
  196.         divisions[div].flags[team] = 1;
  197.     }
  198.     }
  199. }
  200.  
  201. /*
  202.  * parse_options(argcp,argvp):
  203.  *  Parse the command-line and update ARGC/ARGV, exit on error.
  204.  */
  205. static void
  206. parse_options(argcp,argvp)
  207. int *argcp;
  208. char ***argvp;
  209. {
  210.     char *arg;
  211.     int team,division;
  212.  
  213.     while (*argcp > 0) {
  214.     arg = **argvp;
  215.     if (strncmp(arg,"-v",2) == 0) {
  216.         printf("NHL schedule program: version %s, patchlevel %d\n",
  217.            VERSION,PATCHLEVEL);
  218.         exit(0);
  219.     } else if (strncmp(arg,"-h",2) == 0) {
  220.         print_help();
  221.         exit(0);
  222.     } else if (strncmp(arg,"-H",2) == 0) {
  223.         homeonlyflag = 1;
  224.     } else if (strncmp(arg,"-A",2) == 0) {
  225.         awayonlyflag = 1;
  226.     } else if (strncmp(arg,"-n",2) == 0) {
  227.         if ((num_games_to_show=atoi(arg+2)) == 0) {
  228.         error("bad or missing value for -n: \"%s\"\n",arg+2);
  229.         }
  230.     } else if (strncmp(arg,"-t",2) == 0) {
  231.         if ((team=str_to_team(arg+2)) < 0) {
  232.         error("invalid team code: %s\n",arg+2);
  233.         }
  234.         set_team_arg(team,0);
  235.     } else if (strncmp(arg,"-d",2) == 0) {
  236.         if ((division=str_to_division(arg+2)) < 0) {
  237.         error("invalid divison code: %s\n",arg+2);
  238.         }
  239.         set_team_arg(division,1);
  240.     } else if (*arg < '0' || *arg > '9') {
  241.         if ((team=str_to_team(arg)) >= 0) {
  242.         set_team_arg(team,0);
  243.         } else if ((division=str_to_division(arg)) >= 0) {
  244.         set_team_arg(division,1);
  245.         } else {
  246.         error("unknown team or division code: %s\n",arg);
  247.         }
  248.     } else {
  249.         /* Must be dates starting now */
  250.         return;
  251.     }
  252.     *argcp -= 1;
  253.     *argvp += 1;
  254.     }
  255. }
  256.  
  257. /*
  258.  * str_to_team(str):
  259.  *  Converts string STR to a team index (ie., an index into teams[])
  260.  *  if it is a valid team code and returns it, otherwise returns -1.
  261.  */
  262. static int
  263. str_to_team(str)
  264. char *str;
  265. {
  266.     int team;
  267.  
  268.     for (team=0; team < NUM_TEAMS; team++) {
  269.     if (strcmp(str,teams[team].abbrev) == 0)
  270.         return(team);
  271.     }
  272.     return(-1);
  273. }
  274.  
  275. /*
  276.  * str_to_division(str):
  277.  *  Converts string STR to a division index (ie., an index into divisons[])
  278.  *  if it is a valid team code and returns it, otherwise returns -1.
  279.  */
  280. static int
  281. str_to_division(str)
  282. char *str;
  283. {
  284.     int division;
  285.  
  286.     for (division=0; division < NUM_DIVISIONS; division++) {
  287.     if (strcmp(str,divisions[division].abbrev) == 0)
  288.         return(division);
  289.     }
  290.     return(-1);
  291. }
  292.  
  293. /*
  294.  * set_team_arg(team,flag):
  295.  *  Sets global variable team1 or team2 if one isn't set. If both are
  296.  *  already set, prints a message and exits. If FLAG is non-zero, then
  297.  *  this is really a division code not a team, and the appropriate flag
  298.  *  (team1_is_div or team2_is_div) is set.
  299.  */
  300. static void
  301. set_team_arg(team,flag)
  302. int team,flag;
  303. {
  304.     if (team1 == -1) {
  305.     team1 = team;
  306.     team1_is_div = flag;
  307.     } else if (team2 == -1) {
  308.     team2 = team;
  309.     team2_is_div = flag;
  310.     } else {
  311.     error("too many teams or divisions specified\n",NULL);
  312.     }
  313. }
  314.  
  315. /*
  316.  * error(fmt,arg):
  317.  *  Print an error message to stderr using FMT and ARG, then print the
  318.  *  help message and exit.
  319.  */
  320. static void
  321. error(fmt,arg)
  322. char *fmt,*arg;
  323. {
  324.     fprintf(stderr,"%s: ",program);
  325.     fprintf(stderr,fmt,arg);
  326.     print_help();
  327.     exit(1);
  328. }
  329.  
  330. /*
  331.  * print_help():
  332.  *  Print the usage message:
  333.  */
  334. static void
  335. print_help()
  336. {
  337.     int i;
  338.  
  339.     printf("usage: %s [-HAv] [-nNUM] [TEAM|DIV [TEAM|DIV]] [mm/dd ...]\n",program);
  340.     printf(" With no teams or divisions specified, print the league schedule\n");
  341.     printf("   for given dates (default is today if no dates given).\n");
  342.     printf(" With one team or division, print next NUM games (default %d) for\n",DEFAULT_GAMES_TO_SHOW);
  343.     printf("   that team or teams in that division.\n");
  344.     printf(" With two teams or divisions, print next NUM games where first team (or team\n");
  345.     printf("   in first division) plays second team (or team in second division).\n");
  346.     printf(" -H or -A: Show only home or away games, resp., for first team or division.\n");
  347.     printf(" -v: Print version only: This is version %s, patchlevel %d.\n",
  348.        VERSION,PATCHLEVEL);
  349.     printf(" Teams can specified with or without leading -t, from the following list:\n");
  350.     for (i = 0; i < NUM_TEAMS; i++) {
  351.     printf("   %3s - %-12s",teams[i].abbrev,teams[i].city);
  352.     if ((i % 3) == 2)
  353.         printf( "\n");
  354.     }
  355.     if ((i % 3) != 0)
  356.     printf( "\n");
  357.     printf(" Divisions can specified with or without a leading -d, from the following list:\n");
  358.     for (i = 0; i < NUM_DIVISIONS; i++) {
  359.     printf("   %8s - %-12s",divisions[i].abbrev,divisions[i].name);
  360.     if (((i+1) % 2) == 0)
  361.         printf( "\n");
  362.     }
  363.     if (i % 2 != 0)
  364.     printf( "\n");
  365. }
  366.  
  367. /*    -    -    -    -    -    -    -    -    */
  368. /*
  369.  * do_sched(month,day):
  370.  *  Depending on the globals set by cmd-line flags, do the right thing
  371.  *  for the given date.
  372.  */
  373. static void
  374. do_sched(month,day)
  375. int month,day;
  376. {
  377.     int nhlday;
  378.  
  379.     /* Convert date to index in season */
  380.     if ((nhlday=md_to_nhlday(month,day)) < 0) {
  381.     printf("The NHL regular season runs from %d/%d - %d/%d\n",
  382.            nhl_start_month,nhl_start_day,nhl_end_month,nhl_end_day);
  383.     return;
  384.     }
  385.     /* Now do the right thing */
  386.     if (team1 == -1 && team2 == -1) {
  387.     do_nhl_sched(nhlday,month,day);
  388.     } else if (team2 == -1) {
  389.     if (team1_is_div)
  390.         do_div_sched(team1,nhlday,month,day);
  391.     else
  392.         do_team_sched(team1,nhlday,month,day);
  393.     } else if (team1_is_div && team2_is_div) {
  394.     do_div_vs_div(team1,team2,nhlday,month,day);
  395.     } else if (team1_is_div) {
  396.     do_team_vs_div(team2,team1,nhlday,month,day);
  397.     } else if (team2_is_div) {
  398.     do_team_vs_div(team1,team2,nhlday,month,day);
  399.     } else {
  400.     do_team_vs_team(team1,team2,nhlday,month,day);
  401.     }
  402. }
  403.  
  404. /*
  405.  * do_nhl_sched(nhlday,month,day):
  406.  *  Print league schedule for MON and DAY
  407.  */
  408. static void
  409. do_nhl_sched(nhlday,month,day)
  410. int nhlday,month,day;
  411. {
  412.     char code;
  413.     int home,site;
  414.     int count,i;
  415.  
  416.     printf("NHL schedule for %s, %d/%d...\n",
  417.        weekday[nhlday_to_dow(nhlday)],month,day);
  418.     /* Scan today's schedule for games */
  419.     count = 0;
  420.     for (i=0; i < NUM_TEAMS; i++) {
  421.     code = schedule[nhlday][i];
  422.     if (ISAWAYCODE(code)) {
  423.         home = TEAMCODETOINDEX(code);
  424.         printf("     %-12s at %s",teams[i].city,teams[home].city);
  425.         code = schedule[nhlday][home];
  426.         if (ISSITECODE(code)) {
  427.         site = SITECODETOINDEX(code);
  428.         printf(" @ %s",neutral_sites[site]);
  429.         }
  430.         printf("\n");
  431.         count += 1;
  432.     }
  433.     }
  434.     /* If there are no games, see if it is a special day. */
  435.     if (count == 0) {
  436.     printf("     No games scheduled");
  437.     for (i=0; special_dates[i].month != 0; i++) {
  438.         if (month == special_dates[i].month &&
  439.         day == special_dates[i].day) {
  440.         printf(": %s",special_dates[i].text);
  441.         break;
  442.         }
  443.     }
  444.     printf("\n");
  445.     }
  446. }
  447.  
  448. /*    -    -    -    -    -    -    -    -    */
  449. /*
  450.  * do_team_sched(team,nhlday,month,day):
  451.  *  Print upcoming games for TEAM starting at MONTH/DAY.
  452.  */
  453. static void
  454. do_team_sched(team,nhlday,month,day)
  455. int team;
  456. int nhlday,month,day;
  457. {
  458.     char code;
  459.     int home,visitor;
  460.     int count;
  461.  
  462.     if (homeonlyflag) {
  463.     printf("Upcoming %s home games...\n",teams[team].name);
  464.     } else if (awayonlyflag) {
  465.     printf("Upcoming %s away games...\n",teams[team].name);
  466.     } else {
  467.     printf("Upcoming %s games...\n",teams[team].name);
  468.     }
  469.     count = 0;
  470.     while ((nhlday >= 0) && (count < num_games_to_show)) {
  471.     code = schedule[nhlday][team];
  472.     if ((ISHOMECODE(code) || ISSITECODE(code)) &&    /* TEAM is home */
  473.         !awayonlyflag) {
  474.         visitor = find_char(INDEXTOTEAMCODE(team),schedule[nhlday]);
  475.         print_game(nhlday,month,day,visitor,team);
  476.         count += 1;
  477.     } else if (ISAWAYCODE(code) && !homeonlyflag) {    /* TEAM is away */
  478.         home = TEAMCODETOINDEX(code);
  479.         print_game(nhlday,month,day,team,home);
  480.         count += 1;
  481.     }
  482.     inc_date(&month,&day);
  483.     nhlday = md_to_nhlday(month,day);
  484.     }
  485. }
  486.  
  487. /*
  488.  * do_div_sched(div,nhlday,month,day):
  489.  *  Print upcoming games for DIV starting at MONTH/DAY.
  490.  */
  491. static void
  492. do_div_sched(div,nhlday,month,day)
  493. int div;
  494. int nhlday,month,day;
  495. {
  496.     char code;
  497.     int team;
  498.     int count,i;
  499.  
  500.     if (homeonlyflag) {
  501.     printf("Upcoming %s division home games...\n",divisions[div].name);
  502.     } else if (awayonlyflag) {
  503.     printf("Upcoming %s division away games...\n",divisions[div].name);
  504.     } else {
  505.     printf("Upcoming %s division games...\n",divisions[div].name);
  506.     }
  507.     count = 0;
  508.     while ((nhlday >= 0) && (count < num_games_to_show)) {
  509.     for (i=0; i < NUM_TEAMS; i++) {
  510.         code = schedule[nhlday][i];
  511.         if (ISAWAYCODE(code)) {
  512.         team = TEAMCODETOINDEX(code);
  513.         if ((divisions[div].flags[i] && !homeonlyflag) ||
  514.             (divisions[div].flags[team] && !awayonlyflag)) {
  515.             print_game(nhlday,month,day,i,team);
  516.             count += 1;
  517.         }
  518.         }
  519.     }
  520.     inc_date(&month,&day);
  521.     nhlday = md_to_nhlday(month,day);
  522.     }
  523. }
  524.  
  525. /*
  526.  * do_team_vs_team(team1,team2,nhlday,month,day):
  527.  *  Prints upcoming games between TEAM1 and TEAM2 starting at MON/DAY.
  528.  */
  529. static void
  530. do_team_vs_team(team1,team2,nhlday,month,day)
  531. int team1,team2;
  532. int nhlday,month,day;
  533. {
  534.     char code1,code2;
  535.     int count;
  536.  
  537.     if (homeonlyflag) {
  538.     printf("Upcoming games for the %s home to the %s...\n",
  539.            teams[team1].name,teams[team2].name);
  540.     } else if (awayonlyflag) {
  541.     printf("Upcoming games for the %s away at the %s...\n",
  542.            teams[team1].name,teams[team2].name);
  543.     } else {
  544.     printf("Upcoming games between the %s and the %s...\n",
  545.            teams[team1].name,teams[team2].name);
  546.     }
  547.     code1 = INDEXTOTEAMCODE(team1);
  548.     code2 = INDEXTOTEAMCODE(team2);
  549.     count = 0;
  550.     while ((nhlday >= 0) && (count < num_games_to_show)) {
  551.     if (schedule[nhlday][team1] == code2 &&        /* TEAM1 at TEAM2 */
  552.         !homeonlyflag) {
  553.         print_game(nhlday,month,day,team1,team2);
  554.         count += 1;
  555.     } else if (schedule[nhlday][team2] == code1 &&    /* TEAM2 at TEAM1 */
  556.            !awayonlyflag) {
  557.         print_game(nhlday,month,day,team2,team1);
  558.         count += 1;
  559.     }
  560.     inc_date(&month,&day);
  561.     nhlday = md_to_nhlday(month,day);
  562.     }
  563. }
  564.  
  565. /*
  566.  * do_team_vs_div(team,div,nhlday,month,day):
  567.  *  Prints upcoming games between TEAM and teams in DIV starting at MON/DAY.
  568.  */
  569. static void
  570. do_team_vs_div(team,div,nhlday,month,day)
  571. int team,div;
  572. int nhlday,month,day;
  573. {
  574.     char code,teamcode;
  575.     int home,count,i;
  576.  
  577.     if (homeonlyflag) {
  578.     printf("Upcoming games for the %s home to %s division teams...\n",
  579.            teams[team].name,divisions[div].name);
  580.     } else if (awayonlyflag) {
  581.     printf("Upcoming games for the %s away at %s division teams...\n",
  582.            teams[team].name,divisions[div].name);
  583.     } else {
  584.     printf("Upcoming games between the %s and %s division teams...\n",
  585.            teams[team].name,divisions[div].name);
  586.     }
  587.     teamcode = INDEXTOTEAMCODE(team);
  588.     count = 0;
  589.     while ((nhlday >= 0) && (count < num_games_to_show)) {
  590.     code = schedule[nhlday][team];
  591.     if (ISAWAYCODE(code) && !homeonlyflag) {    /* TEAM is away */
  592.         home = TEAMCODETOINDEX(code);
  593.         if (divisions[div].flags[home]) {        /* home is in DIV */
  594.         print_game(nhlday,month,day,team,home);
  595.         count += 1;
  596.         }
  597.     } else if ((ISHOMECODE(code) || ISSITECODE(code)) && /* TEAM is home */
  598.            !awayonlyflag) {
  599.         for (i=0; i < NUM_TEAMS; i++) {
  600.         if (schedule[nhlday][i] == teamcode &&    /* i away at TEAM */
  601.             divisions[div].flags[i]) {        /* i in DIV */
  602.             print_game(nhlday,month,day,i,team);
  603.             count += 1;
  604.         }
  605.         }
  606.     }
  607.     inc_date(&month,&day);
  608.     nhlday = md_to_nhlday(month,day);
  609.     }
  610. }
  611.  
  612. /*
  613.  * do_div_vs_div(div1,div2,nhlday,month,day):
  614.  *  Prints upcoming games between teams in DIV1 and teams in DIV2 starting
  615.  *  at MON/DAY.
  616.  */
  617. static void
  618. do_div_vs_div(div1,div2,nhlday,month,day)
  619. int div1,div2;
  620. int nhlday,month,day;
  621. {
  622.     char code;
  623.     int home;
  624.     int count,i;
  625.  
  626.     if (div1 == div2) {
  627.     printf("Upcoming games between %s division teams...\n",
  628.            divisions[div1].name);
  629.     } else if (homeonlyflag) {
  630.     printf("Upcoming games for %s division teams home to %s division teams...\n",
  631.            divisions[div1].name,divisions[div2].name);
  632.     } else if (awayonlyflag) {
  633.     printf("Upcoming games for %s division teams away at %s division teams...\n",
  634.            divisions[div1].name,divisions[div2].name);
  635.     } else {
  636.     printf("Upcoming games between %s division teams and %s division teams...\n",
  637.            divisions[div1].name,divisions[div2].name);
  638.     }
  639.     count = 0;
  640.     while ((nhlday >= 0) && (count < num_games_to_show)) {
  641.     for (i=0; i < NUM_TEAMS; i++) {
  642.         if (divisions[div1].flags[i]) {        /* Team i in DIV1 */
  643.         code = schedule[nhlday][i];
  644.         if (ISAWAYCODE(code) &&            /* Team i away */
  645.             (div1 == div2 || !homeonlyflag)) {
  646.             home = TEAMCODETOINDEX(code);
  647.             if (divisions[div2].flags[home]) {    /* Home team in DIV2 */
  648.             print_game(nhlday,month,day,i,home);
  649.             count += 1;
  650.             }
  651.         }
  652.         } else if (divisions[div2].flags[i]) {    /* Team i in DIV2 */
  653.         code = schedule[nhlday][i];
  654.         if (ISAWAYCODE(code) &&            /* Team i away */
  655.             (div1 == div2 || !awayonlyflag)) {
  656.             home = TEAMCODETOINDEX(code);
  657.             if (divisions[div1].flags[home]) {    /* Home team in DIV1 */
  658.             print_game(nhlday,month,day,i,home);
  659.             count += 1;
  660.             }
  661.         }
  662.         }
  663.     }
  664.     inc_date(&month,&day);
  665.     nhlday = md_to_nhlday(month,day);
  666.     }
  667. }
  668.  
  669. /*    -    -    -    -    -    -    -    -    */
  670. /*
  671.  * today(monp,dayp):
  672.  *  Set MON and DAY to the current date.
  673.  */
  674. static int
  675. today(monp,dayp)
  676. int *monp,*dayp;
  677. {
  678.     time_t tv;
  679.     struct tm *tmp;
  680.  
  681.     tv = time(NULL);
  682.     tmp = localtime(&tv);
  683.     *monp = tmp->tm_mon+1;             /* We use Jan == 1 */
  684.     *dayp = tmp->tm_mday;
  685.     return(0);
  686. }
  687.  
  688. /*
  689.  * parse_date(date,monp,dayp):
  690.  *  Parse given DATE string (format MM/DD) into MON and DAY.
  691.  */
  692. static int
  693. parse_date(date,monp,dayp)
  694. char *date;
  695. int *monp,*dayp;
  696. {
  697.     if (sscanf(date,"%d/%d",monp,dayp) != 2) {
  698.     fprintf(stderr,"%s: bad date: %s...format is \"mm/dd\"\n",
  699.         program,date);
  700.     return(-1);
  701.     }
  702.     if (*monp < 1 || *monp > 12) {
  703.     fprintf(stderr,"%s: bad month in date: %s\n",program,date);
  704.     return(-1);
  705.     }
  706.     if (*dayp < 1 || *dayp > month_len[*monp]) {
  707.     fprintf(stderr,"%s: bad day in date: %s\n",program,date);
  708.     return(-1);
  709.     }
  710.     return(0);
  711. }
  712.  
  713. /*
  714.  * md_to_nhlday(month,day):
  715.  *  Return the day of the season for the given MONTH/DAY (ie., the index
  716.  *  into schedule[] for that date's games).
  717.  *  Returns -1 if the date is not during the nhl season.
  718.  */
  719. static int
  720. md_to_nhlday(month,day)
  721. int month,day;
  722. {
  723.     int nhlday;
  724.  
  725.     if ((month == nhl_start_month && day < nhl_start_day) ||
  726.     (month == nhl_end_month && day > nhl_end_day) ||
  727.     (month > nhl_end_month && month < nhl_start_month)) {
  728.     /* Not during season */
  729.     nhlday = -1;
  730.     } else if (month >= nhl_start_month) {
  731.     /* Before Jan 1 */
  732.     nhlday = month_start[month] + day - nhl_old_year_offset;
  733.     } else {
  734.     /* After Jan 1 */
  735.     nhlday = month_start[month] + day + nhl_new_year_offset;
  736.     }
  737.     return(nhlday);
  738. }
  739.  
  740. /*
  741.  * nhlday_to_dow(nhlday):
  742.  *  Return the day of the week for the given nhlday (Sun == 0).
  743.  */
  744. static int
  745. nhlday_to_dow(nhlday)
  746. int nhlday;
  747. {
  748.     return(((nhlday % 7) + nhl_start_dow) % 7);
  749. }
  750.  
  751. /*
  752.  * find_char(c,str):
  753.  *  Return index of first occurrence of C in STR, or -1 if not found.
  754.  */
  755. static int
  756. find_char(c,str)
  757. char c;
  758. char *str;
  759. {
  760.     int n = 0;
  761.  
  762.     while (*str) {
  763.     if (c == *str++)
  764.         return(n);
  765.     else
  766.         n += 1;
  767.     }
  768.     return(-1);
  769. }
  770.  
  771. /*
  772.  * inc_date(month,day):
  773.  *  Increment day (and month, if necessary) to the next day.
  774.  */
  775. static void
  776. inc_date(month,day)
  777. int *month,*day;
  778. {
  779.     if (*day >= month_len[*month]) {
  780.     *day   = 1;
  781.     *month += 1;
  782.     if (*month > 12) {
  783.         *month = 1;
  784.     }
  785.     } else {
  786.     (*day)++;
  787.     }
  788. }
  789.  
  790. /*
  791.  * print_game(nhlday,month,day,visitor,home):
  792.  *  Format and output the entry for a game on DOW/MONTH/DAY between teams
  793.  *  VISITOR and HOME, checking for neutral site.
  794.  *  This is used by do_team_sched() and do_head_to_head_sched().
  795.  */
  796. static void
  797. print_game(nhlday,month,day,visitor,home)
  798. int nhlday;
  799. int month,day;
  800. int visitor,home;
  801. {
  802.     char buf[32],code;
  803.     int site;
  804.  
  805.     sprintf(buf,"%s, %d/%d:",weekday[nhlday_to_dow(nhlday)],month,day);
  806.     printf("     %-18s",buf);
  807.     printf("%s at %s",teams[visitor].city,teams[home].city);
  808.     code = schedule[nhlday][home];
  809.     if (ISSITECODE(code)) {
  810.     site = SITECODETOINDEX(code);
  811.     printf(" @ %s",neutral_sites[site]);
  812.     }
  813.     printf("\n");
  814. }
  815.