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** chkichar.c 82** 83** FACILITY: 84** 85** Interface Definition Language (IDL) Compiler 86** 87** ABSTRACT: 88** 89** IDL Compiler Semantic Checking for international character support. 90** 91*/ 92 93#include <nidl.h> /* Standard IDL defs */ 94#include <checker.h> /* Type and constant macros */ 95#include <chkichar.h> /* Protos for I-char checking */ 96 97#include <acf_y.h> /* ACF token values */ 98#include <ast.h> /* Abstract Syntax Tree defs */ 99#include <astp.h> /* AST processing defs */ 100#include <command.h> /* Command option defs */ 101#include <errors.h> /* Error reporting functions */ 102#include <message.h> /* reporting functions */ 103 104/* 105** C H K _ p a r a m _ c s 106** 107** Checks a parameter node's I-char ([cs_*]) attributes. 108** The passed type node is the dereferenced parameter type if the 109** parameter is passed by reference. 110*/ 111void CHK_param_cs 112( 113 AST_parameter_n_t *param_p, /* [in] Ptr to AST parameter node */ 114 AST_type_n_t *type_p /* [in] Parameter type */ 115) 116{ 117 AST_parameter_n_t *pp; 118 AST_field_attr_n_t *fattr_p; 119 120 fattr_p = param_p->field_attrs; 121 122 /* Operation with [in] [cs_char] data requires [cs_stag] parameter */ 123 if (AST_IN_SET(param_p) 124 && (type_p->cs_char_type != NULL 125 || FE_TEST(type_p->fe_info->flags, FE_CT_CS_CHAR))) 126 { 127 for (pp = param_p->uplink->parameters; pp != NULL; pp = pp->next) 128 { 129 if (AST_CS_STAG_SET(pp)) 130 break; 131 } 132 if (pp == NULL) 133 CHECKER_acf_error(param_p, NIDL_OPINCSCHAR); 134 } 135 136 /* Operation with [out] [cs_char] data requires [cs_rtag] parameter */ 137 if (AST_OUT_SET(param_p) 138 && (type_p->cs_char_type != NULL 139 || FE_TEST(type_p->fe_info->flags, FE_CT_CS_CHAR))) 140 { 141 for (pp = param_p->uplink->parameters; pp != NULL; pp = pp->next) 142 { 143 if (AST_CS_RTAG_SET(pp)) 144 break; 145 } 146 if (pp == NULL) 147 CHECKER_acf_error(param_p, NIDL_OPOUTCSCHAR); 148 } 149 150 /* A [cs_stag] parameter must have the [in] attribute */ 151 if (AST_CS_STAG_SET(param_p) && !AST_IN_SET(param_p)) 152 { 153 ASTP_attr_flag_t attr2 = ASTP_IN; 154 CHECKER_error(param_p, NIDL_PRMDEPATTR, "cs_stag", 155 KEYWORDS_lookup_text(AST_attribute_to_token(&attr2))); 156 } 157 158 /* A [cs_drtag] parameter must have the [in] attribute */ 159 if (AST_CS_DRTAG_SET(param_p) && !AST_IN_SET(param_p)) 160 { 161 ASTP_attr_flag_t attr2 = ASTP_IN; 162 CHECKER_error(param_p, NIDL_PRMDEPATTR, "cs_drtag", 163 KEYWORDS_lookup_text(AST_attribute_to_token(&attr2))); 164 } 165 166 /* A [cs_rtag] parameter must have the [out] attribute */ 167 if (AST_CS_RTAG_SET(param_p) && !AST_OUT_SET(param_p)) 168 { 169 ASTP_attr_flag_t attr2 = ASTP_OUT; 170 CHECKER_error(param_p, NIDL_PRMDEPATTR, "cs_rtag", 171 KEYWORDS_lookup_text(AST_attribute_to_token(&attr2))); 172 } 173 174 /* Array attr can't be used for both [cs_char] and non-[cs_char] arrays */ 175 if (FE_TEST(param_p->fe_info->flags, FE_USED_AS_CS_FLD_ATTR) 176 && FE_TEST(param_p->fe_info->flags, FE_USED_AS_REG_FLD_ATTR)) 177 CHECKER_error(param_p, NIDL_ARRATTRSHR); 178 179 /* A [size_is] or [max_is] attr can't be applied to ptr to [cs_char] type */ 180 if (type_p->kind == AST_pointer_k 181 && type_p->type_structure.pointer->pointee_type->cs_char_type != NULL 182 && fattr_p != NULL 183 && (fattr_p->max_is_vec != NULL || fattr_p->size_is_vec != NULL)) 184 CHECKER_error(param_p, NIDL_CSARRSYN); 185 186 /* An array with [cs_char] base type cannot have [ptr] or [unique] attrs */ 187 if (type_p->kind == AST_array_k 188 && type_p->type_structure.array->element_type->cs_char_type != NULL 189 && (AST_PTR_SET(param_p) || AST_UNIQUE_SET(param_p))) 190 CHECKER_error(param_p, NIDL_ARRPTRUNIQ, "cs_char"); 191 192 /* A [cs_stag] param must precede any [in] [cs_char] data in a param list */ 193 if (AST_CS_STAG_SET(param_p)) 194 { 195 for (pp = param_p->uplink->parameters; pp != param_p; pp = pp->next) 196 { 197 if (AST_IN_SET(pp) 198 && (pp->type->cs_char_type != NULL 199 || FE_TEST(pp->type->fe_info->flags, FE_CT_CS_CHAR))) 200 break; 201 } 202 if (pp != param_p) 203 CHECKER_error(param_p, NIDL_TAGBEFDATA); 204 } 205 206 /* A [cs_rtag] param must precede any [out][cs_char] data in a param list */ 207 if (AST_CS_RTAG_SET(param_p)) 208 { 209 for (pp = param_p->uplink->parameters; pp != param_p; pp = pp->next) 210 { 211 if (AST_OUT_SET(pp) 212 && (pp->type->cs_char_type != NULL 213 || FE_TEST(pp->type->fe_info->flags, FE_CT_CS_CHAR))) 214 break; 215 } 216 if (pp != param_p) 217 CHECKER_error(param_p, NIDL_TAGAFTDATA); 218 } 219 220 /* A [handle] binding parameter cannot contain a [cs_char] type */ 221 if (AST_HANDLE_SET(type_p) 222 && param_p == param_p->uplink->parameters /* first param */ 223 && (type_p->cs_char_type != NULL 224 || FE_TEST(type_p->fe_info->flags, FE_CT_CS_CHAR))) 225 CHECKER_error(param_p, NIDL_HANCTYPE, "cs_char"); 226 227 /* Arrays of [cs_char] can only use the [size_is] and [length_is] attrs */ 228 if (type_p->kind == AST_array_k 229 && type_p->type_structure.array->element_type->cs_char_type != NULL 230 && (AST_STRING_SET(type_p) || AST_STRING_SET(param_p) 231 || (fattr_p != NULL 232 && (fattr_p->min_is_vec != NULL 233 || fattr_p->max_is_vec != NULL 234 || fattr_p->first_is_vec != NULL 235 || fattr_p->last_is_vec != NULL)))) 236 CHECKER_error(param_p, NIDL_ARRTYPATTR, "cs_char"); 237 238 /* Tag params must have type unsigned long int passed by value or ref */ 239 if ( (AST_CS_STAG_SET(param_p) 240 || AST_CS_DRTAG_SET(param_p) 241 || AST_CS_RTAG_SET(param_p)) 242 && type_p->kind != AST_long_unsigned_k ) 243 CHECKER_error(param_p, NIDL_TAGPRMTYPE); 244 245 /* Use of [cs_stag] attribute requires -standard extended */ 246 if (AST_CS_STAG_SET(param_p) 247 && (*(int *)CMD_vals[opt_standard] < opt_standard_dce_1_1)) 248 CHECKER_acf_warning(param_p, NIDL_NOPORTATTR, "cs_stag", 249 OPT_STD_EXTENDED); 250 251 /* Use of [cs_drtag] attribute requires -standard extended */ 252 if (AST_CS_DRTAG_SET(param_p) 253 && (*(int *)CMD_vals[opt_standard] < opt_standard_dce_1_1)) 254 CHECKER_acf_warning(param_p, NIDL_NOPORTATTR, "cs_drtag", 255 OPT_STD_EXTENDED); 256 257 /* Use of [cs_rtag] attribute requires -standard extended */ 258 if (AST_CS_RTAG_SET(param_p) 259 && (*(int *)CMD_vals[opt_standard] < opt_standard_dce_1_1)) 260 CHECKER_acf_warning(param_p, NIDL_NOPORTATTR, "cs_rtag", 261 OPT_STD_EXTENDED); 262} 263 264/* 265** C H K _ o p _ c s 266** 267** Checks an operation node's [cs_tag_rtn] attribute and other attributes 268** relating to I-char support. 269*/ 270void CHK_op_cs 271( 272 AST_operation_n_t *op_p /* [in] Ptr to AST operation node */ 273) 274{ 275 AST_parameter_n_t *param_p; 276 int s=0, d=0, r=0; 277 278 /* Operation with [cs_tag_rtn] contains no codeset tag parameters */ 279 if (op_p->cs_tag_rtn_name != NAMETABLE_NIL_ID) 280 { 281 for (param_p = op_p->parameters; param_p; param_p = param_p->next) 282 { 283 if (AST_CS_STAG_SET(param_p) || AST_CS_DRTAG_SET(param_p) 284 || AST_CS_RTAG_SET(param_p)) 285 break; 286 } 287 if (param_p == NULL) 288 CHECKER_acf_warning(op_p, NIDL_OPNOTAGS); 289 } 290 291 /* The [name] attribute cannot be duplicated in the same parameter list */ 292 for (param_p = op_p->parameters; param_p; param_p = param_p->next) 293 { 294 if (AST_CS_STAG_SET(param_p)) s++; 295 if (AST_CS_DRTAG_SET(param_p)) d++; 296 if (AST_CS_RTAG_SET(param_p)) r++; 297 } 298 if (s > 1) 299 CHECKER_acf_error(op_p, NIDL_DUPPRMATTR, "cs_stag"); 300 if (d > 1) 301 CHECKER_acf_error(op_p, NIDL_DUPPRMATTR, "cs_drtag"); 302 if (r > 1) 303 CHECKER_acf_error(op_p, NIDL_DUPPRMATTR, "cs_rtag"); 304 305 /* Use of [cs_tag_rtn] attribute requires -standard extended */ 306 if (op_p->cs_tag_rtn_name != NAMETABLE_NIL_ID 307 && (*(int *)CMD_vals[opt_standard] < opt_standard_dce_1_1)) 308 CHECKER_acf_warning(op_p, NIDL_NOPORTATTR, "cs_tag_rtn", 309 OPT_STD_EXTENDED); 310} 311 312/* 313** C H K _ f i e l d _ c s 314** 315** Checks a structure field node's I-char ([cs_*]) attributes. 316*/ 317void CHK_field_cs 318( 319 AST_field_n_t *field_p /* [in] Ptr to AST field node */ 320) 321{ 322 AST_type_n_t *type_p; 323 AST_field_attr_n_t *fattr_p; 324 325 type_p = field_p->type; 326 fattr_p = field_p->field_attrs; 327 328 /* Array attr cannot be used for both [cs_char] and non-[cs_char] arrays */ 329 if (FE_TEST(field_p->fe_info->flags, FE_USED_AS_CS_FLD_ATTR) 330 && FE_TEST(field_p->fe_info->flags, FE_USED_AS_REG_FLD_ATTR)) 331 CHECKER_error(field_p, NIDL_ARRATTRSHR); 332 333 /* A [size_is] or [max_is] attr can't be applied to ptr to [cs_char] type */ 334 if (type_p->kind == AST_pointer_k 335 && type_p->type_structure.pointer->pointee_type->cs_char_type != NULL 336 && fattr_p != NULL 337 && (fattr_p->max_is_vec != NULL || fattr_p->size_is_vec != NULL)) 338 CHECKER_error(field_p, NIDL_CSARRSYN); 339 340 /* Arrays of [cs_char] can only use the [size_is] and [length_is] attrs */ 341 if (type_p->kind == AST_array_k 342 && type_p->type_structure.array->element_type->cs_char_type != NULL 343 && (AST_STRING_SET(type_p) || AST_STRING_SET(field_p) 344 || (fattr_p != NULL 345 && (fattr_p->min_is_vec != NULL 346 || fattr_p->max_is_vec != NULL 347 || fattr_p->first_is_vec != NULL 348 || fattr_p->last_is_vec != NULL)))) 349 CHECKER_error(field_p, NIDL_ARRTYPATTR, "cs_char"); 350} 351 352/* 353** C H K _ p i p e _ b a s e _ t y p e _ c s 354** 355** Checks a pipe node's base data type for [cs_char] attribute. 356*/ 357void CHK_pipe_base_type_cs 358( 359 AST_pipe_n_t *pipe_p, /* [in] Ptr to AST pipe node */ 360 AST_interface_n_t *int_p ATTRIBUTE_UNUSED /* [in] Ptr to interface node */ 361) 362{ 363 AST_type_n_t *type_p; /* Pipe base data type node */ 364 365 type_p = pipe_p->base_type; 366 367 /* The base type of a pipe cannot be or contain a [cs_char] type */ 368 if (type_p->cs_char_type != NULL 369 || FE_TEST(type_p->fe_info->flags, FE_CT_CS_CHAR)) 370 CHECKER_error(type_p, NIDL_PIPECTYPE, "cs_char"); 371} 372 373/* 374** C H K _ t y p e _ c s 375** 376** Checks a type node's [cs_char] attribute. 377*/ 378void CHK_type_cs 379( 380 AST_type_n_t *top_type_p, /* [in] Top-level presented type */ 381 AST_type_n_t *type_p, /* [in] Ptr to AST type node */ 382 AST_interface_n_t *int_p /* [in] Ptr to interface node */ 383) 384{ 385 char const *type_name; /* Type name */ 386 int type_len; /* Length of type name */ 387 int max_len; /* Maximum identifier length */ 388 389 /* Types with the [cs_char] attribute cannot be nested */ 390 if (type_p->cs_char_type != NULL 391 && FE_TEST(type_p->fe_info->flags, FE_CT_CS_CHAR)) 392 CHECKER_acf_error(type_p, NIDL_TYPENEST, "cs_char"); 393 394 /* A [transmit_as] transmitted type cannot contain a [cs_char] type */ 395 if (type_p->cs_char_type != NULL 396 && FE_TEST(type_p->fe_info->flags, FE_USED_IN_TRANSMITTED)) 397 CHECKER_error(type_p, NIDL_XMITCTYPE, "cs_char"); 398 399 /* Arrays of [cs_char] type cannot be multidimensional */ 400 if (type_p->kind == AST_array_k 401 && type_p->type_structure.array->element_type->cs_char_type != NULL 402 && type_p->type_structure.array->index_count > 1) 403 CHECKER_error(type_p, NIDL_ARRMULTID, "cs_char"); 404 405 /* Type with [cs_char] cannot be or contain type with [transmit_as] */ 406 if (top_type_p->cs_char_type != NULL 407 && (top_type_p->xmit_as_type != NULL 408 || FE_TEST(top_type_p->fe_info->flags, FE_HAS_XMIT_AS)) ) 409 { 410 ASTP_attr_flag_t attr2 = ASTP_TRANSMIT_AS; 411 CHECKER_error(top_type_p, NIDL_TYPECTYPE, "cs_char", 412 KEYWORDS_lookup_text(AST_attribute_to_token(&attr2))); 413 } 414 415 /* Type with [cs_char] cannot be or contain type with [transmit_as] */ 416 if (type_p->cs_char_type != NULL 417 && (type_p->rep_as_type != NULL 418 || FE_TEST(type_p->fe_info->flags, FE_HAS_REP_AS)) ) 419 CHECKER_error(type_p, NIDL_TYPECTYPE, "cs_char", "represent_as"); 420 421 if (type_p->cs_char_type != NULL 422 && type_p->kind != AST_byte_k 423 && !(type_p->kind == AST_structure_k 424 && CHK_struct_is_all_byte_fields(type_p->type_structure.structure))) 425 CHECKER_error(type_p, NIDL_TYPEOFBYTES, "cs_char"); 426 427 /* ACF 'include' statement advised for definition of type 'name' */ 428 if (int_p->includes == NULL 429 && type_p->cs_char_type != NULL 430 && ASTP_lookup_binding(null_parser_location, 431 type_p->cs_char_type->type_name, fe_type_n_k, FALSE) == NULL) 432 { 433 char const *id_name; 434 NAMETABLE_id_to_string(type_p->cs_char_type->type_name, &id_name); 435 CHECKER_acf_warning(type_p, NIDL_INCLTYPE, id_name); 436 } 437 438 /* Maximum identifier length for [cs_char] type is 'n' characters */ 439 if (type_p->cs_char_type != NULL 440 && type_p->name != NAMETABLE_NIL_ID) 441 { 442 NAMETABLE_id_to_string(type_p->name, &type_name); 443 type_len = strlen(type_name); 444 max_len = MAX_ID - strlen("_from_netcs"); 445 if (type_len > max_len) 446 CHECKER_error(type_p, NIDL_MAXIDTYPE, "cs_char", max_len); 447 } 448 449 /* Use of [cs_char] attribute requires -standard extended */ 450 if (type_p->cs_char_type != NULL 451 && (*(int *)CMD_vals[opt_standard] < opt_standard_dce_1_1)) 452 CHECKER_acf_warning(type_p, NIDL_NOPORTATTR, "cs_char", 453 OPT_STD_EXTENDED); 454} 455