Jabber WindowGram Client (JWGC)

Introduction Screenshots Installation Downloads
Documentation Browse Source Resources Project Site

Stable Version
-none-

Latest Version
beta5



Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

node.c

Go to the documentation of this file.
00001 /*
00002  *      Copyright (c) 1989 by the Massachusetts Institute of Technology.
00003  *      For copying and distribution information, see the file
00004  *      "mit-copyright.h".
00005  *
00006  *      Modified for jwgc by Daniel Henninger.
00007  */
00008 
00009 #include "mit-copyright.h"
00010 
00011 #include "node.h"
00012 
00013 /****************************************************************************/
00014 /* */
00015 /* Internal node construction & destruction functions:           */
00016 /* */
00017 /****************************************************************************/
00018 
00019 /*
00020  * NODE_BATCH_SIZE - the number of nodes to malloc at once to save overhead:
00021  */
00022 
00023 #define  NODE_BATCH_SIZE    100
00024 
00025 /*
00026  * The nodes we have malloced are kept in a linked list of bunches of
00027  * NODE_BATCH_SIZE nodes.  Nodes points to the first bunch on the list
00028  * and current_bunch to the last.  All nodes from the first one in the first
00029  * bunch to the last_node_in_current_bunch_used'th one in the last bunch
00030  * are in use.  The others have not been used yet.
00031  */
00032 
00033 static struct _bunch_of_nodes {
00034         struct _bunch_of_nodes *next_bunch;
00035         Node nodes[NODE_BATCH_SIZE];
00036 } *nodes = NULL;
00037 static struct _bunch_of_nodes *current_bunch = NULL;
00038 static int last_node_in_current_bunch_used = -1;
00039 
00040 /*
00041  *  Internal Routine:
00042  *
00043  *    Node *node_create(int opcode)
00044  *        Effects: Creates a node with opcode opcode and returns a pointer
00045  *                 to it.  The next pointer of the returned node is NULL.
00046  *                 If the opcode is STRING_CONSTANT_OPCODE the caller must
00047  *                 ensure that the string_constant field points to a valid
00048  *                 string on the heap when node_DestroyAllNodes is called.
00049  */
00050 
00051 static Node *
00052 node_create(opcode)
00053         int opcode;
00054 {
00055         Node *result;
00056 
00057         if (!nodes) {
00058                 /*
00059                  * Handle special case where no nodes allocated yet:
00060                  */
00061                 current_bunch = nodes = (struct _bunch_of_nodes *)
00062                         malloc(sizeof(struct _bunch_of_nodes));
00063                 nodes->next_bunch = NULL;
00064                 last_node_in_current_bunch_used = -1;
00065         }
00066 
00067         /*
00068          * If all nodes allocated so far in use, allocate another
00069          * bunch of NODE_BATCH_SIZE nodes:
00070          */
00071         if (last_node_in_current_bunch_used == NODE_BATCH_SIZE - 1) {
00072                 current_bunch->next_bunch = (struct _bunch_of_nodes *)
00073                         malloc(sizeof(struct _bunch_of_nodes));
00074                 current_bunch = current_bunch->next_bunch;
00075                 current_bunch->next_bunch = NULL;
00076                 last_node_in_current_bunch_used = -1;
00077         }
00078 
00079         /*
00080          * Get next not already used node & ready it for use:
00081          */
00082         last_node_in_current_bunch_used++;
00083         result = &(current_bunch->nodes[last_node_in_current_bunch_used]);
00084         result->opcode = opcode;
00085         result->next = NULL;
00086 
00087         return (result);
00088 }
00089 
00090 /*
00091  *
00092  */
00093 
00094 void 
00095 node_DestroyAllNodes()
00096 {
00097         struct _bunch_of_nodes *next_bunch;
00098         int i, last_node_used_in_this_bunch;
00099 
00100         while (nodes) {
00101                 next_bunch = nodes->next_bunch;
00102                 last_node_used_in_this_bunch = next_bunch ?
00103                         NODE_BATCH_SIZE - 1 : last_node_in_current_bunch_used;
00104                 for (i = 0; i <= last_node_used_in_this_bunch; i++) {
00105                         if (nodes->nodes[i].opcode == STRING_CONSTANT_OPCODE)
00106                                 free(nodes->nodes[i].d.string_constant);
00107                         else if (nodes->nodes[i].opcode == VARREF_OPCODE)
00108                                 free(nodes->nodes[i].d.string_constant);
00109                         else if (nodes->nodes[i].opcode == VARNAME_OPCODE)
00110                                 free(nodes->nodes[i].d.string_constant);
00111                 }
00112                 free(nodes);
00113                 nodes = next_bunch;
00114         }
00115 
00116         current_bunch = nodes;
00117 }
00118 
00119 /****************************************************************************/
00120 /* */
00121 /* Node construction functions:                         */
00122 /* */
00123 /****************************************************************************/
00124 
00125 Node *
00126 node_create_string_constant(opcode, text)
00127         int opcode;
00128         string text;
00129 {
00130         Node *n;
00131 
00132         n = node_create(opcode);
00133         n->d.string_constant = text;
00134         return (n);
00135 }
00136 
00137 Node *
00138 node_create_noary(opcode)
00139         int opcode;
00140 {
00141         Node *n;
00142 
00143         n = node_create(opcode);
00144         return (n);
00145 }
00146 
00147 Node *
00148 node_create_unary(opcode, arg)
00149         int opcode;
00150         Node *arg;
00151 {
00152         Node *n;
00153 
00154         n = node_create(opcode);
00155         n->d.nodes.first = arg;
00156         return (n);
00157 }
00158 
00159 Node *
00160 node_create_binary(opcode, first_arg, second_arg)
00161         int opcode;
00162         Node *first_arg;
00163         Node *second_arg;
00164 {
00165         Node *n;
00166 
00167         n = node_create(opcode);
00168         n->d.nodes.first = first_arg;
00169         n->d.nodes.second = second_arg;
00170         return (n);
00171 }
00172 
00173 /****************************************************************************/
00174 /* */
00175 /* Node utility functions:                           */
00176 /* */
00177 /****************************************************************************/
00178 
00179 /*
00180  *    Node *reverse_list_of_nodes(Node *list)
00181  *        Modifies: the nodes on the linked list list
00182  *        Effects: Reverses the linked list list and returns it.
00183  *                 This is done by modifing the next pointers of the
00184  *                 list elements to point to the previous node & returning
00185  *                 the address of the (previously) last node.
00186  */
00187 
00188 Node *
00189 reverse_list_of_nodes(list)
00190         Node *list;
00191 {
00192         Node *next_node;
00193         Node *head = NULL;
00194 
00195         while (list) {
00196                 next_node = list->next;
00197 
00198                 /*
00199                  * Add the node list to the beginning of linked list head:
00200                  */
00201                 list->next = head;
00202                 head = list;
00203 
00204                 list = next_node;
00205         }
00206 
00207         return (head);
00208 }


Last updated at Tue Dec 18 21:07:42 PST 2007. This site and project hosted by...SourceForge.net Logo
Source Perspective by Fisheye