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