⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 !best001.c

📁 supplementary source file 1 for The BESTLibrary
💻 C
📖 第 1 页 / 共 2 页
字号:
/*==========================================================================
 *
 *  !BEST001.C                                       Tuesday, April 12, 1994
 *
 *  con_ str_ fil_ counter counter_reg dos_shell
 *  supplementary source file 1 for The BESTLibrary
 *
 *  Authored independently by George Vanous
 *
 *==========================================================================*/


/* ------------------------------------------------------------------------ */
/* ----------------------------  INCLUDE FILES  --------------------------- */

#include <dir.h>
#include <alloc.h>
#include <errno.h>
#include <stdlib.h>
#include <process.h>
#include "!bestlib.h"

/* ------------------------------------------------------------------------ */
/* ------------------------------  MESSAGES  ------------------------------ */

#define MSG01 "\nThis is your first time using %s\nI, %s, hope you enjoy this program\n\n"
#define MSG02 "\n%s has been used %d time"
#define MSG03 "\nThere is %ld bytes of free RAM now available to %s\n"
#define MSG04 "\nThis copy of %s is registered to %s\n"
#define MSG05 "\nThis is the master copy of %s\nIt is registered to its author, %s\n"
#define ERR01 "\n!!! ERROR !!!  I cannot find the data file %s\n"

/* ------------------------------------------------------------------------ */


/*----------------------------------------------------------------------------
 * Shell to DOS.
 *
 * RETURNS:
 * = pointer to an error message
 * = NULL if no error message
 */
char *dos_shell(void)
{
  int error;
  char *commandpath, *textstring;
  struct ffblk ffblk;

  if ((commandpath = getenv("COMSPEC")) == NULL &&
     (commandpath = searchpath("COMMAND.COM")) == NULL) {
    if ((error = findfirst(commandpath = "COMMAND.COM", &ffblk, 0)) == NULL &&
        (error = findfirst(commandpath = "C:\COMMAND.COM", &ffblk, 0)) == NULL &&
        (error = findfirst(commandpath = "C:\DOS\COMMAND.COM", &ffblk, 0)) == NULL &&
        (error = findfirst(commandpath = "C:\BIN\COMMAND.COM", &ffblk, 0)) == NULL) {
      textstring = "Cannot find file COMMAND.COM -- initialize COMSPEC=[path]COMMAND.COM";
      return( textstring );
    }
  }
  video_set(TEXT);
  error = spawnl(P_WAIT, commandpath, commandpath, NULL);

  if (error == -1) {
    switch(errno) {
    case EINVAL : textstring = "Bad argument passed to COMMAND.COM"; break;
    case E2BIG  : textstring = "Too many arguments passed to COMMAND.COM"; break;
    case ENOEXEC: textstring = "Internal error -- exitting strongly suggested"; break;
    case ENOMEM : textstring = "Out of memory -- cannot shell to DOS"; break;
    case ENOENT : textstring = "Cannot find file COMMAND.COM -- initialize COMSPEC=[path]COMMAND.COM";
    }
  }
  else if (!error) textstring = NULL;
  return( textstring );
}

/*----------------------------------------------------------------------------
 * Read, print, and increment the number of program executions.
 * Print a comment, depending on the current execution number.
 * Print the amount of available memory.
 *
 * "filename" - name of the text data file to read the number of program
 *              executions from (this number must be the first byte)
 *            - writes the incremented number of executions back to the file
 * "title"    - name of the program
 * "author"   - name of the author of the program
 * "msgs"     - one comment will be randomly chosen from this array of
 *              messages
 * "msg_num"  - number of messages present
 *
 * RETURNS:
 * = file handle of the opened data file
 */
FILE *fil_count(char *filename, char *title, char *author, char *msgs[], word msg_num)
{
  word counter;                        // usage counter
  FILE *f;                             // file handle

  DASHES;                              // print one line of dashes
  if ((f = fopen(filename, "r+b")) == NULL) {
    fprintf(stderr, ERR01, filename);  // file could not be opened
    exit(1);                           // abort with ERRORLEVEL 1
  }

  /* the first byte of the file is the usage counter -- get it */
  fread(&counter, sizeof(counter), 1, f);

  /* increment the counter and print the correct message */
  if (counter++ == 0)
    printf(MSG01, title, author);      // print "first time used" message
  else {
    printf(MSG02, title, counter);     // print number of program uses
    if (counter != 1)                  // if uses do not equal 1 then
      printf("s");                     //   pluralise
  }
  DOUBLESPACE;

  /* write the incremented counter back to the file */
  rewind(f);                           // go to beginning of file
  fwrite(&counter, sizeof(counter), 1, f);

  // the "fseek" is REQUIRED for the next "fread" to work???
  fseek(f, 0L, SEEK_CUR);

  printf(msgs[random(msg_num)], title);
  printf(MSG03, coreleft(), title);    // print amount of available memory
  return( f );                         // return file handle
}

/*----------------------------------------------------------------------------
 * Read, print, and increment the number of program executions.
 * Print to whom this program is registered.
 * Print the amount of available memory.
 *
 * "filename"  - name of the text data file to read the number of program
 *               executions from (this number must be the first byte)
 *             - writes the incremented number of executions back to the file
 * "title"     - name of the program
 * "author"    - name of the author of the program
 * "registree" - name of the person to whom this program is registered
 *
 * RETURNS:
 * = file handle of the opened data file
 */
FILE *fil_count_reg(char *filename, char *title, char *author, char *registree)
{
  word counter;                        // usage counter
  FILE *f;                             // file handle

  DASHES;                              // print one line of dashes
  if ((f = fopen(filename, "r+b")) == NULL) {
    fprintf(stderr, ERR01, filename);  // file could not be opened
    exit(1);                           // abort with ERRORLEVEL 1
  }

  /* the first byte of the file is the usage counter -- get it */
  fread(&counter, sizeof(counter), 1, f);

  /* increment the counter and print the correct message */
  if (counter++ == 0)
    printf(MSG01, title, author);      // print "first time used" message
  else {
    printf(MSG02, title, counter);     // print number of program uses
    if (counter != 1)                  // if uses do not equal 1 then
      printf("s");                     //   pluralise
  }
  DOUBLESPACE;

  /* write the incremented counter back to the file */
  rewind(f);                           // go to beginning of file
  fwrite(&counter, sizeof(counter), 1, f);

  // the "fseek" is REQUIRED for the next "fread" to work???
  fseek(f, 0L, SEEK_CUR);

  if (!str_cmp(author, registree))     // if this is registered to author then
    printf(MSG05, title, author);      //   print master copy message
  else                                 // else
    printf(MSG04, title, registree);   //   print to whom this is registered

  printf(MSG03, coreleft(), title);    // print amount of available memory
  return( f );                         // return file handle
}

/*----------------------------------------------------------------------------
 * Return the length of a file, in bytes.
 *
 * "f" - file handle of file to return length of
 *
 * RETURNS:
 * = length of file in bytes
 */
long fil_len(FILE *f)
{
  long curpos, length;

  curpos = ftell(f);                   // save current position
  fseek(f, 0L, SEEK_END);              // go to EOF
  length = ftell(f);                   // get EOF position relative to start
  fseek(f, curpos, SEEK_SET);          // go back to original position
  return( length );                    // return length of file, in bytes
}

/*----------------------------------------------------------------------------
 * Read the next string from the current file position.
 *
 * "size" - initial size of text input buffer
 * "f"    - file handle of file to read from
 *
 * RETURNS:
 * = pointer to next string (file pointer is set to byte just beyond word)
 * = NULL if no string was found (file pointer is set to EOF)
 */
char *fil_next_str(word *size, FILE *f)
{
  char ch,                             // temporary character-holder
      *text;                           // text input buffer
  word index = 0,                      // index into text input buffer
       size_org;                       // original initial size of buffer

  text = (char *) malloc(size_org = *size);

  /* ignore initial whitespaces */
  for (ch = getc(f); !is_letternum(ch) && ch != QUOTE; ch = getc(f)) {
    if (ch == EOF) {                   // if we hit end of file
      free(text);                      //  no match was found (free up memory)
      return( NULL );                  //  return NULL
    }
  }

  /* read in next string */
  if (ch == QUOTE) {
    do {
      if (ch == EOF) {                 // if we hit end of file
        free(text);                    //  no match was found (free up memory)
        return( NULL );                //  return NULL
      }
      while (index+2 >= *size)         // allocate more memory if required
        text = (char *) realloc(text, *size += size_org);
      text[index++] = ch;              // store next valid character
      ch = getc(f);                    // get next character
    } while (ch != QUOTE               // loop until next character is a '"'
          && ch != CR && ch != LF);    //  or until it is a CR or LF

    if (ch == QUOTE)                   // if the last character was a '"'
      text[index++] = ch;              //  store it
  }
  else {
    for ( ; is_letternum(ch); ch = getc(f) ) {
      if (index+1 >= *size)            // allocate more memory if required
        text = (char *) realloc(text, *size += size_org);
      text[index++] = ch;              // store next valid character
    }
  }

  text[index] = NULL;                  // end string with NULL-terminator
  return( text );                      // return next string
}

/*----------------------------------------------------------------------------
 * Read the next word from the current file position.
 *
 * "size" - initial size of text input buffer
 * "f"    - file handle of file to read from
 *
 * RETURNS:
 * = pointer to next word (file pointer is set to byte just beyond word)
 * = NULL if no word was found (file pointer is set to EOF)
 */
char *fil_next_word(word *size, FILE *f)
{
  char ch,                             // temporary character-holder
      *text;                           // text input buffer
  word index = 0,                      // index into text input buffer
       size_org;                       // original initial size of buffer

  text = (char *) malloc(size_org = *size);

  /* ignore initial whitespaces */
  for (ch = getc(f); !is_letter(ch); ch = getc(f) ) {
    if (ch == EOF) {                   // if we hit end of file
      free(text);                      //  no match was found (free up memory)
      return( NULL );                  //  return NULL
    }
  }

  /* read in next word */
  for ( ; is_letter(ch); ch = getc(f)) {
    if (index+1 >= *size)              // allocate more memory if required
      text = (char *) realloc(text, *size += size_org);
    text[index++] = ch;                // store valid alphabet character
  }

  text[index] = NULL;                  // end string with NULL-terminator
  return( text );                      // return next word
}

/*----------------------------------------------------------------------------
 * Read from the current file position upto the first occurrence of a string.
 *
 * "str" - string to read up to
 * "size" - initial size of text input buffer
 * "f"   - file handle of file to read from
 *
 * RETURNS:
 * = pointer to contents of file read in (file pointer is set to byte just
 *   beyond match
 * = NULL if no match was found (file pointer is set to EOF)
 */
char *fil_read_to(char *str, word *size, FILE *f)
{
  char ch,                             // temporary character holder
      *text;                           // text input buffer
  int  index_str;                      // index into string-to-read-to
   //  must be integer because: fseek(f, -index_str, SEEK_CUR); (-ve seek)
  word index = 0,                      // index into text input buffer
       size_org;                       // original initial size of buffer

  text = (char *) malloc(size_org = *size);
 while (TRUE)
 {
  while ( (text[index++] = getc(f)) != str[0] ) {
    if (text[index-1] == EOF) {        // if we hit end of file
      free(text);                      //  no match was found (free up memory)
      return( NULL );                  //  return NULL
    }
    if (index+1 >= *size)              // allocate more memory if required
      text = (char *) realloc(text, *size += size_org);
  }

  if (str_len(str) == 1) {
    text[1] = NULL;                    // end string with NULL-terminator
    return( text );                    // return pointer to text input holder
  }
  else {
    for (index_str = 0; (ch = getc(f)) == str[++index_str]; );
    if (index_str == str_len(str)) {   // if we found the string
      fseek(f, -1, SEEK_CUR);          //  rewind to byte just after match
      if (index+index_str > *size)     //  allocate more memory if required
        text = (char *) realloc(text, *size = index_str+index);
      str_copy(text + index, str+1);
      return( text );                  //  return pointer to text input holder
    }
    else if (ch == EOF) {              // if we hit end of file
      free(text);                      //  no match was found (free up memory)
      return( NULL );                  //  return NULL
    }
  }

  fseek(f, -index_str, SEEK_CUR);      // false alarm -- rewind
 }
}

/*----------------------------------------------------------------------------
 * Read from the current file position upto the first occurrence of a string.
 * All comments (beginning with a ';'), blank lines, and extra spaces are
 *   stripped to conserve memory.
 *
 * "str" - string to read up to
 * "size" - initial size of text input buffer
 * "f"   - file handle of file to read from
 *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -