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

📄 memos.gml

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 GML
📖 第 1 页 / 共 2 页
字号:
.code begin
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>

#include "memos.h"

/* This program implements a simple memo facility.
 * Memos may be added to a memo file, displayed
 * on the screen, and deleted.
 *
 * Modified     by              reason
 * ========     ==              ======
 * 87/10/02     Steve McDowell  Initial implementation.
 * 88/09/20     Steve McDowell  Fixed up some style issues,
 *                              introduced use of TRUE and
 *                              FALSE.
 */

/* Define some constants to make the code more readable.
 */
#define TRUE        1
#define FALSE       0
#define NULLCHAR    '\0'

.code break
static const char FileName[] = { "memos.db" };
static const char TempName[] = { "tempmemo.db" };

static MEMO_EL *  MemoHead      = NULL;
static int        MemosModified = FALSE;
static int        QuitFlag      = TRUE;

.code break
typedef enum {
    INVALID,
    HELP,
    ADD,
    DELETE,
    REPLACE,
    SHOW,
    UP,
    DOWN,
    TOP,
    TODAY,
    SAVE,
    QUIT
} ACTION;

.code break
/* This table maps action keywords onto the "actions" defined
 * above. The table also defines short forms for the keywords.
 */
typedef struct {
    ACTION act;
    char * keyword;
} ACTION_MAP;

.code break
static ACTION_MAP KeywordMap[] = {
    HELP,    "help",
    HELP,    "h",
    ADD,     "add",
    ADD,     "a",
    DELETE,  "delete",
    DELETE,  "del",
    REPLACE, "replace",
    REPLACE, "rep",
    SHOW,    "show",
    SHOW,    "sh",
    UP,      "up",
    UP,      "u",
    DOWN,    "down",
    DOWN,    "d",
    DOWN,    "",
    TOP,     "top",
    TODAY,   "today",
    TODAY,   "tod",
    SAVE,    "save",
    SAVE,    "sa",
    QUIT,    "quit",
    QUIT,    "q",

    INVALID, "" };

.code break
/* Maximum buffer length (maximum length of line of memo).
 */
#define MAXLEN 80

/* Function prototypes.
 */
static TEXT_LINE *  AddLine();
static MEMO_EL *    AddMemo();
static MEMO_EL *    DeleteMemo();
static MEMO_EL *    DoActions();
static MEMO_EL *    DoDownAction();
static MEMO_EL *    DoUpAction();
static MEMO_EL *    EnterAMemo();
static ACTION       GetAction();
static void *       MemoMAlloc();
static ACTION       PromptAction();
static ACTION       ReadAction();
static MEMO_EL *    ReadAMemo();
static MEMO_EL *    ShowTodaysMemos();

.code break
extern int main( int argc, char * argv[] )
/****************************************/
{
    int       index;
    MEMO_EL * el;

    printf( "Memo facility\n" );

.code break
/* Check for a single argument that is a question mark,
 * If found, then display the usage notes.
 */
    if( argc == 2  &&  strcmp( argv[1], "?" ) == 0 ) {
        Usage();
        exit( 0 );
    }
    ReadMemos();
    MemosModified = FALSE;
    QuitFlag      = FALSE;

.code break
/* Use the command line parameters, if any, as the first
 * actions to be performed on the memos.
 */
    el = NULL;
    for( index = 1; index < argc; ++index ) {
        el = DoActions( el, GetAction( argv[index] ) );
        if( QuitFlag ) {
            return( FALSE );
        }
    }
    HandleMemoActions( el );
    return( FALSE );
}

.code break
static void ReadMemos( void )
/***************************/

/* Read the memos file, building the structure to contain it.
 */
{
    FILE *    fid;
    MEMO_EL * new_el;
    MEMO_EL * prev_el;
    int       mcount;

    fid = fopen( FileName, "r" );
.code break
    if( fid == NULL ) {
        printf( "Memos file not found."
                " Starting with no memos.\n" );
        return;
    }

.code break
/* Loop reading entire memos.
 */
    prev_el = NULL;
    for( mcount = 0;; mcount++ ) {
        new_el = ReadAMemo( fid );
        if( new_el == NULL ) {
            printf( "%d memo(s) found.\n", mcount );
            fclose( fid );
            return;
        }
.code break
        if( prev_el == NULL ) {
            MemoHead = new_el;
            new_el->prev = NULL;
        } else {
            prev_el->next = new_el;
            new_el->prev = prev_el;
        }
.code break
        new_el->next = NULL;
        prev_el = new_el;
    }
}

.code break
static int ReadLine( char buffer[], int len, FILE * fid )
/*******************************************************/

/* Read a line from the memos file. Handle any I/O errors and
 * EOF. Return the length read, not counting the newline on
 * the end.
 */
{
    if( fgets( buffer, len, fid ) == NULL ) {
        if( feof( fid ) ) {
            return( EOF );
        }
        perror( "Error reading memos file" );
        abort();
    }
.code break
    return( strlen( buffer ) - 1 );
}

.code break
static MEMO_EL * ReadAMemo( FILE * fid )
/**************************************/

/* Read one memo, creating the memo structure and filling it
 * in. Return a pointer to the memo (NULL if none read).
 */
{
    MEMO_EL *   el;
    int         len;
    TEXT_LINE * line;
    char        buffer[MAXLEN];

    len = ReadLine( buffer, MAXLEN, fid );
    if( len == EOF ) {
        return( NULL );
    }

.code break
/* First line must be of the form "Date:" or "Date:YY/MM/DD":
 */
    if( (len != 5  &&  len != 13)
            ||  strncmp( buffer, "Date:", 5 ) != 0 ) {
        BadFormat();
    }
.code break
    buffer[len] = NULLCHAR;
    el = MemoMAlloc( sizeof( MEMO_EL ) );
    el->text = NULL;
    strcpy( el->date, buffer + 5 );
    line = NULL;
.code break
    for( ;; ) {
        len = ReadLine( buffer, MAXLEN, fid );
        if( len == EOF ) {
            BadFormat();
        }
.code break
        buffer[len] = NULLCHAR;
        if( strcmp( buffer, "====" ) == 0 ) {
            return( el );
        }
        line = AddLine( buffer, el, line );
    }
}

.code break
static TEXT_LINE * AddLine( char        buffer[],
                            MEMO_EL *   el,
                            TEXT_LINE * prevline )
/************************************************/

/* Add a line of text to the memo, taking care of all the
 * details of modifying the structure.
 */
{
    TEXT_LINE * line;

    line = MemoMAlloc( sizeof( TEXT_LINE ) + strlen( buffer ) );
    strcpy( line->text, buffer );
    line->next = NULL;
.code break
    if( prevline == NULL ) {
        el->text = line;
    } else {
        prevline->next = line;
    }
    return( line );
}

.code break
static ACTION PromptAction( void )
/********************************/

/* The user didn't specify an action on the command line,
 * so prompt for it.
 */
{
    ACTION act;

    for( ;; ) {
        printf( "\nEnter an action:\n" );
        act = ReadAction();
.code break
        if( act != INVALID ) {
            return( act );
        }
        printf( "\nThat selection was not valid.\n" );
        Help();
    }
}

.code break
static ACTION ReadAction( void )
/******************************/

/* Read an action from the terminal.
 * Return the action code.
 */
{
    char buffer[80];

    if( gets( buffer ) == NULL ) {
        perror( "Error reading action" );
        abort();
    }
.code break
    return( GetAction( buffer ) );
}

.code break
static ACTION GetAction( char buffer[] )
/**************************************/

/* Given the string in the buffer, return the action that
 * corresponds to it.
 * The string in the buffer is first zapped into lower case
 * so that mixed-case entries are recognized.
 */
{
    ACTION_MAP * actmap;
    char *       bufptr;

    for( bufptr = buffer; *bufptr != NULLCHAR; ++bufptr ) {
        *bufptr = tolower( *bufptr );
    }
.code break
    for( actmap = KeywordMap; actmap->act != INVALID; ++actmap ) {
        if( strcmp( buffer, actmap->keyword ) == 0 ) break;
    }
    return( actmap->act );
}

.code break
static void HandleMemoActions( MEMO_EL * el )
/*******************************************/

/* Handle all the actions entered from the keyboard.
 */
{
    for( ;; ) {
        el = DoActions( el, PromptAction() );
        if( QuitFlag ) break;
    }
}

.code break
static MEMO_EL * DoActions( MEMO_EL * el, ACTION act )
/****************************************************/

/* Perform one action on the memos.
 */
{
    MEMO_EL * new_el;
    MEMO_EL * prev_el;

    switch( act ) {
      case HELP:
        Help();
        break;
.code break
      case ADD:
        new_el = AddMemo( el );
        if( new_el != NULL ) {
            el = new_el;
            MemosModified = TRUE;
        }
        break;
.code break
      case DELETE:
        el = DeleteMemo( el );
        MemosModified = TRUE;
        break;
.code break
      case REPLACE:
        prev_el = el;
        new_el = AddMemo( el );
        if( new_el != NULL ) {
            DeleteMemo( prev_el );
            MemosModified = TRUE;
        }
        break;
.code break
      case SHOW:
        DisplayMemo( el );
        break;
.code break
      case UP:
        el = DoUpAction( el );
        break;
.code break
      case DOWN:
        el = DoDownAction( el );
        break;
.code break
      case TOP:
        el = NULL;
        break;
.code break
      case TODAY:
        el = ShowTodaysMemos();
        break;
.code break
      case SAVE:
        if( SaveMemos() ) {
            MemosModified = FALSE;
        }
        break;
.code break
      case QUIT:
        if( WantToQuit() ) {
            QuitFlag = TRUE;
            el = NULL;
        }
    }
.code break
    return( el );
}

.code break
static MEMO_EL * AddMemo( MEMO_EL * el )
/**************************************/

/* Add a memo following the current one.
 */
{

⌨️ 快捷键说明

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