summaryrefslogtreecommitdiff
path: root/usr/src/cmd/msgfmt/xgettext.lx.l
blob: 09aff55371b3e864714fe99979e5706dbae4c0b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
%{
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 * Copyright (c) 1991, 2001 by Sun Microsystems, Inc.
 * All rights reserved.
 */
#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <stdio.h>
#include <string.h>

#define	TRUE	1
#define	FALSE	0

extern int	stdin_only;
extern char	curr_file[];	/* Name of file currently being read. */
extern int	curr_linenum;	/* line number in the current input file */
extern int	warn_linenum;	/* line number of current warning message */
extern int	optind;
extern int	gargc;
extern char	**gargv;

extern void	handle_macro_line(void);
extern void	handle_cplus_comment_line(void);
extern void	handle_open_comment(void);
extern void	handle_close_comment(void);
extern void	handle_gettext(void);
extern void	handle_dgettext(void);
extern void	handle_dcgettext(void);
extern void	handle_textdomain(void);
extern void	handle_character(void);
extern void	handle_open_paren(void);
extern void	handle_close_paren(void);
extern void	handle_esc_newline(void);
extern void	handle_comma(void);
extern void	handle_newline(void);
extern void	handle_quote(void);
extern void	handle_spaces(void);
extern void	handle_spaces(void);
extern void	handle_character(void);

/*
 * The following lex rule basically wants to recognize tokens
 * that can change the current state of scanning source code.
 * Evertime such tokens are recognized, the specific handler will be
 * executed. All other tokens are treated as regular characters and
 * they are all handled the same way.
 * The tricky part was not to miss any specification in ANSI-C code
 * that looks like a meaningful token but not a meaningful one and
 * should be treated as regular characters.
 * For example,
 *	c= '"';d='"'; printf("\"" "\(\)\\\"");
 *	c = ABgettext("Not a gettext");
 *	c = gettextXY("Not a gettext");
 *	c = ABgettextXY("Not a gettext");
 */
%}

IDCHARS		[a-zA-Z0-9_]

%%
^#(.*\\\n)**.*\n	{ handle_macro_line(); }

\/\/		{ handle_cplus_comment_line(); }

\/\* 		{ handle_open_comment(); }

\*\/ 		{ handle_close_comment(); }

dcgettext	{ handle_dcgettext(); }

dgettext	{ handle_dgettext(); }

gettext		{ handle_gettext(); }

textdomain	{ handle_textdomain(); }

{IDCHARS}+	|
\'\"\'		|
\'\\\"\'	|
\\\\		|
\\\"		|
\\\(		|
\\\)		{ handle_character(); }

\(		{ handle_open_paren(); }

\)		{ handle_close_paren(); }

\\\n		{ handle_esc_newline(); }

\,		{ handle_comma(); }

\n		{ handle_newline(); }

\"		{ handle_quote(); }

" "		{ handle_spaces(); }

"\t"		{ handle_spaces(); }

.		{ handle_character(); }

%%

/*
 * Since multiple files can be processed, yywrap() should keep feeding
 * all input files specified.
 */
int
yywrap(void)
{
	FILE	*fp;

	if ((optind >= gargc) || (stdin_only == TRUE)) {
		return (1);
	} else {
		/*
		 * gargv still contains not-processed input files.
		 */
		(void) freopen(gargv[optind], "r", stdin);
		if ((fp = freopen(gargv[optind], "r", stdin)) == NULL) {
			(void) fprintf(stderr, "ERROR, can't open input file: %s\n",
					gargv[optind]);
		}
#ifdef DEBUG
		(void) printf("In yywrap(), opening file  %d, <%s>\n",
				optind, gargv[optind]);
#endif
		/*
		 * Reset global file name and line number for the new file.
		 */
		(void) strcpy(curr_file, gargv[optind]);
		curr_linenum = 0;
		warn_linenum = 0;

		optind++;

		return (0);
	}

} /* yywrap */