1/*
2 * Copyright (c) 2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1.  Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 * 2.  Redistributions in binary form must reproduce the above copyright
13 *     notice, this list of conditions and the following disclaimer in the
14 *     documentation and/or other materials provided with the distribution.
15 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
16 *     contributors may be used to endorse or promote products derived from
17 *     this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Portions of this software have been released under the following terms:
31 *
32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
35 *
36 * To anyone who acknowledges that this file is provided "AS IS"
37 * without any express or implied warranty:
38 * permission to use, copy, modify, and distribute this file for any
39 * purpose is hereby granted without fee, provided that the above
40 * copyright notices and this notice appears in all source code copies,
41 * and that none of the names of Open Software Foundation, Inc., Hewlett-
42 * Packard Company or Digital Equipment Corporation be used
43 * in advertising or publicity pertaining to distribution of the software
44 * without specific, written prior permission.  Neither Open Software
45 * Foundation, Inc., Hewlett-Packard Company nor Digital
46 * Equipment Corporation makes any representations about the suitability
47 * of this software for any purpose.
48 *
49 * Copyright (c) 2007, Novell, Inc. All rights reserved.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 *
54 * 1.  Redistributions of source code must retain the above copyright
55 *     notice, this list of conditions and the following disclaimer.
56 * 2.  Redistributions in binary form must reproduce the above copyright
57 *     notice, this list of conditions and the following disclaimer in the
58 *     documentation and/or other materials provided with the distribution.
59 * 3.  Neither the name of Novell Inc. nor the names of its contributors
60 *     may be used to endorse or promote products derived from this
61 *     this software without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 *
74 * @APPLE_LICENSE_HEADER_END@
75 */
76
77/*
78**
79**  NAME:
80**
81**      user_exc.c
82**
83**  FACILITY:
84**
85**      Interface Definition Language (IDL) Compiler
86**
87**  ABSTRACT:
88**
89**      Code generation for user exceptions
90**
91**
92*/
93
94#include <ast.h>
95#include <be_pvt.h>
96#include <cspell.h>
97#include <user_exc.h>
98
99/******************************************************************************/
100/*                                                                            */
101/*  Declare user exceptions                                                   */
102/*                                                                            */
103/******************************************************************************/
104static void DDBE_list_exceptions
105(
106    FILE *fid,                      /* [in] Handle for emitted C text */
107    AST_interface_n_t *p_interface, /* [in] Pointer to AST interface node */
108    int *p_num_declared_exceptions, /* [out] Number of declared exceptions */
109    int *p_num_extern_exceptions    /* [out] Number of external exceptions */
110)
111{
112    AST_exception_n_t *p_exception;
113
114    *p_num_declared_exceptions = 0;
115    *p_num_extern_exceptions = 0;
116
117    for (p_exception = p_interface->exceptions;
118         p_exception != NULL;
119         p_exception = p_exception->next)
120    {
121        if (AST_EXTERN_SET(p_exception))
122        {
123            fprintf(fid, "extern ");
124            (*p_num_extern_exceptions)++;
125        }
126        else
127            (*p_num_declared_exceptions)++;
128        fprintf(fid, "EXCEPTION ");
129        spell_name(fid, p_exception->name);
130        fprintf(fid, ";\n");
131    }
132}
133
134/******************************************************************************/
135/*                                                                            */
136/*  Spell code to initialize declared exceptions                              */
137/*                                                                            */
138/******************************************************************************/
139static void DDBE_init_exceptions
140(
141    FILE *fid,                      /* [in] Handle for emitted C text */
142    AST_interface_n_t *p_interface  /* [in] Pointer to AST interface node */
143)
144{
145    AST_exception_n_t *p_exception;
146
147    fprintf(fid, "static void IDL_exceptions_init()\n{\n");
148    for (p_exception = p_interface->exceptions;
149         p_exception != NULL;
150         p_exception = p_exception->next)
151    {
152        if ( ! AST_EXTERN_SET(p_exception))
153        {
154            fprintf(fid, "EXCEPTION_INIT(");
155            spell_name(fid, p_exception->name);
156            fprintf(fid, ");\n");
157        }
158    }
159    fprintf(fid, "}\n");
160    fprintf( fid,
161"static RPC_SS_THREADS_ONCE_T IDL_exception_once = RPC_SS_THREADS_ONCE_INIT;\n"
162             );
163}
164
165/******************************************************************************/
166/*                                                                            */
167/*  Spell an array of pointers to the user exceptions                         */
168/*                                                                            */
169/******************************************************************************/
170static void DDBE_ref_exception_array
171(
172    FILE *fid,                      /* [in] Handle for emitted C text */
173    AST_interface_n_t *p_interface  /* [in] Pointer to AST interface node */
174)
175{
176    AST_exception_n_t *p_exception;
177    boolean first = true;
178
179    fprintf(fid, "static EXCEPTION *IDL_exception_addresses[] = {\n");
180    for (p_exception = p_interface->exceptions;
181         p_exception != NULL;
182         p_exception = p_exception->next)
183    {
184        if (first)
185            first = false;
186        else
187            fprintf(fid, ",\n");
188        fprintf(fid, "&");
189        spell_name(fid, p_exception->name);
190    }
191    fprintf(fid, "};\n");
192}
193
194/******************************************************************************/
195/*                                                                            */
196/*  Declare user exception machinery at start of stub                         */
197/*                                                                            */
198/******************************************************************************/
199void DDBE_user_exceptions
200(
201    FILE *fid,                      /* [in] Handle for emitted C text */
202    AST_interface_n_t *p_interface, /* [in] Pointer to AST interface node */
203    int *p_num_declared_exceptions, /* [out] Number of declared exceptions */
204    int *p_num_extern_exceptions    /* [out] Number of external exceptions */
205)
206{
207    DDBE_list_exceptions(fid, p_interface, p_num_declared_exceptions,
208                         p_num_extern_exceptions);
209    if (*p_num_declared_exceptions != 0)
210        DDBE_init_exceptions(fid, p_interface);
211    else if (*p_num_extern_exceptions == 0)
212    {
213        /* No exception machinery to set up */
214        return;
215    }
216    DDBE_ref_exception_array(fid, p_interface);
217}
218