1 %{ 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License, Version 1.0 only 7 * (the "License"). You may not use this file except in compliance 8 * with the License. 9 * 10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11 * or http://www.opensolaris.org/os/licensing. 12 * See the License for the specific language governing permissions 13 * and limitations under the License. 14 * 15 * When distributing Covered Code, include this CDDL HEADER in each 16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17 * If applicable, add the following below this CDDL HEADER, with the 18 * fields enclosed by brackets "[]" replaced with your own identifying 19 * information: Portions Copyright [yyyy] [name of copyright owner] 20 * 21 * CDDL HEADER END 22 * 23 * Copyright (c) 2001 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include "gnu_msgfmt.h" 29 #include "gnu_lex.h" 30 31 static int plural_index; 32 33 %} 34 35 %union { 36 char *str; 37 int num; 38 struct entry msg; 39 struct ch c; 40 } 41 42 %token <num> DOMAIN 43 %token <num> MSGID 44 %token <num> MSGID_PLURAL 45 %token <num> MSGSTR 46 %token <num> NUM 47 %token <str> STR 48 %token <str> COMMENT 49 %token <str> SYMBOL 50 %token <c> CHR 51 %type <msg> message_string plural_messages plural_message 52 %% 53 54 start : 55 | start po 56 ; 57 58 po : comment 59 | domain 60 | body 61 ; 62 63 domain : DOMAIN STR 64 { 65 handle_domain($2); 66 } 67 ; 68 69 comment : COMMENT 70 { 71 handle_comment($1); 72 } 73 74 body : MSGID message_string MSGSTR message_string 75 { 76 struct entry och1, och2; 77 78 och1.no = 1; 79 och1.num = $1; 80 och1.str = $2.str; 81 och1.len = $2.len; 82 och1.pos = NULL; 83 84 och2.no = 1; 85 och2.num = $3; 86 och2.str = $4.str; 87 och2.len = $4.len; 88 och2.pos = NULL; 89 90 handle_message(&och1, &och2); 91 clear_state(); 92 } 93 | MSGID message_string MSGID_PLURAL 94 message_string {plural_index = 0;} plural_messages 95 { 96 size_t len; 97 struct entry och1, och2; 98 struct loc *pos1; 99 char *id_str; 100 101 len = $2.len + $4.len; 102 id_str = (char *)Xmalloc(len); 103 (void) memcpy(id_str, $2.str, $2.len); 104 (void) memcpy(id_str + $2.len, $4.str, $4.len); 105 free($2.str); 106 free($4.str); 107 108 pos1 = (struct loc *)Xmalloc(2 * sizeof (struct loc)); 109 pos1[0].off = 0; 110 pos1[0].len = $2.len; 111 pos1[0].num = $1; 112 pos1[1].off = $2.len; 113 pos1[1].len = $4.len; 114 pos1[1].num = $3; 115 och1.no = 2; 116 och1.num = $1; 117 och1.str = id_str; 118 och1.len = len; 119 och1.pos = pos1; 120 121 och2 = $6; 122 handle_message(&och1, &och2); 123 clear_state(); 124 } 125 | MSGID message_string 126 { 127 error(gettext(ERR_NO_MSGSTR), $1, cur_po); 128 /* NOTREACHED */ 129 } 130 | MSGID message_string MSGID_PLURAL message_string 131 { 132 error(gettext(ERR_NO_MSGSTRS), $1, cur_po); 133 /* NOTRECHED */ 134 } 135 | MSGID message_string plural_messages 136 { 137 error(gettext(ERR_NO_MSGID_PLURAL), $1, cur_po); 138 /* NOTREACHED */ 139 } 140 ; 141 142 message_string : STR 143 { 144 $$.str = $1; 145 $$.len = strlen($1) + 1; 146 } 147 | message_string STR 148 { 149 size_t len, len1, len2; 150 char *str; 151 152 /* $1.len includes null-termination */ 153 len1 = $1.len - 1; 154 len2 = strlen($2); 155 156 /* len doesn't include null-termination */ 157 len = len1 + len2; 158 159 str = (char *)Xmalloc(len + 1); 160 (void) memcpy(str, $1.str, len1); 161 (void) memcpy(str + len1, $2, len2 + 1); 162 free($1.str); 163 free($2); 164 $$.str = str; 165 $$.len = len + 1; 166 } 167 ; 168 169 plural_messages : plural_message 170 { 171 $$ = $1; 172 } 173 | plural_messages plural_message 174 { 175 struct loc *tmp; 176 size_t len; 177 char *plural_str; 178 int no; 179 180 no = $1.no + 1; 181 tmp = (struct loc *)Xrealloc($1.pos, 182 no * sizeof (struct loc)); 183 tmp[no - 1].off = $1.len; 184 tmp[no - 1].len = $2.len; 185 tmp[no - 1].num = $2.num; 186 free($2.pos); 187 188 len = $1.len + $2.len; 189 plural_str = (char *)Xmalloc(len); 190 (void) memcpy(plural_str, $1.str, $1.len); 191 (void) memcpy(plural_str + $1.len, $2.str, $2.len); 192 193 $$.no = no; 194 $$.num = $1.num; 195 $$.str = plural_str; 196 $$.len = len; 197 $$.pos = tmp; 198 free($1.str); 199 free($2.str); 200 } 201 ; 202 203 plural_message : MSGSTR '[' NUM ']' message_string 204 { 205 struct loc *pos; 206 if ($3 != plural_index) { 207 error(gettext(ERR_INVALID_PLURALS), $1, cur_po); 208 /* NOTREACHED */ 209 } 210 plural_index++; 211 pos = (struct loc *)Xmalloc(sizeof (struct loc)); 212 pos->off = 0; 213 pos->len = $5.len; 214 pos->num = $1; 215 $$.no = 1; 216 $$.num = $1; 217 $$.str = $5.str; 218 $$.len = $5.len; 219 $$.pos = pos; 220 } 221 ; 222 %% 223 void 224 yyerror(const char *err) 225 { 226 (void) fprintf(stderr, 227 gettext(ERR_LOCATION), cur_line, cur_po); 228 (void) fprintf(stderr, "%s\n", err); 229 230 exit(1); 231 } 232