home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / c / c_call.zip / CALL.C next >
C/C++ Source or Header  |  1992-09-24  |  14KB  |  498 lines

  1. /* ======================================================================
  2. ** Program CALL.C.
  3. **
  4. ** Copyright, (c) 1989, 1990, 1991, 1992, Sean R. Kirkpatrick
  5. **
  6. ** Released into the public domain, September 1, 1992.
  7. **
  8. ** This program implements a simple telephone book.  A list of data,
  9. ** separated by by '^' (caret) symbols is read from disk.  The parameter(s)
  10. ** on the command line represent text to search for in the file.  The
  11. ** entries of this file look something like this:
  12. **
  13. **   ^
  14. **   first line of text
  15. **   second line of text
  16. **   ...
  17. **   last line of text
  18. **   ^
  19. **
  20. ** Each ^ must be the first character on the line.  This starts a new
  21. ** record.  Any amount of text may appear in between carets, subject to
  22. ** an 80 character limit on each line.
  23. **
  24. ** Modification History
  25. ** ======================================================================= 
  26. ** Date              Rev     Who     What
  27. ** -----------------------------------------------------------------------
  28. ** 6/7/89    1.0     SRK     Created
  29. ** 6/8/89    1.1     SRK     Added to SCCS
  30. ** 6/8/89    1.2     SRK     Minor bug fixes
  31. ** 6/9/89    1.3     SRK     Implemented addName
  32. ** 6/12/89   1.4     SRK     Implemented delName
  33. ** 6/15/89   1.5     SRK     Migrated to RCS from SCCS
  34. ** 4/19/91   1.6     SRK     Port to Power C
  35. ** =======================================================================
  36. */
  37.  
  38. static char _ver[] = "1.6 91/04/19";
  39.  
  40. #define ANSI
  41. #define PWR_C
  42. #undef RCS      /* not under RCS control, don't have a version for DOS */
  43.  
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #include <ctype.h>
  48. #include <malloc.h>
  49. #include <time.h>
  50.  
  51. #ifndef ANSI
  52. #include <file.h>
  53. #endif
  54.  
  55. #ifdef PWR_C
  56. #include <conio.h>
  57. #endif
  58.  
  59. #define LINESIZE 81
  60. #define FALSE 0
  61. #define TRUE !FALSE
  62. #define BUFFSIZE 512
  63.  
  64. struct LineRec {
  65.      struct LineRec * next;
  66.      char info[LINESIZE];
  67. };
  68.  
  69. typedef struct LineRec LineRecType;
  70.  
  71. LineRecType  * lineRec;
  72. LineRecType  * pHead;
  73. LineRecType  * pTail;
  74.  
  75. FILE * fh;
  76. char * callFile;
  77. char   defaultFile[100];
  78.  
  79. char tm[40];
  80. long t;
  81. time_t timer;
  82.  
  83. int Found;
  84. int RemoveName;
  85.  
  86. /* =============================================================== */
  87.  
  88. void pause()
  89. {
  90.     int c;
  91.  
  92.     printf( "--- press any key to continue ---" );
  93.  
  94. #ifdef PWR_C
  95.     c = getch();
  96. #else
  97.     c = getchar();
  98. #endif
  99.  
  100. } /* pause */
  101.  
  102. /* =============================================================== */
  103.  
  104. void display_help()
  105. {
  106. printf( "HELP\n\n" );
  107.  
  108. printf( "Usage: Call [who | +who{,text} | -who] | HELP]\n" );
  109. printf( "\n");
  110. printf( "This program searches a text file for an entry that matches the\n" );
  111. printf( "name supplied on the command line.\n" );
  112. printf( "The file that is searched is called Phones.Txt and it can be\n" );
  113. printf( "located in the current directory, or in a directory specified\n");
  114. printf( "in the DOS environment variable PHONES.  Using a DOS environment\n" );
  115. printf( "has the advantage that the file will always be available to this\n" );
  116. printf( "program regardless of the currently logged directory.\n" );
  117. printf( "\n" );
  118. printf( "You can add this string to your environment by adding a new line\n" );
  119. printf( "to your AUTOEXEC.BAT file: SET PHONES=A:\PHONES.TXT.\n" );
  120. printf( "\n" );
  121. printf( " The format of the phone file is:\n" );
  122. printf( "\n" );
  123. printf( "    ^\n" );
  124. printf( "    name\n" );
  125. printf( "    any text\n" );
  126. printf( "    any number of lines\n" );
  127. printf( "    ^\n" );
  128. pause();
  129. printf( "\n" );
  130. printf( "The carrets serve as text delimiters and must be in column 1.\n" );
  131. printf( "Otherwise the format of the file is free form.  All text between\n" );
  132. printf( "carrets will be displayed if a match is found, otherwise an error\n" );
  133. printf( "message will be displayed.\n" );
  134. printf( "\n" );
  135. printf( "Any number of entries may be included within the file, and\n" );
  136. printf( "there is no limit on the number of lines in each entry.  Upper \n" );
  137. printf( "and lower case letters are not significant, as the program will \n" );
  138. printf( "convert all characters to uppercase before checking for a match.\n" );
  139.  
  140. } /* display_help */
  141.  
  142. /* =============================================================== */
  143.  
  144. void upline( char * l )
  145. {
  146.     while ( (*l != '\n') && (*l != '\0') ) {
  147.         if ( isalpha( *l ) && islower( *l ) )
  148.             *l = toupper( *l );
  149.         *++l;
  150.     }
  151. } /* upline */
  152.  
  153. /* =============================================================== */
  154.  
  155. int strindex( s, t )
  156. char *s, *t;
  157. {
  158. /*
  159. ** out of K&R, check it out
  160. **
  161. ** sure wish my compiler had one of these
  162. */
  163.      int i, j, k;
  164.  
  165.      upline( s ); 
  166.      upline( t );
  167.  
  168.      for ( i = 0; s[i] != '\0'; i++ ) {
  169.              for ( j=i,k=0; t[k] != '\0' && s[j] == t[k];  j++, k++ )
  170.                      ;
  171.              if ( k > 0 && t[k] == '\0' )
  172.                      /* found */
  173.                      return i;
  174.      } /* for */
  175.  
  176.      /* not found */
  177.      return -1;
  178.  
  179. } /* strindex */
  180.  
  181. /* =============================================================== */
  182.  
  183. void init()
  184.  
  185. {
  186.     /* 
  187.     ** if successful, this routine returns to main with a properly
  188.     ** opened phone file, otherwise, it returns to the system.
  189.     */
  190.      strcpy( defaultFile, "phones.txt" );
  191.  
  192.      if ( ( callFile = getenv( "PHONES" ) ) == NULL ) 
  193.              callFile = defaultFile;
  194.      
  195.      if ( ( fh = fopen( callFile, "r" ) ) == NULL ) {
  196.              printf( "Trouble opening: %s!\n\n", callFile );
  197.              exit( 1 );
  198.      }
  199.      
  200. } /* init */
  201.  
  202. /* =============================================================== */
  203.  
  204. void displayName( p )
  205. LineRecType * p;
  206. {
  207.      
  208.     int x = 0;
  209.     pTail = p;
  210.  
  211.     printf( "\n //======================================================\\\\\n" );
  212.     while ( ( pTail != NULL ) && (pTail->info[0] != '^' ) ) {
  213.         printf( "|| " );
  214.         for ( x = 0; pTail->info[x] != '\n' && pTail->info[x] != '\0'; x++ )
  215.             putchar( pTail->info[x] );
  216.         for ( x = 3 + strlen( pTail->info ); x < 59; x++ )
  217.             putchar( ' ' );
  218.         printf( "||\n" );
  219.         pTail = pTail->next;
  220.     }
  221.  
  222.     printf( " \\\\======================================================//\n" );
  223. } /* displayName */
  224.  
  225. /* =============================================================== */
  226.  
  227. void delName( p )
  228. LineRecType * p;
  229. {
  230.      /*
  231.      ** when we enter, we've found an entry that matches the 
  232.      ** command line spec.  Ask if it's ok to delete the record.
  233.      */
  234.  
  235.      int ch;
  236.  
  237.      RemoveName = FALSE;
  238.  
  239.      printf( "Delete this entry? y/n " );
  240.  
  241. #ifdef PWR_C
  242.     ch = getch();
  243. #else
  244.     ch = getchar();
  245. #endif
  246.  
  247.      if ( ch != 'Y' && ch != 'y' ) 
  248.              return;
  249.  
  250.      /*
  251.      ** when we get here, pTail points to the beginning  of the entry
  252.      ** to be deleted.  We need to rewrite the file to eliminate it.
  253.      */
  254.  
  255.      if ( ( fh = fopen( callFile, "w" ) ) == NULL ) {
  256.              printf( "Trouble opening: %s!\n\n", callFile );
  257.              exit( 1 );
  258.      }
  259.  
  260.      pTail = pHead; /* start of the top of the list */
  261.      while ( pTail != NULL ) {
  262.              if ( pTail == p ) {
  263.                      /* skip the entry */
  264.                      pTail = pTail->next;
  265.  
  266.                      while ( ( pTail != NULL ) && ( pTail->info[0] != '^' ) )
  267.                              pTail = pTail->next;
  268.  
  269.                      /* skip past the ending ^ in the deleted entry */
  270.  
  271.                      if ( pTail->info[0] == '^' )
  272.                              pTail = pTail->next;
  273.              } /* while */
  274.              else {
  275.                      fprintf( fh, "%s", pTail->info );
  276.                      pTail = pTail->next;
  277.              } /* else */
  278.      } /* while */
  279. } /* delName */
  280.  
  281. /* =============================================================== */
  282.  
  283. void scanList( who )
  284. char * who;
  285. {
  286.      LineRecType * p;
  287.      pTail = pHead;
  288.  
  289.      while( pTail != NULL ) {
  290.              if ( pTail->info[0] == '^' ) {
  291.                      /* get out if done */
  292.                      if ( pTail->next == NULL )
  293.                              return;
  294.  
  295.                      pTail = pTail->next;
  296.                      p = pTail;
  297.  
  298.                      while ( ( pTail != NULL ) && (pTail->info[0] != '^' ) ) {
  299.                              if ( strindex( pTail->info, who ) != -1 ) {
  300.                                      /*
  301.                                      ** found a match, display the entry
  302.                                      */
  303.                                      Found = TRUE;
  304.                                      displayName( p );
  305.  
  306.                                      if ( RemoveName ) {
  307.                                              delName( p );
  308.                                      } /* if */
  309.                              } /* if */
  310.                              else
  311.                                      pTail = pTail->next;
  312.                      } /* while */
  313.              } /* if */
  314.              else
  315.                      pTail = pTail->next;
  316.      } /* while */
  317. } /* scanList */
  318.  
  319. /* =============================================================== */
  320.  
  321. void buildList()
  322. {
  323.      char line[LINESIZE];
  324.  
  325.      pHead = NULL;
  326.      pTail = pHead;
  327.  
  328.      while ( ( fgets( line, LINESIZE,  fh ) ) != NULL ) {
  329.              if ( ( lineRec = (LineRecType *) malloc( sizeof( LineRecType ) ) ) == NULL ) {
  330.                      printf( "\nMemory allocation error\n\n" );
  331.                      exit( 1 );
  332.              }
  333.              else {
  334.                      strcpy( lineRec->info, line );
  335.  
  336.                      if ( pHead == NULL ) {
  337.                              pHead = lineRec;
  338.                              pTail = lineRec;
  339.                              pHead->next = pTail;
  340.                      } else {
  341.                              pTail->next = lineRec;
  342.                              pTail = lineRec;
  343.                              pTail->next = NULL;
  344.                      } /* else */                    
  345.              } /* else */
  346.      } /* while */
  347.  
  348. } /* buildList */
  349.  
  350. /* =============================================================== */
  351.  
  352. void addName( argc, argv )
  353. int argc;
  354. char *argv[];
  355. {
  356.      int x;
  357.      char *s;
  358.      char *b;
  359.      char line[LINESIZE];
  360.      char buff[BUFFSIZE];
  361.  
  362.      /*
  363.      ** open the file for update at EOF 
  364.      */
  365.      if ( ( fh = fopen( callFile, "a+" ) ) == NULL ) {
  366.              printf( "Trouble opening: %s!\n\n", callFile );
  367.              exit( 1 );
  368.      }
  369.      
  370.      if ( argc > 1 ) {
  371.              /* 
  372.              ** the data to be written to the file comes from the 
  373.              ** command line.
  374.              */
  375.              for ( x = 0; x < argc; x++ ) {
  376.                      /* 
  377.                      ** get all of the data from the command line                                    ** put it in 'buff'
  378.                      */
  379.                      strcat( buff, argv[x] );
  380.                      strcat( buff, " " );
  381.              } /* for */
  382.  
  383.              /*
  384.              ** pick apart the buffer
  385.              ** get all up to the ','
  386.              ** put it in 'line'
  387.              ** write 'line' to file
  388.              ** loop
  389.              */
  390.  
  391.              b = buff;
  392.              while ( ( s = strtok( b, "," )  ) != NULL ) {
  393.                      strcpy( line, s );
  394.                      fprintf( fh, "%s\n", line );    
  395.                      b = NULL;
  396.              } /* while */   
  397.  
  398.              /* 
  399.              ** print out the time of this addition
  400.              */
  401.              t = time( timer );
  402.              fprintf( fh, "\n%s", asctime( localtime(&t) ) );
  403.  
  404.              fprintf( fh, "%c\n", '^' );             
  405.              fclose( fh );
  406.              return;
  407.      } /* if */
  408.  
  409.      /*
  410.      ** if we get this far, only a + appears on the command line.
  411.      ** get input interactively.
  412.      */
  413.      printf( "Enter the data you wish to store.  Place a period as the only entry on the line to end input\n\n" );
  414.  
  415.      for ( ; ; ) {   
  416.              x = 0;
  417.              
  418.              if ( ( fgets( line, sizeof( line ), stdin ) == NULL )
  419.                 || ( line[0] == '.' )  ) {
  420.                      /* 
  421.                      ** save the time of this addition
  422.                      */
  423.                      t = time( timer );
  424.                      fprintf( fh, "\n%s", asctime( localtime(&t) ) );
  425.  
  426.                      fprintf( fh, "%c\n", '^' );
  427.                      fclose( fh );
  428.                      return;
  429.              }
  430.              else {
  431.                      fprintf( fh, "%s", line );              
  432.              }
  433.      } /* for */
  434. } /* addName */
  435.  
  436. /* =============================================================== */
  437.  
  438. main( argc, argv )
  439. int argc;
  440. char * argv[];
  441. {
  442.  
  443.      int x;
  444.      char *ver;
  445.  
  446.      ver = _ver;
  447.  
  448. #ifdef RCS
  449.      while( ! isdigit( *++ver ) && *ver ) ;
  450. #endif
  451.  
  452.      printf( "Call v%s, Copyright 1989, 1990, 1991, Sean R. Kirkpatrick, all rights reserved\n\n", ver );
  453.  
  454.      if ( argc < 2 ) {
  455.             display_help();
  456.             exit(0);
  457.      }
  458.  
  459.      init();
  460.   
  461.      buildList();
  462.  
  463.      printf( "\n==============================================================\n" );
  464.  
  465.  
  466.      for ( x = 1; x < argc; x++ ) {
  467.              Found = FALSE;
  468.  
  469.  
  470.              if ( *argv[x] == '+' ) {
  471.                      *++argv[x];
  472.                      addName( argc - x, &argv[x] );
  473.                      return;
  474.              }
  475.              else if ( *argv[x] == '-' ) {
  476.                      /*
  477.                      ** going to remove the name specified
  478.                      ** advance past the '-'
  479.                      */
  480.                      *++argv[x];
  481.                      RemoveName = TRUE;
  482.              } /* else */
  483.  
  484.              upline( argv[x] );
  485.  
  486.              printf( "\n\nSearching for %s...", argv[x] );
  487.  
  488.              scanList( argv[x] );
  489.  
  490.              if ( Found ) 
  491.                      Found = FALSE;
  492.              else 
  493.                      printf( "not found!\n" );
  494.      } /* for */
  495.  
  496. } /* call */
  497.  
  498.