Restrict locale settings to the file they occur in
This prevents LANG= in an included file from affecting the interpretation of month and day names in the including file. Make the internal pre-processor accept white space between the "#" at the start of the line and the keyword for better compatibility with cpp. Add support for the cpp keywords #warning and #error. MFC after: 3 days
This commit is contained in:
parent
20172854ab
commit
0357fa2632
@ -28,7 +28,7 @@
|
||||
.\" @(#)calendar.1 8.1 (Berkeley) 6/29/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 4, 2020
|
||||
.Dd November 5, 2020
|
||||
.Dt CALENDAR 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -199,13 +199,14 @@ file is preprocessed by a limited subset of
|
||||
internally, allowing the inclusion of shared files such as
|
||||
lists of company holidays or meetings.
|
||||
This limited subset consists of \fB#include\fR, \fB#define\fR,
|
||||
\fB#undef\fR, \fB#ifdef\fR, \fB#ifndef\fR, and \fB#else\fR.
|
||||
\fB#undef\fR, \fB#ifdef\fR, \fB#ifndef\fR, \fB#else\fR, \fB#warning\fR,
|
||||
and \fB#error\fR.
|
||||
.Pp
|
||||
Conditions can be nested and the consistency of opening and closing
|
||||
instructions is checked.
|
||||
Only the first word after #define is used as the name of the
|
||||
condition variable being defined.
|
||||
More than word following #ifdef, #ifndef, or #undef is a ayntax
|
||||
More than word following #ifdef, #ifndef, or #undef is considered a syntax
|
||||
error, since names cannot include white-space.
|
||||
Included files are parsed in a global scope with regard to the condition
|
||||
variables being defined or tested therein.
|
||||
|
@ -130,7 +130,6 @@ struct event {
|
||||
int month;
|
||||
int day;
|
||||
int var;
|
||||
char *date;
|
||||
char *text;
|
||||
char *extra;
|
||||
struct event *next;
|
||||
|
@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <iconv.h>
|
||||
#include <errno.h>
|
||||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
|
||||
static iconv_t conv = (iconv_t)-1;
|
||||
static char *currentEncoding = NULL;
|
||||
@ -204,13 +203,7 @@ event_print_all(FILE *fp)
|
||||
struct tm tm;
|
||||
char dbuf[80];
|
||||
static int d_first;
|
||||
const char *lang;
|
||||
|
||||
lang = getenv("LANG");
|
||||
if (lang == NULL)
|
||||
lang = "C";
|
||||
if (setlocale(LC_ALL, lang) == NULL)
|
||||
(void)setlocale(LC_ALL, "C");
|
||||
d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
|
||||
|
||||
while (walkthrough_dates(&e) != 0) {
|
||||
|
@ -172,6 +172,16 @@ cal_path(void)
|
||||
#define WARN1(format, arg1) \
|
||||
warnx(format " in %s line %d", arg1, cal_path(), cal_line)
|
||||
|
||||
static char*
|
||||
cmptoken(char *line, const char* token)
|
||||
{
|
||||
char len = strlen(token);
|
||||
|
||||
if (strncmp(line, token, len) != 0)
|
||||
return NULL;
|
||||
return (line + len);
|
||||
}
|
||||
|
||||
static int
|
||||
token(char *line, FILE *out, int *skip, int *unskip)
|
||||
{
|
||||
@ -181,7 +191,10 @@ token(char *line, FILE *out, int *skip, int *unskip)
|
||||
const char *this_cal_file;
|
||||
int this_cal_line;
|
||||
|
||||
if (strncmp(line, "endif", 5) == 0) {
|
||||
while (isspace(*line))
|
||||
line++;
|
||||
|
||||
if (cmptoken(line, "endif")) {
|
||||
if (*skip + *unskip == 0) {
|
||||
WARN0("#endif without prior #ifdef or #ifndef");
|
||||
return (T_ERR);
|
||||
@ -194,8 +207,8 @@ token(char *line, FILE *out, int *skip, int *unskip)
|
||||
return (T_OK);
|
||||
}
|
||||
|
||||
if (strncmp(line, "ifdef", 5) == 0) {
|
||||
walk = line + 5;
|
||||
walk = cmptoken(line, "ifdef");
|
||||
if (walk != NULL) {
|
||||
sep = trimlr(&walk);
|
||||
|
||||
if (*walk == '\0') {
|
||||
@ -217,8 +230,8 @@ token(char *line, FILE *out, int *skip, int *unskip)
|
||||
return (T_OK);
|
||||
}
|
||||
|
||||
if (strncmp(line, "ifndef", 6) == 0) {
|
||||
walk = line + 6;
|
||||
walk = cmptoken(line, "ifndef");
|
||||
if (walk != NULL) {
|
||||
sep = trimlr(&walk);
|
||||
|
||||
if (*walk == '\0') {
|
||||
@ -240,8 +253,8 @@ token(char *line, FILE *out, int *skip, int *unskip)
|
||||
return (T_OK);
|
||||
}
|
||||
|
||||
if (strncmp(line, "else", 4) == 0) {
|
||||
walk = line + 4;
|
||||
walk = cmptoken(line, "else");
|
||||
if (walk != NULL) {
|
||||
(void)trimlr(&walk);
|
||||
|
||||
if (*walk != '\0') {
|
||||
@ -267,9 +280,8 @@ token(char *line, FILE *out, int *skip, int *unskip)
|
||||
if (*skip != 0)
|
||||
return (T_OK);
|
||||
|
||||
if (strncmp(line, "include", 7) == 0) {
|
||||
walk = line + 7;
|
||||
|
||||
walk = cmptoken(line, "include");
|
||||
if (walk != NULL) {
|
||||
(void)trimlr(&walk);
|
||||
|
||||
if (*walk == '\0') {
|
||||
@ -306,10 +318,10 @@ token(char *line, FILE *out, int *skip, int *unskip)
|
||||
return (T_OK);
|
||||
}
|
||||
|
||||
if (strncmp(line, "define", 6) == 0) {
|
||||
walk = cmptoken(line, "define");
|
||||
if (walk != NULL) {
|
||||
if (definitions == NULL)
|
||||
definitions = sl_init();
|
||||
walk = line + 6;
|
||||
sep = trimlr(&walk);
|
||||
*sep = '\0';
|
||||
|
||||
@ -323,9 +335,9 @@ token(char *line, FILE *out, int *skip, int *unskip)
|
||||
return (T_OK);
|
||||
}
|
||||
|
||||
if (strncmp(line, "undef", 5) == 0) {
|
||||
walk = cmptoken(line, "undef");
|
||||
if (walk != NULL) {
|
||||
if (definitions != NULL) {
|
||||
walk = line + 5;
|
||||
sep = trimlr(&walk);
|
||||
|
||||
if (*walk == '\0') {
|
||||
@ -345,8 +357,32 @@ token(char *line, FILE *out, int *skip, int *unskip)
|
||||
return (T_OK);
|
||||
}
|
||||
|
||||
return (T_PROCESS);
|
||||
walk = cmptoken(line, "warning");
|
||||
if (walk != NULL) {
|
||||
(void)trimlr(&walk);
|
||||
WARN1("Warning: %s", walk);
|
||||
}
|
||||
|
||||
walk = cmptoken(line, "error");
|
||||
if (walk != NULL) {
|
||||
(void)trimlr(&walk);
|
||||
WARN1("Error: %s", walk);
|
||||
return (T_ERR);
|
||||
}
|
||||
|
||||
WARN1("Undefined pre-processor command \"#%s\"", line);
|
||||
return (T_ERR);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_locale(const char *locale)
|
||||
{
|
||||
(void)setlocale(LC_ALL, locale);
|
||||
#ifdef WITH_ICONV
|
||||
if (!doall)
|
||||
set_new_encoding();
|
||||
#endif
|
||||
setnnames();
|
||||
}
|
||||
|
||||
#define REPLACE(string, slen, struct_) \
|
||||
@ -361,6 +397,7 @@ token(char *line, FILE *out, int *skip, int *unskip)
|
||||
static int
|
||||
cal_parse(FILE *in, FILE *out)
|
||||
{
|
||||
char *mylocale = NULL;
|
||||
char *line = NULL;
|
||||
char *buf;
|
||||
size_t linecap = 0;
|
||||
@ -459,12 +496,9 @@ cal_parse(FILE *in, FILE *out)
|
||||
* and does not run iconv(), this variable has little use.
|
||||
*/
|
||||
if (strncmp(buf, "LANG=", 5) == 0) {
|
||||
(void)setlocale(LC_ALL, buf + 5);
|
||||
#ifdef WITH_ICONV
|
||||
if (!doall)
|
||||
set_new_encoding();
|
||||
#endif
|
||||
setnnames();
|
||||
if (mylocale == NULL)
|
||||
mylocale = strdup(setlocale(LC_ALL, NULL));
|
||||
setup_locale(buf + 5);
|
||||
continue;
|
||||
}
|
||||
/* Parse special definitions: Easter, Paskha etc */
|
||||
@ -538,6 +572,10 @@ cal_parse(FILE *in, FILE *out)
|
||||
|
||||
free(line);
|
||||
fclose(in);
|
||||
if (mylocale != NULL) {
|
||||
setup_locale(mylocale);
|
||||
free(mylocale);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user