aboutsummaryrefslogtreecommitdiff
path: root/libio
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-11-23 09:36:06 +0000
committerUlrich Drepper <drepper@redhat.com>1998-11-23 09:36:06 +0000
commit7d6a833849d8e084bbdc534698e214bca056453f (patch)
tree5e3f4055efe1797b093a2c927730ec7a0908567a /libio
parent9dc09d3060c01726779b4a19a934e6bb0cde5f67 (diff)
downloadglibc-7d6a833849d8e084bbdc534698e214bca056453f.zip
glibc-7d6a833849d8e084bbdc534698e214bca056453f.tar.gz
glibc-7d6a833849d8e084bbdc534698e214bca056453f.tar.bz2
1998-11-23 Ulrich Drepper <drepper@cygnus.com> * Makeconfig: Don't read sysd-sorted unless sysd-dirs is read. Patch by Zack Weinberg. * math/bits/mathcalls.h: Adjust comments. Remove gamma_r prototype. * sysdeps/i386/fpu/bits/mathinline.h: Make log2 only available if __USE_ISOC9X is defined. Provide rint optimization. 1998-11-21 H.J. Lu <hjl@gnu.org> * libio/Versions (_IO_popen, _IO_proc_open, _IO_proc_close, popen, pclose): Add to GLIBC_2.1. * libio/Makefile (routines): Add oldiopopen and oldpclose. (shared-only-routines): Likewise. * libio/pclose.c (pclose): Make it default for GLIBC_2.1. * libio/iopopen.c (_IO_proc_open, _IO_popen, popen, _IO_proc_close): Likewise. * libio/iolibio.h (_IO_new_popen, _IO_old_popen, __new_pclose, __old_pclose): New prototypes. * libio/libioP.h (_IO_new_file_jumps): Removed. (_IO_old_proc_jumps): Added. (_IO_new_proc_open, _IO_old_proc_open): New prototypes. * libio/oldiopopen.c: New file. * libio/oldpclose.c: New file. 1998-11-22 Thorsten Kukuk <kukuk@vt.uni-paderborn.de> * nss/Makefile: Build and install getent. * nss/getent.c: New, get entries from administrative database.
Diffstat (limited to 'libio')
-rw-r--r--libio/Makefile5
-rw-r--r--libio/Versions6
-rw-r--r--libio/iolibio.h4
-rw-r--r--libio/iopopen.c49
-rw-r--r--libio/libioP.h6
-rw-r--r--libio/oldiopopen.c282
-rw-r--r--libio/oldpclose.c44
-rw-r--r--libio/pclose.c14
8 files changed, 383 insertions, 27 deletions
diff --git a/libio/Makefile b/libio/Makefile
index 3dd3705..3a7f3b4 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -43,7 +43,8 @@ all: # Make this the default target; it will be defined in Rules.
include ../Makeconfig
ifeq ($(versioning),yes)
-routines += oldiofopen oldiofdopen oldiofclose oldtmpfile
+routines += oldiofopen oldiofdopen oldiofclose oldiopopen oldpclose \
+ oldtmpfile
endif
CPPFLAGS-.o += -DIO_DEBUG
@@ -63,7 +64,7 @@ aux += oldfileops oldstdfiles
endif
shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops \
- oldstdfiles oldtmpfile
+ oldstdfiles oldiopopen oldpclose oldtmpfile
distribute := iolibio.h libioP.h strfile.h Banner
diff --git a/libio/Versions b/libio/Versions
index c9d74d3..5073a20 100644
--- a/libio/Versions
+++ b/libio/Versions
@@ -81,13 +81,13 @@ libc {
_IO_2_1_stdin_; _IO_2_1_stdout_; _IO_2_1_stderr_;
# functions used in other libraries
- _IO_fclose; _IO_fopen; _IO_fdopen; __asprintf;
+ _IO_fclose; _IO_fopen; _IO_fdopen; _IO_popen; __asprintf;
# functions used in libstdc++
_IO_do_write; _IO_file_attach; _IO_file_close_it; _IO_file_finish;
_IO_file_fopen; _IO_file_init; _IO_file_overflow; _IO_file_seekoff;
_IO_file_setbuf; _IO_file_sync; _IO_file_underflow;
- _IO_file_write; _IO_file_xsputn;
+ _IO_file_write; _IO_file_xsputn; _IO_proc_open; _IO_proc_close;
# Changed getline function in libio.
_IO_getline_info;
@@ -95,6 +95,6 @@ libc {
# f*
fgetpos64; fopen64; freopen64; fseeko; fseeko64; fsetpos64; ftello;
ftello64; fopen; fclose; fdopen; fread_unlocked; fwrite_unlocked;
- fgets_unlocked; fputs_unlocked;
+ fgets_unlocked; fputs_unlocked; popen; pclose;
}
}
diff --git a/libio/iolibio.h b/libio/iolibio.h
index 0ec485e..7b25b40 100644
--- a/libio/iolibio.h
+++ b/libio/iolibio.h
@@ -62,6 +62,10 @@ extern int _IO_obstack_printf __P ((struct obstack *, const char *, ...));
(_IO_file_close_it(FP), _IO_file_fopen(FP, FILENAME, MODE, 1))
#define _IO_fileno(FP) ((FP)->_fileno)
extern _IO_FILE* _IO_popen __P((const char*, const char*));
+extern _IO_FILE* _IO_new_popen __P((const char*, const char*));
+extern _IO_FILE* _IO_old_popen __P((const char*, const char*));
+extern int __new_pclose __P((_IO_FILE *));
+extern int __old_pclose __P((_IO_FILE *));
#define _IO_pclose _IO_fclose
#define _IO_setbuf(_FP, _BUF) _IO_setbuffer(_FP, _BUF, _IO_BUFSIZ)
#define _IO_setlinebuf(_FP) _IO_setvbuf(_FP, NULL, 1, 0)
diff --git a/libio/iopopen.c b/libio/iopopen.c
index 62a6de2..31f9e02 100644
--- a/libio/iopopen.c
+++ b/libio/iopopen.c
@@ -104,7 +104,7 @@ typedef struct _IO_proc_file _IO_proc_file;
static struct _IO_proc_file *proc_file_chain = NULL;
_IO_FILE *
-_IO_proc_open (fp, command, mode)
+_IO_new_proc_open (fp, command, mode)
_IO_FILE *fp;
const char *command;
const char *mode;
@@ -177,7 +177,7 @@ _IO_proc_open (fp, command, mode)
}
_IO_FILE *
-_IO_popen (command, mode)
+_IO_new_popen (command, mode)
const char *command;
const char *mode;
{
@@ -199,23 +199,19 @@ _IO_popen (command, mode)
fp = &new_f->fpx.file.file;
_IO_init (fp, 0);
_IO_JUMPS (fp) = &_IO_proc_jumps;
- _IO_file_init (fp);
+ _IO_new_file_init (fp);
#if !_IO_UNIFIED_JUMPTABLES
new_f->fpx.file.vtable = NULL;
#endif
- if (_IO_proc_open (fp, command, mode) != NULL)
+ if (_IO_new_proc_open (fp, command, mode) != NULL)
return fp;
_IO_un_link (fp);
free (new_f);
return NULL;
}
-#ifdef strong_alias
-strong_alias (_IO_popen, popen);
-#endif
-
int
-_IO_proc_close (fp)
+_IO_new_proc_close (fp)
_IO_FILE *fp;
{
/* This is not name-space clean. FIXME! */
@@ -257,23 +253,40 @@ _IO_proc_close (fp)
struct _IO_jump_t _IO_proc_jumps = {
JUMP_INIT_DUMMY,
- JUMP_INIT(finish, _IO_file_finish),
- JUMP_INIT(overflow, _IO_file_overflow),
- JUMP_INIT(underflow, _IO_file_underflow),
+ JUMP_INIT(finish, _IO_new_file_finish),
+ JUMP_INIT(overflow, _IO_new_file_overflow),
+ JUMP_INIT(underflow, _IO_new_file_underflow),
JUMP_INIT(uflow, _IO_default_uflow),
JUMP_INIT(pbackfail, _IO_default_pbackfail),
- JUMP_INIT(xsputn, _IO_file_xsputn),
+ JUMP_INIT(xsputn, _IO_new_file_xsputn),
JUMP_INIT(xsgetn, _IO_default_xsgetn),
- JUMP_INIT(seekoff, _IO_file_seekoff),
+ JUMP_INIT(seekoff, _IO_new_file_seekoff),
JUMP_INIT(seekpos, _IO_default_seekpos),
- JUMP_INIT(setbuf, _IO_file_setbuf),
- JUMP_INIT(sync, _IO_file_sync),
+ JUMP_INIT(setbuf, _IO_new_file_setbuf),
+ JUMP_INIT(sync, _IO_new_file_sync),
JUMP_INIT(doallocate, _IO_file_doallocate),
JUMP_INIT(read, _IO_file_read),
- JUMP_INIT(write, _IO_file_write),
+ JUMP_INIT(write, _IO_new_file_write),
JUMP_INIT(seek, _IO_file_seek),
- JUMP_INIT(close, _IO_proc_close),
+ JUMP_INIT(close, _IO_new_proc_close),
JUMP_INIT(stat, _IO_file_stat),
JUMP_INIT(showmanyc, _IO_default_showmanyc),
JUMP_INIT(imbue, _IO_default_imbue)
};
+
+#if defined PIC && DO_VERSIONING
+strong_alias (_IO_new_popen, __new_popen)
+default_symbol_version (_IO_new_popen, _IO_popen, GLIBC_2.1);
+default_symbol_version (__new_popen, popen, GLIBC_2.1);
+default_symbol_version (_IO_new_proc_open, _IO_proc_open, GLIBC_2.1);
+default_symbol_version (_IO_new_proc_close, _IO_proc_close, GLIBC_2.1);
+#else
+# ifdef strong_alias
+strong_alias (_IO_new_popen, popen)
+# endif
+# ifdef weak_alias
+weak_alias (_IO_new_popen, _IO_popen)
+weak_alias (_IO_new_proc_open, _IO_proc_open)
+weak_alias (_IO_new_proc_close, _IO_proc_close)
+# endif
+#endif
diff --git a/libio/libioP.h b/libio/libioP.h
index 43fdb40..a9577ce 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -334,10 +334,10 @@ extern int _IO_default_showmanyc __P ((_IO_FILE *));
extern void _IO_default_imbue __P ((_IO_FILE *, void *));
extern struct _IO_jump_t _IO_file_jumps;
-extern struct _IO_jump_t _IO_new_file_jumps;
extern struct _IO_jump_t _IO_old_file_jumps;
extern struct _IO_jump_t _IO_streambuf_jumps;
extern struct _IO_jump_t _IO_proc_jumps;
+extern struct _IO_jump_t _IO_old_proc_jumps;
extern struct _IO_jump_t _IO_str_jumps;
extern int _IO_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
extern int _IO_new_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
@@ -424,7 +424,11 @@ extern void _IO_old_file_finish __P ((_IO_FILE *, int));
/* Jumptable functions for proc_files. */
extern _IO_FILE* _IO_proc_open __P ((_IO_FILE *, const char *, const char *));
+extern _IO_FILE* _IO_new_proc_open __P ((_IO_FILE *, const char *, const char *));
+extern _IO_FILE* _IO_old_proc_open __P ((_IO_FILE *, const char *, const char *));
extern int _IO_proc_close __P ((_IO_FILE *));
+extern int _IO_new_proc_close __P ((_IO_FILE *));
+extern int _IO_old_proc_close __P ((_IO_FILE *));
/* Jumptable functions for strfiles. */
extern int _IO_str_underflow __P ((_IO_FILE *));
diff --git a/libio/oldiopopen.c b/libio/oldiopopen.c
new file mode 100644
index 0000000..c2e7f25
--- /dev/null
+++ b/libio/oldiopopen.c
@@ -0,0 +1,282 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+ Written by Per Bothner <bothner@cygnus.com>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#define _IO_USE_OLD_IO_FILE
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
+#include "libioP.h"
+#if _IO_HAVE_SYS_WAIT
+#include <signal.h>
+#include <unistd.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#ifdef _LIBC
+# include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#ifndef _IO_fork
+#ifdef _LIBC
+#define _IO_fork __vfork
+#else
+#define _IO_fork vfork /* defined in libiberty, if needed */
+#endif
+extern _IO_pid_t _IO_fork __P ((void));
+#endif
+
+#endif /* _IO_HAVE_SYS_WAIT */
+
+#ifndef _IO_pipe
+#ifdef _LIBC
+#define _IO_pipe __pipe
+#else
+#define _IO_pipe pipe
+#endif
+extern int _IO_pipe __P ((int des[2]));
+#endif
+
+#ifndef _IO_dup2
+#ifdef _LIBC
+#define _IO_dup2 __dup2
+#else
+#define _IO_dup2 dup2
+#endif
+extern int _IO_dup2 __P ((int fd, int fd2));
+#endif
+
+#ifndef _IO_waitpid
+#ifdef _LIBC
+#define _IO_waitpid __waitpid
+#else
+#define _IO_waitpid waitpid
+#endif
+#endif
+
+#ifndef _IO_execl
+#define _IO_execl execl
+#endif
+#ifndef _IO__exit
+#define _IO__exit _exit
+#endif
+
+#ifndef _IO_close
+#ifdef _LIBC
+#define _IO_close __close
+#else
+#define _IO_close close
+#endif
+#endif
+
+struct _IO_proc_file
+{
+ struct _IO_FILE_plus file;
+ /* Following fields must match those in class procbuf (procbuf.h) */
+ _IO_pid_t pid;
+ struct _IO_proc_file *next;
+};
+typedef struct _IO_proc_file _IO_proc_file;
+
+static struct _IO_proc_file *old_proc_file_chain = NULL;
+
+_IO_FILE *
+_IO_old_proc_open (fp, command, mode)
+ _IO_FILE *fp;
+ const char *command;
+ const char *mode;
+{
+#if _IO_HAVE_SYS_WAIT
+ volatile int read_or_write;
+ volatile int parent_end, child_end;
+ int pipe_fds[2];
+ _IO_pid_t child_pid;
+ if (_IO_file_is_open (fp))
+ return NULL;
+ if (_IO_pipe (pipe_fds) < 0)
+ return NULL;
+ if (mode[0] == 'r' && mode[1] == '\0')
+ {
+ parent_end = pipe_fds[0];
+ child_end = pipe_fds[1];
+ read_or_write = _IO_NO_WRITES;
+ }
+ else if (mode[0] == 'w' && mode[1] == '\0')
+ {
+ parent_end = pipe_fds[1];
+ child_end = pipe_fds[0];
+ read_or_write = _IO_NO_READS;
+ }
+ else
+ {
+ __set_errno (EINVAL);
+ return NULL;
+ }
+ ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork ();
+ if (child_pid == 0)
+ {
+ int child_std_end = mode[0] == 'r' ? 1 : 0;
+ _IO_close (parent_end);
+ if (child_end != child_std_end)
+ {
+ _IO_dup2 (child_end, child_std_end);
+ _IO_close (child_end);
+ }
+ /* POSIX.2: "popen() shall ensure that any streams from previous
+ popen() calls that remain open in the parent process are closed
+ in the new child process." */
+ while (old_proc_file_chain)
+ {
+ _IO_close (_IO_fileno ((_IO_FILE *) old_proc_file_chain));
+ old_proc_file_chain = old_proc_file_chain->next;
+ }
+
+ _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0);
+ _IO__exit (127);
+ }
+ _IO_close (child_end);
+ if (child_pid < 0)
+ {
+ _IO_close (parent_end);
+ return NULL;
+ }
+ _IO_fileno (fp) = parent_end;
+
+ /* Link into old_proc_file_chain. */
+ ((_IO_proc_file *) fp)->next = old_proc_file_chain;
+ old_proc_file_chain = (_IO_proc_file *) fp;
+
+ _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES);
+ return fp;
+#else /* !_IO_HAVE_SYS_WAIT */
+ return NULL;
+#endif
+}
+
+_IO_FILE *
+_IO_old_popen (command, mode)
+ const char *command;
+ const char *mode;
+{
+ struct locked_FILE
+ {
+ struct _IO_proc_file fpx;
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_t lock;
+#endif
+ } *new_f;
+ _IO_FILE *fp;
+
+ new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
+ if (new_f == NULL)
+ return NULL;
+#ifdef _IO_MTSAFE_IO
+ new_f->fpx.file.file._lock = &new_f->lock;
+#endif
+ fp = &new_f->fpx.file.file;
+ _IO_init (fp, 0);
+ _IO_JUMPS (fp) = &_IO_old_proc_jumps;
+ _IO_old_file_init (fp);
+#if !_IO_UNIFIED_JUMPTABLES
+ new_f->fpx.file.vtable = NULL;
+#endif
+ if (_IO_old_proc_open (fp, command, mode) != NULL)
+ return fp;
+ _IO_un_link (fp);
+ free (new_f);
+ return NULL;
+}
+
+int
+_IO_old_proc_close (fp)
+ _IO_FILE *fp;
+{
+ /* This is not name-space clean. FIXME! */
+#if _IO_HAVE_SYS_WAIT
+ int wstatus;
+ _IO_proc_file **ptr = &old_proc_file_chain;
+ _IO_pid_t wait_pid;
+ int status = -1;
+
+ /* Unlink from old_proc_file_chain. */
+ for ( ; *ptr != NULL; ptr = &(*ptr)->next)
+ {
+ if (*ptr == (_IO_proc_file *) fp)
+ {
+ *ptr = (*ptr)->next;
+ status = 0;
+ break;
+ }
+ }
+
+ if (status < 0 || _IO_close (_IO_fileno(fp)) < 0)
+ return -1;
+ /* POSIX.2 Rationale: "Some historical implementations either block
+ or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting
+ for the child process to terminate. Since this behavior is not
+ described in POSIX.2, such implementations are not conforming." */
+ do
+ {
+ wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0);
+ }
+ while (wait_pid == -1 && errno == EINTR);
+ if (wait_pid == -1)
+ return -1;
+ return wstatus;
+#else /* !_IO_HAVE_SYS_WAIT */
+ return -1;
+#endif
+}
+
+struct _IO_jump_t _IO_old_proc_jumps = {
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_old_file_finish),
+ JUMP_INIT(overflow, _IO_old_file_overflow),
+ JUMP_INIT(underflow, _IO_old_file_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_default_pbackfail),
+ JUMP_INIT(xsputn, _IO_old_file_xsputn),
+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
+ JUMP_INIT(seekoff, _IO_old_file_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_old_file_setbuf),
+ JUMP_INIT(sync, _IO_old_file_sync),
+ JUMP_INIT(doallocate, _IO_file_doallocate),
+ JUMP_INIT(read, _IO_file_read),
+ JUMP_INIT(write, _IO_old_file_write),
+ JUMP_INIT(seek, _IO_file_seek),
+ JUMP_INIT(close, _IO_old_proc_close),
+ JUMP_INIT(stat, _IO_file_stat),
+ JUMP_INIT(showmanyc, _IO_default_showmanyc),
+ JUMP_INIT(imbue, _IO_default_imbue)
+};
+
+strong_alias (_IO_old_popen, __old_popen)
+symbol_version (_IO_old_popen, _IO_popen, GLIBC_2.0);
+symbol_version (__old_popen, popen, GLIBC_2.0);
+symbol_version (_IO_old_proc_open, _IO_proc_open, GLIBC_2.0);
+symbol_version (_IO_old_proc_close, _IO_proc_close, GLIBC_2.0);
diff --git a/libio/oldpclose.c b/libio/oldpclose.c
new file mode 100644
index 0000000..dc789c0
--- /dev/null
+++ b/libio/oldpclose.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#define _IO_USE_OLD_IO_FILE
+#include "libioP.h"
+#include "stdio.h"
+#include <errno.h>
+
+int
+__old_pclose (fp)
+ FILE *fp;
+{
+#if 0
+ /* Does not actually test that stream was created by popen(). Instead,
+ it depends on the filebuf::sys_close() virtual to Do The Right Thing. */
+ if (fp is not a proc_file)
+ return -1;
+#endif
+ return _IO_old_fclose (fp);
+}
+
+symbol_version (__old_pclose, pclose, GLIBC_2.0);
diff --git a/libio/pclose.c b/libio/pclose.c
index 0640d47..9443659 100644
--- a/libio/pclose.c
+++ b/libio/pclose.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -28,7 +28,7 @@
#include <errno.h>
int
-pclose (fp)
+__new_pclose (fp)
FILE *fp;
{
#if 0
@@ -37,5 +37,13 @@ pclose (fp)
if (fp is not a proc_file)
return -1;
#endif
- return _IO_fclose (fp);
+ return _IO_new_fclose (fp);
}
+
+#if defined PIC && DO_VERSIONING
+default_symbol_version (__new_pclose, pclose, GLIBC_2.1);
+#else
+# ifdef weak_alias
+weak_alias (__new_pclose, pclose)
+# endif
+#endif