1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include "gnu_msgfmt.h" 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #define OPT_L 0x01 32*7c478bd9Sstevel@tonic-gate #define OPT_l 0x02 33*7c478bd9Sstevel@tonic-gate #define OPT_ll 0x04 34*7c478bd9Sstevel@tonic-gate #define OPT_w 0x08 35*7c478bd9Sstevel@tonic-gate #define OPT_h 0x10 36*7c478bd9Sstevel@tonic-gate #define OPT_hh 0x20 37*7c478bd9Sstevel@tonic-gate #define OPT_j 0x40 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate static int 40*7c478bd9Sstevel@tonic-gate extract_format(char *norm, const char *sfmt, size_t sz) 41*7c478bd9Sstevel@tonic-gate { 42*7c478bd9Sstevel@tonic-gate const unsigned char *fmt = (const unsigned char *)sfmt; 43*7c478bd9Sstevel@tonic-gate unsigned char c; 44*7c478bd9Sstevel@tonic-gate int t, arg, ap; 45*7c478bd9Sstevel@tonic-gate int dotseen; 46*7c478bd9Sstevel@tonic-gate char flag, conv; 47*7c478bd9Sstevel@tonic-gate int lastarg = -1; 48*7c478bd9Sstevel@tonic-gate int prevarg; 49*7c478bd9Sstevel@tonic-gate int max = 0; 50*7c478bd9Sstevel@tonic-gate int lflag; 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate for (; *fmt; fmt++) { 53*7c478bd9Sstevel@tonic-gate if (*fmt == '%') { 54*7c478bd9Sstevel@tonic-gate if (*++fmt == '%') 55*7c478bd9Sstevel@tonic-gate continue; 56*7c478bd9Sstevel@tonic-gate if (!*fmt) 57*7c478bd9Sstevel@tonic-gate break; 58*7c478bd9Sstevel@tonic-gate prevarg = lastarg; 59*7c478bd9Sstevel@tonic-gate arg = ++lastarg; 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate t = 0; 62*7c478bd9Sstevel@tonic-gate while (*fmt && isdigit(*fmt)) 63*7c478bd9Sstevel@tonic-gate t = t * 10 + *fmt++ - '0'; 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate if (*fmt == '$') { 66*7c478bd9Sstevel@tonic-gate lastarg = arg = t - 1; 67*7c478bd9Sstevel@tonic-gate fmt++; 68*7c478bd9Sstevel@tonic-gate } 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate if (!*fmt) 71*7c478bd9Sstevel@tonic-gate goto end; 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate dotseen = 0; 74*7c478bd9Sstevel@tonic-gate flag = 0; 75*7c478bd9Sstevel@tonic-gate lflag = 0; 76*7c478bd9Sstevel@tonic-gate again: 77*7c478bd9Sstevel@tonic-gate /* Skip flags */ 78*7c478bd9Sstevel@tonic-gate while ((c = *fmt) != '\0') { 79*7c478bd9Sstevel@tonic-gate if (c == '\'' || c == '+' || c == '-' || 80*7c478bd9Sstevel@tonic-gate c == ' ' || c == '#' || c == '0') { 81*7c478bd9Sstevel@tonic-gate fmt++; 82*7c478bd9Sstevel@tonic-gate continue; 83*7c478bd9Sstevel@tonic-gate } 84*7c478bd9Sstevel@tonic-gate break; 85*7c478bd9Sstevel@tonic-gate } 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate while (*fmt && isdigit(*fmt)) 88*7c478bd9Sstevel@tonic-gate fmt++; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate if (*fmt == '*') { 91*7c478bd9Sstevel@tonic-gate if (isdigit(*(fmt + 1))) { 92*7c478bd9Sstevel@tonic-gate fmt++; 93*7c478bd9Sstevel@tonic-gate t = 0; 94*7c478bd9Sstevel@tonic-gate while (*fmt && isdigit(*fmt)) 95*7c478bd9Sstevel@tonic-gate t = t * 10 + *fmt++ - '0'; 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate if (*fmt == '$') { 98*7c478bd9Sstevel@tonic-gate /* 99*7c478bd9Sstevel@tonic-gate * %*4$ 100*7c478bd9Sstevel@tonic-gate */ 101*7c478bd9Sstevel@tonic-gate ap = t - 1; 102*7c478bd9Sstevel@tonic-gate if ((ap * 2 + 1 >= sz) || 103*7c478bd9Sstevel@tonic-gate (norm[ap * 2] && 104*7c478bd9Sstevel@tonic-gate norm[ap * 2] != '*')) { 105*7c478bd9Sstevel@tonic-gate /* error in format */ 106*7c478bd9Sstevel@tonic-gate return (-1); 107*7c478bd9Sstevel@tonic-gate } else { 108*7c478bd9Sstevel@tonic-gate if (ap >= max) 109*7c478bd9Sstevel@tonic-gate max = ap + 1; 110*7c478bd9Sstevel@tonic-gate norm[ap * 2] = '*'; 111*7c478bd9Sstevel@tonic-gate } 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate /* 114*7c478bd9Sstevel@tonic-gate * If digits follow a '*', it is 115*7c478bd9Sstevel@tonic-gate * not loaded as an argument, the 116*7c478bd9Sstevel@tonic-gate * digits are used instead. 117*7c478bd9Sstevel@tonic-gate */ 118*7c478bd9Sstevel@tonic-gate } else { 119*7c478bd9Sstevel@tonic-gate /* 120*7c478bd9Sstevel@tonic-gate * %* 121*7c478bd9Sstevel@tonic-gate */ 122*7c478bd9Sstevel@tonic-gate if (*(fmt + 1) == '$') { 123*7c478bd9Sstevel@tonic-gate fmt++; 124*7c478bd9Sstevel@tonic-gate } else { 125*7c478bd9Sstevel@tonic-gate ap = arg; 126*7c478bd9Sstevel@tonic-gate prevarg = arg; 127*7c478bd9Sstevel@tonic-gate lastarg = ++arg; 128*7c478bd9Sstevel@tonic-gate if ((ap * 2 + 1 >= sz) || 129*7c478bd9Sstevel@tonic-gate (norm[ap * 2] && 130*7c478bd9Sstevel@tonic-gate norm[ap * 2] != '*')) { 131*7c478bd9Sstevel@tonic-gate /* error in format */ 132*7c478bd9Sstevel@tonic-gate return (-1); 133*7c478bd9Sstevel@tonic-gate } else { 134*7c478bd9Sstevel@tonic-gate if (ap >= max) 135*7c478bd9Sstevel@tonic-gate max = ap + 1; 136*7c478bd9Sstevel@tonic-gate norm[ap * 2] = '*'; 137*7c478bd9Sstevel@tonic-gate } 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate } 140*7c478bd9Sstevel@tonic-gate fmt++; 141*7c478bd9Sstevel@tonic-gate } 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate if ((*fmt == '.') || (*fmt == '*')) { 144*7c478bd9Sstevel@tonic-gate if (dotseen) 145*7c478bd9Sstevel@tonic-gate return (-1); 146*7c478bd9Sstevel@tonic-gate dotseen = 1; 147*7c478bd9Sstevel@tonic-gate fmt++; 148*7c478bd9Sstevel@tonic-gate goto again; 149*7c478bd9Sstevel@tonic-gate } 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate if (!*fmt) 152*7c478bd9Sstevel@tonic-gate goto end; 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate while (*fmt) { 155*7c478bd9Sstevel@tonic-gate switch (*fmt) { 156*7c478bd9Sstevel@tonic-gate case 'l': 157*7c478bd9Sstevel@tonic-gate if (!(flag & OPT_ll)) { 158*7c478bd9Sstevel@tonic-gate if (lflag) { 159*7c478bd9Sstevel@tonic-gate flag &= ~OPT_l; 160*7c478bd9Sstevel@tonic-gate flag |= OPT_ll; 161*7c478bd9Sstevel@tonic-gate } else { 162*7c478bd9Sstevel@tonic-gate flag |= OPT_l; 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate lflag++; 166*7c478bd9Sstevel@tonic-gate break; 167*7c478bd9Sstevel@tonic-gate case 'L': 168*7c478bd9Sstevel@tonic-gate flag |= OPT_L; 169*7c478bd9Sstevel@tonic-gate break; 170*7c478bd9Sstevel@tonic-gate case 'w': 171*7c478bd9Sstevel@tonic-gate flag |= OPT_w; 172*7c478bd9Sstevel@tonic-gate break; 173*7c478bd9Sstevel@tonic-gate case 'h': 174*7c478bd9Sstevel@tonic-gate if (flag & (OPT_h|OPT_hh)) 175*7c478bd9Sstevel@tonic-gate flag |= OPT_hh; 176*7c478bd9Sstevel@tonic-gate else 177*7c478bd9Sstevel@tonic-gate flag |= OPT_h; 178*7c478bd9Sstevel@tonic-gate break; 179*7c478bd9Sstevel@tonic-gate case 'j': 180*7c478bd9Sstevel@tonic-gate flag |= OPT_j; 181*7c478bd9Sstevel@tonic-gate break; 182*7c478bd9Sstevel@tonic-gate case 'z': 183*7c478bd9Sstevel@tonic-gate case 't': 184*7c478bd9Sstevel@tonic-gate if (!(flag & OPT_ll)) { 185*7c478bd9Sstevel@tonic-gate flag |= OPT_l; 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate break; 188*7c478bd9Sstevel@tonic-gate case '\'': 189*7c478bd9Sstevel@tonic-gate case '+': 190*7c478bd9Sstevel@tonic-gate case '-': 191*7c478bd9Sstevel@tonic-gate case ' ': 192*7c478bd9Sstevel@tonic-gate case '#': 193*7c478bd9Sstevel@tonic-gate case '.': 194*7c478bd9Sstevel@tonic-gate case '*': 195*7c478bd9Sstevel@tonic-gate goto again; 196*7c478bd9Sstevel@tonic-gate default: 197*7c478bd9Sstevel@tonic-gate if (isdigit(*fmt)) 198*7c478bd9Sstevel@tonic-gate goto again; 199*7c478bd9Sstevel@tonic-gate else 200*7c478bd9Sstevel@tonic-gate goto done; 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate fmt++; 203*7c478bd9Sstevel@tonic-gate } 204*7c478bd9Sstevel@tonic-gate done: 205*7c478bd9Sstevel@tonic-gate if (!*fmt) 206*7c478bd9Sstevel@tonic-gate goto end; 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate if ((c = *fmt) == 'C') { 209*7c478bd9Sstevel@tonic-gate flag |= OPT_l; 210*7c478bd9Sstevel@tonic-gate conv = 'c'; 211*7c478bd9Sstevel@tonic-gate } else if (c == 'd') { 212*7c478bd9Sstevel@tonic-gate conv = 'd'; 213*7c478bd9Sstevel@tonic-gate } else if (c == 'S') { 214*7c478bd9Sstevel@tonic-gate flag |= OPT_l; 215*7c478bd9Sstevel@tonic-gate conv = 's'; 216*7c478bd9Sstevel@tonic-gate } else if (c == 's') { 217*7c478bd9Sstevel@tonic-gate conv = 's'; 218*7c478bd9Sstevel@tonic-gate } else if (c == 'i') { 219*7c478bd9Sstevel@tonic-gate conv = 'i'; 220*7c478bd9Sstevel@tonic-gate } else if (c == 'o') { 221*7c478bd9Sstevel@tonic-gate conv = 'o'; 222*7c478bd9Sstevel@tonic-gate } else if (c == 'u') { 223*7c478bd9Sstevel@tonic-gate conv = 'u'; 224*7c478bd9Sstevel@tonic-gate } else if (c == 'c') { 225*7c478bd9Sstevel@tonic-gate conv = 'c'; 226*7c478bd9Sstevel@tonic-gate } else if (c == 'x') { 227*7c478bd9Sstevel@tonic-gate conv = 'x'; 228*7c478bd9Sstevel@tonic-gate } else if (c == 'X') { 229*7c478bd9Sstevel@tonic-gate conv = 'X'; 230*7c478bd9Sstevel@tonic-gate } else if (c == 'e') { 231*7c478bd9Sstevel@tonic-gate conv = 'e'; 232*7c478bd9Sstevel@tonic-gate } else if (c == 'E') { 233*7c478bd9Sstevel@tonic-gate conv = 'E'; 234*7c478bd9Sstevel@tonic-gate } else if (c == 'f') { 235*7c478bd9Sstevel@tonic-gate conv = 'f'; 236*7c478bd9Sstevel@tonic-gate } else if (c == 'F') { 237*7c478bd9Sstevel@tonic-gate conv = 'F'; 238*7c478bd9Sstevel@tonic-gate } else if (c == 'a') { 239*7c478bd9Sstevel@tonic-gate conv = 'a'; 240*7c478bd9Sstevel@tonic-gate } else if (c == 'A') { 241*7c478bd9Sstevel@tonic-gate conv = 'A'; 242*7c478bd9Sstevel@tonic-gate } else if (c == 'g') { 243*7c478bd9Sstevel@tonic-gate conv = 'g'; 244*7c478bd9Sstevel@tonic-gate } else if (c == 'G') { 245*7c478bd9Sstevel@tonic-gate conv = 'G'; 246*7c478bd9Sstevel@tonic-gate } else if (c == 'p') { 247*7c478bd9Sstevel@tonic-gate conv = 'p'; 248*7c478bd9Sstevel@tonic-gate } else if (c == 'n') { 249*7c478bd9Sstevel@tonic-gate conv = 'n'; 250*7c478bd9Sstevel@tonic-gate } else { 251*7c478bd9Sstevel@tonic-gate lastarg = prevarg; 252*7c478bd9Sstevel@tonic-gate continue; 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate if ((arg * 2 + 1 >= sz) || 256*7c478bd9Sstevel@tonic-gate (norm[arg * 2] && 257*7c478bd9Sstevel@tonic-gate (norm[arg * 2] != conv))) { 258*7c478bd9Sstevel@tonic-gate return (-1); 259*7c478bd9Sstevel@tonic-gate } else { 260*7c478bd9Sstevel@tonic-gate if (arg >= max) 261*7c478bd9Sstevel@tonic-gate max = arg + 1; 262*7c478bd9Sstevel@tonic-gate norm[arg * 2] = conv; 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate norm[arg * 2 + 1] = flag; 265*7c478bd9Sstevel@tonic-gate } 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate end: 269*7c478bd9Sstevel@tonic-gate for (arg = 0; arg < max; arg++) { 270*7c478bd9Sstevel@tonic-gate if (norm[arg * 2] == '\0') 271*7c478bd9Sstevel@tonic-gate return (-1); 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate return (max); 275*7c478bd9Sstevel@tonic-gate } 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate void 279*7c478bd9Sstevel@tonic-gate check_format(struct entry *id, struct entry *str, int is_c_format) 280*7c478bd9Sstevel@tonic-gate { 281*7c478bd9Sstevel@tonic-gate int i, n; 282*7c478bd9Sstevel@tonic-gate int id_b_newline, id_e_newline; 283*7c478bd9Sstevel@tonic-gate int plural_b_newline, plural_e_newline; 284*7c478bd9Sstevel@tonic-gate int str_b_newline, str_e_newline; 285*7c478bd9Sstevel@tonic-gate int id_fmt, plural_fmt, str_fmt; 286*7c478bd9Sstevel@tonic-gate int *pstr_fmt; 287*7c478bd9Sstevel@tonic-gate char *msgid, *plural, *msgstr; 288*7c478bd9Sstevel@tonic-gate char *id_norm, *plural_norm, *str_norm; 289*7c478bd9Sstevel@tonic-gate char **pstr_norm; 290*7c478bd9Sstevel@tonic-gate size_t id_len, id_num; 291*7c478bd9Sstevel@tonic-gate size_t plural_off, plural_len, plural_num; 292*7c478bd9Sstevel@tonic-gate size_t str_len, str_num; 293*7c478bd9Sstevel@tonic-gate size_t osz, nsz; 294*7c478bd9Sstevel@tonic-gate struct loc *p; 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate if (id->len == 1) { 297*7c478bd9Sstevel@tonic-gate /* 298*7c478bd9Sstevel@tonic-gate * null string: header entry 299*7c478bd9Sstevel@tonic-gate * no check is performed 300*7c478bd9Sstevel@tonic-gate */ 301*7c478bd9Sstevel@tonic-gate return; 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate msgid = id->str; 305*7c478bd9Sstevel@tonic-gate id_num = id->num; 306*7c478bd9Sstevel@tonic-gate msgstr = str->str; 307*7c478bd9Sstevel@tonic-gate if (id->no > 1) { 308*7c478bd9Sstevel@tonic-gate /* plural */ 309*7c478bd9Sstevel@tonic-gate id_len = id->pos[0].len; 310*7c478bd9Sstevel@tonic-gate plural_off = id->pos[1].off; 311*7c478bd9Sstevel@tonic-gate plural_len = id->pos[1].len; 312*7c478bd9Sstevel@tonic-gate plural_num = id->pos[1].num; 313*7c478bd9Sstevel@tonic-gate plural = msgid + plural_off; 314*7c478bd9Sstevel@tonic-gate } else { 315*7c478bd9Sstevel@tonic-gate /* no plural form */ 316*7c478bd9Sstevel@tonic-gate id_len = id->len; 317*7c478bd9Sstevel@tonic-gate str_len = str->len; 318*7c478bd9Sstevel@tonic-gate str_num = str->num; 319*7c478bd9Sstevel@tonic-gate plural = NULL; 320*7c478bd9Sstevel@tonic-gate } 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate /* 323*7c478bd9Sstevel@tonic-gate * First checking the newline 324*7c478bd9Sstevel@tonic-gate */ 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate if (!plural) { 327*7c478bd9Sstevel@tonic-gate /* no plural form */ 328*7c478bd9Sstevel@tonic-gate id_b_newline = (msgid[0] == '\n'); 329*7c478bd9Sstevel@tonic-gate id_e_newline = (msgid[id_len - 1 - 1] == '\n'); 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate str_b_newline = (msgstr[0] == '\n'); 332*7c478bd9Sstevel@tonic-gate str_e_newline = (msgstr[str_len - 1 - 1] == '\n'); 333*7c478bd9Sstevel@tonic-gate if (id_b_newline && !str_b_newline) { 334*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_BEGIN_NEWLINE_1), 335*7c478bd9Sstevel@tonic-gate id_num, str_num, cur_po); 336*7c478bd9Sstevel@tonic-gate po_error++; 337*7c478bd9Sstevel@tonic-gate } else if (!id_b_newline && str_b_newline) { 338*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_BEGIN_NEWLINE_2), 339*7c478bd9Sstevel@tonic-gate id_num, str_num, cur_po); 340*7c478bd9Sstevel@tonic-gate po_error++; 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate if (id_e_newline && !str_e_newline) { 343*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_END_NEWLINE_1), 344*7c478bd9Sstevel@tonic-gate id_num, str_num, cur_po); 345*7c478bd9Sstevel@tonic-gate po_error++; 346*7c478bd9Sstevel@tonic-gate } else if (!id_e_newline && str_e_newline) { 347*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_END_NEWLINE_2), 348*7c478bd9Sstevel@tonic-gate id_num, str_num, cur_po); 349*7c478bd9Sstevel@tonic-gate po_error++; 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate } else { 352*7c478bd9Sstevel@tonic-gate /* plural form */ 353*7c478bd9Sstevel@tonic-gate id_b_newline = (msgid[0] == '\n'); 354*7c478bd9Sstevel@tonic-gate id_e_newline = (msgid[id_len - 1 - 1] == '\n'); 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate plural_b_newline = (plural[0] == '\n'); 357*7c478bd9Sstevel@tonic-gate plural_e_newline = (plural[plural_len - 1 -1 ] == '\n'); 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate /* between msgid and msgid_plural */ 360*7c478bd9Sstevel@tonic-gate if (id_b_newline && !plural_b_newline) { 361*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_BEGIN_NEWLINE_3), 362*7c478bd9Sstevel@tonic-gate id_num, plural_num, cur_po); 363*7c478bd9Sstevel@tonic-gate po_error++; 364*7c478bd9Sstevel@tonic-gate } else if (!id_b_newline && plural_b_newline) { 365*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_BEGIN_NEWLINE_4), 366*7c478bd9Sstevel@tonic-gate id_num, plural_num, cur_po); 367*7c478bd9Sstevel@tonic-gate po_error++; 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate if (id_e_newline && !plural_e_newline) { 370*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_END_NEWLINE_3), 371*7c478bd9Sstevel@tonic-gate id_num, plural_num, cur_po); 372*7c478bd9Sstevel@tonic-gate po_error++; 373*7c478bd9Sstevel@tonic-gate } else if (!id_e_newline && plural_e_newline) { 374*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_END_NEWLINE_4), 375*7c478bd9Sstevel@tonic-gate id_num, plural_num, cur_po); 376*7c478bd9Sstevel@tonic-gate po_error++; 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate for (i = 0; i < str->no; i++) { 380*7c478bd9Sstevel@tonic-gate p = str->pos + i; 381*7c478bd9Sstevel@tonic-gate str_b_newline = (msgstr[p->off] == '\n'); 382*7c478bd9Sstevel@tonic-gate str_e_newline = 383*7c478bd9Sstevel@tonic-gate (msgstr[p->off + p->len - 1 - 1] == '\n'); 384*7c478bd9Sstevel@tonic-gate 385*7c478bd9Sstevel@tonic-gate if (id_b_newline && !str_b_newline) { 386*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_BEGIN_NEWLINE_5), 387*7c478bd9Sstevel@tonic-gate id_num, p->num, cur_po, i); 388*7c478bd9Sstevel@tonic-gate po_error++; 389*7c478bd9Sstevel@tonic-gate } else if (!id_b_newline && str_b_newline) { 390*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_BEGIN_NEWLINE_6), 391*7c478bd9Sstevel@tonic-gate id_num, p->num, cur_po, i); 392*7c478bd9Sstevel@tonic-gate po_error++; 393*7c478bd9Sstevel@tonic-gate } 394*7c478bd9Sstevel@tonic-gate 395*7c478bd9Sstevel@tonic-gate if (id_e_newline && !str_e_newline) { 396*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_END_NEWLINE_5), 397*7c478bd9Sstevel@tonic-gate id_num, p->num, cur_po, i); 398*7c478bd9Sstevel@tonic-gate po_error++; 399*7c478bd9Sstevel@tonic-gate } else if (!id_e_newline && str_e_newline) { 400*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_END_NEWLINE_6), 401*7c478bd9Sstevel@tonic-gate id_num, p->num, cur_po, i); 402*7c478bd9Sstevel@tonic-gate po_error++; 403*7c478bd9Sstevel@tonic-gate } 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate } 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate /* 408*7c478bd9Sstevel@tonic-gate * if c-format is not specified, no printf-format check 409*7c478bd9Sstevel@tonic-gate * is performed. 410*7c478bd9Sstevel@tonic-gate */ 411*7c478bd9Sstevel@tonic-gate if (!is_c_format) { 412*7c478bd9Sstevel@tonic-gate return; 413*7c478bd9Sstevel@tonic-gate } 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate osz = id_len * 2; 416*7c478bd9Sstevel@tonic-gate id_norm = (char *)Xcalloc(1, osz); 417*7c478bd9Sstevel@tonic-gate id_fmt = extract_format(id_norm, msgid, osz); 418*7c478bd9Sstevel@tonic-gate if (id_fmt == -1) { 419*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INVALID_FMT), id_num, cur_po); 420*7c478bd9Sstevel@tonic-gate po_error++; 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate if (!plural) { 424*7c478bd9Sstevel@tonic-gate /* no plural */ 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate nsz = str_len * 2; 427*7c478bd9Sstevel@tonic-gate str_norm = (char *)Xcalloc(1, nsz); 428*7c478bd9Sstevel@tonic-gate str_fmt = extract_format(str_norm, msgstr, nsz); 429*7c478bd9Sstevel@tonic-gate if (str_fmt == -1) { 430*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INVALID_FMT), str_num, cur_po); 431*7c478bd9Sstevel@tonic-gate po_error++; 432*7c478bd9Sstevel@tonic-gate } 433*7c478bd9Sstevel@tonic-gate 434*7c478bd9Sstevel@tonic-gate if (id_fmt != str_fmt) { 435*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INCMP_FMT), 436*7c478bd9Sstevel@tonic-gate id_num, str_num, cur_po); 437*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INCMP_FMT_DIFF_1), 438*7c478bd9Sstevel@tonic-gate id_fmt, str_fmt); 439*7c478bd9Sstevel@tonic-gate po_error++; 440*7c478bd9Sstevel@tonic-gate } else { 441*7c478bd9Sstevel@tonic-gate for (n = 0; n < id_fmt; n++) { 442*7c478bd9Sstevel@tonic-gate if ((id_norm[n * 2] != 443*7c478bd9Sstevel@tonic-gate str_norm[n * 2]) || 444*7c478bd9Sstevel@tonic-gate (id_norm[n * 2 + 1] != 445*7c478bd9Sstevel@tonic-gate str_norm[n * 2 + 1])) { 446*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INCMP_FMT), 447*7c478bd9Sstevel@tonic-gate id_num, str_num, cur_po); 448*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INCMP_FMT_DIFF_2), 449*7c478bd9Sstevel@tonic-gate n + 1); 450*7c478bd9Sstevel@tonic-gate po_error++; 451*7c478bd9Sstevel@tonic-gate } 452*7c478bd9Sstevel@tonic-gate } 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate free(str_norm); 455*7c478bd9Sstevel@tonic-gate free(id_norm); 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate return; 458*7c478bd9Sstevel@tonic-gate } 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate /* plural */ 461*7c478bd9Sstevel@tonic-gate nsz = plural_len * 2; 462*7c478bd9Sstevel@tonic-gate plural_norm = (char *)Xcalloc(1, nsz); 463*7c478bd9Sstevel@tonic-gate plural_fmt = extract_format(plural_norm, plural, nsz); 464*7c478bd9Sstevel@tonic-gate if (plural_fmt == -1) { 465*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INVALID_FMT), plural_num, cur_po); 466*7c478bd9Sstevel@tonic-gate po_error++; 467*7c478bd9Sstevel@tonic-gate } 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate pstr_norm = (char **)Xcalloc(str->no, sizeof (char *)); 470*7c478bd9Sstevel@tonic-gate pstr_fmt = (int *)Xcalloc(str->no, sizeof (int)); 471*7c478bd9Sstevel@tonic-gate for (i = 0; i < str->no; i++) { 472*7c478bd9Sstevel@tonic-gate p = str->pos + i; 473*7c478bd9Sstevel@tonic-gate nsz = p->len * 2; 474*7c478bd9Sstevel@tonic-gate pstr_norm[i] = (char *)Xcalloc(1, nsz); 475*7c478bd9Sstevel@tonic-gate pstr_fmt[i] = extract_format(pstr_norm[i], 476*7c478bd9Sstevel@tonic-gate msgstr + p->off, nsz); 477*7c478bd9Sstevel@tonic-gate if (pstr_fmt[i] == -1) { 478*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INVALID_FMT), 479*7c478bd9Sstevel@tonic-gate p->num, cur_po); 480*7c478bd9Sstevel@tonic-gate po_error++; 481*7c478bd9Sstevel@tonic-gate } 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate /* between msgid and msgid_plural */ 485*7c478bd9Sstevel@tonic-gate if (id_fmt != plural_fmt) { 486*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INCMP_FMT), 487*7c478bd9Sstevel@tonic-gate id_num, plural_num, cur_po); 488*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INCMP_FMT_DIFF_1), 489*7c478bd9Sstevel@tonic-gate id_fmt, plural_fmt); 490*7c478bd9Sstevel@tonic-gate po_error++; 491*7c478bd9Sstevel@tonic-gate } else { 492*7c478bd9Sstevel@tonic-gate for (n = 0; n < id_fmt; n++) { 493*7c478bd9Sstevel@tonic-gate if ((id_norm[n * 2] != 494*7c478bd9Sstevel@tonic-gate plural_norm[n * 2]) || 495*7c478bd9Sstevel@tonic-gate (id_norm[n * 2 + 1] != 496*7c478bd9Sstevel@tonic-gate plural_norm[n * 2 + 1])) { 497*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INCMP_FMT), 498*7c478bd9Sstevel@tonic-gate id_num, plural_num, cur_po); 499*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INCMP_FMT_DIFF_2), 500*7c478bd9Sstevel@tonic-gate n + 1); 501*7c478bd9Sstevel@tonic-gate po_error++; 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate } 505*7c478bd9Sstevel@tonic-gate free(plural_norm); 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate /* between msgid and msgstr */ 508*7c478bd9Sstevel@tonic-gate for (i = 0; i < str->no; i++) { 509*7c478bd9Sstevel@tonic-gate p = str->pos + i; 510*7c478bd9Sstevel@tonic-gate if (id_fmt != pstr_fmt[i]) { 511*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INCMP_FMT), 512*7c478bd9Sstevel@tonic-gate id_num, p->num, cur_po); 513*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INCMP_FMT_DIFF_1), 514*7c478bd9Sstevel@tonic-gate id_fmt, pstr_fmt[i]); 515*7c478bd9Sstevel@tonic-gate po_error++; 516*7c478bd9Sstevel@tonic-gate } else { 517*7c478bd9Sstevel@tonic-gate for (n = 0; n < id_fmt; n++) { 518*7c478bd9Sstevel@tonic-gate if ((id_norm[n * 2] != 519*7c478bd9Sstevel@tonic-gate pstr_norm[i][n * 2]) || 520*7c478bd9Sstevel@tonic-gate (id_norm[n * 2 + 1] != 521*7c478bd9Sstevel@tonic-gate pstr_norm[i][n * 2 + 1])) { 522*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INCMP_FMT), 523*7c478bd9Sstevel@tonic-gate id_num, p->num, cur_po); 524*7c478bd9Sstevel@tonic-gate diag(gettext(ERR_INCMP_FMT_DIFF_2), 525*7c478bd9Sstevel@tonic-gate n + 1); 526*7c478bd9Sstevel@tonic-gate po_error++; 527*7c478bd9Sstevel@tonic-gate } 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate } 530*7c478bd9Sstevel@tonic-gate free(pstr_norm[i]); 531*7c478bd9Sstevel@tonic-gate } 532*7c478bd9Sstevel@tonic-gate free(pstr_norm); 533*7c478bd9Sstevel@tonic-gate free(pstr_fmt); 534*7c478bd9Sstevel@tonic-gate free(id_norm); 535*7c478bd9Sstevel@tonic-gate } 536