/* input function: DCC SERVER received some data.. */ static void dcc_server_input(SERVER_DCC_REC *dcc) { char tmpbuf[512], *str; int recvlen, ret; g_return_if_fail(IS_DCC_SERVER(dcc)); do { recvlen = net_receive(dcc->handle, tmpbuf, sizeof(tmpbuf)); ret = line_split(tmpbuf, recvlen, &str, &dcc->readbuf); if (ret == -1) { /* connection lost */ dcc_close(DCC(dcc)); break; } if (ret > 0) { dcc->transfd += ret; signal_emit("dcc server message", 2, dcc, str); } if (dcc->connection_established) { /* We set handle to NULL first because the new (chat/get) is using the same */ /* handle and we don't want dcc_close to disconnect it.*/ dcc->handle = NULL; dcc_close(DCC(dcc)); break; } } while (ret > 0); }
/* SYNTAX: CAT <file> */ static void cmd_cat(const char *data) { LINEBUF_REC *buffer = NULL; char *fname, *fposstr; char tmpbuf[1024], *str; void *free_arg; int f, ret, recvlen, fpos; if (!cmd_get_params(data, &free_arg, 2, &fname, &fposstr)) return; fname = convert_home(fname); fpos = atoi(fposstr); cmd_params_free(free_arg); f = open(fname, O_RDONLY); g_free(fname); if (f == -1) { /* file not found */ printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "%s", g_strerror(errno)); return; } lseek(f, fpos, SEEK_SET); do { recvlen = read(f, tmpbuf, sizeof(tmpbuf)); ret = line_split(tmpbuf, recvlen, &str, &buffer); if (ret > 0) printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%s", str); } while (ret > 0); line_split_free(buffer); close(f); }
static void sig_bot_read(BOT_REC *bot) { BOTNET_REC *botnet; char tmpbuf[1024], *str; int ret, recvlen, reconnect; botnet = bot->botnet; for (;;) { recvlen = bot->handle == -1 ? -1 : net_receive(bot->handle, tmpbuf, sizeof(tmpbuf)); ret = line_split(tmpbuf, recvlen, &str, (LINEBUF_REC **) &bot->buffer); if (ret == 0) break; if (ret == -1) { /* connection lost */ reconnect = !bot->disconnect && bot->uplink; bot_destroy(bot); if (reconnect) { /* wasn't intentional disconnection from our uplink, reconnect */ botnet_connect(botnet); } break; } fprintf(stderr, "%s\r\n", str); signal_emit("botnet event", 2, bot, str); } }
static void sig_exec_input_reader(PROCESS_REC *rec) { char tmpbuf[512], *str; unsigned int recvlen; int err, ret; g_return_if_fail(rec != NULL); recvlen = 0; err = g_io_channel_read(rec->in, tmpbuf, sizeof(tmpbuf), &recvlen); if (err != 0 && err != G_IO_ERROR_AGAIN && errno != EINTR) recvlen = -1; do { ret = line_split(tmpbuf, recvlen, &str, &rec->databuf); if (ret == -1) { /* link to terminal closed? */ g_source_remove(rec->read_tag); rec->read_tag = -1; break; } if (ret > 0) { signal_emit_id(signal_exec_input, 2, rec, str); if (recvlen > 0) recvlen = 0; } } while (ret > 0); }
static int show_help_rec(COMMAND_REC *cmd) { char tmpbuf[1024], *str, *path; LINEBUF_REC *buffer = NULL; int f, ret, recvlen; /* helpdir/command or helpdir/category/command */ if (cmd->category == NULL) path = g_strdup_printf("%s/%s", HELPDIR, cmd->cmd); else path = g_strdup_printf("%s/%s/%s", HELPDIR, cmd->category, cmd->cmd); f = open(path, O_RDONLY); g_free(path); if (f == -1) return FALSE; /* just print to screen whatever is in the file */ do { recvlen = read(f, tmpbuf, sizeof(tmpbuf)); ret = line_split(tmpbuf, recvlen, &str, &buffer); if (ret > 0) printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, str); } while (ret > 0); line_split_free(buffer); close(f); return TRUE; }
static void sig_pidwait(void *pid, void *statusp) { PROCESS_REC *rec; char *str; int status = GPOINTER_TO_INT(statusp); rec = process_find_pid(GPOINTER_TO_INT(pid)); if (rec == NULL) return; /* process exited - print the last line if there wasn't a newline at end. */ if (line_split("\n", 1, &str, &rec->databuf) > 0 && *str != '\0') signal_emit_id(signal_exec_input, 2, rec, str); if (!rec->silent) { if (WIFSIGNALED(status)) { status = WTERMSIG(status); printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "process %d (%s) terminated with signal %d (%s)", rec->id, rec->args, status, g_strsignal(status)); } else { status = WIFEXITED(status) ? WEXITSTATUS(status) : -1; printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "process %d (%s) terminated with return code %d", rec->id, rec->args, status); } } process_destroy(rec, status); }
/* expects * "what" +SP "=" +SP <base> "/" attr *( ',' attr ) in the configuration * file */ spocp_result_t set_attr( void **vpp, void *cd, int argc, char **argv) { ainfo_t *ai=0, *newai ; char *sp; char *buf; int n; LDAPDN dn = NULL; void *vp; traceLog( LOG_DEBUG, "argc: %d, argv[0]: %s", argc, argv[0]); if( argc != 1 ) return SPOCP_PARAM_ERROR; buf = normalize( argv[0]) ; sp = index( buf, '/' ); if ( !sp) return SPOCP_PARAM_ERROR; *sp++ = '\0'; newai = ( ainfo_t * ) calloc (1, sizeof( ainfo_t )); traceLog( LOG_DEBUG, "Base DN[0]: %s", buf ); ldap_str2dn( buf, &dn, LDAP_DN_FORMAT_LDAPV3); ldap_dn2str( dn, &buf, LDAP_DN_FORMAT_LDAPV3); ldap_memfree( dn ); traceLog( LOG_DEBUG, "Base DN[1]: %s", buf); newai->base = buf; newai->attr = line_split( sp, ',', 0, 1, 0, &n); vp = (void *) newai; if( *vpp != 0 ) { ai = (ainfo_t *) *vpp; newai->next = ai; } *vpp = vp; return SPOCP_SUCCESS; }
std::list<Token> Lexer::GetTokens(const std::string& a) { line_count = 0; locs.clear(); std::list<std::string> lines = line_split(a); std::list<Token> ret; for (auto& line : lines) { if (line == "\n") continue; count = 1; line_count++; std::list<std::string> tmp = split(line); int cc = 0; for (auto& t : tmp) { if (is_keyword(t)) { std::for_each(t.begin(), t.end(), to_lower); ret.push_back(Token(KEYWORD, t, locs[cc] - t.size(), line_count)); } else if (ops.find(t) != ops.end()) { ret.push_back(Token(OP, t, locs[cc] - t.size(), line_count)); } else if (t == " "){ } else { //NUM if (t[0] >= '0' && t[0] <= '9') { for (int i = 1; i < t.size(); i++) { if (!(t[i] >= '0' && t[i] <= '9')) { throw(SDBException("Illegal Tokens")); } } ret.push_back(Token(NUM, t, locs[cc] - t.size(), line_count)); //ID } else if ((t[0] >= 'a' && t[0] <= 'z') || (t[0] >= 'A' && t[0] <= 'Z') || t[0] == '_') { if(t.size() >= MAX_ID_LEN) { throw(SDBException("Token Length Too Long")); } ret.push_back(Token(ID, t, locs[cc] - t.size(), line_count)); } } cc++; } } return ret; }
/* input function: DCC CHAT received some data.. */ static void dcc_chat_input(DCC_REC *dcc) { char tmpbuf[512], *str; int recvlen, ret; g_return_if_fail(dcc != NULL); do { recvlen = net_receive(dcc->handle, tmpbuf, sizeof(tmpbuf)); ret = line_split(tmpbuf, recvlen, &str, (LINEBUF_REC **) &dcc->databuf); if (ret == -1) { /* connection lost */ signal_emit("dcc closed", 1, dcc); dcc_destroy(dcc); break; } if (ret > 0) { dcc->transfd += ret; signal_emit("dcc chat message", 2, dcc, str); } } while (ret > 0); }
static char * fqdn2dn( char *fqdn ) { int n, i, len; char **arr, *dn, *tp; arr = line_split( fqdn, '.', 0, 0, 0, &n ); for( i=0, len=0; arr[i]; i++) len += strlen(arr[i]) + 4 ; dn = ( char *) calloc (len+1, sizeof( char )); for( i=0, tp=dn; arr[i]; i++ ) { sprintf( tp, "dc=%s,", arr[i]); tp += strlen( tp); } --tp; *tp = '\0'; for( i=0; arr[i]; i++ ) free( arr[i] ); free(arr); return dn; }
static void _pp_host_get_snmp_devices_thread (GSimpleAsyncResult *res, GObject *object, GCancellable *cancellable) { PpHost *host = (PpHost *) object; PpHostPrivate *priv = host->priv; PpPrintDevice *device; GSDData *data; GError *error; gchar **argv; gchar *stdout_string = NULL; gchar *stderr_string = NULL; gint exit_status; data = g_simple_async_result_get_op_res_gpointer (res); data->devices = g_new0 (PpDevicesList, 1); data->devices->devices = NULL; argv = g_new0 (gchar *, 3); argv[0] = g_strdup ("/usr/lib/cups/backend/snmp"); argv[1] = g_strdup (priv->hostname); /* Use SNMP to get printer's informations */ g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &stdout_string, &stderr_string, &exit_status, &error); g_free (argv[1]); g_free (argv[0]); g_free (argv); if (exit_status == 0 && stdout_string) { gchar **printer_informations = NULL; gint length; printer_informations = line_split (stdout_string); length = g_strv_length (printer_informations); if (length >= 4) { device = g_new0 (PpPrintDevice, 1); device->device_class = g_strdup (printer_informations[0]); device->device_uri = g_strdup (printer_informations[1]); device->device_make_and_model = g_strdup (printer_informations[2]); device->device_info = g_strdup (printer_informations[3]); device->device_name = g_strdup (printer_informations[3]); device->device_name = g_strcanon (device->device_name, ALLOWED_CHARACTERS, '-'); device->acquisition_method = ACQUISITION_METHOD_SNMP; if (length >= 5 && printer_informations[4][0] != '\0') device->device_id = g_strdup (printer_informations[4]); if (length >= 6 && printer_informations[5][0] != '\0') device->device_location = g_strdup (printer_informations[5]); data->devices->devices = g_list_append (data->devices->devices, device); } g_strfreev (printer_informations); g_free (stdout_string); } }
static void sig_listen_client(CLIENT_REC *client, gint handle) { char tmpbuf[1024], *str, *cmd, *args, *p; int ret, recvlen; g_return_if_fail(client != NULL); for (;;) { recvlen = net_receive(handle, tmpbuf, sizeof(tmpbuf)); ret = line_split(tmpbuf, recvlen, &str, &client->buffer); if (ret == -1) { /* connection lost */ remove_client(proxy_data, client); break; } if (ret == 0) break; if (client->server == NULL) continue; cmd = g_strdup(str); args = strchr(cmd, ' '); if (args != NULL) *args++ = '\0'; else args = ""; if (*args == ':') args++; g_strup(cmd); if (!client->connected) { if (proxy_data->password != NULL && strcmp(cmd, "PASS") == 0) { if (strcmp(proxy_data->password, args) != 0) { /* wrong password! */ remove_client(proxy_data, client); break; } client->pass_sent = TRUE; } else if (strcmp(cmd, "NICK") == 0) client->nick = g_strdup(args); else if (strcmp(cmd, "USER") == 0) { if (client->nick == NULL || (proxy_data->password != NULL && !client->pass_sent)) { /* stupid client didn't send us NICK/PASS or, kill it */ remove_client(proxy_data, client); break; } client->connected = TRUE; plugin_proxy_dump_data(client); } } else if (strcmp(cmd, "QUIT") == 0) { remove_client(proxy_data, client); break; } else if (strcmp(cmd, "PING") == 0) { net_transmit(handle, "PONG proxy :nick\n", 17); } else { net_transmit(net_sendbuffer_handle(client->server->handle), str, strlen(str)); net_transmit(net_sendbuffer_handle(client->server->handle), "\n", 1); if (strcmp(cmd, "WHO") == 0) { grab_who(client, args); } else if (strcmp(cmd, "WHOIS") == 0) { /* convert dots to spaces */ for (p = args; *p != '\0'; p++) if (*p == ',') *p = ' '; proxy_redirect_event(client, args, 2, "event 318", -1, "event 402", -1, "event 401", 1, "event 311", 1, "event 301", 1, "event 312", 1, "event 313", 1, "event 317", 1, "event 319", 1, NULL); } else if (strcmp(cmd, "ISON") == 0) { proxy_redirect_event(client, NULL, 1, "event 303", -1, NULL); } else if (strcmp(cmd, "USERHOST") == 0) { proxy_redirect_event(client, args, 1, "event 302", -1, "event 401", 1, NULL); } else if (strcmp(cmd, "MODE") == 0) { /* convert dots to spaces */ gchar *slist, *str, mode; gint argc; p = strchr(args, ' '); if (p != NULL) *p++ = '\0'; mode = p == NULL ? '\0' : *p; slist = g_strdup(args); argc = 1; for (p = slist; *p != '\0'; p++) { if (*p == ',') { *p = ' '; argc++; } } /* get channel mode / bans / exception / invite list */ str = g_strdup_printf("%s %s", args, slist); switch (mode) { case '\0': while (argc-- > 0) proxy_redirect_event(client, str, 3, "event 403", 1, "event 443", 1, "event 324", 1, NULL); break; case 'b': while (argc-- > 0) proxy_redirect_event(client, str, 2, "event 403", 1, "event 368", 1, "event 367", 1, NULL); break; case 'e': while (argc-- > 0) proxy_redirect_event(client, str, 4, "event 403", 1, "event 482", 1, "event 472", -1, "event 349", 1, "event 348", 1, NULL); break; case 'I': while (argc-- > 0) proxy_redirect_event(client, str, 4, "event 403", 1, "event 482", 1, "event 472", -1, "event 347", 1, "event 346", 1, NULL); break; } g_free(str); g_free(slist); } } g_free(cmd); } }
// menu_action: Called when a menu/toolbar item is selected // ----------------------------------------------------- >> static void menu_action(GtkAction *action) { string act = gtk_action_get_name(action); if (act == "WadManager") open_main_window(); else if (act == "Exit") gtk_main_quit(); else if (act == "Close") file_close(); else if (act == "ModeVerts") change_edit_mode(0); else if (act == "ModeLines") change_edit_mode(1); else if (act == "ModeSectors") change_edit_mode(2); else if (act == "ModeThings") change_edit_mode(3); else if (act == "Mode3d") { if (map.opened) start_3d_mode(); } else if (act == "ShowConsole") popup_console(); else if (act == "ShowScriptEditor") open_script_edit(); else if (act == "Preferences") open_prefs_dialog(); else if (act == "About") { gtk_show_about_dialog(GTK_WINDOW(editor_window), "name", "SLADE", "comments", "by Simon 'SlayeR' Judd, 2005", "version", __SLADEVERS, "website", "http://slade.mancubus.net", NULL); } else if (act == "Save") { if (edit_wad) file_save(); else file_saveas(); } else if (act == "SaveAs") file_saveas(); else if (act == "MergeSectors") sector_merge(false); else if (act == "JoinSectors") sector_merge(true); else if (act == "CreateDoor") sector_create_door(open_texture_browser(true, false, false, "-")); else if (act == "CreateStairs") edit_create_stairs(); else if (act == "CheckMapStats") check_map_stats(); else if (act == "CheckTags") message_box(parse_string("%d Tags Cleaned", clean_tags()), GTK_MESSAGE_INFO); else if (act == "CheckVerts") message_box(parse_string("%d Vertices Removed", remove_free_verts()), GTK_MESSAGE_INFO); else if (act == "CheckLines") message_box(parse_string("%d 0-Length Lines Removed", remove_zerolength_lines()), GTK_MESSAGE_INFO); else if (act == "CheckSectors") message_box(parse_string("%d Sectors Removed", remove_unused_sectors()), GTK_MESSAGE_INFO); else if (act == "CheckTextures") check_textures(); else if (act == "AlignX") line_align_x(); else if (act == "CorrectRefs") line_correct_references(); else if (act == "SplitLine") { int splits = 2; string ret = entry_box("Enter Number Of Splits:"); if (ret != "") splits = atoi(ret.c_str()); line_split(splits); } else message_box("Menu action not implemented", GTK_MESSAGE_INFO); force_map_redraw(true, true); }
Tokens jsonnet_lex(const std::string &filename, const char *input) { unsigned long line_number = 1; const char *line_start = input; Tokens r; const char *c = input; Fodder fodder; bool fresh_line = true; // Are we tokenizing from the beginning of a new line? while (*c!='\0') { Token::Kind kind; std::string data; std::string string_block_indent; std::string string_block_term_indent; unsigned new_lines, indent; lex_ws(c, new_lines, indent, line_start, line_number); // If it's the end of the file, discard final whitespace. if (*c == '\0') break; if (new_lines > 0) { // Otherwise store whitespace in fodder. unsigned blanks = new_lines - 1; fodder.emplace_back(FodderElement::LINE_END, blanks, indent, EMPTY); fresh_line = true; } Location begin(line_number, c - line_start + 1); switch (*c) { // The following operators should never be combined with subsequent symbols. case '{': kind = Token::BRACE_L; c++; break; case '}': kind = Token::BRACE_R; c++; break; case '[': kind = Token::BRACKET_L; c++; break; case ']': kind = Token::BRACKET_R; c++; break; case ',': kind = Token::COMMA; c++; break; case '.': kind = Token::DOT; c++; break; case '(': kind = Token::PAREN_L; c++; break; case ')': kind = Token::PAREN_R; c++; break; case ';': kind = Token::SEMICOLON; c++; break; // Numeric literals. case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': kind = Token::NUMBER; data = lex_number(c, filename, begin); break; // String literals. case '"': { c++; for (; ; ++c) { if (*c == '\0') { throw StaticError(filename, begin, "Unterminated string"); } if (*c == '"') { break; } if (*c == '\\' && *(c+1) != '\0') { data += *c; ++c; } if (*c == '\n') { // Maintain line/column counters. line_number++; line_start = c+1; } data += *c; } c++; // Advance beyond the ". kind = Token::STRING_DOUBLE; } break; // String literals. case '\'': { c++; for (; ; ++c) { if (*c == '\0') { throw StaticError(filename, begin, "Unterminated string"); } if (*c == '\'') { break; } if (*c == '\\' && *(c+1) != '\0') { data += *c; ++c; } if (*c == '\n') { // Maintain line/column counters. line_number++; line_start = c+1; } data += *c; } c++; // Advance beyond the '. kind = Token::STRING_SINGLE; } break; // Keywords default: if (is_identifier_first(*c)) { std::string id; for (; is_identifier(*c); ++c) id += *c; if (id == "assert") { kind = Token::ASSERT; } else if (id == "else") { kind = Token::ELSE; } else if (id == "error") { kind = Token::ERROR; } else if (id == "false") { kind = Token::FALSE; } else if (id == "for") { kind = Token::FOR; } else if (id == "function") { kind = Token::FUNCTION; } else if (id == "if") { kind = Token::IF; } else if (id == "import") { kind = Token::IMPORT; } else if (id == "importstr") { kind = Token::IMPORTSTR; } else if (id == "in") { kind = Token::IN; } else if (id == "local") { kind = Token::LOCAL; } else if (id == "null") { kind = Token::NULL_LIT; } else if (id == "self") { kind = Token::SELF; } else if (id == "super") { kind = Token::SUPER; } else if (id == "tailstrict") { kind = Token::TAILSTRICT; } else if (id == "then") { kind = Token::THEN; } else if (id == "true") { kind = Token::TRUE; } else { // Not a keyword, must be an identifier. kind = Token::IDENTIFIER; } data = id; } else if (is_symbol(*c) || *c == '#') { // Single line C++ and Python style comments. if (*c == '#' || (*c == '/' && *(c+1) == '/')) { std::vector<std::string> comment(1); unsigned blanks; unsigned indent; lex_until_newline(c, comment[0], blanks, indent, line_start, line_number); auto kind = fresh_line ? FodderElement::PARAGRAPH : FodderElement::LINE_END; fodder.emplace_back(kind, blanks, indent, comment); fresh_line = true; continue; // We've not got a token, just fodder, so keep scanning. } // Multi-line C style comment. if (*c == '/' && *(c+1) == '*') { unsigned margin = c - line_start; const char *initial_c = c; c += 2; // Avoid matching /*/: skip the /* before starting the search for */. while (!(*c == '*' && *(c+1) == '/')) { if (*c == '\0') { auto msg = "Multi-line comment has no terminating */."; throw StaticError(filename, begin, msg); } if (*c == '\n') { // Just keep track of the line / column counters. line_number++; line_start = c+1; } ++c; } c += 2; // Move the pointer to the char after the closing '/'. std::string comment(initial_c, c - initial_c); // Includes the "/*" and "*/". // Lex whitespace after comment unsigned new_lines_after, indent_after; lex_ws(c, new_lines_after, indent_after, line_start, line_number); std::vector<std::string> lines; if (comment.find('\n') >= comment.length()) { // Comment looks like /* foo */ lines.push_back(comment); fodder.emplace_back(FodderElement::INTERSTITIAL, 0, 0, lines); if (new_lines_after > 0) { fodder.emplace_back(FodderElement::LINE_END, new_lines_after - 1, indent_after, EMPTY); fresh_line = true; } } else { lines = line_split(comment, margin); assert(lines[0][0] == '/'); // Little hack to support PARAGRAPHs with * down the LHS: // Add a space to lines that start with a '*' bool all_star = true; for (auto &l : lines) { if (l[0] != '*') all_star = false; } if (all_star) { for (auto &l : lines) { if (l[0] == '*') l = " " + l; } } if (new_lines_after == 0) { // Ensure a line end after the paragraph. new_lines_after = 1; indent_after = 0; } if (!fresh_line) // Ensure a line end before the comment. fodder.emplace_back(FodderElement::LINE_END, 0, 0, EMPTY); fodder.emplace_back(FodderElement::PARAGRAPH, new_lines_after - 1, indent_after, lines); fresh_line = true; } continue; // We've not got a token, just fodder, so keep scanning. } // Text block if (*c == '|' && *(c+1) == '|' && *(c+2) == '|' && *(c+3) == '\n') { std::stringstream block; c += 4; // Skip the "|||\n" line_number++; // Skip any blank lines at the beginning of the block. while (*c == '\n') { line_number++; ++c; block << '\n'; } line_start = c; const char *first_line = c; int ws_chars = whitespace_check(first_line, c); string_block_indent = std::string(first_line, ws_chars); if (ws_chars == 0) { auto msg = "Text block's first line must start with whitespace."; throw StaticError(filename, begin, msg); } while (true) { assert(ws_chars > 0); // Read up to the \n for (c = &c[ws_chars]; *c != '\n' ; ++c) { if (*c == '\0') throw StaticError(filename, begin, "Unexpected EOF"); block << *c; } // Add the \n block << '\n'; ++c; line_number++; line_start = c; // Skip any blank lines while (*c == '\n') { line_number++; ++c; block << '\n'; } // Examine next line ws_chars = whitespace_check(first_line, c); if (ws_chars == 0) { // End of text block // Skip over any whitespace while (*c == ' ' || *c == '\t') { string_block_term_indent += *c; ++c; } // Expect ||| if (!(*c == '|' && *(c+1) == '|' && *(c+2) == '|')) { auto msg = "Text block not terminated with |||"; throw StaticError(filename, begin, msg); } c += 3; // Leave after the last | data = block.str(); kind = Token::STRING_BLOCK; break; // Out of the while loop. } } break; // Out of the switch. } const char *operator_begin = c; for (; is_symbol(*c) ; ++c) { // Not allowed // in operators if (*c == '/' && *(c+1) == '/') break; // Not allowed /* in operators if (*c == '/' && *(c+1) == '*') break; // Not allowed ||| in operators if (*c == '|' && *(c+1) == '|' && *(c+2) == '|') break; } // Not allowed to end with a + - ~ ! unless a single char. // So, wind it back if we need to (but not too far). while (c > operator_begin + 1 && (*(c-1) == '+' || *(c-1) == '-' || *(c-1) == '~' || *(c-1) == '!')) { c--; } data += std::string(operator_begin, c); if (data == "$") { kind = Token::DOLLAR; data = ""; } else { kind = Token::OPERATOR; } } else { std::stringstream ss; ss << "Could not lex the character "; auto uc = (unsigned char)(*c); if (*c < 32) ss << "code " << unsigned(uc); else ss << "'" << *c << "'"; throw StaticError(filename, begin, ss.str()); } } Location end(line_number, c - line_start); r.emplace_back(kind, fodder, data, string_block_indent, string_block_term_indent, LocationRange(filename, begin, end)); fodder.clear(); fresh_line = false; } Location end(line_number, c - line_start + 1); r.emplace_back(Token::END_OF_FILE, fodder, "", "", "", LocationRange(filename, end, end)); return r; }