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 1991, 1999, 2001-2002 Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All rights reserved. 25*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 26*7c478bd9Sstevel@tonic-gate */ 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <ctype.h> 30*7c478bd9Sstevel@tonic-gate #include <stdio.h> 31*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 32*7c478bd9Sstevel@tonic-gate #include <string.h> 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate #define TRUE 1 35*7c478bd9Sstevel@tonic-gate #define FALSE 0 36*7c478bd9Sstevel@tonic-gate #define MAX_PATH_LEN 1024 37*7c478bd9Sstevel@tonic-gate #define MAX_DOMAIN_LEN 1024 38*7c478bd9Sstevel@tonic-gate #define MAX_STRING_LEN 2048 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #define USAGE "Usage: xgettext [-a [-x exclude-file]] [-jns]\ 41*7c478bd9Sstevel@tonic-gate [-c comment-tag]\n [-d default-domain] [-m prefix] \ 42*7c478bd9Sstevel@tonic-gate [-M suffix] [-p pathname] files ...\n\ 43*7c478bd9Sstevel@tonic-gate xgettext -h\n" 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate #define DEFAULT_DOMAIN "messages" 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate extern char yytext[]; 48*7c478bd9Sstevel@tonic-gate extern int yylex(void); 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate /* 51*7c478bd9Sstevel@tonic-gate * Contains a list of strings to be used to store ANSI-C style string. 52*7c478bd9Sstevel@tonic-gate * Each quoted string is stored in one node. 53*7c478bd9Sstevel@tonic-gate */ 54*7c478bd9Sstevel@tonic-gate struct strlist_st { 55*7c478bd9Sstevel@tonic-gate char *str; 56*7c478bd9Sstevel@tonic-gate struct strlist_st *next; 57*7c478bd9Sstevel@tonic-gate }; 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate /* 60*7c478bd9Sstevel@tonic-gate * istextdomain : Boolean telling if this node contains textdomain call. 61*7c478bd9Sstevel@tonic-gate * isduplicate : Boolean telling if this node duplicate of any other msgid. 62*7c478bd9Sstevel@tonic-gate * msgid : contains msgid or textdomain if istextdomain is true. 63*7c478bd9Sstevel@tonic-gate * msgstr : contains msgstr. 64*7c478bd9Sstevel@tonic-gate * comment : comment extracted in case of -c option. 65*7c478bd9Sstevel@tonic-gate * fname : tells which file contains msgid. 66*7c478bd9Sstevel@tonic-gate * linenum : line number in the file. 67*7c478bd9Sstevel@tonic-gate * next : Next node. 68*7c478bd9Sstevel@tonic-gate */ 69*7c478bd9Sstevel@tonic-gate struct element_st { 70*7c478bd9Sstevel@tonic-gate char istextdomain; 71*7c478bd9Sstevel@tonic-gate char isduplicate; 72*7c478bd9Sstevel@tonic-gate struct strlist_st *msgid; 73*7c478bd9Sstevel@tonic-gate struct strlist_st *msgstr; 74*7c478bd9Sstevel@tonic-gate struct strlist_st *comment; 75*7c478bd9Sstevel@tonic-gate char *fname; 76*7c478bd9Sstevel@tonic-gate int linenum; 77*7c478bd9Sstevel@tonic-gate struct element_st *next; 78*7c478bd9Sstevel@tonic-gate }; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate /* 81*7c478bd9Sstevel@tonic-gate * dname : domain name. NULL if default domain. 82*7c478bd9Sstevel@tonic-gate * gettext_head : Head of linked list containing [d]gettext(). 83*7c478bd9Sstevel@tonic-gate * gettext_tail : Tail of linked list containing [d]gettext(). 84*7c478bd9Sstevel@tonic-gate * textdomain_head : Head of linked list containing textdomain(). 85*7c478bd9Sstevel@tonic-gate * textdomain_tail : Tail of linked list containing textdomain(). 86*7c478bd9Sstevel@tonic-gate * next : Next node. 87*7c478bd9Sstevel@tonic-gate * 88*7c478bd9Sstevel@tonic-gate * Each domain contains two linked list. 89*7c478bd9Sstevel@tonic-gate * (gettext_head, textdomain_head) 90*7c478bd9Sstevel@tonic-gate * If -s option is used, then textdomain_head contains all 91*7c478bd9Sstevel@tonic-gate * textdomain() calls and no textdomain() calls are stored in gettext_head. 92*7c478bd9Sstevel@tonic-gate * If -s option is not used, textdomain_head is empty list and 93*7c478bd9Sstevel@tonic-gate * gettext_head contains all gettext() dgettext(), and textdomain() calls. 94*7c478bd9Sstevel@tonic-gate */ 95*7c478bd9Sstevel@tonic-gate struct domain_st { 96*7c478bd9Sstevel@tonic-gate char *dname; 97*7c478bd9Sstevel@tonic-gate struct element_st *gettext_head; 98*7c478bd9Sstevel@tonic-gate struct element_st *gettext_tail; 99*7c478bd9Sstevel@tonic-gate struct element_st *textdomain_head; 100*7c478bd9Sstevel@tonic-gate struct element_st *textdomain_tail; 101*7c478bd9Sstevel@tonic-gate struct domain_st *next; 102*7c478bd9Sstevel@tonic-gate }; 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate /* 105*7c478bd9Sstevel@tonic-gate * There are two domain linked lists. 106*7c478bd9Sstevel@tonic-gate * def_dom contains default domain linked list and 107*7c478bd9Sstevel@tonic-gate * dom_head contains all other deomain linked lists to be created by 108*7c478bd9Sstevel@tonic-gate * dgettext() calls. 109*7c478bd9Sstevel@tonic-gate */ 110*7c478bd9Sstevel@tonic-gate static struct domain_st *def_dom = NULL; 111*7c478bd9Sstevel@tonic-gate static struct domain_st *dom_head = NULL; 112*7c478bd9Sstevel@tonic-gate static struct domain_st *dom_tail = NULL; 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* 115*7c478bd9Sstevel@tonic-gate * This linked list contains a list of strings to be excluded when 116*7c478bd9Sstevel@tonic-gate * -x option is used. 117*7c478bd9Sstevel@tonic-gate */ 118*7c478bd9Sstevel@tonic-gate static struct exclude_st { 119*7c478bd9Sstevel@tonic-gate struct strlist_st *exstr; 120*7c478bd9Sstevel@tonic-gate struct exclude_st *next; 121*7c478bd9Sstevel@tonic-gate } *excl_head; 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate /* 124*7c478bd9Sstevel@tonic-gate * All option flags and values for each option if any. 125*7c478bd9Sstevel@tonic-gate */ 126*7c478bd9Sstevel@tonic-gate static int aflg = FALSE; 127*7c478bd9Sstevel@tonic-gate static int cflg = FALSE; 128*7c478bd9Sstevel@tonic-gate static char *comment_tag = NULL; 129*7c478bd9Sstevel@tonic-gate static char *default_domain = NULL; 130*7c478bd9Sstevel@tonic-gate static int hflg = FALSE; 131*7c478bd9Sstevel@tonic-gate static int jflg = FALSE; 132*7c478bd9Sstevel@tonic-gate static int mflg = FALSE; 133*7c478bd9Sstevel@tonic-gate static int Mflg = FALSE; 134*7c478bd9Sstevel@tonic-gate static char *suffix = NULL; 135*7c478bd9Sstevel@tonic-gate static char *prefix = NULL; 136*7c478bd9Sstevel@tonic-gate static int nflg = FALSE; 137*7c478bd9Sstevel@tonic-gate static int pflg = FALSE; 138*7c478bd9Sstevel@tonic-gate static char *pathname = NULL; 139*7c478bd9Sstevel@tonic-gate static int sflg = FALSE; 140*7c478bd9Sstevel@tonic-gate static int tflg = FALSE; /* Undocumented option to extract dcgettext */ 141*7c478bd9Sstevel@tonic-gate static int xflg = FALSE; 142*7c478bd9Sstevel@tonic-gate static char *exclude_file = NULL; 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate /* 145*7c478bd9Sstevel@tonic-gate * Each variable shows the current state of parsing input file. 146*7c478bd9Sstevel@tonic-gate * 147*7c478bd9Sstevel@tonic-gate * in_comment : Means inside comment block (C or C++). 148*7c478bd9Sstevel@tonic-gate * in_cplus_comment : Means inside C++ comment block. 149*7c478bd9Sstevel@tonic-gate * in_gettext : Means inside gettext call. 150*7c478bd9Sstevel@tonic-gate * in_dgettext : Means inside dgettext call. 151*7c478bd9Sstevel@tonic-gate * in_dcgettext : Means inside dcgettext call. 152*7c478bd9Sstevel@tonic-gate * in_textdomain : Means inside textdomain call. 153*7c478bd9Sstevel@tonic-gate * in_str : Means currently processing ANSI style string. 154*7c478bd9Sstevel@tonic-gate * in_quote : Means currently processing double quoted string. 155*7c478bd9Sstevel@tonic-gate * in_skippable_string : Means currently processing double quoted string, 156*7c478bd9Sstevel@tonic-gate * that occurs outside a call to gettext, dgettext, 157*7c478bd9Sstevel@tonic-gate * dcgettext, textdomain, with -a not specified. 158*7c478bd9Sstevel@tonic-gate * is_last_comment_line : Means the current line is the last line 159*7c478bd9Sstevel@tonic-gate * of the comment block. This is necessary because 160*7c478bd9Sstevel@tonic-gate * in_comment becomes FALSE when '* /' is encountered. 161*7c478bd9Sstevel@tonic-gate * is_first_comma_found : This is used only for dcgettext because dcgettext() 162*7c478bd9Sstevel@tonic-gate * requires 2 commas. So need to do different action 163*7c478bd9Sstevel@tonic-gate * depending on which commas encountered. 164*7c478bd9Sstevel@tonic-gate * num_nested_open_paren : This keeps track of the number of open parens to 165*7c478bd9Sstevel@tonic-gate * handle dcgettext ((const char *)0,"msg",LC_TIME); 166*7c478bd9Sstevel@tonic-gate */ 167*7c478bd9Sstevel@tonic-gate static int in_comment = FALSE; 168*7c478bd9Sstevel@tonic-gate static int in_cplus_comment = FALSE; 169*7c478bd9Sstevel@tonic-gate static int in_gettext = FALSE; 170*7c478bd9Sstevel@tonic-gate static int in_dgettext = FALSE; 171*7c478bd9Sstevel@tonic-gate static int in_dcgettext = FALSE; 172*7c478bd9Sstevel@tonic-gate static int in_textdomain = FALSE; 173*7c478bd9Sstevel@tonic-gate static int in_str = FALSE; 174*7c478bd9Sstevel@tonic-gate static int in_quote = FALSE; 175*7c478bd9Sstevel@tonic-gate static int is_last_comment_line = FALSE; 176*7c478bd9Sstevel@tonic-gate static int is_first_comma_found = FALSE; 177*7c478bd9Sstevel@tonic-gate static int in_skippable_string = FALSE; 178*7c478bd9Sstevel@tonic-gate static int num_nested_open_paren = 0; 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate /* 181*7c478bd9Sstevel@tonic-gate * This variable contains the first line of gettext(), dgettext(), or 182*7c478bd9Sstevel@tonic-gate * textdomain() calls. 183*7c478bd9Sstevel@tonic-gate * This is necessary for multiple lines of a single call to store 184*7c478bd9Sstevel@tonic-gate * the starting line. 185*7c478bd9Sstevel@tonic-gate */ 186*7c478bd9Sstevel@tonic-gate static int linenum_saved = 0; 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate int stdin_only = FALSE; /* Read input from stdin */ 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate /* 191*7c478bd9Sstevel@tonic-gate * curr_file : Contains current file name processed. 192*7c478bd9Sstevel@tonic-gate * curr_domain : Contains the current domain for each dgettext(). 193*7c478bd9Sstevel@tonic-gate * This is NULL for gettext(). 194*7c478bd9Sstevel@tonic-gate * curr_line : Contains the current line processed. 195*7c478bd9Sstevel@tonic-gate * qstring_buf : Contains the double quoted string processed. 196*7c478bd9Sstevel@tonic-gate * curr_linenum : Line number being processed in the current input file. 197*7c478bd9Sstevel@tonic-gate * warn_linenum : Line number of current warning message. 198*7c478bd9Sstevel@tonic-gate */ 199*7c478bd9Sstevel@tonic-gate char curr_file[MAX_PATH_LEN]; 200*7c478bd9Sstevel@tonic-gate static char curr_domain[MAX_DOMAIN_LEN]; 201*7c478bd9Sstevel@tonic-gate static char curr_line[MAX_STRING_LEN]; 202*7c478bd9Sstevel@tonic-gate static char qstring_buf[MAX_STRING_LEN]; 203*7c478bd9Sstevel@tonic-gate int curr_linenum = 1; 204*7c478bd9Sstevel@tonic-gate int warn_linenum = 0; 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate /* 207*7c478bd9Sstevel@tonic-gate * strhead : This list contains ANSI style string. 208*7c478bd9Sstevel@tonic-gate * Each node contains double quoted string. 209*7c478bd9Sstevel@tonic-gate * strtail : This is the tail of strhead. 210*7c478bd9Sstevel@tonic-gate * commhead : This list contains comments string. 211*7c478bd9Sstevel@tonic-gate * Each node contains one line of comment. 212*7c478bd9Sstevel@tonic-gate * commtail : This is the tail of commhead. 213*7c478bd9Sstevel@tonic-gate */ 214*7c478bd9Sstevel@tonic-gate static struct strlist_st *strhead = NULL; 215*7c478bd9Sstevel@tonic-gate static struct strlist_st *strtail = NULL; 216*7c478bd9Sstevel@tonic-gate static struct strlist_st *commhead = NULL; 217*7c478bd9Sstevel@tonic-gate static struct strlist_st *commtail = NULL; 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate /* 220*7c478bd9Sstevel@tonic-gate * gargc : Same as argc. Used to pass argc to lex routine. 221*7c478bd9Sstevel@tonic-gate * gargv : Same as argv. Used to pass argc to lex routine. 222*7c478bd9Sstevel@tonic-gate */ 223*7c478bd9Sstevel@tonic-gate int gargc; 224*7c478bd9Sstevel@tonic-gate char **gargv; 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate static void add_line_to_comment(void); 227*7c478bd9Sstevel@tonic-gate static void add_qstring_to_str(void); 228*7c478bd9Sstevel@tonic-gate static void add_str_to_element_list(int, char *); 229*7c478bd9Sstevel@tonic-gate static void copy_strlist_to_str(char *, struct strlist_st *); 230*7c478bd9Sstevel@tonic-gate static void end_ansi_string(void); 231*7c478bd9Sstevel@tonic-gate static void free_strlist(struct strlist_st *); 232*7c478bd9Sstevel@tonic-gate void handle_newline(void); 233*7c478bd9Sstevel@tonic-gate static void initialize_globals(void); 234*7c478bd9Sstevel@tonic-gate static void output_comment(FILE *, struct strlist_st *); 235*7c478bd9Sstevel@tonic-gate static void output_msgid(FILE *, struct strlist_st *, int); 236*7c478bd9Sstevel@tonic-gate static void output_textdomain(FILE *, struct element_st *); 237*7c478bd9Sstevel@tonic-gate static void print_help(void); 238*7c478bd9Sstevel@tonic-gate static void read_exclude_file(void); 239*7c478bd9Sstevel@tonic-gate static void trim_line(char *); 240*7c478bd9Sstevel@tonic-gate static void write_all_files(void); 241*7c478bd9Sstevel@tonic-gate static void write_one_file(struct domain_st *); 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate static void lstrcat(char *, const char *); 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate /* 246*7c478bd9Sstevel@tonic-gate * Utility functions to malloc a node and initialize fields. 247*7c478bd9Sstevel@tonic-gate */ 248*7c478bd9Sstevel@tonic-gate static struct domain_st *new_domain(void); 249*7c478bd9Sstevel@tonic-gate static struct strlist_st *new_strlist(void); 250*7c478bd9Sstevel@tonic-gate static struct element_st *new_element(void); 251*7c478bd9Sstevel@tonic-gate static struct exclude_st *new_exclude(void); 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate /* 254*7c478bd9Sstevel@tonic-gate * Main program of xgettext. 255*7c478bd9Sstevel@tonic-gate */ 256*7c478bd9Sstevel@tonic-gate int 257*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 258*7c478bd9Sstevel@tonic-gate { 259*7c478bd9Sstevel@tonic-gate int opterr = FALSE; 260*7c478bd9Sstevel@tonic-gate int c; 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate initialize_globals(); 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "jhax:nsc:d:m:M:p:t")) != EOF) { 265*7c478bd9Sstevel@tonic-gate switch (c) { 266*7c478bd9Sstevel@tonic-gate case 'a': 267*7c478bd9Sstevel@tonic-gate aflg = TRUE; 268*7c478bd9Sstevel@tonic-gate break; 269*7c478bd9Sstevel@tonic-gate case 'c': 270*7c478bd9Sstevel@tonic-gate cflg = TRUE; 271*7c478bd9Sstevel@tonic-gate comment_tag = optarg; 272*7c478bd9Sstevel@tonic-gate break; 273*7c478bd9Sstevel@tonic-gate case 'd': 274*7c478bd9Sstevel@tonic-gate default_domain = optarg; 275*7c478bd9Sstevel@tonic-gate break; 276*7c478bd9Sstevel@tonic-gate case 'h': 277*7c478bd9Sstevel@tonic-gate hflg = TRUE; 278*7c478bd9Sstevel@tonic-gate break; 279*7c478bd9Sstevel@tonic-gate case 'j': 280*7c478bd9Sstevel@tonic-gate jflg = TRUE; 281*7c478bd9Sstevel@tonic-gate break; 282*7c478bd9Sstevel@tonic-gate case 'M': 283*7c478bd9Sstevel@tonic-gate Mflg = TRUE; 284*7c478bd9Sstevel@tonic-gate suffix = optarg; 285*7c478bd9Sstevel@tonic-gate break; 286*7c478bd9Sstevel@tonic-gate case 'm': 287*7c478bd9Sstevel@tonic-gate mflg = TRUE; 288*7c478bd9Sstevel@tonic-gate prefix = optarg; 289*7c478bd9Sstevel@tonic-gate break; 290*7c478bd9Sstevel@tonic-gate case 'n': 291*7c478bd9Sstevel@tonic-gate nflg = TRUE; 292*7c478bd9Sstevel@tonic-gate break; 293*7c478bd9Sstevel@tonic-gate case 'p': 294*7c478bd9Sstevel@tonic-gate pflg = TRUE; 295*7c478bd9Sstevel@tonic-gate pathname = optarg; 296*7c478bd9Sstevel@tonic-gate break; 297*7c478bd9Sstevel@tonic-gate case 's': 298*7c478bd9Sstevel@tonic-gate sflg = TRUE; 299*7c478bd9Sstevel@tonic-gate break; 300*7c478bd9Sstevel@tonic-gate case 't': 301*7c478bd9Sstevel@tonic-gate tflg = TRUE; 302*7c478bd9Sstevel@tonic-gate break; 303*7c478bd9Sstevel@tonic-gate case 'x': 304*7c478bd9Sstevel@tonic-gate xflg = TRUE; 305*7c478bd9Sstevel@tonic-gate exclude_file = optarg; 306*7c478bd9Sstevel@tonic-gate break; 307*7c478bd9Sstevel@tonic-gate case '?': 308*7c478bd9Sstevel@tonic-gate opterr = TRUE; 309*7c478bd9Sstevel@tonic-gate break; 310*7c478bd9Sstevel@tonic-gate } 311*7c478bd9Sstevel@tonic-gate } 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate /* if -h is used, ignore all other options. */ 314*7c478bd9Sstevel@tonic-gate if (hflg == TRUE) { 315*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, USAGE); 316*7c478bd9Sstevel@tonic-gate print_help(); 317*7c478bd9Sstevel@tonic-gate exit(0); 318*7c478bd9Sstevel@tonic-gate } 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate /* -x can be used only with -a */ 321*7c478bd9Sstevel@tonic-gate if ((xflg == TRUE) && (aflg == FALSE)) 322*7c478bd9Sstevel@tonic-gate opterr = TRUE; 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate /* -j cannot be used with -a */ 325*7c478bd9Sstevel@tonic-gate if ((jflg == TRUE) && (aflg == TRUE)) { 326*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 327*7c478bd9Sstevel@tonic-gate "-a and -j options cannot be used together.\n"); 328*7c478bd9Sstevel@tonic-gate opterr = TRUE; 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate /* -j cannot be used with -s */ 332*7c478bd9Sstevel@tonic-gate if ((jflg == TRUE) && (sflg == TRUE)) { 333*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 334*7c478bd9Sstevel@tonic-gate "-j and -s options cannot be used together.\n"); 335*7c478bd9Sstevel@tonic-gate opterr = TRUE; 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate if (opterr == TRUE) { 339*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, USAGE); 340*7c478bd9Sstevel@tonic-gate exit(2); 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate /* error, if no files are specified. */ 344*7c478bd9Sstevel@tonic-gate if (optind == argc) { 345*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, USAGE); 346*7c478bd9Sstevel@tonic-gate exit(2); 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate if (xflg == TRUE) { 350*7c478bd9Sstevel@tonic-gate read_exclude_file(); 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate /* If files are -, then read from stdin */ 354*7c478bd9Sstevel@tonic-gate if (argv[optind][0] == '-') { 355*7c478bd9Sstevel@tonic-gate stdin_only = TRUE; 356*7c478bd9Sstevel@tonic-gate optind++; 357*7c478bd9Sstevel@tonic-gate } else { 358*7c478bd9Sstevel@tonic-gate stdin_only = FALSE; 359*7c478bd9Sstevel@tonic-gate } 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate /* Store argc and argv to pass to yylex() */ 362*7c478bd9Sstevel@tonic-gate gargc = argc; 363*7c478bd9Sstevel@tonic-gate gargv = argv; 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 366*7c478bd9Sstevel@tonic-gate (void) printf("optind=%d\n", optind); 367*7c478bd9Sstevel@tonic-gate { 368*7c478bd9Sstevel@tonic-gate int i = optind; 369*7c478bd9Sstevel@tonic-gate for (; i < argc; i++) { 370*7c478bd9Sstevel@tonic-gate (void) printf(" %d, <%s>\n", i, argv[i]); 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate } 373*7c478bd9Sstevel@tonic-gate #endif 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate if (stdin_only == FALSE) { 376*7c478bd9Sstevel@tonic-gate if (freopen(argv[optind], "r", stdin) == NULL) { 377*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 378*7c478bd9Sstevel@tonic-gate "ERROR, can't open input file: %s\n", argv[optind]); 379*7c478bd9Sstevel@tonic-gate exit(2); 380*7c478bd9Sstevel@tonic-gate } 381*7c478bd9Sstevel@tonic-gate (void) strcpy(curr_file, gargv[optind]); 382*7c478bd9Sstevel@tonic-gate optind++; 383*7c478bd9Sstevel@tonic-gate } 384*7c478bd9Sstevel@tonic-gate 385*7c478bd9Sstevel@tonic-gate /* 386*7c478bd9Sstevel@tonic-gate * Process input. 387*7c478bd9Sstevel@tonic-gate */ 388*7c478bd9Sstevel@tonic-gate (void) yylex(); 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 391*7c478bd9Sstevel@tonic-gate printf("\n======= default_domain ========\n"); 392*7c478bd9Sstevel@tonic-gate print_one_domain(def_dom); 393*7c478bd9Sstevel@tonic-gate printf("======= domain list ========\n"); 394*7c478bd9Sstevel@tonic-gate print_all_domain(dom_head); 395*7c478bd9Sstevel@tonic-gate #endif 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate /* 398*7c478bd9Sstevel@tonic-gate * Write out all .po files. 399*7c478bd9Sstevel@tonic-gate */ 400*7c478bd9Sstevel@tonic-gate write_all_files(); 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate return (0); 403*7c478bd9Sstevel@tonic-gate } /* main */ 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate /* 406*7c478bd9Sstevel@tonic-gate * Prints help information for each option. 407*7c478bd9Sstevel@tonic-gate */ 408*7c478bd9Sstevel@tonic-gate static void 409*7c478bd9Sstevel@tonic-gate print_help(void) 410*7c478bd9Sstevel@tonic-gate { 411*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n"); 412*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 413*7c478bd9Sstevel@tonic-gate "-a\t\t\tfind ALL strings\n"); 414*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 415*7c478bd9Sstevel@tonic-gate "-c <comment-tag>\tget comments containing <flag>\n"); 416*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 417*7c478bd9Sstevel@tonic-gate "-d <default-domain>\tuse <default-domain> for default domain\n"); 418*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 419*7c478bd9Sstevel@tonic-gate "-h\t\t\tHelp\n"); 420*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 421*7c478bd9Sstevel@tonic-gate "-j\t\t\tupdate existing file with the current result\n"); 422*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 423*7c478bd9Sstevel@tonic-gate "-M <suffix>\t\tfill in msgstr with msgid<suffix>\n"); 424*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 425*7c478bd9Sstevel@tonic-gate "-m <prefix>\t\tfill in msgstr with <prefix>msgid\n"); 426*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 427*7c478bd9Sstevel@tonic-gate "-n\t\t\tline# file name and line number info in output\n"); 428*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 429*7c478bd9Sstevel@tonic-gate "-p <pathname>\t\tuse <pathname> for output file directory\n"); 430*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 431*7c478bd9Sstevel@tonic-gate "-s\t\t\tgenerate sorted output files\n"); 432*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 433*7c478bd9Sstevel@tonic-gate "-x <exclude-file>\texclude strings in file <exclude-file> from output\n"); 434*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 435*7c478bd9Sstevel@tonic-gate "-\t\t\tread stdin, use as a filter (input only)\n"); 436*7c478bd9Sstevel@tonic-gate } /* print_help */ 437*7c478bd9Sstevel@tonic-gate 438*7c478bd9Sstevel@tonic-gate /* 439*7c478bd9Sstevel@tonic-gate * Extract file name and line number information from macro line 440*7c478bd9Sstevel@tonic-gate * and set the global variable accordingly. 441*7c478bd9Sstevel@tonic-gate * The valid line format is 442*7c478bd9Sstevel@tonic-gate * 1) # nnn 443*7c478bd9Sstevel@tonic-gate * or 444*7c478bd9Sstevel@tonic-gate * 2) # nnn "xxxxx" 445*7c478bd9Sstevel@tonic-gate * where nnn is line number and xxxxx is file name. 446*7c478bd9Sstevel@tonic-gate */ 447*7c478bd9Sstevel@tonic-gate static void 448*7c478bd9Sstevel@tonic-gate extract_filename_linenumber(char *mline) 449*7c478bd9Sstevel@tonic-gate { 450*7c478bd9Sstevel@tonic-gate int num; 451*7c478bd9Sstevel@tonic-gate char *p, *q, *r; 452*7c478bd9Sstevel@tonic-gate 453*7c478bd9Sstevel@tonic-gate /* 454*7c478bd9Sstevel@tonic-gate * mline can contain multi newline. 455*7c478bd9Sstevel@tonic-gate * line number should be increased by the number of newlines. 456*7c478bd9Sstevel@tonic-gate */ 457*7c478bd9Sstevel@tonic-gate p = mline; 458*7c478bd9Sstevel@tonic-gate while ((p = strchr(p, '\n')) != NULL) { 459*7c478bd9Sstevel@tonic-gate p++; 460*7c478bd9Sstevel@tonic-gate curr_linenum++; 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate p = strchr(mline, ' '); 463*7c478bd9Sstevel@tonic-gate if (p == NULL) 464*7c478bd9Sstevel@tonic-gate return; 465*7c478bd9Sstevel@tonic-gate q = strchr(++p, ' '); 466*7c478bd9Sstevel@tonic-gate if (q == NULL) { 467*7c478bd9Sstevel@tonic-gate /* case 1 */ 468*7c478bd9Sstevel@tonic-gate if ((num = atoi(p)) > 0) { 469*7c478bd9Sstevel@tonic-gate curr_linenum = num; 470*7c478bd9Sstevel@tonic-gate return; 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate } else { 473*7c478bd9Sstevel@tonic-gate /* case 2 */ 474*7c478bd9Sstevel@tonic-gate *q++ = 0; 475*7c478bd9Sstevel@tonic-gate if (*q == '"') { 476*7c478bd9Sstevel@tonic-gate q++; 477*7c478bd9Sstevel@tonic-gate r = strchr(q, '"'); 478*7c478bd9Sstevel@tonic-gate if (r == NULL) { 479*7c478bd9Sstevel@tonic-gate return; 480*7c478bd9Sstevel@tonic-gate } 481*7c478bd9Sstevel@tonic-gate *r = 0; 482*7c478bd9Sstevel@tonic-gate if ((num = atoi(p)) > 0) { 483*7c478bd9Sstevel@tonic-gate curr_linenum = num; 484*7c478bd9Sstevel@tonic-gate (void) strcpy(curr_file, q); 485*7c478bd9Sstevel@tonic-gate } 486*7c478bd9Sstevel@tonic-gate } 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate } /* extract_filename_linenumber */ 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate /* 491*7c478bd9Sstevel@tonic-gate * Handler for MACRO line which starts with #. 492*7c478bd9Sstevel@tonic-gate */ 493*7c478bd9Sstevel@tonic-gate void 494*7c478bd9Sstevel@tonic-gate handle_macro_line(void) 495*7c478bd9Sstevel@tonic-gate { 496*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 497*7c478bd9Sstevel@tonic-gate (void) printf("Macro line=<%s>\n", yytext); 498*7c478bd9Sstevel@tonic-gate #endif 499*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 500*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 503*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 504*7c478bd9Sstevel@tonic-gate } else if (in_comment == FALSE) { 505*7c478bd9Sstevel@tonic-gate extract_filename_linenumber(yytext); 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate curr_linenum--; 509*7c478bd9Sstevel@tonic-gate handle_newline(); 510*7c478bd9Sstevel@tonic-gate } /* handle_macro_line */ 511*7c478bd9Sstevel@tonic-gate 512*7c478bd9Sstevel@tonic-gate /* 513*7c478bd9Sstevel@tonic-gate * Handler for C++ comments which starts with //. 514*7c478bd9Sstevel@tonic-gate */ 515*7c478bd9Sstevel@tonic-gate void 516*7c478bd9Sstevel@tonic-gate handle_cplus_comment_line(void) 517*7c478bd9Sstevel@tonic-gate { 518*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 519*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 522*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 523*7c478bd9Sstevel@tonic-gate } else if ((in_comment == FALSE) && 524*7c478bd9Sstevel@tonic-gate (in_skippable_string == FALSE)) { 525*7c478bd9Sstevel@tonic-gate 526*7c478bd9Sstevel@tonic-gate /* 527*7c478bd9Sstevel@tonic-gate * If already in c comments, don't do anything. 528*7c478bd9Sstevel@tonic-gate * Set both flags to TRUE here. 529*7c478bd9Sstevel@tonic-gate * Both flags will be set to FALSE when newline 530*7c478bd9Sstevel@tonic-gate * encounters. 531*7c478bd9Sstevel@tonic-gate */ 532*7c478bd9Sstevel@tonic-gate in_cplus_comment = TRUE; 533*7c478bd9Sstevel@tonic-gate in_comment = TRUE; 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate } /* handle_cplus_comment_line */ 536*7c478bd9Sstevel@tonic-gate 537*7c478bd9Sstevel@tonic-gate /* 538*7c478bd9Sstevel@tonic-gate * Handler for the comment start (slash asterisk) in input file. 539*7c478bd9Sstevel@tonic-gate */ 540*7c478bd9Sstevel@tonic-gate void 541*7c478bd9Sstevel@tonic-gate handle_open_comment(void) 542*7c478bd9Sstevel@tonic-gate { 543*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 544*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 547*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 548*7c478bd9Sstevel@tonic-gate } else if ((in_comment == FALSE) && 549*7c478bd9Sstevel@tonic-gate (in_skippable_string == FALSE)) { 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate in_comment = TRUE; 552*7c478bd9Sstevel@tonic-gate is_last_comment_line = FALSE; 553*7c478bd9Sstevel@tonic-gate /* 554*7c478bd9Sstevel@tonic-gate * If there is any comment extracted before accidently, 555*7c478bd9Sstevel@tonic-gate * clean it up and start the new comment again. 556*7c478bd9Sstevel@tonic-gate */ 557*7c478bd9Sstevel@tonic-gate free_strlist(commhead); 558*7c478bd9Sstevel@tonic-gate commhead = commtail = NULL; 559*7c478bd9Sstevel@tonic-gate } 560*7c478bd9Sstevel@tonic-gate } 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate /* 563*7c478bd9Sstevel@tonic-gate * Handler for the comment end (asterisk slash) in input file. 564*7c478bd9Sstevel@tonic-gate */ 565*7c478bd9Sstevel@tonic-gate void 566*7c478bd9Sstevel@tonic-gate handle_close_comment(void) 567*7c478bd9Sstevel@tonic-gate { 568*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 569*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 570*7c478bd9Sstevel@tonic-gate 571*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 572*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 573*7c478bd9Sstevel@tonic-gate } else if (in_skippable_string == FALSE) { 574*7c478bd9Sstevel@tonic-gate in_comment = FALSE; 575*7c478bd9Sstevel@tonic-gate is_last_comment_line = TRUE; 576*7c478bd9Sstevel@tonic-gate } 577*7c478bd9Sstevel@tonic-gate } 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate /* 580*7c478bd9Sstevel@tonic-gate * Handler for "gettext" in input file. 581*7c478bd9Sstevel@tonic-gate */ 582*7c478bd9Sstevel@tonic-gate void 583*7c478bd9Sstevel@tonic-gate handle_gettext(void) 584*7c478bd9Sstevel@tonic-gate { 585*7c478bd9Sstevel@tonic-gate /* 586*7c478bd9Sstevel@tonic-gate * If -t option is specified to extrct dcgettext, 587*7c478bd9Sstevel@tonic-gate * don't do anything for gettext(). 588*7c478bd9Sstevel@tonic-gate */ 589*7c478bd9Sstevel@tonic-gate if (tflg == TRUE) { 590*7c478bd9Sstevel@tonic-gate return; 591*7c478bd9Sstevel@tonic-gate } 592*7c478bd9Sstevel@tonic-gate 593*7c478bd9Sstevel@tonic-gate num_nested_open_paren = 0; 594*7c478bd9Sstevel@tonic-gate 595*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 596*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 597*7c478bd9Sstevel@tonic-gate 598*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 599*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 600*7c478bd9Sstevel@tonic-gate } else if (in_comment == FALSE) { 601*7c478bd9Sstevel@tonic-gate in_gettext = TRUE; 602*7c478bd9Sstevel@tonic-gate linenum_saved = curr_linenum; 603*7c478bd9Sstevel@tonic-gate /* 604*7c478bd9Sstevel@tonic-gate * gettext will be put into default domain .po file 605*7c478bd9Sstevel@tonic-gate * curr_domain does not change for gettext. 606*7c478bd9Sstevel@tonic-gate */ 607*7c478bd9Sstevel@tonic-gate curr_domain[0] = NULL; 608*7c478bd9Sstevel@tonic-gate } 609*7c478bd9Sstevel@tonic-gate } /* handle_gettext */ 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate /* 612*7c478bd9Sstevel@tonic-gate * Handler for "dgettext" in input file. 613*7c478bd9Sstevel@tonic-gate */ 614*7c478bd9Sstevel@tonic-gate void 615*7c478bd9Sstevel@tonic-gate handle_dgettext(void) 616*7c478bd9Sstevel@tonic-gate { 617*7c478bd9Sstevel@tonic-gate /* 618*7c478bd9Sstevel@tonic-gate * If -t option is specified to extrct dcgettext, 619*7c478bd9Sstevel@tonic-gate * don't do anything for dgettext(). 620*7c478bd9Sstevel@tonic-gate */ 621*7c478bd9Sstevel@tonic-gate if (tflg == TRUE) { 622*7c478bd9Sstevel@tonic-gate return; 623*7c478bd9Sstevel@tonic-gate } 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate num_nested_open_paren = 0; 626*7c478bd9Sstevel@tonic-gate 627*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 628*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 629*7c478bd9Sstevel@tonic-gate 630*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 631*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 632*7c478bd9Sstevel@tonic-gate } else if (in_comment == FALSE) { 633*7c478bd9Sstevel@tonic-gate in_dgettext = TRUE; 634*7c478bd9Sstevel@tonic-gate linenum_saved = curr_linenum; 635*7c478bd9Sstevel@tonic-gate /* 636*7c478bd9Sstevel@tonic-gate * dgettext will be put into domain file specified. 637*7c478bd9Sstevel@tonic-gate * curr_domain will follow. 638*7c478bd9Sstevel@tonic-gate */ 639*7c478bd9Sstevel@tonic-gate curr_domain[0] = NULL; 640*7c478bd9Sstevel@tonic-gate } 641*7c478bd9Sstevel@tonic-gate } /* handle_dgettext */ 642*7c478bd9Sstevel@tonic-gate 643*7c478bd9Sstevel@tonic-gate /* 644*7c478bd9Sstevel@tonic-gate * Handler for "dcgettext" in input file. 645*7c478bd9Sstevel@tonic-gate */ 646*7c478bd9Sstevel@tonic-gate void 647*7c478bd9Sstevel@tonic-gate handle_dcgettext(void) 648*7c478bd9Sstevel@tonic-gate { 649*7c478bd9Sstevel@tonic-gate /* 650*7c478bd9Sstevel@tonic-gate * dcgettext will be extracted only when -t flag is specified. 651*7c478bd9Sstevel@tonic-gate */ 652*7c478bd9Sstevel@tonic-gate if (tflg == FALSE) { 653*7c478bd9Sstevel@tonic-gate return; 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate num_nested_open_paren = 0; 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate is_first_comma_found = FALSE; 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 661*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 664*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 665*7c478bd9Sstevel@tonic-gate } else if (in_comment == FALSE) { 666*7c478bd9Sstevel@tonic-gate in_dcgettext = TRUE; 667*7c478bd9Sstevel@tonic-gate linenum_saved = curr_linenum; 668*7c478bd9Sstevel@tonic-gate /* 669*7c478bd9Sstevel@tonic-gate * dcgettext will be put into domain file specified. 670*7c478bd9Sstevel@tonic-gate * curr_domain will follow. 671*7c478bd9Sstevel@tonic-gate */ 672*7c478bd9Sstevel@tonic-gate curr_domain[0] = NULL; 673*7c478bd9Sstevel@tonic-gate } 674*7c478bd9Sstevel@tonic-gate } /* handle_dcgettext */ 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gate /* 677*7c478bd9Sstevel@tonic-gate * Handler for "textdomain" in input file. 678*7c478bd9Sstevel@tonic-gate */ 679*7c478bd9Sstevel@tonic-gate void 680*7c478bd9Sstevel@tonic-gate handle_textdomain(void) 681*7c478bd9Sstevel@tonic-gate { 682*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 683*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 684*7c478bd9Sstevel@tonic-gate 685*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 686*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 687*7c478bd9Sstevel@tonic-gate } else if (in_comment == FALSE) { 688*7c478bd9Sstevel@tonic-gate in_textdomain = TRUE; 689*7c478bd9Sstevel@tonic-gate linenum_saved = curr_linenum; 690*7c478bd9Sstevel@tonic-gate curr_domain[0] = NULL; 691*7c478bd9Sstevel@tonic-gate } 692*7c478bd9Sstevel@tonic-gate } /* handle_textdomain */ 693*7c478bd9Sstevel@tonic-gate 694*7c478bd9Sstevel@tonic-gate /* 695*7c478bd9Sstevel@tonic-gate * Handler for '(' in input file. 696*7c478bd9Sstevel@tonic-gate */ 697*7c478bd9Sstevel@tonic-gate void 698*7c478bd9Sstevel@tonic-gate handle_open_paren(void) 699*7c478bd9Sstevel@tonic-gate { 700*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 701*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 702*7c478bd9Sstevel@tonic-gate 703*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 704*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 705*7c478bd9Sstevel@tonic-gate } else if (in_comment == FALSE) { 706*7c478bd9Sstevel@tonic-gate if ((in_gettext == TRUE) || 707*7c478bd9Sstevel@tonic-gate (in_dgettext == TRUE) || 708*7c478bd9Sstevel@tonic-gate (in_dcgettext == TRUE) || 709*7c478bd9Sstevel@tonic-gate (in_textdomain == TRUE)) { 710*7c478bd9Sstevel@tonic-gate in_str = TRUE; 711*7c478bd9Sstevel@tonic-gate num_nested_open_paren++; 712*7c478bd9Sstevel@tonic-gate } 713*7c478bd9Sstevel@tonic-gate } 714*7c478bd9Sstevel@tonic-gate } /* handle_open_paren */ 715*7c478bd9Sstevel@tonic-gate 716*7c478bd9Sstevel@tonic-gate /* 717*7c478bd9Sstevel@tonic-gate * Handler for ')' in input file. 718*7c478bd9Sstevel@tonic-gate */ 719*7c478bd9Sstevel@tonic-gate void 720*7c478bd9Sstevel@tonic-gate handle_close_paren(void) 721*7c478bd9Sstevel@tonic-gate { 722*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 723*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 724*7c478bd9Sstevel@tonic-gate 725*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 726*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 727*7c478bd9Sstevel@tonic-gate } else if (in_comment == FALSE) { 728*7c478bd9Sstevel@tonic-gate if ((in_gettext == TRUE) || 729*7c478bd9Sstevel@tonic-gate (in_dgettext == TRUE) || 730*7c478bd9Sstevel@tonic-gate (in_dcgettext == TRUE) || 731*7c478bd9Sstevel@tonic-gate (in_textdomain == TRUE)) { 732*7c478bd9Sstevel@tonic-gate /* 733*7c478bd9Sstevel@tonic-gate * If this is not the matching close paren with 734*7c478bd9Sstevel@tonic-gate * the first open paren, no action is necessary. 735*7c478bd9Sstevel@tonic-gate */ 736*7c478bd9Sstevel@tonic-gate if (--num_nested_open_paren > 0) 737*7c478bd9Sstevel@tonic-gate return; 738*7c478bd9Sstevel@tonic-gate add_str_to_element_list(in_textdomain, curr_domain); 739*7c478bd9Sstevel@tonic-gate in_str = FALSE; 740*7c478bd9Sstevel@tonic-gate in_gettext = FALSE; 741*7c478bd9Sstevel@tonic-gate in_dgettext = FALSE; 742*7c478bd9Sstevel@tonic-gate in_dcgettext = FALSE; 743*7c478bd9Sstevel@tonic-gate in_textdomain = FALSE; 744*7c478bd9Sstevel@tonic-gate } else if (aflg == TRUE) { 745*7c478bd9Sstevel@tonic-gate end_ansi_string(); 746*7c478bd9Sstevel@tonic-gate } 747*7c478bd9Sstevel@tonic-gate } 748*7c478bd9Sstevel@tonic-gate } /* handle_close_paren */ 749*7c478bd9Sstevel@tonic-gate 750*7c478bd9Sstevel@tonic-gate /* 751*7c478bd9Sstevel@tonic-gate * Handler for '\\n' in input file. 752*7c478bd9Sstevel@tonic-gate * 753*7c478bd9Sstevel@tonic-gate * This is a '\' followed by new line. 754*7c478bd9Sstevel@tonic-gate * This can be treated like a new line except when this is a continuation 755*7c478bd9Sstevel@tonic-gate * of a ANSI-C string. 756*7c478bd9Sstevel@tonic-gate * If this is a part of ANSI string, treat the current line as a double 757*7c478bd9Sstevel@tonic-gate * quoted string and the next line is the start of the double quoted 758*7c478bd9Sstevel@tonic-gate * string. 759*7c478bd9Sstevel@tonic-gate */ 760*7c478bd9Sstevel@tonic-gate void 761*7c478bd9Sstevel@tonic-gate handle_esc_newline(void) 762*7c478bd9Sstevel@tonic-gate { 763*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 764*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, "\\"); 765*7c478bd9Sstevel@tonic-gate 766*7c478bd9Sstevel@tonic-gate curr_linenum++; 767*7c478bd9Sstevel@tonic-gate 768*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 769*7c478bd9Sstevel@tonic-gate add_qstring_to_str(); 770*7c478bd9Sstevel@tonic-gate } else if ((in_comment == TRUE) || 771*7c478bd9Sstevel@tonic-gate (is_last_comment_line == TRUE)) { 772*7c478bd9Sstevel@tonic-gate if (in_cplus_comment == FALSE) { 773*7c478bd9Sstevel@tonic-gate add_line_to_comment(); 774*7c478bd9Sstevel@tonic-gate } 775*7c478bd9Sstevel@tonic-gate } 776*7c478bd9Sstevel@tonic-gate 777*7c478bd9Sstevel@tonic-gate curr_line[0] = NULL; 778*7c478bd9Sstevel@tonic-gate } /* handle_esc_newline */ 779*7c478bd9Sstevel@tonic-gate 780*7c478bd9Sstevel@tonic-gate /* 781*7c478bd9Sstevel@tonic-gate * Handler for '"' in input file. 782*7c478bd9Sstevel@tonic-gate */ 783*7c478bd9Sstevel@tonic-gate void 784*7c478bd9Sstevel@tonic-gate handle_quote(void) 785*7c478bd9Sstevel@tonic-gate { 786*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 787*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate if (in_comment == TRUE) { 790*7c478bd9Sstevel@tonic-gate /*EMPTY*/ 791*7c478bd9Sstevel@tonic-gate } else if ((in_gettext == TRUE) || 792*7c478bd9Sstevel@tonic-gate (in_dgettext == TRUE) || 793*7c478bd9Sstevel@tonic-gate (in_dcgettext == TRUE) || 794*7c478bd9Sstevel@tonic-gate (in_textdomain == TRUE)) { 795*7c478bd9Sstevel@tonic-gate if (in_str == TRUE) { 796*7c478bd9Sstevel@tonic-gate if (in_quote == FALSE) { 797*7c478bd9Sstevel@tonic-gate in_quote = TRUE; 798*7c478bd9Sstevel@tonic-gate } else { 799*7c478bd9Sstevel@tonic-gate add_qstring_to_str(); 800*7c478bd9Sstevel@tonic-gate in_quote = FALSE; 801*7c478bd9Sstevel@tonic-gate } 802*7c478bd9Sstevel@tonic-gate } 803*7c478bd9Sstevel@tonic-gate } else if (aflg == TRUE) { 804*7c478bd9Sstevel@tonic-gate /* 805*7c478bd9Sstevel@tonic-gate * The quote is found outside of gettext, dgetext, and 806*7c478bd9Sstevel@tonic-gate * textdomain. Everytime a quoted string is found, 807*7c478bd9Sstevel@tonic-gate * add it to the string list. 808*7c478bd9Sstevel@tonic-gate * in_str stays TRUE until ANSI string ends. 809*7c478bd9Sstevel@tonic-gate */ 810*7c478bd9Sstevel@tonic-gate if (in_str == TRUE) { 811*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 812*7c478bd9Sstevel@tonic-gate in_quote = FALSE; 813*7c478bd9Sstevel@tonic-gate add_qstring_to_str(); 814*7c478bd9Sstevel@tonic-gate } else { 815*7c478bd9Sstevel@tonic-gate in_quote = TRUE; 816*7c478bd9Sstevel@tonic-gate } 817*7c478bd9Sstevel@tonic-gate } else { 818*7c478bd9Sstevel@tonic-gate in_str = TRUE; 819*7c478bd9Sstevel@tonic-gate in_quote = TRUE; 820*7c478bd9Sstevel@tonic-gate linenum_saved = curr_linenum; 821*7c478bd9Sstevel@tonic-gate } 822*7c478bd9Sstevel@tonic-gate } else { 823*7c478bd9Sstevel@tonic-gate in_skippable_string = (in_skippable_string == TRUE) ? 824*7c478bd9Sstevel@tonic-gate FALSE : TRUE; 825*7c478bd9Sstevel@tonic-gate } 826*7c478bd9Sstevel@tonic-gate } /* handle_quote */ 827*7c478bd9Sstevel@tonic-gate 828*7c478bd9Sstevel@tonic-gate /* 829*7c478bd9Sstevel@tonic-gate * Handler for ' ' or TAB in input file. 830*7c478bd9Sstevel@tonic-gate */ 831*7c478bd9Sstevel@tonic-gate void 832*7c478bd9Sstevel@tonic-gate handle_spaces(void) 833*7c478bd9Sstevel@tonic-gate { 834*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 835*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 836*7c478bd9Sstevel@tonic-gate 837*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 838*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 839*7c478bd9Sstevel@tonic-gate } 840*7c478bd9Sstevel@tonic-gate } /* handle_spaces */ 841*7c478bd9Sstevel@tonic-gate 842*7c478bd9Sstevel@tonic-gate /* 843*7c478bd9Sstevel@tonic-gate * Flattens a linked list containing ANSI string to the one string. 844*7c478bd9Sstevel@tonic-gate */ 845*7c478bd9Sstevel@tonic-gate static void 846*7c478bd9Sstevel@tonic-gate copy_strlist_to_str(char *str, struct strlist_st *strlist) 847*7c478bd9Sstevel@tonic-gate { 848*7c478bd9Sstevel@tonic-gate struct strlist_st *p; 849*7c478bd9Sstevel@tonic-gate 850*7c478bd9Sstevel@tonic-gate str[0] = NULL; 851*7c478bd9Sstevel@tonic-gate 852*7c478bd9Sstevel@tonic-gate if (strlist != NULL) { 853*7c478bd9Sstevel@tonic-gate p = strlist; 854*7c478bd9Sstevel@tonic-gate while (p != NULL) { 855*7c478bd9Sstevel@tonic-gate if (p->str != NULL) { 856*7c478bd9Sstevel@tonic-gate lstrcat(str, p->str); 857*7c478bd9Sstevel@tonic-gate } 858*7c478bd9Sstevel@tonic-gate p = p->next; 859*7c478bd9Sstevel@tonic-gate } 860*7c478bd9Sstevel@tonic-gate } 861*7c478bd9Sstevel@tonic-gate } /* copy_strlist_to_str */ 862*7c478bd9Sstevel@tonic-gate 863*7c478bd9Sstevel@tonic-gate /* 864*7c478bd9Sstevel@tonic-gate * Handler for ',' in input file. 865*7c478bd9Sstevel@tonic-gate */ 866*7c478bd9Sstevel@tonic-gate void 867*7c478bd9Sstevel@tonic-gate handle_comma(void) 868*7c478bd9Sstevel@tonic-gate { 869*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 870*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 871*7c478bd9Sstevel@tonic-gate 872*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 873*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 874*7c478bd9Sstevel@tonic-gate } else if (in_comment == FALSE) { 875*7c478bd9Sstevel@tonic-gate if (in_str == TRUE) { 876*7c478bd9Sstevel@tonic-gate if (in_dgettext == TRUE) { 877*7c478bd9Sstevel@tonic-gate copy_strlist_to_str(curr_domain, strhead); 878*7c478bd9Sstevel@tonic-gate free_strlist(strhead); 879*7c478bd9Sstevel@tonic-gate strhead = strtail = NULL; 880*7c478bd9Sstevel@tonic-gate } else if (in_dcgettext == TRUE) { 881*7c478bd9Sstevel@tonic-gate /* 882*7c478bd9Sstevel@tonic-gate * Ignore the second comma. 883*7c478bd9Sstevel@tonic-gate */ 884*7c478bd9Sstevel@tonic-gate if (is_first_comma_found == FALSE) { 885*7c478bd9Sstevel@tonic-gate copy_strlist_to_str(curr_domain, 886*7c478bd9Sstevel@tonic-gate strhead); 887*7c478bd9Sstevel@tonic-gate free_strlist(strhead); 888*7c478bd9Sstevel@tonic-gate strhead = strtail = NULL; 889*7c478bd9Sstevel@tonic-gate is_first_comma_found = TRUE; 890*7c478bd9Sstevel@tonic-gate } 891*7c478bd9Sstevel@tonic-gate } else if (aflg == TRUE) { 892*7c478bd9Sstevel@tonic-gate end_ansi_string(); 893*7c478bd9Sstevel@tonic-gate } 894*7c478bd9Sstevel@tonic-gate } 895*7c478bd9Sstevel@tonic-gate } 896*7c478bd9Sstevel@tonic-gate } /* handle_comma */ 897*7c478bd9Sstevel@tonic-gate 898*7c478bd9Sstevel@tonic-gate /* 899*7c478bd9Sstevel@tonic-gate * Handler for any other character that does not have special handler. 900*7c478bd9Sstevel@tonic-gate */ 901*7c478bd9Sstevel@tonic-gate void 902*7c478bd9Sstevel@tonic-gate handle_character(void) 903*7c478bd9Sstevel@tonic-gate { 904*7c478bd9Sstevel@tonic-gate if (cflg == TRUE) 905*7c478bd9Sstevel@tonic-gate lstrcat(curr_line, yytext); 906*7c478bd9Sstevel@tonic-gate 907*7c478bd9Sstevel@tonic-gate if (in_quote == TRUE) { 908*7c478bd9Sstevel@tonic-gate lstrcat(qstring_buf, yytext); 909*7c478bd9Sstevel@tonic-gate } else if (in_comment == FALSE) { 910*7c478bd9Sstevel@tonic-gate if (in_str == TRUE) { 911*7c478bd9Sstevel@tonic-gate if (aflg == TRUE) { 912*7c478bd9Sstevel@tonic-gate end_ansi_string(); 913*7c478bd9Sstevel@tonic-gate } 914*7c478bd9Sstevel@tonic-gate } 915*7c478bd9Sstevel@tonic-gate } 916*7c478bd9Sstevel@tonic-gate } /* handle_character */ 917*7c478bd9Sstevel@tonic-gate 918*7c478bd9Sstevel@tonic-gate /* 919*7c478bd9Sstevel@tonic-gate * Handler for new line in input file. 920*7c478bd9Sstevel@tonic-gate */ 921*7c478bd9Sstevel@tonic-gate void 922*7c478bd9Sstevel@tonic-gate handle_newline(void) 923*7c478bd9Sstevel@tonic-gate { 924*7c478bd9Sstevel@tonic-gate curr_linenum++; 925*7c478bd9Sstevel@tonic-gate 926*7c478bd9Sstevel@tonic-gate /* 927*7c478bd9Sstevel@tonic-gate * in_quote is always FALSE here for ANSI-C code. 928*7c478bd9Sstevel@tonic-gate */ 929*7c478bd9Sstevel@tonic-gate if ((in_comment == TRUE) || 930*7c478bd9Sstevel@tonic-gate (is_last_comment_line == TRUE)) { 931*7c478bd9Sstevel@tonic-gate if (in_cplus_comment == TRUE) { 932*7c478bd9Sstevel@tonic-gate in_cplus_comment = FALSE; 933*7c478bd9Sstevel@tonic-gate in_comment = FALSE; 934*7c478bd9Sstevel@tonic-gate } else { 935*7c478bd9Sstevel@tonic-gate add_line_to_comment(); 936*7c478bd9Sstevel@tonic-gate } 937*7c478bd9Sstevel@tonic-gate } 938*7c478bd9Sstevel@tonic-gate 939*7c478bd9Sstevel@tonic-gate curr_line[0] = NULL; 940*7c478bd9Sstevel@tonic-gate /* 941*7c478bd9Sstevel@tonic-gate * C++ comment always ends with new line. 942*7c478bd9Sstevel@tonic-gate */ 943*7c478bd9Sstevel@tonic-gate } /* handle_newline */ 944*7c478bd9Sstevel@tonic-gate 945*7c478bd9Sstevel@tonic-gate /* 946*7c478bd9Sstevel@tonic-gate * Process ANSI string. 947*7c478bd9Sstevel@tonic-gate */ 948*7c478bd9Sstevel@tonic-gate static void 949*7c478bd9Sstevel@tonic-gate end_ansi_string(void) 950*7c478bd9Sstevel@tonic-gate { 951*7c478bd9Sstevel@tonic-gate if ((aflg == TRUE) && 952*7c478bd9Sstevel@tonic-gate (in_str == TRUE) && 953*7c478bd9Sstevel@tonic-gate (in_gettext == FALSE) && 954*7c478bd9Sstevel@tonic-gate (in_dgettext == FALSE) && 955*7c478bd9Sstevel@tonic-gate (in_dcgettext == FALSE) && 956*7c478bd9Sstevel@tonic-gate (in_textdomain == FALSE)) { 957*7c478bd9Sstevel@tonic-gate add_str_to_element_list(FALSE, curr_domain); 958*7c478bd9Sstevel@tonic-gate in_str = FALSE; 959*7c478bd9Sstevel@tonic-gate } 960*7c478bd9Sstevel@tonic-gate } /* end_ansi_string */ 961*7c478bd9Sstevel@tonic-gate 962*7c478bd9Sstevel@tonic-gate /* 963*7c478bd9Sstevel@tonic-gate * Initialize global variables if necessary. 964*7c478bd9Sstevel@tonic-gate */ 965*7c478bd9Sstevel@tonic-gate static void 966*7c478bd9Sstevel@tonic-gate initialize_globals(void) 967*7c478bd9Sstevel@tonic-gate { 968*7c478bd9Sstevel@tonic-gate default_domain = strdup(DEFAULT_DOMAIN); 969*7c478bd9Sstevel@tonic-gate curr_domain[0] = NULL; 970*7c478bd9Sstevel@tonic-gate curr_file[0] = NULL; 971*7c478bd9Sstevel@tonic-gate qstring_buf[0] = NULL; 972*7c478bd9Sstevel@tonic-gate } /* initialize_globals() */ 973*7c478bd9Sstevel@tonic-gate 974*7c478bd9Sstevel@tonic-gate /* 975*7c478bd9Sstevel@tonic-gate * Extract only string part when read a exclude file by removing 976*7c478bd9Sstevel@tonic-gate * keywords (e.g. msgid, msgstr, # ) and heading and trailing blanks and 977*7c478bd9Sstevel@tonic-gate * double quotes. 978*7c478bd9Sstevel@tonic-gate */ 979*7c478bd9Sstevel@tonic-gate static void 980*7c478bd9Sstevel@tonic-gate trim_line(char *line) 981*7c478bd9Sstevel@tonic-gate { 982*7c478bd9Sstevel@tonic-gate int i, p, len; 983*7c478bd9Sstevel@tonic-gate int first = 0; 984*7c478bd9Sstevel@tonic-gate int last = 0; 985*7c478bd9Sstevel@tonic-gate char c; 986*7c478bd9Sstevel@tonic-gate 987*7c478bd9Sstevel@tonic-gate len = strlen(line); 988*7c478bd9Sstevel@tonic-gate 989*7c478bd9Sstevel@tonic-gate /* 990*7c478bd9Sstevel@tonic-gate * Find the position of the last non-whitespace character. 991*7c478bd9Sstevel@tonic-gate */ 992*7c478bd9Sstevel@tonic-gate i = len - 1; 993*7c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 994*7c478bd9Sstevel@tonic-gate while (1) { 995*7c478bd9Sstevel@tonic-gate c = line[i--]; 996*7c478bd9Sstevel@tonic-gate if ((c != ' ') && (c != '\n') && (c != '\t')) { 997*7c478bd9Sstevel@tonic-gate last = ++i; 998*7c478bd9Sstevel@tonic-gate break; 999*7c478bd9Sstevel@tonic-gate } 1000*7c478bd9Sstevel@tonic-gate } 1001*7c478bd9Sstevel@tonic-gate 1002*7c478bd9Sstevel@tonic-gate /* 1003*7c478bd9Sstevel@tonic-gate * Find the position of the first non-whitespace character 1004*7c478bd9Sstevel@tonic-gate * by skipping "msgid" initially. 1005*7c478bd9Sstevel@tonic-gate */ 1006*7c478bd9Sstevel@tonic-gate if (strncmp("msgid ", line, 6) == 0) { 1007*7c478bd9Sstevel@tonic-gate i = 5; 1008*7c478bd9Sstevel@tonic-gate } else if (strncmp("msgstr ", line, 7) == 0) { 1009*7c478bd9Sstevel@tonic-gate i = 6; 1010*7c478bd9Sstevel@tonic-gate } else if (strncmp("# ", line, 2) == 0) { 1011*7c478bd9Sstevel@tonic-gate i = 2; 1012*7c478bd9Sstevel@tonic-gate } else { 1013*7c478bd9Sstevel@tonic-gate i = 0; 1014*7c478bd9Sstevel@tonic-gate } 1015*7c478bd9Sstevel@tonic-gate 1016*7c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 1017*7c478bd9Sstevel@tonic-gate while (1) { 1018*7c478bd9Sstevel@tonic-gate c = line[i++]; 1019*7c478bd9Sstevel@tonic-gate if ((c != ' ') && (c != '\n') && (c != '\t')) { 1020*7c478bd9Sstevel@tonic-gate first = --i; 1021*7c478bd9Sstevel@tonic-gate break; 1022*7c478bd9Sstevel@tonic-gate } 1023*7c478bd9Sstevel@tonic-gate } 1024*7c478bd9Sstevel@tonic-gate 1025*7c478bd9Sstevel@tonic-gate /* 1026*7c478bd9Sstevel@tonic-gate * For Backward compatibility, we consider both double quoted 1027*7c478bd9Sstevel@tonic-gate * string and non-quoted string. 1028*7c478bd9Sstevel@tonic-gate * The double quote is removed before being stored if exists. 1029*7c478bd9Sstevel@tonic-gate */ 1030*7c478bd9Sstevel@tonic-gate if (line[first] == '"') { 1031*7c478bd9Sstevel@tonic-gate first++; 1032*7c478bd9Sstevel@tonic-gate } 1033*7c478bd9Sstevel@tonic-gate if (line[last] == '"') { 1034*7c478bd9Sstevel@tonic-gate last--; 1035*7c478bd9Sstevel@tonic-gate } 1036*7c478bd9Sstevel@tonic-gate 1037*7c478bd9Sstevel@tonic-gate /* 1038*7c478bd9Sstevel@tonic-gate * Now copy the valid part of the string. 1039*7c478bd9Sstevel@tonic-gate */ 1040*7c478bd9Sstevel@tonic-gate p = first; 1041*7c478bd9Sstevel@tonic-gate for (i = 0; i <= (last-first); i++) { 1042*7c478bd9Sstevel@tonic-gate line[i] = line[p++]; 1043*7c478bd9Sstevel@tonic-gate } 1044*7c478bd9Sstevel@tonic-gate line [i] = NULL; 1045*7c478bd9Sstevel@tonic-gate } /* trim_line */ 1046*7c478bd9Sstevel@tonic-gate 1047*7c478bd9Sstevel@tonic-gate /* 1048*7c478bd9Sstevel@tonic-gate * Read exclude file and stores it in the global linked list. 1049*7c478bd9Sstevel@tonic-gate */ 1050*7c478bd9Sstevel@tonic-gate static void 1051*7c478bd9Sstevel@tonic-gate read_exclude_file(void) 1052*7c478bd9Sstevel@tonic-gate { 1053*7c478bd9Sstevel@tonic-gate FILE *fp; 1054*7c478bd9Sstevel@tonic-gate struct exclude_st *tmp_excl; 1055*7c478bd9Sstevel@tonic-gate struct strlist_st *tail; 1056*7c478bd9Sstevel@tonic-gate int ignore_line; 1057*7c478bd9Sstevel@tonic-gate char line [MAX_STRING_LEN]; 1058*7c478bd9Sstevel@tonic-gate 1059*7c478bd9Sstevel@tonic-gate if ((fp = fopen(exclude_file, "r")) == NULL) { 1060*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "ERROR, can't open exclude file: %s\n", 1061*7c478bd9Sstevel@tonic-gate exclude_file); 1062*7c478bd9Sstevel@tonic-gate exit(2); 1063*7c478bd9Sstevel@tonic-gate } 1064*7c478bd9Sstevel@tonic-gate 1065*7c478bd9Sstevel@tonic-gate ignore_line = TRUE; 1066*7c478bd9Sstevel@tonic-gate while (fgets(line, MAX_STRING_LEN, fp) != NULL) { 1067*7c478bd9Sstevel@tonic-gate /* 1068*7c478bd9Sstevel@tonic-gate * Line starting with # is a comment line and ignored. 1069*7c478bd9Sstevel@tonic-gate * Blank line is ignored, too. 1070*7c478bd9Sstevel@tonic-gate */ 1071*7c478bd9Sstevel@tonic-gate if ((line[0] == '\n') || (line[0] == '#')) { 1072*7c478bd9Sstevel@tonic-gate continue; 1073*7c478bd9Sstevel@tonic-gate } else if (strncmp(line, "msgstr", 6) == 0) { 1074*7c478bd9Sstevel@tonic-gate ignore_line = TRUE; 1075*7c478bd9Sstevel@tonic-gate } else if (strncmp(line, "domain", 6) == 0) { 1076*7c478bd9Sstevel@tonic-gate ignore_line = TRUE; 1077*7c478bd9Sstevel@tonic-gate } else if (strncmp(line, "msgid", 5) == 0) { 1078*7c478bd9Sstevel@tonic-gate ignore_line = FALSE; 1079*7c478bd9Sstevel@tonic-gate tmp_excl = new_exclude(); 1080*7c478bd9Sstevel@tonic-gate tmp_excl->exstr = new_strlist(); 1081*7c478bd9Sstevel@tonic-gate trim_line(line); 1082*7c478bd9Sstevel@tonic-gate tmp_excl->exstr->str = strdup(line); 1083*7c478bd9Sstevel@tonic-gate tail = tmp_excl->exstr; 1084*7c478bd9Sstevel@tonic-gate /* 1085*7c478bd9Sstevel@tonic-gate * Prepend new exclude string node to the list. 1086*7c478bd9Sstevel@tonic-gate */ 1087*7c478bd9Sstevel@tonic-gate tmp_excl->next = excl_head; 1088*7c478bd9Sstevel@tonic-gate excl_head = tmp_excl; 1089*7c478bd9Sstevel@tonic-gate } else { 1090*7c478bd9Sstevel@tonic-gate /* 1091*7c478bd9Sstevel@tonic-gate * If more than one line of string forms msgid, 1092*7c478bd9Sstevel@tonic-gate * append it to the string linked list. 1093*7c478bd9Sstevel@tonic-gate */ 1094*7c478bd9Sstevel@tonic-gate if (ignore_line == FALSE) { 1095*7c478bd9Sstevel@tonic-gate trim_line(line); 1096*7c478bd9Sstevel@tonic-gate tail->next = new_strlist(); 1097*7c478bd9Sstevel@tonic-gate tail->next->str = strdup(line); 1098*7c478bd9Sstevel@tonic-gate tail = tail->next; 1099*7c478bd9Sstevel@tonic-gate } 1100*7c478bd9Sstevel@tonic-gate } 1101*7c478bd9Sstevel@tonic-gate } /* while */ 1102*7c478bd9Sstevel@tonic-gate 1103*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 1104*7c478bd9Sstevel@tonic-gate tmp_excl = excl_head; 1105*7c478bd9Sstevel@tonic-gate while (tmp_excl != NULL) { 1106*7c478bd9Sstevel@tonic-gate printf("============================\n"); 1107*7c478bd9Sstevel@tonic-gate tail = tmp_excl->exstr; 1108*7c478bd9Sstevel@tonic-gate while (tail != NULL) { 1109*7c478bd9Sstevel@tonic-gate printf("%s###\n", tail->str); 1110*7c478bd9Sstevel@tonic-gate tail = tail->next; 1111*7c478bd9Sstevel@tonic-gate } 1112*7c478bd9Sstevel@tonic-gate tmp_excl = tmp_excl->next; 1113*7c478bd9Sstevel@tonic-gate } 1114*7c478bd9Sstevel@tonic-gate #endif 1115*7c478bd9Sstevel@tonic-gate } /* read_exclude_file */ 1116*7c478bd9Sstevel@tonic-gate 1117*7c478bd9Sstevel@tonic-gate /* 1118*7c478bd9Sstevel@tonic-gate * Get next character from the string list containing ANSI style string. 1119*7c478bd9Sstevel@tonic-gate * This function returns three valus. (p, *m, *c). 1120*7c478bd9Sstevel@tonic-gate * p is returned by return value and, *m and *c are returned by changing 1121*7c478bd9Sstevel@tonic-gate * values in the location pointed. 1122*7c478bd9Sstevel@tonic-gate * 1123*7c478bd9Sstevel@tonic-gate * p : points node in the linked list for ANSI string. 1124*7c478bd9Sstevel@tonic-gate * Each node contains double quoted string. 1125*7c478bd9Sstevel@tonic-gate * m : The location of the next characters in the double quoted string 1126*7c478bd9Sstevel@tonic-gate * as integer index in the string. 1127*7c478bd9Sstevel@tonic-gate * When it gets to end of quoted string, the next node will be 1128*7c478bd9Sstevel@tonic-gate * read and m starts as zero for every new node. 1129*7c478bd9Sstevel@tonic-gate * c : Stores the value of the characterto be returned. 1130*7c478bd9Sstevel@tonic-gate */ 1131*7c478bd9Sstevel@tonic-gate static struct strlist_st * 1132*7c478bd9Sstevel@tonic-gate get_next_ch(struct strlist_st *p, int *m, char *c) 1133*7c478bd9Sstevel@tonic-gate { 1134*7c478bd9Sstevel@tonic-gate char ch, oct, hex; 1135*7c478bd9Sstevel@tonic-gate int value, i; 1136*7c478bd9Sstevel@tonic-gate 1137*7c478bd9Sstevel@tonic-gate /* 1138*7c478bd9Sstevel@tonic-gate * From the string list, find non-null string first. 1139*7c478bd9Sstevel@tonic-gate */ 1140*7c478bd9Sstevel@tonic-gate 1141*7c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 1142*7c478bd9Sstevel@tonic-gate while (1) { 1143*7c478bd9Sstevel@tonic-gate if (p == NULL) { 1144*7c478bd9Sstevel@tonic-gate break; 1145*7c478bd9Sstevel@tonic-gate } else if (p->str == NULL) { 1146*7c478bd9Sstevel@tonic-gate p = p->next; 1147*7c478bd9Sstevel@tonic-gate } else if (p->str[*m] == NULL) { 1148*7c478bd9Sstevel@tonic-gate p = p->next; 1149*7c478bd9Sstevel@tonic-gate *m = 0; 1150*7c478bd9Sstevel@tonic-gate } else { 1151*7c478bd9Sstevel@tonic-gate break; 1152*7c478bd9Sstevel@tonic-gate } 1153*7c478bd9Sstevel@tonic-gate } 1154*7c478bd9Sstevel@tonic-gate 1155*7c478bd9Sstevel@tonic-gate /* 1156*7c478bd9Sstevel@tonic-gate * No more character is available. 1157*7c478bd9Sstevel@tonic-gate */ 1158*7c478bd9Sstevel@tonic-gate if (p == NULL) { 1159*7c478bd9Sstevel@tonic-gate *c = 0; 1160*7c478bd9Sstevel@tonic-gate return (NULL); 1161*7c478bd9Sstevel@tonic-gate } 1162*7c478bd9Sstevel@tonic-gate 1163*7c478bd9Sstevel@tonic-gate /* 1164*7c478bd9Sstevel@tonic-gate * Check if the character back slash. 1165*7c478bd9Sstevel@tonic-gate * If yes, ANSI defined escape sequence rule is used. 1166*7c478bd9Sstevel@tonic-gate */ 1167*7c478bd9Sstevel@tonic-gate if (p->str[*m] != '\\') { 1168*7c478bd9Sstevel@tonic-gate *c = p->str[*m]; 1169*7c478bd9Sstevel@tonic-gate *m = *m + 1; 1170*7c478bd9Sstevel@tonic-gate return (p); 1171*7c478bd9Sstevel@tonic-gate } else { 1172*7c478bd9Sstevel@tonic-gate /* 1173*7c478bd9Sstevel@tonic-gate * Get next character after '\'. 1174*7c478bd9Sstevel@tonic-gate */ 1175*7c478bd9Sstevel@tonic-gate *m = *m + 1; 1176*7c478bd9Sstevel@tonic-gate ch = p->str[*m]; 1177*7c478bd9Sstevel@tonic-gate switch (ch) { 1178*7c478bd9Sstevel@tonic-gate case 'a': 1179*7c478bd9Sstevel@tonic-gate *c = '\a'; 1180*7c478bd9Sstevel@tonic-gate break; 1181*7c478bd9Sstevel@tonic-gate case 'b': 1182*7c478bd9Sstevel@tonic-gate *c = '\b'; 1183*7c478bd9Sstevel@tonic-gate break; 1184*7c478bd9Sstevel@tonic-gate case 'f': 1185*7c478bd9Sstevel@tonic-gate *c = '\f'; 1186*7c478bd9Sstevel@tonic-gate break; 1187*7c478bd9Sstevel@tonic-gate case 'n': 1188*7c478bd9Sstevel@tonic-gate *c = '\n'; 1189*7c478bd9Sstevel@tonic-gate break; 1190*7c478bd9Sstevel@tonic-gate case 'r': 1191*7c478bd9Sstevel@tonic-gate *c = '\r'; 1192*7c478bd9Sstevel@tonic-gate break; 1193*7c478bd9Sstevel@tonic-gate case 't': 1194*7c478bd9Sstevel@tonic-gate *c = '\t'; 1195*7c478bd9Sstevel@tonic-gate break; 1196*7c478bd9Sstevel@tonic-gate case 'v': 1197*7c478bd9Sstevel@tonic-gate *c = '\v'; 1198*7c478bd9Sstevel@tonic-gate break; 1199*7c478bd9Sstevel@tonic-gate case '0': 1200*7c478bd9Sstevel@tonic-gate case '1': 1201*7c478bd9Sstevel@tonic-gate case '2': 1202*7c478bd9Sstevel@tonic-gate case '3': 1203*7c478bd9Sstevel@tonic-gate case '4': 1204*7c478bd9Sstevel@tonic-gate case '5': 1205*7c478bd9Sstevel@tonic-gate case '6': 1206*7c478bd9Sstevel@tonic-gate case '7': 1207*7c478bd9Sstevel@tonic-gate /* 1208*7c478bd9Sstevel@tonic-gate * Get maximum of three octal digits. 1209*7c478bd9Sstevel@tonic-gate */ 1210*7c478bd9Sstevel@tonic-gate value = ch; 1211*7c478bd9Sstevel@tonic-gate for (i = 0; i < 2; i++) { 1212*7c478bd9Sstevel@tonic-gate *m = *m + 1; 1213*7c478bd9Sstevel@tonic-gate oct = p->str[*m]; 1214*7c478bd9Sstevel@tonic-gate if ((oct >= '0') && (oct <= '7')) { 1215*7c478bd9Sstevel@tonic-gate value = value * 8 + (oct - '0'); 1216*7c478bd9Sstevel@tonic-gate } else { 1217*7c478bd9Sstevel@tonic-gate *m = *m - 1; 1218*7c478bd9Sstevel@tonic-gate break; 1219*7c478bd9Sstevel@tonic-gate } 1220*7c478bd9Sstevel@tonic-gate } 1221*7c478bd9Sstevel@tonic-gate *c = value; 1222*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 1223*7c478bd9Sstevel@tonic-gate /* (void) fprintf(stderr, "octal=%d\n", value); */ 1224*7c478bd9Sstevel@tonic-gate #endif 1225*7c478bd9Sstevel@tonic-gate break; 1226*7c478bd9Sstevel@tonic-gate case 'x': 1227*7c478bd9Sstevel@tonic-gate value = 0; 1228*7c478bd9Sstevel@tonic-gate /* 1229*7c478bd9Sstevel@tonic-gate * Remove all heading zeros first and 1230*7c478bd9Sstevel@tonic-gate * get one or two valuid hexadecimal charaters. 1231*7c478bd9Sstevel@tonic-gate */ 1232*7c478bd9Sstevel@tonic-gate *m = *m + 1; 1233*7c478bd9Sstevel@tonic-gate while (p->str[*m] == '0') { 1234*7c478bd9Sstevel@tonic-gate *m = *m + 1; 1235*7c478bd9Sstevel@tonic-gate } 1236*7c478bd9Sstevel@tonic-gate value = 0; 1237*7c478bd9Sstevel@tonic-gate for (i = 0; i < 2; i++) { 1238*7c478bd9Sstevel@tonic-gate hex = p->str[*m]; 1239*7c478bd9Sstevel@tonic-gate *m = *m + 1; 1240*7c478bd9Sstevel@tonic-gate if (isdigit(hex)) { 1241*7c478bd9Sstevel@tonic-gate value = value * 16 + (hex - '0'); 1242*7c478bd9Sstevel@tonic-gate } else if (isxdigit(hex)) { 1243*7c478bd9Sstevel@tonic-gate hex = tolower(hex); 1244*7c478bd9Sstevel@tonic-gate value = value * 16 + (hex - 'a' + 10); 1245*7c478bd9Sstevel@tonic-gate } else { 1246*7c478bd9Sstevel@tonic-gate *m = *m - 1; 1247*7c478bd9Sstevel@tonic-gate break; 1248*7c478bd9Sstevel@tonic-gate } 1249*7c478bd9Sstevel@tonic-gate } 1250*7c478bd9Sstevel@tonic-gate *c = value; 1251*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 1252*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "hex=%d\n", value); 1253*7c478bd9Sstevel@tonic-gate #endif 1254*7c478bd9Sstevel@tonic-gate *m = *m - 1; 1255*7c478bd9Sstevel@tonic-gate break; 1256*7c478bd9Sstevel@tonic-gate default : 1257*7c478bd9Sstevel@tonic-gate /* 1258*7c478bd9Sstevel@tonic-gate * Undefined by ANSI. 1259*7c478bd9Sstevel@tonic-gate * Just ignore "\". 1260*7c478bd9Sstevel@tonic-gate */ 1261*7c478bd9Sstevel@tonic-gate *c = p->str[*m]; 1262*7c478bd9Sstevel@tonic-gate break; 1263*7c478bd9Sstevel@tonic-gate } 1264*7c478bd9Sstevel@tonic-gate /* 1265*7c478bd9Sstevel@tonic-gate * Advance pointer to point the next character to be parsed. 1266*7c478bd9Sstevel@tonic-gate */ 1267*7c478bd9Sstevel@tonic-gate *m = *m + 1; 1268*7c478bd9Sstevel@tonic-gate return (p); 1269*7c478bd9Sstevel@tonic-gate } 1270*7c478bd9Sstevel@tonic-gate } /* get_next_ch */ 1271*7c478bd9Sstevel@tonic-gate 1272*7c478bd9Sstevel@tonic-gate /* 1273*7c478bd9Sstevel@tonic-gate * Compares two msgids. 1274*7c478bd9Sstevel@tonic-gate * Comparison is done by values, not by characters represented. 1275*7c478bd9Sstevel@tonic-gate * For example, '\t', '\011' and '0x9' are identical values. 1276*7c478bd9Sstevel@tonic-gate * Return values are same as in strcmp. 1277*7c478bd9Sstevel@tonic-gate * 1 if msgid1 > msgid2 1278*7c478bd9Sstevel@tonic-gate * 0 if msgid1 = msgid2 1279*7c478bd9Sstevel@tonic-gate * -1 if msgid1 < msgid2 1280*7c478bd9Sstevel@tonic-gate */ 1281*7c478bd9Sstevel@tonic-gate static int 1282*7c478bd9Sstevel@tonic-gate msgidcmp(struct strlist_st *id1, struct strlist_st *id2) 1283*7c478bd9Sstevel@tonic-gate { 1284*7c478bd9Sstevel@tonic-gate char c1, c2; 1285*7c478bd9Sstevel@tonic-gate int m1, m2; 1286*7c478bd9Sstevel@tonic-gate 1287*7c478bd9Sstevel@tonic-gate m1 = 0; 1288*7c478bd9Sstevel@tonic-gate m2 = 0; 1289*7c478bd9Sstevel@tonic-gate 1290*7c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 1291*7c478bd9Sstevel@tonic-gate while (1) { 1292*7c478bd9Sstevel@tonic-gate id1 = get_next_ch(id1, &m1, &c1); 1293*7c478bd9Sstevel@tonic-gate id2 = get_next_ch(id2, &m2, &c2); 1294*7c478bd9Sstevel@tonic-gate 1295*7c478bd9Sstevel@tonic-gate if ((c1 == 0) && (c2 == 0)) { 1296*7c478bd9Sstevel@tonic-gate return (0); 1297*7c478bd9Sstevel@tonic-gate } 1298*7c478bd9Sstevel@tonic-gate 1299*7c478bd9Sstevel@tonic-gate if (c1 > c2) { 1300*7c478bd9Sstevel@tonic-gate return (1); 1301*7c478bd9Sstevel@tonic-gate } else if (c1 < c2) { 1302*7c478bd9Sstevel@tonic-gate return (-1); 1303*7c478bd9Sstevel@tonic-gate } 1304*7c478bd9Sstevel@tonic-gate } 1305*7c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 1306*7c478bd9Sstevel@tonic-gate } /* msgidcmp */ 1307*7c478bd9Sstevel@tonic-gate 1308*7c478bd9Sstevel@tonic-gate /* 1309*7c478bd9Sstevel@tonic-gate * Check if a ANSI string (which is a linked list itself) is a duplicate 1310*7c478bd9Sstevel@tonic-gate * of any string in the list of ANSI string. 1311*7c478bd9Sstevel@tonic-gate */ 1312*7c478bd9Sstevel@tonic-gate static int 1313*7c478bd9Sstevel@tonic-gate isduplicate(struct element_st *list, struct strlist_st *str) 1314*7c478bd9Sstevel@tonic-gate { 1315*7c478bd9Sstevel@tonic-gate struct element_st *p; 1316*7c478bd9Sstevel@tonic-gate 1317*7c478bd9Sstevel@tonic-gate if (list == NULL) { 1318*7c478bd9Sstevel@tonic-gate return (FALSE); 1319*7c478bd9Sstevel@tonic-gate } 1320*7c478bd9Sstevel@tonic-gate 1321*7c478bd9Sstevel@tonic-gate p = list; 1322*7c478bd9Sstevel@tonic-gate while (p != NULL) { 1323*7c478bd9Sstevel@tonic-gate if (p->msgid != NULL) { 1324*7c478bd9Sstevel@tonic-gate if (msgidcmp(p->msgid, str) == 0) { 1325*7c478bd9Sstevel@tonic-gate return (TRUE); 1326*7c478bd9Sstevel@tonic-gate } 1327*7c478bd9Sstevel@tonic-gate } 1328*7c478bd9Sstevel@tonic-gate p = p->next; 1329*7c478bd9Sstevel@tonic-gate } 1330*7c478bd9Sstevel@tonic-gate 1331*7c478bd9Sstevel@tonic-gate return (FALSE); 1332*7c478bd9Sstevel@tonic-gate } /* isduplicate */ 1333*7c478bd9Sstevel@tonic-gate 1334*7c478bd9Sstevel@tonic-gate /* 1335*7c478bd9Sstevel@tonic-gate * Extract a comment line and add to the linked list containing 1336*7c478bd9Sstevel@tonic-gate * comment block. 1337*7c478bd9Sstevel@tonic-gate * Each comment line is stored in the node. 1338*7c478bd9Sstevel@tonic-gate */ 1339*7c478bd9Sstevel@tonic-gate static void 1340*7c478bd9Sstevel@tonic-gate add_line_to_comment(void) 1341*7c478bd9Sstevel@tonic-gate { 1342*7c478bd9Sstevel@tonic-gate struct strlist_st *tmp_str; 1343*7c478bd9Sstevel@tonic-gate 1344*7c478bd9Sstevel@tonic-gate tmp_str = new_strlist(); 1345*7c478bd9Sstevel@tonic-gate tmp_str->str = strdup(curr_line); 1346*7c478bd9Sstevel@tonic-gate tmp_str->next = NULL; 1347*7c478bd9Sstevel@tonic-gate 1348*7c478bd9Sstevel@tonic-gate if (commhead == NULL) { 1349*7c478bd9Sstevel@tonic-gate /* Empty comment list */ 1350*7c478bd9Sstevel@tonic-gate commhead = tmp_str; 1351*7c478bd9Sstevel@tonic-gate commtail = tmp_str; 1352*7c478bd9Sstevel@tonic-gate } else { 1353*7c478bd9Sstevel@tonic-gate /* append it to the list */ 1354*7c478bd9Sstevel@tonic-gate commtail->next = tmp_str; 1355*7c478bd9Sstevel@tonic-gate commtail = commtail->next; 1356*7c478bd9Sstevel@tonic-gate } 1357*7c478bd9Sstevel@tonic-gate 1358*7c478bd9Sstevel@tonic-gate is_last_comment_line = FALSE; 1359*7c478bd9Sstevel@tonic-gate } /* add_line_to_comment */ 1360*7c478bd9Sstevel@tonic-gate 1361*7c478bd9Sstevel@tonic-gate /* 1362*7c478bd9Sstevel@tonic-gate * Add a double quoted string to the linked list containing ANSI string. 1363*7c478bd9Sstevel@tonic-gate */ 1364*7c478bd9Sstevel@tonic-gate static void 1365*7c478bd9Sstevel@tonic-gate add_qstring_to_str(void) 1366*7c478bd9Sstevel@tonic-gate { 1367*7c478bd9Sstevel@tonic-gate struct strlist_st *tmp_str; 1368*7c478bd9Sstevel@tonic-gate 1369*7c478bd9Sstevel@tonic-gate tmp_str = new_strlist(); 1370*7c478bd9Sstevel@tonic-gate tmp_str->str = strdup(qstring_buf); 1371*7c478bd9Sstevel@tonic-gate tmp_str->next = NULL; 1372*7c478bd9Sstevel@tonic-gate 1373*7c478bd9Sstevel@tonic-gate if (strhead == NULL) { 1374*7c478bd9Sstevel@tonic-gate /* Null ANSI string */ 1375*7c478bd9Sstevel@tonic-gate strhead = tmp_str; 1376*7c478bd9Sstevel@tonic-gate strtail = tmp_str; 1377*7c478bd9Sstevel@tonic-gate } else { 1378*7c478bd9Sstevel@tonic-gate /* Append it to the ANSI string linked list */ 1379*7c478bd9Sstevel@tonic-gate strtail->next = tmp_str; 1380*7c478bd9Sstevel@tonic-gate strtail = strtail->next; 1381*7c478bd9Sstevel@tonic-gate } 1382*7c478bd9Sstevel@tonic-gate 1383*7c478bd9Sstevel@tonic-gate qstring_buf[0] = NULL; 1384*7c478bd9Sstevel@tonic-gate } /* add_qstring_to_str */ 1385*7c478bd9Sstevel@tonic-gate 1386*7c478bd9Sstevel@tonic-gate /* 1387*7c478bd9Sstevel@tonic-gate * Finds the head of domain nodes given domain name. 1388*7c478bd9Sstevel@tonic-gate */ 1389*7c478bd9Sstevel@tonic-gate static struct domain_st * 1390*7c478bd9Sstevel@tonic-gate find_domain_node(char *dname) 1391*7c478bd9Sstevel@tonic-gate { 1392*7c478bd9Sstevel@tonic-gate struct domain_st *tmp_dom, *p; 1393*7c478bd9Sstevel@tonic-gate 1394*7c478bd9Sstevel@tonic-gate /* 1395*7c478bd9Sstevel@tonic-gate * If -a option is specified everything will be written to the 1396*7c478bd9Sstevel@tonic-gate * default domain file. 1397*7c478bd9Sstevel@tonic-gate */ 1398*7c478bd9Sstevel@tonic-gate if (aflg == TRUE) { 1399*7c478bd9Sstevel@tonic-gate if (def_dom == NULL) { 1400*7c478bd9Sstevel@tonic-gate def_dom = new_domain(); 1401*7c478bd9Sstevel@tonic-gate } 1402*7c478bd9Sstevel@tonic-gate return (def_dom); 1403*7c478bd9Sstevel@tonic-gate } 1404*7c478bd9Sstevel@tonic-gate 1405*7c478bd9Sstevel@tonic-gate if ((dname == NULL) || 1406*7c478bd9Sstevel@tonic-gate (dname[0] == NULL) || 1407*7c478bd9Sstevel@tonic-gate (strcmp(dname, default_domain) == 0)) { 1408*7c478bd9Sstevel@tonic-gate if (def_dom == NULL) { 1409*7c478bd9Sstevel@tonic-gate def_dom = new_domain(); 1410*7c478bd9Sstevel@tonic-gate } 1411*7c478bd9Sstevel@tonic-gate if (strcmp(dname, default_domain) == 0) { 1412*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1413*7c478bd9Sstevel@tonic-gate "%s \"%s\" is used in dgettext of file:%s line:%d.\n", 1414*7c478bd9Sstevel@tonic-gate "Warning: default domain name", 1415*7c478bd9Sstevel@tonic-gate default_domain, curr_file, curr_linenum); 1416*7c478bd9Sstevel@tonic-gate } 1417*7c478bd9Sstevel@tonic-gate return (def_dom); 1418*7c478bd9Sstevel@tonic-gate } else { 1419*7c478bd9Sstevel@tonic-gate p = dom_head; 1420*7c478bd9Sstevel@tonic-gate while (p != NULL) { 1421*7c478bd9Sstevel@tonic-gate if (strcmp(p->dname, dname) == 0) { 1422*7c478bd9Sstevel@tonic-gate return (p); 1423*7c478bd9Sstevel@tonic-gate } 1424*7c478bd9Sstevel@tonic-gate p = p->next; 1425*7c478bd9Sstevel@tonic-gate } 1426*7c478bd9Sstevel@tonic-gate 1427*7c478bd9Sstevel@tonic-gate tmp_dom = new_domain(); 1428*7c478bd9Sstevel@tonic-gate tmp_dom->dname = strdup(dname); 1429*7c478bd9Sstevel@tonic-gate 1430*7c478bd9Sstevel@tonic-gate if (dom_head == NULL) { 1431*7c478bd9Sstevel@tonic-gate dom_head = tmp_dom; 1432*7c478bd9Sstevel@tonic-gate dom_tail = tmp_dom; 1433*7c478bd9Sstevel@tonic-gate } else { 1434*7c478bd9Sstevel@tonic-gate dom_tail->next = tmp_dom; 1435*7c478bd9Sstevel@tonic-gate dom_tail = dom_tail->next; 1436*7c478bd9Sstevel@tonic-gate } 1437*7c478bd9Sstevel@tonic-gate return (tmp_dom); 1438*7c478bd9Sstevel@tonic-gate } 1439*7c478bd9Sstevel@tonic-gate } /* find_domain_node */ 1440*7c478bd9Sstevel@tonic-gate 1441*7c478bd9Sstevel@tonic-gate /* 1442*7c478bd9Sstevel@tonic-gate * Frees the ANSI string linked list. 1443*7c478bd9Sstevel@tonic-gate */ 1444*7c478bd9Sstevel@tonic-gate static void 1445*7c478bd9Sstevel@tonic-gate free_strlist(struct strlist_st *ptr) 1446*7c478bd9Sstevel@tonic-gate { 1447*7c478bd9Sstevel@tonic-gate struct strlist_st *p; 1448*7c478bd9Sstevel@tonic-gate 1449*7c478bd9Sstevel@tonic-gate p = ptr; 1450*7c478bd9Sstevel@tonic-gate ptr = NULL; 1451*7c478bd9Sstevel@tonic-gate while (p != NULL) { 1452*7c478bd9Sstevel@tonic-gate ptr = p->next; 1453*7c478bd9Sstevel@tonic-gate free(p->str); 1454*7c478bd9Sstevel@tonic-gate free(p); 1455*7c478bd9Sstevel@tonic-gate p = ptr; 1456*7c478bd9Sstevel@tonic-gate } 1457*7c478bd9Sstevel@tonic-gate } /* free_strlist */ 1458*7c478bd9Sstevel@tonic-gate 1459*7c478bd9Sstevel@tonic-gate /* 1460*7c478bd9Sstevel@tonic-gate * Finds if a ANSI string is contained in the exclude file. 1461*7c478bd9Sstevel@tonic-gate */ 1462*7c478bd9Sstevel@tonic-gate static int 1463*7c478bd9Sstevel@tonic-gate isexcluded(struct strlist_st *strlist) 1464*7c478bd9Sstevel@tonic-gate { 1465*7c478bd9Sstevel@tonic-gate struct exclude_st *p; 1466*7c478bd9Sstevel@tonic-gate 1467*7c478bd9Sstevel@tonic-gate p = excl_head; 1468*7c478bd9Sstevel@tonic-gate while (p != NULL) { 1469*7c478bd9Sstevel@tonic-gate if (msgidcmp(p->exstr, strlist) == 0) { 1470*7c478bd9Sstevel@tonic-gate return (TRUE); 1471*7c478bd9Sstevel@tonic-gate } 1472*7c478bd9Sstevel@tonic-gate p = p->next; 1473*7c478bd9Sstevel@tonic-gate } 1474*7c478bd9Sstevel@tonic-gate return (FALSE); 1475*7c478bd9Sstevel@tonic-gate } /* isexcluded */ 1476*7c478bd9Sstevel@tonic-gate 1477*7c478bd9Sstevel@tonic-gate /* 1478*7c478bd9Sstevel@tonic-gate * Finds if a comment block is to be extracted. 1479*7c478bd9Sstevel@tonic-gate * 1480*7c478bd9Sstevel@tonic-gate * When -c option is specified, find out if comment block contains 1481*7c478bd9Sstevel@tonic-gate * comment-tag as a token separated by blanks. If it does, this 1482*7c478bd9Sstevel@tonic-gate * comment block is associated with the next msgid encountered. 1483*7c478bd9Sstevel@tonic-gate * Comment block is a linked list where each node contains one line 1484*7c478bd9Sstevel@tonic-gate * of comments. 1485*7c478bd9Sstevel@tonic-gate */ 1486*7c478bd9Sstevel@tonic-gate static int 1487*7c478bd9Sstevel@tonic-gate isextracted(struct strlist_st *strlist) 1488*7c478bd9Sstevel@tonic-gate { 1489*7c478bd9Sstevel@tonic-gate struct strlist_st *p; 1490*7c478bd9Sstevel@tonic-gate char *first, *pc; 1491*7c478bd9Sstevel@tonic-gate 1492*7c478bd9Sstevel@tonic-gate 1493*7c478bd9Sstevel@tonic-gate p = strlist; 1494*7c478bd9Sstevel@tonic-gate while (p != NULL) { 1495*7c478bd9Sstevel@tonic-gate first = strdup(p->str); 1496*7c478bd9Sstevel@tonic-gate while ((first != NULL) && (first[0] != NULL)) { 1497*7c478bd9Sstevel@tonic-gate pc = first; 1498*7c478bd9Sstevel@tonic-gate 1499*7c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 1500*7c478bd9Sstevel@tonic-gate while (1) { 1501*7c478bd9Sstevel@tonic-gate if (*pc == NULL) { 1502*7c478bd9Sstevel@tonic-gate break; 1503*7c478bd9Sstevel@tonic-gate } else if ((*pc == ' ') || (*pc == '\t')) { 1504*7c478bd9Sstevel@tonic-gate *pc++ = NULL; 1505*7c478bd9Sstevel@tonic-gate break; 1506*7c478bd9Sstevel@tonic-gate } 1507*7c478bd9Sstevel@tonic-gate pc++; 1508*7c478bd9Sstevel@tonic-gate } 1509*7c478bd9Sstevel@tonic-gate if (strcmp(first, comment_tag) == 0) { 1510*7c478bd9Sstevel@tonic-gate return (TRUE); 1511*7c478bd9Sstevel@tonic-gate } 1512*7c478bd9Sstevel@tonic-gate first = pc; 1513*7c478bd9Sstevel@tonic-gate } 1514*7c478bd9Sstevel@tonic-gate p = p->next; 1515*7c478bd9Sstevel@tonic-gate } /* while */ 1516*7c478bd9Sstevel@tonic-gate 1517*7c478bd9Sstevel@tonic-gate /* 1518*7c478bd9Sstevel@tonic-gate * Not found. 1519*7c478bd9Sstevel@tonic-gate */ 1520*7c478bd9Sstevel@tonic-gate return (FALSE); 1521*7c478bd9Sstevel@tonic-gate } /* isextracted */ 1522*7c478bd9Sstevel@tonic-gate 1523*7c478bd9Sstevel@tonic-gate /* 1524*7c478bd9Sstevel@tonic-gate * Adds ANSI string to the domain element list. 1525*7c478bd9Sstevel@tonic-gate */ 1526*7c478bd9Sstevel@tonic-gate static void 1527*7c478bd9Sstevel@tonic-gate add_str_to_element_list(int istextdomain, char *domain_list) 1528*7c478bd9Sstevel@tonic-gate { 1529*7c478bd9Sstevel@tonic-gate struct element_st *tmp_elem; 1530*7c478bd9Sstevel@tonic-gate struct element_st *p, *q; 1531*7c478bd9Sstevel@tonic-gate struct domain_st *tmp_dom; 1532*7c478bd9Sstevel@tonic-gate int result; 1533*7c478bd9Sstevel@tonic-gate 1534*7c478bd9Sstevel@tonic-gate /* 1535*7c478bd9Sstevel@tonic-gate * This can happen if something like gettext(USAGE) is used 1536*7c478bd9Sstevel@tonic-gate * and it is impossible to get msgid for this gettext. 1537*7c478bd9Sstevel@tonic-gate * Since -x option should be used in this kind of cases, 1538*7c478bd9Sstevel@tonic-gate * it is OK not to catch msgid. 1539*7c478bd9Sstevel@tonic-gate */ 1540*7c478bd9Sstevel@tonic-gate if (strhead == NULL) { 1541*7c478bd9Sstevel@tonic-gate return; 1542*7c478bd9Sstevel@tonic-gate } 1543*7c478bd9Sstevel@tonic-gate 1544*7c478bd9Sstevel@tonic-gate /* 1545*7c478bd9Sstevel@tonic-gate * The global variable curr_domain contains either NULL 1546*7c478bd9Sstevel@tonic-gate * for default_domain or domain name for dgettext(). 1547*7c478bd9Sstevel@tonic-gate */ 1548*7c478bd9Sstevel@tonic-gate tmp_dom = find_domain_node(domain_list); 1549*7c478bd9Sstevel@tonic-gate 1550*7c478bd9Sstevel@tonic-gate /* 1551*7c478bd9Sstevel@tonic-gate * If this msgid is in the exclude file, 1552*7c478bd9Sstevel@tonic-gate * then free the linked list and return. 1553*7c478bd9Sstevel@tonic-gate */ 1554*7c478bd9Sstevel@tonic-gate if ((istextdomain == FALSE) && 1555*7c478bd9Sstevel@tonic-gate (isexcluded(strhead) == TRUE)) { 1556*7c478bd9Sstevel@tonic-gate free_strlist(strhead); 1557*7c478bd9Sstevel@tonic-gate strhead = strtail = NULL; 1558*7c478bd9Sstevel@tonic-gate return; 1559*7c478bd9Sstevel@tonic-gate } 1560*7c478bd9Sstevel@tonic-gate 1561*7c478bd9Sstevel@tonic-gate tmp_elem = new_element(); 1562*7c478bd9Sstevel@tonic-gate tmp_elem->msgid = strhead; 1563*7c478bd9Sstevel@tonic-gate tmp_elem->istextdomain = istextdomain; 1564*7c478bd9Sstevel@tonic-gate /* 1565*7c478bd9Sstevel@tonic-gate * If -c option is specified and TAG matches, 1566*7c478bd9Sstevel@tonic-gate * then associate the comment to the next [d]gettext() calls 1567*7c478bd9Sstevel@tonic-gate * encountered in the source code. 1568*7c478bd9Sstevel@tonic-gate * textdomain() calls will not have any effect. 1569*7c478bd9Sstevel@tonic-gate */ 1570*7c478bd9Sstevel@tonic-gate if (istextdomain == FALSE) { 1571*7c478bd9Sstevel@tonic-gate if ((cflg == TRUE) && (commhead != NULL)) { 1572*7c478bd9Sstevel@tonic-gate if (isextracted(commhead) == TRUE) { 1573*7c478bd9Sstevel@tonic-gate tmp_elem->comment = commhead; 1574*7c478bd9Sstevel@tonic-gate } else { 1575*7c478bd9Sstevel@tonic-gate free_strlist(commhead); 1576*7c478bd9Sstevel@tonic-gate } 1577*7c478bd9Sstevel@tonic-gate commhead = commtail = NULL; 1578*7c478bd9Sstevel@tonic-gate } 1579*7c478bd9Sstevel@tonic-gate } 1580*7c478bd9Sstevel@tonic-gate 1581*7c478bd9Sstevel@tonic-gate tmp_elem->linenum = linenum_saved; 1582*7c478bd9Sstevel@tonic-gate tmp_elem->fname = strdup(curr_file); 1583*7c478bd9Sstevel@tonic-gate 1584*7c478bd9Sstevel@tonic-gate 1585*7c478bd9Sstevel@tonic-gate if (sflg == TRUE) { 1586*7c478bd9Sstevel@tonic-gate /* 1587*7c478bd9Sstevel@tonic-gate * If this is textdomain() call and -s option is specified, 1588*7c478bd9Sstevel@tonic-gate * append this node to the textdomain linked list. 1589*7c478bd9Sstevel@tonic-gate */ 1590*7c478bd9Sstevel@tonic-gate if (istextdomain == TRUE) { 1591*7c478bd9Sstevel@tonic-gate if (tmp_dom->textdomain_head == NULL) { 1592*7c478bd9Sstevel@tonic-gate tmp_dom->textdomain_head = tmp_elem; 1593*7c478bd9Sstevel@tonic-gate tmp_dom->textdomain_tail = tmp_elem; 1594*7c478bd9Sstevel@tonic-gate } else { 1595*7c478bd9Sstevel@tonic-gate tmp_dom->textdomain_tail->next = tmp_elem; 1596*7c478bd9Sstevel@tonic-gate tmp_dom->textdomain_tail = tmp_elem; 1597*7c478bd9Sstevel@tonic-gate } 1598*7c478bd9Sstevel@tonic-gate strhead = strtail = NULL; 1599*7c478bd9Sstevel@tonic-gate return; 1600*7c478bd9Sstevel@tonic-gate } 1601*7c478bd9Sstevel@tonic-gate 1602*7c478bd9Sstevel@tonic-gate /* 1603*7c478bd9Sstevel@tonic-gate * Insert the node to the properly sorted position. 1604*7c478bd9Sstevel@tonic-gate */ 1605*7c478bd9Sstevel@tonic-gate q = NULL; 1606*7c478bd9Sstevel@tonic-gate p = tmp_dom->gettext_head; 1607*7c478bd9Sstevel@tonic-gate while (p != NULL) { 1608*7c478bd9Sstevel@tonic-gate result = msgidcmp(strhead, p->msgid); 1609*7c478bd9Sstevel@tonic-gate if (result == 0) { 1610*7c478bd9Sstevel@tonic-gate /* 1611*7c478bd9Sstevel@tonic-gate * Duplicate id. Do not store. 1612*7c478bd9Sstevel@tonic-gate */ 1613*7c478bd9Sstevel@tonic-gate free_strlist(strhead); 1614*7c478bd9Sstevel@tonic-gate strhead = strtail = NULL; 1615*7c478bd9Sstevel@tonic-gate return; 1616*7c478bd9Sstevel@tonic-gate } else if (result > 0) { 1617*7c478bd9Sstevel@tonic-gate /* move to the next node */ 1618*7c478bd9Sstevel@tonic-gate q = p; 1619*7c478bd9Sstevel@tonic-gate p = p->next; 1620*7c478bd9Sstevel@tonic-gate } else { 1621*7c478bd9Sstevel@tonic-gate tmp_elem->next = p; 1622*7c478bd9Sstevel@tonic-gate if (q != NULL) { 1623*7c478bd9Sstevel@tonic-gate q->next = tmp_elem; 1624*7c478bd9Sstevel@tonic-gate } else { 1625*7c478bd9Sstevel@tonic-gate tmp_dom->gettext_head = tmp_elem; 1626*7c478bd9Sstevel@tonic-gate } 1627*7c478bd9Sstevel@tonic-gate strhead = strtail = NULL; 1628*7c478bd9Sstevel@tonic-gate return; 1629*7c478bd9Sstevel@tonic-gate } 1630*7c478bd9Sstevel@tonic-gate } /* while */ 1631*7c478bd9Sstevel@tonic-gate 1632*7c478bd9Sstevel@tonic-gate /* 1633*7c478bd9Sstevel@tonic-gate * New msgid is the largest or empty list. 1634*7c478bd9Sstevel@tonic-gate */ 1635*7c478bd9Sstevel@tonic-gate if (q != NULL) { 1636*7c478bd9Sstevel@tonic-gate /* largest case */ 1637*7c478bd9Sstevel@tonic-gate q->next = tmp_elem; 1638*7c478bd9Sstevel@tonic-gate } else { 1639*7c478bd9Sstevel@tonic-gate /* empty list */ 1640*7c478bd9Sstevel@tonic-gate tmp_dom->gettext_head = tmp_elem; 1641*7c478bd9Sstevel@tonic-gate } 1642*7c478bd9Sstevel@tonic-gate } else { 1643*7c478bd9Sstevel@tonic-gate /* 1644*7c478bd9Sstevel@tonic-gate * Check if this msgid is already in the same domain. 1645*7c478bd9Sstevel@tonic-gate */ 1646*7c478bd9Sstevel@tonic-gate if (tmp_dom != NULL) { 1647*7c478bd9Sstevel@tonic-gate if (isduplicate(tmp_dom->gettext_head, 1648*7c478bd9Sstevel@tonic-gate tmp_elem->msgid) == TRUE) { 1649*7c478bd9Sstevel@tonic-gate tmp_elem->isduplicate = TRUE; 1650*7c478bd9Sstevel@tonic-gate } 1651*7c478bd9Sstevel@tonic-gate } 1652*7c478bd9Sstevel@tonic-gate /* 1653*7c478bd9Sstevel@tonic-gate * If -s option is not specified, then everything 1654*7c478bd9Sstevel@tonic-gate * is stored in gettext linked list. 1655*7c478bd9Sstevel@tonic-gate */ 1656*7c478bd9Sstevel@tonic-gate if (tmp_dom->gettext_head == NULL) { 1657*7c478bd9Sstevel@tonic-gate tmp_dom->gettext_head = tmp_elem; 1658*7c478bd9Sstevel@tonic-gate tmp_dom->gettext_tail = tmp_elem; 1659*7c478bd9Sstevel@tonic-gate } else { 1660*7c478bd9Sstevel@tonic-gate tmp_dom->gettext_tail->next = tmp_elem; 1661*7c478bd9Sstevel@tonic-gate tmp_dom->gettext_tail = tmp_elem; 1662*7c478bd9Sstevel@tonic-gate } 1663*7c478bd9Sstevel@tonic-gate } 1664*7c478bd9Sstevel@tonic-gate 1665*7c478bd9Sstevel@tonic-gate strhead = strtail = NULL; 1666*7c478bd9Sstevel@tonic-gate } /* add_str_to_element_list */ 1667*7c478bd9Sstevel@tonic-gate 1668*7c478bd9Sstevel@tonic-gate /* 1669*7c478bd9Sstevel@tonic-gate * Write all domain linked list to the files. 1670*7c478bd9Sstevel@tonic-gate */ 1671*7c478bd9Sstevel@tonic-gate static void 1672*7c478bd9Sstevel@tonic-gate write_all_files(void) 1673*7c478bd9Sstevel@tonic-gate { 1674*7c478bd9Sstevel@tonic-gate struct domain_st *tmp; 1675*7c478bd9Sstevel@tonic-gate 1676*7c478bd9Sstevel@tonic-gate /* 1677*7c478bd9Sstevel@tonic-gate * Write out default domain file. 1678*7c478bd9Sstevel@tonic-gate */ 1679*7c478bd9Sstevel@tonic-gate write_one_file(def_dom); 1680*7c478bd9Sstevel@tonic-gate 1681*7c478bd9Sstevel@tonic-gate /* 1682*7c478bd9Sstevel@tonic-gate * If dgettext() exists and -a option is not used, 1683*7c478bd9Sstevel@tonic-gate * then there are non-empty linked list. 1684*7c478bd9Sstevel@tonic-gate */ 1685*7c478bd9Sstevel@tonic-gate tmp = dom_head; 1686*7c478bd9Sstevel@tonic-gate while (tmp != NULL) { 1687*7c478bd9Sstevel@tonic-gate write_one_file(tmp); 1688*7c478bd9Sstevel@tonic-gate tmp = tmp->next; 1689*7c478bd9Sstevel@tonic-gate } 1690*7c478bd9Sstevel@tonic-gate } /* write_all_files */ 1691*7c478bd9Sstevel@tonic-gate 1692*7c478bd9Sstevel@tonic-gate /* 1693*7c478bd9Sstevel@tonic-gate * add an element_st list to the linked list. 1694*7c478bd9Sstevel@tonic-gate */ 1695*7c478bd9Sstevel@tonic-gate static void 1696*7c478bd9Sstevel@tonic-gate add_node_to_polist(struct element_st **pohead, 1697*7c478bd9Sstevel@tonic-gate struct element_st **potail, struct element_st *elem) 1698*7c478bd9Sstevel@tonic-gate { 1699*7c478bd9Sstevel@tonic-gate if (elem == NULL) { 1700*7c478bd9Sstevel@tonic-gate return; 1701*7c478bd9Sstevel@tonic-gate } 1702*7c478bd9Sstevel@tonic-gate 1703*7c478bd9Sstevel@tonic-gate if (*pohead == NULL) { 1704*7c478bd9Sstevel@tonic-gate *pohead = *potail = elem; 1705*7c478bd9Sstevel@tonic-gate } else { 1706*7c478bd9Sstevel@tonic-gate (*potail)->next = elem; 1707*7c478bd9Sstevel@tonic-gate *potail = (*potail)->next; 1708*7c478bd9Sstevel@tonic-gate } 1709*7c478bd9Sstevel@tonic-gate } /* add_node_to_polist */ 1710*7c478bd9Sstevel@tonic-gate 1711*7c478bd9Sstevel@tonic-gate #define INIT_STATE 0 1712*7c478bd9Sstevel@tonic-gate #define IN_MSGID 1 1713*7c478bd9Sstevel@tonic-gate #define IN_MSGSTR 2 1714*7c478bd9Sstevel@tonic-gate #define IN_COMMENT 3 1715*7c478bd9Sstevel@tonic-gate /* 1716*7c478bd9Sstevel@tonic-gate * Reads existing po file into the linked list and returns the head 1717*7c478bd9Sstevel@tonic-gate * of the linked list. 1718*7c478bd9Sstevel@tonic-gate */ 1719*7c478bd9Sstevel@tonic-gate static struct element_st * 1720*7c478bd9Sstevel@tonic-gate read_po(char *fname) 1721*7c478bd9Sstevel@tonic-gate { 1722*7c478bd9Sstevel@tonic-gate struct element_st *tmp_elem = NULL; 1723*7c478bd9Sstevel@tonic-gate struct element_st *ehead = NULL, *etail = NULL; 1724*7c478bd9Sstevel@tonic-gate struct strlist_st *comment_tail = NULL; 1725*7c478bd9Sstevel@tonic-gate struct strlist_st *msgid_tail = NULL; 1726*7c478bd9Sstevel@tonic-gate struct strlist_st *msgstr_tail = NULL; 1727*7c478bd9Sstevel@tonic-gate int state = INIT_STATE; 1728*7c478bd9Sstevel@tonic-gate char line [MAX_STRING_LEN]; 1729*7c478bd9Sstevel@tonic-gate FILE *fp; 1730*7c478bd9Sstevel@tonic-gate 1731*7c478bd9Sstevel@tonic-gate if ((fp = fopen(fname, "r")) == NULL) { 1732*7c478bd9Sstevel@tonic-gate return (NULL); 1733*7c478bd9Sstevel@tonic-gate } 1734*7c478bd9Sstevel@tonic-gate 1735*7c478bd9Sstevel@tonic-gate while (fgets(line, MAX_STRING_LEN, fp) != NULL) { 1736*7c478bd9Sstevel@tonic-gate /* 1737*7c478bd9Sstevel@tonic-gate * Line starting with # is a comment line and ignored. 1738*7c478bd9Sstevel@tonic-gate * Blank line is ignored, too. 1739*7c478bd9Sstevel@tonic-gate */ 1740*7c478bd9Sstevel@tonic-gate if (line[0] == '\n') { 1741*7c478bd9Sstevel@tonic-gate continue; 1742*7c478bd9Sstevel@tonic-gate } else if (line[0] == '#') { 1743*7c478bd9Sstevel@tonic-gate /* 1744*7c478bd9Sstevel@tonic-gate * If tmp_elem is not NULL, there is msgid pair 1745*7c478bd9Sstevel@tonic-gate * stored. Therefore, add it. 1746*7c478bd9Sstevel@tonic-gate */ 1747*7c478bd9Sstevel@tonic-gate if ((tmp_elem != NULL) && (state == IN_MSGSTR)) { 1748*7c478bd9Sstevel@tonic-gate add_node_to_polist(&ehead, &etail, tmp_elem); 1749*7c478bd9Sstevel@tonic-gate } 1750*7c478bd9Sstevel@tonic-gate 1751*7c478bd9Sstevel@tonic-gate if ((state == INIT_STATE) || (state == IN_MSGSTR)) { 1752*7c478bd9Sstevel@tonic-gate state = IN_COMMENT; 1753*7c478bd9Sstevel@tonic-gate tmp_elem = new_element(); 1754*7c478bd9Sstevel@tonic-gate tmp_elem->comment = comment_tail = 1755*7c478bd9Sstevel@tonic-gate new_strlist(); 1756*7c478bd9Sstevel@tonic-gate /* 1757*7c478bd9Sstevel@tonic-gate * remove new line and skip "# " 1758*7c478bd9Sstevel@tonic-gate * in the beginning of the existing 1759*7c478bd9Sstevel@tonic-gate * comment line. 1760*7c478bd9Sstevel@tonic-gate */ 1761*7c478bd9Sstevel@tonic-gate line[strlen(line)-1] = 0; 1762*7c478bd9Sstevel@tonic-gate comment_tail->str = strdup(line+2); 1763*7c478bd9Sstevel@tonic-gate } else if (state == IN_COMMENT) { 1764*7c478bd9Sstevel@tonic-gate comment_tail->next = new_strlist(); 1765*7c478bd9Sstevel@tonic-gate comment_tail = comment_tail->next; 1766*7c478bd9Sstevel@tonic-gate /* 1767*7c478bd9Sstevel@tonic-gate * remove new line and skip "# " 1768*7c478bd9Sstevel@tonic-gate * in the beginning of the existing 1769*7c478bd9Sstevel@tonic-gate * comment line. 1770*7c478bd9Sstevel@tonic-gate */ 1771*7c478bd9Sstevel@tonic-gate line[strlen(line)-1] = 0; 1772*7c478bd9Sstevel@tonic-gate comment_tail->str = strdup(line+2); 1773*7c478bd9Sstevel@tonic-gate } 1774*7c478bd9Sstevel@tonic-gate 1775*7c478bd9Sstevel@tonic-gate } else if (strncmp(line, "domain", 6) == 0) { 1776*7c478bd9Sstevel@tonic-gate /* ignore domain line */ 1777*7c478bd9Sstevel@tonic-gate continue; 1778*7c478bd9Sstevel@tonic-gate } else if (strncmp(line, "msgid", 5) == 0) { 1779*7c478bd9Sstevel@tonic-gate if (state == IN_MSGSTR) { 1780*7c478bd9Sstevel@tonic-gate add_node_to_polist(&ehead, &etail, tmp_elem); 1781*7c478bd9Sstevel@tonic-gate tmp_elem = new_element(); 1782*7c478bd9Sstevel@tonic-gate } else if (state == INIT_STATE) { 1783*7c478bd9Sstevel@tonic-gate tmp_elem = new_element(); 1784*7c478bd9Sstevel@tonic-gate } 1785*7c478bd9Sstevel@tonic-gate 1786*7c478bd9Sstevel@tonic-gate state = IN_MSGID; 1787*7c478bd9Sstevel@tonic-gate trim_line(line); 1788*7c478bd9Sstevel@tonic-gate tmp_elem->msgid = msgid_tail = new_strlist(); 1789*7c478bd9Sstevel@tonic-gate msgid_tail->str = strdup(line); 1790*7c478bd9Sstevel@tonic-gate 1791*7c478bd9Sstevel@tonic-gate } else if (strncmp(line, "msgstr", 6) == 0) { 1792*7c478bd9Sstevel@tonic-gate state = IN_MSGSTR; 1793*7c478bd9Sstevel@tonic-gate trim_line(line); 1794*7c478bd9Sstevel@tonic-gate tmp_elem->msgstr = msgstr_tail = new_strlist(); 1795*7c478bd9Sstevel@tonic-gate msgstr_tail->str = strdup(line); 1796*7c478bd9Sstevel@tonic-gate } else { 1797*7c478bd9Sstevel@tonic-gate /* 1798*7c478bd9Sstevel@tonic-gate * If more than one line of string forms msgid, 1799*7c478bd9Sstevel@tonic-gate * append it to the string linked list. 1800*7c478bd9Sstevel@tonic-gate */ 1801*7c478bd9Sstevel@tonic-gate if (state == IN_MSGID) { 1802*7c478bd9Sstevel@tonic-gate trim_line(line); 1803*7c478bd9Sstevel@tonic-gate msgid_tail->next = new_strlist(); 1804*7c478bd9Sstevel@tonic-gate msgid_tail = msgid_tail->next; 1805*7c478bd9Sstevel@tonic-gate msgid_tail->str = strdup(line); 1806*7c478bd9Sstevel@tonic-gate } else if (state == IN_MSGSTR) { 1807*7c478bd9Sstevel@tonic-gate trim_line(line); 1808*7c478bd9Sstevel@tonic-gate msgstr_tail->next = new_strlist(); 1809*7c478bd9Sstevel@tonic-gate msgstr_tail = msgstr_tail->next; 1810*7c478bd9Sstevel@tonic-gate msgstr_tail->str = strdup(line); 1811*7c478bd9Sstevel@tonic-gate } 1812*7c478bd9Sstevel@tonic-gate } 1813*7c478bd9Sstevel@tonic-gate } /* while */ 1814*7c478bd9Sstevel@tonic-gate 1815*7c478bd9Sstevel@tonic-gate /* 1816*7c478bd9Sstevel@tonic-gate * To insert the last msgid pair. 1817*7c478bd9Sstevel@tonic-gate */ 1818*7c478bd9Sstevel@tonic-gate if (tmp_elem != NULL) { 1819*7c478bd9Sstevel@tonic-gate add_node_to_polist(&ehead, &etail, tmp_elem); 1820*7c478bd9Sstevel@tonic-gate } 1821*7c478bd9Sstevel@tonic-gate 1822*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 1823*7c478bd9Sstevel@tonic-gate { 1824*7c478bd9Sstevel@tonic-gate struct domain_st *tmp_domain = new_domain(); 1825*7c478bd9Sstevel@tonic-gate char tmpstr[256]; 1826*7c478bd9Sstevel@tonic-gate 1827*7c478bd9Sstevel@tonic-gate sprintf(tmpstr, "existing_po file : <%s>", fname); 1828*7c478bd9Sstevel@tonic-gate tmp_domain->dname = strdup(tmpstr); 1829*7c478bd9Sstevel@tonic-gate tmp_domain->gettext_head = ehead; 1830*7c478bd9Sstevel@tonic-gate printf("======= existing po file <%s> ========\n", fname); 1831*7c478bd9Sstevel@tonic-gate print_one_domain(tmp_domain); 1832*7c478bd9Sstevel@tonic-gate } 1833*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 1834*7c478bd9Sstevel@tonic-gate 1835*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 1836*7c478bd9Sstevel@tonic-gate return (ehead); 1837*7c478bd9Sstevel@tonic-gate } /* read_po */ 1838*7c478bd9Sstevel@tonic-gate 1839*7c478bd9Sstevel@tonic-gate /* 1840*7c478bd9Sstevel@tonic-gate * This function will append the second list to the first list. 1841*7c478bd9Sstevel@tonic-gate * If the msgid in the second list contains msgid in the first list, 1842*7c478bd9Sstevel@tonic-gate * it will be marked as duplicate. 1843*7c478bd9Sstevel@tonic-gate */ 1844*7c478bd9Sstevel@tonic-gate static struct element_st * 1845*7c478bd9Sstevel@tonic-gate append_list(struct element_st *l1, struct element_st *l2) 1846*7c478bd9Sstevel@tonic-gate { 1847*7c478bd9Sstevel@tonic-gate struct element_st *p = NULL, *q = NULL, *l1_tail = NULL; 1848*7c478bd9Sstevel@tonic-gate 1849*7c478bd9Sstevel@tonic-gate if (l1 == NULL) 1850*7c478bd9Sstevel@tonic-gate return (l2); 1851*7c478bd9Sstevel@tonic-gate if (l2 == NULL) 1852*7c478bd9Sstevel@tonic-gate return (l1); 1853*7c478bd9Sstevel@tonic-gate 1854*7c478bd9Sstevel@tonic-gate /* 1855*7c478bd9Sstevel@tonic-gate * in this while loop, just mark isduplicate field of node in the 1856*7c478bd9Sstevel@tonic-gate * l2 list if the same msgid exists in l1 list. 1857*7c478bd9Sstevel@tonic-gate */ 1858*7c478bd9Sstevel@tonic-gate p = l2; 1859*7c478bd9Sstevel@tonic-gate while (p != NULL) { 1860*7c478bd9Sstevel@tonic-gate q = l1; 1861*7c478bd9Sstevel@tonic-gate while (q != NULL) { 1862*7c478bd9Sstevel@tonic-gate if (msgidcmp(p->msgid, q->msgid) == 0) { 1863*7c478bd9Sstevel@tonic-gate p->isduplicate = TRUE; 1864*7c478bd9Sstevel@tonic-gate break; 1865*7c478bd9Sstevel@tonic-gate } 1866*7c478bd9Sstevel@tonic-gate q = q->next; 1867*7c478bd9Sstevel@tonic-gate } 1868*7c478bd9Sstevel@tonic-gate p = p->next; 1869*7c478bd9Sstevel@tonic-gate } 1870*7c478bd9Sstevel@tonic-gate 1871*7c478bd9Sstevel@tonic-gate /* Now connect two linked lists. */ 1872*7c478bd9Sstevel@tonic-gate l1_tail = l1; 1873*7c478bd9Sstevel@tonic-gate while (l1_tail->next != NULL) { 1874*7c478bd9Sstevel@tonic-gate if (l1->next == NULL) 1875*7c478bd9Sstevel@tonic-gate break; 1876*7c478bd9Sstevel@tonic-gate l1_tail = l1_tail-> next; 1877*7c478bd9Sstevel@tonic-gate } 1878*7c478bd9Sstevel@tonic-gate l1_tail->next = l2; 1879*7c478bd9Sstevel@tonic-gate 1880*7c478bd9Sstevel@tonic-gate return (l1); 1881*7c478bd9Sstevel@tonic-gate } /* append_list */ 1882*7c478bd9Sstevel@tonic-gate 1883*7c478bd9Sstevel@tonic-gate /* 1884*7c478bd9Sstevel@tonic-gate * Writes one domain list to the file. 1885*7c478bd9Sstevel@tonic-gate */ 1886*7c478bd9Sstevel@tonic-gate static void 1887*7c478bd9Sstevel@tonic-gate write_one_file(struct domain_st *head) 1888*7c478bd9Sstevel@tonic-gate { 1889*7c478bd9Sstevel@tonic-gate FILE *fp; 1890*7c478bd9Sstevel@tonic-gate char fname [MAX_PATH_LEN]; 1891*7c478bd9Sstevel@tonic-gate char dname [MAX_DOMAIN_LEN]; 1892*7c478bd9Sstevel@tonic-gate struct element_st *p; 1893*7c478bd9Sstevel@tonic-gate struct element_st *existing_po_list; 1894*7c478bd9Sstevel@tonic-gate 1895*7c478bd9Sstevel@tonic-gate /* 1896*7c478bd9Sstevel@tonic-gate * If head is NULL, then it still has to create .po file 1897*7c478bd9Sstevel@tonic-gate * so that it will guarantee that the previous .po file was 1898*7c478bd9Sstevel@tonic-gate * alwasys deleted. 1899*7c478bd9Sstevel@tonic-gate * This is why checking NULL pointer has been moved to after 1900*7c478bd9Sstevel@tonic-gate * creating .po file. 1901*7c478bd9Sstevel@tonic-gate */ 1902*7c478bd9Sstevel@tonic-gate 1903*7c478bd9Sstevel@tonic-gate /* 1904*7c478bd9Sstevel@tonic-gate * If domain name is NULL, it is the default domain list. 1905*7c478bd9Sstevel@tonic-gate * The domain name is either "messages" or specified by option -d. 1906*7c478bd9Sstevel@tonic-gate * The default domain name is contained in default_domain variable. 1907*7c478bd9Sstevel@tonic-gate */ 1908*7c478bd9Sstevel@tonic-gate dname[0] = NULL; 1909*7c478bd9Sstevel@tonic-gate if ((head != NULL) && 1910*7c478bd9Sstevel@tonic-gate (head->dname != NULL)) { 1911*7c478bd9Sstevel@tonic-gate (void) strcpy(dname, head->dname); 1912*7c478bd9Sstevel@tonic-gate } else { 1913*7c478bd9Sstevel@tonic-gate (void) strcpy(dname, default_domain); 1914*7c478bd9Sstevel@tonic-gate } 1915*7c478bd9Sstevel@tonic-gate 1916*7c478bd9Sstevel@tonic-gate /* 1917*7c478bd9Sstevel@tonic-gate * path is the current directory if not specified by option -p. 1918*7c478bd9Sstevel@tonic-gate */ 1919*7c478bd9Sstevel@tonic-gate fname[0] = 0; 1920*7c478bd9Sstevel@tonic-gate if (pflg == TRUE) { 1921*7c478bd9Sstevel@tonic-gate (void) strcat(fname, pathname); 1922*7c478bd9Sstevel@tonic-gate (void) strcat(fname, "/"); 1923*7c478bd9Sstevel@tonic-gate } 1924*7c478bd9Sstevel@tonic-gate (void) strcat(fname, dname); 1925*7c478bd9Sstevel@tonic-gate (void) strcat(fname, ".po"); 1926*7c478bd9Sstevel@tonic-gate 1927*7c478bd9Sstevel@tonic-gate /* 1928*7c478bd9Sstevel@tonic-gate * If -j flag is specified, read exsiting .po file and 1929*7c478bd9Sstevel@tonic-gate * append the current list to the end of the list read from 1930*7c478bd9Sstevel@tonic-gate * the existing .po file. 1931*7c478bd9Sstevel@tonic-gate */ 1932*7c478bd9Sstevel@tonic-gate if (jflg == TRUE) { 1933*7c478bd9Sstevel@tonic-gate /* 1934*7c478bd9Sstevel@tonic-gate * If head is NULL, we don't have to change existing file. 1935*7c478bd9Sstevel@tonic-gate * Therefore, just return it. 1936*7c478bd9Sstevel@tonic-gate */ 1937*7c478bd9Sstevel@tonic-gate if (head == NULL) { 1938*7c478bd9Sstevel@tonic-gate return; 1939*7c478bd9Sstevel@tonic-gate } 1940*7c478bd9Sstevel@tonic-gate existing_po_list = read_po(fname); 1941*7c478bd9Sstevel@tonic-gate head->gettext_head = append_list(existing_po_list, 1942*7c478bd9Sstevel@tonic-gate head->gettext_head); 1943*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 1944*7c478bd9Sstevel@tonic-gate if (head->dname != NULL) { 1945*7c478bd9Sstevel@tonic-gate printf("===after merge (-j option): <%s>===\n", 1946*7c478bd9Sstevel@tonic-gate head->dname); 1947*7c478bd9Sstevel@tonic-gate } else { 1948*7c478bd9Sstevel@tonic-gate printf("===after merge (-j option): <NULL>===\n"); 1949*7c478bd9Sstevel@tonic-gate } 1950*7c478bd9Sstevel@tonic-gate print_one_domain(head); 1951*7c478bd9Sstevel@tonic-gate #endif 1952*7c478bd9Sstevel@tonic-gate 1953*7c478bd9Sstevel@tonic-gate } /* if jflg */ 1954*7c478bd9Sstevel@tonic-gate 1955*7c478bd9Sstevel@tonic-gate if ((fp = fopen(fname, "w")) == NULL) { 1956*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1957*7c478bd9Sstevel@tonic-gate "ERROR, can't open output file: %s\n", fname); 1958*7c478bd9Sstevel@tonic-gate exit(2); 1959*7c478bd9Sstevel@tonic-gate } 1960*7c478bd9Sstevel@tonic-gate 1961*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "domain \"%s\"\n", dname); 1962*7c478bd9Sstevel@tonic-gate 1963*7c478bd9Sstevel@tonic-gate /* See comments above in the beginning of this function */ 1964*7c478bd9Sstevel@tonic-gate if (head == NULL) 1965*7c478bd9Sstevel@tonic-gate return; 1966*7c478bd9Sstevel@tonic-gate 1967*7c478bd9Sstevel@tonic-gate /* 1968*7c478bd9Sstevel@tonic-gate * There are separate storage for textdomain() calls if 1969*7c478bd9Sstevel@tonic-gate * -s option is used (textdomain_head linked list). 1970*7c478bd9Sstevel@tonic-gate * Otherwise, textdomain() is mixed with gettext(0 and dgettext(). 1971*7c478bd9Sstevel@tonic-gate * If mixed, the boolean varaible istextdomain is used to see 1972*7c478bd9Sstevel@tonic-gate * if the current node contains textdomain() or [d]gettext(). 1973*7c478bd9Sstevel@tonic-gate */ 1974*7c478bd9Sstevel@tonic-gate if (sflg == TRUE) { 1975*7c478bd9Sstevel@tonic-gate p = head->textdomain_head; 1976*7c478bd9Sstevel@tonic-gate while (p != NULL) { 1977*7c478bd9Sstevel@tonic-gate /* 1978*7c478bd9Sstevel@tonic-gate * textdomain output line already contains 1979*7c478bd9Sstevel@tonic-gate * FIle name and line number information. 1980*7c478bd9Sstevel@tonic-gate * Therefore, does not have to check for nflg. 1981*7c478bd9Sstevel@tonic-gate */ 1982*7c478bd9Sstevel@tonic-gate output_textdomain(fp, p); 1983*7c478bd9Sstevel@tonic-gate p = p->next; 1984*7c478bd9Sstevel@tonic-gate } 1985*7c478bd9Sstevel@tonic-gate } 1986*7c478bd9Sstevel@tonic-gate 1987*7c478bd9Sstevel@tonic-gate p = head->gettext_head; 1988*7c478bd9Sstevel@tonic-gate while (p != NULL) { 1989*7c478bd9Sstevel@tonic-gate 1990*7c478bd9Sstevel@tonic-gate /* 1991*7c478bd9Sstevel@tonic-gate * Comment is printed only if -c is used and 1992*7c478bd9Sstevel@tonic-gate * associated with gettext or dgettext. 1993*7c478bd9Sstevel@tonic-gate * textdomain is not associated with comments. 1994*7c478bd9Sstevel@tonic-gate * Changes: 1995*7c478bd9Sstevel@tonic-gate * comments should be extracted in case of -j option 1996*7c478bd9Sstevel@tonic-gate * because there are read from exising file. 1997*7c478bd9Sstevel@tonic-gate */ 1998*7c478bd9Sstevel@tonic-gate if (((cflg == TRUE) || (jflg == TRUE)) && 1999*7c478bd9Sstevel@tonic-gate (p->istextdomain != TRUE)) { 2000*7c478bd9Sstevel@tonic-gate output_comment(fp, p->comment); 2001*7c478bd9Sstevel@tonic-gate } 2002*7c478bd9Sstevel@tonic-gate 2003*7c478bd9Sstevel@tonic-gate /* 2004*7c478bd9Sstevel@tonic-gate * If -n is used, then file number and line number 2005*7c478bd9Sstevel@tonic-gate * information is printed. 2006*7c478bd9Sstevel@tonic-gate * In case of textdomain(), this information is redundant 2007*7c478bd9Sstevel@tonic-gate * and is not printed. 2008*7c478bd9Sstevel@tonic-gate * If linenum is 0, it means this information has been 2009*7c478bd9Sstevel@tonic-gate * read from existing po file and it already contains 2010*7c478bd9Sstevel@tonic-gate * file and line number info as a comment line. So, it 2011*7c478bd9Sstevel@tonic-gate * should not printed in such case. 2012*7c478bd9Sstevel@tonic-gate */ 2013*7c478bd9Sstevel@tonic-gate if ((nflg == TRUE) && (p->istextdomain == FALSE) && 2014*7c478bd9Sstevel@tonic-gate (p->linenum > 0)) { 2015*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "# File:%s, line:%d\n", 2016*7c478bd9Sstevel@tonic-gate p->fname, p->linenum); 2017*7c478bd9Sstevel@tonic-gate } 2018*7c478bd9Sstevel@tonic-gate 2019*7c478bd9Sstevel@tonic-gate /* 2020*7c478bd9Sstevel@tonic-gate * Depending on the type of node, output textdomain comment 2021*7c478bd9Sstevel@tonic-gate * or msgid. 2022*7c478bd9Sstevel@tonic-gate */ 2023*7c478bd9Sstevel@tonic-gate if ((sflg == FALSE) && 2024*7c478bd9Sstevel@tonic-gate (p->istextdomain == TRUE)) { 2025*7c478bd9Sstevel@tonic-gate output_textdomain(fp, p); 2026*7c478bd9Sstevel@tonic-gate } else { 2027*7c478bd9Sstevel@tonic-gate output_msgid(fp, p->msgid, p->isduplicate); 2028*7c478bd9Sstevel@tonic-gate } 2029*7c478bd9Sstevel@tonic-gate p = p->next; 2030*7c478bd9Sstevel@tonic-gate 2031*7c478bd9Sstevel@tonic-gate } /* while */ 2032*7c478bd9Sstevel@tonic-gate 2033*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 2034*7c478bd9Sstevel@tonic-gate } /* write_one_file */ 2035*7c478bd9Sstevel@tonic-gate 2036*7c478bd9Sstevel@tonic-gate /* 2037*7c478bd9Sstevel@tonic-gate * Prints out textdomain call as a comment line with file name and 2038*7c478bd9Sstevel@tonic-gate * the line number information. 2039*7c478bd9Sstevel@tonic-gate */ 2040*7c478bd9Sstevel@tonic-gate static void 2041*7c478bd9Sstevel@tonic-gate output_textdomain(FILE *fp, struct element_st *p) 2042*7c478bd9Sstevel@tonic-gate { 2043*7c478bd9Sstevel@tonic-gate 2044*7c478bd9Sstevel@tonic-gate if (p == NULL) 2045*7c478bd9Sstevel@tonic-gate return; 2046*7c478bd9Sstevel@tonic-gate 2047*7c478bd9Sstevel@tonic-gate /* 2048*7c478bd9Sstevel@tonic-gate * Write textdomain() line as a comment. 2049*7c478bd9Sstevel@tonic-gate */ 2050*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "# File:%s, line:%d, textdomain(\"%s\");\n", 2051*7c478bd9Sstevel@tonic-gate p->fname, p->linenum, p->msgid->str); 2052*7c478bd9Sstevel@tonic-gate } /* output_textdomain */ 2053*7c478bd9Sstevel@tonic-gate 2054*7c478bd9Sstevel@tonic-gate /* 2055*7c478bd9Sstevel@tonic-gate * Prints out comments from linked list. 2056*7c478bd9Sstevel@tonic-gate */ 2057*7c478bd9Sstevel@tonic-gate static void 2058*7c478bd9Sstevel@tonic-gate output_comment(FILE *fp, struct strlist_st *p) 2059*7c478bd9Sstevel@tonic-gate { 2060*7c478bd9Sstevel@tonic-gate if (p == NULL) 2061*7c478bd9Sstevel@tonic-gate return; 2062*7c478bd9Sstevel@tonic-gate 2063*7c478bd9Sstevel@tonic-gate /* 2064*7c478bd9Sstevel@tonic-gate * Write comment section. 2065*7c478bd9Sstevel@tonic-gate */ 2066*7c478bd9Sstevel@tonic-gate while (p != NULL) { 2067*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "# %s\n", p->str); 2068*7c478bd9Sstevel@tonic-gate p = p->next; 2069*7c478bd9Sstevel@tonic-gate } 2070*7c478bd9Sstevel@tonic-gate } /* output_comment */ 2071*7c478bd9Sstevel@tonic-gate 2072*7c478bd9Sstevel@tonic-gate /* 2073*7c478bd9Sstevel@tonic-gate * Prints out msgid along with msgstr. 2074*7c478bd9Sstevel@tonic-gate */ 2075*7c478bd9Sstevel@tonic-gate static void 2076*7c478bd9Sstevel@tonic-gate output_msgid(FILE *fp, struct strlist_st *p, int duplicate) 2077*7c478bd9Sstevel@tonic-gate { 2078*7c478bd9Sstevel@tonic-gate struct strlist_st *q; 2079*7c478bd9Sstevel@tonic-gate 2080*7c478bd9Sstevel@tonic-gate if (p == NULL) 2081*7c478bd9Sstevel@tonic-gate return; 2082*7c478bd9Sstevel@tonic-gate 2083*7c478bd9Sstevel@tonic-gate /* 2084*7c478bd9Sstevel@tonic-gate * Write msgid section. 2085*7c478bd9Sstevel@tonic-gate * If duplciate flag is ON, prepend "# " in front of every line 2086*7c478bd9Sstevel@tonic-gate * so that they are considered as comment lines in .po file. 2087*7c478bd9Sstevel@tonic-gate */ 2088*7c478bd9Sstevel@tonic-gate if (duplicate == TRUE) { 2089*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "# "); 2090*7c478bd9Sstevel@tonic-gate } 2091*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "msgid \"%s\"\n", p->str); 2092*7c478bd9Sstevel@tonic-gate q = p->next; 2093*7c478bd9Sstevel@tonic-gate while (q != NULL) { 2094*7c478bd9Sstevel@tonic-gate if (duplicate == TRUE) { 2095*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "# "); 2096*7c478bd9Sstevel@tonic-gate } 2097*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, " \"%s\"\n", q->str); 2098*7c478bd9Sstevel@tonic-gate q = q->next; 2099*7c478bd9Sstevel@tonic-gate } 2100*7c478bd9Sstevel@tonic-gate 2101*7c478bd9Sstevel@tonic-gate /* 2102*7c478bd9Sstevel@tonic-gate * Write msgstr section. 2103*7c478bd9Sstevel@tonic-gate * if -M option is specified, append <suffix> to msgid. 2104*7c478bd9Sstevel@tonic-gate * if -m option is specified, prepend <prefix> to msgid. 2105*7c478bd9Sstevel@tonic-gate */ 2106*7c478bd9Sstevel@tonic-gate if (duplicate == TRUE) { 2107*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "# "); 2108*7c478bd9Sstevel@tonic-gate } 2109*7c478bd9Sstevel@tonic-gate if ((mflg == TRUE) || (Mflg == TRUE)) { 2110*7c478bd9Sstevel@tonic-gate if (mflg == TRUE) { 2111*7c478bd9Sstevel@tonic-gate /* 2112*7c478bd9Sstevel@tonic-gate * If single line msgid, add suffix to the same line 2113*7c478bd9Sstevel@tonic-gate */ 2114*7c478bd9Sstevel@tonic-gate if ((Mflg == TRUE) && (p->next == NULL)) { 2115*7c478bd9Sstevel@tonic-gate /* -M and -m and single line case */ 2116*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, 2117*7c478bd9Sstevel@tonic-gate "msgstr \"%s%s%s\"\n", 2118*7c478bd9Sstevel@tonic-gate prefix, p->str, suffix); 2119*7c478bd9Sstevel@tonic-gate } else { 2120*7c478bd9Sstevel@tonic-gate /* -M and -m and multi line case */ 2121*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, 2122*7c478bd9Sstevel@tonic-gate "msgstr \"%s%s\"\n", 2123*7c478bd9Sstevel@tonic-gate prefix, p->str); 2124*7c478bd9Sstevel@tonic-gate } 2125*7c478bd9Sstevel@tonic-gate } else { 2126*7c478bd9Sstevel@tonic-gate if ((Mflg == TRUE) && (p->next == NULL)) { 2127*7c478bd9Sstevel@tonic-gate /* -M only with single line case */ 2128*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "msgstr \"%s%s\"\n", 2129*7c478bd9Sstevel@tonic-gate p->str, suffix); 2130*7c478bd9Sstevel@tonic-gate } else { 2131*7c478bd9Sstevel@tonic-gate /* -M only with multi line case */ 2132*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "msgstr \"%s\"\n", p->str); 2133*7c478bd9Sstevel@tonic-gate } 2134*7c478bd9Sstevel@tonic-gate } 2135*7c478bd9Sstevel@tonic-gate q = p->next; 2136*7c478bd9Sstevel@tonic-gate while (q != NULL) { 2137*7c478bd9Sstevel@tonic-gate if (duplicate == TRUE) { 2138*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "# "); 2139*7c478bd9Sstevel@tonic-gate } 2140*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, " \"%s\"\n", q->str); 2141*7c478bd9Sstevel@tonic-gate q = q->next; 2142*7c478bd9Sstevel@tonic-gate } 2143*7c478bd9Sstevel@tonic-gate /* 2144*7c478bd9Sstevel@tonic-gate * If multi line msgid, add suffix after the last line. 2145*7c478bd9Sstevel@tonic-gate */ 2146*7c478bd9Sstevel@tonic-gate if ((Mflg == TRUE) && (p->next != NULL) && 2147*7c478bd9Sstevel@tonic-gate (suffix[0] != NULL)) { 2148*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, " \"%s\"\n", suffix); 2149*7c478bd9Sstevel@tonic-gate } 2150*7c478bd9Sstevel@tonic-gate } else { 2151*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "msgstr\n"); 2152*7c478bd9Sstevel@tonic-gate } 2153*7c478bd9Sstevel@tonic-gate } /* output_msgid */ 2154*7c478bd9Sstevel@tonic-gate 2155*7c478bd9Sstevel@tonic-gate /* 2156*7c478bd9Sstevel@tonic-gate * Malloc a new element node and initialize fields. 2157*7c478bd9Sstevel@tonic-gate */ 2158*7c478bd9Sstevel@tonic-gate static struct element_st * 2159*7c478bd9Sstevel@tonic-gate new_element(void) 2160*7c478bd9Sstevel@tonic-gate { 2161*7c478bd9Sstevel@tonic-gate struct element_st *tmp; 2162*7c478bd9Sstevel@tonic-gate 2163*7c478bd9Sstevel@tonic-gate tmp = (struct element_st *)malloc(sizeof (struct element_st)); 2164*7c478bd9Sstevel@tonic-gate tmp->istextdomain = FALSE; 2165*7c478bd9Sstevel@tonic-gate tmp->isduplicate = FALSE; 2166*7c478bd9Sstevel@tonic-gate tmp->msgid = NULL; 2167*7c478bd9Sstevel@tonic-gate tmp->msgstr = NULL; 2168*7c478bd9Sstevel@tonic-gate tmp->comment = NULL; 2169*7c478bd9Sstevel@tonic-gate tmp->fname = NULL; 2170*7c478bd9Sstevel@tonic-gate tmp->linenum = 0; 2171*7c478bd9Sstevel@tonic-gate tmp->next = NULL; 2172*7c478bd9Sstevel@tonic-gate 2173*7c478bd9Sstevel@tonic-gate return (tmp); 2174*7c478bd9Sstevel@tonic-gate } /* new_element */ 2175*7c478bd9Sstevel@tonic-gate 2176*7c478bd9Sstevel@tonic-gate /* 2177*7c478bd9Sstevel@tonic-gate * Malloc a new domain node and initialize fields. 2178*7c478bd9Sstevel@tonic-gate */ 2179*7c478bd9Sstevel@tonic-gate static struct domain_st * 2180*7c478bd9Sstevel@tonic-gate new_domain(void) 2181*7c478bd9Sstevel@tonic-gate { 2182*7c478bd9Sstevel@tonic-gate struct domain_st *tmp; 2183*7c478bd9Sstevel@tonic-gate 2184*7c478bd9Sstevel@tonic-gate tmp = (struct domain_st *)malloc(sizeof (struct domain_st)); 2185*7c478bd9Sstevel@tonic-gate tmp->dname = NULL; 2186*7c478bd9Sstevel@tonic-gate tmp->gettext_head = NULL; 2187*7c478bd9Sstevel@tonic-gate tmp->gettext_tail = NULL; 2188*7c478bd9Sstevel@tonic-gate tmp->textdomain_head = NULL; 2189*7c478bd9Sstevel@tonic-gate tmp->textdomain_tail = NULL; 2190*7c478bd9Sstevel@tonic-gate tmp->next = NULL; 2191*7c478bd9Sstevel@tonic-gate 2192*7c478bd9Sstevel@tonic-gate return (tmp); 2193*7c478bd9Sstevel@tonic-gate } /* new_domain */ 2194*7c478bd9Sstevel@tonic-gate 2195*7c478bd9Sstevel@tonic-gate /* 2196*7c478bd9Sstevel@tonic-gate * Malloc a new string list node and initialize fields. 2197*7c478bd9Sstevel@tonic-gate */ 2198*7c478bd9Sstevel@tonic-gate static struct strlist_st * 2199*7c478bd9Sstevel@tonic-gate new_strlist(void) 2200*7c478bd9Sstevel@tonic-gate { 2201*7c478bd9Sstevel@tonic-gate struct strlist_st *tmp; 2202*7c478bd9Sstevel@tonic-gate 2203*7c478bd9Sstevel@tonic-gate tmp = (struct strlist_st *)malloc(sizeof (struct strlist_st)); 2204*7c478bd9Sstevel@tonic-gate tmp->str = NULL; 2205*7c478bd9Sstevel@tonic-gate tmp->next = NULL; 2206*7c478bd9Sstevel@tonic-gate 2207*7c478bd9Sstevel@tonic-gate return (tmp); 2208*7c478bd9Sstevel@tonic-gate } /* new_strlist */ 2209*7c478bd9Sstevel@tonic-gate 2210*7c478bd9Sstevel@tonic-gate /* 2211*7c478bd9Sstevel@tonic-gate * Malloc a new exclude string list node and initialize fields. 2212*7c478bd9Sstevel@tonic-gate */ 2213*7c478bd9Sstevel@tonic-gate static struct exclude_st * 2214*7c478bd9Sstevel@tonic-gate new_exclude(void) 2215*7c478bd9Sstevel@tonic-gate { 2216*7c478bd9Sstevel@tonic-gate struct exclude_st *tmp; 2217*7c478bd9Sstevel@tonic-gate 2218*7c478bd9Sstevel@tonic-gate tmp = (struct exclude_st *)malloc(sizeof (struct exclude_st)); 2219*7c478bd9Sstevel@tonic-gate tmp->exstr = NULL; 2220*7c478bd9Sstevel@tonic-gate tmp->next = NULL; 2221*7c478bd9Sstevel@tonic-gate 2222*7c478bd9Sstevel@tonic-gate return (tmp); 2223*7c478bd9Sstevel@tonic-gate } /* new_exclude */ 2224*7c478bd9Sstevel@tonic-gate 2225*7c478bd9Sstevel@tonic-gate /* 2226*7c478bd9Sstevel@tonic-gate * Local version of strcat to keep within maximum string size. 2227*7c478bd9Sstevel@tonic-gate */ 2228*7c478bd9Sstevel@tonic-gate static void 2229*7c478bd9Sstevel@tonic-gate lstrcat(char *s1, const char *s2) 2230*7c478bd9Sstevel@tonic-gate { 2231*7c478bd9Sstevel@tonic-gate char *es1 = &s1[MAX_STRING_LEN]; 2232*7c478bd9Sstevel@tonic-gate char *ss1 = s1; 2233*7c478bd9Sstevel@tonic-gate 2234*7c478bd9Sstevel@tonic-gate while (*s1++) 2235*7c478bd9Sstevel@tonic-gate ; 2236*7c478bd9Sstevel@tonic-gate --s1; 2237*7c478bd9Sstevel@tonic-gate while (*s1++ = *s2++) 2238*7c478bd9Sstevel@tonic-gate if (s1 >= es1) { 2239*7c478bd9Sstevel@tonic-gate s1[-1] = '\0'; 2240*7c478bd9Sstevel@tonic-gate if ((in_comment == TRUE || in_quote == TRUE) && 2241*7c478bd9Sstevel@tonic-gate (warn_linenum != curr_linenum)) { 2242*7c478bd9Sstevel@tonic-gate if (stdin_only == FALSE) { 2243*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2244*7c478bd9Sstevel@tonic-gate "WARNING: file %s line %d exceeds "\ 2245*7c478bd9Sstevel@tonic-gate "%d characters: \"%15.15s\"\n", 2246*7c478bd9Sstevel@tonic-gate curr_file, curr_linenum, 2247*7c478bd9Sstevel@tonic-gate MAX_STRING_LEN, ss1); 2248*7c478bd9Sstevel@tonic-gate } else { 2249*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2250*7c478bd9Sstevel@tonic-gate "WARNING: line %d exceeds "\ 2251*7c478bd9Sstevel@tonic-gate "%d characters: \"%15.15s\"\n", 2252*7c478bd9Sstevel@tonic-gate curr_linenum, MAX_STRING_LEN, ss1); 2253*7c478bd9Sstevel@tonic-gate } 2254*7c478bd9Sstevel@tonic-gate warn_linenum = curr_linenum; 2255*7c478bd9Sstevel@tonic-gate } 2256*7c478bd9Sstevel@tonic-gate break; 2257*7c478bd9Sstevel@tonic-gate } 2258*7c478bd9Sstevel@tonic-gate } /* lstrcat */ 2259*7c478bd9Sstevel@tonic-gate 2260*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 2261*7c478bd9Sstevel@tonic-gate /* 2262*7c478bd9Sstevel@tonic-gate * Debug print routine. Compiled only with DEBUG on. 2263*7c478bd9Sstevel@tonic-gate */ 2264*7c478bd9Sstevel@tonic-gate void 2265*7c478bd9Sstevel@tonic-gate print_element_list(struct element_st *q) 2266*7c478bd9Sstevel@tonic-gate { 2267*7c478bd9Sstevel@tonic-gate struct strlist_st *r; 2268*7c478bd9Sstevel@tonic-gate 2269*7c478bd9Sstevel@tonic-gate while (q != NULL) { 2270*7c478bd9Sstevel@tonic-gate printf(" istextdomain = %d\n", q->istextdomain); 2271*7c478bd9Sstevel@tonic-gate printf(" isduplicate = %d\n", q->isduplicate); 2272*7c478bd9Sstevel@tonic-gate if ((q->msgid != NULL) && (q->msgid->str != NULL)) { 2273*7c478bd9Sstevel@tonic-gate printf(" msgid = <%s>\n", q->msgid->str); 2274*7c478bd9Sstevel@tonic-gate r = q->msgid->next; 2275*7c478bd9Sstevel@tonic-gate while (r != NULL) { 2276*7c478bd9Sstevel@tonic-gate printf(" <%s>\n", r->str); 2277*7c478bd9Sstevel@tonic-gate r = r->next; 2278*7c478bd9Sstevel@tonic-gate } 2279*7c478bd9Sstevel@tonic-gate } else { 2280*7c478bd9Sstevel@tonic-gate printf(" msgid = <NULL>\n"); 2281*7c478bd9Sstevel@tonic-gate } 2282*7c478bd9Sstevel@tonic-gate if ((q->msgstr != NULL) && (q->msgstr->str != NULL)) { 2283*7c478bd9Sstevel@tonic-gate printf(" msgstr= <%s>\n", q->msgstr->str); 2284*7c478bd9Sstevel@tonic-gate r = q->msgstr->next; 2285*7c478bd9Sstevel@tonic-gate while (r != NULL) { 2286*7c478bd9Sstevel@tonic-gate printf(" <%s>\n", r->str); 2287*7c478bd9Sstevel@tonic-gate r = r->next; 2288*7c478bd9Sstevel@tonic-gate } 2289*7c478bd9Sstevel@tonic-gate } else { 2290*7c478bd9Sstevel@tonic-gate printf(" msgstr= <NULL>\n"); 2291*7c478bd9Sstevel@tonic-gate } 2292*7c478bd9Sstevel@tonic-gate 2293*7c478bd9Sstevel@tonic-gate if (q->comment == NULL) { 2294*7c478bd9Sstevel@tonic-gate printf(" comment = <NULL>\n"); 2295*7c478bd9Sstevel@tonic-gate } else { 2296*7c478bd9Sstevel@tonic-gate printf(" comment = <%s>\n", q->comment->str); 2297*7c478bd9Sstevel@tonic-gate r = q->comment->next; 2298*7c478bd9Sstevel@tonic-gate while (r != NULL) { 2299*7c478bd9Sstevel@tonic-gate printf(" <%s>\n", r->str); 2300*7c478bd9Sstevel@tonic-gate r = r->next; 2301*7c478bd9Sstevel@tonic-gate } 2302*7c478bd9Sstevel@tonic-gate } 2303*7c478bd9Sstevel@tonic-gate 2304*7c478bd9Sstevel@tonic-gate if (q->fname == NULL) { 2305*7c478bd9Sstevel@tonic-gate printf(" fname = <NULL>\n"); 2306*7c478bd9Sstevel@tonic-gate } else { 2307*7c478bd9Sstevel@tonic-gate printf(" fname = <%s>\n", q->fname); 2308*7c478bd9Sstevel@tonic-gate } 2309*7c478bd9Sstevel@tonic-gate printf(" linenum = %d\n", q->linenum); 2310*7c478bd9Sstevel@tonic-gate printf("\n"); 2311*7c478bd9Sstevel@tonic-gate q = q->next; 2312*7c478bd9Sstevel@tonic-gate } 2313*7c478bd9Sstevel@tonic-gate } 2314*7c478bd9Sstevel@tonic-gate 2315*7c478bd9Sstevel@tonic-gate /* 2316*7c478bd9Sstevel@tonic-gate * Debug print routine. Compiled only with DEBUG on. 2317*7c478bd9Sstevel@tonic-gate */ 2318*7c478bd9Sstevel@tonic-gate void 2319*7c478bd9Sstevel@tonic-gate print_one_domain(struct domain_st *p) 2320*7c478bd9Sstevel@tonic-gate { 2321*7c478bd9Sstevel@tonic-gate struct element_st *q; 2322*7c478bd9Sstevel@tonic-gate 2323*7c478bd9Sstevel@tonic-gate if (p == NULL) { 2324*7c478bd9Sstevel@tonic-gate printf("domain pointer = <NULL>\n"); 2325*7c478bd9Sstevel@tonic-gate return; 2326*7c478bd9Sstevel@tonic-gate } else if (p->dname == NULL) { 2327*7c478bd9Sstevel@tonic-gate printf("domain_name = <%s>\n", "<NULL>"); 2328*7c478bd9Sstevel@tonic-gate } else { 2329*7c478bd9Sstevel@tonic-gate printf("domain_name = <%s>\n", p->dname); 2330*7c478bd9Sstevel@tonic-gate } 2331*7c478bd9Sstevel@tonic-gate q = p->gettext_head; 2332*7c478bd9Sstevel@tonic-gate print_element_list(q); 2333*7c478bd9Sstevel@tonic-gate 2334*7c478bd9Sstevel@tonic-gate q = p->textdomain_head; 2335*7c478bd9Sstevel@tonic-gate print_element_list(q); 2336*7c478bd9Sstevel@tonic-gate } /* print_one_domain */ 2337*7c478bd9Sstevel@tonic-gate 2338*7c478bd9Sstevel@tonic-gate void 2339*7c478bd9Sstevel@tonic-gate print_all_domain(struct domain_st *dom_list) 2340*7c478bd9Sstevel@tonic-gate { 2341*7c478bd9Sstevel@tonic-gate struct domain_st *p; 2342*7c478bd9Sstevel@tonic-gate struct element_st *q; 2343*7c478bd9Sstevel@tonic-gate 2344*7c478bd9Sstevel@tonic-gate p = dom_list; 2345*7c478bd9Sstevel@tonic-gate while (p != NULL) { 2346*7c478bd9Sstevel@tonic-gate print_one_domain(p); 2347*7c478bd9Sstevel@tonic-gate p = p->next; 2348*7c478bd9Sstevel@tonic-gate } /* while */ 2349*7c478bd9Sstevel@tonic-gate } /* print_all_domain */ 2350*7c478bd9Sstevel@tonic-gate #endif 2351