Example #1
0
static int _read_for (FILE* fp, int(*match)(wchar_t), wchar_t* buffer, int ret)
{
	const wchar_t* skip = L" \n\t\r";
	wchar_t c;

	if(buffer==NULL){
		static wchar_t _buffer[1024];
		buffer = _buffer;
	}

	wchar_t* cur = buffer;

	while(wcinrange(c=fgetwc(fp), skip)){}
	ungetwc(c, fp);

	while(!feof(fp)){
		if(!match(c=fgetwc(fp))){
			break;
		}
		*cur++ = c;
	}
	if(ret){
		ungetwc(c, fp);
	}

	if(cur==buffer){
		return 0;
	}else{
		*cur++ = L'\0';
		return 1;
	}
}
Example #2
0
File: parsing.c Project: 8l/eight
closure *parse_number(FILE *file, closure *accum)
{
    wchar_t c = fgetwc(file);
    if(iswdigit(c)){
	return parse_number(file, cons(character(c), accum));
    } else if(iswspace(c)) {
	return string_to_number(reverse(accum));
    } else if(c == L')') {
	ungetwc(c, file); 
	return string_to_number(reverse(accum));
    } else {
	ungetwc(c, file);
	return parse_symbol(file, accum);
    }
}
Example #3
0
Result FStream_Unget(FStream* pfStream, wchar_t ch)
{
  int r = ungetwc(ch, pfStream->pFile);
  if (r == WEOF)
  {
  }
  return RESULT_OK;
}
JNIEXPORT jboolean JNICALL Java_mjava_io_SimpleInputStream_hasnextLine (JNIEnv * env, jobject obj)
{
	setlocale(LC_ALL, "Chinese-simplified"); // <clocale>

	wchar_t ch = getwchar();
	if(ch == WEOF) return 0; // 不要用EOF
	//if(ch == L'E') return 0; // 测试:读到E开头的字符串就退出

	ungetwc(ch, stdin);
	return 1;
}
Example #5
0
File: parsing.c Project: 8l/eight
closure *parse_symbol(FILE *file, closure *accum)
{
    //printf("parse sym\n");
    wchar_t c = fgetwc(file);
    if(iswspace(c)) {
	return string_to_symbol(reverse(accum));
    } else if(c == L'\"'){
	ungetwc(c, file); 
	return string_to_symbol(reverse(accum));
    } else if(c == L'('){
	ungetwc(c, file); 
	return string_to_symbol(reverse(accum));
    } else if(c == L')') {
	ungetwc(c, file); 
	return string_to_symbol(reverse(accum));
    } else if(c == L'#'){
	ungetwc(c, file); 
	return string_to_symbol(reverse(accum));
    } else {
	return parse_symbol(file, cons(character(c), accum));
    }
}
Example #6
0
File: parsing.c Project: 8l/eight
closure *parse_null(FILE *file, closure *accum)
{
    //printf("parse null\n");
    wchar_t c = fgetwc(file);
    if(iswspace(c)){
	return parse_null(file, nil());
    } else if(c == L'$'){
	return parse_character(file, nil());
    } else if(c == L'#'){
	parse_comment(file, nil());
	return parse_null(file, accum);
    } else if(c == L'\"'){
	return parse_string(file, nil());
    } else if(c == L'\''){
	wchar_t c = fgetwc(file);
	if (!iswspace(c)){
	    ungetwc(c, file);
	    closure *boo = parse_null(file, nil());
	    if (boo != NULL) return quote(boo);
	}
	return symbol(QUOTE);
    } else if(c == L'@'){
	wchar_t c = fgetwc(file);
	if (!iswspace(c)){
	    ungetwc(c, file);
	    closure *boo = parse_null(file, nil());
	    if (boo != NULL) return list(2, symbol(ATPEND), boo);
	}
	return symbol(ATPEND);
    } else if(c == L','){
	wchar_t c = fgetwc(file);
	if (!iswspace(c)){
	    ungetwc(c, file);
	    closure *boo = parse_null(file, nil());
	    if (boo != NULL) return list(2, symbol(COMMA), boo);
	}
	return symbol(COMMA);
    } else if(c == L'*'){
	wchar_t c = fgetwc(file);
	if (!iswspace(c)){
	    ungetwc(c, file);
	    closure *boo = parse_null(file, nil());
	    if (boo != NULL) return list(2, symbol(ASTERIX), boo);
	}
	return symbol(ASTERIX);
    } else if(iswdigit(c)){
	ungetwc(c, file);
	return parse_number(file, nil());
    } else if(c == L'('){
	return parse_list(file, nil());
    } else if(c == L')'){
	ungetwc(c, file);
	return NULL;
    } else if(c == WEOF || c == EOF){
	return NULL;
    } else {
	return parse_symbol(file, cons(character(c), nil()));
    }
}
Example #7
0
static	int
print(char *name)
{
	static	int	notfirst = 0;
	char	*date = NULL;
	char	*head = NULL;
	int	c;

	if (Multi != 'm' && mustopen(name, &Files[0]) == NULL)
		return (0);
	if (Multi == 'm' && Nfiles == 0 && mustopen(name, &Files[0]) == NULL)
		die("cannot open stdin");
	if (Buffer)
		(void) ungetwc(Files->f_nextc, Files->f_f);
	if (Lnumb)
		Lnumb = 1;
	for (Page = 0; ; putpage()) {
		if (C == WEOF && !(fold && Buffer))
			break;
		if (Buffer)
			nexbuf();
		Inpos = 0;
		if (get(0) == WEOF)
			break;
		(void) fflush(stdout);
		if (++Page >= Fpage) {
			/* Pause if -p and not first page */
			if (Ttyout && Pause && !notfirst++) {
				PROMPT();	/* prompt with bell and pause */
				while ((c = getc(Ttyin)) != EOF && c != '\n')
					;
			}
			if (Margin == 0)
				continue;
			if (date == NULL)
				date = GETDATE();
			if (head == NULL)
				head = Head != NULL ? Head :
				    Nfiles < 2 ? Files->f_name : nulls;
			(void) printf("\n\n");
			Nspace = Offset;
			putspace();
			(void) printf(HEAD);
		}
	}
	C = '\0';
	return (1);
}
Example #8
0
File: parsing.c Project: 8l/eight
closure *parse_list(FILE *file, closure *accum)
{
    //printf("parse list\n");
    //print_closure(accum);
    wchar_t c = fgetwc(file);
    if(c == L')'){
	return reverse(accum);
    } else {
	ungetwc(c, file); 
	closure *boo = parse_null(file, nil());
	if (boo != NULL){
	    return parse_list(file, cons(boo, accum));
	} else {
	    return parse_list(file, accum);
	}
    }
}
Example #9
0
/*
 * Return a character for lexical analyser.
 * Only one returned character is (not enforced) legitimite.
 */
static void
lexungetc(wint_t c)
{
	if (c == '\n')
		--lineno;
	if (c != WEOF) {
		if (conptr == &context[0])
			conptr = &context[NCONTEXT];
		*--conptr = '\0';
	}
	if (progfp != FNULL) {
		(void) ungetwc(c, progfp);
		return;
	}
	if (c == WEOF)
		return;
	*--progptr = c;
	proglen++;
}
Example #10
0
int mpq_inp_wstr10(mpq_t rop, FILE* in) {
	char* buf = malloc(sizeof(char));
	size_t len = 1;
	wint_t c;
	for(;;) {
		c = fgetwc(in);
		if(!(iswdigit(c) || (len == 1 && c == L'-') || (c == L'/')))
			break;
		len++;
		buf = realloc(buf, sizeof(char) * len);
		buf[len - 2] = wctob(c);
	}
	buf[len - 1] = '\0';
	ungetwc(c, in);
	
	int n = mpq_set_str(rop, buf, 10);
	free(buf);
	
	return n;
}
Example #11
0
	size_t Stream::read_line( wchar_t* buffer, size_t length, bool skip_emtpy_line )
	{
		if( file_ == 0 ) throw Invalid_IO();

		size_t count;
		wchar_t c = 0;
		do
		{
			count = 0;
			while( count < length && !feof( file_ ) )
			{
				buffer[count] = c = fgetwc( file_ );
				count++;

				if( c == '\n' ) break;
				if( c == '\r' )
				{
					buffer[count - 1] = c = '\n';

					if( !feof( file_ ) )
					{
						size_t next = fgetwc( file_ );
						if( next != '\n' )
							ungetwc( next, file_ );
					}

					break;
				}
			}
		} while( skip_emtpy_line && count == 1 && c == '\n' );

		if( count < length )
			buffer[count] = 0;
		else if( length > 0 )
			buffer[length - 1] = 0;

		return count;
	}
Example #12
0
static int
do_test (void)
{
  mtrace ();

  char *temp_file;
  TEST_VERIFY_EXIT (create_temp_file ("tst-bz22145.", &temp_file));

  char buf[BUFSIZ];

  {
    /* Check if backup buffer is correctly freed and changing back
       to normal buffer does not trigger an invalid free in case of
       static buffer set by setvbuf.  */

    FILE *f = fopen (temp_file, "w+b");
    TEST_VERIFY_EXIT (f != NULL);

    TEST_VERIFY_EXIT (setvbuf (f, buf, _IOFBF, BUFSIZ) == 0);
    TEST_VERIFY_EXIT (ungetc ('x', f) == 'x');
    TEST_VERIFY_EXIT (fseek (f, 0L, SEEK_SET) == 0);
    TEST_VERIFY_EXIT (fputc ('y', f) ==  'y');

    TEST_VERIFY_EXIT (fclose (f) == 0);
  }

  {
    /* Check if backup buffer is correctly freed and changing back
       to normal buffer does not trigger an invalid free in case of
       static buffer set by setvbuf.  */

    FILE *f = fopen (temp_file, "w+b");
    TEST_VERIFY_EXIT (f != NULL);

    TEST_VERIFY_EXIT (setvbuf (f, buf, _IOFBF, BUFSIZ) == 0);
    TEST_VERIFY_EXIT (ungetc ('x', f) == 'x');
    TEST_VERIFY_EXIT (fputc ('y', f) ==  'y');

    TEST_VERIFY_EXIT (fclose (f) == 0);
  }

  {
    FILE *f = fopen (temp_file, "w+b");
    TEST_VERIFY_EXIT (f != NULL);

    TEST_VERIFY_EXIT (setvbuf (f, buf, _IOFBF, BUFSIZ) == 0);
    TEST_VERIFY_EXIT (ungetwc (L'x', f) == L'x');
    TEST_VERIFY_EXIT (fseek (f, 0L, SEEK_SET) == 0);
    TEST_VERIFY_EXIT (fputwc (L'y', f) ==  L'y');

    TEST_VERIFY_EXIT (fclose (f) == 0);
  }

  {
    FILE *f = fopen (temp_file, "w+b");
    TEST_VERIFY_EXIT (f != NULL);

    TEST_VERIFY_EXIT (setvbuf (f, buf, _IOFBF, BUFSIZ) == 0);
    TEST_VERIFY_EXIT (ungetwc (L'x', f) == L'x');
    TEST_VERIFY_EXIT (fputwc (L'y', f) ==  L'y');

    TEST_VERIFY_EXIT (fclose (f) == 0);
  }

  free (temp_file);

  return 0;
}
Example #13
0
char *u8fgets(char *buf, int len, FILE *file)
{
	wint_t c, c0;
	wchar_t ws[2 + 1];
	char *b, *dst = NULL;

	if(file == stdin) {
		if(buf == NULL || len <= 0) return NULL;

		buf[0] = '\0';
		c0 = L'\0';
		while((c = fgetwc(file)) != WEOF) {
			if(IS_HIGH_SURROGATE(c0)) {
				if(IS_LOW_SURROGATE(c)) {
					ws[0] = c0;
					ws[1] = c;
					ws[2] = L'\0';
				}
				else {
					ungetwc(c, file);
					ws[0] = c0;
					ws[1] = L'\0';
				}
			}
			else if(IS_HIGH_SURROGATE(c)) {
				c0 = c;
				continue;
			}
			else {
				ws[0] = c;
				ws[1] = L'\0';
			}
			c0 = L'\0';

			b = u8wstos(ws);
			if(b) {
				if(len > (int)(strlen(buf) + strlen(b))) {
					strcat(buf, b);
					free(b);
				}
				else {
					free(b);
					if(ws[1] != L'\0') ungetwc(ws[1], file);
					if(ws[0] != L'\0') ungetwc(ws[0], file);
					break;
				}
			}

			if(c == L'\n') break;
		}

		if(c0 != L'\0') {
			ungetwc(c0, file);
		}

		if(strlen(buf) > 0) dst = buf;
	}
	else {
		dst = fgets(buf, len, file);
	}

	return dst;
}
Example #14
0
int main()
{
    mbstate_t mb = {0};
    size_t s = 0;
    tm tm = {0};
    wint_t w = 0;
    ::FILE* fp = 0;
    __darwin_va_list va;
    char* ns = 0;
    wchar_t* ws = 0;
    static_assert((std::is_same<decltype(fwprintf(fp, L"")), int>::value), "");
    static_assert((std::is_same<decltype(fwscanf(fp, L"")), int>::value), "");
    static_assert((std::is_same<decltype(swprintf(ws, s, L"")), int>::value), "");
    static_assert((std::is_same<decltype(swscanf(L"", L"")), int>::value), "");
    static_assert((std::is_same<decltype(vfwprintf(fp, L"", va)), int>::value), "");
    static_assert((std::is_same<decltype(vfwscanf(fp, L"", va)), int>::value), "");
    static_assert((std::is_same<decltype(vswprintf(ws, s, L"", va)), int>::value), "");
    static_assert((std::is_same<decltype(vswscanf(L"", L"", va)), int>::value), "");
    static_assert((std::is_same<decltype(vwprintf(L"", va)), int>::value), "");
    static_assert((std::is_same<decltype(vwscanf(L"", va)), int>::value), "");
    static_assert((std::is_same<decltype(wprintf(L"")), int>::value), "");
    static_assert((std::is_same<decltype(wscanf(L"")), int>::value), "");
    static_assert((std::is_same<decltype(fgetwc(fp)), wint_t>::value), "");
    static_assert((std::is_same<decltype(fgetws(ws, 0, fp)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(fputwc(L' ', fp)), wint_t>::value), "");
    static_assert((std::is_same<decltype(fputws(L"", fp)), int>::value), "");
    static_assert((std::is_same<decltype(fwide(fp, 0)), int>::value), "");
    static_assert((std::is_same<decltype(getwc(fp)), wint_t>::value), "");
    static_assert((std::is_same<decltype(getwchar()), wint_t>::value), "");
    static_assert((std::is_same<decltype(putwc(L' ', fp)), wint_t>::value), "");
    static_assert((std::is_same<decltype(putwchar(L' ')), wint_t>::value), "");
    static_assert((std::is_same<decltype(ungetwc(L' ', fp)), wint_t>::value), "");
    static_assert((std::is_same<decltype(wcstod(L"", (wchar_t**)0)), double>::value), "");
    static_assert((std::is_same<decltype(wcstof(L"", (wchar_t**)0)), float>::value), "");
    static_assert((std::is_same<decltype(wcstold(L"", (wchar_t**)0)), long double>::value), "");
    static_assert((std::is_same<decltype(wcstol(L"", (wchar_t**)0, 0)), long>::value), "");
    static_assert((std::is_same<decltype(wcstoll(L"", (wchar_t**)0, 0)), long long>::value), "");
    static_assert((std::is_same<decltype(wcstoul(L"", (wchar_t**)0, 0)), unsigned long>::value), "");
    static_assert((std::is_same<decltype(wcstoull(L"", (wchar_t**)0, 0)), unsigned long long>::value), "");
    static_assert((std::is_same<decltype(wcscpy(ws, L"")), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcsncpy(ws, L"", s)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcscat(ws, L"")), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcsncat(ws, L"", s)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcscmp(L"", L"")), int>::value), "");
    static_assert((std::is_same<decltype(wcscoll(L"", L"")), int>::value), "");
    static_assert((std::is_same<decltype(wcsncmp(L"", L"", s)), int>::value), "");
    static_assert((std::is_same<decltype(wcsxfrm(ws, L"", s)), size_t>::value), "");
    static_assert((std::is_same<decltype(wcschr((wchar_t*)0, L' ')), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcscspn(L"", L"")), size_t>::value), "");
    static_assert((std::is_same<decltype(wcslen(L"")), size_t>::value), "");
    static_assert((std::is_same<decltype(wcspbrk((wchar_t*)0, L"")), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcsrchr((wchar_t*)0, L' ')), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcsspn(L"", L"")), size_t>::value), "");
    static_assert((std::is_same<decltype(wcsstr((wchar_t*)0, L"")), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcstok(ws, L"", (wchar_t**)0)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wmemchr((wchar_t*)0, L' ', s)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wmemcmp(L"", L"", s)), int>::value), "");
    static_assert((std::is_same<decltype(wmemcpy(ws, L"", s)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wmemmove(ws, L"", s)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wmemset(ws, L' ', s)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcsftime(ws, s, L"", &tm)), size_t>::value), "");
    static_assert((std::is_same<decltype(btowc(0)), wint_t>::value), "");
    static_assert((std::is_same<decltype(wctob(w)), int>::value), "");
    static_assert((std::is_same<decltype(mbsinit(&mb)), int>::value), "");
    static_assert((std::is_same<decltype(mbrlen("", s, &mb)), size_t>::value), "");
    static_assert((std::is_same<decltype(mbrtowc(ws, "", s, &mb)), size_t>::value), "");
    static_assert((std::is_same<decltype(wcrtomb(ns, L' ', &mb)), size_t>::value), "");
    static_assert((std::is_same<decltype(mbsrtowcs(ws, (const char**)0, s, &mb)), size_t>::value), "");
    static_assert((std::is_same<decltype(wcsrtombs(ns, (const wchar_t**)0, s, &mb)), size_t>::value), "");
}
/**
 * Tests the communicator console input.
 */
void test_communicator_console_input() {

    log_write_terminated_message((void*) stdout, L"Test communicator console input:\n");

#ifdef GNU_LINUX_OPERATING_SYSTEM
    // The terminal device name.
    FILE* t = (FILE*) *NULL_POINTER_MEMORY_MODEL;
    // The old termios settings.
    struct termios* to = (struct termios*) *NULL_POINTER_MEMORY_MODEL;
    // The new termios settings.
    struct termios* tn = (struct termios*) *NULL_POINTER_MEMORY_MODEL;

    // Allocate gnu/linux console internals.
    to = (struct termios*) malloc(*INPUT_OUTPUT_SYSTEM_TERMINAL_TYPE_SIZE);
    tn = (struct termios*) malloc(*INPUT_OUTPUT_SYSTEM_TERMINAL_TYPE_SIZE);

    // Set file stream.
    t = stdin;

    // Get file descriptor for file stream.
    // CAUTION! The stream "stdin" must be used instead of "stdout" here!
    int d = fileno(t);

    // Test standard streams.
    int testin = fileno(stdin);
    int testout = fileno(stdout);
    int testerr = fileno(stderr);
    fwprintf(stdout, L"TEST in %i\n", testin);
    fwprintf(stdout, L"TEST out %i\n", testout);
    fwprintf(stdout, L"TEST err %i\n", testerr);

    // Store old termios settings.
    int e = tcgetattr(d, (void*) to);

    if (e != *NUMBER_MINUS_1_INTEGER_MEMORY_MODEL) {

        // Initialise new termios settings.
        *tn = *to;

        // Manipulate termios attributes.
        // Set number of characters.
        tn->c_cc[VMIN] = *NUMBER_1_INTEGER_MEMORY_MODEL;
        tn->c_cc[VTIME] = *NUMBER_0_INTEGER_MEMORY_MODEL;
        tn->c_lflag &= ~ICANON;
        // Switch off echo.
        tn->c_lflag &= ~ECHO;

        // Set new termios attributes.
        tcsetattr(d, TCSANOW, (void*) tn);

        wint_t c = fgetwc(t);

        fwprintf(stdout, L"TEST c: %i\n", c);

        ungetwc(c, t);

        fwprintf(stdout, L"TEST unget c: %i\n", c);

        wint_t again = fgetwc(t);

        fwprintf(stdout, L"TEST again c: %i\n", again);

        // Reset terminal to old settings.
        tcsetattr(d, TCSANOW, (void*) to);

    } else {

        if (errno == EBADF) {

            log_write_terminated_message((void*) stdout, L"Could not store old termios settings. The filedes argument is not a valid file descriptor.\n");

        } else if (errno == ENOTTY) {

            log_write_terminated_message((void*) stdout, L"Could not store old termios settings. The filedes is not associated with a terminal.\n");

        } else {

            log_write_terminated_message((void*) stdout, L"Could not store old termios settings.\n");
        }
    }
// GNU_LINUX_OPERATING_SYSTEM
#endif
}
Example #16
0
LISPTR lisp_read(FILE* in)
{
	LISPTR s = NIL;
	wchar_t ch = fgetwc(in);
	while (iswspace(ch)) {
		ch = fgetwc(in);
	}
	if (ch == '(') {
		// start of cons
		LISPTR last = s = cons(lisp_read(in), NIL);
		while (true) {
			ch = fgetwc(in); while (iswspace(ch)) { ch = fgetwc(in); }
			if (ch==WEOF || ch==')') { break; }
			ungetwc(ch, in);
			LISPTR e = lisp_read(in);
			rplacd(last, cons(e, NIL));
			last = cdr(last);
		}
	} else if (ch == '\'') {
		// '<expr>, sugar for (QUOTE <expr>)
		s = cons(QUOTE, cons(lisp_read(in), NIL));
	} else if (ch == '#') {
		// so-called sharpsign or 'dispatching macro character'
		// http://www.lispworks.com/documentation/HyperSpec/Body/02_dh.htm
		ch = fgetwc(in);
		switch (ch) {
		case '\'':				// function-quote
			s = cons(FUNCTION, cons(lisp_read(in), NIL));
			break;
		default:
			lisp_error(L"invalid char after #");
			break;
		} // switch
	} else if (ch == WEOF) {
		// end of file, return NIL.
	} else {
		// must be an atom - number, symbol or string
		wchar_t name[MAX_ATOM_CHARS];
		int n = 0;
		while (true) {
			if (n < MAX_ATOM_CHARS) {
				name[n++] = towupper(ch);
			}
			ch = fgetwc(in);
			if (ch==WEOF) break;				// better not be inside a string, eh?
			if (name[0] != '"') {
				// not a string
				if (iswspace(ch)) break;
				if (ch==')' || ch=='(') {
					ungetwc(ch, in);
					break;
				}
			} else {
				// collecting a string
				if (ch=='\\') {
					ch = fgetwc(in);
					if (ch==WEOF) break;		// bad luck er bad string syntax
				} else if (ch=='"') {
					break;				// end of string
				}
			}
		} // while (true)
		name[n] = 0;
		if (name[0] == '"') {
			s = intern_string(name+1);
		} else if (isnumber(name)) {
			s = intern_number(name);
		} else {
			s = intern(name);
		}
	}
	return s;
}
/**
 * Senses gnu/linux console message.
 *
 * @param p0 the interrupt
 * @param p1 the mutex
 * @param p2 the sleep time
 * @param p3 the input stream
 */
void communicate_sensing_gnu_linux_console_message(void* p0, void* p1, void* p2, void* p3) {

    if (p3 != *NULL_POINTER_MEMORY_MODEL) {

        FILE* is = (FILE*) p3;

        if (p2 != *NULL_POINTER_MEMORY_MODEL) {

            double* st = (double*) p2;

            if (p1 != *NULL_POINTER_MEMORY_MODEL) {

                pthread_mutex_t* mt = (pthread_mutex_t*) p1;

                if (p0 != *NULL_POINTER_MEMORY_MODEL) {

                    int* irq = (int*) p0;

                    // CAUTION! DO NOT log this function call!
                    // This function is executed within a thread, but the
                    // logging is not guaranteed to be thread-safe and might
                    // cause unpredictable programme behaviour.
                    // Also, this function runs in an endless loop and would produce huge log files.
                    // log_terminated_message((void*) DEBUG_LEVEL_LOG_MODEL, (void*) L"Sense gnu/linux console message.");

                    // Lock gnu/linux console mutex.
                    //
                    // CAUTION! This lock has to stand not only before the interrupt request is set below,
                    // BUT ALSO BEFORE the next character is detected in the input stream!
                    //
                    // This is because the main thread might be reading characters from the
                    // input stream right now in parallel, while this thread tries to read as well.
                    //
                    // This was tested out and lead to errors, because the "ungetwc" function below
                    // was unexpectedly putting back a character such as ^ (escape) or [
                    // which (in the case of escape) caused the programme to exit
                    // and other inputs like arrow down not to be recognised properly.
                    pthread_mutex_lock(mt);

                    // Get character from gnu/linux console input stream,
                    // just to detect that some (event) character is available.
                    // This is also called "peeking ahead" at the input.
                    //
                    // CAUTION! Use 'wint_t' instead of 'int' as return type for
                    // 'getwchar()', since that returns 'WEOF' instead of 'EOF'!
                    wint_t c = fgetwc(is);

                    if (c == WEOF) {

                        // No valid character was returned.

                        // Sleep for some time.
                        // This is to give the central processing unit (cpu) some
                        // time to breathe, that is to be idle or to process other signals.
                        sleep(*st);

                    } else {

                        // Unread character, that is push it back on the stream to
                        // make it available to be input again from the stream, by the
                        // next call to fgetc or another input function on that stream.
                        //
                        // If c is EOF, ungetc does nothing and just returns EOF.
                        // This lets you call ungetc with the return value of getc
                        // without needing to check for an error from getc.
                        //
                        // The character that you push back doesn't have to be the same
                        // as the last character that was actually read from the stream.
                        // In fact, it isn't necessary to actually read any characters
                        // from the stream before unreading them with ungetc!
                        // But that is a strange way to write a program;
                        // usually ungetc is used only to unread a character that was
                        // just read from the same stream.
                        //
                        // The GNU C library only supports one character of pushback.
                        // In other words, it does not work to call ungetc twice without
                        // doing input in between.
                        // Other systems might let you push back multiple characters;
                        // then reading from the stream retrieves the characters in the
                        // reverse order that they were pushed.
                        //
                        // Pushing back characters doesn't alter the file;
                        // only the internal buffering for the stream is affected.
                        // If a file positioning function (such as fseek, fseeko or rewind)
                        // is called, any pending pushed-back characters are discarded.
                        //
                        // Unreading a character on a stream that is at end of file
                        // clears the end-of-file indicator for the stream, because it
                        // makes the character of input available.
                        // After you read that character, trying to read again will
                        // encounter end of file.
                        ungetwc(c, is);

                        // Set gnu/linux console interrupt request to indicate
                        // that a message has been received via gnu/linux console,
                        // which may now be processed in the main thread of this system.
                        *irq = *NUMBER_1_INTEGER_MEMORY_MODEL;
                    }

                    // Unlock gnu/linux console mutex.
                    pthread_mutex_unlock(mt);

                    while (*irq != *NUMBER_0_INTEGER_MEMORY_MODEL) {

                        // Sleep as long as the gnu/linux console interrupt is not handled and reset yet.
                        //
                        // This is to give the central processing unit (cpu) some
                        // time to breathe, that is to be idle or to process other signals.
                        //
                        // Also, many character inputs are processed at once in the main thread
                        // and only if there are no further characters to be read, the irq flag is reset,
                        // so that this endless loop can be left and new inputs detected.
                        sleep(*st);
                    }

                } else {

                    // CAUTION! DO NOT log this function call!
                    // This function is executed within a thread, but the
                    // logging is not guaranteed to be thread-safe and might
                    // cause unpredictable programme behaviour.
                    // log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not sense gnu/linux console message. The interrupt is null.");
                }

            } else {

                // CAUTION! DO NOT log this function call!
                // This function is executed within a thread, but the
                // logging is not guaranteed to be thread-safe and might
                // cause unpredictable programme behaviour.
                // log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not sense gnu/linux console message. The mutex is null.");
            }

        } else {

            // CAUTION! DO NOT log this function call!
            // This function is executed within a thread, but the
            // logging is not guaranteed to be thread-safe and might
            // cause unpredictable programme behaviour.
            // log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not sense gnu/linux console message. The sleep time is null.");
        }

    } else {

        // CAUTION! DO NOT log this function call!
        // This function is executed within a thread, but the
        // logging is not guaranteed to be thread-safe and might
        // cause unpredictable programme behaviour.
        // log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not sense gnu/linux console message. The input stream is null.");
    }
}
Example #18
0
static	void
putspace(void)
{
	int nc = 0;

	for (; Nspace > 0; Outpos += nc, Nspace -= nc) {
#ifdef XPG4
		/* XPG4:  -i:  replace multiple SPACE chars with tab chars */
		if ((Nspace >= 2 && Itabn > 0 &&
			Nspace >= (nc = Itabn - Outpos % Itabn)) && !fold) {
#else
		/* Solaris:  -i:  replace white space with tab chars */
		if ((Itabn > 0 && Nspace >= (nc = Itabn - Outpos % Itabn)) &&
			!fold) {
#endif
			(void) fputwc(Itabc, stdout);
		} else {
			nc = 1;
			(void) putchar(' ');
		}
	}
}


static	void
unget(int colno)
{
	if (Buffer) {
		if (*(Colpts[colno].c_ptr-1) != '\t')
			--(Colpts[colno].c_ptr);
		if (Colpts[colno].c_lno)
			Colpts[colno].c_lno--;
	} else {
		if ((Multi == 'm' && colno == 0) || Multi != 'm')
			if (Lnumb && !foldcol)
				Lnumb--;
		colno = (Multi == 'a') ? 0 : colno;
		(void) ungetwc(Files[colno].f_nextc, Files[colno].f_f);
		Files[colno].f_nextc = C;
	}
}


/*
 * Defer message about failure to open file to prevent messing up
 * alignment of page with tear perforations or form markers.
 * Treat empty file as special case and report as diagnostic.
 */

static	FILE *
mustopen(char *s, FILS *f)
{
	char	*empty_file_msg = gettext("%s -- empty file");
	int	c;

	if (*s == '\0') {
		f->f_name = STDINNAME();
		f->f_f = stdin;
	} else if ((f->f_f = fopen(f->f_name = s, "r")) == NULL) {
		s = ffiler(f->f_name);
		s = strcpy((char *)getspace((UNS) strlen(s) + 1), s);
	}
	if (f->f_f != NULL) {
		errno = 0;
		f->f_nextc = _fgetwc_pr(f->f_f, &c);
		if (f->f_nextc != WEOF) {
			return (f->f_f);
		} else {	/* WEOF */
			if (errno == EILSEQ) {
				f->f_nextc = (wchar_t)c;
				return (f->f_f);
			}
			if (Multi == 'm')
				return (f->f_f);
		}
		(void) sprintf(s = (char *)getspace((UNS) strlen(f->f_name)
		    + 1 + (UNS) strlen(empty_file_msg)),
		    empty_file_msg, f->f_name);
		(void) fclose(f->f_f);
	}
	Error = 1;
	if (Report)
		if (Ttyout) {	/* accumulate error reports */
			Lasterr = Lasterr->e_nextp =
			    (ERR *) getspace((UNS) sizeof (ERR));
			Lasterr->e_nextp = NULL;
			Lasterr->e_mess = s;
		} else {	/* ok to print error report now */
			cerror(s);
			(void) putc('\n', stderr);
		}
	return ((FILE *)NULL);
}
Example #19
0
static int
do_test (void)
{
  size_t i;
  wint_t wc;
  FILE *fp;
  int fd;

  fname = (char *) malloc (strlen (test_dir) + sizeof "/bug-ungetwc2.XXXXXX");
  if (fname == NULL)
    {
      puts ("no memory");
      return 1;
    }
  strcpy (stpcpy (fname, test_dir), "/bug-ungetwc2.XXXXXX");
  fd = mkstemp (fname);
  if (fd == -1)
    {
      printf ("cannot open temporary file: %m\n");
      return 1;
    }
  add_temp_file (fname);

  printf ("\nNote: This program runs on %s locale.\n\n", test_locale);

  if (setlocale (LC_ALL, test_locale) == NULL)
    {
      fprintf (stderr, "Cannot use `%s' locale.\n", test_locale);
      exit (EXIT_FAILURE);
    }

  /* Output to the file. */
  if ((fp = fdopen (fd, "w")) == NULL)
    {
      setlocale (LC_ALL, "C");
      fprintf (stderr, "Cannot make `%s' file.\n", fname);
      exit (EXIT_FAILURE);
    }
  fprintf (fp, "%ls", write_wchars);
  fclose (fp);

  /* Read from the file. */
  fp = fopen (fname, "r");
  if (fp == NULL)
    {
      setlocale (LC_ALL, "C");
      error (EXIT_FAILURE, errno, "cannot open %s", fname);
    }

  printf ("%s is opened.\n", fname);

  for (i = 0; i < last_pos; i++)
    {
      wc = getwc (fp);
      printf ("> `%lc' is gotten.\n", wc);
    }

  /* Unget a wide character. */
  ungetwc (unget_wchar, fp);
  printf ("< `%lc' is ungotten.\n", unget_wchar);

  /* Reget the wide character. */
  wc = getwc (fp);
  printf ("> `%lc' is regotten.\n", wc);

  fflush (stdout);
  fclose (fp);

  return 0;
}
Example #20
0
int
main (void)
{
  FILE *fp;
  const char *str = "abcdef";
  wint_t ret, wc, ungetone = 0x00E4;	/* 0x00E4 means `a umlaut'. */
  char fname[] = "/tmp/tst-ungetwc1.out.XXXXXX";
  int fd;
  int result = 0;

  puts ("This program runs on de_DE.UTF-8 locale.");
  if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL)
    {
      fprintf (stderr, "Err: Cannot run on the de_DE.UTF-8 locale");
      exit (EXIT_FAILURE);
    }

  fd = mkstemp (fname);
  if (fd == -1)
    {
      printf ("cannot open temp file: %m\n");
      exit (EXIT_FAILURE);
    }

  /* Write some characters to `testfile'. */
  if ((fp = fdopen (fd, "w")) == NULL)
    {
      fprintf (stderr, "Cannot open 'testfile'.");
      exit (EXIT_FAILURE);
    }
  fputs (str, fp);
  fclose (fp);

  /* Open `testfile'. */
  if ((fp = fopen (fname, "r")) == NULL)
    {
      fprintf (stderr, "Cannot open 'testfile'.");
      exit (EXIT_FAILURE);
    }

  /* Unget a character. */
  ret = ungetwc (ungetone, fp);
  printf ("Unget a character (0x%04x)\n", (unsigned int) ungetone);
  fflush (stdout);
  if (ret == WEOF)
    {
      puts ("ungetwc() returns NULL.");
      exit (EXIT_SUCCESS);
    }

  /* Reget a character. */
  wc = getwc (fp);
  printf ("Reget a character (0x%04x)\n", (unsigned int) wc);
  fflush (stdout);
  if (wc == ungetone)
    {
      puts ("The ungotten character is equal to the regotten character.");
      fflush (stdout);
    }
  else
    {
      puts ("The ungotten character is not equal to the regotten character.");
      printf ("ungotten one: %04x, regetone: %04x", ungetone, wc);
      fflush (stdout);
      result = 1;
    }
  fclose (fp);

  unlink (fname);

  return result;
}
/**
 * Receives a gnu/linux console character.
 *
 * @param p0 the destination wide character array (Hand over as reference!)
 * @param p1 the destination wide character array count
 * @param p2 the destination wide character array size
 * @param p3 the loop break flag
 * @param p4 the input character
 * @param p5 the escape character mode
 * @param p6 the escape control sequence mode
 * @param p7 the source input stream
 * @param p8 the mutex
 */
void receive_gnu_linux_console_character(void* p0, void* p1, void* p2, void* p3, void* p4, void* p5, void* p6, void* p7, void* p8) {

    if (p7 != *NULL_POINTER_MEMORY_MODEL) {

        FILE* s = (FILE*) p7;

        if (p6 != *NULL_POINTER_MEMORY_MODEL) {

            int* csi = (int*) p6;

            if (p5 != *NULL_POINTER_MEMORY_MODEL) {

                int* esc = (int*) p5;

                if (p4 != *NULL_POINTER_MEMORY_MODEL) {

                    wint_t* c = (wint_t*) p4;

                    if (p3 != *NULL_POINTER_MEMORY_MODEL) {

                        int* b = (int*) p3;

                        log_terminated_message((void*) DEBUG_LEVEL_LOG_MODEL, (void*) L"Receive gnu/linux console character.");

                        // Initialise error number.
                        // It is a global variable/ function and other operations
                        // may have set some value that is not wanted here.
                        //
                        // CAUTION! Initialise the error number BEFORE calling
                        // the function that might cause an error.
                        errno = *NUMBER_0_INTEGER_MEMORY_MODEL;

                        // Lock gnu/linux console mutex.
                        pthread_mutex_lock(p8);

                        // Receive character from source input stream of gnu/linux console.
                        //
                        // CAUTION! The multibyte- is converted to a wide character internally,
                        // so that the return value of type "wint_t" may be casted to "wchar_t".
                        // Function calls to "decode_utf_8_unicode_character_vector" are therefore NOT necessary here!
                        *c = fgetwc(s);

                        // Unlock gnu/linux console mutex.
                        pthread_mutex_unlock(p8);

                        if (errno != EILSEQ) {

                            if (*csi == *NUMBER_1_INTEGER_MEMORY_MODEL) {

                                // Reset escape control sequence flag.
                                *csi = *NUMBER_0_INTEGER_MEMORY_MODEL;

                                // Copy source character to destination character array.
                                overwrite_array(p0, p4, (void*) WIDE_CHARACTER_PRIMITIVE_MEMORY_ABSTRACTION, (void*) PRIMITIVE_MEMORY_MODEL_COUNT, p1, (void*) VALUE_PRIMITIVE_MEMORY_NAME, p1, p2);

                                // Set loop break flag.
                                // An escape character followed by a left square bracket character
                                // were received before. So this is an escape control sequence.
                                // Since all values have been received, the loop can be left now.
                                *b = *NUMBER_1_INTEGER_MEMORY_MODEL;

                            } else if (*esc == *NUMBER_1_INTEGER_MEMORY_MODEL) {

                                // Reset escape character flag.
                                *esc = *NUMBER_0_INTEGER_MEMORY_MODEL;

                                // An escape character was received before.

                                if (*c == *((wint_t*) LEFT_SQUARE_BRACKET_UNICODE_CHARACTER_CODE_MODEL)) {

                                    // The escape character received before is followed by an opening square bracket,
                                    // which means that this is the start of an escape control sequence.

                                    // Set escape control sequence flag.
                                    *csi = *NUMBER_1_INTEGER_MEMORY_MODEL;

                                    // Copy source character to destination character array.
                                    overwrite_array(p0, p4, (void*) WIDE_CHARACTER_PRIMITIVE_MEMORY_ABSTRACTION, (void*) PRIMITIVE_MEMORY_MODEL_COUNT, p1, (void*) VALUE_PRIMITIVE_MEMORY_NAME, p1, p2);

                                } else {

                                    // This is NOT going to be an escape control sequence.
                                    // An escape- followed by another, second character
                                    // (which is not an opening square bracket) has been detected.

                                    // Lock gnu/linux console mutex.
                                    pthread_mutex_lock(p8);

                                    // Unget this character so that it may be processed once more later on.
                                    ungetwc(*c, p7);

                                    // Unlock gnu/linux console mutex.
                                    pthread_mutex_unlock(p8);

                                    // Set loop break flag.
                                    *b = *NUMBER_1_INTEGER_MEMORY_MODEL;
                                }

                            } else if (*c == *((wint_t*) ESCAPE_CONTROL_UNICODE_CHARACTER_CODE_MODEL)) {

                                // Set escape character flag.
                                *esc = *NUMBER_1_INTEGER_MEMORY_MODEL;

                                // Copy source character to destination character array.
                                overwrite_array(p0, p4, (void*) WIDE_CHARACTER_PRIMITIVE_MEMORY_ABSTRACTION, (void*) PRIMITIVE_MEMORY_MODEL_COUNT, p1, (void*) VALUE_PRIMITIVE_MEMORY_NAME, p1, p2);

                            } else if (*c == WEOF) {

                                // The function "communicate_sensing_gnu_linux_console_message" filters out
                                // invalid (non-existing) characters recognised by the return value WEOF (-1).
                                // However, to be on the safe side, they are filtered out here once more.

                                // Set loop break flag.
                                *b = *NUMBER_1_INTEGER_MEMORY_MODEL;

                            } else {

                                // Copy source character to destination character array.
                                overwrite_array(p0, p4, (void*) WIDE_CHARACTER_PRIMITIVE_MEMORY_ABSTRACTION, (void*) PRIMITIVE_MEMORY_MODEL_COUNT, p1, (void*) VALUE_PRIMITIVE_MEMORY_NAME, p1, p2);

                                // Set loop break flag.
                                *b = *NUMBER_1_INTEGER_MEMORY_MODEL;
                            }

                        } else {

                            log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not receive from gnu/linux console. The character reading failed.");

                            // Set loop break flag.
                            *b = *NUMBER_1_INTEGER_MEMORY_MODEL;
                        }

                    } else {

                        log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not receive gnu/linux console character. The loop break flag is null.");
                    }

                } else {

                    log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not receive gnu/linux console character. The input character is null.");
                }

            } else {

                log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not receive gnu/linux console character. The escape character mode is null.");
            }

        } else {

            log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not receive gnu/linux console character. The escape control sequence is null.");
        }

    } else {

        log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not receive gnu/linux console character. The source input stream is null.");
    }
}
Example #22
0
int main()
{
// mbstate_t comes from the underlying C library; it is defined (in C99) as:
//    a complete object type other than an array type that can hold the conversion 
//    state information necessary to convert between sequences of multibyte 
//    characters and wide characters
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-braces"
#endif
    mbstate_t mb = {0};
#if defined(__clang__)
#pragma clang diagnostic pop
#endif

    size_t s = 0;
    tm *tm = 0;
    wint_t w = 0;
    ::FILE* fp = 0;
#ifdef __APPLE__
    __darwin_va_list va;
#else
    __builtin_va_list va;
#endif
    char* ns = 0;
    wchar_t* ws = 0;
    static_assert((std::is_same<decltype(fwprintf(fp, L"")), int>::value), "");
    static_assert((std::is_same<decltype(fwscanf(fp, L"")), int>::value), "");
    static_assert((std::is_same<decltype(swprintf(ws, s, L"")), int>::value), "");
    static_assert((std::is_same<decltype(swscanf(L"", L"")), int>::value), "");
    static_assert((std::is_same<decltype(vfwprintf(fp, L"", va)), int>::value), "");
    static_assert((std::is_same<decltype(vfwscanf(fp, L"", va)), int>::value), "");
    static_assert((std::is_same<decltype(vswprintf(ws, s, L"", va)), int>::value), "");
    static_assert((std::is_same<decltype(vswscanf(L"", L"", va)), int>::value), "");
    static_assert((std::is_same<decltype(fgetwc(fp)), wint_t>::value), "");
    static_assert((std::is_same<decltype(fgetws(ws, 0, fp)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(fputwc(L' ', fp)), wint_t>::value), "");
    static_assert((std::is_same<decltype(fputws(L"", fp)), int>::value), "");
    static_assert((std::is_same<decltype(fwide(fp, 0)), int>::value), "");
    static_assert((std::is_same<decltype(getwc(fp)), wint_t>::value), "");
    static_assert((std::is_same<decltype(putwc(L' ', fp)), wint_t>::value), "");
    static_assert((std::is_same<decltype(ungetwc(L' ', fp)), wint_t>::value), "");
    static_assert((std::is_same<decltype(wcstod(L"", (wchar_t**)0)), double>::value), "");
    static_assert((std::is_same<decltype(wcstof(L"", (wchar_t**)0)), float>::value), "");
    static_assert((std::is_same<decltype(wcstold(L"", (wchar_t**)0)), long double>::value), "");
    static_assert((std::is_same<decltype(wcstol(L"", (wchar_t**)0, 0)), long>::value), "");
    static_assert((std::is_same<decltype(wcstoll(L"", (wchar_t**)0, 0)), long long>::value), "");
    static_assert((std::is_same<decltype(wcstoul(L"", (wchar_t**)0, 0)), unsigned long>::value), "");
    static_assert((std::is_same<decltype(wcstoull(L"", (wchar_t**)0, 0)), unsigned long long>::value), "");
    static_assert((std::is_same<decltype(wcscpy(ws, L"")), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcsncpy(ws, L"", s)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcscat(ws, L"")), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcsncat(ws, L"", s)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcscmp(L"", L"")), int>::value), "");
    static_assert((std::is_same<decltype(wcscoll(L"", L"")), int>::value), "");
    static_assert((std::is_same<decltype(wcsncmp(L"", L"", s)), int>::value), "");
    static_assert((std::is_same<decltype(wcsxfrm(ws, L"", s)), size_t>::value), "");
    static_assert((std::is_same<decltype(wcschr((wchar_t*)0, L' ')), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcscspn(L"", L"")), size_t>::value), "");
    static_assert((std::is_same<decltype(wcslen(L"")), size_t>::value), "");
    static_assert((std::is_same<decltype(wcspbrk((wchar_t*)0, L"")), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcsrchr((wchar_t*)0, L' ')), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcsspn(L"", L"")), size_t>::value), "");
    static_assert((std::is_same<decltype(wcsstr((wchar_t*)0, L"")), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcstok(ws, L"", (wchar_t**)0)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wmemchr((wchar_t*)0, L' ', s)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wmemcmp(L"", L"", s)), int>::value), "");
    static_assert((std::is_same<decltype(wmemcpy(ws, L"", s)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wmemmove(ws, L"", s)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wmemset(ws, L' ', s)), wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcsftime(ws, s, L"", tm)), size_t>::value), "");
    static_assert((std::is_same<decltype(btowc(0)), wint_t>::value), "");
    static_assert((std::is_same<decltype(wctob(w)), int>::value), "");
    static_assert((std::is_same<decltype(mbsinit(&mb)), int>::value), "");
    static_assert((std::is_same<decltype(mbrlen("", s, &mb)), size_t>::value), "");
    static_assert((std::is_same<decltype(mbrtowc(ws, "", s, &mb)), size_t>::value), "");
    static_assert((std::is_same<decltype(wcrtomb(ns, L' ', &mb)), size_t>::value), "");
    static_assert((std::is_same<decltype(mbsrtowcs(ws, (const char**)0, s, &mb)), size_t>::value), "");
    static_assert((std::is_same<decltype(wcsrtombs(ns, (const wchar_t**)0, s, &mb)), size_t>::value), "");

    // These tests fail on systems whose C library doesn't provide a correct overload
    // set for wcschr, wcspbrk, wcsrchr, wcsstr, and wmemchr, unless the compiler is
    // a suitably recent version of Clang.
#if !defined(__APPLE__) || defined(_LIBCPP_PREFERRED_OVERLOAD)
    static_assert((std::is_same<decltype(wcschr((const wchar_t*)0, L' ')), const wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcspbrk((const wchar_t*)0, L"")), const wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcsrchr((const wchar_t*)0, L' ')), const wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wcsstr((const wchar_t*)0, L"")), const wchar_t*>::value), "");
    static_assert((std::is_same<decltype(wmemchr((const wchar_t*)0, L' ', s)), const wchar_t*>::value), "");
#endif

#ifndef _LIBCPP_HAS_NO_STDIN
    static_assert((std::is_same<decltype(getwchar()), wint_t>::value), "");
    static_assert((std::is_same<decltype(vwscanf(L"", va)), int>::value), "");
    static_assert((std::is_same<decltype(wscanf(L"")), int>::value), "");
#endif

#ifndef _LIBCPP_HAS_NO_STDOUT
    static_assert((std::is_same<decltype(putwchar(L' ')), wint_t>::value), "");
    static_assert((std::is_same<decltype(vwprintf(L"", va)), int>::value), "");
    static_assert((std::is_same<decltype(wprintf(L"")), int>::value), "");
#endif
}