Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / osf / uil / UilSarProc.c
1 /* 
2  *  @OSF_COPYRIGHT@
3  *  COPYRIGHT NOTICE
4  *  Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
5  *  ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
6  *  the full copyright text.
7 */ 
8 /* 
9  * HISTORY
10 */ 
11 #ifdef REV_INFO
12 #ifndef lint
13 static char rcsid[] = "$XConsortium: UilSarProc.c /main/12 1995/07/14 09:37:43 drk $"
14 #endif
15 #endif
16
17 /*
18 *  (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
19
20 /*
21 **++
22 **  FACILITY:
23 **
24 **      User Interface Language Compiler (UIL)
25 **
26 **  ABSTRACT:
27 **
28 **      This module contain the routines for processing procedures.
29 **
30 **--
31 **/
32
33
34 /*
35 **
36 **  INCLUDE FILES
37 **
38 **/
39
40 #include "UilDefI.h"
41
42
43 /*
44 **
45 **  DEFINE and MACRO DEFINITIONS
46 **
47 **/
48
49
50
51 /*
52 **
53 **  EXTERNAL VARIABLE DECLARATIONS
54 **
55 **/
56
57
58 /*
59 **
60 **  GLOBAL VARIABLE DECLARATIONS
61 **
62 **/
63
64
65 /*
66 **
67 **  OWN VARIABLE DECLARATIONS
68 **
69 **/
70
71 \f
72 /*
73 **++
74 **  FUNCTIONAL DESCRIPTION:
75 **
76 **      This function create the procedure definition entry symbol 
77 **      node a procedure declaration.
78 **
79 **  FORMAL PARAMETERS:
80 **
81 **      id_frame        ptr to token frame for the procedure name
82 **      param_frame     ptr to token frame or null frame holding the
83 **                      type of the argument
84 **      class_frame     ptr to frame whose b_flags holds private, etc. info
85 **
86 **  IMPLICIT INPUTS:
87 **
88 **      sym_az_current_section_entry    the "current" section list
89 **
90 **  IMPLICIT OUTPUTS:
91 **
92 **      none
93 **
94 **  FUNCTION VALUE:
95 **
96 **      void
97 **
98 **  SIDE EFFECTS:
99 **
100 **      errors may be issued for previously defined name
101 **
102 **--
103 **/
104
105 void
106 sar_create_procedure(XmConst yystype *id_frame, 
107                      XmConst yystype *param_frame, 
108                      XmConst yystype *class_frame, 
109                      XmConst yystype *semi_frame)
110 {
111     sym_name_entry_type     *name_entry;
112     sym_proc_def_entry_type *proc_def_entry;
113     sym_section_entry_type  *section_entry;
114     sym_obj_entry_type      *obj_entry;
115
116     /*
117     **  Call standard routine to check name entry for id_frame.
118     **  This routine handles font name, color names, etc used as ids
119     */
120
121     name_entry = (sym_name_entry_type *) sem_dcl_name( id_frame );
122
123     if (name_entry == NULL)
124         return;
125
126     /*
127     **  Allocate the procedure definition entry and fill it in
128     */
129
130     proc_def_entry = (sym_proc_def_entry_type *)
131         sem_allocate_node (sym_k_proc_def_entry, sym_k_proc_def_entry_size);
132
133     proc_def_entry->b_widget_type = uil_max_object + 1;
134     proc_def_entry->obj_header.az_name = (sym_name_entry_type *) name_entry;
135     name_entry->az_object = (sym_entry_type *) proc_def_entry;
136
137     /* 
138     **  Parameter frame has 4 cases:
139     **      1) no argument checking desired
140     **         syntax: PROCEDURE id
141     **      2) argument checking desired - no argument
142     **         syntax: PROCEDURE id( )
143     **      3) argument checking desired - single argument
144     **         syntax: PROCEDURE id( type )
145     **      4) argument checking desired - single typed widget argument
146     **         syntax: PROCEDURE id( CLASS_NAME )
147     **  These cases are distinguished as follows:
148     **      1) tag = null  type = 0
149     **      2) tag = null  type = sar_k_no_value
150     **      3) tag = token type = argument type
151     **      4) tag = object type = widget type
152     */
153
154     proc_def_entry->v_arg_checking = TRUE;
155
156     switch (param_frame->b_tag)
157     {
158     case sar_k_null_frame:
159         if (param_frame->b_type == sym_k_no_value )
160         {
161             proc_def_entry->b_arg_count = 0;
162             proc_def_entry->b_arg_type = sym_k_no_value;
163         }
164         else
165             proc_def_entry->v_arg_checking = FALSE;
166             
167         break;
168
169     case sar_k_token_frame:
170         proc_def_entry->b_arg_type = param_frame->b_type;
171         proc_def_entry->b_arg_count = 1;
172         break;
173
174     case sar_k_object_frame:
175         _assert((param_frame->b_type == sym_k_widget_entry),
176                 "object frame not widget entry");
177         
178         obj_entry = 
179           (sym_obj_entry_type *)param_frame->value.az_symbol_entry;
180
181         proc_def_entry->b_arg_type = sym_k_widget_ref_value;
182         proc_def_entry->b_arg_count = 1;
183         proc_def_entry->b_widget_type = obj_entry->header.b_type;
184         break;
185         
186     default:
187         _assert( FALSE, "param frame in error" );
188
189     }
190
191     /*
192     **  Process the class clause
193     */
194
195     switch (class_frame->b_flags)
196     {
197     case sym_m_exported:
198         sym_make_external_def( name_entry );
199
200     case sym_m_private:
201     case sym_m_imported:
202         break;
203
204     default:
205         _assert( FALSE, "class frame in error" );
206
207     }
208
209     proc_def_entry->obj_header.b_flags = class_frame->b_flags;
210
211     /*
212     ** save the source file info for this procedure entry
213     */
214     _sar_save_source_info (&proc_def_entry->header, id_frame, semi_frame );
215     sar_assoc_comment((sym_obj_entry_type *)proc_def_entry);       /* preserve comments */
216
217     /*
218     ** allocate a section entry to link the proc_def entry into the structure
219     */
220     section_entry = (sym_section_entry_type *) sem_allocate_node
221                         (sym_k_section_entry, sym_k_section_entry_size);
222
223     /*
224     ** Link this entry off of the current section list
225     */
226     section_entry->next = (sym_entry_type *) sym_az_current_section_entry->entries;
227     sym_az_current_section_entry->entries = (sym_entry_type *) section_entry;
228
229     section_entry->entries = (sym_entry_type *) proc_def_entry;
230
231 }
232 \f
233 /*
234 **++
235 **  FUNCTIONAL DESCRIPTION:
236 **
237 **      This function processes a reference to a procedure.
238 **
239 **  FORMAL PARAMETERS:
240 **
241 **      id_frame        ptr to token frame for the procedure name
242 **      value_frame     ptr to token frame or null frame holding the
243 **                      value of the argument to the procedure
244 **      context         value indicating how the procedure is being used
245 **
246 **  IMPLICIT INPUTS:
247 **
248 **      none
249 **
250 **  IMPLICIT OUTPUTS:
251 **
252 **      none
253 **
254 **  FUNCTION VALUE:
255 **
256 **      a procedure reference entry / NULL in case of an illegal reference
257 **
258 **  SIDE EFFECTS:
259 **
260 **      errors may be issued 
261 **
262 **--
263 **/
264
265 sym_proc_ref_entry_type
266 *sem_reference_procedure( yystype         *id_frame, 
267                           XmConst yystype *value_frame, 
268                           XmConst int     context )
269 {
270     sym_value_entry_type    *value_entry;
271     sym_proc_def_entry_type *proc_def_entry;
272     sym_proc_ref_entry_type *proc_ref_entry;
273
274     /*
275     **  Call standard routine to check name entry for id_frame.
276     **  This routine handles font name, color names, etc used as ids
277     */
278
279     proc_def_entry =
280         (sym_proc_def_entry_type *)
281             sem_ref_name( id_frame, sym_k_proc_def_entry );
282
283     switch (value_frame->b_tag)
284     {
285     case sar_k_null_frame:
286         value_entry = NULL;
287         break;
288
289     case sar_k_value_frame:
290         if ((value_frame->b_flags & sym_m_forward_ref) != 0)
291             value_entry = NULL;
292         else
293             value_entry = (sym_value_entry_type *) 
294                           value_frame->value.az_symbol_entry;
295         break;
296
297     case sar_k_object_frame:
298         value_entry =
299                 (sym_value_entry_type *) value_frame->value.az_symbol_entry;
300         break;
301
302     default:
303         _assert( FALSE, "actual arg in error" );
304     }
305
306     /*
307     **  Allocate the procedure reference entry and fill it in
308     */
309
310     proc_ref_entry = (sym_proc_ref_entry_type *)
311         sem_allocate_node (sym_k_proc_ref_entry, sym_k_proc_ref_entry_size);
312
313     if ((id_frame->b_flags & sym_m_forward_ref) != 0)
314         sym_make_value_forward_ref (id_frame, 
315         (char*)&(proc_ref_entry->az_proc_def), sym_k_patch_list_add);
316     else 
317         proc_ref_entry->az_proc_def = proc_def_entry;
318
319     if ((value_frame->b_flags & sym_m_forward_ref) != 0)
320         sym_make_value_forward_ref (value_frame, 
321         (char*)&(proc_ref_entry->az_arg_value), sym_k_patch_add);
322     else
323         proc_ref_entry->az_arg_value = value_entry;
324
325     /*
326     **  Apply context constraints
327     **
328     **  If this is a procedure being used as a user object,
329     **  it should not have any arguments.  The arguments to such
330     **  a procedure are always a parent widget id and an argument list.
331     **  This constraint is currently inforced by the grammar.
332     **
333     **  At this time the compiler permits all types of values for callback
334     **  arguments.  This may be limited shortly when we see if it is
335     **  reasonable to pass fonts, colors, reasons, etc.
336     */
337
338     return proc_ref_entry;
339
340 }
341
342 \f
343 /*
344 **++
345 **  FUNCTIONAL DESCRIPTION:
346 **
347 **      This function checks to see if a object is defined with the name
348 **      corresponding to the id given in the first parameter.
349 **
350 **  FORMAL PARAMETERS:
351 **
352 **      id_frame        ptr to a token frame on the parse stack holding the name
353 **      tag             the type of construct needed
354 **
355 **  IMPLICIT INPUTS:
356 **
357 **      none
358 **
359 **  IMPLICIT OUTPUTS:
360 **
361 **      none
362 **
363 **  FUNCTION VALUE:
364 **
365 **      ptr to a symbol entry for construct or NULL
366 **
367 **  SIDE EFFECTS:
368 **
369 **      error message if the name is undefined or for a different construct
370 **      forward_ref bit may be turned on in id_frame
371 **--
372 **/
373
374 sym_entry_type
375 *sem_ref_name(yystype     *id_frame, 
376               XmConst int tag)
377 {
378     sym_name_entry_type     *name_entry;
379     sym_entry_type          *symbol_entry;
380
381     _assert( id_frame->b_tag == sar_k_token_frame, "arg1 not id frame" );
382
383     /* 
384     ** The id frame may hold a name or the keyword for a font name, color
385     ** name, reason name etc.  If it is one of these special name, then
386     ** we must see if the symbol table holds a name for the special type.
387     */
388
389     if (id_frame->b_type != NAME)
390     {
391         name_entry = 
392             sym_find_name
393                 ( id_frame->value.az_keyword_entry->b_length,
394                   id_frame->value.az_keyword_entry->at_name );
395
396         if (name_entry == NULL)
397         {
398             diag_issue_diagnostic
399                 ( d_undefined,
400                   _sar_source_position( id_frame ),
401                   diag_tag_text( sym_k_proc_def_entry ),
402                   id_frame->value.az_keyword_entry->at_name );
403
404             return NULL;
405         }
406
407     }
408     else
409         name_entry =
410                 (sym_name_entry_type *) id_frame->value.az_symbol_entry;
411
412     /*
413     ** If the name entry already has no object linked from it, we are
414     ** referencing an undefined object.
415     */
416
417     symbol_entry = name_entry->az_object;
418
419     if (symbol_entry == NULL )
420         {
421         id_frame->b_flags |= sym_m_forward_ref;
422         return NULL;
423         }
424     /*
425     ** If the name entry has the wrong type of object, this is also
426     ** an error.
427     */
428
429     if (symbol_entry->header.b_tag != tag )
430     {
431         diag_issue_diagnostic
432             ( d_ctx_req,
433               _sar_source_position( id_frame ),
434               diag_tag_text( tag ),
435               diag_tag_text( symbol_entry->header.b_tag ) );
436
437         return NULL;
438     }
439
440     return symbol_entry;
441
442 }