?? standard.shar
字號:
X * Function: RaiseExceptionX * Usage: RaiseException(&e, name, value);X * ---------------------------------------X * This function is called by the raise macro and does theX * work necessary to raise the exception. See the exception.c fileX * for details. Clients do not ordinarily call this directly.X */XXvoid RaiseException(exception *e, string name, void *value);XX/*X * Function: HandlerExistsX * Usage: if (HandlerExists(&e)) ...X * ---------------------------------X * Determines whether a handler exists for an exception inX * the dynamically enclosing scope. Intended only for useX * by special clients, such as the Error package.X */XXbool HandlerExists(exception *e);XX/* Define the pseudo-functions for raise and try */XX#define raise(e) RaiseException(&e, #e, NULL)XX#define try \X { \X jmp_buf _tmpbuf; \X context_block _ctx; \X volatile int _es; \X _es = ES_Initialize; \X _ctx.nx = 0; \X _ctx.link = exceptionStack; \X exceptionStack = (context_block *) &_ctx; \X if (setjmp(_tmpbuf) != 0) _es = ES_Exception; \X memcpy((void *) _ctx.jmp, (void *) _tmpbuf, sizeof(jmp_buf)); \X while (1) { \X if (_es == ES_EvalBody)XX#define except(e) \X if (_es == ES_EvalBody) exceptionStack = _ctx.link; \X break; \X } \X if (_es == ES_Initialize) { \X if (_ctx.nx >= MaxExceptionsPerScope) \X exit(ETooManyExceptClauses); \X _ctx.array[_ctx.nx++] = &e; \X } else if (_ctx.id == &e || &e == &ANY) { \X exceptionStack = _ctx.link;XX#define endtry \X if (_es != ES_Initialize) break; \X _es = ES_EvalBody; \X } \X }XX#define GetExceptionName() _ctx.nameX#define GetExceptionValue() _ctx.valueX#define GetCurrentException() _ctx.idXX#endifEND_OF_FILEif test 7974 -ne `wc -c <'cslib/exception.h'`; then echo shar: \"'cslib/exception.h'\" unpacked with wrong size!fi# end of 'cslib/exception.h'fiif test -f 'cslib/gcalloc.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'cslib/gcalloc.h'\"elseecho shar: Extracting \"'cslib/gcalloc.h'\" \(2269 characters\)sed "s/^X//" >'cslib/gcalloc.h' <<'END_OF_FILE'X/*X * File: gcalloc.hX * Version: 1.0X * Last modified on Wed Sep 21 16:21:37 1994 by erobertsX * -----------------------------------------------------X * This file is a stub version of the interface for aX * garbage-collecting allocator that will be part ofX * a future library release. When the garbage-collectingX * allocator is in use, the memory returned by the GetBlockX * and FreeBlock functions in genlib.h can be traced andX * collected automatically when it is no longer accessible.X *X * The garbage-collecting allocator is not part of theX * current cslib distribution. Even so, functions in theX * other libraries call the ProtectVariable and ProtectBlockX * functions, so that they will continue to work when theX * full library is released. Those functions are implementedX * in genlib.c.X */XX#ifndef _gcalloc_hX#define _gcalloc_hXX/*X * Macro: ProtectVariableX * Usage: ProtectVariable(v);X * --------------------------X * This macro registers a global variable with the allocationX * system, so that the variable is traced when the garbageX * collector is used. This operation needs is implementedX * in genlib.c so that code can be written to function correctlyX * whether or not the garbage-collecting allocator is loaded.X */XX#define ProtectVariable(v) ProtectBlock(&v, sizeof v)XX/*X * Function: ProtectBlockX * Usage: ProtectBlock(ptr, nbytes);X * ---------------------------------X * This function is not usually called by clients (who willX * ordinarily use ProtectVariable instead), but has theX * effect of protecting the block of memory beginning atX * ptr and extending for nbytes from the garbage collector.X */XXvoid ProtectBlock(void *ptr, size_t nbytes);XX/*X * Global linkage variable: _acbX * -----------------------------X * This variable is used to hold the allocation control blockX * that provides the linkage between this package and theX * dynamic allocator. The reason for using the structureX * as a linkage is so that the garbage-collecting allocatorX * need not even be loaded if it is not explicitly called.X */XXtypedef struct {X void *(*allocMethod)(size_t nbytes);X void (*freeMethod)(void *ptr);X void (*protectMethod)(void *ptr, size_t nbytes);X} *_GCControlBlock;XXextern _GCControlBlock _acb;XX#endifEND_OF_FILEif test 2269 -ne `wc -c <'cslib/gcalloc.h'`; then echo shar: \"'cslib/gcalloc.h'\" unpacked with wrong size!fi# end of 'cslib/gcalloc.h'fiif test -f 'cslib/genlib.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'cslib/genlib.c'\"elseecho shar: Extracting \"'cslib/genlib.c'\" \(3748 characters\)sed "s/^X//" >'cslib/genlib.c' <<'END_OF_FILE'X/*X * File: genlib.cX * Version: 1.0X * Last modified on Sun Jul 24 10:29:46 1994 by erobertsX * -----------------------------------------------------X * This file implements the general C library package. See theX * interface description in genlib.h for details.X */XX#include <stdio.h>X#include <stddef.h>X#include <string.h>X#include <stdarg.h>XX#include "genlib.h"X#include "gcalloc.h"X#include "exception.h"XX/*X * Constants:X * ----------X * ErrorExitStatus -- Status value used in exit callX * MaxErrorMessage -- Longest error message allowedX */XX#define ErrorExitStatus 1X#define MaxErrorMessage 500XX/* Section 1 -- Define new "primitive" types */XX/*X * Constant: UNDEFINEDX * -------------------X * This entry defines the target of the UNDEFINED constant.X */XXchar undefined_object[] = "UNDEFINED";XX/* Section 2 -- Memory allocation */XX/*X * Implementation notes:X * ---------------------X * The code for the memory allocator is divided betweenX * genlib.c and gcalloc.c, and the division strategy may atX * first seem unnatural, since the function ProtectBlock isX * declared in gcalloc.h but defined here in genlib.c. TheX * intention is to minimize the size of object filesX * produced by linkers that search a library for modulesX * that are actually referenced. The libraries themselvesX * need to call ProtectBlock (usually through the macroX * ProtectVariable), but will not require the actual codeX * for the allocator unless InitGCAllocator is explicitlyX * called.X */XX/*X * Global variable: _acbX * ---------------------X * This variable is used to hold a method suite that makes itX * easy to substitute a garbage-collecting allocator for theX * ANSI allocator.X */XX_GCControlBlock _acb = NULL;XX/* Memory allocation implementation */XXvoid *GetBlock(size_t nbytes)X{X void *result;XX if (_acb == NULL) {X result = malloc(nbytes);X } else {X result = _acb->allocMethod(nbytes);X }X if (result == NULL) Error("No memory available");X return (result);X}XXvoid FreeBlock(void *ptr)X{X if (_acb == NULL) {X free(ptr);X } else {X _acb->freeMethod(ptr);X }X}XXvoid ProtectBlock(void *ptr, size_t nbytes)X{X if (_acb != NULL) _acb->protectMethod(ptr, nbytes);X}XX/* Section 3 -- Basic error handling */XX/*X * Implementation notes: ErrorX * ---------------------------X * Writing the Error function requires some care, since it isX * called in circumstances in which parts of the system may beX * broken. In particular, it is not acceptable for Error toX * call GetBlock, since the error condition may be that theX * system is out of memory, in which case calling GetBlock wouldX * fail. The error string should be allocated dynamically,X * so that this function can be used in reentrant code.X * Note that it is critical to exit if the length bound forX * an error message is exceeded, since this error almostX * certainly corrupts the stack.X */XXvoid Error(string msg, ...)X{X va_list args;X char errbuf[MaxErrorMessage + 1];X string errmsg;X int errlen;XX va_start(args, msg);X vsprintf(errbuf, msg, args);X va_end(args);X errlen = strlen(errbuf);X if (errlen > MaxErrorMessage) {X fprintf(stderr, "Error: Error Message too long\n");X exit(ErrorExitStatus);X }X if (_acb == NULL) {X errmsg = malloc(errlen + 1);X } else {X errmsg = _acb->allocMethod(errlen + 1);X }X if (errmsg == NULL) {X errmsg = "No memory available";X } else {X strcpy(errmsg, errbuf);X }X if (HandlerExists(&ErrorException)) {X RaiseException(&ErrorException, "ErrorException", errmsg);X } else {X fprintf(stderr, "Error: %s\n", errmsg);X exit(ErrorExitStatus);X }X}END_OF_FILEif test 3748 -ne `wc -c <'cslib/genlib.c'`; then echo shar: \"'cslib/genlib.c'\" unpacked with wrong size!fi# end of 'cslib/genlib.c'fiif test -f 'cslib/genlib.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'cslib/genlib.h'\"elseecho shar: Extracting \"'cslib/genlib.h'\" \(6232 characters\)sed "s/^X//" >'cslib/genlib.h' <<'END_OF_FILE'X/*X * File: genlib.hX * Version: 1.0X * Last modified on Sun Jul 24 10:32:49 1994 by erobertsX * -----------------------------------------------------X * This file contains several definitions that form theX * core of a general-purpose ANSI C library developed by EricX * Roberts. The goal of this library is to provide a basicX * set of tools and conventions that increase the readabilityX * of C programs, particularly as they are used in a teachingX * environment.X *X * The basic definitions provided by genlib.h are:X *X * 1. Declarations for several new "primitive" typesX * (most importantly bool and string) that areX * used throughout the other libraries andX * applications as fundamental types.X *X * 2. A new set of functions for memory allocation.X *X * 3. A function for error handling.X *X * 4. A repeat statement for loops with interior exits.X */XX#ifndef _genlib_hX#define _genlib_hXX#include <stdio.h>X#include <stdlib.h>X#include <stddef.h>XX/* Section 1 -- Define new "primitive" types */XX/*X * Type: boolX * ----------X * This type has two values, FALSE and TRUE, which are equal to 0X * and 1, respectively. Most of the advantage of defining this typeX * comes from readability because it allows the programmer toX * provide documentation that a variable will take on only one ofX * these two values. Designing a portable representation, however,X * is surprisingly hard, because many libraries and some compilersX * define these names. The definitions are usually compatible butX * may still be flagged as errors.X */XX#ifdef THINK_CX typedef int bool;X#elseX# ifdef TRUEX# ifndef boolX# define bool intX# endifX# elseX# ifdef boolX# define FALSE 0X# define TRUE 1X# elseX typedef enum {FALSE, TRUE} bool;X# endifX# endifX#endifXX/*X * Type: stringX * ------------X * The type string is identical to the type char *, which isX * traditionally used in C programs. The main point of defining aX * new type is to improve program readability. At the abstractionX * levels at which the type string is used, it is usually notX * important to take the string apart into its component characters.X * Declaring it as a string emphasizes this atomicity.X */XXtypedef char *string;XX/*X * Type: streamX * ------------X * Like string, the stream type is used to provide additionalX * readability and is defined to be equivalent to FILE *X * (which is particularly confusing because it violatesX * standard case conventions). This type is not used inX * the text but is preserved in genlib.h, so it is possibleX * to teach all of CS1 without exposing any pointers.X */XXtypedef FILE *stream;XX/*X * Constant: UNDEFINEDX * -------------------X * Besides NULL, the only other constant of pointer type isX * UNDEFINED, which is used in certain packages as a specialX * sentinel to indicate an undefined pointer value. In manyX * such contexts, NULL is a legitimate data value and isX * therefore inappropriate as a sentinel.X */XX#define UNDEFINED ((void *) undefined_object)XXextern char undefined_object[];XX/* Section 2 -- Memory allocation */XX/*X * General notes:X * --------------X * These functions provide a common interface for memoryX * allocation. All functions in the library that allocateX * memory do so using GetBlock and FreeBlock. Even thoughX * the ANSI standard defines malloc and free for the sameX * purpose, using GetBlock and FreeBlock provides greaterX * compatibility with non-ANSI implementations, automaticX * out-of-memory error detection, and the possibility ofX * substituting a garbage-collecting allocator.X */XX/*X * Function: GetBlockX * Usage: ptr = (type) GetBlock(nbytes);X * -------------------------------------X * GetBlock allocates a block of memory of the given size. IfX * no memory is available, GetBlock generates an error.X */XXvoid *GetBlock(size_t nbytes);XX/*X * Function: FreeBlockX * Usage: FreeBlock(ptr);X * ----------------------X * FreeBlock frees the memory associated with ptr, which mustX * have been allocated using GetBlock, New, or NewArray.X */XXvoid FreeBlock(void *ptr);XX/*X * Macro: NewX * Usage: p = New(pointer-type);X * -----------------------------X * The New pseudofunction allocates enough space to hold an
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -