home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft_Programmers_Library.7z / MPL / msc / mscsampl.txt < prev    next >
Encoding:
Text File  |  2013-11-08  |  6.2 MB  |  214,544 lines

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1.  Microsoft C Optimizing Compiler - v6.0
  2.  
  3.  
  4.  CHRTDEMO.C
  5.  CD-ROM Disc Path:   \SAMPCODE\C\MSC60\CHRTDEMO.C
  6.  
  7.  #include <stdlib.h>
  8.  #include <stdio.h>
  9.  #include <conio.h>
  10.  #include <string.h>
  11.  #include <graph.h>
  12.  #include <pgchart.h>
  13.  #include "chrtdemo.h"
  14.  
  15.  /* Structures for system configuration and chart environment. */
  16.  struct videoconfig vc;
  17.  chartenv ce;
  18.  
  19.  /* Category variables.  */
  20.  short cCat;
  21.  char _far *aCat[MAXVALUES];
  22.  
  23.  /* Series variables.  */
  24.  short cSeries;
  25.  short _far acSeries[MAXSERIES];
  26.  char _far *aSeriesName[MAXSERIES];
  27.  
  28.  /* Temporary holding array for all data. Data values for multi-series
  29.   * bar, column, and line charts remain here. Data for other kinds of
  30.   * charts are transferred to the arrays below.
  31.   */
  32.  float _far aValue[MAXSERIES][MAXVALUES];
  33.  
  34.  /* Data values for single-series charts. First array is used for
  35.   * bar, column, line, and pie. First and second are both used for
  36.   * single-series scatter.
  37.   */
  38.  float _far axValue[MAXVALUES];
  39.  float _far ayValue[MAXVALUES];
  40.  
  41.  /* Data values for multi-series scatter charts.  */
  42.  float _far axValueMS[MAXVALUES][MAXVALUES];
  43.  float _far ayValueMS[MAXVALUES][MAXVALUES];
  44.  
  45.  /* Exploded flags for pie chart.  */
  46.  short _far aExplode[MAXVALUES];
  47.  
  48.  /* Variable used to track control and screen position.  */
  49.  struct SCREENINFO si;
  50.  
  51.  /* Colors of menus and prompts. */
  52.  struct tagColor co;
  53.  
  54.  /* Flags to indicate whether to use imported or default data.  */
  55.  BOOL fDefault = TRUE;
  56.  
  57.  /* Arrays of strings used by the Menu function. The first string is the
  58.   * menu title. The next non-null strings are the menu selections. A null
  59.   * string indicates the end of the list.
  60.   */
  61.  char *pszChartOpt[] =
  62.      { "Options", "Screen Mode", "Windows", "Titles",
  63.        "Axis (X and Y)", "Legend", "Fonts", "Reset", "" };
  64.  
  65.  char *pszChartType[] =
  66.      { "Type", "Bar", "Column", "Line", "Scatter", "Pie", "" };
  67.  
  68.  char *pszMainMenu[] =
  69.      { "Main Menu", "Demo", "View Chart", "Chart Type", "Options",
  70.        "Show Chart Data", "Quit", "" };
  71.  
  72.  /* Sample data.  */
  73.  #define O_JUICE 0
  74.  #define I_TEA   1
  75.  #define H_CHOC  2
  76.  #define TEMPERATURE  3
  77.  
  78.  char _far *aQuarters[] =
  79.      { "First", "Second", "Third", "Fourth" };
  80.  
  81.  char _far *aMonths[] =
  82.      { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  83.        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  84.  
  85.  float _far aSales[3][12] =
  86.  {
  87.      {  3.6F,  3.2F,  3.3F,  3.4F,  3.1F,  2.9F,
  88.         3.0F,  3.6F,  3.2F,  3.3F,  3.5F,  3.9F },
  89.      {  1.0F,  1.3F,  1.4F,  1.7F,  2.2F,  2.9F,
  90.         2.9F,  3.1F,  2.6F,  1.8F,  1.1F,  1.2F },
  91.      {  2.4F,  2.3F,  2.0F,  1.6F,  1.3F,  1.0F,
  92.         0.9F,  0.8F,  1.1F,  1.4F,  1.9F,  2.5F }
  93.  };
  94.  
  95.  float _far aTemperature[12] =
  96.      {  2.9F,  3.2F,  3.9F,  4.8F,  6.0F,  6.5F,
  97.         7.0F,  7.2F,  6.0F,  4.7F,  4.1F,  3.0F };
  98.  
  99.  char _far *aSalesTitles[] =
  100.      { "Orange Juice Sales", "Iced Tea Sales", "Hot Chocolate Sales" };
  101.  
  102.  char *TempTitle = "Average Temperature";
  103.  
  104.  int main()
  105.  {
  106.      Initialize();
  107.      MainMenu();
  108.  
  109.      /* Reset the video mode and screen colors prior to leaving. */
  110.      _setvideomode( _DEFAULTMODE );
  111.      _settextcolor( co.InfoColor );
  112.      _clearscreen( _GCLEARSCREEN );
  113.  
  114.      return 0;
  115.  }
  116.  
  117.  /*  ChartOptions - Gets chart options.
  118.   *
  119.   *  Params: None
  120.   */
  121.  void ChartOptions()
  122.  {
  123.      int iChoice;
  124.  
  125.      PushTitle( pszChartOpt[0] );
  126.      while( (iChoice = Menu( pszChartOpt )) != ESCAPE )
  127.      {
  128.  
  129.          /* Get chart options.  */
  130.          switch( iChoice )
  131.          {
  132.  
  133.              /* Branch to the appropriate menu.  */
  134.              case 1:
  135.                  ScreenMode();
  136.                  break;
  137.  
  138.              case 2:
  139.                  Windows();
  140.                  break;
  141.  
  142.              case 3:
  143.                  Titles();
  144.                  break;
  145.  
  146.              case 4:
  147.                  Axes();
  148.                  break;
  149.  
  150.              case 5:
  151.                  Legend();
  152.                  break;
  153.  
  154.              case 6:
  155.                  FontOptions();
  156.                  break;
  157.  
  158.              case 7:
  159.                  ResetOptions();
  160.                  break;
  161.  
  162.          }
  163.      }
  164.      PopTitle();
  165.  }
  166.  
  167.  /*  ChartType - Gets chart type.
  168.   *
  169.   *  Params: None
  170.   */
  171.  void ChartType()
  172.  {
  173.      int iChoice;
  174.  
  175.      /* Get chart type.  */
  176.      PushTitle( pszChartType[0] );
  177.      iChoice = Menu( pszChartType );
  178.  
  179.      if( iChoice != ESCAPE )
  180.      {
  181.          /* Set the chart type, and get the chart style.  */
  182.          ce.charttype = iChoice;
  183.          switch( iChoice )
  184.          {
  185.  
  186.              case 1:
  187.              case 2:
  188.                  iChoice = BlankMenu( "Style", "Plain Bars", "Stacked Bars" );
  189.                  break;
  190.  
  191.              case 3:
  192.              case 4:
  193.                  iChoice = BlankMenu( "Style", "Lines-Points", "Points Only" )
  194.                  break;
  195.  
  196.              case 5:
  197.                  iChoice = BlankMenu( "Style", "Percent", "No Percent" );
  198.          }
  199.  
  200.          if( iChoice != ESCAPE)
  201.              ce.chartstyle = iChoice;
  202.  
  203.          /* Set default data without changing environment defaults.  */
  204.          DefaultData( ce.charttype, ce.chartstyle, FALSE );
  205.          PopTitle();
  206.      }
  207.      PopTitle();
  208.  }
  209.  
  210.  /*  ClearData - Clears category and value data.
  211.   *
  212.   *  Params: fConfirm - flag specifying whether to query for confirmation
  213.   */
  214.  void ClearData( BOOL fConfirm )
  215.  {
  216.      char chResponse = 'Y';
  217.      int iCat;
  218.  
  219.      WrtForm( 18 );
  220.  
  221.      /* Query for confirmation.  */
  222.      if( fConfirm )
  223.          chResponse = InputCh( "Are you sure? ", "YN\x1b" );
  224.  
  225.      if( chResponse == 'Y' )
  226.      {
  227.  
  228.          /* Clear all relevant data.  */
  229.          for( iCat = 0; iCat < cCat; iCat++ )
  230.              aCat[iCat] = NULL;
  231.          cCat = 0;
  232.          cSeries = 0;
  233.      }
  234.  }
  235.  
  236.  /*  DefaultData - Initializes default data for each kind of chart.
  237.   *
  238.   *  Params: iType - Chart type to be initialized
  239.   *          iStyle - Chart style
  240.   *          fClear - Signal to clear all defaults
  241.   */
  242.  void DefaultData( short iType, short iStyle, BOOL fClear )
  243.  {
  244.      int iCat, iValue, iSubValue, iSeries;
  245.  
  246.      /* Call default chart to clear old values.  */
  247.      if( fClear )
  248.          _pg_defaultchart( &ce, iType, iStyle );
  249.  
  250.      /* Initialize category titles.  */
  251.      cCat = 12;
  252.      for( iCat = 0; iCat < cCat; iCat++ )
  253.          aCat[iCat] = aMonths[iCat];
  254.  
  255.      switch( ce.charttype )
  256.      {
  257.  
  258.          /* Initialize data for each chart type.  */
  259.          case _PG_BARCHART:
  260.  
  261.              strcpy( ce.maintitle.title, "Orange Juice and Iced Tea Sales" );
  262.              cSeries = 2;
  263.              for( iSeries = 0; iSeries < cSeries; iSeries++ )
  264.              {
  265.                  aSeriesName[iSeries] = aSalesTitles[iSeries];
  266.                  acSeries[iSeries] = cCat;
  267.                  for( iValue = 0; iValue < cCat; iValue++ )
  268.                      aValue[iSeries][iValue]  = (float)aSales[iSeries][iValue]
  269.              }
  270.              break;
  271.  
  272.          case _PG_COLUMNCHART:
  273.  
  274.              strcpy( ce.maintitle.title, "Orange Juice Sales" );
  275.              cSeries = 1;
  276.              for( iSeries = 0; iSeries < cSeries; iSeries++ )
  277.              {
  278.                  aSeriesName[iSeries] = aSalesTitles[iSeries];
  279.                  acSeries[iSeries] = cCat;
  280.                  for( iValue = 0; iValue < cCat; iValue++ )
  281.                      aValue[iSeries][iValue]  = (float)aSales[iSeries][iValue]
  282.              }
  283.              break;
  284.  
  285.          case _PG_LINECHART:
  286.  
  287.              strcpy( ce.maintitle.title, "Beverage Sales" );
  288.              cSeries = 3;
  289.              for( iSeries = 0; iSeries < cSeries; iSeries++ )
  290.              {
  291.                  aSeriesName[iSeries] = aSalesTitles[iSeries];
  292.                  acSeries[iSeries] = cCat;
  293.                  for( iValue = 0; iValue < cCat; iValue++ )
  294.                      aValue[iSeries][iValue] = (float)aSales[iSeries][iValue];
  295.              }
  296.              break;
  297.  
  298.          case _PG_SCATTERCHART:
  299.  
  300.              strcpy( ce.maintitle.title,
  301.                      "Average Temperature Compared to Beverage Sales" );
  302.              /* ce.chartstyle = _PG_POINTONLY; */
  303.              cSeries = 4;
  304.  
  305.              aSeriesName[0] = aSalesTitles[I_TEA];
  306.              aSeriesName[2] = aSalesTitles[H_CHOC];
  307.              acSeries[0] = acSeries[1] = acSeries[2] = acSeries[3] = 12;
  308.              for( iValue = 0; iValue < 12; iValue++ )
  309.              {
  310.                  aValue[0][iValue]  = (float)aSales[I_TEA][iValue] ;
  311.                  aValue[1][iValue]  = (float)aSales[TEMPERATURE][iValue] ;
  312.                  aValue[2][iValue]  = (float)aSales[H_CHOC][iValue] ;
  313.                  aValue[3][iValue]  = (float)aSales[TEMPERATURE][iValue] ;
  314.              }
  315.              break;
  316.  
  317.          case _PG_PIECHART:
  318.          default:
  319.  
  320.              strcpy( ce.maintitle.title, "Iced Tea Sales" );
  321.              cCat = 4;
  322.              for( iCat = 0; iCat < cCat; iCat++ )
  323.                  aCat[iCat] = aQuarters[iCat];
  324.  
  325.              cSeries = 1;
  326.              aSeriesName[0] = aSalesTitles[I_TEA];
  327.              acSeries[0] = cCat;
  328.  
  329.              for( iValue = 0; iValue < cCat; iValue++ )
  330.              {
  331.                  aValue[0][iValue] = 0.0;
  332.                  for( iSubValue = 0; iSubValue < 3; iSubValue++ )
  333.                      aValue[0][iValue] += (float)aSales[I_TEA][iSubValue * iVa
  334.              }
  335.              aExplode[3] = 1;
  336.              break;
  337.      }
  338.  }
  339.  
  340.  /*  Demo - Displays a series of sample charts.
  341.   *
  342.   *  Params: None
  343.   */
  344.  void Demo()
  345.  {
  346.      int  cValue;
  347.      palettetype palette_struct;
  348.  
  349.      /* Display the sample data in spreadsheet form. */
  350.      ShowSampleData();
  351.  
  352.      DefaultData( _PG_PIECHART, _PG_NOPERCENT, TRUE );
  353.  
  354.      /* Set video mode and draw charts. For each chart, set default
  355.       * data and modify any desired environment fields. If error,
  356.       * terminate demo.
  357.       */
  358.      _setvideomode( si.mode );
  359.  
  360.      cValue = 4;
  361.      strcpy( ce.subtitle.title, "Default Pie Chart" );
  362.      if( ViewChart() )
  363.          return;
  364.      else
  365.          _clearscreen( _GCLEARSCREEN );
  366.  
  367.      strcpy( ce.subtitle.title, "Customized Pie Chart" );
  368.      ce.chartstyle = _PG_PERCENT;
  369.      ce.legend.place = _PG_BOTTOM;
  370.      if (si.fColor)
  371.      {
  372.          ce.maintitle.titlecolor = ce.subtitle.titlecolor = 0;
  373.          ce.chartwindow.background = 1;
  374.          ce.datawindow.background = ce.legend.legendwindow.background = 6;
  375.          ce.legend.textcolor = 1;
  376.      }
  377.      if( ViewChart() )
  378.          return;
  379.      else
  380.          _clearscreen( _GCLEARSCREEN );
  381.  
  382.      cValue = 12;
  383.      DefaultData( _PG_BARCHART, _PG_PLAINBARS, TRUE );
  384.      strcpy( ce.subtitle.title, "Default Bar Chart" );
  385.      if( ViewChart() )
  386.          return;
  387.      else
  388.          _clearscreen( _GCLEARSCREEN );
  389.  
  390.      strcpy( ce.subtitle.title, "Customized Stacked Bar Chart" );
  391.      strcpy( ce.xaxis.axistitle.title, "Sales in Thousands" );
  392.      strcpy( ce.yaxis.axistitle.title, "Month" );
  393.      ce.chartstyle = _PG_STACKEDBARS;
  394.      ce.legend.place = _PG_RIGHT;
  395.      ce.xaxis.ticdecimals = 2;
  396.      if (si.fColor)
  397.      {
  398.          ce.maintitle.titlecolor = ce.subtitle.titlecolor = 12;
  399.          ce.chartwindow.background = 7;
  400.          ce.datawindow.background = 8;
  401.          ce.legend.textcolor = 0;
  402.          ce.legend.legendwindow.background = 8;
  403.          ce.legend.autosize = FALSE;
  404.          ce.legend.legendwindow.y1 = vc.numypixels - 85;
  405.          ce.legend.legendwindow.y2 = vc.numypixels - 45;
  406.      }
  407.      if( ViewChart() )
  408.          return;
  409.      else
  410.          _clearscreen( _GCLEARSCREEN );
  411.  
  412.      DefaultData( _PG_COLUMNCHART, _PG_PLAINBARS, TRUE );
  413.      strcpy( ce.subtitle.title, "Default Column Chart" );
  414.      if( ViewChart() )
  415.          return;
  416.      else
  417.          _clearscreen( _GCLEARSCREEN );
  418.  
  419.      strcpy( ce.subtitle.title, "Customized Column Chart" );
  420.      strcpy( ce.xaxis.axistitle.title, "Month" );
  421.      strcpy( ce.yaxis.axistitle.title, "Sales in Thousands" );
  422.      ce.legend.place = _PG_BOTTOM;
  423.      if (si.fColor)
  424.      {
  425.          ce.maintitle.titlecolor     = 0;
  426.          ce.subtitle.titlecolor     = 0;
  427.          ce.chartwindow.background = 8;
  428.          ce.datawindow.background = 2;
  429.          ce.legend.legendwindow.background = 10;
  430.      }
  431.      if( ViewChart() )
  432.          return;
  433.      else
  434.          _clearscreen( _GCLEARSCREEN );
  435.  
  436.      DefaultData( _PG_LINECHART, _PG_POINTANDLINE, TRUE );
  437.      strcpy( ce.subtitle.title, "Default Line Chart" );
  438.      if( ViewChart() )
  439.          return;
  440.      else
  441.          _clearscreen( _GCLEARSCREEN );
  442.  
  443.      strcpy( ce.subtitle.title, "Customized Line Chart" );
  444.      strcpy( ce.xaxis.axistitle.title, "Month" );
  445.      strcpy( ce.yaxis.axistitle.title, "Sales in Thousands" );
  446.      ce.legend.place = _PG_RIGHT;
  447.      if (si.fColor)
  448.      {
  449.          ce.maintitle.titlecolor = 1;
  450.          ce.subtitle.titlecolor = 1;
  451.          ce.chartwindow.background = 3;
  452.          ce.datawindow.background = 7;
  453.          ce.legend.legendwindow.background = 7;
  454.          ce.legend.autosize = FALSE;
  455.          ce.legend.legendwindow.y1 = vc.numypixels - 85;
  456.          ce.legend.legendwindow.y2 = vc.numypixels - 45;
  457.      }
  458.      if( ViewChart() )
  459.          return;
  460.      else
  461.          _clearscreen( _GCLEARSCREEN );
  462.  
  463.      DefaultData( _PG_SCATTERCHART, _PG_POINTONLY, TRUE );
  464.      strcpy( ce.subtitle.title, "Default Scatter Chart" );
  465.      if( ViewChart() )
  466.          return;
  467.      else
  468.          _clearscreen( _GCLEARSCREEN );
  469.  
  470.      cSeries = 4;
  471.      strcpy( ce.subtitle.title, "Customized Scatter Chart" );
  472.      strcpy( ce.xaxis.axistitle.title, "Sales in Thousands" );
  473.      strcpy( ce.yaxis.axistitle.title, "Average Temperature" );
  474.      ce.legend.place = _PG_RIGHT;
  475.      if (si.fColor)
  476.      {
  477.          ce.maintitle.titlecolor = 0;
  478.          ce.subtitle.titlecolor = 0;
  479.          ce.chartwindow.background = 4;
  480.          ce.datawindow.background = 8;
  481.          ce.legend.legendwindow.background = 8;
  482.          ce.legend.autosize = FALSE;
  483.          ce.legend.legendwindow.y1 = vc.numypixels - 85;
  484.          ce.legend.legendwindow.y2 = vc.numypixels - 45;
  485.      }
  486.      if( ViewChart() )
  487.          return;
  488.      else
  489.          _clearscreen( _GCLEARSCREEN );
  490.  
  491.      DefaultData( _PG_BARCHART, _PG_PERCENT, TRUE );
  492.  }
  493.  
  494.  /*  FindVideoMode - Finds the "best" video mode for the adaptor in use.
  495.   *
  496.   *  Params: vc - structure of type struct videoconfig
  497.   *
  498.   *  Returns: Best mode
  499.   */
  500.  int FindVideoMode( struct videoconfig vc )
  501.  {
  502.      switch( vc.adapter )
  503.      {
  504.          case _CGA:
  505.          case _OCGA:
  506.              return _HRESBW;
  507.          case _EGA:
  508.                  case _OEGA:
  509.                          return( vc.monitor == _MONO ) ? _ERESNOCOLOR : _ERESC
  510.          case _VGA:
  511.          case _OVGA:
  512.          case _MCGA:
  513.              return _VRES16COLOR;
  514.          case _HGC:
  515.              return _HERCMONO;
  516.          default:
  517.              return _DEFAULTMODE;
  518.      }
  519.  }
  520.  
  521.  /*  Initialize - Does various initialization tasks.
  522.   *
  523.   *  Params: None
  524.   */
  525.  void Initialize( void )
  526.  {
  527.      int iSeries, iValue;
  528.  
  529.      /* Initialize all value arrays to missing.  */
  530.      for( iSeries = 0; iSeries < MAXSERIES; iSeries++ )
  531.      {
  532.  
  533.          axValue[iSeries] = _PG_MISSINGVALUE;
  534.          ayValue[iSeries] = _PG_MISSINGVALUE;
  535.  
  536.          for( iValue = 0; iValue < MAXVALUES; iValue++ )
  537.              aValue[iSeries][iValue] = _PG_MISSINGVALUE;
  538.  
  539.          for( iValue = 0; iValue < MAXVALUES; iValue++ )
  540.          {
  541.              axValueMS[iSeries][iValue] = _PG_MISSINGVALUE;
  542.              ayValueMS[iSeries][iValue] = _PG_MISSINGVALUE;
  543.          }
  544.      }
  545.  
  546.      /* Initialize zero sets. */
  547.      cSeries = 0;
  548.  
  549.      /* Initialize default chart environment, screen mode, and data.  */
  550.      _pg_initchart();
  551.      _getvideoconfig( &vc );
  552.  
  553.      /* Find the best available mode for display.
  554.       * Don't set 256 color, medium resolution (_MRES256COLOR).
  555.       */
  556.      si.mode = FindVideoMode( vc );
  557.  
  558.      if( si.mode == _TEXTMONO )
  559.      {
  560.          _clearscreen( _GCLEARSCREEN );
  561.          _outtext( "No graphics available.  Can't run chart demo." );
  562.          exit( 1 );
  563.      }
  564.  
  565.      SetDisplayColors();
  566.  
  567.      SetGraphMode( si.mode );
  568.      DefaultData( _PG_BARCHART, _PG_PLAINBARS, TRUE );
  569.  
  570.      _setvideomode( _DEFAULTMODE );
  571.  
  572.  
  573.  }
  574.  
  575.  /*  MainMenu - Manages the main menu.
  576.   *
  577.   *  Params: None
  578.   */
  579.  void MainMenu( void )
  580.  {
  581.      int iChoice;
  582.      char chResponse = 'Y';
  583.      char chVerify;
  584.  
  585.      PushTitle( pszMainMenu[0] );
  586.      do
  587.      {
  588.          /* If the user selects Quit, iChoice will contain 6.  If the
  589.           *   user presses ESCAPE, iChoice will be ESCAPE, which is
  590.           *   equal to 27.  In any case, we can test both conditions
  591.           *   by checking to see whether iChoice is less than 6.
  592.           */
  593.          while( (iChoice = Menu( pszMainMenu )) < 6 )
  594.          {
  595.              /* Get main menu selection.  */
  596.              switch( iChoice )
  597.              {
  598.  
  599.                  case 1:
  600.                      /* Display demo charts.  */
  601.                      Demo();
  602.                      _setvideomode( _DEFAULTMODE );
  603.                      break;
  604.  
  605.                  case 2:
  606.                      /* Set graphics video mode, display current chart,
  607.                       * and restore text video mode.
  608.                       */
  609.                      _setvideomode( si.mode );
  610.                      ViewChart();
  611.                      _setvideomode( _DEFAULTMODE );
  612.                      break;
  613.  
  614.                  case 3:
  615.                      /* Get chart type and style.  */
  616.                      ChartType();
  617.                      break;
  618.  
  619.                  case 4:
  620.                      /* Get chart options.  */
  621.                      ChartOptions();
  622.                      break;
  623.                  case 5:
  624.                      /* Show chart data. */
  625.                      ShowChartData();
  626.                      break;
  627.  
  628.              }
  629.  
  630.          }
  631.  
  632.          /* If the user is trying to leave the program using the ESCAPE
  633.           *   key, we must verify the choice.  This is done to prevent
  634.           *   an eager typist from pressing ESCAPE one time too often
  635.           *   and exiting at an unanticipated point.
  636.           */
  637.          if( iChoice == ESCAPE )
  638.          {
  639.              Help( "Press \"Q\" to Actually Quit", co.InputColor );
  640.  
  641.              putchar( BEEP );
  642.              _settextposition( si.help - 1, 32 );
  643.              chVerify = getch();
  644.              if( tolower( chVerify ) != 'q' )
  645.                  iChoice = 0;
  646.              else
  647.                  iChoice = 6;
  648.          }
  649.  
  650.      } while( iChoice != 6 );
  651.      PopTitle();
  652.  }
  653.  
  654.  /*  ResetOptions - After confirmation, resets chart options to default.
  655.   *
  656.   *  Params: None
  657.   */
  658.  void ResetOptions()
  659.  {
  660.      char chResponse;
  661.  
  662.      /* Prompt for confirmation before setting default environment.  */
  663.      ClrForm();
  664.      Help( "Type  'Y' to reset all options, 'N' to keep them.", co.InputColor
  665.      chResponse = InputCh( "Are you sure? ", "YN\x1b" );
  666.      if( chResponse == 'Y' )
  667.          _pg_defaultchart( &ce, 1, 1 );
  668.  
  669.  }
  670.  
  671.  /*  SetGraphMode - Tests the specified graphics mode and sets the xMax
  672.   *  and yMax values in the si (Screen Information) structure.
  673.   *
  674.   *  Params: mode number
  675.   *
  676.   *  Return: FALSE if mode invalid, TRUE if valid
  677.   */
  678.  BOOL SetGraphMode(int mode)
  679.  {
  680.      if (!_setvideomode( mode ) )
  681.          return FALSE;
  682.      else
  683.      {
  684.          _getvideoconfig ( &vc );
  685.          if( !vc.numxpixels )
  686.              return FALSE;
  687.          si.xMax = vc.numxpixels;
  688.          si.yMax = vc.numypixels;
  689.          si.mode = mode;
  690.  
  691.          /* Set flag to indicate whether multiple colors are available.  */
  692.          si.fColor = iscolor( mode );
  693.  
  694.          return TRUE;
  695.      }
  696.  }
  697.  
  698.  /*  ShowChartData - Displays the data in the chart environment.
  699.   *
  700.   *  Params: None
  701.   */
  702.  void ShowChartData()
  703.  {
  704.      int iRow = 2;
  705.      struct _fontinfo fd;
  706.      static char *szContinue =
  707.          "Press any key to continue, ESC to return to the menu.";
  708.  
  709.      _clearscreen( _GCLEARSCREEN );
  710.      SprintAt( iRow++, 1, "short      charttype =  %d", ce.charttype );
  711.      SprintAt( iRow++, 1, "short      chartstyle = %d", ce.chartstyle );
  712.      SprintAt( iRow++, 1, "windowtype chartwindow =" );
  713.      iRow = ShowWindowType( iRow, 1, ce.chartwindow );
  714.      SprintAt( iRow++, 1, "windowtype datawindow =" );
  715.      iRow = ShowWindowType( iRow, 1, ce.datawindow );
  716.      SprintAt( ++iRow, 1, szContinue );
  717.      if( getch() == ESCAPE )
  718.          return;
  719.  
  720.      iRow = 2;
  721.      _clearscreen( _GCLEARSCREEN );
  722.      SprintAt( iRow++, 1, "titletype  maintitle =" );
  723.      iRow = ShowTitleType( iRow, 1, ce.maintitle );
  724.      SprintAt( iRow++, 1, "titletype   subtitle =" );
  725.      iRow = ShowTitleType( iRow, 1, ce.subtitle );
  726.      SprintAt( ++iRow, 1, szContinue );
  727.      if( getch() == ESCAPE )
  728.          return;
  729.  
  730.      iRow = 2;
  731.      _clearscreen( _GCLEARSCREEN );
  732.      SprintAt( iRow++, 1, "axistype       xaxis =" );
  733.      iRow = ShowAxisType( iRow, 1, ce.xaxis );
  734.      SprintAt( ++iRow, 1, szContinue );
  735.      if( getch() == ESCAPE )
  736.          return;
  737.  
  738.      iRow = 2;
  739.      _clearscreen( _GCLEARSCREEN );
  740.      SprintAt( iRow++, 1, "axistype       yaxis =" );
  741.      iRow = ShowAxisType( iRow, 1, ce.yaxis );
  742.      SprintAt( ++iRow, 1, szContinue );
  743.      if( getch() == ESCAPE )
  744.          return;
  745.  
  746.      iRow = 2;
  747.      _clearscreen( _GCLEARSCREEN );
  748.      SprintAt( iRow++, 1, "legendtype     legend =" );
  749.      iRow = ShowLegendType( iRow, 1, ce.legend );
  750.      SprintAt( ++iRow, 1, szContinue );
  751.      if( getch() == ESCAPE )
  752.          return;
  753.  
  754.      iRow = 2;
  755.      _clearscreen( _GCLEARSCREEN );
  756.      if( _getfontinfo( &fd ) != -1 )
  757.      {
  758.          SprintAt( iRow++, 1, "struct _fontinfo =" );
  759.          iRow = ShowFontInfo( iRow, 1, fd );
  760.          SprintAt( ++iRow, 1, "Press any key to continue . . ." );
  761.          getch();
  762.      }
  763.  }
  764.  
  765.  /*  ShowAxisType - Displays data in a variable of type "axistype".
  766.   *
  767.   *  Params: iRow - Row at which to start
  768.   *          iCol - Column from which to indent
  769.   *          theAxis - Variable of type "axistype" to display
  770.   *
  771.   *  Return: Next available row
  772.   */
  773.  int ShowAxisType( int iRow, int iCol, axistype theAxis )
  774.  {
  775.      SprintAt( iRow++, iCol + 5, "short        .grid = %d", theAxis.grid );
  776.      SprintAt( iRow++, iCol + 5, "short   .gridstyle = %d", theAxis.gridstyle
  777.      SprintAt( iRow++, iCol + 5, "titletype axistitle=" );
  778.      iRow = ShowTitleType( iRow, iCol + 5, theAxis.axistitle );
  779.      SprintAt( iRow++, iCol + 5, "short   .axiscolor = %d", theAxis.axiscolor
  780.      SprintAt( iRow++, iCol + 5, "short     .labeled = %s",
  781.          (theAxis.labeled) ? "TRUE" : "FALSE" );
  782.      SprintAt( iRow++, iCol + 5, "short   .rangetype = %d", theAxis.rangetype
  783.      SprintAt( iRow++, iCol + 5, "float     .logbase = %f", theAxis.logbase );
  784.      SprintAt( iRow++, iCol + 5, "short   .autoscale = %s",
  785.          (theAxis.autoscale) ? "TRUE" : "FALSE" );
  786.      SprintAt( iRow++, iCol + 5, "float    .scalemin = %f", theAxis.scalemin )
  787.      SprintAt( iRow++, iCol + 5, "float    .scalemax = %f", theAxis.scalemax )
  788.      SprintAt( iRow++, iCol + 5, "float .scalefactor = %f", theAxis.scalefacto
  789.      iRow = ShowTitleType( iRow, iCol + 5, theAxis.scaletitle );
  790.      SprintAt( iRow++, iCol + 5, "float  .ticinterval = %f", theAxis.ticinterv
  791.      SprintAt( iRow++, iCol + 5, "short    .ticformat = %d", theAxis.ticformat
  792.      SprintAt( iRow++, iCol + 5, "short  .ticdecimals = %d", theAxis.ticdecima
  793.  
  794.      return iRow;
  795.  }
  796.  
  797.  /*  ShowFontInfo - Displays data in a variable of type "_fontinfo".
  798.   *
  799.   *  Params: iRow - Row at which to start
  800.   *          iCol - Column from which to indent
  801.   *          theFont - Variable of type "_fontinfo" to display
  802.   *
  803.   *  Return: Next available row
  804.   */
  805.  int ShowFontInfo( int iRow, int iCol, struct _fontinfo theFont )
  806.  {
  807.      SprintAt( iRow++, iCol + 5, "int          .type = %d", theFont.type );
  808.      SprintAt( iRow++, iCol + 5, "int        .ascent = %d", theFont.ascent );
  809.      SprintAt( iRow++, iCol + 5, "int      .pixwidth = %d", theFont.pixwidth )
  810.      SprintAt( iRow++, iCol + 5, "int     .pixheight = %d", theFont.pixheight
  811.      SprintAt( iRow++, iCol + 5, "int      .avgwidth = %d", theFont.avgwidth )
  812.      SprintAt( iRow++, iCol + 5, "char     .filename = %s", theFont.filename )
  813.      SprintAt( iRow++, iCol + 5, "char     .facename = %s", theFont.facename )
  814.  
  815.      return iRow;
  816.  }
  817.  
  818.  /*  ShowLegendType - Displays data in a variable of type "legendtype".
  819.   *
  820.   *  Params: iRow - Row at which to start
  821.   *          iCol - Column from which to indent
  822.   *          theLegend - Variable of type "legendtype" to display
  823.   *
  824.   *  Return: Next available row
  825.   */
  826.  int ShowLegendType( int iRow, int iCol, legendtype theLegend )
  827.  {
  828.      SprintAt( iRow++, iCol + 5, "short      .legend = %s",
  829.                (theLegend.legend) ? "TRUE" : "FALSE" );
  830.      SprintAt( iRow++, iCol + 5, "short       .place = %d", theLegend.place );
  831.      SprintAt( iRow++, iCol + 5, "short   .textcolor = %d", theLegend.textcolo
  832.      SprintAt( iRow++, iCol + 5, "short    .autosize = %d", theLegend.autosize
  833.      SprintAt( iRow++, iCol + 5, "windowtype legendwindow =" );
  834.      iRow = ShowWindowType( iRow, iCol + 5, theLegend.legendwindow );
  835.  
  836.      return iRow;
  837.  }
  838.  
  839.  /*  ShowSampleData - Displays the sample data for the demo.
  840.   *
  841.   *  Params: None
  842.   */
  843.  void ShowSampleData()
  844.  {
  845.      int  iCat, y, iSeries, iValue;
  846.      char szTmp[80];
  847.  
  848.      /* Display data in table format. */
  849.      _clearscreen( _GCLEARSCREEN );
  850.      PrintAt( 1, 40 - strlen(szTmp) / 2, "Data in Table Format", -1 );
  851.  
  852.      /* Write titles and draw separator line. */
  853.      y = 3;
  854.      for( iCat = 1; iCat <= 12; iCat++ )
  855.      PrintAt( y, iCat * 6, aMonths[iCat - 1], -1 );
  856.  
  857.      memset( szTmp, '-', 69 );
  858.      szTmp[69] = 0;
  859.      PrintAt( ++y, 6, szTmp, -1 );
  860.  
  861.      /* Write data. */
  862.      for( iSeries = 1; iSeries <= 3; iSeries++ )
  863.      {
  864.          PrintAt( y += 2, 4, aSalesTitles[iSeries - 1], -1 );
  865.          y += 2;
  866.          for( iValue = 1; iValue <= 12; iValue++ )
  867.          {
  868.              sprintf( szTmp, "%#3.2f", aSales[iSeries - 1][iValue - 1] );
  869.              PrintAt( y, iValue * 6, (char _far *)szTmp, -1 );
  870.          }
  871.      }
  872.      PrintAt( y += 2, 4, TempTitle, -1 );
  873.      y += 2;
  874.      for( iValue = 1; iValue <= 12; iValue++ )
  875.      {
  876.          sprintf( szTmp, "%#3.1f", aTemperature[iValue - 1] );
  877.          PrintAt( y, iValue * 6, szTmp, -1 );
  878.      }
  879.  
  880.      PrintAt( y += 2, 1, "Press any key to continue . . .", -1 );
  881.      getche();
  882.  }
  883.  
  884.  /*  ShowTitleType - Displays data in a variable of type "titletype".
  885.   *
  886.   *  Params: iRow - Row at which to start
  887.   *          iCol - Column from which to indent
  888.   *          theTitle - Variable of type "titletype" to display
  889.   *
  890.   *  Return: Next available row
  891.   */
  892.  int ShowTitleType( int iRow, int iCol, titletype theTitle )
  893.  {
  894.      SprintAt( iRow++, iCol + 5, "char    .title[%d] = \"%s\"", _PG_TITLELEN,
  895.                   theTitle.title );
  896.      SprintAt( iRow++, iCol + 5, "short  .titlecolor = %d", theTitle.titlecolo
  897.      SprintAt( iRow++, iCol + 5, "short     .justify = %d", theTitle.justify )
  898.  
  899.      return iRow;
  900.  }
  901.  
  902.  /*  ShowWindowType - Displays data in a variable of type "windowtype".
  903.   *
  904.   *  Params: iRow - Row at which to start
  905.   *          iCol - Column from which to indent
  906.   *          theWindow - Variable of type "windowtype" to display
  907.   *
  908.   *  Return: Next available row
  909.   */
  910.  int ShowWindowType( int iRow, int iCol, windowtype theWindow )
  911.  {
  912.      SprintAt( iRow++, iCol + 5, "short          .x1 = %d", theWindow.x1 );
  913.      SprintAt( iRow++, iCol + 5, "short          .y1 = %d", theWindow.y1 );
  914.      SprintAt( iRow++, iCol + 5, "short          .x2 = %d", theWindow.x2 );
  915.      SprintAt( iRow++, iCol + 5, "short          .y2 = %d", theWindow.y2 );
  916.      SprintAt( iRow++, iCol + 5, "short      .border = %d", theWindow.border )
  917.      SprintAt( iRow++, iCol + 5, "short  .background = %d", theWindow.backgrou
  918.      SprintAt( iRow++, iCol + 5, "short .borderstyle = %d", theWindow.borderst
  919.      SprintAt( iRow++, iCol + 5, "short .bordercolor = %d", theWindow.borderco
  920.  
  921.      return iRow;
  922.  }
  923.  
  924.  /*  ShowError - Displays error message for one of the chart library
  925.   *  errors.
  926.   *
  927.   *  Params: iErr - Error number
  928.   */
  929.  void ShowError( int iErr )
  930.  {
  931.      char szTmp[50];
  932.  
  933.      /* Change to text screen.  */
  934.      _setvideomode( _DEFAULTMODE );
  935.  
  936.      /* Select the error text.  */
  937.      switch( iErr )
  938.      {
  939.          case _PG_NOTINITIALIZED:
  940.              strcpy( szTmp, "Chart Library Not Initialized" );
  941.              break;
  942.          case _PG_BADSCREENMODE:
  943.              strcpy( szTmp, "Invalid Screen Mode" );
  944.              break;
  945.          case _PG_BADCHARTTYPE:
  946.              strcpy( szTmp, "Invalid Chart Type" );
  947.              break;
  948.          case _PG_BADCHARTSTYLE:
  949.              strcpy( szTmp, "Invalid Chart Style" );
  950.              break;
  951.          case _PG_BADLEGENDWINDOW:
  952.              strcpy( szTmp, "Invalid Legend Window" );
  953.              break;
  954.          case _PG_BADDATAWINDOW:
  955.              strcpy( szTmp, "No Room for Data window" );
  956.              break;
  957.          case _PG_BADCHARTWINDOW:
  958.              strcpy( szTmp, "Invalid Chart window coordinates" );
  959.              break;
  960.          case _PG_NOMEMORY:
  961.              strcpy( szTmp, "Not Enough Memory for Data Arrays" );
  962.              break;
  963.          case _PG_BADLOGBASE:
  964.              strcpy( szTmp, "X or Y log base <= 0" );
  965.              break;
  966.          case _PG_BADSCALEFACTOR:
  967.              strcpy( szTmp, "X or Y scale factor = 0" );
  968.              break;
  969.          case _PG_TOOSMALLN:
  970.              strcpy( szTmp, "Too few data values" );
  971.              break;
  972.          case _PG_TOOFEWSERIES:
  973.              strcpy( szTmp, "No data series specified" );
  974.              break;
  975.          default:
  976.              strcpy( szTmp, "Unknown error" );
  977.      }
  978.  
  979.      ErrorMsg( szTmp );
  980.  }
  981.  
  982.  /*  ViewChart - Draws the current chart.
  983.   *
  984.   *  Params: None
  985.   */
  986.  int ViewChart()
  987.  {
  988.      int cValue, iValue, iSeries, iErr;
  989.  
  990.      /* Make sure some data exists.  */
  991.      if( cSeries <= 0 )
  992.      {
  993.          fDefault = TRUE;
  994.          DefaultData( ce.charttype, ce.chartstyle, FALSE );
  995.      }
  996.  
  997.      /* Find the longest series.  */
  998.      cValue = 0;
  999.      for( iSeries = 0; iSeries < cSeries; iSeries++ )
  1000.          if( acSeries[iSeries] > cValue )
  1001.              cValue = acSeries[iSeries];
  1002.  
  1003.      _setvideomode( si.mode );
  1004.  
  1005.  
  1006.      /* Process depending on the type of chart.  */
  1007.      switch( ce.charttype )
  1008.      {
  1009.  
  1010.          case _PG_PIECHART:
  1011.          case _PG_BARCHART:
  1012.          case _PG_COLUMNCHART:
  1013.          case _PG_LINECHART:
  1014.  
  1015.              /* Initialize data and draw pie chart or single-series bar,
  1016.               * column, or line chart.
  1017.               */
  1018.              if( (cSeries == 1) ||( ce.charttype == _PG_PIECHART) )
  1019.              {
  1020.  
  1021.                  /* Transfer data into a single-dimension array.  */
  1022.                  for( iValue = 0; iValue < cValue; iValue++ )
  1023.                     axValue[iValue] = aValue[0][iValue];
  1024.  
  1025.                  /* Draw chart.  */
  1026.                  if( ce.charttype == _PG_PIECHART )
  1027.                      iErr = _pg_chartpie( &ce, aCat, axValue,
  1028.                                           aExplode, cValue );
  1029.                  else
  1030.                      iErr = _pg_chart( &ce, aCat, axValue, cValue );
  1031.              }
  1032.              /* If multiple-series, then data is OK. Just draw chart.  */
  1033.              else
  1034.                  iErr = _pg_chartms( &ce, aCat, (float _far *)aValue,
  1035.                                      cSeries, cValue, cValue, aSeriesName );
  1036.              break;
  1037.  
  1038.          case _PG_SCATTERCHART:
  1039.  
  1040.              /* Make sure there are enough data sets.  */
  1041.              if( cSeries == 1 )
  1042.              {
  1043.                  _setvideomode( _DEFAULTMODE );
  1044.                  si.help = 10;
  1045.                  ErrorMsg( "Too few value data columns for scatter chart." );
  1046.                  return 1;
  1047.  
  1048.              }
  1049.              /* If it's a single-series scatter, transfer data to one-
  1050.               * dimensional arrays and make chart call.
  1051.               */
  1052.              else if( cSeries == 2 )
  1053.              {
  1054.                  for( iValue = 0; iValue < cValue; iValue++ )
  1055.                  {
  1056.                      axValue[iValue] = aValue[0][iValue];
  1057.                      ayValue[iValue] = aValue[1][iValue];
  1058.                  }
  1059.                  cSeries = 1;
  1060.                  iErr = _pg_chartscatter( &ce, axValue, ayValue, cValue );
  1061.  
  1062.              }
  1063.              /* If it's a multiple-series scatter, transfer odd columns to
  1064.               * X-axis data array and even columns to Y-axis array and make
  1065.               * chart call.
  1066.               */
  1067.              else
  1068.              {
  1069.  
  1070.                  for( iSeries = 1; iSeries < cSeries; iSeries += 2 )
  1071.                  {
  1072.                      aSeriesName[iSeries / 2] = aSeriesName[iSeries - 1];
  1073.                      for( iValue = 0; iValue < cValue; iValue++ )
  1074.                      {
  1075.                          axValueMS[iSeries / 2][iValue] =
  1076.                              aValue[iSeries - 1][iValue];
  1077.                          ayValueMS[iSeries / 2][iValue] =
  1078.                              aValue[iSeries][iValue];
  1079.                      }
  1080.                  }
  1081.                  cSeries /= 2;
  1082.  
  1083.                  iErr = _pg_chartscatterms( &ce, (float _far *)axValueMS,
  1084.                                             (float _far *)ayValueMS,
  1085.                                             cSeries, cValue, cValue,
  1086.                                             aSeriesName );
  1087.              }
  1088.      }
  1089.  
  1090.      if( !fDefault )
  1091.          ClearData( FALSE );
  1092.  
  1093.      /* If error, show it, else wait for keypress with chart on screen.  */
  1094.      if( iErr )
  1095.      {
  1096.          ShowError( iErr );
  1097.          return iErr;
  1098.      }
  1099.      else
  1100.          return ( getch() == ESCAPE );   /* ESCAPE means stop demo */
  1101.  }
  1102.  
  1103.  
  1104.  CHRTOPT.C
  1105.  CD-ROM Disc Path:   \SAMPCODE\C\MSC60\CHRTOPT.C
  1106.  
  1107.  #include <stdio.h>
  1108.  #include <conio.h>
  1109.  #include <string.h>
  1110.  #include <graph.h>
  1111.  #include <pgchart.h>
  1112.  #include "chrtdemo.h"
  1113.  
  1114.  /* Structures for system configuration and chart environment. */
  1115.  extern struct videoconfig vc;
  1116.  extern chartenv ce;
  1117.  
  1118.  /* Variable used to track control and screen position.  */
  1119.  extern struct SCREENINFO si;
  1120.  
  1121.  /* Colors of menus and prompts. */
  1122.  extern struct tagColor co;
  1123.  
  1124.  /* Arrays of strings used by the Menu function. The first string is the
  1125.   * menu title. The next non-null strings are the menu selections. A null
  1126.   * string indicates the end of the list.
  1127.   */
  1128.  char *pszAxes[] =
  1129.      { "Axis", "X Axis", "Y Axis", "" };
  1130.  
  1131.  char *pszAxis[] =
  1132.      { "? Options", "Grid", "Axis Title", "Color",
  1133.        "Range Type", "Scale", "Tic Marks", "" };
  1134.  
  1135.  char *pszAuto[] =
  1136.      { "Auto", "Auto", "Manual", "" };
  1137.  
  1138.  char *pszBorder[] =
  1139.      { "Type", "Color", "Style", "" };
  1140.  
  1141.  char *pszChartWindow[] =
  1142.      { "Chart", "Size", "Color (Background)", "Border", "" };
  1143.  
  1144.  char *pszDataWindow[] =
  1145.      { "Data", "Color (Background)", "Border", "" };
  1146.  
  1147.  char * pszFontOpt[] =
  1148.      { "Font Options", "Change Typeface", "Set Character Size", "" };
  1149.  
  1150.  char *pszJustify[] =
  1151.      { "Justify", "Left", "Center", "Right", "" };
  1152.  
  1153.  char *pszLegendWindow[] =
  1154.      { "Options", "Place", "Text Color", "Size", "Color (Background)",
  1155.        "Border", "" };
  1156.  
  1157.  char *pszPlace[] =
  1158.      { "Place", "Right", "Bottom", "Overlay", "" };
  1159.  
  1160.  char *pszScale[] =
  1161.      { "Scale", "Low (Min)", "High (Max)", "Scale Factor", "Title", "" };
  1162.  
  1163.  char *pszSize[] =
  1164.      { "Size", "Top", "Left", "Bottom", "Right", "" };
  1165.  
  1166.  char *pszTic[] =
  1167.      { "Tic Type", "Interval", "Format", "Decimals", "" };
  1168.  
  1169.  char *pszTitleOpt[] =
  1170.      { "", "Text", "Color", "Justify", "" };
  1171.  
  1172.  char *pszTitles[] =
  1173.      { "Title", "Main Title", "Sub Title", "" };
  1174.  
  1175.  char *pszTypeface[] =
  1176.      { "Type Faces", "Courier", "Helv", "Tms Rmn", "Modern", "Script",
  1177.             "Roman", "None", "" };
  1178.  
  1179.  char *pszWindows[] =
  1180.      { "Window", "Chart Window", "Data Window", "" };
  1181.  
  1182.  /*  Axes - Selects X or Y axis.
  1183.   *
  1184.   *  Params: none
  1185.   */
  1186.  void Axes()
  1187.  {
  1188.      int iChoice;
  1189.      static axistype *patAxis[2] = { &ce.xaxis, &ce.yaxis };
  1190.  
  1191.      /* Get menu choice and call appropriate axis Menu. */
  1192.      PushTitle( pszAxes[0] );
  1193.      Help( "Choose 'X' or 'Y' Axis", co.InputColor );
  1194.      while( (iChoice = Menu( pszAxes )) != ESCAPE )
  1195.      {
  1196.          /* Modify axis title, depending on choice. */
  1197.          pszAxis[0][0] = (--iChoice == 0) ? 'X' : 'Y';
  1198.  
  1199.          /* Obtain axis information for appropriate axis. */
  1200.          Axis( patAxis[iChoice] );
  1201.      }
  1202.      PopTitle();
  1203.  }
  1204.  
  1205.  /*  Axis - Selects axis options.
  1206.   *
  1207.   *  Params: pat - Pointer to axistype variable
  1208.   */
  1209.  void Axis( axistype *pat )
  1210.  {
  1211.      int iChoice;
  1212.  
  1213.      PushTitle( pszAxis[0] );
  1214.      while( (iChoice = Menu( pszAxis )) != ESCAPE )
  1215.      {
  1216.  
  1217.          /* Get Axis option.  */
  1218.          switch( iChoice )
  1219.          {
  1220.              case 1:
  1221.                  /* Grid or not? */
  1222.                  iChoice = BlankMenu( "Grid", "Grid", "No Grid" );
  1223.                  switch( iChoice )
  1224.                  {
  1225.  
  1226.                      case 1:
  1227.                          /* If yes, set grid flag and get the grid style. */
  1228.                          pat->grid = TRUE;
  1229.                          Help( "Enter a number in the range 0-10.",
  1230.                              co.InputColor );
  1231.                          pat->gridstyle =
  1232.                              InputInt( "Grid Style? ", pat->gridstyle, 0, 10 )
  1233.                          break;
  1234.  
  1235.                      case 2:
  1236.                          /* If no, clear grid flag.  */
  1237.                          pat->grid = FALSE;
  1238.                  }
  1239.                  PopTitle();
  1240.                  break;
  1241.  
  1242.              case 2:
  1243.                  /* Select axis title options. */
  1244.                  pszTitleOpt[0] = "Axis Title";
  1245.                  TitleOpt( &pat->axistitle );
  1246.                  break;
  1247.  
  1248.              case 3:
  1249.                  /* Select color. */
  1250.                  Help( "Enter a number in the range 0-15.", co.InputColor );
  1251.                  pat->axiscolor =
  1252.                      InputInt( "Axis Color? ", pat->axiscolor, 0, 15 );
  1253.                  break;
  1254.  
  1255.              case 4:
  1256.                  /* Get the axis range.  */
  1257.                  AxisRange( pat );
  1258.                  break;
  1259.  
  1260.              case 5:
  1261.                  /* Get the axis scale.  */
  1262.                  AxisScale( pat );
  1263.                  break;
  1264.  
  1265.              case 6:
  1266.                  /* Get axis tic mark options.  */
  1267.                  AxisTics( pat );
  1268.                  break;
  1269.  
  1270.          }
  1271.      }
  1272.      PopTitle();
  1273.  }
  1274.  
  1275.  /*  AxisRange - Selects range for an axis.
  1276.   *
  1277.   *  Params: pat - pointer to axistype variable
  1278.   */
  1279.  void AxisRange( axistype *pat )
  1280.  {
  1281.      int iChoice;
  1282.  
  1283.      iChoice = BlankMenu( "Range Type", "Normal", "Log" );
  1284.      switch( iChoice )
  1285.      {
  1286.          case 1:
  1287.              /* Set range type to linear.  */
  1288.              pat->rangetype = _PG_LINEARAXIS;
  1289.              break;
  1290.  
  1291.          case 2:
  1292.              /* Set range type to log, then query for log base.  */
  1293.              pat->rangetype = _PG_LOGAXIS;
  1294.              Help( "Enter a value greater than or equal 2.", co.InputColor );
  1295.              pat->logbase = (float)InputInt( "Log base? ",
  1296.                                              (int)pat->logbase, 2, 0 );
  1297.              break;
  1298.      }
  1299.      PopTitle();
  1300.  }
  1301.  
  1302.  /*  AxisScale - Selects scale options for an axis.
  1303.   *
  1304.   *  Params: pat - pointer to axistype variable
  1305.   */
  1306.  void AxisScale( axistype *pat )
  1307.  {
  1308.      int iChoice;
  1309.  
  1310.      PushTitle( pszAuto[0] );
  1311.      iChoice = Menu( pszAuto );
  1312.      switch( iChoice )
  1313.      {
  1314.  
  1315.          case 1:
  1316.              /* Set AutoScale flag.  */
  1317.              pat->autoscale = TRUE;
  1318.              break;
  1319.  
  1320.          case 2:
  1321.  
  1322.              /* Clear AutoScale flag and get scale options.  */
  1323.              pat->autoscale = FALSE;
  1324.              PushTitle( pszScale[0] );
  1325.              while( (iChoice = Menu( pszScale )) != ESCAPE )
  1326.              {
  1327.  
  1328.                  switch( iChoice )
  1329.                  {
  1330.  
  1331.                      case 1:
  1332.                          /* Query for scale minimum.  */
  1333.                          Help( "Enter the range minimum value.", co.InputColor
  1334.                          pat->scalemin =
  1335.                              (float)InputInt( "Minimum? ",
  1336.                                               (int)pat->scalemin, 1, 0 );
  1337.                          break;
  1338.  
  1339.                      case 2:
  1340.                          /* Query for scale maximum.  */
  1341.                          Help( "Enter the range maximum value.", co.InputColor
  1342.                          pat->scalemin =
  1343.                              (float)InputInt( "Minimum? ",
  1344.                                               (int)pat->scalemin, 1, 0 );
  1345.                          break;
  1346.  
  1347.                      case 3:
  1348.                          /* Query for scale factor.  */
  1349.                          Help( "Enter scale factor (must be 1 or greater).",
  1350.                                   co.InputColor );
  1351.                          pat->scalefactor =
  1352.                              (float)InputInt( "Scale Factor? ",
  1353.                                               (int)pat->scalefactor, 1, 0 );
  1354.                          break;
  1355.  
  1356.                      case 4:
  1357.                          /* Modify scale title, then use menu to get
  1358.                           * title options.
  1359.                           */
  1360.                          pszTitleOpt[0] = "Scale Title";
  1361.                          TitleOpt( &pat->scaletitle );
  1362.  
  1363.                  }
  1364.              }
  1365.              PopTitle();
  1366.      }
  1367.      PopTitle();
  1368.  }
  1369.  
  1370.  /*  AxisTics - Selects tic options for an axis.
  1371.   *
  1372.   *  Params: pat - pointer to axistype variable
  1373.   */
  1374.  void AxisTics( axistype *pat )
  1375.  {
  1376.      int iChoice;
  1377.  
  1378.      PushTitle( pszTic[0] );
  1379.      while( (iChoice = Menu( pszTic )) != ESCAPE )
  1380.      {
  1381.          switch( iChoice )
  1382.          {
  1383.  
  1384.              case 1:
  1385.                  /* Query for tic interval.  */
  1386.                  Help( "Enter distance in data units.", co.InputColor );
  1387.                  pat->ticinterval =
  1388.                      InputFloat( "Distance between tic marks? ",
  1389.                                 pat->ticinterval );
  1390.                  pat->autoscale = FALSE;
  1391.                  break;
  1392.  
  1393.              case 2:
  1394.                  /* Query for tic format.  */
  1395.                  iChoice = BlankMenu( "Tic Format", "Normal", "Log" );
  1396.                  if( iChoice != ESCAPE )
  1397.                      pat->ticformat = iChoice;
  1398.                  break;
  1399.  
  1400.              case 3:
  1401.                  /* Query for number of decimal places per tic.  */
  1402.                  pat->ticdecimals =
  1403.                      InputInt( "Enter decimal places (0 to 9). ",
  1404.                                 pat->ticdecimals, 0, 9 );
  1405.                  pat->autoscale = FALSE;
  1406.                  break;
  1407.          }
  1408.  
  1409.      }
  1410.      PopTitle();
  1411.  }
  1412.  
  1413.  /*  Border - Specifies border information for a window.
  1414.   *
  1415.   *  Params: pwt - Pointer to windowtype variable
  1416.   */
  1417.  void Border( windowtype *pwt )
  1418.  {
  1419.      int iChoice;
  1420.  
  1421.      /* Ask whether a border is wanted.  */
  1422.      iChoice = BlankMenu( "Border", "Border", "No Border" );
  1423.      switch( iChoice )
  1424.      {
  1425.  
  1426.          case 1:
  1427.  
  1428.              /* If border, set Border flag and query for border options.  */
  1429.              pwt->border= TRUE;
  1430.              PushTitle( pszBorder[0] );
  1431.              while( (iChoice = Menu( pszBorder )) != ESCAPE )
  1432.              {
  1433.                  switch( iChoice )
  1434.                  {
  1435.                      case 1:
  1436.                          /* Query for border color.  */
  1437.                          Help( "Enter a color in the range 0-15.",
  1438.                              co.InputColor );
  1439.                          pwt->bordercolor =
  1440.                              InputInt( "Border color? ",
  1441.                                         pwt->bordercolor, 0, 15 );
  1442.                          break;
  1443.  
  1444.                      case 2:
  1445.                          /* Query for border style.  */
  1446.                          Help( "Enter a style in the range 0-10.", co.InputCol
  1447.                          pwt->borderstyle =
  1448.                              InputInt( "Border style? ",
  1449.                                         pwt->borderstyle, 0, 10 );
  1450.                  }
  1451.              }
  1452.              PopTitle();
  1453.              break;
  1454.  
  1455.          case 2:
  1456.              /* If no border, clear Border flag.  */
  1457.              pwt->border= FALSE;
  1458.      }
  1459.      PopTitle();
  1460.  }
  1461.  
  1462.  /*  ChangeTypeface - Allow the user to specify a new type face.
  1463.   *
  1464.   *  Params: iFaceIndex - index of last typeface
  1465.   *
  1466.   *  Return: index of new typeface
  1467.   */
  1468.  
  1469.  int ChangeTypeface( int iFaceIndex )
  1470.  {
  1471.      int iChoice;
  1472.  
  1473.      /* Get menu choice and call appropriate axis Menu. */
  1474.      PushTitle( pszFontOpt[0] );
  1475.      Help( "Choose one of the type faces listed.", co.InputColor );
  1476.  
  1477.      if( (iChoice = Menu( pszTypeface ) - 1) != ESCAPE )
  1478.      {
  1479.          /* If the user wants the system font, unregister the other fonts. */
  1480.          if( iChoice == NOFONT )
  1481.              _unregisterfonts();
  1482.  
  1483.          /* If the user wants any font but the system font, make sure the
  1484.           *   fonts are registered.
  1485.           */
  1486.          else
  1487.          {
  1488.              /* If last face was NOFONT, register fonts. */
  1489.              if( iFaceIndex == NOFONT )
  1490.              {
  1491.                  /* Assumes font files are in current directory.
  1492.                   * Could be enhanced to handle any directory.
  1493.                   */
  1494.                  if( _registerfonts( "*.FON" ) < 0 )
  1495.                      ErrorMsg( "Font files must be in current directory" );
  1496.                  else
  1497.                      iFaceIndex = iChoice;
  1498.              }
  1499.              else
  1500.                  iFaceIndex = iChoice;
  1501.          }
  1502.      }
  1503.  
  1504.      PopTitle();
  1505.      return iFaceIndex;
  1506.  }
  1507.  
  1508.  /*  ChooseFont - Chooses a font from the font library.
  1509.   *
  1510.   *  Params: WhichFont - A member of the set [COURIER, HELV, TMS_RMN,
  1511.   *                        MODERN, SCRIPT, ROMAN, NOFONT]
  1512.   *          Height    - The desired height of the text (in pixels)
  1513.   */
  1514.  
  1515.  void ChooseFont( int WhichFont, int Height )
  1516.  {
  1517.      static char *FontIds[] =
  1518.      {
  1519.          "courier", "helv", "tms rmn", "modern", "script", "roman"
  1520.      };
  1521.      char SetCommand[30];
  1522.  
  1523.      /* Construct the command to send to _setfont. */
  1524.      sprintf( SetCommand, "t'%s'h%dw0b", FontIds[WhichFont], Height );
  1525.  
  1526.      if( _setfont( SetCommand ) < 0 )
  1527.      {
  1528.          _outtext( "Could not set. Try different font or size" );
  1529.          getch();
  1530.      }
  1531.  }
  1532.  
  1533.  /*  ChartWindow - Gets chart window information.
  1534.   *
  1535.   *  Params: None
  1536.   */
  1537.  void ChartWindow()
  1538.  {
  1539.      int iChoice;
  1540.  
  1541.      PushTitle( pszChartWindow[0] );
  1542.      while( (iChoice = Menu( pszChartWindow )) != ESCAPE )
  1543.      {
  1544.  
  1545.          /* Get window options.  */
  1546.          switch( iChoice )
  1547.          {
  1548.  
  1549.              case 1:
  1550.                  /* Get window size.  */
  1551.                  WindowSize( &ce.chartwindow );
  1552.                  break;
  1553.  
  1554.              case 2:
  1555.                  /* Query for background color.  */
  1556.                  Help( "Enter a number in the range 0-15", co.InputColor );
  1557.                  ce.chartwindow.background =
  1558.                      InputInt( "Background Color? ", ce.chartwindow.background
  1559.                                0, 15 );
  1560.                  break;
  1561.  
  1562.              case 3:
  1563.  
  1564.                  /* Get border options.  */
  1565.                  Border( &ce.chartwindow );
  1566.  
  1567.          }
  1568.      }
  1569.      PopTitle();
  1570.  }
  1571.  
  1572.  /*  DataWindow - Geta data window information.
  1573.   *
  1574.   *  Params: None
  1575.   */
  1576.  void DataWindow()
  1577.  {
  1578.      int iChoice;
  1579.  
  1580.      PushTitle( pszDataWindow[0] );
  1581.      while( (iChoice = Menu( pszDataWindow )) != ESCAPE )
  1582.      {
  1583.  
  1584.          /* Get data window menu options.  */
  1585.          switch( iChoice )
  1586.          {
  1587.  
  1588.              case 1:
  1589.                  /* Query for background color.  */
  1590.                  Help( "Enter a number in the range 0-15", co.InputColor );
  1591.                  ce.datawindow.background =
  1592.                      InputInt( "Background Color? ",
  1593.                                 ce.datawindow.background,
  1594.                                 0, 15 );
  1595.                  break;
  1596.  
  1597.              case 2:
  1598.                  /* Get border options.  */
  1599.                  Border( &ce.datawindow );
  1600.                  break;
  1601.  
  1602.          }
  1603.      }
  1604.      PopTitle();
  1605.  }
  1606.  
  1607.  /*  FontOptions - Allows the user to modify the font used for display.
  1608.   *
  1609.   *  Params: None
  1610.   */
  1611.  
  1612.  void FontOptions()
  1613.  {
  1614.      int iChoice;
  1615.      static int iFaceIndex = NOFONT;
  1616.      static int iTypeSize = 8;
  1617.  
  1618.      /* Get menu choice and call appropriate axis Menu. */
  1619.      PushTitle( pszFontOpt[0] );
  1620.  
  1621.      while( (iChoice = Menu( pszFontOpt )) != ESCAPE )
  1622.      {
  1623.          switch( iChoice )
  1624.          {
  1625.              /* Change Typeface. */
  1626.              case 1:
  1627.                  iFaceIndex = ChangeTypeface( iFaceIndex );
  1628.                  ChooseFont( iFaceIndex, iTypeSize );
  1629.                  break;
  1630.  
  1631.              /* Change Type Size. */
  1632.              case 2:
  1633.  
  1634.                  if( iFaceIndex == NOFONT )
  1635.                  {
  1636.                      ErrorMsg( "Select a font first" );
  1637.                      break;
  1638.                  }
  1639.  
  1640.                  iTypeSize = InputInt( "Enter a type size. ", iTypeSize,
  1641.                                         8, 128 );
  1642.  
  1643.                  ChooseFont( iFaceIndex, iTypeSize );
  1644.                  break;
  1645.  
  1646.              default:
  1647.                  break;
  1648.          }
  1649.      }
  1650.      PopTitle();
  1651.  }
  1652.  
  1653.  /*  Justify - Gets title justification option.
  1654.   *
  1655.   *  Params: Pointer to titletype variable
  1656.   */
  1657.  void Justify( titletype *ptt )
  1658.  {
  1659.      int iChoice;
  1660.  
  1661.      PushTitle( pszJustify[0] );
  1662.      iChoice = Menu( pszJustify );
  1663.      switch( iChoice )
  1664.      {
  1665.  
  1666.          /* Set justification.  */
  1667.          case 1:
  1668.          case 2:
  1669.          case 3:
  1670.              ptt->justify = iChoice;
  1671.      }
  1672.      PopTitle();
  1673.  }
  1674.  
  1675.  /*  Legend - Asks whether a legend is desired, and if so, gets
  1676.   *  legend options.
  1677.   *
  1678.   *  Params: None
  1679.   */
  1680.  void Legend()
  1681.  {
  1682.      int iChoice;
  1683.  
  1684.      /* Is legend desired?  */
  1685.      iChoice = BlankMenu( "Legend", "Legend", "No Legend" );
  1686.      switch( iChoice )
  1687.      {
  1688.          case 1:
  1689.              /* If legend, set legend flag and get options.  */
  1690.              ce.legend.legend = TRUE;
  1691.              PushTitle( pszLegendWindow[0] );
  1692.              do
  1693.              {
  1694.                  iChoice = Menu( pszLegendWindow );
  1695.                  switch( iChoice )
  1696.                  {
  1697.  
  1698.                      case 1:
  1699.                          /* Get legend place.  */
  1700.                          LegendPlace();
  1701.                          break;
  1702.  
  1703.                      case 2:
  1704.                          /* Query for legend color.  */
  1705.                          Help( "Enter a number in the range 0-15.", co.InputCo
  1706.                          ce.legend.textcolor =
  1707.                              InputInt( "Text color? ",
  1708.                                         ce.legend.textcolor,
  1709.                                         0, 15 );
  1710.                          break;
  1711.  
  1712.                      case 3:
  1713.                          /* Get auto or manual sizing.  */
  1714.                          PushTitle( "Auto Legend" );
  1715.                          iChoice = Menu( pszAuto );
  1716.  
  1717.                          /* Set or clear the autosize flag. If manual
  1718.                           * sizing was selected, get legend size.
  1719.                           */
  1720.                          switch( iChoice )
  1721.                          {
  1722.                              case 1:
  1723.                                  ce.legend.autosize = TRUE;
  1724.                                  break;
  1725.  
  1726.                              case 2:
  1727.                                  ce.legend.autosize = FALSE;
  1728.                                  WindowSize( &ce.legend.legendwindow );
  1729.                          }
  1730.                          PopTitle();
  1731.                          break;
  1732.  
  1733.                      case 4:
  1734.                          /* Query for background color.  */
  1735.                          Help( "Type a number in the range 0-15.", co.InputCol
  1736.                          ce.legend.legendwindow.background =
  1737.                              InputInt( "Background color? ",
  1738.                                         ce.legend.legendwindow.background,
  1739.                                         0, 15 );
  1740.                          break;
  1741.  
  1742.                      case 5:
  1743.                          /* Get border options for legend window.  */
  1744.                          Border( &ce.legend.legendwindow );
  1745.                  }
  1746.  
  1747.              } while( iChoice != ESCAPE );
  1748.              PopTitle();
  1749.              break;
  1750.  
  1751.          case 2:
  1752.              /* If no legend wanted, clear flag.  */
  1753.              ce.legend.legend = FALSE;
  1754.  
  1755.      }
  1756.      PopTitle();
  1757.  }
  1758.  
  1759.  /*  LegendPlace - Gets legend placement option.
  1760.   *
  1761.   *  Params: None
  1762.   */
  1763.  void LegendPlace()
  1764.  {
  1765.      int iChoice;
  1766.  
  1767.      /* Get legend placement.  */
  1768.      PushTitle( pszPlace[0] );
  1769.      iChoice = Menu( pszPlace );
  1770.      switch( iChoice )
  1771.      {
  1772.  
  1773.          case 1:
  1774.              ce.legend.place = _PG_RIGHT;
  1775.              break;
  1776.  
  1777.          case 2:
  1778.              ce.legend.place = _PG_BOTTOM;
  1779.              break;
  1780.  
  1781.          case 3:
  1782.              ce.legend.place = _PG_OVERLAY;
  1783.      }
  1784.      PopTitle();
  1785.  }
  1786.  
  1787.  /*  ScreenMode - Gets a new screen mode.
  1788.   *
  1789.   *  Params: None
  1790.   */
  1791.  void ScreenMode()
  1792.  {
  1793.      int iMode, i;
  1794.      char szTmp[80], szHlp[80];
  1795.      static int iLegal[5][11] =
  1796.      {
  1797.          { 3, 4, 5, 6 },
  1798.          { 4, 4, 5, 6, 64 },
  1799.          { 4, 4, 5, 6, 19 },
  1800.          { 7, 4, 5, 6, 13, 14, 15, 16 },
  1801.          { 10, 4, 5, 6, 13, 14, 15, 16, 17, 18, 19 }
  1802.      };
  1803.      int iAdaptor;
  1804.  
  1805.      PushTitle( "Screen Mode" );
  1806.  
  1807.      /* Show appropriate help line for adaptor.  */
  1808.      switch( vc.adapter )
  1809.      {
  1810.          case _HGC:
  1811.              PopTitle();
  1812.              return;
  1813.          case _CGA:
  1814.              iAdaptor = 0;
  1815.              break;
  1816.          case _OCGA:
  1817.              iAdaptor = 1;
  1818.              break;
  1819.          case _MCGA:
  1820.              iAdaptor = 2;
  1821.              break;
  1822.          case _EGA:
  1823.          case _OEGA:
  1824.              if( vc.adapter == _MONO )
  1825.              {
  1826.                  PopTitle();
  1827.                  return;
  1828.              }
  1829.              else
  1830.                  iAdaptor = 3;
  1831.              break;
  1832.          case _VGA:
  1833.          case _OVGA:
  1834.              iAdaptor = 4;
  1835.              break;
  1836.      }
  1837.  
  1838.      /* Form the help line (which gives the choices legal for
  1839.       * the adaptor sensed in the user's machine).
  1840.       */
  1841.      for( iMode = 0, szHlp[0] = '\0'; iMode <= iLegal[iAdaptor][0]; ++iMode )
  1842.      {
  1843.          if( iMode == 0 )
  1844.              strcpy( szTmp, "Enter " );
  1845.          else if( iMode < iLegal[iAdaptor][0] )
  1846.              sprintf( szTmp, "%d, ", iLegal[iAdaptor][iMode] );
  1847.          else
  1848.              sprintf( szTmp, "or %d", iLegal[iAdaptor][iMode] );
  1849.          strcat( szHlp, szTmp );
  1850.      }
  1851.  
  1852.      WrtForm( 18 );
  1853.      Help( szHlp, co.InputColor );
  1854.  
  1855.      /* Query for screen mode. */
  1856.      for( ;; )
  1857.      {
  1858.          iMode = InputInt( "Screen Mode? ", si.mode, 1, 64 );
  1859.          for( i = 1; i <= iLegal[iAdaptor][0]; ++i ) /* Test legal values    *
  1860.              if( iMode == iLegal[iAdaptor][i] )      /* If a match is found  *
  1861.                  break;                              /* Terminate for loop   *
  1862.          if( iMode == iLegal[iAdaptor][i] )          /* If it's a match,     *
  1863.              break;                                  /* terminate do loop,   *
  1864.          else                                        /* otherwise BEEP, and  *
  1865.              putchar( BEEP );                        /* solicit correct data *
  1866.      }
  1867.  
  1868.      PopTitle();
  1869.      if( SetGraphMode( iMode ) )
  1870.          _setvideomode( _DEFAULTMODE );
  1871.      else
  1872.          ShowError( _PG_BADSCREENMODE );
  1873.  
  1874.      /* Force rescaling of the chart by resetting the window
  1875.       * rectangles for the chart and data windows to zero size.
  1876.       */
  1877.      ce.chartwindow.x1 = ce.chartwindow.x2 = ce.chartwindow.y1 =
  1878.          ce.chartwindow.y2 = 0;
  1879.      ce.datawindow = ce.chartwindow;
  1880.  }
  1881.  
  1882.  /*  TitleOpt - Gets title options.
  1883.   *
  1884.   *  Params: ptt - Pointer to titletype variable
  1885.   */
  1886.  void TitleOpt( titletype *ptt )
  1887.  {
  1888.      int iChoice;
  1889.  
  1890.      PushTitle( pszTitleOpt[0] );
  1891.      do
  1892.      {
  1893.          iChoice = Menu( pszTitleOpt );
  1894.          switch( iChoice )
  1895.          {
  1896.  
  1897.              case 1:
  1898.                  /* Query for title text.  */
  1899.                  Help( "70 characters maximum length.", co.InputColor );
  1900.                  InputStr( "Enter Text: ", ptt->title );
  1901.                  break;
  1902.  
  1903.              case 2:
  1904.                  /* Query for title color color.  */
  1905.                  Help( "Enter a number in the range 0-15.", co.InputColor );
  1906.                  ptt->titlecolor =
  1907.                      InputInt( "Title Color? ", ptt->titlecolor, 0, 15 );
  1908.                  break;
  1909.  
  1910.              case 3:
  1911.                  /* Get justify option.  */
  1912.                  Justify( ptt );
  1913.          }
  1914.          ClrHelp();
  1915.  
  1916.      } while( iChoice != ESCAPE );
  1917.      PopTitle();
  1918.  }
  1919.  
  1920.  /*  Titles - Manages Main and Sub title menus.
  1921.   *
  1922.   *  Params: None
  1923.   */
  1924.  void Titles()
  1925.  {
  1926.      int iChoice;
  1927.  
  1928.      PushTitle( pszTitles[0] );
  1929.      do
  1930.      {
  1931.          iChoice = Menu( pszTitles );
  1932.          switch( iChoice )
  1933.          {
  1934.  
  1935.              case 1:
  1936.                  /* Fix menu title and get options for main title.  */
  1937.                  pszTitleOpt[0] = "MainTitle";
  1938.                  TitleOpt( &ce.maintitle );
  1939.                  break;
  1940.  
  1941.              case 2:
  1942.                  /* Fix menu title and get options for subtitle.  */
  1943.                  pszTitleOpt[0] = "Sub Title";
  1944.                  TitleOpt( &ce.subtitle );
  1945.          }
  1946.      } while( iChoice != ESCAPE );
  1947.      PopTitle();
  1948.  }
  1949.  
  1950.  /*  Windows - Selects chart or data window, and gets options for either.
  1951.   *
  1952.   *  Params: None
  1953.   */
  1954.  void Windows()
  1955.  {
  1956.      int iChoice;
  1957.  
  1958.      PushTitle( pszWindows[0] );
  1959.      do
  1960.      {
  1961.  
  1962.          /* Select window and get options for it.  */
  1963.          iChoice = Menu( pszWindows );
  1964.          switch( iChoice )
  1965.          {
  1966.  
  1967.              case 1:
  1968.                  ChartWindow();
  1969.                  break;
  1970.  
  1971.              case 2:
  1972.                  DataWindow();
  1973.  
  1974.          }
  1975.      } while( iChoice != ESCAPE );
  1976.      PopTitle();
  1977.  }
  1978.  
  1979.  /*  WindowSize - Gets coordinates for window location and size.
  1980.   *
  1981.   *  Params: pwt - pointer to windowtype variable
  1982.   */
  1983.  void WindowSize( windowtype *pwt )
  1984.  {
  1985.      int iChoice;
  1986.  
  1987.      /* Get window size settings.  */
  1988.      PushTitle( pszSize[0] );
  1989.      do
  1990.      {
  1991.          /* Query for top, bottom, left, or right of window.  */
  1992.          iChoice = Menu( pszSize );
  1993.          switch( iChoice )
  1994.          {
  1995.  
  1996.              case 1:
  1997.                  Help( "Enter window top in pixels.", co.InputColor );
  1998.                  pwt->y1 = InputInt( "Top? ", pwt->y1, 0, si.yMax );
  1999.                  break;
  2000.  
  2001.              case 2:
  2002.                  Help( "Enter window Left in pixels.", co.InputColor );
  2003.                  pwt->x1 = InputInt( "Left? ", pwt->x1, 0, si.xMax );
  2004.                  break;
  2005.  
  2006.              case 3:
  2007.                  Help( "Enter window bottom in pixels.", co.InputColor );
  2008.                  pwt->y2 = InputInt( "Bottom? ", pwt->y2, 0, si.yMax );
  2009.                  break;
  2010.  
  2011.              case 4:
  2012.                  Help( "Enter window right in pixels.", co.InputColor );
  2013.                  pwt->x2 = InputInt( "Right? ", pwt->x2, 0, si.xMax );
  2014.          }
  2015.      } while( iChoice != ESCAPE );
  2016.      PopTitle();
  2017.  }
  2018.  
  2019.  
  2020.  CHRTSUPT.C
  2021.  CD-ROM Disc Path:   \SAMPCODE\C\MSC60\CHRTSUPT.C
  2022.  
  2023.  #include <stdio.h>
  2024.  #include <stdlib.h>
  2025.  #include <stdarg.h>
  2026.  #include <string.h>
  2027.  #include <conio.h>
  2028.  #include <graph.h>
  2029.  #include <pgchart.h>
  2030.  #include "chrtdemo.h"
  2031.  
  2032.  /* Variables to manage menus.  */
  2033.  int cMenuLevel = 0;                 /* Current menu level   */
  2034.  char *szMenuTitles[10];             /* Stack of menu titles */
  2035.  
  2036.  char *pszBlankMenu[4];
  2037.  
  2038.  /* Variables used to track control and screen position.  */
  2039.  extern struct SCREENINFO si;
  2040.  
  2041.  /* Colors of menus and prompts. */
  2042.  extern struct tagColor co;
  2043.  
  2044.  /*  BlankMenu - Gets responses to two specified choices.
  2045.   *
  2046.   *  Params: pchTitle - Menu title string
  2047.   *          pchChoice1 - Selection 1 string
  2048.   *          pchChoice2 - Selection 2 string
  2049.   *
  2050.   *  Return: Number of choice, or ESCAPE
  2051.   */
  2052.  int BlankMenu( char *pchTitle, char *pchChoice1, char *pchChoice2 )
  2053.  {
  2054.      int iChoice;
  2055.  
  2056.      /* Initialize title and selections.  */
  2057.      pszBlankMenu[0] = pchTitle;
  2058.      pszBlankMenu[1] = pchChoice1;
  2059.      pszBlankMenu[2] = pchChoice2;
  2060.      pszBlankMenu[3] = "\0";
  2061.      PushTitle( pszBlankMenu[0]);
  2062.  
  2063.      while( TRUE )
  2064.      {
  2065.          /* Accept only first letter of either selection, or ESC.  */
  2066.          iChoice = Menu( pszBlankMenu );
  2067.          switch( iChoice )
  2068.          {
  2069.              case 1:
  2070.              case 2:
  2071.              case ESCAPE:
  2072.                  return iChoice;
  2073.          }
  2074.      }
  2075.  }
  2076.  
  2077.  /*  ClrForm - Clears the center of the screen form.
  2078.   *
  2079.   *  Params: None
  2080.   */
  2081.  void ClrForm()
  2082.  {
  2083.  
  2084.      /* Set partial screen window and clear it, then reset full screen.  */
  2085.      _settextwindow( si.top, 1, si.bot, 80 );
  2086.      _clearscreen( _GWINDOW );
  2087.      _settextwindow( 1, 1, 25, 80 );
  2088.  
  2089.  }
  2090.  
  2091.  /*  ClrHelp - Clears the current help line.
  2092.   *
  2093.   *  Params: None
  2094.   */
  2095.  void ClrHelp()
  2096.  {
  2097.      /* Decrement the help line counter and clear the line.  */
  2098.      _settextwindow( --si.help, 1, si.help, 80 );
  2099.      _clearscreen( _GWINDOW );
  2100.      _settextwindow( 1, 1, 25, 80 );
  2101.  }
  2102.  
  2103.  /*  ErrorMsg - Displays an error message.
  2104.   *
  2105.   *  Params: pchMsg - error message string
  2106.   */
  2107.  void ErrorMsg( char *pchMsg )
  2108.  {
  2109.  
  2110.      /* Beep, set error color, and display error message and continue prompt.
  2111.      putch( BEEP );
  2112.      Help( pchMsg, co.ErrorColor );
  2113.      Help( "Press any key to continue.", co.ErrorColor );
  2114.  
  2115.      /* Wait for keypress and clear help lines.  */
  2116.      getch();
  2117.      ClrHelp();
  2118.      ClrHelp();
  2119.  
  2120.  }
  2121.  
  2122.  /*  Help - Displays a help line on the screen.
  2123.   *
  2124.   *  Params: pchMsg - error message string
  2125.   *          sColor - color for message
  2126.   */
  2127.  void Help( char *pchMsg, short sColor )
  2128.  {
  2129.  
  2130.      struct rccoord rcCursor;
  2131.  
  2132.      /* Save current cursor position.  */
  2133.      rcCursor = _gettextposition();
  2134.  
  2135.      /* Print out help line and increment Helpline position variable.  */
  2136.      PrintAt( si.help++, 5, pchMsg, sColor );
  2137.  
  2138.      /* Restore cursor position.  */
  2139.      _settextposition( rcCursor.row, rcCursor.col );
  2140.  
  2141.  }
  2142.  
  2143.  /*  InputCh - Prompts for and returns a character of input.
  2144.   *
  2145.   *  Params: pchPrompt - Prompt string
  2146.   *          pchAccept - String of acceptable characters (case insensitive)
  2147.   *
  2148.   *  Return: Character entered
  2149.   */
  2150.  int InputCh( char *pchPrompt, char *pchAccept )
  2151.  {
  2152.      int chResponse;
  2153.  
  2154.      /* Display prompt.  */
  2155.      PrintAt( si.mid, 10, pchPrompt, co.InputColor );
  2156.  
  2157.      /* Loop until response is valid.  */
  2158.      while( TRUE )
  2159.      {
  2160.          chResponse = toupper( getch() );
  2161.  
  2162.          /* Display and return if acceptable character, or beep if not.  */
  2163.          if( *strchr( pchAccept, chResponse) )
  2164.          {
  2165.              _settextcolor( co.InfoColor );
  2166.              putch( chResponse );
  2167.              return chResponse;
  2168.          }
  2169.          else
  2170.              putch( BEEP );
  2171.      }
  2172.  }
  2173.  
  2174.  /*  InputInt - Prompts for and returns an integer value within a
  2175.   *  specified range.
  2176.   *
  2177.   *  Params: pchPrompt - Prompt string
  2178.   *          iOld - Previous value
  2179.   *          iMin - Minimum value of range
  2180.   *          iMax - Maximum value of range
  2181.   *
  2182.   *  Return: integer input by user
  2183.   */
  2184.  int InputInt( char *pchPrompt, int iOld, int iMin, int iMax )
  2185.  {
  2186.      int i;
  2187.      char szTmp[70];
  2188.  
  2189.      /* Prompt for a string input and convert to an integer until a
  2190.       * value in the specified range is given. Then return the value.
  2191.       */
  2192.      do
  2193.      {
  2194.          InputStr( pchPrompt, itoa( iOld, szTmp, 10) );
  2195.          i = atoi( szTmp );
  2196.      } while( !InRange( i, iMin, iMax) );
  2197.      return i;
  2198.  }
  2199.  
  2200.  /*  InputFloat - Prompts for and returns a float value.
  2201.   *
  2202.   *  Params: pchPrompt - Prompt string
  2203.   *          fOld - Previous value
  2204.   *
  2205.   *  Return: float input by user
  2206.   */
  2207.  float InputFloat( char *pchPrompt, float fOld )
  2208.  {
  2209.      char szTmp[70];
  2210.  
  2211.      /* Prompt for a string input and convert to a float. */
  2212.      sprintf( szTmp, "%f", fOld );
  2213.      InputStr( pchPrompt, szTmp );
  2214.      return (float)atof( szTmp );
  2215.  }
  2216.  
  2217.  /*  InputStr - Prompts for a string. Displays the previous string
  2218.   *  until the first character is given. Then replaces it with new
  2219.   *  entry.
  2220.   *
  2221.   *  Params: pchPrompt - Prompt string
  2222.   *          pchOld - Charater buffer containing previous string; it
  2223.   *            must be long enough to hold new string
  2224.   *
  2225.   *  Return: pointer to pchOld, which now contains new string
  2226.   */
  2227.  char *InputStr( char *pchPrompt, char *pchOld )
  2228.  {
  2229.      char szTmp[81];
  2230.      int x = 5, y = si.mid, ch;
  2231.  
  2232.      /* Display prompt in center of form.  */
  2233.      ClrForm();
  2234.      PrintAt( y, x, pchPrompt, co.InputColor );
  2235.      x += strlen( pchPrompt );
  2236.  
  2237.      /* Print the old value for reference.  */
  2238.      _outtext( pchOld );
  2239.      _settextposition( y, x );
  2240.  
  2241.      /* Wait for input. When received, clear old string.  */
  2242.      while( !(ch = kbhit()) )
  2243.          ;
  2244.      memset( szTmp, ' ', 80 );
  2245.      szTmp[80] = '\0';
  2246.      PrintAt( y, x, szTmp, -1 );
  2247.  
  2248.      /* Get new string. If string entered, return it. If null string
  2249.       * (ENTER key pressed), return old value.
  2250.       */
  2251.      _settextcolor( co.InfoColor );
  2252.      _settextposition( y, x );
  2253.      szTmp[0] = 70;             /* Maximum length to be read */
  2254.  
  2255.      cgets( szTmp );
  2256.      if( szTmp[1] > 0 )         /* Are any characters read?  */
  2257.      {
  2258.          strcpy( pchOld, &szTmp[2] );
  2259.          return &szTmp[2];
  2260.      }
  2261.      else
  2262.      {
  2263.          _settextposition( y, x );
  2264.          return pchOld;
  2265.      }
  2266.  }
  2267.  
  2268.  /*  InRange - Checks an integer to see if it is in a specified range.
  2269.   *
  2270.   *  Params: iValue - Integer to check
  2271.   *          iMin - Minimum value of range
  2272.   *          iMax - Maximim value of range
  2273.   *
  2274.   *  Return: TRUE if in range, FALSE if not
  2275.   */
  2276.  BOOL InRange( int Value, int iMin, int iMax )
  2277.  {
  2278.      /* Check range and return true if valid, false if not. Note that
  2279.       * (iMin >= iMax) is taken as a signal to check only the minimum
  2280.       * value; there is no maximum.
  2281.       */
  2282.      if( Value >= iMin )
  2283.          if( (Value <= iMax) || (iMin >= iMax) )
  2284.              return TRUE;
  2285.      else
  2286.      {
  2287.          ErrorMsg( "Invalid value." );
  2288.          return FALSE;
  2289.      }
  2290.  }
  2291.  
  2292.  /*  Menu - Draws menu on screen and returns choice number.
  2293.   *
  2294.   *  Params: array of menu strings
  2295.   *
  2296.   *  Return: number corresponding to the choice made from the menu
  2297.   */
  2298.  int Menu( char *pszMenuList[] )
  2299.  {
  2300.      int iItem, cItem, yItem, x = 10;
  2301.      int chResponse;
  2302.  
  2303.      /* Count menu items.  */
  2304.      for( cItem = 1; *pszMenuList[cItem]; cItem++ )
  2305.          ;
  2306.      --cItem;
  2307.  
  2308.  
  2309.      /* Clear the form and print the items in the menu.  */
  2310.      WrtForm( 10 + cItem );
  2311.      for( iItem = 1, yItem = 8; iItem <= cItem; iItem++, yItem++ )
  2312.      {
  2313.          PrintAt( yItem, x, pszMenuList[iItem], co.InputColor );
  2314.          PrintChar( yItem, x, pszMenuList[iItem][0], co.HiliteColor );
  2315.      }
  2316.      ++yItem;
  2317.  
  2318.      /* Display prompt and help.  */
  2319.      if( strcmpi( pszMenuList[0], "main menu" ) )    /* If not the main menu *
  2320.          Help( "Type the first letter of your selection or ESC to back up.",
  2321.                    co.InputColor );
  2322.      else
  2323.          Help( "Type the first letter of your selection or \"Q\" to quit.",
  2324.                    co.InputColor );
  2325.  
  2326.      PrintAt( yItem, x += 5, "Choice? ", co.InfoColor );
  2327.      x += 8;
  2328.  
  2329.      /* Loop until a valid choice is made. Beep at invalid choices.  */
  2330.      while( TRUE )
  2331.      {
  2332.          _settextposition( yItem, x );
  2333.          chResponse = toupper( getch() );
  2334.  
  2335.          /* Back up for ESC.  */
  2336.          if( chResponse == 27 )
  2337.          {
  2338.              ClrHelp();
  2339.              return ESCAPE;
  2340.          }
  2341.  
  2342.          /* Search first letters of choices for a match. If found, return
  2343.           * choice and clear help line.
  2344.           */
  2345.          for( iItem = 1; iItem <= cItem; iItem++ )
  2346.          {
  2347.              if( chResponse == toupper( pszMenuList[iItem][0]) )
  2348.              {
  2349.                  putch( chResponse );
  2350.                  ClrHelp();
  2351.                  return iItem;
  2352.              }
  2353.          }
  2354.  
  2355.          /* If we get here, no valid choice was found, so beep and repeat.  */
  2356.          putch( BEEP );
  2357.      }
  2358.  }
  2359.  
  2360.  /*  PopTitle - Pops a menu title from the menu stack.
  2361.   *
  2362.   *  Params: None
  2363.   */
  2364.  void PopTitle()
  2365.  {
  2366.      szMenuTitles[--cMenuLevel] = "";
  2367.  }
  2368.  
  2369.  /*  PrintAt - Prints a string at the row/column coordinates
  2370.   *            specified, in the specified color.
  2371.   *
  2372.   *  Params: row        - row at which to begin output of string
  2373.   *          col        - column at which to begin output of string
  2374.   *          lpszString - zero (null) terminated string
  2375.   *          sColor     - color in which to output string (-1 if
  2376.   *                       PrintAt should leave color alone)
  2377.   */
  2378.  void PrintAt( int row, int column, char _far *lpszString, short sColor )
  2379.  {
  2380.      if( sColor != -1 )
  2381.          _settextcolor( sColor );
  2382.      _settextposition( row, column );
  2383.      _outtext( lpszString );
  2384.  }
  2385.  
  2386.  /*  PrintChar - Prints a character at the row/column coordinates
  2387.   *              specified, in the specified color.
  2388.   *
  2389.   *  Params: row        - row at which to begin output of string
  2390.   *          col        - column at which to begin output of string
  2391.   *          cChar      - character to print
  2392.   *          sColor     - color in which to output string (-1 if
  2393.   *                       PrintChar should leave color alone)
  2394.   */
  2395.  void PrintChar(int row, int column, char cChar, short sColor)
  2396.  {
  2397.      char szTiny[2];
  2398.  
  2399.      szTiny[0] = cChar;
  2400.      szTiny[1] = '\0';
  2401.      PrintAt( row, column, szTiny, sColor );
  2402.  }
  2403.  
  2404.  /*  PushTitle - Pushes a menu title on to the menu stack.
  2405.   *
  2406.   *  Params: pchTitle - title string to push
  2407.   */
  2408.  void PushTitle( char *pchTitle )
  2409.  {
  2410.      szMenuTitles[cMenuLevel++] = pchTitle;
  2411.  }
  2412.  
  2413.  /*  SetDisplayColors - Set the colors to values appropriate to the display
  2414.   *                     adaptor being used.
  2415.   *
  2416.   * Parms: None
  2417.   */
  2418.  void SetDisplayColors()
  2419.  {
  2420.      if( ismono( si.mode ) )
  2421.      {
  2422.          co.InputColor  = M_INPUTCOLOR;
  2423.          co.HiliteColor = M_HILITECOLOR;
  2424.          co.FormColor   = M_FORMCOLOR;
  2425.          co.TitleColor  = M_TITLECOLOR;
  2426.          co.ErrorColor  = M_ERRORCOLOR;
  2427.          co.InfoColor   = M_INFOCOLOR;
  2428.      }
  2429.      else
  2430.      {
  2431.          co.InputColor  = C_INPUTCOLOR;
  2432.          co.HiliteColor = C_HILITECOLOR;
  2433.          co.FormColor   = C_FORMCOLOR;
  2434.          co.TitleColor  = C_TITLECOLOR;
  2435.          co.ErrorColor  = C_ERRORCOLOR;
  2436.          co.InfoColor   = C_INFOCOLOR;
  2437.      }
  2438.  }
  2439.  
  2440.  /*  SprintAt - Format a string, using sprintf() and output to screen
  2441.   *             using PrintAt.
  2442.   *
  2443.   *  Parms: iRow  - Row at which to begin display
  2444.   *         iCol  - Column at which to begin display
  2445.   *         szFmt - Format string (see run-time library documentation for
  2446.   *                 correct formation of a format string)
  2447.   *         ...   - Variables to output
  2448.   */
  2449.  void SprintAt( int iRow, int iCol, char * szFmt, ... )
  2450.  {
  2451.      char szTmp[81];
  2452.      va_list Marker;
  2453.      va_list saveMarker;
  2454.  
  2455.      va_start( Marker, szFmt );
  2456.      saveMarker = Marker;
  2457.      vsprintf( szTmp, szFmt, Marker );
  2458.      va_end( Marker );
  2459.  
  2460.      PrintAt( iRow, iCol, szTmp, -1 );
  2461.  }
  2462.  
  2463.  /*  WrtForm - Displays screen form.
  2464.   *
  2465.   *  Params: yBot - Row number of the bottom row
  2466.   */
  2467.  void WrtForm( int yBot )
  2468.  {
  2469.      int i;
  2470.      char szTmp[81];
  2471.  
  2472.      /* Print message in upper right.  */
  2473.      _clearscreen( _GCLEARSCREEN );
  2474.      PrintAt( 1, 55, "Presentation Graphics Demo", co.TitleColor );
  2475.  
  2476.      /* Clear the top separator line.  */
  2477.      memset( szTmp, ' ', 79 );
  2478.      szTmp[79] = 0;
  2479.  
  2480.      /* Display each level of the menu title.  */
  2481.      _settextposition( 5, 5 );
  2482.      for( i = 0; i < cMenuLevel; i++ )
  2483.      {
  2484.          if( i )
  2485.              _outtext( " - " );
  2486.          _outtext( szMenuTitles[i] );
  2487.      }
  2488.  
  2489.      /* Display the top separator line.  */
  2490.      memset( szTmp, 196, 80 );
  2491.      szTmp[80] = 0;
  2492.      PrintAt( 6, 1, szTmp, co.FormColor );
  2493.  
  2494.      /* Display the bottom separator line.  */
  2495.      PrintAt( yBot, 1, szTmp, co.FormColor );
  2496.  
  2497.      /* Set the global screen variables.  */
  2498.  
  2499.      si.help = yBot + 1;
  2500.      si.top = 7;
  2501.      si.bot = yBot - 1;
  2502.      si.mid = (si.top + si.bot) / 2;
  2503.  }
  2504.  
  2505.  
  2506.  GRDEMO.C
  2507.  CD-ROM Disc Path:   \SAMPCODE\C\MSC60\GRDEMO.C
  2508.  
  2509.  /* GRDEMO.C - Demonstrates capabilities of the Microsoft graphics library.
  2510.   * Uses MENU module to display menus. Uses TURTLE module for Turtle
  2511.   * graphics. This program runs only in DOS and requires GRAPHICS.LIB.
  2512.   */
  2513.  
  2514.  #include <graph.h>
  2515.  #include <math.h>
  2516.  #include <malloc.h>
  2517.  #include <stdlib.h>
  2518.  #include <stdio.h>
  2519.  #include <conio.h>
  2520.  #include <time.h>
  2521.  #include "turtle.h"
  2522.  #include "menu.h"
  2523.  
  2524.  /* Function prototypes */
  2525.  int  main( void );
  2526.  void Circles( void );
  2527.  void Sphere( void );
  2528.  int  Polygons( void );
  2529.  int  Spiral( int angle, double inc );
  2530.  int  InSpiral( double side, int angle, int inc );
  2531.  void Bug( void );
  2532.  void Adjust( void );
  2533.  void Diamond( double xy );
  2534.  
  2535.  /* Returns a random number between min and max, which must be in
  2536.   * integer range.
  2537.   */
  2538.  #define getrandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))
  2539.  
  2540.  /* Constants */
  2541.  #define PI      3.141593
  2542.  #define LASTATR 15
  2543.  #define NLASTATR 14
  2544.  
  2545.  /* Array and enum for main menu */
  2546.  ITEM mnuMain[] =
  2547.  {                    /* Highlight Char  Pos */
  2548.      { 0, "Quit"            },   /* Q     0  */
  2549.      { 0, "Circles"         },   /* C     0  */
  2550.      { 0, "Rotating Sphere" },   /* R     0  */
  2551.      { 0, "Tunnel"          },   /* T     0  */
  2552.      { 0, "Spiral"          },   /* S     0  */
  2553.      { 0, "Inverted Spiral" },   /* I     0  */
  2554.      { 0, "Bug"             },   /* B     0  */
  2555.      { 0, "Adjust Window"   },   /* A     0  */
  2556.      { 0, "Mode Change"     },   /* M     0  */
  2557.      { 0, ""                }
  2558.  };
  2559.  
  2560.  /* Define constants (0, 1, 2,...) for menu choices */
  2561.  enum CHOICES
  2562.  {
  2563.      QUIT, CIRCLES, SPHERE, TUNNEL, SPIRAL, INSPIRAL, BUG, ADJUST, CHANGE
  2564.  };
  2565.  
  2566.  /* Arrays of video mode menu items and of corresponding mode numbers.
  2567.   * Each has a temporary array containing all items, and a pointer version
  2568.   * including all except Olivetti.
  2569.   */
  2570.  ITEM mnuModesT[] =
  2571.  {                    /* Highlight Char  Pos */
  2572.      { 0, "ORESCOLOR "   },      /* O     0  */
  2573.      { 4, "MRES4COLOR "  },      /* 4     4  */
  2574.      { 4, "MRESNOCOLOR"  },      /* N     4  */
  2575.      { 4, "HRESBW"       },      /* B     4  */
  2576.      { 0, "MRES16COLOR"  },      /* M     0  */
  2577.      { 0, "HRES16COLOR"  },      /* H     0  */
  2578.      { 0, "ERESCOLOR"    },      /* E     0  */
  2579.      { 4, "VRES2COLOR"   },      /* 2     4  */
  2580.      { 0, "VRES16COLOR"  },      /* V     0  */
  2581.      { 1, "MRES256COLOR" },      /* R     4  */
  2582.      { 0, ""             }
  2583.  };
  2584.  ITEM *mnuModes = &mnuModesT[1];  /* Default is no Olivetti mode */
  2585.  
  2586.  int aModesT[] =
  2587.  {
  2588.      _ORESCOLOR,
  2589.      _MRES4COLOR,
  2590.      _MRESNOCOLOR,
  2591.      _HRESBW,
  2592.      _MRES16COLOR,
  2593.      _HRES16COLOR,
  2594.      _ERESCOLOR,
  2595.      _VRES2COLOR,
  2596.      _VRES16COLOR,
  2597.      _MRES256COLOR,
  2598.      _TEXTMONO,
  2599.      _ERESNOCOLOR,
  2600.      _HERCMONO
  2601.  };
  2602.  int *aModes = &aModesT[1];              /* Default is no Olivetti mode */
  2603.  
  2604.  /* Global video configuration */
  2605.  struct videoconfig vc;
  2606.  
  2607.  int main()
  2608.  {
  2609.      int rowMid, colMid;
  2610.      int fColor, fFirstTime = TRUE;
  2611.      int iMode, iMainCur = 0, iModesCur = 0;
  2612.  
  2613.      _displaycursor( _GCURSOROFF );
  2614.      _getvideoconfig( &vc );
  2615.      rowMid = vc.numtextrows / 2;
  2616.      colMid = vc.numtextcols / 2;
  2617.  
  2618.      /* Select best graphics mode, adjust menus, set color flag. Note
  2619.       * that this requires checking both the adapter and the mode.
  2620.       */
  2621.      switch( vc.adapter )
  2622.      {
  2623.          case _OCGA:
  2624.              mnuModes = &mnuModesT[0];           /* Turn on Olivetti mode */
  2625.              aModes = &aModesT[0];
  2626.          case _CGA:
  2627.              mnuModesT[4].achItem[0] = '\0';     /* Turn off EGA modes    */
  2628.              iMode = _MRES4COLOR;
  2629.              break;
  2630.          case _HGC:
  2631.              mnuModesT[7].achItem[0] = '\0';
  2632.              iMode = _HERCMONO;
  2633.              break;
  2634.          case _OEGA:
  2635.              mnuModes = &mnuModesT[0];           /* Turn on Olivetti mode */
  2636.              aModes = &aModesT[0];
  2637.          case _EGA:
  2638.              mnuModesT[7].achItem[0] = '\0';     /* Turn off VGA modes    */
  2639.              if( vc.memory > 64 )
  2640.                  iMode = _ERESCOLOR;
  2641.              else
  2642.                  iMode = _HRES16COLOR;
  2643.              break;
  2644.          case _OVGA:
  2645.              mnuModes = &mnuModesT[0];           /* Turn on Olivetti mode */
  2646.              aModes = &aModesT[0];
  2647.          case _VGA:
  2648.              iMode = _VRES16COLOR;
  2649.              break;
  2650.          case _MCGA:
  2651.              iMode = _MRES256COLOR;
  2652.              break;
  2653.          case _MDPA:
  2654.          default:
  2655.              puts( "No graphics mode available.\n" );
  2656.              return TRUE;
  2657.      }
  2658.      switch( vc.mode )
  2659.      {
  2660.          case _TEXTBW80:
  2661.          case _TEXTBW40:
  2662.              fColor = FALSE;
  2663.              break;
  2664.          case _TEXTMONO:
  2665.          case _ERESNOCOLOR:
  2666.          case _HERCMONO:
  2667.              fColor = FALSE;
  2668.              if( iMode != _HERCMONO )
  2669.                  iMode = _ERESNOCOLOR;
  2670.              mnuMain[8].achItem[0] = '\0';       /* Turn off mode change */
  2671.              break;
  2672.          default:
  2673.              fColor = TRUE;
  2674.              break;
  2675.      }
  2676.  
  2677.      /* Find current mode in mode array. */
  2678.      for( iModesCur = 0; aModes[iModesCur] != iMode; iModesCur++ )
  2679.          ;
  2680.  
  2681.      /* Seed randomizer with time. */
  2682.      srand( (unsigned)time( NULL ) );
  2683.  
  2684.      while( TRUE )
  2685.      {
  2686.          /* Set text mode and optionally clear the screen to blue. */
  2687.          _setvideomode(_DEFAULTMODE );
  2688.          if( fColor )
  2689.              _setbkcolor( (long)_TBLUE );
  2690.          _clearscreen( _GCLEARSCREEN );
  2691.  
  2692.          /* Select from menu. */
  2693.          iMainCur = Menu( rowMid, colMid, mnuMain, iMainCur );
  2694.  
  2695.          /* Set graphics mode and initialize turtle graphics. Put border
  2696.           * on window.
  2697.           */
  2698.          if( iMainCur != CHANGE )
  2699.          {
  2700.              _setvideomode( iMode );
  2701.              _displaycursor( _GCURSOROFF );
  2702.              _getvideoconfig( &vc );
  2703.              InitTurtle( &vc );
  2704.              Rectangle( 2 * tc.xMax, 2 * tc.yMax );
  2705.          }
  2706.  
  2707.          /* Branch to menu choice. */
  2708.          switch( iMainCur )
  2709.          {
  2710.              case QUIT:
  2711.                  _setvideomode( _DEFAULTMODE );
  2712.                  return FALSE;
  2713.              case CIRCLES:
  2714.                  Circles();
  2715.                  break;
  2716.              case SPHERE:
  2717.                  Sphere();
  2718.                  break;
  2719.              case TUNNEL:
  2720.                  PenDown( FALSE );
  2721.                  MoveTo( -tc.xMax * .2, tc.yMax * .15 );
  2722.                  PenDown( TRUE );
  2723.                  Polygons();
  2724.                  while( !GetKey( NO_WAIT ) )
  2725.                      NextColorValue( DEFAULT );   /* Rotate palette */
  2726.                  break;
  2727.              case SPIRAL:
  2728.                  if( Spiral( getrandom( 30, 80 ), (double)getrandom( 1, 5 ) )
  2729.                      break;
  2730.                  while( !GetKey( NO_WAIT ) )
  2731.                      NextColorValue( DEFAULT );
  2732.                  break;
  2733.              case INSPIRAL:
  2734.                  NextColorIndex( 0 );
  2735.                  if( InSpiral( (double)getrandom( 8, 20 ),
  2736.                                getrandom( 4, 22 ),
  2737.                                getrandom( 3, 31 ) ) )
  2738.                      break;
  2739.                  while( !GetKey( NO_WAIT ) )
  2740.                      NextColorValue( DEFAULT );
  2741.                  break;
  2742.              case BUG:
  2743.                  Bug();
  2744.                  break;
  2745.              case ADJUST:
  2746.                  Adjust();
  2747.                  continue;
  2748.              case CHANGE:
  2749.                  if( fColor )
  2750.                      _setbkcolor( (long)_TBLUE );
  2751.                  _clearscreen( _GCLEARSCREEN );
  2752.  
  2753.                  iModesCur = Menu( rowMid, colMid, mnuModes, iModesCur );
  2754.                  iMode = aModes[iModesCur];
  2755.                  if( vc.adapter == _MCGA )
  2756.                      switch( iMode )
  2757.                      {
  2758.                          case _MRES16COLOR:
  2759.                          case _HRES16COLOR:
  2760.                          case _ERESCOLOR:
  2761.                          case _VRES16COLOR:
  2762.                              _settextposition( 1, 22 );
  2763.                              _outtext( "Mode not recognized" );
  2764.                              iMode = _MRES256COLOR;
  2765.                      }
  2766.                  break;
  2767.          }
  2768.      }
  2769.  }
  2770.  
  2771.  /* Circles - Draw circles of varying sizes and colors on screen in a
  2772.   * round pattern.
  2773.   *
  2774.   * Params: None
  2775.   *
  2776.   * Return: None
  2777.   *
  2778.   * Uses:   tc
  2779.   */
  2780.  void Circles()
  2781.  {
  2782.      double x, y, xyRadius;
  2783.      int fFill, fPenDown;
  2784.  
  2785.      /* Initialize and save pen and fill flags. */
  2786.      if( tc.cci <= 4 )
  2787.          fFill = SetFill( FALSE );
  2788.      else
  2789.          fFill = SetFill( TRUE );
  2790.      fPenDown = PenDown( FALSE );
  2791.  
  2792.      while( TRUE )
  2793.      {
  2794.          /* Draw circles. */
  2795.          for( xyRadius = 10.0; xyRadius <= 130.0; xyRadius++ )
  2796.          {
  2797.              x = (tc.xMax - 30) * atan( sin( xyRadius / PI ) );
  2798.              y = (tc.yMax - 30) * atan( cos( xyRadius / PI ) );
  2799.              MoveTo( x, y );
  2800.              PenColor( NextColorIndex( DEFAULT ) );
  2801.              Circle( xyRadius );
  2802.              if( GetKey( NO_WAIT ) )
  2803.              {
  2804.                  PenDown( fPenDown );
  2805.                  SetFill( fFill );
  2806.                  return;
  2807.              }
  2808.          }
  2809.  
  2810.          /* For palette modes (except 256 color), start over. */
  2811.          if( tc.ccv == 64 || tc.ccv == 16 )
  2812.          {
  2813.              _clearscreen( _GCLEARSCREEN );
  2814.              SetFill( FALSE );
  2815.              MoveTo( 0.0, 0.0 );
  2816.              PenColor( WHITE );
  2817.              Rectangle( 2 * tc.xMax, 2 * tc.yMax );
  2818.              SetFill( fFill );
  2819.              NextColorValue( DEFAULT );
  2820.          }
  2821.      }
  2822.  }
  2823.  
  2824.  /* Sphere - Draw and fill slices of a sphere. Rotate colors in EGA+ modes
  2825.   * with more than 4 color indexes.
  2826.   *
  2827.   * Params: None
  2828.   *
  2829.   * Return: None
  2830.   *
  2831.   * Uses:   tc
  2832.   */
  2833.  void Sphere()
  2834.  {
  2835.      double xCur, xSize, ySize, xInc;
  2836.      short ciBorder, fFill;
  2837.  
  2838.      ySize = xSize = tc.yMax * 0.9 * 2;
  2839.      fFill = SetFill( FALSE );
  2840.      NextColorIndex( 0 );
  2841.      xInc = xSize / 14;
  2842.      ciBorder = PenColor( DEFAULT );
  2843.      BorderColor( ciBorder );
  2844.  
  2845.      /* Draw slices. */
  2846.      for( xCur = xInc; xCur <= xSize; xCur += xInc * 2 )
  2847.          Ellipse( xCur, ySize );
  2848.      SetFill( TRUE );
  2849.      PenDown( FALSE );
  2850.      Turn( 90 );
  2851.      xSize /= 2;
  2852.      MoveTo( xSize - xInc, 0.0 );
  2853.  
  2854.      NextColorValue( LIMITED );
  2855.  
  2856.      /* Fill slices. */
  2857.      while( tc.xCur >= (-xSize + xInc))
  2858.      {
  2859.          PenColor( NextColorIndex( DEFAULT ) );
  2860.          FillIn();
  2861.          Move( -xInc );
  2862.      }
  2863.  
  2864.      while( !GetKey( NO_WAIT ) )
  2865.          NextColorValue( LIMITED );
  2866.  
  2867.      PenDown( TRUE );
  2868.      SetFill( fFill );
  2869.  }
  2870.  
  2871.  /* Polygons - Draws polygons (starting with triangle) of increasing
  2872.   * size by incrementing the number of sides without changing the
  2873.   * length of sides. Make sure pen is down.
  2874.   *
  2875.   * Params: None
  2876.   *
  2877.   * Return: 1 for user interrupt, 0 for edge of screen encountered
  2878.   *
  2879.   * Uses:   tc
  2880.   */
  2881.  int Polygons()
  2882.  {
  2883.      int cSides = 3, atrib = 1;
  2884.      double dxy = tc.yUnit;
  2885.  
  2886.      while( TRUE )
  2887.      {
  2888.          PenColor( NextColorIndex( DEFAULT ) );
  2889.          if( !Poly( cSides++, dxy += 1.5 ) )
  2890.              return FALSE;
  2891.          if( GetKey( NO_WAIT ) )
  2892.              return TRUE;
  2893.      }
  2894.  }
  2895.  
  2896.  /* Spiral - Draw a spiral by incrementing the length of each side
  2897.   * of a rotating figure.
  2898.   *
  2899.   * Params: ang - determines tightness
  2900.   *         xyInc - determines size of sides
  2901.   *
  2902.   * Return: 1 for user interrupt, 0 for edge of screen encountered
  2903.   *
  2904.   * Uses:   tc
  2905.   */
  2906.  int Spiral( int ang, double xyInc )
  2907.  {
  2908.      double xy = tc.yUnit;
  2909.  
  2910.      while( TRUE )
  2911.      {
  2912.          PenColor( NextColorIndex( DEFAULT ) );
  2913.          if( !Move( xy += xyInc ) )
  2914.              return FALSE;
  2915.          Turn( ang );
  2916.          if( GetKey( NO_WAIT ) )
  2917.              return TRUE;
  2918.      }
  2919.  }
  2920.  
  2921.  /* InSpiral - Draw an inverted spiral by increasing each angle
  2922.   * of a rotating figure while keeping the length of sides constant.
  2923.   *
  2924.   * Params: xy - determines size
  2925.   *         ang - initial angle determines shape
  2926.   *         angInc - determines tightness and shape
  2927.   *
  2928.   * Return: 1 for user interrupt, 0 for edge of screen encountered
  2929.   */
  2930.  int InSpiral( double xy, int ang, int angInc )
  2931.  {
  2932.      while( TRUE )
  2933.      {
  2934.          PenColor( NextColorIndex( DEFAULT ) );
  2935.          if( !Move( xy ) )
  2936.              return FALSE;
  2937.          Turn( ang += angInc );
  2938.          if( GetKey( NO_WAIT ))
  2939.              return TRUE;
  2940.      }
  2941.  }
  2942.  
  2943.  /* Bug - Draws a winged bug on the screen. Then moves it randomly
  2944.   * around the screen.
  2945.   *
  2946.   * Params: None
  2947.   *
  2948.   * Return: None
  2949.   *
  2950.   * Uses:   tc
  2951.   */
  2952.  void Bug()
  2953.  {
  2954.  
  2955.      static unsigned char uTopWing[] = { 0x81, 0x3c, 0xc3, 0x66,
  2956.                                          0x66, 0x0f, 0xf0, 0x18 };
  2957.      static unsigned char uBotWing[] = { 0x66, 0x0f, 0xf0, 0x18,
  2958.                                          0x81, 0x3c, 0xc3, 0x66 };
  2959.      char *buffer;               /* Buffer for image */
  2960.  
  2961.      /* Draw bug. */
  2962.      PenDown( FALSE );
  2963.      SetFill( TRUE );
  2964.      Move( 40.0 );               /* Draw and fill front wings */
  2965.      Turn( 90 );
  2966.      Move( 80.0 );
  2967.      PenColor( 1 );
  2968.      _setfillmask( uTopWing );
  2969.      Ellipse( 172.0, 70.0 );
  2970.      Turn( 180 );
  2971.      Move( 160.0 );
  2972.      Ellipse( 172.0, 70.0 );
  2973.      Turn(-90 );
  2974.      MoveTo( 0.0, 0.0 );
  2975.      Move( 25.0 );               /* Draw and fill back wings */
  2976.      Turn( 90 );
  2977.      Move( 70.0 );
  2978.      PenColor( 2 );
  2979.      _setfillmask( uBotWing );
  2980.      Ellipse( 150.0, 70.0 );
  2981.      Turn( 180 );
  2982.      Move( 140.0 );
  2983.      Ellipse( 150.0, 70.0 );
  2984.      Turn(-90 );
  2985.      MoveTo( 0.0, 0.0 );
  2986.      _setfillmask( NULL );       /* Draw body */
  2987.      PenColor( 3 );
  2988.      BorderColor( 3 );
  2989.      Ellipse( 52.0, 220.0 );
  2990.      PenColor( 1 );              /* Drill eyes */
  2991.      BorderColor( 1 );
  2992.      SetFill( FALSE );
  2993.      Move( 90.0 );
  2994.      Turn( 90 );
  2995.      Move( 22.0 );
  2996.      Circle( 20.0 );
  2997.      PenColor( 0 );
  2998.      FillIn();
  2999.      PenColor( 1 );
  3000.      Turn( 180 );
  3001.      Move( 44.0 );
  3002.      Circle( 20.0 );
  3003.      PenColor( 0 );
  3004.      FillIn();
  3005.  
  3006.      /* Move into position - top-right of image. */
  3007.      MoveTo( 0.0, 0.0 );
  3008.      TurnTo( 0 );
  3009.      Move( 120.0 );
  3010.      Turn( -90 );
  3011.      Move( 175.0 );
  3012.      Turn( 90 );
  3013.  
  3014.      /* Size image and allocate memory for it. */
  3015.      buffer = (char *)malloc( (size_t)ImageSize( 350.0, 240.0 ) );
  3016.      GetImage( 350.0, 240.0, buffer );
  3017.  
  3018.      /* Move randomly, adjusting at edges. */
  3019.      while( !GetKey( NO_WAIT ) )
  3020.      {
  3021.          if( tc.xCur <= (-tc.xMax + 15.0) )
  3022.              TurnTo( 90 );
  3023.          else if( tc.yCur <= (-tc.yMax + 15.0) )
  3024.              TurnTo( 180 );
  3025.          else if( tc.xCur >= (tc.xMax - 365.0) )
  3026.              TurnTo( 270 );
  3027.          else if( tc.yCur >= (tc.yMax - 255.0) )
  3028.              TurnTo( 0 );
  3029.          else
  3030.              Turn( getrandom( -20, 20 ) );
  3031.          Move( 3.0 );
  3032.          PutImage( buffer, _GPSET );
  3033.      }
  3034.      free( (char *)buffer );
  3035.  }
  3036.  
  3037.  /* Adjust - Allow the user to interactively adjust the display window.
  3038.   * Unshifted direction keys adjust the window size. Shifted direction
  3039.   * keys move the window. The numeric keypad plus and minus keys adjust
  3040.   * aspect without changing the window. A window frame and a diamond give
  3041.   * visual feedback on adjustments.
  3042.   *
  3043.   * Params: None
  3044.   *
  3045.   * Return: None
  3046.   *
  3047.   * Uses:   tc and vc
  3048.   */
  3049.  #define WININC 4
  3050.  void Adjust()
  3051.  {
  3052.      short iWriteMode;
  3053.      double xyRadius = 400.0, xEdge, yEdge;
  3054.      char achT[40];
  3055.  
  3056.      /* Display instructions. */
  3057.      _clearscreen( _GCLEARSCREEN );
  3058.      _settextposition( 2, 2 );
  3059.      _outtext(" Grey PLUS and MINUS Adjust aspect" );
  3060.      _settextposition( 3, 2 );
  3061.      _outtext(" Cursor keys         Size window" );
  3062.      _settextposition( 4, 2 );
  3063.      _outtext(" SHIFT cursor keys   Move window" );
  3064.      _settextposition( 5, 2 );
  3065.      _outtext(" ENTER               Finished" );
  3066.  
  3067.      /* Save old write mode and set XOR so you can erase figures by
  3068.       * redrawing. This allows lines to overwrite text without erasing.
  3069.       */
  3070.      iWriteMode = _getwritemode();
  3071.      _setwritemode( _GXOR );
  3072.  
  3073.      while( TRUE )
  3074.      {
  3075.          /* Display data. */
  3076.          _settextposition( 6, 2 );
  3077.          sprintf( achT, " ratio=%1.2f  xMax=%.f  yMax=%.f",
  3078.                   tc.yxRatio, tc.xMax, tc.yMax );
  3079.          _outtext( achT );
  3080.  
  3081.          /* Calculate current box edges. */
  3082.          xEdge = 2 * tc.xMax;
  3083.          yEdge = 2 * tc.yMax;
  3084.  
  3085.          /* Draw border rectangle and diamond that illustrates ratio. */
  3086.          Rectangle( xEdge, yEdge );
  3087.          Diamond( xyRadius );
  3088.  
  3089.          switch( GetKey( CLEAR_WAIT ) )
  3090.          {
  3091.              /* Adjust aspect. */
  3092.              case N_MINUS:
  3093.                  if( tc.yxRatio > 0.4 )
  3094.                      tc.yxRatio = (tc.xMax - (WININC * tc.yUnit)) / tc.yMax;
  3095.                  break;
  3096.  
  3097.              case N_PLUS:
  3098.                  if( tc.yxRatio < 8.0 )
  3099.                      tc.yxRatio = (tc.xMax + (WININC * tc.yUnit)) / tc.yMax;
  3100.                  break;
  3101.  
  3102.              /* Adjust window size. */
  3103.              case U_RT:
  3104.                  if( tc.xsLeft < (vc.numxpixels / 3) )
  3105.                      tc.xsLeft += WININC;
  3106.                  if( tc.xsRight > (vc.numxpixels - (vc.numxpixels / 3)) )
  3107.                      tc.xsRight -= WININC;
  3108.                  break;
  3109.              case U_LT:
  3110.                  if( tc.xsLeft )
  3111.                      tc.xsLeft -= WININC;
  3112.                  if( tc.xsRight < vc.numxpixels )
  3113.                      tc.xsRight += WININC;
  3114.                  break;
  3115.              case U_DN:
  3116.                  if( tc.ysTop < (vc.numypixels / 3) )
  3117.                      tc.ysTop += WININC;
  3118.                  if( tc.ysBot > (vc.numypixels - (vc.numypixels / 3)) )
  3119.                      tc.ysBot -= WININC;
  3120.                  break;
  3121.              case U_UP:
  3122.                  if( tc.ysTop )
  3123.                      tc.ysTop -= WININC;
  3124.                  if( tc.ysBot < vc.numypixels )
  3125.                      tc.ysBot += WININC;
  3126.                  break;
  3127.  
  3128.              /* Adjust window position. */
  3129.              case S_LT:
  3130.                  if( tc.xsLeft )
  3131.                  {
  3132.                      tc.xsLeft -= WININC;
  3133.                      tc.xsRight -= WININC;
  3134.                  }
  3135.                  break;
  3136.              case S_RT:
  3137.                  if( tc.xsRight < vc.numxpixels )
  3138.                  {
  3139.                      tc.xsLeft += WININC;
  3140.                      tc.xsRight += WININC;
  3141.                  }
  3142.                  break;
  3143.              case S_UP:
  3144.                  if( tc.ysTop )
  3145.                  {
  3146.                      tc.ysTop -= WININC;
  3147.                      tc.ysBot -= WININC;
  3148.                  }
  3149.                  break;
  3150.              case S_DN:
  3151.                  if( tc.ysBot < vc.numypixels )
  3152.                  {
  3153.                      tc.ysTop += WININC;
  3154.                      tc.ysBot += WININC;
  3155.                  }
  3156.                  break;
  3157.  
  3158.              /* Finished. */
  3159.              case ENTER:
  3160.                  _setwritemode( iWriteMode );
  3161.                  return;
  3162.  
  3163.              /* Ignore unknown key. */
  3164.              default:
  3165.                  break;
  3166.          }
  3167.          /* Redraw figures to erase them. Reset defaults. */
  3168.          Rectangle( xEdge, yEdge );
  3169.          Diamond( xyRadius );
  3170.          Home();
  3171.      }
  3172.  }
  3173.  
  3174.  /* Routine used by Adjust to draw its diamond. */
  3175.  void Diamond( double xy )
  3176.  {
  3177.          PenDown( FALSE );
  3178.          MoveTo( 0.0, xy );
  3179.          PenDown( TRUE );
  3180.          MoveTo( xy, 0.0 );
  3181.          MoveTo( 0.0, -xy );
  3182.          MoveTo( -xy, 0.0 );
  3183.          MoveTo( 0.0, xy );
  3184.          PenDown( FALSE );
  3185.          MoveTo( 0.0, 0.0 );
  3186.          PenDown( TRUE );
  3187.  }
  3188.  
  3189.  
  3190.  MENU.C
  3191.  CD-ROM Disc Path:   \SAMPCODE\C\MSC60\MENU.C
  3192.  
  3193.  /* MENU - Module of functions to put menus on the screen and handle keyboard
  3194.   * input. To use it, include the MENU.H file in your program. The following
  3195.   * functions are public:
  3196.   *
  3197.   *   Menu       -   Puts a menu on screen and reads input for it
  3198.   *   Box        -   Puts a box on screen (fill it yourself)
  3199.   *   GetKey     -   Gets ASCII or function key
  3200.   *   _outchar   -   Displays character using current text position and color
  3201.   *
  3202.   * The following structures are defined:
  3203.   *
  3204.   *   MENU       -   Defines menu colors, box type, and centering
  3205.   *   ITEM       -   Defines text of menu item and index of highlight characte
  3206.   *
  3207.   * The global variable "mnuAtrib" has type MENU. Change this variable to
  3208.   * change menu appearance.
  3209.   */
  3210.  
  3211.  #include <string.h>
  3212.  #include <stddef.h>
  3213.  #include <ctype.h>
  3214.  #include <graph.h>
  3215.  #include <bios.h>
  3216.  #include "menu.h"
  3217.  
  3218.  /* Prototype for internal function */
  3219.  static void Itemize( int row, int col, int fCur, ITEM itm, int cBlank );
  3220.  
  3221.  /* Default menu attribute. The default works for color or B&W. You can
  3222.   * override the default value by defining your own MENU variable and
  3223.   * assigning it to mnuAtrib, or you can modify specific fields at
  3224.   * run time. For example, you could use a different attribute for color
  3225.   * than for black and white.
  3226.   */
  3227.  MENU mnuAtrib =
  3228.  {
  3229.      _TBLACK, _TBLACK, _TWHITE, _TBRIGHTWHITE, _TBRIGHTWHITE,
  3230.      _TWHITE, _TWHITE, _TBLACK, _TWHITE, _TBLACK,
  3231.      TRUE,
  3232.      '┌', '┐', '┘', '└', '│', '─'
  3233.  };
  3234.  
  3235.  /* Menu - Puts menu on screen and reads menu input from keyboard. When a
  3236.   * highlighted hot key or ENTER is pressed, returns the index of the
  3237.   * selected menu item.
  3238.   *
  3239.   * Params: row and col - If "fCentered" attribute of "mnuAtrib" is true,
  3240.   *           center row and column of menu; otherwise top left of menu
  3241.   *         aItem - array of structure containing the text of each item
  3242.   *           and the index of the highlighted hot key
  3243.   *         iCur - index of the current selection--pass 0 for first item,
  3244.   *           or maintain a static value
  3245.   *
  3246.   * Return: The index of the selected item
  3247.   *
  3248.   * Uses:   mnuAtrib
  3249.   */
  3250.  int Menu( int row, int col, ITEM aItem[], int iCur )
  3251.  {
  3252.      int cItem, cchItem = 2; /* Counts of items and chars per item       */
  3253.      int i, iPrev;           /* Indexes - temporary and previous         */
  3254.      int acchItem[MAXITEM];  /* Array of counts of character in items    */
  3255.      char *pchT;             /* Temporary character pointer              */
  3256.      char achHilite[36];     /* Array for highlight characters           */
  3257.      unsigned uKey;          /* Unsigned key code                        */
  3258.      long bgColor;           /* Screen color, position, and cursor       */
  3259.      short fgColor;
  3260.      struct rccoord rc;
  3261.      unsigned fCursor;
  3262.  
  3263.      /* Save screen information. */
  3264.      fCursor = _displaycursor( _GCURSOROFF );
  3265.      bgColor = _getbkcolor();
  3266.      fgColor = _gettextcolor();
  3267.      rc = _gettextposition();
  3268.  
  3269.      /* Count items, find longest, and put count of each in array. Also,
  3270.       * put the highlighted character from each in a string.
  3271.       */
  3272.      for( cItem = 0; aItem[cItem].achItem[0]; cItem++ )
  3273.      {
  3274.          acchItem[cItem] = strlen( aItem[cItem].achItem );
  3275.          cchItem = (acchItem[cItem] > cchItem) ? acchItem[cItem] : cchItem;
  3276.          i = aItem[cItem].iHilite;
  3277.          achHilite[cItem] = aItem[cItem].achItem[i];
  3278.      }
  3279.      cchItem += 2;
  3280.      achHilite[cItem] = 0;          /* Null-terminate and lowercase string  */
  3281.      strlwr( achHilite );
  3282.  
  3283.      /* Adjust if centered, and draw menu box. */
  3284.      if( mnuAtrib.fCentered )
  3285.      {
  3286.          row -= cItem / 2;
  3287.          col -= cchItem / 2;
  3288.      }
  3289.      Box( row++, col++, cItem, cchItem );
  3290.  
  3291.      /* Put items on menu. */
  3292.      for( i = 0; i < cItem; i++ )
  3293.      {
  3294.          if( i == iCur )
  3295.              Itemize( row + i, col, TRUE, aItem[i], cchItem - acchItem[i] );
  3296.          else
  3297.              Itemize( row + i, col, FALSE, aItem[i], cchItem - acchItem[i] );
  3298.      }
  3299.  
  3300.      while( TRUE )
  3301.      {
  3302.          /* Wait until a uKey is pressed, then evaluate it. */
  3303.          uKey = GetKey( WAIT );
  3304.          switch( uKey )
  3305.          {
  3306.              case U_UP:                      /* Up key       */
  3307.                  iPrev = iCur;
  3308.                  iCur = (iCur > 0) ? (--iCur % cItem) : cItem - 1;
  3309.                  break;
  3310.              case U_DN:                      /* Down key     */
  3311.                  iPrev = iCur;
  3312.                  iCur = (iCur < cItem) ? (++iCur % cItem) : 0;
  3313.                  break;
  3314.              default:
  3315.                  if( uKey > 256 )            /* Ignore unknown function key  *
  3316.                      continue;
  3317.                  pchT = strchr( achHilite, (char)tolower( uKey ) );
  3318.                  if( pchT != NULL )          /* If in highlight string,      *
  3319.                      iCur = pchT - achHilite;/*   evaluate and fall through  *
  3320.                  else
  3321.                      continue;               /* Ignore unknown ASCII key     *
  3322.              case ENTER:
  3323.                  _setbkcolor( bgColor );
  3324.                  _settextcolor( fgColor );
  3325.                  _settextposition( rc.row, rc.col );
  3326.                  _displaycursor( fCursor );
  3327.                  return iCur;
  3328.          }
  3329.          /* Redisplay current and previous. */
  3330.          Itemize( row + iCur, col,
  3331.                   TRUE, aItem[iCur], cchItem - acchItem[iCur] );
  3332.          Itemize( row + iPrev, col,
  3333.                   FALSE, aItem[iPrev], cchItem - acchItem[iPrev] );
  3334.      }
  3335.  }
  3336.  
  3337.  /* Box - Draw menu box, filling interior with blanks of the border color.
  3338.   *
  3339.   * Params: row and col - upper left of box
  3340.   *         rowLast and colLast - height and width
  3341.   *
  3342.   * Return: None
  3343.   *
  3344.   * Uses:   mnuAtrib
  3345.   */
  3346.  void Box( int row, int col, int rowLast, int colLast )
  3347.  {
  3348.      int i;
  3349.      char achT[MAXITEM + 2];         /* Temporary array of characters */
  3350.  
  3351.      /* Set color and position. */
  3352.      _settextposition( row, col );
  3353.      _settextcolor( mnuAtrib.fgBorder );
  3354.      _setbkcolor( mnuAtrib.bgBorder );
  3355.  
  3356.      /* Draw box top. */
  3357.      achT[0] = mnuAtrib.chNW;
  3358.      memset( achT + 1, mnuAtrib.chEW, colLast );
  3359.      achT[colLast + 1] = mnuAtrib.chNE;
  3360.      achT[colLast + 2] = 0;
  3361.      _outtext( achT );
  3362.  
  3363.      /* Draw box sides and center. */
  3364.      achT[0] = mnuAtrib.chNS;
  3365.      memset( achT + 1, ' ', colLast );
  3366.      achT[colLast + 1] = mnuAtrib.chNS;
  3367.      achT[colLast + 2] = 0;
  3368.      for( i = 1; i <= rowLast; ++i )
  3369.      {
  3370.          _settextposition( row + i, col );
  3371.          _outtext( achT );
  3372.      }
  3373.  
  3374.      /* Draw box bottom. */
  3375.      _settextposition( row + rowLast + 1, col );
  3376.      achT[0] = mnuAtrib.chSW;
  3377.      memset( achT + 1, mnuAtrib.chEW, colLast );
  3378.      achT[colLast + 1] = mnuAtrib.chSE;
  3379.      achT[colLast + 2] = 0;
  3380.      _outtext( achT );
  3381.  }
  3382.  
  3383.  /* Itemize - Display one selection (item) of a menu. This function
  3384.   * is normally only used internally by Menu.
  3385.   *
  3386.   * Params: row and col - top left of menu
  3387.   *         fCur - flag set if item is current selection
  3388.   *         itm - structure containing item text and index of highlight
  3389.   *         cBlank - count of blanks to fill
  3390.   *
  3391.   * Return: none
  3392.   *
  3393.   * Uses:   mnuAtrib
  3394.   */
  3395.  void Itemize( int row, int col, int fCur, ITEM itm, int cBlank )
  3396.  {
  3397.      int i;
  3398.      char achT[MAXITEM];             /* Temporary array of characters */
  3399.  
  3400.      /* Set text position and color. */
  3401.      _settextposition( row, col );
  3402.      if( fCur )
  3403.      {
  3404.          _settextcolor( mnuAtrib.fgSelect );
  3405.          _setbkcolor( mnuAtrib.bgSelect );
  3406.      }
  3407.      else
  3408.      {
  3409.          _settextcolor( mnuAtrib.fgNormal );
  3410.          _setbkcolor( mnuAtrib.bgNormal );
  3411.      }
  3412.  
  3413.      /* Display item and fill blanks. */
  3414.      strcat( strcpy( achT, " " ), itm.achItem );
  3415.      _outtext( achT );
  3416.      memset( achT, ' ', cBlank-- );
  3417.      achT[cBlank] = 0;
  3418.      _outtext( achT );
  3419.  
  3420.      /* Set position and color of highlight character, then display it. */
  3421.      i = itm.iHilite;
  3422.      _settextposition( row, col + i + 1 );
  3423.      if( fCur )
  3424.      {
  3425.          _settextcolor( mnuAtrib.fgSelHilite );
  3426.          _setbkcolor( mnuAtrib.bgSelHilite );
  3427.      }
  3428.      else
  3429.      {
  3430.          _settextcolor( mnuAtrib.fgNormHilite );
  3431.          _setbkcolor( mnuAtrib.bgNormHilite );
  3432.      }
  3433.      _outchar( itm.achItem[i] );
  3434.  }
  3435.  
  3436.  /* GetKey - Gets a key from the keyboard. This routine distinguishes
  3437.   * between ASCII keys and function or control keys with different shift
  3438.   * states. It also accepts a flag to return immediately if no key is
  3439.   * available.
  3440.   *
  3441.   * Params: fWait - Code to indicate how to handle keyboard buffer:
  3442.   *   NO_WAIT     Return 0 if no key in buffer, else return key
  3443.   *   WAIT        Return first key if available, else wait for key
  3444.   *   CLEAR_WAIT  Throw away any key in buffer and wait for new key
  3445.   *
  3446.   * Return: One of the following:
  3447.   *
  3448.   *   Keytype                                High Byte    Low Byte
  3449.   *   -------                                ---------    --------
  3450.   *   No key available (only with NO_WAIT)       0           0
  3451.   *   ASCII value                                0        ASCII code
  3452.   *   Unshifted function or keypad               1        scan code
  3453.   *   Shifted function or keypad                 2        scan code
  3454.   *   CTRL function or keypad                    3        scan code
  3455.   *   ALT function or keypad                     4        scan code
  3456.   *
  3457.   * Note:   getkey cannot return codes for keys not recognized by BIOS
  3458.   *         int 16, such as the CTRL-UP or the 5 key on the numeric keypad.
  3459.   */
  3460.  unsigned GetKey( int fWait )
  3461.  {
  3462.      unsigned uKey, uShift;
  3463.  
  3464.      /* If CLEAR_WAIT, drain the keyboard buffer. */
  3465.      if( fWait == CLEAR_WAIT )
  3466.          while( _bios_keybrd( _KEYBRD_READY ) )
  3467.              _bios_keybrd( _KEYBRD_READ );
  3468.  
  3469.      /* If NO_WAIT, return 0 if there is no key ready. */
  3470.      if( !fWait && !_bios_keybrd( _KEYBRD_READY ) )
  3471.          return FALSE;
  3472.  
  3473.      /* Get key code. */
  3474.      uKey = _bios_keybrd( _KEYBRD_READ );
  3475.  
  3476.      /* If low byte is not zero, it's an ASCII key. Check scan code to see
  3477.       * if it's on the numeric keypad. If not, clear high byte and return.
  3478.       */
  3479.      if( uKey & 0x00ff )
  3480.          if( (uKey >> 8) < 69 )
  3481.              return( uKey & 0x00ff );
  3482.  
  3483.      /* For function keys and numeric keypad, put scan code in low byte
  3484.       * and shift state codes in high byte.
  3485.       */
  3486.      uKey >>= 8;
  3487.      uShift = _bios_keybrd( _KEYBRD_SHIFTSTATUS ) & 0x000f;
  3488.      switch( uShift )
  3489.      {
  3490.          case 0:
  3491.              return( 0x0100 | uKey );  /* None (1)    */
  3492.          case 1:
  3493.          case 2:
  3494.          case 3:
  3495.              return( 0x0200 | uKey );  /* Shift (2)   */
  3496.          case 4:
  3497.              return( 0x0300 | uKey );  /* Control (3) */
  3498.          case 8:
  3499.              return( 0x0400 | uKey );  /* Alt (4)     */
  3500.      }
  3501.  }
  3502.  
  3503.  /* _outchar - Display a character. This is the character equivalent of
  3504.   * _outtext. It is affected by _settextposition, _settextcolor, and
  3505.   * _setbkcolor. It should not be used in loops. Build strings and then
  3506.   * _outtext to show multiple characters.
  3507.   *
  3508.   * Params: out - character to be displayed
  3509.   *
  3510.   * Return: none
  3511.   */
  3512.  void _outchar( char out )
  3513.  {
  3514.      static char achT[2] = " ";      /* Temporary array of characters */
  3515.  
  3516.      achT[0] = out;
  3517.      _outtext( achT );
  3518.  }
  3519.  
  3520.  
  3521.  SNAP.C
  3522.  CD-ROM Disc Path:   \SAMPCODE\C\MSC60\SNAP.C
  3523.  
  3524.  /* Snap - An OS/2 screen capture utility
  3525.   *
  3526.   * Snap starts a background process containing a keyboard monitor.
  3527.   * The monitor checks for a hot key (ALT-*). If found, a thread is
  3528.   * launched to write the screen to a file. Various command line options
  3529.   * allow you to specify capture behavior or to deinstall the program.
  3530.   *
  3531.   * To compile, use the following command line:
  3532.   *
  3533.   *   cl /MT /G2s snap.c
  3534.   */
  3535.  
  3536.  /* Function prototypes */
  3537.  int  Monitor( void );
  3538.  void Snap( unsigned long _far *arg );
  3539.  void BackError( char *msgErr );
  3540.  void Syntax( void );
  3541.  void EvalOptions( int argc, char **argv );
  3542.  
  3543.  /* Define constants to enable function groups in OS2 include files */
  3544.  #define INCL_NOCOMMON
  3545.  #define INCL_NOPM
  3546.  #define INCL_KBD            // KBDKEYINFO
  3547.  #define INCL_VIO            // Vio functions
  3548.  #define INCL_DOSMEMMGR      // DosGetShrSeg, DosAllocShrSeg,
  3549.  #define INCL_DOSMONITORS    // DosMon functions
  3550.  #define INCL_DOSMISC        // DosGetEnv
  3551.  #define INCL_DOSSEMAPHORES  // DosSem functions
  3552.  #define INCL_DOSPROCESS     // DosBeep, DosSetPrty
  3553.  #define INCL_DOSINFOSEG     // DosGetInfoSeg
  3554.  #include <os2.h>
  3555.  
  3556.  #include <malloc.h>         // malloc, free
  3557.  #include <process.h>        // _beginthread, _endthread, exit, spawnl
  3558.  #include <string.h>         // strcpy, strcat
  3559.  #include <stdlib.h>         // atoi, itoa, _MAX_PATH
  3560.  #include <stddef.h>         // _threadid variable
  3561.  #include <stdio.h>          // puts, fopen, fwrite, etc.
  3562.  #include <conio.h>          // kbhit
  3563.  
  3564.  #define CON  0              // Handle for the console device
  3565.  #define FAIL -1             // Fail to start thread
  3566.  
  3567.  #define STAR    0x37        // Scan code for * on numeric keypad
  3568.  #define RELEASE 0x40        // Bit mask for key release
  3569.  
  3570.  /* Name and structure for shared memory data */
  3571.  char szShrSeg[] = { "\\SHAREMEM\\SNAP.DAT" };
  3572.  struct SHARED
  3573.  {
  3574.      BOOL  fSound;               // Sound flag
  3575.      BOOL  fAppend;              // Append flag
  3576.      BOOL  fInstall;             // Install flag
  3577.      SHORT cScreen;              // Count of screens
  3578.      LONG  lfWait;               // Wait semaphore
  3579.      CHAR  achSnap[_MAX_PATH];   // Snap file name
  3580.  } _far *pshrSnap = 0;           // Initialize offset to 0. Segment will
  3581.                                  // be initialized by system call.
  3582.  
  3583.  /* Count in bytes of shared segment */
  3584.  #define C_SHARESEG sizeof( struct SHARED )
  3585.  
  3586.  void main( int argc, char **argv )
  3587.  {
  3588.      USHORT offCmd;              // Dummy for DosGetEnv
  3589.      CHAR   *pchSnapExe = 0;     // Pointer to name of executable file
  3590.                                  //   (offset initialized to 0)
  3591.  
  3592.      /* Try to get shared segment (note how selector value is placed
  3593.       * directly in the segment word of the pointer address). There are
  3594.       * three possibilities:
  3595.       *
  3596.       *   - We can't get memory. This means SNAP is not installed,
  3597.       *     so we must allocate the memory and exec ourself in the
  3598.       *     background to install the monitor.
  3599.       *   - We can get memory and we are not installed. This means
  3600.       *     we have been execed by previous process to install monitor.
  3601.       *   - We can get memory and we are already installed. This means
  3602.       *     we were just called to modify options.
  3603.       */
  3604.      if( DosGetShrSeg( szShrSeg, (PSEL)&pshrSnap + 1 ) )
  3605.      {
  3606.          /* Segment doesn't exist, so try to allocate it. */
  3607.          if( DosAllocShrSeg( C_SHARESEG, szShrSeg, (PSEL)&pshrSnap + 1 ) )
  3608.          {
  3609.              puts( "Can't allocate shared memory" );
  3610.              exit( 1 );
  3611.          }
  3612.          else
  3613.          {
  3614.              /* This is the first time through, so we must execute
  3615.               * ourself to do installation. First set defaults, then
  3616.               * modify for options.
  3617.               */
  3618.              pshrSnap->fSound = TRUE;
  3619.              pshrSnap->fAppend = TRUE;
  3620.              pshrSnap->cScreen = 0;
  3621.              pshrSnap->fInstall = FALSE;
  3622.              strcpy( pshrSnap->achSnap, "SNAP.IMG" );
  3623.              DosSemSet( &pshrSnap->lfWait );
  3624.              EvalOptions( argc, argv );
  3625.  
  3626.              /* Get our own path name from the end of the environment
  3627.               * segment. This is the most reliable way to get the full
  3628.               * path name of the current file, since the extension is
  3629.               * ommitted from argv[0].
  3630.               */
  3631.              DosGetEnv( (PUSHORT)&pchSnapExe + 1, &offCmd );
  3632.  
  3633.              /* Adjust forward until we point to full path of .EXE file. */
  3634.              while( *pchSnapExe++ || *pchSnapExe )
  3635.                  ;
  3636.              ++pchSnapExe;
  3637.  
  3638.              /* Spawn ourself as a background process. Can't install
  3639.               * monitor now because we are in foreground. A background
  3640.               * process needs to install the monitor.
  3641.               */
  3642.              if( spawnl( P_DETACH, pchSnapExe, pchSnapExe, NULL ) == -1 )
  3643.              {
  3644.                  puts( "Can't start background process" );
  3645.                  exit( 1 );
  3646.              }
  3647.              puts( "Snap installed" );
  3648.              Syntax();
  3649.  
  3650.              /* Wait for background child process to report receiving
  3651.               * shared data.
  3652.               */
  3653.              DosSemWait( &pshrSnap->lfWait, SEM_INDEFINITE_WAIT );
  3654.          }
  3655.      }
  3656.      else
  3657.      {
  3658.          /* Already installed. We are being run to evaluate options and
  3659.           * modify behavior accordingly.
  3660.           */
  3661.          if( pshrSnap->fInstall )
  3662.              if( argc == 1 )
  3663.                  puts( "Snap already installed" );
  3664.              else
  3665.                  EvalOptions( argc, argv );
  3666.          else
  3667.          {
  3668.              /* Not installed, so we were execed by original SNAP to
  3669.               * install monitor. Tell parent we have received data, set
  3670.               * install flag, and install monitor.
  3671.               */
  3672.              DosSemClear( &pshrSnap->lfWait );
  3673.  
  3674.              /* Set installed flag and start monitor. */
  3675.              pshrSnap->fInstall = TRUE;
  3676.  
  3677.              exit( Monitor() );
  3678.          }
  3679.      }
  3680.  }
  3681.  
  3682.  /* Monitor routine checks keystrokes as they occur and calls
  3683.   * the Snap thread if the hot key is pressed.
  3684.   *
  3685.   * Params: None
  3686.   *
  3687.   * Return: 1 if error, 0 if deinstalled
  3688.   *
  3689.   * Uses:   pshrSnap - Shared memory structure
  3690.   */
  3691.  int Monitor()
  3692.  {
  3693.      #define BUFSIZE 128             // Size for monitor buffers:
  3694.                                      //   64 minimum, 128 recommended
  3695.      #define STACKSIZE 2048          // 2K minimum for any system call
  3696.  
  3697.      PMONIN pmnin;
  3698.      PMONOUT pmnout;
  3699.  
  3700.      struct KEYPACKET                // KBD monitor data record
  3701.      {
  3702.          USHORT fMon;
  3703.          KBDKEYINFO kki;
  3704.          USHORT fDD;
  3705.      } keyBuff;
  3706.      USHORT ckeyBuff = sizeof( keyBuff );
  3707.  
  3708.      HMONITOR hKeyMon;               // Keyboard handle from monitor open
  3709.      PGINFOSEG pGIS = 0, pLIS = 0;   // Information segment structures
  3710.      LONG  lfSnap = FALSE;           // Semaphore for each Snap thread
  3711.  
  3712.      /* Allocate space for monitor read/write buffers and mark size. */
  3713.      pmnin = (PMONIN)malloc( BUFSIZE );
  3714.      pmnin->cb = BUFSIZE;
  3715.      pmnout = (PMONOUT)malloc( BUFSIZE );
  3716.      pmnout->cb = BUFSIZE;
  3717.  
  3718.      /* Register monitor to the keyboard device (KBD$). */
  3719.      if( DosMonOpen( "KBD$", &hKeyMon ) )
  3720.      {
  3721.          BackError( "Can't open monitor" );
  3722.          return 1;
  3723.      }
  3724.  
  3725.      /* Get information segments (all we really need is ID of current
  3726.       * screen group from Global Information Segment).
  3727.       */
  3728.      DosGetInfoSeg( (PSEL)&pGIS + 1, (PSEL)&pLIS + 1 );
  3729.  
  3730.      /* Register the monitor buffers to the current screen group */
  3731.      if( DosMonReg( hKeyMon, (PBYTE)pmnin, (PBYTE)pmnout,
  3732.                     MONITOR_DEFAULT, pGIS->sgCurrent ) )
  3733.      {
  3734.          BackError( "Can't register monitor" );
  3735.          return 1;
  3736.      }
  3737.  
  3738.      /* Make process time critical so keys are interpreted without delay. */
  3739.      DosSetPrty( PRTYS_PROCESS, PRTYC_TIMECRITICAL, 0, 0 );
  3740.  
  3741.      /* Monitor loop - read into monitor buffer and examine. Take action
  3742.       * if hot key, otherwise pass on to device driver.
  3743.       */
  3744.      while( pshrSnap->fInstall )
  3745.      {
  3746.          DosMonRead( (PBYTE)pmnin, IO_WAIT, (PBYTE)&keyBuff, &ckeyBuff );
  3747.  
  3748.          /* Snap if ALT+STAR is down. */
  3749.          if( ((keyBuff.kki.chScan == STAR) || (keyBuff.kki.chScan == 0x2a)) &&
  3750.              (keyBuff.kki.fsState & ALT) &&
  3751.              (!(keyBuff.fDD & RELEASE)) )
  3752.          {
  3753.              /* Make sure last thread is finished */
  3754.              DosSemWait( &lfSnap, SEM_INDEFINITE_WAIT );
  3755.              if( (_beginthread( Snap, NULL, STACKSIZE,
  3756.                                 (PVOID)&lfSnap )) == FAIL )
  3757.                  BackError( "Can't start screen capture thread" );
  3758.              else
  3759.                  DosSemSet( &lfSnap );
  3760.          }
  3761.          else
  3762.              /* Pass the key through if it is not the hot key */
  3763.              DosMonWrite( (PBYTE)pmnout, (PBYTE)&keyBuff, ckeyBuff );
  3764.      }
  3765.  
  3766.      /* Close monitor */
  3767.      free( pmnin );
  3768.      free( pmnout );
  3769.      DosMonClose( hKeyMon );
  3770.      return 0;
  3771.  }
  3772.  
  3773.  /* Screen capture routine (run as a thread). Does a pop-up to get access
  3774.   * to the current screen. Reads characters from the screen into a buffer.
  3775.   * Then filters trailing spaces as it writes buffer to a file.
  3776.   *
  3777.   * Params: plfSnap - pointer to flag indicated snap status
  3778.   *
  3779.   * Return: none
  3780.   *
  3781.   * Uses:   pshrSnap - Shared memory structure
  3782.   */
  3783.  void Snap( ULONG _far *plfSnap )
  3784.  {
  3785.      enum { NOTE_B = 494, NOTE_C = 523, NOTE_F = 698 };
  3786.      CHAR   *pchScreen;              // Buffer for captured screen
  3787.      USHORT cbScreen;                // Count of bytes in buffer
  3788.      FILE   *sFile;                  // File stream
  3789.      USHORT usLine, usPos, usWidth;
  3790.      CHAR   ach[5];
  3791.      USHORT fWait = VP_WAIT | VP_TRANSPARENT;
  3792.      VIOMODEINFO vmi = { sizeof( vmi ) };
  3793.  
  3794.      if( pshrSnap->fSound )
  3795.          DosBeep( NOTE_F, NOTE_C );
  3796.  
  3797.      /* Pop up to current screen and check its size. */
  3798.      VioPopUp( &fWait, CON );
  3799.      VioGetMode( &vmi, CON );
  3800.  
  3801.      /* Allocate memory for a full screen plus one byte */
  3802.      cbScreen = vmi.col * vmi.row;
  3803.      pchScreen = malloc( cbScreen + 1 );
  3804.  
  3805.      /* Read screen and end popup */
  3806.      VioReadCharStr( pchScreen, &cbScreen, 0, 0, CON );
  3807.      VioEndPopUp( 0 );
  3808.  
  3809.      /* Increment screen count (4 digits or less) and convert to string. */
  3810.      pshrSnap->cScreen = (pshrSnap->cScreen + 1) % 9999;
  3811.      itoa( pshrSnap->cScreen, ach, 10 );
  3812.  
  3813.      /* Make numbered file name if appropriate. */
  3814.      if( !pshrSnap->fAppend )
  3815.          strcat( strcat( strcpy( pshrSnap->achSnap, "SNAP" ), ach ), ".IMG" );
  3816.  
  3817.      /* Open file and write buffer to it a line at a time */
  3818.      if( (sFile = fopen( pshrSnap->achSnap, "at" )) == NULL )
  3819.      {
  3820.          BackError( "Can't open file" );
  3821.          --pshrSnap->cScreen;
  3822.      }
  3823.      else
  3824.      {
  3825.          if( pshrSnap->fAppend )
  3826.          {
  3827.              /* Not using fprintf reduces overhead. */
  3828.              fputs( "**** Screen ", sFile );
  3829.              fputs( ach, sFile );
  3830.              fputs( " ****\n", sFile );
  3831.          }
  3832.  
  3833.          for( usLine = 0, usPos = 0; usLine < vmi.row; usLine++ )
  3834.          {
  3835.              /* Throw away trailing spaces */
  3836.              for( usWidth = vmi.col;
  3837.                   (pchScreen[usPos + usWidth - 1] == ' ' ) && usWidth;
  3838.                   usWidth-- )
  3839.                  ;
  3840.              /* Write line and newline */
  3841.              fwrite( pchScreen + usPos, 1, usWidth, sFile );
  3842.              fputc( '\n', sFile );
  3843.              usPos += vmi.col;
  3844.          }
  3845.          fclose( sFile );
  3846.      }
  3847.      if( pshrSnap->fSound )
  3848.          DosBeep( NOTE_C, NOTE_B );
  3849.  
  3850.      /* Free memory and let parent know we are done */
  3851.      free( pchScreen );
  3852.      DosSemClear( plfSnap );
  3853.  }
  3854.  
  3855.  /* Displays an error message from within a background process or thread.
  3856.   * The monitor is in the background and has no screen group, so it must
  3857.   * use VioPopUp to get access to the screen.
  3858.   *
  3859.   * Params: msgErr - error message string
  3860.   *
  3861.   * Return: None
  3862.   */
  3863.  void BackError( char *pchErr )
  3864.  {
  3865.      USHORT fWait = VP_WAIT | VP_TRANSPARENT;
  3866.  
  3867.      VioPopUp( &fWait, CON );
  3868.      puts( pchErr );
  3869.      puts( "Press any key to continue . . ." );
  3870.      while( !kbhit() )
  3871.          ;
  3872.      VioEndPopUp( CON );
  3873.  }
  3874.  
  3875.  /* Displays syntax.
  3876.   *
  3877.   * Params: None
  3878.   *
  3879.   * Return: None
  3880.   */
  3881.  void Syntax()
  3882.  {
  3883.      puts( "\nOptions: " );
  3884.      puts( "\t/H\t  Display help." );
  3885.      puts( "\t/S\t  Turn sound on (default)." );
  3886.      puts( "\t/Q\t  Turn sound off." );
  3887.      puts( "\t/D\t  Deinstall." );
  3888.      puts( "\t/A [path] Append each screen to a file (complete path allowed)."
  3889.      puts( "\t\t  If no file given, default is SNAP.IMG in current directory"
  3890.      puts( "\t\t  Resets screen number to 1." );
  3891.      puts( "\t/N [num]  Create numbered file for each screen." );
  3892.      puts( "\t\t  Example: SNAP1.IMG, SNAP2.IMG in current directory." );
  3893.      puts( "\t\t  Resets screen number to 1 or to num if given." );
  3894.  }
  3895.  
  3896.  /* Evaluate command-line options.
  3897.   *
  3898.   * Params: argc - Number of arguments
  3899.   *         argv - Pointer to argument list
  3900.   *
  3901.   * Return: none
  3902.   *
  3903.   * Uses: Shared memory structure - pshrSnap
  3904.   */
  3905.  void EvalOptions( int argc, char **argv )
  3906.  {
  3907.      SHORT i;
  3908.  
  3909.      /* Look for and handle arguments */
  3910.      for(  i = 1; i < argc; i++ )
  3911.      {
  3912.          if( argv[i][0] == '/' || argv[i][0] == '-' )
  3913.          {
  3914.              switch( argv[i][1] )
  3915.              {
  3916.                  case 'A':
  3917.                  case 'a':
  3918.                      pshrSnap->fAppend = TRUE;
  3919.                      pshrSnap->cScreen = 0;
  3920.                      if( (argv[++i]) &&
  3921.                          (argv[i][0] != '/') &&
  3922.                          (argv[i][0] != '-') )
  3923.  
  3924.                      {
  3925.                          strcpy( pshrSnap->achSnap, argv[i] );
  3926.                          puts( "Append mode - name set" );
  3927.                      }
  3928.                      else
  3929.                          puts( "Append mode" );
  3930.                      break;
  3931.  
  3932.                  case 'N':
  3933.                  case 'n':
  3934.                      pshrSnap->fAppend = FALSE;
  3935.                      puts( "Numbered file mode" );
  3936.                      if( (argv[++i]) &&
  3937.                          (argv[i][0] != '/') &&
  3938.                          (argv[i][0] != '-') )
  3939.                      {
  3940.                          pshrSnap->cScreen = (atoi( argv[i] ) % 9999) - 1;
  3941.                      }
  3942.                      else
  3943.                          pshrSnap->cScreen = 0;
  3944.                      break;
  3945.  
  3946.                  case 'Q':
  3947.                  case 'q':
  3948.                      pshrSnap->fSound = FALSE;
  3949.                      puts( "Sound off" );
  3950.                      break;
  3951.  
  3952.                  case 'S'  :
  3953.                  case 's'  :
  3954.                      pshrSnap->fSound = TRUE;
  3955.                      puts( "Sound on" );
  3956.                      break;
  3957.  
  3958.                  case 'D':
  3959.                  case 'd':
  3960.                      if( pshrSnap->fInstall )
  3961.                      {
  3962.                          pshrSnap->fInstall = FALSE;
  3963.                          puts( "Deinstalling" );
  3964.                      }
  3965.                      else
  3966.                          exit( 0 );
  3967.                      break;
  3968.  
  3969.                  case 'H'  :
  3970.                  case 'h'  :
  3971.                      if( pshrSnap->fInstall )
  3972.                          Syntax();
  3973.                      break;
  3974.              }
  3975.          }
  3976.      }
  3977.  }
  3978.  
  3979.  
  3980.  SORTDEMO.C
  3981.  CD-ROM Disc Path:   \SAMPCODE\C\MSC60\SORTDEMO.C
  3982.  
  3983.  /* SORTDEMO -This program graphically demonstrates six common sorting
  3984.   * algorithms. It prints 25 or 43 horizontal bars of different lengths
  3985.   * in random order, then sorts the bars from shortest to longest.
  3986.   * The program can beep to generate different pitches, depending on the
  3987.   * length and position of the bar.
  3988.   *
  3989.   * The program can be created for DOS or OS/2. To create for OS/2, define
  3990.   * the symbol OS2. Command lines for DOS and OS/2 are shown below:
  3991.   *
  3992.   * DOS:
  3993.   *    cl /Lr sortdemo.c graphics.lib
  3994.   *
  3995.   * OS/2:
  3996.   *    cl /Lp /DOS2 sortdemo.c grtextp.lib
  3997.   */
  3998.  
  3999.  #include <graph.h>          // _outtext, _settextcolor, _settextposition
  4000.  #include <string.h>         // strlen
  4001.  #include <stdio.h>          // sprintf
  4002.  #include <conio.h>          // getch
  4003.  #include <stdlib.h>         // srand, rand, toupper
  4004.  #include <malloc.h>         // malloc, free
  4005.  #include <time.h>           // time, clock
  4006.  
  4007.  enum BOOL { FALSE, TRUE };
  4008.  
  4009.  /* Structure type for colored bars */
  4010.  typedef struct _BAR
  4011.  {
  4012.      char len;
  4013.      char clr;
  4014.  } BAR;
  4015.  
  4016.  /* Structure type for screen cells */
  4017.  typedef struct _CELL
  4018.  {
  4019.      char chChar;
  4020.      char chAttr;
  4021.  } CELL;
  4022.  
  4023.  /* Function prototypes */
  4024.  void main( void  );
  4025.  void Cls( void  );
  4026.  void InitMenu( void  );             // Menu Functions
  4027.  void DrawFrame( int iTop, int Left, int Width, int Height );
  4028.  void RunMenu( void  );
  4029.  void DrawTime( int iCurrentRow );
  4030.  void InitBars( void  );             // Bar functions
  4031.  void ReInitBars( void  );
  4032.  void DrawBar( int iRow );
  4033.  void SwapBars( int iRow1, int iRow2 );
  4034.  void Swaps( BAR *one, BAR *two );
  4035.  void InsertionSort( void  );        // Sort functions
  4036.  void BubbleSort( void  );
  4037.  void HeapSort( void  );
  4038.  void PercolateUp( int iMaxLevel );
  4039.  void PercolateDown( int iMaxLevel );
  4040.  void ExchangeSort( void  );
  4041.  void ShellSort( void  );
  4042.  void QuickSort( int iLow, int iHigh );
  4043.  void Beep( int frequency, int duration );
  4044.  void Sleep( clock_t wait );
  4045.  
  4046.  /* Macro */
  4047.  #define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))
  4048.  #define _outtextxy( ach, x, y )   { _settextposition( y, x ); \
  4049.                                      _outtext( ach ); }
  4050.  
  4051.  /* Constants */
  4052.  #define ESC        27
  4053.  #define BLANK      32
  4054.  #define BLOCK      223
  4055.  #define TOP        1
  4056.  #define FIRSTMENU  (TOP + 6)
  4057.  #define LEFTCOLUMN 48
  4058.  #define PROMPTPOS  27
  4059.  #define WIDTH      (80 - LEFTCOLUMN)
  4060.  #define HEIGHT     (cszMenu + 2)
  4061.  #define MENUCOLOR  15
  4062.  #define BLANKCOLOR 7
  4063.  #define BACKCOLOR  0L
  4064.  #define PAUSELIMIT 900
  4065.  
  4066.  /* Global variables */
  4067.  clock_t clStart, clFinish, clPause = 30L;
  4068.  int fSound, iCurChoice, iSwaps, iCompares, cRow;
  4069.  
  4070.  BAR abarWork[43], abarPerm[43]; // Temporary and permanent sort arrays
  4071.  
  4072.  char *aszMenu[] =
  4073.  {
  4074.      "",
  4075.      "       C Sorting Demo",
  4076.      "",
  4077.      "              Time  Swap  Comp",
  4078.      "",
  4079.      "Insertion",
  4080.      "Bubble",
  4081.      "Heap",
  4082.      "Exchange",
  4083.      "Shell",
  4084.      "Quick",
  4085.      "",
  4086.      "Toggle Sound: ",
  4087.      "",
  4088.      "Pause Factor: ",
  4089.      "<   (Slower)",
  4090.      ">   (Faster)",
  4091.      "",
  4092.      "Type first character of",
  4093.      "choice ( I B H E S Q T < > )",
  4094.      "or ESC key to end program: "
  4095.      "",
  4096.  };
  4097.  int cszMenu = sizeof( aszMenu ) / sizeof( aszMenu[0] );
  4098.  
  4099.  void main()
  4100.  {
  4101.      cRow = _settextrows( 43 );
  4102.      _clearscreen( _GCLEARSCREEN );
  4103.      _displaycursor( _GCURSOROFF );
  4104.      InitBars();
  4105.      InitMenu();
  4106.      RunMenu();                     // Respond to menu until quit
  4107.      _setvideomode( _DEFAULTMODE );
  4108.  }
  4109.  
  4110.  
  4111.  /* InitMenu - Calls the DrawFrame procedure to draw the frame around the
  4112.   * sort menu, then prints the different options stored in the menu array.
  4113.   */
  4114.  void InitMenu()
  4115.  {
  4116.      int  i;
  4117.      char ach[15];
  4118.  
  4119.      _settextcolor( MENUCOLOR );
  4120.      _setbkcolor( BACKCOLOR );
  4121.      DrawFrame( TOP, LEFTCOLUMN - 3, WIDTH + 3, HEIGHT );
  4122.      for( i = 0; i < cszMenu; i++ )
  4123.          _outtextxy( aszMenu[i], LEFTCOLUMN, TOP + i + 1 );
  4124.  
  4125.      /* Print the current value for Sound. */
  4126.      if( fSound )
  4127.          strcpy( ach, "ON " );
  4128.      else
  4129.          strcpy( ach, "OFF" );
  4130.  
  4131.      _outtextxy( ach, LEFTCOLUMN + 14, cszMenu - 7 );
  4132.      sprintf( ach, "%3.3u", clPause / 30 );
  4133.      _outtextxy( ach, LEFTCOLUMN + 14, cszMenu - 5 );
  4134.  
  4135.      /* Erase the speed option if the length of the pause is at a limit. */
  4136.      strcpy( ach, "            " );
  4137.      if( clPause == PAUSELIMIT )
  4138.          _outtextxy( ach, LEFTCOLUMN, cszMenu - 4 );
  4139.      if( clPause == 0L )
  4140.          _outtextxy( ach, LEFTCOLUMN, cszMenu - 3 );
  4141.  }
  4142.  
  4143.  
  4144.  /* DrawFrame - Draws a rectangular frame using the double-line box
  4145.   * characters. The parameters iTop, iLeft, iWidth, and iHeight are
  4146.   * the row and column arguments for the upper-left and lower-right
  4147.   * corners of the frame.
  4148.   */
  4149.  void DrawFrame( int iTop, int iLeft, int iWidth, int iHeight )
  4150.  {
  4151.      enum { ULEFT = 201, URIGHT = 187,
  4152.             LLEFT = 200, LRIGHT = 188, VERTICAL = 186, HORIZONTAL = 205
  4153.           };
  4154.      int iRow;
  4155.      char achTmp[80];
  4156.  
  4157.      memset( achTmp, HORIZONTAL, iWidth );
  4158.      achTmp[0] = ULEFT;
  4159.      achTmp[iWidth - 1] = URIGHT;
  4160.      achTmp[iWidth] = '\0';
  4161.      _outtextxy( achTmp, iLeft, iTop );
  4162.  
  4163.      memset( achTmp, BLANK, iWidth );
  4164.      achTmp[0] = VERTICAL;
  4165.      achTmp[iWidth - 1] = VERTICAL;
  4166.      for(  iRow = iTop + 1; iRow <= iHeight; iRow++ )
  4167.          _outtextxy( achTmp, iLeft, iRow );
  4168.  
  4169.      memset( achTmp, HORIZONTAL, iWidth );
  4170.      achTmp[0] = LLEFT;
  4171.      achTmp[iWidth - 1] = LRIGHT;
  4172.      _outtextxy( achTmp, iLeft, iTop + iHeight );
  4173.  }
  4174.  
  4175.  
  4176.  /* RunMenu - The RunMenu procedure first calls the ReInitBars
  4177.   * procedure to make sure the abarWork is in its unsorted form, then
  4178.   * prompts the user to make one of the following choices:
  4179.   *
  4180.   *  - Run one of the sorting algorithms
  4181.   *  - Toggle sound on or off
  4182.   *  - Increase or decrease speed
  4183.   *  - End the program
  4184.   */
  4185.  void RunMenu()
  4186.  {
  4187.      char    ch;
  4188.  
  4189.      while( TRUE )
  4190.      {
  4191.          iSwaps = iCompares = 0;
  4192.          _settextposition( TOP + cszMenu, LEFTCOLUMN + PROMPTPOS );
  4193.          _displaycursor( _GCURSORON );
  4194.          ch = getch();
  4195.          _displaycursor( _GCURSOROFF );
  4196.  
  4197.          /* Branch to the appropriate procedure depending on the key. */
  4198.          switch( toupper( ch ) )
  4199.          {
  4200.              case 'I':
  4201.                  iCurChoice = 0;
  4202.                  ReInitBars();
  4203.                  InsertionSort();
  4204.                  DrawTime( 0 );   // Print final time
  4205.                  break;
  4206.              case 'B':
  4207.                  iCurChoice = 1;
  4208.                  ReInitBars();
  4209.                  BubbleSort();
  4210.                  DrawTime( 0 );
  4211.                  break;
  4212.  
  4213.              case 'H':
  4214.                  iCurChoice = 2;
  4215.                  ReInitBars();
  4216.                  HeapSort();
  4217.                  DrawTime( 0 );
  4218.                  break;
  4219.  
  4220.              case 'E':
  4221.                  iCurChoice = 3;
  4222.                  ReInitBars();
  4223.                  ExchangeSort();
  4224.                  DrawTime( 0 );
  4225.                  break;
  4226.  
  4227.              case 'S':
  4228.                  iCurChoice = 4;
  4229.                  ReInitBars();
  4230.                  ShellSort();
  4231.                  DrawTime( 0 );
  4232.                  break;
  4233.  
  4234.              case 'Q':
  4235.                  iCurChoice = 5;
  4236.                  ReInitBars();
  4237.                  QuickSort( 0, cRow );
  4238.                  DrawTime( 0 );
  4239.                  break;
  4240.  
  4241.              case '>':
  4242.                  /* Decrease pause length to speed up sorting time, then
  4243.                   * redraw the menu to clear any timing results (since
  4244.                   * they won't compare with future results).
  4245.                   */
  4246.                  if( clPause )
  4247.                      clPause -= 30L;
  4248.                  InitMenu();
  4249.                  break;
  4250.  
  4251.              case '<':
  4252.                  /* Increase pause length to slow down sorting time. */
  4253.                  if( clPause <= 900L )
  4254.                      clPause += 30L;
  4255.                  InitMenu();
  4256.                  break;
  4257.  
  4258.              case 'T':
  4259.                  fSound = !fSound;
  4260.                  InitMenu();
  4261.                  break;
  4262.  
  4263.              case ESC:
  4264.                  return;
  4265.  
  4266.              default:        // Unknown key ignored
  4267.                  break;
  4268.          }
  4269.      }
  4270.  }
  4271.  
  4272.  
  4273.  /* DrawTime - Prints seconds elapsed since the given sorting routine
  4274.   * started. Note that this time includes both the time it takes to redraw
  4275.   * the bars plus the pause while Beep plays a note, and thus is not an
  4276.   * accurate indication of sorting speed.
  4277.   */
  4278.  void DrawTime( int iCurrentRow )
  4279.  {
  4280.      char achTiming[80];
  4281.  
  4282.      _settextcolor( MENUCOLOR );
  4283.      clFinish = clock();
  4284.  
  4285.      sprintf( achTiming, "%7.2f  %4.i  %4.i",
  4286.               (float)(clFinish - clStart) / CLOCKS_PER_SEC,
  4287.               iSwaps, iCompares );
  4288.  
  4289.      /* Print the number of seconds elapsed */
  4290.      _outtextxy( achTiming, LEFTCOLUMN + 11, FIRSTMENU + iCurChoice );
  4291.      if( fSound )
  4292.      {
  4293.          Beep( 60 * iCurrentRow, 75 );   // Play note
  4294.          Sleep( clPause - 75L );         // Pause adjusted for note duration
  4295.      }
  4296.      else
  4297.          Sleep( clPause );               // Pause
  4298.  }
  4299.  
  4300.  
  4301.  /* InitBars - Initializes the bar arrays and the menu box.
  4302.   */
  4303.  void InitBars()
  4304.  {
  4305.      struct videoconfig vc;
  4306.      int aTemp[43], iRow, iRowMax, iRand, iColorMax, iLength;
  4307.  
  4308.      /* Seed the random-number generator. */
  4309.      srand( (unsigned)time( NULL ) );
  4310.      fSound = TRUE;
  4311.      clPause = 30L;
  4312.  
  4313.      /* If monochrome or color burst disabled, use one color */
  4314.      _getvideoconfig( &vc );
  4315.      if( (vc.monitor == _MONO) || (vc.mode == _TEXTBW80) ||
  4316.                                   (vc.mode == _TEXTBW40) )
  4317.          iColorMax = 1;
  4318.      else
  4319.          iColorMax = 15;
  4320.  
  4321.      /* Randomize an array of rows. */
  4322.      for( iRow = 0; iRow < cRow; iRow++ )
  4323.          aTemp[iRow] = iRow + 1;
  4324.      iRowMax = cRow - 1;
  4325.      for( iRow = 0; iRow < cRow; iRow++ )
  4326.      {
  4327.          /* Find a random element in aTemp between 0 and iRowMax,
  4328.           * then assign the value in that element to iLength.
  4329.           */
  4330.          iRand = GetRandom( 0, iRowMax );
  4331.          iLength = aTemp[iRand];
  4332.  
  4333.          /* Overwrite the value in aTemp[iRand] with the value in
  4334.           * aTemp[iRowMax] so the value in aTemp[iRand] is
  4335.           * chosen only once.
  4336.           */
  4337.          aTemp[iRand] = aTemp[iRowMax];
  4338.  
  4339.          /* Decrease the value of iRowMax so that aTemp[iRowMax] can't
  4340.           * be chosen on the next pass through the loop.
  4341.           */
  4342.          --iRowMax;
  4343.          abarPerm[iRow].len = iLength;
  4344.          if( iColorMax == 1 )
  4345.              abarPerm[iRow].clr = BLANKCOLOR;
  4346.          else
  4347.              abarPerm[iRow].clr = iLength % iColorMax + 1;
  4348.      }
  4349.  
  4350.      /* Assign permanent sort values to temporary and draw unsorted bars. */
  4351.      ReInitBars();
  4352.  }
  4353.  
  4354.  
  4355.  /* ReInitBars - Restores the array abarWork to its original unsorted
  4356.   * state and draws the unsorted bars.
  4357.   */
  4358.  void ReInitBars()
  4359.  {
  4360.      int iRow;
  4361.  
  4362.      clStart = clock();
  4363.      for( iRow = 0; iRow < cRow; iRow++ )
  4364.      {
  4365.          abarWork[iRow] = abarPerm[iRow];
  4366.          DrawBar( iRow );
  4367.      }
  4368.  }
  4369.  
  4370.  
  4371.  /* DrawBar - Prints a bar at a specified row by first blanking the
  4372.   * old bar, then drawing a new bar having the length and color given in
  4373.   * the work array.
  4374.   */
  4375.  void DrawBar( int iRow )
  4376.  {
  4377.      int  cSpace;
  4378.      char achT[43];
  4379.  
  4380.      memset( achT, BLOCK, abarWork[iRow].len );
  4381.      cSpace = cRow - abarWork[iRow].len;
  4382.      memset( achT + abarWork[iRow].len, ' ', cSpace );
  4383.      achT[cRow] = '\0';
  4384.      _settextcolor( abarWork[iRow].clr );
  4385.      _outtextxy( achT, 0, iRow + 1 );
  4386.  }
  4387.  
  4388.  
  4389.  /* SwapBars - Calls DrawBar twice to switch the two bars in iRow1 and
  4390.   * iRow2, then calls DrawTime to update the time.
  4391.   */
  4392.  void SwapBars( int iRow1, int iRow2 )
  4393.  {
  4394.      DrawBar( iRow1 );
  4395.      DrawBar( iRow2 );
  4396.      DrawTime( iRow1 );
  4397.  }
  4398.  
  4399.  
  4400.  /* Swaps - Exchanges two bar structures.
  4401.   */
  4402.  void Swaps( BAR *bar1, BAR *bar2 )
  4403.  {
  4404.      BAR barTmp;
  4405.  
  4406.      ++iSwaps;
  4407.      barTmp = *bar1;
  4408.      *bar1  = *bar2;
  4409.      *bar2  = barTmp;
  4410.  }
  4411.  
  4412.  
  4413.  /* InsertionSort - InsertionSort compares the length of each element
  4414.   * with the lengths of all the preceding elements. When the appropriate
  4415.   * place for the new element is found, the element is inserted and
  4416.   * all the other elements are moved down one place.
  4417.   */
  4418.  void InsertionSort()
  4419.  {
  4420.      BAR barTemp;
  4421.      int iRow, iRowTmp, iLength;
  4422.  
  4423.      /* Start at the top. */
  4424.      for( iRow = 0; iRow < cRow; iRow++ )
  4425.      {
  4426.          barTemp = abarWork[iRow];
  4427.          iLength = barTemp.len;
  4428.  
  4429.          /* As long as the length of the temporary element is greater than
  4430.           * the length of the original, keep shifting the elements down.
  4431.           */
  4432.          for( iRowTmp = iRow; iRowTmp; iRowTmp-- )
  4433.          {
  4434.              iCompares++;
  4435.              if( abarWork[iRowTmp - 1].len > iLength )
  4436.              {
  4437.                  ++iSwaps;
  4438.                  abarWork[iRowTmp] = abarWork[iRowTmp - 1];
  4439.                  DrawBar( iRowTmp );         // Print the new bar
  4440.                  DrawTime( iRowTmp );        // Print the elapsed time
  4441.  
  4442.              }
  4443.              else                            // Otherwise, exit
  4444.                  break;
  4445.          }
  4446.  
  4447.          /* Insert the original bar in the temporary position. */
  4448.          abarWork[iRowTmp] = barTemp;
  4449.          DrawBar( iRowTmp );
  4450.          DrawTime( iRowTmp );
  4451.      }
  4452.  }
  4453.  
  4454.  
  4455.  /* BubbleSort - BubbleSort cycles through the elements, comparing
  4456.   * adjacent elements and swapping pairs that are out of order. It
  4457.   * continues to do this until no out-of-order pairs are found.
  4458.   */
  4459.  void BubbleSort()
  4460.  {
  4461.      int iRow, iSwitch, iLimit = cRow;
  4462.  
  4463.      /* Move the longest bar down to the bottom until all are in order. */
  4464.      do
  4465.      {
  4466.          iSwitch = 0;
  4467.          for( iRow = 0; iRow < iLimit; iRow++ )
  4468.          {
  4469.              /* If two adjacent elements are out of order, swap their values
  4470.               * and redraw those two bars.
  4471.               */
  4472.              iCompares++;
  4473.              if( abarWork[iRow].len > abarWork[iRow + 1].len )
  4474.              {
  4475.                  Swaps( &abarWork[iRow], &abarWork[iRow + 1] );
  4476.                  SwapBars( iRow, iRow + 1 );
  4477.                  iSwitch = iRow;
  4478.              }
  4479.          }
  4480.  
  4481.          /* Sort on next pass only to where the last switch was made. */
  4482.          iLimit = iSwitch;
  4483.      } while( iSwitch );
  4484.  }
  4485.  
  4486.  
  4487.  /* HeapSort - HeapSort (also called TreeSort) works by calling
  4488.   * PercolateUp and PercolateDown. PercolateUp organizes the elements
  4489.   * into a "heap" or "tree," which has the properties shown below:
  4490.   *
  4491.   *                             element[1]
  4492.   *                           /            \
  4493.   *                element[2]                element[3]
  4494.   *               /          \              /          \
  4495.   *         element[4]     element[5]   element[6]    element[7]
  4496.   *         /        \     /        \   /        \    /        \
  4497.   *        ...      ...   ...      ... ...      ...  ...      ...
  4498.   *
  4499.   *
  4500.   * Each "parent node" is greater than each of its "child nodes"; for
  4501.   * example, element[1] is greater than element[2] or element[3];
  4502.   * element[4] is greater than element[5] or element[6], and so forth.
  4503.   * Therefore, once the first loop in HeapSort is finished, the
  4504.   * largest element is in element[1].
  4505.   *
  4506.   * The second loop rebuilds the heap (with PercolateDown), but starts
  4507.   * at the top and works down, moving the largest elements to the bottom.
  4508.   * This has the effect of moving the smallest elements to the top and
  4509.   * sorting the heap.
  4510.   */
  4511.  void HeapSort()
  4512.  {
  4513.      int i;
  4514.  
  4515.      for( i = 1; i < cRow; i++ )
  4516.          PercolateUp( i );
  4517.  
  4518.      for( i = cRow - 1; i > 0; i-- )
  4519.      {
  4520.          Swaps( &abarWork[0], &abarWork[i] );
  4521.          SwapBars( 0, i );
  4522.          PercolateDown( i - 1 );
  4523.      }
  4524.  }
  4525.  
  4526.  
  4527.  /* PercolateUp - Converts elements into a "heap" with the largest
  4528.   * element at the top (see the diagram above).
  4529.   */
  4530.  void PercolateUp( int iMaxLevel )
  4531.  {
  4532.      int i = iMaxLevel, iParent;
  4533.  
  4534.      /* Move the value in abarWork[iMaxLevel] up the heap until it has
  4535.       * reached its proper node (that is, until it is greater than either
  4536.       * of its child nodes, or until it has reached 1, the top of the heap).
  4537.       */
  4538.      while( i )
  4539.      {
  4540.          iParent = i / 2;    // Get the subscript for the parent node
  4541.  
  4542.          iCompares++;
  4543.          if( abarWork[i].len > abarWork[iParent].len )
  4544.          {
  4545.              /* The value at the current node is bigger than the value at
  4546.               * its parent node, so swap these two array elements.
  4547.               */
  4548.              Swaps( &abarWork[iParent], &abarWork[i] );
  4549.              SwapBars( iParent, i );
  4550.              i = iParent;
  4551.          }
  4552.          else
  4553.              /* Otherwise, the element has reached its proper place in the
  4554.               * heap, so exit this procedure.
  4555.               */
  4556.              break;
  4557.      }
  4558.  }
  4559.  
  4560.  
  4561.  /* PercolateDown - Converts elements to a "heap" with the largest elements
  4562.   * at the bottom. When this is done to a reversed heap (largest elements
  4563.   * at top), it has the effect of sorting the elements.
  4564.   */
  4565.  void PercolateDown( int iMaxLevel )
  4566.  {
  4567.      int iChild, i = 0;
  4568.  
  4569.      /* Move the value in abarWork[0] down the heap until it has reached
  4570.       * its proper node (that is, until it is less than its parent node
  4571.       * or until it has reached iMaxLevel, the bottom of the current heap).
  4572.       */
  4573.      while( TRUE )
  4574.      {
  4575.          /* Get the subscript for the child node. */
  4576.          iChild = 2 * i;
  4577.  
  4578.          /* Reached the bottom of the heap, so exit this procedure. */
  4579.          if( iChild > iMaxLevel )
  4580.              break;
  4581.  
  4582.          /* If there are two child nodes, find out which one is bigger. */
  4583.          if( iChild + 1 <= iMaxLevel )
  4584.          {
  4585.              iCompares++;
  4586.              if( abarWork[iChild + 1].len > abarWork[iChild].len )
  4587.                  iChild++;
  4588.          }
  4589.  
  4590.          iCompares++;
  4591.          if( abarWork[i].len < abarWork[iChild].len )
  4592.          {
  4593.              /* Move the value down since it is still not bigger than
  4594.               * either one of its children.
  4595.               */
  4596.              Swaps( &abarWork[i], &abarWork[iChild] );
  4597.              SwapBars( i, iChild );
  4598.              i = iChild;
  4599.          }
  4600.          else
  4601.              /* Otherwise, abarWork has been restored to a heap from 1 to
  4602.               * iMaxLevel, so exit.
  4603.               */
  4604.              break;
  4605.      }
  4606.  }
  4607.  
  4608.  
  4609.  /* ExchangeSort - The ExchangeSort compares each element--starting with
  4610.   * the first--with every following element. If any of the following
  4611.   * elements is smaller than the current element, it is exchanged with
  4612.   * the current element and the process is repeated for the next element.
  4613.   */
  4614.  void ExchangeSort()
  4615.  {
  4616.      int iRowCur, iRowMin, iRowNext;
  4617.  
  4618.      for( iRowCur = 0; iRowCur < cRow; iRowCur++ )
  4619.      {
  4620.          iRowMin = iRowCur;
  4621.          for( iRowNext = iRowCur; iRowNext < cRow; iRowNext++ )
  4622.          {
  4623.              iCompares++;
  4624.              if( abarWork[iRowNext].len < abarWork[iRowMin].len )
  4625.              {
  4626.                  iRowMin = iRowNext;
  4627.                  DrawTime( iRowNext );
  4628.              }
  4629.          }
  4630.  
  4631.          /* If a row is shorter than the current row, swap those two
  4632.           * array elements.
  4633.           */
  4634.          if( iRowMin > iRowCur )
  4635.          {
  4636.              Swaps( &abarWork[iRowCur], &abarWork[iRowMin] );
  4637.              SwapBars( iRowCur, iRowMin );
  4638.          }
  4639.      }
  4640.  }
  4641.  
  4642.  
  4643.  /* ShellSort - ShellSort is similar to the BubbleSort. However, it
  4644.   * begins by comparing elements that are far apart (separated by the
  4645.   * value of the iOffset variable, which is initially half the distance
  4646.   * between the first and last element), then comparing elements that
  4647.   * are closer together. When iOffset is one, the last iteration of
  4648.   * is merely a bubble sort.
  4649.   */
  4650.  void ShellSort()
  4651.  {
  4652.      int iOffset, iSwitch, iLimit, iRow;
  4653.  
  4654.      /* Set comparison offset to half the number of bars. */
  4655.      iOffset = cRow / 2;
  4656.  
  4657.      while( iOffset )
  4658.      {
  4659.          /* Loop until offset gets to zero. */
  4660.          iLimit = cRow - iOffset;
  4661.          do
  4662.          {
  4663.              iSwitch = FALSE;     // Assume no switches at this offset.
  4664.  
  4665.              /* Compare elements and switch ones out of order. */
  4666.              for( iRow = 0; iRow <= iLimit; iRow++ )
  4667.              {
  4668.                  iCompares++;
  4669.                  if( abarWork[iRow].len > abarWork[iRow + iOffset].len )
  4670.                  {
  4671.                      Swaps( &abarWork[iRow], &abarWork[iRow + iOffset] );
  4672.                      SwapBars( iRow, iRow + iOffset );
  4673.                      iSwitch = iRow;
  4674.                  }
  4675.              }
  4676.  
  4677.              /* Sort on next pass only to where last switch was made. */
  4678.              iLimit = iSwitch - iOffset;
  4679.          } while( iSwitch );
  4680.  
  4681.          /* No switches at last offset, try one half as big. */
  4682.          iOffset = iOffset / 2;
  4683.      }
  4684.  }
  4685.  
  4686.  
  4687.  /* QuickSort - QuickSort works by picking a random "pivot" element,
  4688.   * then moving every element that is bigger to one side of the pivot,
  4689.   * and every element that is smaller to the other side. QuickSort is
  4690.   * then called recursively with the two subdivisions created by the pivot.
  4691.   * Once the number of elements in a subdivision reaches two, the recursive
  4692.   * calls end and the array is sorted.
  4693.   */
  4694.  void QuickSort( int iLow, int iHigh )
  4695.  {
  4696.      int iUp, iDown, iBreak;
  4697.  
  4698.      if( iLow < iHigh )
  4699.      {
  4700.          /* Only two elements in this subdivision; swap them if they are
  4701.           * out of order, then end recursive calls.
  4702.           */
  4703.          if( (iHigh - iLow) == 1 )
  4704.          {
  4705.              iCompares++;
  4706.              if( abarWork[iLow].len > abarWork[iHigh].len )
  4707.              {
  4708.                  Swaps( &abarWork[iLow], &abarWork[iHigh] );
  4709.                  SwapBars( iLow, iHigh );
  4710.              }
  4711.          }
  4712.          else
  4713.          {
  4714.              iBreak = abarWork[iHigh].len;
  4715.              do
  4716.              {
  4717.                  /* Move in from both sides towards the pivot element. */
  4718.                  iUp = iLow;
  4719.                  iDown = iHigh;
  4720.                  iCompares++;
  4721.                  while( (iUp < iDown) && (abarWork[iUp].len <= iBreak) )
  4722.                      iUp++;
  4723.                  iCompares++;
  4724.                  while( (iDown > iUp) && (abarWork[iDown].len >= iBreak) )
  4725.                      iDown--;
  4726.                  /* If we haven't reached the pivot, it means that two
  4727.                   * elements on either side are out of order, so swap them.
  4728.                   */
  4729.                  if( iUp < iDown )
  4730.                  {
  4731.                      Swaps( &abarWork[iUp], &abarWork[iDown] );
  4732.                      SwapBars( iUp, iDown );
  4733.                  }
  4734.              } while ( iUp < iDown );
  4735.  
  4736.              /* Move pivot element back to its proper place in the array. */
  4737.              Swaps( &abarWork[iUp], &abarWork[iHigh] );
  4738.              SwapBars( iUp, iHigh );
  4739.  
  4740.              /* Recursively call the QuickSort procedure (pass the smaller
  4741.               * subdivision first to use less stack space).
  4742.               */
  4743.              if( (iUp - iLow) < (iHigh - iUp) )
  4744.              {
  4745.                  QuickSort( iLow, iUp - 1 );
  4746.                  QuickSort( iUp + 1, iHigh );
  4747.              }
  4748.              else
  4749.              {
  4750.                  QuickSort( iUp + 1, iHigh );
  4751.                  QuickSort( iLow, iUp - 1 );
  4752.              }
  4753.          }
  4754.      }
  4755.  }
  4756.  
  4757.  /* Beep - Sounds the speaker for a time specified in microseconds by
  4758.   * duration at a pitch specified in hertz by frequency.
  4759.   */
  4760.  void Beep( int frequency, int duration )
  4761.  {
  4762.  /* Use system call for OS/2 */
  4763.  #if defined( OS2 )
  4764.  #define INCL_NOCOMMON
  4765.  #define INCL_NOPM
  4766.  #define INCL_DOSPROCESS
  4767.  #include <os2.h>
  4768.      DosBeep( frequency, duration );
  4769.  #else
  4770.  /* Define procedure for DOS */
  4771.      int control;
  4772.  
  4773.      /* If frequency is 0, Beep doesn't try to make a sound. It
  4774.       * just sleeps for the duration.
  4775.       */
  4776.      if( frequency )
  4777.      {
  4778.          /* 75 is about the shortest reliable duration of a sound. */
  4779.          if( duration < 75 )
  4780.              duration = 75;
  4781.  
  4782.          /* Prepare timer by sending 10111100 to port 43. */
  4783.          outp( 0x43, 0xb6 );
  4784.  
  4785.          /* Divide input frequency by timer ticks per second and
  4786.           * write (byte by byte) to timer.
  4787.           */
  4788.          frequency = (unsigned)(1193180L / frequency);
  4789.          outp( 0x42, (char)frequency );
  4790.          outp( 0x42, (char)(frequency >> 8) );
  4791.  
  4792.          /* Save speaker control byte. */
  4793.          control = inp( 0x61 );
  4794.  
  4795.          /* Turn on the speaker (with bits 0 and 1). */
  4796.          outp( 0x61, control | 0x3 );
  4797.      }
  4798.  
  4799.      Sleep( (clock_t)duration );
  4800.  
  4801.      /* Turn speaker back on if necessary. */
  4802.      if( frequency )
  4803.          outp( 0x61, control );
  4804.  
  4805.               /* DOS version */
  4806.  }
  4807.  
  4808.  /* Pauses for a specified number of microseconds. */
  4809.  void Sleep( clock_t wait )
  4810.  {
  4811.      clock_t goal;
  4812.  
  4813.      goal = wait + clock();
  4814.      while( goal >= clock() )
  4815.          ;
  4816.  }
  4817.  
  4818.  
  4819.  TURTLE.C
  4820.  CD-ROM Disc Path:   \SAMPCODE\C\MSC60\TURTLE.C
  4821.  
  4822.  /* TURTLE - Module of functions to implement turtle graphics. Turtle graphics
  4823.   * is a model for specifying relative movements of an imaginary pointer whose
  4824.   * direction, color, visibility, and other attributes are given default
  4825.   * values using turtle functions. To use the turtle module, include TURTLE.H
  4826.   * in your program. The following functions (many defined as macros)
  4827.   * are public :
  4828.   *
  4829.   *   InitTurtle      - Initiate turtle graphics
  4830.   *   Home            - Reset turtle defaults
  4831.   *   PenDown         - Set pen visibility
  4832.   *   SetFill         - Set fill state
  4833.   *   PenColor        - Set pen color index
  4834.   *   BorderColor     - Set border color index
  4835.   *   Turn            - Set direction relative to current
  4836.   *   TurnTo          - Set absolute direction
  4837.   *   Move            - Move in current direction
  4838.   *   MoveTo          - Move to absolute location
  4839.   *   Poly            - Draw a polygon
  4840.   *   Circle          - Draw a circle with center at current location
  4841.   *   Ellipse         - Draw an ellipse with center at current location
  4842.   *   Rectangle       - Draw a rectangle with center at current location
  4843.   *   ImageSize       - Get size of rectangle with top-left origin
  4844.   *   GetImage        - Get rectangular image with top-left origin
  4845.   *   PutImage        - Put rectangular image with top-left origin
  4846.   *   FillIn          - Fill from the current location to border
  4847.   *   NextColorIndex  - Rotate to next color index
  4848.   *   NextColorValue  - Rotate to next color value
  4849.   *   OnScreen        - Report whether current location is on screen
  4850.   *   RGB             - Combine Red, Green, and Blue elements of color value
  4851.   *
  4852.   * The TURTLE structure, the "tc" global variable (having TURTLE type), and
  4853.   * "vlColors" variable are defined. However, these are not normally used
  4854.   * directly by the programmer.
  4855.   */
  4856.  
  4857.  #include <graph.h>
  4858.  #include <math.h>
  4859.  #include <string.h>
  4860.  #include "turtle.h"
  4861.  
  4862.  #define PI       3.141593
  4863.  
  4864.  long cvlColors[256];            /* Array of long color values              */
  4865.  
  4866.  TURTLE tc = { 1.39 };    /* Initial aspect - adjust for your screen */
  4867.  
  4868.  /* InitTurtle - Initializes all turtle defaults. This function should be
  4869.   * called at least once (after _setvideomode and _getvideoconfig) and
  4870.   * additionally after any change to a new graphics mode.
  4871.   *
  4872.   * Params: vc - pointer to videoconfig structure
  4873.   *
  4874.   * Return: 0 if fail, 1 if success
  4875.   *
  4876.   * Uses:   tc structure variable cvlColors array
  4877.   */
  4878.  short InitTurtle( struct videoconfig *vc )
  4879.  {
  4880.      int i;
  4881.      unsigned cvuInc, cvuRed, cvuGreen, cvuBlue; /* Unsigned portions of */
  4882.      static int mode = -1;                       /*   color values       */
  4883.  
  4884.      /* Terminate if not graphics mode. */
  4885.      if( !vc->numxpixels )
  4886.          return 0;
  4887.  
  4888.      /* If mode has changed, set window coordinates. */
  4889.      if( mode != vc->mode )
  4890.      {
  4891.          mode = vc->mode;
  4892.          tc.xsLeft = tc.ysTop = 0;
  4893.          tc.xsRight = vc->numxpixels - 1;
  4894.          tc.ysBot = vc->numypixels - 1;
  4895.      }
  4896.  
  4897.      /* Set palette flag. */
  4898.      switch( vc->adapter )
  4899.      {
  4900.          case _MDPA:
  4901.          case _CGA:
  4902.          case _OCGA:
  4903.          case _HGC:
  4904.              tc.fPalette = FALSE;
  4905.              break;
  4906.          default:
  4907.              tc.fPalette = TRUE;
  4908.              break;
  4909.      }
  4910.  
  4911.      /* Set palette defaults. */
  4912.      switch( vc->mode )
  4913.      {
  4914.          case _HRESBW:
  4915.          case _HERCMONO:
  4916.          case _ERESNOCOLOR:
  4917.          case _ORESCOLOR:
  4918.          case _VRES2COLOR:
  4919.              tc.ccv = 0;
  4920.              tc.cci = 2;
  4921.              return Home();
  4922.          case _MRES256COLOR:        /* Active bits in this order:          */
  4923.              cvuInc = 12;
  4924.              tc.ccv = tc.cci = 125; /* ???????? ??bbbbbb ??gggggg ??rrrrrr */
  4925.              break;
  4926.          case _ERESCOLOR:
  4927.              if( vc->memory == 64 )
  4928.              {
  4929.                  cvuInc = 32;
  4930.                  tc.ccv = 16;       /* ???????? ??????Bb ??????Gg ??????Rr */
  4931.                  tc.cci = 4;
  4932.                  break;
  4933.              } /* Else fall through */
  4934.          case _VRES16COLOR:
  4935.              cvuInc = 16;
  4936.              tc.ccv = 64;           /* ???????? ??????bb ??????gg ??????rr */
  4937.              tc.cci = 16;
  4938.              break;
  4939.          case _MRES4COLOR:
  4940.          case _MRESNOCOLOR:
  4941.              cvuInc = 32;
  4942.              tc.ccv = 16;           /* ???????? ??????Bb ??????Gg ??????Rr */
  4943.              tc.cci = 4;
  4944.              break;
  4945.          case _MRES16COLOR:
  4946.          case _HRES16COLOR:
  4947.              cvuInc = 32;
  4948.              tc.cci = tc.ccv = 16;  /* ???????? ??????Bb ??????Gg ??????Rr */
  4949.              break;
  4950.      }
  4951.  
  4952.      /* Fill palette arrays. */
  4953.      for( i = 0, cvuBlue = 0; cvuBlue < 64; cvuBlue += cvuInc )
  4954.          for( cvuGreen = 0; cvuGreen < 64; cvuGreen += cvuInc )
  4955.              for( cvuRed = 0; cvuRed < 64; cvuRed += cvuInc )
  4956.                  {
  4957.                      cvlColors[i] = RGB( cvuRed, cvuGreen, cvuBlue );
  4958.                      /* Special case of 6 bits for 16 colors (RGBI).
  4959.                       * If both bits are on for any color, intensity is set.
  4960.                       * If one bit is set for a color, that color is on.
  4961.                       */
  4962.                      if( cvuInc == 32 )
  4963.                          cvlColors[i + 8] = cvlColors[i] | (cvlColors[i] >> 1)
  4964.                      i++;
  4965.                  }
  4966.      cvlColors[tc.ccv - 1] = _BRIGHTWHITE;
  4967.      NextColorValue( DEFAULT );
  4968.      return Home();
  4969.  }
  4970.  
  4971.  /* Home - Resets turtle defaults. This function can be called if you have
  4972.   * not changed the video mode, but you want to put the turtle back in
  4973.   * the center of the window and restore all defaults. For example, you can
  4974.   * change the absolute window corners and then call it to set a new
  4975.   * turtle window.
  4976.   *
  4977.   * Params: None
  4978.   *
  4979.   * Return: 0 if fail, 1 if success
  4980.   *
  4981.   * Uses:   tc
  4982.   */
  4983.  short Home()
  4984.  {
  4985.      struct _wxycoord xy1, xy2;
  4986.  
  4987.      _setviewport( tc.xsLeft, tc.ysTop, tc.xsRight, tc.ysBot );
  4988.  
  4989.      /* Set the window based on screen height 1000 and width based on
  4990.       * aspect ratio.
  4991.       */
  4992.      tc.yMax = 500.0;
  4993.      tc.xMax = tc.yMax * tc.yxRatio;
  4994.      if( !_setwindow( FALSE, -tc.xMax, -tc.yMax, tc.xMax, tc.yMax ) )
  4995.          return 0;
  4996.  
  4997.      /* Calculate the unit size of 1 pixel using Y axis. */
  4998.      xy1 = _getwindowcoord( 1, 1 );
  4999.      xy2 = _getwindowcoord( 1, 2 );
  5000.      tc.yUnit = xy2.wy - xy1.wy;
  5001.  
  5002.      /* Set defaults for current pixel, angle, pen state and fill state. */
  5003.      tc.xCur = tc.yCur = 0.0;
  5004.      _moveto_w( tc.xCur, tc.yCur );
  5005.      TurnTo( 0 );
  5006.      PenDown( TRUE );
  5007.      SetFill( FALSE );
  5008.  
  5009.      /* Make white the last color index and set pen and border to it. */
  5010.      _remappalette( WHITE, _BRIGHTWHITE );
  5011.      BorderColor( WHITE );
  5012.      PenColor( WHITE );
  5013.      _setbkcolor( _BLACK );
  5014.      return 1;
  5015.  }
  5016.  
  5017.  /* PenDown - Sets the visibility of the pen used by Move and MoveTo. The
  5018.   * state can be TRUE (visible), FALSE (invisible), or DEFAULT (return
  5019.   * current without changing).
  5020.   *
  5021.   * Params: fPenDown
  5022.   *
  5023.   * Return: current pen state
  5024.   *
  5025.   * Uses:   tc
  5026.   */
  5027.  int PenDown( int fPenDown )
  5028.  {
  5029.      switch( fPenDown )
  5030.      {
  5031.          case DEFAULT:
  5032.              break;
  5033.          case FALSE:
  5034.              tc.fPenDown = FALSE;
  5035.              break;
  5036.          default:
  5037.              tc.fPenDown = TRUE;
  5038.              break;
  5039.      }
  5040.      return tc.fPenDown;
  5041.  }
  5042.  
  5043.  /* SetFill - Determines the state of filling figures such as Rectangle,
  5044.   * Circle, and Ellipse. State can be TRUE (fill inside), FALSE (border
  5045.   * only), or DEFAULT (return current fill state).
  5046.   *
  5047.   * Params: fFill
  5048.   *
  5049.   * Return: current fill state
  5050.   *
  5051.   * Uses:   tc
  5052.   */
  5053.  short SetFill( short fFill )
  5054.  {
  5055.      switch( fFill )
  5056.      {
  5057.          case DEFAULT:
  5058.              break;
  5059.          case _GBORDER:
  5060.          case FALSE:
  5061.              tc.fFill = _GBORDER;
  5062.              break;
  5063.          default:
  5064.              tc.fFill = _GFILLINTERIOR;
  5065.              break;
  5066.      }
  5067.      return tc.fFill;
  5068.  }
  5069.  
  5070.  /* PenColor - Sets the color index of the pen.
  5071.   *
  5072.   * Params: ciCur - any color index of DEFAULT to return without changing
  5073.   *
  5074.   * Return: current pen color index
  5075.   *
  5076.   * Uses:   tc
  5077.   */
  5078.  short PenColor( short ciCur )
  5079.  {
  5080.      if( ciCur != DEFAULT )
  5081.          _setcolor( tc.ciCur = ciCur );
  5082.      return tc.ciCur;
  5083.  }
  5084.  
  5085.  /* BorderColor - Sets the color index of the border that will be recognized
  5086.   * by fills.
  5087.   *
  5088.   * Params: ciBorder - any color index of DEFAULT to return without changing
  5089.   *
  5090.   * Return: current border color index
  5091.   *
  5092.   * Uses:   tc
  5093.   */
  5094.  short BorderColor( short border )
  5095.  {
  5096.      if( border != DEFAULT )
  5097.          tc.ciBorder = border;
  5098.      return tc.ciBorder;
  5099.  }
  5100.  
  5101.  /* Turn - Sets a new direction relative to the current direction.
  5102.   *
  5103.   * Params: angCur - a positive (clockwise) or negative (counterclockwise)
  5104.   *           angle in degrees
  5105.   *
  5106.   * Return: new current absolute angle
  5107.   *
  5108.   * Uses:   tc
  5109.   */
  5110.  short Turn( short angCur )
  5111.  {
  5112.      return( tc.angCur = ((tc.angCur + angCur) % CIRCUMFERENCE) );
  5113.  }
  5114.  
  5115.  /* TurnTo - Sets a new absolute direction.
  5116.   *
  5117.   * Params: angCur - a positive (clockwise) or negative (counterclockwise)
  5118.   *           angle in degrees (0 points to 12 o'clock)
  5119.   *
  5120.   * Return: new current absolute angle
  5121.   *
  5122.   * Uses:   tc
  5123.   */
  5124.  short TurnTo( short angCur )
  5125.  {
  5126.      if( angCur < 0 )
  5127.          return( tc.angCur = 360 - (angCur % CIRCUMFERENCE) );
  5128.      else
  5129.          return( tc.angCur = angCur % CIRCUMFERENCE );
  5130.  }
  5131.  
  5132.  /* Move - Moves from the current position in the current direction for a
  5133.   * specified distance. A line is drawn if the pen is down. The current
  5134.   * position is reset to the destination.
  5135.   *
  5136.   * Params: dxy - difference between current xy and new xy
  5137.   *
  5138.   * Return: 0 if new position is off screen, nonzero if on screen
  5139.   *
  5140.   * Uses:   tc
  5141.   */
  5142.  short Move( double dxy )
  5143.  {
  5144.      double dx, dy;          /* Differences of X and Y */
  5145.      double angT;
  5146.  
  5147.      /* Calculate new X and Y positions. */
  5148.      angT = (tc.angCur - 90) * (PI / HALFCIRCUMFERENCE);
  5149.      dx = dxy * cos( angT );
  5150.      dy = dxy * sin( angT );
  5151.  
  5152.      /* Move, drawing if pen down, then update position */
  5153.      if( tc.fPenDown )
  5154.          _lineto_w( tc.xCur + dx, tc.yCur + dy );
  5155.      else
  5156.          _moveto_w( tc.xCur + dx, tc.yCur + dy );
  5157.      tc.xCur += dx;
  5158.      tc.yCur += dy;
  5159.      return OnScreen();
  5160.  }
  5161.  
  5162.  /* MoveTo - Moves from the current position to a specified position. A
  5163.   * line is drawn if the pen is down. The current position is reset to the
  5164.   * destination. The current direction is not changed.
  5165.   *
  5166.   * Params: x and y - destination position
  5167.   *
  5168.   * Return: 0 if new position is off screen, nonzero if on screen
  5169.   *
  5170.   * Uses:   tc
  5171.   */
  5172.  short MoveTo( double x, double y )
  5173.  {
  5174.      if( tc.fPenDown )
  5175.          _lineto_w( x, y );
  5176.      else
  5177.          _moveto_w( x, y );
  5178.      tc.xCur = x;
  5179.      tc.yCur = y;
  5180.      return OnScreen();
  5181.  }
  5182.  
  5183.  /* Poly - Draws a polygon.
  5184.   *
  5185.   * Params: cSide - count of polygon sides
  5186.   *         dxySide - distance of each side
  5187.   *
  5188.   * Return: 0 if any part of polygon is off screen, nonzero if on screen
  5189.   */
  5190.  short Poly( int cSide, double dxySide )
  5191.  {
  5192.      short i, angT, fPen, ret = TRUE;
  5193.  
  5194.      /* Make sure pen is down (restore pen state when done). */
  5195.      fPen = PenDown( TRUE );
  5196.  
  5197.      /* Calculate angle, then draw each side. */
  5198.      angT = 360 / cSide;
  5199.      for( i = 1; i <= cSide; i++ )
  5200.      {
  5201.          ret = Move( dxySide ) && ret;
  5202.          Turn( angT );
  5203.      }
  5204.      PenDown( fPen );
  5205.      return ret;
  5206.  }
  5207.  
  5208.  /* NextColorIndex - Rotate to next color index. First attribute (normally
  5209.   * background) and last attribute (white) are skipped.
  5210.   *
  5211.   * Params: ciCur - Specify DEFAULT to use color index from last call,
  5212.   *           or specify a new color to rotate from
  5213.   *
  5214.   * Return: rotated color index
  5215.   *
  5216.   * Uses:   tc
  5217.   */
  5218.  short NextColorIndex( short ciCur )
  5219.  {
  5220.      static short ciPrev = 0;    /* Static to retain index between calls */
  5221.  
  5222.      /* Assign new current if given. */
  5223.      if( ciCur != DEFAULT )
  5224.          ciPrev = ciCur;
  5225.  
  5226.      /* Toggle for two-color modes, rotate for multi-color modes. */
  5227.      if( tc.cci == 2 )
  5228.          return( ciPrev = !ciPrev );
  5229.      else
  5230.          return( ciPrev = (++ciPrev % (tc.cci - 1)) );
  5231.  }
  5232.  
  5233.  /* NextColorValue - Rotate to next color value for adapters (EGA
  5234.   * and higher) that support remappable palettes.
  5235.   *
  5236.   * Params: fAction - DEFAULT (rotate all) or LIMITED (rotate first 14 only)
  5237.   *
  5238.   * Return: None
  5239.   *
  5240.   * Uses:   tc
  5241.   */
  5242.  void NextColorValue( int fAction )
  5243.  {
  5244.      static int icvCur = 1;  /* Current index into color value array */
  5245.      static int ciCur = 1;   /* Current color index                  */
  5246.      int icvT;               /* Temporary index into color values    */
  5247.      int i;
  5248.  
  5249.      /* Ignore modes with no palette values. */
  5250.      if( !tc.fPalette || !tc.ccv )
  5251.          return;
  5252.  
  5253.      /* Increment and rotate color value index. */
  5254.      icvT = (++icvCur % (tc.ccv - 2)) + 1;
  5255.  
  5256.  
  5257.      /* DEFAULT - Remap all color indexes, 14 at a time. For most modes,
  5258.       * this is all the indexes  except first and last. For 256-color
  5259.       * mode, rotating all available indexes would be too slow.
  5260.       */
  5261.      if( fAction == DEFAULT )
  5262.          for( i = 1; i <= 14; i++ )
  5263.              _remappalette( (ciCur++ % (tc.cci - 2)) + 1,
  5264.                             cvlColors[(icvT++ % (tc.ccv - 2)) + 1] );
  5265.  
  5266.      /* LIMITED - Rotate only the first 14 color indexes. */
  5267.      else
  5268.          for( i = 1; i <= 14; i++ )
  5269.              _remappalette( i, cvlColors[(icvT++ % (tc.ccv - 1)) + 1] );
  5270.  }
  5271.  Microsoft Quick-C Sample Code
  5272.  
  5273.  
  5274.  ARGV.C
  5275.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\ARGV.C
  5276.  
  5277.  /* ARGV.C: Demonstrate accessing command-line arguments. */
  5278.  #include <stdio.h>
  5279.  
  5280.  void show_args( char *argument );
  5281.  
  5282.  int main( int argc, char *argv[] )
  5283.  {
  5284.     int count;
  5285.     for( count=0; count < argc; count++ )
  5286.        show_args( argv[count] );
  5287.     return 0;
  5288.  }
  5289.  
  5290.  void show_args( char *argument )
  5291.  {
  5292.     printf( "%s\n", argument );
  5293.  }
  5294.  
  5295.  
  5296.  ARGV1.C
  5297.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\ARGV1.C
  5298.  
  5299.  /* ARGV1.C: Demonstrate null pointers. */
  5300.  #include <stdio.h>
  5301.  
  5302.  void show_args( char *argument );
  5303.  
  5304.  int main( int argc, char **argv )
  5305.  {
  5306.     while( *argv )
  5307.        show_args( *(argv++) );
  5308.     return 0;
  5309.  }
  5310.  
  5311.  void show_args( char *argument )
  5312.  {
  5313.     printf( "%s\n", argument );
  5314.  }
  5315.  
  5316.  
  5317.  ARRAY.C
  5318.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\ARRAY.C
  5319.  
  5320.  /* ARRAY.C: Demonstrate one-dimensional array. */
  5321.  #include <stdio.h>
  5322.  
  5323.  main()
  5324.  {
  5325.     int j;
  5326.     int i_array[3];
  5327.  
  5328.     i_array[0] = 176;
  5329.     i_array[1] = 4069;
  5330.     i_array[2] = 303;
  5331.  
  5332.     printf( "--- Values --------     --- Addresses -------\n\n" );
  5333.  
  5334.     for( j = 0; j < 3; j = j + 1 )
  5335.     {
  5336.        printf( "i_array[%d] = %d", j, i_array[j] );
  5337.        printf( "\t&i_array[%d] = %u\n", j, &i_array[j] );
  5338.     }
  5339.  
  5340.  }
  5341.  
  5342.  
  5343.  BAR.C
  5344.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\BAR.C
  5345.  
  5346.  /* BAR.C:  Create sample bar chart. */
  5347.  #include <conio.h>
  5348.  #include <string.h>
  5349.  #include <graph.h>
  5350.  #include <pgchart.h>
  5351.  #define MONTHS 12
  5352.  typedef enum {FALSE, TRUE} boolean;
  5353.  float far value[MONTHS] =
  5354.  {
  5355.     33.0, 27.0, 42.0, 64.0,106.0,157.0,
  5356.    182.0,217.0,128.0, 62.0, 43.0, 36.0
  5357.  };
  5358.  char far *category[MONTHS] =
  5359.  {
  5360.    "Jan", "Feb", "Mar", "Apr",
  5361.    "May", "Jun", "Jly", "Aug",
  5362.    "Sep", "Oct", "Nov", "Dec"
  5363.  };
  5364.  
  5365.  main()
  5366.  {
  5367.    chartenv env;
  5368.    int mode = _VRES16COLOR;
  5369.    /* Set highest video mode available */
  5370.    while(!_setvideomode( mode ))
  5371.       mode--;
  5372.    if(mode == _TEXTMONO)
  5373.       return(0);
  5374.  
  5375.    /* Initialize chart library and a default bar chart */
  5376.    _pg_initchart();
  5377.  
  5378.    _pg_defaultchart( &env, _PG_BARCHART, _PG_PLAINBARS
  5379.  );
  5380.    /* Add titles and some chart options */
  5381.    strcpy( env.maintitle.title, "Good Neighbor Grocery" );
  5382.    env.maintitle.titlecolor = 6;
  5383.    env.maintitle.justify = _PG_RIGHT;
  5384.    strcpy( env.subtitle.title, "Orange Juice Sales" );
  5385.    env.subtitle.titlecolor = 6;
  5386.    env.subtitle.justify = _PG_RIGHT;
  5387.    strcpy( env.yaxis.axistitle.title, "Months" );
  5388.    strcpy( env.xaxis.axistitle.title, "Quantity (cases)" );
  5389.    env.chartwindow.border = FALSE;
  5390.  
  5391.    /* Parameters for call to _pg_chart are:
  5392.     *    env        - Environment variable
  5393.     *    category   - Category labels
  5394.     *    value      - Data to chart
  5395.     *    MONTHS     - Number of data values */
  5396.  
  5397.    if(_pg_chart( &env, category, value, MONTHS ))
  5398.    {
  5399.       _setvideomode( _DEFAULTMODE );
  5400.       _outtext( "Error:  can't draw chart" );
  5401.    }
  5402.    else
  5403.    {
  5404.        getch();
  5405.        _setvideomode( _DEFAULTMODE );
  5406.     }
  5407.     return(0);
  5408.  }
  5409.  
  5410.  
  5411.  BEEP.C
  5412.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\BEEP.C
  5413.  
  5414.  /* BEEP.C: Demonstrate simple function */
  5415.  #include <stdio.h>
  5416.  
  5417.  void beep( void);
  5418.  
  5419.  main()
  5420.  {
  5421.     printf( "Time to beep\n" );
  5422.     beep();
  5423.     printf( "All done\n" );
  5424.  }
  5425.  
  5426.  void beep( void )
  5427.  {
  5428.     printf( "Beep!\a\n" );
  5429.  }
  5430.  
  5431.  
  5432.  BEEP1.C
  5433.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\BEEP1.C
  5434.  
  5435.  /* BEEP1.C: Demonstrate passing arguments */
  5436.  #include <stdio.h>
  5437.  
  5438.  void beep( int num_beep );
  5439.  
  5440.  main()
  5441.  {
  5442.     printf( "Time to beep\n" );
  5443.     beep( 5 );
  5444.     printf( "All done\n" );
  5445.  }
  5446.  
  5447.  void beep( int num_beep )
  5448.  {
  5449.     while( num_beep > 0  )
  5450.     {
  5451.        printf( "Beep!\a\n" );
  5452.        num_beep = num_beep - 1;
  5453.     }
  5454.  }
  5455.  
  5456.  
  5457.  BEEPER.C
  5458.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\BEEPER.C
  5459.  
  5460.  /* BEEPER.C: Demonstrate simple function */
  5461.  #include <stdio.h>
  5462.  
  5463.  void beep( void);
  5464.  
  5465.  main()
  5466.  {
  5467.     printf( "Time to beep\n" );
  5468.     beep();
  5469.     printf( "All done\n" );
  5470.  }
  5471.  
  5472.  void beep( void )
  5473.  {
  5474.     printf( "Beep!\a\n" );
  5475.  }
  5476.  
  5477.  
  5478.  BEEPER1.C
  5479.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\BEEPER1.C
  5480.  
  5481.  /* BEEPER1.C: Demonstrate passing arguments */
  5482.  #include <stdio.h>
  5483.  
  5484.  void beep( int num_beep );
  5485.  
  5486.  main()
  5487.  {
  5488.     printf( "Time to beep\n" );
  5489.     beep( 5 );
  5490.     printf( "All done\n" );
  5491.  }
  5492.  
  5493.  void beep( int num_beep )
  5494.  {
  5495.     while( num_beep > 0  )
  5496.     {
  5497.        printf( "Beep!\a\n" );
  5498.        num_beep = num_beep - 1;
  5499.     }
  5500.  }
  5501.  
  5502.  
  5503.  BITWISE.C
  5504.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\BITWISE.C
  5505.  
  5506.  /* BITWISE.C: Demonstrate bitwise operators. */
  5507.  #include <stdio.h>
  5508.  
  5509.  main()
  5510.  {
  5511.     printf( "255 & 15 = %d\n", 255 & 15 );
  5512.     printf( "255 | 15 = %d\n", 255 | 15 );
  5513.     printf( "255 ^ 15 = %d\n", 255 ^ 15 );
  5514.     printf( "2 << 2   = %d\n", 2 << 2 );
  5515.     printf( "16 >> 2  = %d\n", 16 >> 2 );
  5516.     printf( "~2       = %d\n", ~2 );
  5517.  }
  5518.  
  5519.  
  5520.  BREAKER.C
  5521.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\BREAKER.C
  5522.  
  5523.  /* BREAKER.C: Demonstrate break statement. */
  5524.  
  5525.  #include <stdio.h>
  5526.  #include <conio.h>
  5527.  
  5528.  main()
  5529.  {
  5530.     char ch;
  5531.     printf( "Press any key. Press Tab to quit.\n" );
  5532.     while( 1 )
  5533.     {
  5534.        ch = getche();
  5535.        if( ch == '\t' )
  5536.        {
  5537.           printf( "\a\nYou pressed Tab\n" );
  5538.           break;
  5539.        }
  5540.     }
  5541.  }
  5542.  
  5543.  
  5544.  BREAKER1.C
  5545.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\BREAKER1.C
  5546.  
  5547.  /* BREAKER1.C: Break only exits one loop. */
  5548.  
  5549.  #include <stdio.h>
  5550.  #include <conio.h>
  5551.  
  5552.  main()
  5553.  {
  5554.     char ch;
  5555.     printf( "Press any key. Press Enter to quit.\n" );
  5556.     do
  5557.     {
  5558.        while( ( ch = getche() ) != '\r' )
  5559.        {
  5560.           if( ch == '\t' )
  5561.           {
  5562.              printf( "\a\nYou pressed Tab\n" );
  5563.              break;
  5564.           }
  5565.        }
  5566.     } while( ch != '\r' );
  5567.     printf( "\nBye bye." );
  5568.  }
  5569.  
  5570.  
  5571.  CGA.C
  5572.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\CGA.C
  5573.  
  5574.  /* CGA.C: Demonstrates CGA colors */
  5575.  #include <stdio.h>
  5576.  #include <graph.h>
  5577.  #include <conio.h>
  5578.  
  5579.  long bkcolor[8] =
  5580.     {_BLACK, _BLUE, _GREEN, _CYAN,
  5581.      _RED, _MAGENTA, _BROWN, _WHITE};
  5582.  
  5583.  char *bkcolor_name [] =
  5584.     {"_BLACK", "_BLUE", "_GREEN", "_CYAN",
  5585.     "_RED", "_MAGENTA", "_BROWN", "_WHITE"};
  5586.  
  5587.  main()
  5588.  {
  5589.     int i, j, k;
  5590.     _setvideomode( _MRES4COLOR );
  5591.     for( i=0; i<= 3; i++ )
  5592.     {
  5593.        _selectpalette( i );
  5594.        for( k=0; k <= 7; k++ )
  5595.        {
  5596.           _setbkcolor( bkcolor[k] );
  5597.           for( j=0; j<=3; j++ )
  5598.           {
  5599.              _settextposition( 1, 1 );
  5600.              printf( "background color: %8s\n", bkcolor_name[k] );
  5601.              printf( "palette: %d\ncolor: %d\n", i, j );
  5602.              _setcolor( j );
  5603.              _rectangle( _GFILLINTERIOR, 160, 100, 320, 200 );
  5604.                 getch();
  5605.           }
  5606.        }
  5607.     }
  5608.     _setvideomode( _DEFAULTMODE );
  5609.  }
  5610.  
  5611.  
  5612.  COLOR.C
  5613.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\COLOR.C
  5614.  
  5615.   /* COLOR.C: Sets a medium resolution mode with maximum color choices */
  5616.  #include <stdio.h>
  5617.  #include <stdlib.h>
  5618.  #include <graph.h>
  5619.  #include <conio.h>
  5620.  struct videoconfig vc;
  5621.  
  5622.  main()
  5623.  {
  5624.     if( _setvideomode( _MRES256COLOR ) )
  5625.        ;
  5626.     else if( _setvideomode( _MRES16COLOR ) )
  5627.        ;
  5628.     else if( _setvideomode( _MRES4COLOR ) )
  5629.        ;
  5630.     else   {
  5631.        printf( "Error: No color graphics capability\n" );
  5632.        exit( 0 );
  5633.     }
  5634.  
  5635.     _getvideoconfig( &vc );
  5636.  
  5637.     printf( "%d available colors\n", vc.numcolors );
  5638.     printf( "%d horizontal pixels\n", vc.numxpixels );
  5639.     printf( "%d vertical pixels\n", vc.numypixels );
  5640.  
  5641.     getch();
  5642.     _clearscreen( _GCLEARSCREEN );
  5643.     _setvideomode( _DEFAULTMODE );
  5644.  }
  5645.  
  5646.  
  5647.  COLTEXT.C
  5648.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\COLTEXT.C
  5649.  
  5650.  /* COLTEXT.C: Displays text in color */
  5651.  #include <stdio.h>
  5652.  #include <conio.h>
  5653.  #include <graph.h>
  5654.  
  5655.  char buffer [80];
  5656.  
  5657.  main()
  5658.  {
  5659.     int blink,fgd;
  5660.     long bgd;
  5661.  
  5662.     _clearscreen( _GCLEARSCREEN );
  5663.     printf( "Text color attributes:\n" );
  5664.  
  5665.     for( blink=0; blink<=16; blink+=16 )
  5666.     {
  5667.        for( bgd=0; bgd<8; bgd++ )
  5668.        {
  5669.           _setbkcolor( bgd );
  5670.           _settextposition( bgd + ((blink / 16) * 9) + 3, 1 );
  5671.           _settextcolor( 7 );
  5672.           sprintf( buffer, "Bgd: %d Fgd:", bgd );
  5673.           _outtext( buffer );
  5674.  
  5675.           for( fgd=0; fgd<16; fgd++ )
  5676.           {
  5677.              _settextcolor( fgd+blink );
  5678.              sprintf( buffer, " %2d ", fgd+blink );
  5679.              _outtext( buffer );
  5680.           }
  5681.        }
  5682.     }
  5683.     getch();
  5684.     _setvideomode( _DEFAULTMODE );
  5685.  }
  5686.  
  5687.  
  5688.  CONT.C
  5689.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\CONT.C
  5690.  
  5691.  /* CONT.C: Demonstrate continue statement. */
  5692.  #include <stdio.h>
  5693.  
  5694.  main()
  5695.  {
  5696.     int count;
  5697.     for( count = 0; count < 10; count++ )
  5698.     {
  5699.        if( count > 3 )
  5700.           continue;
  5701.        printf( "count = %d\n", count );
  5702.     }
  5703.     printf( "Done!\n" );
  5704.  }
  5705.  
  5706.  
  5707.  CONVERT.C
  5708.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\CONVERT.C
  5709.  
  5710.  /* CONVERT.C: Demonstrate type conversions. */
  5711.  #include <stdio.h>
  5712.  
  5713.  main()
  5714.  {
  5715.     char c_val = 10;
  5716.     int i_val = 20;
  5717.     long l_val = 64000;
  5718.     float f_val = 3.1;
  5719.     int result;
  5720.  
  5721.     result = c_val + i_val + l_val + f_val;  /* Error! */
  5722.  
  5723.     printf( "%d\n", result );
  5724.  }
  5725.  
  5726.  
  5727.  COPYFILE.C
  5728.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\COPYFILE.C
  5729.  
  5730.  /* COPYFILE.C: Demonstrate malloc and free functions */
  5731.  
  5732.  <stdio.h>     /* printf function and NULL */
  5733.  <io.h>        /* low-level I/O functions */
  5734.  <conio.h>     /* getch function */
  5735.  <sys\types.h> /* struct members used in stat.h */
  5736.  <sys\stat.h>  /* S_ constants */
  5737.  <fcntl.h>     /* O_ constants */
  5738.  <malloc.h>    /* malloc function */
  5739.  <errno.h>     /* errno global variable */
  5740.  
  5741.  int copyfile( char *source, char *destin );
  5742.  
  5743.  main( int argc, char *argv[] )
  5744.  {
  5745.     if( argc == 3 )
  5746.        if( copyfile( argv[1], argv[2] ) )
  5747.           printf( "Copy failed\n" );
  5748.        else
  5749.           printf( "Copy successful\n" );
  5750.     else
  5751.        printf( "  SYNTAX: COPYFILE <source> <target>\n" );
  5752.  
  5753.     return 0;
  5754.  }
  5755.  
  5756.  int copyfile( char *source, char *target )
  5757.  {
  5758.     char *buf;
  5759.     int hsource, htarget, ch;
  5760.     unsigned count = 50000;
  5761.  
  5762.     if( (hsource = open( source, O_BINARY | O_RDONLY )) == - 1 )
  5763.        return errno;
  5764.     htarget = open( target, O_BINARY | O_WRONLY | O_CREAT | O_EXCL,
  5765.                             S_IREAD | S_IWRITE );
  5766.     if( errno == EEXIST )
  5767.     {
  5768.        cputs( "Target exists. Overwrite? " );
  5769.        ch = getch();
  5770.        if( (ch == 'y') || (ch == 'Y') )
  5771.           htarget = open( target, O_BINARY | O_WRONLY | O_CREAT | O_TRUNC,
  5772.                                   S_IREAD | S_IWRITE );
  5773.        printf( "\n" );
  5774.     }
  5775.     if( htarget == -1 )
  5776.        return errno;
  5777.  
  5778.     if( filelength( hsource ) < count )
  5779.        count = (int)filelength( hsource );
  5780.  
  5781.     buf = (char *)malloc( (size_t)count );
  5782.  
  5783.     if( buf == NULL )
  5784.     {
  5785.        count = _memmax();
  5786.        buf = (char *)malloc( (size_t)count );
  5787.        if( buf == NULL )
  5788.           return ENOMEM;
  5789.     }
  5790.  
  5791.     while( !eof( hsource ) )
  5792.     {
  5793.        if( (count = read( hsource, buf, count )) == -1 )
  5794.           return errno;
  5795.        if( (count = write( htarget, buf, count )) == - 1 )
  5796.           return errno;
  5797.     }
  5798.  
  5799.     close( hsource );
  5800.     close( htarget );
  5801.     free( buf );
  5802.     return 0;
  5803.  }
  5804.  
  5805.  
  5806.  DECRMENT.C
  5807.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\DECRMENT.C
  5808.  
  5809.  /* DECRMENT.C: Demonstrate prefix and postfix operators. */
  5810.  #include <stdio.h>
  5811.  
  5812.  main()
  5813.  {
  5814.     int val, sample = 3, proton = 3;
  5815.     val = sample--;
  5816.     printf( "val = %d  sample = %d\n", val, sample );
  5817.     val = --proton;
  5818.     printf( "val = %d  proton = %d\n", val, proton );
  5819.  }
  5820.  
  5821.  
  5822.  DEFINED.C
  5823.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\DEFINED.C
  5824.  
  5825.  /* DEFINED.C: Demonstrate defined operator. */
  5826.  
  5827.  #define DEBUG 12345
  5828.  
  5829.  main()
  5830.  {
  5831.     #if defined( DEBUG )
  5832.        printf( "Hi\n" );
  5833.     #endif
  5834.  }
  5835.  
  5836.  
  5837.  DO.C
  5838.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\DO.C
  5839.  
  5840.  /* DO.C: Demonstrate do loop. */
  5841.  
  5842.  #include <stdio.h>
  5843.  
  5844.  main()
  5845.  {
  5846.     int test = 10;
  5847.     do
  5848.     {
  5849.        printf( "test = %d\n", test );
  5850.        test = test - 2;
  5851.     }  while( test > 0 );
  5852.  }
  5853.  
  5854.  
  5855.  EGA.C
  5856.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\EGA.C
  5857.  
  5858.  /* EGA.C: Demonstrates EGA palettes */
  5859.  #include <stdio.h>
  5860.  #include <conio.h>
  5861.  #include <graph.h>
  5862.  
  5863.  main()
  5864.  {
  5865.     _setvideomode( _ERESCOLOR );
  5866.     _setcolor( 4 );
  5867.     _rectangle( _GFILLINTERIOR, 50, 50, 200, 200 );
  5868.  
  5869.     _settextposition( 1, 1 );
  5870.     printf( "Normal palette\n" );
  5871.     printf( "Press a key" );
  5872.     getch();
  5873.  
  5874.     _remappalette( 4, _BLUE );
  5875.  
  5876.     _settextposition( 1, 1 );
  5877.     printf( "Remapped palette\n" );
  5878.     printf( "Press a key" );
  5879.     getch();
  5880.  
  5881.     _remappalette( 4, _RED );
  5882.  
  5883.     _settextposition( 1, 1 );
  5884.     printf( "Restored palette\n" );
  5885.     printf( "Press a key to clear the screen" );
  5886.     getch();
  5887.  
  5888.     _clearscreen( _GCLEARSCREEN );
  5889.     _setvideomode( _DEFAULTMODE );
  5890.  }
  5891.  
  5892.  
  5893.  ELSE.C
  5894.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\ELSE.C
  5895.  
  5896.  /* ELSE.C: Demonstrate else clause. */
  5897.  
  5898.  #include <stdio.h>
  5899.  #include <conio.h>
  5900.  
  5901.  main()
  5902.  {
  5903.     char ch;
  5904.     printf( "Press the b key to hear a bell.\n" );
  5905.     ch = getch();
  5906.     if( ch == 'b' )
  5907.        printf( "Beep!\a\n" );
  5908.     else
  5909.        printf( "Bye bye\n" );
  5910.  }
  5911.  
  5912.  
  5913.  ELSE1.C
  5914.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\ELSE1.C
  5915.  
  5916.  /* ELSE1.C: Demonstrate else-if construct. */
  5917.  
  5918.  #include <stdio.h>
  5919.  #include <conio.h>
  5920.  
  5921.  main()
  5922.  {
  5923.     char ch;
  5924.     printf( "Press the b key to hear a bell.\n" );
  5925.     ch = getch();
  5926.     if( ch == 'b' )
  5927.        printf( "Beep!\a\n" );
  5928.     else
  5929.        if( ch == '\r' )
  5930.           printf( "Enter\n" );
  5931.     else
  5932.        printf( "Bye bye\n" );
  5933.  }
  5934.  
  5935.  
  5936.  EMPLOY1.C
  5937.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\EMPLOY1.C
  5938.  
  5939.  /* EMPLOY1.C: Demonstrate structure pointers. */
  5940.  #include <stdio.h>
  5941.  
  5942.  
  5943.  struct employee
  5944.  {
  5945.     char name[10];
  5946.     int months;
  5947.     float wage;
  5948.  };
  5949.  
  5950.  void display( struct employee *e_ptr  );
  5951.  
  5952.  main()
  5953.  {
  5954.     static struct employee jones =
  5955.        {
  5956.        "Jones, J",
  5957.        77,
  5958.        13.68
  5959.        };
  5960.  
  5961.     display( &jones );
  5962.  }
  5963.  
  5964.  void display( struct employee *e_ptr )
  5965.  {
  5966.     printf( "Name: %s\n", e_ptr->name );
  5967.     printf( "Months of service: %d\n", e_ptr->months );
  5968.     printf( "Hourly wage: %6.2f\n", e_ptr->wage );
  5969.  }
  5970.  
  5971.  
  5972.  EMPLOYEE.C
  5973.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\EMPLOYEE.C
  5974.  
  5975.  /* EMPLOYEE.C: Demonstrate structures. */
  5976.  #include <stdio.h>
  5977.  #include <string.h>
  5978.  
  5979.  struct employee
  5980.  {
  5981.     char name[10];
  5982.     int months;
  5983.     float wage;
  5984.  };
  5985.  
  5986.  void display( struct employee show );
  5987.  
  5988.  main()
  5989.  {
  5990.     struct employee jones;
  5991.  
  5992.     strcpy( jones.name, "Jones, J" );
  5993.     jones.months = 77;
  5994.     jones.wage = 13.68;
  5995.  
  5996.     display( jones );
  5997.  }
  5998.  
  5999.  void display( struct employee show )
  6000.  {
  6001.     printf( "Name: %s\n", show.name );
  6002.     printf( "Months of service: %d\n", show.months );
  6003.     printf( "Hourly wage: %6.2f\n", show.wage );
  6004.  }
  6005.  
  6006.  
  6007.  FILE1.C
  6008.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\FILE1.C
  6009.  
  6010.  /* FILE1.C: Visibility in multiple source files.
  6011.  */
  6012.  
  6013.  int chico = 20, harpo = 30;
  6014.  extern void yonder( void );
  6015.  
  6016.  main()
  6017.  {
  6018.     yonder();
  6019.  }
  6020.  
  6021.  
  6022.  FILE2.C
  6023.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\FILE2.C
  6024.  
  6025.  /* FILE2.C: Visibility in multiple source files.
  6026.  */
  6027.  
  6028.  #include <stdio.h>
  6029.  
  6030.  void yonder( void )
  6031.  {
  6032.     extern int chico, harpo;
  6033.     printf( "chico = %d, harpo = %d\n", chico, harpo );
  6034.  }
  6035.  
  6036.  
  6037.  FORLOOP.C
  6038.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\FORLOOP.C
  6039.  
  6040.  /* FORLOOP.C: Demonstrate for loop. */
  6041.  
  6042.  #include <stdio.h>
  6043.  
  6044.  main()
  6045.  {
  6046.     int test;
  6047.     for( test = 10; test > 0; test = test - 2 )
  6048.        printf( "test = %d\n", test );
  6049.  }
  6050.  
  6051.  
  6052.  FORLOOP1.C
  6053.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\FORLOOP1.C
  6054.  
  6055.  /* FORLOOP1.C: Demonstrate multiple expressions. */
  6056.  
  6057.  #include <stdio.h>
  6058.  
  6059.  main()
  6060.  {
  6061.     int a, b;
  6062.     for( a = 256, b = 1; b < 512; a = a / 2, b = b * 2 )
  6063.        printf( "a = %d  b = %d\n", a, b );
  6064.  }
  6065.  
  6066.  
  6067.  FORLOOP2.C
  6068.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\FORLOOP2.C
  6069.  
  6070.  /* FORLOOP2.C: Demonstrate similarity of for and while.
  6071.  */
  6072.  
  6073.  #include <stdio.h>
  6074.  
  6075.  main()
  6076.  {
  6077.     int count;
  6078.  
  6079.     for( count = 0; count < 10; count++ )
  6080.        printf( "count = %d\n", count );
  6081.  
  6082.     count = 0;
  6083.     while( count < 10 )
  6084.     {
  6085.        printf( "count = %d\n", count );
  6086.        count++;
  6087.     }
  6088.  
  6089.  }
  6090.  
  6091.  
  6092.  FUNCPTR.C
  6093.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\FUNCPTR.C
  6094.  
  6095.  /* FUNCPTR.C: Demonstrate function pointers. */
  6096.  #include <stdio.h>
  6097.  
  6098.  main()
  6099.  {
  6100.     int (*func_ptr) ();
  6101.     func_ptr = printf;
  6102.     (*func_ptr) ( "Curiouser and curiouser...\n" );
  6103.  }
  6104.  
  6105.  
  6106.  FUNCPTR1.C
  6107.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\FUNCPTR1.C
  6108.  
  6109.  /* FUNCPTR1.C: Passing function pointers as arguments. */
  6110.  #include <stdio.h>
  6111.  
  6112.  void gimme_func( void (*func_ptr) () );
  6113.  
  6114.  main()
  6115.  {
  6116.     gimme_func( puts );
  6117.     gimme_func( printf );
  6118.  }
  6119.  
  6120.  void gimme_func( void (*func_ptr) () )
  6121.  {
  6122.     (*func_ptr) ( "Ausgezeichnet!" );
  6123.  }
  6124.  
  6125.  
  6126.  GRAPHIC.C
  6127.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\GRAPHIC.C
  6128.  
  6129.  /* GRAPHIC.C: Displays every graphics mode */
  6130.  #include <stdio.h>
  6131.  #include <graph.h>
  6132.  #include <conio.h>
  6133.  
  6134.  struct videoconfig screen;
  6135.  int modes[12] =
  6136.  {
  6137.     _MRES4COLOR, _MRESNOCOLOR, _HRESBW,
  6138.     _HERCMONO,
  6139.     _MRES16COLOR, _HRES16COLOR, _ERESNOCOLOR, _ERESCOLOR,
  6140.     _VRES2COLOR, _VRES16COLOR, _MRES256COLOR, _ORESCOLOR
  6141.  };
  6142.  
  6143.  void print_menu( void );
  6144.  void show_mode( char );
  6145.  
  6146.  main()
  6147.  {
  6148.     char key;
  6149.     print_menu();
  6150.     while( (key = getch()) != 'x' )
  6151.        show_mode( key );
  6152.  }
  6153.  
  6154.  void print_menu( void )
  6155.  {
  6156.     _setvideomode( _DEFAULTMODE );
  6157.     _clearscreen( _GCLEARSCREEN );
  6158.     printf( "Please choose a graphics mode\nType 'x' to exit.\n\n" );
  6159.     printf( "0 _MRES4COLOR\n1 _MRESNOCOLOR\n2 _HRESBW\n" );
  6160.     printf( "3 _HERCMONO\n4 _MRES16COLOR\n5 _HRES16COLOR\n" );
  6161.     printf( "6 _ERESNOCOLOR\n7 _ERESCOLOR\n" );
  6162.     printf( "8 _VRES2COLOR\n9 _VRES16COLOR\na _MRES256COLOR\n" );
  6163.     printf( "b _ORESCOLOR\n" );
  6164.  }
  6165.  
  6166.  void show_mode( char which )
  6167.  {
  6168.     int nc, i;
  6169.     int height, width;
  6170.     int mode = which;
  6171.  
  6172.     if( mode < '0' || mode > '9' )
  6173.        if( mode == 'a' )
  6174.           mode = '9' + 1;
  6175.        else if( mode == 'b' )
  6176.           mode = '9' + 2;
  6177.        else
  6178.           return;
  6179.  
  6180.     if( _setvideomode( modes[mode - '0'] ) )
  6181.     {
  6182.        _getvideoconfig( &screen );
  6183.        nc = screen.numcolors;
  6184.        width = screen.numxpixels/nc;
  6185.        height = screen.numypixels/2;
  6186.        for( i = 0; i < nc; i++ )
  6187.        {
  6188.           _setcolor( i );
  6189.           _rectangle( _GFILLINTERIOR, i * width, 0, (i + 1) * width, height );
  6190.        }
  6191.     }
  6192.     else
  6193.     {
  6194.        printf( " \nVideo mode %c is not available.\n", which);
  6195.        printf( "Please press a key.\n" );
  6196.     }
  6197.     getch();
  6198.     _setvideomode( _DEFAULTMODE );
  6199.     print_menu();
  6200.  }
  6201.  
  6202.  
  6203.  HORIZON.C
  6204.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\HORIZON.C
  6205.  
  6206.  /* HORIZON.C: VGA graphics with cycling of 256 colors */
  6207.  #include <stdio.h>
  6208.  #include <stdlib.h>
  6209.  #include <conio.h>
  6210.  #include <graph.h>
  6211.  
  6212.  #define RED 0x0000003FL
  6213.  #define GRN 0x00003F00L
  6214.  #define BLU 0x003F0000L
  6215.  #define WHT 0x003F3F3FL
  6216.  #define STEP 21
  6217.  
  6218.  struct videoconfig screen;
  6219.  long int rainbow[512];
  6220.  
  6221.  main()
  6222.  {
  6223.     int i;
  6224.     long int col, gray;
  6225.  
  6226.     if( _setvideomode( _MRES256COLOR ) == 0 )
  6227.     {
  6228.        printf("This program requires a VGA card.\n" );
  6229.        exit( 0 );
  6230.     }
  6231.     for( col = 0; col < 64; col++ )
  6232.     {
  6233.        gray = col | (col << 8) | (col << 16);
  6234.        rainbow[col] = rainbow[col + 256] = BLU & gray;
  6235.        rainbow[col + 64] = rainbow[col + 64 + 256] = BLU | gray;
  6236.        rainbow[col + 128] = rainbow[col + 128 + 256] = RED | (WHT & ~gray);
  6237.        rainbow[col + 192] = rainbow[col + 192 + 256] = RED & ~gray;
  6238.     }
  6239.     _setvieworg( 160, 85 );
  6240.  
  6241.     for( i = 0; i < 255; i++ )
  6242.     {
  6243.        _setcolor( 255 - i );
  6244.        _moveto( i, i - 255 );
  6245.        _lineto( -i, 255 - i );
  6246.        _moveto( -i, i - 255 );
  6247.        _lineto( i, 255 - i );
  6248.        _ellipse( _GBORDER, -i, -i / 2, i, i / 2 );
  6249.     }
  6250.     for( i = 0; !kbhit(); i += STEP, i %= 256 )
  6251.        _remapallpalette( &(rainbow[i]) );
  6252.  
  6253.     _setvideomode( _DEFAULTMODE );
  6254.  }
  6255.  
  6256.  
  6257.  IFF.C
  6258.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\IFF.C
  6259.  
  6260.  /* IFF.C: Demonstrate if statement. */
  6261.  
  6262.  #include <stdio.h>
  6263.  #include <conio.h>
  6264.  
  6265.  main()
  6266.  {
  6267.     char ch;
  6268.     printf( "Press the b key to hear a bell.\n" );
  6269.     ch = getche();
  6270.     if( ch == 'b' )
  6271.        printf( "Beep!\a\n" );
  6272.  }
  6273.  
  6274.  
  6275.  INPUT.C
  6276.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\INPUT.C
  6277.  
  6278.  /* INPUT.C: Reads keyboard. */
  6279.  #include <stdio.h>
  6280.  #include <conio.h>
  6281.  #include <ctype.h>
  6282.  
  6283.  main()
  6284.  {
  6285.     int num, c;
  6286.     char name[80];
  6287.     float rb;
  6288.  
  6289.     puts( "** Type \"Name:\" and your name" );
  6290.     scanf( "Name: %40s", name );
  6291.     printf( "** You typed this:\n%s", name );
  6292.     puts( "\n\n** Try again, with the gets function." );
  6293.     fflush( stdin );
  6294.     gets( name );
  6295.     printf( "** You typed this:\n%s\n", name );
  6296.  
  6297.     printf( "\n** Now type an integer.\n" );
  6298.     scanf( "%i", &num );
  6299.     sprintf( name, "** You typed this number: %i\n", num );
  6300.     puts( name );
  6301.  
  6302.     fflush( stdin );
  6303.     printf( "** Enter a floating-point value.\n" );
  6304.     scanf( "%f", &rb );
  6305.     printf( "** The answer is %f or %e\n", rb, rb );
  6306.  
  6307.     printf( "** Continue? Y or N\n" );
  6308.  
  6309.     do
  6310.     {
  6311.        c = getch();
  6312.        c = tolower( c );
  6313.     } while( c != 'y' && c != 'n' );
  6314.  }
  6315.  
  6316.  
  6317.  MACRO.C
  6318.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\MACRO.C
  6319.  
  6320.  /* MACRO.C: Demonstrate macros. */
  6321.  
  6322.  #include <stdio.h>
  6323.  #define ABS(value)  ( (value) >= 0 ? (value) : -(value) )
  6324.  
  6325.  main()
  6326.  {
  6327.     int val = -20;
  6328.     printf( "result = %d\n", ABS(val) );
  6329.  }
  6330.  
  6331.  
  6332.  NFORMAT.C
  6333.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\NFORMAT.C
  6334.  
  6335.  /* NFORMAT.C: Prints numbers and a string. */
  6336.  #include <stdio.h>
  6337.  #include <string.h>
  6338.  
  6339.  main()
  6340.  {
  6341.     int    a = -765,
  6342.            b = 1,
  6343.            c = 44000,
  6344.            d = 33;
  6345.     float  e = 1.33E8,
  6346.            f = -0.1234567,
  6347.            g = 12345.6789,
  6348.            h = 1.0;
  6349.     char   i[80];
  6350.  
  6351.     strcpy( i, "word 1, word 2, word 3, word 4, word 5" );
  6352.  
  6353.     printf( "Unformatted:\n%d %d %d %d\n", a, b, c, d );
  6354.     printf( "%f %f %f %f\n", e, f, g, h );
  6355.     printf( "%s\n", i );
  6356.  }
  6357.  
  6358.  
  6359.  NOT.C
  6360.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\NOT.C
  6361.  
  6362.  /* NOT.C: Demonstrate logical NOT operator. */
  6363.  #include <stdio.h>
  6364.  
  6365.  main()
  6366.  {
  6367.    int val = 0;
  6368.    if( !val )
  6369.       printf( "val is zero" );
  6370.  }
  6371.  
  6372.  
  6373.  OLDSTYLE.C
  6374.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\OLDSTYLE.C
  6375.  
  6376.  /* OLDSTYLE.C: Old-style function. */
  6377.  #include <stdio.h>
  6378.  #define PI 3.14
  6379.  
  6380.  float sphere();
  6381.  
  6382.  main()
  6383.  {
  6384.     float volume;
  6385.     int radius = 3;
  6386.     volume = sphere( radius );
  6387.     printf( "Volume: %f\n", volume );
  6388.  }
  6389.  
  6390.  float sphere( rad )
  6391.  int rad;
  6392.  {
  6393.     float result;
  6394.     result = rad * rad * rad;
  6395.     result = 4 * PI * result;
  6396.     result = result / 3;
  6397.     return result;
  6398.  }
  6399.  
  6400.  
  6401.  PARRAY.C
  6402.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\PARRAY.C
  6403.  
  6404.  /* PARRAY.C: Demonstrate pointer to array. */
  6405.  #include <stdio.h>
  6406.  
  6407.  int i_array[] = { 25, 300, 2, 12 };
  6408.  
  6409.  main()
  6410.  {
  6411.     int *ptr;
  6412.     int count;
  6413.     ptr = &i_array[0];
  6414.     for( count = 0; count < 4 ; count++ )
  6415.     {
  6416.        printf( "i_array[%d] = %d\n", count, *ptr );
  6417.        ptr++;
  6418.     }
  6419.  }
  6420.  
  6421.  
  6422.  PARRAY1.C
  6423.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\PARRAY1.C
  6424.  
  6425.  /* PARRAY1.C: Compact version of PARRAY.C. */
  6426.  #include <stdio.h>
  6427.  
  6428.  int i_array[] = { 25, 300, 2, 12 };
  6429.  
  6430.  main()
  6431.  {
  6432.     int count;
  6433.     int *ptr = i_array;
  6434.     for( count = 0; count < 4 ; count++ )
  6435.        printf( "i_array[%d] = %d\n", count, *ptr++ );
  6436.  }
  6437.  
  6438.  
  6439.  PFUNC.C
  6440.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\PFUNC.C
  6441.  
  6442.  /* PFUNC.C: Passing pointers to a function. */
  6443.  #include <stdio.h>
  6444.  
  6445.  void swap( int *ptr1, int *ptr2 );
  6446.  
  6447.  main()
  6448.  {
  6449.     int first = 1, second = 3;
  6450.     int *ptr = &second;
  6451.     printf( "first: %d  second: %d\n", first, *ptr );
  6452.     swap( &first, ptr );
  6453.     printf( "first: %d  second: %d\n", first, *ptr );
  6454.  }
  6455.  
  6456.  void swap( int *ptr1, int *ptr2 )
  6457.  {
  6458.     int temp;
  6459.     temp = *ptr1;
  6460.     *ptr1 = *ptr2;
  6461.     *ptr2 = temp;
  6462.  }
  6463.  
  6464.  
  6465.  PIE.C
  6466.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\PIE.C
  6467.  
  6468.  /* PIE.C:  Create sample pie chart.  */
  6469.  #include <conio.h>
  6470.  #include <string.h>
  6471.  #include <graph.h>
  6472.  #include <pgchart.h>
  6473.  
  6474.  #define MONTHS 12
  6475.  
  6476.  typedef enum {FALSE, TRUE} boolean;
  6477.  
  6478.  float far value[MONTHS] =
  6479.  {
  6480.     33.0, 27.0, 42.0, 64.0,106.0,157.0,
  6481.    182.0,217.0,128.0, 62.0, 43.0, 36.0
  6482.  };
  6483.  char far *category[MONTHS] =
  6484.  {
  6485.    "Jan", "Feb", "Mar", "Apr",
  6486.    "May", "Jun", "Jly", "Aug",
  6487.    "Sep", "Oct", "Nov", "Dec"
  6488.  };
  6489.  short far explode[MONTHS] = {0};
  6490.  
  6491.  main()
  6492.  {
  6493.    chartenv env;
  6494.    int mode = _VRES16COLOR;
  6495.  
  6496.    /* Set highest video mode available */
  6497.    while(!_setvideomode( mode ))
  6498.       mode--;
  6499.    if(mode == _TEXTMONO)
  6500.       return( 0 );
  6501.  
  6502.    /* Initialize chart library and a default pie chart */
  6503.    _pg_initchart();
  6504.    _pg_defaultchart( &env, _PG_PIECHART, _PG_PERCENT );
  6505.  
  6506.    /* Add titles and some chart options */
  6507.    strcpy( env.maintitle.title, "Good Neighbor Grocery" );
  6508.    env.maintitle.titlecolor = 6;
  6509.    env.maintitle.justify = _PG_RIGHT;
  6510.    strcpy( env.subtitle.title, "Orange Juice Sales" );
  6511.    env.subtitle.titlecolor = 6;
  6512.    env.subtitle.justify = _PG_RIGHT;
  6513.    env.chartwindow.border = FALSE;
  6514.  
  6515.    /* Parameters for call to _pg_chartpie are:
  6516.     *
  6517.     *    env        - Environment variable
  6518.     *    category   - Category labels
  6519.     *    value      - Data to chart
  6520.     *    explode    - Separated pieces
  6521.     *    MONTHS     - Number of data values
  6522.     */
  6523.  
  6524.    if(_pg_chartpie( &env, category, value,
  6525.                      explode, MONTHS ))
  6526.    {
  6527.       _setvideomode( _DEFAULTMODE );
  6528.       _outtext( "Error:  can't draw chart" );
  6529.    }
  6530.    else
  6531.    {
  6532.       getch();
  6533.       _setvideomode( _DEFAULTMODE );
  6534.    }
  6535.    return( 0 );
  6536.  }
  6537.  
  6538.  
  6539.  POINTER.C
  6540.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\POINTER.C
  6541.  
  6542.  /* POINTER.C: Demonstrate pointer basics. */
  6543.  #include <stdio.h>
  6544.  
  6545.  main()
  6546.  {
  6547.     int val = 25;
  6548.     int *ptr;
  6549.     ptr = &val;
  6550.     printf( " val = %d\n", val );
  6551.     printf( "*ptr = %d\n\n", *ptr );
  6552.     printf( "&val = %u\n", &val );
  6553.     printf( " ptr = %d\n", ptr );
  6554.  }
  6555.  
  6556.  
  6557.  POWER2.C
  6558.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\POWER2.C
  6559.  
  6560.  /* POWER2.C */
  6561.  #include <stdio.h>
  6562.  
  6563.  int power2( int num, int power );
  6564.  
  6565.  void main( void )
  6566.  {
  6567.     printf( "3 times 2 to the power of 5 is %d\n", \
  6568.             power2( 3, 5) );
  6569.  }
  6570.  
  6571.  int power2( int num, int power )
  6572.  {
  6573.     _asm
  6574.     {
  6575.        mov ax, num    ; Get first argument
  6576.        mov cx, power  ; Get second argument
  6577.        shl ax, cl     ; AX = AX * ( 2 to the power of CL )
  6578.     }
  6579.     /* Return with result in AX */
  6580.  }
  6581.  
  6582.  
  6583.  PRTESC.C
  6584.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\PRTESC.C
  6585.  
  6586.  /* PRTESC.C: Prints escape characters \",\n, and \t. */
  6587.  #include <stdio.h>
  6588.  #include <string.h>
  6589.  
  6590.  main()
  6591.  {
  6592.     char b[80];
  6593.     int i,j;
  6594.  
  6595.     strcpy( b, "and seven years ago\n" );
  6596.     printf( "\"Four score\n" );
  6597.     printf( b );
  6598.     printf( "\tone tab\n\t\ttwo tabs\n\t\t\tthree tabs\n" );
  6599.     i = sizeof( b );
  6600.     j = strlen( b );
  6601.     printf( "Size is %d\nLength is %d.\n", i, j );
  6602.  }
  6603.  
  6604.  
  6605.  PRTSTR.C
  6606.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\PRTSTR.C
  6607.  
  6608.  /* PRTSTR.C: Prints strings. */
  6609.  #include <stdio.h>
  6610.  #include <string.h>
  6611.  
  6612.  main()
  6613.  {
  6614.     char aline[80], more[80];
  6615.     char *strptr;
  6616.  
  6617.     /* aline = "Another line."; */
  6618.     /* Note: This causes a compiler error */
  6619.  
  6620.     strcpy( aline, "Another line." );
  6621.     strcpy( more, aline );
  6622.     strptr = aline;
  6623.     strcat( aline, "dog" );
  6624.     printf( "A line of text." );
  6625.     printf( aline );
  6626.     printf( more );
  6627.     printf( strptr );
  6628.  }
  6629.  
  6630.  
  6631.  PSTRING.C
  6632.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\PSTRING.C
  6633.  
  6634.  /* PSTRING.C: Demonstrate pointer to a string. */
  6635.  
  6636.  #include <stdio.h>
  6637.  
  6638.  main()
  6639.  {
  6640.     int count;
  6641.     static char name[] = "john";
  6642.     char *ptr = name;
  6643.     for( count = 0; count < 4; count++ )
  6644.     {
  6645.        printf( "name[%d]: %c\n", count, *ptr++ );
  6646.     }
  6647.  }
  6648.  
  6649.  
  6650.  PSTRING1.C
  6651.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\PSTRING1.C
  6652.  
  6653.  /* PSTRING1.C: Look for null at string's end.  */
  6654.  #include <stdio.h>
  6655.  
  6656.  main()
  6657.  {
  6658.     char name[] = "john";
  6659.     char *ptr = name;
  6660.     while( *ptr )
  6661.        printf( "*ptr = %c\n", *ptr++ );
  6662.  }
  6663.  
  6664.  
  6665.  PSTRING2.C
  6666.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\PSTRING2.C
  6667.  
  6668.  /* PSTRING2.C: Demonstrate strings and array notation. */
  6669.  #include <stdio.h>
  6670.  #include <string.h>
  6671.  
  6672.  main()
  6673.  {
  6674.     int count;
  6675.     char name[] = "john";
  6676.     for( count = 0; count < strlen( name ); count++ )
  6677.        printf( "name[%d]: %c\n", count, name[count] );
  6678.  }
  6679.  
  6680.  
  6681.  PSTRING3.C
  6682.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\PSTRING3.C
  6683.  
  6684.  /* PSTRING3.C: Strings and pointer notation.  */
  6685.  #include <stdio.h>
  6686.  #include <string.h>
  6687.  
  6688.  main()
  6689.  {
  6690.     int count;
  6691.     char name[] = "john";
  6692.     for( count = 0; count < strlen( name ); count++ )
  6693.        printf( "*(name+%d) = %c\n", count, *(name+count) );
  6694.  }
  6695.  
  6696.  
  6697.  PTRPTR.C
  6698.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\PTRPTR.C
  6699.  
  6700.  /* PTRPTR.C: Demonstrate a pointer to a pointer. */
  6701.  #include <stdio.h>
  6702.  
  6703.  main()
  6704.  {
  6705.     int val = 501;
  6706.     int *ptr = &val;
  6707.     int **ptr_ptr = &ptr;
  6708.     printf( "val = %d\n", **ptr_ptr );
  6709.  }
  6710.  
  6711.  
  6712.  QCSORT.C
  6713.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\QCSORT.C
  6714.  
  6715.  /* QCSORT.C: Demonstrate sorting array of pointers. */
  6716.  
  6717.  #include <stdio.h>
  6718.  #define SIZE 4
  6719.  
  6720.  void sort( int size, double *p[] );
  6721.  void show( int size, double *p[], double dd[] );
  6722.  
  6723.  main()
  6724.  {
  6725.     int x;
  6726.     double d[] = { 3.333, 1.111, 2.222, 4.444 };
  6727.     double *d_ptr[SIZE];
  6728.     for( x = 0; x < SIZE; x++ )
  6729.        d_ptr[x] = &d[x];
  6730.     show( SIZE, d_ptr, d );
  6731.     sort( SIZE, d_ptr );
  6732.     show( SIZE, d_ptr, d );
  6733.  }
  6734.  
  6735.  void sort( int size, double *p[] )
  6736.  {
  6737.     int x, x1;
  6738.     double *temp;
  6739.     for( x = 0; x < size - 1; x++ )
  6740.        for( x1 = x + 1; x1 < size; x1++ )
  6741.        {
  6742.           if( *p[x] > *p[x1] )
  6743.           {
  6744.              temp = p[x1];
  6745.              p[x1] = p[x];
  6746.              p[x] = temp;
  6747.           }
  6748.        }
  6749.  }
  6750.  
  6751.  void show( int size, double *p[], double dd[] )
  6752.  {
  6753.     int x;
  6754.     printf( "------------------------" );
  6755.     printf( "------------------------\n" );
  6756.     for( x = 0; x < size; x++ )
  6757.     {
  6758.        printf( "*d_ptr[%d] = %1.3f   ", x, *p[x]);
  6759.        printf( "d_ptr[%d] = %u ", x, p[x]);
  6760.        printf( "  d[%d] = %1.3f\n", x, dd[x] );
  6761.     }
  6762.  }
  6763.  
  6764.  
  6765.  QCSORT1.C
  6766.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\QCSORT1.C
  6767.  
  6768.  /* QCSORT1.C: Demonstrate sort with pointer notation. */
  6769.  
  6770.  #include <stdio.h>
  6771.  #define SIZE 4
  6772.  
  6773.  void sort( int size, double **p );
  6774.  void show( int size, double **p, double dd[] );
  6775.  
  6776.  main()
  6777.  {
  6778.     int x;
  6779.     double d[] = { 3.333, 1.111, 2.222, 4.444 };
  6780.     double *d_ptr[SIZE];
  6781.     for( x = 0; x < SIZE; x++ )
  6782.        d_ptr[x] = &d[x];
  6783.     show( SIZE, d_ptr, d );
  6784.     sort( SIZE, d_ptr );
  6785.     show( SIZE, d_ptr, d );
  6786.  }
  6787.  
  6788.  void sort( int size, double **p )
  6789.  {
  6790.     int x, x1;
  6791.     double *temp;
  6792.     for( x = 0; x < size - 1; x++ )
  6793.        for( x1 = x + 1; x1 < size; x1++ )
  6794.        {
  6795.           if( **(p+x) > **(p+x1) )
  6796.           {
  6797.              temp = *(p+x1);
  6798.              *(p+x1) = *(p+x);
  6799.              *(p+x) = temp;
  6800.           }
  6801.        }
  6802.  }
  6803.  
  6804.  void show( int size, double **p, double dd[] )
  6805.  {
  6806.     int x;
  6807.     printf( "------------------------" );
  6808.     printf( "------------------------\n" );
  6809.     for( x = 0; x < size; x++ )
  6810.     {
  6811.        printf( "*d_ptr[%d] = %1.3f   ", x, **(p+x) );
  6812.        printf( "d_ptr[%d] = %u ", x, *(p+x) );
  6813.        printf( "  d[%d] = %1.3f\n", x, dd[x] );
  6814.     }
  6815.  }
  6816.  
  6817.  
  6818.  RDFILE.C
  6819.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\RDFILE.C
  6820.  
  6821.  /* RDFILE.C: Reads a file and prints characters to the screen. */
  6822.  #include <stdio.h>
  6823.  
  6824.  main()
  6825.  {
  6826.     int c;
  6827.     FILE *fp;
  6828.  
  6829.     if( fp = fopen( "c:\\testfile.asc", "rb" ) )
  6830.     {
  6831.        while( (c = fgetc( fp )) != EOF )
  6832.           printf( " %c\t%d\n", c, c );
  6833.        printf( "\nEnd of file marker: %d", c );
  6834.        fclose( fp );
  6835.     }
  6836.     else
  6837.        printf( "Error in opening file\n" );
  6838.  }
  6839.  
  6840.  
  6841.  REALG.C
  6842.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\REALG.C
  6843.  
  6844.  /* REALG.C: Example of real-coordinate graphics */
  6845.  #include <stdio.h>
  6846.  #include <conio.h>
  6847.  #include <graph.h>
  6848.  
  6849.  #define TRUE 1
  6850.  #define FALSE 0
  6851.  
  6852.  int four_colors( void );
  6853.  void three_graphs( void );
  6854.  void grid_shape( void );
  6855.  
  6856.  int halfx, halfy;
  6857.  struct videoconfig screen;
  6858.  double bananas[] =
  6859.  {   -0.3, -0.2, -0.224, -0.1, -0.5, +0.21, +2.9,
  6860.     +0.3, +0.2, 0.0, -0.885, -1.1, -0.3, -0.2,
  6861.     +.001, +.005, +0.14, 0.0, -0.9, -0.13, +0.3
  6862.  };
  6863.  
  6864.  main()
  6865.  {
  6866.     if( four_colors() )
  6867.        three_graphs();
  6868.     else
  6869.        printf( "This program requires a CGA, EGA, or VGA graphics card.\n" );
  6870.  }
  6871.  
  6872.  int four_colors( void )
  6873.  {
  6874.     _getvideoconfig( &screen );
  6875.     switch( screen.adapter )
  6876.     {
  6877.        case _CGA:
  6878.        case _OCGA:
  6879.           _setvideomode( _MRES4COLOR );
  6880.           break;
  6881.        case _EGA:
  6882.        case _OEGA:
  6883.           _setvideomode( _ERESCOLOR );
  6884.           break;
  6885.        case _VGA:
  6886.        case _OVGA:
  6887.           _setvideomode( _VRES16COLOR );
  6888.           break;
  6889.        default:
  6890.           return( FALSE );
  6891.     }
  6892.     _getvideoconfig( &screen );
  6893.     return( TRUE );
  6894.  }
  6895.  
  6896.  void three_graphs( void )
  6897.  {
  6898.     int xwidth, yheight, cols, rows;
  6899.     struct _wxycoord upleft, botright;
  6900.  
  6901.     _clearscreen( _GCLEARSCREEN );
  6902.     xwidth = screen.numxpixels;
  6903.     yheight = screen.numypixels;
  6904.     halfx = xwidth/2;
  6905.     halfy = yheight/2;
  6906.     cols = screen.numtextcols;
  6907.     rows = screen.numtextrows;
  6908.  
  6909.     /* first window */
  6910.     _setviewport( 0, 0, halfx-1, halfy-1 );
  6911.     _settextwindow( 1, 1, rows/2, cols/2 );
  6912.     _setwindow( FALSE, -2.0, -2.0, 2.0, 2.0 );
  6913.     grid_shape();
  6914.     _rectangle( _GBORDER, 0, 0, halfx-1, halfy-1 );
  6915.  
  6916.     /* second window */
  6917.     _setviewport( halfx, 0, xwidth-1, halfy-1 );
  6918.     _settextwindow( 1, cols/2+1, rows/2, cols );
  6919.     _setwindow( FALSE, -3.0, -3.0, 3.0, 3.0 );
  6920.     grid_shape();
  6921.     _rectangle_w( _GBORDER, -3.0, -3.0, 3.0, 3.0 );
  6922.  
  6923.     /* third window */
  6924.     _setviewport( 0, halfy, xwidth-1, yheight-1 );
  6925.     _settextwindow( rows/2+1, 1, rows, cols );
  6926.     _setwindow( TRUE, -3.0, -1.5, 1.5, 1.5 );
  6927.     grid_shape();
  6928.     upleft.wx = -3.0;
  6929.     upleft.wy = -1.5;
  6930.     botright.wx = 1.5;
  6931.     botright.wy = 1.5;
  6932.     _rectangle_wxy( _GBORDER, &upleft, &botright );
  6933.  
  6934.     getch();
  6935.     _setvideomode( _DEFAULTMODE );
  6936.  }
  6937.  
  6938.  void grid_shape( void )
  6939.  {
  6940.     int i, numc, x1, y1, x2, y2;
  6941.     double x, y;
  6942.     char txt[80];
  6943.  
  6944.     numc = screen.numcolors;
  6945.     for( i = 1; i < numc; i++ )
  6946.     {
  6947.        _settextposition( i, 2 );
  6948.        _settextcolor( i );
  6949.        sprintf( txt, "Color %d", i );
  6950.        _outtext( txt );
  6951.     }
  6952.  
  6953.     _setcolor( 1 );
  6954.     _rectangle_w( _GBORDER, -1.0, -1.0, 1.0, 1.0 );
  6955.     _rectangle_w( _GBORDER, -1.02, -1.02, 1.02, 1.02 );
  6956.  
  6957.     for( x = -0.9, i = 0; x < 0.9; x += 0.1 )
  6958.     {
  6959.        _setcolor( 2 );
  6960.        _moveto_w( x, -1.0 );
  6961.        _lineto_w( x, 1.0 );
  6962.        _moveto_w( -1.0, x );
  6963.        _lineto_w( 1.0, x );
  6964.  
  6965.        _setcolor( 3 );
  6966.        _moveto_w( x - 0.1, bananas[i++] );
  6967.        _lineto_w( x, bananas[i] );
  6968.     }
  6969.     _moveto_w( 0.9, bananas[i++] );
  6970.     _lineto_w( 1.0, bananas[i] );
  6971.  }
  6972.  
  6973.  
  6974.  RWFILE.C
  6975.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\RWFILE.C
  6976.  
  6977.  /* RWFILE.C: Reads and writes a file. */
  6978.  #include <stdio.h>
  6979.  #include <string.h>
  6980.  #include <fcntl.h>
  6981.  #include <sys\types.h>
  6982.  #include <sys\stat.h>
  6983.  #include <io.h>
  6984.  
  6985.  #define BUFF 512
  6986.  
  6987.  main()
  6988.  {
  6989.     char inbuffer[BUFF];
  6990.     char outbuffer[BUFF];
  6991.     int infile, outfile, length, num;
  6992.  
  6993.     strcpy( outbuffer, "Happy Birthday." );
  6994.     length = strlen( outbuffer );
  6995.     length++;
  6996.  
  6997.     if( (outfile = open( "testfile.bin",
  6998.        O_CREAT | O_WRONLY | O_BINARY,  S_IWRITE )) != -1 )
  6999.     {
  7000.        if( (num = write( outfile, outbuffer, length )) == -1 )
  7001.           perror( "Error in writing" );
  7002.        printf( "\nBytes written to file: %d\n", num );
  7003.        close( outfile );
  7004.     }
  7005.     else
  7006.        perror( "Error opening outfile" );
  7007.  
  7008.     if( (infile = open( "testfile.bin", O_RDONLY | O_BINARY )) != -1  )
  7009.     {
  7010.        while( length = read( infile, inbuffer, BUFF ) )
  7011.           printf( "%d bytes received so far.\n", length );
  7012.        close( infile );
  7013.        printf( "%s\n", inbuffer );
  7014.     }
  7015.     else
  7016.        perror( "Error opening infile" );
  7017.  }
  7018.  
  7019.  
  7020.  SAMPLER.C
  7021.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\SAMPLER.C
  7022.  
  7023.  /* SAMPLER.C: Display sample text in various fonts. */
  7024.  #include <stdio.h>
  7025.  #include <conio.h>
  7026.  #include <stdlib.h>
  7027.  #include <graph.h>
  7028.  #include <string.h>
  7029.  
  7030.  #define NFONTS 6
  7031.  
  7032.  main()
  7033.  {
  7034.    static unsigned char *text[2*NFONTS] =
  7035.    {
  7036.        "COURIER",        "courier",
  7037.        "HELV",           "helv",
  7038.        "TMS RMN",        "tms rmn",
  7039.        "MODERN",         "modern",
  7040.        "SCRIPT",         "script",
  7041.        "ROMAN",          "roman"
  7042.    };
  7043.    static unsigned char *face[NFONTS] =
  7044.    {
  7045.        "t'courier'",
  7046.        "t'helv'",
  7047.        "t'tms rmn'",
  7048.        "t'modern'",
  7049.        "t'script'",
  7050.        "t'roman'"
  7051.    };
  7052.    static unsigned char list[20];
  7053.    struct videoconfig vc;
  7054.    int mode = _VRES16COLOR;
  7055.    register i;
  7056.  
  7057.    /*  Read header info from all .FON files in
  7058.     *  current directory   */
  7059.    if(_registerfonts( "*.FON" )<0 )
  7060.    {
  7061.       _outtext("Error:  can't register fonts");
  7062.       exit( 0 );
  7063.    }
  7064.  
  7065.    /*   Set highest available video mode */
  7066.    while( !_setvideomode( mode ) )
  7067.       mode--;
  7068.    if( mode == _TEXTMONO )
  7069.       exit ( 0 );
  7070.  
  7071.    /*   Copy video configuration into structure vc */
  7072.    _getvideoconfig( &vc );
  7073.  
  7074.    /*   Display six lines of sample text */
  7075.    for( i = 0; i<NFONTS; i++ )
  7076.    {
  7077.       strcpy( list, face[i] );
  7078.       strcat( list, "h30w24b" );
  7079.  
  7080.       if( !_setfont( list ) )
  7081.       {
  7082.           _setcolor( i + 1 );
  7083.           _moveto( 0, (i * vc.numypixels) / NFONTS );
  7084.           _outgtext( text[i * 2] );
  7085.           _moveto( vc.numxpixels / 2,
  7086.                       (i * vc.numypixels) / NFONTS );
  7087.           _outgtext( text[(i * 2) + 1] );
  7088.       }
  7089.       else
  7090.       {
  7091.           _setvideomode( _DEFAULTMODE );
  7092.           _outtext( "Error:  can't set font" );
  7093.           exit( 0 );
  7094.       }
  7095.    }
  7096.    getch();
  7097.    _setvideomode( _DEFAULTMODE );
  7098.  
  7099.    /* Return memory when finished with fonts */
  7100.    _unregisterfonts();
  7101.    exit( 0 );
  7102.  }
  7103.  
  7104.  
  7105.  SCATTER.C
  7106.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\SCATTER.C
  7107.  
  7108.  /* SCATTER.C:  Create sample scatter diagram. */
  7109.  
  7110.  #include <conio.h>
  7111.  #include <string.h>
  7112.  #include <graph.h>
  7113.  #include <pgchart.h>
  7114.  
  7115.  #define MONTHS 12
  7116.  typedef enum {FALSE, TRUE} boolean;
  7117.  
  7118.  /* Orange juice sales */
  7119.  
  7120.  float far xvalue[MONTHS] =
  7121.  {
  7122.     33.0, 27.0, 42.0, 64.0,106.0,157.0,
  7123.    182.0,217.0,128.0, 62.0, 43.0, 36.0
  7124.  };
  7125.  /* Hot chocolate sales */
  7126.  
  7127.  float far yvalue[MONTHS] =
  7128.  {
  7129.    37.0, 37.0, 30.0, 19.0, 10.0,  5.0,
  7130.     2.0,  1.0,  7.0, 15.0, 28.0, 39.0
  7131.  };
  7132.  
  7133.  main()
  7134.  {
  7135.    chartenv env;
  7136.    int mode = _VRES16COLOR;
  7137.  
  7138.    /* Set highest video mode available */
  7139.  
  7140.    while(!_setvideomode( mode ))
  7141.       mode--;
  7142.    if(mode == _TEXTMONO)
  7143.       return(0);
  7144.  
  7145.    /* Initialize chart library and default
  7146.     * scatter diagram
  7147.     */
  7148.  
  7149.    _pg_initchart();
  7150.  
  7151.    _pg_defaultchart( &env, _PG_SCATTERCHART,
  7152.                      _PG_POINTONLY );
  7153.  
  7154.    /* Add titles and some chart options */
  7155.  
  7156.    strcpy( env.maintitle.title, "Good Neighbor Grocery" );
  7157.    env.maintitle.titlecolor = 6;
  7158.    env.maintitle.justify = _PG_RIGHT;
  7159.    strcpy( env.subtitle.title,
  7160.            "Orange Juice vs Hot Chocolate" );
  7161.    env.subtitle.titlecolor = 6;
  7162.    env.subtitle.justify = _PG_RIGHT;
  7163.    env.yaxis.grid = TRUE;
  7164.    strcpy( env.xaxis.axistitle.title,
  7165.            "Orange Juice Sales" );
  7166.    strcpy( env.yaxis.axistitle.title,
  7167.            "Hot Chocolate Sales" );
  7168.    env.chartwindow.border = FALSE;
  7169.  
  7170.    /* Parameters for call to _pg_chartscatter are:
  7171.     *    env        - Environment variable
  7172.     *    xvalue     - X-axis data
  7173.     *    yvalue     - Y-axis data
  7174.     *    MONTHS     - Number of data values
  7175.     */
  7176.  
  7177.    if(_pg_chartscatter( &env, xvalue,
  7178.                          yvalue, MONTHS ))
  7179.    {
  7180.       _setvideomode( _DEFAULTMODE );
  7181.       _outtext( "Error:  can't draw chart" );
  7182.    }
  7183.    else
  7184.    {
  7185.       getch();
  7186.       _setvideomode( _DEFAULTMODE );
  7187.    }
  7188.    return(0);
  7189.  }
  7190.  
  7191.  
  7192.  SHOWME.C
  7193.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\SHOWME.C
  7194.  
  7195.  /* SHOWME.C: Demonstrate passing by value. */
  7196.  #include <stdio.h>
  7197.  
  7198.  void showme( int a, int b, int c );
  7199.  
  7200.  main()
  7201.  {
  7202.     int x = 10, y = 20, z = 30;
  7203.     showme( z, y, x );
  7204.  }
  7205.  
  7206.  void showme( int a, int b, int c )
  7207.  {
  7208.     printf( "a=%d b=%d c=%d", a, b, c );
  7209.  }
  7210.  
  7211.  
  7212.  SHOWMORE.C
  7213.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\SHOWMORE.C
  7214.  
  7215.  /* SHOWMORE.C: Demonstrate passing by value. */
  7216.  #include <stdio.h>
  7217.  
  7218.  void showme( int any, int old, int name );
  7219.  
  7220.  main()
  7221.  {
  7222.     int x = 10, y = 20, z = 30;
  7223.     showme( z, y, x );
  7224.     printf( "  z=%d   y=%d    x=%d\n", z, y, x );
  7225.  }
  7226.  
  7227.  void showme( int any, int old, int name )
  7228.  {
  7229.     printf( "any=%d old=%d name=%d\n", any, old, name );
  7230.     any = 55;
  7231.     old = 66;
  7232.     name = 77;
  7233.     printf( "any=%d old=%d name=%d\n", any, old, name );
  7234.  }
  7235.  
  7236.  
  7237.  SINE.C
  7238.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\SINE.C
  7239.  
  7240.  /*  SINE.C: Illustrates basic graphics commands */
  7241.  #include <stdio.h>
  7242.  #include <stdlib.h>
  7243.  #include <graph.h>
  7244.  #include <math.h>
  7245.  #include <conio.h>
  7246.  #define PI 3.14159
  7247.  
  7248.  void graphics_mode( void );
  7249.  void draw_lines( void );
  7250.  void sine_wave( void );
  7251.  void draw_shapes( void );
  7252.  void end_program( void );
  7253.  int newx( int );
  7254.  int newy( int );
  7255.  
  7256.  struct videoconfig myscreen;
  7257.  int maxx, maxy;
  7258.  unsigned char diagmask[8] =
  7259.  { 0x93, 0xC9, 0x64, 0xB2, 0x59, 0x2C, 0x96, 0x4B };
  7260.  unsigned char linemask[8] =
  7261.  { 0xFF, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0xCC };
  7262.  
  7263.  main()
  7264.  {
  7265.     graphics_mode();
  7266.     draw_lines();
  7267.     sine_wave();
  7268.     draw_shapes();
  7269.     end_program();
  7270.  }
  7271.  
  7272.  void graphics_mode( void )
  7273.  {
  7274.     _getvideoconfig( &myscreen );
  7275.     switch( myscreen.adapter )
  7276.     {
  7277.        case _CGA:
  7278.           _setvideomode( _HRESBW );
  7279.           break;
  7280.        case _OCGA:
  7281.           _setvideomode( _ORESCOLOR );
  7282.           break;
  7283.        case _EGA:
  7284.        case _OEGA:
  7285.           if( myscreen.monitor == _MONO )
  7286.              _setvideomode( _ERESNOCOLOR );
  7287.           else
  7288.              _setvideomode( _ERESCOLOR );
  7289.           break;
  7290.        case _VGA:
  7291.        case _OVGA:
  7292.        case _MCGA:
  7293.           _setvideomode( _VRES2COLOR );
  7294.           break;
  7295.        case _HGC:
  7296.           _setvideomode( _HERCMONO );
  7297.           break;
  7298.        default:
  7299.           printf( "This program requires a CGA, EGA, VGA, or Hercules card\n"
  7300.           exit( 0 );
  7301.     }
  7302.     _getvideoconfig( &myscreen );
  7303.     maxx = myscreen.numxpixels - 1;
  7304.     maxy = myscreen.numypixels - 1;
  7305.  }
  7306.  
  7307.  int newx( int xcoord )
  7308.  {
  7309.     int nx;
  7310.     float tempx;
  7311.     tempx = ((float) maxx)/ 1000.0;
  7312.     tempx = ((float) xcoord) * tempx + 0.5;
  7313.     return( (int) tempx );
  7314.  }
  7315.  
  7316.  int newy( int ycoord )
  7317.  {
  7318.     int ny;
  7319.     float tempy;
  7320.     tempy = ((float) maxy)/ 1000.0;
  7321.     tempy = ((float) ycoord) * tempy + 0.5;
  7322.     return( (int) tempy );
  7323.  }
  7324.  
  7325.  void sine_wave( void )
  7326.  {
  7327.     int locx, locy;
  7328.     double i, rad;
  7329.  
  7330.     for( i = 0.0; i < 1000.0; i += 3.0 )
  7331.     {
  7332.        rad = -sin( (PI * (float) i) / 250.0 );
  7333.        locx = newx( (int) i );
  7334.        locy = newy( (int) (rad * 250.0) );
  7335.        _setpixel( locx, locy );
  7336.     }
  7337.  }
  7338.  
  7339.  void draw_shapes( void )
  7340.  {
  7341.     _setlinestyle( 0xFFFF );
  7342.     _setfillmask( diagmask );
  7343.     _rectangle( _GBORDER, newx(50), newy(-325), newx(200), newy(-425) );
  7344.     _rectangle( _GFILLINTERIOR, newx(550), newy(-325), newx(700), newy(-425) )
  7345.  
  7346.     _setfillmask( linemask );
  7347.     _ellipse( _GBORDER, newx(50), newy(325), newx(200), newy(425) );
  7348.     _ellipse( _GFILLINTERIOR, newx(550), newy(325), newx(700), newy(425) );
  7349.  }
  7350.  
  7351.  void end_program( void )
  7352.  {
  7353.     getch();
  7354.     _setvideomode( _DEFAULTMODE );
  7355.  }
  7356.  
  7357.  void draw_lines( void )
  7358.  {
  7359.     _rectangle( _GBORDER, 0, 0, maxx, maxy );
  7360.     /* _setcliprgn( 20, 20, maxx - 20, maxy - 20 ); */
  7361.     _setvieworg( 0, newy( 500 ) );
  7362.  
  7363.     _moveto( 0, 0 );
  7364.     _lineto( newx( 1000 ), 0 );
  7365.     _setlinestyle( 0xAA3C );
  7366.     _moveto( 0, newy( -250) );
  7367.     _lineto( newx( 1000 ), newy( -250 ) );
  7368.  
  7369.     _setlinestyle( 0x8888 );
  7370.     _moveto( 0, newy( 250 ) );
  7371.     _lineto( newx( 1000 ), newy( 250 ) );
  7372.  }
  7373.  
  7374.  
  7375.  STATIC.C
  7376.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\STATIC.C
  7377.  
  7378.  /* STATIC.C: Demonstrate static variables. */
  7379.  
  7380.  #include <stdio.h>
  7381.  
  7382.  void add_val( int value );
  7383.  
  7384.  main()
  7385.  {
  7386.     add_val( 1 );
  7387.     add_val( 5 );
  7388.     add_val( 20 );
  7389.  }
  7390.  
  7391.  void add_val( int value )
  7392.  {
  7393.     static int methuselah;
  7394.     if( value == 1 )
  7395.        methuselah = 0;
  7396.     methuselah = methuselah + value;
  7397.     printf( "methuselah = %d\n", methuselah );
  7398.  }
  7399.  
  7400.  
  7401.  STRING.C
  7402.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\STRING.C
  7403.  
  7404.  /* STRING.C: Demonstrate string arrays. */
  7405.  #include <stdio.h>
  7406.  
  7407.  main()
  7408.  {
  7409.     int j;
  7410.     char c_array[] = "Hello";
  7411.  
  7412.     printf( "--- Values --------     --- Addresses -------\n\n" );
  7413.  
  7414.     for( j = 0; j < 6; j = j + 1 )
  7415.     {
  7416.        printf( "c_array[%d]   = %x %c", j, c_array[j], c_array[j] );
  7417.        printf( "\t&c_array[%d]    = %u\n", j, &c_array[j] );
  7418.     }
  7419.  }
  7420.  
  7421.  
  7422.  SVBIN.C
  7423.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\SVBIN.C
  7424.  
  7425.  /* SVBIN.C: Saves integer variables in binary format. */
  7426.  #include <stdio.h>
  7427.  #define ASIZE 10
  7428.  
  7429.  main()
  7430.  {
  7431.     FILE *ap;
  7432.     int zebra[ASIZE], acopy[ASIZE], bcopy[ASIZE];
  7433.     int i;
  7434.  
  7435.     for( i = 0; i < ASIZE; i++ )
  7436.        zebra[i] = 7700 + i;
  7437.  
  7438.     if( (ap = fopen( "binfile", "wb" )) != NULL )
  7439.     {
  7440.        fwrite( zebra, sizeof(zebra), 1, ap );
  7441.        fclose( ap );
  7442.     }
  7443.     else
  7444.        perror( "Write error" );
  7445.  
  7446.     if( (ap = fopen( "morebin", "wb" )) != NULL )
  7447.     {
  7448.        fwrite( &zebra[0], sizeof(zebra[0]), ASIZE, ap );
  7449.        fclose( ap );
  7450.     }
  7451.     else
  7452.        perror( "Write error" );
  7453.  
  7454.     if( (ap = fopen( "binfile", "rb" )) != NULL )
  7455.     {
  7456.        printf( "Hexadecimal values in binfile:\n" );
  7457.        while( (i = fgetc( ap )) != EOF )
  7458.           printf( "%02X ", i );
  7459.        rewind( ap );
  7460.        fread( acopy, sizeof(acopy), 1, ap );
  7461.        rewind( ap );
  7462.        fread( &bcopy[0], sizeof( bcopy[0] ), ASIZE, ap);
  7463.        for( i=0; i<ASIZE; i++ )
  7464.           printf( "\nItem %d = %d\t%d", i, acopy[i], bcopy[i] );
  7465.        fclose( ap );
  7466.  
  7467.     }
  7468.     else
  7469.        perror( "Read error" );
  7470.  
  7471.  }
  7472.  
  7473.  
  7474.  SVTEXT.C
  7475.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\SVTEXT.C
  7476.  
  7477.  /* SVTEXT.C: Save integer variables as text. */
  7478.  #include <stdio.h>
  7479.  
  7480.  int list[] = { 53, -23456, 50, 500, 5000, -99 };
  7481.  extern int errno;
  7482.  char fname[] = "numtext";
  7483.  char temp[81];
  7484.  
  7485.  main()
  7486.  {
  7487.     FILE *fptr;
  7488.     int i;
  7489.  
  7490.     if( (fptr = fopen( "numtext","wt" )) != NULL )
  7491.     {
  7492.        for( i=0; i<6; i++ )
  7493.           fprintf( fptr, "Item %d: %6d \n", i, list[i] );
  7494.        fclose( fptr );
  7495.     }
  7496.     else
  7497.        printf( "Error: Couldn't create file.\n" );
  7498.  
  7499.     if( (fptr = fopen( "badname", "rt" )) != NULL )
  7500.     {
  7501.        /* do nothing */
  7502.     }
  7503.     else
  7504.     {
  7505.        printf( "Error number: %d\n\t", errno );
  7506.        perror( "Couldn't open file BADNAME\n\t" );
  7507.     }
  7508.  
  7509.     if( (fptr = fopen( fname, "rt" )) != NULL )
  7510.     {
  7511.        list[0] = 0;
  7512.        fscanf( fptr, "Item %d: %d \n", &i, &list[0] );
  7513.        printf( "Values read from file:\t %d %d\n", i, list[0] );
  7514.        fgets( temp, 80, fptr );
  7515.        printf( "String from file: \t%s\n", temp );
  7516.        while( (i = fgetc( fptr )) != '\n' )
  7517.           printf( "char: %c \t ASCII: %d \n", i, i );
  7518.        rewind( fptr );
  7519.        printf( "Rewind to start -->\t%s", fgets( temp, 80, fptr ) );
  7520.        fclose( fptr );
  7521.     }
  7522.     else
  7523.        printf( "Trouble opening %s \n", fname );
  7524.  }
  7525.  
  7526.  
  7527.  SWITCH.C
  7528.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\SWITCH.C
  7529.  
  7530.  /* SWITCH.C: Demonstrate switch statement. */
  7531.  
  7532.  #include <stdio.h>
  7533.  #include <conio.h>
  7534.  
  7535.  main()
  7536.  {
  7537.     char ch;
  7538.     printf( "Press the b key to hear a bell.\n" );
  7539.     ch = getch();
  7540.     switch( ch )
  7541.     {
  7542.        case 'b':
  7543.           printf( "Beep!\a\n" );
  7544.           break;
  7545.        case '\r':
  7546.           printf( "Enter\n" );
  7547.           break;
  7548.        default:
  7549.           printf( "Bye bye" );
  7550.           break;
  7551.     }
  7552.  }
  7553.  
  7554.  
  7555.  TWODIM.C
  7556.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\TWODIM.C
  7557.  
  7558.  /* TWODIM.C: Demonstrate multidimensional arrays. */
  7559.  
  7560.  #include <stdio.h>
  7561.  
  7562.  main()
  7563.  {
  7564.     int j, k;
  7565.     int i_array[2][3] = { { 176, 4069, 303 }, { 6, 55, 777 } };
  7566.  
  7567.     printf( "--- Values --------     --- Addresses -------\n\n" );
  7568.  
  7569.     for( j = 0; j < 2; j = j + 1 )
  7570.     {
  7571.        for( k = 0; k < 3; k = k + 1 )
  7572.        {
  7573.           printf( "i_array[%d][%d] = %d", j, k, i_array[j][k] );
  7574.           printf( "\t&i_array[%d][%d] = %u\n", j, k, &i_array[j][k] );
  7575.        }
  7576.        printf( "\n" );
  7577.     }
  7578.  
  7579.  }
  7580.  
  7581.  
  7582.  TYPES.C
  7583.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\TYPES.C
  7584.  
  7585.  /* TYPES.C: Illustrate basic data types. */
  7586.  #include <stdio.h>
  7587.  
  7588.  main()
  7589.  {
  7590.     char char_val        = 'a';
  7591.     int int_val         = 543;
  7592.     float float_val     = 11.1;
  7593.     double double_val   = 66.123456789;
  7594.     printf( "char_val   = %c\n", char_val );
  7595.     printf( "int_val    = %d\n", int_val );
  7596.     printf( "float_val  = %f\n", float_val );
  7597.     printf( "double_val = %2.9f\n", double_val );
  7598.  }
  7599.  
  7600.  
  7601.  VISIBLE.C
  7602.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\VISIBLE.C
  7603.  
  7604.  /* VISIBLE.C: Demonstrate local visibility. */
  7605.  
  7606.  #include <stdio.h>
  7607.  void be_bop( void );
  7608.  
  7609.  main()
  7610.  {
  7611.     int val = 10;
  7612.     be_bop();
  7613.  }
  7614.  
  7615.  void be_bop( void )
  7616.  {
  7617.     printf( "val = %d", val ); /* Error! */
  7618.  }
  7619.  
  7620.  
  7621.  VISIBLE1.C
  7622.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\VISIBLE1.C
  7623.  
  7624.  /* VISIBLE1.C: Demonstrate local visibility. */
  7625.  
  7626.  #include <stdio.h>
  7627.  
  7628.  void be_bop( int param );
  7629.  
  7630.  main()
  7631.  {
  7632.     int val = 10;
  7633.     be_bop( val );
  7634.  }
  7635.  
  7636.  void be_bop( int param )
  7637.  {
  7638.     printf( "%d\n", param );
  7639.  }
  7640.  
  7641.  
  7642.  VISIBLE2.C
  7643.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\VISIBLE2.C
  7644.  
  7645.  /* VISIBLE2.C: Demonstrate external visibility.
  7646.  */
  7647.  
  7648.  #include <stdio.h>
  7649.  
  7650.  void be_bop( int param );
  7651.  
  7652.  main()
  7653.  {
  7654.     be_bop( val ); /* Error! */
  7655.  }
  7656.  
  7657.  int val = 10;
  7658.  
  7659.  void be_bop( int param )
  7660.  {
  7661.     printf( "val = %d\n", param );
  7662.  }
  7663.  
  7664.  
  7665.  VOLUME.C
  7666.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\VOLUME.C
  7667.  
  7668.  /* VOLUME.C: Calculate sphere's volume. */
  7669.  #include <stdio.h>
  7670.  #define PI 3.14
  7671.  
  7672.  float sphere( int rad );
  7673.  
  7674.  main()
  7675.  {
  7676.     float volume;
  7677.     int radius = 3;
  7678.     volume = sphere( radius );
  7679.     printf( "Volume: %f\n", volume );
  7680.  }
  7681.  
  7682.  float sphere( int rad )
  7683.  {
  7684.     float result;
  7685.     result = rad * rad * rad;
  7686.     result = 4 * PI * result;
  7687.     result = result / 3;
  7688.     return result;
  7689.  }
  7690.  
  7691.  
  7692.  WHILE.C
  7693.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\WHILE.C
  7694.  
  7695.  /* WHILE.C: Demonstrate while loop. */
  7696.  
  7697.  #include <stdio.h>
  7698.  
  7699.  main()
  7700.  {
  7701.     int test = 10;
  7702.  
  7703.     while( test > 0 )
  7704.     {
  7705.        printf( "test = %d\n", test );
  7706.        test = test - 2;
  7707.     }
  7708.  }
  7709.  
  7710.  
  7711.  WRFILE.C
  7712.  CD-ROM Disc Path:   \SAMPCODE\QC\QC25\WRFILE.C
  7713.  
  7714.  /* WRFILE.C: Creates and writes to a disk file. */
  7715.  #include <stdio.h>
  7716.  
  7717.  main()
  7718.  {
  7719.     FILE *fp;
  7720.  
  7721.     if( (fp = fopen( "c:\\testfile.asc","w" )) != NULL )
  7722.     {
  7723.        fputs( "Example string", fp );
  7724.        fputc( '\n', fp );
  7725.        fclose( fp );
  7726.     }
  7727.     else
  7728.        printf( "error message\n" );
  7729.  }
  7730.  Proficient C - Sample Code
  7731.  
  7732.  
  7733.  ANSI_CPR.C
  7734.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\13ANSI\ANSI_CPR.C
  7735.  
  7736.  /*
  7737.   *        ansi_cpr -- report where the cursor is located
  7738.   *        The position information is placed in the keyboard buffer
  7739.   *        in the form ESC[rr;ccR where ESC is the value of the
  7740.   *        ESCAPE character (\033) and r and c represent
  7741.   *        decimal values of row and column data.
  7742.   */
  7743.  
  7744.  #include <local\ansi.h>
  7745.  
  7746.  void
  7747.  ansi_cpr(row, col)
  7748.  int        *row,
  7749.          *col;
  7750.  {
  7751.          int i;
  7752.  
  7753.          /* request a cursor position report */
  7754.          ANSI_DSR;
  7755.  
  7756.          /* toss the ESC and '[' */
  7757.          (void) getkey();
  7758.          (void) getkey();
  7759.  
  7760.          /* read the row number */
  7761.          *row = 10 * (getkey() - '0');
  7762.          *row = *row + getkey() - '0';
  7763.  
  7764.          /* toss the ';' separator */
  7765.          (void) getkey();
  7766.  
  7767.          /* read the column number */
  7768.          *col = 10 * (getkey() - '0');
  7769.          *col = *col + getkey() - '0';
  7770.  
  7771.          /* toss the trailing ('R') and return */
  7772.          (void) getkey();
  7773.          (void) getkey();
  7774.          return;
  7775.  }
  7776.  
  7777.  
  7778.  ANSI_TST.C
  7779.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\13ANSI\ANSI_TST.C
  7780.  
  7781.  /*
  7782.   *        ansi_tst -- verify that the ANSI.SYS driver is loaded
  7783.   *        (prints message and exits is ANSI driver not working)
  7784.   */
  7785.  
  7786.  #include <stdio.h>
  7787.  #include <local\ansi.h>
  7788.  #include <local\video.h>
  7789.  
  7790.  #define TST_ROW        2
  7791.  #define TST_COL        75
  7792.  
  7793.  void
  7794.  ansi_tst()
  7795.  {
  7796.          int row, col;
  7797.          static char *help[] = {
  7798.                  "\n",
  7799.                  "ANSI.SYS device driver not loaded:\n",
  7800.                  "  1. Copy ANSI.SYS to your system disk.\n",
  7801.                  "  2. Add the line device=ansi.sys to your\n",
  7802.                  "     CONFIG.SYS file and reboot your machine.\n",
  7803.                  NULL
  7804.          };
  7805.          char **msg;
  7806.  
  7807.          extern int getstate();
  7808.          extern int readcur(int *, int *, int);
  7809.  
  7810.          getstate();
  7811.          ANSI_CUP(TST_ROW, TST_COL);
  7812.          readcur(&row, &col, Vpage);
  7813.          if (row != TST_ROW - 1 || col != TST_COL - 1) {
  7814.                  for (msg = help; *msg != NULL; ++msg)
  7815.                          fputs(*msg, stderr);
  7816.                  exit(1);
  7817.          }
  7818.  
  7819.          return;
  7820.  }
  7821.  
  7822.  
  7823.  BEEP.C
  7824.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\BEEP.C
  7825.  
  7826.  /*
  7827.   *        beep -- sound the terminal beeper
  7828.   */
  7829.  
  7830.  #include <stdio.h>
  7831.  
  7832.  #define BEL        7
  7833.  
  7834.  void
  7835.  beep()
  7836.  {
  7837.          putchar(BEL);
  7838.  }
  7839.  
  7840.  
  7841.  CAT.C
  7842.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\06USER\CAT.C
  7843.  
  7844.  /*
  7845.   *        cat -- concatenate files
  7846.   */
  7847.  
  7848.  #include <stdio.h>
  7849.  #include <stdlib.h>
  7850.  #include <local\std.h>
  7851.  
  7852.  main(argc, argv)
  7853.  int argc;
  7854.  char **argv;
  7855.  {
  7856.          int ch;
  7857.          char *cp;
  7858.          FILE *fp;
  7859.          BOOLEAN errflag, silent;
  7860.          static char pgm[MAXNAME + 1] = { "cat" };
  7861.  
  7862.          extern void getpname(char *, char *);
  7863.          extern int fcopy(FILE *, FILE *);
  7864.          extern int getopt(int, char **, char *);
  7865.          extern int optind;
  7866.          extern char *optarg;
  7867.  
  7868.          /* use an alias if one is given to this program */
  7869.          if (_osmajor >= 3)
  7870.                  getpname(*argv, pgm);
  7871.  
  7872.          /* process optional arguments, if any */
  7873.          errflag = FALSE;
  7874.          silent = FALSE;
  7875.          while ((ch = getopt(argc, argv, "s")) != EOF)
  7876.                  switch (ch) {
  7877.                  case 's':
  7878.                          /* don't complain about non-existent files */
  7879.                          silent = TRUE;
  7880.                          break;
  7881.                  case '?':
  7882.                          /* say what? */
  7883.                          errflag = TRUE;
  7884.                          break;
  7885.                  }
  7886.          if (errflag == TRUE) {
  7887.                  fprintf(stderr, "Usage: %s [-s] file...\n", pgm);
  7888.                  exit(1);
  7889.          }
  7890.  
  7891.          /* process any remaining arguments */
  7892.          argc -= optind;
  7893.          argv += optind;
  7894.          if (argc == 0)
  7895.                  /* no file names -- use standard input */
  7896.                  if (fcopy(stdin, stdout) != 0) {
  7897.                          fprintf(stderr, "error copying stdin");
  7898.                          exit(2);
  7899.                  }
  7900.                  else
  7901.                          exit(0);
  7902.  
  7903.          /* copy the contents of each named file to standard output */
  7904.          for (; argc-- > 0; ++argv) {
  7905.                  if ((fp = fopen(*argv, "r")) == NULL) {
  7906.                          if (silent == FALSE)
  7907.                                  fprintf(stderr, "%s: can't open %s\n",
  7908.                                          pgm, *argv);
  7909.                          continue;
  7910.                  }
  7911.                  if (fcopy(fp, stdout) != 0) {
  7912.                          fprintf(stderr, "%s: Error while copying %s",
  7913.                                  pgm, *argv);
  7914.                          exit(3);
  7915.                  }
  7916.                  if (fclose(fp) != 0) {
  7917.                          fprintf(stderr, "%s: Error closing %s",
  7918.                                  pgm, *argv);
  7919.                          exit(4);
  7920.                  }
  7921.          }
  7922.  
  7923.          exit(0);
  7924.  }
  7925.  
  7926.  
  7927.  CLRSCRN.C
  7928.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\CLRSCRN.C
  7929.  
  7930.  /*
  7931.   *        clrscrn -- clear the "visual" screen page
  7932.   */
  7933.  
  7934.  #include <dos.h>
  7935.  #include <local\std.h>
  7936.  #include <local\bioslib.h>
  7937.  #include <local\video.h>
  7938.  
  7939.  int
  7940.  clrscrn(a)
  7941.  unsigned int a;        /* video attribute for new lines */
  7942.  {
  7943.          union REGS inregs, outregs;
  7944.  
  7945.          inregs.h.ah = SCROLL_UP;
  7946.          inregs.h.al = 0;                /* blank entire window */
  7947.          inregs.h.bh = a;                /* use specified attribute */
  7948.          inregs.h.bl = 0;
  7949.          inregs.x.cx = 0;                /* upper left corner */
  7950.          inregs.h.dh = Maxrow[Vmode] - 1;/* bottom screen row */
  7951.          inregs.h.dl = Maxcol[Vmode] - 1;/* rightmost column */
  7952.          int86(VIDEO_IO, &inregs, &outregs);
  7953.  
  7954.          return (outregs.x.cflag);
  7955.  }
  7956.  
  7957.  
  7958.  CLRW.C
  7959.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\CLRW.C
  7960.  
  7961.  /*
  7962.   *        clrw -- clear specified region of "visual" screen page
  7963.   */
  7964.  
  7965.  #include <dos.h>
  7966.  #include <local\std.h>
  7967.  #include <local\bioslib.h>
  7968.  
  7969.  int
  7970.  clrw(t, l, b, r, a)
  7971.  int t;                /* top row of region to clear */
  7972.  int l;                /* left column */
  7973.  int b;                /* bottom row */
  7974.  int r;                /* right column */
  7975.  unsigned char a;/* attribute for cleared region */
  7976.  {
  7977.          union REGS inregs, outregs;
  7978.  
  7979.          inregs.h.ah = SCROLL_UP;/* scroll visual page up */
  7980.          inregs.h.al = 0;        /* blank entire window */
  7981.          inregs.h.bh = a;        /* attribute of blank lines */
  7982.          inregs.h.bl = 0;
  7983.          inregs.h.ch = t;        /* upper left of scroll region */
  7984.          inregs.h.cl = l;
  7985.          inregs.h.dh = b;        /* lower right of scroll region */
  7986.          inregs.h.dl = r;
  7987.          int86(VIDEO_IO, &inregs, &outregs);
  7988.  
  7989.          return (outregs.x.cflag);
  7990.  }
  7991.  
  7992.  
  7993.  COLORNUM.C
  7994.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\13ANSI\COLORNUM.C
  7995.  
  7996.  /*
  7997.   *        colornum -- return the IBM number for the color
  7998.   *        presented as a string; return -1 if no match.
  7999.   */
  8000.  
  8001.  #include <stdio.h>
  8002.  #include <string.h>
  8003.  #include <local\ibmcolor.h>
  8004.  
  8005.  #define NCHARS        3
  8006.  
  8007.  int
  8008.  colornum(name)
  8009.  char *name;
  8010.  {
  8011.          register int n;
  8012.          static struct color_st {
  8013.                  char *c_name;
  8014.                  int c_num;
  8015.          } colortab[] = {
  8016.                  "black",        IBM_BLACK,
  8017.                  "blue",                IBM_BLUE,
  8018.                  "green",        IBM_GREEN,
  8019.                  "cyan",                IBM_CYAN,
  8020.                  "red",                IBM_RED,
  8021.                  "magenta",        IBM_MAGENTA,
  8022.                  "brown",        IBM_BROWN,
  8023.                  "white",        IBM_WHITE,
  8024.                  "normal",        IBM_NORMAL,
  8025.                  "bright",        IBM_BRIGHT,
  8026.                  "light",        IBM_BRIGHT,
  8027.                  "bold",                IBM_BRIGHT,
  8028.                  "yellow",        IBM_BROWN + IBM_BRIGHT,
  8029.                  "blink",        IBM_BLINK,
  8030.                  "reverse",        IBM_REVERSE,
  8031.                  "invisible",        IBM_INVISIBLE,
  8032.                  NULL,                (-1)
  8033.          };
  8034.  
  8035.          (void) strlwr(name);
  8036.          for (n = 0; colortab[n].c_name != NULL; ++n)
  8037.                  if ((strncmp(name, colortab[n].c_name, NCHARS)) == 0)
  8038.                          return (colortab[n].c_num);
  8039.          return (-1);
  8040.  }
  8041.  
  8042.  
  8043.  CP.C
  8044.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\03DOS\CP.C
  8045.  
  8046.  /*
  8047.   *        cp -- a simplified copy command
  8048.   */
  8049.  
  8050.  #include <stdio.h>
  8051.  
  8052.  main()
  8053.  {
  8054.          int ch;
  8055.  
  8056.          while ((ch = getc(stdin)) != EOF)
  8057.                  putc(ch, stdout);
  8058.          exit(0);
  8059.  }
  8060.  
  8061.  
  8062.  CPBLK.C
  8063.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\11SCREEN\CPBLK.C
  8064.  
  8065.  /*
  8066.   *        cpblk -- copy a block of characters and attributes
  8067.   *        while eliminating "snow" on a standard CGA display
  8068.   */
  8069.  
  8070.  #include <conio.h>
  8071.  #include <memory.h>
  8072.  
  8073.  #define BLKCNT        10
  8074.  #define VSTAT        0x3DA
  8075.  #define VRBIT        8
  8076.  #define WRDCNT        200
  8077.  #define NBYTES        (2 * WRDCNT)
  8078.  
  8079.  /* macro to synchronize with vertical retrace period */
  8080.  #define VSYNC        while ((inp(VSTAT) & VRBIT) == VRBIT); \
  8081.                  while ((inp(VSTAT) & VRBIT) != VRBIT)
  8082.  
  8083.  int
  8084.  cpblk(src_os, src_seg, dest_os, dest_seg)
  8085.  unsigned int src_os, src_seg, dest_os, dest_seg;
  8086.  {
  8087.          register int i;
  8088.          int n;
  8089.          register int delta;
  8090.  
  8091.          n = 0;
  8092.          delta = 0;
  8093.          for (i = 0; i < BLKCNT ; ++i) {
  8094.                  /* copy a block of words during vertical retrace */
  8095.                  VSYNC;
  8096.                  movedata(src_seg, src_os + delta,
  8097.                          dest_seg, dest_os + delta, NBYTES);
  8098.                  n += WRDCNT;
  8099.  
  8100.                  /* adjust buffer offset */
  8101.                  delta += NBYTES;
  8102.          }
  8103.  
  8104.          return (n);
  8105.  }
  8106.  
  8107.  
  8108.  CURBACK.C
  8109.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\CURBACK.C
  8110.  
  8111.  /*
  8112.   *        curback -- move cursor back (left); return the
  8113.   *        value of the new column position
  8114.   */
  8115.  
  8116.  #include <local\bioslib.h>
  8117.  
  8118.  int
  8119.  curback(n, pg)
  8120.  int n, pg;
  8121.  {
  8122.          int r, c;
  8123.  
  8124.          /*
  8125.           *        move the cursor left by up to n positions but
  8126.           *        not past the beginning of the current line
  8127.           */
  8128.          readcur(&r, &c, pg);
  8129.          if (c - n < 0)
  8130.                  c = 0;
  8131.          putcur(r, c, pg);
  8132.          return (c);
  8133.  }
  8134.  
  8135.  
  8136.  CURSOR.C
  8137.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\CURSOR.C
  8138.  
  8139.  /*
  8140.   *        cursor -- interactively set cursor shape
  8141.   */
  8142.  
  8143.  #include <dos.h>
  8144.  #include <stdlib.h>
  8145.  #include <local\video.h>
  8146.  #include <local\keydefs.h>
  8147.  
  8148.  /* additional drawing characters (others are defined in video.h) */
  8149.  #define DOT        254
  8150.  #define NO_DOT        196
  8151.  #define D_POINT        31
  8152.  #define R_POINT 16
  8153.  #define L_POINT 17
  8154.  
  8155.  /* dimensions of the help frame */
  8156.  #define BOX_Y        6
  8157.  #define BOX_X        30
  8158.  
  8159.  /* upper-left row and column of big cursor */
  8160.  int Ulr;
  8161.  int Ulc;
  8162.  int Mid;
  8163.  
  8164.  /* cursor scan-line-selection modes */
  8165.  typedef enum { STARTSCAN, ENDSCAN } CMODE;
  8166.  
  8167.  int
  8168.  main()
  8169.  {
  8170.          int i, j;
  8171.          int ch;
  8172.          int start, end;
  8173.          int height, width;
  8174.          static char spoint[] = { "Start\020" }; /* contains right pointer */
  8175.          static char epoint[] = { "\021Stop" };        /* contains left pointe
  8176.          static char title[] = { "CURSOR: Control cursor shape (V1.0)" };
  8177.          unsigned char
  8178.                  oldattr,        /* video attribute upon entry */
  8179.                  headattr,        /* video attribute of header */
  8180.                  attr,                 /* primary video attribute */
  8181.                  standout;        /* highlighting video attribute */
  8182.          CMODE mode;
  8183.  
  8184.          static void drawdspy(int, int, int, int, int);
  8185.          static void drawstart(int, char *);
  8186.          static void drawend(int, int, char *);
  8187.          static void drawactive(int, int, CMODE);
  8188.          static void showhelp(int, int);
  8189.  
  8190.          /* get video information and initialize */
  8191.          getstate();
  8192.          Mid = Vwidth / 2;
  8193.          readca(&ch, &oldattr, Vpage);        /* preserve user's video attribu
  8194.          getctype(&start, &end, Vpage);        /* and cursor shape */
  8195.          headattr = (WHT << 4) | BLK;
  8196.  
  8197.          /* set parameters based on video mode (default = CGA) */
  8198.          height = width = 8;        /* use an 8 by 8 block character cell */
  8199.          attr = (BLU << 4) | CYAN | BRIGHT;
  8200.          standout = YEL;
  8201.          if (Vmode == MDA_M80) {
  8202.                  /* uses a 14 by 9 dot block character cell */
  8203.                  height = 14;
  8204.                  width = 9;
  8205.                  attr = NORMAL;
  8206.                  standout = BWHT;
  8207.          }
  8208.          setctype(height + 1, height + 1);        /* cursor off */
  8209.  
  8210.          /* basic text and layout */
  8211.          Ulr = 2;
  8212.          Ulc = Mid - width / 2;
  8213.          clrscrn(attr);
  8214.          putcur(0, 0, Vpage);
  8215.          writeca(' ', headattr, Vwidth, Vpage);
  8216.          putcur(0, Mid - strlen(title) / 2, Vpage);
  8217.          writestr(title, Vpage);
  8218.          showhelp(Ulr + height + 1, Mid - BOX_X / 2);
  8219.  
  8220.          /* interactively select cursor shape */
  8221.          mode = STARTSCAN;
  8222.          drawdspy(start, end, standout, width, height);
  8223.          drawstart(start, spoint);
  8224.          drawend(end, width, epoint);
  8225.          drawactive(height, width, mode);
  8226.          while (1) {
  8227.                  switch (ch = getkey()) {
  8228.                  case K_UP:
  8229.                          /* move up one scan line */
  8230.                          if (mode == STARTSCAN)
  8231.                                  drawstart(start--, "      ");
  8232.                          else
  8233.                                  drawend(end--, width, "     ");
  8234.                          break;
  8235.                  case K_DOWN:
  8236.                          /* move down one scan line */
  8237.                          if (mode == STARTSCAN)
  8238.                                  drawstart(start++, "      ");
  8239.                          else
  8240.                                  drawend(end++, width, "     ");
  8241.                          break;
  8242.                  case K_LEFT:
  8243.                          /* starting scan-line-selection mode */
  8244.                          mode = STARTSCAN;
  8245.                          drawactive(height, width, mode);
  8246.                          continue;
  8247.                  case K_RIGHT:
  8248.                          /* ending scan-line-selection mode */
  8249.                          mode = ENDSCAN;
  8250.                          drawactive(height, width, mode);
  8251.                          continue;
  8252.                  case K_RETURN:
  8253.                          /* set the new cursor shape */
  8254.                          setctype(start, end);
  8255.                          clrscrn(oldattr);
  8256.                          putcur(0, 0, Vpage);
  8257.                          exit(0);
  8258.                  }
  8259.  
  8260.                  /* make corrections at cursor image boundaries */
  8261.                  if (start < 0)
  8262.                          start = 0;
  8263.                  else if (start > height)
  8264.                          start = height;
  8265.                  if (end < 0)
  8266.                          end = 0;
  8267.                  else if (end >= height)
  8268.                          end = height - 1;
  8269.  
  8270.                  /* show updated cursor shape and pointers */
  8271.                  drawdspy(start, end, standout, width, height);
  8272.                  drawstart(start, spoint);
  8273.                  drawend(end, width, epoint);
  8274.          }
  8275.  
  8276.          exit(0);
  8277.  } /* end main() */
  8278.  
  8279.  
  8280.  /*
  8281.   *        drawdspy -- draw a magnified image of a cursor with the
  8282.   *        currently active scan lines depicted as a sequence of dots
  8283.   *        and inactive lines depicted as straight lines
  8284.   */
  8285.  
  8286.  static void
  8287.  drawdspy(s, e, a, w, h)
  8288.  int s;        /* starting scan line */
  8289.  int e;        /* ending scan line */
  8290.  int a;        /* video attribute */
  8291.  int w;        /* width */
  8292.  int h;        /* height */
  8293.  {
  8294.          int i;
  8295.  
  8296.          /* display an exploded image of each scan line */
  8297.          for (i = 0; i < h; ++i) {
  8298.                  putcur(Ulr + i, Ulc, Vpage);
  8299.                  if (s >= h)
  8300.                          /* cursor is effectively off */
  8301.                          writeca(NO_DOT, a, w, Vpage);
  8302.                  else if ((s <= e && i >= s && i <= e) || /* a full block */
  8303.                          (s > e && (i <= e || i >= s)))         /* a split blo
  8304.                          writeca(DOT, a, w, Vpage);
  8305.                  else
  8306.                          /* outside start/end range */
  8307.                          writeca(NO_DOT, a, w, Vpage);
  8308.          }
  8309.  } /* end drawdspy() */
  8310.  
  8311.  
  8312.  /*
  8313.   *        drawstart -- display a pointer to the displayed starting
  8314.   *        scan line in the magnified cursor image
  8315.   */
  8316.  
  8317.  static void
  8318.  drawstart(s, sp)
  8319.  int s;                /* starting scan line number */
  8320.  char *sp;        /* visual pointer to the displayed starting scan line */
  8321.  {
  8322.          putcur(Ulr + s, Ulc - strlen(sp), Vpage);
  8323.          putstr(sp, Vpage);
  8324.  } /* end drawstart() */
  8325.  
  8326.  
  8327.  /*
  8328.   *        drawend -- display a pointer to the displayed ending
  8329.   *        scan line in the magnified cursor image
  8330.   */
  8331.  
  8332.  static void
  8333.  drawend(e, w, ep)
  8334.  int e;                /* ending scan line number */
  8335.  int w;                /* width of the cursor image */
  8336.  char *ep;        /* visual pointer to the displayed ending scan line */
  8337.  {
  8338.          putcur(Ulr + e, Ulc + w, Vpage);
  8339.          putstr(ep, Vpage);
  8340.  } /* end drawend() */
  8341.  
  8342.  static void
  8343.  drawactive(h, w, m)
  8344.  int h, w;
  8345.  CMODE m;
  8346.  {
  8347.          int col;
  8348.  
  8349.          /* clear active selector row */
  8350.          putcur(Ulr - 1, Ulc, Vpage);
  8351.          writec(' ', w, Vpage);
  8352.  
  8353.          /* point to active selector */
  8354.          col = (m == STARTSCAN) ? 0 : w - 1;
  8355.          putcur(Ulr - 1, Ulc + col, Vpage);
  8356.          writec(D_POINT, 1, Vpage);
  8357.  } /* end drawactive() */
  8358.  
  8359.  /*
  8360.   *        showhelp -- display a set of instructions about the
  8361.   *        use of the cursor program in a fine-ruled box
  8362.   */
  8363.  
  8364.  static void
  8365.  showhelp(r, c)
  8366.  int r, c;        /* upper-left corner of help frame */
  8367.  {
  8368.          static char title[] = { " Instructions " };
  8369.          extern int drawbox(int, int, int, int, int);
  8370.  
  8371.          /* fine-ruled box */
  8372.          clrw(r, c, r + BOX_Y, c + BOX_X, (WHT << 4) | GRN | BRIGHT);
  8373.          drawbox(r, c, r + BOX_Y, c + BOX_X, Vpage);
  8374.  
  8375.          /* centered title */
  8376.          putcur(r, c + (BOX_X - strlen(title)) / 2, Vpage);
  8377.          putstr(title, Vpage);
  8378.  
  8379.          /* display symbols and text using brute-force positioning */
  8380.          putcur(r + 2, c + 2, Vpage);
  8381.          put_ch(LEFTARROW, Vpage);
  8382.          put_ch(RIGHTARROW, Vpage);
  8383.          putstr("  Change selection mode", Vpage);
  8384.          putcur(r + 3, c + 2, Vpage);
  8385.          put_ch(UPARROW, Vpage);
  8386.          put_ch(DOWNARROW, Vpage);
  8387.          putstr("  Select scan lines", Vpage);
  8388.          putcur(r + 4, c + 2, Vpage);
  8389.          put_ch(L_POINT, Vpage);
  8390.          put_ch(LRC11, Vpage);
  8391.          putstr("  Set shape and exit", Vpage);
  8392.  } /* end showhelp() */
  8393.  
  8394.  
  8395.  DELAY.C
  8396.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\DELAY.C
  8397.  
  8398.  /*
  8399.   *        delay -- provide a delay of ** approximately ** the
  8400.   *        specified duration (resolution is about 0.055 second)
  8401.   */
  8402.  
  8403.  #include <local\timer.h>
  8404.  
  8405.  void
  8406.  delay(d)
  8407.  float d;        /* duration in seconds and fractional seconds */
  8408.  {
  8409.          long ticks, then;
  8410.          extern long getticks();
  8411.  
  8412.          /* convert duration to number of PC clock ticks */
  8413.          ticks = d * TICKRATE;
  8414.  
  8415.          /* delay for the specified interval */
  8416.          then = getticks() + ticks;
  8417.          while (1)
  8418.                  if (getticks() >= then)
  8419.                          break;
  8420.  }
  8421.  
  8422.  
  8423.  DRAWBOX.C
  8424.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\DRAWBOX.C
  8425.  
  8426.  /*
  8427.   *        drawbox -- create a box with IBM line-drawing characters
  8428.   */
  8429.  
  8430.  #include <local\video.h>
  8431.  
  8432.  int
  8433.  drawbox(top, lft, btm, rgt, pg)
  8434.  int top, lft, btm, rgt, pg;
  8435.  {
  8436.          int i;
  8437.          int x;        /* interior line length for top and bottom segments */
  8438.  
  8439.          x = rgt - lft - 1;
  8440.  
  8441.          /* draw the top row */
  8442.          putcur(top, lft, pg);
  8443.          put_ch(ULC11, pg);
  8444.          writec(HBAR1, x, pg);
  8445.          putcur(top, rgt, pg);
  8446.          put_ch(URC11, pg);
  8447.  
  8448.          /* draw the sides */
  8449.          for (i = 1; i < btm - top; ++i)
  8450.          {
  8451.                  putcur(top + i, lft, pg);
  8452.                  put_ch(VBAR1, pg);
  8453.                  putcur(top + i, rgt, pg);
  8454.                  put_ch(VBAR1, pg);
  8455.          }
  8456.  
  8457.          /* draw the bottom row */
  8458.          putcur(btm, lft, pg);
  8459.          put_ch(LLC11, pg);
  8460.          writec(HBAR1, x, pg);
  8461.          putcur(btm, rgt, pg);
  8462.          put_ch(LRC11, pg);
  8463.  }
  8464.  
  8465.  
  8466.  DRVPATH.C
  8467.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\DOS\DRVPATH.C
  8468.  
  8469.  /*
  8470.   *        drvpath -- convert a drive name to a full pathname
  8471.   */
  8472.  
  8473.  #include <stdio.h>
  8474.  #include <dos.h>
  8475.  #include <string.h>
  8476.  #include <ctype.h>
  8477.  #include <local\doslib.h>
  8478.  
  8479.  char *
  8480.  drvpath(path)
  8481.  char path[];        /* path string */
  8482.                  /* must be large enough to hold a full DOS path + NUL */
  8483.  {
  8484.          union REGS inregs, outregs;
  8485.          static int drive(char);
  8486.  
  8487.          /* patch root directory onto drive name */
  8488.          strcat(path, "\\");
  8489.  
  8490.          /* set current directory path for drive from DOS */
  8491.          inregs.h.ah = GET_CUR_DIR;
  8492.          inregs.h.dl = drive(path[0]);                /* convert to drive numb
  8493.          inregs.x.si = (unsigned)&path[3];        /* start of return string */
  8494.          intdos(&inregs, &outregs);
  8495.  
  8496.          return (outregs.x.cflag ? (char *)NULL : path);
  8497.  }
  8498.  
  8499.  static int
  8500.  drive(dltr)
  8501.  char dltr;        /* drive letter */
  8502.  {
  8503.          /* 'A' (or 'a') => 1, 'B' (or 'b') => 2, etc. */
  8504.          return (tolower(dltr) - 'a' + 1);
  8505.  }
  8506.  
  8507.  
  8508.  DSPYTYPE.C
  8509.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\11SCREEN\DSPYTYPE.C
  8510.  
  8511.  /*
  8512.   *        dspytype -- determine display adapter type
  8513.   */
  8514.  
  8515.  #include <stdio.h>
  8516.  #include <dos.h>
  8517.  #include <local\bioslib.h>
  8518.  #include <local\video.h>
  8519.  
  8520.  #define MDA_SEG        0xB000
  8521.  #define CGA_SEG 0xB800
  8522.  
  8523.  main()
  8524.  {
  8525.          extern int memchk(unsigned int, unsigned int);
  8526.          int mdaflag, egaflag, cgaflag;
  8527.          int ega_mem, ega_mode;
  8528.          unsigned int features, switches;
  8529.          static int memtab[] = {
  8530.                  64, 128, 192, 256
  8531.          };
  8532.  
  8533.          mdaflag = egaflag = cgaflag = 0;
  8534.  
  8535.          /* look for display adapters */
  8536.          if (ega_info(&ega_mem, &ega_mode, &features, &switches))
  8537.                  ++egaflag;
  8538.          fputs("Enhanced graphics adapter ", stdout);
  8539.          if (egaflag) {
  8540.                  fputs("installed\n", stdout);
  8541.                  fprintf(stdout, "EGA memory size = %d-KB\n", memtab[ega_mem])
  8542.                  fprintf(stdout, "EGA is in %s mode\n",
  8543.                          ega_mode ? "monochrome" : "color");
  8544.          }
  8545.          else
  8546.                  fputs("not installed\n", stdout);
  8547.  
  8548.          if (egaflag && ega_mode == 0) {
  8549.                  /* look for IBM monochrome memory */
  8550.                  if (memchk(MDA_SEG, 0))
  8551.                          ++mdaflag;
  8552.          }
  8553.          else {
  8554.                  /* look for IBM monochrome memory */
  8555.                  if (memchk(CGA_SEG, 0))
  8556.                          ++cgaflag;
  8557.          }
  8558.          fputs("Monochrome adapter ", stdout);
  8559.          if (mdaflag)
  8560.                  fputs("installed\n", stdout);
  8561.          else
  8562.                  fputs("not installed\n", stdout);
  8563.          fputs("Color/graphics adapter ", stdout);
  8564.          if (cgaflag)
  8565.                  fputs("installed\n", stdout);
  8566.          else
  8567.                  fputs("not installed\n", stdout);
  8568.  
  8569.          /* report video settings */
  8570.          getstate();
  8571.          fprintf(stdout, "mode=%d width=%d page=%d\n", Vmode, Vwidth, Vpage);
  8572.  
  8573.          exit(0);
  8574.  }
  8575.  
  8576.  
  8577.  DUMP.C
  8578.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\10DUMP\DUMP.C
  8579.  
  8580.  /*
  8581.   *        dump -- display contents of non-ASCII files in hex byte and
  8582.   *        ASCII character forms (like the DOS debug dump option)
  8583.   */
  8584.  
  8585.  #include <stdio.h>
  8586.  #include <stdlib.h>
  8587.  #include <fcntl.h>
  8588.  #include <sys\types.h>
  8589.  #include <sys\stat.h>
  8590.  #include <io.h>
  8591.  #include <local\std.h>
  8592.  
  8593.  #define STDINPUT        0
  8594.  #define LINEWIDTH        80
  8595.  
  8596.  main(argc,argv)
  8597.  int argc;
  8598.  char *argv[];
  8599.  {
  8600.          int ch;
  8601.          BOOLEAN        sflag = FALSE,
  8602.                  vflag = FALSE,
  8603.                  errflag = FALSE;
  8604.          int fd;
  8605.          static char pgm[MAXNAME + 1] = { "dump" };
  8606.  
  8607.          extern int getopt(int, char **, char *);
  8608.          extern char *optarg;
  8609.          extern int optind, opterr;
  8610.          extern void getpname(char *, char *);
  8611.          extern int hexdump(int, BOOLEAN);
  8612.          extern void fatal(char *, char *, int);
  8613.  
  8614.          if (_osmajor >= 3)
  8615.                  getpname(*argv, pgm);
  8616.  
  8617.          while ((ch = getopt(argc, argv, "sv")) != EOF)
  8618.                  switch (ch) {
  8619.                  case 's': /* strip -- convert all non-ASCII to '.' */
  8620.                          sflag = TRUE;
  8621.                          break;
  8622.                  case 'v': /* verbose -- tell user what's happening */
  8623.                          vflag = TRUE;
  8624.                          break;
  8625.                  case '?': /* bad option */
  8626.                          errflag = TRUE;
  8627.                          break;
  8628.                  }
  8629.  
  8630.          if (errflag == TRUE) {
  8631.                  fprintf(stderr, "Usage: %s [-sv] [file...]\n", pgm);
  8632.                  exit(1);
  8633.          }
  8634.  
  8635.          if (optind == argc) {
  8636.                  if (setmode(STDINPUT, O_BINARY) == -1)
  8637.                          fatal(pgm, "Cannot set binary mode", 2);
  8638.                  hexdump(STDINPUT, sflag);
  8639.                  exit(0);
  8640.          }
  8641.  
  8642.          for ( ; optind < argc; ++optind) {
  8643.                  if ((fd = open(argv[optind], O_BINARY | O_RDONLY)) == -1) {
  8644.                          fprintf(stderr,
  8645.                                  "%s: Error opening %s -- ", pgm, argv[optind]
  8646.                          perror("");
  8647.                          continue;
  8648.                  }
  8649.                  if (vflag == TRUE)
  8650.                          fprintf(stdout, "\n%s:\n", argv[optind]);
  8651.                  if (hexdump(fd, sflag) == FAILURE) {
  8652.                          fprintf(stderr,
  8653.                                  "%s: Error reading %s -- ", pgm, argv[optind]
  8654.                          perror("");
  8655.                  }
  8656.                  if (close(fd) == -1)
  8657.                          fatal(pgm, "Error closing input file", 3);
  8658.          }
  8659.  
  8660.          exit(0);
  8661.  }
  8662.  
  8663.  
  8664.  EGA_INFO.C
  8665.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\EGA_INFO.C
  8666.  
  8667.  /*
  8668.   *        ega_info -- gather information about an EGA;
  8669.   *        return a non-zero value if one is found
  8670.   */
  8671.  
  8672.  #include <dos.h>
  8673.  #include <local\bioslib.h>
  8674.  
  8675.  #define EGA_INFO 0x10
  8676.  #define NMODES        2
  8677.  #define NMEMSIZ        4
  8678.  
  8679.  int
  8680.  ega_info(memsize, mode, features, switches)
  8681.  int *memsize;                /* EGA memory size indicator: 0 = 64K */
  8682.                          /* 1 = 128K; 2 = 192K; 3 = 256K */
  8683.  int *mode;                /* 0 = color mode; 1 = mono mode */
  8684.                          /* use getstate function to find out which mode */
  8685.  unsigned int
  8686.          *features,        /* feature bit settings */
  8687.          *switches;        /* EGA switch settings */
  8688.  {
  8689.          int result = 0;
  8690.          union REGS inregs, outregs;
  8691.  
  8692.          /* request EGA information */
  8693.          inregs.h.ah = ALT_FUNCTION;
  8694.          inregs.h.bl = EGA_INFO;
  8695.          int86(VIDEO_IO, &inregs, &outregs);
  8696.  
  8697.          *memsize = outregs.h.bl;
  8698.          *mode = outregs.h.bh;
  8699.          *features = outregs.h.ch;
  8700.          *switches = outregs.h.cl;
  8701.  
  8702.          /* return non-zero if EGA installed */
  8703.          if (*memsize >= 0 && *memsize < NMEMSIZ && *mode >= 0 && *mode < NMOD
  8704.                  result = 1;
  8705.          return (result);
  8706.  }
  8707.  
  8708.  
  8709.  EQUIPCHK.C
  8710.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\EQUIPCHK.C
  8711.  
  8712.  /*
  8713.   *        equipchk -- get equipment list
  8714.   */
  8715.  
  8716.  #include <dos.h>
  8717.  #include <local\bioslib.h>
  8718.  #include <local\equip.h>
  8719.  
  8720.  struct EQUIP Eq;
  8721.  
  8722.  int
  8723.  equipchk()
  8724.  {
  8725.          union REGS inregs, outregs;
  8726.  
  8727.          /* call BIOS equipment check routine */
  8728.          int86(EQUIP_CK, &inregs, &outregs);
  8729.  
  8730.          /* extract data from returned data word */
  8731.          Eq.nprint  = (outregs.x.ax & 0xC000) / 0x8000;
  8732.          Eq.game_io = ((outregs.x.ax & 0x1000) / 0x1000) ? 1 : 0;
  8733.          Eq.nrs232  = (outregs.x.ax & 0x0E00) /0x0200;
  8734.          Eq.ndrive  = ((outregs.x.ax & 0x00C0) / 0x0040) + 1;
  8735.          Eq.vmode   = (outregs.x.ax & 0x0030) / 0x0010;
  8736.          Eq.basemem = ((outregs.x.ax & 0x000C) / 0x0004) + 1;
  8737.          Eq.disksys = outregs.x.ax & 0x0001 == 1;
  8738.  
  8739.          return (outregs.x.cflag);
  8740.  }
  8741.  
  8742.  
  8743.  FATAL.C
  8744.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\FATAL.C
  8745.  
  8746.  /*
  8747.   *  fatal -- issue a diagnostic message and terminate
  8748.   */
  8749.  
  8750.  #include <stdio.h>
  8751.  #include <stdlib.h>
  8752.  
  8753.  void
  8754.  fatal(pname, mesg, errlevel)
  8755.  char *pname;        /* program name */
  8756.  char *mesg;        /* message text */
  8757.  int errlevel;        /* errorlevel (exit code) */
  8758.  {
  8759.          /* display error message */
  8760.          fputs(pname, stderr);
  8761.          fputc(':', stderr);
  8762.          fputc(' ', stderr);
  8763.          fputs(mesg, stderr);
  8764.  
  8765.          /* return to DOS with the specified errorlevel */
  8766.          exit(errlevel);
  8767.  }
  8768.  
  8769.  
  8770.  FCONFIG.C
  8771.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\FCONFIG.C
  8772.  
  8773.  /*
  8774.   *        fconfig -- return a FILE pointer to a local or
  8775.   *        global configuration file, or NULL if none found
  8776.   */
  8777.  
  8778.  #include <stdio.h>
  8779.  #include <stdlib.h>
  8780.  #include <string.h>
  8781.  #include <ctype.h>
  8782.  #include <local\std.h>
  8783.  
  8784.  FILE *
  8785.  fconfig(varname, fname)
  8786.  char *varname;
  8787.  char *fname;
  8788.  {
  8789.          FILE *fp;
  8790.          char pname[MAXPATH + 1];
  8791.          char *p;
  8792.  
  8793.          /* look for a local configuration file */
  8794.          if ((fp = fopen(fname, "r")) != NULL)
  8795.                  return (fp);
  8796.  
  8797.          /* look for a directory variable */
  8798.          if ((p = getenv(strupr(varname))) != NULL) {
  8799.                  strcpy(pname, p);
  8800.                  strcat(pname, "\\");
  8801.                  strcat(pname, fname);
  8802.                  if ((fp = fopen(pname, "r")) != NULL)
  8803.                          return (fp);
  8804.          }
  8805.  
  8806.          /* didn't find anything to read */
  8807.          return (NULL);
  8808.  }
  8809.  
  8810.  
  8811.  FCOPY.C
  8812.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\FCOPY.C
  8813.  
  8814.  /*
  8815.   *        fcopy -- copy input stream (fin) to output stream
  8816.   *        (fout) and return an indication of success or failure
  8817.   */
  8818.  
  8819.  #include <stdio.h>
  8820.  
  8821.  #define BUFLEN        1024
  8822.  
  8823.  int
  8824.  fcopy(fin, fout)
  8825.  FILE *fin, *fout;
  8826.  {
  8827.          int errcount = 0;
  8828.          char line[BUFLEN];
  8829.          register char *s;
  8830.  
  8831.          while ((s = fgets(line, BUFLEN, fin)) != NULL)
  8832.                  if (fputs(s, fout) == EOF)
  8833.                          ++errcount;
  8834.          if (ferror(fin))
  8835.                  ++errcount;
  8836.          return (errcount);        /* 0 if all went well */
  8837.  }
  8838.  
  8839.  
  8840.  FIRST_FM.C
  8841.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\DOS\FIRST_FM.C
  8842.  
  8843.  /*
  8844.   *        first_fm - find first file match in work directory
  8845.   */
  8846.  
  8847.  #include <dos.h>
  8848.  #include <local\doslib.h>
  8849.  
  8850.  int
  8851.  first_fm(path, fa)
  8852.  char *path;        /* pathname of directory */
  8853.  int fa;                /* attribute(s) of file to match */
  8854.  {
  8855.          union REGS inregs, outregs;
  8856.  
  8857.          /* find first matching file */
  8858.          inregs.h.ah = FIND_FIRST;
  8859.          inregs.x.cx = fa;
  8860.          inregs.x.dx = (unsigned int)path;
  8861.          (void)intdos(&inregs, &outregs);
  8862.  
  8863.          return (outregs.x.cflag);
  8864.  }
  8865.  
  8866.  
  8867.  GETCTYPE.C
  8868.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\GETCTYPE.C
  8869.  
  8870.  /*
  8871.   *        getctype -- pass back cursor type info (scan lines)
  8872.   */
  8873.  
  8874.  #include <dos.h>
  8875.  #include <local\std.h>
  8876.  #include <local\bioslib.h>
  8877.  
  8878.  #define LO_NIBBLE        0x0F
  8879.  
  8880.  int
  8881.  getctype(start_scan, end_scan, pg)
  8882.  int *start_scan;/* starting scan line */
  8883.  int *end_scan;        /* ending scan line */
  8884.  int pg;                /* "visual" page */
  8885.  {
  8886.          union REGS inregs, outregs;
  8887.  
  8888.          inregs.h.bh = pg;
  8889.          inregs.h.ah = GET_CUR;
  8890.  
  8891.          int86(VIDEO_IO, &inregs, &outregs);
  8892.  
  8893.          /* end_scan = low 4 bits of cl */
  8894.          *end_scan = outregs.h.cl & LO_NIBBLE;
  8895.  
  8896.          /* starting_scan = low 4 bits of ah */
  8897.          *start_scan = outregs.h.ch & LO_NIBBLE;
  8898.  
  8899.          return (outregs.x.cflag);
  8900.  }
  8901.  
  8902.  
  8903.  GETDRIVE.C
  8904.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\DOS\GETDRIVE.C
  8905.  
  8906.  /*
  8907.   *        getdrive -- return the number of the default drive
  8908.   */
  8909.  
  8910.  #include <dos.h>
  8911.  #include <local\doslib.h>
  8912.  
  8913.  int getdrive()
  8914.  {
  8915.          return (bdos(CURRENT_DISK, 0, 0));
  8916.  }
  8917.  
  8918.  
  8919.  GETKEY.C
  8920.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\DOS\GETKEY.C
  8921.  
  8922.  /*
  8923.   *        getkey -- return a code for single combo keystrokes
  8924.   *        - returns a unique code for each keystroke or combination
  8925.   *        - ignores "Ctrl-Break" input
  8926.   */
  8927.  
  8928.  #include <dos.h>
  8929.  #include <local\std.h>
  8930.  #include <local\doslib.h>
  8931.  #include <local\keydefs.h>
  8932.  
  8933.  int
  8934.  getkey()
  8935.  {
  8936.          int ch;
  8937.  
  8938.          /* normal key codes */
  8939.          if ((ch = bdos(KEYIN, 0, 0) & LOBYTE) != '\0')
  8940.                  return (ch);
  8941.  
  8942.          /* convert scan codes to unique internal codes */
  8943.          return ((bdos(KEYIN, 0, 0) & LOBYTE) | XF);
  8944.  }
  8945.  
  8946.  
  8947.  GETNAME.C
  8948.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\GETNAME.C
  8949.  
  8950.  /*
  8951.   *        getname -- strip drive identifier and directory node
  8952.   *        list, if any, from a pathname;  returns a pointer to
  8953.   *        the resulting filename[.ext] string or NULL for error
  8954.   */
  8955.  
  8956.  #include <stdio.h>
  8957.  #include <sys\types.h>
  8958.  #include <sys\stat.h>
  8959.  
  8960.  #define MAXFSPEC 13
  8961.  
  8962.  char *
  8963.  getname(path)
  8964.  char *path;        /* string to modify */
  8965.  {
  8966.          register char *cp;        /* character pointer */
  8967.          struct stat buf;
  8968.  
  8969.          /* try to get information about the pathname */
  8970.          if (stat(path, &buf) != 0)
  8971.                  return (NULL);        /* bad pathname */
  8972.  
  8973.          /* locate the end of the pathname string */
  8974.          cp = path;
  8975.          while (*cp != '\0')
  8976.                  ++cp;
  8977.          --cp;                /* went one too far */
  8978.  
  8979.          /* find the start of the filename part */
  8980.          while (cp > path && *cp != '\\' && *cp != ':' && *cp != '/')
  8981.                  --cp;
  8982.          if (cp > path)
  8983.                  ++cp;        /* on a separator (\, :, or /) -- move one past
  8984.  
  8985.          /* return the full filespec (filename[.ext]) */
  8986.          return (cp);
  8987.  }
  8988.  
  8989.  
  8990.  GETOPT.C
  8991.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\GETOPT.C
  8992.  
  8993.  /*
  8994.   *      Copyright (c) 1984, 1985 AT&T
  8995.   *      All Rights Reserved
  8996.   *
  8997.   *      ----- Author's Note -----
  8998.   *      getopt() is reproduced with permission of the AT&T UNIX(R) System
  8999.   *      Toolchest. This is a public domain version of getopt(3) that is
  9000.   *      distributed to registered Toolchest participants.
  9001.   *      Defining DOS_MODS alters the code slightly to obtain compatibility
  9002.   *      with DOS and support libraries provided with most DOS C compilers.
  9003.   */
  9004.  
  9005.  #define DOS_MODS
  9006.  
  9007.  #if defined (DOS_MODS)
  9008.          /* getopt() for DOS */
  9009.  #else
  9010.  #ident  "@(#)getopt.c   1.9"
  9011.  #endif
  9012.  
  9013.  /*      3.0 SID #       1.2     */
  9014.  /*LINTLIBRARY*/
  9015.  #define NULL    0
  9016.  #define EOF     (-1)
  9017.  
  9018.  /*
  9019.   *      For this to work under versions of DOS prior to 3.00, argv[0]
  9020.   *      must be set in main() to point to a valid program name or a
  9021.   *      reasonable substitute string.   (ARH, 10-8-86)
  9022.   */
  9023.  #define ERR(s, c)       if(opterr){\
  9024.          char errbuf[2];\
  9025.          errbuf[0] = c; errbuf[1] = '\n';\
  9026.          (void) write(2, argv[0], (unsigned)strlen(argv[0]));\
  9027.          (void) write(2, s, (unsigned)strlen(s));\
  9028.          (void) write(2, errbuf, 2);}
  9029.  
  9030.  #if defined (DOS_MODS)
  9031.  /* permit function prototyping under DOS */
  9032.  #include <stdlib.h>
  9033.  #include <string.h>
  9034.  #else
  9035.  /* standard UNIX declarations */
  9036.  extern int strcmp();
  9037.  extern char *strchr();
  9038.  /*
  9039.   *      The following line was moved here from the ERR definition
  9040.   *      to prevent a "duplicate definition" error message when the
  9041.   *      code is compiled under DOS.  (ARH, 10-8-86)
  9042.   */
  9043.  extern int strlen(), write();
  9044.  #endif
  9045.  
  9046.  int     opterr = 1;
  9047.  int     optind = 1;
  9048.  int     optopt;
  9049.  char    *optarg;
  9050.  
  9051.  int
  9052.  getopt(argc, argv, opts)
  9053.  int     argc;
  9054.  char    **argv, *opts;
  9055.  {
  9056.          static int sp = 1;
  9057.          register int c;
  9058.          register char *cp;
  9059.  
  9060.          if(sp == 1)
  9061.                  if(optind >= argc ||
  9062.                     argv[optind][0] != '-' || argv[optind][1] == '\0')
  9063.                          return(EOF);
  9064.                  else if(strcmp(argv[optind], "--") == NULL) {
  9065.                          optind++;
  9066.                          return(EOF);
  9067.                  }
  9068.          optopt = c = argv[optind][sp];
  9069.          if(c == ':' || (cp=strchr(opts, c)) == NULL) {
  9070.                  ERR(": illegal option -- ", c);
  9071.                  if(argv[optind][++sp] == '\0') {
  9072.                          optind++;
  9073.                          sp = 1;
  9074.                  }
  9075.                  return('?');
  9076.          }
  9077.          if(*++cp == ':') {
  9078.                  if(argv[optind][sp+1] != '\0')
  9079.                          optarg = &argv[optind++][sp+1];
  9080.                  else if(++optind >= argc) {
  9081.                          ERR(": option requires an argument -- ", c);
  9082.                          sp = 1;
  9083.                          return('?');
  9084.                  } else
  9085.                          optarg = argv[optind++];
  9086.                  sp = 1;
  9087.          } else {
  9088.                  if(argv[optind][++sp] == '\0') {
  9089.                          sp = 1;
  9090.                          optind++;
  9091.                  }
  9092.                  optarg = NULL;
  9093.          }
  9094.          return(c);
  9095.  }
  9096.  
  9097.  
  9098.  GETPNAME.C
  9099.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\GETPNAME.C
  9100.  
  9101.  /*
  9102.   *        getpname -- extract the base name of a program from
  9103.   *        the pathname string (deletes a drive specifier, any
  9104.   *        leading path node information, and the extension)
  9105.   */
  9106.  
  9107.  #include <stdio.h>
  9108.  #include <ctype.h>
  9109.  
  9110.  char *
  9111.  getpname(path, pname)
  9112.  char *path;        /* full or relative pathname */
  9113.  char *pname;        /* program name pointer */
  9114.  {
  9115.          register char *cp;
  9116.  
  9117.          /* find the end of the pathname string */
  9118.          cp = path;         /* start of pathname */
  9119.          while (*cp != '\0')
  9120.                  ++cp;
  9121.          --cp;                /* went one too far */
  9122.  
  9123.          /* find the start of the filename part */
  9124.          while (cp > path && *cp != '\\' && *cp != ':' && *cp != '/')
  9125.                  --cp;
  9126.          if (cp > path)
  9127.                  ++cp;        /* move off the pathname separator */
  9128.  
  9129.          /* copy the filename part only */
  9130.          while ((*pname = tolower(*cp)) != '.' && *pname != '\0') {
  9131.                  ++cp;
  9132.                  ++pname;
  9133.          }
  9134.          *pname = '\0';
  9135.  }
  9136.  
  9137.  
  9138.  GETREPLY.C
  9139.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\06USER\GETREPLY.C
  9140.  
  9141.  /*
  9142.   *        getreply -- display a message and wait for a reply
  9143.   */
  9144.  
  9145.  #include <stdio.h>
  9146.  #include <stdlib.h>
  9147.  #include <memory.h>
  9148.  #include <ctype.h>
  9149.  #include <local\std.h>
  9150.  #include <local\keydefs.h>
  9151.  #include "linebuf.h"
  9152.  
  9153.  char *
  9154.  getreply(row, col, width, mesg, lp, size, attr, pg)
  9155.  short row, col, width;        /* window location and width */
  9156.  char *mesg;                /* message text */
  9157.  LINEBUF *lp;                /* line pointer */
  9158.  short size;                /* size of line buffer */
  9159.  short attr;                /* video attribute for response field */
  9160.  short pg;                /* active display page */
  9161.  {
  9162.          int n, k, len;
  9163.          short mfw;        /* message field width */
  9164.          short rfw;        /* response field width */
  9165.          short ccol;        /* visible cursor column */
  9166.          int msgflag;        /* non-zero after a message is displayed */
  9167.          char *cp;        /* character pointer */
  9168.          char *wp;        /* pointer to window start */
  9169.          char *tmp;        /* temporary char pointer */
  9170.  
  9171.          extern int writemsg(short, short, short, char *, char *, short);
  9172.  
  9173.          /* display the prompt string and calculate response field width */
  9174.          putcur(row, col, pg);
  9175.          mfw = writemsg(row, col, width, mesg, NULL, pg);
  9176.          rfw = width - mfw;
  9177.          writea(attr, rfw, pg);
  9178.  
  9179.          /* collect the user's response */
  9180.          memset(lp->l_buf, '\0', size);
  9181.          wp = cp = lp->l_buf;
  9182.          putcur(row, col + mfw, pg);
  9183.          msgflag = 0;
  9184.          while ((k = getkey()) != K_RETURN) {
  9185.                  if (msgflag) {
  9186.                          /* clear old messages */
  9187.                          errmsg("");
  9188.                          putcur(row, ccol, pg);
  9189.                          msgflag = 0;
  9190.                  }
  9191.                  if (isascii(k) && isprint(k)) {
  9192.                          len = strlen(cp);
  9193.                          if (cp + len - lp->l_buf < size - 1) {
  9194.                                  memcpy(cp + 1, cp, len);
  9195.                                  *cp = k;
  9196.                                  ++cp;
  9197.                          }
  9198.                          else {
  9199.                                  errmsg("input buffer full");
  9200.                                  ++msgflag;
  9201.                          }
  9202.                  }
  9203.                  else
  9204.                          switch (k) {
  9205.                          case K_LEFT:
  9206.                                  /* move left one character */
  9207.                                  if (cp > lp->l_buf)
  9208.                                          --cp;
  9209.                                  break;
  9210.                          case K_RIGHT:
  9211.                                  /* move right one character */
  9212.                                  if (*cp != '\0')
  9213.                                          ++cp;
  9214.                                  break;
  9215.                          case K_UP:
  9216.                                  /* pop a line off the stack */
  9217.                                  if (lp->l_prev != NULL) {
  9218.                                          lp = lp->l_prev;
  9219.                                          wp = cp = lp->l_buf;
  9220.                                  }
  9221.                                  break;
  9222.                          case K_DOWN:
  9223.                                  /* push a line onto the stack */
  9224.                                  if (lp->l_next != NULL) {
  9225.                                          lp = lp->l_next;
  9226.                                          wp = cp = lp->l_buf;
  9227.                                  }
  9228.                                  break;
  9229.                          case K_HOME:
  9230.                                  /* beginning of buffer */
  9231.                                  cp = lp->l_buf;
  9232.                                  break;
  9233.                          case K_END:
  9234.                                  /* end of buffer */
  9235.                                  while (*cp != '\0')
  9236.                                          ++cp;
  9237.                                  break;
  9238.                          case K_CTRLH:
  9239.                                  if (cp > lp->l_buf) {
  9240.                                          tmp = cp - 1;
  9241.                                          memcpy(tmp, cp, strlen(tmp));
  9242.                                          --cp;
  9243.                                  }
  9244.                                  break;
  9245.                          case K_DEL:
  9246.                                  /* delete character at cursor */
  9247.                                  memcpy(cp, cp + 1, strlen(cp));
  9248.                                  break;
  9249.                          case K_ESC:
  9250.                                  /* cancel current input */
  9251.                                  lp->l_buf[0] = '\0';
  9252.                                  putcur(row, col, pg);
  9253.                                  writec(' ', width, pg);
  9254.                                  return (NULL);
  9255.                          default:
  9256.                                  errmsg("unknown command");
  9257.                                  ++msgflag;
  9258.                                  break;
  9259.                          }
  9260.  
  9261.                  /* adjust the window pointer if necessary */
  9262.                  if (cp < wp)
  9263.                          wp = cp;
  9264.                  else if (cp >= wp + rfw)
  9265.                          wp = cp + 1 - rfw;
  9266.  
  9267.                  /* display the reply window */
  9268.                  ccol = col + mfw;
  9269.                  writemsg(row, ccol, rfw, wp, NULL, pg);
  9270.  
  9271.                  /* reposition the cursor */
  9272.                  ccol = col + mfw + (cp - wp);
  9273.                  putcur(row, ccol, pg);
  9274.          }
  9275.          putcur(row, col, pg);
  9276.          writec(' ', width, pg);        /* blank message area */
  9277.          return (lp->l_buf);
  9278.  }
  9279.  
  9280.  
  9281.  GETSTATE.C
  9282.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\GETSTATE.C
  9283.  
  9284.  /*
  9285.   *        getstate -- update video state structure
  9286.   */
  9287.  
  9288.  #include <dos.h>
  9289.  #include <local\std.h>
  9290.  #include <local\bioslib.h>
  9291.  
  9292.  /* current video state/mode information */
  9293.  short Vmode;
  9294.  short Vwidth;
  9295.  short Vpage;
  9296.  
  9297.  /*
  9298.   *        video tables -- these tables of video parameters use
  9299.   *        a value of -1 to indicate that an item is not supported
  9300.   *        and 0 to indicate that an item has a variable value.
  9301.   */
  9302.  
  9303.  /* video limit tables */
  9304.  short Maxrow[] = {
  9305.          /* CGA modes */
  9306.          25, 25, 25, 25, 25, 25, 25,
  9307.          /* MDA mode */
  9308.          25,
  9309.          /* PCjr modes */
  9310.          25, 25, 25,
  9311.          /* not used */
  9312.          -1, -1,
  9313.          /* EGA modes */
  9314.          25, 25, 25, 25, 43
  9315.  };
  9316.  
  9317.  short Maxcol[] = {
  9318.          /* CGA modes */
  9319.          40, 40, 80, 80, 40, 40, 80,
  9320.          /* MDA mode */
  9321.          80,
  9322.          /* PCjr modes */
  9323.          -1, 40, 80,
  9324.          /* not used */
  9325.          -1, -1,
  9326.          /* EGA modes */
  9327.          80, 80, 80, 80
  9328.  };
  9329.  
  9330.  short Maxpage[] = {
  9331.          /* CGA modes */
  9332.          8, 8, 4, 4, 1, 1, 1,
  9333.          /* MDA mode */
  9334.          1,
  9335.          /* PCjr modes */
  9336.          0, 0, 0,
  9337.          /* not used */
  9338.          -1, -1,
  9339.          /* EGA modes */
  9340.          8, 4, 1, 1
  9341.  };
  9342.  
  9343.  int
  9344.  getstate()
  9345.  {
  9346.          union REGS inregs, outregs;
  9347.  
  9348.          inregs.h.ah = GET_STATE;
  9349.          int86(VIDEO_IO, &inregs, &outregs);
  9350.  
  9351.          Vmode = outregs.h.al;
  9352.          Vwidth = outregs.h.ah;
  9353.          Vpage = outregs.h.bh;
  9354.  
  9355.          return (outregs.x.cflag);
  9356.  }
  9357.  
  9358.  
  9359.  GETSTR.C
  9360.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\14VIEW\GETSTR.C
  9361.  
  9362.  /*
  9363.   *        getstr -- get a string from the keyboard
  9364.   */
  9365.  
  9366.  #include <stdio.h>
  9367.  #include <string.h>
  9368.  #include <local\std.h>
  9369.  #include <local\video.h>
  9370.  #include <local\keydefs.h>
  9371.  
  9372.  char *
  9373.  getstr(buf, width)
  9374.  char *buf;
  9375.  int width;
  9376.  {
  9377.          int row, col;
  9378.          char *cp;
  9379.  
  9380.          /* function prototypes */
  9381.          extern int putcur(int, int, int);
  9382.          extern int readcur(int *, int *, int);
  9383.          extern int writec(char, int, int);
  9384.          extern int getkey();
  9385.  
  9386.          /* gather keyboard input into a string buffer */
  9387.          cp = buf;
  9388.          while ((*cp = getkey()) != K_RETURN && cp - buf < width) {
  9389.                  switch (*cp) {
  9390.                  case K_CTRLH:
  9391.                          /* destructive backspace */
  9392.                          if (cp > buf) {
  9393.                                  readcur(&row, &col, Vpage);
  9394.                                  putcur(row, col - 1, Vpage);
  9395.                                  writec(' ', 1, Vpage);
  9396.                                  --cp;
  9397.                          }
  9398.                          continue;
  9399.                  case K_ESC:
  9400.                          /* cancel string input operation */
  9401.                          return (char *)NULL;
  9402.                  }
  9403.                  put_ch(*cp, Vpage);
  9404.                  ++cp;
  9405.          }
  9406.          *cp = '\0';
  9407.          return (buf);
  9408.  }
  9409.  
  9410.  
  9411.  GETTICKS.C
  9412.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\GETTICKS.C
  9413.  
  9414.  /*
  9415.   *        getticks -- get the current bios clock ticks value
  9416.   */
  9417.  
  9418.  #include <dos.h>
  9419.  #include <local\bioslib.h>
  9420.  
  9421.  long
  9422.  getticks()
  9423.  {
  9424.          long count;
  9425.          union REGS inregs, outregs;
  9426.  
  9427.          /* get BIOS time of day as no. of ticks since midnight */
  9428.          inregs.h.ah = 0;
  9429.          int86(TOD, &inregs, &outregs);
  9430.  
  9431.          /* correct for possible rollover at 24 hours */
  9432.          count = (outregs.h.al != 0) ? 0x01800B0L : 0;
  9433.  
  9434.          /* add current day ticks */
  9435.          count += (outregs.x.dx + (outregs.x.cx << 16));
  9436.  
  9437.          return (count);
  9438.  }
  9439.  
  9440.  
  9441.  GETXLINE.C
  9442.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\GETXLINE.C
  9443.  
  9444.  /*
  9445.   *        getxline -- get a line of text while expanding tabs,
  9446.   *        put text into an array, and return a pointer to the
  9447.   *        resulting null-terminated line
  9448.   */
  9449.  
  9450.  #include <stdio.h>
  9451.  #include <stdlib.h>
  9452.  #include <ctype.h>
  9453.  #include <local\std.h>
  9454.  
  9455.  char *
  9456.  getxline(buf, size, fin)
  9457.  char *buf;
  9458.  int size;
  9459.  FILE *fin;
  9460.  {
  9461.          register int ch;        /* input character */
  9462.          register char *cp;        /* character pointer */
  9463.  
  9464.          extern BOOLEAN tabstop(int);
  9465.  
  9466.          cp = buf;
  9467.          while (--size > 0 && (ch = fgetc(fin)) != EOF) {
  9468.                  if (ch == '\n') {
  9469.                          *cp++ = ch;
  9470.                          break;
  9471.                  }
  9472.                  else if (ch == '\t')
  9473.                          do {
  9474.                                  *cp = ' ';
  9475.                          } while (--size > 0 && (tabstop(++cp - buf) == FALSE)
  9476.                  else
  9477.                          *cp++ = ch & ASCII;
  9478.          }
  9479.          *cp = '\0';
  9480.          return ((ch == EOF && cp == buf) ? NULL : buf);
  9481.  }
  9482.  
  9483.  
  9484.  HEX.C
  9485.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\HEX.C
  9486.  
  9487.  /*
  9488.   *        hex.c -- hex conversions routines
  9489.   */
  9490.  
  9491.  #define NIBBLE        0x000F
  9492.  
  9493.  char hextab[] = {
  9494.          '0', '1', '2', '3', '4', '5', '6', '7',
  9495.          '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
  9496.  };
  9497.  
  9498.  /*
  9499.   *        byte2hex -- convert a byte to a string
  9500.   *        representation of its hexadecimal value
  9501.   */
  9502.  
  9503.  char *
  9504.  byte2hex(data, buf)
  9505.  unsigned char data;
  9506.  char *buf;
  9507.  {
  9508.          register char *cp;
  9509.  
  9510.          cp = buf;
  9511.          *cp++ = hextab[(data >> 4) & NIBBLE];
  9512.          *cp++ = hextab[data & NIBBLE];
  9513.          *cp = '\0';
  9514.  
  9515.          return (buf);
  9516.  } /* end byte2hex() */
  9517.  
  9518.  /*
  9519.   *        word2hex -- convert a word to a string
  9520.   *        representation of its hexadecimal value
  9521.   */
  9522.  
  9523.  char *
  9524.  word2hex(data, buf)
  9525.  unsigned int data;
  9526.  char *buf;
  9527.  {
  9528.          register char *cp;
  9529.  
  9530.          cp = buf;
  9531.          *cp++ = hextab[(data >> 12) & NIBBLE];
  9532.          *cp++ = hextab[(data >> 8) & NIBBLE];
  9533.          *cp++ = hextab[(data >> 4) & NIBBLE];
  9534.          *cp++ = hextab[data & NIBBLE];
  9535.          *cp = '\0';
  9536.  
  9537.          return (buf);
  9538.  } /* end word2hex() */
  9539.  
  9540.  
  9541.  HEX.C
  9542.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\10DUMP\HEX.C
  9543.  
  9544.  /*
  9545.   *        hex.c -- hex conversions routines
  9546.   */
  9547.  
  9548.  #define NIBBLE        0x000F
  9549.  #define BYTE        0x00FF
  9550.  #define WORD        0xFFFF
  9551.  
  9552.  char hextab[] = {
  9553.          '0', '1', '2', '3', '4', '5', '6', '7',
  9554.          '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
  9555.  };
  9556.  
  9557.  /*
  9558.   *        byte2hex -- convert a byte to a string
  9559.   *        representation of its hexadecimal value
  9560.   */
  9561.  
  9562.  char *
  9563.  byte2hex(data, buf)
  9564.  unsigned char data;
  9565.  char *buf;
  9566.  {
  9567.          char *cp;
  9568.          unsigned int d;
  9569.  
  9570.          d = data & BYTE;
  9571.          cp = buf;
  9572.          *cp++ = hextab[(d >> 4) & NIBBLE];
  9573.          *cp++ = hextab[d & NIBBLE];
  9574.          *cp = '\0';
  9575.  
  9576.          return (buf);
  9577.  }
  9578.  
  9579.  /*
  9580.   *        word2hex -- convert a word to a string
  9581.   *        representation of its hexadecimal value
  9582.   */
  9583.  
  9584.  char *
  9585.  word2hex(data, buf)
  9586.  unsigned int data;
  9587.  char *buf;
  9588.  {
  9589.          char *cp;
  9590.          unsigned int d;
  9591.  
  9592.          d = data & WORD;
  9593.          cp = buf;
  9594.          *cp++ = hextab[(d >> 12) & NIBBLE];
  9595.          *cp++ = hextab[(d >> 8) & NIBBLE];
  9596.          *cp++ = hextab[(d >> 4) & NIBBLE];
  9597.          *cp++ = hextab[d & NIBBLE];
  9598.          *cp = '\0';
  9599.  
  9600.          return (buf);
  9601.  }
  9602.  
  9603.  
  9604.  HEXDUMP.C
  9605.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\10DUMP\HEXDUMP.C
  9606.  
  9607.  /*
  9608.   *        hexdump -- read data from an open file and "dump"
  9609.   *        it in side-by-side hex and ASCII to standard output
  9610.   */
  9611.  
  9612.  #include <stdio.h>
  9613.  #include <stdlib.h>
  9614.  #include <ctype.h>
  9615.  #include <local\std.h>
  9616.  
  9617.  #define LINEWIDTH        80
  9618.  #define NBYTES                16
  9619.  #define WORD                0xFFFF
  9620.  #define RGHTMARK        179
  9621.  #define LEFTMARK        179
  9622.  #define DEL                0x7F
  9623.  
  9624.  int hexdump(fd, strip)
  9625.  int fd;
  9626.  BOOLEAN strip;
  9627.  {
  9628.          unsigned char i;
  9629.          int n;                        /* bytes per read operation */
  9630.          unsigned long offset;        /* bytes from start of file */
  9631.          char inbuf[BUFSIZ + 1], outbuf[LINEWIDTH + 1];
  9632.          char hexbuf[5];
  9633.          register char *inp, *outp;
  9634.  
  9635.          extern char *byte2hex(unsigned char, char *);
  9636.          extern char *word2hex(unsigned int, char *);
  9637.  
  9638.          offset = 0;
  9639.          while ((n = read(fd, inbuf, BUFSIZ)) != 0) {
  9640.                  if (n == -1)
  9641.                          return FAILURE;
  9642.                  inp = inbuf;
  9643.                  while (inp < inbuf + n) {
  9644.                          outp = outbuf;
  9645.  
  9646.                          /* offset in hex */
  9647.                          outp += sprintf(outp, "%08lX",
  9648.                                  offset + (unsigned long)(inp - inbuf));
  9649.                          *outp++ = ' ';
  9650.  
  9651.                          /* block of bytes in hex */
  9652.                          for (i = 0; i < NBYTES; ++i) {
  9653.                                  *outp++ = ' ';
  9654.                                  strcpy(outp, byte2hex(*inp++, hexbuf));
  9655.                                  outp += 2;
  9656.                          }
  9657.                          *outp++ = ' ';
  9658.                          *outp++ = ' ';
  9659.                          *outp++ = (strip == TRUE) ? '|' : LEFTMARK;
  9660.  
  9661.                          /* same block of bytes in ASCII */
  9662.                          inp -= NBYTES;
  9663.                          for (i = 0; i < NBYTES; ++i) {
  9664.                                  if (strip == TRUE && (*inp < ' ' || *inp >= D
  9665.                                          *outp = '.';
  9666.                                  else if (iscntrl(*inp))
  9667.                                          *outp = '.';
  9668.                                  else
  9669.                                          *outp = *inp;
  9670.                                  ++inp;
  9671.                                  ++outp;
  9672.                          }
  9673.                          *outp++ = (strip == TRUE) ? '|' : RGHTMARK;
  9674.                          *outp++ = '\n';
  9675.                          *outp = '\0';
  9676.                          fputs(outbuf, stdout);
  9677.                  }
  9678.                  offset += n;
  9679.          }
  9680.          return SUCCESS;
  9681.  }
  9682.  
  9683.  
  9684.  INTERVAL.C
  9685.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\06USER\INTERVAL.C
  9686.  
  9687.  /*
  9688.   *        interval -- report the interval given in seconds as
  9689.   *        a human-readable null-terminated string
  9690.   */
  9691.  
  9692.  #include <stdio.h>
  9693.  
  9694.  char *
  9695.  interval(seconds, buf)
  9696.  long seconds;
  9697.  char *buf;
  9698.  {
  9699.          int hh, mm, ss;
  9700.          long remainder;
  9701.  
  9702.          /* calculate the values */
  9703.          hh = seconds / 3600;
  9704.          remainder = seconds % 3600;
  9705.          mm = remainder / 60;
  9706.          ss = remainder - (mm * 60);
  9707.          sprintf(buf, "%02d:%02d:%02d\0", hh, mm, ss);
  9708.  
  9709.          return (buf);
  9710.  }
  9711.  
  9712.  
  9713.  ISCOLOR.C
  9714.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\ISCOLOR.C
  9715.  
  9716.  /*
  9717.   *        iscolor -- return TRUE if a color display system is
  9718.   *        in use and is set to one of the text modes
  9719.   */
  9720.  
  9721.  #include <local\std.h>
  9722.  #include <local\video.h>
  9723.  
  9724.  BOOLEAN
  9725.  iscolor()
  9726.  {
  9727.          getstate();
  9728.          if (Vmode != CGA_C40 || Vmode != CGA_C80)
  9729.                  return TRUE;
  9730.          return FALSE;
  9731.  }
  9732.  
  9733.  
  9734.  KBD_STAT.C
  9735.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\KBD_STAT.C
  9736.  
  9737.  /*
  9738.   *        kbd_stat -- return the keyboard status
  9739.   *        word (bit-significant)
  9740.   */
  9741.  
  9742.  #include <dos.h>
  9743.  #include <local\bioslib.h>
  9744.  #include <local\keybdlib.h>
  9745.  
  9746.  unsigned char
  9747.  kbd_stat()
  9748.  {
  9749.          union REGS inregs, outregs;
  9750.  
  9751.          inregs.h.ah = KBD_STATUS;
  9752.          int86(KEYBD_IO, &inregs, &outregs);
  9753.  
  9754.          return ((unsigned char)(outregs.h.al));
  9755.  }
  9756.  
  9757.  
  9758.  KEYREADY.C
  9759.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\DOS\KEYREADY.C
  9760.  
  9761.  /*
  9762.   *        keyready -- non-zero if the keyboard buffer
  9763.   *        has any codes waiting
  9764.   */
  9765.  
  9766.  #include <dos.h>
  9767.  #include <local\doslib.h>
  9768.  
  9769.  int
  9770.  keyready()
  9771.  {
  9772.          union REGS inregs, outregs;
  9773.  
  9774.          inregs.h.ah = CH_READY;
  9775.          intdos(&inregs, &outregs);
  9776.  
  9777.          return (outregs.h.al);
  9778.  }
  9779.  
  9780.  
  9781.  LAST_CH.C
  9782.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\LAST_CH.C
  9783.  
  9784.  /*
  9785.   *        last_ch -- return a copy of the last character
  9786.   *        before the NUL byte in a string
  9787.   */
  9788.  
  9789.  char
  9790.  last_ch(s)
  9791.  char *s;
  9792.  {
  9793.          register char *cp;
  9794.  
  9795.          /* find end of s */
  9796.          cp = s;
  9797.          while (*cp != '\0')
  9798.                  ++cp;
  9799.  
  9800.          /* return previous character */
  9801.          --cp;
  9802.          return (*cp);
  9803.  }
  9804.  
  9805.  
  9806.  LINES.C
  9807.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\LINES.C
  9808.  
  9809.  /*
  9810.   *        lines -- send newlines to the output stream
  9811.   */
  9812.  
  9813.  #include <stdio.h>
  9814.  #include <stdlib.h>
  9815.  
  9816.  int
  9817.  lines(n, fp)
  9818.  int n;
  9819.  FILE *fp;
  9820.  {
  9821.          register int i;
  9822.  
  9823.          for (i = 0; i < n; ++i)
  9824.                  if (putc('\n', fp) == EOF && ferror(fp))
  9825.                          break;
  9826.  
  9827.          /* return number of newlines emitted */
  9828.          return (i);
  9829.  }
  9830.  
  9831.  
  9832.  LS.C
  9833.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\08FILE\LS.C
  9834.  
  9835.  /*
  9836.   *        ls -- display a directory listing
  9837.   */
  9838.  
  9839.  #include <stdio.h>
  9840.  #include <stdlib.h>
  9841.  #include <string.h>
  9842.  #include <memory.h>
  9843.  #include <dos.h>
  9844.  #include <direct.h>
  9845.  #include <signal.h>
  9846.  #include <search.h>
  9847.  #include <local\std.h>
  9848.  #include <local\doslib.h>
  9849.  #include "ls.h"
  9850.  
  9851.  /* allocation quantities */
  9852.  #define N_FILES        256
  9853.  #define N_DIRS        16
  9854.  
  9855.  /* global data */
  9856.  int Multicol = 0;
  9857.  int Filetype = 0;
  9858.  int Hidden = 0;
  9859.  int Longlist = 0;
  9860.  int Reverse = 0;
  9861.  int Modtime = 0;
  9862.  
  9863.  main(argc, argv)
  9864.  int argc;
  9865.  char *argv[];
  9866.  {
  9867.          int ch, i;
  9868.          int errflag;                /* error flag */
  9869.          char *ep;                /* environment pointer */
  9870.          int status = 0;                /* return status value */
  9871.          int fileattr;                /* file attribute number */
  9872.          struct DTA buf;                /* private disk buffer */
  9873.          char path[MAXPATH + 1];        /* working pathname */
  9874.          struct OUTBUF *fp, *fq;        /* pointers to file array */
  9875.          char **dp, **dq;        /* pointer to directory pointer array */
  9876.          int fbc = 1;                /* file memory block allocation count */
  9877.          int dbc = 1;                /* directory memory block allocation coun
  9878.          int nfiles;                /* number of file elements */
  9879.          int ndirs;                /* number of directory elements */
  9880.  
  9881.          static char pgm[MAXNAME + 1] = { "ls" };
  9882.  
  9883.          /* function prototypes */
  9884.          void getpname(char *, char *);
  9885.          extern int getopt(int, char **, char *);
  9886.          extern int optind, opterr;
  9887.          extern char *optarg;
  9888.          extern char *drvpath(char *);
  9889.          extern void fatal(char *, char *, int);
  9890.          extern void setdta(char *);
  9891.          extern int first_fm(char *, int);
  9892.          extern int next_fm();
  9893.          extern int ls_fcomp(struct OUTBUF *, struct OUTBUF *);
  9894.          extern int ls_dcomp(char *, char *);
  9895.          extern int ls_single(struct OUTBUF *, int);
  9896.          extern int ls_multi(struct OUTBUF *, int);
  9897.          extern int ls_dirx(char *, char *);
  9898.          int bailout();
  9899.  
  9900.          /* guarantee that needed DOS services are available */
  9901.          if (_osmajor < 2)
  9902.                  fatal(pgm, "ls requires DOS 2.00 or later", 1);
  9903.  
  9904.          /* get program name from DOS (version 3.00 and later) */
  9905.          if (_osmajor >= 3)
  9906.                  getpname(*argv, pgm);
  9907.  
  9908.          /* useful aliases (DOS version 3.00 and later) */
  9909.          if (strcmp(pgm, "lc") == 0)
  9910.                  ++Multicol;
  9911.          if (strcmp(pgm, "lf") == 0) {
  9912.                  ++Multicol;
  9913.                  ++Filetype;
  9914.          }
  9915.  
  9916.          /* prepare for emergencies */
  9917.          if (signal(SIGINT, bailout) == (int(*)())-1) {
  9918.                  perror("Can't set SIGINT");
  9919.                  exit(2);
  9920.          }
  9921.  
  9922.          /* process optional arguments first */
  9923.          errflag = 0;
  9924.          while ((ch = getopt(argc, argv, "aCFlrt")) != EOF)
  9925.                  switch (ch) {
  9926.                  case 'a':
  9927.                          /* all files (hidden, system, etc.) */
  9928.                          ++Hidden;
  9929.                          break;
  9930.                  case 'C':
  9931.                          ++Multicol;
  9932.                          break;
  9933.                  case 'F':
  9934.                          /* show file types (/=directory, *=executable) */
  9935.                          ++Filetype;
  9936.                          break;
  9937.                  case 'l':
  9938.                          /* long list (overrides multicolumn) */
  9939.                          ++Longlist;
  9940.                          break;
  9941.                  case 'r':
  9942.                          /* reverse sort */
  9943.                          ++Reverse;
  9944.                          break;
  9945.                  case 't':
  9946.                          /* sort by file modification time */
  9947.                          ++Modtime;
  9948.                          break;
  9949.                  case '?':
  9950.                          errflag = TRUE;
  9951.                          break;
  9952.                  }
  9953.          argc -= optind;
  9954.          argv += optind;
  9955.  
  9956.          /* check for command-line errors */
  9957.          if (argc < 0 || errflag) {
  9958.                  fprintf(stderr, "Usage: %s [-aCFlrt] [pathname ...]", pgm);
  9959.                  exit(3);
  9960.          }
  9961.  
  9962.          /* allocate initial file and directory storage areas */
  9963.          dp = dq = (char **)malloc(N_DIRS * sizeof (char *));
  9964.          if (dp == NULL)
  9965.                  fatal(pgm, "Out of memory", 4);
  9966.          fp = fq = (struct OUTBUF *)malloc(N_FILES * sizeof (struct OUTBUF));
  9967.          if (fp == NULL)
  9968.                  fatal(pgm, "Out of memory", 4);
  9969.          nfiles = ndirs = 0;
  9970.  
  9971.          /* use current directory if no args */
  9972.          if (argc == 0) {
  9973.                  if (getcwd(path, MAXPATH) == NULL)
  9974.                          fatal(pgm, "Cannot get current directory", 5);
  9975.                  *dq = path;
  9976.                  ndirs = 1;
  9977.          }
  9978.          else {
  9979.                  /* use arguments as file and directory names */
  9980.                  for ( ; argc-- > 0; ++argv) {
  9981.                          strcpy(path, *argv);
  9982.                          if (path[0] == '\\') {
  9983.                                  /* prepend default drive name */
  9984.                                  memcpy(path + 2, path, strlen(path) + 1);
  9985.                                  path[0] = 'a' + getdrive();
  9986.                                  path[1] = ':';
  9987.                          }
  9988.                          if (path[1] == ':' && path[2] == '\0' && drvpath(path
  9989.                                  fprintf(stderr, "%s: Cannot get drive path",
  9990.                                  continue;
  9991.                          }
  9992.  
  9993.                          /* establish private disk transfer area */
  9994.                          setdta((char *)&buf);
  9995.  
  9996.                          /* set file attribute for search */
  9997.                          if (Hidden)
  9998.                                  fileattr = SUBDIR | HIDDEN | SYSTEM | READONL
  9999.                          else
  10000.                                  fileattr = SUBDIR;
  10001.                          if (first_fm(path, fileattr) != 0 && path[3] != '\0')
  10002.                                  fprintf(stderr, "%s -- No such file or direct
  10003.                                  continue;
  10004.                          }
  10005.                          if ((buf.d_attr & SUBDIR) == SUBDIR || path[3] == '\0
  10006.                                  /* path is a (sub)directory */
  10007.                                  *dq = strdup(path);
  10008.                                  if (++ndirs == dbc * N_DIRS) {
  10009.                                          ++dbc;        /* increase space requi
  10010.                                          dp = (char **)realloc(dp, dbc * N_DIR
  10011.                                          if (dp == NULL)
  10012.                                                  fatal(pgm, "Out of memory", 4
  10013.                                          dq = dp + dbc * N_DIRS;
  10014.                                  }
  10015.                                  else
  10016.                                          ++dq;
  10017.                          }
  10018.                          else {
  10019.                                  fq->o_name = strdup(path);
  10020.                                  fq->o_mode = buf.d_attr;
  10021.                                  fq->o_date = buf.d_mdate;
  10022.                                  fq->o_time = buf.d_mtime;
  10023.                                  fq->o_size = buf.d_fsize;
  10024.                                  if (++nfiles == fbc * N_FILES) {
  10025.                                          ++fbc;
  10026.                                          fp = (struct OUTBUF *)realloc(fp, fbc
  10027.                                          if (fp == NULL)
  10028.                                                  fatal(pgm, "Out of memory", 4
  10029.                                          fq = fp + fbc * N_FILES;
  10030.                                  }
  10031.                                  else
  10032.                                          ++fq;
  10033.                          }
  10034.                  }
  10035.          }
  10036.  
  10037.          /* output file list, if any */
  10038.          if (nfiles > 0) {
  10039.                  qsort(fp, nfiles, sizeof(struct OUTBUF), ls_fcomp);
  10040.                  if (Longlist)
  10041.                          ls_long(fp, nfiles);
  10042.                  else if (Multicol)
  10043.                          ls_multi(fp, nfiles);
  10044.                  else
  10045.                          ls_single(fp, nfiles);
  10046.                  putchar('\n');
  10047.          }
  10048.          free(fp);
  10049.  
  10050.          /* output directory lists, if any */
  10051.          if (ndirs == 1 && nfiles == 0) {
  10052.                  /* expand directory and output without header */
  10053.                  if (ls_dirx(pgm, *dp))
  10054.                          fprintf(stderr, "%s -- empty directory\n", strlwr(*dp
  10055.          }
  10056.          else if (ndirs > 0) {
  10057.                  /* expand each directory and output with headers */
  10058.                  dq = dp;
  10059.                  qsort(dp, ndirs, sizeof(char *), ls_dcomp);
  10060.                  while (ndirs-- > 0) {
  10061.                          fprintf(stdout, "%s:\n", strlwr(*dq));
  10062.                          if (ls_dirx(pgm, *dq++))
  10063.                                  fprintf(stderr, "%s -- empty directory\n",
  10064.                                          strlwr(*dq));
  10065.                          putchar('\n');
  10066.                  }
  10067.          }
  10068.  
  10069.          exit(0);
  10070.  }
  10071.  
  10072.  /*
  10073.   *        bailout -- optionally terminate upon interrupt
  10074.   */
  10075.  int
  10076.  bailout()
  10077.  {
  10078.          char ch;
  10079.  
  10080.          signal(SIGINT, bailout);
  10081.          printf("\nTerminate directory listing? ");
  10082.          scanf("%1s", &ch);
  10083.          if (ch == 'y' || ch == 'Y')
  10084.                  exit(1);
  10085.  }
  10086.  
  10087.  
  10088.  LS_DIRX.C
  10089.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\08FILE\LS_DIRX.C
  10090.  
  10091.  /*
  10092.   *        ls_dirx -- expand the contents of a directory using
  10093.   *        the DOS first/next matching file functions
  10094.   */
  10095.  
  10096.  #define DEBUG
  10097.  
  10098.  #include <stdio.h>
  10099.  #include <stdlib.h>
  10100.  #include <string.h>
  10101.  #include <malloc.h>
  10102.  #include <dos.h>
  10103.  #include <direct.h>
  10104.  #include <signal.h>
  10105.  #include <search.h>
  10106.  #include <local\std.h>
  10107.  #include <local\doslib.h>
  10108.  #include "ls.h"
  10109.  
  10110.  #define NFILES        1024
  10111.  
  10112.  extern int Recursive;
  10113.  extern int Longlist;
  10114.  extern int Multicol;
  10115.  extern int Hidden;
  10116.  
  10117.  int
  10118.  ls_dirx(pname, namep)
  10119.  char *pname;
  10120.  char *namep;
  10121.  {
  10122.          int status = 0;                        /* function return value */
  10123.          int n;                                /* number of items found */
  10124.          int fileattr;                        /* attributes of file-matching *
  10125.          struct DTA buf;                        /* disk transfer area */
  10126.          struct OUTBUF *bp, *bq;                /* output buffer pointers */
  10127.          char path[MAXPATH + 1];                /* working path string */
  10128.  
  10129.          extern void setdta(char *);
  10130.          extern int first_fm(char *, int);
  10131.          extern int next_fm();
  10132.          extern int ls_fcomp(struct OUTBUF *, struct OUTBUF *);
  10133.          extern char last_ch(char *);
  10134.  
  10135.          /* allocate a buffer */
  10136.          bp = bq = (struct OUTBUF *)malloc(NFILES * sizeof(struct OUTBUF));
  10137.          if (bp == NULL)
  10138.                  fatal(pname, "Out of memory");
  10139.  
  10140.          /* form name for directory search */
  10141.          strcpy(path, namep);
  10142.          if (last_ch(path) != '\\')
  10143.                  strcat(path, "\\");
  10144.          strcat(path, "*.*");
  10145.  
  10146.          /* list the files found */
  10147.          n = 0;
  10148.          /* establish a private DTA */
  10149.          setdta((char *)&buf);
  10150.          /* select file attributes */
  10151.          if (Hidden)
  10152.                  fileattr = SUBDIR | HIDDEN | SYSTEM | READONLY;
  10153.          else
  10154.                  fileattr = SUBDIR;
  10155.          if (first_fm(path, fileattr) == 0) {
  10156.                  /* add file or directory to the buffer */
  10157.                  do {
  10158.                          if (!Hidden && buf.d_fname[0] == '.')
  10159.                                  continue;
  10160.                          bq->o_name = strdup(buf.d_fname);
  10161.                          bq->o_mode = buf.d_attr;
  10162.                          bq->o_size = buf.d_fsize;
  10163.                          bq->o_date = buf.d_mdate;
  10164.                          bq->o_time = buf.d_mtime;
  10165.                          ++bq;
  10166.                          ++n;
  10167.                          setdta((char *)&buf);        /* reset to our DTA */
  10168.                  } while (next_fm() == 0);
  10169.  
  10170.                  if (n > 0) {
  10171.                          /* got some -- sort and list them */
  10172.                          qsort(bp, n, sizeof(struct OUTBUF), ls_fcomp);
  10173.                          if (Longlist)
  10174.                                  ls_long(bp, n);
  10175.                          else if (Multicol)
  10176.                                  ls_multi(bp, n);
  10177.                          else
  10178.                                  ls_single(bp, n);
  10179.                  }
  10180.          }
  10181.          else
  10182.                  ++status;
  10183.          free(bp);
  10184.  
  10185.          return (status);
  10186.  }
  10187.  
  10188.  
  10189.  LS_FCOMP.C
  10190.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\08FILE\LS_FCOMP.C
  10191.  
  10192.  /*
  10193.   *        ls_fcomp -- file and directory comparison functions
  10194.   */
  10195.  
  10196.  #include <string.h>
  10197.  #include "ls.h"
  10198.  
  10199.  extern int Modtime;
  10200.  extern int Reverse;
  10201.  
  10202.  
  10203.  /*
  10204.   *        ls_fcomp -- compare two "file" items
  10205.   */
  10206.  
  10207.  int
  10208.  ls_fcomp(s1, s2)
  10209.  struct OUTBUF *s1, *s2;
  10210.  {
  10211.          int result;
  10212.  
  10213.          if (Modtime) {
  10214.                  if ((result = s1->o_date - s2->o_date) == 0)
  10215.                          result = s1->o_time - s2->o_time;
  10216.          }
  10217.          else
  10218.                  result = strcmp(s1->o_name, s2->o_name);
  10219.  
  10220.          return (Reverse ? -result : result);
  10221.  } /* end_fcomp() */
  10222.  
  10223.  
  10224.  /*
  10225.   *        dcomp -- compare two "directory" items
  10226.   */
  10227.  
  10228.  int
  10229.  ls_dcomp(s1, s2)
  10230.  char *s1, *s2;
  10231.  {
  10232.          int result;
  10233.  
  10234.          result = strcmp(s1, s2);
  10235.  
  10236.          return (Reverse ? -result : result);
  10237.  } /* end ls_dcomp() */
  10238.  
  10239.  
  10240.  LS_LIST.C
  10241.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\08FILE\LS_LIST.C
  10242.  
  10243.  /*
  10244.   *        ls_list -- list functions (long, single, multi) for ls
  10245.   */
  10246.  
  10247.  #include <stdio.h>
  10248.  #include <string.h>
  10249.  #include "ls.h"
  10250.  
  10251.  #define MAXCOL                80
  10252.  #define MONTH_SHIFT        5
  10253.  #define MONTH_MASK        0x0F
  10254.  #define DAY_MASK        0x1F
  10255.  #define YEAR_SHIFT        9
  10256.  #define DOS_EPOCH        80
  10257.  #define HOUR_SHIFT        11
  10258.  #define HOUR_MASK        0x1F
  10259.  #define MINUTE_SHIFT        5
  10260.  #define MINUTE_MASK        0x3F
  10261.  
  10262.  extern int Filetype;
  10263.  
  10264.  /*
  10265.   *        ls_long -- list items in "long" format (mode time size name)
  10266.   */
  10267.  
  10268.  int
  10269.  ls_long(buf, nelem)
  10270.  struct OUTBUF *buf;
  10271.  int nelem;
  10272.  {
  10273.          int n = 0;
  10274.          char modebuf[5];
  10275.          static void modestr(unsigned short, char *);
  10276.  
  10277.          while (nelem-- > 0) {
  10278.                  /* convert mode number to a string */
  10279.                  modestr(buf->o_mode, modebuf);
  10280.                  printf("%s ", modebuf);
  10281.  
  10282.                  /* display file size in bytes */
  10283.                  if ((buf->o_mode & SUBDIR) == SUBDIR)
  10284.                          printf("        ");
  10285.                  else
  10286.                          printf("%7ld ", buf->o_size);
  10287.  
  10288.                  /* convert date and time values to formatted presentation */
  10289.                  printf("%02d-%02d-%02d ", (buf->o_date >> MONTH_SHIFT) & MONT
  10290.                          buf->o_date & DAY_MASK, (buf->o_date >> YEAR_SHIFT) +
  10291.                  printf("%02d:%02d ", (buf->o_time >> HOUR_SHIFT) & HOUR_MASK,
  10292.                          (buf->o_time >> MINUTE_SHIFT) & MINUTE_MASK);
  10293.  
  10294.                  /* display filenames as lowercase strings */
  10295.                  printf("%s\n", strlwr(buf->o_name));
  10296.  
  10297.                  ++buf;
  10298.                  ++n;
  10299.          }
  10300.  
  10301.          /* tell caller how many entries were printed */
  10302.          return (n);
  10303.  } /* end ls_long() */
  10304.  
  10305.  
  10306.  /*
  10307.   *        ls_single -- list items in a single column
  10308.   */
  10309.  
  10310.  int
  10311.  ls_single(buf, nelem)
  10312.  struct OUTBUF *buf;
  10313.  int nelem;
  10314.  {
  10315.          int n = 0;
  10316.  
  10317.          while (nelem-- > 0) {
  10318.                  printf("%s", strlwr(buf->o_name));
  10319.                  if (Filetype && (buf->o_mode & SUBDIR) == SUBDIR)
  10320.                          putchar('\\');
  10321.                  putchar('\n');
  10322.                  ++buf;
  10323.                  ++n;
  10324.          }
  10325.  
  10326.          /* tell caller how many entries were printed */
  10327.          return (n);
  10328.  } /* end ls_single() */
  10329.  
  10330.  
  10331.  /*
  10332.   *        ls_multi -- list items in multiple columns that
  10333.   *        vary in width and number based on longest item size
  10334.   */
  10335.  
  10336.  int
  10337.  ls_multi(buf, nelem)
  10338.  struct OUTBUF *buf;
  10339.  int nelem;
  10340.  {
  10341.          int i, j;
  10342.          int errcount = 0;
  10343.          struct OUTBUF *tmp;        /* temporary buffer pointer */
  10344.          struct OUTBUF *base;        /* buffer pointer for multi-col output */
  10345.          int n;                        /* number of items in list */
  10346.          int len, maxlen;        /* pathname lengths */
  10347.          int ncols;                /* number of columns to output */
  10348.          int nlines;                /* number of lines to output */
  10349.  
  10350.          /*
  10351.           *  get length of longest pathname and calculate number
  10352.           *  of columns and lines (col width = maxlen + 1)
  10353.           */
  10354.          tmp = buf;
  10355.          n = 0;
  10356.          maxlen = 0;
  10357.          for (tmp = buf, n = 0; n < nelem; ++tmp, ++n)
  10358.                  if ((len = strlen(tmp->o_name)) > maxlen)
  10359.                          maxlen = len;
  10360.          /*
  10361.           *  use width of screen - 1 to allow for newline at end of
  10362.           *  line and leave two spaces between entries (one for optional
  10363.           *  file type flag)
  10364.           */
  10365.          ncols = (MAXCOL - 1) / (maxlen + 2);
  10366.          nlines = n / ncols;
  10367.          if (n % ncols)
  10368.                  ++nlines;
  10369.  
  10370.          /* output multi-column list */
  10371.          base = buf;
  10372.          for (i = 0; i < nlines; ++i) {
  10373.                  tmp = base;
  10374.                  for (j = 0; j < ncols; ++j) {
  10375.                          len = maxlen + 2;
  10376.                          len -= printf("%s", strlwr(tmp->o_name));
  10377.                          if (Filetype && (tmp->o_mode & SUBDIR) == SUBDIR) {
  10378.                                  putchar('\\');
  10379.                                  --len;
  10380.                          }
  10381.                          while (len-- > 0)
  10382.                                  putchar(' ');
  10383.                          tmp += nlines;
  10384.                          if (tmp - buf >= nelem)
  10385.                                  break;
  10386.                  }
  10387.                  putchar('\n');
  10388.                  ++base;
  10389.          }
  10390.  
  10391.          return (errcount);
  10392.  } /* end ls_multi() */
  10393.  
  10394.  
  10395.  static void
  10396.  modestr(mode, s)
  10397.  unsigned short mode;        /* file mode number */
  10398.  char s[];                /* mode string buffer */
  10399.  {
  10400.  
  10401.          /* fill in the mode string to show what's set */
  10402.          s[0] = (mode & SUBDIR) == SUBDIR ? 'd' : '-';
  10403.          s[1] = (mode & HIDDEN) == HIDDEN ? 'h' : '-';
  10404.          s[2] = (mode & SYSTEM) == SYSTEM ? 's' : '-';
  10405.          s[3] = (mode & READONLY) == READONLY ? 'r' : '-';
  10406.          s[4] = '\0';
  10407.  } /* end modestr() */
  10408.  
  10409.  
  10410.  MEMCHK.C
  10411.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\MEMCHK.C
  10412.  
  10413.  /*
  10414.   *        memchk -- look for random-access memory at
  10415.   *        a specified location; return non-zero if found
  10416.   */
  10417.  
  10418.  #include <dos.h>
  10419.  #include <memory.h>
  10420.  
  10421.  int
  10422.  memchk(seg, os)
  10423.  unsigned int seg;
  10424.  unsigned int os;
  10425.  {
  10426.          unsigned char tstval, oldval, newval;
  10427.          unsigned int ds;
  10428.          struct SREGS segregs;
  10429.  
  10430.          /* get value of current data segment */
  10431.          segread(&segregs);
  10432.          ds = segregs.ds;
  10433.  
  10434.          /* save current contents of test location */
  10435.          movedata(seg, os, ds, (unsigned int)&oldval, 1);
  10436.  
  10437.          /* copy a known value into test location */
  10438.          tstval = 0xFC;
  10439.          movedata(ds, (unsigned int)&tstval, seg, os, 1);
  10440.  
  10441.          /* read test value back and comapre to value written */
  10442.          movedata(seg, os, ds, (unsigned int)&newval, 1);
  10443.          if (newval != tstval)
  10444.                  return (0);
  10445.  
  10446.          /* restore original contents of test location */
  10447.          movedata(ds, (unsigned int)&oldval, seg, os, 1);
  10448.  
  10449.          return (1);
  10450.  }
  10451.  
  10452.  
  10453.  MEMSIZE.C
  10454.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\MEMSIZE.C
  10455.  
  10456.  /*
  10457.   *        memsize -- get memory size
  10458.   */
  10459.  
  10460.  #include <dos.h>
  10461.  #include <local\std.h>
  10462.  #include <local\bioslib.h>
  10463.  
  10464.  int
  10465.  memsize()
  10466.  {
  10467.          union REGS inregs, outregs;
  10468.  
  10469.          return (int86(MEM_SIZE, &inregs, &outregs));
  10470.  }
  10471.  
  10472.  
  10473.  MENUMODE.C
  10474.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\13ANSI\MENUMODE.C
  10475.  
  10476.  /*
  10477.   *  menumode -- process user commands interactively
  10478.   */
  10479.  
  10480.  #include <stdio.h>
  10481.  #include <local\ansi.h>
  10482.  #include <local\ibmcolor.h>
  10483.  #include <local\keydefs.h>
  10484.  
  10485.  /* maximum color number */
  10486.  #define MAX_CNUM        15
  10487.  
  10488.  void
  10489.  menumode()
  10490.  {
  10491.          register int ch;
  10492.          int foreground, background, border;
  10493.          extern void setattr(POSITION, int);
  10494.          extern void sc_cmds(int, int, int);
  10495.  
  10496.          /* default attributes */
  10497.          foreground = IBM_WHITE;
  10498.          background = IBM_BLACK;
  10499.          border = IBM_BLACK;
  10500.  
  10501.          ANSI_SGR(ANSI_NORMAL);
  10502.          setattr(FGND, foreground);
  10503.          setattr(BKGND, background);
  10504.          ANSI_ED;
  10505.          palette(0, border);
  10506.          sc_cmds(foreground, background, border);
  10507.          while ((ch = getkey()) != K_RETURN) {
  10508.                  switch (ch) {
  10509.                  case K_F1:
  10510.                          /* decrement foreground color */
  10511.                          if (--foreground < 0)
  10512.                                  foreground = MAX_CNUM;
  10513.                          break;
  10514.                  case K_F2:
  10515.                          /* increment foreground color */
  10516.                          if (++foreground > MAX_CNUM)
  10517.                                  foreground = 0;
  10518.                          break;
  10519.                  case K_F3:
  10520.                          /* decrement background color */
  10521.                          if (--background < 0)
  10522.                                  background = MAX_CNUM;
  10523.                          break;
  10524.                  case K_F4:
  10525.                          /* increment background color */
  10526.                          if (++background > MAX_CNUM)
  10527.                                  background = 0;
  10528.                          break;
  10529.                  case K_F5:
  10530.                          /* decrement border color */
  10531.                          if (--border < 0)
  10532.                                  border = MAX_CNUM;
  10533.                          break;
  10534.                  case K_F6:
  10535.                          /* increment border color number */
  10536.                          if (++border > MAX_CNUM)
  10537.                                  border = 0;
  10538.                          break;
  10539.                  default:
  10540.                          continue;
  10541.                  }
  10542.                  ANSI_SGR(ANSI_NORMAL);
  10543.                  setattr(FGND, foreground);
  10544.                  setattr(BKGND, background);
  10545.                  palette(0, border);
  10546.                  ANSI_ED;
  10547.                  sc_cmds(foreground, background, border);
  10548.          }
  10549.          return;
  10550.  }
  10551.  
  10552.  
  10553.  MESSAGE.C
  10554.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\14VIEW\MESSAGE.C
  10555.  
  10556.  /*
  10557.   *        message -- routines used to display and clear
  10558.   *        messages in a reserved message area
  10559.   */
  10560.  
  10561.  #include "message.h"
  10562.  
  10563.  MESSAGE Ml;
  10564.  extern int writec(char, int, int);
  10565.  
  10566.  /*
  10567.   *        set up the message-line manager
  10568.   */
  10569.  
  10570.  void
  10571.  initmsg(r, c, w, a, pg)
  10572.  int r;                        /* message row */
  10573.  int c;                        /* message column */
  10574.  int w;                        /* width of message field */
  10575.  unsigned char a;        /* message field video attribute */
  10576.  int pg;                        /* active page for messages */
  10577.  {
  10578.          MESSAGE *mp;
  10579.          void clrmsg();
  10580.  
  10581.          mp = &Ml;
  10582.          mp->m_row = r;
  10583.          mp->m_col = c;
  10584.          mp->m_wid = w;
  10585.          mp->m_attr = a;
  10586.          mp->m_pg = pg;
  10587.          mp->m_flag = 1;
  10588.          clrmsg();
  10589.  }
  10590.  
  10591.  
  10592.  /*
  10593.   *        showmsg -- display a message and set the message flag
  10594.   */
  10595.  
  10596.  void
  10597.  showmsg(msg)
  10598.  char *msg;
  10599.  {
  10600.          MESSAGE *mp;
  10601.  
  10602.          mp = &Ml;
  10603.          putcur(mp->m_row, mp->m_col, mp->m_pg);
  10604.          writec(' ', mp->m_wid, mp->m_pg);
  10605.          putstr(msg, mp->m_pg);
  10606.          mp->m_flag = 1;
  10607.          return;
  10608.  }
  10609.  
  10610.  
  10611.  /*
  10612.   *        clrmsg -- erase the message area and reset the message flag
  10613.   */
  10614.  
  10615.  void
  10616.  clrmsg()
  10617.  {
  10618.          MESSAGE *mp;
  10619.  
  10620.          mp = &Ml;
  10621.          if (mp->m_flag != 0) {
  10622.                  putcur(mp->m_row, mp->m_col, mp->m_pg);
  10623.                  writec(' ', mp->m_wid, mp->m_pg);
  10624.                  mp->m_flag = 0;
  10625.          }
  10626.          return;
  10627.  }
  10628.  
  10629.  
  10630.  MX.C
  10631.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\07CONFIG\MX.C
  10632.  
  10633.  /*
  10634.   *        mx -- control Epson MX-series printer
  10635.   */
  10636.  
  10637.  #include <stdio.h>
  10638.  #include <stdlib.h>
  10639.  #include <local\std.h>
  10640.  #include <local\printer.h>
  10641.  
  10642.  extern PRINTER prt;        /* printer data */
  10643.  
  10644.  main(argc, argv)
  10645.  int argc;
  10646.  char **argv;
  10647.  {
  10648.          int ch, font;
  10649.          BOOLEAN errflag;        /* option error */
  10650.          BOOLEAN clrflag;        /* clear special fonts */
  10651.          BOOLEAN rflag;                /* hardware reset */
  10652.          BOOLEAN tflag;                /* top-of-form */
  10653.          FILE *fout;
  10654.          static char pgm[MAXNAME + 1] = { "mx" };
  10655.  
  10656.          extern void fatal(char *, char *, int);
  10657.          extern char *getpname(char *, char *);
  10658.          extern int getopt(int, char **, char *);
  10659.          extern char *optarg;
  10660.          extern int optind, opterr;
  10661.          extern int setprnt();
  10662.          extern int clrprnt(FILE *);
  10663.          extern int setfont(int, FILE *);
  10664.  
  10665.          if (_osmajor >= 3)
  10666.                  getpname(*argv, pgm);
  10667.  
  10668.          if (setprnt() == -1) {
  10669.                  fprintf(stderr, "%s: Bad printer configuration\n", pgm);
  10670.                  exit(1);
  10671.          }
  10672.  
  10673.          /* interpret command line */
  10674.          errflag = clrflag = rflag = tflag = FALSE;
  10675.          font = 0;
  10676.          fout = stdprn;
  10677.          while ((ch = getopt(argc, argv, "bcdefino:prtu")) != EOF) {
  10678.                  switch (ch) {
  10679.                  case 'b':
  10680.                          /* set bold */
  10681.                          font |= EMPHASIZED;
  10682.                          break;
  10683.                  case 'c':
  10684.                          /* set compressed */
  10685.                          font |= CONDENSED;
  10686.                          break;
  10687.                  case 'd':
  10688.                          /* set double strike */
  10689.                          font |= DOUBLE;
  10690.                          break;
  10691.                  case 'e':
  10692.                          /* set double strike */
  10693.                          font |= EXPANDED;
  10694.                          break;
  10695.                  case 'i':
  10696.                          /* set italic */
  10697.                          font |= ITALICS;
  10698.                          break;
  10699.                  case 'n':
  10700.                          /* set normal (clear all special fonts) */
  10701.                          clrflag = TRUE;
  10702.                          break;
  10703.                  case 'o':
  10704.                          /* use specified output stream */
  10705.                          if ((fout = fopen(optarg, "w")) == NULL)
  10706.                                  fatal(pgm, "cannot open output stream", 1);
  10707.                          break;
  10708.                  case 'p':
  10709.                          /* preview control strings on stdout */
  10710.                          fout = stdout;
  10711.                          break;
  10712.                  case 'r':
  10713.                          /* hardware reset */
  10714.                          rflag = TRUE;
  10715.                          break;
  10716.                  case 't':
  10717.                          /* top of form */
  10718.                          tflag = TRUE;
  10719.                          break;
  10720.                  case 'u':
  10721.                          /* set underline */
  10722.                          font |= UNDERLINE;
  10723.                          break;
  10724.                  case '?':
  10725.                          /* unknown option */
  10726.                          errflag = TRUE;
  10727.                          break;
  10728.                  }
  10729.          }
  10730.  
  10731.          /* report errors, if any */
  10732.          if (errflag == TRUE || argc == 1) {
  10733.                  fprintf(stderr, "Usage: %s -option\n", pgm);
  10734.                  fprintf(stderr,
  10735.                          "b=bold, c=compressed, d=double strike, e=expanded\n"
  10736.                  fprintf(stderr,
  10737.                          "i=italic, n=normal, o file=output to file\n");
  10738.                  fprintf(stderr,
  10739.                          "p=preview, r=reset, t=top-of-form, u=underline\n");
  10740.                  exit(2);
  10741.          }
  10742.  
  10743.          /* do hardware reset and formfeed first */
  10744.          if (rflag == TRUE)
  10745.                  fputs(prt.p_init, fout);
  10746.          else if (tflag == TRUE)
  10747.                  fputc('\f', fout);
  10748.  
  10749.          /* clear or set the aggregate font */
  10750.          if (clrflag == TRUE)
  10751.                  clrprnt(fout);
  10752.          else if (setfont(font, fout) == FAILURE) {
  10753.                  fprintf(stderr, "%s: Bad font spec\n", pgm);
  10754.                  exit(3);
  10755.          }
  10756.  
  10757.          exit(0);
  10758.  }
  10759.  
  10760.  
  10761.  NEXT_FM.C
  10762.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\DOS\NEXT_FM.C
  10763.  
  10764.  /*
  10765.   *        next_fm - find next file match in work directory
  10766.   */
  10767.  
  10768.  #include <dos.h>
  10769.  #include <local\doslib.h>
  10770.  
  10771.  int
  10772.  next_fm()
  10773.  {
  10774.          union REGS inregs, outregs;
  10775.  
  10776.          /* find next matching file */
  10777.          inregs.h.ah = FIND_NEXT;
  10778.          (void)intdos(&inregs, &outregs);
  10779.  
  10780.          return (outregs.x.cflag);
  10781.  }
  10782.  
  10783.  
  10784.  NLERASE.C
  10785.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\NLERASE.C
  10786.  
  10787.  /*
  10788.   *        nlerase -- replace the first newline in a string
  10789.   *        with a null character
  10790.   */
  10791.  
  10792.  char *
  10793.  nlerase(s)
  10794.  char *s;
  10795.  {
  10796.          register char *cp;
  10797.  
  10798.          cp = s;
  10799.          while (*cp != '\n' && *cp != '\0')
  10800.                  ++cp;
  10801.          *cp = '\0';
  10802.  
  10803.          return (s);
  10804.  }
  10805.  
  10806.  
  10807.  NOTES1.C
  10808.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\04STDLIB\NOTES1.C
  10809.  
  10810.  /*
  10811.   *        notes1 -- add an entry to a "notes" text file
  10812.   *
  10813.   *        version 1: appends new data to NOTES.TXT in the
  10814.   *        current directory -- uses local date/time stamp
  10815.   *        as a header for each new entry
  10816.   */
  10817.  
  10818.  #include <stdio.h>
  10819.  #include <stdlib.h>
  10820.  #include <time.h>
  10821.  #include <local\std.h>
  10822.  
  10823.  main()
  10824.  {
  10825.          FILE *fp;
  10826.          static char notesfile[MAXPATH + 1] = { "notes.txt" };
  10827.          char ch;
  10828.          long ltime;
  10829.          static char pgm[MAXNAME + 1] = { "notes1" };
  10830.  
  10831.          extern void fatal(char *, char *, int);
  10832.  
  10833.          /* try to open notes file in current directory */
  10834.          if ((fp = fopen(notesfile, "a")) == NULL)
  10835.                  fatal(pgm, notesfile, 1);
  10836.  
  10837.          /* append a header and date/time tag */
  10838.          ltime = time(NULL);
  10839.          fprintf(stderr, "Appending to %s: %s",
  10840.                   notesfile, ctime(<ime));
  10841.          fprintf(fp, "%s", ctime(<ime));
  10842.  
  10843.          /* append new text */
  10844.          while ((ch = getchar()) != EOF)
  10845.                  putc(ch, fp);
  10846.  
  10847.          /* clean up */
  10848.          if (fclose(fp))
  10849.                  fatal(pgm, notesfile, 2);
  10850.          exit(0);
  10851.  }
  10852.  
  10853.  
  10854.  NOTES2.C
  10855.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\04STDLIB\NOTES2.C
  10856.  
  10857.  /*
  10858.   *        notes2 -- add a date/time stamped entry to a
  10859.   *        "notes" data file.  Allow user to optionally
  10860.   *        edit the data file upon completion of the entry.
  10861.   */
  10862.  
  10863.  #include <stdio.h>
  10864.  #include <stdlib.h>
  10865.  #include <time.h>
  10866.  #include <signal.h>
  10867.  #include <process.h>
  10868.  #include <local\std.h>
  10869.  
  10870.  /* length of date/time string */
  10871.  #define DT_STR        26
  10872.  
  10873.  main(argc, argv)
  10874.  int argc;
  10875.  char **argv;
  10876.  {
  10877.          int n;                /* number of lines added */
  10878.          int exitcode = 0;
  10879.          FILE *fp;
  10880.          static char notesfile[MAXPATH + 1] = { "notes.txt" };
  10881.          static char editname[MAXPATH + 1] = { "edlin" };
  10882.          char ch;
  10883.          char dt_stamp[DT_STR];
  10884.          char *s;
  10885.          long ltime;
  10886.          static char pgm[MAXNAME + 1] = { "notes3" };
  10887.  
  10888.          extern void fatal(char *, char *, int);
  10889.          extern void getpname(char *, char *);
  10890.          static int addtxt(FILE *, FILE *);
  10891.  
  10892.          if (_osmajor >= 3)
  10893.                  getpname(*argv, pgm);
  10894.  
  10895.          /* locate the "notes" database file and open it */
  10896.          if (argc > 1)
  10897.                  strcpy(notesfile, *++argv);
  10898.          else if (s = getenv("NOTESFILE"))
  10899.                  strcpy(notesfile, s);
  10900.          if ((fp = fopen(notesfile, "a")) == NULL)
  10901.                  fatal(pgm, notesfile, 1);
  10902.  
  10903.          /* disable Ctrl-Break interrupt */
  10904.          if (signal(SIGINT, SIG_IGN) == (int(*)())-1)
  10905.                  perror("Cannot set signal");
  10906.  
  10907.          /* append a header and date/time tag */
  10908.          ltime = time(NULL);
  10909.          strcpy(dt_stamp, ctime(<ime));
  10910.          fprintf(stderr, "Appending to %s: %s", notesfile, dt_stamp);
  10911.          fprintf(fp, "\n%s", dt_stamp);
  10912.  
  10913.          /* add text to notes file */
  10914.          if ((n = addtxt(stdin, fp)) == 0) {
  10915.                  fputs("No new text", stderr);
  10916.                  if (fclose(fp))
  10917.                          fatal(pgm, notesfile, 2);
  10918.                  exit(0);
  10919.          }
  10920.          else
  10921.                  fprintf(stderr, "%d line(s) added to %s\n", n, notesfile);
  10922.          if (fclose(fp))
  10923.                  fatal(pgm, notesfile, 2);
  10924.  
  10925.          /* optionally edit text in the notes file */
  10926.          fprintf(stderr, "E + ENTER to edit; ENTER alone to quit: ");
  10927.          while ((ch = tolower(getchar())) != '\n')
  10928.                  if (ch = 'e') {
  10929.                          if (s = getenv("EDITOR"))
  10930.                                  strcpy(editname, s);
  10931.                          if ((exitcode = spawnlp(P_WAIT, editname, editname,
  10932.                                  notesfile, NULL)) == -1)
  10933.                                  fatal(pgm, editname, 3);
  10934.                  }
  10935.          exit(exitcode);
  10936.  }
  10937.  
  10938.  /*
  10939.   *        addtxt -- append new text to notes file
  10940.   */
  10941.  static int addtxt(fin, fout)
  10942.  FILE *fin, *fout;
  10943.  {
  10944.          int ch;
  10945.          int col = 0;        /* column */
  10946.          int n = 0;        /* number of lines added */
  10947.  
  10948.          while ((ch = fgetc(fin)) != EOF) {
  10949.                  if (ch == '.' && col == 0) {
  10950.                          ch = fgetc(fin); /* trash the newline */
  10951.                          break;
  10952.                  }
  10953.                  fputc(ch, fout);
  10954.                  if (ch == '\n') {
  10955.                          col = 0;
  10956.                          ++n;
  10957.                  }
  10958.                  else
  10959.                          ++col;
  10960.          }
  10961.          return (n);
  10962.  }
  10963.  
  10964.  
  10965.  PALETTE.C
  10966.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\PALETTE.C
  10967.  
  10968.  /*
  10969.   *        palette        -- set graphics color values or border color
  10970.   */
  10971.  
  10972.  #include <dos.h>
  10973.  #include <local\bioslib.h>
  10974.  
  10975.  int
  10976.  palette(id, color)
  10977.  unsigned int id, color;
  10978.  {
  10979.          union REGS inregs, outregs;
  10980.  
  10981.          inregs.h.ah = PALETTE;
  10982.          inregs.h.bh = id;
  10983.          inregs.h.bl = color;
  10984.          int86(VIDEO_IO, &inregs, &outregs);
  10985.  
  10986.          return(outregs.x.cflag);
  10987.  }
  10988.  
  10989.  
  10990.  PARSE.C
  10991.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\13ANSI\PARSE.C
  10992.  
  10993.  /*
  10994.   *        parse -- process a list of attribute specifications
  10995.   */
  10996.  
  10997.  #include <stdio.h>
  10998.  #include <local\ansi.h>
  10999.  #include <local\std.h>
  11000.  #include <local\ibmcolor.h>
  11001.  
  11002.  /* buffer length for string comparisons */
  11003.  #define NCHARS        3
  11004.  #define C_MASK        0x7
  11005.  
  11006.  void
  11007.  parse(nargs, argvec)
  11008.  int nargs;        /* number of argument vectors */
  11009.  char *argvec[];        /* pointer to the argument vector array */
  11010.  {
  11011.          int i, intensity;
  11012.          int attribute;
  11013.          POSITION pos;
  11014.          char str[NCHARS + 1];
  11015.          extern int colornum(char *);
  11016.          extern void setattr(POSITION, int);
  11017.  
  11018.          /* clear all attributes */
  11019.          ANSI_SGR(ANSI_NORMAL);
  11020.  
  11021.          /* look for a single attribute specification */
  11022.          if (nargs == 2) {
  11023.                  attribute = colornum(argvec[1]);
  11024.                  switch (attribute) {
  11025.                  case IBM_NORMAL:
  11026.                          palette(0, IBM_BLACK);
  11027.                          return;
  11028.                  case IBM_REVERSE:
  11029.                          ANSI_SGR(ANSI_REVERSE);
  11030.                          palette(0, IBM_WHITE);
  11031.                          return;
  11032.                  case IBM_INVISIBLE:
  11033.                          ANSI_SGR(ANSI_INVISIBLE);
  11034.                          return;
  11035.                  case IBM_BLINK:
  11036.                          ANSI_SGR(ANSI_BLINK);
  11037.                          return;
  11038.                  }
  11039.          }
  11040.  
  11041.          /* must be separate attribute specifications */
  11042.          pos = FGND;
  11043.          intensity = 0;
  11044.          for (i = 1; i < nargs; ++i) {
  11045.                  attribute = colornum(argvec[i]);
  11046.                  if (attribute == -1) {
  11047.                          ANSI_ED;
  11048.                          fprintf(stderr, "\nIllegal parameter\n");
  11049.                          exit (2);
  11050.                  }
  11051.                  if (attribute == IBM_BRIGHT) {
  11052.                          intensity = IBM_BRIGHT;
  11053.                          continue;
  11054.                  }
  11055.                  setattr(pos, attribute | intensity);
  11056.                  if (pos == FGND)
  11057.                          pos = BKGND;
  11058.                  else if (pos == BKGND)
  11059.                          pos = BDR;
  11060.                  intensity = 0;
  11061.          }
  11062.          return;
  11063.  }
  11064.  
  11065.  
  11066.  PR.C
  11067.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\09PRINT\PR.C
  11068.  
  11069.  /*
  11070.   *        pr -- file printer
  11071.   */
  11072.  
  11073.  #include <stdio.h>
  11074.  #include <stdlib.h>
  11075.  #include <dos.h>
  11076.  #include <local\std.h>
  11077.  #include "print.h"
  11078.  
  11079.  char Pagelist[MAXLINE];
  11080.  
  11081.  main(argc, argv)
  11082.  int argc;
  11083.  char **argv;
  11084.  {
  11085.          int ch;
  11086.          BOOLEAN errflag;
  11087.          extern PRINT pcnf;
  11088.          static char pgm[MAXNAME + 1] = { "pr" };
  11089.  
  11090.          extern char *getpname(char *, char *);
  11091.          extern int getopt(int, char **, char *);
  11092.          extern char *optarg;
  11093.          extern int optind, opterr;
  11094.          extern int pr_gcnf(char *);
  11095.          extern pr_file(char *, int, char **);
  11096.          extern void pr_help(char *);
  11097.          extern void fixtabs(int);
  11098.          extern int setprnt();
  11099.  
  11100.          if (_osmajor >= 3)
  11101.                  getpname(*argv, pgm);
  11102.  
  11103.          /* do configuration */
  11104.          if (pr_gcnf(pgm) != 0) {
  11105.                  fprintf(stderr, "%s: Configuration error", pgm);
  11106.                  exit(2);
  11107.          }
  11108.          if (setprnt() == -1) {
  11109.                  fprintf(stderr, "%s: Bad printer configuration\n", pgm);
  11110.                  exit(1);
  11111.          }
  11112.          fixtabs(pcnf.p_tabint);
  11113.  
  11114.          /* process command-line arguments */
  11115.          while ((ch = getopt(argc, argv, "efgh:l:no:ps:w:")) != EOF) {
  11116.                  switch (ch) {
  11117.                  case 'e':
  11118.                          /* force "Epson-compatible " printer mode */
  11119.                          pcnf.p_mode = 1;
  11120.                          break;
  11121.                  case 'f':
  11122.                          /* use formfeed to eject a page */
  11123.                          pcnf.p_ff = 1;
  11124.                          break;
  11125.                  case 'g':
  11126.                          /* force "generic" printer mode */
  11127.                          pcnf.p_mode = 0;
  11128.                          break;
  11129.                  case 'h':
  11130.                          /* use specified header */
  11131.                          strcpy(pcnf.p_hdr, optarg);
  11132.                          break;
  11133.                  case 'l':
  11134.                          /* set lines per page */
  11135.                          pcnf.p_len = atoi(optarg);
  11136.                          break;
  11137.                  case 'n':
  11138.                          /* enable line numbering */
  11139.                          pcnf.p_lnum = 1;
  11140.                          break;
  11141.                  case 'o':
  11142.                          /* set left margin */
  11143.                          pcnf.p_lmarg = atoi(optarg);
  11144.                          break;
  11145.                  case 'p':
  11146.                          /* preview output on screen */
  11147.                          strcpy(pcnf.p_dest, "");
  11148.                          break;
  11149.                  case 's':
  11150.                          /* output selected pages */
  11151.                          strcpy(Pagelist, optarg);
  11152.                          break;
  11153.                  case 'w':
  11154.                          /* set page width in columns */
  11155.                          pcnf.p_wid = atoi(optarg);
  11156.                          break;
  11157.                  case '?':
  11158.                          /* unknown option */
  11159.                          errflag = TRUE;
  11160.                          break;
  11161.                  }
  11162.          }
  11163.          if (errflag == TRUE) {
  11164.                  pr_help(pgm);
  11165.                  exit(3);
  11166.          }
  11167.  
  11168.          /* print the files */
  11169.          pr_file(pgm, argc - optind, argv += optind);
  11170.  
  11171.          exit(0);
  11172.  }
  11173.  
  11174.  
  11175.  PRINTER.C
  11176.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\PRINTER.C
  11177.  
  11178.  /*
  11179.   *        printer -- interface functions for printer
  11180.   */
  11181.  
  11182.  #include <stdio.h>
  11183.  #include <stdlib.h>
  11184.  #include <string.h>
  11185.  #include <local\std.h>
  11186.  #include <local\printer.h>
  11187.  
  11188.  PRINTER prt;        /* printer data */
  11189.  
  11190.  /*
  11191.   *        setprnt -- install printer codes from configuration
  11192.   *        file for printer (defaults to Epson MX/FX series)
  11193.   */
  11194.  
  11195.  #define NSELEM        13
  11196.  
  11197.  int
  11198.  setprnt()
  11199.  {
  11200.          int n;
  11201.          char *s, line[MAXLINE];
  11202.          FILE *fp, *fconfig(char *, char *);
  11203.  
  11204.          /* use local or global config file, if any */
  11205.          if ((fp = fconfig("CONFIG", "printer.cnf")) != NULL) {
  11206.                  n = 0;
  11207.                  while (fgets(line, MAXLINE, fp) != NULL) {
  11208.                          if ((s = strtok(line, " \t\n")) == NULL)
  11209.                                  return (-1);
  11210.                          switch (n) {
  11211.                          case 0:
  11212.                                  strcpy(prt.p_init, s);
  11213.                                  break;
  11214.                          case 1:
  11215.                                  strcpy(prt.p_bold, s);
  11216.                                  break;
  11217.                          case 2:
  11218.                                  strcpy(prt.p_ds, s);
  11219.                                  break;
  11220.                          case 3:
  11221.                                  strcpy(prt.p_ital, s);
  11222.                                  break;
  11223.                          case 4:
  11224.                                  strcpy(prt.p_cmp, s);
  11225.                                  break;
  11226.                          case 5:
  11227.                                  strcpy(prt.p_exp, s);
  11228.                                  break;
  11229.                          case 6:
  11230.                                  strcpy(prt.p_ul, s);
  11231.                                  break;
  11232.                          case 7:
  11233.                                  strcpy(prt.p_xbold, s);
  11234.                                  break;
  11235.                          case 8:
  11236.                                  strcpy(prt.p_xds, s);
  11237.                                  break;
  11238.                          case 9:
  11239.                                  strcpy(prt.p_xital, s);
  11240.                                  break;
  11241.                          case 10:
  11242.                                  strcpy(prt.p_xcmp, s);
  11243.                                  break;
  11244.                          case 11:
  11245.                                  strcpy(prt.p_xexp, s);
  11246.                                  break;
  11247.                          case 12:
  11248.                                  strcpy(prt.p_xul, s);
  11249.                                  break;
  11250.                          default:
  11251.                                  /* too many lines */
  11252.                                  return (-1);
  11253.                          }
  11254.                          ++n;
  11255.                  }
  11256.                  if (n != NSELEM)
  11257.                          /* probably not enough lines */
  11258.                          return (-1);
  11259.          }
  11260.  
  11261.          /* or use Epson defaults */
  11262.          strcpy(prt.p_init, "\033@");        /* hardware reset */
  11263.          strcpy(prt.p_bold, "\033E");        /* emphasized mode */
  11264.          strcpy(prt.p_ds, "\033G");        /* double-strike mode */
  11265.          strcpy(prt.p_ital, "\0334");        /* italic mode */
  11266.          strcpy(prt.p_cmp, "\017");        /* condensed mode */
  11267.          strcpy(prt.p_exp, "\016");        /* expanded mode */
  11268.          strcpy(prt.p_ul, "\033-1");        /* underline mode */
  11269.          strcpy(prt.p_xbold, "\033F");        /* cancel emphasized mode */
  11270.          strcpy(prt.p_xds, "\033H");        /* cancel double-strike mode */
  11271.          strcpy(prt.p_xital, "\0335");        /* cancel italic mode */
  11272.          strcpy(prt.p_xcmp, "\022");        /* cancel condensed mode */
  11273.          strcpy(prt.p_xexp, "\024");        /* cancel expanded mode */
  11274.          strcpy(prt.p_xul, "\033-0");        /* cancel underline mode */
  11275.  
  11276.          return (0);
  11277.  }
  11278.  
  11279.  /*
  11280.   *        clrprnt -- clear printer options to default values
  11281.   *        (clears individual options to avoid the "paper creep"
  11282.   *        that occurs with repeated printer resets and to avoid
  11283.   *        changing the printer's notion of top-of-form position)
  11284.   */
  11285.  
  11286.  int
  11287.  clrprnt(fout)
  11288.  FILE *fout;
  11289.  {
  11290.          fputs(prt.p_xbold, fout);        /* cancel emphasized mode */
  11291.          fputs(prt.p_xds, fout);                /* cancel double-strike mode *
  11292.          fputs(prt.p_xital, fout);        /* cancel italic mode */
  11293.          fputs(prt.p_xcmp, fout);        /* cancel condensed mode */
  11294.          fputs(prt.p_xexp, fout);        /* cancel expanded mode */
  11295.          fputs(prt.p_xul, fout);                /* cancel underline mode */
  11296.  } /* end clrprnt() */
  11297.  
  11298.  /*
  11299.   *        setfont -- set the printing font to the type specified
  11300.   *        by the argument (may be a compound font specification)
  11301.   */
  11302.  
  11303.  int
  11304.  setfont(ftype, fout)
  11305.  int ftype;        /* font type specifier */
  11306.  FILE *fout;        /* output stream */
  11307.  {
  11308.          clrprnt(fout);
  11309.          if ((ftype & CONDENSED) == CONDENSED)
  11310.                  if ((ftype & DOUBLE) == DOUBLE ||
  11311.                          (ftype & EMPHASIZED) == EMPHASIZED)
  11312.                          return FAILURE;
  11313.                  else if (*prt.p_cmp)
  11314.                          fputs(prt.p_cmp, fout);
  11315.          if (*prt.p_ds && (ftype & DOUBLE) == DOUBLE)
  11316.                  fputs(prt.p_ds, fout);
  11317.          if (*prt.p_bold && (ftype & EMPHASIZED) == EMPHASIZED)
  11318.                  fputs(prt.p_bold, fout);
  11319.          if (*prt.p_exp && (ftype & EXPANDED) == EXPANDED)
  11320.                  fputs(prt.p_exp, fout);
  11321.          if (*prt.p_ital && (ftype & ITALICS) == ITALICS)
  11322.                  fputs(prt.p_ital, fout);
  11323.          if (*prt.p_ul && (ftype & UNDERLINE) == UNDERLINE)
  11324.                  fputs(prt.p_ul, fout);
  11325.  
  11326.          return SUCCESS;
  11327.  } /* end setfont() */
  11328.  
  11329.  
  11330.  PRTSTR.C
  11331.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\07CONFIG\PRTSTR.C
  11332.  
  11333.  /*
  11334.   *        prtstr -- send text string(s) to standard printer
  11335.   */
  11336.  
  11337.  #include <stdio.h>
  11338.  #include <stdlib.h>
  11339.  #include <local\std.h>
  11340.  
  11341.  main(argc, argv)
  11342.  int argc;
  11343.  char **argv;
  11344.  {
  11345.          int ch;
  11346.          BOOLEAN errflag, lineflag;
  11347.          static char pgm[MAXNAME + 1] = { "prtstr" };
  11348.          FILE *fout;
  11349.  
  11350.          extern char *getpname(char *, char *);
  11351.          extern int getopt(int, char **, char *);
  11352.          extern int optind, opterr;
  11353.          extern char *optarg;
  11354.  
  11355.          if (_osmajor >= 3)
  11356.                  getpname(*argv, pgm);
  11357.  
  11358.          /* process options, if any */
  11359.          errflag = FALSE;
  11360.          lineflag = TRUE;
  11361.          fout = stdprn;
  11362.          while ((ch = getopt(argc, argv, "np")) != EOF)
  11363.                  switch (ch) {
  11364.                  case 'n':
  11365.                          /* don't emit the trailing newline */
  11366.                          lineflag = FALSE;
  11367.                          break;
  11368.                  case 'p':
  11369.                          /* preview on stdout */
  11370.                          fout = stdout;
  11371.                          break;
  11372.                  case '?':
  11373.                          /* bad option */
  11374.                          errflag = TRUE;
  11375.                          break;
  11376.                  }
  11377.          if (errflag == TRUE) {
  11378.                  fprintf(stderr, "Usage: %s [-np] [string...]\n");
  11379.                  exit(1);
  11380.          }
  11381.  
  11382.          /* print the string(s) */
  11383.          argc -= optind;
  11384.          argv += optind;
  11385.          while (argc-- > 1 ) {
  11386.                  fputs(*argv++, fout);
  11387.                  fputc(' ', fout);
  11388.          }
  11389.          fputs(*argv++, fout);
  11390.          if (lineflag == TRUE)
  11391.                  fputc(' ', fout);
  11392.          if (lineflag == TRUE)
  11393.                  fputc('\n', fout);
  11394.  
  11395.          exit(0);
  11396.  }
  11397.  
  11398.  
  11399.  PR_CPY.C
  11400.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\09PRINT\PR_CPY.C
  11401.  
  11402.  /*
  11403.   *        pr_cpy -- copy input stream to output stream
  11404.   */
  11405.  
  11406.  #include <stdio.h>
  11407.  #include <string.h>
  11408.  #include <local\std.h>
  11409.  #include <local\printer.h>
  11410.  #include <sys\types.h>
  11411.  #include <sys\stat.h>
  11412.  #include <time.h>
  11413.  #include "print.h"
  11414.  
  11415.  extern PRINT pcnf;
  11416.  extern char Pagelist[MAXLINE];
  11417.  extern long Highest;
  11418.  
  11419.  int
  11420.  pr_cpy(fin, fout, fname)
  11421.  FILE *fin;
  11422.  FILE *fout;
  11423.  char *fname;
  11424.  {
  11425.          int errcount = 0;
  11426.          unsigned int p_line;        /* page-relative line number */
  11427.          long f_line;                /* file-relative line number */
  11428.          long f_page;                /* file-relative page number */
  11429.          int lnlen;                /* line length */
  11430.          char line[MAXLINE];        /* input line buffer */
  11431.          struct stat tbuf;        /* file information */
  11432.          long ltime;                /* date and time */
  11433.          FILE *fnull, *fx;        /* additional output file pointers */
  11434.  
  11435.          extern void mkslist(char *);        /* make a selection list */
  11436.          extern int selected(long);        /* is item in the list? */
  11437.          extern int spaces(int, FILE *);        /* emit string of spaces */
  11438.          extern int setfont(int, FILE *);/* set printer font type */
  11439.          extern int clrprnt(FILE *);        /* clear special fonts */
  11440.          extern int lines(int, FILE *);        /* emit string of blank lines *
  11441.          static int fit(int, int);        /* will line fit on page? */
  11442.          extern int pr_line(char *, FILE *, unsigned int);
  11443.  
  11444.          /* install page selection list, if any */
  11445.          if (Pagelist[0] != '\0') {
  11446.                  /* open the NUL device for dumping output */
  11447.                  if ((fnull = fopen("NUL", "w")) == NULL) {
  11448.                          perror("Error opening NUL device");
  11449.                          exit(1);
  11450.                  }
  11451.                  mkslist(Pagelist);
  11452.          }
  11453.          else
  11454.                  Highest = BIGGEST;
  11455.  
  11456.          /* get date and time stamp */
  11457.          if (*fname == '\0')
  11458.                  /* using stdin -- use today's date and time */
  11459.                  ltime = time(NULL);
  11460.          else {
  11461.                  if (stat(fname, &tbuf) == -1)
  11462.                          return (-1);
  11463.                  /* use file's modification time */
  11464.                  ltime = tbuf.st_mtime;
  11465.          }
  11466.          p_line = 0;
  11467.          f_line = 1;
  11468.          f_page = 1;
  11469.          while ((lnlen = pr_getln(line, MAXLINE, fin)) > 0 ) {
  11470.                  /* if formfeed or no room for line, eject page */
  11471.                  if (line[0] == '\f' || !fit(lnlen, p_line)) {
  11472.                          /* to top of next page */
  11473.                          if (pcnf.p_ff == 0)
  11474.                                  lines(pcnf.p_len - p_line, fx);
  11475.                          else
  11476.                                  fputc('\f', fx);
  11477.                          p_line = 0;
  11478.                  }
  11479.  
  11480.                  /* if at top of page, print the header */
  11481.                  if (p_line == 0) {
  11482.                          if (f_page > Highest)
  11483.                                  break;
  11484.                          fx = selected(f_page) ? fout : fnull;
  11485.                          p_line += lines(pcnf.p_top1, fx);
  11486.                          if (pcnf.p_mode != 0)
  11487.                                  setfont(EMPHASIZED, fx);
  11488.                          spaces(pcnf.p_lmarg, fx);
  11489.                          if (*pcnf.p_hdr != '\0')
  11490.                                  fprintf(fx, "%s  ", pcnf.p_hdr);
  11491.                          else if (*fname != '\0')
  11492.                                  fprintf(fx, "%s  ", strupr(fname));
  11493.                          fprintf(fx, "Page %u  ", f_page++);
  11494.                          fputs(ctime(<ime), fx);
  11495.                          ++p_line;
  11496.                          if (pcnf.p_mode != 0)
  11497.                                  setfont(pcnf.p_font, fx);
  11498.                          p_line += lines(pcnf.p_top2, fx);
  11499.                  }
  11500.  
  11501.                  /* OK to output the line */
  11502.                  if (line[0] != '\f')
  11503.                          p_line += pr_line(line, fx, f_line++);
  11504.          }
  11505.          if (ferror(fin) != 0)
  11506.                  ++errcount;
  11507.          if (p_line > 0 && p_line < pcnf.p_len)
  11508.                  if (pcnf.p_ff == 0)
  11509.                          lines(pcnf.p_len - p_line, fx);
  11510.                  else
  11511.                          fputc('\f', fx);
  11512.  
  11513.          if (pcnf.p_mode != 0)
  11514.                  clrprnt(fx);
  11515.          return (errcount);
  11516.  }
  11517.  
  11518.  /*
  11519.   *        fit -- return non-zero value if enough physical
  11520.   *        lines are available on the current page to take
  11521.   *        the current logical line of text
  11522.   */
  11523.  
  11524.  NFLDWIDTH  8        /* width of number field */
  11525.  
  11526.  static int
  11527.  fit(len, ln)
  11528.  int len, ln;
  11529.  {
  11530.          int need, left;        /* physical lines */
  11531.          int cols;        /* columns of actual output */
  11532.          int lw;                /* displayable line width */
  11533.  
  11534.          /* total need (columns -> physical lines) */
  11535.          cols = len + (pcnf.p_lnum > 0 ? NFLDWIDTH : 0);
  11536.          lw = pcnf.p_wid - pcnf.p_lmarg - pcnf.p_rmarg;
  11537.          need = 1 + cols / lw;
  11538.  
  11539.          /* lines remaining on page */
  11540.          left = pcnf.p_len - ln - pcnf.p_btm;
  11541.  
  11542.          return (need <= left ? 1 : 0);
  11543.  }
  11544.  
  11545.  
  11546.  PR_FILE.C
  11547.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\09PRINT\PR_FILE.C
  11548.  
  11549.  /*
  11550.   *        pr_file -- process each filename or standard input
  11551.   */
  11552.  
  11553.  #include <stdio.h>
  11554.  #include <stdlib.h>
  11555.  #include <string.h>
  11556.  #include <local\std.h>
  11557.  #include "print.h"
  11558.  
  11559.  int
  11560.  pr_file(pname, ac, av)
  11561.  char *pname;
  11562.  int ac;
  11563.  char **av;
  11564.  {
  11565.          int ch, errcount = 0;
  11566.          FILE *fin, *fout;
  11567.          extern PRINT pcnf;
  11568.  
  11569.          extern void fatal(char *, char *, int);
  11570.          extern int pr_cpy(FILE *, FILE *, char *);
  11571.  
  11572.          /* open output stream only if not already open */
  11573.          if (*pcnf.p_dest == '\0' || strcmp(pcnf.p_dest, "CON") == 0)
  11574.                  fout = stdout;
  11575.          else if (strcmp(pcnf.p_dest, "PRN") == 0)
  11576.                  fout = stdprn;
  11577.          else if (strcmp(pcnf.p_dest, "AUX") == 0)
  11578.                  fout = stdaux;
  11579.          else
  11580.                  if ((fout = fopen(pcnf.p_dest, "w")) == NULL)
  11581.                          fatal(pname, "Error open destination stream", 1);
  11582.  
  11583.          /* prepare input stream */
  11584.          if (ac == 0)
  11585.                  pr_cpy(stdin, fout, "");
  11586.          else {
  11587.                  for (; ac > 0; --ac, ++av) {
  11588.                          if ((fin = fopen(*av, "r")) == NULL) {
  11589.                                  fprintf(stderr, "%s: Error opening %s",
  11590.                                          pname, *av);
  11591.                                  continue;
  11592.                          }
  11593.                          if (pr_cpy(fin, fout, *av) == -1) {
  11594.                                  fprintf(stderr, "%s: Cannot stat %s",
  11595.                                          pname, *av);
  11596.                                  continue;
  11597.                          }
  11598.                          if (fclose(fin) == EOF)
  11599.                                  fatal(pname, "Error closing input file", 2);
  11600.                  }
  11601.          }
  11602.  
  11603.          return (errcount);
  11604.  }
  11605.  
  11606.  
  11607.  PR_GCNF.C
  11608.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\09PRINT\PR_GCNF.C
  11609.  
  11610.  /*
  11611.   *        pr_gcnf -- get configuration for pr program
  11612.   */
  11613.  
  11614.  #include <stdio.h>
  11615.  #include <string.h>
  11616.  #include <local\std.h>
  11617.  #include <local\printer.h>
  11618.  #include "print.h"
  11619.  
  11620.  /* expected number of configuration items */
  11621.  #define N_NBR        12
  11622.  
  11623.  PRINT pcnf;
  11624.  
  11625.  int
  11626.  pr_gcnf(pname)
  11627.  char *pname;
  11628.  {
  11629.          char line[MAXLINE];
  11630.          char *s;
  11631.          int cnf[N_NBR];
  11632.          int n, errcount, good;
  11633.          FILE *fp, *fconfig(char *, char *);
  11634.  
  11635.          /* get configuration file values, if any */
  11636.          n = good = errcount = 0;
  11637.          if ((fp = fconfig("CONFIG", "pr.cnf")) != NULL) {
  11638.                  while (n < N_NBR && (s = fgets(line, MAXLINE, fp)) != NULL) {
  11639.                          cnf[n] = atoi(s);
  11640.                          ++n;
  11641.                  }
  11642.                  if ((s = fgets(line, MAXLINE, fp)) == NULL)
  11643.                          ++errcount;
  11644.                  else
  11645.                          strcpy(pcnf.p_dest, strtok(line, " \t\n"));
  11646.                  if (n != N_NBR)
  11647.                          ++errcount;
  11648.                  if (errcount == 0)
  11649.                          good = 1;
  11650.                  if (fclose(fp) == -1)
  11651.                          fatal(pname, "cannot close config file");
  11652.          }
  11653.  
  11654.          /* use config data is good; use defaults otherwise */
  11655.          pcnf.p_top1 = good ? cnf[0]: TOP1;
  11656.          pcnf.p_top2 = good ? cnf[1] : TOP2;
  11657.          pcnf.p_btm = good ? cnf[2] : BOTTOM;
  11658.          pcnf.p_wid = good ? cnf[3] : MAXPCOL;
  11659.          pcnf.p_lmarg = good ? cnf[4] : MARGIN;
  11660.          pcnf.p_rmarg = good ? cnf[5] : MARGIN;
  11661.          pcnf.p_len = good ? cnf[6] : PAGELEN;
  11662.          pcnf.p_lpi = good ? cnf[7] : LPI;
  11663.          pcnf.p_mode = good ? cnf[8] : 0;
  11664.          pcnf.p_lnum = good ? cnf[9] : 0;
  11665.          pcnf.p_ff = good ? cnf[10] : 0;
  11666.          pcnf.p_tabint = good ? cnf[11] : TABSPEC;
  11667.          if (!good)
  11668.                  strcpy(pcnf.p_dest, "PRN");
  11669.          if (pcnf.p_mode == 1)
  11670.                  pcnf.p_font = CONDENSED;
  11671.          strcpy(pcnf.p_hdr, "");
  11672.  
  11673.          return (errcount);
  11674.  }
  11675.  
  11676.  
  11677.  PR_GETLN.C
  11678.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\09PRINT\PR_GETLN.C
  11679.  
  11680.  /*
  11681.   *        pr_getln -- get a line of text while expanding tabs;
  11682.   *        put text into an array and return the length of the line
  11683.   *        including termination to the calling function.
  11684.   */
  11685.  
  11686.  #include <stdio.h>
  11687.  #include <stdlib.h>
  11688.  #include <local\std.h>
  11689.  
  11690.  int
  11691.  pr_getln(s, lim, fin)
  11692.  char *s;
  11693.  int lim;
  11694.  FILE *fin;
  11695.  {
  11696.          int ch;
  11697.          register char *cp;
  11698.  
  11699.          extern int tabstop();        /* query tabstop array */
  11700.  
  11701.          cp = s;
  11702.          while (--lim > 0 && (ch = fgetc(fin)) != EOF && ch != '\n' && ch != '
  11703.                  if (ch == '\t')
  11704.                          /* loop and store spaces until next tabstop */
  11705.                          do
  11706.                                  *cp++ = ' ';
  11707.                          while (--lim > 0 && tabstop(cp - s) == 0);
  11708.                  else
  11709.                          *cp++ = ch;
  11710.          }
  11711.          if (ch == EOF && cp - s == 0)
  11712.                  ;
  11713.          else if (ch == EOF || ch == '\n')
  11714.                  *cp++ = '\n';        /* assure correct line termination */
  11715.          else if (ch == '\f' && cp - s == 0) {
  11716.                  *cp++ = '\f';
  11717.                  fgetc(fin);        /* toss the trailing newline */
  11718.          }
  11719.          *cp = '\0';
  11720.  
  11721.          return (cp - s);
  11722.  }
  11723.  
  11724.  
  11725.  PR_HELP.C
  11726.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\09PRINT\PR_HELP.C
  11727.  
  11728.  /*
  11729.   *        pr_help -- display an abbreviated manual page
  11730.   */
  11731.  
  11732.  #include <stdio.h>
  11733.  #include <local\std.h>
  11734.  
  11735.  void
  11736.  pr_help(pname)
  11737.  char *pname;
  11738.  {
  11739.          static char *m_str[] = {
  11740.                  "The following options may be used singly or in combination:"
  11741.                  "-e\t set Epson-compatible mode",
  11742.                  "-f\t use formfeed to eject a page (default is newlines)",
  11743.                  "-g\t use generic printer mode",
  11744.                  "-h hdr\t use specified header instead of file name",
  11745.                  "-l len\t set page length in lines (default = 66)",
  11746.                  "-n\t enable line numbering (default = off)",
  11747.                  "-o cols\t offset from left edge in columns (default = 5)",
  11748.                  "-p\t preview output on screen (may be redirected)",
  11749.                  "-s list\t print only selected pages",
  11750.                  "-w cols\t line width in columns (default = 80)"
  11751.          };
  11752.          int i, n = sizeof (m_str)/ sizeof (char *);
  11753.  
  11754.          fprintf(stderr, "Usage: %s [options] file...\n\n", pname);
  11755.          for (i = 0; i < n; ++i)
  11756.                  fprintf(stderr, "%s\n", m_str[i]);
  11757.  
  11758.          return;
  11759.  }
  11760.  
  11761.  
  11762.  PR_LINE.C
  11763.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\09PRINT\PR_LINE.C
  11764.  
  11765.  /*
  11766.   *        pr_line -- ouput a buffered logical line and
  11767.   *        return a count of physical lines produced
  11768.   */
  11769.  
  11770.  #include <stdio.h>
  11771.  #include <stdlib.h>
  11772.  #include <local\std.h>
  11773.  #include "print.h"
  11774.  
  11775.  int
  11776.  pr_line(s, fout, rline)
  11777.  char *s;                /* buffered line of text */
  11778.  FILE *fout;                /* output stream */
  11779.  unsigned int rline;        /* file-relative line number */
  11780.  {
  11781.          int c_cnt;        /* character position in output line */
  11782.          int nlines;        /* number of lines output */
  11783.          extern PRINT pcnf;
  11784.  
  11785.          extern int spaces(int, FILE *);        /* emit string of spaces */
  11786.  
  11787.          nlines = 1;
  11788.          c_cnt = 0;
  11789.  
  11790.          /* output the left indentation, if any */
  11791.          c_cnt += spaces(pcnf.p_lmarg, fout);
  11792.  
  11793.          /* output the line number if numbering enabled */
  11794.          if (pcnf.p_lnum != 0)
  11795.                  c_cnt += fprintf(fout, "%6u  ", rline);
  11796.  
  11797.          /* output the text of the line */
  11798.          while (*s != '\0') {
  11799.                  if (c_cnt > (pcnf.p_wid - pcnf.p_rmarg)) {
  11800.                          fputc('\n', fout);
  11801.                          ++nlines;
  11802.                          c_cnt = 0;
  11803.                          c_cnt = spaces(pcnf.p_lmarg, fout);
  11804.                  }
  11805.                  fputc(*s, fout);
  11806.                  ++s;
  11807.                  ++c_cnt;
  11808.          }
  11809.  
  11810.          return (nlines);
  11811.  }
  11812.  
  11813.  
  11814.  PUTCUR.C
  11815.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\PUTCUR.C
  11816.  
  11817.  /*
  11818.   *        putcur -- put cursor at specified position (row, col)
  11819.   */
  11820.  
  11821.  #include <dos.h>
  11822.  #include <local\std.h>
  11823.  #include <local\bioslib.h>
  11824.  
  11825.  putcur(r, c, pg)
  11826.  unsigned int
  11827.          r,        /* row */
  11828.          c,        /* column */
  11829.          pg;        /* screen page for writes */
  11830.  {
  11831.          union REGS inregs, outregs;
  11832.  
  11833.          inregs.h.ah = CUR_POS;
  11834.          inregs.h.bh = pg & 0x07;
  11835.          inregs.h.dh = r & 0xFF;
  11836.          inregs.h.dl = c & 0xFF;
  11837.  
  11838.          int86(VIDEO_IO, &inregs, &outregs);
  11839.  
  11840.          return (outregs.x.cflag);
  11841.  } /* end putcur() */
  11842.  
  11843.  
  11844.  PUTFLD.C
  11845.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\PUTFLD.C
  11846.  
  11847.  /*
  11848.   *        putfld -- display a string in the prevailing
  11849.   *        video attribute while compressing runs of a
  11850.   *        single character, and pad the field to full width
  11851.   *        with spaces if necessary
  11852.   */
  11853.  
  11854.  int
  11855.  putfld(s, w, pg)
  11856.  register char *s;        /* string to write */
  11857.  int w;                        /* field width */
  11858.  int pg;                        /* screen page for writes */
  11859.  {
  11860.          int r, c, cols;
  11861.          register int n;
  11862.  
  11863.          extern int putcur(int, int, int);
  11864.          extern int readcur(int *, int *, int);
  11865.          extern int writec(unsigned char, int, int);
  11866.  
  11867.          /* get starting (current) position */
  11868.          readcur(&r, &c, pg);
  11869.  
  11870.          /* write the string */
  11871.          for (n = 0; *s != '\0' && n < w; s += cols, n += cols) {
  11872.                  putcur(r, c + n, pg);
  11873.                  /* compress runs to a single call on writec() */
  11874.                  cols = 1;
  11875.                  while (*(s + cols) == *s && n + cols < w)
  11876.                          ++cols;
  11877.                  writec(*s, cols, pg);
  11878.          }
  11879.  
  11880.          /* pad the field, if necessary */
  11881.          if (n < w) {
  11882.                  putcur(r, c + n, pg);
  11883.                  writec(' ', w - n, pg);
  11884.          }
  11885.  
  11886.          return (w - n);
  11887.  }
  11888.  
  11889.  
  11890.  PUTSTR.C
  11891.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\PUTSTR.C
  11892.  
  11893.  /*
  11894.   *        putstr -- display a character string in the
  11895.   *        prevailing video attribute and return number
  11896.   *        characters displayed
  11897.   */
  11898.  
  11899.  int
  11900.  putstr(s, pg)
  11901.  register char *s;
  11902.  unsigned int pg;
  11903.  {
  11904.          unsigned int r, c, c0;
  11905.  
  11906.          readcur(&r, &c, pg);
  11907.          for (c0 = c; *s != '\0'; ++s, ++c) {
  11908.                  putcur(r, c, pg);
  11909.                  writec(*s, 1, pg);
  11910.          }
  11911.          putcur(r, c, pg);
  11912.          return (c - c0);
  11913.  }
  11914.  
  11915.  
  11916.  PUT_CH.C
  11917.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\PUT_CH.C
  11918.  
  11919.  /*
  11920.   *        put_ch -- display a character in the prevailing video
  11921.   *        attribute and advance the cursor position
  11922.   */
  11923.  
  11924.  #include <local\video.h>
  11925.  
  11926.  int
  11927.  put_ch(ch, pg)
  11928.  register char ch;
  11929.  int pg;
  11930.  {
  11931.          int r, c, c0;
  11932.  
  11933.          readcur(&r, &c, pg);
  11934.          writec(ch, 1, pg);
  11935.          putcur(r, ++c, pg);
  11936.          return (1);
  11937.  }
  11938.  
  11939.  
  11940.  PWD.C
  11941.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\08FILE\PWD.C
  11942.  
  11943.  /*
  11944.   *        pwd -- print (display actually) the current directory pathname
  11945.   */
  11946.  
  11947.  #include <stdio.h>
  11948.  #include <direct.h>
  11949.  #include <local\std.h>
  11950.  
  11951.  main()
  11952.  {
  11953.          char *path;
  11954.  
  11955.          if ((path = getcwd(NULL, MAXPATH)) == NULL) {
  11956.                  perror("Error getting current directory");
  11957.                  exit(1);
  11958.          }
  11959.          printf("%s\n", path);
  11960.          exit(0);
  11961.  }
  11962.  
  11963.  _setargv()
  11964.  {
  11965.  }
  11966.  
  11967.  _setenvp()
  11968.  {
  11969.  }
  11970.  
  11971.  _nullcheck()
  11972.  {
  11973.  }
  11974.  
  11975.  
  11976.  READCA.C
  11977.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\READCA.C
  11978.  
  11979.  /*
  11980.   *        readca -- read character and attribute at current position
  11981.   */
  11982.  
  11983.  #include <dos.h>
  11984.  #include <local\std.h>
  11985.  #include <local\bioslib.h>
  11986.  
  11987.  int readca(ch, attr, pg)
  11988.  unsigned char *ch;
  11989.  unsigned char *attr;
  11990.  unsigned int pg;        /* screen page for reads */
  11991.  {
  11992.          union REGS inregs, outregs;
  11993.  
  11994.          inregs.h.ah = READ_CHAR_ATTR;
  11995.          inregs.h.bh = pg;                /* display page */
  11996.  
  11997.          int86(VIDEO_IO, &inregs, &outregs);
  11998.  
  11999.          *ch = outregs.h.al;                /* character */
  12000.          *attr = outregs.h.ah;                /* attribute */
  12001.  
  12002.          /* return the value in AX register */
  12003.          return (outregs.x.cflag);
  12004.  } /* end readca() */
  12005.  
  12006.  
  12007.  READCUR.C
  12008.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\READCUR.C
  12009.  
  12010.  /*
  12011.   *        readcur        -- pass back the cursor position (row, col)
  12012.   */
  12013.  
  12014.  #include <dos.h>
  12015.  #include <local\std.h>
  12016.  #include <local\bioslib.h>
  12017.  
  12018.  unsigned int readcur(row, col, pg)
  12019.  unsigned int *row;        /* current row */
  12020.  unsigned int *col;        /* current column */
  12021.  unsigned int pg;        /* screen page */
  12022.  {
  12023.          union REGS inregs, outregs;
  12024.  
  12025.          inregs.h.ah = GET_CUR;
  12026.          inregs.h.bh = pg;
  12027.  
  12028.          int86(VIDEO_IO, &inregs, &outregs);
  12029.  
  12030.          *col = outregs.h.dl;                /* col */
  12031.          *row = outregs.h.dh;                /* row */
  12032.  
  12033.          return (outregs.x.cflag);
  12034.  } /* end readcur() */
  12035.  
  12036.  
  12037.  READDOT.C
  12038.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\READDOT.C
  12039.  
  12040.  /*
  12041.   *        readdot -- read the value of a pixel
  12042.   *        (in graphics mode only)
  12043.   */
  12044.  
  12045.  #include <dos.h>
  12046.  #include <local\std.h>
  12047.  #include <local\bioslib.h>
  12048.  
  12049.  int
  12050.  readdot(row, col, dcolor)
  12051.  int row, col;
  12052.  int *dcolor;        /* pointer to dot color */
  12053.  {
  12054.          union REGS inregs, outregs;
  12055.  
  12056.          inregs.h.ah = READ_DOT;
  12057.          inregs.x.cx = col;
  12058.          inregs.x.dx = row;
  12059.          int86(VIDEO_IO, &inregs, &outregs);
  12060.          *dcolor = outregs.h.al;
  12061.  
  12062.          return (outregs.x.cflag);
  12063.  }
  12064.  
  12065.  
  12066.  REPLAY.C
  12067.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\03DOS\REPLAY.C
  12068.  
  12069.  /*
  12070.   *        replay -- echo the command-line arguments
  12071.   *        to standard output
  12072.   */
  12073.  
  12074.  #include <stdio.h>
  12075.  #include <stdlib.h>
  12076.  #include <local\std.h>
  12077.  
  12078.  main(argc, argv)
  12079.  int argc;
  12080.  char **argv;
  12081.  {
  12082.          int i;
  12083.          char **p;
  12084.          static char pgm[MAXNAME + 1] = { "replay" };
  12085.  
  12086.          void getpname(char *, char *);
  12087.  
  12088.          /* get program name from DOS (version 3.00 and later) */
  12089.          if (_osmajor >= 3)
  12090.                  getpname(*argv, pgm);
  12091.  
  12092.          /* check for arguments */
  12093.          if (argc == 1)
  12094.                  exit(1);        /* none given */
  12095.  
  12096.          /* echo the argument list, one per line */
  12097.          p = argv;
  12098.          printf("%s arguments:\n\n", pgm);
  12099.          for (--argc, ++argv; argc > 0; --argc, ++argv)
  12100.                  printf("argv[%d] -> %s\n", argv - p, *argv);
  12101.          exit(0);
  12102.  } /* end main() */
  12103.  
  12104.  
  12105.  RM.C
  12106.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\08FILE\RM.C
  12107.  
  12108.  /*
  12109.   *        rm -- remove file(s)
  12110.   */
  12111.  
  12112.  #include <stdio.h>
  12113.  #include <stdlib.h>
  12114.  #include <sys\types.h>
  12115.  #include <sys\stat.h>
  12116.  #include <ctype.h>
  12117.  #include <io.h>
  12118.  #include <local\std.h>
  12119.  
  12120.  main(argc, argv)
  12121.  int argc;
  12122.  char *argv[];
  12123.  {
  12124.          int ch;
  12125.          BOOLEAN errflag,
  12126.                  iflag;
  12127.  
  12128.          static char pgm[MAXNAME + 1] = { "rm" };
  12129.          extern void getpname(char *, char *);
  12130.          static void do_rm(char *, char *, BOOLEAN);
  12131.          extern int getopt(int, char **, char *);
  12132.          extern int optind, opterr;
  12133.          extern char *optarg;
  12134.  
  12135.          /* get program name from DOS (version 3.00 and later) */
  12136.          if (_osmajor >= 3)
  12137.                  getpname(*argv, pgm);
  12138.  
  12139.          /* process optional arguments first */
  12140.          errflag = iflag = FALSE;
  12141.          while ((ch = getopt(argc, argv, "i")) != EOF)
  12142.                  switch (ch) {
  12143.                  case 'i':
  12144.                          /* interactive -- requires confirmation */
  12145.                          iflag = TRUE;
  12146.                          break;
  12147.                  case '?':
  12148.                          /* say what? */
  12149.                          errflag = TRUE;
  12150.                          break;
  12151.                  }
  12152.          argc -= optind;
  12153.          argv += optind;
  12154.  
  12155.          if (argc <= 0 || errflag == TRUE) {
  12156.                  fprintf(stderr, "%s [-i] file(s)\n", pgm);
  12157.                  exit(1);
  12158.          }
  12159.  
  12160.          /* process remaining arguments */
  12161.          for (; argc-- > 0; ++argv)
  12162.                  do_rm(pgm, *argv, iflag);
  12163.  
  12164.          exit(0);
  12165.  } /* end main() */
  12166.  
  12167.  /*
  12168.   *        do_rm -- remove a file
  12169.   */
  12170.  
  12171.  static void
  12172.  do_rm(pname, fname, iflag)
  12173.  char *pname, *fname;
  12174.  BOOLEAN iflag;
  12175.  {
  12176.          int result = 0;
  12177.          struct stat statbuf;
  12178.          static BOOLEAN affirm();
  12179.  
  12180.          if (iflag == TRUE) {
  12181.                  fprintf(stderr, "%s (y/n): ", fname);
  12182.                  if (affirm() == FALSE)
  12183.                          return;
  12184.          }
  12185.          if ((result = unlink(fname)) == -1) {
  12186.                  fprintf(stderr, "%s: ", pname);
  12187.                  perror(fname);
  12188.          }
  12189.          return;
  12190.  }
  12191.  
  12192.  /*
  12193.   *        affirm -- return TRUE if the first character of the
  12194.   *        user's response is 'y' or FALSE otherwise
  12195.   */
  12196.  
  12197.  #define MAXSTR        64
  12198.  
  12199.  static BOOLEAN
  12200.  affirm()
  12201.  {
  12202.          char line[MAXSTR + 1];
  12203.          char *response;
  12204.  
  12205.          response = fgets(line, MAXSTR, stdin);
  12206.          return (tolower(*response) == 'y' ? TRUE : FALSE);
  12207.  }
  12208.  
  12209.  
  12210.  RUN_ONCE.C
  12211.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\04STDLIB\RUN_ONCE.C
  12212.  
  12213.  /*
  12214.   *        run_once -- run a program one time and then
  12215.   *        "hang" the system to prevent unwanted use
  12216.   */
  12217.  
  12218.  #include <stdio.h>
  12219.  #include <stdlib.h>
  12220.  #include <process.h>
  12221.  #include <local\std.h>
  12222.  
  12223.  main(argc, argv)
  12224.  int argc;
  12225.  char *argv[];
  12226.  {
  12227.          extern void fatal(char *, char *, int);
  12228.  
  12229.          /* skip over the program name */
  12230.          ++argv;
  12231.  
  12232.          /* run the specified command line [pgmname arg(s)] */
  12233.          if (spawnvp(P_WAIT, *argv, argv) == -1)
  12234.                  fatal("run_once", "Error running specified program", 1);
  12235.          fprintf(stderr, "Please turn off the power to the computer.\n");
  12236.  
  12237.          /* do nothing */
  12238.          FOREVER
  12239.                  ;
  12240.  }
  12241.  
  12242.  
  12243.  SB_BOX.C
  12244.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\12SBUF\SB_BOX.C
  12245.  
  12246.  /*
  12247.   *        sb_box -- draw a box around the perimeter of a window
  12248.   *        using the appropriate IBM graphics characters
  12249.   */
  12250.  
  12251.  #include <local\sbuf.h>
  12252.  #include <local\video.h>
  12253.  #include <local\box.h>
  12254.  
  12255.  int
  12256.  sb_box(win, type, attr)
  12257.  struct REGION *win;
  12258.  short type;
  12259.  unsigned char attr;
  12260.  {
  12261.          register short r;        /* row index */
  12262.          short x;                /* interior horizontal line length */
  12263.          short maxr, maxc;        /* maximum row and col values */
  12264.          BOXTYPE *boxp;                /* pointer to box drawing character str
  12265.          static BOXTYPE box[] = {
  12266.                  '+',   '+',   '+',   '+',   '-',   '-',   '|',   '|',
  12267.                  ULC11, URC11, LLC11, LRC11, HBAR1, HBAR1, VBAR1, VBAR1,
  12268.                  ULC22, URC22, LLC22, LRC22, HBAR2, HBAR2, VBAR2, VBAR2,
  12269.                  ULC12, URC12, LLC12, LRC12, HBAR1, HBAR1, VBAR2, VBAR2,
  12270.                  ULC21, URC21, LLC21, LRC21, HBAR2, HBAR2, VBAR1, VBAR1,
  12271.                  BLOCK, BLOCK, BLOCK, BLOCK, HBART, HBARB, BLOCK, BLOCK
  12272.          };
  12273.  
  12274.          boxp = &box[type];
  12275.          maxc = win->c1 - win->c0;
  12276.          maxr = win->r1 - win->r0;
  12277.          x = maxc - 1;
  12278.  
  12279.          /* draw top row */
  12280.          sb_move(win, 0, 0);
  12281.          sb_wca(win, boxp->ul, attr, 1);
  12282.          sb_move(win, 0, 1);
  12283.          sb_wca(win, boxp->tbar, attr, x);
  12284.          sb_move(win, 0, maxc);
  12285.          sb_wca(win, boxp->ur, attr, 1);
  12286.  
  12287.          /* draw left and right sides */
  12288.          for (r = 1; r < maxr; ++r) {
  12289.                  sb_move(win, r, 0);
  12290.                  sb_wca(win, boxp->lbar, attr, 1);
  12291.                  sb_move(win, r, maxc);
  12292.                  sb_wca(win, boxp->rbar, attr, 1);
  12293.          }
  12294.  
  12295.          /* draw bottom row */
  12296.          sb_move(win, maxr, 0);
  12297.          sb_wca(win, boxp->ll, attr, 1);
  12298.          sb_move(win, maxr, 1);
  12299.          sb_wca(win, boxp->bbar, attr, x);
  12300.          sb_move(win, maxr, maxc);
  12301.          sb_wca(win, boxp->lr, attr, 1);
  12302.  
  12303.          return SB_OK;
  12304.  }
  12305.  
  12306.  
  12307.  SB_FILL.C
  12308.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\12SBUF\SB_FILL.C
  12309.  
  12310.  /*
  12311.   *         sb_fill -- fill region routines
  12312.   */
  12313.  
  12314.  #include <local\sbuf.h>
  12315.  
  12316.  extern struct BUFFER Sbuf;
  12317.  extern union CELL Scrnbuf[SB_ROWS][SB_COLS];
  12318.  
  12319.  /*
  12320.   *        sb_fill -- set all cells in a specified region
  12321.   *        to the same character/attribute value
  12322.   */
  12323.  
  12324.  int
  12325.  sb_fill(win, ch, attr)
  12326.  struct REGION *win;
  12327.  unsigned char ch;        /* fill character */
  12328.  unsigned char attr;        /* fill attribute */
  12329.  {
  12330.          register int i, j;
  12331.          unsigned short ca;
  12332.  
  12333.          ca = (attr << 8) | ch;
  12334.          for (i = win->sr0; i <= win->sr1; ++i) {
  12335.                  for (j = win->sc0; j <= win->sc1; ++j)
  12336.                          Scrnbuf[i][j].cap = ca;
  12337.                  if (win->sc0 < Sbuf.lcol[i])
  12338.                          Sbuf.lcol[i] = win->sc0;
  12339.                  if (win->sc1 > Sbuf.rcol[i])
  12340.                          Sbuf.rcol[i] = win->sc1;
  12341.          }
  12342.          Sbuf.flags |= SB_DELTA;
  12343.  
  12344.          return SB_OK;
  12345.  }
  12346.  
  12347.  
  12348.  /*
  12349.   *        sb_fillc -- set all cells in a specified region
  12350.   *        to the same character value; leave attributes undisturbed
  12351.   */
  12352.  
  12353.  int
  12354.  sb_fillc(win, ch)
  12355.  struct REGION *win;
  12356.  unsigned char ch;        /* fill character */
  12357.  {
  12358.          register int i, j;
  12359.  
  12360.          for (i = win->sr0; i <= win->sr1; ++i) {
  12361.                  for (j = win->sc0; j <= win->sc1; ++j)
  12362.                          Scrnbuf[i][j].b.ch = ch;
  12363.                  if (win->sc0 < Sbuf.lcol[i])
  12364.                          Sbuf.lcol[i] = win->sc0;
  12365.                  if (win->sc1 > Sbuf.rcol[i])
  12366.                          Sbuf.rcol[i] = win->sc1;
  12367.          }
  12368.          Sbuf.flags |= SB_DELTA;
  12369.  
  12370.          return SB_OK;
  12371.  }
  12372.  
  12373.  
  12374.  /*
  12375.   *        sb_filla -- set all cells in a specified region
  12376.   *        to the same attribute value; leave characters undisturbed
  12377.   */
  12378.  
  12379.  int
  12380.  sb_filla(win, attr)
  12381.  struct REGION *win;
  12382.  unsigned char attr;        /* fill attribute */
  12383.  {
  12384.          register int i, j;
  12385.  
  12386.          for (i = win->sr0; i <= win->sr1; ++i) {
  12387.                  for (j = win->sc0; j <= win->sc1; ++j)
  12388.                          Scrnbuf[i][j].b.attr = attr;
  12389.                  if (win->sc0 < Sbuf.lcol[i])
  12390.                          Sbuf.lcol[i] = win->sc0;
  12391.                  if (win->sc1 > Sbuf.rcol[i])
  12392.                          Sbuf.rcol[i] = win->sc1;
  12393.          }
  12394.          Sbuf.flags |= SB_DELTA;
  12395.  
  12396.          return SB_OK;
  12397.  }
  12398.  
  12399.  
  12400.  SB_INIT.C
  12401.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\12SBUF\SB_INIT.C
  12402.  
  12403.  /*
  12404.   *        sb_init -- initialize the buffered screen interface
  12405.   */
  12406.  
  12407.  #include <stdio.h>
  12408.  #include <stdlib.h>
  12409.  #include <string.h>
  12410.  #include <local\sbuf.h>
  12411.  
  12412.  /* global data declarations */
  12413.  struct BUFFER Sbuf;                        /* control information */
  12414.  union CELL Scrnbuf[SB_ROWS][SB_COLS];        /* screen buffer array */
  12415.  
  12416.  int
  12417.  sb_init()
  12418.  {
  12419.          int i;
  12420.          char *um;        /* update mode */
  12421.  
  12422.          /* set initial parameter values */
  12423.          Sbuf.bp = &Scrnbuf[0][0];
  12424.          Sbuf.row = Sbuf.col = 0;
  12425.          for (i = 0; i < SB_ROWS; ++i) {
  12426.                  Sbuf.lcol[i] = SB_COLS;
  12427.                  Sbuf.rcol[i] = 0;
  12428.          }
  12429.          Sbuf.flags = 0;
  12430.  
  12431.          /* set screen update mode */
  12432.          um = strupr(getenv("UPDATEMODE"));
  12433.          if (um == NULL || strcmp(um, "BIOS") == 0)
  12434.                  Sbuf.flags &= ~SB_DIRECT;
  12435.          else if (strcmp(um, "DIRECT") == 0)
  12436.                  Sbuf.flags |= SB_DIRECT;
  12437.          else
  12438.                  return SB_ERR;
  12439.  
  12440.          return SB_OK;
  12441.  }
  12442.  
  12443.  
  12444.  SB_MOVE.C
  12445.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\12SBUF\SB_MOVE.C
  12446.  
  12447.  /*
  12448.   *        sb_move -- move the screen buffer "cursor"
  12449.   */
  12450.  
  12451.  #include <local\sbuf.h>
  12452.  
  12453.  extern struct BUFFER Sbuf;
  12454.  extern union CELL Scrnbuf[SB_ROWS][SB_COLS];
  12455.  
  12456.  int
  12457.  sb_move(win, r, c)
  12458.  struct REGION *win;        /* window pointer */
  12459.  register short r, c;        /* buffer row and column */
  12460.  {
  12461.          /* don't change anything if request is out of range */
  12462.          if (r < 0 || r > win->r1 - win->r0 || c < 0 || c > win->c1 - win->c0)
  12463.                  return SB_ERR;
  12464.          win->row = r;
  12465.          win->col = c;
  12466.          Sbuf.row = r + win->r0;
  12467.          Sbuf.col = c + win->c0;
  12468.          return SB_OK;
  12469.  }
  12470.  
  12471.  
  12472.  SB_NEW.C
  12473.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\12SBUF\SB_NEW.C
  12474.  
  12475.  /*
  12476.   *        sb_new -- prepare a new window (rectangular region)
  12477.   *        and return a pointer to it
  12478.   */
  12479.  
  12480.  #include <stdio.h>
  12481.  #include <malloc.h>
  12482.  #include <local\sbuf.h>
  12483.  
  12484.  struct REGION *
  12485.  sb_new(top, left, height, width)
  12486.  int top;        /* top row */
  12487.  int left;        /* left column */
  12488.  int height;        /* total rows */
  12489.  int width;        /* total columns */
  12490.  {
  12491.          struct REGION *new;
  12492.  
  12493.          /* allocate the control data structure */
  12494.          new = (struct REGION *)malloc(sizeof (struct REGION));
  12495.          if (new != NULL) {
  12496.                  new->r0 = new->sr0 = top;
  12497.                  new->r1 = new->sr1 = top + height - 1;
  12498.                  new->c0 = new->sc0 = left;
  12499.                  new->c1 = new->sc1 = left + width - 1;
  12500.                  new->row = new->col = 0;
  12501.                  new->wflags = 0;
  12502.          }
  12503.          return (new);
  12504.  }
  12505.  
  12506.  
  12507.  SB_PUT.C
  12508.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\12SBUF\SB_PUT.C
  12509.  
  12510.  /*
  12511.   *        sb_put -- routines to put characters and strings into the
  12512.   *        screen buffer; the cursor location is altered
  12513.   */
  12514.  
  12515.  #include <local\sbuf.h>
  12516.  #include <ctype.h>
  12517.  
  12518.  extern struct BUFFER Sbuf;
  12519.  extern union CELL Scrnbuf[SB_ROWS][SB_COLS];
  12520.  
  12521.  /*
  12522.   *        sb_putc -- put a character into a screen buffer window
  12523.   */
  12524.  
  12525.  int
  12526.  sb_putc(win, ch)
  12527.  struct REGION *win;
  12528.  unsigned char ch;
  12529.  {
  12530.          short cmax, rmax;
  12531.          short lim;
  12532.          short noscroll = 0, puterr = 0;
  12533.  
  12534.          /* calculate screen buffer position and limits */
  12535.          cmax = win->c1 - win->c0;
  12536.          rmax = win->r1 - win->r0;
  12537.          Sbuf.row = win->r0 + win->row;
  12538.          Sbuf.col = win->c0 + win->col;
  12539.  
  12540.          /* process the character */
  12541.          switch (ch) {
  12542.          case '\b':
  12543.                  /* non-destructive backspace */
  12544.                  if (win->col > 0) {
  12545.                          --win->col;
  12546.                          Sbuf.col = win->c0 + win->col;
  12547.                          return SB_OK;
  12548.                  }
  12549.                  else
  12550.                          return SB_ERR;
  12551.          case '\n':
  12552.                  /* clear trailing line segment */
  12553.                  while (win->col < cmax)
  12554.                          if (sb_putc(win, ' ') == SB_ERR)
  12555.                                  ++puterr;
  12556.                  break;
  12557.          case '\t':
  12558.                  /* convert tab to required number of spaces */
  12559.                  lim = win->col + 8 - (win->col & 0x7);
  12560.                  while (win->col < lim)
  12561.                          if (sb_putc(win, ' ') == SB_ERR)
  12562.                                  ++puterr;
  12563.                  break;
  12564.          default:
  12565.                  /* if printable ASCII, place the character in the buffer */
  12566.                  if (isascii(ch) && isprint(ch))
  12567.                          Scrnbuf[Sbuf.row][Sbuf.col].b.ch = ch;
  12568.                  if (Sbuf.col < Sbuf.lcol[Sbuf.row])
  12569.                          Sbuf.lcol[Sbuf.row] = Sbuf.col;
  12570.                  if (Sbuf.col > Sbuf.rcol[Sbuf.row])
  12571.                          Sbuf.rcol[Sbuf.row] = Sbuf.col;
  12572.                  break;
  12573.          }
  12574.  
  12575.          /* update the cursor position */
  12576.          if (win->col < cmax)
  12577.                  ++win->col;
  12578.          else if (win->row < rmax) {
  12579.                  win->col = 0;
  12580.                  ++win->row;
  12581.          }
  12582.          else if ((win->wflags & SB_SCROLL) == SB_SCROLL) {
  12583.                  sb_scrl(win, 1);
  12584.                  win->col = 0;
  12585.                  win->row = rmax;
  12586.          }
  12587.          else
  12588.                  ++noscroll;
  12589.  
  12590.          /* update screen buffer position */
  12591.          Sbuf.row = win->r0 + win->row;
  12592.          Sbuf.col = win->c0 + win->col;
  12593.          Sbuf.flags |= SB_DELTA;
  12594.  
  12595.          return ((noscroll || puterr) ? SB_ERR : SB_OK);
  12596.  } /* end sb_putc() */
  12597.  
  12598.  
  12599.  /*
  12600.   *        sb_puts -- put a string into the screen buffer
  12601.   */
  12602.  
  12603.  int
  12604.  sb_puts(win, s)
  12605.  struct REGION *win;
  12606.  unsigned char *s;
  12607.  {
  12608.          while (*s)
  12609.                  if (sb_putc(win, *s++) == SB_ERR)
  12610.                          return SB_ERR;
  12611.          return SB_OK;
  12612.  } /* end sb_puts() */
  12613.  
  12614.  
  12615.  SB_READ.C
  12616.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\12SBUF\SB_READ.C
  12617.  
  12618.  /*
  12619.   *        sb_read -- read character/attribute data
  12620.   */
  12621.  
  12622.  #include <local\sbuf.h>
  12623.  
  12624.  extern struct BUFFER Sbuf;
  12625.  extern union CELL Scrnbuf[SB_ROWS][SB_COLS];
  12626.  
  12627.  unsigned char
  12628.  sb_ra(win)
  12629.  struct REGION *win;        /* window pointer */
  12630.  {
  12631.          return (Scrnbuf[win->r0 + win->row][win->c0 + win->col].b.attr);
  12632.  } /* end sb_ra() */
  12633.  
  12634.  
  12635.  /*
  12636.   *        sb_rc -- read character from current location in screen buffer
  12637.   */
  12638.  
  12639.  unsigned char
  12640.  sb_rc(win)
  12641.  struct REGION *win;        /* window pointer */
  12642.  {
  12643.          return (Scrnbuf[win->r0 + win->row][win->c0 + win->col].b.ch);
  12644.  } /* end sb_rc() */
  12645.  
  12646.  
  12647.  /*
  12648.   *        sb_rca -- read character/attribute pair from current
  12649.   *        location in screen buffer
  12650.   */
  12651.  
  12652.  unsigned short
  12653.  sb_rca(win)
  12654.  struct REGION *win;        /* window pointer */
  12655.  {
  12656.          return (Scrnbuf[win->r0 + win->row][win->c0 + win->col].cap);
  12657.  } /* end sb_rca() */
  12658.  
  12659.  
  12660.  SB_SCRL.C
  12661.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\12SBUF\SB_SCRL.C
  12662.  
  12663.  /*
  12664.   *        sb_scrl -- scrolling routines
  12665.   */
  12666.  
  12667.  #include <local\sbuf.h>
  12668.  
  12669.  extern struct BUFFER Sbuf;
  12670.  extern union CELL Scrnbuf[SB_ROWS][SB_COLS];
  12671.  
  12672.  
  12673.  /*
  12674.   *        sb_scrl -- scroll the specified window
  12675.   *        n lines (direction indicated by sign)
  12676.   */
  12677.  
  12678.  int
  12679.  sb_scrl(win, n)
  12680.  struct REGION *win;
  12681.  short n;                /* number of rows to scroll */
  12682.  {
  12683.          register short r, c;
  12684.  
  12685.          if (n == 0)
  12686.                  /* clear the entire region to spaces */
  12687.                  sb_fillc(win, ' ');
  12688.          else if (n > 0) {
  12689.                  /* scroll n rows up */
  12690.                  for (r = win->sr0; r <= win->sr1 - n; ++r) {
  12691.                          for (c = win->sc0; c <= win->sc1; ++c)
  12692.                                  Scrnbuf[r][c] = Scrnbuf[r + n][c];
  12693.                          if (win->sc0 < Sbuf.lcol[r])
  12694.                                  Sbuf.lcol[r] = win->sc0;
  12695.                          if (win->sc1 > Sbuf.rcol[r])
  12696.                                  Sbuf.rcol[r] = win->sc1;
  12697.                  }
  12698.                  for ( ; r <= win->sr1; ++r) {
  12699.                          for (c = win->sc0; c <= win->sc1; ++c)
  12700.                                  Scrnbuf[r][c].b.ch = ' ';
  12701.                          if (win->sc0 < Sbuf.lcol[r])
  12702.                                  Sbuf.lcol[r] = win->sc0;
  12703.                          if (win->sc1 > Sbuf.rcol[r])
  12704.                                  Sbuf.rcol[r] = win->sc1;
  12705.                  }
  12706.          }
  12707.          else {
  12708.                  /* scroll n rows down */
  12709.                  n = -n;
  12710.                  for (r = win->sr1; r >= win->sr0 + n; --r) {
  12711.                          for (c = win->sc0; c <= win->sc1; ++c)
  12712.                                  Scrnbuf[r][c] = Scrnbuf[r - n][c];
  12713.                          if (win->sc0 < Sbuf.lcol[r])
  12714.                                  Sbuf.lcol[r] = win->sc0;
  12715.                          if (win->sc1 > Sbuf.rcol[r])
  12716.                                  Sbuf.rcol[r] = win->sc1;
  12717.                  }
  12718.                  for ( ; r >= win->sr0; --r) {
  12719.                          for (c = win->sc0; c <= win->sc1; ++c)
  12720.                                  Scrnbuf[r][c].b.ch = ' ';
  12721.                          if (win->sc0 < Sbuf.lcol[r])
  12722.                                  Sbuf.lcol[r] = win->sc0;
  12723.                          if (win->sc1 > Sbuf.rcol[r])
  12724.                                  Sbuf.rcol[r] = win->sc1;
  12725.                  }
  12726.          }
  12727.          Sbuf.flags |= SB_DELTA;
  12728.          return SB_OK;
  12729.  } /* end sb_scrl() */
  12730.  
  12731.  
  12732.  /*
  12733.   *        sb_set_scrl -- set the scroll region boundaries
  12734.   */
  12735.  
  12736.  int
  12737.  sb_set_scrl(win, top, left, bottom, right)
  12738.  struct REGION *win;        /* window pointer */
  12739.  short top, left;        /* upper-left corner */
  12740.  short bottom, right;        /* lower-left corner */
  12741.  {
  12742.          if (top < 0 || left < 0 ||
  12743.                  bottom > win->r1 - win->r0 || right > win->c1 - win->c0)
  12744.                  return SB_ERR;
  12745.          win->sr0 = win->r0 + top;
  12746.          win->sc0 = win->c0 + left;
  12747.          win->sr1 = win->r0 + bottom - 1;
  12748.          win->sc1 = win->c0 + right - 1;
  12749.          return SB_OK;
  12750.  } /* end sb_set_scrl() */
  12751.  
  12752.  
  12753.  SB_SHOW.C
  12754.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\12SBUF\SB_SHOW.C
  12755.  
  12756.  /*
  12757.   *        sb_show -- copy the screen buffer to display memory
  12758.   */
  12759.  
  12760.  #include <stdio.h>
  12761.  #include <dos.h>
  12762.  #include <memory.h>
  12763.  #include <local\sbuf.h>
  12764.  #include <local\video.h>
  12765.  
  12766.  #define        MDA_SEG        0xB000
  12767.  #define        CGA_SEG        0xB800
  12768.  #define NBYTES        (2 * SB_COLS)
  12769.  
  12770.  /* macro to synchronize with vertical retrace period */
  12771.  #define VSTAT        0x3DA
  12772.  #define VRBIT        8
  12773.  #define VSYNC        while ((inp(VSTAT) & VRBIT) == VRBIT); \
  12774.                  while ((inp(VSTAT) & VRBIT) != VRBIT)
  12775.  
  12776.  extern struct BUFFER Sbuf;
  12777.  extern union CELL Scrnbuf[SB_ROWS][SB_COLS];
  12778.  
  12779.  int
  12780.  sb_show(pg)
  12781.  short pg;
  12782.  {
  12783.          register short r, c;
  12784.          short n;
  12785.          short count, ncols;
  12786.          unsigned int src_os, dest_os;
  12787.          struct SREGS segregs;
  12788.  
  12789.          if ((Sbuf.flags & SB_DIRECT) == SB_DIRECT) {
  12790.                  /* use the direct-screen interface */
  12791.                  segread(&segregs);
  12792.  
  12793.                  /* determine extent of changes */
  12794.                  n = 0;
  12795.                  for (r = 0; r < SB_ROWS; ++r)
  12796.                          if (Sbuf.lcol[r] <= Sbuf.rcol[r])
  12797.                                  ++n;
  12798.                  src_os = dest_os = 0;
  12799.                  if (n <= 2)
  12800.                          /* copy only rows that contain changes */
  12801.                          for (r = 0; r < SB_ROWS; ++r) {
  12802.                                  if (Sbuf.lcol[r] <= Sbuf.rcol[r]) {
  12803.                                          /* copy blocks during vertical retrac
  12804.                                          VSYNC;
  12805.                                          movedata(segregs.ds,
  12806.                                                  (unsigned)&Scrnbuf[0][0] + sr
  12807.                                                  CGA_SEG, dest_os, NBYTES);
  12808.                                          Sbuf.lcol[r] = SB_COLS;
  12809.                                          Sbuf.rcol[r] = 0;
  12810.                                  }
  12811.                                  src_os += SB_COLS;
  12812.                                  dest_os += NBYTES;
  12813.                          }
  12814.                  else {
  12815.                          /* copy the entire buffer */
  12816.                          count = 3 * NBYTES;
  12817.                          ncols = 3 * SB_COLS;
  12818.                          for (r = 0; r < SB_ROWS - 1; r += 3) {
  12819.                                  VSYNC;
  12820.                                  movedata(segregs.ds, (unsigned)&Scrnbuf[0][0]
  12821.                                          + src_os, CGA_SEG, dest_os, count);
  12822.                                  src_os += ncols;
  12823.                                  dest_os += count;
  12824.                          }
  12825.                          VSYNC;
  12826.                          movedata(segregs.ds, (unsigned)&Scrnbuf[0][0] + src_o
  12827.                                  CGA_SEG, dest_os, NBYTES);
  12828.                          for (r = 0; r < SB_ROWS; ++r) {
  12829.                                  Sbuf.lcol[r] = SB_COLS;
  12830.                                  Sbuf.rcol[r] = 0;
  12831.                          }
  12832.                  }
  12833.          }
  12834.          else
  12835.                  /* use the BIOS video interface */
  12836.                  for (r = 0; r < SB_ROWS; ++r)
  12837.                          /* copy only changed portions of lines */
  12838.                          if (Sbuf.lcol[r] < SB_COLS && Sbuf.rcol[r] > 0) {
  12839.                                  for (c = Sbuf.lcol[r]; c <= Sbuf.rcol[r]; ++c
  12840.                                          putcur(r, c, pg);
  12841.                                          writeca(Scrnbuf[r][c].b.ch,
  12842.                                                  Scrnbuf[r][c].b.attr, 1, pg);
  12843.                                  }
  12844.                                  Sbuf.lcol[r] = SB_COLS;
  12845.                                  Sbuf.rcol[r] = 0;
  12846.                          }
  12847.  
  12848.          /* the display now matches the buffer -- clear flag bit */
  12849.          Sbuf.flags &= ~SB_DELTA;
  12850.  
  12851.          return SB_OK;
  12852.  }
  12853.  
  12854.  
  12855.  SB_TEST.C
  12856.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\12SBUF\SB_TEST.C
  12857.  
  12858.  /*
  12859.   *        sb_test -- driver for screen-buffer interface functions
  12860.   */
  12861.  
  12862.  #include <stdio.h>
  12863.  #include <stdlib.h>
  12864.  #include <conio.h>
  12865.  #include <local\std.h>
  12866.  #include <local\keydefs.h>
  12867.  #include <local\sbuf.h>
  12868.  #include <local\video.h>
  12869.  #include <local\box.h>
  12870.  #include "sb_test.h"
  12871.  
  12872.  #define BEL 7
  12873.  
  12874.  extern struct BUFFER Sbuf;
  12875.  
  12876.  main(argc, argv)
  12877.  int argc;
  12878.  char *argv[];
  12879.  {
  12880.          char *s, line[MAXLINE];
  12881.          int k;
  12882.          short i;
  12883.          FILE *fp;
  12884.          char fname[MAXPATH];
  12885.          struct REGION *cmnd, *stat, *text, *help, *curwin;
  12886.          unsigned char cmndattr, statattr, textattr, helpattr, curattr;
  12887.          unsigned char ch, userattr;
  12888.  
  12889.          /* function prototypes */
  12890.          int sb_init();
  12891.          int sb_move(struct REGION *, short, short);
  12892.          struct REGION *sb_new(short, short, short, short);
  12893.          int sb_putc(struct REGION *, unsigned char);
  12894.          int sb_puts(struct REGION *, char *);
  12895.          int sb_show(short);
  12896.          int sb_fill(struct REGION *, unsigned char, unsigned char);
  12897.          char *get_fname(struct REGION *, char *, short);
  12898.  
  12899.          getstate();
  12900.          readca(&ch, &userattr, Vpage);
  12901.  
  12902.          /* set up the screen buffer */
  12903.          if (sb_init() == SB_ERR) {
  12904.                  fprintf(stderr, "Bad UPDATEMODE value in environment\n");
  12905.                  exit(1);
  12906.          }
  12907.  
  12908.          /* set up windows and scrolling regions */
  12909.          cmnd = sb_new(CMND_ROW, CMND_COL, CMND_HT, CMND_WID);
  12910.          stat = sb_new(STAT_ROW, STAT_COL, STAT_HT, STAT_WID);
  12911.          text = sb_new(TEXT_ROW, TEXT_COL, TEXT_HT, TEXT_WID);
  12912.          help = sb_new(HELP_ROW, HELP_COL, HELP_HT, HELP_WID);
  12913.          text->wflags |= SB_SCROLL;
  12914.          sb_set_scrl(help, 1, 1, HELP_HT - 1, HELP_WID - 1);
  12915.  
  12916.          /* display each primary window in its own attribute */
  12917.          cmndattr = GRN;
  12918.          statattr = (WHT << 4) | BLK;
  12919.          textattr = (BLU << 4) | CYAN;
  12920.          helpattr = (GRN << 4) | YEL;
  12921.          sb_fill(cmnd, ' ', cmndattr);
  12922.          if (sb_move(cmnd, 0, 0) == SB_OK)
  12923.                  sb_puts(cmnd, "SB_TEST (Version 1.0)");
  12924.          sb_fill(stat, ' ', statattr);
  12925.          if (sb_move(stat, 0, 0) == SB_OK)
  12926.                  sb_puts(stat, "*** STATUS AREA ***");
  12927.          for (i = 0; i <= text->r1 - text->r0; ++i) {
  12928.                  sb_move(text, i, 0);
  12929.                  sb_wca(text, i + 'a', textattr,
  12930.                          text->c1 - text->c0 + 1);
  12931.          }
  12932.          if (sb_move(text, 10, 25) == SB_OK)
  12933.                  sb_puts(text, " *** TEXT DISPLAY AREA *** ");
  12934.          sb_show(Vpage);
  12935.          curwin = text;
  12936.          curattr = textattr;
  12937.  
  12938.          /* respond to user commands */
  12939.          while ((k = getkey()) != K_ESC) {
  12940.                  switch (k) {
  12941.                  case K_UP:
  12942.                          sb_scrl(curwin, 1);
  12943.                          break;
  12944.                  case K_DOWN:
  12945.                          sb_scrl(curwin, -1);
  12946.                          break;
  12947.                  case K_PGUP:
  12948.                          sb_scrl(curwin, curwin->sr1 - curwin->sr0);
  12949.                          break;
  12950.                  case K_PGDN:
  12951.                          sb_scrl(curwin, -(curwin->sr1 - curwin->sr0));
  12952.                          break;
  12953.                  case K_ALTC:
  12954.                          /* clear the current window */
  12955.                          sb_fill(curwin, ' ', curattr);
  12956.                          break;
  12957.                  case K_ALTH:
  12958.                          /* display help */
  12959.                          curwin = help;
  12960.                          curattr = helpattr;
  12961.                          for (i = 0; i < help->r1 - help->r0; ++i) {
  12962.                                  sb_move(help, i, 0);
  12963.                                  sb_wca(help, i + 'a', helpattr,
  12964.                                          help->c1 - help->c0 + 1);
  12965.                          }
  12966.                          sb_box(help, BOXBLK, helpattr);
  12967.                          break;
  12968.                  case K_ALTS:
  12969.                          /* fill the command area with letters */
  12970.                          curwin = stat;
  12971.                          curattr = statattr;
  12972.                          sb_fill(stat, 's', statattr);
  12973.                          break;
  12974.                  case K_ALTT:
  12975.                          /* fill the text area */
  12976.                          curwin = text;
  12977.                          curattr = textattr;
  12978.                          for (i = 0; i <= text->r1 - text->r0; ++i) {
  12979.                                  sb_move(text, i, 0);
  12980.                                  sb_wca(text, i + 'a', textattr,
  12981.                                          text->c1 - text->c0 + 1);
  12982.                          }
  12983.                          break;
  12984.                  case K_ALTR:
  12985.                          /* read a file into the current window */
  12986.                          sb_fill(stat, ' ', statattr);
  12987.                          sb_move(stat, 0, 0);
  12988.                          sb_puts(stat, "File to read: ");
  12989.                          sb_show(Vpage);
  12990.                          (void)get_fname(stat, fname, MAXPATH);
  12991.                          if ((fp = fopen(fname, "r")) == NULL) {
  12992.                                  sb_fill(stat, ' ', statattr);
  12993.                                  sb_move(stat, 0, 0);
  12994.                                  sb_puts(stat, "Cannot open ");
  12995.                                  sb_puts(stat, fname);
  12996.                          }
  12997.                          else {
  12998.                                  sb_fill(stat, ' ', statattr);
  12999.                                  sb_move(stat, 0, 0);
  13000.                                  sb_puts(stat, "File: ");
  13001.                                  sb_puts(stat, fname);
  13002.                                  sb_show(Vpage);
  13003.                                  sb_fill(text, ' ', textattr);
  13004.                                  sb_move(text, 0, 0);
  13005.                                  putcur(text->r0, text->c0, Vpage);
  13006.                                  while ((s = fgets(line, MAXLINE, fp)) != NULL
  13007.                                          if (sb_puts(text, s) == SB_ERR) {
  13008.                                                  clrscrn(userattr);
  13009.                                                  putcur(0, 0, Vpage);
  13010.                                                  fprintf(stderr, "puts error\n
  13011.                                                  exit(1);
  13012.                                          }
  13013.                                          sb_show(Vpage);
  13014.                                  }
  13015.                                  if (ferror(fp)) {
  13016.                                          putcur(text->r0, text->c0, Vpage);
  13017.                                          fprintf(stderr, "Error reading file\n
  13018.                                  }
  13019.                                  fclose(fp);
  13020.                          }
  13021.                          break;
  13022.                  default:
  13023.                          /* say what? */
  13024.                          fputc(BEL, stderr);
  13025.                          continue;
  13026.                  }
  13027.                  if ((Sbuf.flags & SB_DELTA) == SB_DELTA)
  13028.                          sb_show(Vpage);
  13029.          }
  13030.  
  13031.          clrscrn(userattr);
  13032.          putcur(0, 0, Vpage);
  13033.          exit(0);
  13034.  }
  13035.  
  13036.  /*
  13037.   *        get_fname -- get a filename from the user
  13038.   */
  13039.  
  13040.  char *
  13041.  get_fname(win, path, lim)
  13042.  struct REGION *win;
  13043.  char *path;
  13044.  short lim;
  13045.  {
  13046.          int ch;
  13047.          char *s;
  13048.  
  13049.          s = path;
  13050.          sb_show(Vpage);
  13051.          while ((ch = getch()) != K_RETURN) {
  13052.                  if (ch == '\b')
  13053.                          --s;
  13054.                  else {
  13055.                          sb_putc(win, ch);
  13056.                          *s++ = ch;
  13057.                  }
  13058.                  sb_show(Vpage);
  13059.          }
  13060.          *s = '\0';
  13061.          return (path);
  13062.  }
  13063.  
  13064.  
  13065.  SB_WRITE.C
  13066.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\12SBUF\SB_WRITE.C
  13067.  
  13068.  /*
  13069.   *        sb_write -- screen buffer write routines
  13070.   */
  13071.  
  13072.  #include <local\sbuf.h>
  13073.  
  13074.  extern struct BUFFER Sbuf;
  13075.  extern union CELL Scrnbuf[SB_ROWS][SB_COLS];
  13076.  
  13077.  /*
  13078.   *        sb_wa -- write an attribute to a region of the screen buffer
  13079.   */
  13080.  
  13081.  int
  13082.  sb_wa(win, attr, n)
  13083.  struct REGION *win;        /* window pointer */
  13084.  unsigned char attr;        /* attribute */
  13085.  short n;                /* repetition count */
  13086.  {
  13087.          short i;
  13088.          short row;
  13089.          short col;
  13090.  
  13091.          i = n;
  13092.          row = win->r0 + win->row;
  13093.          col = win->c0 + win->col;
  13094.          while (i--)
  13095.                  Scrnbuf[row][col + i].b.attr = attr;
  13096.  
  13097.          /* marked the changed region */
  13098.          if (col < Sbuf.lcol[row])
  13099.                  Sbuf.lcol[row] = col;
  13100.          if (col + n > Sbuf.rcol[row])
  13101.                  Sbuf.rcol[row] = col + n;
  13102.          Sbuf.flags |= SB_DELTA;
  13103.  
  13104.          return (i == 0) ? SB_OK : SB_ERR;
  13105.  } /* end sb_wa() */
  13106.  
  13107.  
  13108.  /*
  13109.   *        sb_wc -- write a character to a region of the screen buffer
  13110.   */
  13111.  
  13112.  int
  13113.  sb_wc(win, ch, n)
  13114.  struct REGION *win;        /* window pointer */
  13115.  unsigned char ch;        /* character */
  13116.  short n;                /* repetition count */
  13117.  {
  13118.          short i;
  13119.          short row;
  13120.          short col;
  13121.  
  13122.          i = n;
  13123.          row = win->r0 + win->row;
  13124.          col = win->c0 + win->col;
  13125.          while (i--)
  13126.                  Scrnbuf[row][col + i].b.ch = ch;
  13127.  
  13128.          /* marked the changed region */
  13129.          if (col < Sbuf.lcol[row])
  13130.                  Sbuf.lcol[row] = col;
  13131.          if (col + n > Sbuf.rcol[row])
  13132.                  Sbuf.rcol[row] = col + n;
  13133.          Sbuf.flags |= SB_DELTA;
  13134.  
  13135.          return (i == 0 ? SB_OK : SB_ERR);
  13136.  } /* end sb_wc() */
  13137.  
  13138.  
  13139.  /*
  13140.   *        sb_wca -- write a character/attribute pair to a region
  13141.   *        of the screen buffer
  13142.   */
  13143.  
  13144.  int
  13145.  sb_wca(win, ch, attr, n)
  13146.  struct REGION *win;        /* window pointer */
  13147.  unsigned char ch;        /* character */
  13148.  unsigned char attr;        /* attribute */
  13149.  short n;                /* repetition count */
  13150.  {
  13151.          int i;
  13152.          short row;
  13153.          short col;
  13154.  
  13155.          i = n;
  13156.          row = win->r0 + win->row;
  13157.          col = win->c0 + win->col;
  13158.          while (i--)
  13159.                  Scrnbuf[row][col + i].cap = (attr << 8) | ch;
  13160.  
  13161.          /* marked the changed region */
  13162.          if (col < Sbuf.lcol[row])
  13163.                  Sbuf.lcol[row] = col;
  13164.          if (col + n > Sbuf.rcol[row])
  13165.                  Sbuf.rcol[row] = col + n;
  13166.          Sbuf.flags |= SB_DELTA;
  13167.  
  13168.          return (i == 0 ? SB_OK : SB_ERR);
  13169.  } /* end sb_wca() */
  13170.  
  13171.  
  13172.  SC.C
  13173.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\13ANSI\SC.C
  13174.  
  13175.  /*
  13176.   *        SetColor (sc) -- set foreground, background, and border
  13177.   *        attributes on systems equipped with color display systems
  13178.   *
  13179.   *        Usage:        sc [foreground [background [border]]]
  13180.   *                sc [attribute]
  13181.   */
  13182.  
  13183.  #include <stdio.h>
  13184.  #include <dos.h>
  13185.  #include <local\std.h>
  13186.  #include <local\ansi.h>
  13187.  #include <local\ibmcolor.h>
  13188.  
  13189.  main(argc, argv)
  13190.  int argc;
  13191.  char **argv;
  13192.  {
  13193.          extern void ansi_tst();
  13194.          extern BOOLEAN iscolor();
  13195.          extern void setattr(POSITION, int);
  13196.          extern void menumode();
  13197.          extern parse(int, char **);
  13198.  
  13199.          ansi_tst();
  13200.          if (iscolor() == FALSE) {
  13201.                  fprintf(stderr, "\n\nSystem not in a color text mode.\n");
  13202.                  fprintf(stderr, "Use the MODE command to set the mode.\n");
  13203.                  exit(2);
  13204.          }
  13205.  
  13206.          /* process either batch or interactive commands */
  13207.          if (argc > 1)
  13208.                  /* batch mode processing */
  13209.                  parse(argc, argv);
  13210.          else
  13211.                  /* no command-line args -- interactive mode */
  13212.                  menumode();
  13213.  
  13214.          ANSI_ED;
  13215.          exit (0);
  13216.  }
  13217.  
  13218.  
  13219.  SCROLL.C
  13220.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\SCROLL.C
  13221.  
  13222.  /*
  13223.   *        scroll -- scroll a region of the "visual" screen
  13224.   *        page up or down by n rows (0 = initialize region)
  13225.   */
  13226.  
  13227.  #include <dos.h>
  13228.  #include <local\std.h>
  13229.  #include <local\bioslib.h>
  13230.  
  13231.  int
  13232.  scroll(t, l, b, r, n, a)
  13233.  int t;        /* top row of scroll region */
  13234.  int l;        /* left column */
  13235.  int b;        /* bottom row */
  13236.  int r;        /* right column */
  13237.  int n;        /* number of lines to scroll */
  13238.          /* sign indicates direction to scroll */
  13239.          /* 0 means scroll all lines in the region (initialize) */
  13240.  unsigned char a;/* attribute for new lines */
  13241.  {
  13242.          union REGS inregs, outregs;
  13243.  
  13244.          if (n < 0) {
  13245.                  /* scroll visual page down n lines */
  13246.                  inregs.h.ah = SCROLL_DN;
  13247.                  inregs.h.al = -n;
  13248.          }
  13249.          else {
  13250.                  /* scroll visual page up n lines */
  13251.                  inregs.h.ah = SCROLL_UP;
  13252.                  inregs.h.al = n;
  13253.          }
  13254.          inregs.h.bh = a;        /* attribute of blank lines */
  13255.          inregs.h.bl = 0;
  13256.          inregs.h.ch = t;        /* upper-left of scroll region */
  13257.          inregs.h.cl = l;
  13258.          inregs.h.dh = b;        /* lower-right of scroll region */
  13259.          inregs.h.dl = r;
  13260.          int86(VIDEO_IO, &inregs, &outregs);
  13261.  
  13262.          return (outregs.x.cflag);
  13263.  }
  13264.  
  13265.  
  13266.  SC_CMDS.C
  13267.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\13ANSI\SC_CMDS.C
  13268.  
  13269.  /*
  13270.   *        sc_cmds -- display command summary
  13271.   */
  13272.  
  13273.  #include <stdio.h>
  13274.  #include <local\ansi.h>
  13275.  
  13276.  void
  13277.  sc_cmds(fg, bkg, bdr)
  13278.  int fg, bkg, bdr;
  13279.  {
  13280.          static char *color_xlat[] = {
  13281.                  "Black (0)", "Blue (1)", "Green (2)", "Cyan (3)",
  13282.                  "Red (4)", "Magenta (5)", "Brown (6)", "White (7)",
  13283.                  "Grey (8)", "Light blue (9)", "Light green (10)",
  13284.                  "Light cyan (11)", "Light red (12)", "Light magenta (13)",
  13285.                  "Yellow (14)", "Bright white (15)"
  13286.          };
  13287.  
  13288.          ANSI_CUP(2, 29);
  13289.          fputs("*** SetColor (SC) ***", stdout);
  13290.          ANSI_CUP(4, 17);
  13291.          fputs("Attribute  Decrement  Increment  Current Value", stdout);
  13292.          ANSI_CUP(5, 17);
  13293.          fputs("---------  ---------  ---------  -------------", stdout);
  13294.          ANSI_CUP(6, 17);
  13295.          fputs("Foreground    F1         F2", stdout);
  13296.          ANSI_CUP(7, 17);
  13297.          fputs("Background    F3         F4", stdout);
  13298.          ANSI_CUP(8, 17);
  13299.          fputs("Border        F5         F6", stdout);
  13300.          ANSI_CUP(6, 50);
  13301.          fputs(color_xlat[fg], stdout);
  13302.          ANSI_CUP(7, 50);
  13303.          fputs(color_xlat[bkg], stdout);
  13304.          ANSI_CUP(8, 50);
  13305.          fputs(color_xlat[bdr], stdout);
  13306.          ANSI_CUP(10, 17);
  13307.          fputs("Type RETURN to exit. SetColor/Version 2.2", stdout);
  13308.          return;
  13309.  }
  13310.  
  13311.  
  13312.  SELECT.C
  13313.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\SELECT.C
  13314.  
  13315.  /*
  13316.   *        select -- functions to create a selection table and
  13317.   *        to determine whether an item is an entry in the table
  13318.   */
  13319.  
  13320.  #include <stdio.h>
  13321.  #include <stdlib.h>
  13322.  #include <string.h>
  13323.  #include <local\std.h>
  13324.  
  13325.  #define NRANGES        10
  13326.  #define NDIGITS        5
  13327.  
  13328.  struct slist_st {
  13329.          long int s_min;
  13330.          long int s_max;
  13331.  } Slist[NRANGES + 1];
  13332.  
  13333.  long Highest = 0;
  13334.  
  13335.  /*
  13336.   *        mkslist -- create the selection lookup table
  13337.   */
  13338.  
  13339.  int
  13340.  mkslist(list)
  13341.  char *list;
  13342.  {
  13343.          int i;
  13344.          char *listp, *s;
  13345.          long tmp;
  13346.  
  13347.          static long save_range();
  13348.  
  13349.          /* fill in table of selected items */
  13350.          if (*list == '\0') {
  13351.                  /* if no list, select all */
  13352.                  Slist[0].s_min = 0;
  13353.                  Slist[0].s_max = Highest = BIGGEST;
  13354.                  Slist[1].s_min = -1;
  13355.          }
  13356.          else {
  13357.                  listp = list;
  13358.                  for (i = 0; i < NRANGES; ++i) {
  13359.                          if ((s = strtok(listp, ", \t")) == NULL)
  13360.                                  break;
  13361.                          if ((tmp = save_range(i, s)) > Highest)
  13362.                                  Highest = tmp;
  13363.                          listp = NULL;
  13364.                  }
  13365.                  Slist[i].s_min = -1;
  13366.          }
  13367.          return (0);
  13368.  } /* end mkslist() */
  13369.  
  13370.  /*
  13371.   *        selected -- return non-zero value if the number
  13372.   *        argument is a member of the selection list
  13373.   */
  13374.  
  13375.  int
  13376.  selected(n)
  13377.  unsigned int n;
  13378.  {
  13379.          int i;
  13380.  
  13381.          /* look for converted number in selection list */
  13382.          for (i = 0; Slist[i].s_min != -1; ++i)
  13383.                  if (n >= Slist[i].s_min && n <= Slist[i].s_max)
  13384.                          return (1);
  13385.          return (0);
  13386.  } /* end selected() */
  13387.  
  13388.  /*
  13389.   *        save_range -- convert a string number spec to a
  13390.   *        numeric range in the selection table and return
  13391.   *        the highest number in the range
  13392.   */
  13393.  
  13394.  static long
  13395.  save_range(n, s)
  13396.  int n;
  13397.  char *s;
  13398.  {
  13399.          int radix = 10;
  13400.          char *cp, num[NDIGITS + 1];
  13401.  
  13402.          /* get the first (and possibly only) number */
  13403.          cp = num;
  13404.          while (*s != '\0' && *s != '-')
  13405.                  *cp++ = *s++;
  13406.          *cp = '\0';
  13407.          Slist[n].s_min = atol(num);
  13408.          if (*s == '\0')
  13409.                  /* pretty narrow range, huh? */
  13410.                  return (Slist[n].s_max = Slist[n].s_min);
  13411.  
  13412.          /* get the second number */
  13413.          if (*++s == '\0')
  13414.                  /* unspecified top end of range */
  13415.                  Slist[n].s_max = BIGGEST;
  13416.          else {
  13417.                  cp = num;
  13418.                  while (*s != '\0' && *s != '-')
  13419.                          *cp++ = *s++;
  13420.                  *cp = '\0';
  13421.                  Slist[n].s_max = atol(num);
  13422.          }
  13423.          return (Slist[n].s_max);
  13424.  } /* end save_range() */
  13425.  
  13426.  
  13427.  SETATTR.C
  13428.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\13ANSI\SETATTR.C
  13429.  
  13430.  /*
  13431.   *        setattr -- execute an attribute update
  13432.   */
  13433.  
  13434.  #include <stdio.h>
  13435.  #include <local\ansi.h>
  13436.  #include <local\ibmcolor.h>
  13437.  
  13438.  #define C_MASK        0x7
  13439.  
  13440.  void
  13441.  setattr(pos, attr)
  13442.  POSITION pos;        /* attribute position */
  13443.  int attr;        /* composite attribute number (base attr | intensity) */
  13444.  {
  13445.          static int ibm2ansi[] = {
  13446.                  ANSI_BLACK, ANSI_BLUE, ANSI_GREEN, ANSI_CYAN,
  13447.                  ANSI_RED, ANSI_MAGENTA, ANSI_BROWN, ANSI_WHITE
  13448.          };
  13449.  
  13450.          switch (pos) {
  13451.          case FGND:
  13452.                  if (attr & IBM_BRIGHT)
  13453.                          ANSI_SGR(ANSI_BOLD);
  13454.                  ANSI_SGR(ibm2ansi[attr & C_MASK] + ANSI_FOREGROUND);
  13455.                  break;
  13456.          case BKGND:
  13457.                  if (attr & IBM_BRIGHT)
  13458.                          ANSI_SGR(ANSI_BLINK);
  13459.                  ANSI_SGR(ibm2ansi[attr & C_MASK] + ANSI_BACKGROUND);
  13460.                  break;
  13461.          case BDR:
  13462.                  palette(0, attr);
  13463.                  break;
  13464.          }
  13465.          return;
  13466.  }
  13467.  
  13468.  
  13469.  SETCTYPE.C
  13470.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\SETCTYPE.C
  13471.  
  13472.  /*
  13473.   *        setctype -- set the cursor start and end raster scan lines
  13474.   */
  13475.  
  13476.  #include <dos.h>
  13477.  #include <local\bioslib.h>
  13478.  
  13479.  #define LO_NIBBLE        0x0F
  13480.  #define CURSOR_OFF        0x2
  13481.  #define MAXSCANLN        15
  13482.  
  13483.  int
  13484.  setctype(start, end)
  13485.  int start;        /* starting raster scan line */
  13486.  int end;        /* ending raster scan line */
  13487.  {
  13488.          union REGS inregs, outregs;
  13489.  
  13490.          inregs.h.ah = CUR_TYPE;
  13491.          inregs.h.ch = start & LO_NIBBLE;
  13492.          inregs.h.cl = end & LO_NIBBLE;
  13493.          if (start >= MAXSCANLN) {
  13494.                  inregs.h.ah |= CURSOR_OFF;
  13495.                  inregs.h.al = MAXSCANLN;
  13496.          }
  13497.          int86(VIDEO_IO, &inregs, &outregs);
  13498.  
  13499.          return (outregs.x.cflag);
  13500.  }
  13501.  
  13502.  
  13503.  SETDTA.C
  13504.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\DOS\SETDTA.C
  13505.  
  13506.  /*
  13507.   *        setdta -- tell DOS where to do disk transfers
  13508.   */
  13509.  
  13510.  #include <dos.h>
  13511.  #include <local\doslib.h>
  13512.  
  13513.  void
  13514.  setdta(bp)
  13515.  char *bp;        /* pointer to byte-aligned disk transfer area */
  13516.  {
  13517.          union REGS inregs, outregs;
  13518.  
  13519.          inregs.h.ah = SET_DTA;
  13520.          inregs.x.dx = (unsigned int)bp;
  13521.          (void)intdos(&inregs, &outregs);
  13522.  }
  13523.  
  13524.  
  13525.  SETFREQ.C
  13526.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\SETFREQ.C
  13527.  
  13528.  /*
  13529.   *        setfreq -- sets PC's tone generator to run
  13530.   *        continuously at the specified frequency
  13531.   */
  13532.  
  13533.  #include <conio.h>
  13534.  #include <local\timer.h>
  13535.  
  13536.  void
  13537.  setfreq(f)
  13538.  unsigned f;        /* frequency in Hertz (approximate) */
  13539.  {
  13540.          unsigned divisor = TIMER_CLK / f;
  13541.  
  13542.          outp(TIMER_CTRL, TIMER_PREP);                /* prepare timer */
  13543.          outp(TIMER_COUNT, (divisor & 0xFF));        /* low byte of divisor */
  13544.          outp(TIMER_COUNT, (divisor >> 8));        /* high byte of divisor */
  13545.  }
  13546.  
  13547.  
  13548.  SETMYDIR.C
  13549.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\03DOS\SETMYDIR.C
  13550.  
  13551.  /*
  13552.   *        setmydir -- try to change the DOS environment
  13553.   */
  13554.  
  13555.  #include <stdio.h>
  13556.  #include <stdlib.h>
  13557.  #include <local\std.h>
  13558.  
  13559.  main(argc, argv)
  13560.  int argc;
  13561.  char **argv;
  13562.  {
  13563.          register char **p;
  13564.          static char var[] = { "MYDIR" };
  13565.          static char pgm[MAXNAME + 1] = { "setmydir" };
  13566.          extern void fatal(char *, char *, int);
  13567.          extern void getpname(char *, char *);
  13568.  
  13569.          /* use an alias if one is given to this program */
  13570.          if (_osmajor >= 3)
  13571.                  getpname(*argv, pgm);
  13572.  
  13573.          /* try to add the MYDIR variable to the environment */
  13574.          if (putenv("MYDIR=c:\\mydir") == -1)
  13575.                  fatal(pgm, "Error changing environment", 1);
  13576.  
  13577.          /* display the environment for this process */
  13578.          for (p = environ; *p; p++) {
  13579.                  printf("%s\n", *p);
  13580.          }
  13581.  
  13582.          exit(0);
  13583.  }
  13584.  
  13585.  
  13586.  SETPAGE.C
  13587.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\SETPAGE.C
  13588.  
  13589.  /*
  13590.   *        setpage -- select "visual" screen page for viewing
  13591.   *        (the "active" page is the one being written to)
  13592.   */
  13593.  
  13594.  #include <dos.h>
  13595.  #include <local\std.h>
  13596.  #include <local\bioslib.h>
  13597.  #include <local\video.h>
  13598.  
  13599.  int
  13600.  setpage(pg)
  13601.  int pg;        /* visual screen page number */
  13602.  {
  13603.          union REGS inregs, outregs;
  13604.  
  13605.          /* check page number against table */
  13606.          if (Maxpage[Vmode] > 0 && (pg < 0 || pg >= Maxpage[Vmode]))
  13607.                  return (-1);
  13608.  
  13609.          /* change the visual page */
  13610.          inregs.h.ah = SET_PAGE;
  13611.          inregs.h.al = pg;
  13612.          int86(VIDEO_IO, &inregs, &outregs);
  13613.  
  13614.          return (outregs.x.cflag);
  13615.  }
  13616.  
  13617.  
  13618.  SETVMODE.C
  13619.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\SETVMODE.C
  13620.  
  13621.  /*
  13622.   *        setvmode -- set the video mode
  13623.   *        (color/graphics systems only)
  13624.   */
  13625.  
  13626.  #include <dos.h>
  13627.  #include <local\std.h>
  13628.  #include <local\bioslib.h>
  13629.  
  13630.  /***********************************************************
  13631.  *
  13632.  * mode # (m)        description
  13633.  * ------------- ---------------------------------
  13634.  * PC MODES:
  13635.  *         0        40x25 Mono text        (c/g default)
  13636.  *         1        40x25 Color text
  13637.  *        2        80x25 Mono text
  13638.  *        3        80x25 Color text
  13639.  *        4        320x200 4-color graphics (med res)
  13640.  *        5        320x200 Mono graphics (med res)
  13641.  *        6        640x200 2-color graphics (hi res)
  13642.  *        7        80x25 on monochrome adapter
  13643.  *
  13644.  * PCjr MODES:
  13645.  *        8        160x200 16-color graphics
  13646.  *        9        320x200 16-color graphics
  13647.  *        10        640x200 4-color fraphics
  13648.  *
  13649.  * EGA MODES:
  13650.  *        13        320x200 16-color graphics
  13651.  *        14        620x200 16-color graphics
  13652.  *        15        640x350 mono graphics
  13653.  *        16        640x350 color graphics (4- or 16-color)
  13654.  ***********************************************************/
  13655.  
  13656.  int
  13657.  setvmode(vmode)
  13658.  unsigned int vmode;        /* user-specified mode number */
  13659.  {
  13660.          union REGS inregs, outregs;
  13661.  
  13662.          inregs.h.ah = SET_MODE;
  13663.          inregs.h.al = vmode;        /* value not checked */
  13664.          int86(VIDEO_IO, &inregs, &outregs);
  13665.  
  13666.          /* update video structure */
  13667.          getstate();
  13668.  
  13669.          return (outregs.x.cflag);
  13670.  }
  13671.  
  13672.  
  13673.  SHOW.C
  13674.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\10DUMP\SHOW.C
  13675.  
  13676.  /*
  13677.   *        show -- a filter that displays the contents of a file
  13678.   *        in a way that is guaranteed to be displayable
  13679.   */
  13680.  
  13681.  #include <stdio.h>
  13682.  #include <stdlib.h>
  13683.  #include <fcntl.h>
  13684.  #include <io.h>
  13685.  #include <local\std.h>
  13686.  
  13687.  main(argc, argv)
  13688.  int argc;
  13689.  char **argv;
  13690.  {
  13691.          int ch;
  13692.          FILE *fp;
  13693.          BOOLEAN sflag = FALSE;        /* strip non-ASCII characters */
  13694.          BOOLEAN vflag = FALSE;        /* verbose mode */
  13695.          BOOLEAN wflag = FALSE;        /* filter typical word processing codes
  13696.          BOOLEAN errflag = FALSE;
  13697.          static char pgm[] = { "show" };
  13698.  
  13699.          extern int getopt(int, char **, char *);
  13700.          extern char *optarg;
  13701.          extern int optind, opterr;
  13702.          extern int showit(FILE *, BOOLEAN, BOOLEAN);
  13703.          extern void fatal(char *, char *, int);
  13704.  
  13705.          if (_osmajor >= 3)
  13706.                  getpname(*argv, pgm);
  13707.  
  13708.          while ((ch = getopt(argc, argv, "svw")) != EOF) {
  13709.                  switch (ch) {
  13710.                  case 's': /* strip non-ASCII characters */
  13711.                          sflag = TRUE;
  13712.                          break;
  13713.                  case 'v': /* verbose */
  13714.                          vflag = TRUE;
  13715.                          break;
  13716.                  case 'w': /* use word-processing conventions */
  13717.                          wflag = sflag = TRUE;
  13718.                          break;
  13719.                  case '?':
  13720.                          errflag = TRUE;
  13721.                          break;
  13722.                  }
  13723.          }
  13724.  
  13725.          /* check for errors */
  13726.          if (errflag == TRUE) {
  13727.                  fprintf(stderr, "Usage: %s [-sv] [file...]\n", pgm);
  13728.                  exit(1);
  13729.          }
  13730.  
  13731.          /* if no file names, use standard input */
  13732.          if (optind == argc) {
  13733.                  if (setmode(fileno(stdin), O_BINARY) == -1)
  13734.                          fatal(pgm, "Cannot set binary mode on stdin", 2);
  13735.                  showit(stdin, sflag, wflag);
  13736.                  exit(0);
  13737.          }
  13738.  
  13739.          /* otherwise, process remainder of command line */
  13740.          for ( ; optind < argc; ++optind) {
  13741.                  if ((fp = fopen(argv[optind], "rb")) == NULL) {
  13742.                          fprintf(stderr,
  13743.                                  "%s: Error opening %s\n", pgm, argv[optind]);
  13744.                          perror("");
  13745.                          continue;
  13746.                  }
  13747.                  if (vflag == TRUE)
  13748.                          fprintf(stdout, "\n%s:\n", argv[optind]);
  13749.                  if (showit(fp, sflag, wflag) != 0) {
  13750.                          fprintf(stderr,
  13751.                                  "%s: Error reading %s\n", pgm, argv[optind]);
  13752.                          perror("");
  13753.                  }
  13754.                  if (fclose(fp) == EOF)
  13755.                          fatal(pgm, "Error closing input file", 2);
  13756.          }
  13757.  
  13758.          exit(0);
  13759.  }
  13760.  
  13761.  
  13762.  SHOWENV.C
  13763.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\03DOS\SHOWENV.C
  13764.  
  13765.  /*
  13766.   *        showenv        -- display the values of any DOS variables
  13767.   *        named on the invocation command line
  13768.   */
  13769.  
  13770.  #include <stdio.h>
  13771.  #include <stdlib.h>
  13772.  #include <string.h>
  13773.  #include <local\std.h>
  13774.  
  13775.  main(argc, argv, envp)
  13776.  int argc;
  13777.  char **argv;
  13778.  char **envp;
  13779.  {
  13780.          register char *ep;
  13781.          static char pgm[MAXNAME + 1] = { "showenv" };
  13782.          extern void getpname(char *, char *);
  13783.  
  13784.          /* use an alias if one is given to this program */
  13785.          if (_osmajor >= 3)
  13786.                  getpname(*argv, pgm);
  13787.  
  13788.          /* if no arguments, show full environment list */
  13789.          if (argc == 1)
  13790.                  for (; *envp; ++envp)
  13791.                          printf("%s\n", *envp);
  13792.          else {
  13793.                  /*
  13794.                   *  treat all args as DOS variable names and
  13795.                   *  display values of only specified variables
  13796.                   */
  13797.                  ++argv;        /* skip past command name */
  13798.                  --argc;
  13799.                  while (argc > 0) {
  13800.                          if ((ep = getenv(strupr(*argv))) == NULL)
  13801.                                  fprintf(stderr, "%s not defined\n", *argv);
  13802.                          else
  13803.                                  printf("%s=%s\n", *argv, ep);
  13804.                          ++argv;
  13805.                          --argc;
  13806.                  }
  13807.          }
  13808.          exit(0);
  13809.  }
  13810.  
  13811.  
  13812.  SHOWIT.C
  13813.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\10DUMP\SHOWIT.C
  13814.  
  13815.  /*
  13816.   *        showit -- make non-printable characters in
  13817.   *        the stream fp visible (or optionally strip them)
  13818.   */
  13819.  
  13820.  #include <stdio.h>
  13821.  #include <ctype.h>
  13822.  #include <local\std.h>
  13823.  
  13824.  int
  13825.  showit(fp, strip, wp)
  13826.  FILE *fp;
  13827.  BOOLEAN strip;        /* strip non-ASCII codes */
  13828.  BOOLEAN wp;        /* filter typical word processing codes */
  13829.  {
  13830.          int ch;
  13831.  
  13832.          clearerr(fp);
  13833.          while ((ch = getc(fp)) != EOF)
  13834.                  if (isascii(ch) && (isprint(ch) || isspace(ch)))
  13835.                          switch (ch) {
  13836.                          case '\r':
  13837.                                  if (wp == TRUE) {
  13838.                                          if ((ch = getc(fp)) != '\n')
  13839.                                                  ungetc(ch, fp);
  13840.                                          putchar('\r');
  13841.                                          putchar('\n');
  13842.                                  }
  13843.                                  else
  13844.                                          putchar(ch);
  13845.                                  break;
  13846.                          default:
  13847.                                  putchar(ch);
  13848.                                  break;
  13849.                          }
  13850.                  else if (strip == FALSE)
  13851.                          printf("\\%02X", ch);
  13852.                  else if (wp == TRUE && isprint(ch & ASCII))
  13853.                          putchar(ch & ASCII);
  13854.          return (ferror(fp));
  13855.  }
  13856.  
  13857.  
  13858.  SHOWTABS.C
  13859.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\07CONFIG\SHOWTABS.C
  13860.  
  13861.  /*
  13862.   *        showtabs -- graphically display tabstop settings
  13863.   */
  13864.  
  13865.  #include <stdio.h>
  13866.  #include <stdlib.h>
  13867.  #include <local\std.h>
  13868.  
  13869.  #define MAXCOL          80
  13870.  #define TABWIDTH  8
  13871.  
  13872.  extern long Highest;
  13873.  
  13874.  main(argc, argv)
  13875.  int argc;
  13876.  char *argv[];
  13877.  {
  13878.          int ch, i;
  13879.          int interval, tablist[MAXLINE + 1], *p;
  13880.          char *tabstr;
  13881.          BOOLEAN errflag, fflag, vflag;
  13882.          static char pgm[MAXNAME + 1] = { "showtabs" };
  13883.  
  13884.          extern char *getpname(char *, char *);
  13885.          extern int getopt(int, char **, char *);
  13886.          extern char *optarg;
  13887.          extern int optind, opterr;
  13888.          extern int mkslist(char *);
  13889.          extern int selected(long);
  13890.          extern void fixtabs(int);
  13891.          extern void vartabs(int *);
  13892.          extern int tabstop(int);
  13893.  
  13894.          if (_osmajor >= 3)
  13895.                  getpname(*argv, pgm);
  13896.  
  13897.          /* process command-line options */
  13898.          errflag = fflag = vflag = FALSE;
  13899.          interval = 0;
  13900.          while ((ch = getopt(argc, argv, "f:v:")) != EOF) {
  13901.                  switch (ch) {
  13902.                  case 'f':
  13903.                          /* used fixed tabbing interval */
  13904.                          if (vflag == FALSE) {
  13905.                                  fflag = TRUE;
  13906.                                  interval = atoi(optarg);
  13907.                          }
  13908.                          break;
  13909.                  case 'v':
  13910.                          /* use list of tabs */
  13911.                          if (fflag == FALSE) {
  13912.                                  vflag = TRUE;
  13913.                                  strcpy(tabstr, optarg);
  13914.                          }
  13915.                          break;
  13916.                  case '?':
  13917.                          errflag = TRUE;
  13918.                          break;
  13919.                  }
  13920.          }
  13921.          if (errflag == TRUE) {
  13922.                  fprintf(stderr, "Usage: %s [-f interval | -v tablist]\n", pgm
  13923.                  exit(2);
  13924.          }
  13925.  
  13926.          /* set the tabstops */
  13927.          if (vflag == TRUE) {
  13928.                  /* user-supplied variable tab list */
  13929.                  mkslist(tabstr);
  13930.                  p = tablist;
  13931.                  for (i = 0; i < MAXLINE && i < Highest; ++i)
  13932.                          *p++ = selected((long)i + 1) ? i : 0;
  13933.                  *p = -1;        /* terminate the list */
  13934.                  vartabs(tablist);
  13935.          }
  13936.          else if (fflag == TRUE)
  13937.                  /* user-supplied fixed tabbing interval */
  13938.                  fixtabs(interval);
  13939.          else
  13940.                  /* hardware default tabbing interval*/
  13941.                  fixtabs(TABWIDTH);
  13942.  
  13943.          /* display current tabs settings */
  13944.          for (i = 0; i < MAXCOL; ++i)
  13945.                  if (tabstop(i))
  13946.                          fputc('T', stdout);
  13947.                  else if ((i + 1) % 10 == 0)
  13948.                          fputc('+', stdout);
  13949.                  else
  13950.                          fputc('-', stdout);
  13951.          fputc('\n', stdout);
  13952.  
  13953.          exit(0);
  13954.  }
  13955.  
  13956.  
  13957.  SOUND.C
  13958.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\06USER\SOUND.C
  13959.  
  13960.  /*
  13961.   *        sound -- produce a constant tone for a specified duration
  13962.   */
  13963.  
  13964.  #include <local\sound.h>
  13965.  
  13966.  void
  13967.  sound(f, dur)
  13968.  unsigned int f;        /* frequency of pitch in hertz */
  13969.  float dur;        /* in seconds and tenths of seconds */
  13970.  {
  13971.          extern void setfreq(unsigned int);
  13972.          extern void delay(float);
  13973.  
  13974.          /* set frequency in hertz */
  13975.          setfreq(f);
  13976.  
  13977.          /* turn the speaker on for specified duration */
  13978.          SPKR_ON;
  13979.          delay(dur);
  13980.          SPKR_OFF;
  13981.  }
  13982.  
  13983.  
  13984.  SOUNDS.C
  13985.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\06USER\SOUNDS.C
  13986.  
  13987.  /*
  13988.   *        sounds -- make various sounds on demand
  13989.   */
  13990.  
  13991.  #include <stdio.h>
  13992.  #include <conio.h>
  13993.  #include <math.h>
  13994.  
  13995.  #define ESC        27
  13996.  
  13997.  extern void sound(unsigned int, float);
  13998.  
  13999.  main()
  14000.  {
  14001.          int ch;
  14002.  
  14003.          fprintf(stderr, "1=warble 2=error 3=confirm 4=warn\n");
  14004.          fprintf(stderr, "Esc=quit\n");
  14005.          while ((ch = getch()) != ESC)
  14006.                  switch (ch) {
  14007.                  case '1':
  14008.                          warble();
  14009.                          break;
  14010.                  case '2':
  14011.                          error();
  14012.                          break;
  14013.                  case '3':
  14014.                          confirm();
  14015.                          break;
  14016.                  case '4':
  14017.                          warn();
  14018.                          break;
  14019.                  }
  14020.          exit(0);
  14021.  }
  14022.  
  14023.  #define CYCLES        3
  14024.  #define LOTONE        600
  14025.  #define HITONE        1200
  14026.  #define PERIOD        0.1
  14027.  
  14028.  warble()
  14029.  {
  14030.          int i;
  14031.  
  14032.          for (i = 0; i < 2 * CYCLES; ++i)
  14033.                  if (i % 2)
  14034.                          sound(LOTONE, PERIOD);
  14035.                  else
  14036.                          sound(HITONE, PERIOD);
  14037.  }
  14038.  
  14039.  error()
  14040.  {
  14041.          float d = 0.15;
  14042.  
  14043.          sound(440, d);
  14044.          sound(220, d);
  14045.  }
  14046.  
  14047.  confirm()
  14048.  {
  14049.          float d = 0.15;
  14050.  
  14051.          sound(440, d);
  14052.          sound(880, d);
  14053.  }
  14054.  
  14055.  warn()
  14056.  {
  14057.          float d = 0.2;
  14058.  
  14059.          sound(100, d);
  14060.  }
  14061.  
  14062.  
  14063.  SPACES.C
  14064.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\SPACES.C
  14065.  
  14066.  /*
  14067.   *        spaces -- send spaces (blanks) to the output stream
  14068.   */
  14069.  
  14070.  #include <stdio.h>
  14071.  #include <stdlib.h>
  14072.  
  14073.  int
  14074.  spaces(n, fp)
  14075.  int n;
  14076.  FILE *fp;
  14077.  {
  14078.          register int i;
  14079.  
  14080.          for (i = 0; i < n; ++i)
  14081.                  if (putc(' ', fp) == EOF && ferror(fp))
  14082.                          break;
  14083.  
  14084.          /* return number of spaces emitted */
  14085.          return (i);
  14086.  }
  14087.  
  14088.  
  14089.  SPKR.C
  14090.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\06USER\SPKR.C
  14091.  
  14092.  /*
  14093.   *        spkr -- turn speaker ON/OFF
  14094.   *
  14095.   *                no args => OFF
  14096.   *                any arg(s) => ON
  14097.   */
  14098.  
  14099.  #include <local\sound.h>
  14100.  
  14101.  main(argc, argv)
  14102.  int argc;
  14103.  char **argv;
  14104.  {
  14105.          /* turn speaker on or off */
  14106.          if (argc == 1)
  14107.                  SPKR_OFF;
  14108.          else
  14109.                  SPKR_ON;
  14110.          exit(0);
  14111.  }
  14112.  
  14113.  
  14114.  ST.C
  14115.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\11SCREEN\ST.C
  14116.  
  14117.  /*
  14118.   *        st -- screen test using cpblk function
  14119.   */
  14120.  
  14121.  #include <stdio.h>
  14122.  #include <stdlib.h>
  14123.  #include <conio.h>
  14124.  #include <ctype.h>
  14125.  #include <dos.h>
  14126.  #include <local\std.h>
  14127.  #include <local\video.h>
  14128.  
  14129.  #define CG_SEG                0xB800
  14130.  #define MONO_SEG        0xB000
  14131.  #define NBYTES                0x1000
  14132.  #define PAGESIZ                (NBYTES / 2)
  14133.  #define PG0_OS                0
  14134.  #define PG1_OS                PG0_OS + NBYTES
  14135.  #define ESC                27
  14136.  #define MAXSCAN                14
  14137.  
  14138.  main(argc, argv)
  14139.  int argc;
  14140.  char *argv[];
  14141.  {
  14142.          int i;
  14143.          int k;                                /* user command character */
  14144.          int ca;                                /* character/attribute word */
  14145.          int ch;                                /* character value read */
  14146.          int row, col;                        /* cursor position upon entry */
  14147.          int c_start, c_end;                /* cursor scan lines */
  14148.          unsigned char attr;                /* saved video attribute */
  14149.          unsigned dseg;                        /* destination buffer segment *
  14150.          unsigned os;                        /* page offset in bytes */
  14151.          static unsigned sbuf[NBYTES];        /* screen buffer */
  14152.          unsigned *bp;                        /* screen element pointer */
  14153.          unsigned sseg;                        /* source segment */
  14154.          int special;                        /* use special copy routine */
  14155.          int apg, vpg;                        /* active and visual display pag
  14156.  
  14157.          /* segment register values */
  14158.          struct SREGS segregs;
  14159.  
  14160.          extern void swap_int(int *, int *);
  14161.  
  14162.          static char pgm[] = { "st" };        /* program name */
  14163.  
  14164.          /* save user's current video state */
  14165.          getstate();
  14166.          readcur(&row, &col, Vpage);
  14167.          putcur(row - 1, 0, Vpage);
  14168.          readca(&ch, &attr, Vpage);
  14169.          getctype(&c_start, &c_end, Vpage);
  14170.          setctype(MAXSCAN, c_end);
  14171.          clrscrn(attr);
  14172.          putcur(1, 1, Vpage);
  14173.  
  14174.          /* initialize destination segment */
  14175.          special = 1;
  14176.          fputs("ScreenTest (ST): ", stderr);
  14177.          if (Vmode == CGA_C80 || Vmode == CGA_M80) {
  14178.                  dseg = CG_SEG;
  14179.                  fprintf(stderr, "Using CGA mode %d", Vmode);
  14180.          }
  14181.          else if (Vmode == MDA_M80) {
  14182.                  dseg = MONO_SEG;
  14183.                  fprintf(stderr, "Using MDA (mode %d)", Vmode);
  14184.                  special = 0;
  14185.          } else
  14186.                  fprintf(stderr, "%s: Requires 80-column text mode\n", pgm);
  14187.  
  14188.          /* process command-line arguments */
  14189.          if (argc > 2) {
  14190.                  fprintf(stderr, "Usage: %s [x]\n", pgm);
  14191.                  exit(2);
  14192.          }
  14193.          else if (argc == 2)
  14194.                  special = 0;        /* bypass special block move */
  14195.  
  14196.          /* get data segment value */
  14197.          segread(&segregs);
  14198.          sseg = segregs.ds;
  14199.  
  14200.          /* set up "active" and "visual" display pages */
  14201.          apg = 1;        /* page being written to */
  14202.          vpg = 0;        /* page being viewed */
  14203.  
  14204.          /* display buffers on the user's command */
  14205.          fprintf(stderr, " -- Type printable text; Esc=exit");
  14206.          while ((k = getkey()) != ESC) {
  14207.                  if (isascii(k) && isprint(k)) {
  14208.                          /* fill the buffer */
  14209.                          ca = ((k % 0xEF) << 8) | k;
  14210.                          for (bp = sbuf; bp - sbuf < PAGESIZ; ++bp)
  14211.                                  *bp = ca;
  14212.                          if (Vmode == MDA_M80)
  14213.                                  os = 0;
  14214.                          else
  14215.                                  os = (apg == 0) ? PG0_OS : PG1_OS;
  14216.                          if (special)
  14217.                                  cpblk(sbuf, sseg, os, dseg);
  14218.                          else
  14219.                                  movedata(sseg, sbuf, dseg, os, NBYTES);
  14220.                          if (Vmode != MDA_M80) {
  14221.                                  swap_int(&apg, &vpg);
  14222.                                  setpage(vpg);
  14223.                          }
  14224.                  }
  14225.                  else {
  14226.                          clrscrn(attr);
  14227.                          putcur(0, 0, Vpage);
  14228.                          writestr(" Type printable text; Esc = exit ", vpg);
  14229.                  }
  14230.          }
  14231.  
  14232.          /* restore user's video conditions and return to DOS */
  14233.          setpage(Vpage);
  14234.          clrscrn(attr);
  14235.          putcur(0, 0, Vpage);
  14236.          setctype(c_start, c_end);
  14237.          exit(0);
  14238.  }
  14239.  
  14240.  
  14241.  STRDUP.C
  14242.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\14VIEW\STRDUP.C
  14243.  
  14244.  /*
  14245.   *        strdup -- duplicate a string
  14246.   */
  14247.  
  14248.  #include <stdio.h>
  14249.  #include <malloc.h>
  14250.  #include <string.h>
  14251.  
  14252.  char *
  14253.  strdup(str)
  14254.  char *str;
  14255.  {
  14256.          char *buf;
  14257.  
  14258.          buf = malloc(strlen(str) + 1);
  14259.          return (buf == NULL ? buf : strcpy(buf, str));
  14260.  }
  14261.  
  14262.  
  14263.  STRING.C
  14264.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\STRING.C
  14265.  
  14266.  /*
  14267.   *        string -- emit a sequence of n repetitions of the
  14268.   *        character ch
  14269.   */
  14270.  
  14271.  #include <stdio.h>
  14272.  #include <stdlib.h>
  14273.  
  14274.  int
  14275.  string(n, ch, fp)
  14276.  int n;
  14277.  char ch;
  14278.  FILE *fp;
  14279.  {
  14280.          register int i;
  14281.  
  14282.          for (i = 0; i < n; ++i)
  14283.                  if (fputc(ch, fp) == EOF && ferror(fp))
  14284.                          break;
  14285.  
  14286.          /* return number of actual repetitions */
  14287.          return (i);
  14288.  }
  14289.  
  14290.  
  14291.  SWAP_INT.C
  14292.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\11SCREEN\SWAP_INT.C
  14293.  
  14294.  /*
  14295.   *        swap_int -- exchange the values of the two integers
  14296.   */
  14297.  
  14298.  void
  14299.  swap_int(p1, p2)
  14300.  register int *p1;
  14301.  register int *p2;
  14302.  {
  14303.          int tmp;
  14304.  
  14305.          /* exchange the values */
  14306.          tmp = *p1;
  14307.          *p1 = *p2;
  14308.          *p2 = tmp;
  14309.  }
  14310.  
  14311.  
  14312.  SWEEP.C
  14313.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\06USER\SWEEP.C
  14314.  
  14315.  /*
  14316.   *        sweep -- produce a sound that sweeps from
  14317.   *        a low to a high frequency repeatedly until a
  14318.   *        key is pressed
  14319.   */
  14320.  
  14321.  #include <conio.h>
  14322.  #include <local\sound.h>
  14323.  
  14324.  main()
  14325.  {
  14326.          unsigned int f;
  14327.          int d, n;
  14328.          extern void setfreq(unsigned int);
  14329.  
  14330.          SPKR_ON;
  14331.          while (1) {
  14332.                  /* give user a way out */
  14333.                  if (kbhit())
  14334.                          break;
  14335.                  n = 10;
  14336.                  for (f = 100; f <= 5000; f += n) {
  14337.                          setfreq(f);
  14338.                          d = 1000;
  14339.                          /* fake a short delay (machine dependednt) */
  14340.                          while (d-- > 0)
  14341.                                  ;
  14342.                          n += 10;
  14343.                  }
  14344.          }
  14345.          SPKR_OFF;
  14346.          exit(0);
  14347.  }
  14348.  
  14349.  
  14350.  TABS.C
  14351.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\TABS.C
  14352.  
  14353.  /*
  14354.   *        tabs -- a group of cooperating functions that set
  14355.   *        and report the settings of "tabstops"
  14356.   */
  14357.  
  14358.  #include <local\std.h>
  14359.  
  14360.  static char Tabstops[MAXLINE];
  14361.  
  14362.  /*
  14363.   *        fixtabs -- set up fixed-interval tabstops
  14364.   */
  14365.  void
  14366.  fixtabs(interval)
  14367.  register int interval;
  14368.  {
  14369.          register int i;
  14370.  
  14371.          for (i = 0; i < MAXLINE; i++)
  14372.                  Tabstops[i] = (i % interval == 0) ? 1 : 0;
  14373.  } /* end fixtabs() */
  14374.  
  14375.  /*
  14376.   *        vartabs -- set up variable tabstops from an array
  14377.   *        integers terminated by a -1 entry
  14378.   */
  14379.  void
  14380.  vartabs(list)
  14381.  int *list;
  14382.  {
  14383.          register int i;
  14384.  
  14385.          /* initialize the tabstop array */
  14386.          for (i = 0; i < MAXLINE; ++i)
  14387.                  Tabstops[i] = 0;
  14388.  
  14389.          /* set user-sprcified tabstops */
  14390.          while (*list != -1)
  14391.                  Tabstops[*++list] = 1;
  14392.  } /* end vartabs() */
  14393.  
  14394.  /*
  14395.   *        tabstop -- return non-zero if col is a tabstop
  14396.   */
  14397.  int
  14398.  tabstop(col)
  14399.  register int col;
  14400.  {
  14401.          return (col >= MAXLINE ? 1 : Tabstops[col]);
  14402.  } /* end tabstop() */
  14403.  
  14404.  
  14405.  TEE.C
  14406.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\08FILE\TEE.C
  14407.  
  14408.  /*
  14409.   *        tee -- a "pipe fitter" for DOS
  14410.   */
  14411.  
  14412.  #include <stdio.h>
  14413.  #include <stdlib.h>
  14414.  #include <string.h>
  14415.  #include <local\std.h>
  14416.  
  14417.  main(argc, argv)
  14418.  int argc;
  14419.  char *argv[];
  14420.  {
  14421.          register int ch, n;
  14422.          static char openmode[] = { "w" };
  14423.          static char pgm[MAXPATH + 1] = { "tee" };
  14424.          FILE *fp[_NFILE];        /* array of file pointers */
  14425.  
  14426.          extern int getopt(int, char **, char *);
  14427.          extern int optind, opterr;
  14428.          extern char *optarg;
  14429.          extern void getpname(char *, char *);
  14430.  
  14431.          /* check for an alias */
  14432.          if (_osmajor >= 3)
  14433.                  getpname(argv[0], pgm);
  14434.  
  14435.          /* process command-line options, if any */
  14436.          while ((ch = getopt(argc, argv, "a")) != EOF)
  14437.                  switch (ch) {
  14438.                  case 'a':
  14439.                          strcpy(openmode, "a");
  14440.                          break;
  14441.                  case '?':
  14442.                          break;
  14443.                  }
  14444.          n = argc -= optind;
  14445.          argv += optind;
  14446.  
  14447.          /* check for errors */
  14448.          if (argc > _NFILE) {
  14449.                  fprintf(stderr, "Too many files (max = %d)\n", _NFILE);
  14450.                  exit(1);
  14451.          }
  14452.  
  14453.          /* open the output file(s) */
  14454.          for (n = 0; n < argc; ++n) {
  14455.                  if ((fp[n] = fopen(argv[n], openmode)) == NULL) {
  14456.                          fprintf(stderr, "Cannot open %s\n", argv[n]);
  14457.                          continue;
  14458.                  }
  14459.          }
  14460.  
  14461.          /* copy input to stdout plus opened file(s) */
  14462.          while ((ch = getchar()) != EOF) {
  14463.                  putchar(ch);
  14464.                  for (n = 0; n < argc; ++n)
  14465.                          if (fp[n] != NULL)
  14466.                                  fputc(ch, fp[n]);
  14467.          }
  14468.  
  14469.          /* close file(s) */
  14470.          if (fcloseall() == -1) {
  14471.                  fprintf(stderr, "Error closing a file\n");
  14472.                  exit(2);
  14473.          }
  14474.  
  14475.          exit(0);
  14476.  }
  14477.  
  14478.  
  14479.  TIMEDATA.C
  14480.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\04STDLIB\TIMEDATA.C
  14481.  
  14482.  /*
  14483.   *        timedata -- time zone and time value tests
  14484.   */
  14485.  
  14486.  #include <stdio.h>
  14487.  #include <time.h>
  14488.  
  14489.  main()
  14490.  {
  14491.          long now;
  14492.          struct tm *tbuf;
  14493.  
  14494.          /* get TZ data into global variables */
  14495.          tzset();
  14496.  
  14497.          /* display the global time values */
  14498.          printf("daylight savings time flag = %d\n", daylight);
  14499.          printf("difference (in seconds) from GMT = %ld\n", timezone);
  14500.          printf("standard time zone string is %s\n", tzname[0]);
  14501.          printf("daylight time zone string is %s\n", tzname[1]);
  14502.  
  14503.          /*
  14504.           *  display the current date and time values for
  14505.           *  local and universal time
  14506.           */
  14507.          now = time(NULL);
  14508.          printf("\nctime():\t%s\n", ctime(&now));
  14509.          tbuf = localtime(&now);
  14510.          printf("local time:\t%s\n", asctime(tbuf));
  14511.          tbuf = gmtime(&now);
  14512.          printf("universal time:\t%s\n", asctime(tbuf));
  14513.  
  14514.          exit(0);
  14515.  }
  14516.  
  14517.  
  14518.  TIMER.C
  14519.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\06USER\TIMER.C
  14520.  
  14521.  /*
  14522.   *        timer -- general purpose timer program; uses the
  14523.   *        PC's intra-application communication area (ICA) as
  14524.   *        a time and date buffer
  14525.   */
  14526.  
  14527.  #include <dos.h>
  14528.  #include <stdio.h>
  14529.  #include <stdlib.h>
  14530.  #include <string.h>
  14531.  #include <time.h>
  14532.  #include <memory.h>
  14533.  #include <local\std.h>
  14534.  
  14535.  #define NBYTES                16
  14536.  #define ICA_SEG        0x4F
  14537.  #define MAXTNUM                3
  14538.  #define TIMEMASK        0x3FFFFFFF
  14539.  #define FLAGBIT                0x80000000
  14540.  #define IDBIT                0x40000000
  14541.  
  14542.  main(argc, argv)
  14543.  int argc;
  14544.  char *argv[];
  14545.  {
  14546.          int ch;
  14547.          char *cp;
  14548.          int tn;                        /* timer number */
  14549.          int errflag;                /* error flag */
  14550.          int eflag;                /* elapsed time flag */
  14551.          int sflag;                /* start timer flag */
  14552.          char dest[MAXPATH + 1];        /* destination file name */
  14553.          char timestr[MAXLINE];        /* buffer for elapsed time string */
  14554.          long now;                /* current time */
  14555.          long then;                /* previously recorded time */
  14556.          FILE *fout;
  14557.          unsigned long tdata[MAXTNUM];
  14558.  
  14559.          struct SREGS segregs;
  14560.  
  14561.          static char pgm[MAXNAME + 1] = { "timer" };
  14562.  
  14563.          static void usage(char *, char *);
  14564.          extern char interval(long, char *);
  14565.          extern char *getpname(char *, char *);
  14566.          extern int getopt(int, char **, char *);
  14567.          extern int optind, opterr;
  14568.          extern char *optarg;
  14569.  
  14570.          if (_osmajor >= 3)
  14571.                  getpname(*argv, pgm);
  14572.  
  14573.          /* process optional arguments */
  14574.          fout = stdout;
  14575.          tn = 0;
  14576.          errflag = eflag = sflag = 0;
  14577.          while ((ch = getopt(argc, argv, "0123ef:s")) != EOF) {
  14578.                  switch (ch) {
  14579.                  case 'e':
  14580.                          /* report elapsed timing */
  14581.                          ++eflag;
  14582.                          break;
  14583.                  case 'f':
  14584.                          /* use specified log file or stream */
  14585.                          strcpy(dest, optarg);
  14586.                          if ((fout = fopen(dest, "a")) == NULL) {
  14587.                                  fprintf(stderr, "%s: Cannot open %s\n",
  14588.                                          pgm, dest);
  14589.                                  exit(1);
  14590.                          }
  14591.                          break;
  14592.                  case 's':
  14593.                          /* start (or restart) timing an interval */
  14594.                          ++sflag;
  14595.                          break;
  14596.                  case '0':
  14597.                  case '1':
  14598.                  case '2':
  14599.                  case '3':
  14600.                          /* use specified timer */
  14601.                          tn = ch - 0x30;
  14602.                          break;
  14603.                  case '?':
  14604.                          /* bad option flag */
  14605.                          ++errflag;
  14606.                          break;
  14607.                  }
  14608.          }
  14609.          argc -= optind;
  14610.          argv += optind;
  14611.  
  14612.          /* check for errors */
  14613.          if (errflag > 0 || argc > 0)
  14614.                  usage(pgm, "Bad command line option(s)");
  14615.  
  14616.          segread(&segregs);
  14617.  
  14618.          /* report current date and time */
  14619.          now = time(NULL);
  14620.          fprintf(fout, "%s", ctime(&now));
  14621.  
  14622.          /* control and report timer data */
  14623.          if (eflag) {
  14624.                  /* report elapsed time for specified timer */
  14625.                  movedata(ICA_SEG, 0, segregs.ds, tdata, NBYTES);
  14626.                  then = tdata[tn];
  14627.                  if ((then & FLAGBIT) != FLAGBIT || (then & IDBIT) != IDBIT) {
  14628.                          fprintf(stderr, "Timer database corrupted or not set\
  14629.                          exit(1);
  14630.                  }
  14631.                  interval(now - (then & TIMEMASK), timestr);
  14632.                  fprintf(stdout, "Elapsed time = %s\n", timestr);
  14633.          }
  14634.          if (sflag) {
  14635.                  /* start (or restart) specified timer */
  14636.                  movedata(ICA_SEG, 0, segregs.ds, tdata, NBYTES);
  14637.                  tdata[tn] = (now & TIMEMASK) | FLAGBIT | IDBIT;
  14638.                  movedata(segregs.ds, tdata, ICA_SEG, 0, NBYTES);
  14639.          }
  14640.          fputc('\n', fout);
  14641.  
  14642.          exit(0);
  14643.  }
  14644.  
  14645.  /*
  14646.   *        usage -- display a usage message and exit
  14647.   *        with an error indication
  14648.   */
  14649.  
  14650.  static void
  14651.  usage(pname, mesg)
  14652.  char *pname;
  14653.  char *mesg;
  14654.  {
  14655.          fprintf(stderr, "%s\n", mesg);
  14656.          fprintf(stderr, "Usage: %s [-efs#]\n", pname);
  14657.          fprintf(stderr, "\t-e \tshow an elapsed time (must use start first)\n
  14658.          fprintf(stderr, "\t-f file\tappend output to specified file\n");
  14659.          fprintf(stderr, "\t-s \tstart (or restart) an interval timer\n");
  14660.          fprintf(stderr, "\t-# \tselect a timer (0 to 3; default is 0)\n");
  14661.          exit(2);
  14662.  }
  14663.  
  14664.  
  14665.  TONE.C
  14666.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\06USER\TONE.C
  14667.  
  14668.  /*
  14669.   *        tone -- set the frequency of the sound generator
  14670.   */
  14671.  
  14672.  #include <stdio.h>
  14673.  
  14674.  main(argc, argv)
  14675.  int argc;
  14676.  char **argv;
  14677.  {
  14678.          extern void setfreq(unsigned int);
  14679.  
  14680.          if (argc != 2) {
  14681.                  fprintf(stderr, "Usage: tone hertz\n");
  14682.                  exit(1);
  14683.          }
  14684.  
  14685.          /* set the frequency in Hertz */
  14686.          setfreq(atoi(*++argv));
  14687.          exit(0);
  14688.  }
  14689.  
  14690.  
  14691.  TOUCH.C
  14692.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\08FILE\TOUCH.C
  14693.  
  14694.  /*
  14695.   *        touch -- update modification time of file(s)
  14696.   */
  14697.  
  14698.  #include <stdio.h>
  14699.  #include <stdlib.h>
  14700.  #include <ctype.h>
  14701.  #include <sys\types.h>
  14702.  #include <sys\stat.h>
  14703.  #include <sys\utime.h>
  14704.  #include <io.h>
  14705.  #include <errno.h>
  14706.  #include <local\std.h>
  14707.  
  14708.  /* error return -- big enough not to be mistaken for a bad file count */
  14709.  #define ERR        0x7FFF
  14710.  
  14711.  main(argc, argv)
  14712.  int argc;
  14713.  char *argv[];
  14714.  {
  14715.          int ch;
  14716.          int i;
  14717.          int badcount;                /* # of files that can't be updated */
  14718.          struct stat statbuf;        /* buffer for stat results */
  14719.          BOOLEAN errflag,        /* error flag */
  14720.                  cflag,                /* creation flag */
  14721.                  vflag;                /* verbose flag */
  14722.          FILE *fp;
  14723.  
  14724.          static char pgm[MAXNAME + 1] = { "touch" };
  14725.          extern int getopt(int, char **, char *);
  14726.          extern int optind, opterr;
  14727.          extern char *optarg;
  14728.          extern void getpname(char *, char *);
  14729.          static void usage(char *);
  14730.  
  14731.          /* get program name from DOS (version 3.00 and later) */
  14732.          if (_osmajor >= 3)
  14733.                  getpname(argv[0], pgm);
  14734.  
  14735.          /* process optional arguments first */
  14736.          errflag = cflag = vflag = FALSE;
  14737.          badcount = 0;
  14738.          while ((ch = getopt(argc, argv, "cv")) != EOF)
  14739.                  switch (ch) {
  14740.                  case 'c':
  14741.                          /* don't create files */
  14742.                          cflag = TRUE;
  14743.                          break;
  14744.                  case 'v':
  14745.                          /* verbose -- report activity */
  14746.                          vflag = TRUE;
  14747.                          break;
  14748.                  case '?':
  14749.                          errflag = TRUE;
  14750.                          break;
  14751.                  }
  14752.          argc -= optind;
  14753.          argv += optind;
  14754.  
  14755.          /* check for errors including no file names */
  14756.          if (errflag == TRUE || argc <= 0) {
  14757.                  usage(pgm);
  14758.                  exit(ERR);
  14759.          }
  14760.  
  14761.          /* update modification times of files */
  14762.          for (; argc-- > 0; ++argv) {
  14763.                  if (stat(*argv, &statbuf) == -1) {
  14764.                          /* file doesn't exist */
  14765.                          if (cflag == TRUE) {
  14766.                                  /* don't create it */
  14767.                                  ++badcount;
  14768.                                  continue;
  14769.                          }
  14770.                          else if ((fp = fopen(*argv, "w")) == NULL) {
  14771.                                  fprintf(stderr, "%s: Cannot create %s\n",
  14772.                                          pgm, *argv);
  14773.                                  ++badcount;
  14774.                                  continue;
  14775.                          }
  14776.                          else {
  14777.                                  if (fclose(fp) == EOF) {
  14778.                                          perror("Error closing file");
  14779.                                          exit(ERR);
  14780.                                  }
  14781.                                  if (stat(*argv, &statbuf) == -1) {
  14782.                                          fprintf(stderr, "%s: Cannot stat %s\n
  14783.                                          ++badcount;
  14784.                                          continue;
  14785.                                  }
  14786.                          }
  14787.                  }
  14788.                  if (utime(*argv, NULL) == -1) {
  14789.                          ++badcount;
  14790.                          perror("Error updating date/time stamp");
  14791.                          continue;
  14792.                  }
  14793.                  if (vflag == TRUE)
  14794.                          fprintf(stderr, "Touched file %s\n", *argv);
  14795.          }
  14796.  
  14797.          exit(badcount);
  14798.  } /* end main() */
  14799.  
  14800.  /*
  14801.   *        usage -- display an informative usage message
  14802.   */
  14803.  
  14804.  static void
  14805.  usage(pname)
  14806.  char *pname;
  14807.  {
  14808.          fprintf(stderr, "Usage: %s [-cv] file ...\n", pname);
  14809.          fprintf(stderr, "\t-c  Do not create any files\n");
  14810.          fprintf(stderr, "\t-v  Verbose mode -- report activities\n");
  14811.  } /* end usage() */
  14812.  
  14813.  /*
  14814.   *        dummy functions to show how to save a little space
  14815.   */
  14816.  
  14817.  _setenvp()
  14818.  {
  14819.  }
  14820.  
  14821.  #ifndef DEBUG
  14822.  _nullcheck()
  14823.  {
  14824.  }
  14825.  #endif
  14826.  
  14827.  
  14828.  TSTREPLY.C
  14829.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\06USER\TSTREPLY.C
  14830.  
  14831.  /*
  14832.   *        tstreply -- test the getreply function
  14833.   */
  14834.  
  14835.  #include <stdio.h>
  14836.  #include <string.h>
  14837.  #include <local\std.h>
  14838.  #include <local\video.h>
  14839.  #include "linebuf.h"
  14840.  
  14841.  #define INPUT_ROW        0
  14842.  #define INPUT_COL        40
  14843.  #define WIDTH                40
  14844.  
  14845.  int Apage = 0;
  14846.  BOOLEAN Silent = FALSE;
  14847.  
  14848.  main(argc, argv)
  14849.  int argc;
  14850.  char *argv[];
  14851.  {
  14852.          unsigned int r, c, ch, attr, revattr;
  14853.          char reply[MAXPATH + 1];
  14854.          LINEBUF buf;
  14855.  
  14856.          extern char *getreply(short, short, short,
  14857.                  char *, LINEBUF *, short, short, short);
  14858.  
  14859.          /* process command line */
  14860.          if (argc == 2 && strcmp(argv[1], "-s") == 0)
  14861.                  Silent = TRUE;
  14862.          else if (argc > 2) {
  14863.                  fprintf(stderr, "Usage: tstreply [-s]\n");
  14864.                  exit(1);
  14865.          }
  14866.  
  14867.          /* initial setup */
  14868.          getstate();
  14869.          readca(&ch, &attr, Apage);
  14870.          revattr = ((attr << 4) | (attr >> 4)) & 0x77;
  14871.          clrscrn(attr);
  14872.          putcur(0, 0, Apage);
  14873.          writestr("TSTREPLY", Apage);
  14874.          putcur(1, 0, Apage);
  14875.          writec(HLINE, Maxcol[Vmode] - 1, Apage);
  14876.          buf.l_buf = reply;
  14877.          buf.l_next = buf.l_prev = (LINEBUF *)NULL;
  14878.  
  14879.          /* demo getreply() */
  14880.  
  14881.          if (getreply(INPUT_ROW, INPUT_COL, WIDTH, "File: ", &buf,
  14882.                  MAXPATH, revattr, 0) == NULL) {
  14883.                  putcur(INPUT_ROW, INPUT_COL, Apage);
  14884.                  writeca(' ', attr, WIDTH, Apage);
  14885.                  putcur(2, 0, Apage);
  14886.                  fprintf(stderr, "input aborted\n");
  14887.                  exit(1);
  14888.          }
  14889.          putcur(INPUT_ROW, INPUT_COL, Apage);
  14890.          writeca(' ', attr, WIDTH, Apage);
  14891.          putcur(2, 0, Apage);
  14892.          fprintf(stderr, "reply = %s\n", reply);
  14893.          exit(0);
  14894.  }
  14895.  
  14896.  #define MSG_ROW        24
  14897.  #define MSG_COL        0
  14898.  
  14899.  int
  14900.  errmsg(mesg)
  14901.  char *mesg;
  14902.  {
  14903.          int n;
  14904.          extern void sound(unsigned int, float);
  14905.  
  14906.          putcur(MSG_ROW, MSG_COL, Apage);
  14907.          if ((n = strlen(mesg)) > 0) {
  14908.                  writestr(mesg, Apage);
  14909.                  if (Silent == FALSE)
  14910.                          sound(100, 0.2);
  14911.          }
  14912.          else
  14913.                  writec(' ', Maxcol[Vmode] - 1 - MSG_COL, Apage);
  14914.          return (n);
  14915.  }
  14916.  
  14917.  
  14918.  TSTSEL.C
  14919.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\07CONFIG\TSTSEL.C
  14920.  
  14921.  /*
  14922.   *        tstsel -- test driver for the "select" functions
  14923.   */
  14924.  
  14925.  #include <stdio.h>
  14926.  #include <local\std.h>
  14927.  
  14928.  #define MAXTEST        20
  14929.  #define NRANGES        10
  14930.  #define NDIGITS        5
  14931.  
  14932.  extern struct slist_st {
  14933.          long int s_min;
  14934.          long int s_max;
  14935.  } Slist[NRANGES + 1];
  14936.  
  14937.  main (argc, argv)
  14938.  int argc;
  14939.  char **argv;
  14940.  {
  14941.          int i;
  14942.          extern int mkslist(char *);
  14943.          extern int selected(unsigned int);
  14944.          static void showlist();
  14945.  
  14946.          if (argc != 2) {
  14947.                  fprintf(stderr, "Usage: tstsel list\n");
  14948.                  exit(1);
  14949.          }
  14950.          printf("argv[1] = %s\n", argv[1]);
  14951.          mkslist(argv[1]);
  14952.          showlist();
  14953.          for (i = 0; i < MAXTEST; ++i)
  14954.                  printf("%2d -> %s\n", i, selected(i) ? "YES" : "NO");
  14955.          exit(0);
  14956.  }
  14957.  
  14958.  /*
  14959.   *        showlist -- display the contents of the select list
  14960.   */
  14961.  
  14962.  static void
  14963.  showlist()
  14964.  {
  14965.          int i;
  14966.  
  14967.          /* scan the selection list and display values */
  14968.          for (i = 0; i <= NRANGES; ++i)
  14969.                  printf("%2d %5ld %5ld\n", i, Slist[i].s_min, Slist[i].s_max);
  14970.  }
  14971.  
  14972.  
  14973.  USERATTR.C
  14974.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\13ANSI\USERATTR.C
  14975.  
  14976.  /*
  14977.   *        userattr -- set video attributes to user-specified values
  14978.   *        (DOS environment parameters) or to reasonable defaults and
  14979.   *        return success or a failure indication for bad attributes
  14980.   */
  14981.  
  14982.  #include <stdio.h>
  14983.  #include <stdlib.h>
  14984.  #include <string.h>
  14985.  #include <local\std.h>
  14986.  #include <local\ansi.h>
  14987.  #include <local\ibmcolor.h>
  14988.  
  14989.  int
  14990.  userattr(foreground, background, border)
  14991.  char *foreground, *background, *border;
  14992.  {
  14993.          register char *s;
  14994.          static int attrset(POSITION, char *);
  14995.  
  14996.          if ((s = getenv("FGND")) == NULL)
  14997.                  s = foreground;
  14998.          if (attrset(FGND, s) == -1)
  14999.                  return FAILURE;
  15000.  
  15001.          if ((s = getenv("BKGND")) == NULL)
  15002.                  s = background;
  15003.          if (attrset(BKGND, s) == -1)
  15004.                  return FAILURE;
  15005.  
  15006.          if ((s = getenv("BORDER")) == NULL)
  15007.                  s = border;
  15008.          if (attrset(BDR, s) == -1)
  15009.                  return FAILURE;
  15010.  
  15011.          return SUCCESS;
  15012.  }
  15013.  
  15014.  /*
  15015.   *        attrset -- parse the color spec and try to set it.
  15016.   *        return 0 if OK and -1 upon error (bad color number)
  15017.   */
  15018.  static int
  15019.  attrset(apos, str)
  15020.  POSITION apos;
  15021.  register char *str;
  15022.  {
  15023.          register int attr;
  15024.          extern int colornum(char *);
  15025.          extern void setattr(POSITION, int);
  15026.  
  15027.          if ((attr = colornum(strtok(str, " \t"))) == IBM_BRIGHT)
  15028.                  attr |= colornum(strtok(NULL, " \t"));
  15029.          if (attr >= 0)
  15030.                  setattr(apos, attr);
  15031.          else
  15032.                  return (-1);
  15033.          return (0);
  15034.  }
  15035.  
  15036.  
  15037.  VER.C
  15038.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\DOS\VER.C
  15039.  
  15040.  /*
  15041.   *        ver -- get the MS-DOS (or PC-DOS) version number
  15042.   */
  15043.  
  15044.  #include <local\doslib.h>
  15045.  
  15046.  /************************************************************
  15047.  *  For MS-DOS versions prior to 2.00, the low byte (AL) of
  15048.  *  the return value is zero.  For versions 2.00 and beyond,
  15049.  *  the low byte is the major version number and the high
  15050.  *  byte (AH) is the minor version number.
  15051.  ************************************************************/
  15052.  
  15053.  int ver()
  15054.  {
  15055.          return(bdos(DOS_VERSION, 0, 0));
  15056.  }
  15057.  
  15058.  
  15059.  VF.C
  15060.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\14VIEW\VF.C
  15061.  
  15062.  /*
  15063.   *        vf -- view a file using a full-screen window onto
  15064.   *        an in-memory text file buffer
  15065.   */
  15066.  
  15067.  #include <stdio.h>
  15068.  #include <stdlib.h>
  15069.  #include <string.h>
  15070.  #include <local\std.h>
  15071.  #include <local\video.h>
  15072.  #include "vf.h"
  15073.  
  15074.  extern int setctype(int, int);
  15075.  int Startscan, Endscan;        /* cursor scan line range */
  15076.  unsigned char Attr;        /* primary display attribute */
  15077.  unsigned char Revattr;        /* reverse video for highlighting */
  15078.  unsigned char Usrattr;        /* user's original attribute */
  15079.  
  15080.  main(argc, argv)
  15081.  int argc;
  15082.  char **argv;
  15083.  {
  15084.          int ch;
  15085.          unsigned char chr;
  15086.          BOOLEAN errflag;
  15087.          BOOLEAN numbers;
  15088.          int errcode;
  15089.          FILE *fp;
  15090.          extern char *optarg;
  15091.          extern int optind;
  15092.          static char pgm[MAXNAME + 1] = { "vf" };
  15093.  
  15094.          /* function prototypes */
  15095.          void clean();
  15096.          extern clrscrn(unsigned char);
  15097.          extern void getpname(char *, char *);
  15098.          extern void fixtabs(int);
  15099.          extern void initmsg(int, int, int, unsigned char, int);
  15100.          extern int getopt(int, char **, char *);
  15101.          extern int vf_cmd(FILE *, char *, BOOLEAN);
  15102.          extern int readca(unsigned char *, unsigned char *, unsigned int);
  15103.          extern int getctype(int *, int *, int);
  15104.  
  15105.          errcode = 0;
  15106.          fixtabs(TABWIDTH);
  15107.  
  15108.          /* get program name from DOS (version 3.00 and later) */
  15109.          if (_osmajor >= 3)
  15110.                  getpname(*argv, pgm);
  15111.  
  15112.          /* be sure we have needed DOS support */
  15113.          if (_osmajor < 2) {
  15114.                  fprintf(stderr, "%s requires DOS 2.00 or later\n", pgm);
  15115.                  exit(1);
  15116.          }
  15117.  
  15118.          /* process optional arguments first */
  15119.          errflag = numbers = FALSE;
  15120.          while ((ch = getopt(argc, argv, "n")) != EOF)
  15121.                  switch (ch) {
  15122.                  case 'n':
  15123.                          /* turn on line numbering */
  15124.                          numbers = TRUE;
  15125.                          break;
  15126.                  case '?':
  15127.                          /* bad option */
  15128.                          errflag = TRUE;
  15129.                          break;
  15130.                  }
  15131.  
  15132.          /* check for command-line errors */
  15133.          argc -= optind;
  15134.          argv += optind;
  15135.          if (errflag == TRUE || argc == 0) {
  15136.                  fprintf(stderr, "Usage: %s [-n] file...\n", pgm);
  15137.                  exit(1);
  15138.          }
  15139.  
  15140.          /* get current video attribute and set VF attributes */
  15141.          getstate();
  15142.          readca(&chr, &Usrattr, Vpage);        /* save user's attribute settin
  15143.          /*
  15144.           * These colors are modified from those presented in the
  15145.           * book so that VF will work on all monochrome and
  15146.           * color systems the same way -- change them to suit
  15147.           * your own shade of reality and operating conditions
  15148.           */
  15149.          Attr = Usrattr;                        /* basic text attributes */
  15150.          /* reverse video for highlighting */
  15151.          Revattr = ((Attr & 0x7) << 4) | (Attr >> 4);
  15152.          clrscrn(Attr);
  15153.  
  15154.          /* save user's cursor shape and turn cursor off */
  15155.          getctype(&Startscan, &Endscan, Vpage);
  15156.          setctype(MAXSCAN, MAXSCAN);
  15157.  
  15158.          /* set up the message line manager */
  15159.          initmsg(MSGROW, MSGCOL, Maxcol[Vmode] - MSGCOL, Attr, Vpage);
  15160.  
  15161.          /* display first screen page */
  15162.          putcur(0, 0, Vpage);
  15163.          putstr("ViewFile/1.0  H=Help Q=Quit Esc=Next", Vpage);
  15164.          putcur(1, 0, Vpage);
  15165.          writea(Revattr, Maxcol[Vmode], Vpage);
  15166.  
  15167.          for (; argc-- > 0; ++argv) {
  15168.                  if ((fp = fopen(*argv, "r")) == NULL) {
  15169.                          fprintf(stderr, "%s: cannot open %s -- ", pgm, *argv)
  15170.                          perror("");
  15171.                          ++errcode;
  15172.                          continue;
  15173.                  }
  15174.                  if (vf_cmd(fp, *argv, numbers) != 0)
  15175.                          break;
  15176.                  fclose(fp);
  15177.          }
  15178.          clean();
  15179.          exit(errcode);
  15180.  }
  15181.  
  15182.  
  15183.  /*
  15184.   *        clean -- restore the user's original conditions
  15185.   */
  15186.  
  15187.  void
  15188.  clean()
  15189.  {
  15190.          /* set screen to user's attribute */
  15191.          clrscrn(Usrattr);
  15192.          putcur(0, 0, Vpage);
  15193.  
  15194.          /* restore user's cursor shape */
  15195.          setctype(Startscan, Endscan);
  15196.  }
  15197.  
  15198.  
  15199.  VF_CMD.C
  15200.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\14VIEW\VF_CMD.C
  15201.  
  15202.  /*
  15203.   *        vf_cmd -- ViewFile command processor
  15204.   */
  15205.  
  15206.  #include <stdio.h>
  15207.  #include <stdlib.h>
  15208.  #include <string.h>
  15209.  #include <ctype.h>
  15210.  #include <local\std.h>
  15211.  #include <local\keydefs.h>
  15212.  #include <local\video.h>
  15213.  #include "vf.h"
  15214.  #include "message.h"
  15215.  
  15216.  extern unsigned char Attr;
  15217.  
  15218.  int
  15219.  vf_cmd(fp, fname, numbers)
  15220.  FILE *fp;
  15221.  char *fname;
  15222.  BOOLEAN numbers;
  15223.  {
  15224.          register int i;                /* general index */
  15225.          unsigned int offset;        /* horizontal scroll offset */
  15226.          unsigned int n;                /* relative line number */
  15227.          int memerr;                /* flag for memory allocation errors */
  15228.          char *s, lbuf[MAXLINE];        /* input line buffer and pointer */
  15229.          int k;                        /* key code (see keydefs.h) */
  15230.          int radix = 10;                /* base for number-to-character conver
  15231.          char number[17];        /* buffer for conversions */
  15232.          int errcount = 0;        /* error counter */
  15233.          DNODE *tmp;                /* pointer to buffer control nodes */
  15234.          DIRECTION srchdir;        /* search direction */
  15235.          char *ss;                /* pointer to search string */
  15236.          static char srchstr[MAXSTR] = { "" };        /* search string buffer
  15237.          DNODE *head;                /* pointer to starting node of text buffe
  15238.          DNODE *current;                /* pointer to the current node (text l
  15239.          static DNODE *freelist;        /* pointer to starting node of "free"
  15240.                                  /* initialized to 0 at runtime; retains value
  15241.  
  15242.          /* function prototypes */
  15243.          static void prtshift(int, int);
  15244.          extern DNODE *vf_mklst();
  15245.          extern DNODE *vf_alloc(int);
  15246.          extern DNODE *vf_ins(DNODE *, DNODE *);
  15247.          extern DNODE *vf_del(DNODE *, DNODE *);
  15248.          extern DNODE *search(DNODE *, DIRECTION, char *);
  15249.          extern DNODE *gotoln(DNODE *);
  15250.          extern char *getxline(char *, int, FILE *);
  15251.          extern char *getsstr(char *);
  15252.          extern int clrscrn(unsigned char);
  15253.          extern void showhelp(unsigned char);
  15254.          extern void clrmsg();
  15255.          extern void vf_dspy(DNODE *, DNODE *, int, BOOLEAN);
  15256.          extern int putstr(char *, int);
  15257.          extern int writec(char, int, int);
  15258.          extern char *nlerase(char *);
  15259.  
  15260.          /* display the file name */
  15261.          offset = 0;
  15262.          putcur(HEADROW, 0, Vpage);
  15263.          writec(' ', Maxcol[Vmode], Vpage);
  15264.          putstr("File: ", Vpage);
  15265.          putstr(fname, Vpage);
  15266.  
  15267.          /* establish the text buffer */
  15268.          memerr = 0;
  15269.          if ((head = vf_mklst()) == NULL)
  15270.                  ++memerr;
  15271.          if (freelist == NULL && (freelist = vf_alloc(N_NODES)) == NULL)
  15272.                  ++memerr;
  15273.          if (memerr) {
  15274.                  clean();
  15275.                  fprintf(stderr, "Memory allocation error\n");
  15276.                  exit(1);
  15277.          }
  15278.  
  15279.          /* read the file into the buffer */
  15280.          current = head;
  15281.          n = 0;
  15282.          while ((s = getxline(lbuf, MAXLINE, fp)) != NULL) {
  15283.                  /* add a node to the list */
  15284.                  if ((freelist = vf_ins(current, freelist)) == NULL)
  15285.                          ++memerr;
  15286.                  current = current->d_next;
  15287.  
  15288.                  /* save the received text in a line buffer */
  15289.                  if ((current->d_line = strdup(nlerase(s))) == NULL)
  15290.                          ++memerr;
  15291.                  if (memerr) {
  15292.                          clean();
  15293.                          fprintf(stderr, "File too big to load\n");
  15294.                          exit(1);
  15295.                  }
  15296.                  current->d_lnum = ++n;
  15297.                  current->d_flags = 0;
  15298.          }
  15299.  
  15300.          /* show the file size as a count of lines */
  15301.          putstr(" (", Vpage);
  15302.          putstr(itoa(current->d_lnum, number, radix), Vpage);
  15303.          putstr(" lines)", Vpage);
  15304.          prtshift(offset, Vpage);
  15305.          current = head->d_next;
  15306.          vf_dspy(head, current, offset, numbers);
  15307.  
  15308.          /* process user commands */
  15309.          while ((k = getkey()) != K_ESC) {
  15310.                  clrmsg();
  15311.                  switch (k) {
  15312.                  case 'b':
  15313.                  case 'B':
  15314.                  case K_HOME:
  15315.                          current = head->d_next;
  15316.                          break;
  15317.                  case 'e':
  15318.                  case 'E':
  15319.                  case K_END:
  15320.                          current = head->d_prev;
  15321.                          i = NROWS - 1;
  15322.                          while (i-- > 0)
  15323.                                  if (current->d_prev != head->d_next)
  15324.                                          current = current->d_prev;
  15325.                          break;
  15326.                  case K_PGUP:
  15327.                  case 'u':
  15328.                  case 'U':
  15329.                          i = NROWS - OVERLAP;
  15330.                          while (i-- > 0)
  15331.                                  if (current != head->d_next)
  15332.                                          current = current->d_prev;
  15333.                          break;
  15334.                  case K_PGDN:
  15335.                  case 'd':
  15336.                  case 'D':
  15337.                          i = NROWS - OVERLAP;
  15338.                          while (i-- > 0)
  15339.                                  if (current != head->d_prev)
  15340.                                          current = current->d_next;
  15341.                          break;
  15342.                  case K_UP:
  15343.                  case '-':
  15344.                          if (current == head->d_next)
  15345.                                  continue;
  15346.                          current = current->d_prev;
  15347.                          break;
  15348.                  case K_DOWN:
  15349.                  case '+':
  15350.                          if (current == head->d_prev)
  15351.                                  continue;
  15352.                          current = current->d_next;
  15353.                          break;
  15354.                  case K_RIGHT:
  15355.                  case '>':
  15356.                  case '.':
  15357.                          if (offset < MAXLINE - SHIFTWIDTH)
  15358.                                  offset += SHIFTWIDTH;
  15359.                          prtshift(offset, Vpage);
  15360.                          break;
  15361.                  case K_LEFT:
  15362.                  case '<':
  15363.                  case ',':
  15364.                          if ((offset -= SHIFTWIDTH) < 0)
  15365.                                  offset = 0;
  15366.                          prtshift(offset, Vpage);
  15367.                          break;
  15368.                  case K_ALTG:
  15369.                  case 'g':
  15370.                  case 'G':
  15371.                          if ((tmp = gotoln(head)) == NULL)
  15372.                                  continue;
  15373.                          current = tmp;
  15374.                          break;
  15375.                  case K_ALTH:
  15376.                  case 'h':
  15377.                  case 'H':
  15378.                  case '?':
  15379.                          showhelp(Attr);
  15380.                          break;
  15381.                  case K_ALTN:
  15382.                  case 'n':
  15383.                  case 'N':
  15384.                          numbers = (numbers == TRUE) ? FALSE : TRUE;
  15385.                          break;
  15386.                  case K_ALTQ:
  15387.                  case 'q':
  15388.                  case 'Q':
  15389.                          clrscrn(Attr);
  15390.                          putcur(0, 0, Vpage);
  15391.                          return (-1);
  15392.                  case 'r':
  15393.                  case 'R':
  15394.                  case '\\':
  15395.                          srchdir = BACKWARD;
  15396.                          ss = getsstr(srchstr);
  15397.                          if (ss == NULL)
  15398.                                  /* cancel search */
  15399.                                  break;
  15400.                          if (strlen(ss) > 0)
  15401.                                  strcpy(srchstr, ss);
  15402.                          if ((tmp = search(current, srchdir, srchstr)) == NULL
  15403.                                  continue;
  15404.                          current = tmp;
  15405.                          break;
  15406.                  case 's':
  15407.                  case 'S':
  15408.                  case '/':
  15409.                          srchdir = FORWARD;
  15410.                          ss = getsstr(srchstr);
  15411.                          if (ss == NULL)
  15412.                                  /* cancel search */
  15413.                                  break;
  15414.                          if (strlen(ss) > 0)
  15415.                                  strcpy(srchstr, ss);
  15416.                          if ((tmp = search(current, srchdir, srchstr)) == NULL
  15417.                                  continue;
  15418.                          current = tmp;
  15419.                          break;
  15420.                  default:
  15421.                          /* ignore all other keys */
  15422.                          continue;
  15423.                  }
  15424.                  vf_dspy(head, current, offset, numbers);
  15425.          }
  15426.          clrmsg();
  15427.  
  15428.          /* release the allocated text buffer memory */
  15429.          while (head->d_next != head) {
  15430.                  /* release text buffer */
  15431.                  free(head->d_next->d_line);
  15432.  
  15433.                  /* put node back on the freelist */
  15434.                  freelist = vf_del(head->d_next, freelist);
  15435.          }
  15436.          /* release the list header node */
  15437.          free((char *)head);
  15438.  
  15439.          return (errcount);
  15440.  }
  15441.  
  15442.  /*
  15443.   *        prtshift -- display the number of columns of horizontal shift
  15444.   */
  15445.  
  15446.  #define SHFTDSP        5
  15447.  
  15448.  static void
  15449.  prtshift(amt, pg)
  15450.  int amt, pg;
  15451.  {
  15452.          char number[17];
  15453.          int radix = 10;
  15454.  
  15455.          /* clear the shift display area */
  15456.          putcur(1, Maxcol[Vmode] - 1 - SHFTDSP, pg);
  15457.          writec(' ', SHFTDSP, pg);
  15458.  
  15459.          /* display the new shift amount, if any */
  15460.          if (amt > 0) {
  15461.                  putstr(itoa(amt, number, radix), pg);
  15462.                  putstr("->", pg);
  15463.          }
  15464.  }
  15465.  
  15466.  
  15467.  VF_DSPY.C
  15468.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\14VIEW\VF_DSPY.C
  15469.  
  15470.  /*
  15471.   *        vf_dspy -- display a screen page
  15472.   */
  15473.  
  15474.  #include <stdio.h>
  15475.  #include <stdlib.h>
  15476.  #include <string.h>
  15477.  #include <ctype.h>
  15478.  #include <local\video.h>
  15479.  #include <local\std.h>
  15480.  #include <local\bioslib.h>
  15481.  #include "vf.h"
  15482.  
  15483.  /* number field width */
  15484.  #define NFW        8
  15485.  
  15486.  void
  15487.  vf_dspy(buf, lp, os, numbers)
  15488.  DNODE *buf;
  15489.  register DNODE *lp;
  15490.  int os;
  15491.  BOOLEAN numbers;
  15492.  {
  15493.          register int i;
  15494.          int j;
  15495.          int textwidth;
  15496.          char *cp;
  15497.          char nbuf[NFW + 1];
  15498.  
  15499.          textwidth = Maxcol[Vmode];
  15500.          if (numbers == TRUE)
  15501.                  textwidth -= NFW;
  15502.  
  15503.          for (i = 0; i < NROWS; ++i) {
  15504.                  putcur(TOPROW + i, 0, Vpage);
  15505.                  cp = lp->d_line;
  15506.                  if (numbers == TRUE) {
  15507.                          sprintf(nbuf, "%6u", lp->d_lnum);
  15508.                          putfld(nbuf, NFW, Vpage);
  15509.                          putcur(TOPROW + i, NFW, Vpage);
  15510.                  }
  15511.                  if (os < strlen(cp))
  15512.                          putfld(cp + os, textwidth, Vpage);
  15513.                  else
  15514.                          writec(' ', textwidth, Vpage);
  15515.                  if (lp == buf->d_prev) {
  15516.                          ++i;
  15517.                          break;        /* no more displayable lines */
  15518.                  }
  15519.                  else
  15520.                          lp = lp->d_next;
  15521.          }
  15522.  
  15523.          /* clear and mark any unused lines */
  15524.          for ( ; i < NROWS; ++i) {
  15525.                  putcur(i + TOPROW, 0, Vpage);
  15526.                  writec(' ', Maxcol[Vmode], Vpage);
  15527.                  writec('~', 1, Vpage);
  15528.          }
  15529.          return;
  15530.  }
  15531.  
  15532.  
  15533.  VF_LIST.C
  15534.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\14VIEW\VF_LIST.C
  15535.  
  15536.  /*
  15537.   *        vf_list -- linked list management functions
  15538.   */
  15539.  
  15540.  #include <stdio.h>
  15541.  #include <malloc.h>
  15542.  #include "vf.h"
  15543.  
  15544.  /*
  15545.   *        vf_mklst -- create a new list by allocating a node,
  15546.   *        making it point to itself, and setting its values
  15547.   *        to zero (appropriately cast)
  15548.   */
  15549.  
  15550.  DNODE *
  15551.  vf_mklst()
  15552.  {
  15553.          DNODE *new;
  15554.  
  15555.          new = (DNODE *)malloc(sizeof (DNODE));
  15556.          if (new != NULL) {
  15557.                  new->d_next = new;
  15558.                  new->d_prev = new;
  15559.                  new->d_lnum = new->d_flags = 0;
  15560.                  new->d_line = (char *)NULL;
  15561.          }
  15562.          return (new);
  15563.  } /* end vf_mklst() */
  15564.  
  15565.  
  15566.  /*
  15567.   *        vf_alloc -- create a pool of available nodes
  15568.   */
  15569.  
  15570.  DNODE *
  15571.  vf_alloc(n)
  15572.  int n;
  15573.  {
  15574.          register DNODE *new;
  15575.          register DNODE *tmp;
  15576.  
  15577.          /* allocate a block of n nodes */
  15578.          new = (DNODE *)malloc(n * sizeof (DNODE));
  15579.  
  15580.          /* if allocation OK, string the nodes in one direction */
  15581.          if (new != NULL) {
  15582.                  for (tmp = new; 1 + tmp - new < n; tmp = tmp->d_next)
  15583.                          tmp->d_next = tmp + 1;
  15584.                  tmp->d_next = (DNODE *)NULL;
  15585.          }
  15586.  
  15587.          return (new);        /* pointer to free list */
  15588.  } /* end vf_alloc() */
  15589.  
  15590.  
  15591.  /*
  15592.   *        vf_ins -- insert a node into a list after the specified node
  15593.   */
  15594.  
  15595.  DNODE *
  15596.  vf_ins(node, avail)
  15597.  DNODE *node, *avail;
  15598.  {
  15599.          DNODE *tmp;
  15600.          DNODE *vf_alloc(int);
  15601.  
  15602.          /*
  15603.           *  check freelist -- get another block of nodes
  15604.           *  if the list is almost empty
  15605.           */
  15606.          if (avail->d_next == NULL)
  15607.                  if ((avail->d_next = vf_alloc(N_NODES)) == NULL)
  15608.                          /* not enough memory */
  15609.                          return (DNODE *)NULL;
  15610.  
  15611.          /* get a node from the freelist */
  15612.          tmp = avail;
  15613.          avail = avail->d_next;
  15614.  
  15615.          /* insert the node into the list after node */
  15616.          tmp->d_prev = node;
  15617.          tmp->d_next = node->d_next;
  15618.          node->d_next->d_prev = tmp;
  15619.          node->d_next = tmp;
  15620.  
  15621.          /* point to next node in the freelist */
  15622.          return (avail);
  15623.  } /* end vf_ins() */
  15624.  
  15625.  
  15626.  /*
  15627.   *        vf_del -- delete a node from a list
  15628.   */
  15629.  
  15630.  DNODE *
  15631.  vf_del(node, avail)
  15632.  DNODE *node, *avail;
  15633.  {
  15634.          /* unlink the node from the list */
  15635.          node->d_prev->d_next = node->d_next;
  15636.          node->d_next->d_prev = node->d_prev;
  15637.  
  15638.          /* return the deleted node to the freelist */
  15639.          node->d_next = avail;
  15640.          avail = node;
  15641.  
  15642.          /* point to the new freelist node */
  15643.          return (avail);
  15644.  } /* end vf_del() */
  15645.  
  15646.  
  15647.  VF_SRCH.C
  15648.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\14VIEW\VF_SRCH.C
  15649.  
  15650.  /*
  15651.   *        vf_srch -- search functions
  15652.   */
  15653.  
  15654.  #include <stdio.h>
  15655.  #include <stdlib.h>
  15656.  #include <string.h>
  15657.  #include <local\std.h>
  15658.  #include "vf.h"
  15659.  
  15660.  /*
  15661.   *        search -- search for a literal string in the buffer
  15662.   */
  15663.  
  15664.  DNODE *
  15665.  search(buf, dir, str)
  15666.  DNODE *buf;
  15667.  DIRECTION dir;
  15668.  char *str;
  15669.  {
  15670.          int n;
  15671.          register DNODE *lp;
  15672.          register char *cp;
  15673.  
  15674.          extern void showmsg(char *);
  15675.  
  15676.          /* try to find a match -- wraps around buffer boundaries */
  15677.          n = strlen(str);
  15678.          lp = (dir == FORWARD) ? buf->d_next : buf->d_prev;
  15679.          while (lp != buf) {
  15680.                  if ((cp = lp->d_line) != NULL)        /* skip over header nod
  15681.                          while (*cp != '\n' && *cp != '\0') {
  15682.                                  if (strncmp(cp, str, n) == 0)
  15683.                                          return (lp);
  15684.                                  ++cp;
  15685.                          }
  15686.                  lp = (dir == FORWARD) ? lp->d_next : lp->d_prev;
  15687.          }
  15688.          showmsg("Not found");
  15689.          return ((DNODE *)NULL);
  15690.  }
  15691.  
  15692.  
  15693.  /*
  15694.   *        getsstr -- prompt the user for a search string
  15695.   */
  15696.  
  15697.  extern int Startscan, Endscan;
  15698.  
  15699.  char *
  15700.  getsstr(str)
  15701.  char *str;
  15702.  {
  15703.          char line[MAXSTR];
  15704.          char *resp;
  15705.  
  15706.          extern int putstr(char *, int);
  15707.          extern char *getstr(char *, int);
  15708.          extern int put_ch(char, int);
  15709.          extern void showmsg(char *);
  15710.          extern void clrmsg();
  15711.  
  15712.          static char prompt[] = { "Search for: " };
  15713.  
  15714.          /* get search string */
  15715.          showmsg(prompt);
  15716.          setctype(Startscan, Endscan);                /* cursor on */
  15717.          resp = getstr(line, MAXSTR - strlen(prompt));
  15718.          setctype(MAXSCAN, MAXSCAN);                /* cursor off */
  15719.          if (resp == NULL)
  15720.                  return (char *)NULL;
  15721.          if (strlen(resp) == 0)
  15722.                  return (str);
  15723.          showmsg(resp);
  15724.          return (resp);
  15725.  }
  15726.  
  15727.  
  15728.  VF_UTIL.C
  15729.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\14VIEW\VF_UTIL.C
  15730.  
  15731.  /*
  15732.   *        vf_util -- utility functions for ViewFile
  15733.   */
  15734.  
  15735.  #include <stdio.h>
  15736.  #include <stdlib.h>
  15737.  #include <string.h>
  15738.  #include <local\std.h>
  15739.  #include <local\video.h>
  15740.  #include <local\keydefs.h>
  15741.  #include "vf.h"
  15742.  
  15743.  extern int Startscan, Endscan;
  15744.  
  15745.  #define NDIGITS        6
  15746.  
  15747.  /*
  15748.   *        gotoln -- jump to an absolute line number
  15749.   */
  15750.  
  15751.  DNODE *
  15752.  gotoln(buf)
  15753.  DNODE *buf;
  15754.  {
  15755.          register int ln;
  15756.          register DNODE *lp;
  15757.          char line[NDIGITS + 1];
  15758.  
  15759.          extern void showmsg(char *);
  15760.          extern char *getstr(char *, int);
  15761.  
  15762.          /* get line number from user */
  15763.          showmsg("Line number: ");
  15764.          setctype(Startscan, Endscan);                        /* cursor on */
  15765.          ln = atoi(getstr(line, NDIGITS + 1));
  15766.          setctype(MAXSCAN, MAXSCAN);                        /* cursor off */
  15767.  
  15768.          /* check boundary conditions */
  15769.          if (ln > buf->d_prev->d_lnum || ln <= 0) {
  15770.                  showmsg("Line out of range");
  15771.                  return ((DNODE *)NULL);
  15772.          }
  15773.  
  15774.          /* find the line */
  15775.          for (lp = buf->d_next; ln != lp->d_lnum; lp = lp->d_next)
  15776.                  ;
  15777.          return (lp);
  15778.  }
  15779.  
  15780.  
  15781.  /*
  15782.   *        showhelp -- display a help frame
  15783.   */
  15784.  
  15785.  #define HELPROW        TOPROW + 3
  15786.  #define HELPCOL        10
  15787.  #define VBORDER        1
  15788.  #define HBORDER        2
  15789.  
  15790.  void
  15791.  showhelp(textattr)
  15792.  unsigned char textattr;        /* attribute of text area */
  15793.  {
  15794.          register int i, n;
  15795.          int nlines, ncols;
  15796.          unsigned char helpattr;
  15797.          static char *help[] = {
  15798.                  "PgUp (U)        Scroll up the file one screen page",
  15799.                  "PgDn (D)        Scroll down the file one screen page",
  15800.                  "Up arrow (-)    Scroll up in the file one line",
  15801.                  "Down arrow (+)  Scroll down in the file one line",
  15802.                  "Right arrow (>) Scroll right by 20 columns",
  15803.                  "Left arrow (<)  Scroll left by 20 columns",
  15804.                  "Home (B)        Go to beginning of file buffer",
  15805.                  "End (E)         Go to end of file buffer",
  15806.                  "Alt-g (G)       Go to a specified line in the buffer",
  15807.                  "Alt-h (H or ?)  Display this help frame",
  15808.                  "Alt-n (N)       Toggle line-numbering feature",
  15809.                  "\\ (R)           Reverse search for a literal text string",
  15810.                  "/ (S)           Search forward for a literal text string",
  15811.                  "Esc             Next file from list (quits if none)",
  15812.                  "Alt-q (Q)       Quit",
  15813.                  "--------------------------------------------------------",
  15814.                  "            << Press a key to continue >>",
  15815.                  (char *)NULL
  15816.          };
  15817.  
  15818.          /* prepare help window */
  15819.          ncols = 0;
  15820.          for (i = 0; help[i] != (char *)NULL; ++i)
  15821.                  if ((n = strlen(help[i])) > ncols)
  15822.                          ncols = n;
  15823.          nlines = i - 1;
  15824.          --ncols;
  15825.          helpattr = (RED << 4) | BWHT;
  15826.          clrw(HELPROW - VBORDER, HELPCOL - HBORDER,
  15827.                  HELPROW + nlines + VBORDER, HELPCOL + ncols + HBORDER,
  15828.                  helpattr);
  15829.          drawbox(HELPROW - VBORDER, HELPCOL - HBORDER,
  15830.                  HELPROW + nlines + VBORDER, HELPCOL + ncols + HBORDER,
  15831.                  Vpage);
  15832.  
  15833.          /* display the help text */
  15834.          for (i = 0; help[i] != (char *)NULL; ++i) {
  15835.                  putcur(HELPROW + i, HELPCOL, Vpage);
  15836.                  putstr(help[i], Vpage);
  15837.          }
  15838.  
  15839.          /* pause until told by a keypress to proceed */
  15840.          getkey();
  15841.  
  15842.          /* restore help display area to the text attribute */
  15843.          clrw(HELPROW - VBORDER, HELPCOL - HBORDER,
  15844.                  HELPROW + nlines + VBORDER, HELPCOL + ncols + HBORDER,
  15845.                  textattr);
  15846.  }
  15847.  
  15848.  
  15849.  WARN.C
  15850.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\UTIL\WARN.C
  15851.  
  15852.  /*
  15853.   *        warn -- display a warning message in a highly
  15854.   *        visible place; return number of characters written
  15855.   */
  15856.  
  15857.  #include <stdio.h>
  15858.  
  15859.  int
  15860.  warn(pname, mesg)
  15861.  char *pname, *mesg;
  15862.  {
  15863.          return (fprintf(stderr, "%s: %s\n", pname, mesg));
  15864.  }
  15865.  
  15866.  
  15867.  WRITEA.C
  15868.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\WRITEA.C
  15869.  
  15870.  /*
  15871.   *        writea -- write attribute only to screen memory (faked by
  15872.   *        reading char and attr and writing back the original
  15873.   *        character and the new attribute at each position)
  15874.   */
  15875.  
  15876.  #include <local\std.h>
  15877.  
  15878.  int writea(a, n, pg)
  15879.  unsigned char a;/* video attribute */
  15880.  int n;                /* number of positions to write */
  15881.  int pg;                /* screen page */
  15882.  {
  15883.          int i;
  15884.          int status;
  15885.          unsigned short chx, attrx;
  15886.          unsigned short r, c;
  15887.  
  15888.          /* get starting (current) position */
  15889.          status = 0;
  15890.          status = readcur(&r, &c, pg);
  15891.          for (i = 0; i < n; ++i) {
  15892.                  status += putcur(r, c + i, pg);
  15893.                  status += readca(&chx, &attrx, pg);
  15894.                  status += writeca(chx, a, 1, pg);
  15895.          }
  15896.  
  15897.          /* restore cursor position */
  15898.          status += putcur(r, c, pg);
  15899.  
  15900.          return (status);
  15901.  }
  15902.  
  15903.  
  15904.  WRITEC.C
  15905.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\WRITEC.C
  15906.  
  15907.  /*
  15908.   *        writec -- write a character only
  15909.   *        (leave attribute undisturbed)
  15910.   */
  15911.  
  15912.  #include <dos.h>
  15913.  #include <local\std.h>
  15914.  #include <local\bioslib.h>
  15915.  
  15916.  int
  15917.  writec(ch, count, pg)
  15918.  unsigned char ch;        /* character */
  15919.  int count;                /* repetitions */
  15920.  int pg;                        /* screen page for writes */
  15921.  {
  15922.          union REGS inregs, outregs;
  15923.  
  15924.          inregs.h.ah = WRITE_CHAR;
  15925.          inregs.h.al = ch;
  15926.          inregs.h.bh = pg;
  15927.          inregs.x.cx = count;
  15928.          int86(VIDEO_IO, &inregs, &outregs);
  15929.  
  15930.          return (outregs.x.cflag);
  15931.  }
  15932.  
  15933.  
  15934.  WRITECA.C
  15935.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\WRITECA.C
  15936.  
  15937.  /*
  15938.   *        writeca -- write character and attribute to the screen
  15939.   */
  15940.  
  15941.  #include <dos.h>
  15942.  #include <local\std.h>
  15943.  #include <local\bioslib.h>
  15944.  
  15945.  int
  15946.  writeca(ch, attr, count, pg)
  15947.  unsigned char ch;        /* character */
  15948.  unsigned char attr;        /* attribute */
  15949.  int count;                /* number of repetitions */
  15950.  int pg;                        /* screen page for writes */
  15951.  {
  15952.          union REGS inregs, outregs;
  15953.  
  15954.          inregs.h.ah = WRITE_CHAR_ATTR;
  15955.          inregs.h.al = ch;
  15956.          inregs.h.bh = pg;
  15957.          inregs.h.bl = attr;
  15958.          inregs.x.cx = count;
  15959.          int86(VIDEO_IO, &inregs, &outregs);
  15960.  
  15961.          return (outregs.x.cflag);
  15962.  }
  15963.  
  15964.  
  15965.  WRITEDOT.C
  15966.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\WRITEDOT.C
  15967.  
  15968.  /*
  15969.   *        writedot -- display a dot at the specified position
  15970.   */
  15971.  
  15972.  #include <dos.h>
  15973.  #include <local\std.h>
  15974.  #include <local\bioslib.h>
  15975.  
  15976.  int
  15977.  writedot(r, c, color)
  15978.  int r, c;        /* row and column cordinate */
  15979.  int color;        /* dot (pixel) color */
  15980.  {
  15981.          union REGS inregs, outregs;
  15982.  
  15983.          inregs.h.ah = WRITE_DOT;
  15984.          inregs.h.al = color;
  15985.          inregs.x.cx = c;
  15986.          inregs.x.dx = r;
  15987.          int86(VIDEO_IO, &inregs, &outregs);
  15988.  
  15989.          return (outregs.x.cflag);
  15990.  }
  15991.  
  15992.  
  15993.  WRITEMSG.C
  15994.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\WRITEMSG.C
  15995.  
  15996.  /*
  15997.   *        writemsg -- displays a message in a field of the prevailing
  15998.   *        video attribute and returns the number of displayable message
  15999.   *        characters written; truncates the message if its too long
  16000.   *        to fit in the field
  16001.   */
  16002.  
  16003.  #include <stdio.h>
  16004.  #include <local\std.h>
  16005.  
  16006.  int writemsg(r, c, w, s1, s2, pg)
  16007.  int r, c, w ;
  16008.  char *s1, *s2;
  16009.  int pg;
  16010.  {
  16011.          int n = 0;
  16012.          char *cp;
  16013.  
  16014.          /* display first part of the message */
  16015.          if (s1 != NULL)
  16016.                  for (cp = s1; *cp != '\0' && n < w; ++n, ++cp) {
  16017.                          putcur(r, c + n, pg);
  16018.                          writec(*cp, 1, pg);
  16019.                  }
  16020.  
  16021.          /* display second part of the message */
  16022.          if (s2 != NULL)
  16023.                  for (cp = s2; *cp != '\0' && n < w; ++n, ++cp) {
  16024.                          putcur(r, c + n, pg);
  16025.                          writec(*cp, 1, pg);
  16026.                  }
  16027.  
  16028.          /* pad the remainder of the field, if any, with spaces */
  16029.          if (n < w) {
  16030.                  putcur(r, c + n, pg);
  16031.                  writec(' ', w - n, pg);
  16032.          }
  16033.  
  16034.          return (n);
  16035.  }
  16036.  
  16037.  
  16038.  WRITESTR.C
  16039.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\WRITESTR.C
  16040.  
  16041.  /*
  16042.   *        writestr -- write a string in
  16043.   *        the prevailing video attribute
  16044.   */
  16045.  
  16046.  #include <local\std.h>
  16047.  
  16048.  int
  16049.  writestr(s, pg)
  16050.  register char *s;        /* string to write */
  16051.  unsigned int pg;        /* screen page for writes */
  16052.  {
  16053.          unsigned int r, c, c0;
  16054.  
  16055.          readcur(&r, &c, pg);
  16056.          for (c0 = c; *s != '\0'; ++s, ++c) {
  16057.                  putcur(r, c, pg);
  16058.                  writec(*s, 1, pg);
  16059.          }
  16060.  
  16061.          /* restore cursor position and return # of characters displayed */
  16062.          putcur(r, c0, pg);
  16063.          return (c - c0);
  16064.  }
  16065.  
  16066.  
  16067.  WRITETTY.C
  16068.  CD-ROM Disc Path:   \SAMPCODE\PROF_C\05OSLIB\BIOS\WRITETTY.C
  16069.  
  16070.  /*
  16071.   *        writetty -- write to screen using TTY interface
  16072.   */
  16073.  
  16074.  #include <dos.h>
  16075.  #include <local\std.h>
  16076.  #include <local\bioslib.h>
  16077.  
  16078.  int
  16079.  writetty(ch, attr, pg)
  16080.  unsigned char ch;        /* character */
  16081.  unsigned char attr;        /* video attribute */
  16082.  int pg;                        /* screen page for writes */
  16083.  {
  16084.          union REGS inregs, outregs;
  16085.  
  16086.          inregs.h.ah = WRITE_TTY;
  16087.          inregs.h.al = ch;
  16088.          inregs.h.bl = attr;
  16089.          inregs.h.bh = pg;
  16090.          int86(VIDEO_IO, &inregs, &outregs);
  16091.  
  16092.          return (outregs.x.cflag);
  16093.  }
  16094.  Quick-C Programming - Sample Code
  16095.  
  16096.  
  16097.  12_10A.C
  16098.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\12_10A.C
  16099.  
  16100.  #include "texed.h"
  16101.  menu()
  16102.  {
  16103.      struct key_struct *kp, *Read_kbd();
  16104.      int cur_key, cur_move;
  16105.  
  16106.      kp = Read_kbd();
  16107.      cur_key = kp->key;
  16108.      cur_move = kp->move;
  16109.      if (cur_key == ERROR)
  16110.          return (cur_move);
  16111.      return (cur_key);
  16112.  }
  16113.  
  16114.  
  16115.  12_10B.C
  16116.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\12_10B.C
  16117.  
  16118.  #include "texed.h"
  16119.  struct key_struct *Read_key()
  16120.  {
  16121.      struct key_struct k;
  16122.  
  16123.      k.key = getch();
  16124.      if (k.key == ERROR)
  16125.      k.move = getch();
  16126.          return (&k);
  16127.  }
  16128.  
  16129.  
  16130.  12_8A.C
  16131.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\12_8A.C
  16132.  
  16133.  #define OK 1
  16134.  #define ERROR 0
  16135.  menu()
  16136.  {
  16137.      struct key_struct {
  16138.          char key;
  16139.          unsigned char move;
  16140.      } *kp, *Read_kbd();
  16141.      int cur_key, cur_move;
  16142.  
  16143.      kp = Read_kbd();
  16144.      cur_key = kp->key;
  16145.      cur_move = kp->move;
  16146.      if (cur_key == ERROR)
  16147.          return (cur_move);
  16148.      return (cur_key);
  16149.  }
  16150.  
  16151.  
  16152.  12_8B.C
  16153.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\12_8B.C
  16154.  
  16155.  #define OK 1
  16156.  #define ERROR 0
  16157.  struct key_struct {
  16158.      char key;
  16159.      unsigned char move;
  16160.  };
  16161.  
  16162.  struct key_struct *Read_key()
  16163.  {
  16164.      struct key_struct k;
  16165.  
  16166.      k.key = getch();
  16167.      if (k.key == ERROR)
  16168.          k.move = getch();
  16169.      return (&k);
  16170.  }
  16171.  
  16172.  
  16173.  ACME.C
  16174.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\ACME.C
  16175.  
  16176.  /* acme.c  --     illustrate an assortment of the     */
  16177.  /*                C library string-handling routines  */
  16178.  
  16179.  <stdio.h>         /* for NULL */
  16180.  <string.h>        /* for strchr(), et al */
  16181.  
  16182.  #define NAME_PATTERN \
  16183.  "first<space>last  or\n\
  16184.  first<space>middle<space>last"
  16185.  
  16186.  #define ADDRESS_PATTERN \
  16187.  "number<space>street<comma><space>city<comma>"
  16188.  
  16189.  char Buf[BUFSIZ];        /* global I/O buffer */
  16190.  
  16191.  main()
  16192.  {
  16193.      char *ocp, *cp, *first, *last, *street, *city;
  16194.      void Prompt(), Cant();
  16195.  
  16196.      printf("Acme Employment Questionaire\n");
  16197.  
  16198.      /*
  16199.       * Expect first<space>last or
  16200.       *        first<space>middle<space>last
  16201.       */
  16202.      Prompt("Full Name");
  16203.       /* search forward for a space */
  16204.      if ((cp = strchr(Buf,' ')) == NULL)
  16205.          Cant("First Name", NAME_PATTERN);
  16206.      *cp = '\0';
  16207.      first = strdup(Buf);
  16208.      *cp = ' ';
  16209.  
  16210.       /* Search back from end for a space */
  16211.      if ((cp = strrchr(Buf,' ')) == NULL)
  16212.          Cant("Last Name", NAME_PATTERN);
  16213.      last = strdup(++cp);
  16214.  
  16215.      /*
  16216.       * Expect number<space>street<comma><space>city<comma>
  16217.       */
  16218.      Prompt("Full Address");
  16219.       /* search forward for a comma */
  16220.      if ((cp = strchr(Buf,',')) == NULL)
  16221.          Cant("Street", ADDRESS_PATTERN);
  16222.      *cp = '\0';
  16223.      street = strdup(Buf);
  16224.  
  16225.       /* Search forward from last comma for next comma */
  16226.      if ((ocp = strchr(++cp,',')) == NULL)
  16227.          Cant("City", ADDRESS_PATTERN);
  16228.      *ocp = '\0';
  16229.      city = strdup(++cp);
  16230.  
  16231.      printf("\n\nYou Entered:\n");
  16232.      printf("\tFirst Name: \"%s\"\n", first);
  16233.      printf("\tLast Name:  \"%s\"\n", last);
  16234.      printf("\tStreet:     \"%s\"\n", street);
  16235.      printf("\tCity:       \"%s\"\n", city);
  16236.  
  16237.  }
  16238.  
  16239.  void Cant(char *what, char *pattern)
  16240.  {
  16241.      printf("\n\n\bFormat Error!!!\n");
  16242.      printf("Can't parse your %s.\n", what );
  16243.      printf("Expected an entry of the form:\n\n");
  16244.      printf("%s\n\nAborted\n", pattern);
  16245.      exit(1);
  16246.  }
  16247.  
  16248.  void Prompt(char *str)
  16249.  {
  16250.      while (1)
  16251.          {
  16252.          printf("\n%s: ", str );
  16253.          if (gets(Buf) == NULL || *Buf == '\0')
  16254.              {
  16255.              printf("Do you wish to quit? ");
  16256.              if (gets(Buf) == NULL || *Buf == 'y')
  16257.                  exit (0);
  16258.              continue;
  16259.              }
  16260.          break;
  16261.          }
  16262.  }
  16263.  
  16264.  
  16265.  ALERT.C
  16266.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\ALERT.C
  16267.  
  16268.  /* alert.c -- sounds alarm by calling a        */
  16269.  /*            beep() function with a parameter */
  16270.  
  16271.  main()
  16272.  {
  16273.      void beep(times);  /* function declaration */
  16274.      printf("*** Alert! Alert! ***\n");
  16275.      beep(3);     /* call beep() with parameter */
  16276.  }
  16277.  
  16278.  void beep(times)
  16279.      int times;   /* declare function parameter */
  16280.  {
  16281.      int count;
  16282.  
  16283.      /* check that parameter is between 1 and 4 */
  16284.      if ((times < 1) || (times > 4))
  16285.          {
  16286.          printf("Error in beep(): %d beeps specified.\n",
  16287.                  times);
  16288.          printf("Specify one to four beeps");
  16289.          }
  16290.      else /* sound the beeps */
  16291.          for (count = 1; count <= times; count++)
  16292.              printf("\a");  /* "alert" escape sequence */
  16293.  }
  16294.  
  16295.  
  16296.  ALLCOLOR.C
  16297.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\ALLCOLOR.C
  16298.  
  16299.  /* allcolor.c -- shows _ERESCOLOR 64-color palette     */
  16300.  /* If you load graphics.qlb, no program list is needed.*/
  16301.  
  16302.  /*  Hit <g> to advance left palette, <G> to go back.   */
  16303.  /*  Hit <h> to advance right palette, <H> to go back.  */
  16304.  /*  Hit <Esc> to quit                                  */
  16305.  #include <stdio.h>
  16306.  #include <graph.h>
  16307.  #include <conio.h>
  16308.  #define MAXCOLORS 64
  16309.  #define ESC '\033'
  16310.  long Ega_to_vga(int);   /* color value conversion */
  16311.  
  16312.  main(argc, argv)
  16313.  int argc;
  16314.  char *argv[];
  16315.  {
  16316.      struct videoconfig vc;
  16317.      int mode = _ERESCOLOR;
  16318.      int xmax, ymax;
  16319.      int c1 = 1;
  16320.      int c2 = 4;
  16321.      char left[11];
  16322.      char right[11];
  16323.      int lpos, rpos;
  16324.      char ch;
  16325.  
  16326.      if (argc > 1)
  16327.          mode = atoi(argv[1]);
  16328.      if (_setvideomode(mode) == 0)
  16329.      {
  16330.          fprintf(stderr,"%d mode not supported\n", mode);
  16331.          exit(1);
  16332.      }
  16333.      _getvideoconfig(&vc);
  16334.      _setlogorg(vc.numxpixels/2, vc.numypixels/2);
  16335.  
  16336.      xmax = vc.numxpixels / 2 - 1;
  16337.      ymax = vc.numypixels / 2 - 1;
  16338.      lpos = vc.numxpixels/32 - 5;
  16339.      rpos = lpos + vc.numxpixels / 16;
  16340.      _setcolor(1);
  16341.      _rectangle(_GFILLINTERIOR, -xmax, -ymax, 0, ymax);
  16342.      _setcolor(4);
  16343.      _rectangle(_GFILLINTERIOR, 1, -ymax, xmax, ymax);
  16344.      sprintf(left,"<-G %2d g->", c1);
  16345.      sprintf(right,"<-H %2d h->", c2);
  16346.      _settextcolor(6);
  16347.      _settextposition(0, 0);
  16348.      _outtext("Press Esc to quit");
  16349.      _settextposition(24, lpos);
  16350.      _outtext(left);
  16351.      _settextposition(24, rpos);
  16352.      _outtext(right);
  16353.      while ((ch = getch()) != ESC)
  16354.      {
  16355.          switch (ch)
  16356.          {
  16357.              case 'g': c1 = (c1 + 1) % MAXCOLORS;
  16358.                        _remappalette(1, Ega_to_vga(c1));
  16359.                        break;
  16360.              case 'G': c1 = (c1 - 1) % MAXCOLORS;
  16361.                        _remappalette(1, Ega_to_vga(c1));
  16362.                        break;
  16363.              case 'h': c2 = (c2 + 1) % MAXCOLORS;
  16364.                        _remappalette(4, Ega_to_vga(c2));
  16365.                        break;
  16366.              case 'H': c2 = (c2 - 1) % MAXCOLORS;
  16367.                        _remappalette(4, Ega_to_vga(c2));
  16368.                        break;
  16369.          }
  16370.          sprintf(left,"<-G %2d ->g", c1);
  16371.          sprintf(right,"<-H %2d ->h", c2);
  16372.          _settextposition(0, 0);
  16373.          _outtext("Press Esc to quit");
  16374.          _settextposition(24, lpos);
  16375.          _outtext(left);
  16376.          _settextposition(24, rpos);
  16377.          _outtext(right);
  16378.      }
  16379.      _setvideomode(_DEFAULTMODE);
  16380.  }
  16381.  long Ega_to_vga(egacolor)
  16382.  int egacolor;       /* ega color value */
  16383.  {
  16384.      static long vgavals[6] = {0x2A0000L, 0x002A00L, 0x00002AL,
  16385.                                0x150000L, 0x001500L, 0x000015L};
  16386.      long vgacolor = 0L; /* vga color value */
  16387.      int bit;
  16388.  
  16389.      for (bit = 0; bit < 6; bit++)
  16390.          vgacolor += ((egacolor >> bit) &1) * vgavals[bit];
  16391.      return (vgacolor);
  16392.  }
  16393.  
  16394.  
  16395.  ALLVGA.C
  16396.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\ALLVGA.C
  16397.  
  16398.  /* allvga.c -- shows _MRES256COLOR 256K colors         */
  16399.  /* If you load graphics.qlb, no program list is needed.*/
  16400.  
  16401.  #include <stdio.h>
  16402.  #include <stdlib.h>
  16403.  #include <graph.h>
  16404.  #include <conio.h>
  16405.  #define FULLBRIGHT 64
  16406.  #define ESC '\033'
  16407.  char label[2][7] = {"ACTIVE", "      "};
  16408.  
  16409.  main(argc, argv)
  16410.  int argc;
  16411.  char *argv[];
  16412.  {
  16413.      struct videoconfig vc;
  16414.      int mode = _MRES256COLOR;
  16415.      int xmax, ymax;
  16416.      static long colors[2] = {_BLUE, _RED};
  16417.      char left[11];
  16418.      char right[11];
  16419.      int lpos, rpos;
  16420.      char ch;
  16421.      unsigned long blue = _BLUE >> 16;
  16422.      unsigned long green = 0L;
  16423.      unsigned long red = 0L;
  16424.      long color;
  16425.      short palnum = 0;
  16426.  
  16427.      if (argc > 1)
  16428.          mode = atoi(argv[1]);
  16429.      if (_setvideomode(mode) == 0)
  16430.          {
  16431.          fprintf(stderr,"%d mode not supported\n", mode);
  16432.          exit(1);
  16433.          }
  16434.      _getvideoconfig(&vc);
  16435.      _setlogorg(vc.numxpixels/2, vc.numypixels/2);
  16436.  
  16437.      xmax = vc.numxpixels / 2 - 1;
  16438.      ymax = vc.numypixels / 2 - 1;
  16439.      lpos = vc.numxpixels / 32 - 5;
  16440.      rpos = lpos + vc.numxpixels/16;
  16441.      _remappalette(2, _RED);
  16442.      _setcolor(1);
  16443.      _rectangle(_GFILLINTERIOR, -xmax, -ymax, 0, ymax);
  16444.      _setcolor(2);
  16445.      _rectangle(_GFILLINTERIOR, 1, -ymax, xmax, ymax);
  16446.      sprintf(left," %6lxH ", colors[0]);
  16447.      sprintf(right," %6lxH ", colors[1]);
  16448.      _settextcolor(6);
  16449.      _settextposition(1, 1);
  16450.      _outtext("Press Tab to toggle panels, Esc to quit.");
  16451.      _settextposition(2, 1);
  16452.      _outtext("B increases blue level, b decreases it. ");
  16453.      _settextposition(3, 1);
  16454.      _outtext("G and g control green, R and r red.     ");
  16455.      _settextposition(24, lpos);
  16456.      _outtext(left);
  16457.      _settextposition(24, rpos);
  16458.      _outtext(right);
  16459.      _settextposition(5, 7);
  16460.      _outtext(label[0]);
  16461.      _settextposition(5, 27);
  16462.      _outtext(label[1]);
  16463.      while ((ch = getch()) != ESC)
  16464.          {
  16465.          switch (ch)
  16466.              {
  16467.              case '\t': _settextposition(5, 27);
  16468.                         _outtext(label[palnum]);
  16469.                         palnum ^= 1;
  16470.                         blue = (colors[palnum] << 16) & 0x3F;
  16471.                         green = (colors[palnum] << 8) & 0x3F;
  16472.                         red = colors[palnum] & 0x3F;
  16473.                         _settextposition(5, 7);
  16474.                         _outtext(label[palnum]);
  16475.                         break;
  16476.              case 'B':  blue = (blue + 1) % FULLBRIGHT;
  16477.                         colors[palnum] = blue << 16 |
  16478.                                 green << 8 | red;
  16479.                         _remappalette(palnum + 1, colors[palnum]);
  16480.  
  16481.                         break;
  16482.              case 'b':  blue = (blue - 1) % FULLBRIGHT;
  16483.                         colors[palnum] = blue << 16 |
  16484.                                 green << 8 | red;
  16485.                         _remappalette(palnum + 1, colors[palnum]);
  16486.  
  16487.                         break;
  16488.              case 'G':  green = (green + 1) % FULLBRIGHT;
  16489.                         colors[palnum] = blue << 16 |
  16490.                                 green << 8 | red;
  16491.                         _remappalette(palnum + 1, colors[palnum]);
  16492.  
  16493.                         break;
  16494.              case 'g':  green = (green - 1) % FULLBRIGHT;
  16495.                         colors[palnum] = blue << 16 |
  16496.                                 green << 8 | red;
  16497.                         _remappalette(palnum + 1, colors[palnum]);
  16498.  
  16499.                         break;
  16500.              case 'R':  red = (red + 1) % FULLBRIGHT;
  16501.                         colors[palnum] = blue << 16 |
  16502.                                 green << 8 | red;
  16503.                         _remappalette(palnum + 1, colors[palnum]);
  16504.  
  16505.                         break;
  16506.              case 'r':  red = (red - 1) % FULLBRIGHT;
  16507.                         colors[palnum] = blue << 16 |
  16508.                                 green << 8 | red;
  16509.                         _remappalette(palnum + 1, colors[palnum]);
  16510.  
  16511.                         break;
  16512.  
  16513.              }
  16514.          sprintf(left," %6lxH ", colors[0]);
  16515.          sprintf(right," %6lxH ", colors[1]);
  16516.          _settextposition(24, lpos);
  16517.          _outtext(left);
  16518.          _settextposition(24, rpos);
  16519.          _outtext(right);
  16520.          }
  16521.      _setvideomode(_DEFAULTMODE);
  16522.  }
  16523.  
  16524.  
  16525.  ALPHABET.C
  16526.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP04\ALPHABET.C
  16527.  
  16528.  
  16529.  /* ALPHABET.C -- uses for loop to         */
  16530.  /*               print lowercase alphabet */
  16531.  
  16532.  main()
  16533.  {
  16534.      int i;
  16535.      for (i = 'a'; i <= 'z'; i++)
  16536.          {
  16537.          printf("%c", i);
  16538.          }
  16539.  }
  16540.  
  16541.  
  16542.  
  16543.  ANIMATE.C
  16544.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP04\ANIMATE.C
  16545.  
  16546.  
  16547.  /* ANIMATE.C -- animate a graphics character */
  16548.  /*              until a key is pressed       */
  16549.  
  16550.  /* Special characters */
  16551.  #define RTARROW 175
  16552.  #define LFTARROW 174
  16553.  #define BLANK 32
  16554.  #define BACKSPACE 8
  16555.  
  16556.  main()
  16557.  {
  16558.      int pos, i, j = 1;
  16559.      while ( !kbhit() )
  16560.          {
  16561.          pos = 1;
  16562.          while (pos < 79)
  16563.              {
  16564.              putch(RTARROW);
  16565.              i = 1;
  16566.              while (i < 1000)
  16567.                  {
  16568.                  j = i + 10;
  16569.                  i++;
  16570.                  }
  16571.              putch(BACKSPACE);
  16572.              putch(BLANK);
  16573.              pos++;
  16574.              }
  16575.          while (pos > 1)
  16576.              {
  16577.              putch(LFTARROW);
  16578.              i = 1;
  16579.              while (i < 1000)
  16580.                  {
  16581.                  j = i + 10;
  16582.                  i++;
  16583.                  }
  16584.              putch(BACKSPACE);
  16585.              putch(BLANK);
  16586.              putch(BACKSPACE);
  16587.              putch(BACKSPACE);
  16588.              pos--;
  16589.              }
  16590.          }
  16591.  }
  16592.  
  16593.  
  16594.  
  16595.  ARRAY1.C
  16596.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP07\ARRAY1.C
  16597.  
  16598.  /* array1.c -- how to declare arrays legally         */
  16599.  
  16600.  #define SIZEOARRAY 26
  16601.  
  16602.  main()
  16603.  {
  16604.      char  initials[26];
  16605.      int   num_men[26], num_women[SIZEOARRAY];
  16606.      float ages[SIZEOARRAY * 2];
  16607.  }
  16608.  
  16609.  
  16610.  ARROW.C
  16611.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\ARROW.C
  16612.  
  16613.  /* arrow.c -- fill inside and outside of a line       */
  16614.  /*            drawing                                 */
  16615.  /* If you load graphics.qlb, no program list is needed*/
  16616.  
  16617.  #include <stdio.h>
  16618.  #include <graph.h>
  16619.  #include <conio.h>
  16620.  #define ESC '\033'
  16621.  BKCOLS 16   /* use 16 background colors */
  16622.  long Bkcolors[BKCOLS] = {_BLACK, _BLUE, _GREEN, _CYAN,
  16623.                   _RED, _MAGENTA, _BROWN, _WHITE,
  16624.                   _GRAY, _LIGHTBLUE, _LIGHTGREEN,
  16625.                   _LIGHTCYAN, _LIGHTRED, _LIGHTMAGENTA,
  16626.                   _LIGHTYELLOW,_BRIGHTWHITE };
  16627.  char Mask[8] = {0x90, 0x68, 0x34, 0x19, 0x19, 0x34, 0x68,
  16628.                  0x90};
  16629.  char Outmask[8] = {0xff, 0x80, 0x80, 0x80, 0xff, 0x08, 0x08,
  16630.                     0x08};
  16631.  main(argc, argv)
  16632.  int argc;
  16633.  char *argv[];
  16634.  {
  16635.      struct videoconfig vc;
  16636.      int mode = _MRES4COLOR;
  16637.      float x1, y1, x2, y2, x3, y3, y4, x5, y5;
  16638.      long bk = _BLUE;
  16639.  
  16640.      if (argc > 1)
  16641.          mode = atoi(argv[1]);
  16642.      if (_setvideomode(mode) == 0)
  16643.          {
  16644.          printf("Can't set mode %d.\n", mode);
  16645.          exit(1);
  16646.          }
  16647.      _getvideoconfig(&vc);
  16648.  
  16649.      x1 = 0.1 * vc.numxpixels;
  16650.      x2 = 0.7 * vc.numxpixels;
  16651.      x3 = 0.6 * vc.numxpixels;
  16652.      x5 = 0.9 * vc.numxpixels;
  16653.      y1 = 0.45 * vc.numypixels;
  16654.      y2 = 0.55 * vc.numypixels;
  16655.      y3 = 0.3 * vc.numypixels;
  16656.      y4 = 0.7 * vc.numypixels;
  16657.      y5 = 0.5 * vc.numypixels;
  16658.      _selectpalette(0);
  16659.      _setcolor(1);
  16660.      _moveto(x1, y1);
  16661.      _lineto(x2, y1);
  16662.      _lineto(x3, y3);
  16663.      _lineto(x5, y5);
  16664.      _lineto(x3, y4);
  16665.      _lineto(x2, y2);
  16666.      _lineto(x1, y2);
  16667.      _lineto(x1, y1);
  16668.      _setcolor(2);
  16669.      _setfillmask(Mask);
  16670.      _floodfill(x2, y5, 1) ;
  16671.      _setcolor(3);
  16672.      _setfillmask(Outmask);     /* restores default mask */
  16673.      _floodfill(5, 5, 1) ;
  16674.      _settextcolor(1);
  16675.      _settextposition(23, 0);
  16676.      _outtext("Press <enter> to change background.");
  16677.      _settextposition(24, 0);
  16678.      _outtext("Press <esc> to end.");
  16679.      while (getch() != ESC)
  16680.          _setbkcolor(Bkcolors[++bk % BKCOLS]);
  16681.      _setvideomode(_DEFAULTMODE);
  16682.  }
  16683.  
  16684.  
  16685.  ASGNKEY.C
  16686.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\ASGNKEY.C
  16687.  
  16688.  /*   asgnkey.c -- uses ansi.sys to assign meanings   */
  16689.  /*                to several function keys.          */
  16690.  /*  Note: This requires ANSI.SYS to be installed.    */
  16691.  
  16692.  #define KASSIGN(K, S) printf("\033[0;%d;\"%s\";13p", K, S)
  16693.  /* This macro assigns string S to key K */
  16694.  #define F5 63
  16695.  #define F6 64
  16696.  #define F7 65
  16697.  #define F8 66
  16698.  #define F9 67
  16699.  #define F10 68
  16700.  main()
  16701.  {
  16702.       KASSIGN(F5, "DIR *.C");
  16703.       KASSIGN(F6, "DIR *.H");
  16704.       KASSIGN(F7, "DIR *.OBJ");
  16705.       KASSIGN(F8, "DIR *.EXE");
  16706.       KASSIGN(F9, "DIR /W");
  16707.       KASSIGN(F10, "CD \\");
  16708.  }
  16709.  
  16710.  
  16711.  ASIMOV.C
  16712.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP07\ASIMOV.C
  16713.  
  16714.  /* asimov.c -- illustrates how to initialize an      */
  16715.  /*             array with starting values            */
  16716.  
  16717.  #define MAXL 16
  16718.  char Letters[MAXL] = {
  16719.      'e', 'I', 'a', 'N', 'o', 'R', 'O', 'o',
  16720.      'u', 't', 'o', 'R', 'l', 'o', 'B', 'b',
  16721.  };
  16722.  
  16723.  main()
  16724.  {
  16725.      int num, i;
  16726.  
  16727.      printf("Guess my identity with numbers.\n");
  16728.      printf("(any non number quits)\n\n");
  16729.  
  16730.      while (scanf("%d", &num) == 1)
  16731.          {
  16732.          if (num <= 0)
  16733.              {
  16734.              printf("Guesses must be above zero\n");
  16735.              continue;
  16736.              }
  16737.          for (i = 1; i <= num; ++i)
  16738.              {
  16739.              printf("%c", Letters[(i * num) % MAXL]);
  16740.              }
  16741.          printf("\n");
  16742.          }
  16743.  }
  16744.  
  16745.  
  16746.  ATTRIB.C
  16747.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\ATTRIB.C
  16748.  
  16749.  /* attrib.c -- this program illustrates attributes */
  16750.  /* program list: attrib.c, scrfun.c                */
  16751.  /* user include files: scrn.h                      */
  16752.  /* Note: activate Screen Swapping On in Debug menu */
  16753.  #include <stdio.h>
  16754.  #include <conio.h>
  16755.  #include "scrn.h"
  16756.  #define PAGE 0
  16757.  #define ESC '\033'
  16758.  char *Format = "This message is displayed using an "
  16759.                 "attribute value of %2X hex (%s).";
  16760.  int Get_attrib(char *);
  16761.  void Print_attr(char *, unsigned char, unsigned char);
  16762.  
  16763.  main()
  16764.  {
  16765.  
  16766.      int attribute;       /* value of attribute */
  16767.      char attr_str[9];    /* attr. in string form */
  16768.      char mesg[80];
  16769.  
  16770.      Clearscr();
  16771.      Home();
  16772.      printf("Enter an attribute as an 8-digit binary "
  16773.             "number, such as 00000111, and see a\n"
  16774.             "message displayed using that attribute."
  16775.             "Hit <Esc> to quit.\n"
  16776.             "Attribute = ");
  16777.      while ((attribute = Get_attrib(attr_str)) != -1)
  16778.          {
  16779.          Setcurs(10,0,PAGE);
  16780.          sprintf(mesg, Format, attribute, attr_str);
  16781.          Print_attr(mesg, attribute, PAGE);
  16782.          Setcurs(2, 12, PAGE);
  16783.          printf("         ");  /* clear old display */
  16784.          Setcurs(2, 12, PAGE);
  16785.          }
  16786.      Clearscr();
  16787.  }
  16788.  
  16789.  /* The following function reads in a binary number    */
  16790.  /* as a sequence of 1s and 0s. It places the 1 and 0  */
  16791.  /* characters in a string whose address is passed as  */
  16792.  /* an argument. It returns the numeric value of the   */
  16793.  /* binary number. Bad input is summarily rejected.    */
  16794.  /* The function returns -1 when you press Esc.        */
  16795.  
  16796.  int Get_attrib(a_str)
  16797.  char a_str[];     /* attribute as binary string */
  16798.  {
  16799.      int attrib[8];
  16800.      int index = 7;
  16801.      int ch;
  16802.      int attribute = 0; /* attrib. as numeric value */
  16803.      int pow;
  16804.  
  16805.      a_str[8] = '\0';  /* terminate string */
  16806.      while ((index >= 0) &&  (ch = getch()) != ESC)
  16807.          {
  16808.          if (ch != '0' && ch != '1')  /* bad input */
  16809.              putch('\a');
  16810.          else
  16811.              {
  16812.              putch(ch);
  16813.              a_str[index] = ch;      /* string form */
  16814.              attrib[index--] = ch - '0'; /* numeric */
  16815.              }
  16816.          }
  16817.      if (ch == ESC)
  16818.          return (-1);
  16819.      else            /* convert numeric array to a number */
  16820.          {
  16821.          for(index = 0, pow = 1; index < 8;
  16822.                                    index++, pow *= 2)
  16823.              attribute += attrib[index] * pow;
  16824.          return attribute;
  16825.          }
  16826.  }
  16827.  
  16828.  /* The following function prints the string str using */
  16829.  /* attribute attr on the indicated page.              */
  16830.  /* It uses functions from the scrfun.c file.          */
  16831.  
  16832.  void Print_attr(str, attr, page)
  16833.  char *str;
  16834.  unsigned char attr, page;
  16835.  {
  16836.      while (*str != '\0')
  16837.          {
  16838.          Write_ch_atr(*str++, attr , page, 1);
  16839.          Cursrt();
  16840.          }
  16841.  }
  16842.  
  16843.  
  16844.  AVGTEMP.C
  16845.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\AVGTEMP.C
  16846.  
  16847.  /* avgtemp.c -- finds average temperature */
  16848.  /*              for the week              */
  16849.  
  16850.  main()
  16851.  {
  16852.      int t1, t2, t3, t4, t5, t6, t7;
  16853.      float avg;
  16854.  
  16855.      printf("Enter the high temperature for:\n");
  16856.      printf("Monday: ");
  16857.      scanf("%d", &t1);
  16858.      printf("Tuesday: ");
  16859.      scanf("%d", &t2);
  16860.      printf("Wednesday: ");
  16861.      scanf("%d", &t3);
  16862.      printf("Thursday: ");
  16863.      scanf("%d", &t4);
  16864.      printf("Friday: ");
  16865.      scanf("%d", &t5);
  16866.      printf("Saturday: ");
  16867.      scanf("%d", &t6);
  16868.      printf("Sunday: ");
  16869.      scanf("%d", &t7);
  16870.  
  16871.      /* calculate and display average */
  16872.      avg = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7.0;
  16873.            /* divide by 7.0 to ensure float result */
  16874.      printf("The average high temperature for");
  16875.      printf(" this week was %5.2f degrees.\n", avg);
  16876.  }
  16877.  
  16878.  
  16879.  BACKWARD.C
  16880.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\BACKWARD.C
  16881.  
  16882.  /* backward.c -- the backwards word displayer         */
  16883.  
  16884.  #include <stdio.h>
  16885.  #define SIZE 5
  16886.  char word[SIZE] = "trap";
  16887.  main()
  16888.  {
  16889.      unsigned int index;
  16890.  
  16891.      printf("%s backwards is ", word);
  16892.      for (index = SIZE - 2; index >= 0; index--)
  16893.          putchar(word[index]);
  16894.      putchar('\n');
  16895.  }
  16896.  
  16897.  
  16898.  
  16899.  BADPUTC.C
  16900.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\BADPUTC.C
  16901.  
  16902.  /* badputc.c -- misusing putc()                  */
  16903.  
  16904.  #include <stdio.h>
  16905.  main()
  16906.  {
  16907.      FILE *fp;
  16908.      int ch;
  16909.  
  16910.      if ((fp = fopen("junk", "w")) == NULL)
  16911.          exit(1);
  16912.  
  16913.      while ((ch = getchar()) != EOF)
  16914.          putc(fp, ch);
  16915.      fclose(fp);
  16916.  }
  16917.  
  16918.  
  16919.  
  16920.  BADREF.C
  16921.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\BADREF.C
  16922.  
  16923.  /* badref.c -- misusing a pointer                     */
  16924.  main()
  16925.  {
  16926.      char name[81];
  16927.      char *pt_ch;
  16928.  
  16929.      printf("Enter your first name: -> ");
  16930.      scanf("%s", name);
  16931.      *pt_ch = name[1];
  16932.      printf("The second letter of your name is %c\n",
  16933.              *pt_ch );
  16934.  }
  16935.  
  16936.  
  16937.  
  16938.  BADSIGN.C
  16939.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\BADSIGN.C
  16940.  
  16941.  /* badsign.c -- uncaught typo                 */
  16942.  
  16943.  main()
  16944.  {
  16945.      int i;
  16946.      int j = 1;
  16947.  
  16948.      for (i = 0; i < 10; i++)
  16949.          {
  16950.          j =+ 10;         /* transposed += */
  16951.          printf("%4d ", j);
  16952.          }
  16953.      printf("\n");
  16954.  }
  16955.  
  16956.  
  16957.  
  16958.  BIFFRED.C
  16959.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\BIFFRED.C
  16960.  
  16961.  /* biffred.c  --  strings in the string pool can be */
  16962.  /*                manipulated via pointers          */
  16963.  
  16964.  char Start[] = "start";
  16965.  
  16966.  main()
  16967.  {
  16968.      char *cp;
  16969.      int pass;
  16970.  
  16971.      for (pass = 0; pass < 2; ++pass)
  16972.          {
  16973.          printf("My name is FRED\n");
  16974.  
  16975.          cp = Start;
  16976.  
  16977.          while (*cp != 'F')
  16978.              ++cp;
  16979.  
  16980.          *cp   = 'B';
  16981.          *++cp = 'I';
  16982.          *++cp = 'F';
  16983.          *++cp = 'F';
  16984.          }
  16985.  }
  16986.  
  16987.  
  16988.  BITOUT.C
  16989.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\BITOUT.C
  16990.  
  16991.  /* bitout.c  -- compiles one way on an IBM-PC and      */
  16992.  /*              another on a 68000 chip-based machine  */
  16993.  
  16994.  CHIP_80286    /* don't define on a 68000 machine */
  16995.  #include <stdio.h>
  16996.  
  16997.  main()
  16998.  {
  16999.      int num;
  17000.  
  17001.      printf("Enter an integer number and I will print"
  17002.             " it out in binary\nNumber: ");
  17003.  
  17004.      if (scanf("%d", &num) != 1)
  17005.          {
  17006.          fprintf(stderr, "Not an integer\n");
  17007.          exit(1);
  17008.          }
  17009.      Bitout(num);
  17010.  }
  17011.  
  17012.  Bitout(unsigned int num)
  17013.  {
  17014.      int i, j;
  17015.      unsigned char *cp;
  17016.  
  17017.      cp = (char *)#
  17018.  
  17019.  defined(CHIP_80286)    /* IBM-PC */
  17020.      for (i = 1; i >= 0; --i)
  17021.  #endif
  17022.  !defined(CHIP_80286)   /* otherwise 68000 machine */
  17023.      for (i = 0; i < 4; ++i)
  17024.  #endif
  17025.          {
  17026.          for (j = 7; j >= 0; --j)
  17027.              putchar((cp[i] & (1 << j)) ? '1' : '0');
  17028.          }
  17029.      putchar('\n');
  17030.  }
  17031.  
  17032.  
  17033.  BITWISE.C
  17034.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP07\BITWISE.C
  17035.  
  17036.  /* bitwise.c -- demonstrate the bitwise operators */
  17037.  
  17038.  #include <stdio.h>
  17039.  
  17040.  main()
  17041.  {
  17042.      unsigned int val1, val2, result;
  17043.      int ch;
  17044.      extern void show();
  17045.  
  17046.      while(1)
  17047.          {
  17048.          printf("\nval1: ");
  17049.          if (scanf("%d", &val1) != 1)
  17050.              break;
  17051.  
  17052.          printf("val2: ");
  17053.          if (scanf("%d", &val2) != 1)
  17054.              break;
  17055.  
  17056.          printf("\tval1   = ");
  17057.          show(val1);
  17058.          printf("\tval2   = ");
  17059.          show(val2);
  17060.  
  17061.          printf("Bitwise Operator: ");
  17062.          while ((ch = getchar()) == '\n')
  17063.              {
  17064.              continue;
  17065.              }
  17066.          if (ch == EOF)
  17067.              break;
  17068.          switch (ch)
  17069.              {
  17070.              case '&':
  17071.                  result = val1 & val2;
  17072.                  printf("Executing: result = val1 & val2;\n");
  17073.                  break;
  17074.              case '|':
  17075.                  result = val1 |= val2;
  17076.                  printf("Executing: result = val1 | val2;\n");
  17077.                  break;
  17078.              case '^':
  17079.                  result = val1 ^= val2;
  17080.                  printf("Executing: result = val1 ^ val2;\n");
  17081.                  break;
  17082.              case '~':
  17083.                  result = ~val1;
  17084.                  printf("Executing: result = ~val1;\n");
  17085.                  printf("\tresult = ");
  17086.                  show(result);
  17087.                  result = ~val2;
  17088.                  printf("Executing: result = ~val2;\n");
  17089.                  break;
  17090.              case '<':
  17091.                  result = val1 <<= val2;
  17092.                  printf("Executing: result = val1 <<val2;\n");
  17093.                  break;
  17094.              case '>':
  17095.                  result = val1 >>= val2;
  17096.                  printf("Executing: result = val1 >>val2;\n");
  17097.                  break;
  17098.              case 'q':
  17099.              case 'Q':
  17100.                  return(0);
  17101.                default:
  17102.                  continue;
  17103.              }
  17104.          printf("\tresult = ");
  17105.          show(result);
  17106.          }
  17107.  }
  17108.  
  17109.  void bitout(unsigned char num[])
  17110.  {
  17111.      int bytes = 2, i, j;
  17112.  
  17113.      /* IBM PC stores ints low/hi. */
  17114.      for (i = bytes-1; i >= 0; --i)
  17115.          {
  17116.          for (j = 7; j >= 0; --j)
  17117.              {
  17118.              putchar((num[i]&(1<<j))?'1':'0');
  17119.              }
  17120.          }
  17121.  }
  17122.  
  17123.  void show(unsigned int val)
  17124.  {
  17125.      extern void bitout();
  17126.  
  17127.      printf("(%05u decimal)", val);
  17128.      bitout(&val);
  17129.      printf(" binary\n");
  17130.  }
  17131.  
  17132.  
  17133.  BLANK.C
  17134.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\BLANK.C
  17135.  
  17136.  /* blank.c -- blanks MDA screen                        */
  17137.  /* program list -- blank.c (outp() not in core lib)    */
  17138.  
  17139.  #include <conio.h>
  17140.  CONTROLREG 0x3B8 /* control register MDA */
  17141.  #define DEFAULTSET 0x29
  17142.  #define VIDEOOFF 0x21
  17143.  main()
  17144.  {
  17145.      outp(CONTROLREG, VIDEOOFF);
  17146.      getch();
  17147.      outp(CONTROLREG, DEFAULTSET);
  17148.  }
  17149.  
  17150.  
  17151.  BOX.C
  17152.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP07\BOX.C
  17153.  
  17154.  /* box.c  --  demonstrate the result of initializing  */
  17155.  /*            a three-dimensional array               */
  17156.  
  17157.  main()
  17158.  {
  17159.      static int cube[3][3][3] = {
  17160.          1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  17161.          13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
  17162.          23, 24, 25, 26, 27 };
  17163.      int plane;
  17164.      extern void Draw_plane();
  17165.  
  17166.      for (plane = 0; plane < 3; ++plane)
  17167.          {
  17168.          Draw_plane(cube, plane);
  17169.          }
  17170.  }
  17171.  
  17172.  void Draw_plane(int box[3][3][3], int slice)
  17173.      {
  17174.      int row, col;
  17175.  
  17176.      printf("Plane[%d] =\n", slice);
  17177.      for (row = 0; row < 3; ++row)
  17178.          {
  17179.          for (col = 0; col < 3; ++col)
  17180.              {
  17181.              printf( "%2d ", box[slice][row][col]);
  17182.              }
  17183.          printf("\n");
  17184.          }
  17185.      printf("\n");
  17186.  }
  17187.  
  17188.  
  17189.  BREAK.C
  17190.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP05\BREAK.C
  17191.  
  17192.  /* break.c -- shows how to get out of loop with BREAK */
  17193.  
  17194.  #include <stdio.h>
  17195.  #define TRUE 1
  17196.  
  17197.  main()
  17198.  {
  17199.      int number;
  17200.      while (TRUE) /* endless loop */
  17201.          {
  17202.          /* get a random number between 0 and 32767 */
  17203.          number = rand();
  17204.          printf("%d\n", number);
  17205.  
  17206.          /* break out of loop if random number */
  17207.          /* is greater than 32000              */
  17208.          if (number > 32000)
  17209.              break; /* exit WHILE loop */
  17210.          }
  17211.      printf("Broken out of WHILE loop.\n");
  17212.  }
  17213.  
  17214.  
  17215.  BUBSORT.C
  17216.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP07\BUBSORT.C
  17217.  
  17218.  /* bubsort.c  --  passing an array to a function  */
  17219.  /*                affects the original array      */
  17220.  
  17221.  #define NUMINTS 6
  17222.  
  17223.  extern void Bub_sort();
  17224.  extern void Triple();
  17225.  
  17226.  main()
  17227.  {
  17228.      int num = 2, i;
  17229.      static int list[NUMINTS] = { 6, 5, 4, 3, 2, 1 };
  17230.  
  17231.      printf("num before Triple = %d\n", num);
  17232.      Triple(num);
  17233.      printf("num after Triple  = %d\n", num);
  17234.      printf("list[0] before Triple = %d\n", list[0]);
  17235.      Triple(list[0]);
  17236.      printf("list[0] after Triple  = %d\n", list[0]);
  17237.  
  17238.      printf("Before sorting -> ");
  17239.      for (i = 0; i < NUMINTS; ++i)
  17240.          {
  17241.          printf("%d ", list[i]);
  17242.          }
  17243.      printf("\n");
  17244.  
  17245.      Bub_sort(list);
  17246.      printf("After sorting ->  ");
  17247.      for (i = 0; i < NUMINTS; ++i)
  17248.          {
  17249.          printf("%d ", list[i]);
  17250.          }
  17251.      printf("\n");
  17252.  
  17253.  }
  17254.  
  17255.  void Triple(int x)  /* function doesn't affect original */
  17256.  {
  17257.      x *= 3;
  17258.  }
  17259.  
  17260.  void Bub_sort(int vals[NUMINTS]) /* function changes original */
  17261.  {
  17262.      int i, j, temp;
  17263.  
  17264.      for (i = (NUMINTS - 1); i > 0; --i)
  17265.          {
  17266.          for (j = 0; j < i; ++j)
  17267.              {
  17268.              if (vals[j] > vals[j+1])
  17269.                  {
  17270.                  temp      = vals[j];
  17271.                  vals[j]   = vals[j+1];
  17272.                  vals[j+1] = temp;
  17273.                  }
  17274.              }
  17275.          }
  17276.  }
  17277.  
  17278.  
  17279.  BUG.C
  17280.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\BUG.C
  17281.  
  17282.  /* bug.c  --  shows how different levels of debugging  */
  17283.  /*            output can be produced using #if         */
  17284.  
  17285.  DEBUG_LEVEL 2      /* 0 = none, 1-2 for debug  */
  17286.  #include <stdio.h>
  17287.  
  17288.  main()
  17289.  {
  17290.      int ret;
  17291.  
  17292.  #if (DEBUG_LEVEL == 2)
  17293.      fprintf(stderr, "Entering main()\n");
  17294.  #endif
  17295.  
  17296.  #if (DEBUG_LEVEL == 1)
  17297.      fprintf(stderr, "Calling sub()\n");
  17298.  #endif
  17299.  
  17300.      ret = sub();
  17301.  
  17302.  #if (DEBUG_LEVEL == 1)
  17303.      fprintf(stderr, "sub() returned %d\n", ret);
  17304.  #endif
  17305.  
  17306.  #if (DEBUG_LEVEL == 2)
  17307.      fprintf(stderr, "Leaving main()\n");
  17308.  #endif
  17309.  
  17310.  }
  17311.  
  17312.  sub()
  17313.  {
  17314.      return (5);
  17315.  }
  17316.  
  17317.  
  17318.  CARD.C
  17319.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP11\CARD.C
  17320.  
  17321.  /* card.c  --  demonstrates how to declare structures  */
  17322.  /*             and how to use structure members        */
  17323.  
  17324.  <stdio.h>      /* for NULL  and stdin */
  17325.  <string.h>     /* for strdup()        */
  17326.  
  17327.  #define MAXN 79
  17328.  
  17329.  struct cardstruct {                 /* global pattern */
  17330.      char *first, *last, *middle;
  17331.      long street_num;
  17332.      char *street, *city, *state;
  17333.      long zip;
  17334.      int  area_code;
  17335.      long phone;
  17336.  };
  17337.  
  17338.  main()
  17339.  {
  17340.      char *Str_Input();
  17341.      long Lint_Input();
  17342.      struct cardstruct card1;
  17343.  
  17344.      card1.first         = Str_Input("First Name");
  17345.      card1.last          = Str_Input("Last Name");
  17346.      card1.middle        = Str_Input("Middle Name");
  17347.      card1.street_num    = Lint_Input("Street Number");
  17348.      card1.street        = Str_Input("Street Name");
  17349.      card1.city          = Str_Input("City");
  17350.      card1.state         = Str_Input("State");
  17351.      card1.zip           = Lint_Input("Zip Code");
  17352.      card1.area_code     = (int)Lint_Input("Area Code");
  17353.      card1.phone         = Lint_Input("Phone Number");
  17354.  
  17355.      printf("\n\n");
  17356.      printf("%s %s %s\n", card1.first, card1.middle,
  17357.              card1.last);
  17358.      printf("%ld %s, %s, %s %ld\n", card1.street_num,
  17359.              card1.street, card1.city, card1.state,
  17360.              card1.zip);
  17361.      printf("(%d) %ld\n", card1.area_code, card1.phone);
  17362.  
  17363.      return (0);
  17364.      }
  17365.  
  17366.  char *Str_Input(char *prompt)
  17367.      {
  17368.      char buf[MAXN+1], *ptr;
  17369.  
  17370.      printf("%s: ", prompt);
  17371.      if (fgets(buf, MAXN, stdin) == NULL)
  17372.          exit(0);
  17373.      buf[strlen(buf) - 1] = '\0'; /* strip '\n' */
  17374.      if (strlen(buf) == 0)
  17375.          exit(0);
  17376.      if ((ptr = strdup(buf)) == NULL)
  17377.          exit(0);
  17378.      return (ptr);
  17379.  }
  17380.  
  17381.  long Lint_Input(char *prompt)
  17382.  {
  17383.      char buf[MAXN + 1];
  17384.      long num;
  17385.  
  17386.      printf("%s: ", prompt);
  17387.      if (fgets(buf, MAXN, stdin) == NULL)
  17388.          exit(0);
  17389.      if (sscanf(buf, "%ld", &num) != 1)
  17390.          exit(0);
  17391.      return (num);
  17392.  }
  17393.  
  17394.  
  17395.  CARD2.C
  17396.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP11\CARD2.C
  17397.  
  17398.  /* card2.c --  demonstrates structure assignment and   */
  17399.  /*             how to pass a structure to a function   */
  17400.  
  17401.  <stdio.h>      /* for NULL  and stdin */
  17402.  <string.h>     /* for strdup()        */
  17403.  
  17404.  #define MAXN 79
  17405.  
  17406.  struct cardstruct {                 /* global pattern */
  17407.      char *first, *last, *middle;
  17408.      long street_num;
  17409.      char *street, *city, *state;
  17410.      long zip;
  17411.      int  area_code;
  17412.      long phone;
  17413.  };
  17414.  
  17415.  main()
  17416.  {
  17417.      int  i;
  17418.      char *Str_Input();
  17419.      long Lint_Input();
  17420.      struct cardstruct card1, card2;
  17421.  
  17422.      for (i = 0; i < 2; i++) /* do twice */
  17423.          {
  17424.          printf("\nCard %d:\n\n", i + 1);
  17425.  
  17426.          card1.first         = Str_Input("First Name");
  17427.          card1.last          = Str_Input("Last Name");
  17428.          card1.middle        = Str_Input("Middle Name");
  17429.          card1.street_num    = Lint_Input("Street Number");
  17430.          card1.street        = Str_Input("Street Name");
  17431.          card1.city          = Str_Input("City");
  17432.          card1.state         = Str_Input("State");
  17433.          card1.zip           = Lint_Input("Zip Code");
  17434.          card1.area_code     = (int)Lint_Input("Area Code");
  17435.          card1.phone         = Lint_Input("Phone Number");
  17436.  
  17437.          if (i == 0)
  17438.              card2 = card1;      /* structure assignment */
  17439.          }
  17440.      Showcard(card2);
  17441.      Showcard(card1);
  17442.  
  17443.  }
  17444.  
  17445.  Showcard(struct cardstruct card)
  17446.  {
  17447.      printf("\n\n");
  17448.  
  17449.      printf("%s %s %s\n", card.first, card.middle,
  17450.              card.last);
  17451.      printf("%ld %s, %s, %s %ld\n", card.street_num,
  17452.              card.street, card.city, card.state,
  17453.              card.zip);
  17454.      printf("(%d) %ld\n", card.area_code, card.phone);
  17455.  }
  17456.  
  17457.  char *Str_Input(char *prompt)
  17458.  {
  17459.      char buf[MAXN + 1], *ptr;
  17460.  
  17461.      printf("%s: ", prompt);
  17462.      if (fgets(buf, MAXN, stdin) == NULL)
  17463.          exit(0);
  17464.      buf[strlen(buf) - 1] = '\0'; /* strip '\n' */
  17465.      if (strlen(buf) == 0)
  17466.          exit(0);
  17467.      if ((ptr = strdup(buf)) == NULL)
  17468.          exit(0);
  17469.      return (ptr);
  17470.  }
  17471.  
  17472.  long Lint_Input(char *prompt)
  17473.  {
  17474.      char buf[MAXN + 1];
  17475.      long num;
  17476.  
  17477.      printf("%s: ", prompt);
  17478.      if (fgets(buf, MAXN, stdin) == NULL)
  17479.          exit(0);
  17480.      if (sscanf(buf, "%ld", &num) != 1)
  17481.          exit(0);
  17482.      return (num);
  17483.  }
  17484.  
  17485.  
  17486.  CARD3.C
  17487.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP11\CARD3.C
  17488.  
  17489.  /* card3.c --  demonstrates pointers to structures     */
  17490.  
  17491.  <stdio.h>      /* for NULL  and stdin */
  17492.  <string.h>     /* for strdup()        */
  17493.  
  17494.  #define MAXN 79
  17495.  
  17496.  struct cardstruct {                 /* global pattern */
  17497.      char *first, *last, *middle;
  17498.      long street_num;
  17499.      char *street, *city, *state;
  17500.      long zip;
  17501.      int  area_code;
  17502.      long phone;
  17503.  };
  17504.  
  17505.  main()
  17506.  {
  17507.      int  i;
  17508.      char *Str_Input();
  17509.      long Lint_Input();
  17510.      struct cardstruct card1, card2;
  17511.  
  17512.      for (i = 0; i < 2; i++) /* do twice */
  17513.          {
  17514.          printf("\nCard %d:\n\n", i + 1);
  17515.  
  17516.          card1.first         = Str_Input("First Name");
  17517.          card1.last          = Str_Input("Last Name");
  17518.          card1.middle        = Str_Input("Middle Name");
  17519.          card1.street_num    = Lint_Input("Street Number");
  17520.          card1.street        = Str_Input("Street Name");
  17521.          card1.city          = Str_Input("City");
  17522.          card1.state         = Str_Input("State");
  17523.          card1.zip           = Lint_Input("Zip Code");
  17524.          card1.area_code     = (int)Lint_Input("Area Code");
  17525.          card1.phone         = Lint_Input("Phone Number");
  17526.  
  17527.          if (i == 0)
  17528.              card2 = card1;
  17529.          }
  17530.      Showcard(&card2);     /* pass addresses of structures */
  17531.      Showcard(&card1);
  17532.  
  17533.      return (0);
  17534.  }
  17535.  
  17536.  Showcard(cardptr)
  17537.  struct cardstruct *cardptr; /* pointer receives an address */
  17538.      {
  17539.      printf("\n\n");
  17540.  
  17541.      printf("%s %s %s\n", cardptr->first, cardptr->middle,
  17542.              cardptr->last);
  17543.      printf("%ld %s, %s, %s %ld\n", cardptr->street_num,
  17544.              cardptr->street, cardptr->city, cardptr->state,
  17545.              cardptr->zip);
  17546.      printf("(%d) %ld\n", cardptr->area_code, cardptr->phone);
  17547.      }
  17548.  
  17549.  char *Str_Input(char *prompt)
  17550.      {
  17551.      char buf[MAXN + 1], *ptr;
  17552.  
  17553.      printf("%s: ", prompt);
  17554.      if (fgets(buf, MAXN, stdin) == NULL)
  17555.          exit(0);
  17556.      buf[strlen(buf) - 1] = '\0'; /* strip '\n' */
  17557.      if (strlen(buf) == 0)
  17558.          exit(0);
  17559.      if ((ptr = strdup(buf)) == NULL)
  17560.          exit(0);
  17561.      return (ptr);
  17562.  }
  17563.  
  17564.  long Lint_Input(char *prompt)
  17565.  {
  17566.      char buf[MAXN + 1];
  17567.      long num;
  17568.  
  17569.      printf("%s: ", prompt);
  17570.      if (fgets(buf, MAXN, stdin) == NULL)
  17571.          exit(0);
  17572.      if (sscanf(buf, "%ld", &num) != 1)
  17573.          exit(0);
  17574.      return (num);
  17575.  }
  17576.  
  17577.  
  17578.  CCOPY.C
  17579.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP10\CCOPY.C
  17580.  
  17581.  /* ccopy.c  --  Copies a file, cutting blank lines and  */
  17582.  /*              leading space from lines of copy        */
  17583.  
  17584.  <stdio.h>        /* for FILE, BUFSIZ, NULL */
  17585.  <ctype.h>        /* for iswhite()          */
  17586.  
  17587.  main(argc, argv)
  17588.  int argc;
  17589.  char *argv[];
  17590.  {
  17591.      FILE *fp_in, *fp_out;
  17592.      char buf[BUFSIZ];
  17593.      char *cp;
  17594.  
  17595.      if (argc != 3)
  17596.          {
  17597.          printf("usage: ccopy infile outfile\n");
  17598.          exit(1);
  17599.          }
  17600.      if ((fp_in = fopen(argv[1], "r")) == NULL)
  17601.          {
  17602.          printf("Can't open %s for reading.\n", argv[1]);
  17603.          exit(1);
  17604.          }
  17605.      if ((fp_out = fopen(argv[2], "w")) == NULL)
  17606.          {
  17607.          printf("Can't open %s for writing.\n", argv[2]);
  17608.          exit(1);
  17609.          }
  17610.  
  17611.      printf("Copying and Crushing: %s->%s ...",
  17612.              argv[1], argv[2]);
  17613.  
  17614.      while (fgets(buf, BUFSIZ, fp_in) != NULL)
  17615.          {
  17616.          cp = buf;
  17617.          if (*cp == '\n')    /* blank line */
  17618.              continue;
  17619.          while (isspace(*cp))
  17620.              {
  17621.              ++cp;
  17622.              }
  17623.          if (*cp == '\0')    /* empty line */
  17624.              continue;
  17625.          if (fputs(cp, fp_out) == EOF)
  17626.              {
  17627.              printf("\nError writing %s.\n", argv[2]);
  17628.              exit(1);
  17629.              }
  17630.          }
  17631.      printf("Done\n");
  17632.  }
  17633.  
  17634.  
  17635.  CCOPY2.C
  17636.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP10\CCOPY2.C
  17637.  
  17638.  /* ccopy2.c  -- copies a file, cutting blank lines and    */
  17639.  /*              leading space from lines of copy          */
  17640.  
  17641.  /*              Modified to demonstrate stdout and stderr */
  17642.  
  17643.  <stdio.h>        /* for FILE, BUFSIZ, NULL */
  17644.  <ctype.h>        /* for iswhite()          */
  17645.  
  17646.  main(argc, argv)
  17647.  int argc;
  17648.  char *argv[];
  17649.  {
  17650.      FILE *fp_in, *fp_out;
  17651.      char buf[BUFSIZ];
  17652.      char *cp;
  17653.  
  17654.      if (argc < 2)
  17655.          {
  17656.          fprintf(stderr, "usage: ccopy infile {outfile}\n");
  17657.          exit(1);
  17658.          }
  17659.      if ((fp_in = fopen(argv[1], "r")) == NULL)
  17660.          {
  17661.          fprintf(stderr, "\"%s\": Can't open.\n", argv[1]);
  17662.          exit(1);
  17663.          }
  17664.      if (argc == 3)
  17665.          {
  17666.          if ((fp_out = fopen(argv[2], "w")) == NULL)
  17667.              {
  17668.              fprintf(stderr, "\"%s\": Can't open.\n", argv[2]);
  17669.              exit(1);
  17670.              }
  17671.          }
  17672.      else
  17673.          fp_out = stdout;
  17674.  
  17675.      while (fgets(buf, BUFSIZ, fp_in) != NULL)
  17676.          {
  17677.          cp = buf;
  17678.          if (*cp == '\n')    /* blank line */
  17679.              continue;
  17680.          while (isspace(*cp))
  17681.              {
  17682.              ++cp;
  17683.              }
  17684.          if (*cp == '\0')    /* empty line */
  17685.              continue;
  17686.          if (fputs(cp, fp_out) == EOF)
  17687.              {
  17688.              fprintf(stderr, "Error writing.\n");
  17689.              exit(1);
  17690.              }
  17691.          }
  17692.      if (! feof(fp_in))      /* error reading? */
  17693.          {
  17694.          fprintf(stderr, "\"%s\": Error reading.\n", argv[1]);
  17695.          exit(1);
  17696.          }
  17697.  }
  17698.  
  17699.  
  17700.  CH2000.C
  17701.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\CH2000.C
  17702.  
  17703.  /* ch2000.c -- fill screen with 2000 characters        */
  17704.  /*    This program demonstrates direct memory access   */
  17705.  /*    of video memory.  It is set up for the MDA.      */
  17706.  /*    Assign CGAMEM instead of MONMEM to screen for    */
  17707.  /*    CGA and CGA-compatible modes.                    */
  17708.  /*    Press a key to fill; press Esc to quit.          */
  17709.  /* Note: activate Screen Swapping On in Debug menu     */
  17710.  
  17711.  #include <conio.h>
  17712.  #include "scrn.h"
  17713.  typedef unsigned short (far * VIDMEM);
  17714.  MONMEM ((VIDMEM) (0xB000L << 16)) /* monochrome */
  17715.  CGAMEM ((VIDMEM) (0xB800L << 16)) /* cga, ega */
  17716.  #define ESC '\033'
  17717.  #define CHARS 2000
  17718.  AMASK 0xFF   /* keep attribute in range */
  17719.  main()
  17720.  {
  17721.       unsigned ch;          /* character to be displayed */
  17722.       unsigned attrib = 7;  /* initial attribute         */
  17723.       VIDMEM screen;        /* pointer to video RAM      */
  17724.       int offset;           /* location on screen        */
  17725.  
  17726.       screen = MONMEM;      /* monochrome initialization */
  17727.       while ((ch = getch()) != ESC)
  17728.       {
  17729.          for (offset = 0; offset < CHARS; offset++)
  17730.            *(screen + offset) = ((attrib++ & AMASK) << 8)
  17731.       }
  17732.  }
  17733.  
  17734.  
  17735.  CH2001.C
  17736.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\CH2001.C
  17737.  
  17738.  /* ch2001.c -- fill screen with 2000 characters        */
  17739.  /*    This program demonstrates direct memory access   */
  17740.  /*    of video memory.  It uses the current video mode */
  17741.  /*    value to select the proper video RAM address.    */
  17742.  /*    Press a key to fill; press Esc to quit.          */
  17743.  /* Program list: ch2001.c, scrfun.lib                  */
  17744.  /* Note: activate Screen Swapping On in Debug menu     */
  17745.  
  17746.  #include <conio.h>
  17747.  #include "scrn.h"
  17748.  typedef unsigned short (far * VIDMEM);
  17749.  MONMEM ((VIDMEM) (0xB000L << 16)) /* monochrome */
  17750.  CGAMEM ((VIDMEM) (0xB800L << 16)) /* cga, ega */
  17751.  #define ESC '\033'
  17752.  #define CHARS 2000
  17753.  #define AMASK 0xFF
  17754.  main()
  17755.  {
  17756.       unsigned ch, mode;
  17757.       unsigned attrib = 7;
  17758.       VIDMEM screen;         /* pointer to video RAM */
  17759.       int offset;
  17760.  
  17761.       if ((mode = Getvmode()) == TEXTMONO)
  17762.            screen = MONMEM;
  17763.       else if (mode == TEXTC80 || mode == TEXTBW80)
  17764.            screen = CGAMEM;
  17765.       else
  17766.            exit(1);
  17767.       while ((ch = getch()) != ESC)
  17768.            {
  17769.            for (offset = 0; offset < CHARS; offset++)
  17770.                *(screen + offset) = ((attrib++ & AMASK) << 8) | ch;
  17771.            }
  17772.  }
  17773.  
  17774.  
  17775.  CHANGE.C
  17776.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\CHANGE.C
  17777.  
  17778.  /* change.c  -- a changemaking program demonstrates   */
  17779.  /*              how pointers advance the correct      */
  17780.  /*              number of bytes based on type         */
  17781.  
  17782.  #define NCOINS (4)
  17783.  CENT (0x9b)  /* IBM PC cent character */
  17784.  #define WAIT printf("(Press any key to continue)"); \
  17785.               getch(); printf("\n\n")
  17786.  
  17787.  main()
  17788.  {
  17789.      static int coins[NCOINS] = {25, 10, 5, 1};
  17790.      int *coin_ptr, i = 0;
  17791.      int pennies1, pennies2, count;
  17792.      float amount;
  17793.  
  17794.      printf("Enter an amount and I will ");
  17795.      printf(" give you change.\nAmount: ");
  17796.      if (scanf("%f", &amount) != 1)
  17797.          {
  17798.          printf("I don't know how to change that!\n");
  17799.          exit(1);
  17800.          }
  17801.      pennies2 = pennies1 = (int)(amount * 100.0);
  17802.  
  17803.      coin_ptr = coins;
  17804.      for (i = 0; i < NCOINS; ++i)
  17805.          {
  17806.          WAIT;
  17807.          count = 0;
  17808.          while ((pennies1 -= coins[i]) >= -1)
  17809.              ++count;
  17810.          if (count > 0)
  17811.              {
  17812.              printf("%4d %2d%c", count, coins[i], CENT);
  17813.              printf(" coins by array offset.\n");
  17814.              }
  17815.          if (pennies1 == 0)
  17816.              break;
  17817.          pennies1 += coins[i];
  17818.  
  17819.          count = 0;
  17820.          while ((pennies2 -= *coin_ptr) >= -1)
  17821.              ++count;
  17822.          if (count > 0)
  17823.              {
  17824.              printf("%4d %2d%c", count, *coin_ptr, CENT);
  17825.              printf(" coins by pointer indirection.\n");
  17826.              }
  17827.          if (pennies2 == 0)
  17828.              break;
  17829.          pennies2 += *coin_ptr;
  17830.          ++coin_ptr;
  17831.          }
  17832.  }
  17833.  
  17834.  
  17835.  CHANGE2.C
  17836.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\CHANGE2.C
  17837.  
  17838.  /* change2.c -- modified to demonstrate passing       */
  17839.  /*              an address to a function              */
  17840.  
  17841.  #define NCOINS (4)
  17842.  CENT (0x9b)  /* IBM PC cent character */
  17843.  
  17844.  main()
  17845.  {
  17846.      static int coins[NCOINS] = {25, 10, 5, 1};
  17847.      int pennies;
  17848.      float amount;
  17849.  
  17850.      printf("Enter an amount and I will ");
  17851.      printf(" give you change.\nAmount: ");
  17852.      if (scanf("%f", &amount) != 1)
  17853.          {
  17854.          printf("I don't know how to change that!\n");
  17855.          exit(1);
  17856.          }
  17857.      pennies = (int)(amount * 100.0);
  17858.  
  17859.      Show_change( coins, &coins[NCOINS], pennies);
  17860.  
  17861.  }
  17862.  
  17863.  Show_change( int amts[], int *end, int due)
  17864.  {
  17865.      int count;
  17866.  
  17867.      while ( amts < end )    /* compare pointers */
  17868.          {
  17869.          count = 0;
  17870.          while ((due -= *amts) >= -1)
  17871.              {
  17872.              ++count;
  17873.              }
  17874.          if (count > 0)
  17875.              printf("%4d %2d%c\n", count, *amts, CENT);
  17876.          if (due == 0)
  17877.              break;
  17878.          due += *amts;
  17879.  
  17880.          ++amts;             /* increment a pointer */
  17881.          }
  17882.  }
  17883.  
  17884.  
  17885.  CHARS.C
  17886.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\CHARS.C
  17887.  
  17888.  /* chars.c -- shows some variables of type char */
  17889.  /*            as both characters and integers   */
  17890.  
  17891.  main()
  17892.  {
  17893.      char ch1 = 'A', ch2 = 'a';
  17894.  
  17895.      printf("The character %c has ASCII code %d\n", ch1, ch1);
  17896.      printf("If you add ten, you get %c\n", ch1 + 10);
  17897.      printf("The character %c has ASCII code %d\n", ch2, ch2);
  17898.  }
  17899.  
  17900.  
  17901.  CHOOSE.C
  17902.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\CHOOSE.C
  17903.  
  17904.  /* choose.c   --  an array of pointers to functions   */
  17905.  /*                used to create a menu               */
  17906.  
  17907.  void Choice1(), Choice2(), Choice3();
  17908.  
  17909.  void (*Dochoice[3])() = {Choice1, Choice2, Choice3};
  17910.  
  17911.  main()
  17912.      {
  17913.      int ch;
  17914.  
  17915.      printf("Select 1, 2 or 3: ");
  17916.      ch = getch(); putch(ch);
  17917.      ch -= '1';
  17918.      if (ch < 0 || ch > 2)
  17919.          printf("\nNo such choice.\n");
  17920.      else
  17921.          Dochoice[ch]();
  17922.  
  17923.  }
  17924.  
  17925.  void Choice1(void)
  17926.  {
  17927.          printf("\nThis is choice 1\n");
  17928.  }
  17929.  
  17930.  void Choice2(void)
  17931.  {
  17932.          printf("\nThis is choice 2\n");
  17933.  }
  17934.  
  17935.  void Choice3(void)
  17936.  {
  17937.          printf("\nThis is choice 3\n");
  17938.  }
  17939.  
  17940.  
  17941.  COL256.C
  17942.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\COL256.C
  17943.  
  17944.  /*  col256.c  -- show 256 colors in mode 19             */
  17945.  /* If you load graphics.qlb, no program list is needed. */
  17946.  
  17947.  #include <stdio.h>
  17948.  #include <graph.h>
  17949.  #include <conio.h>
  17950.  #define ESC '\033'
  17951.  #define ROWS 16
  17952.  #define COLS 16
  17953.  main()
  17954.  {
  17955.      struct videoconfig vc;
  17956.      int mode = _MRES256COLOR;
  17957.      short xmax, ymax;           /* screen size */
  17958.      short xcs[ROWS][COLS];      /* coordinates of the */
  17959.      short ycs[ROWS][COLS];      /* 256 rectangles     */
  17960.      short row, col;
  17961.  
  17962.  
  17963.      if (_setvideomode(mode) == 0)
  17964.          {
  17965.          fprintf(stderr, "%d mode not supported\n", mode);
  17966.          exit(1);
  17967.          }
  17968.      _getvideoconfig(&vc);
  17969.  
  17970.      xmax = vc.numxpixels - 1;
  17971.      ymax = vc.numypixels - 1;
  17972.  
  17973.      /* Compute an interior point for each rectangle. */
  17974.      for (col = 0; col < COLS; col++)
  17975.          for (row = 0; row < ROWS; row++)
  17976.              {
  17977.              xcs[row][col] =  col * xmax / COLS + 5;
  17978.              ycs[row][col] =  row * ymax / ROWS + 5;
  17979.  
  17980.              }
  17981.  
  17982.      /* draw outside boundary */
  17983.      _setcolor(1);
  17984.      _rectangle(_GBORDER, 0, 0, xmax, ymax);
  17985.  
  17986.      /* draw gridwork */
  17987.      for (col = 1; col < COLS ; col++)
  17988.          {
  17989.          _moveto(col * (xmax + 1) / COLS, 0);
  17990.          _lineto(col * (xmax + 1) / COLS, ymax);
  17991.          }
  17992.      for (row = 1; row < ROWS;  row++)
  17993.          {
  17994.          _moveto(0, row * (ymax + 1) / ROWS);
  17995.          _lineto(xmax, row * (ymax + 1) / ROWS);
  17996.          }
  17997.  
  17998.      /*  fill in rectangles with palette colors */
  17999.      for (col = 0; col < COLS; col++)
  18000.          for (row = 0; row < ROWS; row++)
  18001.              {
  18002.              _setcolor(row * ROWS + col);
  18003.              _floodfill(xcs[row][col], ycs[row][col],1);
  18004.              }
  18005.  
  18006.      /* terminate program */
  18007.      getch();
  18008.      _setvideomode(_DEFAULTMODE);
  18009.  }
  18010.  
  18011.  
  18012.  CONDITN.C
  18013.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\CONDITN.C
  18014.  
  18015.  /* conditn.c -- attempt to use conditional op */
  18016.  
  18017.  main()
  18018.  {
  18019.      int n, m;
  18020.  
  18021.      n = 2;
  18022.      m = (n != 2) : 0 ? 1;  /* almost right */
  18023.      printf("%d\n", m);
  18024.  }
  18025.  
  18026.  
  18027.  CONTINUE.C
  18028.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP05\CONTINUE.C
  18029.  
  18030.  /* continue.c -- shows CONTINUE in loop */
  18031.  
  18032.  main()
  18033.  {
  18034.      int sw = 0;
  18035.      char ch;
  18036.      while (1) /* endless loop */
  18037.      {
  18038.          /* print current status */
  18039.          if (sw)
  18040.              printf("\nSwitch is ON\n");
  18041.          else
  18042.              printf("\nSwitch is OFF\n");
  18043.  
  18044.          printf("Do you want to quit? ");
  18045.          if (ch = getche() == 'y')
  18046.              break;    /* exit loop on yes */
  18047.  
  18048.          printf("\nDo you want to toggle the switch? ");
  18049.          if (ch = getche() != 'y')
  18050.              continue; /* restart loop on yes */
  18051.  
  18052.          sw = !sw;     /* toggle switch */
  18053.          }
  18054.  }
  18055.  
  18056.  
  18057.  CONTROL.C
  18058.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\CONTROL.C
  18059.  
  18060.  /* control.c  --  demonstrate string justification */
  18061.  /*                using printf()                   */
  18062.  
  18063.  char Some_text[] = "Some Text";
  18064.  char Left_control[] =    "<<%-15s>>";
  18065.  char Right_control[] =    "<<%15s>>";
  18066.  
  18067.  main()
  18068.  {
  18069.      char ch;
  18070.  
  18071.      while (1)
  18072.          {
  18073.          printf("Select l)eft r)ight or q)uit: ");
  18074.          ch = getch();
  18075.          putch( ch );
  18076.  
  18077.          printf("\n\n");
  18078.          switch((int) ch)
  18079.              {
  18080.              case 'l':
  18081.              case 'L':
  18082.                  printf(Left_control, Some_text);
  18083.                  break;
  18084.              case 'r':
  18085.              case 'R':
  18086.                  printf(Right_control, Some_text);
  18087.                  break;
  18088.              case 'q':
  18089.              case 'Q':
  18090.                  exit (0);
  18091.              default:
  18092.                  printf("Huh?");
  18093.                  break;
  18094.              }
  18095.          printf("\n\n");
  18096.          }
  18097.  }
  18098.  
  18099.  
  18100.  CONVERT.C
  18101.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\CONVERT.C
  18102.  
  18103.  /* convert.c -- converts Farenheit temprature       */
  18104.  /*              to Centigrade; gets value from user */
  18105.  
  18106.  main()
  18107.  {
  18108.      float ftemp, ctemp;
  18109.  
  18110.      printf("What is the temprature in Farenheit? ");
  18111.      scanf("%f", &ftemp);
  18112.      ctemp = (ftemp - 32.0) * 5 / 9.0;
  18113.  
  18114.      printf("The temprature in Centigrade is %5.2f", ctemp);
  18115.  }
  18116.  
  18117.  
  18118.  DBLBAR.C
  18119.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\DBLBAR.C
  18120.  
  18121.  /* dblbar.c -- prints header using */
  18122.  /*             line() function     */
  18123.  
  18124.  #define DOUBLE_BAR 205
  18125.  
  18126.  main()
  18127.  {
  18128.      void line();       /* declare line() function */
  18129.  
  18130.      line(10);          /* call line() function    */
  18131.      printf("dblbar.c -- prints header using\n");
  18132.      printf("line() function\n");
  18133.      line(50);          /* call line() again       */
  18134.  }
  18135.  
  18136.  void line()            /* function definition     */
  18137.  {
  18138.      int pos;
  18139.      for (pos = 1; pos <= 40; pos++)
  18140.          putch(DOUBLE_BAR);
  18141.      printf("\n");
  18142.  }
  18143.  
  18144.  
  18145.  DEBUG.C
  18146.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP04\DEBUG.C
  18147.  
  18148.  
  18149.  /* DEBUG.C -- for practice with debugger */
  18150.  
  18151.  main()
  18152.  {
  18153.      char response;
  18154.      int number, max_numbers = 5, count = 0, total = 0;
  18155.      float average;
  18156.  
  18157.      printf("Continue (y/n)? ");
  18158.      response = getche();
  18159.      while ((response != 'n') && (count < max_numbers))
  18160.          printf("\nEnter a number: ");
  18161.          scanf("%d", &number);
  18162.          total += number;
  18163.          printf("Continue (y/n)? ");
  18164.          response = getche();
  18165.      average = total / count;
  18166.      printf("\nTotal is %d\n", total);
  18167.      printf("Average is %f\n", average);
  18168.  }
  18169.  
  18170.  
  18171.  
  18172.  DIALOG.C
  18173.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\DIALOG.C
  18174.  
  18175.  /* dialog.c  -- a conversation using gets() and puts()  */
  18176.  
  18177.  <stdio.h>          /* for NULL and BUFSIZ */
  18178.  
  18179.  #define THE_QUESTION \
  18180.  "And what is your view on the current price of corn\n\
  18181.  and the stability of our trade import balance?"
  18182.  
  18183.  main()
  18184.  {
  18185.      char name[BUFSIZ],
  18186.           buf[BUFSIZ];
  18187.      extern char *gets();
  18188.  
  18189.      name[0] = '\0';         /* clear the name */
  18190.  
  18191.      puts("\n\nHi there. And what is your name?");
  18192.  
  18193.      if (gets(name) != NULL && name[0] != '\0')
  18194.          {
  18195.          printf("\nPleased to meet you, %s.\n", name);
  18196.          puts(THE_QUESTION);
  18197.  
  18198.          /*
  18199.           * force an extra <enter> before replying.
  18200.           */
  18201.          do
  18202.              {
  18203.              if (gets(buf) == NULL)
  18204.                  break;
  18205.  
  18206.              } while (*buf != '\0');     /* wait for empty line */
  18207.  
  18208.          puts("Sorry. I needed to think about that.");
  18209.          printf("Nice talking to you, %s.\n", name);
  18210.          }
  18211.      else
  18212.          puts("How rude!");
  18213.  
  18214.      puts("Goodbye.");
  18215.  }
  18216.  
  18217.  
  18218.  DIGSUM.C
  18219.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\DIGSUM.C
  18220.  
  18221.  /* digsum.c -- sum digits in input                    */
  18222.  #include <stdio.h>
  18223.  main()
  18224.  {
  18225.      int ch;
  18226.      int digits = 0;  /* number of digits in input */
  18227.      int others = 0;  /* number of non-digits in input */
  18228.  
  18229.  
  18230.      while ((ch = getchar()) != EOF)
  18231.      if (ch <= '0' && ch >= '9')
  18232.              others++;
  18233.          else
  18234.              digits++;
  18235.      printf("digits = %d, others = %d", digits, others);
  18236.  }
  18237.  
  18238.  
  18239.  DIRX.C
  18240.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP10\DIRX.C
  18241.  
  18242.  /* dirx.c  --  directory examples  */
  18243.  
  18244.  #include <direct.h>
  18245.  #include <stdio.h>
  18246.  
  18247.  #define SUBDIR "SUBDIR"
  18248.  #define SUBSUBDIR "SUBSUB"
  18249.  
  18250.  main()
  18251.  {
  18252.      char *current_dir;
  18253.      void Err();
  18254.  
  18255.      if ((current_dir = getcwd(NULL, 0)) == NULL)
  18256.          Err("getcwd()", "Can't get current directory.");
  18257.  
  18258.      if (mkdir(SUBDIR) != 0)
  18259.          Err( SUBSUBDIR, "Can't make directory." );
  18260.  
  18261.      if (chdir(SUBDIR) != 0)
  18262.          Err( SUBDIR, "Can't cd into directory." );
  18263.  
  18264.      if (mkdir(SUBSUBDIR) != 0)
  18265.          Err( SUBSUBDIR, "Can't make directory." );
  18266.  
  18267.      if (chdir(current_dir) != 0)
  18268.          Err( SUBDIR, "Can't cd back to." );
  18269.  
  18270.      if (rmdir(SUBDIR) != 0)
  18271.          Err( SUBDIR, "Can't remove directory." );
  18272.  
  18273.  }
  18274.  
  18275.  void Err(char *what, char *msg)
  18276.  {
  18277.      fprintf(stderr, "\"%s\": %s\n", what, msg );
  18278.      exit (1);
  18279.  }
  18280.  
  18281.  
  18282.  DO.C
  18283.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP04\DO.C
  18284.  
  18285.  
  18286.  /* DO.C -- a simple do-while loop */
  18287.  
  18288.  main()
  18289.  {
  18290.      int i = 1;
  18291.      do
  18292.          {
  18293.          printf("%d\n", i);
  18294.          i++;
  18295.          }
  18296.      while (i < 11);
  18297.      printf("Done!\n");
  18298.  }
  18299.  
  18300.  
  18301.  
  18302.  DOTS.C
  18303.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\DOTS.C
  18304.  
  18305.  /* dots.c -- illustrates the _setcolor(), _setpixel(), */
  18306.  /*           and _selectpalette() functions from the   */
  18307.  /*           QuickC graphics library                   */
  18308.  /* If you load graphics.qlb, no program list is needed */
  18309.  
  18310.  #include <conio.h>
  18311.  #include <stdio.h>
  18312.  #include <stdlib.h>
  18313.  #include <graph.h>
  18314.  #define ESC '\033'
  18315.  BKCOLS 8      /* number of background colors */
  18316.  PALNUM 4      /* number of palettes */
  18317.  long Bkcolors[BKCOLS] = {_BLACK, _BLUE, _GREEN, _CYAN, _RED,
  18318.                           _MAGENTA, _BROWN, _WHITE};
  18319.  main (argc, argv)
  18320.  int argc;
  18321.  char *argv[];
  18322.  {
  18323.       struct videoconfig vc;
  18324.       unsigned int col, row;
  18325.       short color = 0;
  18326.       int bkc_index = 1;  /* blue background */
  18327.       short palette = 0;  /* red, green, brown */
  18328.       int firstcol, firstrow, lastrow, lastcol;
  18329.       int mode = _MRES4COLOR;
  18330.       int ch;
  18331.  
  18332.       if (argc > 1)
  18333.            mode = atoi(argv[1]);
  18334.  
  18335.       if (_setvideomode(mode) == 0)
  18336.       {
  18337.            printf("Can't do that mode.\n");
  18338.            exit(1);
  18339.       }
  18340.       _getvideoconfig(&vc);
  18341.       firstcol = vc.numxpixels / 5;
  18342.       firstrow = vc.numypixels / 5;
  18343.       lastcol = 4 * vc.numxpixels / 5;
  18344.       lastrow = 4 * vc.numypixels / 5;
  18345.       _selectpalette(palette);
  18346.       _setbkcolor (Bkcolors[bkc_index]);
  18347.       for (col = firstcol; col <= lastcol; ++col)
  18348.       {
  18349.            _setcolor((++color / 3) % vc.numcolors);
  18350.            for (row = firstrow; row <= lastrow; ++row)
  18351.                 _setpixel(col, row);
  18352.       }
  18353.       while ((ch = getch()) != ESC)
  18354.       {
  18355.            if (ch == 'p')
  18356.                  _selectpalette(++palette % PALNUM);
  18357.            else if (ch == 'b')
  18358.                  _setbkcolor(Bkcolors[++bkc_index % BKCOLS]);
  18359.       }
  18360.       _setvideomode(_DEFAULTMODE);  /* reset orig. mode */
  18361.  }
  18362.  
  18363.  
  18364.  DOWHILE.C
  18365.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\DOWHILE.C
  18366.  
  18367.  /* dowhile.c -- misuse of do while loop     */
  18368.  
  18369.  main()
  18370.  {
  18371.      int i = 0;
  18372.  
  18373.      do while (i < 10)
  18374.          {
  18375.          printf("Happy Fourth of July!\n");
  18376.          i++;
  18377.          }
  18378.      printf("VOOOM\n");
  18379.  }
  18380.  
  18381.  
  18382.  
  18383.  DOWHILE2.C
  18384.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\DOWHILE2.C
  18385.  
  18386.  /* dowhile2.c -- ok use of do while loop     */
  18387.  
  18388.  main()
  18389.  {
  18390.      int i = 0;
  18391.  
  18392.      do
  18393.          {
  18394.          printf("Happy Fourth of July!\n");
  18395.          i++;
  18396.          } while (i < 10) ;
  18397.      printf("VOOOM\n");
  18398.  }
  18399.  
  18400.  
  18401.  DRAWCHAR.C
  18402.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\DRAWCHAR.C
  18403.  
  18404.  /* drawchar.c -- drawing module for grafdraw.c         */
  18405.  /* translates keystrokes to graphic characters,        */
  18406.  /* manages cursor control and function keys            */
  18407.  
  18408.  #include <conio.h>
  18409.  #include "keys.h"
  18410.  #include "scrn.h"
  18411.  #include "grafchar.h"
  18412.  extern unsigned char Grchr[];  /* defined in grafchar.c */
  18413.  
  18414.  void Draw_chars()
  18415.  {
  18416.      int ch, chout;
  18417.      unsigned char attrib = NORMAL;
  18418.      unsigned char draw = TRUE;
  18419.  
  18420.      chout = Grchr[0];  /* default graphics character */
  18421.      while ((ch = getch()) != ESC)
  18422.          {
  18423.          if (ch >= '0' && ch <= '_')
  18424.              chout = Grchr[ch - '0'];
  18425.              /* this maps the 0 key to the first */
  18426.              /* graphics character, etc.         */
  18427.          else if (ch == SPACE)
  18428.              chout = SPACE;
  18429.          else if (ch == 0) /* process cursor keys */
  18430.              {             /* and function keys   */
  18431.              ch = getch();
  18432.              switch (ch)
  18433.                  {
  18434.                  case PU : draw = FALSE;
  18435.                            break;
  18436.                  case PD : draw = TRUE;
  18437.                            break;
  18438.                  case UP : if (draw)
  18439.                                Write_ch_atr(chout, attrib,
  18440.                                             PAGE, 1);
  18441.                            if (!Cursup())
  18442.                                putch(BEEP);
  18443.                            break;
  18444.                  case DN : if (draw)
  18445.                                Write_ch_atr(chout, attrib,
  18446.                                             PAGE, 1);
  18447.                            if (!Cursdn_lim(BOTLINE))
  18448.                                putch(BEEP);
  18449.                            break;
  18450.                  case LT : if (draw)
  18451.                                Write_ch_atr(chout, attrib,
  18452.                                             PAGE, 1);
  18453.                            if (!Curslt())
  18454.                                putch(BEEP);
  18455.                            break;
  18456.                  case RT : if (draw)
  18457.                                Write_ch_atr(chout, attrib,
  18458.                                             PAGE, 1);
  18459.                            if (!Cursrt())
  18460.                                putch(BEEP);
  18461.                            break;
  18462.                  case F1 : attrib = NORMAL; break;
  18463.                  case F2 : attrib = VIDREV; break;
  18464.                  case F3 : attrib ^= BLINK; break;
  18465.                  case F4 : attrib ^= INTENSE; break;
  18466.                  default : putch(BEEP);
  18467.                  }
  18468.              }
  18469.          }
  18470.  }
  18471.  
  18472.  
  18473.  EGATOVGA.C
  18474.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\EGATOVGA.C
  18475.  
  18476.  /* egatovga.c -- converts ega color values to vga      */
  18477.  /*               color values.                         */
  18478.  
  18479.  long Ega_to_vga(egacolor)
  18480.  int egacolor;        /* ega color value */
  18481.  {
  18482.      static long vgavals[6] = {0x2a0000L, 0x002a00L,
  18483.                           0x00002aL, 0x150000L,
  18484.                           0x001500L, 0x000015L};
  18485.       /* array holds VGA equivalents to EGA bits */
  18486.      long vgacolor = 0L; /* vga color value */
  18487.      int bit;
  18488.  
  18489.      /* convert each bit to equivalent, and sum */
  18490.      for (bit = 0; bit < 6; bit++)
  18491.          vgacolor += ((egacolor >> bit) &1) * vgavals[bit];
  18492.      return (vgacolor);
  18493.  }
  18494.  
  18495.  
  18496.  EGGS.C
  18497.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\EGGS.C
  18498.  
  18499.  /*  eggs.c -- draws colorful eggs                                      */
  18500.  /*  This program illustrates use of the video configuration            */
  18501.  /*  structure, the _ellipse() function, the effect of over-            */
  18502.  /*  lapping solid figures, and a the use of logical coordinates.       */
  18503.  /*  If you load graphics.qlb, no program list is needed.               */
  18504.  
  18505.  #include <stdio.h>
  18506.  #include <stdlib.h>
  18507.  #include <graph.h>
  18508.  #include <conio.h>
  18509.  #define ESC '\033'
  18510.  
  18511.  main(argc, argv)
  18512.  int argc;
  18513.  char *argv[];
  18514.  {
  18515.      struct videoconfig vc;
  18516.      int mode = _MRES4COLOR;
  18517.      short xcent[3], ycent[3]; /* egg centers */
  18518.      short xsize, ysize;       /* egg limits  */
  18519.      int egg;
  18520.  
  18521.      if (argc > 1)
  18522.          mode = atoi(argv[1]);
  18523.      if (_setvideomode(mode) == 0)
  18524.      {
  18525.          printf("Can't open mode %d\n", mode);
  18526.          exit(1);
  18527.      }
  18528.      _getvideoconfig(&vc);
  18529.      xsize = 0.3 * vc.numxpixels;
  18530.      ysize = 0.3 * vc.numypixels;
  18531.      xcent[0] = 0.3 * vc.numxpixels;
  18532.      xcent[1] = 0.5 * vc.numxpixels;
  18533.      xcent[2] = 0.7 * vc.numxpixels;
  18534.      ycent[0] = ycent[2] = 0.4 * vc.numypixels;
  18535.      ycent[1] = 0.6 * vc.numypixels;
  18536.  
  18537.      _selectpalette(0);
  18538.      _setbkcolor(_MAGENTA);
  18539.      for (egg = 0; egg < 3; egg++)
  18540.      {
  18541.          _setlogorg(xcent[egg], ycent[egg]);
  18542.          _setcolor(egg + 1);
  18543.          _ellipse(_GFILLINTERIOR, -xsize, -ysize, xsize, ysize);
  18544.      }
  18545.      _settextposition(24, 0);
  18546.      _settextcolor(1);
  18547.      _outtext("Strike any key to terminate.");
  18548.      getch();
  18549.      _setvideomode(_DEFAULTMODE);
  18550.  }
  18551.  
  18552.  
  18553.  ERR.C
  18554.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\ERR.C
  18555.  
  18556.  /* err.c  --  illustrates __FILE__ and __LINE__ in */
  18557.  /*            tracing a small program              */
  18558.  
  18559.  #define ERR printf("Tracing: \"%s\" line %d\n",\
  18560.                      __FILE__, __LINE__);
  18561.  main()
  18562.  {
  18563.      ERR
  18564.      err1();
  18565.      ERR
  18566.      err2();
  18567.      ERR
  18568.  }
  18569.  
  18570.  err1()
  18571.  {
  18572.      ERR
  18573.      err2();
  18574.  }
  18575.  
  18576.  err2()
  18577.  {
  18578.      ERR
  18579.  }
  18580.  
  18581.  
  18582.  EXPO.C
  18583.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\EXPO.C
  18584.  
  18585.  /* expo.c -- uses exp() function to  */
  18586.  /*            calculate powers       */
  18587.  
  18588.  main()
  18589.  {
  18590.      int expo(number, power);
  18591.      int number, power;
  18592.  
  18593.      printf("Enter a number: ");
  18594.      scanf("%d", &number);
  18595.      printf("Raise to what power? ");
  18596.      scanf("%d", &power);
  18597.  
  18598.      printf("Result: %d", expo(number, power));
  18599.  }
  18600.  
  18601.  int expo(number, power)
  18602.  {
  18603.      int count, value;
  18604.      int total = 1;      /* store value of calculation */
  18605.      if (power < 0)      /* reject negative exponents  */
  18606.          {
  18607.          printf("Error in expo(): negative exponent\n");
  18608.          return(0);
  18609.          }
  18610.  
  18611.      if (power == 0) /* any number to 0 power is 1 */
  18612.          return(1);
  18613.  
  18614.      if (power == 1) /* any number to 1 power is itself */
  18615.          return(number);
  18616.  
  18617.      /* calculate for power > 1 */
  18618.      for (count = 1; count <= power; count++)
  18619.          total *= number;
  18620.      return(total);
  18621.  }
  18622.  
  18623.  
  18624.  EXTERNAL.C
  18625.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\EXTERNAL.C
  18626.  
  18627.  /* external.c -- shows an external variable */
  18628.  
  18629.  #define PI 3.14159
  18630.  int length; /* external (global) variable */
  18631.              /* declared before main ()    */
  18632.  
  18633.  main()
  18634.      {
  18635.      void square(), triangle(), circle();
  18636.  
  18637.      printf("What length do you want to use? ");
  18638.      scanf("%d", &length);
  18639.  
  18640.      square();   /* calculate areas */
  18641.      triangle();
  18642.      circle();
  18643.      }
  18644.  
  18645.  void square()
  18646.      {
  18647.      float area;
  18648.      area = length * length;
  18649.      printf("A square with sides of %d has an area of %f\n",
  18650.              length, area);
  18651.      }
  18652.  
  18653.  void triangle()
  18654.      {
  18655.      float area;
  18656.      area = (length * length) / 2;
  18657.      printf("A right triangle with sides of %d has an area %f\n",
  18658.              length, area);
  18659.      }
  18660.  
  18661.  void circle()
  18662.      {
  18663.      float area;
  18664.      area = (length * length * PI);
  18665.      printf("A circle with radius of %d has area of %f\n",
  18666.              length, area);
  18667.      }
  18668.  
  18669.  
  18670.  FIELDS.C
  18671.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\FIELDS.C
  18672.  
  18673.  /* fields.c -- shows the same number with different */
  18674.  /*             field widths and number of decimals  */
  18675.  
  18676.  main()
  18677.  {
  18678.      float f = 123.4560;
  18679.  
  18680.      printf("%12.6f\n", f);
  18681.      printf("%8.4f\n", f);
  18682.      printf("%8.3f\n", f);
  18683.      printf("%8.2f\n", f);
  18684.  }
  18685.  
  18686.  
  18687.  FILE.C
  18688.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\FILE.C
  18689.  
  18690.  /* file.c  --  the file I/O routines for texed */
  18691.  
  18692.  Load_file()
  18693.  {
  18694.      printf("\nLoading ..... done.\n");
  18695.  }
  18696.  
  18697.  Save_file()
  18698.  {
  18699.      printf("\nSaving ...... done.\n");
  18700.  }
  18701.  
  18702.  
  18703.  FLOATS.C
  18704.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\FLOATS.C
  18705.  
  18706.  /* floats.c  -- show floating values in regular */
  18707.  /*              and exponential format          */
  18708.  
  18709.  main()
  18710.  {
  18711.      float f1 = 2500.125, f2 = 0.0033, f3 = -50.99;
  18712.  
  18713.      printf("%f\t %e\n\n", f1, f1);
  18714.      printf("%f\t %e\n\n", f2, f2);
  18715.      printf("%f\t %e\n", f3, f3);
  18716.  }
  18717.  
  18718.  
  18719.  FMENU.C
  18720.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP10\FMENU.C
  18721.  
  18722.  /* fmenu.c  --  demonstrates file renaming, etc. */
  18723.  
  18724.  #include <direct.h>
  18725.  #include <stdio.h>
  18726.  #include <string.h>
  18727.  
  18728.  #define MAXPATH (80)
  18729.  char From_name[MAXPATH],
  18730.       To_name[MAXPATH];
  18731.  
  18732.  int Input(char *prompt, char buf[])
  18733.  {
  18734.      printf("%s: ", prompt);
  18735.      if (gets(buf) == NULL || *buf == '\0')
  18736.          return (0);
  18737.      return (1);
  18738.  }
  18739.  void Rename(void)
  18740.  {
  18741.      printf("->Rename/move\n");
  18742.      if (!Input("From", From_name)) return;
  18743.      if (!Input("To", To_name)) return;
  18744.      if (rename(From_name, To_name) != 0)
  18745.          perror("RENAME");
  18746.      else
  18747.          printf("Renamed: \"%s\" -> \"%s\"\n",
  18748.                  From_name, To_name);
  18749.  }
  18750.  void Remove(void)
  18751.  {
  18752.      printf("->Remove\n");
  18753.      if (!Input("Remove", From_name)) return;
  18754.      if (!Input("Are You Sure", To_name)) return;
  18755.      if (*To_name != 'y' && *To_name != 'Y')
  18756.          return;
  18757.      if (remove(From_name) != 0)
  18758.          perror(From_name);
  18759.      else
  18760.          printf("Removed: \"%s\"\n", From_name);
  18761.  }
  18762.  void Maketemp(void)
  18763.  {
  18764.      printf("->Maketemp\n");
  18765.      if (!Input("In What Directory", From_name))
  18766.          return;
  18767.      (void)strcat(From_name, "\\XXXXXX");
  18768.      if (mktemp(From_name) == NULL)
  18769.          printf("Can't create a unique name.\n");
  18770.      else
  18771.          printf("Created: \"%s\"\n", From_name);
  18772.  }
  18773.  void Quit(void)
  18774.  {
  18775.      printf("->Quit\n");
  18776.      if (!Input("Are You Sure", From_name))
  18777.          return;
  18778.      if (*From_name != 'y' && *From_name != 'Y')
  18779.          return;
  18780.      exit(0);
  18781.  }
  18782.  
  18783.  main()
  18784.  {
  18785.      static void (*doit[])() = {Rename, Remove, Maketemp, Quit};
  18786.      int ch;
  18787.  
  18788.      while (1)
  18789.          {
  18790.          printf("--------------------------------------------\n");
  18791.          printf("1) Rename/move a file or rename a directory.\n");
  18792.          printf("2) Remove a file.\n");
  18793.          printf("3) Make a unique temporary file.\n");
  18794.          printf("4) Quit.\n");
  18795.          printf("--------------------------------------------\n");
  18796.          printf("Select: ");
  18797.  
  18798.          do
  18799.              {
  18800.              ch = getchar();
  18801.              } while (ch < '1' || ch > '4');
  18802.          getchar();    /* gobble trailing newline */
  18803.          printf("%c\n\n", ch);
  18804.          ch -= '1';
  18805.          doit[ch]();
  18806.          }
  18807.  }
  18808.  
  18809.  
  18810.  FORLOOP.C
  18811.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP04\FORLOOP.C
  18812.  
  18813.  
  18814.  /* FORLOOP.C -- a simple for loop that   */
  18815.  /*              counts to ten            */
  18816.  
  18817.  main()
  18818.  {
  18819.      int i;
  18820.      for (i = 1; i <= 10; i++)
  18821.          {
  18822.          printf("%d\n",i);  /* body of loop */
  18823.          }
  18824.      printf("All done!\n");
  18825.      /* executed when i > 10 */
  18826.  }
  18827.  
  18828.  
  18829.  
  18830.  FORMATS.C
  18831.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\FORMATS.C
  18832.  
  18833.  /* formats.c -- shows what happens when format */
  18834.  /*              doesn't match data type        */
  18835.  
  18836.  main()
  18837.  {
  18838.      int i = 5;
  18839.      printf("As integer:      %d\n", i);
  18840.      printf("As long integer: %ld\n", i);
  18841.      printf("As exponential:  %e\n", i);
  18842.      printf("As float:        %f\n", i);
  18843.  }
  18844.  
  18845.  
  18846.  GALAX.C
  18847.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP05\GALAX.C
  18848.  
  18849.  /* GALAX.C -- creates an ellipse by selecting */
  18850.  /*              from random pixels            */
  18851.  
  18852.  <graph.h> /* for graphics */
  18853.  <math.h>  /* for sqrt() */
  18854.  <conio.h> /* for kbhit() */
  18855.  
  18856.  main()
  18857.  {
  18858.      int pixels, radius = 50;
  18859.      double center_x = 320, center_y = 100,
  18860.          xpos, ypos;
  18861.      srand(0);
  18862.      _setvideomode(_HRESBW);
  18863.      _setcolor(1);
  18864.      for (pixels = 1; pixels < 25000; pixels++)
  18865.          {
  18866.          /* draws filled ellipse, due */
  18867.          /* to dimensions of hires screen */
  18868.          /* generate random location */
  18869.          xpos = rand() % 639;
  18870.          ypos = rand() % 199;
  18871.          if (sqrt /* is distance within radius? */
  18872.                ((xpos - center_x) * (xpos - center_x)
  18873.                + (ypos - center_y) * (ypos - center_y))
  18874.                < radius)
  18875.             _setpixel(xpos, ypos);
  18876.          if (kbhit() )
  18877.               break; /* exit if key pressed */
  18878.          }
  18879.      getch(); /* freeze screen until key pressed */
  18880.      _setvideomode(_DEFAULTMODE);
  18881.  }
  18882.  
  18883.  
  18884.  GETCH.C
  18885.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\GETCH.C
  18886.  
  18887.  /*     getch.c -- using getch()             */
  18888.  #include <conio.h>
  18889.  main()
  18890.  {
  18891.      int count = 1;
  18892.  
  18893.      printf("Please enter a word.\n");
  18894.      while (getch() != '\r')
  18895.          printf("%d.. ", count++);
  18896.      printf("\n%d characters altogether\n", count - 1);
  18897.  }
  18898.  
  18899.  
  18900.  GETCHAR.C
  18901.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\GETCHAR.C
  18902.  
  18903.  /*      getchar.c -- using getchar()         */
  18904.  
  18905.  #include <stdio.h>
  18906.  main()
  18907.  {
  18908.      int count = 1;
  18909.  
  18910.      printf("Please enter a word.\n");
  18911.      while (getchar() != '\n')       /* here it is */
  18912.          printf("%d.. ", count++);
  18913.      printf("\n%d characters altogether\n", count - 1);
  18914.  }
  18915.  
  18916.  
  18917.  GETCHE.C
  18918.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\GETCHE.C
  18919.  
  18920.  /*     getche.c -- using getche()             */
  18921.  <conio.h>     /* note different file included */
  18922.  main()
  18923.  {
  18924.      int count = 1;
  18925.  
  18926.      printf("Please enter a word.\n");
  18927.      while (getche() != '\r')    /* changed comparison */
  18928.          printf("%d.. ", count++);
  18929.      printf("\n%d characters altogether\n", count - 1);
  18930.  }
  18931.  
  18932.  
  18933.  GETCLOSE.C
  18934.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\GETCLOSE.C
  18935.  
  18936.  /* getclose.c -- a number game using */
  18937.  /*               random numbers      */
  18938.  
  18939.  #define TRUE 1
  18940.  #define FALSE 0
  18941.  
  18942.      /* external variables */
  18943.      int number,     /* total number in current game   */
  18944.          moves,      /* number of moves in current game*/
  18945.          target,     /* target number to reach         */
  18946.          done,       /* true if game is over           */
  18947.          score,      /* score of current game          */
  18948.          wins = 0,   /* number of games won            */
  18949.          losses = 0, /* number of games lost           */
  18950.          total = 0;  /* total score                    */
  18951.  
  18952.      char move;
  18953.  
  18954.      /* function prototype declarations */
  18955.      void intro(void);       /* tell player about game   */
  18956.      char getyn(void);       /* get yes/no response      */
  18957.      int  random(int num);   /* random between 1 and num */
  18958.      void new_target(void);  /* target number for game   */
  18959.      char get_move(void);    /* get player's move        */
  18960.      void do_move(void);     /* generate num from move   */
  18961.      void check_move(void);  /* won, lost, or continue?  */
  18962.      void show_score(void);  /* show score for game      */
  18963.      void show_total(void);  /* show total score         */
  18964.  
  18965.  main()
  18966.  {
  18967.      intro();         /* print instructions */
  18968.  
  18969.      while (TRUE)     /* new games until user quits */
  18970.          {
  18971.          printf("\nDo you want to continue? ");
  18972.          if (getyn() != 'y')
  18973.              break;   /* exit program */
  18974.  
  18975.          done = FALSE;
  18976.          number = moves = score = 0;
  18977.          new_target();  /* target number for this game */
  18978.          while (!done)  /* play one game */
  18979.              {
  18980.              get_move();/* user selects random number  */
  18981.              do_move(); /* generate random number      */
  18982.                         /* and add                     */
  18983.              check_move();  /* win, lose, or continue? */
  18984.              }
  18985.          show_score();  /* score for this game */
  18986.          show_total();  /* total score         */
  18987.          }
  18988.  }
  18989.  
  18990.  void intro(void)
  18991.  {
  18992.      printf("Welcome to Getclose\n\n");
  18993.      printf("The object of this game is to\n");
  18994.      printf("try to get as close to the target\n");
  18995.      printf("number as possible in as few\n");
  18996.      printf("moves as possible by choosing from\n");
  18997.      printf("various ranges of random numbers.\n");
  18998.      printf("You score if you get within 4 of the\n");
  18999.      printf("target; a 100 point bonus for hitting\n");
  19000.      printf("the target, but no score if you go over.\n\n");
  19001.      }
  19002.  
  19003.  char getyn(void)
  19004.                      /* get yes or no answer      */
  19005.                      /* repeats until valid entry */
  19006.  {
  19007.      char ch;  /* character to read and return */
  19008.  
  19009.      while (TRUE)
  19010.          {
  19011.          printf(" (y or n) ");
  19012.          ch = getche();
  19013.          printf("\n");
  19014.          if ((ch == 'y') || (ch == 'n'))
  19015.          /* valid response, break out of loop */
  19016.              break;
  19017.          /* give error message and loop again */
  19018.          printf("please enter ");
  19019.          }
  19020.      return(ch);
  19021.      }
  19022.  
  19023.  int random(int num)
  19024.      /* generate random number between 1 and num     */
  19025.      /* doesn't use library function srand() because */
  19026.      /* we don't want the same seed each time        */
  19027.  {
  19028.      long seconds, result;
  19029.      time(&seconds);   /* randomize with system time */
  19030.      return (abs ((int)seconds * rand() % num) + 1);
  19031.  }
  19032.  
  19033.  void new_target(void)
  19034.               /* generate a new target number */
  19035.               /* between 50 and 99            */
  19036.  {
  19037.      target = 50 + random(49);
  19038.      printf("\nYour target for this game is %d\n",
  19039.          target);
  19040.  }
  19041.  
  19042.  char get_move(void)
  19043.      {
  19044.      while (TRUE)
  19045.          {
  19046.          printf("\nPick a random number from 1 to\n");
  19047.          printf("a) 5  b) 10  c) 25  d) 50  e) 100 ");
  19048.          move = getche();
  19049.          if ((move >= 'a') && (move <= 'e'))
  19050.              {
  19051.              ++moves; /* count the move */
  19052.              break;   /* valid response */
  19053.              }
  19054.          /* invalid response, try again */
  19055.          printf("\nPlease type a, b, c, d, or e\n");
  19056.          }
  19057.  }
  19058.  
  19059.  void do_move(void)
  19060.      {
  19061.      int num = 0;  /* random value to obtain */
  19062.      switch (move)
  19063.          {
  19064.          case 'a' :
  19065.              num = random(5);
  19066.              break;
  19067.          case 'b' :
  19068.              num = random(10);
  19069.              break;
  19070.          case 'c' :
  19071.              num = random(25);
  19072.              break;
  19073.          case 'd' :
  19074.              num = random(50);
  19075.              break;
  19076.          case 'e' :
  19077.              num = random(100);
  19078.              break;
  19079.          }
  19080.      number += num;  /* add new number to total */
  19081.      printf("\n\nYou got a %d. Number is now: %d ", num, number);
  19082.      printf("(Target is %d)\n", target);
  19083.  }
  19084.  
  19085.  void check_move(void)
  19086.  {
  19087.      int temp;
  19088.      if (number > target)
  19089.          {
  19090.          printf("\nYou went over! ");
  19091.          printf("No score this game.\n");
  19092.          losses++;
  19093.          done = TRUE; /* to break out of loop */
  19094.          }
  19095.      if (number == target)
  19096.          {
  19097.          printf("\nYou hit the target ");
  19098.          printf("for 100 bonus points!\n");
  19099.          score = (100 / moves) + 100;
  19100.          total += score;
  19101.          wins++;
  19102.          done = TRUE;
  19103.          }
  19104.      if ((number >= (target - 4)) && (number < target))
  19105.          {
  19106.          temp = 100 / moves;
  19107.          /* does player want to go for broke? */
  19108.          printf("\nTake %d points (y) or continue (n)? ",
  19109.              temp);
  19110.          if (getyn() == 'y')
  19111.              {
  19112.              score = temp;
  19113.              total += score;
  19114.              wins++;
  19115.              done = TRUE;
  19116.              }
  19117.         }
  19118.  }
  19119.  
  19120.  void show_score(void)
  19121.  {
  19122.      printf("\nYou scored %d points in %d moves.\n",
  19123.          score, moves);
  19124.  }
  19125.  
  19126.  void show_total(void)
  19127.  {
  19128.      printf("You have won %d games ", wins);
  19129.      printf("and lost %d.\n", losses);
  19130.      printf("Your total score is %d\n", total);
  19131.  }
  19132.  
  19133.  
  19134.  GETPUT.C
  19135.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\GETPUT.C
  19136.  
  19137.  /*  getput.c -- illustrates _getimage(), _putimage(), */
  19138.  /*              the image-background interaction, and */
  19139.  /*              the aspect ratio                      */
  19140.  /* If you load graphics.qlb, no program list is needed*/
  19141.  
  19142.  #include <stdio.h>
  19143.  <stdlib.h>  /* declares malloc()  */
  19144.  #include <graph.h>
  19145.  #include <conio.h>
  19146.  #define ESC '\033'
  19147.  
  19148.  /* The following variables describe various          */
  19149.  /* coordinates and sizes.                            */
  19150.  /* They are declared externally so that they can be  */
  19151.  /* shared easily by several functions.               */
  19152.  int X1, Yb1, X2, Y2, Xdelta, Xside, Yside; /* image  */
  19153.  int Xmid, Xmax, Ymid, Ymax;           /* background  */
  19154.  int Xps, Xpr, Xand, Xor, Xxor, Ytop, Ybot; /* copies */
  19155.  int X[3], Y[3];
  19156.  float Ar;    /* aspect ratio */
  19157.  
  19158.  struct videoconfig Vc;
  19159.  char Mask[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0};
  19160.  void Initialize(void), Drawfig(void),
  19161.        Drawbackground(void), Drawcopies(void);
  19162.  
  19163.  main(argc, argv)
  19164.  int argc;
  19165.  char *argv[];
  19166.  {
  19167.      int mode = _MRES4COLOR;
  19168.  
  19169.      if (argc > 1)
  19170.          mode = atoi(argv[1]);
  19171.      if (_setvideomode(mode) == 0)
  19172.      {
  19173.          fprintf(stderr, "Can't handle mode %d\n", mode);
  19174.          exit(1);
  19175.      }
  19176.      Initialize();
  19177.      Drawfig();
  19178.      Drawbackground();
  19179.      Drawcopies();
  19180.      _settextposition(1, 1);
  19181.      _outtext("Press a key to end");
  19182.      _settextposition(3, 1);
  19183.      _outtext("_GPSET _GPRESET _GAND");
  19184.      _settextposition(11, 5);
  19185.      _outtext("_GOR _GXOR");
  19186.      getch();
  19187.      _setvideomode(_DEFAULTMODE);
  19188.  }
  19189.  
  19190.  void Initialize()
  19191.  {
  19192.      _getvideoconfig(&Vc);
  19193.      Ar = (float) (10 * Vc.numypixels)/
  19194.            (6.5 * Vc.numxpixels);
  19195.      _setlogorg(0, 0);
  19196.      Xmid = Vc.numxpixels / 2;
  19197.      Ymid = Vc.numypixels / 2;
  19198.      Xmax = Vc.numxpixels - 1;
  19199.      Ymax = Vc.numypixels - 1;
  19200.      /* locate three background rectangles */
  19201.      X[0] = Xmid;
  19202.      Y[0] = 0;
  19203.      X[1] = Xmid;
  19204.      Y[1] = Ymid;
  19205.      X[2] = 0;
  19206.      Y[2] = Ymid;
  19207.      X1 = 0.2 * Vc.numxpixels;
  19208.      Yb1 = 0.2 * Vc.numypixels;
  19209.      Xdelta = 0.033 * Vc.numxpixels;
  19210.      Xside = 3 * Xdelta;
  19211.      Yside = 3 * Ar * Xdelta;
  19212.      X2 = X1 + Xside;
  19213.      Y2 = Yb1 + Yside;
  19214.      /* offsets for _putimage() */
  19215.      Xps = .05 * Vc.numxpixels;
  19216.      Xpr = .20 * Vc.numxpixels;
  19217.      Xand = 0.35 * Vc.numxpixels;
  19218.      Xor = .10 * Vc.numxpixels;
  19219.      Xxor = .30 * Vc.numxpixels;
  19220.      Ytop = .05 * Vc.numypixels;
  19221.      Ybot = 2 * Ytop + Yside;
  19222.      _selectpalette(0);
  19223.  }
  19224.  
  19225.  void Drawfig()
  19226.  {
  19227.      _setcolor(1);
  19228.      _rectangle(_GFILLINTERIOR, X1, Yb1,
  19229.                 X1 + Xdelta , Y2);
  19230.      _setcolor(2);
  19231.      _rectangle(_GFILLINTERIOR,X1 + Xdelta + 1, Yb1,
  19232.                 X1 + 2 * Xdelta, Y2);
  19233.      _setcolor(3);
  19234.      _rectangle(_GFILLINTERIOR,X1 +  2 * Xdelta + 1,
  19235.                 Yb1, X2, Y2);
  19236.  
  19237.  }
  19238.  
  19239.  void Drawbackground()
  19240.  {
  19241.      _setfillmask(Mask);
  19242.      _setcolor(1);
  19243.      _rectangle(_GFILLINTERIOR, Xmid, 0, Xmax - 1, Ymid - 1);
  19244.      _setcolor(2);
  19245.      _rectangle(_GFILLINTERIOR, Xmid, Ymid, Xmax, Ymax);
  19246.      _setcolor (3);
  19247.      _rectangle(_GFILLINTERIOR, 0, Ymid, Xmid - 1, Ymax);
  19248.  
  19249.  }
  19250.  
  19251.  void Drawcopies()
  19252.  {
  19253.      int quad;   /* quadrant used */
  19254.      char far *storage;
  19255.  
  19256.      storage = (char far *) malloc((unsigned)_imagesize(
  19257.                 X1, Yb1, X2, Y2));
  19258.      _getimage(X1, Yb1, X2, Y2, storage);
  19259.  
  19260.      for (quad = 0; quad < 3; quad++)
  19261.          {
  19262.          _putimage(X[quad] + Xps, Y[quad] + Ytop,
  19263.                    storage, _GPSET);
  19264.          _putimage(X[quad] + Xpr, Y[quad] + Ytop,
  19265.                    storage, _GPRESET);
  19266.          _putimage (X[quad] + Xand, Y[quad] + Ytop,
  19267.                     storage, _GAND);
  19268.          _putimage (X[quad] + Xor, Y[quad] + Ybot,
  19269.                     storage, _GOR);
  19270.          _putimage(X[quad] + Xxor, Y[quad] + Ybot,
  19271.                    storage, _GXOR);
  19272.          }
  19273.  }
  19274.  
  19275.  
  19276.  GETYN.C
  19277.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\GETYN.C
  19278.  
  19279.  /* getyn.c -- calls char function getyn()    */
  19280.  /*               with error checking         */
  19281.  
  19282.  #define TRUE 1
  19283.  
  19284.  main()
  19285.  {
  19286.      char ch;
  19287.      char getyn();
  19288.  
  19289.      printf("Do you want to continue? ");
  19290.      if ((ch = getyn()) == 'y')
  19291.          printf("Answer was y\n");
  19292.      else
  19293.          printf("Answer was n\n");
  19294.      printf("Value of ch was %c\n", ch);
  19295.  }
  19296.  
  19297.  char getyn()
  19298.  {
  19299.      char ch;
  19300.      while (TRUE)
  19301.          {
  19302.          printf(" (y or n) ");
  19303.          ch = getche();
  19304.          printf("\n");
  19305.          if ((ch == 'y') || (ch == 'n'))
  19306.          /* valid response, break out of loop */
  19307.              break;
  19308.          /* give error message and loop again */
  19309.          printf("please enter ");
  19310.          }
  19311.      return(ch);
  19312.  }
  19313.  
  19314.  
  19315.  GRAPHBOX.C
  19316.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP04\GRAPHBOX.C
  19317.  
  19318.  
  19319.  /* GRAPHBOX.C -- defined to use PC-specific */
  19320.  /*               graphics characters        */
  19321.  
  19322.  #define NL 10
  19323.  #define CR 13
  19324.  #define BLANK 32
  19325.  #define UPLEFT 201
  19326.  #define UPRIGHT 187
  19327.  #define LOWLEFT 200
  19328.  #define LOWRIGHT 188
  19329.  #define LINE 205
  19330.  #define SIDE 186
  19331.  
  19332.  main()
  19333.  {
  19334.      int i, j, height, width;
  19335.  
  19336.      /* get height and width from user */
  19337.      printf("How high a box do you want? ");
  19338.      scanf("%d", &height);
  19339.      printf("How wide do you want it to be? ");
  19340.      scanf("%d", &width);
  19341.  
  19342.      /* draw top of box */
  19343.      putch(UPLEFT);
  19344.      for (i = 0; i < (width - 2); i++)
  19345.          putch(LINE);
  19346.      putch(UPRIGHT);
  19347.      putch(NL);
  19348.      putch(CR); /* go to next line */
  19349.  
  19350.      /* draw sides of box */
  19351.      for (i = 0; i < height - 2; i++)  /* outer loop */
  19352.          {
  19353.          putch(SIDE); /* left side */
  19354.          for (j = 0; j < (width - 2); j++) /* inner loop */
  19355.              {
  19356.              putch(BLANK);
  19357.              }
  19358.          putch(SIDE); /* right side */
  19359.          putch(NL);
  19360.          putch(CR); /* move to next line */
  19361.          }
  19362.  
  19363.      /* draw bottom of box */
  19364.      putch(LOWLEFT);
  19365.      for (i = 0; i < (width - 2); i++)
  19366.          putch(LINE);
  19367.      putch(LOWRIGHT);
  19368.      putch(NL);
  19369.      putch(CR); /* box is done, move cursor to new line */
  19370.  }
  19371.  
  19372.  
  19373.  
  19374.  GRAPHCHA.C
  19375.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\GRAPHCHA.C
  19376.  
  19377.  /*   grafchar.c -- draws graphics characters with      */
  19378.  /*                 attributes on the screen            */
  19379.  /*  Program list : grafchar.c, initstuf.c, drawchar.c, */
  19380.  /*                  scrfun.c                           */
  19381.  /*  User include files: keys.h, scrn.h, grafchar.h     */
  19382.  /*  Note: activate Screen Swapping On in Debug menu    */
  19383.  
  19384.  #include "grafchar.h"
  19385.  unsigned char Grchr[NUMCHARS];  /* to store graphics set */
  19386.  void Init_stuff(void);      /* in initstuf.c */
  19387.  void Draw_chars(void);      /* in drawchar.c */
  19388.  
  19389.  main()
  19390.  {
  19391.      Init_stuff();  /* initialize vital elements */
  19392.      Draw_chars();  /* map keys to graphics characters */
  19393.  }
  19394.  
  19395.  
  19396.  HARDWARE.C
  19397.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\HARDWARE.C
  19398.  
  19399.  /* hardware.c -- shows a mixture of int, */
  19400.  /*               float, and char types   */
  19401.  
  19402.  main()
  19403.  {
  19404.      int threads    = 8;       /* threads per inch */
  19405.      float length   = 1.25,    /* length in inches */
  19406.            diameter = 0.425,   /* diameter in inches */
  19407.            price    = 0.89;    /* price per hundred */
  19408.      char bin = 'A';           /* kept in bin A */
  19409.      long quantity = 42300;    /* number in bin */
  19410.  
  19411.      printf("Screws: %d threads/inch\n%f inches long\n",
  19412.              threads, length);
  19413.      printf("%f diameter\n\n", diameter);
  19414.      printf("Price per 100: %f\n", price);
  19415.      printf("Stored in bin: %c\nQuantity on hand: %ld",
  19416.              bin, quantity);
  19417.  }
  19418.  
  19419.  
  19420.  HELLO.C
  19421.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\HELLO.C
  19422.  
  19423.  /* hello.c  --  legal ways to initialize strings as */
  19424.  /*              arrays of char values               */
  19425.  
  19426.  char Gphrase[] = {
  19427.      'H','e','l','l','o','\n','\0' };    /* global initialization */
  19428.  
  19429.  main()
  19430.  {
  19431.      static char gphrase[] = {
  19432.          'h','e','l','l','o','\n','\0' };    /* local initialization */
  19433.  
  19434.      printf("Global: %s\n", Gphrase);
  19435.      printf("Local:  %s\n", gphrase);
  19436.  
  19437.  }
  19438.  
  19439.  
  19440.  HELP.C
  19441.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\HELP.C
  19442.  
  19443.  /*  help.c -- uses paging and direct memory access    */
  19444.  /*            to display a help screen                */
  19445.  /*  Program list: help.c, writestr.c, writechr.c,     */
  19446.  /*                scrfun.c                            */
  19447.  /*  User include files: scrn.h, color.h               */
  19448.  /*  Note: activate Screen Swapping On in Debug menu   */
  19449.  
  19450.  #include <stdio.h>
  19451.  #include <conio.h>
  19452.  #include "color.h"
  19453.  #include "scrn.h"
  19454.  typedef unsigned int (far * VIDMEM);
  19455.  #define CGAMEM ((VIDMEM) (0xB800L << 16))
  19456.  #define PAGESIZE 2000
  19457.  #define PAGEOFFSET  0x800L
  19458.  #define ESC '\033'
  19459.  #define ATTR1 (BG_BLUE | YELLOW)
  19460.  #define ATTR2 (BG_YELLOW | BLUE)
  19461.  #define ATTR3 (BG_RED | YELLOW | BLINK | INTENSE)
  19462.  #define CH1  (unsigned short) '\xB1'
  19463.  char *str1 = "Press ? key for help.";
  19464.  char *str2 = "Press Enter key to return.";
  19465.  char *str3 = "Press Esc key to quit.";
  19466.  char *str4 = "\xB1HELP!\xB1";
  19467.  void Write_chars(VIDMEM, unsigned short, unsigned
  19468.                      short, unsigned short);
  19469.  void Write_str(VIDMEM, unsigned short, char *);
  19470.  
  19471.  main()
  19472.  {
  19473.      int ch;
  19474.      unsigned char page = 0;
  19475.      unsigned char mode;
  19476.  
  19477.      mode = Getvmode();
  19478.      if (mode != TEXTC80 && mode != TEXTBW80)
  19479.      {
  19480.          printf("Only modes 2 and 3 supported. Bye.\n");
  19481.          exit(1);
  19482.      }
  19483.      Setpage (page);
  19484.      Write_chars(CGAMEM, '\0', ATTR2, PAGESIZE);
  19485.      Write_str(CGAMEM + 2 * COLS, ATTR1, str1);
  19486.      Write_str(CGAMEM + 2 * COLS, ATTR1, str1);
  19487.      Write_str(CGAMEM + 22 * COLS, ATTR1, str3);
  19488.      Write_chars(CGAMEM + PAGEOFFSET, '\0', ATTR1, PAGESIZE);
  19489.      Write_str(CGAMEM + PAGEOFFSET + 20 * COLS, ATTR2, str2);
  19490.      Write_str(CGAMEM + PAGEOFFSET + 22 * COLS, ATTR1, str3);
  19491.      Write_chars(CGAMEM + PAGEOFFSET + 10 * COLS + 36,
  19492.                  CH1, ATTR3, 7);
  19493.      Write_str(CGAMEM + PAGEOFFSET + 11 * COLS + 36,
  19494.                ATTR3, str4);
  19495.      Write_chars(CGAMEM + PAGEOFFSET + 12 * COLS + 36,
  19496.                  CH1, ATTR3, 7);
  19497.  
  19498.      while ((ch = getch()) != ESC)
  19499.          {
  19500.          if (ch == '?' && page == 0)
  19501.              Setpage (page = 1);
  19502.          else if (ch == '\r' && page == 1)
  19503.              Setpage(page = 0);
  19504.          }
  19505.      Write_chars(CGAMEM, '\0', NORMAL, PAGESIZE);
  19506.      Write_chars(CGAMEM + PAGEOFFSET, '\0', NORMAL, PAGESIZE);
  19507.  }
  19508.  
  19509.  
  19510.  HEXOUT.C
  19511.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP07\HEXOUT.C
  19512.  
  19513.  /* hexout.c --  print a floating point variable in */
  19514.  /*              hexadecimal format                 */
  19515.  
  19516.  extern void Hexout();
  19517.  
  19518.  main()
  19519.  {
  19520.      float fary[1];
  19521.  
  19522.      printf("Enter a floating point number\n");
  19523.      printf("(Any nonnumeric entry quits)\n\n");
  19524.      while (scanf("%f", &fary[0]) == 1)
  19525.          {
  19526.          Hexout(fary);
  19527.          }
  19528.      return (0);
  19529.  }
  19530.  
  19531.  void Hexout(unsigned char chary[])
  19532.  {
  19533.      int i;
  19534.  
  19535.      for (i = 0; i < sizeof(float); ++i)
  19536.          {
  19537.          printf("%02X ", chary[i]);
  19538.          }
  19539.      printf("\n\n");
  19540.  }
  19541.  
  19542.  
  19543.  IBMIQ.C
  19544.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\IBMIQ.C
  19545.  
  19546.  /* ibmiq.c -- a short dialog                          */
  19547.  
  19548.  #include <stdio.h>
  19549.  main()
  19550.  {
  19551.      char name[80];
  19552.      int iq;
  19553.  
  19554.      printf("Enter your first name: -> ");
  19555.      scanf("%s", name);
  19556.      printf("Enter your IQ: -> ");
  19557.      scanf("%d", iq);
  19558.      printf("Well, %s, my IQ is %d!", name, 2 * iq - 1 );
  19559.  }
  19560.  
  19561.  
  19562.  IF.C
  19563.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP05\IF.C
  19564.  
  19565.  /* if.c -- simple IF statement */
  19566.  
  19567.  char ch;
  19568.  main()
  19569.  {
  19570.      printf("Do you want to continue y/n? "); /* prompt */
  19571.      if (ch = getche() == 'y')
  19572.          printf("\nLet's continue ...\n");    /* if true */
  19573.      printf("\nAll done.\n");                 /* always executed */
  19574.  }
  19575.  
  19576.  
  19577.  IFELSE.C
  19578.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP05\IFELSE.C
  19579.  
  19580.  /* ifelse.c -- IF with ELSE */
  19581.  
  19582.  char ch;
  19583.  int num;
  19584.  main()
  19585.  {
  19586.      printf("Are you a new user? y/n? ");
  19587.      if (ch = getche() == 'y')
  19588.          {
  19589.          /* executed if IF is true */
  19590.          printf("\n\nYou must register to use this\n");
  19591.          printf("bulletin board. Please read\n");
  19592.          printf("Bulletin #1 first. Thank You.\n");
  19593.          }
  19594.      else
  19595.          /* executed if IF is false */
  19596.          {
  19597.          printf("\n\nEnter your secret number: ");
  19598.          scanf("d", &num);
  19599.          }
  19600.  }
  19601.  
  19602.  
  19603.  INCDEC.C
  19604.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\INCDEC.C
  19605.  
  19606.  /* incdec.c -- shows effect of            */
  19607.  /*             increments and decrements  */
  19608.  
  19609.  main()
  19610.  {
  19611.      int a = 10;
  19612.  
  19613.      printf("a is %d\n", a);
  19614.      printf("++a is %d\n", ++a);
  19615.      printf("--a sets a back to %d\n", --a);
  19616.  }
  19617.  
  19618.  
  19619.  INDEXER.C
  19620.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\INDEXER.C
  19621.  
  19622.  /* indexer.c -- use indices to display an array      */
  19623.  
  19624.  #include <stdio.h>
  19625.  int code1[] = {2, 4, 6, 8};
  19626.  int code2[] = {1, 3, 7, 9};
  19627.  int code3[] = {5, 10, 15, 20};
  19628.  main()
  19629.  {
  19630.      int index;
  19631.      int size = (sizeof code2) / (sizeof (int));
  19632.  
  19633.      for ( index = 1; index <= size; size++)
  19634.         printf("%3d ", code2[index]);
  19635.      putchar('\n');
  19636.  }
  19637.  
  19638.  
  19639.  
  19640.  INDEXER2.C
  19641.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\INDEXER2.C
  19642.  
  19643.  /* indexer2.c -- use indices to display an array      */
  19644.  
  19645.  #include <stdio.h>
  19646.  int code1[] = {2, 4, 6, 8};
  19647.  int code2[] = {1, 3, 7, 9};
  19648.  int code3[] = {5, 10, 15, 20};
  19649.  main()
  19650.  {
  19651.      int index;
  19652.      int size = (sizeof code2) / (sizeof (int));
  19653.                  /* get number of elements in array */
  19654.  
  19655.      for ( index = 1; index <= size; index++)
  19656.         printf("%3d ", code2[index]);
  19657.      putchar('\n');
  19658.  }
  19659.  
  19660.  
  19661.  INFLATE.C
  19662.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP04\INFLATE.C
  19663.  
  19664.  
  19665.  /* INFLATE.C -- shows multiple initialization */
  19666.  /*              and calculations in for loop  */
  19667.  
  19668.  main()
  19669.  {
  19670.      int year;
  19671.      float value, rate;
  19672.      printf("What do you think the inflation rate will be?");
  19673.      scanf("%f", &rate);
  19674.      printf("If the dollar is worth 100 cents in 1987\n");
  19675.      printf("and the inflation rate is %2.2f, then:\n", rate);
  19676.  
  19677.      for (year=1988, value = 1.0; year <=1999;
  19678.           value *= (1.0 - rate),
  19679.           printf("in %d the dollar will be worth", year),
  19680.           printf(" %2.0f cents\n", value * 100),
  19681.           ++year
  19682.           );
  19683.  }
  19684.  
  19685.  
  19686.  
  19687.  INITSTUF.C
  19688.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\INITSTUF.C
  19689.  
  19690.  /*  initstuf.c -- initializing module for grafchar.c */
  19691.  /*  assign graphics character codes to an array      */
  19692.  /*  and initialize screen                            */
  19693.  
  19694.  "scrn.h"   /* Clearscr(), Home(), Setcurs() */
  19695.  #include "grafchar.h"
  19696.  extern unsigned char Grchr[];  /* defined in grafchar.c */
  19697.  void Print_attr(char *, unsigned char, unsigned char);
  19698.  void Init_stuff()
  19699.  {
  19700.      int i;
  19701.  
  19702.      /* initialize array with graphics characters */
  19703.      for (i = 0; i < NUMCHARS; i++)
  19704.          Grchr[i] = GCSTART + i;
  19705.      Clearscr();
  19706.      Home();
  19707.  
  19708.      /*   show key meanings at bottom of screen */
  19709.      Setcurs(BOTLINE + 1, 0, PAGE);
  19710.      for (i = 0; i < 40; i++) /* graphics chars */
  19711.      {
  19712.          putch(Grchr[i]);
  19713.          putch(SPACE);
  19714.      }
  19715.      Setcurs(BOTLINE + 2, 0, PAGE);
  19716.      for (i = 0; i < 40; i++)  /* key assignments */
  19717.      {
  19718.          putch('0' + i);
  19719.          putch(SPACE);
  19720.      }
  19721.      Setcurs(BOTLINE + 3, 0, PAGE);
  19722.      for (i = 40; i < NUMCHARS; i++) /* second row */
  19723.      {
  19724.          putch(Grchr[i]);
  19725.          putch(SPACE);
  19726.      }
  19727.          /* show function key assignments */
  19728.      printf(" SPACE : ERASE  PgUp : No Draw ");
  19729.      printf(" PgDn : Draw  ESC : Quit");
  19730.      Setcurs(BOTLINE + 4, 0, PAGE);
  19731.      for (i = 40; i < NUMCHARS; i++) /* second row */
  19732.      {
  19733.          putch('0' + i);
  19734.          putch(SPACE);
  19735.      }
  19736.         /* more function key assignments */
  19737.      Print_attr("F1 : Normal ", NORMAL, PAGE);
  19738.      Print_attr("F2 : Reverse Video ", VIDREV, PAGE);
  19739.      Setcurs(BOTLINE + 5, 16, PAGE);
  19740.      Print_attr("F3 : Blinking ", NORMAL | BLINK, PAGE);
  19741.      Print_attr("F4 : Intense ", NORMAL | INTENSE, PAGE);
  19742.      Home();
  19743.  }
  19744.  
  19745.  void Print_attr(str, attr, page)
  19746.  char *str;
  19747.  unsigned char attr, page;
  19748.  {
  19749.      while (*str != '\0')
  19750.      {
  19751.          Write_ch_atr(*str++, attr, page, 1);
  19752.          Cursrt();
  19753.      }
  19754.  }
  19755.  
  19756.  
  19757.  INTVARS.C
  19758.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\INTVARS.C
  19759.  
  19760.  /* intvars.c -- declare, define, and print */
  19761.  /*              some integer variables     */
  19762.  
  19763.  main()
  19764.  {
  19765.      /* declare variables */
  19766.      int length, beam;
  19767.      unsigned int displacement;
  19768.      /* assign values to variables */
  19769.      length = 824;
  19770.      beam = 118;
  19771.      displacement = 41676;
  19772.  
  19773.      /* print out values */
  19774.      printf("The battleship Bismarck was %d feet long",
  19775.              length);
  19776.      printf(" with a beam of %d feet,\n", beam);
  19777.      printf("and displaced %u tons.\n", displacement);
  19778.  }
  19779.  
  19780.  
  19781.  INVERT.C
  19782.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\INVERT.C
  19783.  
  19784.  /* invert.c  --  combines character classification and */
  19785.  /*               transformation to invert text         */
  19786.  
  19787.  <stdio.h>         /* for NULL           */
  19788.  <ctype.h>         /* for toupper, et al */
  19789.  
  19790.  main()
  19791.  {
  19792.      char buf[BUFSIZ];
  19793.      int i;
  19794.  
  19795.      printf("Type in a line of text and I will invert it.\n");
  19796.  
  19797.      if (gets(buf) == NULL)
  19798.          exit(1);
  19799.  
  19800.      /* Print the string backwards. */
  19801.      for (i = (strlen(buf) -1); i >= 0; --i)
  19802.          {
  19803.          if (isupper(buf[i]))            /* upper to lower */
  19804.              putchar(tolower(buf[i]));
  19805.          else if (islower(buf[i]))       /* lower to upper */
  19806.              putchar(toupper(buf[i]));
  19807.          else
  19808.              putchar(buf[i]);
  19809.          }
  19810.      putchar('\n');
  19811.  
  19812.  }
  19813.  
  19814.  
  19815.  KEYS.C
  19816.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\KEYS.C
  19817.  
  19818.  /* keys.c  --   The keyboard input-handling routines  */
  19819.  /*              for the texed editor.                 */
  19820.  
  19821.  Edit_file()
  19822.  {
  19823.      char ch;
  19824.  
  19825.      printf("\nYou are now in the editor.\n");
  19826.      printf("Press 'Q' to exit back to main menu.\n");
  19827.  
  19828.      do
  19829.          {
  19830.          ch = getch();
  19831.          putch(ch);
  19832.          } while (ch != 'Q');
  19833.  
  19834.      printf("\n\n");
  19835.  }
  19836.  
  19837.  
  19838.  L2WORDS.C
  19839.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\L2WORDS.C
  19840.  
  19841.  /* l2words.c  --  employ an array of pointers to   */
  19842.  /*                strings to bust a line of text   */
  19843.  /*                into its component words         */
  19844.  
  19845.  <stdio.h>          /* for NULL and BUFSIZ */
  19846.  
  19847.  main()
  19848.  {
  19849.      char **Line2words();    /* declare function type */
  19850.      char **list;            /* pointer to pointer    */
  19851.      char buf[BUFSIZ];       /* buffer for input      */
  19852.      int  count, i, quote_flag;
  19853.  
  19854.      printf("Enter a line of text and I will break\n");
  19855.      printf("it up for you.\n");
  19856.  
  19857.      if (gets(buf) == NULL)
  19858.          exit(1);
  19859.  
  19860.      list = Line2words(buf, &count);
  19861.  
  19862.      for (i = 0; i < count; i++)
  19863.          {
  19864.          quote_flag = 0;
  19865.          printf("<");
  19866.          if (list[i] != buf)
  19867.              {
  19868.              if( list[i][-1] == '"')    /* negative subscript */
  19869.                  {
  19870.                  ++quote_flag;
  19871.                  printf("\"");
  19872.                  }
  19873.              }
  19874.          printf("%s", list[i]);
  19875.  
  19876.          if (quote_flag)
  19877.              printf("\"");
  19878.  
  19879.          printf(">\n");
  19880.          }
  19881.  }
  19882.  
  19883.  #define MAXW 64
  19884.  
  19885.  char **Line2words(char *line, int  *count)
  19886.  {
  19887.      static char *words[MAXW];
  19888.      int  index;
  19889.  
  19890.      index = 0;        /* zero internal index */
  19891.  
  19892.      while (*line != '\0')
  19893.          {
  19894.          /* turn spaces and tabs into zeros */
  19895.          if (*line == ' ' || *line == '\t')
  19896.              {
  19897.              *(line++) = '\0';
  19898.              continue;
  19899.              }
  19900.          words[index] = line++;    /* found a word */
  19901.  
  19902.          /* is it quoted? */
  19903.          if ( *(words[index]) == '"')
  19904.              {
  19905.              /* Yes, advance pointer to just past quote. */
  19906.              ++words[index];
  19907.  
  19908.              /* find next quote. */
  19909.              while (*line && *line != '"')
  19910.                  {
  19911.                  ++line;
  19912.                  }
  19913.  
  19914.              /* and turn it into a '\0'. */
  19915.              if (*line)
  19916.                  *(line++) = '\0';
  19917.              }
  19918.          else
  19919.              {
  19920.              /* otherwise skip to next space */
  19921.              while (*line && *line != ' ' && *line != '\t')
  19922.                  {
  19923.                  ++line;
  19924.                  }
  19925.              }
  19926.          if (++index == MAXW)
  19927.              break;
  19928.          }
  19929.      *count = index;        /* set count via pointer   */
  19930.      return (words);        /* return address of array */
  19931.  }
  19932.  
  19933.  
  19934.  LEFTSTR.C
  19935.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\LEFTSTR.C
  19936.  
  19937.  /* leftstr.c -- a C version of BASIC's LEFT$ */
  19938.  
  19939.  #include <stdio.h>
  19940.  
  19941.  char *Leftstr(char *str, int cnt)
  19942.  {
  19943.      static char *cp = NULL;
  19944.      char *malloc();
  19945.  
  19946.      if (cnt > strlen(str))
  19947.          cnt = strlen(str);
  19948.      if (cp != NULL)
  19949.          free(cp);
  19950.      if ((cp = malloc(cnt + 1)) == NULL)
  19951.          return (NULL);
  19952.      strncpy(cp, str, cnt);
  19953.      return (cp);
  19954.  }
  19955.  
  19956.  
  19957.  LINES.C
  19958.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\LINES.C
  19959.  
  19960.  /* lines.c -- calls line() with */
  19961.  /*            five parameters   */
  19962.  
  19963.  #include <graph.h>
  19964.  
  19965.  main()
  19966.  {
  19967.      void line (x1, y1, x2, y2, color);
  19968.  
  19969.      int x1, x2, y1, y2, i, color;
  19970.  
  19971.      _setvideomode(_MRES16COLOR); /* 320 x 200  16 col. */
  19972.      srand(2);                    /* new random seed    */
  19973.      for (i = 0; i < 100; i++)
  19974.          {
  19975.          x1 = rand() % 319;       /* random coordinates */
  19976.          x2 = rand() % 319;
  19977.          y1 = rand() % 199;
  19978.          y2 = rand() % 199;
  19979.          color = (rand() % 14) + 1; /* random color 1-15 */
  19980.          line(x1, y1, x2, y2, color); /* draw a line   */
  19981.          }
  19982.      while(!kbhit() ); /* wait for key to be hit */
  19983.  
  19984.      _setvideomode(_DEFAULTMODE); /* restore video mode */
  19985.  }
  19986.  
  19987.  void line (x1, y1, x2, y2, color)
  19988.  int x1, y1, x2, y2, color;
  19989.  {
  19990.      _moveto(x1, y1); /* position at first endpoint   */
  19991.      _setcolor(color);
  19992.      _lineto(x2, y2); /* draw line to second endpoint */
  19993.  }
  19994.  
  19995.  
  19996.  LINES43.C
  19997.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\LINES43.C
  19998.  
  19999.  /* lines43.c -- leaves EGA in 43-line mode */
  20000.  
  20001.  #include <dos.h>
  20002.  #include <conio.h>
  20003.  #define VIDEO 0x10
  20004.  #define SETVMODE 0
  20005.  CHAR_GEN 0x11   /* an EGA BIOS function number */
  20006.  #define ROM8X8   0x12
  20007.  #define BLOCK 0
  20008.  #define TEXTC80 3
  20009.  
  20010.  main()
  20011.  {
  20012.       union REGS reg;
  20013.  
  20014.       reg.h.ah = SETVMODE;    /* set text mode */
  20015.       reg.h.al = TEXTC80;
  20016.       int86(VIDEO, ®, ®);
  20017.  
  20018.       reg.h.ah = CHAR_GEN;   /* char generator routine */
  20019.       reg.h.al = ROM8X8;  /* use 8x8 ROM character box */
  20020.       reg.h.bl = BLOCK;   /* copy to block 0 */
  20021.       int86(VIDEO, ®, ®);
  20022.  }
  20023.  
  20024.  
  20025.  LINE_CNT.C
  20026.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\LINE_CNT.C
  20027.  
  20028.  /*  line_cnt.c -- An overly active line counter       */
  20029.  #include <stdio.h>
  20030.  main()
  20031.  {
  20032.      int ch;
  20033.      int lines = 0;
  20034.  
  20035.      while ( (ch = getchar() ) != EOF )
  20036.          if ( ch = '\n')
  20037.              lines++;
  20038.      printf("There were %d lines\n", lines);
  20039.  }
  20040.  
  20041.  
  20042.  
  20043.  LOCAL.C
  20044.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\LOCAL.C
  20045.  
  20046.  /* local.c -- local variables defined */
  20047.  /*            within functions        */
  20048.  
  20049.  main()
  20050.      {
  20051.      int n = 12;
  20052.      int func1(), funct2();
  20053.      printf("n in main(): val %d ", n);
  20054.      printf("address %d\n", &n);
  20055.  
  20056.      printf("Calling func1()\n");
  20057.      func1();
  20058.      printf("Calling func2()\n");
  20059.      func2();
  20060.      }
  20061.  
  20062.  int func1()
  20063.      {
  20064.      int n = 8; /* local variable */
  20065.      printf("n in func1(): val %d ", n);
  20066.      printf("address %d\n", &n);
  20067.      }
  20068.  
  20069.  int func2()
  20070.      {
  20071.      int n = 20; /* local variable */
  20072.      printf("n in func2(): val %d ", n);
  20073.      printf("address %d\n", &n);
  20074.      }
  20075.  
  20076.  
  20077.  M.C
  20078.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP05\M.C
  20079.  
  20080.  /* m.c -- draw a letter M        */
  20081.  /*        using IF and CONTINUE  */
  20082.  
  20083.  /* define characters */
  20084.  
  20085.  CH 'M'    /* character to "draw" with */
  20086.  #define BLANK ' '
  20087.  #define NL 10
  20088.  #define CR 13
  20089.  LEFT 20   /* left side of M   */
  20090.  RIGHT 46  /* right side of M  */
  20091.  BOTTOM 22 /* last line to use */
  20092.  main()
  20093.  {
  20094.      int pos, line;
  20095.      /* space to left side */
  20096.      for (line = 1; line <= BOTTOM; line++)
  20097.          {
  20098.          for (pos = 1; pos < LEFT; pos++)
  20099.              {
  20100.              putch(BLANK);
  20101.              }
  20102.          putch(CH); /* draw left side */
  20103.  
  20104.          /* are we past midpoint? */
  20105.          if (line > ((RIGHT - LEFT) / 2))
  20106.              {
  20107.              /* yes, so just draw right side */
  20108.              for (pos = LEFT; pos < RIGHT; pos++)
  20109.                  {
  20110.                  putch(BLANK);
  20111.                  }
  20112.              putch(CH);
  20113.              putch(NL);
  20114.              putch(CR);
  20115.              continue; /* start loop over, do next line */
  20116.              }
  20117.              /* not past midpoint, check for interior */
  20118.          for (pos = LEFT; pos < RIGHT; pos++)
  20119.              {
  20120.              if ((pos == (LEFT + line )) ||
  20121.                   (pos == (RIGHT - line )))
  20122.                  putch(CH);
  20123.              else
  20124.                  putch(BLANK);
  20125.              }
  20126.         putch(CH);
  20127.         putch(NL);
  20128.         putch(CR); /* could also use printf("\n"); */
  20129.         }
  20130.  }
  20131.  
  20132.  
  20133.  MAGIC.C
  20134.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP07\MAGIC.C
  20135.  
  20136.  /* magic.c  --  demonstrate use of a two-dimensional  */
  20137.  /*              array of type int                     */
  20138.  
  20139.  main()
  20140.  {
  20141.      static int square[3][3] = { 5, 8, 3, 4, 2, 0, 7, 1, 6 };
  20142.      int zrow = 1, zcol = 2;  /* location of the zero */
  20143.      int num, row, col, i , j, rowdist, coldist;
  20144.  
  20145.      while (1)
  20146.          {
  20147.          printf("Swap what with zero?\n");
  20148.          printf("(Q to quit)\n");
  20149.  
  20150.          /* Print the square. */
  20151.          for (i = 0; i < 3; ++i)
  20152.              {
  20153.              for (j = 0; j < 3; ++j)
  20154.                  {
  20155.                  printf(" %d ", square[i][j] );
  20156.                  }
  20157.              printf("\n");
  20158.              }
  20159.  
  20160.          /* Input the user number. */
  20161.          if ((num = getch()) == 'Q')
  20162.              exit(0);
  20163.          num -= '0';
  20164.          if (num < 1 || num > 9)
  20165.              {
  20166.              printf("Not a legal number.\n\n");
  20167.              continue;
  20168.              }
  20169.  
  20170.          /* Find that square. */
  20171.          for (row = 0; row < 3; ++row)
  20172.              {
  20173.              for(col = 0; col < 3; ++col)
  20174.                  {
  20175.                  if (num == square[row][col])
  20176.                      {
  20177.                      goto GOTIT;
  20178.                      }
  20179.                  }
  20180.              }
  20181.  GOTIT:
  20182.          /* Check for a legal move. */
  20183.          if (row > 2 || col > 2)
  20184.              {
  20185.              printf("Bad Box Specification\n\n");
  20186.              continue;
  20187.              }
  20188.          rowdist = zrow - row;
  20189.          if (rowdist < 0)
  20190.              rowdist *= -1;
  20191.          coldist = zcol - col;
  20192.          if (coldist < 0)
  20193.              coldist *= -1;
  20194.          if (rowdist > 1 || coldist > 1)
  20195.              {
  20196.              printf("Not A Neighbor\n\n");
  20197.              continue;
  20198.              }
  20199.  
  20200.          /* Make the move. */
  20201.          square[zrow][zcol] = square[row][col];
  20202.          square[row][col] = 0;
  20203.          zrow = row;
  20204.          zcol = col;
  20205.  
  20206.          /* See if done, and solved. */
  20207.          for (i = 0; i < 3; ++i)
  20208.              {
  20209.              for (j = 0; j < 3; ++j)
  20210.                  {
  20211.                  if (square[i][j] != ((i * 3) + j))
  20212.                      {
  20213.                      break;
  20214.                      }
  20215.                  }
  20216.              }
  20217.          if ((i * j) == 9)
  20218.              break;
  20219.          }
  20220.      printf("\n\aYOU GOT IT !!!\n");
  20221.  }
  20222.  
  20223.  
  20224.  MASKS.C
  20225.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\MASKS.C
  20226.  
  20227.  /*  masks.c -- illustrates _setfillmask() and         */
  20228.  /*             _floodfill()                           */
  20229.  /* Program list: masks.c                              */
  20230.  /* If you load graphics.qlb, no program list is needed*/
  20231.  
  20232.  #include <stdio.h>
  20233.  #include <stdlib.h>
  20234.  #include <conio.h>
  20235.  #include <graph.h>
  20236.  unsigned char Inversemask[8];
  20237.  unsigned char Masks[3][8] = {
  20238.              {0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00},
  20239.              {0xff,0x80,0x80,0x80,0xff,0x08,0x08,0x08},
  20240.              {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa}};
  20241.  main(argc, argv)
  20242.  int argc;
  20243.  char *argv[];
  20244.  {
  20245.      struct videoconfig vc;
  20246.      int mode = _MRES4COLOR;
  20247.      short xc, yc;
  20248.      short box, i;
  20249.  
  20250.      if (argc > 1)
  20251.          mode = atoi(argv[1]);
  20252.      if (_setvideomode(mode) == 0)
  20253.      {
  20254.          fprintf(stderr,"Can't set mode %d\n", mode);
  20255.          exit(1);
  20256.      }
  20257.      _getvideoconfig(&vc);
  20258.      xc = vc.numxpixels / 2;
  20259.      yc = vc.numypixels / 2;
  20260.      for (i = 0; i < 8; i++)
  20261.          Inversemask[i] = ~Masks[1][i];
  20262.      _setlogorg(xc, yc);
  20263.      _selectpalette(0);
  20264.      _setcolor(1);
  20265.      _rectangle(_GBORDER, -xc + 1, -yc + 1, xc - 1, yc - 1);
  20266.      _moveto(-xc + 1, -yc / 3);
  20267.      _lineto(xc -1, -yc / 3);
  20268.      _moveto(-xc + 1, yc / 3);
  20269.      _lineto(xc -1, yc / 3);
  20270.      for (box = 0; box < 3; box++)
  20271.      {
  20272.           _setcolor(box + 1);
  20273.           _setfillmask(Masks[box]);
  20274.           _floodfill(0, (box - 1) * yc / 2, 1);
  20275.      }
  20276.      _settextposition(5, 10);
  20277.      _outtext("Press a key to continue");
  20278.      getch();
  20279.      _setcolor(3);
  20280.      _setfillmask(Inversemask);
  20281.      _floodfill (0, 0, 1);
  20282.      _setcolor(2);
  20283.      _setfillmask(Masks[0]);
  20284.      _floodfill(0, yc / 2, 1);
  20285.      _settextposition(5, 10);
  20286.      _outtext("Press a key to terminate");
  20287.      getch();
  20288.      _setvideomode(_DEFAULTMODE);
  20289.  }
  20290.  
  20291.  
  20292.  MATH.C
  20293.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\MATH.C
  20294.  
  20295.  /* math.c -- shows arithmetic and       */
  20296.  /*           precedence via expressions */
  20297.  
  20298.  main()
  20299.  {
  20300.      int a = 10, b = 4, c = 2;
  20301.  
  20302.      /* simple arithmetic expressions */
  20303.      printf("99 + 2 = %d\n", 99 + 2);  /* ints */
  20304.      printf("5 - 12 = %d\n", 5 - 12);
  20305.      printf("7.25 + 3.5 = %f\n", 7.25 + 3.5);
  20306.                                          /* floats */
  20307.  
  20308.      /* compare presedence on these */
  20309.      printf("20 * 20 + 40 = %d\n", 20 * 20 + 40);
  20310.      printf("20 * (20 + 40) = %d\n", 20 * (20 + 40));
  20311.      printf("a * a - c + b = %d\n", a * a - c + b);
  20312.      printf("a * (a - (c + b)) = %d\n",
  20313.              a * (a - (c + b)));
  20314.  
  20315.      /* compare integer and float division */
  20316.  
  20317.      printf("Integers: 5 / 2 = %d\n", 5 / 2);
  20318.      printf("Floats: 5.0 / 2.0 = %f\n", 5.0 / 2.0);
  20319.  }
  20320.  
  20321.  
  20322.  MATHTEST.C
  20323.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\MATHTEST.C
  20324.  
  20325.  /* mathtest.c -- driver for do_math()                 */
  20326.  /* Program list: mathtest.c (to link math functions)  */
  20327.  
  20328.  #include <stdio.h>
  20329.  double do_math(double);
  20330.  main()
  20331.  {
  20332.      double input, result;
  20333.  
  20334.      printf("Enter a number: ");
  20335.      while (scanf("%lf", &input) == 1)
  20336.          {
  20337.          result = do_math(input);
  20338.          printf("input = %.2e, result = %.2e\n", input,
  20339.                  result);
  20340.          printf("Next number (q to quit): ");
  20341.          }
  20342.  }
  20343.  
  20344.  #include <math.h>
  20345.  double do_math(x)
  20346.  double x;
  20347.  {
  20348.      return (sin (x) * exp (-x));
  20349.  }
  20350.  
  20351.  
  20352.  
  20353.  MENU.C
  20354.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\MENU.C
  20355.  
  20356.  /*  menu.c -- uses ansi.sys for cursor control and   */
  20357.  /*            for video reverse in a sample menu     */
  20358.  /*  Note: Requires that ANSI.SYS be installed.       */
  20359.  
  20360.  #include <conio.h>
  20361.  ITEMS 5           /* number of menu items */
  20362.  UP 72             /* scan code for up arrow */
  20363.  DOWN 80           /* scan code for down arrow */
  20364.  VIDREV "\033[7m"  /* reverse video attribute */
  20365.  ATTOFF "\033[0m"  /* turn attributes off   */
  20366.  ED()   printf("\033[2J")  /* erase display */
  20367.  HOME() printf("\033[H")  /* home the cursor */
  20368.  CUU(Y) printf("\033[%dA",Y);  /* cursor up */
  20369.  CUD(Y) printf("\033[%dB",Y);  /* cursor down */
  20370.  
  20371.  char *Menu[ITEMS] = {"Add a number to the list",
  20372.                       "Delete a number from the list",
  20373.                       "Clear the list",
  20374.                       "Sum the list",
  20375.                       "Quit"};
  20376.  char *Heading =
  20377.  "Use arrow keys to highlight choice. "
  20378.  "Use Enter key to select choice.";
  20379.  
  20380.  void showmenu(int);
  20381.  int getmesg(int);
  20382.  main()
  20383.  {
  20384.      int messno = 0; /* message to be highlighted */
  20385.      ED();
  20386.      showmenu(messno);
  20387.      while (messno != ITEMS - 1)
  20388.          {
  20389.          messno = getmesg(messno);
  20390.          ED();
  20391.          switch (messno)
  20392.             {
  20393.             case 0 :
  20394.             case 1 :
  20395.             case 2 :
  20396.             case 3 : printf("...pretending to work ...");
  20397.                      printf("Hit any key to continue\n");
  20398.                      getch();
  20399.                      ED();
  20400.                      showmenu(messno);
  20401.                      break;
  20402.             case 4 : printf("Quitting!\n");
  20403.                      break;
  20404.             default: printf("Programming error!\n");
  20405.                      break;
  20406.             }
  20407.          }
  20408.  }
  20409.  
  20410.  /* showmenu() displays the menu  */
  20411.  void showmenu(highlite)
  20412.  int highlite;   /* message number to be highlighted */
  20413.  {
  20414.      int n;
  20415.      char *start;
  20416.  
  20417.      HOME();
  20418.      printf("%s", Heading);
  20419.      for (n = 0; n < ITEMS; n++)
  20420.      {
  20421.          if (n == highlite)
  20422.              start = VIDREV; /* turn on reverse video */
  20423.          else
  20424.              start = ATTOFF;
  20425.          printf("\n\n%s%s%s", start, Menu[n], ATTOFF);
  20426.      }
  20427.      HOME();
  20428.      CUD(2 + 2 * highlite);
  20429.  }
  20430.  
  20431.  /*  getmesg() selects a menu item */
  20432.  int getmesg(mnum)
  20433.  int mnum; /* current message number */
  20434.  {
  20435.      char ch;
  20436.  
  20437.      while ((ch = getch()) != '\r')
  20438.          if (ch == 0)
  20439.              {
  20440.              ch = getch();
  20441.              switch (ch)
  20442.                  {
  20443.                  case UP   : if (mnum > 0)
  20444.                                  {
  20445.                                  CUU(2);
  20446.                                  showmenu (--mnum);
  20447.                                  }
  20448.                              else
  20449.                                  {
  20450.                                  CUD(2 * ITEMS - 2);
  20451.                                  showmenu(mnum=ITEMS-1);
  20452.                                  }
  20453.                              break;
  20454.                  case DOWN : if (mnum < ITEMS - 1)
  20455.                                  {
  20456.                                  CUD(2);
  20457.                                  showmenu(++mnum);
  20458.                                  }
  20459.                              else
  20460.                                  {
  20461.                                  CUU(2 * ITEMS - 2);
  20462.                                  showmenu(mnum = 0);
  20463.                                  }
  20464.                              break;
  20465.                  }
  20466.              }
  20467.          return mnum;
  20468.  }
  20469.  
  20470.  
  20471.  MIDSTR.C
  20472.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\MIDSTR.C
  20473.  
  20474.  /* midstr.c -- a C version of BASIC's MID$  */
  20475.  
  20476.  #include <stdio.h>
  20477.  
  20478.  char *Midstr(char *str, int where, int cnt)
  20479.  {
  20480.      static char *cp = NULL;
  20481.      char *malloc();
  20482.  
  20483.      if (cnt > strlen(str + where))
  20484.          cnt = strlen(str + where);
  20485.      if (cp != NULL)
  20486.          free(cp);
  20487.      if ((cp = malloc(cnt + 1)) == NULL)
  20488.          return (NULL);
  20489.      strncpy(cp, str+where, cnt);
  20490.      return (cp);
  20491.  }
  20492.  
  20493.  
  20494.  
  20495.  MISIDENT.C
  20496.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\MISIDENT.C
  20497.  
  20498.  /* misident.c -- careless typing              */
  20499.  
  20500.  #defne BIG 3
  20501.  main()
  20502.  {
  20503.      char ltr;
  20504.      integer num;
  20505.  
  20506.      num = 2 + BIG;
  20507.      lrt = 'a';
  20508.      printf("%c %d\n", ltr, num);
  20509.  }
  20510.  
  20511.  
  20512.  
  20513.  MIXED.C
  20514.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\MIXED.C
  20515.  
  20516.  /* mixed.c -- shows the effects of mixing */
  20517.  /*            data types in an expression */
  20518.  
  20519.  main()
  20520.  {
  20521.      int     i = 50, iresult;
  20522.      long    l = 1000000, lresult;
  20523.      float   f = 10.5, fresult;
  20524.      double  d = 1000.005, dresult;
  20525.  
  20526.      fresult = i + f;         /* int + float to float */
  20527.      printf("%f\n", fresult);
  20528.  
  20529.      fresult = i * f;         /* int * float to float */
  20530.      printf("%f\n", fresult);
  20531.  
  20532.      lresult = l + f;         /* long + int to long */
  20533.      printf("%f\n", lresult);
  20534.  
  20535.      printf("%f\n", d * f);   /* double * float */
  20536.                                   /* to double */
  20537.      fresult = d * f;         /* assigned to a float */
  20538.      printf("%f\n", fresult); /* loses some precision */
  20539.  
  20540.      /* debugging a division problem */
  20541.  
  20542.      iresult = i / l;          /* int / long to int */
  20543.      printf("%d\n", iresult);  /* whoops! loses result */
  20544.      printf("%ld\n", iresult); /* this won't fix it */
  20545.      fresult = i / l;          /* store in float result */
  20546.      printf("%f\n", fresult);  /* doesn't work */
  20547.      dresult = i / l;          /* try a double */
  20548.      printf("%f\n", dresult);  /* doesn't work */
  20549.      fresult = (float) i / l;  /* try type cast */
  20550.      printf("%f\n", fresult);  /* correct result */
  20551.  }
  20552.  
  20553.  
  20554.  MIXLOOPS.C
  20555.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP04\MIXLOOPS.C
  20556.  
  20557.  
  20558.  /* MIXLOOPS.C -- reads characters,       */
  20559.  /*               beeps for ASCII count   */
  20560.  /*               uses a while and a for  */
  20561.  
  20562.  #include <conio.h>
  20563.  
  20564.  main()
  20565.  {
  20566.      char ch;
  20567.      int  i;
  20568.  
  20569.      while ((ch = getche()) != ' ')  /* get a char. */
  20570.          {
  20571.          for (i = 'a'; i <= ch; ++i) /* count up to */
  20572.              {                       /* alphabet pos.*/
  20573.              printf("In FOR loop!\n");
  20574.              printf("\a");  /* sound beep each time */
  20575.              }
  20576.          }
  20577.  }
  20578.  
  20579.  
  20580.  
  20581.  MIXTYPES.C
  20582.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\MIXTYPES.C
  20583.  
  20584.  /* mixtypes.c -- shows problem with calling           */
  20585.  /*               a function with wrong type parameter */
  20586.  
  20587.  main()
  20588.  {
  20589.      /* didn't bother to declare int function */
  20590.      float n = 5.0;
  20591.      int i;
  20592.  
  20593.      printf("n in main() is %f\n", n);
  20594.      i = examine(n);    /* pass float to function */
  20595.      printf("examine() returned n as %d\n", i);
  20596.  }
  20597.  
  20598.  examine(num)  /* function didn't declare return type */
  20599.  {
  20600.      printf("examine() says n is %d\n", num);
  20601.      return(num);
  20602.  }
  20603.  
  20604.  
  20605.  
  20606.  MODEINFO.C
  20607.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\MODEINFO.C
  20608.  
  20609.  /* modeinfo.c -- set modes and obtain information      */
  20610.  /* Demonstrates _setvideomode() and _getvideoconfig()  */
  20611.  /* If you load graphics.qlb, no program list is needed.*/
  20612.  
  20613.  #include <conio.h>
  20614.  #include <graph.h>
  20615.  struct videoconfig vc;
  20616.  int modes[15] ={_TEXTBW40, _TEXTC40, _TEXTBW80, _TEXTC80,
  20617.          _MRES4COLOR, _MRESNOCOLOR, _HRESBW, _TEXTMONO,
  20618.          _MRES16COLOR, _HRES16COLOR, _ERESNOCOLOR, _ERESCOLOR,
  20619.          _VRES2COLOR, _VRES16COLOR, _MRES256COLOR};
  20620.  char *Adapt(short), *Display(short);
  20621.  main()
  20622.  {
  20623.      int i;
  20624.  
  20625.      for (i = 0; i < 15; i++)
  20626.      {
  20627.          if (_setvideomode(modes[i]))
  20628.          {
  20629.              _getvideoconfig(&vc);
  20630.              printf("video mode is %d\n", vc.mode);
  20631.              printf("number of columns is %d\n", vc.numtextcols);
  20632.              printf("number of colors is %d\n", vc.numcolors);
  20633.              printf("number of pages is %d\n", vc.numvideopages);
  20634.              printf("adapter is %s\n", Adapt(vc.adapter));
  20635.              printf("display is %s\n", Display(vc.monitor));
  20636.              printf("the adapter has %dK of memory\n",
  20637.                      vc.memory);
  20638.          }
  20639.          else
  20640.              printf("mode %d not supported\n", modes[i]);
  20641.          printf("strike a key for next mode\n");
  20642.          getch();
  20643.      }
  20644.      _setvideomode (_DEFAULTMODE);
  20645.  }
  20646.  
  20647.  /* Adapt() returns a pointer to a string describing   */
  20648.  /* the adapter characterized by adapt_num.            */
  20649.  char *Adapt(adapt_num)
  20650.  short adapt_num; /* videoconfig.adapter value         */
  20651.  {
  20652.      static char *anames[6] = {"Monochrome", "CGA", "EGA",
  20653.                                "MCGA", "VGA", "Not known"};
  20654.      char *point;
  20655.  
  20656.      switch (adapt_num)
  20657.      {
  20658.          case _MDPA : point = anames[0];
  20659.                       break;
  20660.          case _CGA  : point = anames[1];
  20661.                       break;
  20662.          case _EGA  : point = anames[2];
  20663.                       break;
  20664.          case _MCGA : point = anames[3];
  20665.                       break;
  20666.          case _VGA  : point = anames[4];
  20667.                       break;
  20668.          default    : point = anames[5];
  20669.      }
  20670.      return point;
  20671.  }
  20672.  
  20673.  /* Display() returns a pointer to a string describing  */
  20674.  /* the monitor characterized by disp.                  */
  20675.  char *Display(disp)
  20676.  short disp;  /* videoconfig.monitor value              */
  20677.  {
  20678.      static char *types[5] = {"monochrome", "color",
  20679.                               "enhanced color", "analog",
  20680.                               "unknown"};
  20681.      char *point;
  20682.  
  20683.      if (disp & _MONO)
  20684.          point = types[0];
  20685.      else if (disp & _COLOR)
  20686.          point = types[1];
  20687.      else if (disp & _ENHCOLOR)
  20688.          point = types[2];
  20689.      else if (disp & _ANALOG)
  20690.          point = types[3];
  20691.      else
  20692.          point = types[4];
  20693.      return point;
  20694.  }
  20695.  
  20696.  
  20697.  MOIRE.C
  20698.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\MOIRE.C
  20699.  
  20700.  /*   moire.c -- variation on dots.c                   */
  20701.  /* If you load graphics.qlb, no program list is needed*/
  20702.  #include <conio.h>
  20703.  #include <stdio.h>
  20704.  #include <stdlib.h>
  20705.  #include <graph.h>
  20706.  #define ESC '\033'
  20707.  BKCOLS 8      /* number of background colors */
  20708.  PALNUM 4      /* number of palettes */
  20709.  long Bkcolors[BKCOLS] = {_BLACK, _BLUE, _GREEN, _CYAN, _RED,
  20710.                           _MAGENTA, _BROWN, _WHITE};
  20711.  main (argc, argv)
  20712.  int argc;
  20713.  char *argv[];
  20714.  {
  20715.       struct videoconfig vc;
  20716.       unsigned int col, row;
  20717.       short color = 0;
  20718.       int bkc_index = 1;  /* blue background */
  20719.       short palette = 0;  /* red, green, brown */
  20720.       int firstcol, firstrow, lastrow, lastcol;
  20721.       int mode = _MRES4COLOR;
  20722.       int ch;
  20723.  
  20724.       if (argc > 1)
  20725.            mode = atoi(argv[1]);
  20726.  
  20727.       if (_setvideomode(mode) == 0)
  20728.            {
  20729.            printf("Can't do that mode.\n");
  20730.            exit(1);
  20731.            }
  20732.       _getvideoconfig(&vc);
  20733.       firstcol = vc.numxpixels / 5;
  20734.       firstrow = vc.numypixels / 5;
  20735.       lastcol = 4 * vc.numxpixels / 5;
  20736.       lastrow = 4 * vc.numypixels / 5;
  20737.       _selectpalette(palette);
  20738.       _setbkcolor (Bkcolors[bkc_index]);
  20739.       for (col = firstcol; col <= lastcol; ++col)
  20740.            {
  20741.  
  20742.            for (row = firstrow; row <= lastrow; ++row)
  20743.                 {
  20744.                 _setcolor(((row*row + col*col)/10)%vc.numcolors);
  20745.                 _setpixel(col, row);
  20746.                 }
  20747.            }
  20748.       while ((ch = getch()) != ESC)
  20749.            {
  20750.            if (ch == 'p')
  20751.                  _selectpalette(++palette % PALNUM);
  20752.            else if (ch == 'b')
  20753.                  _setbkcolor(Bkcolors[++bkc_index % BKCOLS]);
  20754.            }
  20755.       _setvideomode(_DEFAULTMODE);  /* reset orig. mode */
  20756.  }
  20757.  
  20758.  
  20759.  NARROW.C
  20760.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\NARROW.C
  20761.  
  20762.  /* narrow.c -- a choppy C program */
  20763.  
  20764.  main( )
  20765.  {
  20766.  printf
  20767.  ("Hello, and welcome to QuickC!\n");
  20768.  }
  20769.  
  20770.  
  20771.  ONELINE.C
  20772.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\ONELINE.C
  20773.  
  20774.  /* oneline.c -- shows how printf() continues  */
  20775.  /*              on the same line              */
  20776.  
  20777.  main()
  20778.  {
  20779.      printf("All displayed on");
  20780.      printf("the same line, with no space");
  20781.      printf(" unless specified.");
  20782.              /* note added space in line above */
  20783.  }
  20784.  
  20785.  
  20786.  OPEQUAL.C
  20787.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\OPEQUAL.C
  20788.  
  20789.  /* opequal.c -- shows combination math/assignment */
  20790.  /*              operators and increment operators */
  20791.  
  20792.  main()
  20793.  {
  20794.      int m = 10, n = 5;
  20795.      printf("Starting values: m = %d n = %d\n",
  20796.              m, n);
  20797.  
  20798.      /* combination of arithmetic and assignment */
  20799.      printf("m += 2 makes m %d\n", m += 2);
  20800.      printf("m -= n makes m %d\n", m -= n);
  20801.      printf("m *= 2 makes m %d\n", m *= 2);
  20802.  
  20803.      /* two ways to increment m */
  20804.      printf("m = m + 1 makes m %d\n",
  20805.              m = m + 1);
  20806.      printf("m += 1 makes m %d\n",
  20807.              m += 1);
  20808.  }
  20809.  
  20810.  
  20811.  PACK.C
  20812.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\PACK.C
  20813.  
  20814.  /* pack.c  --  demonstrates structure packing with */
  20815.  /*             the #pragma pack() directive        */
  20816.  
  20817.  pack(4)        /* 1, 2 or 4 */
  20818.  
  20819.  main()
  20820.  {
  20821.      struct {
  20822.          char ch1;
  20823.          int  int1;
  20824.          char ch2;
  20825.          long int2;
  20826.      } s;
  20827.  
  20828.      printf("ch1  -> %lu\n", (unsigned long)(&s.ch1));
  20829.      printf("int1 -> %lu\n", (unsigned long)(&s.int1));
  20830.      printf("ch2  -> %lu\n", (unsigned long)(&s.ch2));
  20831.      printf("int2 -> %lu\n", (unsigned long)(&s.int2));
  20832.  }
  20833.  
  20834.  
  20835.  PASSWORD.C
  20836.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\PASSWORD.C
  20837.  
  20838.  /*  password.c -- requires a password to complete the   */
  20839.  /*                program; illustrates a use of getch() */
  20840.  
  20841.  #include <stdio.h>
  20842.  #include <conio.h>
  20843.  #include <string.h>
  20844.  #define GUESS_LIMIT 4
  20845.  WORD_LIMIT 10  /* maximum length of password */
  20846.  #define TRUE 1
  20847.  #define FALSE 0
  20848.  char *Password = "I'mOk";
  20849.  main()
  20850.  {
  20851.       int g_count = 0;           /* guesses taken */
  20852.       int w_count;               /* letters accepted */
  20853.       int in_count;              /* letters entered  */
  20854.       char entry[WORD_LIMIT + 1];
  20855.       char ch;
  20856.       int correct, go_on;
  20857.  
  20858.       do
  20859.            {
  20860.            puts("Enter the secret password.");
  20861.            in_count = w_count = 0;
  20862.            /* the following loop accepts no more chars */
  20863.            /* than entry[] will hold, but keeps track  */
  20864.            /* of total number typed                    */
  20865.            while ((ch = getch()) != '\r')
  20866.                 {
  20867.                 if (w_count < WORD_LIMIT)
  20868.                      entry[w_count++] = ch;
  20869.                 in_count++;
  20870.                 }
  20871.            entry[w_count] = '\0';
  20872.            if (in_count != w_count)
  20873.                 correct = FALSE;    /* too many chars */
  20874.            else
  20875.                 correct = (strcmp(entry, Password) == 0);
  20876.            g_count++;
  20877.            go_on = !correct && g_count < GUESS_LIMIT;
  20878.            if (go_on)
  20879.                 puts("\nNo good; try again.");
  20880.            } while (go_on);
  20881.       if (!correct)
  20882.            {
  20883.            puts("Sorry, no more guesses.  Bye.");
  20884.            return(1);
  20885.            }
  20886.       puts("Welcome to Swiss bank account 2929100.");
  20887.       puts("Your current balance is $10,232,862.61.");
  20888.       return(0);
  20889.  }
  20890.  
  20891.  
  20892.  PEEK.C
  20893.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\PEEK.C
  20894.  
  20895.  /* peek.c    -- demonstrates how to cast an int to a  */
  20896.  /*              pointer                               */
  20897.  
  20898.  main()
  20899.  {
  20900.      char *mem_ptr;
  20901.      unsigned int address;
  20902.  
  20903.      while (1)
  20904.          {
  20905.          printf("Examine what memory location?\n");
  20906.          printf("Enter location in decimal: ");
  20907.          if (scanf("%u", &address) != 1)
  20908.              break;
  20909.  
  20910.          mem_ptr = (char *)address;   /* cast  */
  20911.  
  20912.          printf("The value in %u is 0x%02X\n",
  20913.                  address, (unsigned char)*mem_ptr);
  20914.          }
  20915.  }
  20916.  
  20917.  
  20918.  PHONE.C
  20919.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP10\PHONE.C
  20920.  
  20921.  /* phone.c  -- a telephone number mini-database that  */
  20922.  /*             demonstrates fseek()                   */
  20923.  
  20924.  <stdio.h>          /* for FILE, BUFSIZ, NULL */
  20925.  
  20926.  #define MAXL (128)
  20927.  char Name[MAXL];
  20928.  char Number[MAXL];
  20929.  char File[] = "C:\\TMP\\PHONE.DB";
  20930.  int  Count;
  20931.  FILE *Fp;
  20932.  int  Distance = (MAXL * MAXL);
  20933.  
  20934.  main(argc, argv)
  20935.  int argc;
  20936.  char *argv[];
  20937.  {
  20938.      if (argc == 1)
  20939.          Ask();
  20940.      else
  20941.          Find(argv[1]);
  20942.  
  20943.      return (0);
  20944.      }
  20945.  
  20946.  Find(char *str)
  20947.      {
  20948.      int i;
  20949.  
  20950.      if ((Fp = fopen(File, "r")) == NULL)
  20951.          {
  20952.          fprintf(stderr, "\"%s\": Can't Read\n", File);
  20953.          exit (1);
  20954.          }
  20955.      if (fread(&Count, 1, sizeof(int), Fp) != sizeof(int))
  20956.          {
  20957.          fprintf(stderr,"\"%s\": Error Reading\n", File);
  20958.          exit (1);
  20959.          }
  20960.      for (i = 0; i < Count; i++)
  20961.          {
  20962.          fread(Name, 1, MAXL, Fp);
  20963.          fread(Number, 1, MAXL, Fp);
  20964.          if (ferror(Fp))
  20965.              {
  20966.              fprintf(stderr, "\"%s\": Error Reading.\n", File);
  20967.              exit (1);
  20968.              }
  20969.          if (strcmp(*str, *Name) == 0)
  20970.              {
  20971.              printf("Name: %s\n", Name);
  20972.              printf("Number: %s\n", Number);
  20973.              return;
  20974.              }
  20975.          }
  20976.      fprintf(stderr, "\"%s\": Not in database.\n", str);
  20977.      return;
  20978.  }
  20979.  
  20980.  Ask()
  20981.  {
  20982.      if ((Fp = fopen(File, "r+")) == NULL)
  20983.          Make();
  20984.      else if (fread(&Count, 1, sizeof(int),Fp) != sizeof(int))
  20985.          {
  20986.          fprintf(stderr, "\"%s\": Error Reading\n", File);
  20987.          exit (1);
  20988.          }
  20989.      printf("Name: ");
  20990.      if (gets(Name) == NULL || *Name == '\0')
  20991.          return;
  20992.      printf("Number: ");
  20993.      if (gets(Number) == NULL || *Number == '\0')
  20994.          return;
  20995.      if (fseek(Fp, (long)(Distance * Count), SEEK_CUR) != 0)
  20996.          {
  20997.          fprintf(stderr, "\"%s\": Error Seeking.\n", File);
  20998.          exit (1);
  20999.          }
  21000.      fwrite(Name, 1, MAXL, Fp);
  21001.      fwrite(Number, 1, MAXL, Fp);
  21002.      if (ferror(Fp))
  21003.          {
  21004.          fprintf(stderr, "\"%s\": Error Writing.\n", File);
  21005.          exit (1);
  21006.          }
  21007.      if (fseek(Fp, 0L, SEEK_SET) != 0)
  21008.          {
  21009.          fprintf(stderr, "\"%s\": Error Seeking.\n", File);
  21010.          exit (1);
  21011.          }
  21012.      ++Count;
  21013.      if (fwrite(&Count, 1, sizeof(int),Fp) != sizeof(int))
  21014.          {
  21015.          fprintf(stderr, "\"%s\": Error Writing\n", File);
  21016.          exit (1);
  21017.          }
  21018.      return;
  21019.  }
  21020.  
  21021.  Make()
  21022.  {
  21023.      if ((Fp = fopen(File, "w+")) == NULL)
  21024.          {
  21025.          fprintf(stderr, "\"%s\": Can't Create\n", File);
  21026.          exit (1);
  21027.          }
  21028.      Count = 0;
  21029.      if (fwrite(&Count, 1, sizeof(int), Fp) != sizeof(int))
  21030.          {
  21031.          fprintf(stderr," \"%s\": Error Creating\n", File);
  21032.          exit (1);
  21033.          }
  21034.  }
  21035.  
  21036.  
  21037.  PHWORD.C
  21038.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\PHWORD.C
  21039.  
  21040.  /* phword.c   --  generate all the possible words     */
  21041.  /*                in a phone number; demonstrates     */
  21042.  /*                functions that return addresses     */
  21043.  
  21044.  MAXD (7)    /* 7 digits max */
  21045.  
  21046.  main()
  21047.  {
  21048.      int digits[MAXD], ndigits = 0, line = 0;
  21049.      char *letters;
  21050.      signed char digit;
  21051.      int a, b, c, d, e, f, g;
  21052.      extern char *Range();
  21053.  
  21054.      printf("Enter Phone Number (7 digits): ");
  21055.      do
  21056.          {
  21057.          digit = getch() - '0';
  21058.          if (digit == ('-' - '0'))
  21059.              continue;
  21060.          if (digit < 0 || digit > 9)
  21061.              {
  21062.              printf("\nAborted: Non Digit\n");
  21063.              return(1);
  21064.              }
  21065.          digits[ndigits++] = digit;
  21066.          printf("%d", digit);
  21067.          } while (ndigits < 7);
  21068.      printf("\n");
  21069.  
  21070.      for( a = 0; a < 3; ++a)
  21071.       for( b = 0; b < 3; ++b)
  21072.        for( c = 0; c < 3; ++c)
  21073.         for( d = 0; d < 3; ++d)
  21074.          for( e = 0; e < 3; ++e)
  21075.           for( f = 0; f < 3; ++f)
  21076.            for( g = 0; g < 3; ++g)
  21077.                {
  21078.                printf("%c", Range(digits[0])[a]);
  21079.                printf("%c", Range(digits[1])[b]);
  21080.                printf("%c", Range(digits[2])[c]);
  21081.                printf("%c", Range(digits[3])[d]);
  21082.                printf("%c", Range(digits[4])[e]);
  21083.                printf("%c", Range(digits[5])[f]);
  21084.                printf("%c", Range(digits[6])[g]);
  21085.                printf("\n");
  21086.                if (++line == 20)
  21087.                    {
  21088.                    printf("Press Any key for More");
  21089.                    printf(" (or q to quit): ");
  21090.                    if (getch() == 'q')
  21091.                        return (0);
  21092.                    printf("\n");
  21093.                    line = 0;
  21094.                    }
  21095.                }
  21096.  }
  21097.  
  21098.  char *Range(int key)
  21099.      {
  21100.      static char keys[10][3] = {
  21101.          {'0', '0', '0' },
  21102.          {'1', '1', '1' },
  21103.          {'a', 'b', 'c' },
  21104.          {'d', 'e', 'f' },
  21105.          {'g', 'h', 'i' },
  21106.          {'j', 'k', 'l' },
  21107.          {'m', 'n', 'o' },
  21108.          {'p', 'r', 's' },
  21109.          {'t', 'u', 'v' },
  21110.          {'w', 'x', 'y' }
  21111.      };
  21112.  
  21113.      return (keys[key]);
  21114.  }
  21115.  
  21116.  
  21117.  PIXELS.C
  21118.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP05\PIXELS.C
  21119.  
  21120.  /* pixels.c -- create shapes       */
  21121.  /*             from random pixels  */
  21122.  
  21123.  <graph.h> /* for graphics */
  21124.  
  21125.  main()
  21126.  {
  21127.      int pixels, xpos, ypos;
  21128.      /* window coordinates */
  21129.      int xmin = 100, xmax = 540;
  21130.      int ymin = 50,  ymax = 150;
  21131.  
  21132.      srand(0);               /* init random nums */
  21133.      _setvideomode(_HRESBW); /* CGA 640 x 200    */
  21134.      _setcolor(1);           /* white foreground */
  21135.  
  21136.      /* generate random pixel locations      */
  21137.      for (pixels = 1; pixels < 10000; pixels++)
  21138.          {
  21139.          xpos = rand() % 639;
  21140.          ypos = rand() % 199;
  21141.  
  21142.          /* set pixel if within window */
  21143.          if ((xpos > xmin && xpos < xmax) &&
  21144.               (ypos > ymin && ypos < ymax))
  21145.             _setpixel(xpos, ypos);
  21146.          }
  21147.      getch(); /* freeze screen until key pressed */
  21148.               /* restore original video mode */
  21149.      _setvideomode(_DEFAULTMODE);
  21150.  }
  21151.  
  21152.  
  21153.  POINTER.C
  21154.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\POINTER.C
  21155.  
  21156.  /* pointer.c  --  demonstrates pointer declaration,   */
  21157.  /*                assignment, and use                 */
  21158.  
  21159.  #define WAIT printf("(press any key)"); getch(); \
  21160.               printf("\n\n")
  21161.  
  21162.  main()
  21163.  {
  21164.      int num, *address_var;
  21165.  
  21166.      num = 0;
  21167.      address_var = #
  21168.  
  21169.      printf("The address of the variable ");
  21170.      printf("\"num\" is:  0x%04X\n", &num );
  21171.      printf("The value in the pointer ");
  21172.      printf("\"address_var\" is:  0x%04X\n", address_var);
  21173.      printf("The value in the variable ");
  21174.      printf("\"num\" is: %d\n", num );
  21175.      WAIT;
  21176.      printf("Since \"address_var\" points to \"num\"\n");
  21177.      printf("the value in ");
  21178.      printf("\"*address_var\" is: %d\n", *address_var);
  21179.      WAIT;
  21180.      printf("To verify this, let's store 3 in\n");
  21181.      printf("\"*address_var\", then print out ");
  21182.      printf("\"num\" and \"*address_var\"\n");
  21183.      printf("again.\n");
  21184.      WAIT;
  21185.  
  21186.      printf("Doing: *address_var = 3;\n\n");
  21187.      *address_var = 3;
  21188.  
  21189.      printf("The address of the variable ");
  21190.      printf("\"num\" is:  0x%04X\n", &num);
  21191.      printf("The value in the pointer ");
  21192.      printf("\"address_var\" is:  0x%04X\n", address_var);
  21193.      printf("The value in the variable ");
  21194.      printf("\"num\" is: %d\n", num);
  21195.      WAIT;
  21196.      printf("Since \"address_var\" points to \"num\"\n");
  21197.      printf("the value in ");
  21198.      printf("\"*address_var\" is: %d\n", *address_var);
  21199.      WAIT;
  21200.  
  21201.      printf("Now we will add 15 to \"num\" and print\n");
  21202.      printf("\"num\" and \"*address_var\" again.\n");
  21203.      WAIT;
  21204.  
  21205.      printf("Doing: num += 15;\n\n");
  21206.      num += 15;
  21207.  
  21208.      printf("The address of the variable ");
  21209.      printf("\"num\" is:  0x%04X\n", &num);
  21210.      printf("The value in the pointer ");
  21211.      printf("\"address_var\" is:  0x%04X\n", address_var);
  21212.      printf("The value in the variable ");
  21213.      printf("\"num\" is: %d\n", num);
  21214.      WAIT;
  21215.      printf("Since \"address_var\" points to \"num\"\n");
  21216.      printf("the value in ");
  21217.      printf("\"*address_var\" is: %d\n", *address_var);
  21218.      WAIT;
  21219.  
  21220.      printf("Doing: return (*address_var);\n\n");
  21221.      return (*address_var);
  21222.  }
  21223.  
  21224.  
  21225.  PORTINFO.C
  21226.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\PORTINFO.C
  21227.  
  21228.  /* portinfo.c -- reads port values                    */
  21229.  /* program list -- portinfo.c (inp() not in core lib) */
  21230.  
  21231.  #include <conio.h>
  21232.  #include <stdio.h>
  21233.  main()
  21234.  {
  21235.      unsigned int portnum;
  21236.      int regvalue;
  21237.  
  21238.      printf("Enter number (in hex) of the port ");
  21239.      printf("you wish to read: ");
  21240.      while (scanf("%x", &portnum) == 1)
  21241.          {
  21242.      regvalue = inp(portnum);
  21243.      printf("\nValue returned for port %x is %d (decimal)"
  21244.             "  %x (hex)\n", portnum, regvalue, regvalue);
  21245.      printf("Next port? (q to quit): ");
  21246.          }
  21247.  }
  21248.  
  21249.  
  21250.  POWER.C
  21251.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\POWER.C
  21252.  
  21253.  /* power.c -- attempting to raise to a power   */
  21254.  
  21255.  main()
  21256.  {
  21257.      int number;
  21258.  
  21259.      number = 10**3; /* raise 10 to 3rd power? */
  21260.      printf("%d\n", number);
  21261.  }
  21262.  
  21263.  
  21264.  PREPOST.C
  21265.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\PREPOST.C
  21266.  
  21267.  /* prepost.c -- shows effect of pre- */
  21268.  /*              and post-increments  */
  21269.  /*              and decrements       */
  21270.  
  21271.  main()
  21272.  {
  21273.      int b = 100;
  21274.  
  21275.      printf("b is %d\n", b);
  21276.      printf("b++ is still %d\n", b++);
  21277.      printf("but after it's used, ");
  21278.      printf("b is incremented to %d\n\n, b);
  21279.  
  21280.      printf("++b, on the other hand, ");
  21281.      printf("is immediately %d\n", ++b);
  21282.  }
  21283.  
  21284.  
  21285.  PROTO.C
  21286.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\PROTO.C
  21287.  
  21288.  /* proto.c -- demonstrate function prototyping */
  21289.  /*            and parameter checking           */
  21290.  
  21291.  main()
  21292.  {
  21293.      float n = 9995.997;
  21294.      int i;
  21295.      int examine(int num);  /* declare function */
  21296.                             /* with prototype   */
  21297.  
  21298.      printf("n in main() is %f\n", n);
  21299.      i = examine(n);    /* pass float to function */
  21300.      printf("examine() returned n as %d\n", i);
  21301.  }
  21302.  
  21303.  int examine(num)
  21304.  {
  21305.      printf("examine() says n is %d\n", num);
  21306.      return(num);
  21307.  }
  21308.  
  21309.  
  21310.  QCHELLO.C
  21311.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP02\QCHELLO.C
  21312.  
  21313.  /* qchello.c -- a simple C program */
  21314.  
  21315.  main()
  21316.  {
  21317.      printf("Hello, and welcome to QuickC!\n");
  21318.  }
  21319.  
  21320.  
  21321.  RACE.C
  21322.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\RACE.C
  21323.  
  21324.  /* race.c -- race of the patterned circles             */
  21325.  /*    Illustrates animation with _getimage() and       */
  21326.  /*    _putimage(), random number use with srand() and  */
  21327.  /*    rand(), and system clock use with time() and     */
  21328.  /*    ftime().
  21329.  /* Program list: race.c (for srand(), rand(), and      */
  21330.  /*                       ftime())                      */
  21331.  
  21332.  #include <stdio.h>
  21333.  #include <stdlib.h>
  21334.  #include <conio.h>
  21335.  #include <graph.h>
  21336.  #include <time.h>
  21337.  #include <sys\types.h>
  21338.  #include <sys\timeb.h>
  21339.  
  21340.  #define END 25
  21341.  #define FIGNUM 3
  21342.  typedef char far *PTFRCHAR;
  21343.  PTFRCHAR Bufs[FIGNUM];
  21344.  unsigned char Masks[FIGNUM][8] = {
  21345.              {0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00},
  21346.              {0xF0,0xF0,0xF0,0xF0,0x0F,0x0F,0x0F,0x0F},
  21347.              {0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA}};
  21348.  short Xul[FIGNUM], Yul[FIGNUM];  /* figure locations */
  21349.  short Xsize, Ysize;              /* figure size      */
  21350.  struct videoconfig Vc;
  21351.  void Initialize(void);
  21352.  void Draw_n_store(void);
  21353.  void Move_figs(void);
  21354.  void Wait(double);
  21355.  
  21356.  main(argc, argv)
  21357.  int argc;
  21358.  char *argv[];
  21359.  {
  21360.      int mode = _MRES4COLOR;
  21361.  
  21362.      if (argc > 1)
  21363.          mode = atoi(argv[1]);
  21364.      if (_setvideomode(mode) == 0)
  21365.      {
  21366.          fprintf(stderr,"mode %d not supported\n",mode);
  21367.          exit(1);
  21368.      }
  21369.      Initialize();
  21370.      Draw_n_store();
  21371.      _settextcolor(2);
  21372.      _settextposition(1, 1);
  21373.      _outtext("Place your bets and type a key");
  21374.      _settextposition(25, 1);
  21375.      _outtext("Type a key again when done");
  21376.      getch();
  21377.      Move_figs();
  21378.      getch();
  21379.      _setvideomode(_DEFAULTMODE);
  21380.  }
  21381.  
  21382.  void Initialize()
  21383.  {
  21384.      int i;
  21385.      float ar;  /* aspect ratio */
  21386.  
  21387.      _getvideoconfig(&Vc);
  21388.      ar = (float)(10 * Vc.numypixels) / (6.5 * Vc.numxpixels);
  21389.        /* set size, initial positions */
  21390.      Xsize = Vc.numxpixels / 30;
  21391.      Ysize = ar * Xsize;
  21392.      for(i = 0; i < FIGNUM; i++)
  21393.      {
  21394.          Xul[i] = 0;
  21395.          Yul[i] = (i + 1) * Vc.numypixels /
  21396.                        (FIGNUM + 1);
  21397.      }
  21398.      _selectpalette(0);
  21399.      _setcolor(1);
  21400.          /*  draw finish line */
  21401.      _moveto(END * Xsize, 0);
  21402.      _lineto(END * Xsize, Vc.numypixels - 1);
  21403.  }
  21404.  
  21405.  void Draw_n_store() /* draw images, save them */
  21406.  {
  21407.      int i;
  21408.  
  21409.      for (i = 0; i < FIGNUM; i++)
  21410.          {
  21411.          _setcolor(i + 1);
  21412.          _setfillmask(Masks[i]);
  21413.          _ellipse(_GFILLINTERIOR ,Xul[i], Yul[i],
  21414.                   Xul[i] + Xsize, Yul[i] + Ysize);
  21415.          _ellipse(_GBORDER ,Xul[i], Yul[i],
  21416.                   Xul[i] + Xsize, Yul[i] + Ysize);
  21417.          Bufs[i] = (PTFRCHAR) malloc((unsigned int)
  21418.                     _imagesize(0,Yul[i], Xul[i] +
  21419.                     Xsize, Yul[i] + Ysize));
  21420.          _getimage(Xul[i],Yul[i], Xul[i] + Xsize, Yul[i] +
  21421.                    Ysize, Bufs[i]);
  21422.  
  21423.          }
  21424.  }
  21425.  void Move_figs()
  21426.  {
  21427.      int i, j;
  21428.      static int dx[FIGNUM] = {0, 0, 0}; /* displacements */
  21429.      time_t tval;
  21430.  
  21431.      time(&tval);    /*   use the current time value   */
  21432.      srand(tval);    /*   to initialize rand()         */
  21433.      while (dx[0] < END && dx[1] < END && dx[2] < END)
  21434.          {
  21435.          for (i = 0; i < FIGNUM; i++)
  21436.              {
  21437.              /* advance the figure one position if  */
  21438.              /* rand() returns an even number       */
  21439.              if (rand() % 2 == 0)
  21440.                  {
  21441.                  /* erase old image */
  21442.                  _putimage(dx[i] * Xsize, Yul[i],
  21443.                            Bufs[i], _GXOR);
  21444.                  /* redraw in new position */
  21445.                  _putimage((1 + dx[i]) * Xsize, Yul[i],
  21446.                            Bufs[i], _GPSET);
  21447.                  dx[i]++;
  21448.                  }
  21449.              }
  21450.          Wait(0.15);
  21451.          }
  21452.      for (j = 0; j < 5; j++)
  21453.          {
  21454.          for(i = 0; i < FIGNUM; i++)
  21455.              {
  21456.              /* flash winning figure */
  21457.              if (dx[i] >= END)
  21458.                  {
  21459.                  Wait(0.2);
  21460.                  _putimage(dx[i] * Xsize,Yul[i],
  21461.                            Bufs[i], _GPRESET);
  21462.                  Wait(0.2);
  21463.                  _putimage(dx[i] * Xsize,Yul[i],
  21464.                            Bufs[i], _GPSET);
  21465.                  }
  21466.              }
  21467.          }
  21468.  }
  21469.  
  21470.  void Wait(pause) /* wait for pause seconds */
  21471.  double pause;
  21472.  {
  21473.      struct timeb start, end;
  21474.      long delay;
  21475.  
  21476.      delay = 1000 * pause;  /* convert to milliseconds */
  21477.      ftime(&start);
  21478.      ftime(&end);
  21479.      while ((1000 * (end.time - start.time) +
  21480.              + end.millitm - start.millitm) < delay)
  21481.          ftime(&end);
  21482.  }
  21483.  
  21484.  
  21485.  
  21486.  READKEY.C
  21487.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\READKEY.C
  21488.  
  21489.  /* readkey.c -- contains the Readkey() function     */
  21490.  #include <dos.h>
  21491.  KEYINTR 0x16  /* keyboard read interrupt */
  21492.  GETCHAR 0     /* read scancode function  */
  21493.  struct SCANCODE {
  21494.                  unsigned char ascii;  /* ascii code */
  21495.                  unsigned char scan;   /* scan code  */
  21496.                  };
  21497.  
  21498.  struct SCANCODE Readkey()
  21499.  {
  21500.      union REGS reg;
  21501.      struct SCANCODE scancode;
  21502.  
  21503.      reg.h.ah = GETCHAR;         /* specify function */
  21504.      int86(KEYINTR, ®, ®); /* note use of & oper.*/
  21505.      scancode.ascii = reg.h.al;
  21506.      scancode.scan = reg.h.ah;
  21507.      return (scancode);
  21508.  }
  21509.  
  21510.  
  21511.  RECALL.C
  21512.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\RECALL.C
  21513.  
  21514.  /* recall.c -- displays previously stored screen,     */
  21515.  /*             including attributes.  Uses DMA.       */
  21516.  /* Program list: recall.c, scrfun.c                   */
  21517.  /* User include files: scrn.h, grafchar.h             */
  21518.  /* Note: activate Screen Swapping On in Debug menu    */
  21519.  
  21520.  #include <stdio.h>
  21521.  #include <conio.h>
  21522.  #include "scrn.h"
  21523.  #include "grafchar.h"
  21524.  
  21525.  main(ac, ar)
  21526.  int ac;
  21527.  char *ar[];
  21528.  {
  21529.       unsigned char mode;
  21530.       unsigned short char_attr;
  21531.       FILE *save;
  21532.       unsigned int offset;
  21533.       char filename[81];
  21534.       VIDMEM screen;
  21535.  
  21536.       if (ac < 2)
  21537.            {
  21538.            fprintf(stderr, "Usage: %s filename\n", ar[0]);
  21539.            exit(1);
  21540.            }
  21541.  
  21542.       if ((save = fopen(ar[1],"rb")) == NULL)
  21543.            {
  21544.            fprintf(stderr, "Can't open %s\n", ar[1]);
  21545.            exit(1);
  21546.            }
  21547.  
  21548.       if ((mode = Getvmode()) == TEXTMONO)
  21549.            screen = MONMEM;
  21550.       else if (mode == TEXTC80 || mode == TEXTBW80)
  21551.            screen = CGAMEM;
  21552.       else
  21553.          exit(1);
  21554.  
  21555.       Clearscr();
  21556.       for (offset = 0; offset < CHARS; offset++)
  21557.            {
  21558.            fread(&char_attr, 2, 1, save);
  21559.            screen[offset] = char_attr;
  21560.            }
  21561.       fclose(save);
  21562.       Setcurs(23, 0, PAGE);
  21563.       getch();   /* anti scrolling for QC environment */
  21564.  }
  21565.  
  21566.  
  21567.  RECEIPTS.C
  21568.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\RECEIPTS.C
  21569.  
  21570.  /* receipts.c -- calculates gross and net */
  21571.  /*               receipts on sales        */
  21572.  
  21573.  main()
  21574.  {
  21575.      int units = 38;       /* number sold */
  21576.      float price = 149.99, /* price per item */
  21577.      rate = 0.06;          /* sales tax rate */
  21578.  
  21579.      /* variables to hold calculated totals */
  21580.      float gross, tax, net;
  21581.  
  21582.      /* perform calculations */
  21583.      net = units * price;
  21584.      tax = net * rate;
  21585.      gross = net + tax;
  21586.  
  21587.      /* print results */
  21588.      printf("\tSales Report\n");
  21589.      printf("Net sales: \t%6.2f\n", net);
  21590.      printf("Tax:\t\t %5.2f\n", tax);
  21591.      printf("Gross sales:\t%6.2f\n", gross);
  21592.  }
  21593.  
  21594.  
  21595.  RECT.C
  21596.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\RECT.C
  21597.  
  21598.  /*  rect.c -- illustrates logical coordinates,         */
  21599.  /*            the _rectangle() and _setlinestyle()     */
  21600.  /*            functions                                */
  21601.  /* If you load graphics.qlb, no program list is needed */
  21602.  
  21603.  #include <stdio.h>
  21604.  #include <graph.h>
  21605.  #include <conio.h>
  21606.  #define STYLES 5
  21607.  short Linestyles[STYLES] = {0xFFFF, 0x8888, 0x7777,
  21608.                              0x00FF, 0x8787};
  21609.  
  21610.  main(argc, argv)
  21611.  int argc;
  21612.  char *argv[];
  21613.  {
  21614.      struct videoconfig vc;
  21615.      int mode = _MRES4COLOR;
  21616.      int xcent, ycent;
  21617.      int xsize, ysize;
  21618.      int i;
  21619.  
  21620.      if (argc > 1)
  21621.          mode = atoi(argv[1]);
  21622.      if (_setvideomode(mode) == 0)
  21623.      {
  21624.          printf("Can't open that mode.\n");
  21625.          exit(1);
  21626.      }
  21627.      _getvideoconfig(&vc);
  21628.      xcent = vc.numxpixels / 2 - 1;
  21629.      ycent = vc.numypixels / 2 - 1;
  21630.      _setlogorg(xcent, ycent);
  21631.      xsize = 0.9 * xcent;
  21632.      ysize = 0.9 * ycent;
  21633.      _selectpalette(1);
  21634.      _setcolor(3);
  21635.      _rectangle(_GBORDER, -xsize, -ysize, xsize, ysize);
  21636.      xsize *= 0.9;
  21637.      ysize *= 0.9;
  21638.      _setcolor(1);
  21639.      _rectangle(_GFILLINTERIOR, -xsize, -ysize, xsize, ysize);
  21640.      for (i = 0; i < 16; i++)
  21641.      {
  21642.          _setcolor(((i % 2) == 0) ? 2 : 3);
  21643.          _setlinestyle(Linestyles[ i % 5 ]);
  21644.          xsize *= 0.9;
  21645.          ysize *= 0.9;
  21646.          _rectangle(_GBORDER, -xsize, -ysize, xsize, ysize);
  21647.      }
  21648.      getch();      /* Type a key to terminate. */
  21649.      _setvideomode(_DEFAULTMODE);
  21650.  }
  21651.  
  21652.  
  21653.  RECURSE.C
  21654.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\RECURSE.C
  21655.  
  21656.  /* recurse.c -- demonstrates recursion */
  21657.  
  21658.  int level = 1; /* recursion level */
  21659.  main()
  21660.  {
  21661.      int num, result;
  21662.  
  21663.      printf("Factorial of what number? ");
  21664.      scanf("%d", &num);
  21665.      result = factorial(num);
  21666.      printf("Result is: %d\n", result);
  21667.  }
  21668.  
  21669.  factorial(number)
  21670.  {
  21671.      int result;
  21672.      printf("entering: ");
  21673.      printf("level %d. number = %d. &number = %d\n",
  21674.              level++, number, &number);
  21675.  
  21676.      if (number == 0)
  21677.          result = 1;
  21678.      else
  21679.          result = number * factorial(number - 1);
  21680.  
  21681.      printf("exiting : ");
  21682.      printf("level %d. number = %d. &number = %d. ",
  21683.              --level, number, &number);
  21684.      printf("result = %d\n", result);
  21685.  
  21686.      return(result);
  21687.  }
  21688.  
  21689.  
  21690.  REKEY.C
  21691.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\REKEY.C
  21692.  
  21693.  /* rekey.c -- transliterates typed input             */
  21694.  /*    This program illustrates getch() and putch().  */
  21695.  
  21696.  #include <stdio.h>
  21697.  #include <conio.h>
  21698.  #include <ctype.h>
  21699.  ESC '\033'   /* the escape key */
  21700.  char Newchars[] = "qwertyuiopasdfghjklzxcvbnm";
  21701.   /* values to be assigned to the a,b,c keys, etc. */
  21702.  main()
  21703.  {
  21704.      char ch;
  21705.  
  21706.      printf("Type characters and see them transformed;\n");
  21707.      printf("Press the Esc key to terminate.\n");
  21708.      while ((ch = getch()) != ESC)
  21709.          if (islower(ch))
  21710.              putch(Newchars[ch - 'a']);
  21711.          else if (isupper(ch))
  21712.              {
  21713.              ch = tolower(ch);
  21714.              putch(toupper(Newchars[ch - 'a']));
  21715.              }
  21716.          else if (ch == '\r')
  21717.              {
  21718.              putch('\n');
  21719.              putch('\r');
  21720.              }
  21721.          else
  21722.              putch(ch);
  21723.  }
  21724.  
  21725.  
  21726.  RELATION.C
  21727.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\RELATION.C
  21728.  
  21729.  /* relation.c -- shows effect of      */
  21730.  /*               relational operators */
  21731.  
  21732.  main()
  21733.  {
  21734.      int a = 5, b = 3, c = 4;
  21735.      printf("a = %d\t b = %d\t c = %d\n", a, b, c);
  21736.  
  21737.      printf("Expression a > b has a value of %d\n",
  21738.              a > b);
  21739.      printf("Expression a == c has a value of %d\n",
  21740.              a == c);
  21741.      printf("Expression a > (b + c) has a value of %d\n",
  21742.              a > (b + c));
  21743.      printf("Expression a = b has a value of %d\n",
  21744.              a = b); /* what happened here? */
  21745.  }
  21746.  
  21747.  
  21748.  REMOIRE.C
  21749.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\REMOIRE.C
  21750.  
  21751.  /* remoire.c -- adds palette remapping to moire.c      */
  21752.  #include <conio.h>
  21753.  #include <stdio.h>
  21754.  #include <stdlib.h>
  21755.  #include <graph.h>
  21756.  #define ESC '\033'
  21757.  #define MAXCOLORS 64
  21758.  #define PALCOLORS 16
  21759.  long Ega_to_vga(int);
  21760.  
  21761.  main (argc, argv)
  21762.  int argc;
  21763.  char *argv[];
  21764.  {
  21765.      struct videoconfig vc;
  21766.      unsigned int col, row;
  21767.      long colors[MAXCOLORS];
  21768.      long palette[PALCOLORS];
  21769.      int index;
  21770.      int shift = 1;
  21771.      int firstcol, firstrow, lastrow, lastcol;
  21772.      int mode = _ERESCOLOR;
  21773.  
  21774.  
  21775.      if (argc > 1)
  21776.          mode = atoi(argv[1]);
  21777.  
  21778.      if (_setvideomode(mode) == 0)
  21779.          {
  21780.          printf("Can't do that mode.\n");
  21781.          exit(1);
  21782.          }
  21783.      /* Create array of all 64 color values. */
  21784.      for (index = 0; index < MAXCOLORS; index++)
  21785.          colors[index] = Ega_to_vga(index);
  21786.      /* Create array of 16 palette choices. */
  21787.      for (index = 0; index < PALCOLORS; index++)
  21788.          palette[index] = colors[index];
  21789.      _remapallpalette(palette);
  21790.      _getvideoconfig(&vc);
  21791.      firstcol = vc.numxpixels / 5;
  21792.      firstrow = vc.numypixels / 5;
  21793.      lastcol = 4 * vc.numxpixels / 5;
  21794.      lastrow = 4 * vc.numypixels / 5;
  21795.  
  21796.      for (col = firstcol; col <= lastcol; ++col)
  21797.          {
  21798.          for (row = firstrow; row <= lastrow; ++row)
  21799.              {
  21800.              _setcolor(((row * row + col * col) / 10)
  21801.                         % vc.numcolors);
  21802.              _setpixel(col, row);
  21803.              }
  21804.          }
  21805.      _settextposition(1, 1);
  21806.      _outtext("Type a key to stop or start.");
  21807.      _settextposition(2, 1);
  21808.      _outtext("Type [Esc] while paused to quit.");
  21809.      do
  21810.          {
  21811.          while (!kbhit())
  21812.              {
  21813.              /*  Set palette array to new color values. */
  21814.              for (index = 1; index < PALCOLORS; index++)
  21815.                  palette[index] = (colors[(index + shift)
  21816.                                    % MAXCOLORS]);
  21817.              _remapallpalette(palette);
  21818.              shift++;
  21819.               }
  21820.           getch();  /* pause until key is typed */
  21821.          }  while (getch() != ESC);
  21822.  
  21823.      _setvideomode(_DEFAULTMODE);  /* reset orig. mode */
  21824.  }
  21825.  
  21826.  long Ega_to_vga(egacolor)
  21827.  int egacolor;       /* ega color value */
  21828.  {
  21829.      static long vgavals[6] = {0x2A0000L, 0x002A00L, 0x00002AL,
  21830.                                0x150000L, 0x001500L, 0x000015L};
  21831.      long vgacolor = 0L; /* vga color value */
  21832.      int bit;
  21833.  
  21834.      for (bit = 0; bit < 6; bit++)
  21835.          vgacolor += ((egacolor >> bit) &1) * vgavals[bit];
  21836.      return (vgacolor);
  21837.  }
  21838.  
  21839.  
  21840.  REVERSE.C
  21841.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\REVERSE.C
  21842.  
  21843.  /* reverse.c -- demonstrates an array of pointers     */
  21844.  /*              by reversing lines of text            */
  21845.  
  21846.  <stdio.h>         /* for NULL   */
  21847.  <malloc.h>        /* for size_t */
  21848.  
  21849.  #define MAXL 20
  21850.  
  21851.  main()
  21852.  {
  21853.      char *cptrs[MAXL];     /* array of pointers */
  21854.      char *cp;
  21855.      int count, i, j, ch;
  21856.      extern char *Getbyte();
  21857.  
  21858.  
  21859.      printf("Type in several lines of text, and I will\n");
  21860.      printf("print them back out in reverse order.\n");
  21861.      printf("(Any blank line ends input):\n");
  21862.  
  21863.      for (i = 0; i < MAXL; ++i)
  21864.          {
  21865.          cp = Getbyte();
  21866.          cptrs[i] = cp;     /* assign address to pointer */
  21867.          count = 0;
  21868.          while ((ch = getchar()) != '\n') /* gather line */
  21869.              {
  21870.              *cp = ch;
  21871.              cp = Getbyte();
  21872.              ++count;
  21873.              }
  21874.          *cp = '\0';
  21875.          if (count == 0)    /* all done if blank line */
  21876.              break;
  21877.          }
  21878.      printf("---------<reversed>---------\n");
  21879.      for (j = i-1; j >= 0; --j)
  21880.          {
  21881.          printf("%s\n", cptrs[j]);
  21882.          }
  21883.  }
  21884.  
  21885.  char *Getbyte(void)
  21886.  {
  21887.      char *cp;
  21888.  
  21889.      if ((cp = sbrk(1)) == (char *)-1)
  21890.          {
  21891.          printf("Panic: sbrk failed\n");
  21892.          exit(1);
  21893.          }
  21894.      return (cp);
  21895.  }
  21896.  
  21897.  
  21898.  REVERSE2.C
  21899.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\REVERSE2.C
  21900.  
  21901.  /* reverse2.c -- demonstrates a pointer to a pointer  */
  21902.  
  21903.  <stdio.h>         /* for NULL   */
  21904.  <malloc.h>        /* for size_t */
  21905.  
  21906.  #define MAXL 20
  21907.  
  21908.  main()
  21909.  {
  21910.      char *cptrs[MAXL];
  21911.      char **pp;             /* pointer to pointer */
  21912.      char *cp;
  21913.      int count, i, ch;
  21914.      extern char *Getbyte();
  21915.  
  21916.      printf("Type in several lines of text, and I will\n");
  21917.      printf("print them back out in reverse order.\n");
  21918.      printf("(Any blank line ends input):\n");
  21919.  
  21920.      for (i = 0; i < MAXL; ++i)
  21921.          {
  21922.          cp = Getbyte();
  21923.          cptrs[i] = cp;     /* assign address to pointer */
  21924.          count = 0;
  21925.          while ((ch = getchar()) != '\n') /* gather line */
  21926.              {
  21927.              *cp = ch;
  21928.              cp = Getbyte();
  21929.              ++count;
  21930.              }
  21931.          *cp = '\0';
  21932.          if (count == 0)    /* all done if blank line */
  21933.              break;
  21934.          }
  21935.      printf("---------<reversed>---------\n");
  21936.      pp = &cptrs[i];
  21937.      while (pp >= cptrs)
  21938.          {
  21939.          printf("%s\n", *(pp--));
  21940.          }
  21941.  }
  21942.  
  21943.  char *Getbyte(void)
  21944.  {
  21945.      char *cp;
  21946.  
  21947.      if ((cp = sbrk(1)) == (char *)-1)
  21948.          {
  21949.          printf("Panic: sbrk failed\n");
  21950.          exit(1);
  21951.          }
  21952.      return (cp);
  21953.  }
  21954.  
  21955.  
  21956.  RIGHTSTR.C
  21957.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\RIGHTSTR.C
  21958.  
  21959.  /* rightstr.c -- a C version of BASIC's RIGHT$ */
  21960.  
  21961.  #include <stdio.h>
  21962.  
  21963.  char *Rightstr(char *str, int cnt)
  21964.  {
  21965.      static char *cp = NULL;
  21966.      char *malloc();
  21967.  
  21968.      if (cnt > strlen(str))
  21969.          cnt = strlen(str);
  21970.      if (cp != NULL)
  21971.          free(cp);
  21972.      if ((cp = malloc(cnt + 1)) == NULL)
  21973.          return (NULL);
  21974.      strcpy(cp, str + strlen(str) - cnt);
  21975.      return (cp);
  21976.  }
  21977.  
  21978.  
  21979.  RINGS.C
  21980.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\RINGS.C
  21981.  
  21982.  /*  rings.c -- shoots colored rings                   */
  21983.  /*  This program illustrates _remapallpalette() and   */
  21984.  /*  how it can be used to produce the appearance of   */
  21985.  /*  motion. The program is intended for EGA modes 13, */
  21986.  /*  14, and 16.                                       */
  21987.  /* Program list: rings.c                              */
  21988.  /* If you load graphics.qlb, no program list is needed*/
  21989.  
  21990.  #include <stdio.h>
  21991.  #include <stdlib.h>
  21992.  #include <conio.h>
  21993.  #include <graph.h>
  21994.  #define ESC '\033'
  21995.  
  21996.  long Colors[16] = {_BLACK, _BLUE, _GREEN, _CYAN,
  21997.                   _RED, _MAGENTA, _BROWN, _WHITE,
  21998.                   _GRAY, _LIGHTBLUE, _LIGHTGREEN,
  21999.                   _LIGHTCYAN, _LIGHTRED, _LIGHTMAGENTA,
  22000.                   _LIGHTYELLOW,_BRIGHTWHITE };
  22001.  
  22002.  main(argc, argv)
  22003.  int argc;
  22004.  char *argv[];
  22005.  {
  22006.      struct videoconfig vc;
  22007.      float aspect;
  22008.      short xmax, ymax;
  22009.      long int newpalette[16];
  22010.      long int temp;
  22011.      int index;
  22012.      int hot1 = 1;  /* first colored ring  */
  22013.      int hot2 = 8;  /* second colored ring */
  22014.      int mode = _ERESCOLOR;
  22015.      int ch;
  22016.  
  22017.      if (argc > 1)
  22018.          mode = atoi(argv[1]);
  22019.      if (mode < 13)
  22020.      {
  22021.          fprintf(stderr,"Requires EGA or VGA mode\n");
  22022.          exit(1);
  22023.      }
  22024.      if (_setvideomode(mode) == 0)
  22025.      {
  22026.          fprintf(stderr,"% d mode unavailable\n", mode);
  22027.          exit(2);
  22028.      }
  22029.      _getvideoconfig(&vc);
  22030.      _setlogorg(vc.numxpixels / 2 - 1, vc.numypixels / 2 - 1);
  22031.      aspect = (10.0 * vc.numypixels) / (6.5 * vc.numxpixels);
  22032.      ymax = vc.numypixels / 2 - 2;
  22033.      xmax = ymax / aspect;
  22034.      for (index = 2; index < 16; index++)
  22035.          newpalette[index] = _LIGHTBLUE;
  22036.      newpalette[0] = _GRAY;
  22037.      newpalette[hot1] = _RED;
  22038.      newpalette[hot2] = _LIGHTRED;
  22039.      _remapallpalette(newpalette);  /* set initial palette */
  22040.      _setcolor(1);
  22041.      _ellipse(_GFILLINTERIOR, -xmax, -ymax, xmax, ymax);
  22042.      /* draw concentric circles */
  22043.      for (index = 2; index < 16; index++)
  22044.          {
  22045.          xmax /= 1.4;
  22046.          ymax /= 1.4;
  22047.          _setcolor(index);
  22048.          _ellipse(_GFILLINTERIOR, -xmax, -ymax, xmax, ymax);
  22049.          }
  22050.      do
  22051.          {
  22052.          while (!kbhit())
  22053.              {
  22054.              temp = newpalette[15];
  22055.              for(index = 15; index > 1; index--)
  22056.                  newpalette[index] = newpalette[index - 1];
  22057.              newpalette[1] = temp;
  22058.              _remapallpalette(newpalette);
  22059.              hot1 = hot1 % 15 + 1;  /* index of colored ring */
  22060.              hot2 = hot2 % 15 + 1;
  22061.              }
  22062.          ch = getch();
  22063.          if (ch > '1' && ch < '8')  /* reassign colors */
  22064.              {
  22065.              newpalette[hot1] = Colors[ ch - '0'];
  22066.              newpalette[hot2] = Colors[ ch - '0' + 8];
  22067.              }
  22068.           } while (ch != ESC);
  22069.      _clearscreen(_GCLEARSCREEN);
  22070.      _setvideomode(_DEFAULTMODE);
  22071.  }
  22072.  
  22073.  
  22074.  ROAMSCRN.C
  22075.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\ROAMSCRN.C
  22076.  
  22077.  /*   roamscrn.c  -- puts text on screen, positions    */
  22078.  /*                  cursor with arrow keys, uses F1   */
  22079.  /*                  and F2 to control video inverse.  */
  22080.  /*   program list -- roamscreen.c, scrfun.lib         */
  22081.  /*   user include files -- keys.h, scrn.h             */
  22082.  /*  Note: Activate Screen Swapping On in Debug menu   */
  22083.  #include <conio.h>
  22084.  #include "keys.h"
  22085.  #include "scrn.h"
  22086.  #define BELL '\a'
  22087.  #define ESC '\033'
  22088.  #define PAGE 0
  22089.  
  22090.  char *Heading =
  22091.  "Use standard keys to enter text. Use arrow keys to "
  22092.  "reposition cursor.\nUse F2 to turn on video inverse "
  22093.  "and F1 to turn it off.\nHit the ESC key to quit.\n";
  22094.  
  22095.  main()
  22096.  {
  22097.      int ch;
  22098.      unsigned char atr = NORMAL;
  22099.  
  22100.      Clearscr();
  22101.      Home();
  22102.      printf("%s", Heading);
  22103.      while ((ch = getch()) != ESC)
  22104.          {
  22105.          if (ch == '\r')
  22106.              {
  22107.              putch('\n');
  22108.              putch('\r');
  22109.              }
  22110.          else if (ch != 0)
  22111.              {
  22112.                 Write_ch_atr(ch, atr, PAGE, 1);
  22113.              if (!Cursrt())
  22114.                  putch(BELL);
  22115.              }
  22116.          else
  22117.              {
  22118.              ch = getch();
  22119.              switch (ch)
  22120.                  {
  22121.                  case F1 : atr = NORMAL; break;
  22122.                  case F2 : atr = VIDREV; break;
  22123.                      case UP : Rewrite(atr, PAGE);
  22124.                            if (!Cursup())
  22125.                              putch(BELL);
  22126.                            break;
  22127.                      case DN : Rewrite(atr, PAGE);
  22128.                            if (!Cursdn())
  22129.                              putch(BELL);
  22130.                            break;
  22131.                      case LT : Rewrite(atr, PAGE);
  22132.                            if (!Curslt())
  22133.                              putch(BELL);
  22134.                            break;
  22135.                      case RT : Rewrite(atr, PAGE);
  22136.                            if (!Cursrt())
  22137.                              putch(BELL);
  22138.                            break;
  22139.                  default : break;
  22140.                  }
  22141.              }
  22142.          }
  22143.  }
  22144.  
  22145.  
  22146.  ROLO.C
  22147.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP11\ROLO.C
  22148.  
  22149.  /* rolo.c  --  demonstrates pointers to structures     */
  22150.  
  22151.  <stdio.h>      /* for NULL  and stdin */
  22152.  <string.h>     /* for strdup()        */
  22153.  
  22154.  #define MAXN 79
  22155.  #define MAXCARDS 3
  22156.  
  22157.  struct cardstruct {                 /* global pattern */
  22158.      char first[MAXN],
  22159.           last[MAXN],
  22160.           middle[MAXN];
  22161.      unsigned long street_no;
  22162.      char street[MAXN],
  22163.           city[MAXN],
  22164.           state[MAXN];
  22165.      unsigned long zip;
  22166.      unsigned int area;
  22167.      unsigned long phone;
  22168.  };
  22169.  
  22170.  struct cardstruct cards[MAXCARDS];
  22171.  
  22172.  main()
  22173.  {
  22174.      int i;
  22175.  
  22176.      for (i = 0; i < MAXCARDS; ++i)
  22177.          {
  22178.          printf("\n<card %d of %d>\n", i + 1, MAXCARDS);
  22179.          Input(&cards[i]);
  22180.          }
  22181.      for (i = 0; i < MAXCARDS; ++i)
  22182.          {
  22183.          printf("\n<%d> ", i + 1);
  22184.          Showcard(&cards[i]);
  22185.          }
  22186.  }
  22187.  
  22188.  Input(struct cardstruct *cardp)
  22189.  {
  22190.      char *Str_Input();
  22191.      long Lint_Input();
  22192.  
  22193.      strcpy(cardp->first,Str_Input("First Name"));
  22194.      strcpy(cardp->last,Str_Input("Last Name"));
  22195.      strcpy(cardp->middle,Str_Input("Middle Name"));
  22196.      cardp->street_no = Lint_Input("Street Number");
  22197.      strcpy(cardp->street,Str_Input("Street"));
  22198.      strcpy(cardp->city,Str_Input("City"));
  22199.      strcpy(cardp->state,Str_Input("State"));
  22200.      cardp->zip = Lint_Input("Zip Code");
  22201.      cardp->area = (int)Lint_Input("Area Code");
  22202.      cardp->phone = Lint_Input("Phone Number");
  22203.  }
  22204.  
  22205.  char *Str_Input(char *prompt)
  22206.  {
  22207.      char buf[MAXN + 1], *ptr;
  22208.  
  22209.      printf("%s: ", prompt);
  22210.      if (fgets(buf, MAXN, stdin) == NULL)
  22211.          exit(0);
  22212.      buf[strlen(buf) - 1] = '\0'; /* strip '\n' */
  22213.      if (strlen(buf) == 0)
  22214.          exit(0);
  22215.      if ((ptr = strdup(buf)) == NULL)
  22216.          exit(0);
  22217.      return (ptr);
  22218.  }
  22219.  
  22220.  long Lint_Input(char *prompt)
  22221.  {
  22222.      char buf[MAXN + 1];
  22223.      long  num;
  22224.  
  22225.      printf("%s: ", prompt);
  22226.      if (fgets(buf, MAXN, stdin) == NULL)
  22227.          exit(0);
  22228.      if (sscanf(buf, "%ld", &num) != 1)
  22229.          exit(0);
  22230.      return (num);
  22231.  }
  22232.  
  22233.  Showcard(struct cardstruct *cardptr)
  22234.  {
  22235.      printf("\n\n");
  22236.      printf("%s %s %s\n", cardptr->first, cardptr->middle,
  22237.              cardptr->last);
  22238.      printf("%ld %s, %s, %s %ld\n", cardptr->street_no,
  22239.              cardptr->street, cardptr->city, cardptr->state,
  22240.              cardptr->zip);
  22241.      printf("(%d) %ld\n", cardptr->area, cardptr->phone);
  22242.  }
  22243.  
  22244.  
  22245.  ROLO2.C
  22246.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP11\ROLO2.C
  22247.  
  22248.  /* rolo2.c --  demonstrates a linked list */
  22249.  
  22250.  <stdio.h>      /* for NULL  and stdin */
  22251.  <string.h>     /* for strdup()        */
  22252.  <malloc.h>     /* for malloc()        */
  22253.  
  22254.  #define MAXN 79
  22255.  
  22256.  struct cardstruct {          /* global pattern */
  22257.      char first[MAXN],
  22258.           last[MAXN],
  22259.           middle[MAXN];
  22260.      unsigned long street_no;
  22261.      char street[MAXN],
  22262.           city[MAXN],
  22263.           state[MAXN];
  22264.      unsigned long zip;
  22265.      unsigned int area;
  22266.      unsigned long phone;
  22267.      struct   cardstruct *nextcard;
  22268.  };
  22269.  
  22270.  main()
  22271.  {
  22272.      int i;
  22273.      struct cardstruct card, *first, *current;
  22274.  
  22275.      first = (struct cardstruct *)malloc(sizeof(struct cardstruct));
  22276.      if(first == NULL)
  22277.          exit(1);
  22278.      if (Input(&card) != 0)
  22279.          exit(1);
  22280.      *first = card;
  22281.      current = first;
  22282.  
  22283.      while (Input(&card) == 0)
  22284.          {
  22285.          current->nextcard =
  22286.              (struct cardstruct *)malloc(sizeof(struct cardstruct));
  22287.          if(current->nextcard == NULL)
  22288.              exit(1);
  22289.          current = current->nextcard;
  22290.          *current = card;
  22291.          }
  22292.      current->nextcard = NULL;
  22293.  
  22294.      Dumplist(first);
  22295.  }
  22296.  
  22297.  Dumplist(struct cardstruct *head)
  22298.  {
  22299.      do
  22300.          {
  22301.          Showcard(head);
  22302.          } while ((head = head->nextcard) != NULL);
  22303.  }
  22304.  
  22305.  Showcard(struct cardstruct *cardptr)
  22306.  {
  22307.      printf("\n\n");
  22308.  
  22309.      printf("%s %s %s\n", cardptr->first, cardptr->middle,
  22310.              cardptr->last);
  22311.      printf("%ld %s, %s, %s %ld\n", cardptr->street_no,
  22312.              cardptr->street, cardptr->city, cardptr->state,
  22313.              cardptr->zip);
  22314.      printf("(%d) %ld\n", cardptr->area, cardptr->phone);
  22315.  }
  22316.  
  22317.  Input(struct cardstruct *cardp)
  22318.  {
  22319.      char *Str_Input();
  22320.      long Lint_Input();
  22321.  
  22322.      printf("\n<new card> (Empty first name Quits)\n");
  22323.      strcpy(cardp->first,Str_Input("First Name"));
  22324.      if (*(cardp->first) == '\0')
  22325.          return (1);
  22326.      strcpy(cardp->last,Str_Input("Last Name"));
  22327.      strcpy(cardp->middle,Str_Input("Middle Name"));
  22328.      cardp->street_no = Lint_Input("Street Number");
  22329.      strcpy(cardp->street,Str_Input("Street"));
  22330.      strcpy(cardp->city,Str_Input("City"));
  22331.      strcpy(cardp->state,Str_Input("State"));
  22332.      cardp->zip = Lint_Input("Zip Code");
  22333.      cardp->area = (int)Lint_Input("Area Code");
  22334.      cardp->phone = Lint_Input("Phone Number");
  22335.      return (0);
  22336.  }
  22337.  
  22338.  char *Str_Input(char *prompt)
  22339.  {
  22340.      char buf[MAXN + 1], *ptr;
  22341.  
  22342.      printf("%s: ", prompt);
  22343.      if (fgets(buf, MAXN, stdin) == NULL)
  22344.          exit(0);
  22345.      buf[strlen(buf) - 1] = '\0'; /* strip '\n' */
  22346.      if ((ptr = strdup(buf)) == NULL)
  22347.          exit(0);
  22348.      return (ptr);
  22349.  }
  22350.  
  22351.  long Lint_Input(char *prompt)
  22352.  {
  22353.      char buf[MAXN + 1];
  22354.      long  num;
  22355.  
  22356.      printf("%s: ", prompt);
  22357.      if (fgets(buf, MAXN, stdin) == NULL)
  22358.          exit(0);
  22359.      if (sscanf(buf, "%ld", &num) != 1)
  22360.          num = 0;
  22361.      return (num);
  22362.  }
  22363.  
  22364.  
  22365.  SADD.C
  22366.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP07\SADD.C
  22367.  
  22368.  /* sadd.c -- a small adding machine that illustrates  */
  22369.  /*           the need for array bounds checking.      */
  22370.  
  22371.  main()
  22372.  {
  22373.      int offset = 0, i, result = 0;
  22374.      int stack[3];
  22375.  
  22376.      while (scanf("%d", &stack[offset]) == 1)
  22377.          {
  22378.          ++offset;
  22379.          }
  22380.      for (i = 0; i < offset; ++i)
  22381.          {
  22382.          result += stack[i];
  22383.          }
  22384.      printf("-------------\n");
  22385.      printf("%d\n", result);
  22386.  
  22387.  }
  22388.  
  22389.  
  22390.  SADD2.C
  22391.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP07\SADD2.C
  22392.  
  22393.  /* sadd2.c -- a small adding machine that includes */
  22394.  /*            array bounds checking.               */
  22395.  
  22396.  #define MAXSTAK 3
  22397.  
  22398.  main()
  22399.  {
  22400.      int offset = 0, i, result = 0;
  22401.      int stack[MAXSTAK];
  22402.  
  22403.      while (scanf("%d", &stack[offset]) == 1)
  22404.          {
  22405.          if (++offset >= MAXSTAK)
  22406.              {
  22407.              printf("Stack Full\n");
  22408.              break;
  22409.              }
  22410.          }
  22411.      for (i = 0; i < offset; ++i)
  22412.          {
  22413.          result += stack[i];
  22414.          }
  22415.      printf("-------------\n");
  22416.      printf("%d\n", result);
  22417.  
  22418.  }
  22419.  
  22420.  
  22421.  SAVEGRAF.C
  22422.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\SAVEGRAF.C
  22423.  
  22424.  /* savegraf.c -- uses DMA to save screen of graphics  */
  22425.  /*               characters and attributes            */
  22426.  /* Program list - savegraf.c, initstuf.c, drawchar.c, */
  22427.  /*                savescrn.c, scrfun.c                */
  22428.  /* User include files - scrn.h, keys.h, grafchar.h    */
  22429.  /* Note: activate Screen Swapping On in Debug menu    */
  22430.  
  22431.  
  22432.  #include "grafchar.h"
  22433.  unsigned char Grchr[NUMCHARS];  /* to store graphics set */
  22434.  void Init_stuff(void);
  22435.  void Draw_chars(void);
  22436.  void Save_screen(void);  /* in savescrn.c */
  22437.  
  22438.  main()
  22439.  {
  22440.      int ch;
  22441.  
  22442.      Init_stuff();  /* initialize vital elements */
  22443.      Draw_chars();  /* map keys to graphics characters */
  22444.      Setcurs(BOTLINE + 1, 0, PAGE);
  22445.      printf("%-80s", "Save screen? <y/n> ");
  22446.      Setcurs(BOTLINE + 1, 20, PAGE);
  22447.      ch = getche();
  22448.      if (ch == 'y' || ch == 'Y')
  22449.          Save_screen();
  22450.      Setcurs(BOTLINE + 2, 0, PAGE);
  22451.      printf("%-80s\n", "BYE!");
  22452.  }
  22453.  
  22454.  
  22455.  SAVESCRN.C
  22456.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\SAVESCRN.C
  22457.  
  22458.  /* savescrn.c -- saves screen, including attribute    */
  22459.  /*               values, in a file                    */
  22460.  /*               Uses direct memory access.           */
  22461.  
  22462.  <stdio.h>  /* for file-handling */
  22463.  #include "scrn.h"
  22464.  #include "grafchar.h"
  22465.  void Save_screen()
  22466.  {
  22467.      FILE *save;
  22468.      char filename[80];
  22469.      unsigned char mode;
  22470.      unsigned short char_attr;  /* character,attribute */
  22471.      int offset;
  22472.      VIDMEM screen;
  22473.  
  22474.       if ((mode = Getvmode()) == TEXTMONO)
  22475.            screen = MONMEM;
  22476.       else if (mode == TEXTC80 || mode == TEXTBW80)
  22477.            screen = CGAMEM;
  22478.       else
  22479.          exit(1);
  22480.      Setcurs(BOTLINE + 1, 0, PAGE);
  22481.      printf("Please enter name for save file: ");
  22482.      scanf("%s", filename);
  22483.      if ((save = fopen(filename,"wb")) == NULL)
  22484.          {
  22485.          fprintf(stderr,"Can't open %s\n", filename);
  22486.          exit(1);
  22487.          }
  22488.     for (offset = 0; offset < CHARS; offset++)
  22489.          {
  22490.          char_attr = screen[offset];
  22491.          fwrite(&char_attr, 2, 1, save);
  22492.          }
  22493.     fclose(save);
  22494.  }
  22495.  
  22496.  
  22497.  SCANCODE.C
  22498.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\SCANCODE.C
  22499.  
  22500.  /*   scancode.c -- displays ASCII or scan code         */
  22501.  /*   This program illustrates using getch() to detect  */
  22502.  /*   special keys such as function keys.               */
  22503.  
  22504.  #include <conio.h>
  22505.  ESC '\033'     /* ESC key */
  22506.  main()
  22507.  {
  22508.       int ch;
  22509.  
  22510.       printf("Strike keys and see the codes!\n");
  22511.       printf("Press the Esc key to quit.\n");
  22512.  
  22513.       while ((ch = getch()) != ESC)
  22514.            {
  22515.            if (ch != 0)
  22516.                 {
  22517.                 if (ch <= 32)    /* control characters */
  22518.                      printf("^%c has ASCII code %d\n",
  22519.                              ch + 64, ch);
  22520.                 else
  22521.                      printf("%c has ASCII code %d\n", ch, ch);
  22522.                 }
  22523.            else              /* ch IS 0 */
  22524.                 {
  22525.                 ch = getch();  /* get scan code */
  22526.                 printf("Scan code is %d\n", ch);
  22527.                 }
  22528.            }
  22529.  }
  22530.  
  22531.  
  22532.  SCANLINE.C
  22533.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\SCANLINE.C
  22534.  
  22535.  /* scanline.c  -- demonstrates how scanf() reads  */
  22536.  /*                the individual words of a line  */
  22537.  
  22538.  #define INTRO \
  22539.  "Type in lines of text. They will be printed out\n\
  22540.  one word per line, thus demonstrating scanf().\n\
  22541.  (Type Ctrl-Z to Quit)\n"
  22542.  
  22543.  main()
  22544.  {
  22545.      char buf[512];    /* should be big enough */
  22546.  
  22547.      printf(INTRO);
  22548.  
  22549.      /*
  22550.       * scanf() returns the number of items
  22551.       * its control string matched.
  22552.       */
  22553.      while (scanf("%s", buf) == 1)
  22554.          {
  22555.          printf("%s\n", buf);
  22556.          }
  22557.  
  22558.  }
  22559.  
  22560.  
  22561.  SCAPE.C
  22562.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\SCAPE.C
  22563.  
  22564.  /* scape.c -- uses nondefault EGA colors              */
  22565.  /* If you load graphics.qlb, no program list is needed.*/
  22566.  
  22567.  #include <stdio.h>
  22568.  #include <graph.h>
  22569.  #include "egacolor.h"
  22570.  #include <stdlib.h>
  22571.  #include <conio.h>
  22572.  #define SKY (b | B | g)
  22573.  #define OCEAN b
  22574.  #define SAND (R | g | b)
  22575.  #define SUN (R | G | r | g)
  22576.  
  22577.  main(argc, argv)
  22578.  int argc;
  22579.  char *argv[];
  22580.  {
  22581.      struct videoconfig vc;
  22582.      int mode = _ERESCOLOR;
  22583.      short xmax, ymax, sunx, suny, sunsizex, sunsizey;
  22584.      float ar;
  22585.  
  22586.  
  22587.      if (argc > 1)
  22588.          mode = atoi(argv[1]);
  22589.      if (_setvideomode(mode) == 0)
  22590.          {
  22591.          fprintf(stderr,"mode %d not supported\n", mode);
  22592.          exit(1);
  22593.          }
  22594.      _getvideoconfig(&vc);
  22595.      xmax = vc.numxpixels - 1;
  22596.      ymax = vc.numypixels - 1;
  22597.      sunx = 0.7 * xmax;
  22598.      suny = 0.2 * ymax;
  22599.      ar = (float)(10 * vc.numypixels) / (6.5 * vc.numxpixels);
  22600.      sunsizex = xmax / 30;
  22601.      sunsizey = ar * sunsizex;
  22602.      _remappalette(1, SKY);
  22603.      _remappalette(2, OCEAN);
  22604.      _remappalette(3, SAND);
  22605.      _remappalette(4, SUN);
  22606.      _setcolor(1);
  22607.      _rectangle(_GFILLINTERIOR, 0, 0, xmax, 2 * ymax / 5);
  22608.      _setcolor(4);
  22609.      _ellipse(_GFILLINTERIOR, sunx - sunsizex, suny -
  22610.               sunsizey, sunx + sunsizex, suny + sunsizey);
  22611.      _setcolor(2);
  22612.      _rectangle(_GFILLINTERIOR, 0, 2 * ymax / 5, xmax,
  22613.                 2 * ymax / 3);
  22614.      _setcolor(3);
  22615.      _rectangle(_GFILLINTERIOR, 0, 2 * ymax / 3, xmax, ymax);
  22616.      getch();
  22617.      _setvideomode(_DEFAULTMODE);
  22618.  }
  22619.  
  22620.  
  22621.  SCORE.C
  22622.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\SCORE.C
  22623.  
  22624.  /* score.c -- defines and prints   */
  22625.  /*            int and long vars    */
  22626.  
  22627.  main()
  22628.  {
  22629.      /* declare some int variables and assign values */
  22630.      /* to them in the same statement                */
  22631.  
  22632.      int home = 5, visitors = 2, inning =7, attendance = 31300;
  22633.      long total_attendance = 1135477;  /* long int */
  22634.  
  22635.      /* print out the values */
  22636.  
  22637.      printf("The score after %d innings is \n", inning);
  22638.      printf("Home team %d, Visitors %d.\n\n", home, visitors);
  22639.      printf("The attendance today is %d.\n", attendance);
  22640.      printf("Attendance this year to date is %ld.",
  22641.              total_attendance);
  22642.  }
  22643.  
  22644.  
  22645.  SCRANGE.C
  22646.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\SCRANGE.C
  22647.  
  22648.  /* scrange.c  --  illustrates scanf()'s control */
  22649.  /*                directives                    */
  22650.  
  22651.  main()
  22652.  {
  22653.      char buf[512],    /* should be big enough */
  22654.           dummy[2];    /* for \n and \0        */
  22655.      int  num;
  22656.  
  22657.      do
  22658.          {
  22659.          printf("Running:\n");
  22660.          printf("\tscanf(\"%%d\", &num);\n");
  22661.          printf("\tscanf(\"%%[^\\n]\", buf);\n");
  22662.          printf("\tscanf(\"%%[\\n]\", dummy);\n");
  22663.  
  22664.          printf("\nType enough to satisfy this:\n");
  22665.          printf("(Set num equal to zero to quit)\n");
  22666.  
  22667.          scanf("%d", &num);
  22668.          scanf("%[^\n]", buf);
  22669.          scanf("%[\n]", dummy);
  22670.  
  22671.          printf("\n\tnum = %d\n", num);
  22672.          printf("\tbuf[] = \"%s\"\n", buf);
  22673.          printf("\n\n");
  22674.  
  22675.          } while (num != 0) ;
  22676.  
  22677.  }
  22678.  
  22679.  
  22680.  SCRFUN.C
  22681.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\SCRFUN.C
  22682.  
  22683.  /*  scrfun.c -- contains several video BIOS calls     */
  22684.  /*  Setcurs() sets the cursor position                */
  22685.  /*  Getcurs() gets the cursor postion                 */
  22686.  /*  Setpage() sets the current video page             */
  22687.  /*  Setvmode() sets the video mode                    */
  22688.  /*  Clearscr() clears the screen                      */
  22689.  /*  Read_ch_atr() reads the character and             */
  22690.  /*                attribute at the cursor             */
  22691.  /*  Write_ch_atr() writes a character and             */
  22692.  /*                 attribute at the cursor            */
  22693.  /*  Rewrite() rewrites a screen character             */
  22694.  /*            with a new attribute                    */
  22695.  /*  Getvmode() gets the current video mode            */
  22696.  /*  Getpage() gets the current video page             */
  22697.  /*                                                    */
  22698.  /*  The following functions use Setcurs() to move the */
  22699.  /*  one position at a time up to a limit.             */
  22700.  /*  Curslt_lim() moves cursor one column left         */
  22701.  /*  Cursrt_lim() moves cursor one column right        */
  22702.  /*  Cursup_lim() moves cursor one line up             */
  22703.  /*  Cursdn_lim() moves cursor one line down           */
  22704.  /*                                                    */
  22705.  /*  Programs using these functions should include the */
  22706.  /*  scrn.h file                                       */
  22707.  
  22708.  #include <dos.h>
  22709.  #include "scrn.h"
  22710.  
  22711.  /* sets cursor to row, column, and page */
  22712.  void Setcurs(row, col, page)
  22713.  unsigned char row, col, page;
  22714.  {
  22715.      union REGS reg;
  22716.  
  22717.      reg.h.ah = SETCURSOR;
  22718.      reg.h.dh = row;
  22719.      reg.h.dl = col;
  22720.      reg.h.bh = page;
  22721.      int86(VIDEO, ®, ®);
  22722.  }
  22723.  
  22724.  /* gets current cursor row, column for given page */
  22725.  void Getcurs(pr, pc, page)
  22726.  unsigned char *pr, *pc, page;
  22727.  {
  22728.      union REGS reg;
  22729.  
  22730.      reg.h.ah = GETCURSOR;
  22731.      reg.h.bh = page;
  22732.      int86(VIDEO, ®, ®);
  22733.      *pr = reg.h.dh;  /* row number */
  22734.      *pc = reg.h.dl;   /* column number */
  22735.  }
  22736.  
  22737.  
  22738.  /* sets page to given value */
  22739.  void Setpage(page)
  22740.  unsigned char page;
  22741.  {
  22742.      union REGS reg;
  22743.  
  22744.      reg.h.ah = SETPAGE;
  22745.      reg.h.al = page;
  22746.      int86(VIDEO, ®, ®);
  22747.  }
  22748.  
  22749.  /* sets video mode to given mode */
  22750.  void Setvmode(mode)
  22751.  unsigned char mode;
  22752.  {
  22753.      union REGS reg;
  22754.  
  22755.      reg.h.ah = SETMODE;
  22756.      reg.h.al = mode;
  22757.      int86(VIDEO, ®, ®);
  22758.  }
  22759.  
  22760.  /* clear the screen */
  22761.  void Clearscr()
  22762.  {
  22763.      union REGS reg;
  22764.  
  22765.      reg.h.ah = SCROLL;
  22766.      reg.h.al = 0;
  22767.      reg.h.ch = 0;
  22768.      reg.h.cl = 0;
  22769.      reg.h.dh = ROWS - 1;
  22770.      reg.h.dl = COLS - 1;
  22771.      reg.h.bh = NORMAL;
  22772.      int86(VIDEO, ®, ®);
  22773.  }
  22774.  
  22775.  /* reads the character and attribute at the cursor */
  22776.  /* position on a given page                        */
  22777.  void Read_ch_atr(pc, pa, page)
  22778.  unsigned char *pc, *pa;
  22779.  unsigned char page;
  22780.  {
  22781.      union REGS reg;
  22782.  
  22783.      reg.h.ah = READCHATR;
  22784.      reg.h.bh = page;
  22785.      int86(VIDEO, ®, ®);
  22786.      *pc = reg.h.al;  /* character at cursor */
  22787.      *pa = reg.h.ah;  /* attribute at cursor */
  22788.  }
  22789.  
  22790.  /* writes a given character and attribute at the */
  22791.  /* cursor on a given page for num times          */
  22792.  void Write_ch_atr(ch, atr, page, num)
  22793.  unsigned char ch, atr, page;
  22794.  unsigned int num;
  22795.  {
  22796.      union REGS reg;
  22797.  
  22798.      reg.h.ah = WRITECHATR;
  22799.      reg.h.al = ch;
  22800.      reg.h.bl = atr;
  22801.      reg.h.bh = page;
  22802.      reg.x.cx = num;
  22803.      int86(VIDEO, ®, ®);
  22804.  }
  22805.  
  22806.  /* rewrites the character at the cursor using    */
  22807.  /* attribute at                                  */
  22808.  void Rewrite(at, page)
  22809.  unsigned char at, page;
  22810.  {
  22811.       unsigned char ch, atr;
  22812.  
  22813.       Read_ch_atr(&ch, &atr, page);
  22814.       Write_ch_atr(ch, at, page, 1);
  22815.  }
  22816.  
  22817.  /* obtains the current video mode */
  22818.  unsigned char Getvmode()
  22819.  {
  22820.      union REGS reg;
  22821.  
  22822.      reg.h.ah = GETMODE;
  22823.      int86(VIDEO, ®, ®);
  22824.      return reg.h.al;
  22825.  }
  22826.  
  22827.  /* obtains the current video page */
  22828.  unsigned char Getpage()
  22829.  {
  22830.      union REGS reg;
  22831.  
  22832.      reg.h.ah = GETMODE;
  22833.      int86(VIDEO, ®, ®);
  22834.      return reg.h.bh;
  22835.  }
  22836.  
  22837.  /* moves cursor one column left, but not past */
  22838.  /* the given limit                            */
  22839.  unsigned char Curslt_lim(limit)
  22840.  unsigned char limit;
  22841.  {
  22842.      unsigned char row, col, page;
  22843.      unsigned char status = 1;
  22844.  
  22845.      Getcurs(&row, &col, page = Getpage());
  22846.      if (col > limit)
  22847.          Setcurs(row, col - 1, page);
  22848.      else
  22849.          status = 0;
  22850.      return status;
  22851.  }
  22852.  
  22853.  /* moves cursor one column right, but not past */
  22854.  /* the given limit                             */
  22855.  unsigned char Cursrt_lim(limit)
  22856.  unsigned char limit;
  22857.  {
  22858.      unsigned char row, col, page;
  22859.      unsigned char status = 1;
  22860.  
  22861.      Getcurs(&row, &col, page = Getpage());
  22862.      if (col < limit)
  22863.          Setcurs(row, col + 1, page);
  22864.      else
  22865.          status = 0;
  22866.      return status;
  22867.  }
  22868.  
  22869.  /* move cursor one row down, but not past */
  22870.  /* the given limit                        */
  22871.  unsigned char Cursup_lim(limit)
  22872.  unsigned char limit;
  22873.  {
  22874.      unsigned char row, col, page;
  22875.      unsigned char status = 1;
  22876.  
  22877.      Getcurs(&row, &col, page = Getpage());
  22878.      if (row > limit)
  22879.          Setcurs(row - 1, col, page);
  22880.      else
  22881.          status = 0;
  22882.      return status;
  22883.  }
  22884.  
  22885.  /* move cursor one row down, but not past */
  22886.  /* the given limit                        */
  22887.  unsigned char Cursdn_lim(limit)
  22888.  unsigned char limit;
  22889.  {
  22890.      unsigned char row, col, page;
  22891.      unsigned char status = 1;
  22892.  
  22893.      Getcurs(&row, &col, page = Getpage());
  22894.      if (row < limit)
  22895.          Setcurs(row + 1, col, page);
  22896.      else
  22897.          status = 0;
  22898.      return status;
  22899.  }
  22900.  
  22901.  
  22902.  SCRFUN.C
  22903.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\SCRFUN.C
  22904.  
  22905.  /*  scrfun.c -- contains several video BIOS calls     */
  22906.  /*  Setcurs() sets the cursor position                */
  22907.  /*  Getcurs() gets the cursor postion                 */
  22908.  /*  Setpage() sets the current video page             */
  22909.  /*  Setvmode() sets the video mode                    */
  22910.  /*  Clearscr() clears the screen                      */
  22911.  /*  Read_ch_atr() reads the character and             */
  22912.  /*                attribute at the cursor             */
  22913.  /*  Write_ch_atr() writes a character and             */
  22914.  /*                 attribute at the cursor            */
  22915.  /*  Rewrite() rewrites a screen character             */
  22916.  /*            with a new attribute                    */
  22917.  /*  Getvmode() gets the current video mode            */
  22918.  /*  Getpage() gets the current video page             */
  22919.  /*                                                    */
  22920.  /*  The following functions use Setcurs() to move the */
  22921.  /*  one position at a time up to a limit.             */
  22922.  /*  Curslt_lim() moves cursor one column left         */
  22923.  /*  Cursrt_lim() moves cursor one column right        */
  22924.  /*  Cursup_lim() moves cursor one line up             */
  22925.  /*  Cursdn_lim() moves cursor one line down           */
  22926.  /*                                                    */
  22927.  /*  Programs using these functions should include the */
  22928.  /*  scrn.h file                                       */
  22929.  
  22930.  #include <dos.h>
  22931.  #include "scrn.h"
  22932.  
  22933.  /* sets cursor to row, column, and page */
  22934.  void Setcurs(row, col, page)
  22935.  unsigned char row, col, page;
  22936.  {
  22937.      union REGS reg;
  22938.  
  22939.      reg.h.ah = SETCURSOR;
  22940.      reg.h.dh = row;
  22941.      reg.h.dl = col;
  22942.      reg.h.bh = page;
  22943.      int86(VIDEO, ®, ®);
  22944.  }
  22945.  
  22946.  /* gets current cursor row, column for given page */
  22947.  void Getcurs(pr, pc, page)
  22948.  unsigned char *pr, *pc, page;
  22949.  {
  22950.      union REGS reg;
  22951.  
  22952.      reg.h.ah = GETCURSOR;
  22953.      reg.h.bh = page;
  22954.      int86(VIDEO, ®, ®);
  22955.      *pr = reg.h.dh;  /* row number */
  22956.      *pc = reg.h.dl;   /* column number */
  22957.  }
  22958.  
  22959.  
  22960.  /* sets page to given value */
  22961.  void Setpage(page)
  22962.  unsigned char page;
  22963.  {
  22964.      union REGS reg;
  22965.  
  22966.      reg.h.ah = SETPAGE;
  22967.      reg.h.al = page;
  22968.      int86(VIDEO, ®, ®);
  22969.  }
  22970.  
  22971.  /* sets video mode to given mode */
  22972.  void Setvmode(mode)
  22973.  unsigned char mode;
  22974.  {
  22975.      union REGS reg;
  22976.  
  22977.      reg.h.ah = SETMODE;
  22978.      reg.h.al = mode;
  22979.      int86(VIDEO, ®, ®);
  22980.  }
  22981.  
  22982.  /* clear the screen */
  22983.  void Clearscr()
  22984.  {
  22985.      union REGS reg;
  22986.  
  22987.      reg.h.ah = SCROLL;
  22988.      reg.h.al = 0;
  22989.      reg.h.ch = 0;
  22990.      reg.h.cl = 0;
  22991.      reg.h.dh = ROWS - 1;
  22992.      reg.h.dl = COLS - 1;
  22993.      reg.h.bh = NORMAL;
  22994.      int86(VIDEO, ®, ®);
  22995.  }
  22996.  
  22997.  /* reads the character and attribute at the cursor */
  22998.  /* position on a given page                        */
  22999.  void Read_ch_atr(pc, pa, page)
  23000.  unsigned char *pc, *pa;
  23001.  unsigned char page;
  23002.  {
  23003.      union REGS reg;
  23004.  
  23005.      reg.h.ah = READCHATR;
  23006.      reg.h.bh = page;
  23007.      int86(VIDEO, ®, ®);
  23008.      *pc = reg.h.al;  /* character at cursor */
  23009.      *pa = reg.h.ah;  /* attribute at cursor */
  23010.  }
  23011.  
  23012.  /* writes a given character and attribute at the */
  23013.  /* cursor on a given page for num times          */
  23014.  void Write_ch_atr(ch, atr, page, num)
  23015.  unsigned char ch, atr, page;
  23016.  unsigned int num;
  23017.  {
  23018.      union REGS reg;
  23019.  
  23020.      reg.h.ah = WRITECHATR;
  23021.      reg.h.al = ch;
  23022.      reg.h.bl = atr;
  23023.      reg.h.bh = page;
  23024.      reg.x.cx = num;
  23025.      int86(VIDEO, ®, ®);
  23026.  }
  23027.  
  23028.  /* rewrites the character at the cursor using    */
  23029.  /* attribute at                                  */
  23030.  void Rewrite(at, page)
  23031.  unsigned char at, page;
  23032.  {
  23033.       unsigned char ch, atr;
  23034.  
  23035.       Read_ch_atr(&ch, &atr, page);
  23036.       Write_ch_atr(ch, at, page, 1);
  23037.  }
  23038.  
  23039.  /* obtains the current video mode */
  23040.  unsigned char Getvmode()
  23041.  {
  23042.      union REGS reg;
  23043.  
  23044.      reg.h.ah = GETMODE;
  23045.      int86(VIDEO, ®, ®);
  23046.      return reg.h.al;
  23047.  }
  23048.  
  23049.  /* obtains the current video page */
  23050.  unsigned char Getpage()
  23051.  {
  23052.      union REGS reg;
  23053.  
  23054.      reg.h.ah = GETMODE;
  23055.      int86(VIDEO, ®, ®);
  23056.      return reg.h.bh;
  23057.  }
  23058.  
  23059.  /* moves cursor one column left, but not past */
  23060.  /* the given limit                            */
  23061.  unsigned char Curslt_lim(limit)
  23062.  unsigned char limit;
  23063.  {
  23064.      unsigned char row, col, page;
  23065.      unsigned char status = 1;
  23066.  
  23067.      Getcurs(&row, &col, page = Getpage());
  23068.      if (col > limit)
  23069.          Setcurs(row, col - 1, page);
  23070.      else
  23071.          status = 0;
  23072.      return status;
  23073.  }
  23074.  
  23075.  /* moves cursor one column right, but not past */
  23076.  /* the given limit                             */
  23077.  unsigned char Cursrt_lim(limit)
  23078.  unsigned char limit;
  23079.  {
  23080.      unsigned char row, col, page;
  23081.      unsigned char status = 1;
  23082.  
  23083.      Getcurs(&row, &col, page = Getpage());
  23084.      if (col < limit)
  23085.          Setcurs(row, col + 1, page);
  23086.      else
  23087.          status = 0;
  23088.      return status;
  23089.  }
  23090.  
  23091.  /* move cursor one row down, but not past */
  23092.  /* the given limit                        */
  23093.  unsigned char Cursup_lim(limit)
  23094.  unsigned char limit;
  23095.  {
  23096.      unsigned char row, col, page;
  23097.      unsigned char status = 1;
  23098.  
  23099.      Getcurs(&row, &col, page = Getpage());
  23100.      if (row > limit)
  23101.          Setcurs(row - 1, col, page);
  23102.      else
  23103.          status = 0;
  23104.      return status;
  23105.  }
  23106.  
  23107.  /* move cursor one row down, but not past */
  23108.  /* the given limit                        */
  23109.  unsigned char Cursdn_lim(limit)
  23110.  unsigned char limit;
  23111.  {
  23112.      unsigned char row, col, page;
  23113.      unsigned char status = 1;
  23114.  
  23115.      Getcurs(&row, &col, page = Getpage());
  23116.      if (row < limit)
  23117.          Setcurs(row + 1, col, page);
  23118.      else
  23119.          status = 0;
  23120.      return status;
  23121.  }
  23122.  
  23123.  
  23124.  SCRINV.C
  23125.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\SCRINV.C
  23126.  
  23127.  /* scrinv.c  --  using a far pointer to access text   */
  23128.  /*               screen memory                        */
  23129.  
  23130.  #define ROWS 25
  23131.  #define COLS 80
  23132.  
  23133.  main()
  23134.  {
  23135.      int far *screenp;
  23136.      int temp, i;
  23137.  
  23138.      do
  23139.          {
  23140.          /* use 0xB800000 for EGA or VGA */
  23141.          screenp = (int far *)0xB0000000;
  23142.  
  23143.          for (i = 0; i < ((ROWS*COLS)/2); ++i)
  23144.              {
  23145.              temp = screenp[i];
  23146.              screenp[i] = screenp[(ROWS*COLS)-i-1];
  23147.              screenp[(ROWS*COLS)-i-1] = temp;
  23148.              }
  23149.          } while (getch() != 'Q');
  23150.  
  23151.  }
  23152.  
  23153.  
  23154.  SCRMENU.C
  23155.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP11\SCRMENU.C
  23156.  
  23157.  /* scrmenu.c  -- uses bit fields to modify your text   */
  23158.  /*               screen's attributes                   */
  23159.  
  23160.  char *Choice_Words[] = {
  23161.      "Quit",
  23162.      "Foreground",
  23163.      "Intensity",
  23164.      "Background",
  23165.      "Blinking"
  23166.  };
  23167.  enum Choices {
  23168.      Quit,
  23169.      Foreground,
  23170.      Intensity,
  23171.      Background,
  23172.      Blinking
  23173.  };
  23174.  
  23175.  /* use 0xB800000 for EGA or VGA */
  23176.  #define SCR_START (0xB0000000)
  23177.  #define SCR_SIZE (25 * 80)
  23178.  
  23179.  main()
  23180.  {
  23181.      enum Choices choice;
  23182.  
  23183.      printf("Select from the following by number:\n");
  23184.  
  23185.      for (choice = Quit; choice <= Blinking; ++choice)
  23186.          {
  23187.          printf("%d. %s\n", choice, Choice_Words[choice]);
  23188.          }
  23189.  
  23190.      printf("\nWhich: ");
  23191.      do
  23192.          {
  23193.          choice = getch();
  23194.          choice -= '0';
  23195.          if (choice < Foreground || choice > Blinking)
  23196.              continue;
  23197.          Redraw(choice);
  23198.          } while (choice != Quit);
  23199.  
  23200.  }
  23201.  
  23202.  Redraw(enum Choices field)
  23203.  {
  23204.      struct screen_char {
  23205.          unsigned int character  :8,
  23206.                       foreground :3,
  23207.                       intensity  :1,
  23208.                       background :3,
  23209.                       blink      :1;
  23210.      } scrchar, far *sp, far *ep;
  23211.  
  23212.      sp = (struct screen_char far *)SCR_START;
  23213.      ep = sp + SCR_SIZE;
  23214.  
  23215.      while (sp < ep)
  23216.          {
  23217.          scrchar = *sp;
  23218.          switch (field)
  23219.              {
  23220.              case Foreground:
  23221.                  scrchar.foreground = (scrchar.foreground)? 0 : 7;
  23222.                  break;
  23223.              case Intensity:
  23224.                  scrchar.intensity = (scrchar.intensity)? 0 : 1;
  23225.                  break;
  23226.              case Background:
  23227.                  scrchar.background = (scrchar.background)? 0 : 7;
  23228.                  break;
  23229.              case Blinking:
  23230.                  scrchar.blink = (scrchar.blink)? 0 : 1;
  23231.                  break;
  23232.              }
  23233.          *(sp++) = scrchar;
  23234.          }
  23235.  }
  23236.  
  23237.  
  23238.  SCRREST.C
  23239.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP10\SCRREST.C
  23240.  
  23241.  /* scrrest.c  --  demonstrates read() by restoring */
  23242.  /*                text screen from any file.       */
  23243.  
  23244.  <stdio.h>        /* for stderr              */
  23245.  <fcntl.h>        /* for O_RDONLY | O_BINARY */
  23246.  
  23247.  #define SCRCHARS  (25 * 80)
  23248.  int Buf[SCRCHARS];
  23249.  
  23250.  main(argc, argv)
  23251.  int argc;
  23252.  char *argv[];
  23253.  {
  23254.      int *cp, *ep;
  23255.      int far *sp;
  23256.      int fd_in, bytes;
  23257.  
  23258.      if (argc != 2)
  23259.          {
  23260.          fprintf(stderr, "usage: scrrest file.scr\n");
  23261.          exit(0);
  23262.          }
  23263.      if ((fd_in = open(argv[1], O_RDONLY | O_BINARY)) < 0)
  23264.          {
  23265.          fprintf(stderr, "\"%s\": Can't open to read.\n", argv[1]);
  23266.          exit(1);
  23267.          }
  23268.      /* Read it. */
  23269.      bytes = read(fd_in, Buf, SCRCHARS * 2);
  23270.      if (bytes < 0)
  23271.          {
  23272.          fprintf(stderr, "\"%s\": Error Reading.\n", argv[1]);
  23273.          exit(1);
  23274.          }
  23275.      if (bytes == 0)
  23276.          {
  23277.          fprintf(stderr, "\"%s\": Empty File.\n", argv[1]);
  23278.          exit(1);
  23279.          }
  23280.      /* Copy the buffer to screen memory. */
  23281.      ep = &Buf[bytes / 2];
  23282.      cp = Buf;
  23283.  
  23284.      /* use 0xB800000 for EGA or VGA */
  23285.      sp = (int far *)(0xB0000000);
  23286.      for (; cp < ep; ++cp, ++sp)
  23287.          *sp = *cp;
  23288.  }
  23289.  
  23290.  
  23291.  SCRSAVE.C
  23292.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP10\SCRSAVE.C
  23293.  
  23294.  /* scrsave.c  --  demonstrates write() by saving the */
  23295.  /*                text screen to a file.             */
  23296.  
  23297.  <stdio.h>        /* for stderr              */
  23298.  <fcntl.h>        /* for O_CREAT | O_BINARY  */
  23299.  <sys\types.h>    /* for stat.h              */
  23300.  <sys\stat.h>     /* for S_IREAD | S_IWRITE  */
  23301.  
  23302.  #define SCRCHARS  (25 * 80)
  23303.  int Buf[SCRCHARS];
  23304.  
  23305.  main(argc, argv)
  23306.  int argc;
  23307.  char *argv[];
  23308.  {
  23309.      int *cp, *ep, fname[16];
  23310.      int far *sp;
  23311.      int fd_out, bytes;
  23312.  
  23313.      if (argc != 2)
  23314.          {
  23315.          fprintf(stderr, "usage: scrsave file\n");
  23316.          exit(0);
  23317.          }
  23318.      if (strlen(argv[1]) > 8)
  23319.          {
  23320.          fprintf(stderr, "\"%s\": File name too long.\n", argv[1]);
  23321.          exit(1);
  23322.          }
  23323.      strcpy(fname, argv[1]);
  23324.      strcat(fname, ".SCR");
  23325.      if (access(fname, 0) == 0)
  23326.          {
  23327.          fprintf(stderr, "\"%s\": Won't overwrite.\n", fname);
  23328.          exit(1);
  23329.          }
  23330.      if ((fd_out = open(fname, O_WRONLY|O_CREAT|O_BINARY,
  23331.                         S_IREAD|S_IWRITE)) < 0)
  23332.          {
  23333.          fprintf(stderr, "\"%s\": Can't create.\n", fname);
  23334.          exit(1);
  23335.          }
  23336.      /* Copy the screen into a near buffer. */
  23337.      ep = &Buf[SCRCHARS - 1];
  23338.      cp = Buf;
  23339.      /* use 0xB800000 for EGA or VGA */
  23340.      sp = (int far *)(0xB0000000);
  23341.      for (; cp < ep; ++cp, ++sp)
  23342.          *cp = *sp;
  23343.      /* Write it. */
  23344.      bytes = write(fd_out, Buf, SCRCHARS * 2);
  23345.      if (bytes != SCRCHARS * 2)
  23346.          {
  23347.          fprintf(stderr, "\"%s\": Error writing.\n", fname);
  23348.          exit(1);
  23349.          }
  23350.  }
  23351.  
  23352.  
  23353.  SETCURS.C
  23354.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\SETCURS.C
  23355.  
  23356.  /* setcurs.c -- moves cursor, checks out Setcurs() */
  23357.  #include <dos.h>
  23358.  #include <stdio.h>
  23359.  #define VIDEO 0x10
  23360.  #define SETCURSOR 2
  23361.  void Setcurs(unsigned char, unsigned char,
  23362.               unsigned char);
  23363.  main()
  23364.  {
  23365.      int row, col;
  23366.  
  23367.      printf("Enter row and column: (q to quit)\n");
  23368.      while (scanf("%d %d", &row, &col) == 2)
  23369.      {
  23370.          Setcurs(row, col, 0);
  23371.          printf("Enter row and column: (q to quit)");
  23372.      }
  23373.  }
  23374.  
  23375.  /* Setcurs() -- sets cursor to row, column, and page */
  23376.  void Setcurs(row, col, page)
  23377.  unsigned char row, col, page;
  23378.  {
  23379.      union REGS reg;
  23380.  
  23381.      reg.h.ah = SETCURSOR;
  23382.      reg.h.dh = row;
  23383.      reg.h.dl = col;
  23384.      reg.h.bh = page;
  23385.      int86(VIDEO, ®, ®);
  23386.  }
  23387.  
  23388.  
  23389.  SHIFTADD.C
  23390.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\SHIFTADD.C
  23391.  
  23392.  /* shiftadd.c -- shift and add numbers               */
  23393.  
  23394.  main()
  23395.  {
  23396.      int x = 0x12;
  23397.      int y;
  23398.  
  23399.      y = x << 8 + 2;
  23400.      printf("y is 0x%x\n", y);
  23401.  }
  23402.  
  23403.  
  23404.  
  23405.  SHORTIF.C
  23406.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP05\SHORTIF.C
  23407.  
  23408.  /* shortif.c -- shows 'shorthand' IF / ELSE   */
  23409.  /*           -- gets absolute value of number */
  23410.  
  23411.  main()
  23412.  {
  23413.      int num, pos, abs;
  23414.      printf("Enter a whole number: ");
  23415.      scanf("%d", &num);
  23416.  
  23417.      pos = (num >= 0); /* is number positive? */
  23418.  
  23419.      abs = (pos) ? num : -num;  /* assigns negative of */
  23420.                        /* number if number is negative */
  23421.      if (pos)
  23422.          printf ("The number is positive.\n");
  23423.      else
  23424.          printf("The number is negative.\n");
  23425.      printf("Absolute value of number is: %d\n", abs);
  23426.  }
  23427.  
  23428.  
  23429.  SHOW2.C
  23430.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\SHOW2.C
  23431.  
  23432.  /* show2.c  --     shows how to use main()'s envp */
  23433.  
  23434.  <stdio.h>        /* for NULL */
  23435.  
  23436.  main(argc, argv, envp)
  23437.  int argc;
  23438.  char *argv[], *envp[];
  23439.  {
  23440.      int i;
  23441.  
  23442.      printf("argc = %d\n", argc);
  23443.      printf("\n");
  23444.  
  23445.      for (i = 0; i < argc; ++i)
  23446.          {
  23447.          printf("argv[%d] -> \"%s\"\n", i, argv[i]);
  23448.          }
  23449.      printf("argv[%d] -> NULL\n", i);
  23450.      printf("\n");
  23451.  
  23452.      for (i= 0; envp[i] != NULL; ++i)
  23453.          {
  23454.          printf("envp[%d] -> \"%s\"\n", i, envp[i]);
  23455.          }
  23456.      printf("envp[%d] -> NULL\n", i);
  23457.  
  23458.  }
  23459.  
  23460.  
  23461.  SHOWARGS.C
  23462.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\SHOWARGS.C
  23463.  
  23464.  /* showargs.c  --  shows how to access the arguments   */
  23465.  /*                 passed to main()                    */
  23466.  
  23467.  <stdio.h>        /* for NULL */
  23468.  
  23469.  main(argc, argv)
  23470.  int argc;
  23471.  char *argv[];
  23472.  {
  23473.      int i;
  23474.  
  23475.      printf("argc = %d\n", argc);
  23476.      printf("\n");
  23477.  
  23478.      for (i = 0; i < argc; ++i)
  23479.          {
  23480.          printf("argv[%d] -> \"%s\"\n", i, argv[i]);
  23481.          }
  23482.      printf("argv[%d] -> NULL\n", i);
  23483.      printf("\n");
  23484.  
  23485.  }
  23486.  
  23487.  
  23488.  SHOWCODE.C
  23489.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\SHOWCODE.C
  23490.  
  23491.  /*  showcode.c -- shows ASCII and scan codes for    */
  23492.  /*                keystrokes                        */
  23493.  /* Note: Set Screen Swapping On in the Debug menu.  */
  23494.  #include <stdio.h>
  23495.  #include <dos.h>
  23496.  KEYINTR 0x16  /* keyboard read interrupt */
  23497.  GETCHAR 0     /* read scancode function  */
  23498.  ESC '\033'    /* escape key              */
  23499.  struct SCANCODE {
  23500.                  unsigned char ascii;  /* ascii code */
  23501.                  unsigned char scan;   /* scan code  */
  23502.                  };
  23503.  struct SCANCODE Readkey();
  23504.  
  23505.  main()
  23506.  {
  23507.      struct SCANCODE keys;
  23508.  
  23509.      printf("Press keys to see their scancodes. ");
  23510.      printf("Press the Esc key to quit.\n");
  23511.      do  {
  23512.          keys = Readkey();
  23513.          if (keys.ascii > 0 && keys.ascii < 040)
  23514.              printf("^%c: ascii = %3d, scan = %3d\n",
  23515.                      keys.ascii + 0100, keys.ascii,
  23516.                      keys.scan);
  23517.          else if (keys.ascii >= 40)
  23518.              printf(" %c: ascii = %3d, scan = %3d\n",
  23519.                      keys.ascii, keys.ascii, keys.scan);
  23520.          else
  23521.              printf("  : ascii = %3d, scan = %3d\n",
  23522.                      keys.ascii, keys.scan);
  23523.          } while (keys.ascii != ESC);
  23524.  }
  23525.  
  23526.  struct SCANCODE Readkey()
  23527.  {
  23528.      union REGS reg;
  23529.      struct SCANCODE scancode;
  23530.  
  23531.      reg.h.ah = GETCHAR;
  23532.      int86(KEYINTR, ®, ®);
  23533.      scancode.ascii = reg.h.al;
  23534.      scancode.scan = reg.h.ah;
  23535.      return (scancode);
  23536.  }
  23537.  
  23538.  
  23539.  SPECS.C
  23540.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\SPECS.C
  23541.  
  23542.  /* specs.c -- shows printf() format  */
  23543.  /*            specifiers for numbers */
  23544.  
  23545.  main()
  23546.  {
  23547.      int    i = 122;       /* ASCII code for 'z' */
  23548.      long   l = 93000000;  /* distance to Sun (miles) */
  23549.      float  f = 192450.88; /* someone's bottom line */
  23550.      double d = 2.0e+030;  /* mass of Sun (kg.) */
  23551.  
  23552.      printf("%d\n", i);  /* integer as decimal */
  23553.      printf("%x\n", i);  /* integer as hex */
  23554.      printf("%ld\n", l); /* long */
  23555.      printf("%f\n", f);  /* float as decimal */
  23556.      printf("%e\n", f);  /* float as exponential */
  23557.      printf("%f\n", d);  /* double as decimal */
  23558.      printf("%d\n", d);  /* double as exponential */
  23559.  }
  23560.  
  23561.  
  23562.  SQUARE.C
  23563.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\SQUARE.C
  23564.  
  23565.  /* square.c  --  a quiz to demonstrate passing        */
  23566.  /*               pointers and addresses in functions  */
  23567.  
  23568.  main()
  23569.  {
  23570.      int val, count, guess;
  23571.  
  23572.      for (count = 1; count < 255; ++count)
  23573.          {
  23574.          val = count;
  23575.          printf("\nWhat is the square of %d?\n", val);
  23576.          if (scanf("%d", &guess) != 1)
  23577.              return(0);           /* non-number exits   */
  23578.  
  23579.          if(Square(&val) != 0)    /* pass val's address */
  23580.              {
  23581.              printf("Range Error\n");
  23582.              exit(1);
  23583.              }
  23584.          if (val != guess)
  23585.              printf("Wrong. It is %d.\n", val);
  23586.          else
  23587.              printf("Right!\n");
  23588.          printf("Continue? ");
  23589.          if (getche() != 'y')
  23590.              break;
  23591.          }
  23592.  }
  23593.  
  23594.  int Square(int *where)
  23595.  {
  23596.      if (*where > 181 || *where < -181)
  23597.          return (-1);
  23598.      *where = (*where) * (*where);
  23599.      return (0);
  23600.  }
  23601.  
  23602.  
  23603.  SQUARE2.C
  23604.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\SQUARE2.C
  23605.  
  23606.              /* LISTING 8-2 */
  23607.  
  23608.  /* square.c  --  A quiz to demonstrate passing        */
  23609.  /*               pointers and addresses in functions. */
  23610.  
  23611.  #include <stdio.h>
  23612.  
  23613.  main()
  23614.      {
  23615.      int val, count, guess;
  23616.  
  23617.      for (count = 1; count < 255; ++count)
  23618.          {
  23619.          val = count;
  23620.          printf("\nWhat is the square of %d?\n", val);
  23621.          if (scanf(" %d", &guess) != 1)
  23622.              return(0);           /* non-number exits   */
  23623.  
  23624.          if(Square(&val) != 0)    /* pass val's address */
  23625.              {
  23626.              printf("Range Error\n");
  23627.              exit(1);
  23628.              }
  23629.  
  23630.          if (val != guess)
  23631.              printf("Wrong. It is %d.\n", val);
  23632.          else
  23633.              printf("Right!\n");
  23634.  
  23635.  
  23636.          printf("Continue? ");
  23637.          if (getche() != 'y')
  23638.              break;
  23639.          }
  23640.      return (0);
  23641.      }
  23642.  
  23643.  int Square(int *where)
  23644.      {
  23645.      if (*where > 181 || *where < -181)
  23646.          return (-1);
  23647.      *where = (*where) * (*where);
  23648.      return (0);
  23649.      }
  23650.  
  23651.  
  23652.  STATIC.C
  23653.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\STATIC.C
  23654.  
  23655.  /* static.c -- demonstrates a static variable */
  23656.  /*             that holds count of lines,     */
  23657.  /*             words, and characters          */
  23658.  
  23659.  main()
  23660.      {
  23661.      void countline();
  23662.      printf("Type some lines of text.\n");
  23663.      printf("Start a line with a . to quit.\n\n");
  23664.  
  23665.      while (getche() != '.')
  23666.          countline();  /* accumulate word and */
  23667.                        /* line counts         */
  23668.      }
  23669.  
  23670.  void countline()
  23671.      {
  23672.      static int words = 0; /* static variables */
  23673.      static int chars = 0;
  23674.      char ch;
  23675.      ++chars; /* count char typed when */
  23676.               /* function was called   */
  23677.  
  23678.      while ((ch = getche()) != '\r')
  23679.          {
  23680.          ++chars;
  23681.          if (ch == ' ')
  23682.              ++words;
  23683.          }
  23684.          ++words; /* count last word */
  23685.  
  23686.      printf("\nWords so far %d. Chars. so far %d\n", words, chars);
  23687.      }
  23688.  
  23689.  
  23690.  STRINGS.C
  23691.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\STRINGS.C
  23692.  
  23693.  /* strings.c -- shows two ways to print */
  23694.  /*              a string with printf()  */
  23695.  
  23696.  main()
  23697.  {
  23698.      printf("This uses a string literal by itself\n");
  23699.      printf("%s", "This plugs the literal into %s\n");
  23700.  }
  23701.  
  23702.  
  23703.  STRINGS.C
  23704.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP10\STRINGS.C
  23705.  
  23706.  /* strings.c  --  opens a file and searches it for */
  23707.  /*                possible strings                 */
  23708.  
  23709.  <stdio.h>       /* for FILE, BUFSIZ & EOF */
  23710.  <ctype.h>       /* for isprint()          */
  23711.  
  23712.  main(argc, argv)
  23713.  int argc;
  23714.  char *argv[];
  23715.  {
  23716.      FILE *fp;
  23717.      char buf[BUFSIZ];
  23718.      int ch, count;
  23719.  
  23720.      if (argc != 2)
  23721.          {
  23722.          fprintf(stderr, "usage: strings file\n");
  23723.          exit(1);
  23724.          }
  23725.      if ((fp = fopen(argv[1], "rb")) == NULL)
  23726.          {
  23727.          fprintf(stderr, "Can't open %s\n", argv[1]);
  23728.          exit(1);
  23729.          }
  23730.  
  23731.      count = 0;
  23732.      while ((ch = fgetc(fp)) != EOF)
  23733.          {
  23734.          if (! isprint(ch) || count >= (BUFSIZ - 1))
  23735.              {
  23736.              if (count > 5)
  23737.                  {
  23738.                  buf[count] = 0;
  23739.                  puts(buf);
  23740.                  }
  23741.              count = 0;
  23742.              continue;
  23743.              }
  23744.          buf[count++] = ch;
  23745.          }
  23746.  }
  23747.  
  23748.  
  23749.  STRIO.C
  23750.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP13\STRIO.C
  23751.  
  23752.  /* strio.c -- uses cgets() and cputs()                   */
  23753.  /* program list -- strio.c (cgets() not in core library) */
  23754.  #include <conio.h>
  23755.  #define MAXSIZE 6
  23756.  main()
  23757.  {
  23758.       char store[MAXSIZE + 2];
  23759.  
  23760.       store[0] = MAXSIZE; /* put limit in first element */
  23761.       cputs("What's your name?\n\r");
  23762.       cgets(store);
  23763.       cputs("\n\rI'll remember you, ");
  23764.       cputs(store + 2);
  23765.       cputs("!\n\r");
  23766.  }
  23767.  
  23768.  
  23769.  STRPOOL.C
  23770.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\STRPOOL.C
  23771.  
  23772.  /* strpool.c  -- dumps the string pool to show how     */
  23773.  /*               quoted strings are stored             */
  23774.  
  23775.  #define PHRASE \
  23776.  "This is one long sentence that the compiler \
  23777.  combines into a single string."
  23778.  
  23779.  char Start[]        = "start";
  23780.  char Long_phrase[]  = PHRASE;
  23781.  char Short_phrase[] = "This is a short phrase";
  23782.  char Cent_string[]  = "\x9b";
  23783.  
  23784.  main()
  23785.  {
  23786.      static char local_phrase[] = "This is local";
  23787.      char *cp;
  23788.  
  23789.      printf("Dump of the string pool:\n");
  23790.      printf("-----------------------\n");
  23791.  
  23792.      printf("\"");                /* print leading quote */
  23793.  
  23794.      /*
  23795.       * Note that the address of a string can be
  23796.       * assigned to a pointer: cp = Start
  23797.       */
  23798.      for (cp = Start; *cp != '^'; ++cp)
  23799.          {
  23800.          if (*cp == '\0')        /* print '\0' as a quote */
  23801.              printf("\"\n\"");
  23802.          else if (*cp == '\n' )  /* print '\n' as '\' 'n' */
  23803.              printf("\\n");
  23804.          else
  23805.              printf("%c", *cp);
  23806.          }
  23807.      printf("^");                /* marks end */
  23808.  }
  23809.  
  23810.  
  23811.  SUMNUMS.C
  23812.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\SUMNUMS.C
  23813.  
  23814.  /* sumnums.c -- type mismatch in function arguments  */
  23815.  /*              No function prototyping              */
  23816.  
  23817.  int sums();
  23818.  
  23819.  main()
  23820.  {
  23821.      float a = 10.0;
  23822.      float b = 20.0;
  23823.      int c;
  23824.  
  23825.      c = sums(a, b);
  23826.      printf("sum of %.1f and %.1f is %d\n", a, b, c); ;
  23827.  }
  23828.  
  23829.  int sums(x, y)
  23830.  int x, y;
  23831.  {
  23832.      return (x + y);
  23833.  }
  23834.  
  23835.  
  23836.  
  23837.  SUMNUMS2.C
  23838.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\SUMNUMS2.C
  23839.  
  23840.  /* sumnums2.c -- type mismatch in function arguments  */
  23841.  /*               Function prototyping              */
  23842.  
  23843.  int sums(int, int);
  23844.  main()
  23845.  {
  23846.      float a = 10.0;
  23847.      float b = 20.0;
  23848.      int c;
  23849.  
  23850.      c = sums(a, b);
  23851.      printf("sum of %.1f and %.1f is %d\n", a, b, c);
  23852.  }
  23853.  int sums(x, y)
  23854.  int x, y;
  23855.  {
  23856.      return ( x + y);
  23857.  }
  23858.  
  23859.  
  23860.  
  23861.  SWITCH.C
  23862.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP05\SWITCH.C
  23863.  
  23864.  /* switch.c -- demonstrates switch statement */
  23865.  /*             prints values according       */
  23866.  /*             to user's choice              */
  23867.  
  23868.  <math.h> /* for sqrt() */
  23869.  #define TRUE 1
  23870.  main()
  23871.  {
  23872.      char choice;   /* routine wanted by user   */
  23873.      int number;    /* number entered by user   */
  23874.  
  23875.      while (TRUE)   /* endless loop */
  23876.      {
  23877.          printf("\nSelect value wanted:\n");
  23878.          printf("o = octal  h = hex   s = square\n");
  23879.          printf("r = square root  q = quit: ");
  23880.          choice = getche(); printf("\n");
  23881.  
  23882.          if (choice == 'q')
  23883.              break; /* exits WHILE loop; ends program */
  23884.  
  23885.          /* rest of program executed if base <> 'q' */
  23886.              printf("Enter a whole number: ");
  23887.              scanf("%d", &number);
  23888.  
  23889.          switch (choice) /* print according to */
  23890.                          /* choice requested   */
  23891.              {
  23892.              case 'o':   /* print octal */
  23893.                  printf("Result: %o\n", number);
  23894.                  break;  /* break here in each case    */
  23895.                          /* exits the switch statement */
  23896.  
  23897.              case 'h':   /* print hex */
  23898.                  printf("Result: %x\n", number);
  23899.                  break;
  23900.  
  23901.              case 's':   /* square */
  23902.                  printf("Result: %d\n", number * number);
  23903.                  break;
  23904.  
  23905.              case 'r':   /* square root */
  23906.                  printf("Result: %f\n", sqrt(number) );
  23907.                  break;
  23908.  
  23909.              default:
  23910.                  printf("Choice must be o, h, s, r, or q\n");
  23911.              }
  23912.       }
  23913.  }
  23914.  
  23915.  
  23916.  TABLE.C
  23917.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP04\TABLE.C
  23918.  
  23919.  
  23920.  /* TABLE.C -- prints square root, square, and cube */
  23921.  /*            for the numbers 1 thru 9             */
  23922.  
  23923.  <math.h> /* include math functions so we  */
  23924.                    /*  can do square root           */
  23925.  
  23926.  main()
  23927.  {
  23928.      int i;
  23929.      printf("i\t sqrt(i)\tsquare(i)\tcube(i)\n\n");
  23930.      for (i = 1; i < 10; i++)
  23931.          /* beginning of body of loop */
  23932.          {
  23933.          printf("%d\t", i);
  23934.          printf("%f\t", sqrt(i));
  23935.          printf("%d\t\t", i * i);
  23936.          printf("%d\n", i * i * i);
  23937.          }
  23938.          /* end of body of loop */
  23939.  }
  23940.  
  23941.  
  23942.  
  23943.  TABS.C
  23944.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\TABS.C
  23945.  
  23946.  /* tabs.c -- shows formatting with the \t */
  23947.  /*           tab escape sequence          */
  23948.  
  23949.  main()
  23950.  {
  23951.      int    q1 = 338, q2 = 57, q3 = 1048, q4 = 778,
  23952.             /* quantity in bin */
  23953.             t1 = 6, t2 = 8, t3 = 12, t4 = 16;
  23954.             /* threads per inch */
  23955.  
  23956.      float  s1 = 0.250, s2 = 0.500, s3 = 0.750, s4 = 1.0;
  23957.             /* size in inches */
  23958.  
  23959.      /* print table header */
  23960.      printf("number\t\t size\t\t threads\n");
  23961.      printf("in bin\t\t (inches)\t per inch\n\n");
  23962.  
  23963.      /* print lines of table */
  23964.      printf("%d\t\t %f\t %d\n", q1, s1, t1);
  23965.      printf("%d\t\t %f\t %d\n", q2, s2, t2);
  23966.      printf("%d\t\t %f\t %d\n", q3, s3, t3);
  23967.      printf("%d\t\t %f\t %d\n", q4, s4, t4);
  23968.  }
  23969.  
  23970.  
  23971.  TEST.C
  23972.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\TEST.C
  23973.  
  23974.  /* test.c -- test the routines in basic.lib */
  23975.  /* Program list: test.c and basic.lib       */
  23976.  
  23977.  #include <stdio.h>
  23978.  
  23979.  main()
  23980.  {
  23981.      static char string[] = "This is a test.";
  23982.      char *cp, *Leftstr(), *Midstr(), *Rightstr();
  23983.  
  23984.      printf("Testing: \"%s\"\n", string);
  23985.  
  23986.      if ((cp = Leftstr(string, 4)) == NULL)
  23987.          {
  23988.          printf("Error in Leftstr()\n");
  23989.          exit(1);
  23990.          }
  23991.      printf("Leftstr() returned: \"%s\"\n", cp);
  23992.  
  23993.      if ((cp = Midstr(string, 4, 5)) == NULL)
  23994.          {
  23995.          printf("Error in Midstr()\n");
  23996.          exit(1);
  23997.          }
  23998.      printf("Midstr() returned: \"%s\"\n", cp);
  23999.  
  24000.      if ((cp = Rightstr(string, 5)) == NULL)
  24001.          {
  24002.          printf("Error in Rightstr()\n");
  24003.          exit(1);
  24004.          }
  24005.      printf("Rightstr() returned: \"%s\"\n", cp);
  24006.  }
  24007.  
  24008.  
  24009.  TESTER.C
  24010.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP16\TESTER.C
  24011.  
  24012.  /* tester.c -- demonstrates the assert() macro        */
  24013.  /* Program list: tester.c (to link math functions)    */
  24014.  
  24015.  #include <assert.h>
  24016.  #include <stdio.h>
  24017.  #include <math.h>
  24018.  main()
  24019.  {
  24020.      float s1 = 3.0;
  24021.      float s2 = 4.0;
  24022.      float sumsq;
  24023.      float hypot;
  24024.  
  24025.      sumsq = s1*s1 - s2*s2;
  24026.      assert(sumsq >= 0);
  24027.      hypot = sqrt(sumsq);
  24028.      printf("hypotenuse is %.2f\n", hypot);
  24029.  }
  24030.  
  24031.  
  24032.  TEXED.C
  24033.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP12\TEXED.C
  24034.  
  24035.  /* texed.c  --  main entry point to the editor; the   */
  24036.  /*              menu and signal handlers are here     */
  24037.  
  24038.  main(argc, argv)
  24039.  int argc;
  24040.  char *argv[];
  24041.  {
  24042.      char ch;
  24043.  
  24044.      while (1)
  24045.          {
  24046.          printf("\nTexEd Main Menu\n");
  24047.          printf("Select from:\n");
  24048.          printf("0) Quit\n\n");
  24049.          printf("1) Load File\n");
  24050.          printf("2) Save File\n");
  24051.          printf("3) Edit File\n");
  24052.          printf("Which: ");
  24053.          do
  24054.              {
  24055.              ch = getch();
  24056.              ch -= '0';
  24057.              } while (ch < 0 || ch > 3);
  24058.          printf("%d\n\n", (int)ch);
  24059.          switch(ch)
  24060.              {
  24061.              case 0: exit(0);
  24062.              case 1: Load_file(); break;
  24063.              case 2: Save_file(); break;
  24064.              case 3: Edit_file(); break;
  24065.              }
  24066.          }
  24067.  }
  24068.  
  24069.  
  24070.  TIMER.C
  24071.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP04\TIMER.C
  24072.  
  24073.  
  24074.  /* TIMER.C -- uses do loop to    */
  24075.  /*            check elapsed time */
  24076.  
  24077.  #include <time.h>
  24078.  
  24079.  main()
  24080.  {
  24081.      long start, end, /* starting and ending times */
  24082.                       /* measured in seconds since */
  24083.                       /* Jan. 1, 1970 */
  24084.           ltime;      /* used to get val from time function */
  24085.      int seconds;     /* elapsed time to be set */
  24086.  
  24087.      printf("QuickC Egg Timer\n");
  24088.      printf("Enter time to set in seconds: ");
  24089.      scanf("%d", &seconds);
  24090.      start = time(<ime);  /* get system elapsed seconds */
  24091.                             /* since 1-1-70 */
  24092.      end = start + seconds; /* calculate alarm time */
  24093.  
  24094.      do
  24095.         ;                       /* null statement for loop body */
  24096.      while (time(<ime) < end);   /* wait for alarm time  */
  24097.  
  24098.      printf("Time's Up!\a\a\a\n");
  24099.  }
  24100.  
  24101.  
  24102.  
  24103.  TIMER2.C
  24104.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP06\TIMER2.C
  24105.  
  24106.  /* timer2.c -- interval timer             */
  24107.  /*             calls delay(), uses beep() */
  24108.  
  24109.  main()
  24110.  {
  24111.      /* function declarations */
  24112.      void beep (times);
  24113.      void delay (seconds);
  24114.  
  24115.      /* variable declarations */
  24116.      int seconds, interval, tick;
  24117.  
  24118.      printf("Set for how many seconds? ");
  24119.      scanf("%d", &seconds);
  24120.      printf("Interval to show in seconds? ");
  24121.      scanf("%d", &interval);
  24122.      printf("Press a key to start timing\n");
  24123.      getch();
  24124.  
  24125.      tick = 0;                /* run "clock" for */
  24126.      while (tick < seconds)   /* time specified  */
  24127.          {
  24128.          delay(interval); /* wait interval seconds */
  24129.          tick += interval;
  24130.          printf("%d\n", tick);
  24131.          beep(1);
  24132.          }
  24133.      beep(3);
  24134.  }
  24135.  
  24136.  void delay(seconds)
  24137.                 /* wait for number of seconds specified */
  24138.                 /* see TIMER.C in chapter 4 for details */
  24139.                 /* on the library function time().      */
  24140.  
  24141.  int seconds;   /* parameter declaration */
  24142.  {
  24143.      /* variable declarations */
  24144.      long start, end, /* starting and ending times */
  24145.                       /* measured in seconds since */
  24146.                       /* Jan. 1, 1970 */
  24147.           ltime;      /* used to get val from time function */
  24148.  
  24149.      start = time(<ime);  /* get system elapsed seconds */
  24150.                             /* since 1-1-70 */
  24151.      end = start + seconds; /* calculate alarm time */
  24152.  
  24153.      do
  24154.         ;                          /* null statement for loop body */
  24155.      while (time(<ime) < end);   /* wait for end of time  */
  24156.  }
  24157.  
  24158.  void beep(times)
  24159.      /* parameter declaration */
  24160.  int times;
  24161.  {
  24162.      /* variable declaration  */
  24163.      int count;
  24164.  
  24165.  
  24166.      /* check that parameter is between 1 and 4 */
  24167.      if ((times < 1) || (times > 4))
  24168.          {
  24169.          printf("Error in beep(): %d beeps specified.\n",
  24170.              times);
  24171.          printf("Specify one to four beeps");
  24172.          }
  24173.      else /* sound the beeps */
  24174.          for (count = 1; count <= times; count++)
  24175.              printf("\a");  /* "alert" escape sequence */
  24176.  }
  24177.  
  24178.  
  24179.  TINY.C
  24180.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\TINY.C
  24181.  
  24182.  /* tiny.c -- the smallest possible C */
  24183.  /*           program with comments   */
  24184.  
  24185.  main() /* function name and argument list */
  24186.  {
  24187.         /* function definition in braces */
  24188.  }
  24189.  
  24190.  
  24191.  TODAY.C
  24192.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP11\TODAY.C
  24193.  
  24194.  /* today.c  -- demonstrates using enum  */
  24195.  
  24196.  main()
  24197.  {
  24198.      enum week_days {
  24199.          monday = 1,    /* start with 1 */
  24200.          tuesday,
  24201.          wednesday,
  24202.          thursday,
  24203.          friday,
  24204.          saturday,
  24205.          sunday
  24206.      } pay_day;
  24207.  
  24208.      static char *day_names[] = {
  24209.          "",
  24210.          "monday",
  24211.          "tuesday",
  24212.          "wednesday",
  24213.          "thursday",
  24214.          "friday",
  24215.          "saturday",
  24216.          "sunday"
  24217.      };
  24218.  
  24219.      printf("What day do you want to be paid on?\n");
  24220.  
  24221.      for (pay_day = monday; pay_day <= sunday; ++pay_day)
  24222.          {
  24223.          printf("%d. %s\n", pay_day, day_names[pay_day]);
  24224.          }
  24225.  
  24226.      printf("Which (%d-%d): ", monday, sunday);
  24227.  
  24228.      do
  24229.          {
  24230.          pay_day = getch();
  24231.          pay_day -= '0';
  24232.          } while (pay_day < monday || pay_day > sunday);
  24233.  
  24234.      printf("%d\n\n", pay_day);
  24235.  
  24236.      printf("You selected %s\n", day_names[pay_day]);
  24237.  
  24238.  }
  24239.  
  24240.  
  24241.  TOTAL.C
  24242.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\TOTAL.C
  24243.  
  24244.  /* total.c  -- how to build an array on the fly    */
  24245.  
  24246.  <stdio.h>         /* for NULL   */
  24247.  <malloc.h>        /* for size_t */
  24248.  
  24249.  main()
  24250.  {
  24251.      int *iptr, count = 0, i, total;
  24252.      size_t bytes = sizeof(int);
  24253.  
  24254.      /* Start the array with room for one value. */
  24255.      if ((iptr = malloc(bytes)) == NULL)
  24256.          {
  24257.          printf("Oops, malloc failed\n");
  24258.          exit(1);
  24259.          }
  24260.  
  24261.      printf("Enter as many integer values as you want.\n");
  24262.      printf("I will build an array on the fly with them.\n");
  24263.      printf("(Any non-number means you are done.)\n");
  24264.  
  24265.      while (scanf("%d", &iptr[count]) == 1)
  24266.          {
  24267.          ++count;
  24268.          /* Enlarge the array. */
  24269.          if ((iptr = realloc(iptr,bytes*(count+1))) == NULL)
  24270.              {
  24271.              printf("Oops, realloc failed\n");
  24272.              exit(1);
  24273.              }
  24274.          }
  24275.      total = 0;
  24276.      printf("You entered:\n");
  24277.      for (i = 0; i < count; i++)
  24278.          {
  24279.          printf("iptr[%d] = %d\n", i, iptr[i]);
  24280.          total += iptr[i];
  24281.          }
  24282.      printf("\nTotal: %d\n", total);
  24283.      return (0);
  24284.  }
  24285.  
  24286.  
  24287.  TOTAL2.C
  24288.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP08\TOTAL2.C
  24289.  
  24290.  /* total2.c -- how to build an array on the fly       */
  24291.  /*             using sbrk()                           */
  24292.  
  24293.  <stdio.h>        /* for NULL   */
  24294.  <malloc.h>       /* for size_t */
  24295.  
  24296.  main()
  24297.      {
  24298.      int *iptr, count = 0, i, total;
  24299.      size_t bytes = sizeof(int);
  24300.  
  24301.      /* Start the array with room for one value. */
  24302.      iptr = sbrk(0);
  24303.      if (sbrk(bytes) == (int *)-1)
  24304.          {
  24305.          printf("Oops, sbrk failed\n");
  24306.          exit(1);
  24307.          }
  24308.  
  24309.      printf("Enter as many integer values as you want.\n");
  24310.      printf("I will build an array on the fly with them.\n");
  24311.      printf("(Any non-number means you are done.)\n");
  24312.  
  24313.      while (scanf("%d", &iptr[count]) == 1)
  24314.          {
  24315.          ++count;
  24316.          /* Enlarge the array. */
  24317.          if (sbrk(bytes) == (int *)-1)
  24318.              {
  24319.              printf("Oops, sbrk failed\n");
  24320.              exit(1);
  24321.              }
  24322.          }
  24323.      total = 0;
  24324.      for (i = 0; i < count; i++)
  24325.          total += iptr[i];
  24326.      /* just print the total this time */
  24327.      printf( "%d\n", total);
  24328.  }
  24329.  
  24330.  
  24331.  TRUTH.C
  24332.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\TRUTH.C
  24333.  
  24334.  /* truth.c -- shows logical operators */
  24335.  
  24336.  main()
  24337.  {
  24338.      printf("1 AND 1 is %d\n", 1 && 1);
  24339.      printf("1 AND 0 is %d\n", 1 && 0);
  24340.      printf("0 AND 0 is %d\n", 0 && 0);
  24341.      printf("1 OR 1 is %d\n",  1 || 1);
  24342.      printf("1 OR 0 is %d\n",  1 || 0);
  24343.      printf("0 OR 0 is %d\n",  0 || 0);
  24344.  }
  24345.  
  24346.  
  24347.  TTT.C
  24348.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP07\TTT.C
  24349.  
  24350.  /* ttt.c    --  a tic-tac-toe game demonstrates  */
  24351.  /*              passing two-dimensional arrays   */
  24352.  /*              to functions                     */
  24353.  
  24354.  main()
  24355.  {
  24356.      static char board[3][3] = {
  24357.          { '-', '-', '-' },
  24358.          { '-', '-', '-' },
  24359.          { '-', '-', '-' },
  24360.      };
  24361.      int row, col, ch;
  24362.      extern char Check_winner();
  24363.      extern void Make_move(), Draw_field();
  24364.  
  24365.      printf("You are X and make the first move.\n");
  24366.      while (1)
  24367.          {
  24368.          printf("Specify coordinate for your X.\n");
  24369.          printf("(eg, as a2, or Q to quit)\n");
  24370.  
  24371.          /* Print the square. */
  24372.          Draw_field(board);
  24373.  
  24374.          /* Input the user's coordinates. */
  24375.          if ((row = getch()) == 'Q')
  24376.              exit(0);
  24377.          row -= 'a';
  24378.          col = getch() - '1';
  24379.  
  24380.          /* Check for a legal move. */
  24381.          if (row < 0 || row > 2 || col < 0 || col > 2)
  24382.              {
  24383.              printf("Bad Square Specification\n\n");
  24384.              continue;
  24385.              }
  24386.          if (board[row][col] != '-')
  24387.              {
  24388.              printf("Sorry, Square Occupied\n\n");
  24389.              continue;
  24390.              }
  24391.  
  24392.          /* Make the move. */
  24393.          board[row][col] = 'X';
  24394.          if ((ch = Check_winner(board)) != '-' || ch == 't')
  24395.              break;
  24396.          Make_move(board);
  24397.          if ((ch = Check_winner(board)) != '-' || ch == 't')
  24398.              break;
  24399.          }
  24400.      Draw_field(board);
  24401.      if (ch == 't')
  24402.          printf("It's a tie!\n");
  24403.      else if (ch == 'X')
  24404.          printf("You win!\n");
  24405.      else
  24406.          printf("I win!\n");
  24407.  }
  24408.  
  24409.  char Check_winner(char field[][3])
  24410.  {
  24411.      int row, col;
  24412.  
  24413.      for (row = col = 0; row < 3; ++row, ++col)
  24414.          {
  24415.          if (field[row][0] != '-'             /* horizontal */
  24416.                  && field[row][0] == field[row][1]
  24417.                  && field[row][1] == field[row][2] )
  24418.              {
  24419.              return(field[row][0]);
  24420.              }
  24421.          if (field[0][col] != '-'             /* vertical */
  24422.                  && field[0][col] == field[1][col]
  24423.                  && field[1][col] == field[2][col] )
  24424.              {
  24425.              return(field[0][col]);
  24426.              }
  24427.          }
  24428.      if (field[0][0] != '-'         /* right diagonal */
  24429.              && field[0][0] == field[1][1]
  24430.              && field[1][1] == field[2][2] )
  24431.          {
  24432.          return(field[0][0]);
  24433.          }
  24434.      if (field[0][2] != '-'         /* left diagonal */
  24435.              && field[0][2] == field[1][1]
  24436.              && field[1][1] == field[2][0] )
  24437.          {
  24438.          return(field[0][2]);
  24439.          }
  24440.  
  24441.      for (row = 0; row < 3; ++row)        /* any moves left */
  24442.          {
  24443.          for (col = 0; col < 3; ++col)
  24444.              {
  24445.              if (field[row][col] == '-')
  24446.                  {
  24447.                  return('-');
  24448.                  }
  24449.              }
  24450.          }
  24451.      return ('t');
  24452.  }
  24453.  
  24454.  void Make_move(char field[3][3])
  24455.  {
  24456.      int row, col;
  24457.  
  24458.      for (row = 2; row >= 0; --row)
  24459.          {
  24460.          for (col = 2; col >= 0; --col)
  24461.              {
  24462.              if (field[row][col] == '-')
  24463.                  {
  24464.                  field[row][col] = 'O';
  24465.                  return;
  24466.                  }
  24467.              }
  24468.          }
  24469.  }
  24470.  
  24471.  void Draw_field(char field[][3])
  24472.  {
  24473.      int row, col;
  24474.  
  24475.      printf("\n   1  2  3\n\n");
  24476.      for (row = 0; row < 3; ++row)
  24477.          {
  24478.          printf("%c ", 'a'+row);
  24479.          for (col = 0; col < 3; ++col)
  24480.              {
  24481.              printf(" %c ", field[row][col] );
  24482.              }
  24483.          printf("\n");
  24484.          }
  24485.      printf("\n");
  24486.  }
  24487.  
  24488.  
  24489.  UDEMO.C
  24490.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP11\UDEMO.C
  24491.  
  24492.  /* udemo.c  --  demonstrates a union at work */
  24493.  
  24494.  #include <stdio.h>
  24495.  
  24496.  char *Strings[6] = {
  24497.          "Quit",
  24498.          "line of text",
  24499.          "floating point double value",
  24500.          "long integer value",
  24501.          "floating point value",
  24502.          "integer value"
  24503.  };
  24504.  
  24505.  struct Unitstruct {
  24506.      union {
  24507.          char   wtype[BUFSIZ];
  24508.          double dtype;
  24509.          long   ltype;
  24510.          float  ftype;
  24511.          int    itype;
  24512.      } manyu;
  24513.      int type_in_union;
  24514.  };
  24515.  
  24516.  main()
  24517.  {
  24518.      struct Unitstruct one_of_many;
  24519.  
  24520.      while ((one_of_many.type_in_union = Menu()) != 0)
  24521.          {
  24522.          Inputval(&one_of_many);
  24523.          Printval(&one_of_many);
  24524.          }
  24525.  }
  24526.  
  24527.  Inputval(struct Unitstruct *one_of_many)
  24528.      {
  24529.      printf("\nEnter a %s: ", Strings[one_of_many->type_in_union]);
  24530.      switch(one_of_many->type_in_union)
  24531.          {
  24532.          case 1:
  24533.              fgets(one_of_many->manyu.wtype, BUFSIZ, stdin);
  24534.              break;
  24535.          case 2:
  24536.              scanf("%lf", &(one_of_many->manyu.dtype));
  24537.              while (getchar() != '\n');
  24538.              break;
  24539.          case 3:
  24540.              scanf("%ld", &(one_of_many->manyu.ltype));
  24541.              while (getchar() != '\n');
  24542.              break;
  24543.          case 4:
  24544.              scanf("%f", &(one_of_many->manyu.ftype));
  24545.              while (getchar() != '\n');
  24546.              break;
  24547.          case 5:
  24548.              scanf("%i", &(one_of_many->manyu.itype));
  24549.              while (getchar() != '\n');
  24550.              break;
  24551.          }
  24552.  }
  24553.  
  24554.  Printval(struct Unitstruct *one_of_many)
  24555.  {
  24556.      printf("The %s you entered\nwas: ", Strings[one_of_many->type_in_union]);
  24557.      switch (one_of_many->type_in_union)
  24558.          {
  24559.          case 1:
  24560.              fputs(one_of_many->manyu.wtype, stdout);
  24561.              break;
  24562.          case 2:
  24563.              printf("%lf", one_of_many->manyu.dtype);
  24564.              break;
  24565.          case 3:
  24566.              printf("%ld", one_of_many->manyu.ltype);
  24567.              break;
  24568.          case 4:
  24569.              printf("%f", one_of_many->manyu.ftype);
  24570.              break;
  24571.          case 5:
  24572.              printf("%i", one_of_many->manyu.itype);
  24573.              break;
  24574.          }
  24575.      printf("\n\n");
  24576.  }
  24577.  
  24578.  Menu()
  24579.  {
  24580.      int i;
  24581.      char ch;
  24582.  
  24583.      for (i = 0; i < 6; ++i)
  24584.          {
  24585.          printf("%d) %s\n", i, Strings[i]);
  24586.          }
  24587.      printf("Which: ");
  24588.      do
  24589.          {
  24590.          ch = getch();
  24591.          } while (ch < '0' || ch > '5');
  24592.      printf("%c\n", ch);
  24593.      return (ch - '0');
  24594.  }
  24595.  
  24596.  
  24597.  UNDOVER.C
  24598.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP07\UNDOVER.C
  24599.  
  24600.  /* undover.c -- illustrates the effect of underinitializing and */
  24601.  /*              overinitializing arrays.                        */
  24602.  
  24603.  int Primes[6] = { 1, 2, 3, 5, 7, 11 };
  24604.  #define NUMP (sizeof(Primes)/sizeof(int))
  24605.  
  24606.  main()
  24607.  {
  24608.      int i;
  24609.  
  24610.      printf("The first %d primes are: ", NUMP);
  24611.      for (i = 0; i < NUMP; ++i)
  24612.          {
  24613.          printf("%d ", Primes[i]);
  24614.          }
  24615.      printf("\n");
  24616.  }
  24617.  
  24618.  
  24619.  UPITY.C
  24620.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP10\UPITY.C
  24621.  
  24622.  /* upity.c --  makes an uppercase copy of a file using */
  24623.  /*             fread() and fwrite()                    */
  24624.  
  24625.  <string.h>        /* for strrchr() */
  24626.  <stdio.h>         /* for NULL      */
  24627.  <malloc.h>        /* for malloc()  */
  24628.  <ctype.h>         /* for isupper() */
  24629.  
  24630.  #define HUNK 512
  24631.  
  24632.  main(argc, argv)
  24633.  int argc;
  24634.  char *argv[];
  24635.  {
  24636.      char *cp, newname[128], *np;
  24637.      FILE *fp;
  24638.      int  hunks = 0, bytes = 0, totbytes = 0;
  24639.      int  i;
  24640.      if (argc != 2)
  24641.          {
  24642.          printf("usage: upity file\n");
  24643.          exit(1);
  24644.          }
  24645.  
  24646.      if ((fp = fopen(argv[1], "rb")) == NULL)
  24647.          {
  24648.          printf("\"%s\": Can't open.\n", argv[1]);
  24649.          exit(1);
  24650.          }
  24651.      if ((cp = malloc(HUNK)) == NULL)
  24652.          {
  24653.          printf("Malloc Failed.\n");
  24654.          exit(1);
  24655.          }
  24656.  
  24657.      while ((bytes = fread(cp + (HUNK * hunks), 1, HUNK, fp)) == HUNK)
  24658.          {
  24659.          totbytes += bytes;
  24660.          ++hunks;
  24661.          if ((cp = realloc(cp, HUNK + (HUNK * hunks))) == NULL)
  24662.              {
  24663.              printf("Realloc Failed.\n");
  24664.              exit(1);
  24665.              }
  24666.          }
  24667.      if (bytes < 0)
  24668.          {
  24669.          printf("\"%s\": Error Reading.\n", argv[1]);
  24670.          exit(1);
  24671.          }
  24672.      totbytes += bytes;
  24673.  
  24674.      for (i = 0; i < totbytes; ++i)
  24675.          if (islower(cp[i]))
  24676.              cp[i] = toupper(cp[i]);
  24677.  
  24678.      (void)fclose(fp);
  24679.  
  24680.      if ((np = strrchr(argv[1], '.')) != NULL)
  24681.          *np = '\0';
  24682.      strcpy(newname, argv[1]);
  24683.      strcat(newname, ".up");
  24684.      if ((fp = fopen(newname, "wb")) == NULL)
  24685.          {
  24686.          printf("\"%s\": Can't open.\n", argv[1]);
  24687.          exit(1);
  24688.          }
  24689.  
  24690.      if (fwrite(cp, 1, totbytes, fp) != totbytes)
  24691.          {
  24692.          printf("\"%s\": Error writing.\n", argv[1]);
  24693.          exit(1);
  24694.          }
  24695.  
  24696.  }
  24697.  
  24698.  
  24699.  VARADDRS.C
  24700.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\VARADDRS.C
  24701.  
  24702.  /* varaddrs.c -- use & operator to get     */
  24703.  /*               addresses of variables    */
  24704.  
  24705.  main()
  24706.  {
  24707.      char c1, c2;
  24708.      int i;
  24709.      long l;
  24710.      float f;
  24711.      double d;
  24712.  
  24713.      printf("Address of c1 %d\n", &c1);
  24714.      printf("Address of c2 %d\n", &c2);
  24715.      printf("Address of i  %d\n", &i);
  24716.      printf("Address of l  %d\n", &l);
  24717.      printf("Address of f  %d\n", &f);
  24718.      printf("Address of d  %d\n", &d);
  24719.  }
  24720.  
  24721.  
  24722.  VARSIZE.C
  24723.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP03\VARSIZE.C
  24724.  
  24725.  /* varsize.c -- shows amount of memory */
  24726.  /*              by various types       */
  24727.  
  24728.  main()
  24729.  {
  24730.      printf("Size of a char is %d\n", sizeof(char));
  24731.      printf("Size of an int is %d\n", sizeof(int));
  24732.      printf("Size of a long is %d\n", sizeof(long));
  24733.      printf("Size of a float is %d\n", sizeof(float));
  24734.      printf("Size of a double is %d\n", sizeof(double));
  24735.  }
  24736.  
  24737.  
  24738.  VGAMAP.C
  24739.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP15\VGAMAP.C
  24740.  
  24741.  /*  vgamap.c  -- remaps the vga mode 19 palette        */
  24742.  /* Program list: vgamap.c (for rand())                 */
  24743.  #include <stdio.h>
  24744.  #include <graph.h>
  24745.  #include <conio.h>
  24746.  #define ESC '\033'
  24747.  #define PALSIZE 256
  24748.  #define ROWS 16
  24749.  #define COLS 16
  24750.  #define MIDBLUE 0x190000L
  24751.  long newpal[PALSIZE]; /* array of color values */
  24752.  
  24753.  main()
  24754.  {
  24755.      struct videoconfig vc;
  24756.      int mode = _MRES256COLOR;
  24757.      short xmax, ymax;
  24758.      short xcs[ROWS][COLS];
  24759.      short ycs[ROWS][COLS];
  24760.      short row, col;
  24761.      long colorval;       /* VGA color value */
  24762.      long index;          /* looping index   */
  24763.      short palval;        /* palette value */
  24764.      int c_base;  /* color base -- blue, green, or red */
  24765.      int ch;
  24766.  
  24767.      if (_setvideomode(mode) == 0)
  24768.          {
  24769.          fprintf(stderr, "%d mode not supported\n", mode);
  24770.          exit(1);
  24771.          }
  24772.      _getvideoconfig(&vc);
  24773.      xmax = vc.numxpixels - 1;
  24774.      ymax = vc.numypixels - 1;
  24775.      for (col = 0; col < COLS; col++)
  24776.          for (row = 0; row < ROWS; row++)
  24777.              {
  24778.              xcs[row][col] =  col * xmax / COLS + 5;
  24779.              ycs[row][col] =  row * ymax / ROWS + 5;
  24780.              }
  24781.      _setcolor(1);
  24782.      _rectangle(_GBORDER, 0, 0, xmax, ymax);
  24783.      for (col = 1; col < COLS ; col++)
  24784.          {
  24785.          _moveto(col * (xmax + 1) / COLS, 0);
  24786.          _lineto(col * (xmax + 1) / COLS, ymax);
  24787.          }
  24788.      for (row = 1; row < ROWS;  row++)
  24789.          {
  24790.          _moveto(0, row * (ymax + 1) / ROWS);
  24791.          _lineto(xmax, row * (ymax + 1) / ROWS);
  24792.          }
  24793.  
  24794.      for (col = 0; col < COLS; col++)
  24795.          for (row = 0; row < ROWS; row++)
  24796.              {
  24797.              _setcolor(row * ROWS + col);
  24798.              _floodfill(xcs[row][col], ycs[row][col],1);
  24799.               }
  24800.      getch();
  24801.  
  24802.      /*  initialize newpal[] to 64 shades of blue, 64
  24803.          shades of green, 64 shades of red, and 64 shades
  24804.          of magenta */
  24805.      for (index = 0; index < 64; index++)
  24806.          {
  24807.          newpal[index] = index << 16;
  24808.          newpal[index + 64] = index << 8;
  24809.          newpal[index + 128] = index;
  24810.          newpal[index + 192] = index | MIDBLUE;
  24811.          }
  24812.      _remapallpalette(newpal);
  24813.      getch();
  24814.  
  24815.      /* set squares and colors randomly -- ESC
  24816.         terminates loop, and other keystrokes toggle
  24817.         it on and off */
  24818.      do
  24819.          {
  24820.          while (!kbhit())
  24821.              {
  24822.              palval = rand() % PALSIZE;
  24823.              colorval = 0L;
  24824.              for (c_base = 0; c_base < 3; c_base++)
  24825.                  colorval += ((long) rand() % 64) <<
  24826.                               (c_base * 8);
  24827.              _remappalette (palval, colorval);
  24828.              }
  24829.          ch = getch();
  24830.          if (ch != ESC)
  24831.              ch = getch();
  24832.          } while (ch != ESC);
  24833.      _setvideomode(_DEFAULTMODE);
  24834.  }
  24835.  
  24836.  
  24837.  VIEW.C
  24838.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP10\VIEW.C
  24839.  
  24840.  /* view.c  --  demonstrates lseek() by displaying  */
  24841.  /*             a file and moving around in it      */
  24842.  
  24843.  <fcntl.h>           /* for open()         */
  24844.  <stdio.h>           /* for SEEK_CUR, etc. */
  24845.  
  24846.  #define HUNK 512
  24847.  #define MOVE 512L
  24848.  
  24849.  main(argc, argv)
  24850.  int argc;
  24851.  char *argv[];
  24852.  {
  24853.      char ch, buf[HUNK];
  24854.      long position = 0L;
  24855.      int  bytes, eofflag = 0, fd_in;
  24856.  
  24857.      if (argc != 2)
  24858.          {
  24859.          fprintf(stderr, "Usage: view file\n");
  24860.          exit(0);
  24861.          }
  24862.  
  24863.      if ((fd_in = open(argv[1], O_RDONLY)) < 0)
  24864.          {
  24865.          fprintf(stderr, "\"%s\": Can't open.\n", argv[1]);
  24866.          exit(1);
  24867.          }
  24868.  
  24869.      for (;;)
  24870.          {
  24871.          bytes = read(fd_in, buf, HUNK);
  24872.          if (bytes == 0)
  24873.              {
  24874.              if (! eofflag)
  24875.                  {
  24876.                  fprintf(stderr, "\n<<at end of file>>\n");
  24877.                  ++eofflag;
  24878.                  }
  24879.              else
  24880.                  exit(0);
  24881.              }
  24882.          else if (bytes < 0)
  24883.              {
  24884.              fprintf(stderr, "\"%s\": Error Reading.\n", argv[1]);
  24885.              exit(1);
  24886.              }
  24887.          else
  24888.              {
  24889.              eofflag = 0;
  24890.              position = lseek(fd_in, 0L, SEEK_CUR);
  24891.              if (position == -1L)
  24892.                  {
  24893.                  fprintf(stderr, "\"%s\": Error Seeking.\n", argv[1]);
  24894.                  exit(1);
  24895.                  }
  24896.              Print(buf, bytes);
  24897.              do
  24898.                  {
  24899.                  ch = getch();
  24900.                  if (ch == 'q' || ch == 'Q')
  24901.                      exit(0);
  24902.                  } while (ch != '+' && ch != '-');
  24903.  
  24904.              if (ch == '-')
  24905.                  {
  24906.                  position = lseek(fd_in, -2 * MOVE, SEEK_CUR);
  24907.                  if (position == -1L)
  24908.                      {
  24909.                      fprintf(stderr, "\"%s\": Error Seeking.\n", argv[1]);
  24910.                      exit(1);
  24911.                      }
  24912.                  }
  24913.              }
  24914.          }
  24915.  }
  24916.  
  24917.  Print(char *buf, int cnt)
  24918.  {
  24919.      int i;
  24920.  
  24921.      for (i = 0; i < cnt; ++i, ++buf)
  24922.          {
  24923.          if (*buf < ' ' && *buf != '\n' && *buf != '\t')
  24924.              printf("^%c", *buf + '@');
  24925.          else
  24926.              putchar(*buf);
  24927.          }
  24928.  }
  24929.  
  24930.  
  24931.  WHATCHAR.C
  24932.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP09\WHATCHAR.C
  24933.  
  24934.  /* whatchar.c  --  demonstrates the character         */
  24935.  /*                 classification routines in ctype.h */
  24936.  
  24937.  <stdio.h>        /* for NULL and BUFSIZ */
  24938.  <ctype.h>        /* for iscntl(), et al */
  24939.  #define MAXL 20
  24940.  
  24941.  main()
  24942.  {
  24943.      char buf[BUFSIZ];
  24944.      int i;
  24945.  
  24946.      printf("Enter a line of text (20 chars max):\n");
  24947.      if (gets(buf) == NULL)
  24948.          exit(1);
  24949.  
  24950.      for (i = 0; i < MAXL; ++i)
  24951.          {
  24952.          if (buf[i] == '\0')
  24953.              break;
  24954.          printf("'%c' ->", buf[i]);
  24955.          if (isalpha(buf[i]))   printf(" isalpha");
  24956.          if (isascii(buf[i]))   printf(" isascii");
  24957.          if (iscntrl(buf[i]))   printf(" iscntrl");
  24958.          if (isgraph(buf[i]))   printf(" isgraph");
  24959.          if (isprint(buf[i]))   printf(" isprint");
  24960.          if (isdigit(buf[i]))   printf(" isdigit");
  24961.          if (isupper(buf[i]))   printf(" isupper");
  24962.          if (islower(buf[i]))   printf(" islower");
  24963.          if (ispunct(buf[i]))   printf(" ispunct");
  24964.          if (isspace(buf[i]))   printf(" isspace");
  24965.          if (isalnum(buf[i]))   printf(" isalnum");
  24966.          if (isxdigit(buf[i]))  printf(" isxdigit");
  24967.          printf("\n");
  24968.          }
  24969.  }
  24970.  
  24971.  
  24972.  WHILE.C
  24973.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP04\WHILE.C
  24974.  
  24975.  
  24976.  /* WHILE.C -- a simple while loop */
  24977.  
  24978.  main()
  24979.  {
  24980.      int count = 1;
  24981.  
  24982.      while (count < 11)  /* loop condition */
  24983.          /* body of loop */
  24984.          {
  24985.          printf("%d\n", count);
  24986.          count++ ;
  24987.          }
  24988.      printf("Done!\n");
  24989.  }
  24990.  
  24991.  
  24992.  
  24993.  WRITECHR.C
  24994.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\WRITECHR.C
  24995.  
  24996.  /* writechr.c -- writes char and attribute repeatedly */
  24997.  /*               using DMA                            */
  24998.  /* write character ch with attribute attr num times   */
  24999.  /* starting at location pstart -- uses array notation */
  25000.  
  25001.  typedef unsigned int (far * VIDMEM);
  25002.  
  25003.  void Write_chars(pstart, ch, attr, num)
  25004.  VIDMEM pstart;
  25005.  unsigned short ch, attr, num;
  25006.  {
  25007.      register count;
  25008.      unsigned short pair;
  25009.  
  25010.      pair = (attr << 8) | (ch & 0x00FF) ;
  25011.      for (count = 0; count < num; count++)
  25012.          pstart[count] = pair;
  25013.  }
  25014.  
  25015.  
  25016.  WRITESTR.C
  25017.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP14\WRITESTR.C
  25018.  
  25019.  /*  writestr.c -- writes string and attribute using DMA */
  25020.  /*  write the string str with attribute attr at         */
  25021.  /*  location pstart -- uses pointer notation.           */
  25022.  
  25023.  typedef unsigned int (far * VIDMEM);
  25024.  
  25025.  void Write_str(pstart, attr, str)
  25026.  VIDMEM pstart;
  25027.  unsigned short attr;
  25028.  char *str;
  25029.  {
  25030.      while (*str != '\0')
  25031.          *pstart++ = (attr << 8) | (*str++ & 0x00FF);
  25032.  }
  25033.  
  25034.  
  25035.  XMAS.C
  25036.  CD-ROM Disc Path:   \SAMPCODE\QC_PROG\CHAP07\XMAS.C
  25037.  
  25038.  /* xmas.c -- fills an array with values, then passes */
  25039.  /*           each of those values to a function.     */
  25040.  
  25041.  main()
  25042.  {
  25043.      int i, j, widths[20];
  25044.      void Center_out();
  25045.  
  25046.      for (i = 0, j = 1; i < 18; ++i, j += 2)
  25047.          {
  25048.          widths[i] = j;
  25049.          }
  25050.      widths[i++] = 3;
  25051.      widths[i] = 3;
  25052.  
  25053.      for (i = 0; i < 20; i++)
  25054.          {
  25055.          Center_out('X', widths[i]);
  25056.          }
  25057.  
  25058.  }
  25059.  
  25060.  void Center_out(char character, int width)
  25061.  {
  25062.      int i;
  25063.  
  25064.      for (i = 0; i < ((80 - width) / 2); ++i)
  25065.          {
  25066.          putch(' ');
  25067.          }
  25068.      for (i = 0; i < width; ++i)
  25069.          {
  25070.          putch(character);
  25071.          }
  25072.      putch('\r');
  25073.      putch('\n');
  25074.  }
  25075.  Misc. `C' Sample Code from Microsoft
  25076.  
  25077.  
  25078.  ABS.C
  25079.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ABS.C
  25080.  
  25081.  /* ABS.C: Demonstrate macros. */
  25082.  
  25083.  #include <stdio.h>
  25084.  #define ABS(value)  ( (value) >= 0 ? (value) : -(value) )
  25085.  
  25086.  main()
  25087.  {
  25088.     int val = -20;
  25089.     printf( "result = %d\n", ABS(val) );
  25090.  }
  25091.  
  25092.  
  25093.  ALARM.C
  25094.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ALARM.C
  25095.  
  25096.  /* ALARM.C illustrates inline assembly and functions or keywords
  25097.   * related to Terminate-and-Stay-Resident programs. Functions include:
  25098.   *      _dos_setvect    _dos_getvect    _dos_keep
  25099.   *      _chain_intr     _enable         _disable
  25100.   *
  25101.   * Keywords:
  25102.   *      interrupt       _asm
  25103.   * Directive:
  25104.   *      #pragma
  25105.   * Pragma:
  25106.   *      check_stack     check_pointer
  25107.   * Global variables:
  25108.   *      _psp            _amblksiz
  25109.   *
  25110.   * WARNING: You must run ALARM from the DOS command line. The QC
  25111.   * environment does not permit TSRs to be installed from inside it, since
  25112.   * this would cause subsequent memory problems.
  25113.   *
  25114.   * See HARDERR.C for another example of inline assembler. See MOVEMEM.C
  25115.   * for another pragma example.
  25116.   */
  25117.  
  25118.  #include <dos.h>
  25119.  #include <malloc.h>
  25120.  #include <stdio.h>
  25121.  #include <stdlib.h>
  25122.  #include <time.h>
  25123.  
  25124.  /* Stack and pointer checking off */
  25125.  #pragma check_stack( off )
  25126.  #pragma check_pointer( off )
  25127.  
  25128.  /* Inline assembler macro to sound a bell. Note that comments in macros must
  25129.   * be in the C format, not the assembler format.
  25130.   */
  25131.  #define BEEP() _asm { \
  25132.                          _asm     push bx        /* Save register   */ \
  25133.                          _asm     sub  bx, bx    /* Page 0          */ \
  25134.                          _asm     mov  ax, 0E07h /* TTY bell        */ \
  25135.                          _asm     int  10h       /* BIOS 10         */ \
  25136.                          _asm     pop  bx        /* Restore         */ \
  25137.                      }
  25138.  
  25139.  #define TICKPERMIN  1092L
  25140.  #define MINPERHOUR  60L
  25141.  enum BOOLEAN { FALSE, TRUE };
  25142.  
  25143.  /* Prototypes for interrupt functions */
  25144.  void (interrupt far *oldtimer)( void );
  25145.  void (interrupt far *oldvideo)( void );
  25146.  void interrupt far newtimer( void );
  25147.  void interrupt far newvideo( unsigned _es, unsigned _ds, unsigned _di,
  25148.                               unsigned _si, unsigned _bp, unsigned _sp,
  25149.                               unsigned _bx, unsigned _dx, unsigned _cx,
  25150.                               unsigned _ax, unsigned _ip, unsigned _cs,
  25151.                               unsigned _flags );
  25152.  
  25153.  /* Variables that will be accessed inside TSR must be global. */
  25154.  int  ftimesup = FALSE, fintimer = FALSE, finvideo = FALSE;
  25155.  long goaltick;
  25156.  long far *pcurtick = (long far *)0x0000046cL;
  25157.  
  25158.  /* Huge pointers force compiler to do segment arithmetic for us. */
  25159.  char huge *tsrstack;
  25160.  char huge *appstack;
  25161.  char huge *tsrbottom;
  25162.  
  25163.  main( int argc, char **argv )
  25164.  {
  25165.      long minute, hour;
  25166.      unsigned tsrsize;
  25167.  
  25168.      /* Initialize stack and bottom of program. */
  25169.      _asm mov  WORD PTR tsrstack[0], sp
  25170.      _asm mov  WORD PTR tsrstack[2], ss
  25171.      FP_SEG( tsrbottom ) = _psp;
  25172.      FP_OFF( tsrbottom ) = 0;
  25173.  
  25174.      /* Use 16 paragraph heap (controlled through global in malloc.h). */
  25175.      _amblksiz = 256;
  25176.  
  25177.      /* Program size is:
  25178.       *     top of stack
  25179.       *   - bottom of program (converted to paragraphs)
  25180.       *   + paragraphs in the heap plus
  25181.       *   + one extra paragraph just to be safe
  25182.       */
  25183.      tsrsize = ((tsrstack - tsrbottom) >> 4) + (_amblksiz >> 4) + 1;
  25184.  
  25185.      /* If command-line, convert time to ticks past midnight. Time must
  25186.       * include 0 in first place (0930, not 930). Time must be later than
  25187.       * current time.
  25188.       */
  25189.      if( argc < 2 )
  25190.      {
  25191.          puts( "  Syntax: ALARM <hhmm> " );
  25192.          puts( "     where <hhmm> is time (in military format) to ring alarm"
  25193.          exit( 1 );
  25194.      }
  25195.  
  25196.      minute = atol( argv[1] + 2 );
  25197.      argv[1][2] = 0;
  25198.      hour = atol( argv[1] );
  25199.      goaltick = (hour * MINPERHOUR * TICKPERMIN) + (minute * TICKPERMIN);
  25200.      if( *pcurtick > goaltick )
  25201.      {
  25202.          puts( "It's past that time now" );
  25203.          exit( 1 );
  25204.      }
  25205.  
  25206.      /* Replace existing timer and video routines with ours. */
  25207.      oldtimer = _dos_getvect( 0x1c );
  25208.      _dos_setvect( 0x1c, newtimer );
  25209.      oldvideo = _dos_getvect( 0x10 );
  25210.      _dos_setvect( 0x10, newvideo );
  25211.  
  25212.      /* Free the PSP segment and terminate with program resident. */
  25213.      _dos_freemem( _psp );
  25214.      _dos_keep( 0, tsrsize );
  25215.  }
  25216.  
  25217.  /* newtimer - Our timer interrupt compares current time to goal. If earlier
  25218.   * it just continues. If later, it beeps and sets a flag to quit checking.
  25219.   */
  25220.  void interrupt far newtimer()
  25221.  {
  25222.      if( ftimesup )
  25223.          _chain_intr( oldtimer );
  25224.      else
  25225.      {
  25226.          /* First execute the original timer interrupt. */
  25227.          (*oldtimer)();
  25228.          if( *pcurtick > goaltick )
  25229.          {
  25230.              /* If time is up, set flag so we'll never return. */
  25231.              ftimesup = TRUE;
  25232.  
  25233.              /* Save current stack of application, and set old stack of TSR.
  25234.               * This is for safety since we don't know the state of the
  25235.               * application stack, but we do know the state of our own stack.
  25236.               * Turn off interrupts during the stack switch.
  25237.               */
  25238.              _disable();
  25239.              _asm \
  25240.              {
  25241.                  mov  WORD PTR appstack[0], sp   ; Save current stack
  25242.                  mov  WORD PTR appstack[2], ss
  25243.                  mov  sp, WORD PTR tsrstack[0]   ; Load new stack
  25244.                  mov  ss, WORD PTR tsrstack[2]
  25245.              }
  25246.              _enable();
  25247.  
  25248.              /* Make sure we're not in video interrupt, then BEEP. This check
  25249.               * prevents the rare but potentially dangerous case of
  25250.               * calling INT 10 to beep while INT 10 is already running.
  25251.               */
  25252.              while( finvideo )
  25253.                  ;
  25254.              BEEP();
  25255.              BEEP();
  25256.              BEEP();
  25257.  
  25258.              /* Restore application stack. */
  25259.              _disable();
  25260.              _asm \
  25261.              {
  25262.                  mov  sp, WORD PTR appstack[0]
  25263.                  mov  ss, WORD PTR appstack[2]
  25264.              }
  25265.              _enable();
  25266.          }
  25267.      }
  25268.  }
  25269.  
  25270.  /* newvideo - This routine protects against reentering INT 10 while it is
  25271.   * already executing. This could be disastrous if the interrupt routine was
  25272.   * interrupted while it was accessing a hardware register.
  25273.   */
  25274.  void interrupt far newvideo( unsigned _es, unsigned _ds, unsigned _di,
  25275.                               unsigned _si, unsigned _bp, unsigned _sp,
  25276.                               unsigned _bx, unsigned _dx, unsigned _cx,
  25277.                               unsigned _ax, unsigned _ip, unsigned _cs,
  25278.                               unsigned _flags )
  25279.  {
  25280.      static unsigned save_bp;
  25281.  
  25282.      /* If not already in (most of the time), chain to original. */
  25283.      if( !finvideo )
  25284.          _chain_intr( oldvideo );
  25285.      else
  25286.      {
  25287.  
  25288.          /* Set the inside flag, then make sure all the real registers
  25289.           * that might be passed to an interrupt 10h match the parameter
  25290.           * registers. Some of the real registers may be modified by the
  25291.           * preceding code. Note that BP must be saved in a static (nonstack)
  25292.           * variable so that it can be retrieved without modifying the stack.
  25293.           */
  25294.          finvideo = TRUE;
  25295.          _asm \
  25296.          {
  25297.              mov ax, _ax
  25298.              mov bx, _bx
  25299.              mov cx, _cx
  25300.              mov dx, _dx
  25301.              mov es, _es
  25302.              mov di, _di
  25303.              mov save_bp, bp
  25304.              mov bp, _bp
  25305.          }
  25306.  
  25307.          /* Call the original interrupt. */
  25308.          (*oldvideo)();
  25309.  
  25310.          /* Make sure that any values returned in real registers by the
  25311.           * interrupt are updated in the parameter registers. Reset the flag.
  25312.           */
  25313.          _asm \
  25314.          {
  25315.              mov bp, save_bp
  25316.              mov _bp, bp
  25317.              mov _di, di
  25318.              mov _es, es
  25319.              mov _dx, dx
  25320.              mov _cx, cx
  25321.              mov _bx, bx
  25322.              mov _ax, ax
  25323.          }
  25324.          finvideo = FALSE;
  25325.      }
  25326.  }
  25327.  
  25328.  
  25329.  ANIMATE.C
  25330.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\ANIMATE.C
  25331.  
  25332.  /* ANIMATE.C illustrates animation functions including:
  25333.   *          _imagesize     _getimage     _putimage
  25334.   */
  25335.  
  25336.  #include <conio.h>
  25337.  #include <stddef.h>
  25338.  #include <stdlib.h>
  25339.  #include <malloc.h>
  25340.  #include <graph.h>
  25341.  
  25342.  short action[5]  = { _GPSET,   _GPRESET, _GXOR,    _GOR,     _GAND    };
  25343.  char *descrip[5] = { "PSET  ", "PRESET", "XOR   ", "OR    ", "AND   " };
  25344.  
  25345.  main()
  25346.  {
  25347.      char far *buffer;
  25348.      short i, x, y = 30;
  25349.      size_t imsize;
  25350.      short mode = _VRES16COLOR;
  25351.  
  25352.      while( !_setvideomode( mode ) )         /* Find best graphics mode    */
  25353.          mode--;
  25354.      if (mode == _TEXTMONO )
  25355.          exit( 1 );                          /* No graphics available      */
  25356.      _setcolor( 3 );
  25357.      for ( i = 0; i < 5; i++ )
  25358.      {
  25359.          x = 50; y += 40;
  25360.          _settextposition( 1, 1 );           /* Display action type        */
  25361.          _outtext( descrip[i] );
  25362.                                              /* Draw and measure ellipse   */
  25363.          _ellipse( _GFILLINTERIOR, x - 15, y - 15, x + 15, y + 15 );
  25364.          imsize = (size_t)_imagesize( x - 16, y - 16, x + 16, y + 16 );
  25365.          buffer = (char far *)_fmalloc( imsize );
  25366.          if ( buffer == (char far *)NULL )
  25367.              exit( 1 );
  25368.                                              /* Get master copy of ellipse */
  25369.          _getimage( x - 16, y - 16, x + 16, y + 16, buffer );
  25370.          while( x < 260 )                    /* Copy row of ellipses       */
  25371.          {                                   /*   with specified action    */
  25372.              x += 5;
  25373.              _putimage( x - 16, y - 16, buffer, action[i] );
  25374.          }
  25375.          _ffree( (char far *)buffer );       /* Free memory                */
  25376.          getch();
  25377.      }
  25378.      exit( !_setvideomode( _DEFAULTMODE ) );
  25379.  }
  25380.  
  25381.  
  25382.  ARGS.C
  25383.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ARGS.C
  25384.  
  25385.  /* ARGS.C illustrates the following variables used for accessing
  25386.   * command-line arguments and environment variables:
  25387.   *      argc            argv            envp
  25388.   *
  25389.   * Also illustrates getting a process ID with:
  25390.   *      getpid
  25391.   */
  25392.  
  25393.  #include <stdio.h>
  25394.  #include <process.h>
  25395.  
  25396.  main( int argc,             /* Number of strings in array argv          */
  25397.        char *argv[],         /* Array of command-line argument strings   */
  25398.        char **envp )         /* Array of environment variable strings    */
  25399.  {
  25400.      int count;
  25401.  
  25402.      /* Display each command-line argument. */
  25403.      printf( "\nCommand-line arguments:\n" );
  25404.      for( count = 0; count < argc; count++ )
  25405.          printf( "  argv[%d]   %s\n", count, argv[count] );
  25406.  
  25407.      /* Display each environment variable. */
  25408.      printf( "\nEnvironment variables:\n" );
  25409.      while( *envp != NULL )
  25410.          printf( "  %s\n", *(envp++) );
  25411.  
  25412.      /* If run from DOS, shows different ID for DOS than for DOS shell.
  25413.       * If execed or spawned, shows ID of parent.
  25414.       */
  25415.      printf( "\nProcess id of parent: %d", getpid() );
  25416.      exit( 0 );
  25417.  }
  25418.  
  25419.  
  25420.  ARGV.C
  25421.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ARGV.C
  25422.  
  25423.  /* ARGV.C: Demonstrate accessing command-line arguments.
  25424.  */
  25425.  
  25426.  #include <stdio.h>
  25427.  
  25428.  void show_args( char *argument );
  25429.  
  25430.  int main( int argc, char *argv[] )
  25431.  {
  25432.     int count;
  25433.     for( count=0; count < argc; count++ )
  25434.        show_args( argv[count] );
  25435.     return 0;
  25436.  }
  25437.  
  25438.  void show_args( char *argument )
  25439.  {
  25440.     printf( "%s\n", argument );
  25441.  }
  25442.  
  25443.  
  25444.  ARGV1.C
  25445.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ARGV1.C
  25446.  
  25447.  /* ARGV1.C: Demonstrate null pointers. */
  25448.  
  25449.  #include <stdio.h>
  25450.  
  25451.  void show_args( char *argument );
  25452.  
  25453.  int main( int argc, char **argv )
  25454.  {
  25455.     while( *argv )
  25456.        show_args( *(argv++) );
  25457.     return 0;
  25458.  }
  25459.  
  25460.  void show_args( char *argument )
  25461.  {
  25462.     printf( "%s\n", argument );
  25463.  }
  25464.  
  25465.  
  25466.  ARRAY.C
  25467.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ARRAY.C
  25468.  
  25469.  /* ARRAY.C: Demonstrate arrays. */
  25470.  
  25471.  #include <stdio.h>
  25472.  
  25473.  main()
  25474.  {
  25475.     int j, k;
  25476.     static int i_array[2][3] = { { 12, 2, 444 }, { 6, 55, 777 } };
  25477.     static char c_array[] = "Hello";
  25478.  
  25479.     printf( "--- Values --------     --- Addresses -------\n\n" );
  25480.  
  25481.     for( j = 0; j < 2; j = j + 1 )
  25482.     {
  25483.        for( k = 0; k < 3; k = k + 1 )
  25484.        {
  25485.           printf( "i_array[%d][%d] = %d", j, k, i_array[j][k] );
  25486.           printf( "\t&i_array[%d][%d] = %u\n", j, k, &i_array[j][k] );
  25487.        }
  25488.        printf( "\n" );
  25489.     }
  25490.  
  25491.     for( j = 0; j < 6; j = j + 1 )
  25492.     {
  25493.        printf( "c_array[%d]   = %x %c", j, c_array[j], c_array[j] );
  25494.        printf( "\t&c_array[%d]    = %u\n", j, &c_array[j] );
  25495.     }
  25496.  }
  25497.  
  25498.  
  25499.  ASSERT.C
  25500.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ASSERT.C
  25501.  
  25502.  /* ASSERT.C illustrates function:
  25503.   *      assert
  25504.   */
  25505.  
  25506.  #include <stdio.h>
  25507.  #include <conio.h>
  25508.  #include <string.h>
  25509.  #include <assert.h>
  25510.  
  25511.  #define MAXSTR 120
  25512.  
  25513.  void chkstr( char *string );    /* Prototype */
  25514.  
  25515.  main()
  25516.  {
  25517.      char string1[MAXSTR], string2[MAXSTR];
  25518.  
  25519.      /* Do various processes on strings and check the results. If
  25520.       * none cause errors, force on error with empty string.
  25521.       */
  25522.      printf( "Enter a string: " );
  25523.      gets( string1 );
  25524.      chkstr( string1 );
  25525.  
  25526.      printf( "Enter another string: " );
  25527.      gets( string2 );
  25528.      chkstr( string2 );
  25529.  
  25530.      strcat( string1, string2 );
  25531.      chkstr( string1 );
  25532.      printf( "string1 + string2 = %s\n", string1 );
  25533.  
  25534.      chkstr( "" );
  25535.      printf( "You'll never get here\n" );
  25536.  }
  25537.  
  25538.  void chkstr( char *string )
  25539.  {
  25540.      assert( string != NULL );               /* Cannot be NULL */
  25541.      assert( *string != '\0' );              /* Cannot be empty */
  25542.      assert( strlen( string ) < MAXSTR );    /* Length must be positive */
  25543.  }
  25544.  
  25545.  
  25546.  ATEXIT.C
  25547.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ATEXIT.C
  25548.  
  25549.  /* ATEXIT.C illustrates:
  25550.   *      atexit          onexit
  25551.   */
  25552.  
  25553.  #include <stdlib.h>
  25554.  #include <stdio.h>
  25555.  ANSI                /* Comment out to try onexit     */
  25556.  
  25557.  /* Prototypes */
  25558.  void fn1( void ), fn2( void ), fn3( void ), fn4( void );
  25559.  
  25560.  main()
  25561.  {
  25562.  
  25563.      /* atexit is ANSI standard. It returns 0 for success, nonzero
  25564.       * for fail.
  25565.       */
  25566.  #ifdef ANSI
  25567.      atexit( fn1 );
  25568.      atexit( fn2 );
  25569.      atexit( fn3 );
  25570.      atexit( fn4 );
  25571.  
  25572.      /* onexit is Microsoft extension. It returns pointer to function
  25573.       * for success, NULL for fail.
  25574.       */
  25575.  #else
  25576.      onexit( fn1 );
  25577.      onexit( fn2 );
  25578.      onexit( fn3 );
  25579.      onexit( fn4 );
  25580.  #endif
  25581.  
  25582.      printf( "This is executed first.\n" );
  25583.  }
  25584.  
  25585.  void fn1()
  25586.  {
  25587.      printf( "next.\n" );
  25588.  }
  25589.  
  25590.  void fn2()
  25591.  {
  25592.      printf( "executed " );
  25593.  }
  25594.  
  25595.  void fn3()
  25596.  {
  25597.      printf( "is " );
  25598.  }
  25599.  
  25600.  void fn4()
  25601.  {
  25602.      printf( "This " );
  25603.  }
  25604.  
  25605.  
  25606.  ATONUM.C
  25607.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ATONUM.C
  25608.  
  25609.  /* ATONUM.C illustrates string to number conversion functions including:
  25610.   *      atof            atoi            atol            gcvt
  25611.   *
  25612.   * It also illustrates:
  25613.   *      cgets           cputs
  25614.   */
  25615.  
  25616.  #include <stdlib.h>
  25617.  #include <string.h>
  25618.  #include <conio.h>
  25619.  
  25620.  #define MAXSTR 100
  25621.  
  25622.  char cnumbuf[MAXSTR] = { MAXSTR + 2, 0 };
  25623.  numbuf cnumbuf + 2          /* Actual buffer starts at byte 3 */
  25624.  char tmpbuf[MAXSTR];
  25625.  
  25626.  /* Numeric input and output without printf. */
  25627.  main()
  25628.  {
  25629.      int     integer;
  25630.      long    longint;
  25631.      float   real;
  25632.  
  25633.      /* Using cgets (rather than gets) allows use of DOS editing keys
  25634.       * (or of editing keys from DOS command line editors).
  25635.       */
  25636.      cputs( "Enter an integer: " );
  25637.      cgets( cnumbuf );
  25638.      cputs( "\n\r" );                /* cputs doesn't translate \n     */
  25639.      integer = atoi( numbuf );
  25640.      strcpy( tmpbuf, numbuf );
  25641.      strcat( tmpbuf, " + " );
  25642.  
  25643.      cputs( "Enter a long integer: " );
  25644.      cgets( cnumbuf );
  25645.      cputs( "\n\r" );
  25646.      longint = atol( numbuf );
  25647.      strcat( tmpbuf, numbuf );
  25648.      strcat( tmpbuf, " + " );
  25649.  
  25650.      cputs( "Enter a floating point number: " );
  25651.      cgets( cnumbuf );
  25652.      cputs( "\n\r" );
  25653.      real = atof( numbuf );
  25654.      strcat( tmpbuf, numbuf );
  25655.      strcat( tmpbuf, " = " );
  25656.  
  25657.      gcvt( integer + longint + real, 4, numbuf );
  25658.      strcat( tmpbuf, numbuf );
  25659.      strcat( tmpbuf, "\n\r" );
  25660.  
  25661.      cputs( tmpbuf );
  25662.  }
  25663.  
  25664.  
  25665.  BADSEMI.C
  25666.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\BADSEMI.C
  25667.  
  25668.  /* BADSEMI.C: Misplaced semicolon. */
  25669.  
  25670.  #include <stdio.h>
  25671.  
  25672.  main()
  25673.  {
  25674.     int count;
  25675.     for( count = 0; count < 500; count++ ); /* Error! */
  25676.     {
  25677.        printf( "count = %d\n", count );
  25678.        printf( "And the beat goes on...\n" );
  25679.     }
  25680.  }
  25681.  
  25682.  
  25683.  BADSEMI1.C
  25684.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\BADSEMI1.C
  25685.  
  25686.  /* BADSEMI1.C: Misplaced semicolon. */
  25687.  
  25688.  #include <stdio.h>
  25689.  
  25690.  main()
  25691.  {
  25692.     int count;
  25693.     for( count = 0; count < 500; count++ )
  25694.        ; /* Null statement */
  25695.     {
  25696.        printf( "count = %d\n", count );
  25697.        printf( "And the beat goes on...\n" );
  25698.     }
  25699.  }
  25700.  
  25701.  
  25702.  BEEP.C
  25703.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\UTILITY\BEEP.C
  25704.  
  25705.  /* BEEP.C illustrates timing and port input and output functions
  25706.   * including:
  25707.   *      inp             outp            clock
  25708.   * Also keyword:
  25709.   *      enum
  25710.   *
  25711.   * In addition to the delay use shown here, clock can be used as a
  25712.   * timer as shown in SIEVE.C.
  25713.   */
  25714.  
  25715.  #include <time.h>
  25716.  #include <conio.h>
  25717.  
  25718.  void beep( unsigned duration, unsigned frequency );
  25719.  void delay( clock_t wait );
  25720.  
  25721.  
  25722.  enum notes
  25723.  {   /* Enumeration of notes and frequencies     */
  25724.      C0 = 262, D0 = 296, E0 = 330, F0 = 349, G0 = 392, A0 = 440, B0 = 494,
  25725.      C1 = 523, D1 = 587, E1 = 659, F1 = 698, G1 = 784, A1 = 880, B1 = 988,
  25726.      EIGHTH = 125, QUARTER = 250, HALF = 500, WHOLE = 1000, END = 0
  25727.  } song[] =
  25728.  {   /* Array initialized to notes of song       */
  25729.      C1, HALF, G0, HALF, A0, HALF, E0, HALF, F0, HALF, E0, QUARTER,
  25730.      D0, QUARTER, C0, WHOLE, END
  25731.  };
  25732.  
  25733.  int main ()
  25734.  {
  25735.      int note = 0;
  25736.  
  25737.      while( song[note] )
  25738.          beep( song[note++], song[note++] );
  25739.  }
  25740.  
  25741.  /* beep - sounds the speaker for a time specified in microseconds by
  25742.   * duration at a pitch specified in hertz by frequency.
  25743.   */
  25744.  void beep( unsigned duration, unsigned frequency )
  25745.  {
  25746.      int control;
  25747.  
  25748.      /* If frequency is 0, beep doesn't try to make a sound. It
  25749.       * just sleeps for the duration.
  25750.       */
  25751.      if (frequency)
  25752.      {
  25753.          /* 75 is the shortest reliable duration of a sound. */
  25754.          if( duration < 75 )
  25755.              duration = 75;
  25756.  
  25757.          /* Prepare timer by sending 10111100 to port 43. */
  25758.          outp( 0x43, 0xb6 );
  25759.  
  25760.          /* Divide input frequency by timer ticks per second and
  25761.           * write (byte by byte) to timer.
  25762.           */
  25763.          frequency = (unsigned)(1193180L / frequency);
  25764.          outp( 0x42, (char)frequency );
  25765.          outp( 0x42, (char)(frequency >> 8) );
  25766.  
  25767.          /* Save speaker control byte. */
  25768.          control = inp( 0x61 );
  25769.  
  25770.          /* Turn on the speaker (with bits 0 and 1). */
  25771.          outp( 0x61, control | 0x3 );
  25772.      }
  25773.  
  25774.      delay( (clock_t)duration );
  25775.  
  25776.      /* Turn speaker back on if necessary. */
  25777.      if( frequency )
  25778.          outp( 0x61, control );
  25779.  }
  25780.  
  25781.  /* delay - Pauses for a specified number of microseconds. */
  25782.  void delay( clock_t wait )
  25783.  {
  25784.      clock_t goal;
  25785.  
  25786.      goal = wait + clock();
  25787.      while( goal > clock() )
  25788.          ;
  25789.  }
  25790.  
  25791.  
  25792.  BESSEL.C
  25793.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\BESSEL.C
  25794.  
  25795.  /* BESSEL.C illustrates Bessel functions including:
  25796.   *      j0          j1          jn          y0          y1          yn
  25797.   */
  25798.  
  25799.  #include <math.h>
  25800.  #include <stdio.h>
  25801.  
  25802.  main()
  25803.  {
  25804.      double x = 2.387;
  25805.      int n = 3, c;
  25806.  
  25807.      printf( "Bessel functions for x = %f:\n", x );
  25808.      printf( "  Kind\t\tOrder\t\Function\tResult\n\n" );
  25809.      printf( "  First\t\t0\tj0( x )\t\t%f\n", j0( x ) );
  25810.      printf( "  First\t\t1\tj1( x )\t\t%f\n", j1( x ) );
  25811.      for( c = 2; c < 10; c++ )
  25812.          printf( "  First\t\t%d\tjn( n, x )\t%f\n", c, jn( c, x ) );
  25813.  
  25814.      printf( "  Second\t0\ty0( x )\t\t%f\n", y0( x ) );
  25815.      printf( "  Second\t1\ty1( x )\t\t%f\n", y1( x ) );
  25816.      for( c = 2; c < 10; c++ )
  25817.          printf( "  Second\t%d\tyn( n, x )\t%f\n", c, yn( c, x ) );
  25818.  }
  25819.  
  25820.  
  25821.  BINTEXT.C
  25822.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\BINTEXT.C
  25823.  
  25824.  /* BINTEXT.C illustrates changing between binary and text modes for
  25825.   * stream I/O using function:
  25826.   *      setmode
  25827.   * and global variable:
  25828.   *      _fmode
  25829.   */
  25830.  
  25831.  #include <stdio.h>
  25832.  #include <fcntl.h>
  25833.  #include <io.h>
  25834.  #include <string.h>
  25835.  <stdlib.h>         /* For _fmode and exit */
  25836.  
  25837.  main()
  25838.  {
  25839.      FILE *htmp;
  25840.      char name[13];
  25841.  
  25842.      /* Set default mode to binary and open file. */
  25843.      _fmode = O_BINARY;
  25844.      if( (htmp = fopen( tmpnam( name ), "w+" )) == NULL )
  25845.          exit( 1 );
  25846.      fprintf( htmp, "\nThis\nis\nsome\nbinary\ntext.\n\n" );
  25847.  
  25848.      /* Flush buffer and change mode to text. */
  25849.      fflush( htmp );
  25850.      setmode( fileno( htmp ), O_TEXT );
  25851.      fprintf( htmp, "\nThis\nis\nsome\ntext\ntext.\n\n" );
  25852.      fclose( htmp );
  25853.  
  25854.      system( strcat( "TYPE ", name ) );
  25855.      remove( name );
  25856.      exit( 0 );
  25857.  }
  25858.  
  25859.  
  25860.  BREAKER.C
  25861.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\BREAKER.C
  25862.  
  25863.  /* BREAKER.C: Demonstrate break statement. */
  25864.  
  25865.  #include <stdio.h>
  25866.  #include <conio.h>
  25867.  
  25868.  main()
  25869.  {
  25870.     char ch;
  25871.     printf( "Press any key. Press TAB to quit.\n" );
  25872.     while( 1 )
  25873.     {
  25874.        ch = getche();
  25875.        if( ch == '\t' )
  25876.        {
  25877.           printf( "\a\nYou pressed TAB.\n" );
  25878.           break;
  25879.        }
  25880.     }
  25881.  }
  25882.  
  25883.  
  25884.  BREAKER1.C
  25885.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\BREAKER1.C
  25886.  
  25887.  /* BREAKER1.C: Break only exits one loop. */
  25888.  
  25889.  #include <stdio.h>
  25890.  #include <conio.h>
  25891.  
  25892.  main()
  25893.  {
  25894.     char ch;
  25895.     printf( "Press any key. Press RETURN to quit.\n" );
  25896.     do
  25897.     {
  25898.        while( ( ch = getche() ) != '\r' )
  25899.        {
  25900.           if( ch == '\t' )
  25901.           {
  25902.              printf( "\a\nYou pressed TAB.\n" );
  25903.              break;
  25904.           }
  25905.        }
  25906.     } while( ch != '\r' );
  25907.     printf( "\nBye bye." );
  25908.  }
  25909.  
  25910.  
  25911.  BUFTEST.C
  25912.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\BUFTEST.C
  25913.  
  25914.  /* BUFTEST.C illustrates buffer control for stream I/O using functions:
  25915.   *      setbuf              setvbuf
  25916.   */
  25917.  
  25918.  #include <stdio.h>
  25919.  #include <stdlib.h>
  25920.  #include <time.h>
  25921.  #define BUF2SIZ 2048
  25922.  
  25923.  long countln( FILE *stream );           /* Prototype        */
  25924.  char buf1[BUFSIZ], buf2[BUF2SIZ];       /* File buffers     */
  25925.  
  25926.  main( int argc, char *argv[] )
  25927.  {
  25928.      time_t start;
  25929.      FILE *stream;
  25930.      int  c;
  25931.  
  25932.      /* Use our buffer with the default size. This gives us the option
  25933.       * of examining and/or modifying the buffer during I/0 (though the
  25934.       * example doesn't illustrate this).
  25935.       */
  25936.      if( (stream = fopen( argv[1], "rt" )) == NULL )
  25937.          exit( 1 );
  25938.      setbuf( stream, buf1 );
  25939.      start = clock();
  25940.      c = countln( stream );
  25941.      printf( "Time: %5.2f\tBuffering: Normal\tBuffer size: %d\n",
  25942.               ((float)clock() - start) / CLK_TCK, BUFSIZ );
  25943.  
  25944.      /* Use a larger buffer. */
  25945.      if( (stream = fopen( argv[1], "rt" )) == NULL )
  25946.          exit( 1 );
  25947.      setvbuf( stream, buf2, _IOFBF, sizeof( buf2 ) );
  25948.      start = clock();
  25949.      c = countln( stream );
  25950.      printf( "Time: %5.2f\tBuffering: Normal\tBuffer size: %d\n",
  25951.               ((float)clock() - start) / CLK_TCK, BUF2SIZ );
  25952.  
  25953.      /* Try it with no buffering. */
  25954.      if( (stream = fopen( argv[1], "rt" )) == NULL )
  25955.          exit( 1 );
  25956.      setvbuf( stream, NULL, _IONBF, 0 );
  25957.      start = clock();
  25958.      c = countln( stream );
  25959.      printf( "Time: %5.2f\tBuffering: Normal\tBuffer size: %d\n",
  25960.               ((float)clock() - start) / CLK_TCK, 0 );
  25961.  
  25962.      printf( "File %s has %d lines", argv[1], c );
  25963.      exit( 0 );
  25964.  }
  25965.  
  25966.  /* Count lines in text files and close file. */
  25967.  long countln( FILE *stream )
  25968.  {
  25969.      char linebuf[120];
  25970.      long c = 0;
  25971.  
  25972.      while( !feof( stream ) )
  25973.      {
  25974.          fgets( linebuf, 121, stream );
  25975.          ++c;
  25976.      }
  25977.      fclose( stream );
  25978.      return c;
  25979.  }
  25980.  
  25981.  
  25982.  CABS.C
  25983.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MATH\CABS.C
  25984.  
  25985.  /* CABS.C illustrates functions:
  25986.   *      cabs            hypot
  25987.   */
  25988.  
  25989.  #include <math.h>
  25990.  #include <stdio.h>
  25991.  
  25992.  main()
  25993.  {
  25994.      static struct complex ne = {  3.0,  4.0 }, se = { -3.0, -4.0 },
  25995.                            sw = { -3.0, -4.0 }, nw = { -3.0,  4.0 };
  25996.  
  25997.      printf( "Absolute %4.1lf + %4.1lfi:\t\t%4.1f\n",
  25998.              ne.x, ne.y, cabs( ne ) );
  25999.      printf( "Absolute %4.1lf + %4.1lfi:\t\t%4.1f\n",
  26000.              sw.x, sw.y, cabs( sw ) );
  26001.  
  26002.      printf( "Hypotenuse of %4.1lf and %4.1lf:\t%4.1f\n",
  26003.              se.x, se.y, hypot( se.x, se.y ) );
  26004.      printf( "Hypotenuse of %4.1lf and %4.1lf:\t%4.1f\n",
  26005.              nw.x, nw.y, hypot( nw.x, nw.y ) );
  26006.  }
  26007.  
  26008.  
  26009.  
  26010.  CASE.C
  26011.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\CASE.C
  26012.  
  26013.  /* CASE.C illustrates case conversion and other conversions.
  26014.   * Functions illustrated include:
  26015.   *      strupr          toupper         _toupper
  26016.   *      strlwr          tolower         _tolower
  26017.   *      strrev          toascii
  26018.   */
  26019.  
  26020.  #include <string.h>
  26021.  #include <stdio.h>
  26022.  #include <ctype.h>
  26023.  
  26024.  char mstring[] = "Dog Saw Dad Live On";
  26025.  char *ustring, *tstring, *estring;
  26026.  char *p;
  26027.  
  26028.  main()
  26029.  {
  26030.      printf( "Original:\t%s\n", mstring );
  26031.  
  26032.      /* Upper and lower case. */
  26033.      ustring = strupr( strdup( mstring ) );
  26034.      printf( "Upper case:\t%s\n", ustring );
  26035.  
  26036.      printf( "Lower case:\t%s\n", strlwr( ustring ) );
  26037.  
  26038.      /* Reverse case of each character. */
  26039.      tstring = strdup( mstring );
  26040.      for( p = tstring; *p; p++ )
  26041.      {
  26042.          if( isupper( *p ) )
  26043.              *p = tolower( *p );
  26044.          else
  26045.              *p = toupper( *p );
  26046.  
  26047.          /* This alternate code (commented out) shows how to use _tolower
  26048.           * and _toupper for the same purpose.
  26049.          if( isupper( *p ) )
  26050.              *p = _tolower( *p );
  26051.          else if( islower( *p ) )
  26052.              *p = _toupper( *p );
  26053.           */
  26054.      }
  26055.      printf( "Toggle case:\t%s\n", tstring );
  26056.  
  26057.      /* Encode and decode string. The decoding technique will convert
  26058.       * WordStar-style strings, which have some high bits set.
  26059.       */
  26060.      estring = strdup( mstring );
  26061.      for( p = estring; *p; p++ )
  26062.          *p = *p | 0x80;
  26063.      printf( "Encoded:\t%s\n", estring );
  26064.  
  26065.      for( p = estring; *p; p++ )
  26066.          *p = toascii( *p );
  26067.      printf( "Decoded:\t%s\n", estring );
  26068.  
  26069.      printf( "Reversed:\t%s\n", strrev( ustring ) );
  26070.  }
  26071.  
  26072.  
  26073.  CGA.C
  26074.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\CGA.C
  26075.  
  26076.  /* CGA.C: Demonstrates CGA colors */
  26077.  #include <stdio.h>
  26078.  #include <graph.h>
  26079.  #include <conio.h>
  26080.  
  26081.  long bkcolor[8] =
  26082.     {_BLACK, _BLUE, _GREEN, _CYAN,
  26083.      _RED, _MAGENTA, _BROWN, _WHITE};
  26084.  
  26085.  char *bkcolor_name [] =
  26086.     {"_BLACK", "_BLUE", "_GREEN", "_CYAN",
  26087.     "_RED", "_MAGENTA", "_BROWN", "_WHITE"};
  26088.  
  26089.  main()
  26090.  {
  26091.     int i, j, k;
  26092.     _setvideomode( _MRES4COLOR );
  26093.     for( i=0; i<= 3; i++ )
  26094.     {
  26095.        _selectpalette( i );
  26096.        for( k=0; k <= 7; k++ )
  26097.        {
  26098.           _setbkcolor( bkcolor[k] );
  26099.           for( j=0; j<=3; j++ )
  26100.           {
  26101.              _settextposition( 1, 1 );
  26102.              printf( "background color: %8s\n", bkcolor_name[k] );
  26103.              printf( "palette: %d\ncolor: %d\n", i, j );
  26104.              _setcolor( j );
  26105.              _rectangle( _GFILLINTERIOR, 160, 100, 320, 200 );
  26106.                 getch();
  26107.           }
  26108.        }
  26109.     }
  26110.     _setvideomode( _DEFAULTMODE );
  26111.  }
  26112.  
  26113.  
  26114.  CGAPAL.C
  26115.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\CGAPAL.C
  26116.  
  26117.  /* CGAPAL.C illustrates CGA palettes using:
  26118.   *      _selectpalette
  26119.   */
  26120.  
  26121.  #include <stdio.h>
  26122.  #include <stdlib.h>
  26123.  #include <conio.h>
  26124.  #include <graph.h>
  26125.  
  26126.  long bkcolor[8] = { _BLACK,  _BLUE,     _GREEN,  _CYAN,
  26127.                      _RED,    _MAGENTA,  _BROWN,  _WHITE };
  26128.  char *bkname [] = { "BLACK", "BLUE",    "GREEN", "CYAN",
  26129.                      "RED",   "MAGENTA", "BROWN", "WHITE" };
  26130.  main()
  26131.  {
  26132.      int i, j, k;
  26133.  
  26134.      if ( !_setvideomode( _MRES4COLOR ) )
  26135.          exit( 1 );
  26136.      for( i = 0; i < 4; i++ )
  26137.      {
  26138.          _selectpalette( i );
  26139.          for( k = 0; k < 8; k++ )
  26140.          {
  26141.              _setbkcolor( bkcolor[k] );
  26142.              for( j = 0; j < 4; j++ )
  26143.              {
  26144.                  _settextposition( 1, 1 );
  26145.                  printf( "Background color: %8s\n", bkname[k] );
  26146.                  printf( "Palette: %d\nColor: %d\n", i, j );
  26147.                  _setcolor( j );
  26148.                  _rectangle( _GFILLINTERIOR, 160, 100, 320, 200 );
  26149.                  getch();
  26150.              }
  26151.          }
  26152.      }
  26153.      exit( !_setvideomode( _DEFAULTMODE ) );
  26154.  }
  26155.  
  26156.  
  26157.  CHMOD1.C
  26158.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\CHMOD1.C
  26159.  
  26160.  /* CHMOD1.C illustrates reading and changing file attribute and time using:
  26161.   *      access          chmod           utime
  26162.   *
  26163.   * See CHMOD2.C for a more powerful variation of this program using
  26164.   * _dos functions.
  26165.   */
  26166.  
  26167.  #include <io.h>
  26168.  #include <sys\types.h>
  26169.  #include <sys\stat.h>
  26170.  #include <sys\utime.h>
  26171.  #include <stdio.h>
  26172.  #include <conio.h>
  26173.  #include <stdlib.h>
  26174.  
  26175.  enum FILEATTRIB { EXIST, WRITE = 2, READ = 4, READWRITE = 6 };
  26176.  
  26177.  /* Exist macro uses access */
  26178.  #define EXIST( name ) !access( name, EXIST )
  26179.  
  26180.  main( int argc, char *argv[] )
  26181.  {
  26182.      if( !EXIST( argv[1] ) )
  26183.      {
  26184.          printf( "Syntax:  CHMOD1 <filename>" );
  26185.          exit( 1 );
  26186.      }
  26187.  
  26188.      if( !access( argv[1], WRITE ) )
  26189.      {
  26190.          printf( "File %s is read/write. Change to read only? ", argv[1] );
  26191.  
  26192.          /* Note: Use stdlib.h for function definition of toupper rather
  26193.           * than macro version in ctype.h. Macro side effects would cause
  26194.           * macro version to read two keys.
  26195.           */
  26196.          if( toupper( getch() ) == 'Y' )
  26197.              chmod( argv[1], S_IREAD );
  26198.      }
  26199.      else
  26200.      {
  26201.          printf( "File %s is read only. Change to read/write? ", argv[1] );
  26202.          if( toupper( getch() ) == 'Y' )
  26203.              chmod( argv[1], S_IREAD | S_IWRITE );
  26204.      }
  26205.  
  26206.      printf( "\nUpdate file time to current time? " );
  26207.      if( toupper( getch() ) == 'Y' )
  26208.          utime( argv[1], NULL );
  26209.      exit( 0 );
  26210.  }
  26211.  
  26212.  
  26213.  CHMOD2.C
  26214.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\CHMOD2.C
  26215.  
  26216.  /* CHMOD2.C illustrates reading and changing file attributes and file
  26217.   * time using:
  26218.   *      _dos_getftime       _dos_setftime
  26219.   *      _dos_getfileattr    _dos_setfileattr
  26220.   *
  26221.   * See CHMOD1.C for a simpler variation of this program using the utime,
  26222.   * access, and chmod functions.
  26223.   */
  26224.  
  26225.  #include <dos.h>
  26226.  #include <fcntl.h>
  26227.  #include <stdio.h>
  26228.  #include <conio.h>
  26229.  #include <stdlib.h>
  26230.  #include <sys\types.h>
  26231.  #include <sys\stat.h>
  26232.  
  26233.  char *datestr( unsigned d, char *buf );     /* Prototypes */
  26234.  char *timestr( unsigned t, char *buf );
  26235.  
  26236.  main( int argc, char *argv[] )
  26237.  {
  26238.      unsigned fdate, ftime, fattr;
  26239.      struct dosdate_t ddate;
  26240.      struct dostime_t dtime;
  26241.      int hsource;
  26242.      char timebuf[10], datebuf[10], *pkind;
  26243.  
  26244.      /* Open to get file handle and test for errors (such as nonexistence). */
  26245.      if( _dos_open( argv[1], O_RDONLY, &hsource ) )
  26246.      {
  26247.          printf( "Can't open file\n" );
  26248.          exit( 1 );
  26249.      }
  26250.  
  26251.      /* Get time, date, and attribute of file. */
  26252.      _dos_getftime( hsource, &fdate, &ftime );
  26253.      _dos_getfileattr( argv[1], &fattr );
  26254.  
  26255.      /* Convert information into formatted strings. */
  26256.      datestr( fdate, datebuf );
  26257.      timestr( ftime, timebuf );
  26258.  
  26259.      if( fattr & _A_SUBDIR )
  26260.          pkind = "Directory";
  26261.      else if( fattr & _A_VOLID )
  26262.          pkind = "Label";
  26263.      else
  26264.          pkind = "File";
  26265.  
  26266.      printf( "%-12s   %-8s   %-9s   %-9s    %s %s %s\n",
  26267.              "FILE", "TIME", "DATE", "KIND", "RDO", "HID", "SYS" );
  26268.      printf( "%-12s   %8s   %8s    %-9s     %c   %c   %c\n",
  26269.              argv[1], timebuf, datebuf, pkind,
  26270.              (fattr & _A_RDONLY) ? 'Y' : 'N',
  26271.              (fattr & _A_HIDDEN) ? 'Y' : 'N',
  26272.              (fattr & _A_SYSTEM) ? 'Y' : 'N' );
  26273.  
  26274.      /* Update file time or attribute. */
  26275.      printf( "Change: (T)ime  (R)ead only  (H)idden  (S)ystem\n" );
  26276.      switch( toupper( getch() ) )    /* Use stdlib.h, not ctype.h */
  26277.      {
  26278.          case 'T':               /* Set to current time */
  26279.              _dos_gettime( &dtime );
  26280.              _dos_getdate( &ddate );
  26281.              ftime = (dtime.hour << 11) | (dtime.minute << 5);
  26282.              fdate = ((ddate.year - 1980) << 9) | (ddate.month << 5) |
  26283.                        ddate.day;
  26284.              _dos_setftime( hsource, fdate, ftime );
  26285.              break;
  26286.          case 'R':               /* Toggle read only */
  26287.              _dos_setfileattr( argv[1], fattr ^ _A_RDONLY );
  26288.              break;
  26289.          case 'H':               /* Toggle hidden    */
  26290.              _dos_setfileattr( argv[1], fattr ^ _A_HIDDEN );
  26291.              break;
  26292.          case 'S':               /* Toggle system    */
  26293.              _dos_setfileattr( argv[1], fattr ^ _A_SYSTEM );
  26294.              break;
  26295.      }
  26296.      _dos_close( hsource );
  26297.      exit( 1 );
  26298.  }
  26299.  
  26300.  /* Take unsigned time in the format:                fedcba9876543210
  26301.   * s=2 sec incr, m=0-59, h=23                       hhhhhmmmmmmsssss
  26302.   * Change to a 9-byte string (ignore seconds):      hh:mm ?m
  26303.   */
  26304.  char *timestr( unsigned t, char *buf )
  26305.  {
  26306.      int h = (t >> 11) & 0x1f, m = (t >> 5) & 0x3f;
  26307.  
  26308.      sprintf( buf, "%2.2d:%02.2d %cm", h % 12, m,  h > 11 ? 'p' : 'a' );
  26309.      return buf;
  26310.  }
  26311.  
  26312.  /* Take unsigned date in the format:    fedcba9876543210
  26313.   * d=1-31, m=1-12, y=0-119 (1980-2099)  yyyyyyymmmmddddd
  26314.   * Change to a 9-byte string:           mm/dd/yy
  26315.   */
  26316.  char *datestr( unsigned d, char *buf )
  26317.  {
  26318.      sprintf( buf, "%2.2d/%02.2d/%02.2d",
  26319.               (d >> 5) & 0x0f, d & 0x1f, (d >> 9) + 80 );
  26320.      return buf;
  26321.  }
  26322.  
  26323.  
  26324.  CMPSTR.C
  26325.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\CMPSTR.C
  26326.  
  26327.  /* CMPSTR.C illustrates string and memory comparison functions including:
  26328.   *       memcmp        memicmp
  26329.   *       strncmp       strnicmp
  26330.   *       strcmp        stricmp          strcmpi
  26331.   */
  26332.  
  26333.  #include <memory.h>
  26334.  #include <string.h>
  26335.  #include <stdio.h>
  26336.  
  26337.  char string1[] = "The quick brown dog jumps over the lazy fox";
  26338.  char string2[] = "The QUICK brown fox jumps over the lazy dog";
  26339.  
  26340.  main()
  26341.  {
  26342.      char tmp[20];
  26343.      int result;
  26344.  
  26345.      printf( "Compare strings:\n\t\t%s\n\t\t%s\n\n", string1, string2 );
  26346.  
  26347.      printf( "Function:\tmemcmp\n" );
  26348.      result = memcmp( string1, string2 , 42 );
  26349.      if( result > 0 )
  26350.          strcpy( tmp, "greater than" );
  26351.      else if( result < 0 )
  26352.          strcpy( tmp, "less than" );
  26353.      else
  26354.          strcpy( tmp, "equal to" );
  26355.      printf( "Result:\t\tString 1 is %s than string 2\n\n", tmp );
  26356.  
  26357.      printf( "Function:\tmemicmp\n" );
  26358.      result = memicmp( string1, string2, 42 );
  26359.      if( result > 0 )
  26360.          strcpy( tmp, "greater than" );
  26361.      else if( result < 0 )
  26362.          strcpy( tmp, "less than" );
  26363.      else
  26364.          strcpy( tmp, "equal to" );
  26365.      printf( "Result:\t\tString 1 is %s than string 2\n\n", tmp );
  26366.  
  26367.      printf( "Function:\tstrncmp\n" );
  26368.      result = strncmp( string1, string2 , 42 );
  26369.      if( result > 0 )
  26370.          strcpy( tmp, "greater than" );
  26371.      else if( result < 0 )
  26372.          strcpy( tmp, "less than" );
  26373.      else
  26374.          strcpy( tmp, "equal to" );
  26375.      printf( "Result:\t\tString 1 is %s than string 2\n\n", tmp );
  26376.  
  26377.      printf( "Function:\tstrnicmp\n" );
  26378.      result = strnicmp( string1, string2, 42 );
  26379.      if( result > 0 )
  26380.          strcpy( tmp, "greater than" );
  26381.      else if( result < 0 )
  26382.          strcpy( tmp, "less than" );
  26383.      else
  26384.          strcpy( tmp, "equal to" );
  26385.      printf( "Result:\t\tString 1 is %s than string 2\n\n", tmp );
  26386.  
  26387.      printf( "Function:\tstrcmp\n" );
  26388.      result = strcmp( string1, string2 );
  26389.      if( result > 0 )
  26390.          strcpy( tmp, "greater than" );
  26391.      else if( result < 0 )
  26392.          strcpy( tmp, "less than" );
  26393.      else
  26394.          strcpy( tmp, "equal to" );
  26395.      printf( "Result:\t\tString 1 is %s than string 2\n\n", tmp );
  26396.  
  26397.      printf( "Function:\tstricmp or strcmpi\n" );
  26398.      result = stricmp( string1, string2 );
  26399.      /* strcmpi (commented out) is the same as stricmp.
  26400.      result = strcmpi( string1, string2 );
  26401.       */
  26402.      if( result > 0 )
  26403.          strcpy( tmp, "greater than" );
  26404.      else if( result < 0 )
  26405.          strcpy( tmp, "less than" );
  26406.      else
  26407.          strcpy( tmp, "equal to" );
  26408.      printf( "Result:\t\tString 1 is %s than string 2\n", tmp );
  26409.  }
  26410.  
  26411.  
  26412.  COLOR.C
  26413.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\COLOR.C
  26414.  
  26415.   /* COLOR.C: Sets a medium resolution mode with maximum color choices */
  26416.  
  26417.  #include <stdio.h>
  26418.  #include <stdlib.h>
  26419.  #include <graph.h>
  26420.  #include <conio.h>
  26421.  struct videoconfig vc;
  26422.  
  26423.  main()
  26424.  {
  26425.     if( _setvideomode( _MRES256COLOR ) )
  26426.        ;
  26427.     else if( _setvideomode( _MRES16COLOR ) )
  26428.        ;
  26429.     else if( _setvideomode( _MRES4COLOR ) )
  26430.        ;
  26431.     else   {
  26432.        printf( "Error: No color graphics capability\n" );
  26433.        exit( 0 );
  26434.     }
  26435.  
  26436.     _getvideoconfig( &vc );
  26437.  
  26438.     printf( "%d available colors\n", vc.numcolors );
  26439.     printf( "%d horizontal pixels\n", vc.numxpixels );
  26440.     printf( "%d vertical pixels\n", vc.numypixels );
  26441.  
  26442.     getch();
  26443.     _clearscreen( _GCLEARSCREEN );
  26444.     _setvideomode( _DEFAULTMODE );
  26445.  }
  26446.  
  26447.  
  26448.  COLTEXT.C
  26449.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\COLTEXT.C
  26450.  
  26451.  /* COLTEXT.C: Displays text in color */
  26452.  #include <stdio.h>
  26453.  #include <conio.h>
  26454.  #include <graph.h>
  26455.  
  26456.  char buffer [80];
  26457.  
  26458.  main()
  26459.  {
  26460.     int blink,fgd;
  26461.     long bgd;
  26462.  
  26463.     _clearscreen( _GCLEARSCREEN );
  26464.     printf( "Text color attributes:\n" );
  26465.  
  26466.     for( blink=0; blink<=16; blink+=16 )
  26467.     {
  26468.        for( bgd=0; bgd<8; bgd++ )
  26469.        {
  26470.           _setbkcolor( bgd );
  26471.           _settextposition( bgd + ((blink / 16) * 9) + 3, 1 );
  26472.           _settextcolor( 7 );
  26473.           sprintf( buffer, "Bgd: %d Fgd:", bgd );
  26474.           _outtext( buffer );
  26475.  
  26476.           for( fgd=0; fgd<16; fgd++ )
  26477.           {
  26478.              _settextcolor( fgd+blink );
  26479.              sprintf( buffer, " %2d ", fgd+blink );
  26480.              _outtext( buffer );
  26481.           }
  26482.        }
  26483.     }
  26484.     getch();
  26485.     _setvideomode( _DEFAULTMODE );
  26486.  }
  26487.  
  26488.  
  26489.  COM.C
  26490.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\COM.C
  26491.  
  26492.  /* COM.C illustrates serial port access using function:
  26493.   *      _bios_serialcom
  26494.   */
  26495.  
  26496.  #include <bios.h>
  26497.  #include <stdio.h>
  26498.  
  26499.  main()
  26500.  {
  26501.      unsigned status, port;
  26502.  
  26503.      for( port = 0; port < 3; port++ )
  26504.      {
  26505.          status = _bios_serialcom( _COM_STATUS, port, 0 );
  26506.  
  26507.          /* Report status of each serial port and test whether there is a
  26508.           * modem for each. If data-set-ready and clear-to-send, modem exists.
  26509.           */
  26510.          printf( "COM%c status: %.4X\tModem: %s\n",
  26511.                  (char)port + '1', status,
  26512.                  (status & 0x0030) ? "YES" : "NO" );
  26513.      }
  26514.  }
  26515.  
  26516.  
  26517.  COMMA.C
  26518.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\COMMA.C
  26519.  
  26520.  /* COMMA.C: Demonstrate comma operator. */
  26521.  
  26522.  #include <stdio.h>
  26523.  
  26524.  main()
  26525.  {
  26526.     int val = 5, val1 = 666, temp;
  26527.     temp = val, val = val1, val1 = temp;
  26528.     printf( "val = %d  val1 = %d\n", val, val1 );
  26529.  }
  26530.  
  26531.  
  26532.  CONT.C
  26533.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\CONT.C
  26534.  
  26535.  /* CONT.C: Demonstrate continue statement. */
  26536.  
  26537.  #include <stdio.h>
  26538.  
  26539.  main()
  26540.  {
  26541.     int count;
  26542.     for( count = 0; count < 10; count++ )
  26543.     {
  26544.        if( count > 3 )
  26545.           continue;
  26546.        printf( "count = %d\n", count );
  26547.     }
  26548.     printf( "Done!\n" );
  26549.  }
  26550.  
  26551.  
  26552.  CONT1.C
  26553.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\CONT1.C
  26554.  
  26555.  /* CONT1.C: Demonstrate alternative to continue. */
  26556.  
  26557.  #include <stdio.h>
  26558.  
  26559.  main()
  26560.  {
  26561.     int count;
  26562.     for( count = 0; count < 10; count++ )
  26563.     {
  26564.        if( count < 4 )
  26565.           printf( "count = %d\n", count );
  26566.     }
  26567.     printf( "Done!\n" );
  26568.  }
  26569.  
  26570.  
  26571.  CONVERT.C
  26572.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\CONVERT.C
  26573.  
  26574.  /* CONVERT.C: Demonstrate type conversions. */
  26575.  
  26576.  #include <stdio.h>
  26577.  
  26578.  main()
  26579.  {
  26580.     char c_val = 10;
  26581.     int i_val = 20;
  26582.     long l_val = 64000;
  26583.     float f_val = 3.1;
  26584.     int result;
  26585.  
  26586.     result = c_val + i_val + l_val + f_val;  /* Error! */
  26587.  
  26588.     printf( "%d\n", result );
  26589.  }
  26590.  
  26591.  
  26592.  COPROC.C
  26593.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MATH\COPROC.C
  26594.  
  26595.  /* COPROC.C illustrates use of the status and control words of a floating
  26596.   * point coprocessor (or emulator). Functions illustrated include:
  26597.   *      _clear87            _status87           _control87
  26598.   */
  26599.  
  26600.  #include <stdio.h>
  26601.  #include <conio.h>
  26602.  #include <float.h>
  26603.  #include <stdlib.h>
  26604.  #include <string.h>
  26605.  
  26606.  double dx = 1e-40, dy;
  26607.  float fx, fy;
  26608.  unsigned status, control;
  26609.  char tmpstr[20];
  26610.  char *binstr( int num, char *buffer );
  26611.  
  26612.  main()
  26613.  {
  26614.      printf( "Status Word Key:\n" );
  26615.      printf( "B\tBusy flag\n0-3\tCondition codes\nS\tStack top pointer\n" );
  26616.      printf( "E\tError summary\nF\tStack flag\nP\tPrecision exception\n" );
  26617.      printf( "U\tUnderflow exception\nO\tOverflow exception\n" );
  26618.      printf( "Z\tZero divide exception\nD\tDenormalized exception\n" );
  26619.      printf( "I\tInvalid operation exception\n\n" );
  26620.  
  26621.      binstr(  _clear87(), tmpstr );
  26622.      printf( "B3SSS210EFPUOZDI  Function\tCondition\n\n" );
  26623.      printf( "%16s  _clear87\tAfter clearing\n", tmpstr );
  26624.  
  26625.      /* Storing double to float that hasn't enough precision for it
  26626.       * causes underflow and precision exceptions.
  26627.       */
  26628.      fx = dx;
  26629.      binstr(  _status87(), tmpstr );
  26630.      printf( "%16s  _status87\tAfter moving double to float\n", tmpstr );
  26631.  
  26632.      /* Storing float with lost precision back to double adds denormalized
  26633.       * exception (previous exceptions remain).
  26634.       */
  26635.      dy = fx;
  26636.      binstr(  _clear87(), tmpstr );
  26637.      printf( "%16s  _clear87\tAfter moving float to double\n", tmpstr );
  26638.  
  26639.      /* Using clear87() erases previous exceptions. */
  26640.      fy = dy;
  26641.      binstr(  _status87(), tmpstr );
  26642.      printf( "%16s  _status87\tAfter moving double to float\n\n", tmpstr );
  26643.  
  26644.      getch();
  26645.      printf( "Control Word Key:\n" );
  26646.      printf( "i\tInfinity control\nr\tRounding control\n" );
  26647.      printf( "p\tPrecision control\ne\tInterrupt enable mask\n" );
  26648.      printf( "U\tUnderflow mask\nO\tOverflow mask\n" );
  26649.      printf( "Z\tZero divide mask\nD\tDenormalized mask\n" );
  26650.      printf( "I\tInvalid operation mask\n\n" );
  26651.      printf( "???irrppe?PUOZDI  Result\n" );
  26652.      fy = .1;
  26653.  
  26654.      /* Show current control word. */
  26655.      binstr( _control87( 0, 0 ), tmpstr );
  26656.      printf( "%16s  %.1f * %.1f = %.15e with initial precision\n",
  26657.              tmpstr, fy, fy, fy * fy );
  26658.  
  26659.      /* Set precision to 24 bits. */
  26660.      binstr( _control87( PC_24, MCW_PC ), tmpstr );
  26661.      printf( "%16s  %.1f * %.1f = %.15e with 24 bit precision\n",
  26662.              tmpstr, fy, fy, fy * fy );
  26663.  
  26664.      /* Restore default. */
  26665.      binstr( _control87( CW_DEFAULT, 0xffff ), tmpstr );
  26666.      printf( "%16s  %.1f * %.1f = %.15e with default precision\n",
  26667.              tmpstr, fy, fy, fy * fy );
  26668.  }
  26669.  
  26670.  /* Convert integer to string of 16 binary characters. */
  26671.  char *binstr( int num, char *buffer )
  26672.  {
  26673.      char tmp[17];
  26674.      int  len;
  26675.  
  26676.      memset( buffer, '0', 16 );
  26677.      len = strlen( itoa( num, tmp, 2 ) );
  26678.      strcpy( buffer + 16 - len, tmp );
  26679.      return buffer;
  26680.  }
  26681.  
  26682.  
  26683.  COPY2.C
  26684.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\COPY2.C
  26685.  
  26686.  /* COPY2.C illustrates DOS file I/O and DOS memory allocation functions
  26687.   * including:
  26688.   *      _dos_open       _dos_close      _dos_creatnew   _dos_creat
  26689.   *      _dos_read       _dos_write      _dos_allocmem   _dos_free
  26690.   *
  26691.   * See COPY1.C for another version of the copyfile function.
  26692.   */
  26693.  
  26694.  #include <dos.h>
  26695.  #include <fcntl.h>
  26696.  #include <conio.h>
  26697.  #include <stdio.h>
  26698.  
  26699.  int copyfile( char *source, char *destin );     /* Prototype */
  26700.  
  26701.  main( int argc, char *argv[] )
  26702.  {
  26703.      if( argc == 3 )
  26704.          if( copyfile( argv[1], argv[2] ) )
  26705.              printf( "Copy failed\n" );
  26706.          else
  26707.              printf( "Copy successful\n" );
  26708.      else
  26709.          printf( "  SYNTAX: COPY2 <source> <target>\n" );
  26710.  }
  26711.  
  26712.  /* Function to copy one file to another (both specified by path).
  26713.   * Dynamically allocates memory for the file buffer. Prompts before
  26714.   * overwriting existing file. Returns 0 if successful, or an error
  26715.   * number if unsuccessful. This function uses dos functions only; no
  26716.   * standard C library functions are used.
  26717.   */
  26718.  #define EXIST 80
  26719.  enum ATTRIB { NORMAL, RDONLY, HIDDEN, SYSTEM = 4 };
  26720.  int copyfile( char *source, char *target )
  26721.  {
  26722.      char far *buf = NULL;
  26723.      static char prompt[] = "Target exists. Overwrite? ", newline[] = "\n\r";
  26724.      int hsource, htarget, ch;
  26725.      unsigned ret, segbuf, count;
  26726.  
  26727.      /* Attempt to dynamically allocate all of memory (0xffff paragraphs).
  26728.       * This will fail, but will return the amount actually available
  26729.       * in segbuf. Then allocate this amount.
  26730.       */
  26731.      _dos_allocmem( 0xffff, &segbuf );
  26732.      count = segbuf;
  26733.      if( ret = _dos_allocmem( count, &segbuf ) )
  26734.          return ret;
  26735.      FP_SEG( buf ) = segbuf;
  26736.  
  26737.      /* Open source file and create target, overwriting if necessary. */
  26738.      if( ret = _dos_open( source, O_RDONLY, &hsource ) )
  26739.          return ret;
  26740.      ret = _dos_creatnew( target, NORMAL, &htarget );
  26741.      if( ret == EXIST )
  26742.      {
  26743.          /* Use _dos_write to display prompts. Use bdos to call
  26744.           * function 1 to get and echo keystroke.
  26745.           */
  26746.          _dos_write( 1, prompt, sizeof( prompt ) - 1, &ch );
  26747.          ch = bdos( 1, 0, 0 ) & 0x00ff;
  26748.          if( (ch == 'y') || (ch == 'Y') )
  26749.              ret = _dos_creat( target, NORMAL, &htarget );
  26750.          _dos_write( 1, newline, sizeof( newline ) - 1, &ch );
  26751.      }
  26752.      if( ret )
  26753.          return ret;
  26754.  
  26755.      /* Read and write until there is nothing left. */
  26756.      while( count )
  26757.      {
  26758.          /* Read and write input. */
  26759.          if( (ret = _dos_read( hsource, buf, count, &count )) )
  26760.              return ret;
  26761.          if( (ret = _dos_write( htarget, buf, count, &count )) )
  26762.              return ret;
  26763.      }
  26764.  
  26765.      /* Close files and free memory. */
  26766.      _dos_close( hsource );
  26767.      _dos_close( htarget );
  26768.      _dos_freemem( segbuf );
  26769.      return 0;
  26770.  }
  26771.  
  26772.  
  26773.  
  26774.  CPYSTR.C
  26775.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\CPYSTR.C
  26776.  
  26777.  /* CPYSTR.C illustrate memory and string copy and move functions including:
  26778.   *      memccpy         memcpy          memmove
  26779.   *      strncpy         strcpy          strdup          strlen
  26780.   */
  26781.  
  26782.  #include <memory.h>
  26783.  #include <string.h>
  26784.  #include <stdio.h>
  26785.  #include <conio.h>
  26786.  #include <dos.h>
  26787.  
  26788.  char string1[60] = "The quick brown dog jumps over the lazy fox";
  26789.  char string2[60] = "The quick brown fox jumps over the lazy dog";
  26790.  /*                           1         2         3         4         5 *
  26791.   *                  12345678901234567890123456789012345678901234567890 */
  26792.  main()
  26793.  {
  26794.      char buffer[61];
  26795.      char *pdest, *newstring;
  26796.      int  pos;
  26797.  
  26798.      printf( "Function:\tmemccpy 60 characters or to character 's'\n" );
  26799.      printf( "Source:\t\t%s\n", string1 );
  26800.      pdest = memccpy( buffer, string1, 's', 60 );
  26801.      *pdest = '\0';
  26802.      printf( "Result:\t\t%s\n", buffer );
  26803.      printf( "Length:\t\t%d characters\n\n", strlen( buffer ) );
  26804.  
  26805.      pos = pdest - buffer;
  26806.      printf( "Function:\tstrcpy\n" );
  26807.      printf( "Source:\t\t%s\n", string2 + pos );
  26808.      pdest = strcpy( buffer + pos, string2 + pos );
  26809.      printf( "Result:\t\t%s\n", buffer );
  26810.      printf( "Length:\t\t%d characters\n\n", strlen( buffer ) );
  26811.  
  26812.      printf( "Function:\tmemcpy 20 characters\n" );
  26813.      printf( "Source:\t\t%s\n", string2 );
  26814.      memcpy( buffer, string2, 20 );
  26815.      printf( "Result:\t\t%s\n", buffer );
  26816.      printf( "Length:\t\t%d characters\n\n", strlen( buffer ) );
  26817.  
  26818.      printf( "Function:\tstrncpy 30 characters\n" );
  26819.      printf( "Source:\t\t%s\n", string1 + 20 );
  26820.      pdest = strncpy( buffer + 20, string1 + 20, 30 );
  26821.      printf( "Result:\t\t%s\n", buffer );
  26822.      printf( "Length:\t\t%d characters\n\n", strlen( buffer ) );
  26823.  
  26824.      getch();
  26825.  
  26826.      printf( "Function:\tstrdup\n" );
  26827.      printf( "Source:\t\t%s\n", buffer );
  26828.      newstring = strdup( buffer );
  26829.      printf( "Result:\t\t%s\n", newstring );
  26830.      printf( "Length:\t\t%d characters\n\n", strlen( newstring ) );
  26831.  
  26832.      /* Illustrate overlapping copy: memmove handles it correctly;
  26833.       * memcpy does not.
  26834.       */
  26835.      printf( "Function:\tmemcpy with overlap\n" );
  26836.      printf( "Source:\t\t%s\n", string1 + 4 );
  26837.      printf( "Destination:\t%s\n", string1 + 10 );
  26838.      memcpy( string1 + 10, string1 + 4, 40 );
  26839.      printf( "Result:\t\t%s\n", string1 );
  26840.      printf( "Length:\t\t%d characters\n\n", strlen( string1 ) );
  26841.  
  26842.      printf( "Function:\tmemmove with overlap\n" );
  26843.      printf( "Source:\t\t%s\n", string2 + 4 );
  26844.      printf( "Destination:\t%s\n", string2 + 10 );
  26845.      memmove( string2 + 10, string2 + 4, 40 );
  26846.      printf( "Result:\t\t%s\n", string2 );
  26847.      printf( "Length:\t\t%d characters\n\n", strlen( string2 ) );
  26848.  }
  26849.  
  26850.  
  26851.  DECRMENT.C
  26852.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\DECRMENT.C
  26853.  
  26854.  /* DECRMENT.C: Demonstrate prefix and postfix operators.
  26855.  */
  26856.  
  26857.  #include <stdio.h>
  26858.  main()
  26859.  {
  26860.     int val, sample = 3, proton = 3;
  26861.     val = sample--;
  26862.     printf( "val = %d  sample = %d\n", val, sample );
  26863.     val = --proton;
  26864.     printf( "val = %d  proton = %d\n", val, proton );
  26865.  }
  26866.  
  26867.  
  26868.  DIRECT.C
  26869.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\DIRECT.C
  26870.  
  26871.  /* DIRECT.C illustrates directory functions and miscellaneous file
  26872.   * and other functions including:
  26873.   *      getcwd          mkdir           chdir           rmdir
  26874.   *      system          mktemp          remove          unlink
  26875.   *      stat
  26876.   *
  26877.   * See NULLFILE.C for an example of fstat, which is similar to stat.
  26878.   */
  26879.  
  26880.  #include <direct.h>
  26881.  #include <stdlib.h>
  26882.  #include <stdio.h>
  26883.  #include <conio.h>
  26884.  #include <io.h>
  26885.  #include <time.h>
  26886.  #include <sys/types.h>
  26887.  #include <sys/stat.h>
  26888.  
  26889.  main()
  26890.  {
  26891.      char cwd[_MAX_DIR];
  26892.      static char tmpdir[] = "DRXXXXXX";
  26893.      struct stat filestat;
  26894.  
  26895.      /* Get the current working directory. */
  26896.      getcwd( cwd, _MAX_DIR );
  26897.  
  26898.      /* Try to make temporary name for directory. */
  26899.      if( mktemp( tmpdir ) == NULL )
  26900.      {
  26901.          perror( "Can't make temporary directory" );
  26902.          exit( 1 );
  26903.      }
  26904.  
  26905.      /* Try to create a new directory, and if successful, change to it. */
  26906.      if( !mkdir( tmpdir ) )
  26907.      {
  26908.          chdir( tmpdir );
  26909.  
  26910.          /* Create and display a file to prove it. */
  26911.          system( "echo This is a test. > TEST.TXT" );
  26912.          system( "type test.txt" );
  26913.  
  26914.          /* Display some file statistics. */
  26915.          if( !stat( "TEST.TXT", &filestat ) )
  26916.          {
  26917.              printf( "File: TEST.TXT\n" );
  26918.              printf( "Drive %c:\n", filestat.st_dev + 'A' );
  26919.              printf( "Directory: %s\\%s\n", cwd + 2, tmpdir );
  26920.              printf( "Size: %ld\n", filestat.st_size );
  26921.              printf( "Created: %s", ctime( &filestat.st_atime ) );
  26922.          }
  26923.          getch();
  26924.  
  26925.          /* Delete file, go back to original directory, and remove
  26926.           * directory. Note that under DOS, remove is equivalent to unlink,
  26927.           * so this line could be used instead.
  26928.          unlink( "TEST.TXT" );
  26929.           */
  26930.          remove( "TEST.TXT" );
  26931.          chdir( cwd );
  26932.          rmdir( tmpdir );
  26933.      }
  26934.  }
  26935.  
  26936.  
  26937.  DISK.C
  26938.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\DISK.C
  26939.  
  26940.  /* DISK.C illustrates low-level disk access using functions:
  26941.   *      _bios_disk          _dos_getdiskfree
  26942.   */
  26943.  
  26944.  #include <stdio.h>
  26945.  #include <conio.h>
  26946.  #include <bios.h>
  26947.  #include <dos.h>
  26948.  #include <stdlib.h>
  26949.  
  26950.  char far diskbuf[512];
  26951.  
  26952.  main( int argc, char *argv[] )
  26953.  {
  26954.      unsigned status = 0, i;
  26955.      struct diskinfo_t di;
  26956.      struct diskfree_t df;
  26957.      unsigned char far *p, linebuf[17];
  26958.  
  26959.      if( argc != 5 )
  26960.      {
  26961.          printf( "  SYNTAX: DISK <driveletter> <head> <track> <sector>" );
  26962.          exit( 1 );
  26963.      }
  26964.  
  26965.      if( (di.drive = toupper( argv[1][0] ) - 'A' ) > 1 )
  26966.      {
  26967.          printf( "Must be floppy drive" );
  26968.          exit( 1 );
  26969.      }
  26970.      di.head     = atoi( argv[2] );
  26971.      di.track    = atoi( argv[3] );
  26972.      di.sector   = atoi( argv[4] );
  26973.      di.nsectors = 1;
  26974.      di.buffer   = diskbuf;
  26975.  
  26976.      /* Get information about disk size. */
  26977.      if( _dos_getdiskfree( di.drive + 1, &df ) )
  26978.          exit( 1 );
  26979.  
  26980.      /* Try reading disk three times before giving up. */
  26981.      for( i = 0; i < 3; i++ )
  26982.      {
  26983.          status = _bios_disk( _DISK_READ, &di ) >> 8;
  26984.          if( !status )
  26985.              break;
  26986.      }
  26987.  
  26988.      /* Display one sector. */
  26989.      if( status )
  26990.          printf( "Error: 0x%.2x\n", status );
  26991.      else
  26992.      {
  26993.          for( p = diskbuf, i = 0; p < (diskbuf + df.bytes_per_sector); p++ )
  26994.          {
  26995.              linebuf[i++] = (*p > 32) ? *p : '.';
  26996.              printf( "%.2x ", *p );
  26997.              if( i == 16 )
  26998.              {
  26999.                  linebuf[i] = '\0';
  27000.                  printf( " %16s\n", linebuf );
  27001.                  i = 0;
  27002.              }
  27003.          }
  27004.      }
  27005.      exit( 1 );
  27006.  }
  27007.  
  27008.  
  27009.  DO.C
  27010.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\DO.C
  27011.  
  27012.  /* DO.C: Demonstrate do loop. */
  27013.  
  27014.  #include <stdio.h>
  27015.  
  27016.  main()
  27017.  {
  27018.     int test = 10;
  27019.     do
  27020.     {
  27021.        printf( "test = %d\n", test );
  27022.        test -= 2;
  27023.     }  while( test > 0 );
  27024.  }
  27025.  
  27026.  
  27027.  DOSMEM.C
  27028.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MEMORY\DOSMEM.C
  27029.  
  27030.  /* DOSMEM.C illustrates functions:
  27031.   *      _dos_allocmem       _dos_setblock       _dos_freemem
  27032.   *
  27033.   * See COPY2.C for another example of _dos_allocmem and _dos_freemem.
  27034.   */
  27035.  
  27036.  #include <dos.h>
  27037.  #include <stdio.h>
  27038.  #include <stdlib.h>
  27039.  
  27040.  main()
  27041.  {
  27042.      char far *buf = NULL, far *p;
  27043.      unsigned segbuf, maxbuf, size = 512;
  27044.  
  27045.      /* Allocate 512-byte buffer. Convert the size to paragraphs).
  27046.       * Assign the segment to the buffer. Fill with A's.
  27047.       */
  27048.      if( _dos_allocmem( size >> 4, &segbuf ) )
  27049.          exit( 1 );
  27050.      FP_SEG( buf ) = segbuf;
  27051.      for( p = buf; p < (buf + size); p++ )
  27052.          *p = 'A';
  27053.  
  27054.      /* Double the allocation. Fill the second half with B's. */
  27055.      size *= 2;
  27056.      if( _dos_setblock( size >> 4, segbuf, &maxbuf ) )
  27057.          exit( 1 );
  27058.      FP_SEG( buf ) = segbuf;
  27059.      for( p = buf + (size / 2); p < (buf + size); p++ )
  27060.          *p = 'B';
  27061.      *(--p) = '\0';
  27062.  
  27063.      printf( "Memory available: %u paragraphs\n", maxbuf );
  27064.      printf( "Buffer at %Fp contains:\n%Fs", (int far *)buf, buf );
  27065.  
  27066.      /* Free memory */
  27067.      exit( !_dos_freemem( segbuf ) );
  27068.  }
  27069.  
  27070.  
  27071.  EGA.C
  27072.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\EGA.C
  27073.  
  27074.  /* EGA.C: Demonstrates EGA palettes */
  27075.  #include <stdio.h>
  27076.  #include <conio.h>
  27077.  #include <graph.h>
  27078.  
  27079.  main()
  27080.  {
  27081.     _setvideomode( _ERESCOLOR );
  27082.     _setcolor( 4 );
  27083.     _rectangle( _GFILLINTERIOR, 50, 50, 200, 200 );
  27084.  
  27085.     _settextposition( 1, 1 );
  27086.     printf( "Normal palette\n" );
  27087.     printf( "Press a key" );
  27088.     getch();
  27089.  
  27090.     _remappalette( 4, _BLUE );
  27091.  
  27092.     _settextposition( 1, 1 );
  27093.     printf( "Remapped palette\n" );
  27094.     printf( "Press a key" );
  27095.     getch();
  27096.  
  27097.     _remappalette( 4, _RED );
  27098.  
  27099.     _settextposition( 1, 1 );
  27100.     printf( "Restored palette\n" );
  27101.     printf( "Press a key to clear the screen" );
  27102.     getch();
  27103.  
  27104.     _clearscreen( _GCLEARSCREEN );
  27105.     _setvideomode( _DEFAULTMODE );
  27106.  }
  27107.  
  27108.  
  27109.  ELSE.C
  27110.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ELSE.C
  27111.  
  27112.  /* ELSE.C: Demonstrate else clause. */
  27113.  
  27114.  #include <stdio.h>
  27115.  #include <conio.h>
  27116.  #define  B_KEY  'b'
  27117.  
  27118.  main()
  27119.  {
  27120.     char ch;
  27121.     printf( "Press the b key to hear a bell.\n" );
  27122.     ch = getch();
  27123.     if( ch == B_KEY )
  27124.        printf( "Beep!\a\n" );
  27125.     else
  27126.        printf( "Bye bye.\n" );
  27127.  }
  27128.  
  27129.  
  27130.  ELSE1.C
  27131.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ELSE1.C
  27132.  
  27133.  /* ELSE1.C: Demonstrate else-if construct. */
  27134.  
  27135.  #include <stdio.h>
  27136.  #include <conio.h>
  27137.  #define  B_KEY  'b'
  27138.  #define  ENTER_KEY '\r'
  27139.  
  27140.  main()
  27141.  {
  27142.     char ch;
  27143.     printf( "Press the b key to hear a bell.\n" );
  27144.     ch = getch();
  27145.     if( ch == B_KEY )
  27146.        printf( "Beep!\a\n" );
  27147.     else
  27148.        if( ch == ENTER_KEY )
  27149.           printf( "What a boring selection...\n" );
  27150.     else
  27151.        printf( "Bye bye.\n" );
  27152.  }
  27153.  
  27154.  
  27155.  EMPLOY1.C
  27156.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\EMPLOY1.C
  27157.  
  27158.  /* EMPLOY1.C: Demonstrate structure pointers. */
  27159.  
  27160.  #include <stdio.h>
  27161.  
  27162.  
  27163.  struct employee
  27164.  {
  27165.     char name[10];
  27166.     int months;
  27167.     float wage;
  27168.  };
  27169.  
  27170.  void display( struct employee *e_ptr  );
  27171.  
  27172.  main()
  27173.  {
  27174.     static struct employee jones =
  27175.        {
  27176.        "Jones, J",
  27177.        77,
  27178.        13.68
  27179.        };
  27180.  
  27181.     display( &jones );
  27182.  }
  27183.  
  27184.  void display( struct employee *e_ptr )
  27185.  {
  27186.     printf( "Name: %s\n", e_ptr->name );
  27187.     printf( "Months of service: %d\n", e_ptr->months );
  27188.     printf( "Hourly wage: %6.2f\n", e_ptr->wage );
  27189.  }
  27190.  
  27191.  
  27192.  EMPLOYEE.C
  27193.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\EMPLOYEE.C
  27194.  
  27195.  /* EMPLOYEE.C: Demonstrate structures. */
  27196.  
  27197.  #include <stdio.h>
  27198.  #include <string.h>
  27199.  
  27200.  struct employee
  27201.  {
  27202.     char name[10];
  27203.     int months;
  27204.     float wage;
  27205.  };
  27206.  
  27207.  void display( struct employee show );
  27208.  
  27209.  main()
  27210.  {
  27211.     struct employee jones;
  27212.  
  27213.     strcpy( jones.name, "Jones, J" );
  27214.     jones.months = 77;
  27215.     jones.wage = 13.68;
  27216.  
  27217.     display( jones );
  27218.  }
  27219.  
  27220.  void display( struct employee show )
  27221.  {
  27222.     printf( "Name: %s\n", show.name );
  27223.     printf( "Months of service: %d\n", show.months );
  27224.     printf( "Hourly wage: %6.2f\n", show.wage );
  27225.  }
  27226.  
  27227.  
  27228.  ENVIRON1.C
  27229.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ENVIRON1.C
  27230.  
  27231.  /* ENVIRON.C illustrates environment variable functions including:
  27232.   *      getenv          putenv          _searchenv
  27233.   */
  27234.  
  27235.  #include <stdlib.h>
  27236.  #include <string.h>
  27237.  #include <stdio.h>
  27238.  
  27239.  main()
  27240.  {
  27241.      char *pathvar, pathbuf[128], filebuf[128];
  27242.  
  27243.      /* Get the PATH environment variable and save a copy of it. */
  27244.      pathvar = getenv( "PATH" );
  27245.      strcpy( pathbuf, pathvar );
  27246.      printf( "Old PATH: %s\n", pathvar ? pathvar : "variable not set");
  27247.  
  27248.      /* Add a new directory to the path. */
  27249.      strcat( pathbuf, ";\\QC;" );
  27250.      if( putenv( pathbuf ) == -1 )
  27251.      {
  27252.          printf( "Failed\n");
  27253.          return 1;
  27254.      }
  27255.      else
  27256.          printf( "New PATH: %s\n", pathbuf );
  27257.  
  27258.      /* Search for file in the new path. */
  27259.      _searchenv( "QC.INI", "PATH", filebuf );
  27260.      if( *filebuf )
  27261.          printf( "QC.INI found at %s\n", filebuf );
  27262.      else
  27263.          printf( "QC.INI not found\n" );
  27264.  
  27265.      /* Restore original path. */
  27266.      if( putenv( pathvar ) == -1 )
  27267.          printf( "Failed\n");
  27268.      else
  27269.          printf( "Old PATH: %s\n", pathvar );
  27270.      return 0;
  27271.  }
  27272.  
  27273.  
  27274.  ERROR.C
  27275.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\ERROR.C
  27276.  
  27277.  /* ERROR.C illustrates stream file error handling. Functions illustrated
  27278.   * include:
  27279.   *      ferror          clearerr        exit            _exit
  27280.   *      perror          strerror        _strerror
  27281.   *
  27282.   * The _exit routine is not specifically illustrated, but it is the same
  27283.   * as exit except that file buffers are not flushed and atexit and onexit
  27284.   * are not called.
  27285.   */
  27286.  
  27287.  #include <stdio.h>
  27288.  #include <string.h>
  27289.  #include <stdlib.h>
  27290.  #include <errno.h>
  27291.  enum BOOL { FALSE, TRUE };
  27292.  
  27293.  FILE *stream;
  27294.  char string[] = "This should never be written";
  27295.  void errortest( FILE *stream, char *msg, int fterm );
  27296.  
  27297.  main( int argc, char *argv[] )
  27298.  {
  27299.      /* Open file and test to see if open caused error. If so, terminate. */
  27300.      stream = fopen( argv[1], "r" );
  27301.      errortest( stream, "Can't open file", TRUE );
  27302.  
  27303.      /* Try to write to a read-only file, then test to see if write
  27304.       * caused error. If so, clear error, but don't terminate.
  27305.       */
  27306.      fprintf( stream, "%s\n", string );
  27307.      errortest( stream, "Can't write file", FALSE );
  27308.      exit( 0 );
  27309.  }
  27310.  
  27311.  /* Error test routine takes a stream, a message, and a flag telling whether
  27312.   * to terminate if there is an error.
  27313.   */
  27314.  void errortest( FILE *stream, char *msg, int fterm )
  27315.  {
  27316.      /* If stream doesn't exist (failed fopen) or if there is an error
  27317.       * on the stream, handle error.
  27318.       */
  27319.      if( (stream == NULL) || (ferror( stream )) )
  27320.      {
  27321.          perror( msg );
  27322.          /* _strerror and strerror can be used to get the same result
  27323.           * as perror, as illustrated by these lines (commented out).
  27324.          printf( "%s: %s\n", msg, strerror( errno ) );
  27325.          printf( _strerror( msg ) );
  27326.           */
  27327.  
  27328.          /* Terminate or clear error, depending on terminate flag. */
  27329.          if( fterm )
  27330.              exit( errno );
  27331.          else
  27332.              clearerr( stream );
  27333.      }
  27334.  }
  27335.  
  27336.  
  27337.  EXEC.C
  27338.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\EXEC.C
  27339.  
  27340.  /* EXEC.C illustrates the different versions of exec including:
  27341.   *      execl           execle          execlp          execlpe
  27342.   *      execv           execve          execvp          execvpe
  27343.   *
  27344.   * Although EXEC.C can exec any program, you can verify how different
  27345.   * versions handle arguments and environment by compiling and
  27346.   * specifying the sample program ARGS.C. See SPAWN.C for examples
  27347.   * of the similar spawn functions.
  27348.   */
  27349.  
  27350.  #include <stdio.h>
  27351.  #include <conio.h>
  27352.  #include <process.h>
  27353.  
  27354.  char *my_env[] =                /* Environment for exec?e */
  27355.  {
  27356.      "THIS=environment will be",
  27357.      "PASSED=to child by the",
  27358.      "SPAWN=functions",
  27359.      NULL
  27360.  };
  27361.  
  27362.  main()
  27363.  {
  27364.      char *args[4], prog[80];
  27365.      int ch;
  27366.  
  27367.      printf( "Enter name of program to exec: " );
  27368.      gets( prog );
  27369.      printf( " 1. execl   2. execle   3. execlp   4. execlpe\n" );
  27370.      printf( " 5. execv   6. execve   7. execvp   8. execvpe\n" );
  27371.      printf( "Type a number from 1 to 8 (or 0 to quit): " );
  27372.      ch = getche();
  27373.      if( (ch < '1') || (ch > '8') )
  27374.          exit( 1 );
  27375.      printf( "\n\n" );
  27376.  
  27377.      /* Arguments for execv? */
  27378.      args[0] = prog;             /* First argument ignored under most */
  27379.      args[1] = "exec??";         /*   recent versions of DOS          */
  27380.      args[2] = "two";
  27381.      args[3] = NULL;
  27382.  
  27383.      switch( ch )
  27384.      {
  27385.          case '1':
  27386.              execl( prog, prog, "execl", "two", NULL );
  27387.              break;
  27388.          case '2':
  27389.              execle( prog, prog, "execle", "two", NULL, my_env );
  27390.              break;
  27391.          case '3':
  27392.              execlp( prog, prog, "execlp", "two", NULL );
  27393.              break;
  27394.          case '4':
  27395.              execlpe( prog, prog, "execlpe", "two", NULL, my_env );
  27396.              break;
  27397.          case '5':
  27398.              execv( prog, args );
  27399.              break;
  27400.          case '6':
  27401.              execve( prog, args, my_env );
  27402.              break;
  27403.          case '7':
  27404.              execvp( prog, args );
  27405.              break;
  27406.          case '8':
  27407.              execvpe( prog, args, my_env );
  27408.              break;
  27409.          default:
  27410.              break;
  27411.      }
  27412.  
  27413.      /* This point is only reached if exec fails. */
  27414.      printf( "\nProcess was not execed." );
  27415.      exit( 0 );
  27416.  }
  27417.  
  27418.  
  27419.  EXTDIR.C
  27420.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\EXTDIR.C
  27421.  
  27422.  /* EXTDIR.C illustrates wild card handling using functions:
  27423.   *      _dos_findfirst      _dos_findnext       sprintf
  27424.   */
  27425.  
  27426.  #include <stdlib.h>
  27427.  #include <stdio.h>
  27428.  #include <conio.h>
  27429.  #include <ctype.h>
  27430.  #include <dos.h>
  27431.  #include <io.h>
  27432.  #include <sys\types.h>
  27433.  #include <sys\utime.h>
  27434.  #include <sys\stat.h>
  27435.  
  27436.  long fileinfo( struct find_t *find );       /* Prototypes */
  27437.  char *timestr( unsigned d, char *buf );
  27438.  char *datestr( unsigned d, char *buf );
  27439.  
  27440.  main( int argc, char *argv[] )
  27441.  {
  27442.      struct find_t find;
  27443.      long size;
  27444.  
  27445.      /* Find first matching file, then find additional matches. */
  27446.      if( !_dos_findfirst( argv[1], 0xffff, &find ) )
  27447.      {
  27448.          printf( "%-12s   %-8s    %-8s   %-8s   %-9s   %s %s %s %s\n",
  27449.                  "FILE", "SIZE", "TIME", "DATE", "KIND",
  27450.                  "RDO", "HID", "SYS", "ARC" );
  27451.          size = fileinfo( &find );
  27452.      }
  27453.      else
  27454.      {
  27455.          printf( "  SYNTAX: TOUCH <wildfilespec>" );
  27456.          exit( 1 );
  27457.      }
  27458.      while( !_dos_findnext( &find ) )
  27459.          size += fileinfo( &find );
  27460.      printf( "%-12s   %8ld\n\n", "Total", size );
  27461.      exit( 0 );
  27462.  }
  27463.  
  27464.  long fileinfo( struct find_t *pfind )
  27465.  {
  27466.      char timebuf[10], datebuf[10], *pkind;
  27467.  
  27468.      datestr( pfind->wr_date, datebuf );
  27469.      timestr( pfind->wr_time, timebuf );
  27470.  
  27471.      if( pfind->attrib & _A_SUBDIR )
  27472.          pkind = "Directory";
  27473.      else if( pfind->attrib & _A_VOLID )
  27474.          pkind = "Label";
  27475.      else
  27476.          pkind = "File";
  27477.  
  27478.      printf( "%-12s   %8ld    %8s   %8s   %-9s    %c   %c   %c   %c\n",
  27479.              pfind->name, pfind->size, timebuf, datebuf, pkind,
  27480.              (pfind->attrib & _A_RDONLY) ? 'Y' : 'N',
  27481.              (pfind->attrib & _A_HIDDEN) ? 'Y' : 'N',
  27482.              (pfind->attrib & _A_SYSTEM) ? 'Y' : 'N',
  27483.              (pfind->attrib & _A_ARCH)   ? 'Y' : 'N' );
  27484.      return pfind->size;
  27485.  }
  27486.  
  27487.  /* Take unsigned time in the format:                fedcba9876543210
  27488.   * s=2 sec incr, m=0-59, h=23                       hhhhhmmmmmmsssss
  27489.   * Change to a 9-byte string (ignore seconds):      hh:mm ?m
  27490.   */
  27491.  char *timestr( unsigned t, char *buf )
  27492.  {
  27493.      int h = (t >> 11) & 0x1f, m = (t >> 5) & 0x3f;
  27494.  
  27495.      sprintf( buf, "%2.2d:%02.2d %cm", h % 12, m,  h > 11 ? 'p' : 'a' );
  27496.      return buf;
  27497.  }
  27498.  
  27499.  /* Take unsigned date in the format:    fedcba9876543210
  27500.   * d=1-31, m=1-12, y=0-119 (1980-2099)  yyyyyyymmmmddddd
  27501.   * Change to a 9-byte string:           mm/dd/yy
  27502.   */
  27503.  char *datestr( unsigned d, char *buf )
  27504.  {
  27505.      sprintf( buf, "%2.2d/%02.2d/%02.2d",
  27506.               (d >> 5) & 0x0f, d & 0x1f, (d >> 9) + 80 );
  27507.      return buf;
  27508.  }
  27509.  
  27510.  
  27511.  EXTERR.C
  27512.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\EXTERR.C
  27513.  
  27514.  /* EXTERR.C illustrates function:
  27515.   *      dosexterr
  27516.   */
  27517.  
  27518.  #include <dos.h>
  27519.  #include <fcntl.h>
  27520.  #include <stdio.h>
  27521.  #include <stdlib.h>
  27522.  
  27523.  void errorinfo( void );     /* Prototype */
  27524.  
  27525.  main( int argc, char *argv[] )
  27526.  {
  27527.      int hsource;
  27528.  
  27529.      /* Open to get file handle and test for errors. Try specifying
  27530.       * invalid files to show different errors.
  27531.       */
  27532.      if( _dos_open( argv[1], O_RDWR, &hsource ) )
  27533.          errorinfo();
  27534.      printf( "No error\n" );
  27535.      _dos_close( hsource );
  27536.      exit( 0 );
  27537.  }
  27538.  
  27539.  void errorinfo()
  27540.  {
  27541.      struct DOSERROR err;
  27542.      static char *eclass[] =
  27543.      {
  27544.          "", "Out of Resource", "Temporary Situation", "Authorization",
  27545.          "Internal", "Hardware Failure", "System Failure", "Application Error"
  27546.          "Not Found", "Bad Format", "Locked", "Media", "Already Exists",
  27547.          "Unknown"
  27548.      };
  27549.      static char *eaction[] =
  27550.      {
  27551.          "", "Retry", "Delay Retry", "User", "Abort", "Immediate Exit",
  27552.          "Ignore", "Retry After User Intervention"
  27553.      };
  27554.      static char *elocus[] =
  27555.      {
  27556.          "", "Unknown", "Block Device", "Net", "Serial Device", "Memory"
  27557.      };
  27558.  
  27559.  
  27560.      /* Get error information and display class, action, and locus. */
  27561.      dosexterr( &err );
  27562.      printf( "Class:\t%s\nAction:\t%s\nLocus:\t%s\nAction\t",
  27563.              eclass[err.class], eaction[err.action], elocus[err.locus] );
  27564.  
  27565.      /* Errors that could be caused by sample _dos_open. You can expand
  27566.       * this list to handle others.
  27567.       */
  27568.      switch( err.exterror )
  27569.      {
  27570.          case 2:
  27571.              printf( "File not found\n" );
  27572.              break;
  27573.          case 3:
  27574.              printf( "Path not found\n" );
  27575.              break;
  27576.          case 5:
  27577.              printf( "Access denied\n" );
  27578.              break;
  27579.      }
  27580.      exit( err.exterror );
  27581.  }
  27582.  
  27583.  
  27584.  FACTOR.C
  27585.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\FACTOR.C
  27586.  
  27587.  /* FACTOR.C: Demonstrate functions.
  27588.   *  NOTE:  a value > 16 will overflow a long integer.
  27589.   */
  27590.  
  27591.  #include <stdio.h>
  27592.  
  27593.  long factor( int param );
  27594.  
  27595.  main()
  27596.  {
  27597.     int num;
  27598.     long result;
  27599.     /* Display a prompt */
  27600.     printf( "Type a number: " );
  27601.     /* Input a numeric value, assign to num */
  27602.     scanf( "%d", &num );
  27603.     result = factor( num );
  27604.     printf( "Factorial of %d is %ld\n", num, result );
  27605.  }
  27606.  
  27607.  long factor( int param )
  27608.  {
  27609.     long value = 1;
  27610.     while( param > 1 )
  27611.     {
  27612.        value = value * param;
  27613.        param = param - 1;
  27614.     }
  27615.     return value;
  27616.  }
  27617.  
  27618.  
  27619.  FCVT.C
  27620.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\FCVT.C
  27621.  
  27622.  /* FCVT.C illustrates floating point to string conversion functions:
  27623.   *      gcvt            ecvt            fcvt
  27624.   *
  27625.   * See MKFPSTR.C for an example of using the data returned by fcvt
  27626.   * to build a formatted string. See ATONUM.C for an example of using
  27627.   * the string returned by gcvt.
  27628.   */
  27629.  
  27630.  #include <stdlib.h>
  27631.  #include <stdio.h>
  27632.  #include <string.h>
  27633.  
  27634.  main()
  27635.  {
  27636.      int decimal, sign;
  27637.      char *pnumstr;
  27638.      int precision = 7;
  27639.      char numbuf[50];
  27640.      double number1, number2;
  27641.  
  27642.      printf( "Enter two floating point numbers: " );
  27643.      scanf( "%lf %lf", &number1, &number2 );
  27644.  
  27645.      /* With gcvt, precision specifies total number of digits.
  27646.       * The decimal place and sign are inserted in the string.
  27647.       */
  27648.      gcvt( number1 + number2, precision, numbuf );
  27649.      printf( "\nString produced by gcvt: %s\n", numbuf );
  27650.      printf( "Total digits: %d\n", precision );
  27651.  
  27652.      /* With ecvt, precision specifies total number of digits.
  27653.       * The decimal place and sign are provided for use in formatting.
  27654.       */
  27655.      pnumstr = ecvt( number1 + number2, precision, &decimal, &sign );
  27656.      printf( "\nString produced by ecvt: %s\nSign: %s\n",
  27657.               pnumstr, sign ? "-" : "+" );
  27658.      printf( "Digits left of decimal: %d\nTotal digits: %d\n",
  27659.               decimal, precision );
  27660.  
  27661.      /* With fcvt, precision specifies digits after decimal place.
  27662.       * The decimal place and sign are provided for use in formatting.
  27663.       */
  27664.      pnumstr = fcvt( number1 + number2, precision, &decimal, &sign );
  27665.      printf( "\nString produced by fcvt: %s\nSign: %s\n",
  27666.               pnumstr, sign ? "-" : "+"  );
  27667.      printf( "Digits left of decimal: %d\nDigits after decimal: %d\n",
  27668.               decimal, precision );
  27669.  }
  27670.  
  27671.  
  27672.  FIGURE.C
  27673.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\FIGURE.C
  27674.  
  27675.  /* FIGURE.C illustrates graphics drawing functions including:
  27676.   *      _setpixel   _lineto     _moveto     _rectangle      _ellipse
  27677.   *      _arc        _pie
  27678.   *
  27679.   * Window versions of graphics drawing functions (such as _rectangle_w,
  27680.   * _ellipse_wxy, and _lineto_w) are illustrated in WINDOW.C and GEDIT.C.
  27681.   */
  27682.  
  27683.  #include <conio.h>
  27684.  #include <stdlib.h>
  27685.  #include <graph.h>
  27686.  
  27687.  main()
  27688.  {
  27689.      short x, y;
  27690.      short mode = _VRES16COLOR;
  27691.  
  27692.      while( !_setvideomode( mode ) )     /* Find best graphics mode   */
  27693.          mode--;
  27694.      if( mode == _TEXTMONO )
  27695.          exit( 1 );                      /* No graphics available     */
  27696.  
  27697.      for( x = 10, y = 50; y < 90; x += 2, y += 3 )/* Draw pixels      */
  27698.          _setpixel( x, y );
  27699.      getch();
  27700.  
  27701.      for( x = 60, y = 50; y < 90; y += 3 )        /* Draw lines       */
  27702.      {
  27703.          _moveto( x, y );
  27704.          _lineto( x + 20, y );
  27705.      }
  27706.      getch();
  27707.  
  27708.      x = 110; y = 70;                             /* Draw rectangles  */
  27709.      _rectangle( _GBORDER,       x - 20, y - 20, x, y );
  27710.      _rectangle( _GFILLINTERIOR, x + 20, y + 20, x, y );
  27711.      getch();
  27712.  
  27713.      x = 160;                                     /* Draw ellipses    */
  27714.      _ellipse( _GBORDER,       x - 20, y - 20, x, y );
  27715.      _ellipse( _GFILLINTERIOR, x + 20, y + 20, x, y );
  27716.      getch();
  27717.  
  27718.      x = 210;                                     /* Draw arcs        */
  27719.      _arc( x - 20, y - 20, x, y, x, y - 10, x - 10, y );
  27720.      _arc( x + 20, y + 20, x, y, x + 10, y + 20, x + 20, y + 10 );
  27721.      getch();
  27722.  
  27723.      x = 260;                                    /* Draw pies        */
  27724.      _pie( _GBORDER,       x - 20, y - 20, x, y, x, y - 10, x - 10, y );
  27725.      _pie( _GFILLINTERIOR, x + 20, y + 20, x, y,
  27726.                            x + 10, y + 20, x + 20, y + 10 );
  27727.      getch();
  27728.  
  27729.      exit( !_setvideomode( _DEFAULTMODE ) );
  27730.  }
  27731.  
  27732.  
  27733.  FILEONE.C
  27734.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\FILEONE.C
  27735.  
  27736.  /* FILEONE.C: Visibility in multiple source files.
  27737.  */
  27738.  
  27739.  int chico = 20, harpo = 30;
  27740.  extern void yonder( void );
  27741.  
  27742.  main()
  27743.  {
  27744.     yonder();
  27745.  }
  27746.  
  27747.  
  27748.  FILETWO.C
  27749.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\FILETWO.C
  27750.  
  27751.  /* FILETWO.C: Visibility in multiple source files.
  27752.  */
  27753.  
  27754.  #include <stdio.h>
  27755.  
  27756.  void yonder( void )
  27757.  {
  27758.     extern int chico, harpo;
  27759.     printf( "chico = %d, harpo = %d\n", chico, harpo );
  27760.  }
  27761.  
  27762.  
  27763.  FILL.C
  27764.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\FILL.C
  27765.  
  27766.  /* FILL.C illustrates color, filling, and linestyle functions including:
  27767.   *    _setlinestyle      _setfillmask       _setcolor
  27768.   *    _getlinestyle      _floodfill
  27769.   *
  27770.   * The _getfillmask function is not shown, but its use is similar to
  27771.   * _getlinestyle.
  27772.   */
  27773.  
  27774.  #include <conio.h>
  27775.  #include <graph.h>
  27776.  #include <time.h>
  27777.  #include <stdlib.h>
  27778.  
  27779.  main()
  27780.  {
  27781.      short x, y, xinc, yinc, xwid, ywid;
  27782.      unsigned char fill[8];
  27783.      struct videoconfig vc;
  27784.      unsigned seed = (unsigned)time( 0L );   /* Different seed each time */
  27785.      short i, color, mode = _VRES16COLOR;
  27786.  
  27787.      while( !_setvideomode( mode ) )         /* Find best graphics mode  */
  27788.          mode--;
  27789.      if (mode == _TEXTMONO )
  27790.          exit( 1 );                          /* No graphics available    */
  27791.      _getvideoconfig( &vc );
  27792.  
  27793.      xinc = vc.numxpixels / 8;               /* Size variables to mode   */
  27794.      yinc = vc.numxpixels / 8;
  27795.      xwid = (xinc / 2) - 4;
  27796.      ywid = (yinc / 2) - 4;
  27797.  
  27798.      /* Draw circles and lines with different patterns. */
  27799.      for( x = xinc; x <= (vc.numxpixels - xinc); x += xinc )
  27800.      {
  27801.          for( y = yinc; y <= (vc.numypixels - yinc); y += yinc )
  27802.          {
  27803.              /* Vary random seed, randomize fill and color. */
  27804.              srand( seed = (seed + 431) * 5 );
  27805.              for( i = 0; i < 8; i++ )
  27806.                  fill[i] = rand();
  27807.              _setfillmask( fill );
  27808.              color = (rand() % vc.numcolors) + 1;
  27809.              _setcolor( color );
  27810.  
  27811.              /* Draw ellipse and fill with random color. */
  27812.              _ellipse( _GBORDER, x - xwid, y - ywid, x + xwid, y + ywid );
  27813.              _setcolor( (rand() % vc.numcolors) + 1 );
  27814.              _floodfill( x, y, color );
  27815.  
  27816.              /* Draw vertical and horizontal lines. Vertical line style
  27817.               * is opposite of (not) horizontal style. Since lines are
  27818.               * overdrawn with several linestyles, this has the effect of
  27819.               * combining colors and styles.
  27820.               */
  27821.              _setlinestyle( rand() );
  27822.              _moveto( 0, y + ywid + 4 );
  27823.              _lineto( vc.numxpixels - 1, y + ywid + 4 );
  27824.              _setlinestyle( ~_getlinestyle() );
  27825.              _moveto( x + xwid + 4, 0 );
  27826.              _lineto( x + xwid + 4, vc.numypixels - 1 );
  27827.          }
  27828.      }
  27829.      getch();
  27830.      exit( !_setvideomode( _DEFAULTMODE ) );
  27831.  }
  27832.  
  27833.  
  27834.  FINDSTR.C
  27835.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\FINDSTR.C
  27836.  
  27837.  /* FINDSTR.C illustrates memory and string search functions including:
  27838.   *       memchr        strchr        strrchr            strstr
  27839.   */
  27840.  
  27841.  #include <memory.h>
  27842.  #include <string.h>
  27843.  #include <stdio.h>
  27844.  
  27845.  int  ch = 'r';
  27846.  char str[] =    "lazy";
  27847.  char string[] = "The quick brown dog jumps over the lazy fox";
  27848.  char fmt1[] =   "         1         2         3         4         5";
  27849.  char fmt2[] =   "12345678901234567890123456789012345678901234567890";
  27850.  
  27851.  main()
  27852.  {
  27853.      char *pdest;
  27854.      int result;
  27855.  
  27856.      printf( "String to be searched:\n\t\t%s\n", string );
  27857.      printf( "\t\t%s\n\t\t%s\n\n", fmt1, fmt2 );
  27858.  
  27859.      printf( "Function:\tmemchr\n" );
  27860.      printf( "Search char:\t%c\n", ch );
  27861.      pdest = memchr( string, ch, sizeof( string ) );
  27862.      result = pdest - string + 1;
  27863.      if( pdest != NULL )
  27864.          printf( "Result:\t\t%c found at position %d\n\n", ch, result );
  27865.      else
  27866.          printf( "Result:\t\t%c not found\n" );
  27867.  
  27868.      printf( "Function:\tstrchr\n" );
  27869.      printf( "Search char:\t%c\n", ch );
  27870.      pdest = strchr( string, ch );
  27871.      result = pdest - string + 1;
  27872.      if( pdest != NULL )
  27873.          printf( "Result:\t\t%c found at position %d\n\n", ch, result );
  27874.      else
  27875.          printf( "Result:\t\t%c not found\n" );
  27876.  
  27877.      printf( "Function:\tstrrchr\n" );
  27878.      printf( "Search char:\t%c\n", ch );
  27879.      pdest = strrchr( string, ch );
  27880.      result = pdest - string + 1;
  27881.      if( pdest != NULL )
  27882.          printf( "Result:\t\t%c found at position %d\n\n", ch, result );
  27883.      else
  27884.          printf( "Result:\t\t%c not found\n" );
  27885.  
  27886.      printf( "Function:\tstrstr\n" );
  27887.      printf( "Search string:\t%s\n", str );
  27888.      pdest = strstr( string, str );
  27889.      result = pdest - string + 1;
  27890.      if( pdest != NULL )
  27891.          printf( "Result:\t\t%s found at position %d\n\n", str, result );
  27892.      else
  27893.          printf( "Result:\t\t%c not found\n" );
  27894.  }
  27895.  
  27896.  
  27897.  FOR1.C
  27898.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\FOR1.C
  27899.  
  27900.  /* FOR1.C: Demonstrate multiple expressions. */
  27901.  
  27902.  #include <stdio.h>
  27903.  
  27904.  main()
  27905.  {
  27906.     int a, b;
  27907.     for( a = 256, b = 1; b < 512; a /= 2, b *= 2 )
  27908.        printf( "a = %d  b = %d\n", a, b );
  27909.  }
  27910.  
  27911.  
  27912.  FOR2.C
  27913.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\FOR2.C
  27914.  
  27915.  /* FOR2.C: Demonstrate variations on for loop. */
  27916.  
  27917.  #include <stdio.h>
  27918.  #include <conio.h>
  27919.  
  27920.  main()
  27921.  {
  27922.     for( printf( "Type something\n" ); getche() != '\r'; )
  27923.        ; /* Null statement */
  27924.  }
  27925.  
  27926.  
  27927.  FOR3.C
  27928.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\FOR3.C
  27929.  
  27930.  /* FOR3.C: Demonstrate similarity of for and while.
  27931.  */
  27932.  
  27933.  #include <stdio.h>
  27934.  
  27935.  main()
  27936.  {
  27937.     int count;
  27938.  
  27939.     for( count = 0; count < 10; count++ )
  27940.        printf( "count = %d\n", count );
  27941.  
  27942.     count = 0;
  27943.     while( count < 10 )
  27944.     {
  27945.        printf( "count = %d\n", count );
  27946.        count++;
  27947.     }
  27948.  
  27949.  }
  27950.  
  27951.  
  27952.  FOR4.C
  27953.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\FOR4.C
  27954.  
  27955.  /* FOR.C: Demonstrate for loop. */
  27956.  
  27957.  #include <stdio.h>
  27958.  
  27959.  main()
  27960.  {
  27961.     int test;
  27962.     for( test = 10; test > 0; test -= 2 )
  27963.        printf( "test = %d\n", test );
  27964.  }
  27965.  
  27966.  
  27967.  FREECT.C
  27968.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\FREECT.C
  27969.  
  27970.  /* FREECT.C illustrates the following heap functions:
  27971.   *      _freect         _memavl
  27972.   */
  27973.  
  27974.  #include <malloc.h>
  27975.  #include <stdio.h>
  27976.  
  27977.  main()
  27978.  {
  27979.      char near *bufs[64];
  27980.      unsigned request, avail, i;
  27981.  
  27982.      printf( "Near heap bytes free: %u\n\n", _memavl() );
  27983.      printf( "How many 1K buffers do you want from the near heap? " );
  27984.      scanf( "%d", &request );
  27985.      if( request > 64 )
  27986.      {
  27987.          printf( "There are only 64K in a segment.\n" );
  27988.          request = 64;
  27989.      }
  27990.  
  27991.      avail = _freect( 1024 );
  27992.      request = (avail > request) ? request : avail;
  27993.      printf( "You can have %d buffers\n", request );
  27994.  
  27995.      printf( "They are available at:\n");
  27996.      for( i = 0; i < request; i++ )
  27997.      {
  27998.          bufs[i] = (char near *)_nmalloc( 1024 );
  27999.          printf( "%2d %Fp   ", i + 1, (char far *)bufs[i] );
  28000.          if( (i % 5) == 4 )
  28001.              printf( "\n" );
  28002.      }
  28003.      printf( "\n\nNear heap bytes free: %u\n\n", _memavl() );
  28004.      printf( "Freeing buffers . . ." );
  28005.      for( i = request; i; i-- )
  28006.          _nfree( bufs[i] );
  28007.      printf( "\n\nNear heap bytes free: %u", _memavl() );
  28008.  }
  28009.  
  28010.  
  28011.  FSAMPLER.C
  28012.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\FSAMPLER.C
  28013.  
  28014.  /* SAMPLER.C: Display sample text in various fonts.
  28015.  */
  28016.  
  28017.  #include <stdio.h>
  28018.  #include <conio.h>
  28019.  #include <stdlib.h>
  28020.  #include <graph.h>
  28021.  #include <string.h>
  28022.  
  28023.  #define NFONTS 6
  28024.  
  28025.  main()
  28026.  
  28027.  {
  28028.    static unsigned char *text[2*NFONTS] =
  28029.    {
  28030.        "COURIER",        "courier",
  28031.        "HELV",           "helv",
  28032.        "TMS RMN",        "tms rmn",
  28033.        "MODERN",         "modern",
  28034.        "SCRIPT",         "script",
  28035.        "ROMAN",          "roman"
  28036.    };
  28037.    static unsigned char *face[NFONTS] =
  28038.    {
  28039.        "t'courier'",
  28040.        "t'helv'",
  28041.        "t'tms rmn'"
  28042.        "t'modern'"
  28043.        "t'script'"
  28044.        "t'roman'"
  28045.    };
  28046.    static unsigned char list[20];
  28047.    struct videoconfig vc;
  28048.    int mode = _VRES16COLOR;
  28049.    register i;
  28050.  
  28051.    /*  Read header info from all .FON files in
  28052.     *  current directory   */
  28053.  
  28054.    if(_registerfonts( "*.FON" )<0 )
  28055.    {
  28056.       _outtext("Error:  can't register fonts");
  28057.       exit( 0 );
  28058.    }
  28059.  
  28060.    /*   Set highest available video mode */
  28061.  
  28062.    while( !_setvideomode( mode ) )
  28063.       mode--;
  28064.    if( mode == _TEXTMONO )
  28065.       exit ( 0 );
  28066.  
  28067.    /*   Copy video configuration into structure vc */
  28068.  
  28069.    _getvideoconfig( &vc );
  28070.  
  28071.    /*   Display six lines of sample text */
  28072.  
  28073.    for( i = 0; i<NFONTS; i++ )
  28074.    {
  28075.       strcpy( list, face[i] );
  28076.       strcat( list, "h30w24b" );
  28077.  
  28078.       if( !_setfont( list ) )
  28079.       {
  28080.           _setcolor( i + 1 );
  28081.           _moveto( 0, (i * vc.numypixels) / NFONTS );
  28082.           _outgtext( text[i * 2] );
  28083.           _moveto( vc.numxpixels / 2,
  28084.                       (i * vc.numypixels) / NFONTS );
  28085.           _outgtext( text[(i * 2) + 1] );
  28086.       }
  28087.       else
  28088.       {
  28089.           _setvideomode( _DEFAULTMODE );
  28090.           _outtext( "Error:  can't set font" );
  28091.           exit( 0 );
  28092.       }
  28093.    }
  28094.    getch();
  28095.    _setvideomode( _DEFAULTMODE );
  28096.  
  28097.    /* Return memory when finished with fonts */
  28098.  
  28099.    _unregisterfonts();
  28100.    exit( 0 );
  28101.  }
  28102.  
  28103.  
  28104.  FUNCPTR.C
  28105.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\FUNCPTR.C
  28106.  
  28107.  /* FUNCPTR.C: Demonstrate function pointers. */
  28108.  
  28109.  #include <stdio.h>
  28110.  
  28111.  main()
  28112.  {
  28113.     int (*func_ptr) ();
  28114.     func_ptr = printf;
  28115.     (*func_ptr) ( "Curiouser and curiouser...\n" );
  28116.  }
  28117.  
  28118.  
  28119.  FUNCPTR1.C
  28120.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\FUNCPTR1.C
  28121.  
  28122.  /* FUNCPTR1.C: Passing function pointers as arguments.
  28123.  */
  28124.  
  28125.  #include <stdio.h>
  28126.  
  28127.  void gimme_func( void (*func_ptr) () );
  28128.  
  28129.  main()
  28130.  {
  28131.     gimme_func( puts );
  28132.     gimme_func( printf );
  28133.  }
  28134.  
  28135.  void gimme_func( void (*func_ptr) () )
  28136.  {
  28137.     (*func_ptr) ( "Ausgezeichnet!" );
  28138.  }
  28139.  
  28140.  
  28141.  FUNGET.C
  28142.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\FUNGET.C
  28143.  
  28144.  /* FUNGET.C illustrates getting and ungetting characters from a file.
  28145.   * Functions illustrated include:
  28146.   *      getc            getchar         ungetc
  28147.   *      fgetc           fgetchar
  28148.   *
  28149.   * Although getchar and fgetchar are not specifically used in the example,
  28150.   * they are equivalent to using getc or fgetc with stdin. See HEXDUMP.C
  28151.   * for another example of getc and fgetc.
  28152.   */
  28153.  
  28154.  #include <conio.h>
  28155.  #include <stdio.h>
  28156.  #include <ctype.h>
  28157.  #include <string.h>
  28158.  #include <stdlib.h>
  28159.  
  28160.  void getword( FILE *stream, char *buf );
  28161.  void skiptoword( FILE *stream );
  28162.  
  28163.  main()
  28164.  {
  28165.      char buffer[128];
  28166.      FILE *infile;
  28167.  
  28168.      printf( "Enter file name: " );
  28169.      gets( buffer );
  28170.      if( (infile = fopen( buffer, "rb" )) == NULL )
  28171.      {
  28172.          perror( "Can't open file" );
  28173.          exit( 1 );
  28174.      }
  28175.  
  28176.      /* Read each word and print reversed version. */
  28177.      while( 1 )
  28178.      {
  28179.          skiptoword( infile );
  28180.          getword( infile, buffer );
  28181.          puts( strrev( buffer ) );
  28182.      }
  28183.  }
  28184.  
  28185.  /* Read one word (defined as a string of alphanumeric characters). */
  28186.  void getword( FILE *stream, char *p )
  28187.  {
  28188.      int  ch;
  28189.  
  28190.      do
  28191.      {
  28192.          /* Macro version used here, but function version could be used:
  28193.          ch = fgetc( stream );
  28194.           */
  28195.          ch = getc( stream );        /* Get characters until EOF  */
  28196.          if( ch == EOF )             /*   or non-alphanumeric     */
  28197.              exit( 0 );
  28198.          *(p++) = (char)ch;
  28199.      } while( isalnum( ch ) );
  28200.      ungetc( ch, stream );           /* Put non-alphanumeric back */
  28201.      *(--p) = '\0';                  /* Null-terminate            */
  28202.  }
  28203.  
  28204.  /* Throw away non-digit characters. */
  28205.  void skiptoword( FILE *stream )
  28206.  {
  28207.      int  ch;
  28208.  
  28209.      do
  28210.      {
  28211.          ch = getc( stream );
  28212.          if( ch == EOF )
  28213.              exit( 0 );
  28214.      } while( !isalnum( ch ) );
  28215.      ungetc( ch, stream );
  28216.  }
  28217.  
  28218.  
  28219.  GETCH.C
  28220.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\GETCH.C
  28221.  
  28222.  /* GETCH.C illustrates how to process ASCII or extended keys.
  28223.   * Functions illustrated include:
  28224.   *      getch           getche
  28225.   */
  28226.  
  28227.  #include <conio.h>
  28228.  #include <ctype.h>
  28229.  #include <stdio.h>
  28230.  
  28231.  main()
  28232.  {
  28233.      int key;
  28234.  
  28235.      /* Read and display keys until ESC is pressed. */
  28236.      while( 1 )
  28237.      {
  28238.          /* If first key is 0, then get second extended. */
  28239.          if( !(key = getch()) )
  28240.          {
  28241.              key = getch();
  28242.              printf( "ASCII: no\tChar: NA\t" );
  28243.          }
  28244.  
  28245.          /* Otherwise there's only one key. */
  28246.          else
  28247.              printf( "ASCII: yes\tChar: %c \t", isgraph( key ) ? key : ' ' );
  28248.  
  28249.          printf( "Decimal: %d\tHex: %X\n", key, key );
  28250.  
  28251.          /* Echo character response to prompt. */
  28252.          if( key == 27)
  28253.          {
  28254.              printf( "Do you really want to quit? (Y/n) " );
  28255.              key = getche();
  28256.              printf( "\n" );
  28257.              if( (toupper( key ) == 'Y') || (key == 13) )
  28258.                  break;
  28259.          }
  28260.      }
  28261.  }
  28262.  
  28263.  
  28264.  GOODMAC.C
  28265.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\GOODMAC.C
  28266.  
  28267.  /* GOODMAC.C: Parentheses in macro arguments. */
  28268.  #include <stdio.h>
  28269.  
  28270.  #define FOURX(arg)  ( (arg) * 4 )
  28271.  
  28272.  main()
  28273.  {
  28274.     int val;
  28275.     val = FOURX( 2 + 3 );
  28276.     printf( "val = %d\n", val );
  28277.  }
  28278.  
  28279.  
  28280.  GOODSEMI.C
  28281.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\GOODSEMI.C
  28282.  
  28283.  /* GOODSEMI.C */
  28284.  
  28285.  #include <stdio.h>
  28286.  
  28287.  main()
  28288.  {
  28289.     int count;
  28290.     for( count = 0; count < 500; count++ )
  28291.     {
  28292.        printf( "count = %d\n", count );
  28293.        printf( "And the beat goes on...\n" );
  28294.     }
  28295.  }
  28296.  
  28297.  
  28298.  GRAPHIC.C
  28299.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\GRAPHIC.C
  28300.  
  28301.  /* GRAPHIC.C: Displays every graphics mode */
  28302.  
  28303.  #include <stdio.h>
  28304.  #include <graph.h>
  28305.  #include <conio.h>
  28306.  
  28307.  struct videoconfig screen;
  28308.  int modes[12] =
  28309.  {
  28310.     _MRES4COLOR, _MRESNOCOLOR, _HRESBW,
  28311.     _HERCMONO,
  28312.     _MRES16COLOR, _HRES16COLOR, _ERESNOCOLOR, _ERESCOLOR,
  28313.     _VRES2COLOR, _VRES16COLOR, _MRES256COLOR
  28314.  };
  28315.  
  28316.  void print_menu( void );
  28317.  void show_mode( char );
  28318.  
  28319.  main()
  28320.  {
  28321.     char key;
  28322.     print_menu();
  28323.     while( (key = getch()) != 'x' )
  28324.        show_mode( key );
  28325.  }
  28326.  
  28327.  void print_menu( void )
  28328.  {
  28329.     _setvideomode( _DEFAULTMODE );
  28330.     _clearscreen( _GCLEARSCREEN );
  28331.     printf( "Please choose a graphics mode\nType 'x' to exit.\n\n" );
  28332.     printf( "0 _MRES4COLOR\n1 _MRESNOCOLOR\n2 _HRESBW\n" );
  28333.     printf( "3 _HERCMONO\n4 _MRES16COLOR\n5 _HRES16COLOR\n" );
  28334.     printf( "6 _ERESNOCOLOR\n7 _ERESCOLOR\n" );
  28335.     printf( "8 _VRES2COLOR\n9 _VRES16COLOR\na _MRES256COLOR\n" );
  28336.  }
  28337.  
  28338.  void show_mode( char which )
  28339.  {
  28340.     int nc, i;
  28341.     int height, width;
  28342.     int mode = which;
  28343.  
  28344.     if( mode < '0' || mode > '9' )
  28345.        if( mode == 'a' )
  28346.           mode = '9' + 1;
  28347.        else if( mode == 'b' )
  28348.           mode = '9' + 2;
  28349.        else
  28350.           return;
  28351.  
  28352.     if( _setvideomode( modes[mode - '0'] ) )
  28353.     {
  28354.        _getvideoconfig( &screen );
  28355.        nc = screen.numcolors;
  28356.        width = screen.numxpixels/nc;
  28357.        height = screen.numypixels/2;
  28358.        for( i = 0; i < nc; i++ )
  28359.        {
  28360.           _setcolor( i );
  28361.           _rectangle( _GFILLINTERIOR, i * width, 0, (i + 1) * width, height );
  28362.        }
  28363.     }
  28364.     else
  28365.     {
  28366.        printf( " \nVideo mode %c is not available.\n", which);
  28367.        printf( "Please press a key.\n" );
  28368.     }
  28369.     getch();
  28370.     _setvideomode( _DEFAULTMODE );
  28371.     print_menu();
  28372.  }
  28373.  
  28374.  
  28375.  HALLOC.C
  28376.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MEMORY\HALLOC.C
  28377.  
  28378.  /* HALLOC.C illustrates dynamic allocation of huge memory using functions:
  28379.   *      halloc          hfree
  28380.   */
  28381.  
  28382.  #include <stdio.h>
  28383.  #include <malloc.h>
  28384.  #include <stdlib.h>
  28385.  
  28386.  main()
  28387.  {
  28388.      char huge *bigbuf, huge *p;
  28389.      long count = 100000L;
  28390.  
  28391.      /* Allocate huge buffer. */
  28392.      bigbuf = (char huge *)halloc( count, sizeof( char ) );
  28393.      if( bigbuf == NULL )
  28394.      {
  28395.          printf( "Insufficient memory" );
  28396.          exit( 1 );
  28397.      }
  28398.  
  28399.      /* Fill the buffer with characters. */
  28400.      for( p = bigbuf; count; count--, p++ )
  28401.          *p = (char)(count % 10) + '0';
  28402.  
  28403.      /* Free huge buffer. */
  28404.      hfree( bigbuf );
  28405.      exit( 0 );
  28406.  }
  28407.  
  28408.  
  28409.  HARDERR.C
  28410.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\HARDERR.C
  28411.  
  28412.  /* HARDERR.C illustrates handling of hardware errors using functions:
  28413.   *      _harderr            _hardresume         _hardretn
  28414.   */
  28415.  
  28416.  #include <stdio.h>
  28417.  #include <conio.h>
  28418.  #include <stdlib.h>
  28419.  #include <direct.h>
  28420.  #include <string.h>
  28421.  #include <dos.h>
  28422.  #include <bios.h>
  28423.  
  28424.  void far hardhandler( unsigned deverr, unsigned doserr, unsigned far *hdr );
  28425.  int _bios_str( char *p );
  28426.  
  28427.  main()
  28428.  {
  28429.      /* Install our hard error handler. */
  28430.      _harderr( hardhandler );
  28431.  
  28432.      /* Test it. */
  28433.      printf( "Make sure there is no disk in drive A:\n" );
  28434.      printf( "Press a key when ready...\n" );
  28435.      getch();
  28436.      if( mkdir( "a:\test" ) )
  28437.      {
  28438.          printf( "Failed" );
  28439.          exit( 1 );
  28440.      }
  28441.      else
  28442.      {
  28443.          printf( "Succeeded" );
  28444.          rmdir( "a:test" );
  28445.          exit( 0 );
  28446.      }
  28447.  }
  28448.  
  28449.  /* Handler to deal with hard error codes. Since DOS is not reentrant,
  28450.   * it is not safe use DOS calls to do I/O within the DOS Critical Error
  28451.   * Handler (int 24h) used by _harderr. Therefore, screen output and
  28452.   * keyboard input must be done through the BIOS.
  28453.   */
  28454.  void far hardhandler( unsigned deverr, unsigned doserr, unsigned far *hdr )
  28455.  {
  28456.      int ch;
  28457.      static char buf[200], tmpbuf[10];
  28458.  
  28459.      /* Copy message to buffer, then use BIOS to print it. */
  28460.      strcpy( buf, "\n\rDevice error code: " );
  28461.      strcat( buf, itoa( deverr, tmpbuf, 10 ) );
  28462.      strcat( buf, "\n\rDOS error code:    " );
  28463.      strcat( buf, itoa( doserr, tmpbuf, 10 ) );
  28464.      strcat( buf, "\n\r(R)etry, (F)ail, or (Q)uit? " );
  28465.  
  28466.      /* Use BIOS to write strings and get a key. */
  28467.      _bios_str( buf );
  28468.      ch = _bios_keybrd( _KEYBRD_READ ) & 0x00ff;
  28469.      _bios_str( "\n\r" );
  28470.  
  28471.      switch( ch )
  28472.      {
  28473.          case 'R':
  28474.          case 'r':       /* Try again */
  28475.          default:
  28476.              _hardresume( _HARDERR_RETRY );
  28477.          case 'F':
  28478.          case 'f':       /* Return to DOS with error code */
  28479.              _hardretn( doserr );
  28480.          case 'Q':
  28481.          case 'q':       /* Quit program */
  28482.              _hardresume( _HARDERR_ABORT );
  28483.  
  28484.      }
  28485.  }
  28486.  
  28487.  /* Display a string using BIOS interrupt 0x0e (Write TTY). Return length
  28488.   * of string displayed.
  28489.   */
  28490.  int _bios_str( char *p )
  28491.  {
  28492.      union REGS inregs, outregs;
  28493.      char *start = p;
  28494.  
  28495.      inregs.h.ah = 0x0e;
  28496.      for( ; *p; p++ )
  28497.      {
  28498.          inregs.h.al = *p;
  28499.          int86( 0x10, &inregs, &outregs );
  28500.      }
  28501.      return p - start;
  28502.  }
  28503.  
  28504.  
  28505.  HEAPWALK.C
  28506.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MEMORY\HEAPWALK.C
  28507.  
  28508.  /* HEAPWALK.C illustrates heap testing functions including:
  28509.   *      _heapchk        _fheapchk       _nheapchk
  28510.   *      _heapset        _fheapset       _nheapset
  28511.   *      _heapwalk       _fheapwalk      _nheapwalk
  28512.   *      _msize          _fmsize         _nmsize
  28513.   *
  28514.   * Only the model independent versions are shown. They map to the model
  28515.   * dependent versions, depending on the memory model.
  28516.   */
  28517.  
  28518.  #include <stdio.h>
  28519.  #include <conio.h>
  28520.  #include <malloc.h>
  28521.  #include <stdlib.h>
  28522.  #include <time.h>
  28523.  
  28524.  /* Macro to get a random integer within a specified range */
  28525.  #define getrandom( min, max ) ((rand() % (int)((max) - (min))) + (min) + 1)
  28526.  
  28527.  void heapdump( char fill );
  28528.  void heapstat( int status );
  28529.  
  28530.  main()
  28531.  {
  28532.      int *p[10], i;
  28533.  
  28534.      srand( (unsigned)time( 0L ) );  /* Seed with current time. */
  28535.  
  28536.      /* Check heap status. Should be OK at start of heap. */
  28537.      heapstat( _heapchk() );
  28538.  
  28539.      /* Now do some operations that affect the heap. In this example,
  28540.       * allocate random-size blocks.
  28541.       */
  28542.      for( i = 0; i < 10; i++ )
  28543.      {
  28544.          if( (p[i] = (int *)calloc( getrandom( 1, 10000 ),
  28545.                                     sizeof( int ) )) == NULL )
  28546.          {
  28547.              --i;
  28548.              break;
  28549.          }
  28550.          printf( "Allocated %u at %p\n", _msize( p[i] ), (void far *)p[i] );
  28551.      }
  28552.  
  28553.      /* Fill all free blocks with the test character. */
  28554.      heapstat( _heapset( 254 ) );
  28555.  
  28556.      /* In a real program, you might do operations here on the allocated
  28557.       * buffers. Then do heapdump to make sure none of the operations wrote
  28558.       * to free blocks.
  28559.       */
  28560.      heapdump( 254 );
  28561.  
  28562.      /* Do some more heap operations. */
  28563.      for( ; i >= 0; i-- )
  28564.      {
  28565.          free( p[i] );
  28566.          printf( "Deallocating %u at %p\n", _msize( p[i] ), (void far *)p[i] )
  28567.      }
  28568.  
  28569.      /* Check heap again. */
  28570.      heapdump( 254 );
  28571.  }
  28572.  
  28573.  /* Test routine to check each block in the heap. */
  28574.  void heapdump( char fill )
  28575.  {
  28576.      struct _heapinfo hi;
  28577.      int heapstatus, i;
  28578.      char far *p;
  28579.  
  28580.      /* Walk through entries, displaying results and checking free blocks. */
  28581.      printf( "\nHeap dump:\n" );
  28582.      hi._pentry = NULL;
  28583.      while( (heapstatus = _heapwalk( &hi )) == _HEAPOK )
  28584.      {
  28585.          printf( "\n\t%s block at %p of size %u\t",
  28586.                  hi._useflag == _USEDENTRY ? "USED" : "FREE",
  28587.                  hi._pentry, hi._size );
  28588.  
  28589.          /* For free entries, check each byte to see that it still has
  28590.           * only the fill character.
  28591.           */
  28592.          if( hi._useflag != _USEDENTRY )
  28593.          {
  28594.              for( p = (char far *)hi._pentry, i = 0; i < hi._size; p++, i++ )
  28595.                  if( (char)*p != fill )
  28596.                      break;
  28597.              if( i == hi._size )
  28598.                  printf( "Not changed" );
  28599.              else
  28600.                  printf( "Changed" );
  28601.          }
  28602.      }
  28603.      heapstat( heapstatus );
  28604.  }
  28605.  
  28606.  /* Report on the status returned by _heapwalk, _heapset, or _heapchk. */
  28607.  void heapstat( int status )
  28608.  {
  28609.      printf( "\nHeap status: " );
  28610.      switch( status )
  28611.      {
  28612.          case _HEAPOK:
  28613.              printf( "OK - heap is fine" );
  28614.              break;
  28615.          case _HEAPEMPTY:
  28616.              printf( "OK - empty heap" );
  28617.              break;
  28618.          case _HEAPEND:
  28619.              printf( "OK - end of heap" );
  28620.              break;
  28621.          case _HEAPBADPTR:
  28622.              printf( "ERROR - bad pointer to heap" );
  28623.              break;
  28624.          case _HEAPBADBEGIN:
  28625.              printf( "ERROR - bad start of heap" );
  28626.              break;
  28627.          case _HEAPBADNODE:
  28628.              printf( "ERROR - bad node in heap" );
  28629.              break;
  28630.      }
  28631.      printf( "\n\n" );
  28632.  }
  28633.  
  28634.  
  28635.  HEXDUMP1.C
  28636.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\HEXDUMP1.C
  28637.  
  28638.  /* HEXDUMP.C illustrates directory splitting and character stream I/O.
  28639.   * Functions illustrated include:
  28640.   *      _splitpath      _makepath
  28641.   *      fgetc           fputc           fgetchar        fputchar
  28642.   *      getc            putc            getchar         putchar
  28643.   *
  28644.   * While fgetchar, getchar, fputchar, and putchar are not specifically
  28645.   * used in the example, they are equivalent to using fgetc or getc with
  28646.   * stdin, or to using fputc or putc with stdout. See FUNGET.C for another
  28647.   * example of fgetc and getc.
  28648.   */
  28649.  
  28650.  #include <stdio.h>
  28651.  #include <conio.h>
  28652.  #include <io.h>
  28653.  #include <dos.h>
  28654.  #include <stdlib.h>
  28655.  #include <string.h>
  28656.  
  28657.  main()
  28658.  {
  28659.      FILE *infile, *outfile;
  28660.      char inpath[_MAX_PATH], outpath[_MAX_PATH];
  28661.      char drive[_MAX_DRIVE], dir[_MAX_DIR];
  28662.      char fname[_MAX_FNAME], ext[_MAX_EXT];
  28663.      int  in, size;
  28664.      long i = 0L;
  28665.  
  28666.      /* Query for and open input file. */
  28667.      printf( "Enter input file name: " );
  28668.      gets( inpath );
  28669.      strcpy( outpath, inpath );
  28670.      if( (infile = fopen( inpath, "rb" )) == NULL )
  28671.      {
  28672.          printf( "Can't open input file" );
  28673.          exit( 1 );
  28674.      }
  28675.  
  28676.      /* Build output file by splitting path and rebuilding with
  28677.       * new extension.
  28678.       */
  28679.      _splitpath( outpath, drive, dir, fname, ext );
  28680.      strcpy( ext, "hx" );
  28681.      _makepath( outpath, drive, dir, fname, ext );
  28682.  
  28683.      /* If file does not exist, open it */
  28684.      if( access( outpath, 0 ) )
  28685.      {
  28686.          outfile = fopen( outpath, "wb" );
  28687.          printf( "Creating %s from %s . . .\n", outpath, inpath );
  28688.      }
  28689.      else
  28690.      {
  28691.          printf( "Output file already exists" );
  28692.          exit( 1 );
  28693.      }
  28694.  
  28695.      printf( "(B)yte or (W)ord: " );
  28696.      size = getche();
  28697.  
  28698.      /* Get each character from input and write to output. */
  28699.      while( !feof( infile ) )
  28700.      {
  28701.          if( (size == 'W') || (size == 'w') )
  28702.          {
  28703.              in = getw( infile );
  28704.              fprintf( outfile, " %.4X", in );
  28705.              if( !(++i % 8) )
  28706.                  putw( 0x0D0A, outfile );        /* New line      */
  28707.          }
  28708.          else
  28709.          {
  28710.              /* This example uses the fgetc and fputc functions. You
  28711.               * could also use the macro versions:
  28712.              in = getc( infile );
  28713.               */
  28714.              in = fgetc( infile );
  28715.              fprintf( outfile, " %.2X", in );
  28716.              if( !(++i % 16) )
  28717.              {
  28718.                  /* Macro version:
  28719.                  putc( 13, outfile );
  28720.                   */
  28721.                  fputc( 13, outfile );           /* New line      */
  28722.                  fputc( 10, outfile );
  28723.              }
  28724.          }
  28725.      }
  28726.      fclose( infile );
  28727.      fclose( outfile );
  28728.      exit( 0 );
  28729.  }
  28730.  
  28731.  
  28732.  HORIZON.C
  28733.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\HORIZON.C
  28734.  
  28735.  /* HORIZON.C: VGA graphics with cycling of 256 colors */
  28736.  
  28737.  #include <stdio.h>
  28738.  #include <stdlib.h>
  28739.  #include <conio.h>
  28740.  #include <graph.h>
  28741.  
  28742.  #define RED 0x0000003FL
  28743.  #define GRN 0x00003F00L
  28744.  #define BLU 0x003F0000L
  28745.  #define WHT 0x003F3F3FL
  28746.  #define STEP 21
  28747.  
  28748.  struct videoconfig screen;
  28749.  long int rainbow[512];
  28750.  
  28751.  main()
  28752.  {
  28753.     int i;
  28754.     long int col, gray;
  28755.  
  28756.     if( _setvideomode( _MRES256COLOR ) == 0 )
  28757.     {
  28758.        printf("This program requires a VGA card.\n" );
  28759.        exit( 0 );
  28760.     }
  28761.     for( col = 0; col < 64; col++ )
  28762.     {
  28763.        gray = col | (col << 8) | (col << 16);
  28764.        rainbow[col] = rainbow[col + 256] = BLU & gray;
  28765.        rainbow[col + 64] = rainbow[col + 64 + 256] = BLU | gray;
  28766.        rainbow[col + 128] = rainbow[col + 128 + 256] = RED | (WHT & ~gray);
  28767.        rainbow[col + 192] = rainbow[col + 192 + 256] = RED & ~gray;
  28768.     }
  28769.     _setvieworg( 160, 85 );
  28770.  
  28771.     for( i = 0; i < 255; i++ )
  28772.     {
  28773.        _setcolor( 255 - i );
  28774.        _moveto( i, i - 255 );
  28775.        _lineto( -i, 255 - i );
  28776.        _moveto( -i, i - 255 );
  28777.        _lineto( i, 255 - i );
  28778.        _ellipse( _GBORDER, -i, -i / 2, i, i / 2 );
  28779.     }
  28780.     for( i = 0; !kbhit(); i += STEP, i %= 256 )
  28781.        _remapallpalette( &(rainbow[i]) );
  28782.  
  28783.     _setvideomode( _DEFAULTMODE );
  28784.  }
  28785.  
  28786.  
  28787.  IF1.C
  28788.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\IF1.C
  28789.  
  28790.  /* IF.C: Demonstrate if statement. */
  28791.  
  28792.  #include <stdio.h>
  28793.  #include <conio.h>
  28794.  #define  B_KEY  'b'
  28795.  
  28796.  main()
  28797.  {
  28798.     char ch;
  28799.     printf( "Press the b key to hear a bell.\n" );
  28800.     ch = getche();
  28801.     if( ch == B_KEY )
  28802.        printf( "Beep!\a\n" );
  28803.  }
  28804.  
  28805.  
  28806.  INCMAC.C
  28807.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\INCMAC.C
  28808.  
  28809.  /* INCMAC.C: Increment operator in macro argument.
  28810.  */
  28811.  
  28812.  #include <stdio.h>
  28813.  #define ABS(value)  ( (value) >= 0 ? (value) : -(value) )
  28814.  
  28815.  main()
  28816.  {
  28817.     static int array[4] = {3, -20, -555, 6};
  28818.     int *ptr = array;
  28819.     int val, count;
  28820.     for( count = 0; count < 4; count++ )
  28821.     {
  28822.        val = ABS(*ptr++); /* Error! */
  28823.        printf( "abs of array[%d] = %d\n", count, val );
  28824.     }
  28825.  }
  28826.  
  28827.  
  28828.  INCMAC1.C
  28829.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\INCMAC1.C
  28830.  
  28831.  /* INCMAC1.C: Increment operator in the for statement.
  28832.  */
  28833.  
  28834.  #include <stdio.h>
  28835.  #define ABS(value)  ( (value) >= 0 ? (value) : -(value) )
  28836.  
  28837.  main()
  28838.  {
  28839.     static int array[4] = {3, -20, -555, 6};
  28840.     int *ptr = array;
  28841.     int val, count;
  28842.     for( count = 0; count < 4; count++, ptr++ )
  28843.     {
  28844.        val = ABS(*ptr);
  28845.        printf( "abs of array[%d] = %d\n", count, val );
  28846.     }
  28847.  }
  28848.  
  28849.  
  28850.  INTMATH.C
  28851.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MATH\INTMATH.C
  28852.  
  28853.  /* INTMATH.C illustrates integer math functions including:
  28854.   *      abs         labs        min         max         div         ldiv
  28855.   *
  28856.   * See MATH.C for an example of the similar fabs function.
  28857.   */
  28858.  
  28859.  #include <stdlib.h>
  28860.  #include <stdio.h>
  28861.  #include <math.h>
  28862.  
  28863.  main()
  28864.  {
  28865.      int x, y;
  28866.      long lx, ly;
  28867.      div_t divres;
  28868.      ldiv_t ldivres;
  28869.  
  28870.      printf( "Enter two integers: " );
  28871.      scanf( "%d %d", &x, &y );
  28872.  
  28873.      printf("Function\tResult\n\n" );
  28874.      printf( "abs\t\tThe absolute value of %d is %d\n", x, abs( x ) );
  28875.      printf( "min\t\tThe lesser of %d and %d is %d\n", x, y, min( x, y ) );
  28876.      printf( "max\t\tThe greater of %d and %d is %d\n", x, y, max( x, y ) );
  28877.      divres = div( x, y );
  28878.      printf( "div\t\tFor %d / %d, quotient is %d and remainder is %d\n\n",
  28879.              x, y, divres.quot, divres.rem );
  28880.  
  28881.      printf( "Enter two long integers: " );
  28882.      scanf( "%ld %ld", &lx, &ly );
  28883.  
  28884.      printf("Function\tResult\n\n" );
  28885.      ldivres = ldiv( lx, ly );
  28886.      printf( "labs\t\tThe absolute value of %ld is %ld\n", lx, labs( lx ) );
  28887.      printf( "ldiv\t\tFor %ld / %ld, quotient is %ld and remainder is %ld\n",
  28888.              lx, ly, ldivres.quot, ldivres.rem );
  28889.  }
  28890.  
  28891.  
  28892.  IS.C
  28893.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\IS.C
  28894.  
  28895.  /* IS.C illustrates character classification functions including:
  28896.   *      isprint         isascii         isalpha         isalnum
  28897.   *      isupper         islower         isdigit         isxdigit
  28898.   *      ispunct         isspace         iscntrl         isgraph
  28899.   *
  28900.   * Console output is also shown using:
  28901.   *      cprintf
  28902.   *
  28903.   * See PRINTF.C for additional examples of formatting for cprintf.
  28904.   */
  28905.  
  28906.  #include <ctype.h>
  28907.  #include <conio.h>
  28908.  
  28909.  main()
  28910.  {
  28911.      int ch;
  28912.  
  28913.      /* Display each ASCII character with character type table. */
  28914.      for( ch = 0; ch < 256; ch++ )
  28915.      {
  28916.          if( ch % 22 == 0 )
  28917.          {
  28918.              if( ch )
  28919.                  getch();
  28920.  
  28921.              /* Note that cprintf does not convert "\n" to a CR/LF sequence.
  28922.               * You can specify this sequence with "\n\r".
  28923.               */
  28924.              cprintf( "\n\rNum Char ASCII Alpha AlNum Cap Low Digit " );
  28925.              cprintf( "XDigit Punct White CTRL Graph Print \n\r" );
  28926.          }
  28927.          cprintf( "%3d  ", ch );
  28928.  
  28929.          /* Console output functions (cprint, cputs, and putch) display
  28930.           * graphic characters for all values except 7 (bell), 8 (backspace),
  28931.           * 10 (line feed), 13 (carriage return), and 255.
  28932.           */
  28933.          if( ch == 7 || ch == 8 || ch == 10 || ch == 13 || ch == 255 )
  28934.              cprintf("NV" );
  28935.          else
  28936.              cprintf("%c ", ch );
  28937.          cprintf( "%5s", isascii( ch )  ? "Y" : "N" );
  28938.          cprintf( "%6s", isalpha( ch )  ? "Y" : "N" );
  28939.          cprintf( "%6s", isalnum( ch )  ? "Y" : "N" );
  28940.          cprintf( "%5s", isupper( ch )  ? "Y" : "N" );
  28941.          cprintf( "%4s", islower( ch )  ? "Y" : "N" );
  28942.          cprintf( "%5s", isdigit( ch )  ? "Y" : "N" );
  28943.          cprintf( "%7s", isxdigit( ch ) ? "Y" : "N" );
  28944.          cprintf( "%6s", ispunct( ch )  ? "Y" : "N" );
  28945.          cprintf( "%6s", isspace( ch )  ? "Y" : "N" );
  28946.          cprintf( "%5s", iscntrl( ch )  ? "Y" : "N" );
  28947.          cprintf( "%6s", isprint( ch )  ? "Y" : "N" );
  28948.          cprintf( "%6s\n\r", isgraph( ch )  ? "Y" : "N" );
  28949.      }
  28950.  }
  28951.  
  28952.  
  28953.  KBHIT.C
  28954.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\KBHIT.C
  28955.  
  28956.  /* KBHIT.C illustrates:
  28957.   *      kbhit
  28958.   */
  28959.  
  28960.  #include <conio.h>
  28961.  
  28962.  main()
  28963.  {
  28964.      /* Display message until key is pressed. Use getch to throw key away. */
  28965.      while( !kbhit() )
  28966.          cputs( "Hit me!! " );
  28967.      getch();
  28968.  }
  28969.  
  28970.  
  28971.  KEYBRD.C
  28972.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\UTILITY\KEYBRD.C
  28973.  
  28974.  /* KEYBRD.C illustrates:
  28975.   *      _bios_keybrd
  28976.   */
  28977.  
  28978.  #include <bios.h>
  28979.  #include <stdio.h>
  28980.  #include <ctype.h>
  28981.  
  28982.  main()
  28983.  {
  28984.      unsigned key, shift;
  28985.      unsigned char scan, ascii = 0;
  28986.  
  28987.      /* Read and display keys until ESC is pressed. */
  28988.      while( ascii != 27 )
  28989.      {
  28990.          /* Drain any keys in the keyboard type-ahead buffer, then get
  28991.           * the current key. If you want the last key typed rather than
  28992.           * the key currently being typed, omit the initial loop.
  28993.           */
  28994.          while( _bios_keybrd( _KEYBRD_READY ) )
  28995.              _bios_keybrd( _KEYBRD_READ );
  28996.          key = _bios_keybrd( _KEYBRD_READ );
  28997.  
  28998.          /* Get shift state. */
  28999.          shift = _bios_keybrd( _KEYBRD_SHIFTSTATUS );
  29000.  
  29001.          /* Split key into scan and ascii parts. */
  29002.          scan = key >> 8;
  29003.          ascii = key & 0x00ff;
  29004.  
  29005.          /* Categorize key. */
  29006.          if( ascii )
  29007.              printf( "ASCII: yes\tChar: %c \t",
  29008.                      isgraph( ascii ) ? ascii : ' ' );
  29009.          else
  29010.              printf( "ASCII: no\tChar: NA\t" );
  29011.          printf( "Code: %.2X\tScan: %.2X\t Shift: %.2X\n",
  29012.                  ascii, scan, shift );
  29013.      }
  29014.  }
  29015.  
  29016.  
  29017.  LOCK.C
  29018.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\LOCK.C
  29019.  
  29020.  /* LOCK.C illustrates network file sharing functions:
  29021.   *      sopen       locking
  29022.   *
  29023.   * Also the global variable:
  29024.   *      _osmajor
  29025.   *
  29026.   * The program requires DOS 3.0 or higher. The DOS SHARE command must
  29027.   * be loaded. The locking mechanism will only work if the program is
  29028.   * run from a network drive.
  29029.   */
  29030.  
  29031.  #include <stdio.h>
  29032.  #include <conio.h>
  29033.  #include <io.h>
  29034.  #include <fcntl.h>
  29035.  #include <sys\types.h>
  29036.  #include <sys\stat.h>
  29037.  #include <sys\locking.h>
  29038.  #include <share.h>
  29039.  <stdlib.h>         /* For _osmajor and exit */
  29040.  
  29041.  void error( char *msg );
  29042.  
  29043.  main( int argc, char *argv[] )
  29044.  {
  29045.      int handle, i;
  29046.      static char msg[] = "Are any of these bytes locked?";
  29047.      char buf[1];
  29048.  
  29049.      /* Check for DOS version >= 3.0 */
  29050.      if( _osmajor < 3 )
  29051.          error( "Must be DOS 3.0 or higher" );
  29052.  
  29053.      /* If no argument, write file and lock some bytes in it. */
  29054.      if( argc == 1 )
  29055.      {
  29056.          /* Open file with deny none sharing. */
  29057.          handle = sopen( "tmpfil", O_BINARY | O_RDWR | O_CREAT,
  29058.                                    SH_DENYNO, S_IREAD | S_IWRITE );
  29059.          if( handle == -1 )
  29060.              error( "Can't open file\n" );
  29061.  
  29062.          write( handle, msg, sizeof( msg ) - 1 );
  29063.  
  29064.          /* Lock 10 bytes starting at byte 10. */
  29065.          lseek( handle, 10L, SEEK_SET );
  29066.          if( locking( handle, LK_LOCK, 10L ) )
  29067.              error( "Locking failed\n" );
  29068.          printf( "Locked 10 bytes starting at byte 10\n" );
  29069.  
  29070.          system( "LOCK read" );
  29071.          getch();
  29072.  
  29073.          /* Unlock. */
  29074.          lseek( handle, 10L, SEEK_SET );
  29075.          locking( handle, LK_UNLCK, 10L );
  29076.          printf( "\nUnlocked 10 bytes starting at byte 10\n" );
  29077.  
  29078.          system( "LOCK read" );
  29079.          getch();
  29080.      }
  29081.  
  29082.      /* If argument, Try to read some locked bytes. */
  29083.      else
  29084.      {
  29085.          /* Open file with deny none sharing. */
  29086.          handle = sopen( "tmpfil", O_BINARY | O_RDWR,
  29087.                                    SH_DENYNO, S_IREAD | S_IWRITE );
  29088.          if( handle == -1 )
  29089.              error( "Can't open file\n" );
  29090.  
  29091.          for( i = 0; i < sizeof( msg ) - 1; i++ )
  29092.          {
  29093.              /* Print characters until locked bytes are reached. */
  29094.              if( read( handle, buf, 1 ) == -1 )
  29095.                  break;
  29096.              else
  29097.                  putchar( *buf );
  29098.          }
  29099.      }
  29100.      close( handle );
  29101.      exit( 0 );
  29102.  }
  29103.  
  29104.  void error( char *errmsg )
  29105.  {
  29106.      printf( errmsg );
  29107.      exit( 1 );
  29108.  }
  29109.  
  29110.  
  29111.  MATH.C
  29112.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MATH\MATH.C
  29113.  
  29114.  /* MATH.C illustrates floating point math functions including:
  29115.   *      exp             pow             sqrt            frexp
  29116.   *      log             log10           ldexp           modf
  29117.   *      ceil            floor           fabs            fmod
  29118.   */
  29119.  
  29120.  #include <math.h>
  29121.  #include <float.h>
  29122.  #include <stdio.h>
  29123.  #include <stdlib.h>
  29124.  
  29125.  main()
  29126.  {
  29127.      double x, rx, y;
  29128.      int n;
  29129.  
  29130.      printf( "\nEnter a real number: " );
  29131.      scanf( "%lf", &x );
  29132.  
  29133.      printf( "Mantissa: %2.2lf\tExponent: %d\n", frexp( x, &n ), n );
  29134.      printf( "Fraction: %2.2lf\tInteger: %lf\n", modf( x, &y ), y );
  29135.  
  29136.      printf("\nFunction\tResult for %2.2f\n\n", x );
  29137.      if( (rx = exp( x )) && (errno != ERANGE) )
  29138.          printf( "exp\t\t%2.2f\n", rx );
  29139.      else
  29140.          errno = 0;
  29141.      if( x > 0.0 )
  29142.          printf( "log\t\t%2.2f\n", log( x ) );
  29143.      if( x > 0.0 )
  29144.          printf( "log10\t\t%2.2f\n", log10( x ) );
  29145.      if( x >= 0.0 )
  29146.          printf( "sqrt\t\t%2.2f\n", sqrt( x ) );
  29147.      printf( "ceil\t\t%2.2f\n", ceil( x ) );
  29148.      printf( "floor\t\t%2.2f\n", floor( x ) );
  29149.      printf( "fabs\t\t%2.2f\n", fabs( x ) );
  29150.  
  29151.      printf( "\nEnter another real number: " );
  29152.      scanf( "%lf", &y );
  29153.      printf("\nFunction\tResult for %2.2f and %2.2f\n\n", x, y );
  29154.      printf( "fmod\t\t%2.2f\n", fmod( x, y ) );
  29155.      rx = pow( x, y );
  29156.      if( (errno != ERANGE) && (errno != EDOM) )
  29157.          printf( "pow\t\t%2.2f\n", rx );
  29158.      else
  29159.          errno = 0;
  29160.      rx = hypot( x, y );
  29161.      if( errno != ERANGE )
  29162.          printf( "hypot\t\t%2.2f\n", hypot( x, y ) );
  29163.      else
  29164.          errno = 0;
  29165.  
  29166.      printf( "\nEnter an integer exponent: " );
  29167.      scanf( "%d", &n );
  29168.      rx = ldexp( x, n );
  29169.      if( errno != ERANGE )
  29170.      {
  29171.          printf("\nFunction\tResult for %2.2f to power %d\n\n", x, n );
  29172.          printf( "ldexp\t\t%2.2f\n", ldexp( x, n ) );
  29173.      }
  29174.  }
  29175.  
  29176.  
  29177.  MATHERR.C
  29178.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MATH\MATHERR.C
  29179.  
  29180.  /* MATHERR.C illustrates writing an error routine for math functions.
  29181.   * The error function must be:
  29182.   *      matherr
  29183.   *
  29184.   * To use matherr, you must turn off the Extended Dictionary flag within
  29185.   * the QC environment (Options-Make-Linker Flags) or use the /NOE linker
  29186.   * option outside the environment. For example:
  29187.   *      QCL matherr.c /link /NOE
  29188.   */
  29189.  
  29190.  #include <math.h>
  29191.  #include <string.h>
  29192.  #include <stdio.h>
  29193.  
  29194.  main()
  29195.  {
  29196.      /* Do several math operations that cause errors. The matherr
  29197.       * routine handles DOMAIN errors, but lets the system handle
  29198.       * other errors normally.
  29199.       */
  29200.      printf( "log( -2.0 ) = %e\n", log( -2.0 ) );
  29201.      printf( "log10( -5.0 ) = %e\n", log10( -5.0 ) );
  29202.      printf( "log( 0.0 ) = %e\n", log( 0.0 ) );
  29203.  }
  29204.  
  29205.  /* Routine to handle several math errors caused by passing a negative
  29206.   * argument to log or log10 (DOMAIN errors). If this happens, matherr
  29207.   * returns the natural or base-10 logarithm of the absolute value of
  29208.   * the argument and suppresses the usual error message.
  29209.   */
  29210.  int matherr( struct exception *except )
  29211.  {
  29212.      /* Handle DOMAIN errors for log or log10. */
  29213.      if( except->type == DOMAIN )
  29214.      {
  29215.          if( strcmp( except->name, "log" ) == 0 )
  29216.          {
  29217.              except->retval = log( -(except->arg1) );
  29218.              printf( "Special: using absolute value: %s: DOMAIN error\n",
  29219.                      except->name );
  29220.              return 1;
  29221.          }
  29222.          else if( strcmp( except->name, "log10" ) == 0 )
  29223.          {
  29224.              except->retval = log10( -(except->arg1) );
  29225.              printf( "Special: using absolute value: %s: DOMAIN error\n",
  29226.                      except->name );
  29227.              return 1;
  29228.          }
  29229.      }
  29230.      else
  29231.      {
  29232.          printf( "Normal: " );
  29233.          return 0;    /* Else use the default actions */
  29234.      }
  29235.  }
  29236.  
  29237.  
  29238.  MENU.C
  29239.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\UTILITY\MENU.C
  29240.  
  29241.  /* MENU - Module of functions to put menus on the screen and handle keyboard
  29242.   * input. To use it, include the MENU.H file in your program. The following
  29243.   * functions are public:
  29244.   *
  29245.   *   Menu       -   Puts a menu on screen and reads input for it
  29246.   *   Box        -   Puts a box on screen (fill it yourself)
  29247.   *   GetKey     -   Gets ASCII or function key
  29248.   *   _outchar   -   Displays character using current text position and color
  29249.   *
  29250.   * The following structures are defined:
  29251.   *
  29252.   *   MENU       -   Defines menu colors, box type, and centering
  29253.   *   ITEM       -   Defines text of menu item and index of highlight characte
  29254.   *
  29255.   * The global variable "mnuAtrib" has type MENU. Change this variable to
  29256.   * change menu appearance.
  29257.   */
  29258.  
  29259.  #include <string.h>
  29260.  #include <stddef.h>
  29261.  #include <ctype.h>
  29262.  #include <graph.h>
  29263.  #include <bios.h>
  29264.  #include "menu.h"
  29265.  
  29266.  /* Default menu attribute. The default works for color or B&W. You can
  29267.   * override the default value by defining your own MENU variable and
  29268.   * assigning it to mnuAtrib. Or you can modify specific fields at
  29269.   * run time. For example, you could use a different attribute for color
  29270.   * than for black and white.
  29271.   */
  29272.  struct MENU mnuAtrib =
  29273.  {
  29274.      _TBLACK, _TBLACK, _TWHITE, _TBRIGHTWHITE, _TBRIGHTWHITE,
  29275.      _TWHITE, _TWHITE, _TBLACK, _TWHITE, _TBLACK,
  29276.      TRUE,
  29277.      '┌', '┐', '┘', '└', '│', '─'
  29278.  };
  29279.  
  29280.  /* Menu - Puts menu on screen and reads menu input from keyboard. When a
  29281.   * highlighted hot key or ENTER is pressed, returns the index of the
  29282.   * selected menu item.
  29283.   *
  29284.   * Params: row and col - If "fCentered" attribute of "mnuAtrib" is true,
  29285.   *           center row and column of menu; otherwise top left of menu
  29286.   *         aItem - array of structure containing the text of each item
  29287.   *           and the index of the highlighted hot key
  29288.   *         iCur - index of the current selection--pass 0 for first item,
  29289.   *           or maintain a static value
  29290.   *
  29291.   * Return: The index of the selected item
  29292.   *
  29293.   * Uses:   mnuAtrib
  29294.   */
  29295.  int Menu( int row, int col, struct ITEM aItem[], int iCur )
  29296.  {
  29297.      int cItem, cchItem = 2; /* Counts of items and chars per item       */
  29298.      int i, iPrev;           /* Indexes - temporary and previous         */
  29299.      int acchItem[MAXITEM];  /* Array of counts of character in items    */
  29300.      char *pchT;             /* Temporary character pointer              */
  29301.      char achHilite[36];     /* Array for highlight characters           */
  29302.      unsigned uKey;          /* Unsigned key code                        */
  29303.      long bgColor;           /* Screen color, position, and cursor       */
  29304.      short fgColor;
  29305.      struct rccoord rc;
  29306.      unsigned fCursor;
  29307.  
  29308.      /* Save screen information. */
  29309.      fCursor = _displaycursor( _GCURSOROFF );
  29310.      bgColor = _getbkcolor();
  29311.      fgColor = _gettextcolor();
  29312.      rc = _gettextposition();
  29313.  
  29314.      /* Count items, find longest, and put count of each in array. Also,
  29315.       * put the highlighted character from each in a string.
  29316.       */
  29317.      for( cItem = 0; aItem[cItem].achItem[0]; cItem++ )
  29318.      {
  29319.          acchItem[cItem] = strlen( aItem[cItem].achItem );
  29320.          cchItem = (acchItem[cItem] > cchItem) ? acchItem[cItem] : cchItem;
  29321.          i = aItem[cItem].iHilite;
  29322.          achHilite[cItem] = aItem[cItem].achItem[i];
  29323.      }
  29324.      cchItem += 2;
  29325.      achHilite[cItem] = 0;          /* Null-terminate and lowercase string  */
  29326.      strlwr( achHilite );
  29327.  
  29328.      /* Adjust if centered, and draw menu box. */
  29329.      if( mnuAtrib.fCentered )
  29330.      {
  29331.          row -= cItem / 2;
  29332.          col -= cchItem / 2;
  29333.      }
  29334.      Box( row++, col++, cItem, cchItem );
  29335.  
  29336.      /* Put items on menu. */
  29337.      for( i = 0; i < cItem; i++ )
  29338.      {
  29339.          if( i == iCur )
  29340.              Itemize( row + i, col, TRUE, aItem[i], cchItem - acchItem[i] );
  29341.          else
  29342.              Itemize( row + i, col, FALSE, aItem[i], cchItem - acchItem[i] );
  29343.      }
  29344.  
  29345.      while( TRUE )
  29346.      {
  29347.          /* Wait until a uKey is pressed, then evaluate it. */
  29348.          uKey = GetKey( WAIT );
  29349.          switch( uKey )
  29350.          {
  29351.              case U_UP:                      /* Up key       */
  29352.                  iPrev = iCur;
  29353.                  iCur = (iCur > 0) ? (--iCur % cItem) : cItem - 1;
  29354.                  break;
  29355.              case U_DN:                      /* Down key     */
  29356.                  iPrev = iCur;
  29357.                  iCur = (iCur < cItem) ? (++iCur % cItem) : 0;
  29358.                  break;
  29359.              default:
  29360.                  if( uKey > 256 )             /* Ignore unknown function key
  29361.                      continue;
  29362.                  pchT = strchr( achHilite, (char)tolower( uKey ) );
  29363.                  if( pchT != NULL )          /* If in highlight string,      *
  29364.                      iCur = pchT - achHilite;/*   evaluate and fall through  *
  29365.                  else
  29366.                      continue;               /* Ignore unkown ASCII key      *
  29367.              case ENTER:
  29368.                  _setbkcolor( bgColor );
  29369.                  _settextcolor( fgColor );
  29370.                  _settextposition( rc.row, rc.col );
  29371.                  _displaycursor( fCursor );
  29372.                  return iCur;
  29373.          }
  29374.          /* Redisplay current and previous. */
  29375.          Itemize( row + iCur, col, TRUE, aItem[iCur], cchItem - acchItem[iCur]
  29376.          Itemize( row + iPrev, col, FALSE, aItem[iPrev], cchItem - acchItem[iP
  29377.      }
  29378.  }
  29379.  
  29380.  /* Box - Draw menu box, filling interior with blanks of the border color.
  29381.   *
  29382.   * Params: row and col - upper left of box
  29383.   *         rowLast and colLast - height and width
  29384.   *
  29385.   * Return: None
  29386.   *
  29387.   * Uses:   mnuAtrib
  29388.   */
  29389.  void Box( int row, int col, int rowLast, int colLast )
  29390.  {
  29391.      int i;
  29392.      char achT[MAXITEM + 2];         /* Temporary array of characters */
  29393.  
  29394.      /* Set color and position. */
  29395.      _settextposition( row, col );
  29396.      _settextcolor( mnuAtrib.fgBorder );
  29397.      _setbkcolor( mnuAtrib.bgBorder );
  29398.  
  29399.      /* Draw box top. */
  29400.      achT[0] = mnuAtrib.chNW;
  29401.      memset( achT + 1, mnuAtrib.chEW, colLast );
  29402.      achT[colLast + 1] = mnuAtrib.chNE;
  29403.      achT[colLast + 2] = 0;
  29404.      _outtext( achT );
  29405.  
  29406.      /* Draw box sides and center. */
  29407.      achT[0] = mnuAtrib.chNS;
  29408.      memset( achT + 1, ' ', colLast );
  29409.      achT[colLast + 1] = mnuAtrib.chNS;
  29410.      achT[colLast + 2] = 0;
  29411.      for( i = 1; i <= rowLast; ++i )
  29412.      {
  29413.          _settextposition( row + i, col );
  29414.          _outtext( achT );
  29415.      }
  29416.  
  29417.      /* Draw box bottom. */
  29418.      _settextposition( row + rowLast + 1, col );
  29419.      achT[0] = mnuAtrib.chSW;
  29420.      memset( achT + 1, mnuAtrib.chEW, colLast );
  29421.      achT[colLast + 1] = mnuAtrib.chSE;
  29422.      achT[colLast + 2] = 0;
  29423.      _outtext( achT );
  29424.  }
  29425.  
  29426.  /* Itemize - Display one (item) selection of a menu. This function
  29427.   * is normally only used internally by Menu.
  29428.   *
  29429.   * Params: row and col - top left of menu
  29430.   *         fCur - flag set if item is current selection
  29431.   *         itm - structure containing item text and index of highlight
  29432.   *         cBlank - count of blanks to fill
  29433.   *
  29434.   * Return: none
  29435.   *
  29436.   * Uses:   mnuAtrib
  29437.   */
  29438.  void Itemize( int row, int col, int fCur, struct ITEM itm, int cBlank )
  29439.  {
  29440.      int i;
  29441.      char achT[MAXITEM];             /* Temporary array of characters */
  29442.  
  29443.      /* Set text position and color. */
  29444.      _settextposition( row, col );
  29445.      if( fCur )
  29446.      {
  29447.          _settextcolor( mnuAtrib.fgSelect );
  29448.          _setbkcolor( mnuAtrib.bgSelect );
  29449.      }
  29450.      else
  29451.      {
  29452.          _settextcolor( mnuAtrib.fgNormal );
  29453.          _setbkcolor( mnuAtrib.bgNormal );
  29454.      }
  29455.  
  29456.      /* Display item and fill blanks. */
  29457.      strcat( strcpy( achT, " " ), itm.achItem );
  29458.      _outtext( achT );
  29459.      memset( achT, ' ', cBlank-- );
  29460.      achT[cBlank] = 0;
  29461.      _outtext( achT );
  29462.  
  29463.      /* Set position and color of highlight character, then display it. */
  29464.      i = itm.iHilite;
  29465.      _settextposition( row, col + i + 1 );
  29466.      if( fCur )
  29467.      {
  29468.          _settextcolor( mnuAtrib.fgSelHilite );
  29469.          _setbkcolor( mnuAtrib.bgSelHilite );
  29470.      }
  29471.      else
  29472.      {
  29473.          _settextcolor( mnuAtrib.fgNormHilite );
  29474.          _setbkcolor( mnuAtrib.bgNormHilite );
  29475.      }
  29476.      _outchar( itm.achItem[i] );
  29477.  }
  29478.  
  29479.  /* GetKey - Gets a key from the keyboard. This routine distinguishes
  29480.   * between ASCII keys and function or control keys with different shift
  29481.   * states. It also accepts a flag to return immediately if no key is
  29482.   * available.
  29483.   *
  29484.   * Params: fWait - Code to indicate how to handle keyboard buffer:
  29485.   *   NO_WAIT     Return 0 if no key in buffer, else return key
  29486.   *   WAIT        Return first key if available, else wait for key
  29487.   *   CLEAR_WAIT  Throw away any key in buffer and wait for new key
  29488.   *
  29489.   * Return: One of the following:
  29490.   *
  29491.   *   Keytype                                High Byte    Low Byte
  29492.   *   -------                                ---------    --------
  29493.   *   No key available (only with NO_WAIT)       0           0
  29494.   *   ASCII value                                0        ASCII code
  29495.   *   Unshifted function or keypad               1        scan code
  29496.   *   Shifted function or keypad                 2        scan code
  29497.   *   CTRL function or keypad                    3        scan code
  29498.   *   ALT function or keypad                     4        scan code
  29499.   *
  29500.   * Note:   getkey cannot return codes for keys not recognized by BIOS
  29501.   *         int 16, such as the CTRL-UP or the 5 key on the numeric keypad.
  29502.   */
  29503.  unsigned GetKey( int fWait )
  29504.  {
  29505.      unsigned uKey, uShift;
  29506.  
  29507.      /* If CLEAR_WAIT, drain the keyboard buffer. */
  29508.      if( fWait == CLEAR_WAIT )
  29509.          while( _bios_keybrd( _KEYBRD_READY ) )
  29510.              _bios_keybrd( _KEYBRD_READ );
  29511.  
  29512.      /* If NO_WAIT, return 0 if there is no key ready. */
  29513.      if( !fWait && !_bios_keybrd( _KEYBRD_READY ) )
  29514.          return FALSE;
  29515.  
  29516.      /* Get key code. */
  29517.      uKey = _bios_keybrd( _KEYBRD_READ );
  29518.  
  29519.      /* If low byte is not zero, its an ASCII key. Check scan code to see
  29520.       * if it's on the numeric keypad. If not, clear high byte and return.
  29521.       */
  29522.      if( uKey & 0x00ff )
  29523.          if( (uKey >> 8) < 69 )
  29524.              return( uKey & 0x00ff );
  29525.  
  29526.      /* For function keys and numeric keypad, put scan code in low byte
  29527.       * and shift state codes in high byte.
  29528.       */
  29529.      uKey >>= 8;
  29530.      uShift = _bios_keybrd( _KEYBRD_SHIFTSTATUS ) & 0x000f;
  29531.      switch( uShift )
  29532.      {
  29533.          case 0:
  29534.              return( 0x0100 | uKey );  /* None (1)    */
  29535.          case 1:
  29536.          case 2:
  29537.          case 3:
  29538.              return( 0x0200 | uKey );  /* Shift (2)   */
  29539.          case 4:
  29540.              return( 0x0300 | uKey );  /* Control (3) */
  29541.          case 8:
  29542.              return( 0x0400 | uKey );  /* Alt (4)     */
  29543.      }
  29544.  }
  29545.  
  29546.  /* _outchar - Display a character. This is the character equivalent of
  29547.   * _outtext. It is affected by _settextposition, _settextcolor, and
  29548.   * _setbkcolor. It should not be used in loops. Build strings and then
  29549.   * _outtext to show multiple characters.
  29550.   *
  29551.   * Params: out - character to be displayed
  29552.   *
  29553.   * Return: none
  29554.   */
  29555.  void _outchar( char out )
  29556.  {
  29557.      static char achT[2] = " ";      /* Temporary array of characters */
  29558.  
  29559.      achT[0] = out;
  29560.      _outtext( achT );
  29561.  }
  29562.  
  29563.  
  29564.  MKFPSTR.C
  29565.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\MKFPSTR.C
  29566.  
  29567.  /* MKFPSTR.C illustrates building and displaying floating point strings
  29568.   * without printf. Functions illustrated include:
  29569.   *      strcat          strncat         cscanf          fcvt
  29570.   */
  29571.  
  29572.  #include <stdlib.h>
  29573.  #include <conio.h>
  29574.  #include <string.h>
  29575.  
  29576.  main()
  29577.  {
  29578.      int decimal, sign;
  29579.      int precision = 7;
  29580.      static char numbuf[50] = "";
  29581.      char *pnumstr, tmpbuf[50];
  29582.      double number1, number2;
  29583.  
  29584.      cputs( "Enter two floating point numbers: " );
  29585.      cscanf( "%lf %lf", &number1, &number2 );
  29586.      putch( '\n' );
  29587.  
  29588.      /* Use information from fcvt to format number string. */
  29589.      pnumstr = fcvt( number1 + number2, precision, &decimal, &sign );
  29590.  
  29591.      /* Start with sign if negative. */
  29592.      if( sign )
  29593.          strcat( numbuf, "-" );
  29594.  
  29595.      if( decimal <= 0 )
  29596.      {
  29597.          /* If decimal is left of first digit (decimal negative), put
  29598.           * in leading zeros, then add digits.
  29599.           */
  29600.          strcat( numbuf, "0." );
  29601.          memset( tmpbuf, '0', (size_t)abs( decimal ) );
  29602.          tmpbuf[abs( decimal )] = 0;
  29603.          strcat( numbuf, tmpbuf );
  29604.          strcat( numbuf, pnumstr );
  29605.      }
  29606.      else
  29607.      {
  29608.          /* If decimal is right of first digit, put in leading digits.
  29609.           * then add decimal and trailing digits.
  29610.           */
  29611.          strncat( numbuf, pnumstr, (size_t)decimal );
  29612.          strcat( numbuf, "." );
  29613.          strcat( numbuf, pnumstr + decimal );
  29614.      }
  29615.      cputs( strcat( "Total is: ", numbuf ) );
  29616.  }
  29617.  
  29618.  
  29619.  MORE.C
  29620.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\MORE.C
  29621.  
  29622.  /* MORE.C illustrates line input and output using:
  29623.   *      gets            puts            isatty          fileno
  29624.   *
  29625.   * Like the DOS MORE command, it is a filter whose input and output can
  29626.   * be redirected.
  29627.   */
  29628.  
  29629.  #include <stdio.h>
  29630.  #include <bios.h>
  29631.  #include <io.h>
  29632.  
  29633.  main()
  29634.  {
  29635.      long line = 0, page = 0;
  29636.      char tmp[128];
  29637.  
  29638.      /* Get each line from standard input and write to standard output. */
  29639.      while( 1 )
  29640.      {
  29641.          /* If standard out is the screen, wait for key after each screen. */
  29642.          if( isatty( fileno( stdout ) ) )
  29643.          {
  29644.              /* Wait for key every 23 lines. You must get the key directly
  29645.               * from the BIOS, since input is usually redirected.
  29646.               */
  29647.              if( !(++line % 23 ) )
  29648.                  _bios_keybrd( _KEYBRD_READ );
  29649.          }
  29650.          /* Must be redirected to file, so send a header every 58 lines. */
  29651.          else
  29652.          {
  29653.              if( !(line++ % 58) )
  29654.                  printf( "\f\nPage: %d\n\n", ++page );
  29655.          }
  29656.  
  29657.          /* Get and put a line of text. */
  29658.          if( gets( tmp ) == NULL )
  29659.              break;
  29660.          puts( tmp );
  29661.  
  29662.      }
  29663.  }
  29664.  
  29665.  
  29666.  MOVEMEM.C
  29667.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MEMORY\MOVEMEM.C
  29668.  
  29669.  /* MOVEMEM.C illustrate direct memory access using functions:
  29670.   *      movedata        FP_SEG          FP_OFF
  29671.   *
  29672.   * Also illustrated:
  29673.   *      pack pragma
  29674.   *
  29675.   * See COPY2.C for another example of FP_SEG.
  29676.   */
  29677.  
  29678.  #include <memory.h>
  29679.  #include <stdio.h>
  29680.  #include <dos.h>
  29681.  
  29682.  pack(1)     /* Use pragma to force packing on byte boundaries. */
  29683.  
  29684.  struct LOWMEMVID
  29685.  {
  29686.      char     vidmode;       /* 0x449 */
  29687.      unsigned scrwid;        /* 0x44A */
  29688.      unsigned scrlen;        /* 0x44C */
  29689.      unsigned scroff;        /* 0x44E */
  29690.      struct   LOCATE
  29691.      {
  29692.          unsigned char col;
  29693.          unsigned char row;
  29694.      } csrpos[8];            /* 0x450 */
  29695.      struct   CURSIZE
  29696.      {
  29697.          unsigned char end;
  29698.          unsigned char start;
  29699.      } csrsize;              /* 0x460 */
  29700.      char     page;          /* 0x462 */
  29701.  } vid;
  29702.  struct LOWMEMVID far *pvid = &vid;
  29703.  
  29704.  main()
  29705.  {
  29706.      int page;
  29707.  
  29708.      /* Move system information into uninitialized structure variable. */
  29709.      movedata( 0, 0x449, FP_SEG( pvid ), FP_OFF( pvid ), sizeof( vid ) );
  29710.  
  29711.      printf( "Move data from low memory 0000:0449 to structure at %Fp\n\n",
  29712.               (void far *)&vid );
  29713.  
  29714.      printf( "Mode:\t\t\t%u\n", vid.vidmode );
  29715.      printf( "Page:\t\t\t%u\n", vid.page );
  29716.      printf( "Screen width:\t\t%u\n", vid.scrwid );
  29717.      printf( "Screen length:\t\t%u\n", vid.scrlen );
  29718.      printf( "Cursor size:\t\tstart: %u\tend: %u\n",
  29719.               vid.csrsize.start, vid.csrsize.end );
  29720.      printf( "Cursor location:\t" );
  29721.      for( page = 0; page < 8; page++ )
  29722.          printf( "page:\t%u\tcolumn: %u\trow: %u\n\t\t\t",
  29723.                  page, vid.csrpos[page].col, vid.csrpos[page].row );
  29724.  }
  29725.  
  29726.  
  29727.  NFORMAT.C
  29728.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\NFORMAT.C
  29729.  
  29730.  /* NFORMAT.C: Prints numbers and a string. */
  29731.  
  29732.  #include <stdio.h>
  29733.  #include <string.h>
  29734.  
  29735.  main()
  29736.  {
  29737.     int    a = -765,
  29738.            b = 1,
  29739.            c = 44000,
  29740.            d = 33;
  29741.     float  e = 1.33E8,
  29742.            f = -0.1234567,
  29743.            g = 12345.6789,
  29744.            h = 1.0;
  29745.     char   i[80];
  29746.  
  29747.     strcpy( i, "word 1, word 2, word 3, word 4, word 5" );
  29748.  
  29749.     printf( "Unformatted:\n%d %d %d %d\n", a, b, c, d );
  29750.     printf( "%f %f %f %f\n", e, f, g, h );
  29751.     printf( "%s\n", i );
  29752.  }
  29753.  
  29754.  
  29755.  NOT.C
  29756.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\NOT.C
  29757.  
  29758.  /* NOT.C: Demonstrate logical NOT operator. */
  29759.  
  29760.  #include <stdio.h>
  29761.  
  29762.  main()
  29763.  {
  29764.    int val = 0;
  29765.    if( !val )
  29766.       printf( "val is zero" );
  29767.  }
  29768.  
  29769.  
  29770.  NULLFILE.C
  29771.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\NULLFILE.C
  29772.  
  29773.  /* NULLFILE.C illustrates these functions:
  29774.   *      chsize          umask           setmode
  29775.   *      creat           fstat
  29776.   */
  29777.  
  29778.  #include <stdio.h>
  29779.  #include <conio.h>
  29780.  #include <io.h>
  29781.  #include <fcntl.h>
  29782.  #include <sys\types.h>
  29783.  #include <sys\stat.h>
  29784.  #include <stdlib.h>
  29785.  #include <time.h>
  29786.  
  29787.  main()
  29788.  {
  29789.      int fhandle;
  29790.      long fsize;
  29791.      struct stat fstatus;
  29792.      char fname[80];
  29793.  
  29794.      /* Create a file of a specified length. */
  29795.      printf( "What dummy file do you want to create: " );
  29796.      gets( fname );
  29797.      if( !access( fname, 0 ) )
  29798.      {
  29799.          printf( "File exists" );
  29800.          exit( 1 );
  29801.      }
  29802.  
  29803.      /* Mask out write permission. This means that a later call to open
  29804.       * will not be able to set write permission. This is not particularly
  29805.       * useful in DOS, but umask is provided primarily for compatibility
  29806.       * with systems (such as Unix) that allow multiple permission levels.
  29807.       */
  29808.      umask( S_IWRITE );
  29809.  
  29810.      /* Despite write request, file is read only because of mask. */
  29811.      if( (fhandle = creat( fname, S_IREAD | S_IWRITE )) == -1 )
  29812.      {
  29813.          printf( "File can't be created" );
  29814.          exit( 1 );
  29815.      }
  29816.  
  29817.      /* Since creat uses the default mode (usually text), you must
  29818.       * use setmode to make sure the mode is binary.
  29819.       */
  29820.      setmode( fhandle, O_BINARY );
  29821.  
  29822.      printf( "How long do you want the file to be? " );
  29823.      scanf( "%ld", &fsize );
  29824.      chsize( fhandle, fsize );
  29825.  
  29826.      /* Display statistics. */
  29827.      fstat( fhandle, &fstatus );
  29828.      printf( "File: %s\n", fname );
  29829.      printf( "Size: %ld\n", fstatus.st_size );
  29830.      printf( "Drive %c:\n", fstatus.st_dev + 'A' );
  29831.      printf( "Permission: %s\n",
  29832.              (fstatus.st_mode & S_IWRITE) ? "Read/Write" : "Read Only" );
  29833.      printf( "Created: %s", ctime( &fstatus.st_atime ) );
  29834.  
  29835.      close( fhandle );
  29836.      exit( 0 );
  29837.  }
  29838.  
  29839.  
  29840.  NUMTOA.C
  29841.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\NUMTOA.C
  29842.  
  29843.  /* NUMTOA.C illustrates number to string conversion functions including:
  29844.   *      itoa            ltoa            ultoa
  29845.   */
  29846.  
  29847.  #include <stdlib.h>
  29848.  #include <stdio.h>
  29849.  
  29850.  main()
  29851.  {
  29852.      int  base, i;
  29853.      long l;
  29854.      unsigned long ul;
  29855.      char buffer[60];
  29856.  
  29857.      printf( "Enter an integer: " );
  29858.      scanf( "%d", &i );
  29859.      for( base =  2; base <= 16; base += 2 )
  29860.      {
  29861.          itoa( i, buffer, base );
  29862.          if( base != 10 )
  29863.              printf( "%d in base %d is: %s\n", i, base, buffer );
  29864.      }
  29865.  
  29866.      printf( "Enter a long integer: " );
  29867.      scanf( "%ld", &l );
  29868.      for( base =  2; base <= 16; base += 2 )
  29869.      {
  29870.          ltoa( l, buffer, base );
  29871.          if( base != 10 )
  29872.              printf( "%ld in base %d is: %s\n", l, base, buffer );
  29873.      }
  29874.  
  29875.      printf( "Enter an unsigned long integer: " );
  29876.      scanf( "%lu", &ul );
  29877.      for( base =  2; base <= 16; base += 2 )
  29878.      {
  29879.          ultoa( ul, buffer, base );
  29880.          if( base != 10 )
  29881.              printf( "%lu in base %d is: %s\n", ul, base, buffer );
  29882.      }
  29883.  }
  29884.  
  29885.  
  29886.  PAGE.C
  29887.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\PAGE.C
  29888.  
  29889.  /* PAGE.C illustrates video page functions including:
  29890.   *      _getactivepage  _getvisualpage  _setactivepage  _setvisualpage
  29891.   */
  29892.  
  29893.  #include <conio.h>
  29894.  #include <graph.h>
  29895.  #include <time.h>
  29896.  
  29897.  void delay( clock_t wait );         /* Prototype */
  29898.  char *jumper[] = { { "\\o/\n O \n/ \\" },
  29899.                     { "_o_\n O \n( )"   },
  29900.                     { " o \n/O\\\n/ \\" },
  29901.                     { " o \n O \n( )"   }
  29902.                   };
  29903.  main()
  29904.  {
  29905.      int i, oldvpage, oldapage, oldcursor;
  29906.  
  29907.      _clearscreen( _GCLEARSCREEN );
  29908.      oldcursor = _displaycursor( _GCURSOROFF );
  29909.      oldapage  = _getactivepage();
  29910.      oldvpage  = _getvisualpage();
  29911.  
  29912.      /* Draw image on each page */
  29913.      for( i = 0; i < 4; i++ )
  29914.      {
  29915.          _setactivepage( i );
  29916.          _settextposition( 1, 1 );
  29917.          _outtext( jumper[i] );
  29918.      }
  29919.  
  29920.      while( !kbhit() )
  29921.          /* Cycle through pages 0 to 3 */
  29922.          for( i = 0; i < 4; i++ )
  29923.          {
  29924.              _setvisualpage( i );
  29925.              delay( 100L );
  29926.          }
  29927.      getch();
  29928.  
  29929.      /* Restore original page and cursor. */
  29930.      _displaycursor( oldcursor );
  29931.      _setactivepage( oldapage );
  29932.      _setvisualpage( oldvpage );
  29933.  }
  29934.  
  29935.  /* delay - Pauses for a specified number of microseconds. */
  29936.  void delay( clock_t wait )
  29937.  {
  29938.      clock_t goal;
  29939.  
  29940.      goal = wait + clock();
  29941.      while( goal > clock() )
  29942.          ;
  29943.  }
  29944.  
  29945.  
  29946.  PAGER.C
  29947.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\PAGER.C
  29948.  
  29949.  /* PAGER.C illustrates line input and output on stream text files.
  29950.   * Functions illustrated include:
  29951.   *      fopen           fclose          fcloseall       feof
  29952.   *      fgets           fputs           rename
  29953.   */
  29954.  
  29955.  #include <stdio.h>
  29956.  #include <io.h>
  29957.  #include <dos.h>
  29958.  #include <stdlib.h>
  29959.  #include <string.h>
  29960.  
  29961.  #define MAXSTRING 128
  29962.  #define PAGESIZE 55
  29963.  enum BOOL { FALSE, TRUE };
  29964.  
  29965.  void quit( int error );
  29966.  FILE *infile, *outfile;
  29967.  char outpath[] = "tmXXXXXX";
  29968.  
  29969.  main( int argc, char *argv[] )
  29970.  {
  29971.      char tmp[MAXSTRING];
  29972.      long line = 0, page = 1;
  29973.      int  endflag = FALSE;
  29974.  
  29975.      /* Open file (from command line) and output (temporary) files. */
  29976.      if( (infile = fopen( argv[1], "rt" )) == NULL )
  29977.          quit( 1 );
  29978.      mktemp( outpath );
  29979.      if( (outfile = fopen( outpath, "wt" )) == NULL )
  29980.          quit( 2 );
  29981.  
  29982.      /* Get each line from input and write to output. */
  29983.      while( 1 )
  29984.      {
  29985.          /* Insert form feed and page header at the top of each page. */
  29986.          if( !(line++ % PAGESIZE) )
  29987.              fprintf( outfile, "\f\nPage %d\n\n", page++ );
  29988.  
  29989.          if( fgets( tmp, MAXSTRING - 1, infile ) == NULL )
  29990.              if( feof( infile ) )
  29991.                  break;
  29992.              else
  29993.                  quit( 3 );
  29994.          if( fputs( tmp, outfile ) == EOF )
  29995.              quit( 3 );
  29996.      }
  29997.  
  29998.      /* Close files and move temporary file to original by deleting
  29999.       * original and renaming temporary.
  30000.       */
  30001.      fcloseall();
  30002.      remove( argv[1] );
  30003.      rename( outpath, argv[1] );
  30004.      exit( 0 );
  30005.  }
  30006.  
  30007.  /* Handle errors. */
  30008.  void quit( int error )
  30009.  {
  30010.      switch( error )
  30011.      {
  30012.          case 1:
  30013.              perror( "Can't open input file" );
  30014.              break;
  30015.          case 2:
  30016.              perror( "Can't open output file" );
  30017.              fclose( infile );
  30018.              break;
  30019.          case 3:
  30020.              perror( "Error processing file" );
  30021.              fclose( infile );
  30022.              fclose( outfile );
  30023.              remove( outpath );
  30024.              break;
  30025.      }
  30026.      exit( error );
  30027.  }
  30028.  
  30029.  
  30030.  PALETTE1.C
  30031.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\PALETTE1.C
  30032.  
  30033.  /* PALETTE.C illustrates functions for assigning color values to
  30034.   * color indexes. Functions illustrated include:
  30035.   *      _remappalette       _remapallpalette
  30036.   */
  30037.  
  30038.  #include <graph.h>
  30039.  #include <conio.h>
  30040.  #include <stdio.h>
  30041.  #include <stdlib.h>
  30042.  
  30043.  /* Macro for mixing Red, Green, and Blue elements of color */
  30044.  #define RGB(r,g,b) (((long) ((b) << 8 | (g)) << 8) | (r))
  30045.  
  30046.  main()
  30047.  {
  30048.      short red, blue, green;
  30049.      short inc, i, mode, cells, x, y, xinc, yinc;
  30050.      long tmp, pal[256];
  30051.      char buf[40];
  30052.      struct videoconfig vc;
  30053.  
  30054.      /* Make sure all palette numbers are valid */
  30055.      for( i = 0; i < 256; i++ )
  30056.          pal[i] = _BLACK;
  30057.  
  30058.      /* Loop through each graphics mode that supports palettes. */
  30059.      for( mode = _MRES4COLOR; mode <= _MRES256COLOR; mode++ )
  30060.      {
  30061.          if( mode == _ERESNOCOLOR )
  30062.              mode++;
  30063.          if( !_setvideomode( mode ) )
  30064.              continue;
  30065.  
  30066.          /* Set variables for each mode. */
  30067.          _getvideoconfig( &vc );
  30068.          switch( vc.numcolors )
  30069.          {
  30070.              case 256:           /* Active bits in this order:           */
  30071.                  cells = 13;
  30072.                  inc = 12;       /* ???????? ??bbbbbb ??gggggg ??rrrrrr  */
  30073.                  break;
  30074.              case  16:
  30075.                  cells = 4;
  30076.                  if( (vc.mode == _ERESCOLOR) || (vc.mode == _VRES16COLOR) )
  30077.                      inc = 16;   /* ???????? ??????bb ??????gg ??????rr  */
  30078.                  else
  30079.                      inc = 32;   /* ???????? ??????Bb ??????Gg ??????Rr  */
  30080.                  break;
  30081.              case   4:
  30082.                  cells = 2;
  30083.                  inc = 32;       /* ???????? ??????Bb ??????Gg ??????Rr  */
  30084.                  break;
  30085.              default:
  30086.                  continue;
  30087.          }
  30088.          xinc = vc.numxpixels / cells;
  30089.          yinc = vc.numypixels / cells;
  30090.  
  30091.          /* Fill palette arrays in BGR order */
  30092.          for( i = 0, blue = 0; blue < 64; blue += inc )
  30093.              for( green = 0; green < 64; green += inc )
  30094.                  for( red = 0; red < 64; red += inc )
  30095.                  {
  30096.                      pal[i] = RGB( red, green, blue );
  30097.                      /* Special case of using 6 bits to represent 16 colors.
  30098.                       * If both bits are on for any color, intensity is set.
  30099.                       * If one bit is set for a color, the color is on.
  30100.                       */
  30101.                      if( inc == 32 )
  30102.                          pal[i + 8] = pal[i] | (pal[i] >> 1);
  30103.                      i++;
  30104.                  }
  30105.  
  30106.          /* If palettes available, remap all palettes at once. */
  30107.          if( !_remapallpalette( pal ) )
  30108.          {
  30109.              _setvideomode( _DEFAULTMODE );
  30110.              _outtext( "Palettes not available with this adapter" );
  30111.              exit( 1 );
  30112.          }
  30113.  
  30114.          /* Draw colored squares */
  30115.          for( i = 0, x = 0; x < vc.numxpixels; x += xinc )
  30116.              for( y = 0; y < vc.numypixels; y += yinc )
  30117.              {
  30118.                  _setcolor( i++ );
  30119.                  _rectangle( _GFILLINTERIOR, x, y, x + xinc, y + yinc );
  30120.              }
  30121.          sprintf( buf, "Mode %d has %d colors", vc.mode, vc.numcolors );
  30122.          _setcolor( vc.numcolors / 2 );
  30123.          _outtext( buf );
  30124.          getch();
  30125.  
  30126.          /* Change each palette entry separately in GRB order. */
  30127.          for( i = 0, green = 0; green < 64; green += inc )
  30128.              for( red = 0; red < 64; red += inc )
  30129.                  for(blue = 0; blue < 64; blue += inc )
  30130.                  {
  30131.                      tmp = RGB( red, green, blue );
  30132.                      _remappalette( i, tmp );
  30133.                      if( inc == 32 )
  30134.                          _remappalette( i + 8, tmp | (tmp >> 1) );
  30135.                      i++;
  30136.                  }
  30137.          getch();
  30138.      }
  30139.      exit( !_setvideomode( _DEFAULTMODE ) );
  30140.  }
  30141.  
  30142.  
  30143.  PARRAY.C
  30144.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\PARRAY.C
  30145.  
  30146.  /* PARRAY.C: Demonstrate pointer to array. */
  30147.  
  30148.  #include <stdio.h>
  30149.  
  30150.  int i_array[] = { 25, 300, 2, 12 };
  30151.  
  30152.  main()
  30153.  {
  30154.     int *ptr;
  30155.     int count;
  30156.     ptr = &i_array[0];
  30157.     for( count = 0; count < 4 ; count++ )
  30158.     {
  30159.        printf( "array[%d] = %d\n", count, *ptr );
  30160.        ptr++;
  30161.     }
  30162.  }
  30163.  
  30164.  
  30165.  PARRAY1.C
  30166.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\PARRAY1.C
  30167.  
  30168.  /* PARRAY1.C: Compact version of PARRAY.C. */
  30169.  
  30170.  #include <stdio.h>
  30171.  
  30172.  int i_array[] = { 25, 300, 2, 12 };
  30173.  
  30174.  
  30175.  main()
  30176.  {
  30177.     int count;
  30178.     int *ptr = i_array;
  30179.     for( count = 0; count < 4 ; count++ )
  30180.        printf( "array[%d] = %d\n", count, *ptr++ );
  30181.  }
  30182.  
  30183.  
  30184.  PFUNC.C
  30185.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\PFUNC.C
  30186.  
  30187.  /* PFUNC.C: Passing pointers to a function. */
  30188.  
  30189.  #include <stdio.h>
  30190.  
  30191.  void swap( int *ptr1, int *ptr2 );
  30192.  
  30193.  main()
  30194.  {
  30195.     int first = 1, second = 3;
  30196.     int *ptr = &second;
  30197.     printf( "first: %d  second: %d\n", first, *ptr );
  30198.     swap( &first, ptr );
  30199.     printf( "first: %d  second: %d\n", first, *ptr );
  30200.  }
  30201.  
  30202.  void swap( int *ptr1, int *ptr2 )
  30203.  {
  30204.     int temp;
  30205.     temp = *ptr1;
  30206.     *ptr1 = *ptr2;
  30207.     *ptr2 = temp;
  30208.  }
  30209.  
  30210.  
  30211.  POINTER.C
  30212.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\POINTER.C
  30213.  
  30214.  /* POINTER.C: Demonstrate pointer basics. */
  30215.  
  30216.  #include <stdio.h>
  30217.  
  30218.  main()
  30219.  {
  30220.     int val = 25;
  30221.     int *ptr;
  30222.     ptr = &val;
  30223.     printf( " val = %d\n", val );
  30224.     printf( "*ptr = %d\n\n", *ptr );
  30225.     printf( "&val = %u\n", &val );
  30226.     printf( " ptr = %d\n", ptr );
  30227.  }
  30228.  
  30229.  
  30230.  PRINTF.C
  30231.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\PRINTF.C
  30232.  
  30233.  /* PRINTF.C illustrates output formatting with:
  30234.   *      printf
  30235.   *
  30236.   * The rules for formatting also apply to cprintf, sprintf, vfprintf,
  30237.   * vprintf, and vsprintf. For other examples of printf formatting,
  30238.   * see EXTDIR.C (sprintf), VPRINTF (vprintf), TABLE.C (fprintf),
  30239.   * ROTATE.C (printf), and IS.C (cprintf).
  30240.   */
  30241.  
  30242.  #include <stdio.h>
  30243.  
  30244.  main()
  30245.  {
  30246.      char ch = 'h', *string = "computer";
  30247.      int count = 234, *ptr, hex = 0x10, oct = 010, dec = 10;
  30248.      double fp = 251.7366;
  30249.  
  30250.      /* Display integers. */
  30251.      printf("%d    %+d    %06d    %X    %x    %o\n\n",
  30252.              count, count, count, count, count, count );
  30253.  
  30254.      /* Count characters printed. */
  30255.      printf( "            V\n" );
  30256.      printf( "1234567890123%n45678901234567890\n", &count );
  30257.      printf( "Number of characters printed: %d\n\n", count );
  30258.  
  30259.      /* Display characters. */
  30260.      printf( "%10c%5c\n\n", ch, ch );
  30261.  
  30262.      /* Display strings. */
  30263.      printf( "%25s\n%25.4s\n\n", string, string );
  30264.  
  30265.      /* Display real numbers. */
  30266.      printf( "%f    %.2f    %e    %E\n\n", fp, fp, fp, fp );
  30267.  
  30268.      /* Display in different radixes. */
  30269.      printf( "%i    %i    %i\n\n", hex, oct, dec );
  30270.  
  30271.      /* Display pointers. */
  30272.      ptr = &count;
  30273.      printf( "%Np    %p    %Fp\n", ptr, (int far *)ptr, (int far *)ptr );
  30274.  }
  30275.  
  30276.  
  30277.  PRTESC.C
  30278.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\PRTESC.C
  30279.  
  30280.  /* PRTESC.C: Prints escape characters \",\n, and \t.
  30281.  */
  30282.  
  30283.  #include <stdio.h>
  30284.  #include <string.h>
  30285.  
  30286.  main()
  30287.  {
  30288.     char b[80];
  30289.     int i,j;
  30290.  
  30291.     strcpy( b, "and seven years ago\n" );
  30292.     printf( "\"Four score\n" );
  30293.     printf( b );
  30294.     printf( "\tone tab\n\t\ttwo tabs\n\t\t\tthree tabs\n" );
  30295.     i = sizeof( b );
  30296.     j = strlen( b );
  30297.     printf( "Size is %d\nLength is %d.\n", i, j );
  30298.  }
  30299.  
  30300.  
  30301.  PSTRING.C
  30302.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\PSTRING.C
  30303.  
  30304.  /* PSTRING.C: Demonstrate pointer to a string. */
  30305.  
  30306.  #include <stdio.h>
  30307.  
  30308.  main()
  30309.  {
  30310.     int count;
  30311.     static char name[] = "john";
  30312.     char *ptr = name;
  30313.     for( count = 0; count < 4; count++ )
  30314.     {
  30315.        printf( "name[%d]: %c\n", count, *ptr++ );
  30316.     }
  30317.  }
  30318.  
  30319.  
  30320.  PSTRING1.C
  30321.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\PSTRING1.C
  30322.  
  30323.  /* PSTRING1.C: Look for null at string's end.  */
  30324.  
  30325.  #include <stdio.h>
  30326.  
  30327.  main()
  30328.  {
  30329.     static char name[] = "john";
  30330.     char *ptr = name;
  30331.     while( *ptr )
  30332.        printf( "*ptr = %c\n", *ptr++ );
  30333.  }
  30334.  
  30335.  
  30336.  PSTRING2.C
  30337.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\PSTRING2.C
  30338.  
  30339.  /* PSTRING2.C: Demonstrate strings and array notation.
  30340.  */
  30341.  
  30342.  #include <stdio.h>
  30343.  #include <string.h>
  30344.  
  30345.  main()
  30346.  {
  30347.     int count;
  30348.     static char name[] = "john";
  30349.     for( count = 0; count < strlen( name ); count++ )
  30350.        printf( "name[%d]: %c\n", count, name[count] );
  30351.  }
  30352.  
  30353.  
  30354.  PSTRING3.C
  30355.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\PSTRING3.C
  30356.  
  30357.  /* PSTRING3.C: Strings and pointer notation.  */
  30358.  
  30359.  #include <stdio.h>
  30360.  #include <string.h>
  30361.  
  30362.  main()
  30363.  {
  30364.     int count;
  30365.     static char name[] = "john";
  30366.     for( count = 0; count < strlen( name ); count++ )
  30367.        printf( "*(name+count) = %c\n", *(name+count) );
  30368.  }
  30369.  
  30370.  
  30371.  PTRPTR.C
  30372.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\PTRPTR.C
  30373.  
  30374.  /* PTRPTR.C: Demonstrate a pointer to a pointer. */
  30375.  
  30376.  #include <stdio.h>
  30377.  
  30378.  main()
  30379.  {
  30380.     int val = 501;
  30381.     int *ptr = &val;
  30382.     int **ptr_ptr = &ptr;
  30383.     printf( "val = %d\n", **ptr_ptr );
  30384.  }
  30385.  
  30386.  
  30387.  QSORT.C
  30388.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\QSORT.C
  30389.  
  30390.  /* QSORT.C illustates randomizing, sorting, and searching. Functions
  30391.   * illustrated include:
  30392.   *      srand           rand            qsort
  30393.   *      lfind           lsearch         bsearch
  30394.   *
  30395.   * The lsearch function is not specifically shown in the program, but
  30396.   * its use is the same as lfind except that if it does not find the
  30397.   * element, it inserts it at the end of the array rather than failing.
  30398.   */
  30399.  
  30400.  #include <search.h>
  30401.  #include <stdlib.h>
  30402.  #include <string.h>
  30403.  #include <stdio.h>
  30404.  #include <time.h>
  30405.  
  30406.  #define  ASIZE 1000
  30407.  unsigned array[ASIZE];
  30408.  
  30409.  /* Macro to get a random integer within a specified range */
  30410.  #define getrandom( min, max ) ((rand() % (int)((max) - (min))) + (min) + 1)
  30411.  
  30412.  /* Must be declared before call */
  30413.  unsigned cmpgle( unsigned *arg1, unsigned *arg2 );
  30414.  unsigned cmpe( unsigned *arg1, unsigned *arg2 );
  30415.  
  30416.  main()
  30417.  {
  30418.      unsigned i, *result, elements = ASIZE, key = ASIZE / 2;
  30419.  
  30420.      /* Seed the random number generator with current time. */
  30421.      srand( (unsigned)time( 0L ) );
  30422.  
  30423.      /* Build a random array of integers. */
  30424.      printf( "Randomizing . . .\n" );
  30425.      for( i = 0; i < ASIZE; i++ )
  30426.          array[i] = getrandom( 1, ASIZE );
  30427.  
  30428.      /* Show every tenth element. */
  30429.      printf( "Printing every tenth element . . .\n" );
  30430.      for( i = 9; i < ASIZE; i += 10 )
  30431.      {
  30432.          printf( "%5u", array[i] );
  30433.          if( !(i % 15) )
  30434.              printf( "\n" );
  30435.      }
  30436.  
  30437.      /* Find element using linear search. */
  30438.      printf( "\nDoing linear search . . .\n" );
  30439.      result = (unsigned *)lfind( (char *)&key, (char *)array, &elements,
  30440.                                  sizeof( unsigned ), cmpe);
  30441.      if( result == NULL )
  30442.          printf( "  Value %u not found\n", key );
  30443.      else
  30444.          printf( "  Value %u found in element %u\n", key, result - array + 1);
  30445.  
  30446.      /* Sort array using Quicksort algorithm. */
  30447.      printf( "Sorting . . .\n" );
  30448.      qsort( (void *)array, (size_t)ASIZE, sizeof( int ), cmpgle );
  30449.  
  30450.      /* Show every tenth element. */
  30451.      printf( "Printing every tenth element . . .\n" );
  30452.      for( i = 9; i < ASIZE; i += 10 )
  30453.      {
  30454.          printf( "%5u", array[i] );
  30455.          if( !(i % 15) )
  30456.              printf( "\n" );
  30457.      }
  30458.  
  30459.      /* Find element using binary search. Note that the array must
  30460.       * be previously sorted before using binary search.
  30461.       */
  30462.      printf( "\nDoing binary search . . .\n" );
  30463.      result = (unsigned *)bsearch( (char *)&key, (char *)array, elements,
  30464.                                    sizeof( unsigned ), cmpgle);
  30465.      if( result == NULL )
  30466.          printf( "  Value %u not found\n", key );
  30467.      else
  30468.          printf( "  Value %u found in element %u\n", key, result - array + 1 )
  30469.  }
  30470.  
  30471.  /* Compare and return greater than (1), less than (-1), or equal to (0).
  30472.   * This function is called by qsort and bsearch.
  30473.   */
  30474.  unsigned cmpgle( unsigned *arg1, unsigned *arg2 )
  30475.  {
  30476.      if( *arg1 > *arg2 )
  30477.          return 1;
  30478.      else if( *arg1 < *arg2 )
  30479.          return -1;
  30480.      else
  30481.          return 0;
  30482.  }
  30483.  
  30484.  /* Compare and return equal (1) or not equal (0). This function is
  30485.   * called by lfind and lsearch.
  30486.   */
  30487.  unsigned cmpe( unsigned *arg1, unsigned *arg2 )
  30488.  {
  30489.      return !( *arg1 == *arg2 );
  30490.  }
  30491.  
  30492.  
  30493.  RDFILE.C
  30494.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\RDFILE.C
  30495.  
  30496.  /* RDFILE.C: Reads a file and prints characters to
  30497.   * the screen.  If you get "Error in opening file" try
  30498.   * running wrfile.c before you run this again.
  30499.   */
  30500.  
  30501.  #include <stdio.h>
  30502.  
  30503.  main()
  30504.  {
  30505.     int c;
  30506.     FILE *fp;
  30507.  
  30508.     if( fp = fopen( "c:\\testfile.asc", "rb" ) )
  30509.     {
  30510.        while( (c = fgetc( fp )) != EOF )
  30511.           printf( " %c\t%d\n", c, c );
  30512.        printf( "\nEnd of file marker: %d", c );
  30513.        fclose( fp );
  30514.     }
  30515.     else
  30516.        printf( "Error in opening file\n" );
  30517.  }
  30518.  
  30519.  
  30520.  RDKEYBRD.C
  30521.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\RDKEYBRD.C
  30522.  
  30523.  /* INPUT.C: Reads keyboard. */
  30524.  
  30525.  #include <stdio.h>
  30526.  #include <conio.h>
  30527.  #include <ctype.h>
  30528.  
  30529.  main()
  30530.  {
  30531.     int num;
  30532.     char c;
  30533.     char name[80];
  30534.     float rb;
  30535.  
  30536.     puts( "** Type \"Name:\" and your name" );
  30537.     scanf( "Name: %40s", name );
  30538.     printf( "** You typed this:\n%s", name );
  30539.     puts( "\n\n** Try again, with the gets function." );
  30540.     fflush( stdin );
  30541.     gets( name );
  30542.     printf( "** You typed this:\n%s\n", name );
  30543.  
  30544.     printf( "\n** Now type an integer.\n" );
  30545.     scanf( "%i", &num );
  30546.     sprintf( name, "** You typed this number: %i\n", num );
  30547.     puts( name );
  30548.  
  30549.     fflush( stdin );
  30550.     printf( "** Enter a floating-point value.\n" );
  30551.     scanf( "%f", &rb );
  30552.     printf( "** The answer is %f or %e\n", rb, rb );
  30553.  
  30554.     printf( "** Continue? Y or N\n" );
  30555.  
  30556.     do
  30557.        c = tolower( getch() );
  30558.     while( c != 'y' && c != 'n' );
  30559.  
  30560.  }
  30561.  
  30562.  
  30563.  REALG.C
  30564.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\REALG.C
  30565.  
  30566.   /* REALG.C: Example of real-coordinate graphics */
  30567.  
  30568.  #include <stdio.h>
  30569.  #include <conio.h>
  30570.  #include <graph.h>
  30571.  
  30572.  #define TRUE 1
  30573.  #define FALSE 0
  30574.  
  30575.  int four_colors( void );
  30576.  void three_graphs( void );
  30577.  void grid_shape( void );
  30578.  
  30579.  int halfx, halfy;
  30580.  struct videoconfig screen;
  30581.  double bananas[] =
  30582.  {   -0.3, -0.2, -0.224, -0.1, -0.5, +0.21, +2.9,
  30583.     +0.3, +0.2, 0.0, -0.885, -1.1, -0.3, -0.2,
  30584.     +.001, +.005, +0.14, 0.0, -0.9, -0.13, +0.3
  30585.  };
  30586.  
  30587.  
  30588.  main()
  30589.  {
  30590.     if( four_colors() )
  30591.        three_graphs();
  30592.     else
  30593.        printf( "This program requires a CGA, EGA, or VGA graphics card.\n"
  30594.  );
  30595.  }
  30596.  /*
  30597.  . Additional functions defined below
  30598.  .
  30599.  .
  30600.  */
  30601.   /* four_colors function from REALG.C */
  30602.  
  30603.  int four_colors( void )
  30604.  {
  30605.     _getvideoconfig( &screen );
  30606.     switch( screen.adapter )
  30607.     {
  30608.        case _CGA:
  30609.        case _OCGA:
  30610.           _setvideomode( _MRES4COLOR );
  30611.           break;
  30612.        case _EGA:
  30613.        case _OEGA:
  30614.           _setvideomode( _ERESCOLOR );
  30615.           break;
  30616.        case _VGA:
  30617.        case _OVGA:
  30618.           _setvideomode( _VRES16COLOR );
  30619.           break;
  30620.        default:
  30621.           return( FALSE );
  30622.     }
  30623.     _getvideoconfig( &screen );
  30624.     return( TRUE );
  30625.  }
  30626.  /* three_graphs function from REALG.C */
  30627.  
  30628.  void three_graphs( void )
  30629.  {
  30630.     int xwidth, yheight, cols, rows;
  30631.     struct _wxycoord upleft, botright;
  30632.  
  30633.     _clearscreen( _GCLEARSCREEN );
  30634.     xwidth = screen.numxpixels;
  30635.     yheight = screen.numypixels;
  30636.     halfx = xwidth/2;
  30637.     halfy = yheight/2;
  30638.     cols = screen.numtextcols;
  30639.     rows = screen.numtextrows;
  30640.  
  30641.     /* first window */
  30642.     _setviewport( 0, 0, halfx-1, halfy-1 );
  30643.     _settextwindow( 1, 1, rows/2, cols/2 );
  30644.     _setwindow( FALSE, -2.0, -2.0, 2.0, 2.0 );
  30645.     grid_shape();
  30646.     _rectangle( _GBORDER, 0, 0, halfx-1, halfy-1 );
  30647.  
  30648.     /* second window */
  30649.     _setviewport( halfx, 0, xwidth-1, halfy-1 );
  30650.     _settextwindow( 1, cols/2+1, rows/2, cols );
  30651.     _setwindow( FALSE, -3.0, -3.0, 3.0, 3.0 );
  30652.     grid_shape();
  30653.     _rectangle_w( _GBORDER, -3.0, -3.0, 3.0, 3.0 );
  30654.  
  30655.     /* third window */
  30656.     _setviewport( 0, halfy, xwidth-1, yheight-1 );
  30657.     _settextwindow( rows/2+1, 1, rows, cols );
  30658.     _setwindow( TRUE, -3.0, -1.5, 1.5, 1.5 );
  30659.     grid_shape();
  30660.     upleft.wx = -3.0;
  30661.     upleft.wy = -1.5;
  30662.     botright.wx = 1.5;
  30663.     botright.wy = 1.5;
  30664.     _rectangle_wxy( _GBORDER, &upleft, &botright );
  30665.  
  30666.     getch();
  30667.     _setvideomode( _DEFAULTMODE );
  30668.  }
  30669.  /* grid_shape from the REALG.C program */
  30670.  
  30671.  void grid_shape( void )
  30672.  {
  30673.     int i, numc, x1, y1, x2, y2;
  30674.     double x, y;
  30675.     char txt[80];
  30676.  
  30677.     numc = screen.numcolors;
  30678.     for( i = 1; i < numc; i++ )
  30679.     {
  30680.        _settextposition( i, 2 );
  30681.        _settextcolor( i );
  30682.        sprintf( txt, "Color %d", i );
  30683.        _outtext( txt );
  30684.     }
  30685.  
  30686.     _setcolor( 1 );
  30687.     _rectangle_w( _GBORDER, -1.0, -1.0, 1.0, 1.0 );
  30688.     _rectangle_w( _GBORDER, -1.02, -1.02, 1.02, 1.02 );
  30689.  
  30690.     for( x = -0.9, i = 0; x < 0.9; x += 0.1 )
  30691.     {
  30692.        _setcolor( 2 );
  30693.        _moveto_w( x, -1.0 );
  30694.        _lineto_w( x, 1.0 );
  30695.        _moveto_w( -1.0, x );
  30696.        _lineto_w( 1.0, x );
  30697.  
  30698.        _setcolor( 3 );
  30699.        _moveto_w( x - 0.1, bananas[i++] );
  30700.        _lineto_w( x, bananas[i] );
  30701.     }
  30702.     _moveto_w( 0.9, bananas[i++] );
  30703.     _lineto_w( 1.0, bananas[i] );
  30704.  }
  30705.  
  30706.  
  30707.  REALLOC1.C
  30708.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MEMORY\REALLOC1.C
  30709.  
  30710.  /* REALLOC.C illustrates heap functions:
  30711.   *      calloc      realloc         _expand
  30712.   */
  30713.  
  30714.  #include <stdio.h>
  30715.  #include <malloc.h>
  30716.  
  30717.  main()
  30718.  {
  30719.      int  *bufint;
  30720.      char *bufchar;
  30721.  
  30722.      printf( "Allocate two 512 element buffers\n" );
  30723.      if( (bufint = (int *)calloc( 512, sizeof( int ) )) == NULL )
  30724.          exit( 1 );
  30725.      printf( "Allocated %d bytes at %Fp\n",
  30726.              _msize( bufint ), (void far *)bufint );
  30727.  
  30728.      if( (bufchar = (char *)calloc( 512, sizeof( char ) )) == NULL )
  30729.          exit( 1 );
  30730.      printf( "Allocated %d bytes at %Fp\n",
  30731.              _msize( bufchar ), (void far *)bufchar );
  30732.  
  30733.      /* Expand the second buffer, reallocate the first. Note that trying
  30734.       * to expand the first buffer would fail because the second buffer
  30735.       * would be in the way.
  30736.       */
  30737.      if( (bufchar = (char *)_expand( bufchar, 1024 )) == NULL )
  30738.          printf( "Can't expand" );
  30739.      else
  30740.          printf( "Expanded block to %d bytes at %Fp\n",
  30741.                  _msize( bufchar ), (void far *)bufchar );
  30742.  
  30743.      if( (bufint = (int *)realloc( bufint, 1024 * sizeof( int ) )) == NULL )
  30744.          printf( "Can't reallocate" );
  30745.      else
  30746.          printf( "Reallocated block to %d bytes at %Fp\n",
  30747.                  _msize( bufint ), (void far *)bufint );
  30748.  
  30749.      /* Free memory */
  30750.      free( bufint );
  30751.      free( bufchar );
  30752.      exit( 0 );
  30753.  }
  30754.  
  30755.  
  30756.  RECORDS1.C
  30757.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\RECORDS1.C
  30758.  
  30759.  /* RECORDS1.C illustrates reading and writing of file records using seek
  30760.   * functions including:
  30761.   *      fseek       rewind      ftell
  30762.   *
  30763.   * Other general functions illustrated include:
  30764.   *      tmpfile     rmtmp       fread       fwrite
  30765.   *
  30766.   * Also illustrated:
  30767.   *      struct
  30768.   *
  30769.   * See RECORDS2.C for a version program using fgetpos and fsetpos.
  30770.   */
  30771.  
  30772.  #include <stdio.h>
  30773.  #include <io.h>
  30774.  #include <string.h>
  30775.  
  30776.  /* File record */
  30777.  struct RECORD
  30778.  {
  30779.      int     integer;
  30780.      long    doubleword;
  30781.      double  realnum;
  30782.      char    string[15];
  30783.  } filerec = { 0, 1, 10000000.0, "eel sees tar" };
  30784.  
  30785.  main()
  30786.  {
  30787.      int c, newrec;
  30788.      size_t recsize = sizeof( filerec );
  30789.      FILE *recstream;
  30790.      long recseek;
  30791.  
  30792.      /* Create and open temporary file. */
  30793.      recstream = tmpfile();
  30794.  
  30795.      /* Write 10 unique records to file. */
  30796.      for( c = 0; c < 10; c++ )
  30797.      {
  30798.          ++filerec.integer;
  30799.          filerec.doubleword *= 3;
  30800.          filerec.realnum /= (c + 1);
  30801.          strrev( filerec.string );
  30802.  
  30803.          fwrite( &filerec, recsize, 1, recstream );
  30804.      }
  30805.  
  30806.      /* Find a specified record. */
  30807.      do
  30808.      {
  30809.          printf( "Enter record betweeen 1 and 10 (or 0 to quit): " );
  30810.          scanf( "%d", &newrec );
  30811.  
  30812.          /* Find and display valid records. */
  30813.          if( (newrec >= 1) && (newrec <= 10) )
  30814.          {
  30815.              recseek = (long)((newrec - 1) * recsize);
  30816.              fseek( recstream, recseek, SEEK_SET );
  30817.  
  30818.              fread( &filerec, recsize, 1, recstream );
  30819.  
  30820.              printf( "Integer:\t%d\n", filerec.integer );
  30821.              printf( "Doubleword:\t%ld\n", filerec.doubleword );
  30822.              printf( "Real number:\t%.2f\n", filerec.realnum );
  30823.              printf( "String:\t\t%s\n\n", filerec.string );
  30824.          }
  30825.      } while( newrec );
  30826.  
  30827.      /* Starting at first record, scan each for specific value. The following
  30828.       * line is equivalent to:
  30829.       *      fseek( recstream, 0L, SEEK_SET );
  30830.       */
  30831.      rewind( recstream );
  30832.  
  30833.      do
  30834.      {
  30835.          fread( &filerec, recsize, 1, recstream );
  30836.      } while( filerec.doubleword < 1000L );
  30837.  
  30838.      recseek = ftell( recstream );
  30839.      /* Equivalent to: recseek = fseek( recstream, 0L, SEEK_CUR ); */
  30840.      printf( "\nFirst doubleword above 1000 is %ld in record %d\n",
  30841.              filerec.doubleword, recseek / recsize );
  30842.  
  30843.      /* Close and delete temporary file. */
  30844.      rmtmp();
  30845.  }
  30846.  
  30847.  
  30848.  RECORDS2.C
  30849.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\RECORDS2.C
  30850.  
  30851.  /* RECORDS2.C illustrates reading and writing of file records with the
  30852.   * following functions:
  30853.   *      fgetpos     fsetpos
  30854.   *
  30855.   * See RECORDS1.C for a version using fseek, rewind, and ftell.
  30856.   */
  30857.  
  30858.  #include <stdio.h>
  30859.  #include <io.h>
  30860.  
  30861.  /* File record */
  30862.  struct RECORD
  30863.  {
  30864.      int     integer;
  30865.      long    doubleword;
  30866.      double  realnum;
  30867.  } filerec = { 0, 1, 10000000.0 };
  30868.  
  30869.  main()
  30870.  {
  30871.      int c, newrec;
  30872.      size_t recsize = sizeof( filerec );
  30873.      FILE *recstream;
  30874.      fpos_t *recpos;
  30875.  
  30876.      /* Create and open temporary file. */
  30877.      recstream = tmpfile();
  30878.  
  30879.      /* Write 10 unique records to file. */
  30880.      for( c = 0; c < 10; c++ )
  30881.      {
  30882.          ++filerec.integer;
  30883.          filerec.doubleword *= 3;
  30884.          filerec.realnum /= (c + 1);
  30885.  
  30886.          fwrite( &filerec, recsize, 1, recstream );
  30887.      }
  30888.  
  30889.      /* Find a specified record. */
  30890.      do
  30891.      {
  30892.          printf( "Enter record betweeen 1 and 10 (or 0 to quit): " );
  30893.          scanf( "%d", &newrec );
  30894.  
  30895.          /* Find and display valid records. */
  30896.          if( (newrec >= 1) && (newrec <= 10) )
  30897.          {
  30898.              *recpos = (fpos_t)((newrec - 1) * recsize);
  30899.              fsetpos( recstream, recpos );
  30900.              fread( &filerec, recsize, 1, recstream );
  30901.  
  30902.              printf( "Integer:\t%d\n", filerec.integer );
  30903.              printf( "Doubleword:\t%ld\n", filerec.doubleword );
  30904.              printf( "Real number:\t%.2f\n", filerec.realnum );
  30905.          }
  30906.      } while( newrec );
  30907.  
  30908.      /* Starting at first record, scan each for specific value. */
  30909.      *recpos = (fpos_t)0;
  30910.      fsetpos( recstream, recpos );
  30911.      do
  30912.      {
  30913.          fread( &filerec, recsize, 1, recstream );
  30914.      } while( filerec.doubleword < 1000L );
  30915.  
  30916.      fgetpos( recstream, recpos );
  30917.      printf( "\nFirst doubleword above 1000 is %ld in record %d\n",
  30918.              filerec.doubleword, *recpos / recsize );
  30919.  
  30920.      /* Close and delete temporary file. */
  30921.      rmtmp();
  30922.  }
  30923.  
  30924.  
  30925.  ROTATE.C
  30926.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\ROTATE.C
  30927.  
  30928.  /* ROTATE.C illustrates bit rotation functions including:
  30929.   *      _rotl           _rotr           _lrotl          _lrotr
  30930.   *
  30931.   * _lrotl and _lrotr are not shown in the program, but they are the
  30932.   * same as _rotl and _rotr except that they work on long integers.
  30933.   */
  30934.  
  30935.  #include <stdlib.h>
  30936.  #include <stdio.h>
  30937.  #include <string.h>
  30938.  
  30939.  char *binstr( int num, char *buffer );      /* Prototype */
  30940.  
  30941.  main()
  30942.  {
  30943.      int  shift, i, ir, il;
  30944.      char tmpbuf[20];
  30945.  
  30946.      printf( "Enter integer: " );
  30947.      scanf( "%d", &i );
  30948.      printf( "\n\n" );
  30949.  
  30950.      /* Display table header for rotates. */
  30951.      printf( "%6s    %-7s    %16s    %-7s    %16s\n",
  30952.              " ", "Left", " ", "Right", " " );
  30953.      printf( "%6s    %7s    %16s    %7s    %16s\n\n",
  30954.              "Shift", "Decimal", "Binary", "Decimal", "Binary" );
  30955.  
  30956.      /* Display table of rotated values. */
  30957.      for( shift = 0; shift <= 16; shift++ )
  30958.      {
  30959.          il = _rotl( i, shift ); ;
  30960.          printf( "%5d    %7d    %16s    ", shift, il, binstr( il,  tmpbuf ) );
  30961.          ir = _rotr( i, shift );
  30962.          printf( "%7d    %16s\n", ir, binstr( ir, tmpbuf ) );
  30963.      }
  30964.  }
  30965.  
  30966.  /* Convert integer to string of 16 binary characters. */
  30967.  char *binstr( int num, char *buffer )
  30968.  {
  30969.      char tmp[17];
  30970.      int  len;
  30971.  
  30972.      memset( buffer, '0', 16 );
  30973.      len = strlen( itoa( num, tmp, 2 ) );
  30974.      strcpy( buffer + 16 - len, tmp );
  30975.      return buffer;
  30976.  }
  30977.  
  30978.  
  30979.  RWFILE.C
  30980.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\RWFILE.C
  30981.  
  30982.  /* RWFILE.C: Reads and writes a file. */
  30983.  
  30984.  #include <stdio.h>
  30985.  #include <string.h>
  30986.  #include <fcntl.h>
  30987.  #include <sys\types.h>
  30988.  #include <sys\stat.h>
  30989.  #include <io.h>
  30990.  
  30991.  #define BUFF 512
  30992.  
  30993.  main()
  30994.  {
  30995.     char inbuffer[BUFF];
  30996.     char outbuffer[BUFF];
  30997.     int infile, outfile, length, num;
  30998.  
  30999.     strcpy( outbuffer, "Happy Birthday." );
  31000.     length = strlen( outbuffer );
  31001.     length++;
  31002.  
  31003.     if( (outfile = open( "testfile.bin",
  31004.        O_CREAT | O_WRONLY | O_BINARY,  S_IWRITE )) != -1 )
  31005.     {
  31006.        if( (num = write( outfile, outbuffer, length )) == -1 )
  31007.           perror( "Error in writing" );
  31008.        printf( "\nBytes written to file: %d\n", num );
  31009.        close( outfile );
  31010.     }
  31011.     else
  31012.        perror( "Error opening outfile" );
  31013.  
  31014.     if( (infile = open( "testfile.bin", O_RDONLY | O_BINARY )) != -1  )
  31015.     {
  31016.        while( length = read( infile, inbuffer, BUFF ) )
  31017.           printf( "%d bytes received so far.\n", length );
  31018.        close( infile );
  31019.        printf( "%s\n", inbuffer );
  31020.     }
  31021.     else
  31022.        perror( "Error opening infile" );
  31023.  }
  31024.  
  31025.  
  31026.  SBRK.C
  31027.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MEMORY\SBRK.C
  31028.  
  31029.  /* SBRK.C illustrates memory allocation with function:
  31030.   *      sbrk
  31031.   */
  31032.  
  31033.  #include <malloc.h>
  31034.  #include <stdio.h>
  31035.  #include <stdlib.h>
  31036.  
  31037.  main()
  31038.  {
  31039.      char *bufA, *bufB, *bufC;
  31040.  
  31041.      /* Allocate 512 bytes. */
  31042.      if( (bufA = sbrk( 512 )) == (char *)-1 )
  31043.          exit( 1 );
  31044.      printf( "Allocate:\t256\tLocation:\t%p\n", (int far *)bufA );
  31045.  
  31046.      /* Allocate 50 bytes. */
  31047.      if( (bufB = sbrk( 50 )) == (char *)-1 )
  31048.          exit( 1 );
  31049.      printf( "Allocate:\t50\tLocation:\t%p\n", (int far *)bufB );
  31050.  
  31051.      /* Deallocate 256 bytes. */
  31052.      sbrk( -256 );
  31053.      printf( "Deallocate:\t256\n" );
  31054.  
  31055.      /* Allocate 20 bytes. */
  31056.      if( (bufC = sbrk( 20 )) == (char *)-1 )
  31057.          exit( 1 );
  31058.      printf( "Allocate:\t20\tLocation:\t%p\n", (int far *)bufC );
  31059.      exit( 0 );
  31060.  }
  31061.  
  31062.  
  31063.  SCANF.C
  31064.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\SCANF.C
  31065.  
  31066.  /* SCANF.C illustrates formatted input. Functions illustrated include:
  31067.   *          scanf           fflush          flushall
  31068.   *
  31069.   * For other examples of formatted input, see TABLE.C (fscanf) and
  31070.   * SETTIME.C (sscanf).
  31071.   */
  31072.  
  31073.  #include <stdio.h>
  31074.  #include <conio.h>
  31075.  
  31076.  main()
  31077.  {
  31078.      int result, integer;
  31079.      float fp;
  31080.      char string[81];
  31081.  
  31082.      /* Get numbers. */
  31083.      printf( "Enter an integer and a floating point number: " );
  31084.      scanf( "%d %f", &integer, &fp );
  31085.      printf( "%d + %f = %f\n\n", integer, fp, integer + fp );
  31086.  
  31087.      /* Read each word as a string. */
  31088.      printf( "Enter a sentence of four words with scanf: " );
  31089.      for( integer = 0; integer < 4; integer++ )
  31090.      {
  31091.          scanf( "%s", string );
  31092.          printf( "%s\n", string );
  31093.      }
  31094.  
  31095.      /* Clear the input buffer and get with gets. */
  31096.      fflush( stdin );
  31097.      printf( "Enter the same sentence with gets: " );
  31098.      gets( string );
  31099.      printf( "%s\n", string );
  31100.  
  31101.      /* Specify delimiters. The ^ inside the brackets says accept any
  31102.       * character except the following other characters in brackets (tab
  31103.       * and newline in the example).
  31104.       */
  31105.      printf( "Enter the same sentence with scanf and delimiters: " );
  31106.      scanf( "%[^\n\t]s", string );
  31107.      printf( "%s\n", string );
  31108.  
  31109.      /* Loop until input value is 0. */
  31110.      printf( "\n\nEnter numbers in C decimal (num), hex (0xnum), " );
  31111.      printf( "or octal (0num) format.\nEnter 0 to quit\n\n" );
  31112.      do
  31113.      {
  31114.          printf( "Enter number: " );
  31115.          result = scanf( "%i", &integer );
  31116.          if( result )
  31117.              /* Display valid integers. */
  31118.              printf( "Decimal: %i  Octal: 0%o  Hexadecimal: 0x%X\n\n",
  31119.                      integer, integer, integer );
  31120.          else
  31121.          {   /* Read invalid characters. Then flush and continue. */
  31122.              scanf( "%s", string );
  31123.              printf( "Invalid number: %s\n\n", string );
  31124.              flushall();
  31125.              integer = 1;
  31126.          }
  31127.      } while( integer );
  31128.  }
  31129.  
  31130.  
  31131.  SEEK.C
  31132.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\SEEK.C
  31133.  
  31134.  /* SEEK.C illustrates low-level file I/O functions including:
  31135.   *      filelength      lseek           tell
  31136.   */
  31137.  
  31138.  #include <io.h>
  31139.  #include <conio.h>
  31140.  #include <stdio.h>
  31141.  <fcntl.h>          /* O_ constant definitions */
  31142.  #include <process.h>
  31143.  
  31144.  void error( char *errmsg );
  31145.  
  31146.  main()
  31147.  {
  31148.      int handle, ch;
  31149.      unsigned count;
  31150.      long position, length;
  31151.      char buffer[2], fname[80];
  31152.  
  31153.      /* Get file name and open file. */
  31154.      do
  31155.      {
  31156.          printf( "Enter file name: " );
  31157.          gets( fname );
  31158.          handle = open( fname, O_BINARY | O_RDONLY );
  31159.      } while( handle == -1 );
  31160.  
  31161.      /* Get and print length. */
  31162.      length = filelength( handle );
  31163.      printf( "\nFile length of %s is: %ld\n\n", fname, length );
  31164.  
  31165.      /* Report the character at a specified position. */
  31166.      do
  31167.      {
  31168.          printf( "Enter integer position less than file length: " );
  31169.          scanf( "%ld", &position );
  31170.      } while( position > length );
  31171.  
  31172.      lseek( handle, position, SEEK_SET );
  31173.      if( read( handle, buffer, 1 ) == -1 )
  31174.          error( "Read error" );
  31175.      printf( "Character at byte %ld is ASCII %u ('%c')\n\n",
  31176.              position, *buffer, *buffer );
  31177.  
  31178.      /* Search for a specified character and report its position. */
  31179.      lseek( handle, 0L, SEEK_SET);           /* Set to position 0 */
  31180.      printf( "Type character to search for: " );
  31181.      ch = getche();
  31182.  
  31183.      /* Read until character is found */
  31184.      do
  31185.      {
  31186.          if( (count = read( handle, buffer, 1 )) == -1 )
  31187.              error( "Read error" );
  31188.      } while( (*buffer != (char)ch) && count );
  31189.  
  31190.      /* Report the current position. */
  31191.      position = tell( handle );
  31192.      if( count )
  31193.          printf( "\nFirst ASCII %u ('%c') is at byte %ld\n",
  31194.                  ch, ch, position );
  31195.      else
  31196.          printf( "\nASCII %u ('%c') not found\n", ch, ch );
  31197.      close( handle );
  31198.      exit( 0 );
  31199.  }
  31200.  
  31201.  void error( char *errmsg )
  31202.  {
  31203.      perror( errmsg );
  31204.      exit( 1 );
  31205.  }
  31206.  
  31207.  
  31208.  SETROWS.C
  31209.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\SETROWS.C
  31210.  
  31211.  /* SETROWS.C illustrates
  31212.   *      _settextrows
  31213.   */
  31214.  
  31215.  #include <graph.h>
  31216.  #include <stdlib.h>
  31217.  
  31218.  main( int argc, char ** argv )
  31219.  {
  31220.      struct videoconfig vc;
  31221.      short rows = atoi( argv[1] );
  31222.  
  31223.      _getvideoconfig( &vc );
  31224.  
  31225.      /* Make sure new rows is valid and the same as requested rows. */
  31226.      if( !rows || (_settextrows( rows ) != rows) )
  31227.          _outtext( "\nSyntax: SETROWS [ 25 | 43 | 50 ]\n" );
  31228.  
  31229.      /* Always return old rows for batch file testing. */
  31230.      exit( vc.numtextrows );
  31231.  }
  31232.  
  31233.  
  31234.  SETSTR.C
  31235.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\SETSTR.C
  31236.  
  31237.  /* SETSTR.C illustrate string and memory set functions including:
  31238.   *     memset           strnset         strset
  31239.   */
  31240.  
  31241.  #include <memory.h>
  31242.  #include <string.h>
  31243.  #include <stdio.h>
  31244.  
  31245.  char string[60] = "The quick brown dog jumps over the lazy fox ";
  31246.  /*                          1         2         3         4         5 *
  31247.   *                 12345678901234567890123456789012345678901234567890 */
  31248.  main()
  31249.  {
  31250.      printf( "Function:\tmemset with fill character '█'\n" );
  31251.      printf( "Destination:\t%s\n", string );
  31252.      memset( string + 10, '█', 5 );
  31253.      printf( "Result:\t\t%s\n\n", string );
  31254.  
  31255.      printf( "Function:\tstrnset with fill character '█'\n" );
  31256.      printf( "Destination:\t%s\n", string );
  31257.      strnset( string + 15, '█', 5 );
  31258.      printf( "Result:\t\t%s\n\n", string );
  31259.  
  31260.      printf( "Function:\tstrset with fill character '█'\n" );
  31261.      printf( "Destination:\t%s\n", string );
  31262.      strset( string + 20, '█' );
  31263.      printf( "Result:\t\t%s\n\n", string );
  31264.  }
  31265.  
  31266.  
  31267.  SETTIME.C
  31268.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\SETTIME.C
  31269.  
  31270.  /* SETTIME.C illustates getting and setting the DOS time and date using:
  31271.   *      _dos_gettime    _dos_settime    _dos_getdate    _dos_setdate
  31272.   *
  31273.   * Formatted input to a string is illustrated using:
  31274.   *      sscanf
  31275.   */
  31276.  
  31277.  #include <dos.h>
  31278.  #include <stdio.h>
  31279.  #include <conio.h>
  31280.  #include <string.h>
  31281.  
  31282.  struct dosdate_t ddate;
  31283.  struct dostime_t dtime;
  31284.  
  31285.  main()
  31286.  {
  31287.      unsigned tmpday, tmpmonth, tmpyear;
  31288.      unsigned tmphour, tmpminute, tmpsecond;
  31289.      static char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }
  31290.      char tmpbuf[20];
  31291.  
  31292.      /* Get current date. */
  31293.      _dos_getdate( &ddate );
  31294.      printf( "Date: %u/%02u/%02u %s\n",
  31295.              ddate.month, ddate.day, ddate.year - 1900,
  31296.              days[ddate.dayofweek] );
  31297.      printf( "Enter new date: " );
  31298.  
  31299.      /* Get a date string and if it's not 0 (for CR), assign it to date. */
  31300.      gets( tmpbuf );
  31301.      if( strlen( tmpbuf ) )
  31302.      {
  31303.          /* NOTE: You must read the month and day into a temporary unsigned
  31304.           * variable. If you try to read directly into the unsigned char
  31305.           * values ddate.day or ddate.month, sscanf (or scanf) will read a
  31306.           * word, thus overriding adjacent bytes.
  31307.           */
  31308.          sscanf( tmpbuf, "%u/%u/%u", &tmpmonth, &tmpday, &tmpyear );
  31309.          if( (tmpyear - 80) <= 20 )
  31310.              ddate.year = tmpyear + 1900;
  31311.          else if( (tmpyear >= 1980) && (tmpyear <= 2099 ) )
  31312.              ddate.year = tmpyear;
  31313.          if( (tmpmonth + 1) <= 13 )
  31314.              ddate.month = (unsigned char)tmpmonth;
  31315.          if( (tmpday + 1) <= 32 )
  31316.              ddate.day = (unsigned char)tmpday;
  31317.          _dos_setdate( &ddate );
  31318.          _dos_getdate( &ddate );
  31319.          printf( "New date: %u/%02u/%02u %s\n",
  31320.                  ddate.month, ddate.day, ddate.year - 1900,
  31321.                  days[ddate.dayofweek] );
  31322.      }
  31323.  
  31324.      /* Get current time. */
  31325.      _dos_gettime( &dtime );
  31326.      printf( "Time: %u:%02u:%02u\n", dtime.hour, dtime.minute, dtime.second );
  31327.      printf( "Enter new time: " );
  31328.  
  31329.      /* Get a time string and if it's not 0 (for CR), assign it to time. */
  31330.      gets( tmpbuf );
  31331.      if( strlen( tmpbuf ) )
  31332.      {
  31333.          sscanf( tmpbuf, "%u:%u:%u", &tmphour, &tmpminute, &tmpsecond );
  31334.          if( tmphour < 24 )
  31335.              dtime.hour = (unsigned char)tmphour;
  31336.          if( tmpminute < 60 )
  31337.              dtime.minute = (unsigned char)tmpminute;
  31338.          if( tmpsecond < 60 )
  31339.              dtime.second = (unsigned char)tmpsecond;
  31340.          _dos_settime( &dtime );
  31341.          _dos_gettime( &dtime );
  31342.          printf( "New time: %u:%02u:%02u\n",
  31343.                  dtime.hour, dtime.minute, dtime.second );
  31344.      }
  31345.  }
  31346.  
  31347.  
  31348.  
  31349.  SHOWME1.C
  31350.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\SHOWME1.C
  31351.  
  31352.  /* SHOWME1.C: Demonstrate passing by value. */
  31353.  
  31354.  #include <stdio.h>
  31355.  
  31356.  void showme( int any, int old, int name );
  31357.  
  31358.  main()
  31359.  {
  31360.     int x = 10, y = 20, z = 30;
  31361.     showme( z, y, x );
  31362.  
  31363.     printf( "z=%d y=%d x=%d\n", z, y, x );
  31364.  }
  31365.  
  31366.  void showme( int any, int old, int name )
  31367.  {
  31368.     printf( "any=%d old=%d name=%d\n", any, old, name );
  31369.     any = 55;
  31370.     old = 66;
  31371.     name = 77;
  31372.     printf( "any=%d old=%d name=%d\n", any, old, name );
  31373.  }
  31374.  
  31375.  
  31376.  SIGNAL1.C
  31377.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\SIGNAL1.C
  31378.  
  31379.  /* SIGNAL.C illustrates setting up signal interrupt routines. Functions
  31380.   * illustrated include:
  31381.   *      signal          abort           raise           _fpreset
  31382.   *
  31383.   * The program also illustrates saving an environment and then doing a
  31384.   * long jump to return to it using functions:
  31385.   *      setjmp          longjmp
  31386.   */
  31387.  
  31388.  #include <stdio.h>
  31389.  #include <conio.h>
  31390.  #include <signal.h>
  31391.  #include <process.h>
  31392.  #include <setjmp.h>
  31393.  #include <stdlib.h>
  31394.  #include <float.h>
  31395.  
  31396.  void ctrlchandler( void );          /* Prototypes */
  31397.  void aborthandler( void );
  31398.  void fphandler( int sig, int num );
  31399.  
  31400.  jmp_buf mark;                       /* Address for long jump to jump to */
  31401.  
  31402.  main()
  31403.  {
  31404.      double n1, n2, r;
  31405.      int jmpret;
  31406.  
  31407.      /* Modify abort behavior. */
  31408.      if( signal( SIGABRT, aborthandler ) == SIG_ERR )
  31409.      {
  31410.          printf( "Couldn't set SIGABRT\n" );
  31411.          exit( 1 );
  31412.      }
  31413.  
  31414.      /* Modify CTRL+C behavior. */
  31415.      if( signal( SIGINT, ctrlchandler ) == SIG_ERR )
  31416.      {
  31417.          fprintf( stderr, "Couldn't set SIGINT\n" );
  31418.          abort();
  31419.      }
  31420.  
  31421.      /* Set up pointer to error handler. */
  31422.      if( signal( SIGFPE, fphandler ) == SIG_ERR )
  31423.      {
  31424.          fprintf( stderr, "Couldn't set SIGFPE\n" );
  31425.          abort();
  31426.      }
  31427.  
  31428.      /* Save stack environment for return in case of error. First time
  31429.       * through, jmpret is 0, so true conditional is executed. If an
  31430.       * error occurs, jmpret will be set to -1 and false conditional
  31431.       * will be executed.
  31432.       */
  31433.      jmpret = setjmp( mark );
  31434.      if( jmpret == 0 )
  31435.      {
  31436.          /* Try forcing error by dividing by 0 or using very large numbers. */
  31437.          printf( "Enter number to divide or CTRL-C: " );
  31438.          scanf( "%lf", &n1 );
  31439.          printf( "Enter number to divide by or CTRL-C: " );
  31440.          scanf( "%lf", &n2 );
  31441.          r = n1 / n2;
  31442.  
  31443.          /* This won't be reached if error occurs. */
  31444.          printf( "\n%4.3g / %4.3g = %4.3g\n", n1, n2, r );
  31445.      }
  31446.      else
  31447.          printf( "Recovered from floating-point error\n" );
  31448.  
  31449.      /* Fake CTRL+C. Program will abort or exit, depending on user
  31450.       * response in handler.
  31451.       */
  31452.      raise( SIGINT );
  31453.      exit( 0 );
  31454.  }
  31455.  
  31456.  /* Function called whenever SIGINT (CTRL+C) interrupt is called. */
  31457.  void ctrlchandler()
  31458.  {
  31459.      int ch;
  31460.  
  31461.      /* Disallow CTRL+C during handler. */
  31462.      signal( SIGINT, SIG_IGN );
  31463.  
  31464.      printf( "Abort processing? " );
  31465.      ch = getche();
  31466.      printf( "\n" );
  31467.      if( (ch == 'y') || (ch == 'Y') )
  31468.          abort();
  31469.      else
  31470.  
  31471.          /* The CTRL+C interrupt must be reset to our handler since by
  31472.           * default DOS resets it to the system handler.
  31473.           */
  31474.          signal( SIGINT, ctrlchandler );
  31475.  }
  31476.  
  31477.  /* Function called whenever SIGABRT interrupt is called. */
  31478.  void aborthandler()
  31479.  {
  31480.      printf( "The abort() function was called\n" );
  31481.      exit( 1 );
  31482.  }
  31483.  
  31484.  /* Function called whenever SIGFPE interrupt is called. */
  31485.  void fphandler( int sig, int num )
  31486.  {
  31487.      printf( "Signal: %d   Subcode: 0x%x\n", sig, num );
  31488.  
  31489.      /* Initialize floating-point package. */
  31490.      _fpreset();
  31491.  
  31492.      /* Restore calling environment and jump back to setjmp. Return -1
  31493.       * so that setjmp will return false for conditional test.
  31494.       */
  31495.      longjmp( mark, -1 );
  31496.  }
  31497.  
  31498.  
  31499.  SIZEOF.C
  31500.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\SIZEOF.C
  31501.  
  31502.  /* SIZEOF.C: Demonstrate sizeof operator. */
  31503.  
  31504.  #include <stdio.h>
  31505.  
  31506.  char string[] = "Hello, world";
  31507.  
  31508.  main()
  31509.  {
  31510.     int val;
  31511.     printf( "An int is %d bytes long\n", sizeof( int ) );
  31512.     printf( "The string is %d bytes long\n", sizeof string );
  31513.  }
  31514.  
  31515.  
  31516.  SORT.C
  31517.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\SORT.C
  31518.  
  31519.  /* SORT.C illustates randomizing, sorting, and searching. Functions
  31520.   * illustrated include:
  31521.   *      srand           rand            qsort
  31522.   *      lfind           lsearch         bsearch
  31523.   *
  31524.   * The lsearch function is not specifically shown in the program, but
  31525.   * its use is the same as lfind except that if it does not find the
  31526.   * element, it inserts it at the end of the array rather than failing.
  31527.   */
  31528.  
  31529.  #include <search.h>
  31530.  #include <stdlib.h>
  31531.  #include <string.h>
  31532.  #include <stdio.h>
  31533.  #include <time.h>
  31534.  
  31535.  #define  ASIZE 1000
  31536.  unsigned array[ASIZE];
  31537.  
  31538.  /* Macro to get a random integer within a specified range */
  31539.  #define getrandom( min, max ) ((rand() % (int)((max) - (min))) + (min) + 1)
  31540.  
  31541.  /* Must be declared before call */
  31542.  unsigned cmpgle( unsigned *arg1, unsigned *arg2 );
  31543.  unsigned cmpe( unsigned *arg1, unsigned *arg2 );
  31544.  
  31545.  main()
  31546.  {
  31547.      unsigned i, *result, elements = ASIZE, key = ASIZE / 2;
  31548.  
  31549.      /* Seed the random number generator with current time. */
  31550.      srand( (unsigned)time( 0L ) );
  31551.  
  31552.      /* Build a random array of integers. */
  31553.      printf( "Randomizing . . .\n" );
  31554.      for( i = 0; i < ASIZE; i++ )
  31555.          array[i] = getrandom( 1, ASIZE );
  31556.  
  31557.      /* Show every tenth element. */
  31558.      printf( "Printing every tenth element . . .\n" );
  31559.      for( i = 9; i < ASIZE; i += 10 )
  31560.      {
  31561.          printf( "%5u", array[i] );
  31562.          if( !(i % 15) )
  31563.              printf( "\n" );
  31564.      }
  31565.  
  31566.      /* Find element using linear search. */
  31567.      printf( "\nDoing linear search . . .\n" );
  31568.      result = (unsigned *)lfind( (char *)&key, (char *)array, &elements,
  31569.                                  sizeof( unsigned ), cmpe);
  31570.      if( result == NULL )
  31571.          printf( "  Value %u not found\n", key );
  31572.      else
  31573.          printf( "  Value %u found in element %u\n", key, result - array + 1);
  31574.  
  31575.      /* Sort array using Quicksort algorithm. */
  31576.      printf( "Sorting . . .\n" );
  31577.      qsort( (void *)array, (size_t)ASIZE, sizeof( int ), cmpgle );
  31578.  
  31579.      /* Show every tenth element. */
  31580.      printf( "Printing every tenth element . . .\n" );
  31581.      for( i = 9; i < ASIZE; i += 10 )
  31582.      {
  31583.          printf( "%5u", array[i] );
  31584.          if( !(i % 15) )
  31585.              printf( "\n" );
  31586.      }
  31587.  
  31588.      /* Find element using binary search. Note that the array must
  31589.       * be previously sorted before using binary search.
  31590.       */
  31591.      printf( "\nDoing binary search . . .\n" );
  31592.      result = (unsigned *)bsearch( (char *)&key, (char *)array, elements,
  31593.                                    sizeof( unsigned ), cmpgle);
  31594.      if( result == NULL )
  31595.          printf( "  Value %u not found\n", key );
  31596.      else
  31597.          printf( "  Value %u found in element %u\n", key, result - array + 1 )
  31598.  
  31599.  }
  31600.  
  31601.  /* Compare and return greater than (1), less than (-1), or equal to (0).
  31602.   * This function is called by qsort and bsearch.
  31603.   */
  31604.  unsigned cmpgle( unsigned *arg1, unsigned *arg2 )
  31605.  {
  31606.      if( *arg1 > *arg2 )
  31607.          return 1;
  31608.      else if( *arg1 < *arg2 )
  31609.          return -1;
  31610.      else
  31611.          return 0;
  31612.  }
  31613.  
  31614.  /* Compare and return equal (1) or not equal (0). This function is
  31615.   * called by lfind and lsearch.
  31616.   */
  31617.  unsigned cmpe( unsigned *arg1, unsigned *arg2 )
  31618.  {
  31619.      return !( *arg1 == *arg2 );
  31620.  }
  31621.  
  31622.  
  31623.  SORT1.C
  31624.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\SORT1.C
  31625.  
  31626.  /* SORT1.C: Demonstrate sort with pointer notation.
  31627.  */
  31628.  
  31629.  #include <stdio.h>
  31630.  #define SIZE 4
  31631.  
  31632.  void sort( int size, double **p );
  31633.  void show( int size, double **p, double dd[] );
  31634.  
  31635.  main()
  31636.  {
  31637.     int x;
  31638.     static double d[] = { 3.333, 1.111, 2.222, 4.444 };
  31639.     static double *d_ptr[SIZE];
  31640.     for( x = 0; x < SIZE; x++ )
  31641.        d_ptr[x] = &d[x];
  31642.     show( SIZE, d_ptr, d );
  31643.     sort( SIZE, d_ptr );
  31644.     show( SIZE, d_ptr, d );
  31645.  }
  31646.  
  31647.  void sort( int size, double **p )
  31648.  {
  31649.     int x, x1;
  31650.     double *temp;
  31651.     for( x = 0; x < size - 1; x++ )
  31652.        for( x1 = x + 1; x1 < size; x1++ )
  31653.        {
  31654.           if( **(p+x) > **(p+x1) )
  31655.           {
  31656.              temp = *(p+x1);
  31657.              *(p+x1) = *(p+x);
  31658.              *(p+x) = temp;
  31659.           }
  31660.        }
  31661.  }
  31662.  
  31663.  void show( int size, double **p, double dd[] )
  31664.  {
  31665.     int x;
  31666.     printf( "------------------------" );
  31667.     printf( "------------------------\n" );
  31668.     for( x = 0; x < size; x++ )
  31669.     {
  31670.        printf( "*d_ptr[%d] = %1.3f   ", x, **(p+x) );
  31671.        printf( "d_ptr[%d] = %u ", x, *(p+x) );
  31672.        printf( "  d[%d] = %1.3f\n", x, dd[x] );
  31673.     }
  31674.  }
  31675.  
  31676.  
  31677.  SPAWN.C
  31678.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\SPAWN.C
  31679.  
  31680.  /* SPAWN.C illustrates the different versions of spawn including:
  31681.   *      spawnl          spawnle         spawnlp         spawnlpe
  31682.   *      spawnv          spawnve         spawnvp         spawnvpe
  31683.   *
  31684.   * Although SPAWN.C can spawn any program, you can verify how different
  31685.   * versions handle arguments and environment by compiling and
  31686.   * specifying the sample program ARGS.C. See EXEC.C for examples
  31687.   * of the similar exec functions.
  31688.   */
  31689.  
  31690.  #include <stdio.h>
  31691.  #include <conio.h>
  31692.  #include <process.h>
  31693.  
  31694.  char *my_env[] =                        /* Environment for spawn?e */
  31695.  {
  31696.      "THIS=environment will be",
  31697.      "PASSED=to child by the",
  31698.      "SPAWN=functions",
  31699.      NULL
  31700.  };
  31701.  
  31702.  main()
  31703.  {
  31704.      char *args[4], prog[80];
  31705.      int ch, r;
  31706.  
  31707.      printf( "Enter name of program to spawn: " );
  31708.      gets( prog );
  31709.      printf( " 1. spawnl   2. spawnle   3. spawnlp   4. spawnlpe\n" );
  31710.      printf( " 5. spawnv   6. spawnve   7. spawnvp   8. spawnvpe\n" );
  31711.      printf( "Type a number from 1 to 8 (or 0 to quit): " );
  31712.      ch = getche();
  31713.      if( (ch < '1') || (ch > '8') )
  31714.          exit( -1 );
  31715.      printf( "\n\n" );
  31716.  
  31717.      /* Arguments for spawnv? */
  31718.      args[0] = prog;             /* First argument ignored under most */
  31719.      args[1] = "spawn??";        /*   recent versions of DOS          */
  31720.      args[2] = "two";
  31721.      args[2] = "two";
  31722.      args[3] = NULL;
  31723.  
  31724.      switch( ch )
  31725.      {
  31726.          case '1':
  31727.              r = spawnl( P_WAIT, prog, prog, "spawnl", "two", NULL );
  31728.              break;
  31729.          case '2':
  31730.              r = spawnle( P_WAIT, prog, prog, "spawnle", "two", NULL, my_env )
  31731.              break;
  31732.          case '3':
  31733.              r = spawnlp( P_WAIT, prog, prog, "spawnlp", "two", NULL );
  31734.              break;
  31735.          case '4':
  31736.              r = spawnlpe( P_WAIT, prog, prog, "spawnlpe", "two", NULL, my_env
  31737.              break;
  31738.          case '5':
  31739.              r = spawnv( P_WAIT, prog, args );
  31740.              break;
  31741.          case '6':
  31742.              r = spawnve( P_WAIT, prog, args, my_env );
  31743.              break;
  31744.          case '7':
  31745.              r = spawnvp( P_WAIT, prog, args );
  31746.              break;
  31747.          case '8':
  31748.              r = spawnvpe( P_WAIT, prog, args, my_env );
  31749.              break;
  31750.          default:
  31751.              break;
  31752.      }
  31753.      if( r == -1 )
  31754.          printf( "Couldn't spawn process" );
  31755.      else
  31756.          printf( "\nReturned from SPAWN!" );
  31757.      exit( r );
  31758.  }
  31759.  
  31760.  
  31761.  STACK.C
  31762.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MEMORY\STACK.C
  31763.  
  31764.  /* STACK.C illustrates stack functions including:
  31765.   *      alloca          stackavail
  31766.   */
  31767.  
  31768.  #include <malloc.h>
  31769.  #include <stdio.h>
  31770.  
  31771.  main()
  31772.  {
  31773.      char *buffer;
  31774.  
  31775.      printf( "Bytes available on stack: %u\n", stackavail() );
  31776.  
  31777.      /* Allocate memory for string. */
  31778.      buffer = alloca( 120 * sizeof( char ) );
  31779.      printf( "Enter a string: " );
  31780.      gets( buffer );
  31781.      printf( "You entered: %s\n", buffer );
  31782.  
  31783.      printf( "Bytest available on stack: %u\n", stackavail() );
  31784.  }
  31785.  
  31786.  
  31787.  STATIC.C
  31788.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\STATIC.C
  31789.  
  31790.  /* STATIC.C: Demonstrate static variables. */
  31791.  
  31792.  #include <stdio.h>
  31793.  
  31794.  void add_ten( int val );
  31795.  
  31796.  main()
  31797.  {
  31798.     int val = 10;
  31799.     add_ten( val++ );
  31800.     add_ten( val );
  31801.  }
  31802.  
  31803.  void add_ten( int value )
  31804.  {
  31805.     static int methuselah;
  31806.     if( value == 10 )
  31807.        methuselah = 0;
  31808.     methuselah = methuselah + value;
  31809.     printf( "methuselah = %d\n", methuselah );
  31810.  }
  31811.  
  31812.  
  31813.  STRTONUM.C
  31814.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\STRTONUM.C
  31815.  
  31816.  /* STRTONUM.C illustrates string to number conversion functions including:
  31817.   *      strtod              strtol              strtoul
  31818.   */
  31819.  
  31820.  #include <stdlib.h>
  31821.  #include <stdio.h>
  31822.  
  31823.  main()
  31824.  {
  31825.      char *string, *stopstring;
  31826.      double x;
  31827.      long l;
  31828.      unsigned long ul;
  31829.      int base;
  31830.  
  31831.      /* Convert string to double. */
  31832.      string = "3.1415926INVALID";
  31833.      x = strtod( string, &stopstring );
  31834.      printf( "\nString: %s\n", string );
  31835.      printf( "\tDouble:\t\t\t%f\n", x );
  31836.      printf( "\tScan stopped at:\t%s\n", stopstring );
  31837.  
  31838.      /* Convert string to long using bases 2, 4, and 8. */
  31839.      string = "-10110134932";
  31840.      printf( "\nString: %s\n", string );
  31841.      for( base = 2; base <= 8; base *= 2 )
  31842.      {
  31843.          l = strtol( string, &stopstring, base );
  31844.          printf( "\tBase %d signed long:\t%ld\n", base, l );
  31845.          printf( "\tScan stopped at:\t%s\n", stopstring );
  31846.      }
  31847.  
  31848.      /* Convert string to unsigned long using bases 2, 4, and 8. */
  31849.      string = "10110134932";
  31850.      printf( "\nString: %s\n", string );
  31851.      for( base = 2; base <= 8; base *= 2 )
  31852.      {
  31853.          ul = strtoul( string, &stopstring, base);
  31854.          printf("\tBase %d unsigned long:\t%ld\n", base, ul );
  31855.          printf("\tScan stopped at:\t%s\n", stopstring );
  31856.      }
  31857.  }
  31858.  
  31859.  
  31860.  SVBIN.C
  31861.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\SVBIN.C
  31862.  
  31863.  /* SVBIN.C: Saves integer variables in binary format.
  31864.  */
  31865.  
  31866.  #include <stdio.h>
  31867.  #define ASIZE 10
  31868.  
  31869.  main()
  31870.  {
  31871.     FILE *ap;
  31872.     int zebra[ASIZE], acopy[ASIZE], bcopy[ASIZE];
  31873.     int i;
  31874.  
  31875.     for( i = 0; i < ASIZE; i++ )
  31876.        zebra[i] = 7700 + i;
  31877.  
  31878.     if( (ap = fopen( "binfile", "wb" )) != NULL )
  31879.     {
  31880.        fwrite( zebra, sizeof(zebra), 1, ap );
  31881.        fclose( ap );
  31882.     }
  31883.     else
  31884.        perror( "Write error" );
  31885.  
  31886.     if( (ap = fopen( "morebin", "wb" )) != NULL )
  31887.     {
  31888.        fwrite( &zebra[0], sizeof(zebra[0]), ASIZE, ap );
  31889.        fclose( ap );
  31890.     }
  31891.     else
  31892.        perror( "Write error" );
  31893.  
  31894.     if( (ap = fopen( "binfile", "rb" )) != NULL )
  31895.     {
  31896.        printf( "Hexadecimal values in binfile:\n" );
  31897.        while( (i = fgetc( ap )) != EOF )
  31898.           printf( "%02X ", i );
  31899.        rewind( ap );
  31900.        fread( acopy, sizeof(acopy), 1, ap );
  31901.  
  31902.  
  31903.  
  31904.        rewind( ap );
  31905.        fread( &bcopy[0], sizeof( bcopy[0] ), ASIZE, ap);
  31906.        for( i=0; i<ASIZE; i++ )
  31907.           printf( "\nItem %d = %d\t%d", i, acopy[i], bcopy[i] );
  31908.        fclose( ap );
  31909.  
  31910.     }
  31911.     else
  31912.        perror( "Read error" );
  31913.  
  31914.  }
  31915.  
  31916.  
  31917.  SVTEXT.C
  31918.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\SVTEXT.C
  31919.  
  31920.  /* SVTEXT.C: Save integer variables as text. */
  31921.  
  31922.  #include <stdio.h>
  31923.  
  31924.  int list[] = { 53, -23456, 50, 500, 5000, -99 };
  31925.  extern int errno;
  31926.  char fname[] = "numtext";
  31927.  char temp[81];
  31928.  
  31929.  main()
  31930.  {
  31931.     FILE *fptr;
  31932.     int i;
  31933.  
  31934.     if( (fptr = fopen( "numtext","wt" )) != NULL )
  31935.     {
  31936.        for( i=0; i<6; i++ )
  31937.           fprintf( fptr, "Item %d: %6d \n", i, list[i] );
  31938.        fclose( fptr );
  31939.     }
  31940.     else
  31941.        printf( "Error: Couldn't create file.\n" );
  31942.  
  31943.     if( (fptr = fopen( "badname", "rt" )) != NULL )
  31944.     {
  31945.        /* do nothing */
  31946.     }
  31947.     else
  31948.     {
  31949.        printf( "Error number: %d\n\t", errno );
  31950.        perror( "Couldn't open file BADNAME\n\t" );
  31951.     }
  31952.  
  31953.     if( (fptr = fopen( fname, "rt" )) != NULL )
  31954.     {
  31955.        list[0] = 0;
  31956.        fscanf( fptr, "Item %d: %d \n", &i, &list[0] );
  31957.        printf( "Values read from file:\t %d %d\n", i, list[0] );
  31958.        fgets( temp, 80, fptr );
  31959.        printf( "String from file: \t%s\n", temp );
  31960.        while( (i = fgetc( fptr )) != '\n' )
  31961.           printf( "char: %c \t ASCII: %d \n", i, i );
  31962.        rewind( fptr );
  31963.        printf( "Rewind to start -->\t%s", fgets( temp, 80, fptr ) );
  31964.        fclose( fptr );
  31965.     }
  31966.     else      printf( "Trouble opening %s \n", fname );
  31967.  }
  31968.  
  31969.  
  31970.  SWAB.C
  31971.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\SWAB.C
  31972.  
  31973.  /* SWAB.C illustrates:
  31974.   *      swab
  31975.   */
  31976.  
  31977.  #include <stdlib.h>
  31978.  #include <stdio.h>
  31979.  
  31980.  char from[] = "BADCFEHGJILKNMPORQTSVUXWZY";
  31981.  char to[] =   "..........................";
  31982.  
  31983.  main()
  31984.  {
  31985.      printf( "Before:\t%s\n\t%s\n\n", from, to );
  31986.      swab( from, to, sizeof( from ) );
  31987.      printf( "After:\t%s\n\t%s\n\n", from, to );
  31988.  }
  31989.  
  31990.  
  31991.  SWITCH.C
  31992.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\SWITCH.C
  31993.  
  31994.  /* SWITCH.C: Demonstrate switch statement. */
  31995.  
  31996.  #include <stdio.h>
  31997.  #include <conio.h>
  31998.  #define  B_KEY  'b'
  31999.  #define  ENTER_KEY  '\r'
  32000.  
  32001.  main()
  32002.  {
  32003.     char ch;
  32004.     printf( "Press the b key to hear a bell.\n" );
  32005.     ch = getch();
  32006.     switch( ch )
  32007.     {
  32008.        case B_KEY:
  32009.           printf( "Beep!\a\n" );
  32010.           break;
  32011.        case ENTER_KEY:
  32012.           printf( "What a boring selection...\n" );
  32013.           break;
  32014.        default:
  32015.           printf( "Bye bye." );
  32016.           break;
  32017.     }
  32018.  }
  32019.  
  32020.  
  32021.  SYSCALL.C
  32022.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\SYSCALL.C
  32023.  
  32024.  /* SYSCALL.C illustrates system calls to DOS and BIOS interrupts using
  32025.   * functions:
  32026.   *      intdos          intdosx         bdos
  32027.   *      int86           int86x          segread
  32028.   *
  32029.   * The int86x call is not specifically shown in the example, but it is
  32030.   * the same as intdosx except that an interrupt number must be supplied.
  32031.   */
  32032.  
  32033.  #include <dos.h>
  32034.  #include <stdio.h>
  32035.  #define LPT1 0
  32036.  
  32037.  union REGS inregs, outregs;
  32038.  struct SREGS segregs;
  32039.  
  32040.  main()
  32041.  {
  32042.      const char far *buffer = "Dollar-sign terminated string\n\r$";
  32043.      char far *p;
  32044.  
  32045.      /* Print a $-terminated string on the screen using DOS function 0x9. */
  32046.      inregs.h.ah = 0x9;
  32047.      inregs.x.dx = FP_OFF( buffer );
  32048.      segregs.ds = FP_SEG( buffer );
  32049.      intdosx( &inregs, &outregs, &segregs );
  32050.  
  32051.      /* Get DOS version using DOS function 0x30. */
  32052.      inregs.h.ah = 0x30;
  32053.      intdos( &inregs, &outregs );
  32054.      printf( "\nMajor: %d\tMinor: %d\tOEM number: %d\n\n",
  32055.              outregs.h.al, outregs.h.ah, outregs.h.bh );
  32056.  
  32057.      segread( &segregs );
  32058.      printf( "Segments:\n\tCS\t%.4x\n\tDS\t%.4x\n\tES\t%.4x\n\tSS\t%.4x\n\n",
  32059.              segregs.cs, segregs.ds, segregs.es, segregs.ss );
  32060.  
  32061.      /* Make sure printer is available. Fail if any error bit is on,
  32062.       * or if either operation bit is off.
  32063.       */
  32064.      inregs.h.ah = 0x2;
  32065.      inregs.x.dx = LPT1;
  32066.      int86( 0x17, &inregs, &outregs );
  32067.      if(  (outregs.h.ah & 0x29) || !(outregs.h.ah & 0x80) ||
  32068.                                    !(outregs.h.ah & 0x10) )
  32069.          printf( "Printer not available." );
  32070.      else
  32071.      {
  32072.          /* Output a string to the printer using DOS function 0x5. */
  32073.          for( p = buffer; *p != '$'; p++ )
  32074.              bdos( 0x05, *p, 0 );
  32075.  
  32076.          /* Do print screen. */
  32077.          inregs.h.ah = 0x05;
  32078.          int86( 0x05, &inregs, &outregs );
  32079.      }
  32080.  }
  32081.  
  32082.  
  32083.  SYSINFO.C
  32084.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\SYSINFO.C
  32085.  
  32086.  /* SYSINFO.C illustrates miscellaneous DOS and BIOS status functions
  32087.   * including:
  32088.   *      _dos_getdrive       _dos_setdrive       _dos_getdiskfree
  32089.   *      _bios_memsize       _bios_equiplist     _bios_printer
  32090.   *
  32091.   * See DISK.C for another example of _dos_getdiskfree.
  32092.   *
  32093.   * Also illustrated:
  32094.   *      union               bitfield struct
  32095.   */
  32096.  
  32097.  #include <dos.h>
  32098.  #include <bios.h>
  32099.  #include <conio.h>
  32100.  #include <stdio.h>
  32101.  #define LPT1 0
  32102.  
  32103.  main()
  32104.  {
  32105.      struct diskfree_t drvinfo;
  32106.      unsigned drive, drivecount, memory, pstatus;
  32107.      union
  32108.      {                                   /* Access equiment either as:    */
  32109.          unsigned u;                     /*   unsigned or                 */
  32110.          struct                          /*   bit fields                  */
  32111.          {
  32112.              unsigned diskflag : 1;      /* Diskette drive installed?     */
  32113.              unsigned coprocessor : 1;   /* Coprocessor? (except on PC)   */
  32114.              unsigned sysram : 2;        /* Ram on system board           */
  32115.              unsigned video : 2;         /* Startup video mode            */
  32116.              unsigned disks : 2;         /* Drives 00=1, 01=2, 10=3, 11=4 */
  32117.              unsigned dma : 1;           /* 0=Yes, 1=No (1 for PC Jr.)    */
  32118.              unsigned comports : 3;      /* Serial ports                  */
  32119.              unsigned game : 1;          /* Game adapter installed?       */
  32120.              unsigned modem : 1;         /* Internal modem?               */
  32121.              unsigned printers : 2;      /* Number of printers            */
  32122.          } bits;
  32123.      } equip;
  32124.      static char y[] = "YES", n[] = "NO";
  32125.  
  32126.      /* Get current drive. */
  32127.      _dos_getdrive( &drive );
  32128.      printf( "Current drive:\t\t\t%c:\n", 'A' + drive - 1 );
  32129.  
  32130.      /* Set drive to current drive in order to get number of drives. */
  32131.      _dos_setdrive( drive, &drivecount );
  32132.  
  32133.      _dos_getdiskfree( drive, &drvinfo );
  32134.      printf( "Disk space free:\t\t%ld\n",
  32135.              (long)drvinfo.avail_clusters *
  32136.              drvinfo.sectors_per_cluster *
  32137.              drvinfo.bytes_per_sector );
  32138.  
  32139.      /* Get new drive and number of logical drives in system. */
  32140.      _dos_getdrive( &drive );
  32141.      printf( "Number of logical drives:\t%d\n", drivecount );
  32142.  
  32143.      memory = _bios_memsize();
  32144.      printf( "Memory:\t\t\t\t%dK\n", memory );
  32145.  
  32146.      equip.u = _bios_equiplist();
  32147.  
  32148.      printf( "Disk drive installed:\t\t%s\n", equip.bits.diskflag ? y : n );
  32149.      printf( "Coprocessor installed:\t\t%s\n", equip.bits.coprocessor ? y : n
  32150.      printf( "Game adapter installed:\t\t%s\n", equip.bits.game ? y : n );
  32151.      printf( "Serial ports:\t\t\t%d\n", equip.bits.comports );
  32152.      printf( "Number of printers:\t\t%d\n", equip.bits.printers );
  32153.  
  32154.      /* Fail if any error bit is on, or if either operation bit is off. */
  32155.      pstatus = _bios_printer( _PRINTER_STATUS, LPT1, 0 );
  32156.      if( (pstatus & 0x29) || !(pstatus & 0x80) || !(pstatus & 0x10) )
  32157.          pstatus = 0;
  32158.      else
  32159.          pstatus = 1;
  32160.      printf( "Printer available:\t\t%s\n", pstatus ? y : n );
  32161.  }
  32162.  
  32163.  
  32164.  
  32165.  TABLE.C
  32166.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\TABLE.C
  32167.  
  32168.  /* TABLE.C illustrates reading and writing formatted file data using
  32169.   * functions:
  32170.   *      fprintf         fscanf
  32171.   */
  32172.  
  32173.  #include <stdio.h>
  32174.  #include <io.h>
  32175.  #include <fcntl.h>
  32176.  #include <sys\types.h>
  32177.  #include <sys\stat.h>
  32178.  #include <stdlib.h>
  32179.  
  32180.  main()
  32181.  {
  32182.      char buf[128];
  32183.      FILE *ftable;
  32184.      long l, tl;
  32185.      float fp, tfp;
  32186.      int  i, c = 'A';
  32187.  
  32188.      /* Open an existing file for reading. Fail if file doesn't exist. */
  32189.      if( (ftable = fopen( "table.smp", "r")) != NULL )
  32190.      {
  32191.          /* Read data from file and total it. */
  32192.          for( i = 0, tl = 0, tfp = 0.0; i < 10; i++ )
  32193.          {
  32194.              fscanf( ftable, "\t%s %c: %ld %f\n", buf, &c, &l, &fp );
  32195.              tl += l;
  32196.              tfp += fp;
  32197.              printf( "\t%s %c: %7ld %9.2f\n", buf, c, l, fp );
  32198.          }
  32199.          printf( "\n\tTotal:  %7ld %9.2f\n", tl, tfp );
  32200.      }
  32201.      else
  32202.      {
  32203.          /* File did not exist. Create it for writing. */
  32204.          if( (ftable = fopen( "table.smp", "w" )) == NULL )
  32205.              exit( 1 );
  32206.  
  32207.          /* Write table to file. */
  32208.          for( i = 0, l = 99999, fp = 3.14; i < 10; i++ )
  32209.              fprintf( ftable, "\tLine %c: %7ld %9.2f\n",
  32210.                       c++, l /= 2, fp *= 2 );
  32211.  
  32212.          printf( "Created table file. Run again to read it.\n" );
  32213.      }
  32214.      fclose( ftable );
  32215.      exit( 0 );
  32216.  }
  32217.  
  32218.  
  32219.  TEMPNAME.C
  32220.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\TEMPNAME.C
  32221.  
  32222.  /* TEMPNAME.C illustrates:
  32223.   *      tmpnam          tempnam
  32224.   */
  32225.  
  32226.  #include <stdio.h>
  32227.  
  32228.  main()
  32229.  {
  32230.      char *name1, *name2;
  32231.      int c;
  32232.  
  32233.      /* Create several temporary file names in the current directory. */
  32234.      for( c = 0; c < 5; c++ )
  32235.          if( (name1 = tmpnam( NULL )) != NULL )
  32236.              printf( "%s is a safe temporary file name.\n", name1 );
  32237.  
  32238.      /* Create a temporary file name with prefix TEMP and place it in
  32239.       * the first of these directories that exists:
  32240.       *   1. TMP environment directory
  32241.       *   2. C:\TEMPFILE
  32242.       *   3. P_tmpdir directory (defined in stdio.h)
  32243.       */
  32244.      if( (name2 = tempnam( "C:\\TEMPFILE", "TEMP" )) != NULL )
  32245.          printf( "%s is a safe temporary file name.\n", name2 );
  32246.  
  32247.  }
  32248.  
  32249.  
  32250.  TEXT.C
  32251.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\TEXT.C
  32252.  
  32253.  /* TEXT.C illustrates text output functions including:
  32254.   *    _gettextcolor   _getbkcolor   _gettextposition   _outtext
  32255.   *    _settextcolor   _setbkcolor   _settextposition   _clearscreen
  32256.   *
  32257.   * See MODES.C for another use of _outtext and WINDOW.C for another
  32258.   * use of _clearscreen.
  32259.   */
  32260.  
  32261.  #include <conio.h>
  32262.  #include <stdio.h>
  32263.  #include <graph.h>
  32264.  
  32265.  char buffer [80];
  32266.  
  32267.  main()
  32268.  {
  32269.      short blink, fgd, oldfgd;
  32270.      long bgd, oldbgd;
  32271.      struct rccoord oldpos;
  32272.  
  32273.      /* Save original foreground, background, and text position. */
  32274.      oldfgd = _gettextcolor();
  32275.      oldbgd = _getbkcolor();
  32276.      oldpos = _gettextposition();
  32277.      _clearscreen( _GCLEARSCREEN );
  32278.  
  32279.      /* First time no blink, second time blinking. */
  32280.      for( blink = 0; blink <= 16; blink += 16 )
  32281.      {
  32282.  
  32283.          /* Loop through 8 background colors. */
  32284.          for( bgd = 0; bgd < 8; bgd++ )
  32285.          {
  32286.              _setbkcolor( bgd );
  32287.              _settextposition( (short)bgd + ((blink / 16) * 9) + 3, 1 );
  32288.              _settextcolor( 7 );
  32289.              sprintf(buffer, "Back: %d Fore:", bgd );
  32290.              _outtext( buffer );
  32291.  
  32292.              /* Loop through 16 foreground colors. */
  32293.              for( fgd = 0; fgd < 16; fgd++ )
  32294.              {
  32295.                  _settextcolor( fgd + blink );
  32296.                  sprintf( buffer, " %2d ", fgd + blink );
  32297.                  _outtext( buffer );
  32298.              }
  32299.          }
  32300.      }
  32301.      getch();
  32302.  
  32303.      /* Restore original foreground and background. */
  32304.      _settextcolor( oldfgd );
  32305.      _setbkcolor( oldbgd );
  32306.      _clearscreen( _GCLEARSCREEN );
  32307.      _settextposition( oldpos.row, oldpos.col );
  32308.  }
  32309.  
  32310.  
  32311.  TIMES.C
  32312.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\TIMES.C
  32313.  
  32314.  /* TIMES.C illustrates various time and date functions including:
  32315.   *      time            ftime           ctime
  32316.   *      localtime       asctime         gmtime          mktime
  32317.   *      _strtime        _strdate        tzset
  32318.   *
  32319.   * Also the global variable:
  32320.   *      tzname
  32321.   */
  32322.  
  32323.  #include <time.h>
  32324.  #include <stdio.h>
  32325.  #include <sys\types.h>
  32326.  #include <sys\timeb.h>
  32327.  #include <string.h>
  32328.  
  32329.  main()
  32330.  {
  32331.      char timebuf[9], datebuf[9];
  32332.      static char ampm[] = "AM";
  32333.      time_t ltime;
  32334.      struct timeb tstruct;
  32335.      struct tm *today, *tomorrow, *gmt;
  32336.  
  32337.      /* Set time zone from TZ environment variable. If TZ is not set,
  32338.       * PST8PDT is used (Pacific standard time, daylight savings).
  32339.       */
  32340.      tzset();
  32341.  
  32342.      /* Get Xenix-style time and display as number and string. */
  32343.      time( <ime );
  32344.      printf( "Time in seconds since GMT 1/1/70:\t%ld\n", ltime );
  32345.      printf( "Xenix time and date:\t\t\t%s", ctime( <ime ) );
  32346.  
  32347.      /* Display GMT. */
  32348.      gmt = gmtime( <ime );
  32349.      printf( "Greenwich Mean Time:\t\t\t%s", asctime( gmt ) );
  32350.  
  32351.      /* Convert to local time structure and adjust for PM if necessary. */
  32352.      today = localtime( <ime );
  32353.      if( today->tm_hour > 12 )
  32354.      {
  32355.          strcpy( ampm, "PM" );
  32356.          today->tm_hour -= 12;
  32357.      }
  32358.      /* Note how pointer addition is used to skip the first 11 characters
  32359.       * and printf is used to trim off terminating characters.
  32360.       */
  32361.      printf( "12-hour time:\t\t\t\t%.8s %s\n",
  32362.              asctime( today ) + 11, ampm );
  32363.  
  32364.      /* Make tomorrow's time. */
  32365.      *tomorrow = *today;
  32366.      tomorrow->tm_mday++;
  32367.      if( mktime( tomorrow ) != (time_t)-1 )
  32368.          printf( "Tomorrow's date:\t\t\t%d/%d/%.2d\n",
  32369.                  tomorrow->tm_mon + 1, tomorrow->tm_mday, tomorrow->tm_year );
  32370.  
  32371.      /* Display DOS date and time. */
  32372.      _strtime( timebuf );
  32373.      printf( "DOS time:\t\t\t\t%s\n", timebuf );
  32374.      _strdate( datebuf );
  32375.      printf( "DOS date:\t\t\t\t%s\n", datebuf );
  32376.  
  32377.      /* Print additional time information. */
  32378.      ftime( &tstruct );
  32379.      printf( "Plus miliseconds:\t\t\t%u\n", tstruct.millitm );
  32380.      printf( "Zone difference in seconds from GMT:\t%u\n", tstruct.timezone );
  32381.      printf( "Time zone name:\t\t\t\t%s\n", tzname[0] );
  32382.      printf( "Daylight savings:\t\t\t%s\n", tstruct.dstflag ? "YES" : "NO" );
  32383.  }
  32384.  
  32385.  
  32386.  TOKEN.C
  32387.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\TOKEN.C
  32388.  
  32389.  /* TOKEN.C illustrates tokenizing and searching for any of several
  32390.   * characters. Functions illustrated include:
  32391.   *      strcspn         strspn          strpbrk         strtok
  32392.   */
  32393.  
  32394.  #include <string.h>
  32395.  #include <stdio.h>
  32396.  
  32397.  main()
  32398.  {
  32399.      char string[100];
  32400.      static char vowels[] = "aeiouAEIOU", seps[] = " \t\n,";
  32401.      char *p;
  32402.      int  count;
  32403.  
  32404.      printf( "Enter a string: " );
  32405.      gets( string );
  32406.  
  32407.      /* Delete one word at a time. */
  32408.      p = string;
  32409.      while( *p )
  32410.      {
  32411.          printf( "String remaining: %s\n", p );
  32412.          p += strcspn( p, seps );    /* Find next separator     */
  32413.          p += strspn( p, seps );     /* Find next non-separator */
  32414.      }
  32415.  
  32416.      /* Count vowels. */
  32417.      p = string;
  32418.      count = 0;
  32419.      while( *(p - 1) )
  32420.      {
  32421.          p = strpbrk( p, vowels );   /* Find next vowel         */
  32422.          p++;
  32423.          count++;
  32424.      }
  32425.      printf( "\nVowels in string: %d\n\n", count - 1 );
  32426.  
  32427.      /* Break into tokens. */
  32428.      count = 0;
  32429.      p = strtok( string, seps );     /* Find first token        */
  32430.      while( p != NULL )
  32431.      {
  32432.          printf( "Token %d: %s\n", ++count, p );
  32433.          p = strtok( NULL, seps );   /* Find next token         */
  32434.      }
  32435.  }
  32436.  
  32437.  
  32438.  TOOLS.C
  32439.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\UTILITY\TOOLS.C
  32440.  
  32441.  /* TOOLS - Module containing several general functions that can be used
  32442.   * from any program. Include TOOLS.H to use.
  32443.   */
  32444.  
  32445.  #include <conio.h>
  32446.  #include <string.h>
  32447.  #include <time.h>
  32448.  #include <graph.h>
  32449.  #include <bios.h>
  32450.  #include "tools.h"
  32451.  
  32452.  /* delay - Pauses for a specified number of microseconds. Used to slow
  32453.   * life by delaying between generations.
  32454.   *
  32455.   * Params: wait - time in microseconds
  32456.   *
  32457.   * Return: None
  32458.   */
  32459.  void delay( clock_t wait )
  32460.  {
  32461.  
  32462.      clock_t t1, t2;
  32463.  
  32464.      if( !wait )
  32465.          return;
  32466.  
  32467.      t1 = wait + clock();
  32468.      do
  32469.      {
  32470.          t2 = clock();
  32471.      } while( t2 < t1 );
  32472.  }
  32473.  
  32474.  /* getkey - Gets a key from the keyboard. This routine distinguishes
  32475.   * between ASCII keys and function or control keys with different shift
  32476.   * states. It also accepts a flag to return immediately if no key is
  32477.   * available.
  32478.   *
  32479.   * Params: waitflag - Code to indicate how to handle keyboard buffer:
  32480.   *   NO_WAIT     Return 0 if no key in buffer, else return key
  32481.   *   WAIT        Return first key if available, else wait for key
  32482.   *   CLEAR_WAIT  Throw away any key in buffer and wait for new key
  32483.   *
  32484.   * Return: One of the following:
  32485.   *
  32486.   *   Keytype                                High Byte    Low Byte
  32487.   *   -------                                ---------    --------
  32488.   *   No key available (only with NO_WAIT)       0           0
  32489.   *   ASCII value                                0        ASCII code
  32490.   *   Unshifted function or keypad               1        scan code
  32491.   *   Shifted function or keypad                 2        scan code
  32492.   *   CTRL function or keypad                    3        scan code
  32493.   *   ALT function or keypad                     4        scan code
  32494.   *
  32495.   * Note:   getkey cannot return codes for keys not recognized by BIOS
  32496.   *         int 16, such as the CTRL-UP or the 5 key on the numeric keypad.
  32497.   */
  32498.  unsigned getkey( int waitflag )
  32499.  {
  32500.      unsigned inkey, shiftstate;
  32501.  
  32502.      /* If CLEAR_WAIT, drain the keyboard buffer. */
  32503.      if( waitflag == CLEAR_WAIT )
  32504.          while( _bios_keybrd( _KEYBRD_READY ) )
  32505.              _bios_keybrd( _KEYBRD_READ );
  32506.  
  32507.      /* If NO_WAIT, return 0 if there is no key ready. */
  32508.      if( !waitflag && !_bios_keybrd( _KEYBRD_READY ) )
  32509.          return FALSE;
  32510.  
  32511.      /* Get key code. */
  32512.      inkey = _bios_keybrd( _KEYBRD_READ );
  32513.  
  32514.      /* If low byte is not zero, its an ASCII key. Check scan code to see
  32515.       * if it's on the numeric keypad. If not, clear high byte and return.
  32516.       */
  32517.      if( inkey & 0x00ff )
  32518.          if( (inkey >> 8) < 69 )
  32519.              return( inkey & 0x00ff );
  32520.  
  32521.      /* For function keys and numeric keypad, put scan code in low byte
  32522.       * and shift state codes in high byte.
  32523.       */
  32524.      inkey >>= 8;
  32525.      shiftstate = _bios_keybrd( _KEYBRD_SHIFTSTATUS ) & 0x000f;
  32526.      switch( shiftstate )
  32527.      {
  32528.          case 0:
  32529.              return( 0x0100 | inkey );  /* None (1)    */
  32530.          case 1:
  32531.          case 2:
  32532.          case 3:
  32533.              return( 0x0200 | inkey );  /* Shift (2)   */
  32534.          case 4:
  32535.              return( 0x0300 | inkey );  /* Control (3) */
  32536.          case 8:
  32537.              return( 0x0400 | inkey );  /* Alt (4)     */
  32538.      }
  32539.  }
  32540.  
  32541.  
  32542.  TOUCH1.C
  32543.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\TOUCH1.C
  32544.  
  32545.  /* TOUCH.C illustrates wild card handling and changing file time and
  32546.   * attribute. Functions used include:
  32547.   *      _dos_findfirst      _dos_findnext
  32548.   *      utime               chmod
  32549.   */
  32550.  
  32551.  #include <stdlib.h>
  32552.  #include <stdio.h>
  32553.  #include <conio.h>
  32554.  #include <ctype.h>
  32555.  #include <dos.h>
  32556.  #include <io.h>
  32557.  #include <sys\types.h>
  32558.  #include <sys\utime.h>
  32559.  #include <sys\stat.h>
  32560.  
  32561.  void fileinfo( struct find_t *find );
  32562.  char *timestr( unsigned d, char *buf );
  32563.  char *datestr( unsigned d, char *buf );
  32564.  
  32565.  main( int argc, char *argv[] )
  32566.  {
  32567.      struct find_t find;
  32568.  
  32569.      /* Find first matching file, then find additional matches. */
  32570.      if( !_dos_findfirst( argv[1], 0xffff, &find ) )
  32571.          fileinfo( &find );
  32572.      else
  32573.      {
  32574.          printf( "  SYNTAX: TOUCH <wildfilespec>" );
  32575.          return 1;
  32576.      }
  32577.      while( !_dos_findnext( &find ) )
  32578.          fileinfo( &find );
  32579.  }
  32580.  
  32581.  void fileinfo( struct find_t *pfind )
  32582.  {
  32583.      char timebuf[10], datebuf[10], *pkind;
  32584.      int ch;
  32585.  
  32586.      datestr( pfind->wr_date, datebuf );
  32587.      timestr( pfind->wr_time, timebuf );
  32588.  
  32589.      if( pfind->attrib & _A_SUBDIR )
  32590.          pkind = "Directory";
  32591.      else if( pfind->attrib & _A_VOLID )
  32592.          pkind = "Label";
  32593.      else
  32594.          pkind = "File";
  32595.  
  32596.      printf( "%-12s   %6ld   %8s   %9s   %-9s    %c %c %c %c\n",
  32597.              pfind->name, pfind->size, timebuf, datebuf, pkind,
  32598.              (pfind->attrib & _A_RDONLY) ? 'R' : ' ',
  32599.              (pfind->attrib & _A_HIDDEN) ? 'H' : ' ',
  32600.              (pfind->attrib & _A_SYSTEM) ? 'S' : ' ',
  32601.              (pfind->attrib & _A_ARCH) ? 'A' : ' ' );
  32602.  
  32603.      printf( "(T)ime update   (R)ead only   (Q)uit   Any other next\n" );
  32604.      ch = getch();
  32605.      switch( toupper( ch ) )
  32606.      {
  32607.          case 'T':               /* Set to current time */
  32608.              utime( pfind->name, NULL );
  32609.              break;
  32610.          case 'R':               /* Toggle read only */
  32611.              if( pfind->attrib & _A_RDONLY )
  32612.                  chmod( pfind->name, S_IWRITE );
  32613.              else
  32614.                  chmod( pfind->name, S_IREAD );
  32615.              break;
  32616.          case 'Q':               /* Quit */
  32617.              exit( 1 );
  32618.      }
  32619.  }
  32620.  
  32621.  /* Take unsigned date in the format:    fedcba9876543210
  32622.   * (year is 1980 - year)                yyyyyyymmmmddddd
  32623.   * Change to a 9-byte string:           mm/dd/yy
  32624.   */
  32625.  char *datestr( unsigned d, char *buf )
  32626.  {
  32627.      sprintf( buf, "%2.2d/%02.2d/%02.2d",
  32628.               (d >> 5) & 0x0f, d & 0x1f, (d >> 9) + 80 );
  32629.      return buf;
  32630.  }
  32631.  
  32632.  /* Take unsigned time in the format:                fedcba9876543210
  32633.   * (hours and minutes 0-based)                      hhhhhmmmmmmsssss
  32634.   * Change to a 9-byte string (ignore seconds):      hh:mm ?m
  32635.   */
  32636.  char *timestr( unsigned t, char *buf )
  32637.  {
  32638.      int h = (t >> 11) & 0x1f, m = (t >> 5) & 0x3f;
  32639.  
  32640.      sprintf( buf, "%2.2d:%02.2d %cm", h % 12, m,  h > 11 ? 'p' : 'a' );
  32641.      return buf;
  32642.  }
  32643.  
  32644.  
  32645.  TRIG.C
  32646.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\MATH\TRIG.C
  32647.  
  32648.  /* TRIG.C illustrates trignometric functions including:
  32649.   *    cos          cosh           acos
  32650.   *    sin          sinh           asin
  32651.   *    tan          tanh           atan          atan2
  32652.   */
  32653.  
  32654.  #include <math.h>
  32655.  #include <float.h>
  32656.  #include <stdio.h>
  32657.  #include <stdlib.h>
  32658.  
  32659.  main()
  32660.  {
  32661.      double x, rx, y;
  32662.  
  32663.      do
  32664.      {
  32665.          printf( "\nEnter a real number between 1 and -1: " );
  32666.          scanf( "%lf", &x );
  32667.      } while( (x > 1.0) || (x < -1.0) );
  32668.  
  32669.      printf("\nFunction\tResult for %2.2f\n\n", x );
  32670.      if( (x <= 1.0) && (x >= -1.0) )
  32671.      {
  32672.          printf( "acos\t\t%2.2f\n", acos( x ) );
  32673.          printf( "asin\t\t%2.2f\n", asin( x ) );
  32674.      }
  32675.      if( (rx = cos( x )) && (errno != ERANGE) )
  32676.          printf( "cos\t\t%2.2f\n", rx );
  32677.      else
  32678.          errno = 0;
  32679.      if( (rx = sin( x )) && (errno != ERANGE) )
  32680.          printf( "sin\t\t%2.2f\n", rx );
  32681.      else
  32682.          errno = 0;
  32683.      if( (rx = cosh( x )) && (errno != ERANGE) )
  32684.          printf( "cosh\t\t%2.2f\n", rx );
  32685.      else
  32686.          errno = 0;
  32687.      if( (rx = sinh( x )) && (errno != ERANGE) )
  32688.          printf( "sinh\t\t%2.2f\n", rx );
  32689.      else
  32690.          errno = 0;
  32691.  
  32692.      printf( "\nEnter a real number of any size: " );
  32693.      scanf( "%lf", &x );
  32694.      printf("\nFunction\tResult for %2.2f\n\n", x );
  32695.      printf( "atan\t\t%2.2f\n", atan( x ) );
  32696.      if( (rx = tan( x )) && (errno != ERANGE) )
  32697.          printf( "tan\t\t%2.2f\n", rx );
  32698.      else
  32699.          errno = 0;
  32700.      printf( "tanh\t\t%2.2f\n", tanh( x ) );
  32701.  
  32702.      printf( "\nEnter another real number of any size: " );
  32703.      scanf( "%lf", &y );
  32704.      printf("\nFunction\tResult for %2.2f and %2.2f\n\n", x, y );
  32705.      if( rx = atan2( x, y ) )
  32706.          printf( "atan2\t\t%2.2f\n", rx );
  32707.      else
  32708.          errno = 0;
  32709.  }
  32710.  
  32711.  
  32712.  TRUTH.C
  32713.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\TRUTH.C
  32714.  
  32715.  /* TRUTH.C: Demonstrate true and false values. */
  32716.  
  32717.  #include <stdio.h>
  32718.  
  32719.  main()
  32720.  {
  32721.     printf( "C generates %d for true\n", 2 == 2 );
  32722.     printf( "C generates %d for false\n", 2 == 4 );
  32723.     if( -33 )
  32724.        printf( "C recognizes any nonzero value as true\n" );
  32725.  }
  32726.  
  32727.  
  32728.  TYPEIT.C
  32729.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\FILE\TYPEIT.C
  32730.  
  32731.  /* TYPEIT.C illustrates reassigning handles and streams using functions:
  32732.   *      freopen         dup             dup2
  32733.   *
  32734.   * The example also illustrates:
  32735.   *      setargv
  32736.   *
  32737.   * To make the program handle wild cards, link it with the SETARGV.OBJ
  32738.   * file. You can do this in the QC environment by creating a program list
  32739.   * containg TYPEIT.C and SETARGV.OBJ (include the path or put in current
  32740.   * directory). You must also turn off the Extended Dictionary flag
  32741.   * within the QC environment (Options-Make-Linker Flags) or use the /NOE
  32742.   * linker option outside the environment. For example:
  32743.   *    QCL typeit.c setargv /link /NOE
  32744.   */
  32745.  
  32746.  #include <stdio.h>
  32747.  #include <conio.h>
  32748.  #include <io.h>
  32749.  #include <process.h>
  32750.  
  32751.  main( int argc, char **argv )
  32752.  {
  32753.      FILE *ftmp;
  32754.      int htmp;
  32755.  
  32756.      /* Duplicate handle of stdin. Save the original to restore later. */
  32757.      htmp = dup( fileno( stdin ) );
  32758.  
  32759.      /* Process each command line argument. */
  32760.      while( *(++argv) != NULL )
  32761.      {
  32762.          /* Original stdin used for getch. */
  32763.          printf( "Press any key to display file: %s\n", *argv );
  32764.          getch();
  32765.  
  32766.          /* Reassign stdin to input file. */
  32767.          ftmp = freopen( *argv, "rb", stdin );
  32768.  
  32769.          if( (ftmp == NULL) || (htmp == -1 ) )
  32770.          {
  32771.              perror( "Can't reassign standard input" );
  32772.              exit( 1 );
  32773.          }
  32774.  
  32775.          /* Spawn MORE, which will receive the open input file as its standard
  32776.           * input. MORE can be the DOS MORE or the sample program MORE.C.
  32777.           */
  32778.          spawnvp( P_WAIT, "MORE", NULL );
  32779.  
  32780.          /* Reassign stdin back to original so that we can use the
  32781.           * original stdin to get a key.
  32782.           */
  32783.          dup2( htmp, fileno( stdin ) );
  32784.      }
  32785.      exit( 0 );
  32786.  }
  32787.  
  32788.  
  32789.  TYPES.C
  32790.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\TYPES.C
  32791.  
  32792.  /* TYPES.C: Illustrate basic data types. */
  32793.  
  32794.  #include <stdio.h>
  32795.  
  32796.  main()
  32797.  {
  32798.     char char_val        = 'a';
  32799.     int int_val               = 543;
  32800.     float float_val     = 11.1;
  32801.     double double_val   = 66.123456789;
  32802.     printf( "char_val   = %c\n", char_val );
  32803.     printf( "int_val    = %d\n", int_val );
  32804.     printf( "float_val  = %f\n", float_val );
  32805.     printf( "double_val = %2.9f\n", double_val );
  32806.  }
  32807.  
  32808.  
  32809.  UNGET.C
  32810.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\UNGET.C
  32811.  
  32812.  /* UNGET.C illustrates getting and ungetting characters from the console.
  32813.   * Functions illustrated include:
  32814.   *      getch           ungetch         putch
  32815.   */
  32816.  
  32817.  #include <conio.h>
  32818.  #include <stdio.h>
  32819.  #include <ctype.h>
  32820.  
  32821.  void skiptodigit( void );
  32822.  int getnum( void );
  32823.  
  32824.  main()
  32825.  {
  32826.      int c, array[10];
  32827.  
  32828.      /* Get five numbers from console. Then display them. */
  32829.      for( c = 0; c < 5; c++ )
  32830.      {
  32831.          skiptodigit();
  32832.          array[c] = getnum();
  32833.          printf( "\t" );
  32834.      }
  32835.      for( c  = 0; c < 5; c++ )
  32836.          printf( "\n\r%d", array[c] );
  32837.      printf( "\n" );
  32838.  }
  32839.  
  32840.  /* Convert digit characters into a number until a non-digit is received. */
  32841.  int getnum()
  32842.  {
  32843.      int ch, num =  0;
  32844.  
  32845.      while( isdigit( ch = getch() ) )
  32846.      {
  32847.          putch( ch );                        /* Display digit      */
  32848.          num = (num * 10) + ch  - '0';       /* Convert to number  */
  32849.      }
  32850.      ungetch( ch );                          /* Put non-digit back */
  32851.      return num;                             /* Return result      */
  32852.  }
  32853.  
  32854.  /* Throw away non-digit characters. */
  32855.  void skiptodigit()
  32856.  {
  32857.      int ch;
  32858.  
  32859.      while( !isdigit( ch = getch() ) )
  32860.          ;
  32861.      ungetch( ch );
  32862.  }
  32863.  
  32864.  
  32865.  VARARG.C
  32866.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\VARARG.C
  32867.  
  32868.  /* VARARG.C illustrates passing a variable number of arguments using the
  32869.   * following macros:
  32870.   *      va_start            va_arg              va_end
  32871.   *      va_list             va_decl (Unix only)
  32872.   */
  32873.  
  32874.  #include <stdio.h>
  32875.  ANSI            /* Comment out for UNIX version     */
  32876.  ANSI             /* ANSI compatible version          */
  32877.  #include <stdarg.h>
  32878.  int average( int first, ... );
  32879.                    /* UNIX compatible version          */
  32880.  #include <varargs.h>
  32881.  int average( va_list );
  32882.  #endif
  32883.  
  32884.  main()
  32885.  {
  32886.      /* Call with 3 integers. Minus -1 is used as terminator.  */
  32887.      printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );
  32888.  
  32889.      /* Call with 4 integers. */
  32890.      printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );
  32891.  
  32892.      /* Call with just -1 terminator. */
  32893.      printf( "Average is: %d\n", average( -1 ) );
  32894.  }
  32895.  
  32896.  /* Return the average of a variable list of integers. */
  32897.  ANSI             /* ANSI compatible version    */
  32898.  int average( int first, ... )
  32899.  {
  32900.      int count = 0, sum = 0, i = first;
  32901.      va_list marker;
  32902.  
  32903.      va_start( marker, first );      /* Initialize variable arguments */
  32904.      while( i != -1 )
  32905.      {
  32906.          sum += i;
  32907.          count++;
  32908.          i = va_arg( marker, int);
  32909.      }
  32910.      va_end( marker );               /* Reset variable arguments      */
  32911.      return( sum ? (sum / count) : 0 );
  32912.  }
  32913.        /* UNIX compatible version must use old-style definition */
  32914.  int average( va_alist )
  32915.  va_dcl
  32916.  {
  32917.      int i, count, sum;
  32918.      va_list marker;
  32919.  
  32920.      va_start( marker );             /* Initialize variable arguments */
  32921.      for( sum = count = 0; (i = va_arg( marker, int)) != -1;  count++ )
  32922.          sum += i;
  32923.      va_end( marker );               /* Reset variable arguments      */
  32924.      return( sum ? (sum / count) : 0 );
  32925.  }
  32926.  #endif
  32927.  
  32928.  
  32929.  VISIBLE.C
  32930.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\VISIBLE.C
  32931.  
  32932.  /* VISIBLE.C: Demonstrate visibility of variables.
  32933.  */
  32934.  
  32935.  #include <stdio.h>
  32936.  void be_bop( void );
  32937.  
  32938.  main()
  32939.  {
  32940.     int var1 = 10;
  32941.     be_bop();
  32942.  }
  32943.  
  32944.  void be_bop( void )
  32945.  {
  32946.     printf( "var1 = %d", var1 ); /* Error! */
  32947.  }
  32948.  
  32949.  
  32950.  VISIBLE1.C
  32951.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\VISIBLE1.C
  32952.  
  32953.  /* VISIBLE1.C: Demonstrate visibility of variables.
  32954.  */
  32955.  
  32956.  #include <stdio.h>
  32957.  
  32958.  void be_bop( int param );
  32959.  
  32960.  main()
  32961.  {
  32962.     int var1 = 10;
  32963.     be_bop( var1 );
  32964.  }
  32965.  
  32966.  void be_bop( int param )
  32967.  {
  32968.     printf( "%d\n", param );
  32969.  }
  32970.  
  32971.  
  32972.  VISIBLE2.C
  32973.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\VISIBLE2.C
  32974.  
  32975.  /* VISIBLE2.C: Demonstrate visibility of variables.
  32976.  */
  32977.  
  32978.  #include <stdio.h>
  32979.  
  32980.  void be_bop( int param );
  32981.  
  32982.  main()
  32983.  {
  32984.     be_bop( var1 ); /* Error! */
  32985.  }
  32986.  
  32987.  int var1 = 10;
  32988.  
  32989.  void be_bop( int param )
  32990.  {
  32991.     printf( "var1 = %d\n", param );
  32992.  }
  32993.  
  32994.  
  32995.  VOLUME.C
  32996.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\VOLUME.C
  32997.  
  32998.  /* VOLUME.C: Calculate sphere's volume. */
  32999.  
  33000.  #include <stdio.h>
  33001.  #define PI 3.14
  33002.  
  33003.  float sphere( int rad );
  33004.  
  33005.  main()
  33006.  {
  33007.     float volume;
  33008.     int radius = 3;
  33009.     volume = sphere( radius );
  33010.     printf( "Volume: %f\n", volume );
  33011.  }
  33012.  
  33013.  float sphere( int rad )
  33014.  {
  33015.     float result;
  33016.     result = rad * rad * rad;
  33017.     result = 4 * PI * result;
  33018.     result = result / 3;
  33019.     return result;
  33020.  }
  33021.  
  33022.  
  33023.  WHILE.C
  33024.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\WHILE.C
  33025.  
  33026.  /* WHILE.C: Demonstrate while loop. */
  33027.  
  33028.  #include <stdio.h>
  33029.  
  33030.  main()
  33031.  {
  33032.     int test = 10;
  33033.  
  33034.  while( test > 0 )
  33035.     {
  33036.        printf( "test = %d\n", test );
  33037.        test -= 2;
  33038.     }
  33039.  }
  33040.  
  33041.  
  33042.  WINDOW.C
  33043.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\WINDOW.C
  33044.  
  33045.  /* WINDOW.C illustrates windows and coordinate systems, using the
  33046.   * following functions:
  33047.   *    _setviewport   _setvieworg    _setcliprgn     _setwindow
  33048.   *    _rectangle     _rectangle_w   _rectangle_wxy  _clearscreen
  33049.   *    _ellipse       _ellipse_w     _ellipse_wxy
  33050.   *
  33051.   * Although not all illustrated here, functions ending in _w
  33052.   * are similar to _rectangle_w and _ellipse_w; functions ending
  33053.   * in _wxy are similar to _rectangle_wxy and _ellipse_wxy.
  33054.   */
  33055.  
  33056.  #include <conio.h>
  33057.  #include <graph.h>
  33058.  #include <stdlib.h>
  33059.  
  33060.  main()
  33061.  {
  33062.      short xhalf, yhalf, xquar, yquar;
  33063.      struct _wxycoord upleft, botright;
  33064.      struct videoconfig vc;
  33065.      short mode = _VRES16COLOR;
  33066.  
  33067.      while( !_setvideomode( mode ) )     /* Find best graphics mode   */
  33068.          mode--;
  33069.      if( mode == _TEXTMONO )
  33070.          exit( 1 );                      /* No graphics available     */
  33071.      _getvideoconfig( &vc );
  33072.  
  33073.      xhalf = vc.numxpixels / 2;
  33074.      yhalf = vc.numypixels / 2;
  33075.      xquar = xhalf / 2;
  33076.      yquar = yhalf / 2;
  33077.  
  33078.      /* First window - integer physical coordinates */
  33079.      _setviewport( 0, 0, xhalf - 1, yhalf - 1 );
  33080.      _rectangle( _GBORDER, 0,  0, xhalf - 1, yhalf - 1 );
  33081.      _ellipse( _GFILLINTERIOR, xquar / 4, yquar / 4,
  33082.                                xhalf - (xquar / 4), yhalf - (yquar / 4) );
  33083.      getch();
  33084.      _clearscreen( _GVIEWPORT );
  33085.      _rectangle( _GBORDER, 0,  0, xhalf - 1, yhalf - 1 );
  33086.  
  33087.      /* Second window - integer world coordinates with clip region */
  33088.      _setcliprgn( xhalf, 0, vc.numxpixels, yhalf );
  33089.      _setvieworg( xhalf + xquar - 1, yquar - 1 );
  33090.      _rectangle( _GBORDER, -xquar + 1, -yquar + 1, xquar, yquar );
  33091.      _ellipse( _GFILLINTERIOR, (-xquar * 3) / 4, (-yquar * 3) / 4,
  33092.                                (xquar * 3) / 4, (yquar * 3) / 4 );
  33093.      getch();
  33094.      _clearscreen( _GVIEWPORT );
  33095.      _rectangle( _GBORDER, -xquar + 1, -yquar + 1, xquar, yquar );
  33096.  
  33097.      /* Third window */
  33098.      _setviewport( xhalf, yhalf, vc.numxpixels - 1, vc.numypixels - 1 );
  33099.      _setwindow( 0, -4.0, -5.0, 4.0, 5.0 );
  33100.      _rectangle_w( _GBORDER, -4.0, -5.0, 4.0, 5.0 );
  33101.      _ellipse_w( _GFILLINTERIOR, -3.0, -3.5, 3.0, 3.5 );
  33102.      getch();
  33103.      _clearscreen( _GVIEWPORT );
  33104.      _rectangle_w( _GBORDER, -4.0, -5.0, 4.0, 5.0 );
  33105.  
  33106.      /* Fourth window */
  33107.      _setviewport( 0, yhalf, xhalf - 1, vc.numypixels - 1 );
  33108.      _setwindow( 0, -4.0, -5.0, 4.0, 5.0 );
  33109.      upleft.wx = -4.0;
  33110.      upleft.wy = -5.0;
  33111.      botright.wx = 4.0;
  33112.      botright.wy = 5.0;
  33113.      _rectangle_wxy( _GBORDER, &upleft, &botright );
  33114.      upleft.wx = -3.0;
  33115.      upleft.wy = -3.5;
  33116.      botright.wx = 3.0;
  33117.      botright.wy = 3.5;
  33118.      _ellipse_wxy( _GFILLINTERIOR, &upleft, &botright );
  33119.  
  33120.      getch();
  33121.      exit( !_setvideomode( _DEFAULTMODE ) );
  33122.  }
  33123.  
  33124.  
  33125.  WPRINTF.C
  33126.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\GRAPHICS\WPRINTF.C
  33127.  
  33128.  /* WPRINTF.C shows how to use vprintf functions to write new versions
  33129.   * of printf. Functions illustrated include:
  33130.   *      vsprintf        vprintf         vfprintf
  33131.   *
  33132.   * The vsprintf function is used in the example. The other variations
  33133.   * can be used similarly.
  33134.   */
  33135.  
  33136.  #include <stdio.h>
  33137.  #include <graph.h>
  33138.  #include <string.h>
  33139.  #include <stdarg.h>
  33140.  #include <malloc.h>
  33141.  
  33142.  int wprintf( short row, short col, short clr, long bclr, char *fmt, ... );
  33143.  
  33144.  main()
  33145.  {
  33146.      short fgd = 0;
  33147.      long  bgd = 0L;
  33148.  
  33149.      _clearscreen( _GCLEARSCREEN );
  33150.      _outtext( "Color text example:\n\n" );
  33151.  
  33152.      /* Loop through 8 background colors. */
  33153.      for( bgd = 0L; bgd < 8; bgd++ )
  33154.      {
  33155.          wprintf( (int)bgd + 3, 1, 7, bgd, "Back: %d Fore:", bgd );
  33156.  
  33157.          /* Loop through 16 foreground colors. */
  33158.          for( fgd = 0; fgd < 16; fgd++ )
  33159.              wprintf( -1, -1, fgd, -1L, " %2d ", fgd );
  33160.      }
  33161.  }
  33162.  
  33163.  /* Full-screen window version of printf that takes row, column, textcolor,
  33164.   * and background color as its first arguments, followed by normal printf
  33165.   * format strings (except that \t is not handled). You can specify -1 for
  33166.   * any of the first arguments to use the current value. The function returns
  33167.   * the number of characters printed, or a negative number for errors.
  33168.   */
  33169.  int wprintf( short row, short col, short clr, long bclr, char *fmt, ... )
  33170.  {
  33171.      struct  rccoord tmppos;
  33172.      short   ret, size;
  33173.      va_list marker;
  33174.      char    *buffer;
  33175.  
  33176.      /* It's probably safe to use a buffer 512 bytes long or five times
  33177.       * longer than the format string.
  33178.       */
  33179.      size = strlen( fmt );
  33180.      size = (size > 512) ? 512 : size * 5;
  33181.      if( (buffer = (char *)malloc( size )) == NULL )
  33182.          return -1;
  33183.  
  33184.      /* Set text position. */
  33185.      tmppos = _gettextposition();
  33186.      if( row < 1 )
  33187.          row = tmppos.row;
  33188.      if( col < 1 )
  33189.          col = tmppos.col;
  33190.      _settextposition( row, col );
  33191.  
  33192.      /* Set foreground and background colors. */
  33193.      if( clr >= 0 )
  33194.          _settextcolor( clr );
  33195.      if( bclr >= 0 )
  33196.          _setbkcolor( bclr );
  33197.  
  33198.      /* Write text to a string and output the string. */
  33199.      va_start( marker, fmt );
  33200.      ret = vsprintf( buffer, fmt, marker );
  33201.      va_end( marker );
  33202.      _outtext( buffer );
  33203.      free( buffer );
  33204.      return ret;
  33205.  }
  33206.  
  33207.  
  33208.  WRAP.C
  33209.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\WRAP.C
  33210.  
  33211.  /* WRAP.C illustrates:
  33212.   *      _wrapon
  33213.   */
  33214.  
  33215.  #include <conio.h>
  33216.  #include <graph.h>
  33217.  
  33218.  main()
  33219.  {
  33220.      _wrapon( _GWRAPON );
  33221.      while( !kbhit() )
  33222.          _outtext( "Wrap on! " );
  33223.  
  33224.      getch();
  33225.      _clearscreen( _GCLEARSCREEN );
  33226.      _wrapon( _GWRAPOFF );
  33227.      while( !kbhit() )
  33228.          _outtext( "Wrap off!" );
  33229.      getch();
  33230.  }
  33231.  
  33232.  
  33233.  WRFILE.C
  33234.  CD-ROM Disc Path:   \SAMPCODE\C\OTHER\LEARN\WRFILE.C
  33235.  
  33236.  /* WRFILE.C: Creates and writes to a disk file. */
  33237.  
  33238.  #include <stdio.h>
  33239.  
  33240.  main()
  33241.  {
  33242.     FILE *fp;
  33243.  
  33244.     if( (fp = fopen( "c:\\testfile.asc","w" )) != NULL )
  33245.     {
  33246.        fputs( "Example string", fp );
  33247.        fputc( '\n', fp );
  33248.        fclose( fp );
  33249.     }
  33250.     else
  33251.        printf( "error message\n" );
  33252.  }
  33253.  ALDE Public Domain Sample Code
  33254.  
  33255.  
  33256.  2UP.C
  33257.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\UTIL\CUG236\2UP.C
  33258.  
  33259.  /*
  33260.          HEADER:                CUG236;
  33261.          TITLE:                Multi-Column Output Stacker;
  33262.          DATE:                05/23/87;
  33263.          DESCRIPTION:        "Formats text into one or more columns.  Has seve
  33264.                          command line parameters that can be set.";
  33265.          KEYWORDS:        Software tools, Text filters, Text formatters;
  33266.          FILENAME:        2UP.C;
  33267.          WARNINGS:        "The author claims copyrights and authorizes
  33268.                          non-commercial use only.";
  33269.          AUTHORS:        Eugene H. Mallory, William C. Colley III;
  33270.          COMPILERS:        vanilla;
  33271.  */
  33272.  
  33273.  /*********************************************************************
  33274.  *                                2UP                                     *
  33275.  **********************************************************************
  33276.  *                   COPYRIGHT 1983 EUGENE H. MALLORY                     *
  33277.  *                                                                     *
  33278.  * Hacked from BDS C to portable C 23 MAY 1987 by W. C. Colley, III.  *
  33279.  * This involved removing the -w option as it relies upon a non-             *
  33280.  * portable direct console I/O call.  In the process, I also reworked *
  33281.  * the thing into standard C puncutation and optimized various             *
  33282.  * sections of code so that even a stupid compiler can make a good    *
  33283.  * executable from it.                                                     *
  33284.  *                                                                     *
  33285.  *********************************************************************/
  33286.  
  33287.  #include <stdio.h>
  33288.  
  33289.  #define MAXW                132
  33290.  
  33291.  /*  Portability Note:  8-bit systems often don't have header file
  33292.      ctype.h.  If your system doesn't have it, uncomment the #define
  33293.      NO_CTYPE_H.
  33294.  
  33295.  /*
  33296.  #define         NO_CTYPE_H
  33297.  */
  33298.  
  33299.  /*  Portability Note:  Some older compilers don't know the new data
  33300.      type void.        If yours is one of these compilers, uncomment the
  33301.      following #define:
  33302.  
  33303.  /*
  33304.  #define void                int
  33305.  */
  33306.  
  33307.  #ifdef         NO_CTYPE_H
  33308.  int isdigit();
  33309.  #else
  33310.  #include <ctype.h>
  33311.  #endif
  33312.  
  33313.  #ifndef TRUE
  33314.  #define TRUE  1
  33315.  #endif
  33316.  
  33317.  #ifndef FALSE
  33318.  #define FALSE 0
  33319.  #endif
  33320.  
  33321.  char string[MAXW + 2];
  33322.  char array[90][MAXW + 2];
  33323.  int ncol = 0, col = 0, len = 0, margin = 0, space = 0, width;
  33324.  int bm = 0, doneflag = FALSE, tm = 0;
  33325.  void exit();
  33326.  
  33327.  int main(argc,argv)
  33328.  int argc;
  33329.  char **argv;
  33330.  {
  33331.      int i, j, k, atoi();
  33332.      void error(), strmov();
  33333.  
  33334.  /*********************************************************************
  33335.  ***                  ARGUMENT PROCESSING                                   **
  33336.  *********************************************************************/
  33337.  
  33338.      char c, *ss;
  33339.      int ii, jj, optionerr;
  33340.  
  33341.      optionerr = 0;
  33342.      for (ii = argc - 1; ii > 0; --ii)
  33343.          if (argv[ii][0] == '-') {
  33344.              for (ss = &argv[ii][1]; *ss != '\0';) {
  33345.                  c = *ss++;
  33346.                  switch (toupper(c)) {
  33347.                      case 'L':        len = atoi(ss);         break;
  33348.  
  33349.                      case 'C':        col= atoi(ss);        break;
  33350.  
  33351.                      case 'M':        margin = atoi(ss);  break;
  33352.  
  33353.                      case 'T':        tm = atoi(ss);        break;
  33354.  
  33355.                      case 'B':        bm = atoi(ss);        break;
  33356.  
  33357.                      case 'S':        space = atoi(ss);  break;
  33358.  
  33359.                      case 'N':        ncol= atoi(ss);         break;
  33360.  
  33361.                      case 'H':        optionerr = TRUE;  break;
  33362.  
  33363.                      default:        fprintf(stderr,"2UP: Illegal option %c.\n
  33364.                                  optionerr = TRUE;  break;
  33365.                  }
  33366.                  while (isdigit(*ss)) ss++;
  33367.              }
  33368.              for (jj = ii; jj < (argc-1); ++jj) argv[jj] = argv[jj + 1];
  33369.              argc--;
  33370.          }
  33371.      if (optionerr) {
  33372.          fprintf(stderr,"2UP:   Legal options are:\n");
  33373.          fprintf(stderr,"-Ln    Page length.\n");
  33374.          fprintf(stderr,"-Cn    Column width .\n");
  33375.          fprintf(stderr,"-Mn    Margin.\n");
  33376.          fprintf(stderr,"-Tn    Top margin.\n");
  33377.          fprintf(stderr,"-Bn    Bottom margin.\n");
  33378.          fprintf(stderr,"-Sn    Space between columns.\n");
  33379.          fprintf(stderr,"-Nn    Number of columns.\n");
  33380.          return !0;
  33381.      }
  33382.      if (ncol == 0) ncol = 2;
  33383.      if (len == 0) len = 66;
  33384.      if (col == 0) col = (80 - margin - space * (ncol - 1)) / ncol;
  33385.      if (len > 88) error("2UP: Too long a page, 88 lines is maximum.");
  33386.      if ((margin + ncol * col + (ncol - 1) * space) > MAXW)
  33387.          error("2UP: Total width exceeds 132.");
  33388.      len = len - tm - bm;
  33389.      if (len < 1) error("2UP: Insufficient length.");
  33390.  
  33391.  /*********************************************************************
  33392.  ***                     END OF ARGUMENT PROCESSING
  33393.  *********************************************************************/
  33394.  /*********************************/
  33395.  /*        MAIN LOOP                 */
  33396.  /*********************************/
  33397.      width = margin + ncol * col + (ncol - 1) * space;
  33398.      do {
  33399.          for (i = 1; i <= len; ++i)
  33400.              for (j = 1;j <= MAXW + 1; ++j) array[i][j] = ' ';
  33401.          for (k = 0; k < ncol; ++k) {
  33402.              for (i = 1; i <= len; ++i) {
  33403.                  if (gets(string))
  33404.                      strmov(&array[i][margin+k*col+k*space+1],string,col);
  33405.                  else {
  33406.                      if (!k && i == 1) return 0;
  33407.                      doneflag = TRUE;  goto end_of_file;
  33408.                  }
  33409.              }
  33410.          }
  33411.  end_of_file:
  33412.          for (i = 1; i <= tm; ++i) puts("\n");
  33413.          for (i = 1; i <= len; ++i) {
  33414.              for (j = MAXW + 1; j; --j)
  33415.                  if (array[i][j] != ' ' || j == 1) {
  33416.                      array[i][j+1] = 0;        break;
  33417.                  }
  33418.              puts(&array[i][1]);
  33419.          }
  33420.          for (i = bm; i; --i) puts("\n");
  33421.      } while (!doneflag);
  33422.      return 0;
  33423.  }
  33424.  
  33425.  void strmov(s1,s2,n)
  33426.  char *s1,*s2;
  33427.  int n;
  33428.  {
  33429.      char c;
  33430.  
  33431.      while (n--) {
  33432.          if (!(c = *s2++) || c == '\n') break;
  33433.          *s1++ = c;
  33434.      }
  33435.  }
  33436.  
  33437.  void error(msg)
  33438.  char *msg;
  33439.  {
  33440.      fprintf(stderr,"%s\n",msg);
  33441.      exit(!0);
  33442.  }
  33443.  
  33444.  
  33445.  ABORT.C
  33446.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\LIB\DLIBSSRC\ABORT.C
  33447.  
  33448.  #include <stdio.h>
  33449.  
  33450.  void abort()
  33451.  /*
  33452.   *        Prints the message "Abnormal program termination" to stderr and
  33453.   *        calls _exit() with a status code of 3.
  33454.   */
  33455.  {
  33456.          fputs("Abnormal program termination\n", stderr);
  33457.          fflush(stderr);
  33458.          _exit(3);
  33459.  }
  33460.  
  33461.  
  33462.  ABOUT.C
  33463.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\ZED\ABOUT\ABOUT.C
  33464.  
  33465.  /*  about.c
  33466.  *
  33467.  *   Usage:           about  <name>  [<catfile>]
  33468.  *
  33469.  *   Examples:        about calloc
  33470.  *                    about *
  33471.  *                    about * b:c.cat
  33472.  *                    about fourier b:math.dat
  33473.  *
  33474.  *    Description:    For each line in <catfile> beginning as ":<name>",
  33475.  *                    successive lines are displayed until the next line
  33476.  *                    begins with ":";  if <name> is *, all entries are
  33477.  *                    displayed;  <catfile> defaults to "about.dat".
  33478.  *
  33479.  *    Purpose:        The file about.dat contains synopses of C functions,
  33480.  *                    thus making "about" an elementary "help facility".
  33481.  *
  33482.  *                    However, <catfile> may be any list of :<name>'s of
  33483.  *                    interest, with each name on a separate line, and
  33484.  *                    each followed by its respective text to be displayed.
  33485.  *
  33486.  *    Limitations:    A simple linear search is used, so probably no more
  33487.  *                    than a few hundred names can be handled usefully.
  33488.  *
  33489.  *    Language:       C (DeSmet 2.4)
  33490.  *
  33491.  *    Author:         R. E. Sawyer
  33492.  *                    3620 Spencer St. 30, Torrance, CA 90503
  33493.  *                    1 Jan 85
  33494.  */
  33495.  
  33496.  #define CATFILE "about.dat"
  33497.  #define DEFCHAR ':'
  33498.  #define BUFLEN 82
  33499.  
  33500.  int fin;
  33501.  
  33502.  main(ac, av)
  33503.      int ac;
  33504.      char *av[];
  33505.      {
  33506.      char *catfile;
  33507.      char buf[BUFLEN];
  33508.      int showall;
  33509.      int done;
  33510.      int more;
  33511.  
  33512.      showall = 0;
  33513.      done = 0;
  33514.  
  33515.      if ((ac < 2) || (ac > 3))
  33516.          {
  33517.          printf("\nUsage:    about  <name>  [<catfile>]\n");
  33518.          printf("\nFor each line in <catfile> beginning as \":<name>\",");
  33519.          printf("\nsuccessive lines are displayed until the next line");
  33520.          printf("\nbegins with \":\";  if <name> is *, all entries are");
  33521.          printf("\ndisplayed;  <catfile> defaults to \"about.dat\".\n");
  33522.          exit();
  33523.          }
  33524.      else if (ac == 2)
  33525.          {
  33526.          if ((fin = fopen(catfile = CATFILE, "r")) == 0)
  33527.              {
  33528.              printf("\n---File %s not found", catfile);
  33529.              exit();
  33530.              }
  33531.          }
  33532.      else if (ac ==3)
  33533.          {
  33534.          if ((fin = fopen(catfile = av[2], "r")) == 0)
  33535.              {
  33536.              printf("\n---File %s not found", catfile);
  33537.              exit();
  33538.              }
  33539.          }
  33540.      if (*av[1] == '*')
  33541.          showall = 1;
  33542.      printf("\n(Catalogue file:  %s)\n\n", catfile);
  33543.      more = fgets(buf, BUFLEN - 1, fin);
  33544.      while (more)
  33545.          {
  33546.          if ((buf[0] == DEFCHAR)
  33547.              && ((comp(av[1], buf + 1) == 0) || showall))
  33548.              {
  33549.              more = print_text(buf);
  33550.              if (!showall)
  33551.                  {
  33552.                  done = 1;
  33553.                  break;
  33554.                  }
  33555.              }
  33556.          else
  33557.              more = fgets(buf, BUFLEN - 1, fin);
  33558.          }
  33559.      if ((done != 1) && !showall)
  33560.          printf("\"%s\" is not catalogued\n\n", av[1]);
  33561.      fclose(fin);
  33562.      }
  33563.  
  33564.  int comp(s, t)
  33565.      char *s, *t;
  33566.      {
  33567.      int i;
  33568.  
  33569.      for (i = 0; (t[i] > ' ') && (t[i] <= '~'); ++i)
  33570.          ;
  33571.      t[i] = '\0';
  33572.      return strcmp(s, t);
  33573.      }
  33574.  
  33575.  int print_text(buf)
  33576.      char buf[];
  33577.      {
  33578.      int more;
  33579.      printf("%s:\n", &buf[1]);
  33580.      while (((more = fgets(buf, BUFLEN - 1, fin)) != 0)
  33581.          && (buf[0] != DEFCHAR))
  33582.          {
  33583.          puts(buf);
  33584.          }
  33585.      return more;
  33586.      }
  33587.  
  33588.  
  33589.  ABS.C
  33590.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\LIB\JPLC2\ABS.C
  33591.  
  33592.  /* 1.0  07-06-84 */
  33593.  /************************************************************************
  33594.   *                        Robert C. Tausworthe
  33595.   *                        Jet Propulsion Laboratory                        *
  33596.   *                        Pasadena, CA 91009                1984
  33597.   ************************************************************************/
  33598.  
  33599.  #include "defs.h"
  33600.  
  33601.  /************************************************************************/
  33602.          int
  33603.  abs(n)                        /* return the integer absolute value of int n
  33604.  
  33605.  /*----------------------------------------------------------------------*/
  33606.  int n;
  33607.  {
  33608.          return ABS(n);
  33609.  }
  33610.  
  33611.  
  33612.  ABSREAD.C
  33613.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\LATTICE\DSKTST\ABSREAD.C
  33614.  
  33615.  #include <dos.h>
  33616.  /****************************************************************************
  33617.  *
  33618.  *  absolute disk read (calls disk bios) 0x80 = 1st hard disk
  33619.  *
  33620.  *****************************************************************************
  33621.  absread(drive,cyl,head,record,count,buffer)
  33622.  int drive, cyl, head, record, count;
  33623.  char *buffer;
  33624.  {
  33625.    union  REGS  reg;
  33626.    struct SREGS seg;
  33627.    int err = 0;
  33628.    segread(&seg);
  33629.    reg.h.ch = (cyl & 0x00ff);             /* lo order cylinder */
  33630.    reg.h.cl = (((cyl & 0xff00) << 6) | record);
  33631.    reg.h.dh = head;
  33632.    reg.h.dl = drive;
  33633.    reg.h.al = count;
  33634.    reg.h.ah = 2;
  33635.    reg.x.bx = (unsigned int) buffer;                    /* point to buffer */
  33636.    err = int86x(0x13,®,®,&seg); /* read the disk */
  33637.    err = (err >> 8);
  33638.    return(err);
  33639.  }
  33640.  
  33641.  
  33642.  ADD1TO2.C
  33643.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\UTIL\SUPER_C\ADD1TO2.C
  33644.  
  33645.  /*              Example: Add 1 to 2 and Print It
  33646.   */
  33647.  
  33648.  /*      main()
  33649.  
  33650.          Function: Add 1 and 2 and print the result.
  33651.  
  33652.          Algorithm: Call add to add the two numbers, and printf to print them.
  33653.  */
  33654.  
  33655.  main()
  33656.  
  33657.  {
  33658.          printf("1 + 2 = %d.\n",add(1,2));
  33659.  }
  33660.  
  33661.  
  33662.  
  33663.  ADDLF.C
  33664.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MSC\ADDLF.C
  33665.  
  33666.  /* addlf -- copy input to output; add line-feeds only if necessary.
  33667.   *            WHRauser   10-4-83                   a better mouse trap.
  33668.   */
  33669.  <stdio.h>           /* Microsoft C  Ver 1.04 */
  33670.  
  33671.   CR  0x000D           /* carriage return */
  33672.   LF  0x000A           /* line feed */
  33673.  #define  TRUE          1
  33674.  #define  FALSE          0
  33675.  
  33676.  main()            /* copy input to output and add line-feeds only if needed.
  33677.  {
  33678.      int  c;
  33679.      int  addlf = FALSE;
  33680.  
  33681.      while ((c = getchar()) != EOF) {
  33682.           if (addlf  &  c != LF) {
  33683.                putchar(LF);
  33684.                addlf = FALSE;
  33685.           }
  33686.           putchar(c);
  33687.           if (c == CR)  addlf = TRUE;
  33688.      }
  33689.  }
  33690.  
  33691.  
  33692.  ADDLF.C
  33693.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\UTIL\TABS\ADDLF.C
  33694.  
  33695.  
  33696.  /* addlf -- copy input to output; add line-feeds only if necessary.
  33697.   *          WHRauser   10-4-83             a better mouse trap.
  33698.   */
  33699.  <stdio.h>         /* Microsoft C  Ver 1.04 */
  33700.  
  33701.   CR  0x000D        /* carriage return */
  33702.   LF  0x000A        /* line feed */
  33703.  #define  TRUE     1
  33704.  #define  FALSE    0
  33705.  
  33706.  main()      /* copy input to output and add line-feeds only if needed. */
  33707.  {
  33708.      int  c;
  33709.      int  addlf = FALSE;
  33710.  
  33711.      while ((c = getchar()) != EOF) {
  33712.           if (addlf  &  c != LF) {
  33713.                putchar(LF);
  33714.                addlf = FALSE;
  33715.           }
  33716.           putchar(c);
  33717.           if (c == CR)  addlf = TRUE;
  33718.      }
  33719.  }
  33720.  
  33721.  
  33722.  
  33723.  AGENT.C
  33724.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\LIB\R_LA4_01\AGENT.C
  33725.  
  33726.  /* AGENTS.C - From "Microsoft C Programming for the IBM, page   */
  33727.  /* 300, by Robert Lafore. The program uses an array of struct-  */
  33728.  /* ures to maintain a list of agents in memory. It is also a    */
  33729.  /* continuation of the development of a simple database started */
  33730.  /* on page 292.                                                 */
  33731.  /****************************************************************/
  33732.  
  33733.  #include <stdio.h>
  33734.  #define TRUE 1
  33735.  
  33736.  struct personnel {
  33737.     char name [30];
  33738.     int agnumb;
  33739.     float height;
  33740.  };
  33741.  struct personnel agent[50];      /*array of 50 structures*/
  33742.  int n = 0;
  33743.  
  33744.  main()
  33745.  {
  33746.  char ch;
  33747.  
  33748.     while(TRUE) {
  33749.        printf("\nType 'e' to enter new agent");
  33750.        printf("\n  'L' to list all agents: ");
  33751.        ch = getche();
  33752.        switch (ch) {
  33753.           case 'e':
  33754.              newname();
  33755.              break;
  33756.           case 'L':
  33757.              listall();
  33758.              break;
  33759.           default:
  33760.              puts("\nEnter only selections listed");
  33761.        }
  33762.     }
  33763.  }
  33764.  
  33765.  /* newname */
  33766.  /* puts a new agent in the database */
  33767.  newname()
  33768.  {
  33769.     printf("\nRecord %d: \nEnter name: ", n + 1);
  33770.     gets(agent[n].name);
  33771.     printf("Enter agent number (3 digits): ");
  33772.     scanf("%d", &agent[n].agnumb);
  33773.     printf("Enter height in inches: ");
  33774.     scanf("%f", &agent[n++].height);
  33775.     fflush(stdin);
  33776.  }
  33777.  
  33778.  /* listall() */
  33779.  /* lists all agents and data */
  33780.  listall()
  33781.  {
  33782.  int j;
  33783.  
  33784.     if (n < 1)
  33785.        printf("\nEmpty list.\n");
  33786.     for(j = 0; j < n; j++) {
  33787.        printf("\nRecord number %d\n", j + 1);
  33788.        printf("   Name: %s\n", agent[j].name);
  33789.        printf("   Agent number: %03d\n", agent[j].agnumb);
  33790.        printf("   Height: %4.2f\n", agent[j].height);
  33791.     }
  33792.  }
  33793.  
  33794.  
  33795.  
  33796.  AGENT2.C
  33797.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\LIB\R_LA4_01\AGENT2.C
  33798.  
  33799.  /* AGENT2.C - From page 309 of "Microsoft C Programming for the */
  33800.  /* IBM by Robert Lafore. This is the final program of the data- */
  33801.  /* base started on page 292. it uses linked lists.              */
  33802.  /****************************************************************/
  33803.  
  33804.  <stdio.h>           /*defines 'stdin'*/
  33805.  #define TRUE 1
  33806.  struct prs {
  33807.     char name[30];
  33808.     int agnumb;
  33809.     float height;
  33810.     struct prs *ptrnext;       /*ptr to next structure*/
  33811.  };
  33812.  struct prs *ptrfirst, *ptrthis, *ptrnew;
  33813.  
  33814.  main()
  33815.  {
  33816.  char ch;
  33817.  
  33818.     ptrfirst = (struct prs *)NULL;         /*no input yet*/
  33819.     while (TRUE) {
  33820.        printf("\nType 'e' to enter new agent");
  33821.        printf("\n  'L' to list all agents: ");
  33822.        ch = getche();
  33823.        switch (ch) {
  33824.           case 'e':
  33825.              newname();
  33826.              break;
  33827.           case 'L':
  33828.              listall();
  33829.              break;
  33830.           default:
  33831.              puts("\nEnter only selections listed");
  33832.        }
  33833.     }
  33834.  }
  33835.  
  33836.  /* newname() */      /*puts a new agent in the database*/
  33837.  newname()
  33838.  {
  33839.     ptrnew = (struct prs *) malloc(sizeof(struct prs));
  33840.     if (ptrfirst == (struct prs *)NULL)  /*if none already, save addr*/
  33841.        ptrfirst = ptrthis = ptrnew;
  33842.     else {                     /*not first item, go to end of list*/
  33843.        ptrthis = ptrfirst;     /* (start at begin ) */
  33844.        while (ptrthis->ptrnext != (struct prs *)NULL)
  33845.           ptrthis = ptrthis->ptrnext;      /*find next item*/
  33846.        ptrthis->ptrnext = ptrnew;          /*pt to new item*/
  33847.        ptrthis = ptrnew;                   /*go to new item*/
  33848.     }
  33849.     printf("\nEnter name: ");
  33850.     gets(ptrthis->name);
  33851.     printf("Enter number: ");
  33852.     scanf("%d", &ptrthis->agnumb);
  33853.     printf("Enter height: ");
  33854.     scanf("%f", &ptrthis->height);
  33855.     fflush(stdin);
  33856.     ptrthis->ptrnext = (struct prs *)NULL;    /*this is end*/
  33857.  }
  33858.  
  33859.  /* listall() */      /*lists all agents and data */
  33860.  listall()
  33861.  {
  33862.     if (ptrfirst == (struct prs *)NULL) {  /*if empty list*/
  33863.        printf("\nEmpty list.\n");
  33864.        return;
  33865.     }
  33866.     ptrthis = ptrfirst;           /*start at first item*/
  33867.     do {
  33868.        printf("\nName: %s\n", ptrthis->name);
  33869.        printf("Number: %03d\n", ptrthis->agnumb);
  33870.        printf("Height: %4.2f\n", ptrthis->height);
  33871.        ptrthis = ptrthis->ptrnext;      /*move to next item*/
  33872.     } while(ptrthis != (struct prs *)NULL);   /*quit on null ptr*/
  33873.  }
  33874.  
  33875.  
  33876.  
  33877.  AGENTR.C
  33878.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\LIB\R_LA4_02\AGENTR.C
  33879.  
  33880.  /* AGENTR.C - From page 453 of "Microsoft C Programming for     */
  33881.  /* the IBM" by Robert Lafore. This is a simple database program.*/
  33882.  /* I added 2 if statements to file in book. One is after else   */
  33883.  /* statement in rfile() function. This prevents adding exist-   */
  33884.  /* ing records to array (a duplication making the array twice   */
  33885.  /* as large) when selecting 'r' while an array already exists.  */
  33886.  /* It will then only read a file to array at program startup.   */
  33887.  /* The second if statement added is in the first case statement.*/
  33888.  /* This will prevent erasing an existing database by automat-   */
  33889.  /* ically writing it to disk before selecting enter a name,     */
  33890.  /* otherwise selecting enter before writing will start the new  */
  33891.  /* database at n == 0 after opening the disk file.              */
  33892.  /****************************************************************/
  33893.  
  33894.  #include "stdio.h"
  33895.  #define TRUE 1
  33896.  
  33897.  struct personnel {                  /*define data structure*/
  33898.     char name [40];
  33899.     int agnumb;
  33900.     float height;
  33901.  };
  33902.  struct personnel agent[50];         /*array of 50 structures*/
  33903.  int n = 0;
  33904.  
  33905.  main()
  33906.  {
  33907.  char ch;
  33908.  
  33909.     while(TRUE) {
  33910.        printf("\n'e' Enter new agent\n'l' List all agents");
  33911.        printf("\n'w' Write file\n'r' Read file: ");
  33912.        ch = getche();
  33913.        switch(ch) {
  33914.           case 'e':
  33915.              if (n == 0)
  33916.                 rfile();
  33917.              newname();
  33918.              break;
  33919.           case 'l':
  33920.              listall();
  33921.              break;
  33922.           case 'w':
  33923.              wfile();
  33924.              break;
  33925.           case 'r':
  33926.              rfile();
  33927.              break;
  33928.           default:
  33929.              puts("\nEnter only selections listed.");
  33930.        }
  33931.     }
  33932.  }
  33933.  
  33934.  /* newname */    /* puts a new agent in the database */
  33935.  newname()
  33936.  {
  33937.  
  33938.     printf("\nRecord %d.\nEnter name: ", n + 1);
  33939.     gets(agent[n].name);
  33940.     printf("\nEnter agent number (3 digits): ");
  33941.     scanf("%d", &agent[n].agnumb);
  33942.     printf("Enter height in inches: ");
  33943.     scanf("%f", &agent[n++].height);
  33944.     fflush(stdin);
  33945.  }
  33946.  
  33947.  /* listall() */   /*lists all agents and data */
  33948.  listall()
  33949.  {
  33950.  int j;
  33951.  
  33952.     if(n < 1)
  33953.        printf("\nEmpty list.\n");
  33954.     for(j = 0; j < n; j++) {
  33955.        printf("\nRecord number %d\n", j + 1);
  33956.        printf("   Name: %s\n", agent[j].name);
  33957.        printf("   Agent number: %03d\n", agent[j].agnumb);
  33958.        printf("   Height: %4.2f\n", agent[j].height);
  33959.     }
  33960.  }
  33961.  
  33962.  /* wfile */    /* writes array of structures to file */
  33963.  wfile()
  33964.  {
  33965.  FILE *fptr;
  33966.  
  33967.     if(n < 1) {
  33968.        printf("\nCan't write empty list.\n");
  33969.        return;
  33970.     }
  33971.     if((fptr = fopen("c:agents.rec", "wb")) == NULL)
  33972.        printf("\nCan't open file agents.rec\n");
  33973.     else {
  33974.        fwrite(agent, sizeof(agent[0]), n, fptr);
  33975.        fclose(fptr);
  33976.        printf("\nFile of %d records written.\n", n);
  33977.     }
  33978.  }
  33979.  
  33980.  /* rfile() */  /* reads records from file into array */
  33981.  rfile()
  33982.  {
  33983.  FILE *fptr;
  33984.  
  33985.     if((fptr = fopen("c:agents.rec", "rb")) == NULL)
  33986.        printf("\nCan't open file agents.rec\n");
  33987.     else {
  33988.        if(n == 0)  /*Fill array only at start, otherwise will dup entire file*
  33989.           while(fread(&agent[n], sizeof(agent[n]), 1, fptr) == 1)
  33990.              n++;
  33991.     fclose(fptr);
  33992.     printf("\nFile read. Total agents is %d.\n", n);
  33993.     }
  33994.  }
  33995.  
  33996.  
  33997.  
  33998.  ALLDIR.C
  33999.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\LATTICE\ALLDIR.C
  34000.  
  34001.  /* ALLDIR.C  a program to traverse DOS's tree-structured directory, looking
  34002.     for the file(s) specified. They are then displayed on the screen.
  34003.     Basically, I got damned tired of DOS not being able to tell me what's
  34004.     where.
  34005.      The basic traverse from directory to directory portion is a
  34006.     very versatile toy around which many useful utilities can (and will,
  34007.     I'm sure!) be written. Here's another one of them. I'll do more as time
  34008.     and inclination permits, but I'll turn this one loose because I think
  34009.     it's useful.
  34010.      This is written for MSDOS 2.0 or better, using the LATTICE C Compiler,
  34011.     on a Compaq. 7-20-84 jjw
  34012.     ps I know this could be shortened drastically and speeded up by
  34013.     combining some of the modules into larger functions, but this way was
  34014.     much easier to write & de-bug modularly and so I left it that way. Also,
  34015.     some of the modules might be useful in themselves to build into a
  34016.     library. This program differs from most C code I've seen before because
  34017.     1.) it does something useful.
  34018.     2.) it does not have pointers to pointers to arrays of pointers to functio
  34019.         returning pointers. It is easy and straight-forward, at the expense of
  34020.         some speed and length.
  34021.     3.) it is commented. Not extensively, but fairly well. The hard parts have
  34022.         to do with the dirstak, which is not a stack but a queue (dirqueue
  34023.         looked too silly to me and d_queue made me think of peanut buster
  34024.         parfaits). If puzzled, follow it through but keep the msdos manual
  34025.         handy to see what byte is what.
  34026.     If you have any questions about this, drop me a note. I frequent almost
  34027.     every tech-oriented CPM bulletin board around Chicago, Il.
  34028.     Name is John Welch, or just jjw.
  34029.             2397 John Smith Dr. Apt B
  34030.             Schaumburg, Il 60194 */
  34031.  
  34032.  #include "dos.h"
  34033.  #include "stdio.h"
  34034.  
  34035.  main(argc,argv)
  34036.  int argc;
  34037.  char *argv[];
  34038.  {
  34039.  char look[15],start[100],init_dir[100],drive[2],flag1,stuff[100];
  34040.  int first,last,temp,temp1,ret;
  34041.  
  34042.  printf("ALLDIR.C Ver 1.00 1-25-85 John J. Welch\n");
  34043.  printf("(for help, type ALLDIR HELP)\n\n");
  34044.  
  34045.  if (argc == 1)
  34046.   {
  34047.    /* get the filename to erase */
  34048.    printf("Filename to find -->");
  34049.    scanf("%s",look);
  34050.  
  34051.    /* get the drive we're going to do the erasing on */
  34052.    printf("Enter the drive letter -->");
  34053.    scanf("%s",stuff);
  34054.    drive[1] = stuff[0];
  34055.  
  34056.    /* get starting directory */
  34057.    printf("Directory to start in (absolute path from root) -->");
  34058.    scanf("%s",start);
  34059.  
  34060.    /* do we want to do all sub-directories, too, or just this one? */
  34061.    printf("Traverse all sub-directories under this one -->");
  34062.    scanf("%s",stuff);
  34063.    if ((stuff[0] == 'y') || (stuff[0] == 'Y'))
  34064.     flag1 = 1; /* if they specified Y, set the flag */
  34065.    else
  34066.     flag1 = 0; /* anything but Y or y means NO */
  34067.  
  34068.    }
  34069.  else
  34070.   {
  34071.    if (argc != 2)
  34072.     {
  34073.  HERE:
  34074.      printf("For prompts, just type ALLDIR.\n");
  34075.      printf("Command line syntax is ALLDIR [drive:][starting path]file.ext[/y]
  34076.      printf("where [drive:] is optional drive,\n");
  34077.      printf("  [starting path] is optional path to start at,\n");
  34078.      printf("  file.ext is the file name (wildcards ok) to look for,\n");
  34079.      printf("  [/y] is optionally if you want to do all sub-directories under
  34080.      printf("  starting directory (default value is no).\n");
  34081.      return;
  34082.     }
  34083.    else
  34084.     {
  34085.      if ((strcmp(argv[1],"HELP") == 0) || (strcmp(argv[1],"help") == 0))
  34086.       goto HERE;
  34087.  
  34088.      first = 0; /* first character of the command line */
  34089.      drive[1] = 255; /* set up to default to current drive */
  34090.      flag1 = 0; /* default it to not do sub-dirs */
  34091.      if (argv[1][1] == ':') /* if there was a drive specified, pick the letter
  34092.      { /*off and store it someplace */
  34093.       drive[1] = argv[1][0];
  34094.       first = 2; /* now, the first character in the command line is #2 */
  34095.      }
  34096.      last = strlen(argv[1]); /* get the length of the command line */
  34097.      if (argv[1][last-2] == '/') /* if they used the toggle, set it up */
  34098.      {
  34099.       if ((argv[1][last-1] == 'y') || (argv[1][last-1] == 'Y'))
  34100.        flag1 = 1; /* if they specified Y, set the flag */
  34101.       else
  34102.        flag1 = 0; /* anything but Y or y means NO */
  34103.       last -= 2; /* bump the last character down */
  34104.       argv[1][last] = 0; /* and now, null terminate the command line */
  34105.      }
  34106.  
  34107.      for (temp = last; ((argv[1][temp] != ':') && (temp >= first) && (argv[1][
  34108.  
  34109.      for (temp1 = first; temp1 < temp+1; temp1++) /* get pathname (if any) */
  34110.      {start[temp1-first] = argv[1][temp1];}
  34111.      start[temp1-first] = 0; /* null terminate it */
  34112.  
  34113.      for (temp1 = temp+1; temp1 <= last; temp1++) /* get the filename to look
  34114.      {look[temp1-(temp+1)] = argv[1][temp1];}
  34115.      look[temp1-(temp+1)] = 0; /* null terminate this */
  34116.  
  34117.     }
  34118.    }
  34119.  
  34120.  /* get the drive we started in */
  34121.  get_drive(drive);
  34122.  
  34123.  if (drive[1] == 255) /* if the default was for current drive, use it */
  34124.   drive[1] = drive[0];
  34125.  else /* otherwise, normalize whatever they typed in to start with a=0 */
  34126.   if ((drive[1] > 'A') && (drive[1] < 'Z'))
  34127.     drive[1] = drive[1] - 'A';
  34128.   else
  34129.     drive[1] = drive[1] - 'a';
  34130.  
  34131.  /* change to the starting drive */
  34132.  ret=chg_drive(drive[1]);
  34133.  
  34134.  if (ret < drive[1])
  34135.    printf("invalid drive selected...\n");
  34136.  else
  34137.   {
  34138.    /* get the directory we started in */
  34139.    init_dir[0] = '\\';
  34140.    get_dir(init_dir+1);
  34141.  
  34142.    if (start[0] == 0) /* if there was no starting path, use the current one */
  34143.     strcpy(start,init_dir);
  34144.  
  34145.    /* do the actual work */
  34146.    doit(look,start,flag1);
  34147.  
  34148.    /* change back to the initial drive */
  34149.    chg_drive(drive[0]);
  34150.  
  34151.    /* now, change back to the initial directory */
  34152.    chg_dir(init_dir);
  34153.   } /* end else */
  34154.  
  34155.  } /* end function */
  34156.  
  34157.  doit(look,start,flag1)
  34158.  char *look,*start,flag1;
  34159.  
  34160.  {
  34161.   char file[3],name[128],*dirstak,curdir[140],*getmem();
  34162.   int ret,tmp,top_ndx,bottom_ndx;
  34163.  
  34164.   dirstak = getmem(10000); /* get a hunk of memory for the directory queue */
  34165.   if (dirstak == 0) /* if the getmem returned a null, error */
  34166.   {printf("not enough memory...\n");
  34167.    return;}
  34168.  
  34169.  /* set the DTA to someplace we can use */
  34170.   put_dta(name);
  34171.  
  34172.   top_ndx = 0;    /* set pointer to top of directory queue */
  34173.   bottom_ndx = 0; /* set pointer to bottom of queue */
  34174.  
  34175.   /* put the starting directory in the queue */
  34176.   for (tmp = 0; start[tmp] != 0; tmp++)
  34177.    {dirstak[bottom_ndx++] = start[tmp];}
  34178.   dirstak[bottom_ndx++] = 0;
  34179.  
  34180.   while (top_ndx != bottom_ndx)
  34181.    {
  34182.     /* check for any sub-directories */
  34183.     ret = dirscan(file,name,curdir,dirstak,&top_ndx,&bottom_ndx);
  34184.  
  34185.     if (ret != 3)
  34186.      {
  34187.       /* run through the directory, querying for each file */
  34188.       filscan(look,name);
  34189.      }
  34190.  
  34191.     /* if only do this one directory, end here */
  34192.     if (flag1 == 0)
  34193.     {
  34194.      rlsmem(dirstak,10000);
  34195.      return(1);
  34196.     }
  34197.  
  34198.    } /* end while loop */
  34199.    rlsmem(dirstak,10000);
  34200.  
  34201.  } /* end function */
  34202.  
  34203.  dirscan(file,name,curdir,dirstak,top_ptr,bot_ptr)
  34204.  char *file,*name,*curdir,*dirstak;
  34205.  int *top_ptr,*bot_ptr;
  34206.  {
  34207.   int ret,tmp,top_ndx,bottom_ndx,*p_file;
  34208.  
  34209.   bottom_ndx = *bot_ptr;
  34210.   top_ndx = *top_ptr;
  34211.  
  34212.   /* initialize the file name for the directory search */
  34213.   file[0] = '*';
  34214.   file[1] = '.';
  34215.   file[2] = 0;
  34216.  
  34217.   tmp = 0;
  34218.   for (top_ndx; dirstak[top_ndx] != 0; top_ndx++)
  34219.    { curdir[tmp++] = dirstak[top_ndx];}
  34220.   curdir[tmp] = 0;
  34221.   ++top_ndx;
  34222.   ret = chg_dir(curdir);
  34223.   if (ret != 3)
  34224.    {
  34225.     printf("\n\n     %s\n",curdir);
  34226.     find_dir(name,file,curdir,dirstak,&bottom_ndx);
  34227.    }
  34228.   *bot_ptr = bottom_ndx;
  34229.   *top_ptr = top_ndx;
  34230.  
  34231.   return(ret);
  34232.  }
  34233.  
  34234.  find_dir(name,file,curdir,dirstak,bot_ndx)
  34235.  char *name,*file,*curdir,*dirstak;
  34236.  int *bot_ndx;
  34237.  {
  34238.   int ret,tmp,bottom_ndx;
  34239.   unsigned temp;
  34240.  
  34241.   bottom_ndx = *bot_ndx; /* set the local variable = the real thing. */
  34242.  
  34243.  /* search for first directory entry */
  34244.   temp = 0x0010;
  34245.   ret = srch1st(file,temp);
  34246.  
  34247.  /* while the return from search is successful, check for dir attribute
  34248.     and make sure it isn't a . or .. entry, put the whole pathname (null
  34249.     terminated) at the bottom of the queue */
  34250.  
  34251.   while (ret != 18)
  34252.   { if ((name[21] == 0x10) && (name[30] != '.'))
  34253.     {
  34254.      for (tmp = 0; curdir[tmp] != 0; tmp++)
  34255.      {dirstak[bottom_ndx] = curdir[tmp];
  34256.       ++bottom_ndx;}
  34257.      if (curdir[1] != 0)
  34258.       {dirstak[bottom_ndx++] = '\\';}
  34259.     for (tmp = 30; name[tmp] != 0; tmp++)
  34260.      {dirstak[bottom_ndx] = name[tmp];
  34261.       ++bottom_ndx;}
  34262.     dirstak[bottom_ndx++] = 0;
  34263.  
  34264.     } /* end if */
  34265.      ret = srchnext(file); /* get another directory entry */
  34266.   } /* end while */
  34267.  
  34268.   *bot_ndx = bottom_ndx; /*now restore the real value to its proper place */
  34269.  
  34270.  } /* end function */
  34271.  
  34272.  filscan(look,name)
  34273.  char *look,*name;
  34274.  {
  34275.   int ret,numb;
  34276.   char tmp,line[35],flag;
  34277.   unsigned temp;
  34278.   long make_line(),total;
  34279.  
  34280.   total = 0;
  34281.   numb = 0;
  34282.   flag = 0;
  34283.   temp = 0x0000;
  34284.   ret = srch1st(look,temp); /* start looking for files */
  34285.  
  34286.   while (ret != 18)
  34287.   {
  34288.    total += make_line(line,name);
  34289.    numb++;
  34290.    printf(line);
  34291.    if (flag == 0)
  34292.    {printf("         ");
  34293.     flag = 1;}
  34294.    else
  34295.    {printf("\n");
  34296.     flag = 0;}
  34297.  
  34298.    ret = srchnext(look); /* get another directory entry */
  34299.   } /* end while */
  34300.   if (flag == 1)
  34301.    printf("\n");
  34302.   printf("  --> %d files, total space = %8lu<--\n",numb,total);
  34303.  
  34304.  } /* end function */
  34305.  
  34306.  put_dta(p_dta)
  34307.  char *p_dta;
  34308.  {
  34309.   union REGS inreg;
  34310.   union REGS outreg;
  34311.  
  34312.   inreg.h.ah = 0x1a;
  34313.   inreg.x.dx = p_dta;
  34314.  
  34315.   intdos(&inreg,&outreg);
  34316.  
  34317.   return(0);
  34318.  }
  34319.  
  34320.  srch1st(p_file,attr)
  34321.  int *p_file;
  34322.  unsigned attr;
  34323.  {
  34324.   union REGS inreg;
  34325.   union REGS outreg;
  34326.  
  34327.   inreg.h.ah = 0x4e;
  34328.   inreg.x.cx = attr;
  34329.   inreg.x.dx = p_file;
  34330.  
  34331.   intdos(&inreg,&outreg);
  34332.  
  34333.   return(outreg.x.ax);
  34334.  }
  34335.  
  34336.  srchnext(p_file)
  34337.  int *p_file;
  34338.  {
  34339.   union REGS inreg;
  34340.   union REGS outreg;
  34341.  
  34342.   inreg.h.ah = 0x4f;
  34343.  
  34344.   intdos(&inreg,&outreg);
  34345.  
  34346.   return(outreg.x.ax);
  34347.  }
  34348.  
  34349.  chg_dir(curdir)
  34350.  char *curdir;
  34351.  {
  34352.   union REGS inreg;
  34353.   union REGS outreg;
  34354.  
  34355.   inreg.h.ah = 0x3b;
  34356.   inreg.x.dx = curdir;
  34357.  
  34358.   intdos(&inreg,&outreg);
  34359.  
  34360.   return(outreg.x.ax);
  34361.  }
  34362.  
  34363.  get_dir(temp)
  34364.  char *temp;
  34365.  {
  34366.   union REGS inreg;
  34367.   union REGS outreg;
  34368.  
  34369.   inreg.h.ah = 0x47;
  34370.   inreg.h.dl = 0; /* relative drive */
  34371.   inreg.x.si = temp; /* where to put the pathname */
  34372.  
  34373.   intdos(&inreg,&outreg);
  34374.  
  34375.   return(outreg.x.ax);
  34376.  }
  34377.  
  34378.  get_drive(where)
  34379.  char *where;
  34380.  {
  34381.   union REGS inreg;
  34382.   union REGS outreg;
  34383.  
  34384.   inreg.h.ah = 0x19;
  34385.  
  34386.   intdos(&inreg,&outreg);
  34387.  
  34388.   *where = outreg.h.al;
  34389.  }
  34390.  
  34391.  era_file(which)
  34392.  char *which;
  34393.  {
  34394.   union REGS inreg;
  34395.   union REGS outreg;
  34396.  
  34397.   inreg.h.ah = 0x41;
  34398.   inreg.x.dx = which; /* pointer to filename */
  34399.  
  34400.   intdos(&inreg,&outreg);
  34401.  
  34402.   /* there's no easy way to check for errors, so don't even do it.
  34403.      dos returns error flag in carry flag, LATTICE C can't access it without
  34404.      your own assembler routine. I have one, but it's a bit hairy. For those
  34405.      who insist on doing things right, drop me a note. jjw */
  34406.  }
  34407.  
  34408.  chg_drive(drive)
  34409.  char drive;
  34410.  {
  34411.   union REGS inreg;
  34412.   union REGS outreg;
  34413.  
  34414.   inreg.h.ah = 0x0e;
  34415.   inreg.h.dl = drive;
  34416.  
  34417.   intdos(&inreg,&outreg);
  34418.  
  34419.   return(outreg.h.al);
  34420.  }
  34421.  
  34422.  
  34423.  /************************************************************************/
  34424.  /*                         make_line()                                  */
  34425.  /*           make the line of directory info to be printed              */
  34426.  /*                                                                      */
  34427.  /************************************************************************/
  34428.  
  34429.  long make_line(dst,nam)
  34430.  char *dst,*nam;
  34431.  {
  34432.   unsigned g1,g2,g3; /* garbage variables */
  34433.   char flag,temp; /* flagged or not, temporary counter */
  34434.   char name[9],ext[5],*where; /* hold the file name & extension, which place t
  34435.   int ret; /* true if we are did not go off the bottom of the dir */
  34436.   long size,g7,t1,t2,t3; /* size of file in bytes, temp variables */
  34437.   char direct[23];
  34438.  
  34439.   t1 = 256; /* offset for high size low */
  34440.   t2 = 65536; /* offset for low size high */
  34441.   t3 = 16777216; /* offset for high size high */
  34442.  
  34443.    for (temp = 24; temp != 43; temp++) /* load the date, size and name */
  34444.    { direct[temp-21] = nam[temp]; /* put the char into the dir area */ }
  34445.  
  34446.    for (temp = 0; temp != 6; temp++) /* blank out the extension */
  34447.    { ext[temp] = 0; }
  34448.  
  34449.    for (temp = 0; temp != 10; temp++) /* blank out the file name */
  34450.    { name[temp] = 0; }
  34451.  
  34452.    where = name; /* start by putting the name in the name */
  34453.  
  34454.    for (temp = 0; temp <= 12; temp++) /* copy over the file name */
  34455.    { if (direct[9+temp] == '.') /* if we hit the seperator between name & ext,
  34456.      {
  34457.       where = ext; /*switch over to the extension */
  34458.       temp++; /* skip to next character */
  34459.      }
  34460.      if (direct[9+temp] == 0) /* if we're at the end of the string, stop */
  34461.       temp = 13; /* exit condition */
  34462.      else
  34463.      {
  34464.       *where = direct[9+temp]; /* copy the char over to the array */
  34465.       where++; /* increment pointer */
  34466.      }
  34467.    }
  34468.  
  34469.      g1 = direct[4]; /* will be the year */
  34470.      g2 = direct[4]*256+direct[3]; /* will be the month */
  34471.      g3 = direct[3]; /* will be the day */
  34472.  
  34473.      g7 = direct[5]; /* compute size in bytes */
  34474.      size = g7;
  34475.      g7 = direct[6];
  34476.      size = size + (g7*t1);
  34477.      g7 = direct[7];
  34478.      size = size + (g7*t2);
  34479.      g7 = direct[8];
  34480.      size = size + (g7*t3); /* will be the file size in bytes */
  34481.  
  34482.      /* shift things around to get rid of un-necessary bits */
  34483.      g1 >>= 1; /* right-shift month by 1 */
  34484.      g2 <<= 7; /* left-shift day by 7 */
  34485.      g2 >>= 12; /* then right-shift by 12 to drop off garbage bits */
  34486.      g3 &= 0x1f; /* mask off garbage bits to get the year */
  34487.  
  34488.      sprintf(dst,"%-8s.%-3s  %02d-%02d-%02d %8lu",name,ext,g2,g3,g1+80,size);
  34489.      /* make a useful string out of the flag, name, date and size */
  34490.  
  34491.  return(size);
  34492.  }
  34493.  
  34494.  
  34495.  ALLOC.C
  34496.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\ZED\STEVIE\ALLOC.C
  34497.  
  34498.  /*
  34499.   * STevie - ST editor for VI enthusiasts.    ...Tim Thompson...twitch!tjt...
  34500.   *
  34501.   * Extensive modifications by:  Tony Andrews       onecom!wldrdg!tony
  34502.   * Turbo C 1.5 port by: Denny Muscatelli 061988
  34503.   */
  34504.  
  34505.  #include "stevie.h"
  34506.  
  34507.  /*
  34508.   * This file contains various routines dealing with allocation and
  34509.   * deallocation of data structures.
  34510.   */
  34511.  
  34512.  char *
  34513.  alloc(size)
  34514.  unsigned size;
  34515.  {
  34516.          char *p;                /* pointer to new storage space */
  34517.  
  34518.          p = malloc(size);
  34519.          if ( p == (char *)NULL ) {        /* if there is no more room... */
  34520.                  emsg("alloc() is unable to find memory!");
  34521.          }
  34522.          return(p);
  34523.  }
  34524.  
  34525.  char *
  34526.  strsave(string)
  34527.  char *string;
  34528.  {
  34529.          return(strcpy(alloc((unsigned)(strlen(string)+1)),string));
  34530.  }
  34531.  
  34532.  void
  34533.  screenalloc()
  34534.  {
  34535.          /*
  34536.           * If we're changing the size of the screen, free the old arrays
  34537.           */
  34538.          if (Realscreen != NULL)
  34539.                  free(Realscreen);
  34540.          if (Nextscreen != NULL)
  34541.                  free(Nextscreen);
  34542.  
  34543.          Realscreen = malloc((unsigned)(Rows*Columns));
  34544.          Nextscreen = malloc((unsigned)(Rows*Columns));
  34545.  }
  34546.  
  34547.  /*
  34548.   * Allocate and initialize a new line structure with room for
  34549.   * 'nchars' characters.
  34550.   */
  34551.  LINE *
  34552.  newline(nchars)
  34553.  int        nchars;
  34554.  {
  34555.          register LINE        *l;
  34556.  
  34557.          if ((l = (LINE *) alloc(sizeof(LINE))) == NULL)
  34558.                  return (LINE *) NULL;
  34559.  
  34560.          l->s = alloc(nchars);                /* the line is empty */
  34561.          l->s[0] = NUL;
  34562.          l->size = nchars;
  34563.  
  34564.          l->prev = (LINE *) NULL;        /* should be initialized by caller */
  34565.          l->next = (LINE *) NULL;
  34566.  
  34567.          return l;
  34568.  }
  34569.  
  34570.  /*
  34571.   * filealloc() - construct an initial empty file buffer
  34572.   */
  34573.  void
  34574.  filealloc()
  34575.  {
  34576.          if ((Filemem->linep = newline(1)) == NULL) {
  34577.                  fprintf(stderr,"Unable to allocate file memory!\n");
  34578.                  exit(1);
  34579.          }
  34580.          if ((Fileend->linep = newline(1)) == NULL) {
  34581.                  fprintf(stderr,"Unable to allocate file memory!\n");
  34582.                  exit(1);
  34583.          }
  34584.          Filemem->index = 0;
  34585.          Fileend->index = 0;
  34586.  
  34587.          Filemem->linep->next = Fileend->linep;
  34588.          Fileend->linep->prev = Filemem->linep;
  34589.  
  34590.          *Curschar = *Filemem;
  34591.          *Topchar  = *Filemem;
  34592.  
  34593.          Filemem->linep->num = 0;
  34594.          Fileend->linep->num = 0xffff;
  34595.  
  34596.          clrall();                /* clear all marks */
  34597.  }
  34598.  
  34599.  /*
  34600.   * freeall() - free the current buffer
  34601.   *
  34602.   * Free all lines in the current buffer.
  34603.   */
  34604.  void
  34605.  freeall()
  34606.  {
  34607.          LINE        *lp, *xlp;
  34608.  
  34609.          for (lp = Filemem->linep; lp != NULL ;lp = xlp) {
  34610.                  if (lp->s != NULL)
  34611.                          free(lp->s);
  34612.                  xlp = lp->next;
  34613.                  free(lp);
  34614.          }
  34615.  
  34616.          Curschar->linep = NULL;                /* clear pointers */
  34617.          Filemem->linep = NULL;
  34618.          Fileend->linep = NULL;
  34619.  }
  34620.  
  34621.  /*
  34622.   * bufempty() - return TRUE if the buffer is empty
  34623.   */
  34624.  bool_t
  34625.  bufempty()
  34626.  {
  34627.          return (buf1line() && Filemem->linep->s[0] == NUL);
  34628.  }
  34629.  
  34630.  /*
  34631.   * buf1line() - return TRUE if there is only one line
  34632.   */
  34633.  bool_t
  34634.  buf1line()
  34635.  {
  34636.          return (Filemem->linep->next == Fileend->linep);
  34637.  }
  34638.  
  34639.  /*
  34640.   * lineempty() - return TRUE if the current line is empty
  34641.   */
  34642.  bool_t
  34643.  lineempty()
  34644.  {
  34645.          return (Curschar->linep->s[0] == NUL);
  34646.  }
  34647.  
  34648.  /*
  34649.   * endofline() - return TRUE if the given position is at end of line
  34650.   *
  34651.   * This routine will probably never be called with a position resting
  34652.   * on the NUL byte, but handle it correctly in case it happens.
  34653.   */
  34654.  bool_t
  34655.  endofline(p)
  34656.  register LPTR        *p;
  34657.  {
  34658.          return (p->linep->s[p->index] == NUL || p->linep->s[p->index+1] == NU
  34659.  }
  34660.  /*
  34661.   * canincrease(n) - returns TRUE if the current line can be increased 'n' byt
  34662.   *
  34663.   * This routine returns immediately if the requested space is available.
  34664.   * If not, it attempts to allocate the space and adjust the data structures
  34665.   * accordingly. If everything fails it returns FALSE.
  34666.   */
  34667.  bool_t
  34668.  canincrease(n)
  34669.  register int        n;
  34670.  {
  34671.          register int        nsize;
  34672.          register char        *s;                /* pointer to new space */
  34673.  
  34674.          nsize = strlen(Curschar->linep->s) + 1 + n;        /* size required *
  34675.  
  34676.          if (nsize <= Curschar->linep->size)
  34677.                  return TRUE;
  34678.  
  34679.          /*
  34680.           * Need to allocate more space for the string. Allow some extra
  34681.           * space on the assumption that we may need it soon. This avoids
  34682.           * excessive numbers of calls to malloc while entering new text.
  34683.           */
  34684.          if ((s = alloc(nsize + SLOP)) == NULL) {
  34685.                  emsg("Can't add anything, file is too big!");
  34686.                  State = NORMAL;
  34687.                  return FALSE;
  34688.          }
  34689.  
  34690.          Curschar->linep->size = nsize + SLOP;
  34691.          strcpy(s, Curschar->linep->s);
  34692.          free(Curschar->linep->s);
  34693.          Curschar->linep->s = s;
  34694.  
  34695.          return TRUE;
  34696.  }
  34697.  
  34698.  
  34699.  ALLOT.C
  34700.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\LIB\JPLC2\ALLOT.C
  34701.  
  34702.  /* 1.3  02-11-86                                                 (allot.c)
  34703.   ************************************************************************
  34704.   *                        Robert C. Tausworthe
  34705.   *                        Jet Propulsion Laboratory                        *
  34706.   *                        Pasadena, CA 91009                1985, 86        *
  34707.   ************************************************************************/
  34708.  
  34709.  #include "defs.h"
  34710.  #include "stdtyp.h"
  34711.  
  34712.  /*----------------------------------------------------------------------*/
  34713.  
  34714.  LOCAL HEADER base;                 /* empty list to get started.
  34715.  LOCAL HEADER *allocp = NULL;        /* last allocated block.                *
  34716.  
  34717.  /************************************************************************/
  34718.          char *
  34719.  allot(nbytes)                /* Return pointer to block of memory nbytes in
  34720.                             size, or NULL if none available.                */
  34721.  /*----------------------------------------------------------------------*/
  34722.  unsigned nbytes;
  34723.  {
  34724.          HEADER *morecore();        /* Almost straight out of K & R.        */
  34725.          FAST HEADER *p, *q;
  34726.          FAST unsigned ru, au;        /* requested units, allotted units.
  34727.          unsigned n_units();
  34728.  
  34729.          if ((q = allocp) IS NULL)
  34730.          {        base.s.ptr = allocp = q = &base;
  34731.                  base.s.size = 0;
  34732.          }
  34733.          ru = n_units(nbytes);                /* convert to units        */
  34734.          for (p = q->s.ptr; ; q = p, p = p->s.ptr)
  34735.          {        if (p->s.size >= nbytes)
  34736.                  {        if ((au = n_units(p->s.size)) > ru)
  34737.                          {        p->s.size = (au -= ru) * sizeof(HEADER);
  34738.                                   p += au;
  34739.                          }
  34740.                          else                /* allot the whole block.
  34741.                                  q->s.ptr = p->s.ptr;
  34742.                          allocp = q;
  34743.                          return (char *) p;
  34744.                  }
  34745.                  if ((p IS allocp) AND NOT(p = morecore(ru)))
  34746.                          return NULL; /* wrapped around free list and
  34747.                                          no memory left.
  34748.          }
  34749.  }
  34750.  /*\p*********************************************************************/
  34751.          VOID
  34752.  liberate(ap, nbytes)        /* Put block of nbytes pointed to by ap into the
  34753.                             available list.                                */
  34754.  /*----------------------------------------------------------------------*/
  34755.  char *ap;
  34756.  unsigned nbytes;
  34757.  {
  34758.          FAST HEADER *p, *q;
  34759.          unsigned n_units();
  34760.  
  34761.          if (NOT p)
  34762.                  return;
  34763.  
  34764.          p = (HEADER *) ap;                        /* point to header        *
  34765.          for (q = allocp; NOT(q < p AND p < q->s.ptr); q = q->s.ptr)
  34766.                  if (q >= q->s.ptr AND (q < p OR p < q->s.ptr))
  34767.                          break;               /* stop if at one end or another
  34768.  
  34769.          p->s.size = nbytes;                        /* record the size
  34770.          if ((p + n_units(p->s.size)) IS q->s.ptr /* join to upper nghbor?*/
  34771.             AND (nbytes % sizeof(HEADER)) IS 0)        /* only if no holes.
  34772.          {        p->s.size += q->s.ptr->s.size;
  34773.                  p->s.ptr = q->s.ptr->s.ptr;
  34774.          }
  34775.          else
  34776.                  p->s.ptr = q->s.ptr;
  34777.          if (q + n_units(q->s.size) IS p)        /* join to lower nbr? */
  34778.          {        q->s.size += p->s.size;
  34779.                  q->s.ptr = p->s.ptr;
  34780.          }
  34781.          else
  34782.                  q->s.ptr = p;
  34783.          allocp = q;
  34784.  }
  34785.  /*\p*********************************************************************/
  34786.          LOCAL HEADER *
  34787.  morecore(nu)                /* ask system for nu blocks of memory and put on
  34788.                             the available list. Return ptr to the block. */
  34789.  /*----------------------------------------------------------------------*/
  34790.  unsigned nu;
  34791.  {
  34792.          char *sbrk();
  34793.          FAST char *cp;
  34794.          FAST HEADER *up;
  34795.          FAST unsigned rnu;
  34796.  
  34797.          rnu = NALLOC * ((nu + NALLOC - 1) / NALLOC);
  34798.          cp = sbrk(nu = rnu * sizeof(HEADER));        /* nu now no. of bytes
  34799.          if ((int) cp IS EOF)                        /* no space at all
  34800.                  return NULL;
  34801.  
  34802.          up = (HEADER *) cp;
  34803.          liberate((char *) up, nu);
  34804.          return allocp;
  34805.  }
  34806.  
  34807.  /************************************************************************/
  34808.          unsigned
  34809.  n_units(n)                /* return the number of HEADER-sized units
  34810.                             required to cover n bytes.
  34811.  /*----------------------------------------------------------------------*/
  34812.  unsigned n;
  34813.  {
  34814.          return (n + sizeof(HEADER) - 1) / sizeof(HEADER);
  34815.  }
  34816.  
  34817.  
  34818.  ANAGRAM.C
  34819.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\LIB\R_LA4_02\ANAGRAM.C
  34820.  
  34821.  /* ANAGRAM.C - From page 584 of "Microsoft C Programming for    */
  34822.  /* the IBM" by Robert Lafore. Creates all possible letter ar-   */
  34823.  /* rangements in a given word. The version in the book doesn't  */
  34824.  /* work correctly. The line I changed is marked in the comments */
  34825.  /* in the source code. The printf() was added because in the    */
  34826.  /* recursive function rotate is called before the original      */
  34827.  /* word is printed.                                             */
  34828.  /****************************************************************/
  34829.  
  34830.  char word[40];
  34831.  int length;
  34832.  main()
  34833.  {
  34834.  
  34835.     printf("\n\nType word: ");
  34836.     gets(word);
  34837.     length = strlen(word);
  34838.     printf("%s\n", word);               /*** ADDED TO SOURCE ***/
  34839.     permute(0);
  34840.  }
  34841.  
  34842.  /* permute */  /* prints all permutations of word */
  34843.                 /* word begins at position startperm */
  34844.  permute(startperm)
  34845.  int startperm;
  34846.  {
  34847.  int j;
  34848.  
  34849.     if(length - startperm < 2)       /* exit if one char */
  34850.        return;
  34851.     for(j = startperm; j < length - 1; j++)  {   /*# chars in word-1*/
  34852.        permute(startperm + 1);       /*permutes all but first*/
  34853.        rotate(startperm);            /*rotate all chars*/
  34854.        printf("%s\n", word);
  34855.     }
  34856.     permute(startperm + 1); /*restore word to*/
  34857.     rotate(startperm);               /*form at entry*/
  34858.  }
  34859.  
  34860.  /* rotate() */    /*rotates word one char left*/
  34861.                    /*word begins at char pos startrot*/
  34862.  rotate(startrot)
  34863.  int startrot;
  34864.  {
  34865.  int j;
  34866.  char ch;
  34867.  
  34868.     ch = word[startrot];             /*save first char*/
  34869.     for(j = startrot; j < length - 1; j++) /*move other chars left*/
  34870.        word[j] = word[j + 1];              /* one position */
  34871.     word[length - 1] = ch;
  34872.  }
  34873.  
  34874.  
  34875.  
  34876.  ANALYZE.C
  34877.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\UTIL\CC68\ANALYZE.C
  34878.  
  34879.  #include        <stdio.h>
  34880.  #include        "c.h"
  34881.  #include        "expr.h"
  34882.  #include        "gen.h"
  34883.  #include        "cglbdec.h"
  34884.  
  34885.  /*
  34886.   *        68000 C compiler
  34887.   *
  34888.   *        Copyright 1984, 1985, 1986 Matthew Brandt.
  34889.   *  all commercial rights reserved.
  34890.   *
  34891.   *        This compiler is intended as an instructive tool for personal use.
  34892.   *        use for profit without the written consent of the author is prohibi
  34893.   *
  34894.   *        This compiler may be distributed freely for non-commercial use as l
  34895.   *        as this notice stays intact. Please forward any enhancements or que
  34896.   *        to:
  34897.   *
  34898.   *                Matthew Brandt
  34899.   *                Box 920337
  34900.   *                Norcross, Ga 30092
  34901.   */
  34902.  
  34903.  extern struct amode     push[], pop[];
  34904.  
  34905.  /*
  34906.   *      this module will step through the parse tree and find all
  34907.   *      optimizable expressions. at present these expressions are
  34908.   *      limited to expressions that are valid throughout the scope
  34909.   *      of the function. the list of optimizable expressions is:
  34910.   *
  34911.   *              constants
  34912.   *              global and static addresses
  34913.   *              auto addresses
  34914.   *              contents of auto addresses.
  34915.   *
  34916.   *      contents of auto addresses are valid only if the address is
  34917.   *      never referred to without dereferencing.
  34918.   *
  34919.   *      scan will build a list of optimizable expressions which
  34920.   *      opt1 will replace during the second optimization pass.
  34921.   */
  34922.  
  34923.  static struct cse       *olist;         /* list of optimizable expressions */
  34924.  
  34925.  equalnode(node1, node2)
  34926.  /*
  34927.   *      equalnode will return 1 if the expressions pointed to by
  34928.   *      node1 and node2 are equivalent.
  34929.   */
  34930.  struct enode    *node1, *node2;
  34931.  {       if( node1 == 0 || node2 == 0 )
  34932.                  return 0;
  34933.          if( node1->nodetype != node2->nodetype )
  34934.                  return 0;
  34935.          if( (node1->nodetype == en_icon || node1->nodetype == en_labcon ||
  34936.              node1->nodetype == en_nacon || node1->nodetype == en_autocon) &&
  34937.              node1->v.i == node2->v.i )
  34938.                  return 1;
  34939.          if( lvalue(node1) && equalnode(node1->v.p[0], node2->v.p[0]) )
  34940.                  return 1;
  34941.          return 0;
  34942.  }
  34943.  
  34944.  struct cse      *searchnode(node)
  34945.  /*
  34946.   *      searchnode will search the common expression table for an entry
  34947.   *      that matches the node passed and return a pointer to it.
  34948.   */
  34949.  struct enode    *node;
  34950.  {       struct cse      *csp;
  34951.          csp = olist;
  34952.          while( csp != 0 ) {
  34953.                  if( equalnode(node,csp->exp) )
  34954.                          return csp;
  34955.                  csp = csp->next;
  34956.                  }
  34957.          return 0;
  34958.  }
  34959.  
  34960.  struct enode    *copynode(node)
  34961.  /*
  34962.   *      copy the node passed into a new enode so it wont get
  34963.   *      corrupted during substitution.
  34964.   */
  34965.  struct enode    *node;
  34966.  {       struct enode    *temp;
  34967.          if( node == 0 )
  34968.                  return 0;
  34969.          temp = xalloc(sizeof(struct enode));
  34970.          temp->nodetype = node->nodetype;
  34971.          temp->v.p[0] = node->v.p[0];
  34972.          temp->v.p[1] = node->v.p[1];
  34973.          return temp;
  34974.  }
  34975.  
  34976.  enternode(node,duse)
  34977.  /*
  34978.   *      enternode will enter a reference to an expression node into the
  34979.   *      common expression table. duse is a flag indicating whether or not
  34980.   *      this reference will be dereferenced.
  34981.   */
  34982.  struct enode    *node;
  34983.  int             duse;
  34984.  {       struct cse      *csp;
  34985.          if( (csp = searchnode(node)) == 0 ) {   /* add to tree */
  34986.                  csp = xalloc(sizeof(struct cse));
  34987.                  csp->next = olist;
  34988.                  csp->uses = 1;
  34989.                  csp->duses = (duse != 0);
  34990.                  csp->exp = copynode(node);
  34991.                  csp->voidf = 0;
  34992.                  olist = csp;
  34993.                  return csp;
  34994.                  }
  34995.          ++(csp->uses);
  34996.          if( duse )
  34997.                  ++(csp->duses);
  34998.          return csp;
  34999.  }
  35000.  
  35001.  struct cse      *voidauto(node)
  35002.  /*
  35003.   *      voidauto will void an auto dereference node which points to
  35004.   *      the same auto constant as node.
  35005.   */
  35006.  struct enode    *node;
  35007.  {       struct cse      *csp;
  35008.          csp = olist;
  35009.          while( csp != 0 ) {
  35010.                  if( lvalue(csp->exp) && equalnode(node,csp->exp->v.p[0]) ) {
  35011.                          if( csp->voidf )
  35012.                                  return 0;
  35013.                          csp->voidf = 1;
  35014.                          return csp;
  35015.                          }
  35016.                  csp = csp->next;
  35017.                  }
  35018.          return 0;
  35019.  }
  35020.  
  35021.  scanexpr(node,duse)
  35022.  /*
  35023.   *      scanexpr will scan the expression pointed to by node for optimizable
  35024.   *      subexpressions. when an optimizable expression is found it is entered
  35025.   *      into the tree. if a reference to an autocon node is scanned the
  35026.   *      corresponding auto dereferenced node will be voided. duse should be
  35027.   *      set if the expression will be dereferenced.
  35028.   */
  35029.  struct enode    *node;
  35030.  {       struct cse      *csp, *csp1;
  35031.          int             n;
  35032.          if( node == 0 )
  35033.                  return;
  35034.          switch( node->nodetype ) {
  35035.                  case en_icon:
  35036.                  case en_labcon:
  35037.                  case en_nacon:
  35038.                          enternode(node,duse);
  35039.                          break;
  35040.                  case en_autocon:
  35041.                          if( (csp = voidauto(node)) != 0 ) {
  35042.                                  csp1 = enternode(node,duse);
  35043.                                  csp1->uses = (csp1->duses += csp->uses);
  35044.                                  }
  35045.                          else
  35046.                                  enternode(node,duse);
  35047.                          break;
  35048.                  case en_b_ref:
  35049.                  case en_w_ref:
  35050.                  case en_l_ref:
  35051.                          if( node->v.p[0]->nodetype == en_autocon ) {
  35052.                                  csp = enternode(node,duse);
  35053.                                  if( csp->voidf )
  35054.                                          scanexpr(node->v.p[0],1);
  35055.                                  }
  35056.                          else
  35057.                                  scanexpr(node->v.p[0],1);
  35058.                          break;
  35059.                  case en_cbl:    case en_cwl:
  35060.                  case en_cbw:    case en_uminus:
  35061.                  case en_compl:  case en_ainc:
  35062.                  case en_adec:   case en_not:
  35063.                          scanexpr(node->v.p[0],duse);
  35064.                          break;
  35065.                  case en_asadd:  case en_assub:
  35066.                  case en_add:    case en_sub:
  35067.                          scanexpr(node->v.p[0],duse);
  35068.                          scanexpr(node->v.p[1],duse);
  35069.                          break;
  35070.                  case en_mul:    case en_div:
  35071.                  case en_lsh:    case en_rsh:
  35072.                  case en_mod:    case en_and:
  35073.                  case en_or:     case en_xor:
  35074.                  case en_lor:    case en_land:
  35075.                  case en_eq:     case en_ne:
  35076.                  case en_gt:     case en_ge:
  35077.                  case en_lt:     case en_le:
  35078.                  case en_asmul:  case en_asdiv:
  35079.                  case en_asmod:  case en_aslsh:
  35080.                  case en_asrsh:  case en_asand:
  35081.                  case en_asor:   case en_cond:
  35082.                  case en_void:   case en_assign:
  35083.                          scanexpr(node->v.p[0],0);
  35084.                          scanexpr(node->v.p[1],0);
  35085.                          break;
  35086.                  case en_fcall:
  35087.                          scanexpr(node->v.p[0],1);
  35088.                          scanexpr(node->v.p[1],0);
  35089.                          break;
  35090.                  }
  35091.  }
  35092.  
  35093.  scan(block)
  35094.  /*
  35095.   *      scan will gather all optimizable expressions into the expression
  35096.   *      list for a block of statements.
  35097.   */
  35098.  struct snode    *block;
  35099.  {       while( block != 0 ) {
  35100.                  switch( block->stype ) {
  35101.                          case st_return:
  35102.                          case st_expr:
  35103.                                  opt4(&block->exp);
  35104.                                  scanexpr(block->exp,0);
  35105.                                  break;
  35106.                          case st_while:
  35107.                          case st_do:
  35108.                                  opt4(&block->exp);
  35109.                                  scanexpr(block->exp,0);
  35110.                                  scan(block->s1);
  35111.                                  break;
  35112.                          case st_for:
  35113.                                  opt4(&block->label);
  35114.                                  scanexpr(block->label,0);
  35115.                                  opt4(&block->exp);
  35116.                                  scanexpr(block->exp,0);
  35117.                                  scan(block->s1);
  35118.                                  opt4(&block->s2);
  35119.                                  scanexpr(block->s2,0);
  35120.                                  break;
  35121.                          case st_if:
  35122.                                  opt4(&block->exp);
  35123.                                  scanexpr(block->exp,0);
  35124.                                  scan(block->s1);
  35125.                                  scan(block->s2);
  35126.                                  break;
  35127.                          case st_switch:
  35128.                                  opt4(&block->exp);
  35129.                                  scanexpr(block->exp,0);
  35130.                                  scan(block->s1);
  35131.                                  break;
  35132.                          case st_case:
  35133.                                  scan(block->s1);
  35134.                                  break;
  35135.                          }
  35136.                  block = block->next;
  35137.                  }
  35138.  }
  35139.  
  35140.  exchange(c1)
  35141.  /*
  35142.   *      exchange will exchange the order of two expression entries
  35143.   *      following c1 in the linked list.
  35144.   */
  35145.  struct cse      **c1;
  35146.  {       struct cse      *csp1, *csp2;
  35147.          csp1 = *c1;
  35148.          csp2 = csp1->next;
  35149.          csp1->next = csp2->next;
  35150.          csp2->next = csp1;
  35151.          *c1 = csp2;
  35152.  }
  35153.  
  35154.  int     desire(csp)
  35155.  /*
  35156.   *      returns the desirability of optimization for a subexpression.
  35157.   */
  35158.  struct cse      *csp;
  35159.  {       if( csp->voidf || (csp->exp->nodetype == en_icon &&
  35160.                          csp->exp->v.i < 16 && csp->exp->v.i >= 0))
  35161.                  return 0;
  35162.          if( lvalue(csp->exp) )
  35163.                  return 2 * csp->uses;
  35164.          return csp->uses;
  35165.  }
  35166.  
  35167.  int     bsort(list)
  35168.  /*
  35169.   *      bsort implements a bubble sort on the expression list.
  35170.   */
  35171.  struct cse      **list;
  35172.  {       struct cse      *csp1, *csp2;
  35173.          int             i;
  35174.          csp1 = *list;
  35175.          if( csp1 == 0 || csp1->next == 0 )
  35176.                  return 0;
  35177.          i = bsort( &(csp1->next));
  35178.          csp2 = csp1->next;
  35179.          if( desire(csp1) < desire(csp2) ) {
  35180.                  exchange(list);
  35181.                  return 1;
  35182.                  }
  35183.          return 0;
  35184.  }
  35185.  
  35186.  allocate()
  35187.  /*
  35188.   *      allocate will allocate registers for the expressions that have
  35189.   *      a high enough desirability.
  35190.   */
  35191.  {       struct cse      *csp;
  35192.          struct enode    *exptr;
  35193.          int             datareg, addreg, mask, rmask, i;
  35194.          struct amode    *ap, *ap2;
  35195.          datareg = 3;
  35196.          addreg = 10;
  35197.          mask = 0;
  35198.                  rmask = 0;
  35199.          while( bsort(&olist) );         /* sort the expression list */
  35200.          csp = olist;
  35201.          while( csp != 0 ) {
  35202.                  if( desire(csp) < 3 )
  35203.                          csp->reg = -1;
  35204.                  else if( csp->duses > csp->uses / 4 && addreg < 14 )
  35205.                          csp->reg = addreg++;
  35206.                  else if( datareg < 8 )
  35207.                          csp->reg = datareg++;
  35208.                  else
  35209.                          csp->reg = -1;
  35210.                  if( csp->reg != -1 )
  35211.                                  {
  35212.                                                  rmask = rmask | (1 << (15 - c
  35213.                          mask = mask | (1 << csp->reg);
  35214.                                  }
  35215.                  csp = csp->next;
  35216.                  }
  35217.          if( mask != 0 )
  35218.                  gen_code(op_movem,4,make_mask(rmask),push);
  35219.          save_mask = mask;
  35220.          csp = olist;
  35221.          while( csp != 0 ) {
  35222.                  if( csp->reg != -1 )
  35223.                          {               /* see if preload needed */
  35224.                          exptr = csp->exp;
  35225.                          if( !lvalue(exptr) || (exptr->v.p[0]->v.i > 0) )
  35226.                                  {
  35227.                                  initstack();
  35228.                                  ap = gen_expr(exptr,F_ALL,4);
  35229.                                  if( csp->reg < 8 )
  35230.                                          ap2 = makedreg(csp->reg);
  35231.                                  else
  35232.                                          ap2 = makeareg(csp->reg - 8);
  35233.                                  gen_code(op_move,4,ap,ap2);
  35234.                                  freeop(ap);
  35235.                                  }
  35236.                          }
  35237.                  csp = csp->next;
  35238.                  }
  35239.  }
  35240.  
  35241.  repexpr(node)
  35242.  /*
  35243.   *      repexpr will replace all allocated references within an expression
  35244.   *      with tempref nodes.
  35245.   */
  35246.  struct enode    *node;
  35247.  {       struct cse      *csp;
  35248.          if( node == 0 )
  35249.                  return;
  35250.          switch( node->nodetype ) {
  35251.                  case en_icon:
  35252.                  case en_nacon:
  35253.                  case en_labcon:
  35254.                  case en_autocon:
  35255.                          if( (csp = searchnode(node)) != 0 )
  35256.                                  if( csp->reg > 0 ) {
  35257.                                          node->nodetype = en_tempref;
  35258.                                          node->v.i = csp->reg;
  35259.                                          }
  35260.                          break;
  35261.                  case en_b_ref:
  35262.                  case en_w_ref:
  35263.                  case en_l_ref:
  35264.                          if( (csp = searchnode(node)) != 0 ) {
  35265.                                  if( csp->reg > 0 ) {
  35266.                                          node->nodetype = en_tempref;
  35267.                                          node->v.i = csp->reg;
  35268.                                          }
  35269.                                  else
  35270.                                          repexpr(node->v.p[0]);
  35271.                                  }
  35272.                          else
  35273.                                  repexpr(node->v.p[0]);
  35274.                          break;
  35275.                  case en_cbl:    case en_cbw:
  35276.                  case en_cwl:    case en_uminus:
  35277.                  case en_not:    case en_compl:
  35278.                  case en_ainc:   case en_adec:
  35279.                          repexpr(node->v.p[0]);
  35280.                          break;
  35281.                  case en_add:    case en_sub:
  35282.                  case en_mul:    case en_div:
  35283.                  case en_mod:    case en_lsh:
  35284.                  case en_rsh:    case en_and:
  35285.                  case en_or:     case en_xor:
  35286.                  case en_land:   case en_lor:
  35287.                  case en_eq:     case en_ne:
  35288.                  case en_lt:     case en_le:
  35289.                  case en_gt:     case en_ge:
  35290.                  case en_cond:   case en_void:
  35291.                  case en_asadd:  case en_assub:
  35292.                  case en_asmul:  case en_asdiv:
  35293.                  case en_asor:   case en_asand:
  35294.                  case en_asmod:  case en_aslsh:
  35295.                  case en_asrsh:  case en_fcall:
  35296.                  case en_assign:
  35297.                          repexpr(node->v.p[0]);
  35298.                          repexpr(node->v.p[1]);
  35299.                          break;
  35300.                  }
  35301.  }
  35302.  
  35303.  repcse(block)
  35304.  /*
  35305.   *      repcse will scan through a block of statements replacing the
  35306.   *      optimized expressions with their temporary references.
  35307.   */
  35308.  struct snode    *block;
  35309.  {       while( block != 0 ) {
  35310.                  switch( block->stype ) {
  35311.                          case st_return:
  35312.                          case st_expr:
  35313.                                  repexpr(block->exp);
  35314.                                  break;
  35315.                          case st_while:
  35316.                          case st_do:
  35317.                                  repexpr(block->exp);
  35318.                                  repcse(block->s1);
  35319.                                  break;
  35320.                          case st_for:
  35321.                                  repexpr(block->label);
  35322.                                  repexpr(block->exp);
  35323.                                  repcse(block->s1);
  35324.                                  repexpr(block->s2);
  35325.                                  break;
  35326.                          case st_if:
  35327.                                  repexpr(block->exp);
  35328.                                  repcse(block->s1);
  35329.                                  repcse(block->s2);
  35330.                                  break;
  35331.                          case st_switch:
  35332.                                  repexpr(block->exp);
  35333.                                  repcse(block->s1);
  35334.                                  break;
  35335.                          case st_case:
  35336.                                  repcse(block->s1);
  35337.                                  break;
  35338.                          }
  35339.                  block = block->next;
  35340.                  }
  35341.  }
  35342.  
  35343.  opt1(block)
  35344.  /*
  35345.   *      opt1 is the externally callable optimization routine. it will
  35346.   *      collect and allocate common subexpressions and substitute the
  35347.   *      tempref for all occurrances of the expression within the block.
  35348.   *
  35349.   *                optimizer is currently turned off...
  35350.   */
  35351.  struct snode    *block;
  35352.  {
  35353.                  olist = 0;
  35354.          scan(block);            /* collect expressions */
  35355.          allocate();             /* allocate registers */
  35356.          repcse(block);          /* replace allocated expressions */
  35357.  }
  35358.  
  35359.  
  35360.  
  35361.  ANSI.C
  35362.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\DESMET_C\ANSI.C
  35363.  
  35364.  /*************************************************************************
  35365.  main function to test some of the ansi device driving functions
  35366.  which follow below.  NOTE:  you need your device set to ansi.sys in the
  35367.  config.sys for this to work.
  35368.  
  35369.  written by Rex Jaeschke of Rockville, MD. 1983 (301) 251-8987
  35370.  compiler used DeSmet v2.2
  35371.  
  35372.  ci () is a DeSmet compiler specific function which does direct console
  35373.  input of 1 character without echoing it. It is used in sgr_dsr and the
  35374.  testing program only. All else should run on any compiler.
  35375.  *************************************************************************/
  35376.  
  35377.  #define CTRL_C 3
  35378.  #define BELL 7
  35379.  #define NULL '\0'
  35380.  LINEMIN 1  /* Minimum screen line # */
  35381.  LINEMAX 25 /* Maximum screen line # */
  35382.  COLMMIN 1  /* Minimum screen column # */
  35383.  COLMMAX 80 /* Maximum screen column # */
  35384.  #define L_ARROW 75
  35385.  #define R_ARROW 77
  35386.  #define U_ARROW 72
  35387.  #define D_ARROW 80
  35388.  #define HOME 71
  35389.  #define END 79
  35390.  #define C_HOME 119
  35391.  
  35392.  main ()
  35393.  {
  35394.      int c;
  35395.  
  35396.      scr_ed ();               /* clear screen */
  35397.      scr_cup (12,40);         /* move to screen center */
  35398.      while ((c = ci()) != CTRL_C) {
  35399.           if (c == NULL) {    /* do we have extended code? */
  35400.                c = ci();
  35401.                switch (c) {
  35402.                case L_ARROW:
  35403.                     scr_cub (1);
  35404.                     break;
  35405.                case R_ARROW:
  35406.                     scr_cuf (1);
  35407.                     break;
  35408.                case U_ARROW:
  35409.                     scr_cuu (1);
  35410.                     break;
  35411.                case D_ARROW:
  35412.                     scr_cud (1);
  35413.                     break;
  35414.                case C_HOME:
  35415.                     scr_ed ();
  35416.                     break;
  35417.                case HOME:
  35418.                     scr_cup (LINEMIN,COLMMIN);
  35419.                     break;
  35420.                case END:
  35421.                     scr_cup (LINEMAX,COLMMAX);
  35422.                     break;
  35423.                default:
  35424.                     putchar (BELL);
  35425.                     break;
  35426.                }
  35427.           }
  35428.           else
  35429.                putchar (BELL);
  35430.      }
  35431.  }
  35432.  
  35433.  
  35434.  ESCAPE 27  /* ASCII ESC character definition */
  35435.  
  35436.  /*************************************************************************
  35437.  SCR_CUB - Cursor Backward.
  35438.  
  35439.  Moves the cursor backward n columns. Current line remains unchanged. If # of
  35440.  columns exceeds left-of-screen, cursor is left at the left-most column.
  35441.  *************************************************************************/
  35442.  
  35443.  scr_cub (ncolms)
  35444.  int ncolms;
  35445.  {
  35446.      printf ("%c[%dD",ESCAPE,ncolms);
  35447.  }
  35448.  
  35449.  /*************************************************************************
  35450.  SCR_CUD - Cursor Down.
  35451.  
  35452.  Moves the cursor down n lines. Current column remains unchanged. If # of line
  35453.  to move down exceeds bottom-of-screen, cursor is left at the bottom.
  35454.  *************************************************************************/
  35455.  
  35456.  scr_cud (nlines)
  35457.  int nlines;
  35458.  {
  35459.      printf ("%c[%dB",ESCAPE,nlines);
  35460.  }
  35461.  
  35462.  /*************************************************************************
  35463.  SCR_CUF - Cursor Forward.
  35464.  
  35465.  Moves the cursor forward n columns. Current line remains unchanged. If # of
  35466.  columns exceeds right-of-screen, cursor is left at the right-most column.
  35467.  *************************************************************************/
  35468.  
  35469.  scr_cuf (ncolms)
  35470.  int ncolms;
  35471.  {
  35472.      printf ("%c[%dC",ESCAPE,ncolms);
  35473.  }
  35474.  
  35475.  /*************************************************************************
  35476.  SCR_CUP - Cursor Position. (same as HVP)
  35477.  
  35478.  Moves the cursor to the specified position line,colm.
  35479.  *************************************************************************/
  35480.  
  35481.  scr_cup (line,colm)
  35482.  int line,colm;
  35483.  {
  35484.      printf ("%c[%d;%dH",ESCAPE,line,colm);
  35485.  }
  35486.  
  35487.  /*************************************************************************
  35488.  SCR_CUU - Cursor Up.
  35489.  
  35490.  Moves the cursor up n lines. Current column remains unchanged. If # of lines
  35491.  to move up exceeds top-of-screen, cursor is left at the top.
  35492.  *************************************************************************/
  35493.  
  35494.  scr_cuu (nlines)
  35495.  int nlines;
  35496.  {
  35497.      printf ("%c[%dA",ESCAPE,nlines);
  35498.  }
  35499.  
  35500.  /*************************************************************************
  35501.  SCR_DSR - Device Status Report.
  35502.  
  35503.  Returns the Cursor Position Report (CPR) sequence in the form ESC[line;colmR
  35504.  
  35505.  ci () is a DeSmet compiler specific function which does direct console
  35506.  input of 1 character without echoing it.
  35507.  *************************************************************************/
  35508.  
  35509.  scr_dsr (line,colm)
  35510.  int *line,*colm;
  35511.  {
  35512.      int i = 0;
  35513.      char cpr[10];
  35514.  
  35515.      printf ("%c[6n",ESCAPE);
  35516.      while ((cpr[i++] = ci ()) != 'R')
  35517.           ;
  35518.      cpr[i] = '\0';
  35519.  
  35520.  /* format of cpr[] is ESC[rr;ccR row and colm are always two digits */
  35521.  
  35522.      *line = ((cpr[2]-'0')*10)+cpr[3]-'0';
  35523.      *colm = ((cpr[5]-'0')*10)+cpr[6]-'0';
  35524.  }
  35525.  
  35526.  /*************************************************************************
  35527.  SCR_ED - Erase in Display.
  35528.  
  35529.  Erases all of the screen leaving the cursor at home
  35530.  *************************************************************************/
  35531.  
  35532.  scr_ed ()
  35533.  {
  35534.      printf ("%c[2J",ESCAPE);
  35535.  }
  35536.  
  35537.  /*************************************************************************
  35538.  SCR_EL - Erase in Line.
  35539.  
  35540.  Erases from the cursor to the end of the line including the cursor position.
  35541.  *************************************************************************/
  35542.  
  35543.  scr_el ()
  35544.  {
  35545.      printf ("%c[2K",ESCAPE);
  35546.  }
  35547.  
  35548.  /*************************************************************************
  35549.  SCR_HVP - Horizontal and Vertical Position. (same as CUP)
  35550.  
  35551.  Moves the cursor to the specified position line,colm.
  35552.  *************************************************************************/
  35553.  
  35554.  scr_hvp (line,colm)
  35555.  int line,colm;
  35556.  {
  35557.      printf ("%c[%d;%dH",ESCAPE,line,colm);
  35558.  }
  35559.  
  35560.  /*************************************************************************
  35561.  SCR_RCP - Restore Cursor Position.
  35562.  
  35563.  Restores the cursor to the value it had when previously saved by scr_scp.
  35564.  *************************************************************************/
  35565.  
  35566.  scr_rcp ()
  35567.  {
  35568.      printf ("%c[u",ESCAPE);
  35569.  }
  35570.  
  35571.  /*************************************************************************
  35572.  SCR_SCP - Save Cursor Position.
  35573.  
  35574.  Saves the current cursor position for later restoration by scr_rcp.
  35575.  *************************************************************************/
  35576.  
  35577.  scr_scp ()
  35578.  {
  35579.      printf ("%c[s",ESCAPE);
  35580.  }
  35581.  
  35582.  /*************************************************************************
  35583.  SCR_SGR - Set Graphics Rendition.
  35584.  
  35585.  Sets the character attribute specified by the parameter.
  35586.  Attributes remain in force until reset or changed.
  35587.  *************************************************************************/
  35588.  
  35589.  scr_sgr (attrib)
  35590.  int attrib;
  35591.  {
  35592.      printf ("%c[%dm",ESCAPE,attrib);
  35593.  }
  35594.  
  35595.  /*************************************************************************
  35596.  SCR_SM - Set Mode.
  35597.  
  35598.  Sets the screen width or type specified by the parameter.
  35599.  *************************************************************************/
  35600.  
  35601.  scr_sm (param)
  35602.  int param;
  35603.  {
  35604.      printf ("%c[=%dh",ESCAPE,param);
  35605.  }
  35606.  
  35607.  /*************************************************************************
  35608.  SCR_RM - Reset Mode.
  35609.  
  35610.  Sets the screen width or type specified by the parameter.
  35611.  *************************************************************************/
  35612.  
  35613.  scr_rm (param)
  35614.  int param;
  35615.  {
  35616.      printf ("%c[=%dl",ESCAPE,param);
  35617.  }
  35618.  
  35619.  
  35620.  ANSI.C
  35621.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\LIB\ME39SRC2\ANSI.C
  35622.  
  35623.  /*
  35624.   * The routines in this file provide support for ANSI style terminals
  35625.   * over a serial line. The serial I/O services are provided by routines in
  35626.   * "termio.c". It compiles into nothing if not an ANSI device.
  35627.   */
  35628.  
  35629.         termdef        1                        /* don't define "term" externa
  35630.  
  35631.  #include        <stdio.h>
  35632.  #include        "estruct.h"
  35633.  #include        "edef.h"
  35634.  
  35635.  #if     ANSI
  35636.  
  35637.  #if        AMIGA
  35638.  NROW    23                      /* Screen size.                 */
  35639.  NCOL    77                      /* Edit if you want to.         */
  35640.  #else
  35641.  NROW    25                      /* Screen size.                 */
  35642.  NCOL    80                      /* Edit if you want to.         */
  35643.  #endif
  35644.         NPAUSE        100                        /* # times thru update to pau
  35645.         MARGIN        8                        /* size of minimim margin and
  35646.         SCRSIZ        64                        /* scroll size for extended li
  35647.  BEL     0x07                    /* BEL character.               */
  35648.  ESC     0x1B                    /* ESC character.               */
  35649.  
  35650.  extern  int     ttopen();               /* Forward references.          */
  35651.  extern  int     ttgetc();
  35652.  extern  int     ttputc();
  35653.  extern  int     ttflush();
  35654.  extern  int     ttclose();
  35655.  extern  int     ansimove();
  35656.  extern  int     ansieeol();
  35657.  extern  int     ansieeop();
  35658.  extern  int     ansibeep();
  35659.  extern  int     ansiopen();
  35660.  extern        int        ansirev();
  35661.  extern        int        ansiclose();
  35662.  extern        int        ansikopen();
  35663.  extern        int        ansikclose();
  35664.  extern        int        ansicres();
  35665.  
  35666.  #if        COLOR
  35667.  extern        int        ansifcol();
  35668.  extern        int        ansibcol();
  35669.  
  35670.  int        cfcolor = -1;                /* current forground color */
  35671.  int        cbcolor = -1;                /* current background color */
  35672.  
  35673.  #if        AMIGA
  35674.  /* apperently the AMIGA does not follow the ANSI standards as
  35675.     regards to colors....maybe because of the default pallette
  35676.     settings?
  35677.  */
  35678.  
  35679.  int coltran[8] = {2, 3, 5, 7, 0, 4, 6, 1};        /* color translation table
  35680.  #endif
  35681.  #endif
  35682.  
  35683.  /*
  35684.   * Standard terminal interface dispatch table. Most of the fields point into
  35685.   * "termio" code.
  35686.   */
  35687.  TERM    term    = {
  35688.          NROW-1,
  35689.          NROW-1,
  35690.          NCOL,
  35691.          NCOL,
  35692.          MARGIN,
  35693.          SCRSIZ,
  35694.          NPAUSE,
  35695.          ansiopen,
  35696.          ansiclose,
  35697.          ansikopen,
  35698.          ansikclose,
  35699.          ttgetc,
  35700.          ttputc,
  35701.          ttflush,
  35702.          ansimove,
  35703.          ansieeol,
  35704.          ansieeop,
  35705.          ansibeep,
  35706.          ansirev,
  35707.          ansicres
  35708.  #if        COLOR
  35709.          , ansifcol,
  35710.          ansibcol
  35711.  #endif
  35712.  };
  35713.  
  35714.  #if        COLOR
  35715.  ansifcol(color)                /* set the current output color */
  35716.  
  35717.  int color;        /* color to set */
  35718.  
  35719.  {
  35720.          if (color == cfcolor)
  35721.                  return;
  35722.          ttputc(ESC);
  35723.          ttputc('[');
  35724.  #if        AMIGA
  35725.          ansiparm(coltran[color]+30);
  35726.  #else
  35727.          ansiparm(color+30);
  35728.  #endif
  35729.          ttputc('m');
  35730.          cfcolor = color;
  35731.  }
  35732.  
  35733.  ansibcol(color)                /* set the current background color */
  35734.  
  35735.  int color;        /* color to set */
  35736.  
  35737.  {
  35738.          if (color == cbcolor)
  35739.                  return;
  35740.          ttputc(ESC);
  35741.          ttputc('[');
  35742.  #if        AMIGA
  35743.          ansiparm(coltran[color]+40);
  35744.  #else
  35745.          ansiparm(color+40);
  35746.  #endif
  35747.          ttputc('m');
  35748.          cbcolor = color;
  35749.  }
  35750.  #endif
  35751.  
  35752.  ansimove(row, col)
  35753.  {
  35754.          ttputc(ESC);
  35755.          ttputc('[');
  35756.          ansiparm(row+1);
  35757.          ttputc(';');
  35758.          ansiparm(col+1);
  35759.          ttputc('H');
  35760.  }
  35761.  
  35762.  ansieeol()
  35763.  {
  35764.          ttputc(ESC);
  35765.          ttputc('[');
  35766.          ttputc('K');
  35767.  }
  35768.  
  35769.  ansieeop()
  35770.  {
  35771.  #if        COLOR
  35772.          ansifcol(gfcolor);
  35773.          ansibcol(gbcolor);
  35774.  #endif
  35775.          ttputc(ESC);
  35776.          ttputc('[');
  35777.          ttputc('J');
  35778.  }
  35779.  
  35780.  ansirev(state)                /* change reverse video state */
  35781.  
  35782.  int state;        /* TRUE = reverse, FALSE = normal */
  35783.  
  35784.  {
  35785.  #if        COLOR
  35786.          int ftmp, btmp;                /* temporaries for colors */
  35787.  #endif
  35788.  
  35789.          ttputc(ESC);
  35790.          ttputc('[');
  35791.          ttputc(state ? '7': '0');
  35792.          ttputc('m');
  35793.  #if        COLOR
  35794.          if (state == FALSE) {
  35795.                  ftmp = cfcolor;
  35796.                  btmp = cbcolor;
  35797.                  cfcolor = -1;
  35798.                  cbcolor = -1;
  35799.                  ansifcol(ftmp);
  35800.                  ansibcol(btmp);
  35801.          }
  35802.  #endif
  35803.  }
  35804.  
  35805.  ansicres()        /* change screen resolution */
  35806.  
  35807.  {
  35808.          return(TRUE);
  35809.  }
  35810.  
  35811.  spal(dummy)                /* change pallette settings */
  35812.  
  35813.  {
  35814.          /* none for now */
  35815.  }
  35816.  
  35817.  ansibeep()
  35818.  {
  35819.          ttputc(BEL);
  35820.          ttflush();
  35821.  }
  35822.  
  35823.  ansiparm(n)
  35824.  register int    n;
  35825.  {
  35826.          register int q,r;
  35827.  
  35828.          q = n/10;
  35829.          if (q != 0) {
  35830.                  r = q/10;
  35831.                  if (r != 0) {
  35832.                          ttputc((r%10)+'0');
  35833.                  }
  35834.                  ttputc((q%10) + '0');
  35835.          }
  35836.          ttputc((n%10) + '0');
  35837.  }
  35838.  
  35839.  ansiopen()
  35840.  {
  35841.  #if     V7 | USG | BSD
  35842.          register char *cp;
  35843.          char *getenv();
  35844.  
  35845.          if ((cp = getenv("TERM")) == NULL) {
  35846.                  puts("Shell variable TERM not defined!");
  35847.                  exit(1);
  35848.          }
  35849.          if (strcmp(cp, "vt100") != 0) {
  35850.                  puts("Terminal type not 'vt100'!");
  35851.                  exit(1);
  35852.          }
  35853.  #endif
  35854.          strcpy(sres, "NORMAL");
  35855.          revexist = TRUE;
  35856.          ttopen();
  35857.  }
  35858.  
  35859.  ansiclose()
  35860.  
  35861.  {
  35862.  #if        COLOR
  35863.          ansifcol(7);
  35864.          ansibcol(0);
  35865.  #endif
  35866.          ttclose();
  35867.  }
  35868.  
  35869.  ansikopen()        /* open the keyboard (a noop here) */
  35870.  
  35871.  {
  35872.  }
  35873.  
  35874.  ansikclose()        /* close the keyboard (a noop here) */
  35875.  
  35876.  {
  35877.  }
  35878.  
  35879.  #if        FLABEL
  35880.  fnclabel(f, n)                /* label a function key */
  35881.  
  35882.  int f,n;        /* default flag, numeric argument [unused] */
  35883.  
  35884.  {
  35885.          /* on machines with no function keys...don't bother */
  35886.          return(TRUE);
  35887.  }
  35888.  #endif
  35889.  #else
  35890.  ansihello()
  35891.  {
  35892.  }
  35893.  #endif
  35894.  
  35895.  
  35896.  ANYFILE.C
  35897.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\LIB\CSOURCE\ANYFILE.C
  35898.  
  35899.                                           /* Chapter 10 - Program 7 */
  35900.  #include "stdio.h"
  35901.  
  35902.  main()
  35903.  {
  35904.  FILE *fp1;
  35905.  char oneword[100],filename[25];
  35906.  char *c;
  35907.  
  35908.     printf("Enter filename -> ");
  35909.     scanf("%s",filename);         /* read the desired filename */
  35910.     fp1 = fopen(filename,"r");
  35911.  
  35912.     do {
  35913.        c = fgets(oneword,100,fp1); /* get one line from the file */
  35914.        if (c != NULL)
  35915.           printf("%s",oneword);    /* display it on the monitor  */
  35916.     } while (c != NULL);          /* repeat until NULL          */
  35917.  
  35918.     fclose(fp1);
  35919.  }
  35920.  
  35921.  
  35922.  
  35923.  ANYWHERE.C
  35924.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\UTIL\ANYWHERE\ANYWHERE.C
  35925.  
  35926.  /***************************************************************
  35927.  *                                                               *
  35928.  *           WHERE                                               *
  35929.  *                                                               *
  35930.  * Where is a program to locate files on the PC hard disk.      *
  35931.  * It requires DOS 2.x or 3.x.                                       *
  35932.  *                                                               *
  35933.  * The command line syntax is:                                       *
  35934.  * where [starting directory]filename.ext                       *
  35935.  *                                                               *
  35936.  * Written by Mark S. Ackerman                                       *
  35937.  * PROGRAM IS WRITTEN IN MARK WILLIAMS  M W C 8 6  LANGUAGE     *
  35938.  * Copyright 1984, 1985 by Mark S. Ackerman.  Permission is     *
  35939.  * granted for unlimited copies if not sold or otherwise        *
  35940.  * exchanged for gain.                                               *
  35941.  *  PUBLISHED IN PC TECH JOURNAL - OCT '85 - VOL 3, NO. 10      *
  35942.  *                                                               *
  35943.  *  MODIFIED FOR LATTICE C VER 2.15 BY JOHN TEICHERT NOV 85     *
  35944.  *     Names shortened to 8 significant characters.               *
  35945.  *     Elimination of PTOREG() function                               *
  35946.  *     flag86 defined to return flags from intdosx()               *
  35947.  *     Use segread to set up regs for intdosx() function.       *
  35948.  *     Program modified to look for drive designator with colon.*
  35949.  *     DATE structure defined with bits high order to low order.*
  35950.  *     intrpt.h replaced with dos.h header file                       *
  35951.  *     rindex() function replaced with strrchr() function.      *
  35952.  *                                                               *
  35953.  *  MODIFIED FOR MICROSOFT V3 BY JOHN TEICHERT JAN 86.               *
  35954.  *     flag86 REDEFINED to dos_result for  intdosx() ax reg     *
  35955.  *     modified to use flag in REGS structure.                       *
  35956.  *     DATE structure defined with bits low order to high order.*
  35957.  *     _stack will not produce large stack in ver 3.0 must use  *
  35958.  *             link option or exemod program.                       *
  35959.  *                                                               *
  35960.  *   Added Code And Became ANYWHERE  JOHN TEICHERT FEB 86       *
  35961.  *                                                               *
  35962.  *        Taking advantange of V3 access to the environment      *
  35963.  *        string we set up the following.                        *
  35964.  *                                                               *
  35965.  *        1. An Environment String indicating what disk drives   *
  35966.  *           you want ANYWHERE to search as follows:               *
  35967.  *                                                               *
  35968.  *           AWDISK=d:[;d:[;d:;...d:]]                               *
  35969.  *                                                               *
  35970.  *              where d: is the drive specifier for one or more  *
  35971.  *              fixed disk(s).                                       *
  35972.  *                                                               *
  35973.  *              drive specifiers are searched in the order they  *
  35974.  *              are entered.                                       *
  35975.  *                                                               *
  35976.  *        2. The user can specify the environment string with    *
  35977.  *           the use of the set command in the autoexec.bat file.*
  35978.  *           As an example:                                       *
  35979.  *                                                               *
  35980.  *                set awdisks=c:;e:;d:                               *
  35981.  *                                                               *
  35982.  *           would be placed into the autoexec.bat file.               *
  35983.  *                                                               *
  35984.  *        With this modification the user has extended directory *
  35985.  *        capabilities by automatically searching all disk drives*
  35986.  *        listed in the environment string or isolated to a      *
  35987.  *        single drive by placing a drive specifier in the       *
  35988.  *        command line argument string.                               *
  35989.  *                                                               *
  35990.  *        Be sure to use the /stack option on the link with      *
  35991.  *        Microsoft V3 C compiler or stack problems will result  *
  35992.  *        if many subdirectories.  8K seems to work well.        *
  35993.  *                                                               *
  35994.  *                                                               *
  35995.  *        Added a few little perks May 1987 - Michael L Kaufman  *
  35996.  *                                                               *
  35997.  ***************************************************************/
  35998.  
  35999.  
  36000.  /***************************************************************
  36001.  * The C header files                                               *
  36002.  * These identify library routines like printf() and int86x()  *
  36003.  ***************************************************************/
  36004.  
  36005.  <stdio.h>   /* standard i/o                              */
  36006.  <dos.h>     /* functions for DOS interrupt calls     */
  36007.  
  36008.  /***************************************************************
  36009.  * Structure for MS-DOS date and time fields                       *
  36010.  * See pages 4-6 and 4-7 of the DOS 2.1 technical               *
  36011.  * reference manual for more information                        *
  36012.  * This structure is used in the next structure definition      *
  36013.  ***************************************************************/
  36014.  
  36015.  struct msdos_date
  36016.          {
  36017.          unsigned ms_sec    : 5; /* time in 2 sec. int (5 bits)*/
  36018.          unsigned ms_min    : 6; /* minutes (6 bits)              */
  36019.          unsigned ms_hour   : 5; /* hours (5 bits)              */
  36020.          unsigned ms_day    : 5; /* day of month (5 bits)      */
  36021.          unsigned ms_month  : 4; /* month (4 bits)              */
  36022.          unsigned ms_year   : 7; /* year since 1980 (7 bits)   */
  36023.          };
  36024.  
  36025.  /***************************************************************
  36026.  * Definition of DOS Disk Transfer Area (DTA)                       *
  36027.  ***************************************************************/
  36028.  
  36029.  /***************************************************************
  36030.  * Structure filled in by MS-DOS for interrupt 21 calls               *
  36031.  * See page 5-46 of the DOS 2.1 technical reference               *
  36032.  * manual for more information                                       *
  36033.  ***************************************************************/
  36034.  
  36035.  struct DTA
  36036.          {
  36037.          char        DTA_dosinfo[21];       /* used by DOS                */
  36038.          char        DTA_attr;               /* file attribute byte        */
  36039.          struct msdos_date DTA_date;    /* date struct. as above */
  36040.          long        DTA_size;               /* file size                */
  36041.          char        DTA_filename[13];      /* file name (w/o path)        */
  36042.          };
  36043.  
  36044.  
  36045.  /***************************************************************
  36046.  *                Definitions of constants                       *
  36047.  ***************************************************************/
  36048.  
  36049.  carry_set 0x0001 /* mask for flag register               */
  36050.                           /* for carry bit                       */
  36051.  no_type   0x00         /* no bits set on file attribute byte */
  36052.  directory_type         0x10 /* directory file bit on file    */
  36053.                                /* info word                       */
  36054.  
  36055.  no_more_files         18        /* DOS return code for                */
  36056.                                  /* no more files                */
  36057.  
  36058.  end_of_string         '\0'   /* C uses a binary zero to      */
  36059.                                  /* signal end of string         */
  36060.  
  36061.  backslash '\\'   /* the backslash character           */
  36062.  colon          ':'    /* Drive separator  JT 11/85           */
  36063.  semicolon ';'   /* Environment string drive separator   */
  36064.  
  36065.  char *month[] = {
  36066.                  "Jan","Feb","Mar","Apr","May","Jun",
  36067.                  "Jul","Aug","Sep","Oct","Nov","Dec"
  36068.                  };
  36069.  
  36070.  char *time_of_day[2] = {"AM","PM"};
  36071.  
  36072.  
  36073.  /***************************************************************
  36074.  *                Define the type "filename"                     *
  36075.  *                        to be a string of 65 characters  -JT   *
  36076.  ***************************************************************/
  36077.  
  36078.  typedef char filename[65];                   /* Change to 65 -JT
  36079.  
  36080.  /***************************************************************
  36081.  *                                                               *
  36082.  * The following filename strings are used in the program:      *
  36083.  *                                                               *
  36084.  *        chk_str                 filename to be searched for    *
  36085.  *                                filename in the command line)  *
  36086.  *        dir_string                directory name to be searched  *
  36087.  *        new_dstr                directory name to be searched  *
  36088.  *                                  on next recursive call       *
  36089.  *        cur_str                 temporary string for searching *
  36090.  *                                  in a specific directory      *
  36091.  ***************************************************************/
  36092.  
  36093.  
  36094.  /***************************************************************
  36095.  * Definition of any forward-referenced functions               *
  36096.  ***************************************************************/
  36097.  
  36098.  char *DATE();
  36099.  char *space();
  36100.  
  36101.  /***************************************************************
  36102.  *                Global variables                               *
  36103.  ***************************************************************/
  36104.  
  36105.  filename chk_str;                        /* this string "remembers" user inpu
  36106.  union        REGS        r8086;                        /* structure to allow
  36107.                                          /*   registers for interrupts
  36108.  struct        SREGS        s8086;                        /*   structure for s
  36109.  char                date_str[40];                /* print output string for d
  36110.  int                count=0;                /* Number of matches dislplayed
  36111.  char                spce[] = "                                           ";
  36112.  int                lastzero = 41;
  36113.  unsigned        dos_result;                /* Return code from DOS
  36114.  
  36115.  /**
  36116.  *        FOLLOWING CODE COMMENTED OUT FOR V3.0 SINCE CAN'T FIND A WAY TO DO I
  36117.  *        WITH A VARIABLE.
  36118.  **/
  36119.  
  36120.  /*int                  _stack = 8192;           Insure large stack to support
  36121.  /*                                           recursion in look routine
  36122.  
  36123.  /***************************************************************
  36124.  *                MAIN() -- the beginning of the code               *
  36125.  ***************************************************************/
  36126.  
  36127.  main( argc, argv, envp )
  36128.  int        argc;
  36129.  char        *argv[];
  36130.  char        *envp[];                        /* Version 3 pointer to environ *
  36131.  {
  36132.  /**
  36133.  *        External        function
  36134.  **/
  36135.  char                        *strrchr();        /* Lattice function which sear
  36136.                                          /* for the last occurrance of the  */
  36137.                                          /* desired character
  36138.  
  36139.  char                        *strchr();        /* Lattice function which searc
  36140.                                          /* for the first occurrance of the */
  36141.                                          /* desired character
  36142.  
  36143.  filename               dir_string;        /* directory to be searched
  36144.  
  36145.  char                       *usr_file;        /* address of filename in
  36146.                                          /* command line argument           */
  36147.                                          /* (ie, the filename)
  36148.  
  36149.  char *last_loc;                         /* address of last backslash in    */
  36150.                                          /* command line argument           */
  36151.  
  36152.  char *dos_parm;                         /* address of
  36153.                                          /* command line argument           */
  36154.  
  36155.  int  lst_dchr;                                /* last character
  36156.                                          /* in directory string
  36157.  
  36158.  /** added for ANYWHERE JT **/
  36159.  int                        strcmpi();        /* Microsoft V3 function to do a
  36160.                                          /*   string compare without regard
  36161.                                          /*   to case.
  36162.  void                        strcat();        /* String concatenate function
  36163.      MAXEDRV        16                /* Set max number of drives
  36164.  char                        *strdup();        /* MSC string dup function
  36165.  char                        *getcwd();        /* MSC ver3 function to return
  36166.                                          /* current working directory
  36167.  char                        *envdup;        /* pointer to duplicate of env st
  36168.  char                        *envdrv[MAXEDRV];   /* pointer to each drive
  36169.                                          /* in envdup
  36170.  filename                env_dir_string; /* Environment directory string
  36171.  char                        **cur_envp;        /* current environmnet array p
  36172.  char                        *env_stp;        /* Current environment string po
  36173.  char                        *env_chp;        /* environment character pointer
  36174.  static        char                envid[]="AWDISK=";  /* Our environment stri
  36175.  char                        *envid_p;        /* current id string ptr
  36176.  filename                dos_cwd;        /* buffer to hold cur working dir
  36177.  int                        env_cnt;        /* count of number of drives
  36178.  int                        envd_len;        /* length of the environment stri
  36179.  int                        wi;                /* A working integer
  36180.  struct        {
  36181.          unsigned        drive        : 1;        /* drive specifier found in
  36182.          unsigned        found        : 1;        /* environment contains AWDI
  36183.          unsigned        srchcwd : 1;        /* Search for current work dir
  36184.          unsigned        addcwd        : 1;        /* Add current working dire
  36185.          } flag;
  36186.  
  36187.  /********************************************************
  36188.  *        check number of incoming arguments                *
  36189.  *        if incorrect, write an error message                *
  36190.  ********************************************************/
  36191.  
  36192.  if (argc != 2)
  36193.      {
  36194.      printf( "ERR  usage is:   AW    [starting directory]filename.ext\n\n");
  36195.      printf( "Environment string is: AWDISK=d: [;d: [;....d:] ]\n");
  36196.      return;
  36197.      }
  36198.  
  36199.  /**        Added for Lattice C Version 2.15 JT
  36200.  *        Initialize the segment structure for later dos interrupt calls.
  36201.  **/
  36202.  
  36203.  segread( &s8086 );                /* initialize segments for interrupt calls
  36204.  dos_result = 0;                 /* init interrupt return variable MSCV3.   */
  36205.  
  36206.  /**
  36207.  *        dos_parm is set to the first argument in the
  36208.  *        command line
  36209.  **/
  36210.  
  36211.  dos_parm = *(++argv);
  36212.  
  36213.  /**
  36214.  *        If a drive specifier is found we do not want to go through overhead
  36215.  *        of environment string search.                AW - JT
  36216.  *        If no drive specifier is found we will extract the drive of the
  36217.  *            current working directory to be added to the array of environmen
  36218.  *            drives.
  36219.  **/
  36220.  flag.srchcwd = 1;                        /* Init true until command line
  36221.                                          /*     option added.
  36222.  if ( strchr( dos_parm, colon ) )
  36223.      {
  36224.      flag.drive = 1;                        /* Set drive specifier true
  36225.      flag.found = 0;                        /* Set environment found false
  36226.      }
  36227.  else
  36228.      {
  36229.      /**
  36230.      *        Drive flag is set to zero
  36231.      *        If the search current working directory flag is true then:
  36232.      *            Current working directory is obtained and the drive isolated
  36233.      *                from the directory string.
  36234.      **/
  36235.      flag.drive = 0;
  36236.      if ( flag.srchcwd )
  36237.          {
  36238.          getcwd(dos_cwd,sizeof(dos_cwd)-1);
  36239.          env_chp = strchr( dos_cwd, colon );
  36240.          *++env_chp = end_of_string;
  36241.          }
  36242.      }
  36243.  /**
  36244.  *   We check to see if there was a drive specifier found.  If so we
  36245.  +        want to continue rather than check the environment string for the
  36246.  *        AWDISK= parameter
  36247.  **/
  36248.  if (flag.drive)
  36249.      {
  36250.      /**
  36251.      *        There was a drive specifier so we zero the env_cnt variable
  36252.      **/
  36253.      env_cnt = 0;
  36254.      }
  36255.  else
  36256.      {
  36257.      /**
  36258.      *        The drive specifier was  found in the DOS command argument there
  36259.      *            the environment strings will be searched for the AWDISK= par
  36260.      **/
  36261.      cur_envp = envp;                    /* init current environ pointer */
  36262.      flag.found = 0;                    /* init flag found false            */
  36263.      /**
  36264.      *            Check each environment string to see if it is the AW
  36265.      *            environment string.  The envp array is terminated with
  36266.      *            a NULL pointer.  The search is terminated when found is
  36267.      *            true or the environment pointer is NULL.
  36268.      **/
  36269.      while( *cur_envp && !flag.found )
  36270.          {
  36271.          envid_p = envid;        /* init pointer to our environ id */
  36272.          env_chp = *cur_envp;        /* init pointer to environ string */
  36273.          flag.found = 1;         /* Set flag found = true to enter loop */
  36274.          /**
  36275.          *   Compare each character in the string to AWDISK=
  36276.          **/
  36277.          for ( env_cnt=0; (env_cnt<(sizeof(envid)-1)) && flag.found; env_cnt++
  36278.              {
  36279.              if ( *envid_p++ != *env_chp++ )
  36280.                  flag.found = 0;
  36281.              else
  36282.                  flag.found = 1;
  36283.              }
  36284.  
  36285.          /**
  36286.          *   If found true then copy string to our buffer
  36287.          *   Replace ';' with 0x00
  36288.          *   Count the number of drives found
  36289.          *   Set addcwd true to add the current working directory
  36290.          **/
  36291.          if ( flag.found )
  36292.              {
  36293.              flag.addcwd = 1;
  36294.              /**
  36295.              *        Create a duplicate of the environment string
  36296.              *        If it cannot be created we will probably fail but allow
  36297.              *        continuation just in case
  36298.              **/
  36299.              if (!(envdup = strdup(env_chp)))
  36300.                  {
  36301.                  fprintf( stderr, "Memory alloc problems\n" );
  36302.                  env_cnt = 0;                /* zero count cause we're goin ou
  36303.                  break;                        /* allow current drive to conti
  36304.                  }
  36305.              /**
  36306.              *        Examine the environment string for a ";"
  36307.              *        Replace each semicolon with a "\0" to terminate the stri
  36308.              *        Increment the env_cnt variable for each drive in the sys
  36309.              *            that the user wished to examine
  36310.              *        Place the pointer to the beginning of drive in the envdr
  36311.              *            variable.
  36312.              **/
  36313.              envd_len = strlen(envdup);        /* get length of environment st
  36314.              env_cnt  = 0;                /* Set count of drives to zero
  36315.              env_stp  = envdup;                /* Set the string pointer to cu
  36316.              while ( (envd_len > 0) && (env_cnt < MAXEDRV) )
  36317.                  {
  36318.                  /**
  36319.                  *   Look for the semicolon
  36320.                  **/
  36321.                  if (env_chp = strchr(env_stp,semicolon))
  36322.                      {
  36323.                      /**
  36324.                      *        We have a semicolon : See if its false
  36325.                      **/
  36326.                      if (env_chp-env_stp)
  36327.                          {
  36328.                          /**
  36329.                          *   There is a string so put in array
  36330.                          *   Decrement the length field
  36331.                          *   Change the value of the semi colon to a end of st
  36332.                          *   Set up a new pointer beyond env_stp
  36333.                          **/
  36334.                          envdrv[env_cnt++] = env_stp;
  36335.                          envd_len = envd_len-((env_chp-env_stp)+1);
  36336.                          *env_chp = end_of_string;
  36337.                          /**
  36338.                          *   Check the environment entry against the current
  36339.                          *        working directory.  If equal set addcwd to
  36340.                          *        false
  36341.                          **/
  36342.                          if ( strcmpi( dos_cwd, env_stp ) == 0 )
  36343.                              flag.addcwd = 0;
  36344.                          env_stp = ++env_chp;
  36345.                          }
  36346.                      else
  36347.                          {
  36348.                          /**
  36349.                          *   There was no string just a semicolon
  36350.                          *   Decrement the length field
  36351.                          *   setup a new pointer beyond the semi-colon
  36352.                          **/
  36353.                          --envd_len;
  36354.                          env_stp = ++env_chp;
  36355.                          }
  36356.                      }
  36357.                  else
  36358.                      {
  36359.                      /**
  36360.                      *        There was no semi-colon so we are on the last dr
  36361.                      *            entry.
  36362.                      *        Place address in array and increment count
  36363.                      *        Set the remaining string length to zero to exit.
  36364.                      *        See if last entry matches current working direct
  36365.                      *            if so don't add it.
  36366.                      **/
  36367.                      envdrv[env_cnt++] = env_stp;
  36368.                      envd_len = 0;
  36369.                      if ( strcmpi( dos_cwd, env_stp ) == 0 )
  36370.                          flag.addcwd = 0;
  36371.                      if ( flag.addcwd )
  36372.                          {
  36373.                          if ( (env_cnt < MAXEDRV) && (flag.srchcwd) )
  36374.                              envdrv[env_cnt++] = dos_cwd;
  36375.                          }
  36376.                      }
  36377.                  }
  36378.              }
  36379.          else
  36380.              {
  36381.              /**
  36382.              *        This environment string is not the one we want therefore
  36383.              *        Increment current environment pointer and continue
  36384.              **/
  36385.              cur_envp++;
  36386.              }
  36387.          }   /* End While */
  36388.      }        /* End Else */
  36389.  
  36390.  /**
  36391.  * The dos_parm is then searched for the last
  36392.  * occurrence of a backslash to find the end of
  36393.  * the directory name.
  36394.  **/
  36395.  
  36396.  last_loc = strrchr(dos_parm,backslash);
  36397.  
  36398.  
  36399.  /********************************************************
  36400.  * If there was not a backslash (and therefore the        *
  36401.  *     beginning directory is the root directory)        *
  36402.  * begin                                                 *
  36403.  *   copy command line argument into chk_str                *
  36404.  *   copy root directory into dir_string                 *
  36405.  * end                                                        *
  36406.  * else                                                        *
  36407.  * (if there was a backslash and therefore a beginning        *
  36408.  *     directory specified in the command line)                *
  36409.  * begin                                                 *
  36410.  *   set the usr_file to the next character                *
  36411.  *        past the backslash                                *
  36412.  *   copy the usr_file into chk_str                        *
  36413.  *   copy the command line argument into                 *
  36414.  *        dir_string                                        *
  36415.  *   terminate dir_string just after the                 *
  36416.  *        last backslash (therefore leaving only the        *
  36417.  *        the directory name in the string)                *
  36418.  * end                                                        *
  36419.  ********************************************************/
  36420.  
  36421.  if (last_loc == NULL)
  36422.      {
  36423.      /**
  36424.      * Since no backslash we'll still check for a drive designator LC 2.14 -JT
  36425.      **/
  36426.      last_loc = strchr(dos_parm, colon);
  36427.      if (last_loc == NULL)
  36428.          {
  36429.          strcpy(chk_str,dos_parm);
  36430.          strcpy(dir_string,"\\");
  36431.          }
  36432.      else
  36433.          {
  36434.          usr_file = last_loc + 1;
  36435.          strcpy(chk_str,usr_file);
  36436.          strcpy(dir_string,dos_parm);
  36437.          lst_dchr = usr_file - dos_parm;
  36438.          dir_string[lst_dchr++] = backslash;        /* Fake path */
  36439.          dir_string[lst_dchr]   = end_of_string; /* terminate directory str */
  36440.          }
  36441.      }
  36442.  else
  36443.      {
  36444.      usr_file = last_loc + 1;
  36445.      strcpy(chk_str,usr_file);
  36446.      strcpy(dir_string,dos_parm);
  36447.      lst_dchr = usr_file - dos_parm;
  36448.      dir_string[lst_dchr] = end_of_string;
  36449.      }
  36450.  
  36451.  
  36452.  /**
  36453.  *   if the environment string was found concatenate environment drives
  36454.  *        with the directory string that was extracted.
  36455.  *   else look for just the directory string
  36456.  **/
  36457.  
  36458.  if ( flag.found)
  36459.      {
  36460.      for ( wi = 0; wi < env_cnt; wi++ )
  36461.          {
  36462.          /**
  36463.          *   Search each directory in the environment array
  36464.          **/
  36465.          strcpy( env_dir_string, envdrv[ wi ] );
  36466.          strcat( env_dir_string, dir_string );
  36467.          LOOK( env_dir_string );
  36468.          }
  36469.      }
  36470.  else
  36471.      {
  36472.      /**
  36473.      *        There is no environment loop so look only for directory string
  36474.      **/
  36475.      LOOK(dir_string);
  36476.      }
  36477.  
  36478.  return;
  36479.  
  36480.  }
  36481.  
  36482.  /**/
  36483.  /*********************************************************
  36484.  *        LOOK is the recursive procedure in WHERE         *
  36485.  *        It is called once for each subdirectory          *
  36486.  *********************************************************/
  36487.  
  36488.  LOOK(dir_string)
  36489.  char *dir_string;
  36490.  {
  36491.  
  36492.  struct DTA cur_DTA;                /* used to return data from DOS  */
  36493.  
  36494.  filename new_dstr;                /* the directory to be                 */
  36495.                                  /* searched on the next          */
  36496.                                  /* call to LOOK()                 */
  36497.  
  36498.  filename cur_str;                /* temporary filename                 */
  36499.                                  /* string for searching for         */
  36500.                                  /* directories                         */
  36501.  
  36502.  
  36503.  /**
  36504.  * Form cur_str by copying dir_string and                *
  36505.  *    and then concatenating "*.*" to look through all   *
  36506.  *    files                                                *
  36507.  **/
  36508.  
  36509.  strcpy(cur_str,dir_string);
  36510.  strcat(cur_str,"*.*");
  36511.  
  36512.  /**
  36513.  * Set the Disk Transfer Area in DOS to the cur_DTA        *
  36514.  *    structure                                                *
  36515.  * Get the first subdirectory in this directory                *
  36516.  **/
  36517.  
  36518.  SET_DTA(&cur_DTA);
  36519.  GET_FIRST(cur_str,directory_type);
  36520.  
  36521.  /**
  36522.  * while there are more subdirectories in this directory *
  36523.  * begin                                                 *
  36524.  *   double check for proper directories (see text)        *
  36525.  *   if a directory                                        *
  36526.  *   begin                                                *
  36527.  *     set up the new_dstr for the                        *
  36528.  *     next call to LOOK (see text)                        *
  36529.  *     call LOOK                                         *
  36530.  *     reset Disk Transfer Address (see text)                *
  36531.  *   end                                                 *
  36532.  *   look for next directory                                *
  36533.  * end                                                        *
  36534.  **/
  36535.  
  36536.  while (!(r8086.x.cflag & carry_set))
  36537.      {
  36538.      if (cur_DTA.DTA_attr == directory_type &&
  36539.         cur_DTA.DTA_filename[0] != '.')
  36540.          {
  36541.          strcpy(new_dstr,dir_string);
  36542.          strcat(new_dstr,cur_DTA.DTA_filename);
  36543.          strcat(new_dstr,"\\");
  36544.          LOOK(new_dstr);
  36545.          SET_DTA(&cur_DTA);
  36546.          }
  36547.      GET_NEXT();
  36548.      }
  36549.  
  36550.  /********************************************************
  36551.  * if there are no more subdirectories in this directory *
  36552.  *   look for files                                        *
  36553.  * else                                                        *
  36554.  *   print an error message                                *
  36555.  ********************************************************/
  36556.  
  36557.  if (r8086.x.ax == no_more_files)
  36558.      GET_FILES(dir_string,&cur_DTA);
  36559.  else
  36560.      printf("problem with looking thru %s\n",dir_string);
  36561.  return;
  36562.  
  36563.  }
  36564.  
  36565.  
  36566.  /********************************************************
  36567.  * GET_FILES                                                *
  36568.  * is called once per directory to look for the                *
  36569.  *   actual files matching the search string                *
  36570.  ********************************************************/
  36571.  
  36572.  GET_FILES(dir_string,cur_DTA)
  36573.  char *dir_string;
  36574.  struct DTA *cur_DTA;
  36575.  {
  36576.  
  36577.  filename cur_str;
  36578.  
  36579.  /********************************************************
  36580.  * Form cur_str by copying dir_string into  *
  36581.  *   it and then concatenating the chk_str onto           *
  36582.  *   the end                                                *
  36583.  ********************************************************/
  36584.  
  36585.  strcpy(cur_str,dir_string);
  36586.  strcat(cur_str,chk_str);
  36587.  
  36588.  /*********************************************************
  36589.  * Get the first file that matches cur_str         *
  36590.  ********************************************************/
  36591.  
  36592.  GET_FIRST(cur_str,no_type);
  36593.  
  36594.  /********************************************************
  36595.  * while there are more files that match the search        *
  36596.  *   string:                                                *
  36597.  * begin                                                 *
  36598.  *   print the file information                                *
  36599.  *   get the next file                                        *
  36600.  * end                                                        *
  36601.  ********************************************************/
  36602.  
  36603.  while (!(r8086.x.cflag & carry_set))
  36604.      {
  36605.  
  36606.      /*  If we have gotten a screenful pause for a keystroke */
  36607.      if (++count==24) {
  36608.          printf("\t\t<<Hit any key to continue or Q to abort>>");
  36609.          count =        getch();
  36610.          printf("\r\t\t\t\t\t\t\t\t\r");
  36611.          if ((count == 'Q') || (count == 'q'))
  36612.                  exit(1);
  36613.          count = 0;
  36614.          }
  36615.  
  36616.      printf(" %10ld %s   %s%s\n", (*cur_DTA).DTA_size,
  36617.                          DATE(&((*cur_DTA).DTA_date)),
  36618.                          dir_string, (*cur_DTA).DTA_filename);
  36619.      GET_NEXT();
  36620.      }
  36621.  
  36622.  /*********************************************************
  36623.  * if error in looking for a file                        *
  36624.  *    print error message and return                        *
  36625.  ********************************************************/
  36626.  
  36627.  if (r8086.x.ax != no_more_files)
  36628.      printf("problem with looking for %s\n",cur_str);
  36629.  
  36630.  return;
  36631.  
  36632.  }
  36633.  
  36634.  /********************************************************
  36635.  * GET_NEXT does an interrupt 21h, function 4Fh                *
  36636.  * Function 4fh is Get next directory entry                *
  36637.  ********************************************************/
  36638.  
  36639.  GET_NEXT()
  36640.  
  36641.  {
  36642.  r8086.x.ax = 0x4f00;
  36643.  
  36644.  dos_result = int86x( 0x21, &r8086, &r8086, &s8086 );
  36645.  
  36646.  return;
  36647.  }
  36648.  
  36649.  
  36650.  /********************************************************
  36651.  * SET_DTA does an interrupt 21h, function 1Ah                *
  36652.  *   The DS:DX pair is set to the address of the         *
  36653.  *   cur_DTA data structure                            *
  36654.  ********************************************************/
  36655.  
  36656.  SET_DTA(cur_DTA)
  36657.  struct DTA        *cur_DTA;
  36658.  {
  36659.  
  36660.  r8086.x.ax = 0x1a00;
  36661.  r8086.x.dx = (int)cur_DTA;                /* set offset to disk transfer area
  36662.  
  36663.  dos_result = int86x(0x21, &r8086, &r8086, &s8086 );
  36664.  
  36665.  return;
  36666.  
  36667.  }
  36668.  
  36669.  /********************************************************
  36670.  * GET_FIRST does an interrupt 21h, function 4Eh         *
  36671.  *   The CX register is set to either normal or                *
  36672.  *   directory type (see text)                                *
  36673.  *   The DS:DX pair is set to the address of the         *
  36674.  *   search string                                        *
  36675.  ********************************************************/
  36676.  
  36677.  GET_FIRST(sea_str,filetype)
  36678.  char *sea_str;
  36679.  int filetype;
  36680.  {
  36681.  
  36682.  r8086.x.ax = 0x4e00;                                /* Set DOS function
  36683.  r8086.x.cx = filetype;                                /* Set search attribute
  36684.  r8086.x.dx = (int)    sea_str;                  /* Set address of string */
  36685.  
  36686.  dos_result = int86x( 0x21, &r8086, &r8086, &s8086 );
  36687.  
  36688.  return;
  36689.  
  36690.  }
  36691.  
  36692.  /********************************************************
  36693.  * DATE takes the date field from the current DTA        *
  36694.  *   structure and returns a string containing the        *
  36695.  *   information in formatted ASCII                        *
  36696.  ********************************************************/
  36697.  
  36698.  char *DATE(dateptr)
  36699.  struct msdos_date *dateptr;
  36700.  {
  36701.  
  36702.  sprintf(date_str, "%02d-%02d-%02d %02d:%02d %s",
  36703.          dateptr->ms_month, dateptr->ms_day,
  36704.          dateptr->ms_year+80, (dateptr->ms_hour)%12,
  36705.          dateptr->ms_min, time_of_day[((dateptr->ms_hour)/12)]);
  36706.  return(date_str);
  36707.  
  36708.  }
  36709.  
  36710.  char *space(where)
  36711.  int where;
  36712.  {
  36713.          spce[lastzero] = ' ';
  36714.          spce[where] = '\0';
  36715.          return spce;
  36716.  }
  36717.  
  36718.  
  36719.  AREACODE.C
  36720.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\ZED\AREACODE.C
  36721.  
  36722.  /* area.c   11/26/83
  36723.     Modified 3-18-86 by Charles Ransom
  36724.     [update area codes -CR]
  36725.  
  36726.          Telephone area code search program
  36727.                  (C) 1983 Martin Smith
  36728.          Compuserve 72155,1214   Source ST2259
  36729.          310 Cinnamon Oak Lane   (713) 661-1241 [Office]
  36730.          Houston, Texas  77079   (713) 464-6737 [Home]
  36731.  
  36732.          Find area codes by entering an area code or state name on the
  36733.          command line.  Multiple codes, names are permitted up to 20,
  36734.          the limit set forth for C86 Computer Innovations(tm) compiler.
  36735.          Program written for IBM-PC with PC-DOS 2.0, but no machine-specific
  36736.          code is involved.
  36737.  
  36738.          The table is near the top of this file to make it easier to maintain.
  36739.          Area codes don't change much, but just this year in Houston our
  36740.          area code was broken off from the surrounding area.
  36741.          The format of the table is simple, so adding cities to the city list
  36742.          or even new states or regions won't upset the program if a few easy
  36743.          rules are followed:
  36744.  
  36745.          1) The table format is one array of string pointers.
  36746.          2) A state name consists of a two character postal abbreviation,
  36747.             like CA for California, and then the actual name,
  36748.             a)  All data on this line is lowercase. A multiple word name,
  36749.                 like New Jersey, would be entered as "njnew*jersey" , .
  36750.                 This prevents argv from making two arguments out of the name.
  36751.          3) An area code is the three digit code, followed by whatever text.
  36752.             a)  As many area codes, cities as you want are ok.
  36753.          4) All entries need to be enclosed in quotes (") and followed by a
  36754.             comma.
  36755.  */
  36756.  
  36757.  #include "stdio.h"
  36758.  areacode(s,x)
  36759.  char *s;
  36760.  int x;
  36761.  {
  36762.  unsigned strlen();
  36763.  
  36764.  static char *area[] =
  36765.  {  "alalabama"    , "205 All locations",
  36766.     "akalaska"     , "907 All locations",
  36767.     "azarizona"    , "602 All locations",
  36768.     "ararkansas"   , "501 All locations",
  36769.     "cacalifornia" ,
  36770.          "805 Bakersfield" , "209 Fresno" , "213 Los Angeles" ,
  36771.          "213 Burbank" , "714 Camp Pendelton" , "415 Palo Alto",
  36772.          "916 Folsom" , "714 Fullerton" , "805 Oxnard"
  36773.          "916 Sacramento" , "619 San Diego" , "415 San Francisco" ,
  36774.          "707 Santa Rosa" , "408 San Jose" , "213 Santa Monica" ,
  36775.     "cncanada" ,
  36776.          "519 London, Ont." , "514 Montreal, Quebec" , "403 Alberta" ,
  36777.          "613 Ottawa, Ont." , "418 Quebec, Quebec" , "306 Saskatchewan" ,
  36778.          "416 Toronto, Ont." , "604 British Columbia" , "204 Manitoba" ,
  36779.          "807 East Ontario" , "705 West Ontario" , "819 NW Quebec" ,
  36780.          "709 Newfoundland" , "506 New Brunswick" ,
  36781.          "902 Nova Scotia, Prince Edward Island" ,
  36782.     "cocolorado"   , "303 All locations" ,
  36783.     "ctconnecticut" , "203 All locations" ,
  36784.     "dedelaware"   , "302 All locations" ,
  36785.     "dcdistrict of*columbia" , "202 Washington" ,
  36786.     "flflorida" ,
  36787.          "813 Ft. Myers, Winter Haven" , "904 Jacksonville" ,
  36788.          "305 Miami, Key West, Ft. Lauderdale" ,
  36789.     "gageorgia" ,
  36790.          "404 Atlanta, Rome" , "912 Waycross" ,
  36791.     "hihawaii"  , "808 All locations" ,
  36792.     "ididaho"   , "208 All locations" ,
  36793.     "ilillinois" ,
  36794.          "618 Alton, Mt. Vernon" , "312 Chicago, Aurora, Waukegan" ,
  36795.          "815 Rockford" , "217 Springfield" , "309 Peoria" ,
  36796.     "inindiana" ,
  36797.          "812 Evansville" , "219 Gary, South Bend, Warsaw" ,
  36798.          "317 Indianapolis, Kokomo" ,
  36799.     "iaiowa" ,
  36800.          "712 Council Bluffs" , "515 Des Moines" , "319 Dubuque" ,
  36801.     "kskansas" ,
  36802.          "316 Wichita, Dodge City" ,
  36803.          "913 Topeka, Lawrence, Manhattan, Salina" ,
  36804.     "kykentucky" ,
  36805.          "502 Louisville, Frankfort, Paducah, Shelbyville" , "606 Winchester"
  36806.     "lalouisiana" ,
  36807.          "504 Baton Rouge, New Orleans" , "318 Lake Charles" ,
  36808.     "memaine"      , "207 All locations" ,
  36809.     "mdmaryland"   , "301 All locations" ,
  36810.     "mamassachusetts" ,
  36811.          "617 Boston, New Bedford, Plymouth, Worchester" ,
  36812.          "413 Springfield" ,
  36813.     "mxmexico" ,
  36814.          "905 Mexico City" , "706 NW Mexico" ,
  36815.     "mimichigan" ,
  36816.          "313 Detroit, Ann Arbor, Flint" ,
  36817.          "616 Battle Creek, Grand Rapids, Kalamazoo" ,
  36818.          "517 Lansing" , "906 Escanaba" ,
  36819.     "mnminnesota" ,
  36820.          "218 Duluth" , "612 Minneapolis, St. Paul" , "507 Rochester" ,
  36821.     "msmississippi" , "601 All locations" ,
  36822.     "momissouri" ,
  36823.          "816 Belton, Independence, Kansas City, Marshall, St. Joseph, Sedalia
  36824.          "314 St. Louis, Cape Girardeau, Columbia, Fulton, Hannibal, \n\tJeffe
  36825.          "417 Joplin, Springfield" ,
  36826.     "mtmontana"    , "406 All locations" ,
  36827.     "nenebraska" ,
  36828.          "402 Omaha, Lincoln" , "308 North Platte" ,
  36829.     "nvnevada"     , "702 All locations" ,
  36830.     "nhnew*hampshire" , "603 All locations" ,
  36831.     "njnew*jersey" ,
  36832.          "609 Atlantic City, Camden, Trenton" ,
  36833.          "201 Newark, Hackensack, New Brunswick, Patterson" ,
  36834.     "nmnew*mexico" , "505 All locations" ,
  36835.     "nynew*york" ,
  36836.          "518 Albany, Schenectady" , "607 Binghamton" ,
  36837.          "716 Buffalo, Niagara Falls, Rochester" , "914 White Plains" ,
  36838.          "212 New York City" , "315 Syracuse" ,
  36839.     "ncnorth*carolina" ,
  36840.          "704 Charlotte, Salisbury" ,
  36841.          "919 Greenville, Raleigh, Winston-Salem" ,
  36842.     "ndnorth*dakota" , "701 All locations" ,
  36843.     "ohohio" ,
  36844.          "216 Akron, Cleveland, Youngstown" ,
  36845.          "513 Cincinnati, Dayton" , "614 Columbus" ,
  36846.          "419 Toledo" ,
  36847.     "okoklahoma" ,
  36848.          "918 Tulsa, Bartlesville, McAlester, Muskogee" ,
  36849.          "405 Oklahoma City, Enid, Norman, Ponca City, Stillwater" ,
  36850.     "ororegon"      , "503 All locations" ,
  36851.     "papennsylvania" ,
  36852.          "215 Philadelphia, Allentown" , "814 Erie" ,
  36853.          "412 Pittsburgh" , "717 Harrisburg, Scranton" ,
  36854.     "prpuerto*rico"  ,
  36855.  "809 Anguilla, Antigua, Bahamas, Barbados, Bermuda, Cayman Islands, \n\tDomin
  36856.     "rirhode*island" , "401 All locations" ,
  36857.     "scsouth*carolina" , "803 All locations" ,
  36858.     "sdsouth*dakota" , "605 All locations" ,
  36859.     "tntennessee" ,
  36860.          "615 Nashville, Chattanooga" , "901 Memphis" ,
  36861.     "txtexas" ,
  36862.          "915 Abilene, Alpine, Big Spring, El Paso, Midland, Odessa" ,
  36863.          "512 Austin, Brownsville, Corpus Christi, Del Rio, Eagle Pass, \n\tLa
  36864.          "806 Amarillo, Dalhart, Lubbock" ,
  36865.          "713 Houston, Baytown, Pasadena" ,
  36866.          "409 Bay City, Beaumont, Bryan, College Station, Galveston, Huntsvill
  36867.          "214 Dallas, Ennis, Greenville, Jefferson, Longview, Sherman, Tyler"
  36868.          "817 Fort Worth, Denton, Temple, Waco, Wichita Falls" ,
  36869.     "ututah"        , "801 All locations" ,
  36870.     "vtvermont"     , "802 All locations" ,
  36871.     "vivirgin*islands" , "809 All locations" ,
  36872.     "vavirginia" ,
  36873.          "804 Charlottesville, Newport News, Norfolk, Richmond" ,
  36874.          "703 Roanoke, Winchester" ,
  36875.     "wawashington" ,
  36876.          "206 Seattle, Olympia, Vancouver" , "509 Walla Walla" ,
  36877.     "  wide area"   , "800 All locations" ,
  36878.     "wvwest*virginia" , "304 All locations" ,
  36879.     "wiwisconsin" ,
  36880.          "414 Milwaukee, Green Bay, Racine" ,
  36881.          "608 Madison" , "715 Wausau" ,
  36882.     "wywyoming"     , "307 All locations" ,
  36883.     NULL  } ;
  36884.  
  36885.      int i,j,found;
  36886.      unsigned k;
  36887.      char temp[64];
  36888.      char *t;
  36889.  
  36890.      if (x==2)   /* a number area code */
  36891.      {
  36892.          found=0;
  36893.          for (i=0; area[i] != NULL; i++)
  36894.             {
  36895.             if (strncmp(area[i],s,3)==0)  /* test for match */
  36896.                  {
  36897.                  for (j=i-1; satoi(area[j]) != 0; --j)  /* then go back for st
  36898.                          ;
  36899.                  stprint(area[j]);       /* special print out for state name *
  36900.                  putchar('\n');
  36901.                  printf("    %s.\n\n",area[i]);
  36902.                  found=-1;
  36903.                  break;                  /* stop when found */
  36904.                  }
  36905.             }
  36906.          if (found==0)
  36907.                  printf("Not found, %s.\n\n",s);
  36908.  
  36909.       }
  36910.      else
  36911.      if (x==1)   /* state name or two letter code is input */
  36912.      {
  36913.          for (i=0; s[i] != '\0'; i++)    /* make everything lowercase */
  36914.                  s[i]=tolower(s[i]);
  36915.          if (strlen(s)==2)               /* two letter code assumed */
  36916.                  {
  36917.                  found=0;
  36918.                  for (i=0; area[i] != NULL; i++)
  36919.                          {
  36920.                          if (strncmp(s,area[i],2)==0)
  36921.                                  {
  36922.                                  stprint(area[i]);
  36923.                                  putchar('\n');
  36924.                                  for (j=i+1; satoi(area[j]) != 0;j++)
  36925.                                          printf("    %s.\n",area[j]);
  36926.                                  found=-1;
  36927.                                  putchar('\n');
  36928.                                  break;
  36929.                                  }
  36930.                          }
  36931.                  if (found==0)
  36932.                          printf("Not found, %s.\n",s);
  36933.                  }
  36934.          else                            /* otherwise try for state name */
  36935.          {
  36936.          k=strlen(s);                    /* ok if partial name */
  36937.          found=0;
  36938.                  for (i=0; area[i] != NULL; i++)
  36939.                          {
  36940.                          if (satoi(area[i])==0)
  36941.                                  {
  36942.                                  t=area[i];
  36943.                                  t=t+2;
  36944.                                  strcpy(temp,t);
  36945.                                  if (strncmp(temp,s,k) == 0)
  36946.                                          {
  36947.                                          stprint(area[i]);
  36948.                                          putchar('\n');
  36949.                                          for (j=i+1; satoi(area[j]) != 0;j++)
  36950.                                                  printf("    %s.\n",area[j]);
  36951.                                          found=-1;
  36952.                                          putchar('\n');
  36953.                                          break;
  36954.                                          }
  36955.                                  }
  36956.                          }
  36957.                          if (found==0)
  36958.                                  printf("Not found, %s.\n",s);
  36959.          }
  36960.     }
  36961.     else         /* print entire list */
  36962.     {
  36963.       for (i=0; area[i] != NULL; i++)
  36964.       {
  36965.          if (satoi(area[i])==0)
  36966.                  {
  36967.                  putchar('\n');
  36968.                  stprint(area[i]);
  36969.                  putchar('\n');
  36970.                  }
  36971.          else
  36972.                  printf("    %s.\n",area[i]);
  36973.       }
  36974.     }
  36975.  }
  36976.  
  36977.  /* special printout for state name */
  36978.  stprint(s)
  36979.  char s[];
  36980.  {
  36981.          int i;
  36982.          putchar(toupper(s[0]));
  36983.          putchar(toupper(s[1]));
  36984.          printf("  ");
  36985.          putchar(toupper(s[2]));
  36986.          for (i=3; s[i] != '\0'; i++)
  36987.                  {
  36988.                  if (s[i]=='*')
  36989.                          {
  36990.                          putchar(' ');
  36991.                          putchar(toupper(s[++i]));
  36992.                          }
  36993.                  else
  36994.                          putchar(s[i]);
  36995.                  }
  36996.          printf(" area code(s): ");
  36997.  }
  36998.  
  36999.  main(argc,argv)
  37000.  int  argc;
  37001.  char *argv[];
  37002.  {
  37003.          int i,satoi();
  37004.          printf("   ** Area Code Finder **\n");
  37005.          printf("    (C) Marty Smith 1983 \n\n");
  37006.          printf("    Modified by Charles Ransom -1986\n\n");
  37007.          if (argc==1)
  37008.          {
  37009.          printf("Program searches for telephone area codes,\n");
  37010.          printf("   as area xxx xxx xxx etc.\n");
  37011.          printf("   xxx is an Area Code or State name.\n");
  37012.          printf("   Two letter state postal codes like TX for Texas, CA for Ca
  37013.          printf("      can be used, otherwise type in the state name.\n");
  37014.          printf("   Enter two word state names like this: New*Jersey.\n");
  37015.          printf("   Enter area * for a list of all Area Codes.\n");
  37016.          }
  37017.          else
  37018.          if (*argv[1]=='*')
  37019.                  areacode(argv[1],0);
  37020.          else
  37021.          {
  37022.          for (i=1; i < argc; ++i)
  37023.                  {
  37024.                  if (satoi(argv[i])==0)
  37025.                        areacode(argv[i],1);
  37026.                  else
  37027.                        areacode(argv[i],2);
  37028.                  }
  37029.          }
  37030.  }
  37031.  
  37032.  /* integer convert to number */
  37033.  int satoi(s)
  37034.  char s[];
  37035.  {
  37036.          int i, n, sign;
  37037.  
  37038.          for (i=0; s[i]==' ' || s[i]=='\n' || s[i]=='\t'; i++)
  37039.                  ;  /* skip white space */
  37040.  
  37041.          sign = 1;
  37042.          if (s[i] == '+' || s[i] == '-')
  37043.                  sign = (s[i++]=='+') ? 1 : -1;
  37044.          for (n=0; s[i] >= '0' && s[i] <= '9'; i++)
  37045.                  n = 10 * n + s[i] - '0';
  37046.          return(sign * n);
  37047.  
  37048.  }
  37049.  
  37050.  
  37051.  
  37052.  ASCIDUMP.C
  37053.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\FUNC\DUMPS\ASCIDUMP.C
  37054.  
  37055.  /****************************************************************************
  37056.  /*                                                                          *
  37057.  /* ASCIDUMP.C                                                               *
  37058.  /*                                                                          *
  37059.  /* This program prints the ASCII decimal codes and actual text for a file   *
  37060.  /* specified as the first command line argument. It reads the file a block  *
  37061.  /* at a time and prints the decimal value of each character, then prints    *
  37062.  /* the translated characters at the end of the line. It translates certain  *
  37063.  /* special characters like BELL, LF, FF to spaces for printing              *
  37064.  /*                                                                          *
  37065.  /* Written by: Jim Niederriter   12/26/83                                   *
  37066.  /*                                                                          *
  37067.  /****************************************************************************
  37068.  /*                                                                          *
  37069.  /* This program was written for the Lattice `C' Compiler, and works under   *
  37070.  /* version 1.04 or 2.00.                                                    *
  37071.  /*                                                                          *
  37072.  /****************************************************************************
  37073.  
  37074.  #include <stdio.h>
  37075.  #define  BELL   7
  37076.  #define  MAXCHR 30
  37077.  #define  NULL   0
  37078.  
  37079.  main(argc, argv)
  37080.  int argc;
  37081.  char *argv[];
  37082.  {
  37083.       int loopx, linecnt;
  37084.       int x, f1, stats, flag, fmode;
  37085.       long countr;
  37086.       char buffer[MAXCHR + 1];
  37087.       FILE *f2, *fopen();
  37088.  
  37089.  /****** Looks for filename as first command line argument *******************
  37090.  
  37091.       if (argc < 2)
  37092.       {
  37093.            puts("Requires file name in command line\n");
  37094.            putch(BELL);
  37095.            exit(1);
  37096.       }
  37097.  
  37098.  /****** Opens printer as LPT1 ***********************************************
  37099.  
  37100.       if ((f2 = fopen("LPT1:", "w")) == NULL)
  37101.       {
  37102.            puts("Can't open printer file\n");
  37103.            putch(BELL);
  37104.            exit(1);
  37105.       }
  37106.  /****** Open file as read-only, and in `untranslated' mode...(does not   */
  37107.  /****** convert CR/LF). *************************************************/
  37108.  
  37109.       fmode = 0;          /* mode for `read-only' */
  37110.       fmode = 0x8000;     /* set to read in `untranslated' or binary mode */
  37111.  
  37112.       if ((f1 = open(argv[1], fmode)) == NULL)
  37113.       {
  37114.            printf("Can't open file %s.\n", argv[1]);
  37115.            putch(BELL);
  37116.            exit(1);
  37117.       }
  37118.  /***** Printer codes are set up for EPSON FX (change to match your printer */
  37119.  
  37120.       fprintf(f2, "\x1BP\x0F");     /* set printer to PICA, CONDENSED  */
  37121.  
  37122.  /**** This one sets the `skip over perforation' to 3 lines *****************/
  37123.  
  37124.       fprintf(f2, "\x1BN\x03\nCount                              File ");
  37125.       fprintf(f2, "dump for file name: %s \n", argv[1]);
  37126.  
  37127.       countr = loopx = linecnt = 0;
  37128.       flag = 1;
  37129.       while (flag)
  37130.       {
  37131.            flag = 0;
  37132.            setmem(buffer, MAXCHR, NULL);               /* clear buffer  */
  37133.            if ((stats = read(f1, buffer, MAXCHR)) > 0) /* read blk from file *
  37134.            {
  37135.                 fprintf(f2, "%05ld   ", countr);        /* print char count */
  37136.                 countr += MAXCHR;
  37137.                 flag = 1;
  37138.  
  37139.                 for (x=0; x <= (MAXCHR-1); x++)
  37140.                 {
  37141.                      fprintf(f2, "%03d", buffer[x]);  /* print decimal value *
  37142.  
  37143.  /****** change any special characters to SPACE for printing *****************
  37144.  
  37145.                      if (buffer[x] < 32 || buffer[x] > 128)
  37146.                           buffer[x] = ' ';    /* get rid of unprintables */
  37147.  
  37148.                      if ((loopx +=1) == 5)
  37149.                      {
  37150.                           fprintf(f2, " ");            /* 5 at a time */
  37151.                           loopx = 0;
  37152.                      }
  37153.                 }
  37154.                 fprintf(f2, "*");             /* print translated characters *
  37155.                 for (x=0; x <= (MAXCHR-1); x++)
  37156.                      fprintf(f2, "%c", buffer[x]);
  37157.                 fprintf(f2, "*\n");
  37158.                 if ((linecnt += 1) == 5)
  37159.                 {
  37160.                      fprintf(f2, "\n");       /* skip 1 after every 5 lines */
  37161.                      linecnt = 0;
  37162.                 }
  37163.            }
  37164.       }
  37165.       fprintf(f2, "\x1BP\x0C");     /* set back to normal & do forms feed */
  37166.       fflush(f2);
  37167.       fclose(f2);
  37168.  }
  37169.  
  37170.  
  37171.  ASIN.C
  37172.  CD-ROM Disc Path:   \SAMPCODE\ALDE_C\MISC\LIB\JPLC2\ASIN.C
  37173.  
  37174.  /* 1.0  04-27-84 */
  37175.  /************************************************************************
  37176.   *                        Robert C. Tausworthe
  37177.   *                        Jet Propulsion Laboratory                        *
  37178.   *                        Pasadena, CA 91009                1984
  37179.   ************************************************************************
  37180.   *        Programmmed using the algorithms given in:
  37181.   *
  37182.   *        Coty, William J., Jr., and Waite, William, SOFTWARE MANUAL FOR
  37183.   *        THE ELEMENTARY FUNCTIONS, Prentice-Hall Series in Computational
  37184.   *        Mathematics, Prentice-Hall, Inc., Inglewood Cliffs, NJ, 1980,
  37185.   *        pp. 174-193.
  37186.   *
  37187.   *----------------------------------------------------------------------*/
  37188.  
  37189.  #include "defs.h"
  37190.  #include "stdtyp.h"
  37191.  #include "errno.h"
  37192.  #include "mathtyp.h"
  37193.  #include "mathcons.h"
  37194.  
  37195.  /*----------------------------------------------------------------------*/
  37196.  
  37197.  #define P0         +1.0
  37198.  #define P1         -0.27368494524164255994e+2
  37199.  #define P2         +0.57208227877891731407e+2
  37200.  #define P3         -0.39688862997504877339e+2
  37201.  #define P4         +0.10152522233806463645e+2
  37202.  #define P5         -0.69674573447350646411
  37203.  #define P(g)         ((((P5*g P4)*g P3)*g P2)*g P1)
  37204.  
  37205.  #define Q0         -0.16421096714498560795e+3
  37206.  #define Q1         +0.41714430248260412556e+3
  37207.  #define Q2         -0.38186303361750149284e+3
  37208.  #define Q3         +0.15095270841030604719e+3
  37209.  #define Q4         -0.23823859153670238830e+2
  37210.  #define Q(g)         (((((g Q4)*g Q3)*g Q2)*g Q1)*g Q0)
  37211.  
  37212.  LOCAL double asincos();
  37213.  
  37214.  /************************************************************************/
  37215.          double
  37216.  asin(x)                        /* return the trigonometric arc-sine of x
  37217.  
  37218.  /*----------------------------------------------------------------------*/
  37219.  double x;
  37220.  {
  37221.          return asincos(x, 0);
  37222.  }
  37223.  
  37224.  /*\p*********************************************************************/
  37225.  
  37226.  double acos(x)                /* return the trigonometric arc-cosine of x
  37227.  
  37228.  /*----------------------------------------------------------------------*/
  37229.  double x;
  37230.  {
  37231.          return asincos(x, 1);
  37232.  }
  37233.  
  37234.  /************************************************************************/
  37235.          LOCAL double
  37236.  asincos(x, flg)                /* return arc sin or cos, depending on flg
  37237.  
  37238.  /*----------------------------------------------------------------------*/
  37239.  double x;
  37240.  {
  37241.          double y, g, r;
  37242.          FAST int i;
  37243.          LOCAL double a[2] = { 0.0, PIover4};
  37244.          LOCAL double b[2] = { PIover2, PIover4};
  37245.  
  37246.          y = ABS(x);
  37247.          i = flg;
  37248.          if (y < FADEOUT)
  37249.                  r = y;
  37250.          else
  37251.          {        if (y > 0.5)
  37252.                  {        i = 1 - i;
  37253.                          if (y > 1.0)
  37254.                          {        errno = EDOM;
  37255.                                  return 0.0;
  37256.                          }
  37257.                          g = ldexp((0.5 - y) + 0.5, -1);
  37258.                          y = -ldexp(sqrt(g), 1);
  37259.                  } else
  37260.                          g = y * y;
  37261.                  r = y + y *
  37262.                          ((P(g) * g)
  37263.                          / Q(g));
  37264.