// Gather data up to next start-of-tag or end-of-buffer. // Translate entity references (&). // Ignore non-whitespace control characters and get rid of \r's. // If find non-empty token, fill in a[*pai], bump *pai, and return Data. // Otherwise return -1; static int getdata(TokenSource* ts, int firstc, int starti, Token* a, int* pai) { Rune* s; int j; int c; Token* tok; Rune buf[SMALLBUFSIZE]; s = nil; j = 0; for(c = firstc; c >= 0; c = getchar(ts)){ if(c == '&') { c = ampersand(ts); if(c < 0) break; } else if(c < ' ') { if(isspace(c)) { if(c == '\r') { // ignore it unless no following '\n', // in which case treat it like '\n' c = getchar(ts); if(c != '\n') { if(c >= 0) ungetchar(ts, c); c = '\n'; } } } else { if(warn) fprint(2, "warning: non-whitespace control character %d ignored\n", c); c = 0; } } else if(c == '<') { ungetchar(ts, c); break; } if(c != 0) { buf[j++] = c; if(j == nelem(buf)-1) { s = buftostr(s, buf, j); j = 0; } } } s = buftostr(s, buf, j); if(s == nil) return -1; tok = &a[(*pai)++]; tok->tag = Data; tok->text = s; tok->attr = nil; tok->starti = starti; return Data; }
/* * The main shell function */ main() { int i; char **args; int result; int block; int output; int input; char *output_filename; char *input_filename; // Set up the signal handler sigset(SIGCHLD, sig_handler); // Setup the signal handler struct sigaction sa; // Setup the SIGPROCMASK sigset_t blockmask; // Make sure the signal handlers are setup if(sigprocmask(SIG_BLOCK, &blockmask, NULL) == -1) { perror("Failed to setup signal handler."); return 1; } // Loop forever while(1) { // Print out the prompt and get the input printf("->"); args = getline(); // No input, continue if(args[0] == NULL) continue; // Check for internal shell commands, such as exit if(internal_command(args)) continue; // Check for an ampersand block = (ampersand(args) == 0); // Check for redirected input input = redirect_input(args, &input_filename); switch(input) { case -1: printf("Syntax error!\n"); continue; break; case 0: break; case 1: printf("Redirecting input from: %s\n", input_filename); break; } // Check for redirected output output = redirect_output(args, &output_filename); switch(output) { case -1: printf("Syntax error!\n"); continue; break; case 0: break; case 1: printf("Redirecting output to: %s\n", output_filename); break; case 2: printf("Appending output to: %s\n", output_filename); break; } // Do the command do_command(args, block, input, input_filename, output, output_filename, sigaction, blockmask, 0, 0); } }
// We've just seen a '<'. Gather up stuff to closing '>' (if buffer // ends before then, return -1). // If it's a tag, look up the name, gather the attributes, and return // the appropriate token. // Else it's either just plain data or some kind of ignorable stuff: // return Data or Comment as appropriate. // If it's not a Comment, put it in a[*pai] and bump *pai. static int gettag(TokenSource* ts, int starti, Token* a, int* pai) { int rbra; int ans; Attr* al; int nexti; int c; int ti; int afnd; int attid; int quote; Rune* val; int nv; int i; int tag; Token* tok; Rune buf[BIGBUFSIZE]; rbra = 0; nexti = ts->i; tok = &a[*pai]; tok->tag = Notfound; tok->text = nil; tok->attr = nil; tok->starti = starti; c = getchar(ts); if(c == '/') { rbra = RBRA; c = getchar(ts); } if(c < 0) goto eob_done; if(c >= 256 || !isalpha(c)) { // not a tag if(c == '!') { ans = comment(ts); if(ans != -1) return ans; goto eob_done; } else { backup(ts, nexti); tok->tag = Data; tok->text = _Strdup(L"<"); (*pai)++; return Data; } } // c starts a tagname buf[0] = c; i = 1; while(1) { c = getchar(ts); if(c < 0) goto eob_done; if(!ISNAMCHAR(c)) break; // if name is bigger than buf it won't be found anyway... if(i < BIGBUFSIZE) buf[i++] = c; } if(_lookup(tagtable, Numtags, buf, i, &tag)) tok->tag = tag + rbra; else tok->text = _Strndup(buf, i); // for warning print, in build // attribute gathering loop al = nil; while(1) { // look for "ws name" or "ws name ws = ws val" (ws=whitespace) // skip whitespace attrloop_continue: while(c < 256 && isspace(c)) { c = getchar(ts); if(c < 0) goto eob_done; } if(c == '>') goto attrloop_done; if(c == '<') { if(warn) fprint(2, "warning: unclosed tag\n"); ungetchar(ts, c); goto attrloop_done; } if(c >= 256 || !isalpha(c)) { if(warn) fprint(2, "warning: expected attribute name\n"); // skipt to next attribute name while(1) { c = getchar(ts); if(c < 0) goto eob_done; if(c < 256 && isalpha(c)) goto attrloop_continue; if(c == '<') { if(warn) fprint(2, "warning: unclosed tag\n"); ungetchar(ts, 60); goto attrloop_done; } if(c == '>') goto attrloop_done; } } // gather attribute name buf[0] = c; i = 1; while(1) { c = getchar(ts); if(c < 0) goto eob_done; if(!ISNAMCHAR(c)) break; if(i < BIGBUFSIZE-1) buf[i++] = c; } afnd = _lookup(attrtable, Numattrs, buf, i, &attid); if(warn && !afnd) { buf[i] = 0; fprint(2, "warning: unknown attribute name %S\n", buf); } // skip whitespace while(c < 256 && isspace(c)) { c = getchar(ts); if(c < 0) goto eob_done; } if(c != '=') { if(afnd) al = newattr(attid, nil, al); goto attrloop_continue; } //# c is '=' here; skip whitespace while(1) { c = getchar(ts); if(c < 0) goto eob_done; if(c >= 256 || !isspace(c)) break; } quote = 0; if(c == '\'' || c == '"') { quote = c; c = getchar(ts); if(c < 0) goto eob_done; } val = nil; nv = 0; while(1) { valloop_continue: if(c < 0) goto eob_done; if(c == '>') { if(quote) { // c might be part of string (though not good style) // but if line ends before close quote, assume // there was an unmatched quote ti = ts->i; while(1) { c = getchar(ts); if(c < 0) goto eob_done; if(c == quote) { backup(ts, ti); buf[nv++] = '>'; if(nv == BIGBUFSIZE-1) { val = buftostr(val, buf, nv); nv = 0; } c = getchar(ts); goto valloop_continue; } if(c == '\n') { if(warn) fprint(2, "warning: apparent unmatched quote\n"); backup(ts, ti); c = '>'; goto valloop_done; } } } else goto valloop_done; } if(quote) { if(c == quote) { c = getchar(ts); if(c < 0) goto eob_done; goto valloop_done; } if(c == '\r') { c = getchar(ts); goto valloop_continue; } if(c == '\t' || c == '\n') c = ' '; } else { if(c < 256 && isspace(c)) goto valloop_done; } if(c == '&') { c = ampersand(ts); if(c == -1) goto eob_done; } buf[nv++] = c; if(nv == BIGBUFSIZE-1) { val = buftostr(val, buf, nv); nv = 0; } c = getchar(ts); } valloop_done: if(afnd) { val = buftostr(val, buf, nv); al = newattr(attid, val, al); } } attrloop_done: tok->attr = al; (*pai)++; return tok->tag; eob_done: if(warn) fprint(2, "warning: incomplete tag at end of page\n"); backup(ts, nexti); tok->tag = Data; tok->text = _Strdup(L"<"); return Data; }
void update_links( void ) { char_data* ch; link_data* link; text_data* receive; fd_set read_set; fd_set write_set; fd_set exec_set; struct timeval start; struct timeval timeout; gettimeofday( &start, NULL ); timeout.tv_sec = 1; timeout.tv_usec = 0; FD_ZERO( &read_set ); FD_ZERO( &write_set ); FD_ZERO( &exec_set ); FD_SET( socket_one, &read_set ); FD_SET( socket_two, &read_set ); for( link = link_list; link != NULL; link = link->next ) { FD_SET( link->channel, &read_set ); FD_SET( link->channel, &write_set ); FD_SET( link->channel, &exec_set ); } if( (int) select( FD_SETSIZE, &read_set, &write_set, &exec_set, &timeout ) < 0 ) panic( "Update links: select" ); if( FD_ISSET( socket_one, &read_set ) ) open_link( socket_one ); if( FD_ISSET( socket_two, &read_set ) ) open_link( socket_two ); for( link = link_list; link != NULL; link = link_next ) { link_next = link->next; if( FD_ISSET( link->channel, &exec_set ) ) { write( link->player ); close_socket( link ); continue; } if( FD_ISSET( link->channel, &read_set ) ) { link->idle = 0; if( link->player != NULL ) link->player->timer = current_time; if( !read_link( link ) ) { write( link->player ); close_socket( link ); continue; } } if( link->idle++ > 10000 && link->connected != CON_PLAYING ) { send( link, "\n\r\n\r-- CONNECTION TIMEOUT --\n\r" ); close_socket( link, TRUE ); } } pulse_time[ TIME_READ_INPUT ] = stop_clock( start ); gettimeofday( &start, NULL ); for( link = link_list; link != NULL; link = link_next ) { link_next = link->next; if( link->command = ( ( receive = link->receive ) != NULL ) ) { ampersand( receive ); link->receive = receive->next; link->idle = 0; if( link->connected == CON_PLAYING ) { stop_idling( ch = link->character ); interpret( link->character, receive->message.text ); } else nanny( link, receive->message.text ); delete receive; } } pulse_time[ TIME_COMMANDS ] = stop_clock( start ); gettimeofday( &start, NULL ); for( link = link_list; link != NULL; link = link_next ) { link_next = link->next; if( link->idle%25 == 0 && FD_ISSET( link->channel, &write_set ) && !process_output( link ) ) { write( link->player ); close_socket( link ); } } pulse_time[ TIME_WRITE_OUTPUT ] = stop_clock( start ); return; }
/* * The main shell function */ main() { int i; char **args; int result; int block; int output; int input; char *output_filename; char *input_filename; // Set up the signal handler sigset(SIGCHLD, sig_handler); // Loop forever while(1) { // Print out the prompt and get the input printf("->"); args = my_getline(); // No input, continue if(args[0] == NULL) continue; // Check for internal shell commands, such as exit if(internal_command(args)) continue; // Check for tilde (~) tilde(args); // Check for an ampersand block = (ampersand(args) == 0); // Check for redirected input input = redirect_input(args, &input_filename); switch(input) { case -1: printf("Syntax error!\n"); continue; break; case 0: break; case 1: if (DEBUG) printf("Redirecting input from: %s\n", input_filename); break; } // Check for redirected output output = redirect_output(args, &output_filename); switch(output) { case -1: printf("Syntax error!\n"); continue; break; case 0: break; case 1: if (DEBUG) printf("Redirecting (Overriding) output to: %s\n", output_filename); break; case 2: if (DEBUG) printf("Redirecting (Appending) output to: %s\n", output_filename); break; } // Do the command do_command(args, block, input, input_filename, output, output_filename); for (i = 0; args[i] != NULL; i++) free(args[i]); } }
// Returns the next token in the character stream. // If no next token can be identified, an error // is emitted and we return the error token. Token Lexer::scan() { // Keep consuming characters until we find // a token. while (true) { space(); // Update the position of the current source location. // This denotes the beginning of the current token. loc_ = in_.location(); switch (peek()) { case 0: return eof(); case '{': return lbrace(); case '}': return rbrace(); case '(': return lparen(); case ')': return rparen(); case '[': return lbrack(); case ']': return rbrack(); case ',': return comma(); case ':': return colon(); case ';': return semicolon(); case '.': return dot(); case '+': return plus(); case '-': return minus(); case '*': return star(); case '/': get(); if (peek() == '/') { comment(); continue; } else { return slash(); } case '%': return percent(); case '=': return equal(); case '!': return bang(); case '<': return langle(); case '>': return rangle(); case '&': return ampersand(); case '|': return bar(); case '^': return hat(); case '0': // if the next character is a 'b' then this // is a binary literal if (peek(1) == 'b') return binary_integer(); // if the next character is an 'x' then this // is a hexadecimal integer if (peek(1) == 'x') return hexadecimal_integer(); // otherwise proceed to regular integer lexing case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return integer(); case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_': return word(); case '\'': return character(); case '"': return string(); default: return error(); } } }