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

📄 itcl_util.c

📁 linux 下的源代码分析阅读器 red hat公司新版
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * ------------------------------------------------------------------------ *      PACKAGE:  [incr Tcl] *  DESCRIPTION:  Object-Oriented Extensions to Tcl * *  [incr Tcl] provides object-oriented extensions to Tcl, much as *  C++ provides object-oriented extensions to C.  It provides a means *  of encapsulating related procedures together with their shared data *  in a local namespace that is hidden from the outside world.  It *  promotes code re-use through inheritance.  More than anything else, *  it encourages better organization of Tcl applications through the *  object-oriented paradigm, leading to code that is easier to *  understand and maintain. * *  This segment provides common utility functions used throughout *  the other [incr Tcl] source files. * * ======================================================================== *  AUTHOR:  Michael J. McLennan *           Bell Labs Innovations for Lucent Technologies *           mmclennan@lucent.com *           http://www.tcltk.com/itcl * *     RCS:  $Id: itcl_util.c 144 2003-02-05 10:56:26Z mdejong $ * ======================================================================== *           Copyright (c) 1993-1998  Lucent Technologies, Inc. * ------------------------------------------------------------------------ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */#include "itclInt.h"#include "tclCompile.h"/* *  POOL OF LIST ELEMENTS FOR LINKED LIST */static Itcl_ListElem *listPool = NULL;static int listPoolLen = 0;#define ITCL_VALID_LIST 0x01face10  /* magic bit pattern for validation */#define ITCL_LIST_POOL_SIZE 200     /* max number of elements in listPool *//* *  These records are used to keep track of reference-counted data *  for Itcl_PreserveData and Itcl_ReleaseData. */typedef struct ItclPreservedData {    ClientData data;                /* reference to data */    int usage;                      /* number of active uses */    Tcl_FreeProc *fproc;            /* procedure used to free data */} ItclPreservedData;static Tcl_HashTable *ItclPreservedList = NULL;/* *  This structure is used to take a snapshot of the interpreter *  state in Itcl_SaveInterpState.  You can snapshot the state, *  execute a command, and then back up to the result or the *  error that was previously in progress. */typedef struct InterpState {    int validate;                   /* validation stamp */    int status;                     /* return code status */    Tcl_Obj *objResult;             /* result object */    char *errorInfo;                /* contents of errorInfo variable */    char *errorCode;                /* contents of errorCode variable */} InterpState;#define TCL_STATE_VALID 0x01233210  /* magic bit pattern for validation *//* * ------------------------------------------------------------------------ *  Itcl_Assert() * *  Called whenever an assert() test fails.  Prints a diagnostic *  message and abruptly exits. * ------------------------------------------------------------------------ */voidItcl_Assert(testExpr, fileName, lineNumber)    char *testExpr;   /* string representing test expression */    char *fileName;   /* file name containing this call */    int lineNumber;   /* line number containing this call */{#ifndef NDEBUG    fprintf(stderr, "Assertion failed: \"%s\" (line %d of %s)",        testExpr, lineNumber, fileName);    abort();#endif}/* * ------------------------------------------------------------------------ *  Itcl_InitStack() * *  Initializes a stack structure, allocating a certain amount of memory *  for the stack and setting the stack length to zero. * ------------------------------------------------------------------------ */voidItcl_InitStack(stack)    Itcl_Stack *stack;     /* stack to be initialized */{    stack->values = stack->space;    stack->max = sizeof(stack->space)/sizeof(ClientData);    stack->len = 0;}/* * ------------------------------------------------------------------------ *  Itcl_DeleteStack() * *  Destroys a stack structure, freeing any memory that may have been *  allocated to represent it. * ------------------------------------------------------------------------ */voidItcl_DeleteStack(stack)    Itcl_Stack *stack;     /* stack to be deleted */{    /*     *  If memory was explicitly allocated (instead of using the     *  built-in buffer) then free it.     */    if (stack->values != stack->space) {        ckfree((char*)stack->values);    }    stack->values = NULL;    stack->len = stack->max = 0;}/* * ------------------------------------------------------------------------ *  Itcl_PushStack() * *  Pushes a piece of client data onto the top of the given stack. *  If the stack is not large enough, it is automatically resized. * ------------------------------------------------------------------------ */voidItcl_PushStack(cdata,stack)    ClientData cdata;      /* data to be pushed onto stack */    Itcl_Stack *stack;     /* stack */{    ClientData *newStack;    if (stack->len+1 >= stack->max) {        stack->max = 2*stack->max;        newStack = (ClientData*)            ckalloc((unsigned)(stack->max*sizeof(ClientData)));        if (stack->values) {            memcpy((char*)newStack, (char*)stack->values,                (size_t)(stack->len*sizeof(ClientData)));            if (stack->values != stack->space)                ckfree((char*)stack->values);        }        stack->values = newStack;    }    stack->values[stack->len++] = cdata;}/* * ------------------------------------------------------------------------ *  Itcl_PopStack() * *  Pops a bit of client data from the top of the given stack. * ------------------------------------------------------------------------ */ClientDataItcl_PopStack(stack)    Itcl_Stack *stack;  /* stack to be manipulated */{    if (stack->values && (stack->len > 0)) {        stack->len--;        return stack->values[stack->len];    }    return (ClientData)NULL;}/* * ------------------------------------------------------------------------ *  Itcl_PeekStack() * *  Gets the current value from the top of the given stack. * ------------------------------------------------------------------------ */ClientDataItcl_PeekStack(stack)    Itcl_Stack *stack;  /* stack to be examined */{    if (stack->values && (stack->len > 0)) {        return stack->values[stack->len-1];    }    return (ClientData)NULL;}/* * ------------------------------------------------------------------------ *  Itcl_GetStackValue() * *  Gets a value at some index within the stack.  Index "0" is the *  first value pushed onto the stack. * ------------------------------------------------------------------------ */ClientDataItcl_GetStackValue(stack,pos)    Itcl_Stack *stack;  /* stack to be examined */    int pos;            /* get value at this index */{    if (stack->values && (stack->len > 0)) {        assert(pos < stack->len);        return stack->values[pos];    }    return (ClientData)NULL;}/* * ------------------------------------------------------------------------ *  Itcl_InitList() * *  Initializes a linked list structure, setting the list to the empty *  state. * ------------------------------------------------------------------------ */voidItcl_InitList(listPtr)    Itcl_List *listPtr;     /* list to be initialized */{    listPtr->validate = ITCL_VALID_LIST;    listPtr->num      = 0;    listPtr->head     = NULL;    listPtr->tail     = NULL;}/* * ------------------------------------------------------------------------ *  Itcl_DeleteList() * *  Destroys a linked list structure, deleting all of its elements and *  setting it to an empty state.  If the elements have memory associated *  with them, this memory must be freed before deleting the list or it *  will be lost. * ------------------------------------------------------------------------ */voidItcl_DeleteList(listPtr)    Itcl_List *listPtr;     /* list to be deleted */{    Itcl_ListElem *elemPtr;    assert(listPtr->validate == ITCL_VALID_LIST);    elemPtr = listPtr->head;    while (elemPtr) {        elemPtr = Itcl_DeleteListElem(elemPtr);    }    listPtr->validate = 0;}/* * ------------------------------------------------------------------------ *  Itcl_CreateListElem() * *  Low-level routined used by procedures like Itcl_InsertList() and *  Itcl_AppendList() to create new list elements.  If elements are *  available, one is taken from the list element pool.  Otherwise, *  a new one is allocated. * ------------------------------------------------------------------------ */Itcl_ListElem*Itcl_CreateListElem(listPtr)    Itcl_List *listPtr;     /* list that will contain this new element */{    Itcl_ListElem *elemPtr;    if (listPoolLen > 0) {        elemPtr = listPool;        listPool = elemPtr->next;        --listPoolLen;    }    else {        elemPtr = (Itcl_ListElem*)ckalloc((unsigned)sizeof(Itcl_ListElem));    }    elemPtr->owner = listPtr;    elemPtr->value = NULL;    elemPtr->next  = NULL;    elemPtr->prev  = NULL;    return elemPtr;}/* * ------------------------------------------------------------------------ *  Itcl_DeleteListElem() * *  Destroys a single element in a linked list, returning it to a pool of *  elements that can be later reused.  Returns a pointer to the next *  element in the list. * ------------------------------------------------------------------------ */Itcl_ListElem*Itcl_DeleteListElem(elemPtr)    Itcl_ListElem *elemPtr;     /* list element to be deleted */{    Itcl_List *listPtr;    Itcl_ListElem *nextPtr;    nextPtr = elemPtr->next;    if (elemPtr->prev) {        elemPtr->prev->next = elemPtr->next;    }    if (elemPtr->next) {        elemPtr->next->prev = elemPtr->prev;    }    listPtr = elemPtr->owner;    if (elemPtr == listPtr->head)        listPtr->head = elemPtr->next;    if (elemPtr == listPtr->tail)        listPtr->tail = elemPtr->prev;    --listPtr->num;    if (listPoolLen < ITCL_LIST_POOL_SIZE) {        elemPtr->next = listPool;        listPool = elemPtr;        ++listPoolLen;    }    else {        ckfree((char*)elemPtr);    }    return nextPtr;}/* * ------------------------------------------------------------------------ *  Itcl_InsertList() * *  Creates a new list element containing the given value and returns *  a pointer to it.  The element is inserted at the beginning of the *  specified list. * ------------------------------------------------------------------------ */Itcl_ListElem*Itcl_InsertList(listPtr,val)    Itcl_List *listPtr;     /* list being modified */    ClientData val;         /* value associated with new element */{    Itcl_ListElem *elemPtr;    assert(listPtr->validate == ITCL_VALID_LIST);    elemPtr = Itcl_CreateListElem(listPtr);    elemPtr->value = val;    elemPtr->next  = listPtr->head;    elemPtr->prev  = NULL;    if (listPtr->head) {        listPtr->head->prev = elemPtr;    }    listPtr->head  = elemPtr;    if (listPtr->tail == NULL) {        listPtr->tail = elemPtr;    }    ++listPtr->num;    return elemPtr;}/* * ------------------------------------------------------------------------ *  Itcl_InsertListElem() * *  Creates a new list element containing the given value and returns *  a pointer to it.  The element is inserted in the list just before *  the specified element. * ------------------------------------------------------------------------ */Itcl_ListElem*Itcl_InsertListElem(pos,val)    Itcl_ListElem *pos;     /* insert just before this element */    ClientData val;         /* value associated with new element */{    Itcl_List *listPtr;    Itcl_ListElem *elemPtr;    listPtr = pos->owner;    assert(listPtr->validate == ITCL_VALID_LIST);    assert(pos != NULL);    elemPtr = Itcl_CreateListElem(listPtr);    elemPtr->value = val;    elemPtr->prev = pos->prev;    if (elemPtr->prev) {        elemPtr->prev->next = elemPtr;    }    elemPtr->next = pos;    pos->prev     = elemPtr;    if (listPtr->head == pos) {        listPtr->head = elemPtr;    }    if (listPtr->tail == NULL) {        listPtr->tail = elemPtr;    }    ++listPtr->num;    return elemPtr;}/* * ------------------------------------------------------------------------ *  Itcl_AppendList() * *  Creates a new list element containing the given value and returns *  a pointer to it.  The element is appended at the end of the *  specified list. * ------------------------------------------------------------------------ */Itcl_ListElem*Itcl_AppendList(listPtr,val)    Itcl_List *listPtr;     /* list being modified */    ClientData val;         /* value associated with new element */{    Itcl_ListElem *elemPtr;    assert(listPtr->validate == ITCL_VALID_LIST);    elemPtr = Itcl_CreateListElem(listPtr);    elemPtr->value = val;    elemPtr->prev  = listPtr->tail;    elemPtr->next  = NULL;    if (listPtr->tail) {        listPtr->tail->next = elemPtr;    }    listPtr->tail  = elemPtr;    if (listPtr->head == NULL) {        listPtr->head = elemPtr;    }    ++listPtr->num;    return elemPtr;}/* * ------------------------------------------------------------------------ *  Itcl_AppendListElem() * *  Creates a new list element containing the given value and returns *  a pointer to it.  The element is inserted in the list just after *  the specified element. * ------------------------------------------------------------------------

⌨️ 快捷键说明

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