File: wl_pointer.c

package info (click to toggle)
gwm 1.8d-2
  • links: PTS
  • area: main
  • in suites: potato, woody
  • size: 5,120 kB
  • ctags: 3,030
  • sloc: ansic: 19,617; makefile: 1,763; lisp: 437; sh: 321; ml: 21
file content (218 lines) | stat: -rw-r--r-- 5,337 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/* Copyright 1989 GROUPE BULL -- See license conditions in file COPYRIGHT
 * Copyright 1989 Massachusetts Institute of Technology
 */
/************************\
* 			 *
*  WOOL_OBJECT: Pointer	 *
*  BODY			 *
* 			 *
\************************/

/* Pointers are like atoms, but instead of pointing toward a WOOL_OBJECT,
 * they refer via their "ptr" field to just ANY memory location able to hold
 * a long.
 * 
 * Thus setting a pointer to a value COPIES this value at the location pointed
 * to.
 * 
 * If a pointer is NULL, then it is an offset in the Context structure,
 * whose offset is taken in the pre-field (set field of active values)
 */

#include "EXTERN.h"
#include <stdio.h>
#include "wool.h"
#include "wl_atom.h"
#include "wl_list.h"
#include "wl_number.h"
#include "wl_string.h"
#include "wl_active.h"
#include "INTERN.h"
#include "wl_pointer.h"

/*
 * Constructor: WLPointer_make
 *     arg 1: The atom (or pointer) to be used 
 *     arg 2: The pointer to the location which will be updated by
 *            setting this pointer
 *     returns the pointer, which is our arg1 but modified in place
 * 
 * C programmers should rather use wool_pointer_make below.
 */

WOOL_Pointer
WLPointer_make(atom, ptr)
WOOL_Atom atom;			/* previously allocated atom */
long	  *ptr;			/* location pointed to */
{
    must_be_atom(atom, 0);
    if (atom -> type == WLAtom) {	/* free what was pointed */
	decrease_reference(atom -> c_val);
    }
    atom -> type = WLPointer;	/* just change type of object */
    ((WOOL_Pointer) atom) -> ptr = ptr;
    WLPointerBase(atom) = NULL;
    return (WOOL_Pointer) atom;
}

/*
 * wool_pointer_make:
 * High level function callable from C. Makes a pointer with a string and a
 * C pointer
 */

WOOL_Pointer
wool_pointer_make(name, ptr)
char *name;
char *ptr;
{
    return WLPointer_make(wool_atom(name), ptr);
}

/* wool_base_pointer_make:
 * High level function callable from C. Makes a pointer with a string, a base
 * and a C pointer
 */

WOOL_Pointer
wool_base_pointer_make(name, base, ptr)
char *name;
char **base, *ptr;
{
    WOOL_Pointer wl_ptr = WLPointer_make(wool_atom(name), ptr - *base);
    WOOL_Pointer_internal int_ptr =  WL_Pointer_internal(wl_ptr);

    int_ptr -> base = base;
    return wl_ptr;
}

/*
 * wool_self_pointer_make:
 * to make a pointer to a given value (stored in the Quark field)
 * 
 * the prefix is a control char prefixed to the name to act as a domain name
 * for names. Currently chars are used for:
 * 
 * 	^F	for X fonts id
 * 	^X	for X intern atoms
 * 	^M	for mallocated blocs (MLEAK tracing)
 *	^T	for tags
 */

WOOL_Pointer
wool_self_pointer_make(name, prefix, ppointer)
char *name;
char prefix;
WOOL_Pointer *ppointer;
{
    char	prefixed_name[MAX_TEMP_STRING_SIZE + 1];

    prefixed_name[0] = prefix;
    prefixed_name[1] = '\0';
    strcat(prefixed_name, name);
    *ppointer = (WOOL_Pointer) wool_atom(prefixed_name);
    if((*ppointer) -> type == WLAtom) {
	(*ppointer) -> ptr = (long *) (((char *) *ppointer) - 
		(sizeof(struct _WOOL_Active_internal)
		- sizeof(struct _WOOL_Active)));
	(*ppointer) -> type = WLPointer;
	*((*ppointer) -> ptr) = 0;
	return NULL;
    }
    return *ppointer;
}

/*
 * Evaluating a pointer yields the WOOL number containing the value pointed
 * to by the Pointer
 */

WOOL_OBJECT
WLPointer_eval(obj)
WOOL_Pointer obj;
{
    if (WLPointerBase(obj)) {
	WOOL_Pointer_internal int_ptr = WL_Pointer_internal(obj);

	return (WOOL_OBJECT) WLNumber_make(
			   *((long *)( *(int_ptr -> base) + int_ptr -> ptr)));
    } else
	return (WOOL_OBJECT) WLNumber_make(*(obj -> ptr));
}

/*
 * returns the raw value
 */

long
WLPointer_get_C_value(obj)
WOOL_Pointer obj;
{
    if (WLPointerBase(obj)) {
	WOOL_Pointer_internal int_ptr = WL_Pointer_internal(obj);

	return *((long *) (*(int_ptr -> base) + int_ptr -> ptr));
    } else
	return *(obj -> ptr);
}

/*
 * WLPointer_execute:
 * like active-values: without args gets, with 1 arg, sets
 */

WOOL_OBJECT 
WLPointer_execute(obj, list)
WOOL_Pointer     obj;
WOOL_List 	 list;
{
    if (list -> size == 1) {
	return (WOOL_OBJECT) WLPointer_eval(obj);
    } else if (list -> size == 2) {
	return (WOOL_OBJECT) WLPointer_set(obj, list -> list[1]);
    } else {
	return wool_error(BAD_NUMBER_OF_ARGS, list -> size - 1);
    }
}

/*
 * used to set value pointed to
 */

WOOL_OBJECT
WLPointer_set(obj, value)
WOOL_Pointer obj;
WOOL_OBJECT value;
{
    WOOL_OBJECT evaluated_value = WOOL_send(
						 WOOL_eval, value, (value));
    long            C_value = (long) WOOL_send(
		      WOOL_get_C_value, evaluated_value, (evaluated_value));
    WOOL_OBJECT     result = (WOOL_OBJECT) WLNumber_make(C_value);

    if (WLPointerBase(obj)) {
	WOOL_Pointer_internal int_ptr = WL_Pointer_internal(obj);

	*((long *) (*(int_ptr -> base) + int_ptr -> ptr)) = C_value;
    } else
	*(obj -> ptr) = C_value;
    return result;
}

WOOL_OBJECT
WLPointer_setq(obj, value)
WOOL_Pointer obj;
WOOL_OBJECT value;
{
    WOOL_OBJECT     result = (WOOL_OBJECT) WLNumber_make(value);
    long            C_value = (long) WOOL_send(
		      WOOL_get_C_value, value, (value));

    if (WLPointerBase(obj)) {
        WOOL_Pointer_internal int_ptr = WL_Pointer_internal(obj);

        *((long *) (*(int_ptr -> base) + int_ptr -> ptr)) = C_value;
    } else
        *(obj -> ptr) = C_value;
    return result;
}