📄 input.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)input.c 1.1 92/07/30 Copyr 1985 Sun Micro";#endif#endif/* * Copyright (c) 1985 by Sun Microsystems, Inc. *//* last edited January 28, 1985, 13:19:14 */#include <sunwindow/io_stream.h>#define Get_Input_Ops \ struct input_ops_vector *ops;\ if (in->stream_type != Input) exit(1);\ ops = in->ops.input_opschar *stream_getstring();/* GENERIC INPUT FUNCTIONS */intstream_chars_avail(in) STREAM *in;{ Get_Input_Ops; return ((*ops->chars_avail) (in));}intstream_getc(in) STREAM *in;{ Get_Input_Ops; return ((*ops->str_getc) (in));}intstream_peekc(in) STREAM *in;{ int c; c = stream_getc(in); if (c != EOF) (void) stream_ungetc(c, in); return (c);}intstream_ungetc(c, in) char c; STREAM *in;{ Get_Input_Ops; return ((*ops->ungetc) (c, in)); /* NOT IMPLEMENTED YET : GENERIC CASE WHERE ungetc not DEFINED */}char *stream_gets(s, in) char *s; STREAM *in;{ return (stream_getstring(s, 10000, in, False));}char *stream_fgets(s, n, in) char *s; int n; STREAM *in;{ return (stream_getstring(s, n, in, True));}static char *stream_getstring(s, n, in, include_newline) char *s; int n; STREAM *in; Bool include_newline;{ int i, c; Get_Input_Ops; if (ops->str_fgets != NULL) { if ((*ops->str_fgets) (s, n, in) == NULL) return (NULL); else if (!include_newline) { i = strlen(s); if (s[i - 1] == '\n') s[i - 1] = '\0'; } return (s); } /* str_fgets not defined. simulate with n calls to getc */ for (i = 0; i < n; i++) { c = (*ops->str_getc) (in); if (c == EOF) { s[i] = '\0'; break; } else if (c == '\n' && (i == 0 || s[i - 1] != '\\')) { /* * \ followed by newline copies both \ and newline * into s without terminating */ if (include_newline) s[i++] = c; break; } s[i] = c; } if (i == 0) return (NULL); s[i] = '\0'; return (s);}/* * stream_get_token is used for tokenizing input, where more degree of * flexibility is required than simply delimiting tokens by white spaces * characters are divided into three classes, Break, Sepr, and Other. * separators (Sepr) serve to delimit a token. Leading separators are * skipped. think of separators as white space. Break characters delimit * tokens, and are themselves tokens. Thus, if a break character is the first * thing seen it is returned as the token. If any non-separator characters * have been seen, then they are returned as the token, and the break * character will be the returned as the result of the next call to * get_token. for example, if charproc returns Sepr for space, and Break for * '(' and ')' and Other for all alphabetic characters, then the string "now * (is) the" will yield five tokens consisting of "now" "(" "is" ")" and * "the" * * get_token stores the token that it constructs into dest, which is also * returned as its value. STREAM *in; * * get_token returns NULL, rather than the empty string, corresponding to the * case where the token is empty */char *stream_get_token(in, dest, charproc) STREAM *in; char *dest; enum CharClass (*charproc) ();{ int c; int i = 0; for (;;) { c = stream_getc(in); if (c == EOF) goto done; switch ((*charproc) (c)) { case Sepr: if (i != 0) /* something seen */ goto backup; else continue; case Break: if (i == 0) { /* * nothing seen yet, this character is the * token */ dest[i++] = (char) c; goto done; } else goto backup; case Other: dest[i++] = (char) c; } }backup: (void) stream_ungetc((char) c, in);done: dest[i] = '\0'; return (i == 0 ? NULL : dest);}/* * stream_get_sequence is a more primitive tokenizer than get_token. it takes * a procedure which for each character specifies whether the character is to * terminate the sequence, and whether or not the character is to be included * in the sequence. (If the character terminates the sequence, but is not * included, then it will be seen again on the next call.) For example, * having seen a \"\, to read to the matching \"\, call get_sequence with an * action procedure that returns {True, True} for \"\ and {False, True} for * everything else. (If you want to detect the case where a " is preceded by * a \\, simply save the last character and modify the procedure accordingly. * * Note that gettoken can be defined in terms of get_sequence by having Other * characters return {False, True}, and also noticing whether any have been * seen yet, having Seprs return {(seen_some_others ? True : False), False} * and Break characters return {True, (seen_some_others ? False : True)} * * returns NULL for the empty sequence */char *stream_get_sequence(in, dest, charproc) STREAM *in; char *dest; struct CharAction (*charproc) ();{ int c; struct CharAction action; int i = 0; FOREVER { c = stream_getc(in); if (c == EOF) goto done; action = (*charproc) (c); if (action.include) dest[i++] = (char) c; if (action.stop) { if (!action.include) goto backup; /* if c was not included, * then need to put it back */ else goto done; } }backup: (void) stream_ungetc((char) c, in);done: dest[i] = '\0'; return (i == 0 ? NULL : dest);}voidskip_over(in, charproc) STREAM *in; enum CharClass (*charproc) ();{ char c; FOREVER { c = stream_getc(in); if (charproc(c) != Sepr) { (void) stream_ungetc(c, in); break; } }}intstream_set_pos(in, n) STREAM *in; int n;{ Get_Input_Ops; if (ops->set_pos) return (*ops->set_pos) (in, n); else return (-1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -