From f58e7aa8b145b05d7965b6dc31c2835d9da412f3 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Thu, 28 Oct 2010 18:42:35 -0400 Subject: [PATCH] PR12169: fix tokenize() * tapset/tokenize.stp: New file for tokenize(). Use per-context statics. * doc/SystemTap_Tapset_Reference/tapsets.tmpl: Pull it into new docs. * tapset/string.stp: Remove old tokenize() code. * translate.cxx (emit_common_header): Add STAP_NEED_CONTEXT_TOKENIZE bits. (translate_pass): Emit global %{ %} embeds before context definition. --- doc/SystemTap_Tapset_Reference/tapsets.tmpl | 1 + tapset/string.stp | 38 ---------------- tapset/tokenize.stp | 48 +++++++++++++++++++++ translate.cxx | 14 ++++-- 4 files changed, 59 insertions(+), 42 deletions(-) create mode 100644 tapset/tokenize.stp diff --git a/doc/SystemTap_Tapset_Reference/tapsets.tmpl b/doc/SystemTap_Tapset_Reference/tapsets.tmpl index 26b4a41c9..54cb9f717 100644 --- a/doc/SystemTap_Tapset_Reference/tapsets.tmpl +++ b/doc/SystemTap_Tapset_Reference/tapsets.tmpl @@ -273,6 +273,7 @@ strings to longs. !Itapset/string.stp +!Itapset/tokenize.stp Utility functions for using ansi control chars in logs diff --git a/tapset/string.stp b/tapset/string.stp index cd8f6c213..811e48c0d 100644 --- a/tapset/string.stp +++ b/tapset/string.stp @@ -111,44 +111,6 @@ function text_strn:string(input:string, len:long, quoted:long) _stp_text_str(THIS->__retvalue, THIS->input, len, THIS->quoted, 0); %} -/** - * sfunction tokenize - Return the next non-empty token in a string. - * - * General Syntax: tokenize:string (input:string, delim:string) - * - * @input: String to tokenize. If NULL, returns the next non-empty token - * in the string passed in the previous call to tokenize(). - * @delim: Token delimiter. Set of characters that delimit the tokens. - * - * Description: This function returns the next non-empty token in the - * given input string, where the tokens are delimited by characters in - * the delim string. If the input string is non-NULL, it returns the - * first token. If the input string is NULL, it returns the next - * token in the string passed in the previous call to tokenize. - * If no delimiter is found, the entire remaining input string is - * returned. It returns NULL when no more tokens are available. - */ -function tokenize:string(input:string, delim:string) -%{ - static char str[MAXSTRINGLEN]; - static char *str_start; - static char *str_end; - char *token = NULL; - char *token_end = NULL; - - if (THIS->input[0]) { - strncpy(str, THIS->input, MAXSTRINGLEN); - str_start = &str[0]; - str_end = &str[0] + strlen(str); - } - do { - token = strsep(&str_start, THIS->delim); - } while (token && !token[0]); - if (token) { - token_end = (str_start ? str_start - 1 : str_end); - memcpy(THIS->__retvalue, token, token_end - token + 1); - } -%} /** * sfunction - str_replace Replaces all instances of a substring with another. diff --git a/tapset/tokenize.stp b/tapset/tokenize.stp new file mode 100644 index 000000000..6226fc614 --- /dev/null +++ b/tapset/tokenize.stp @@ -0,0 +1,48 @@ +// Tokenize tapset +// Copyright (C) 2010 Red Hat, Inc. +// +// This file is part of systemtap, and is free software. You can +// redistribute it and/or modify it under the terms of the GNU General +// Public License (GPL); either version 2, or (at your option) any +// later version. + +%{ +#define STAP_NEED_CONTEXT_TOKENIZE 1 +%} + +/** + * sfunction tokenize - Return the next non-empty token in a string. + * + * General Syntax: tokenize:string (input:string, delim:string) + * + * @input: String to tokenize. If NULL, returns the next non-empty token + * in the string passed in the previous call to tokenize(). + * @delim: Token delimiter. Set of characters that delimit the tokens. + * + * Description: This function returns the next non-empty token in the + * given input string, where the tokens are delimited by characters in + * the delim string. If the input string is non-NULL, it returns the + * first token. If the input string is NULL, it returns the next + * token in the string passed in the previous call to tokenize. + * If no delimiter is found, the entire remaining input string is + * returned. It returns NULL when no more tokens are available. + */ +function tokenize:string(input:string, delim:string) +%{ /* unprivileged */ + char *token = NULL; + char *token_end = NULL; + + if (THIS->input[0]) { + strncpy(CONTEXT->tok_str, THIS->input, MAXSTRINGLEN); + CONTEXT->tok_start = &CONTEXT->tok_str[0]; + CONTEXT->tok_end = &CONTEXT->tok_str[0] + strlen(CONTEXT->tok_str); + } + do { + token = strsep(& CONTEXT->tok_start, THIS->delim); + } while (token && !token[0]); + if (token) { + token_end = (CONTEXT->tok_start ? CONTEXT->tok_start - 1 : CONTEXT->tok_end); + memcpy(THIS->__retvalue, token, token_end - token + 1); + } +%} + diff --git a/translate.cxx b/translate.cxx index 35faf2f82..f360940e0 100644 --- a/translate.cxx +++ b/translate.cxx @@ -930,6 +930,11 @@ c_unparser::emit_common_header () o->newline() << "int actionremaining;"; o->newline() << "int nesting;"; o->newline() << "string_t error_buffer;"; + o->newline() << "#ifdef STAP_NEED_CONTEXT_TOKENIZE"; + o->newline() << "string_t tok_str;"; + o->newline() << "char *tok_start;"; + o->newline() << "char *tok_end;"; + o->newline() << "#endif"; o->newline() << "const char *last_error;"; // NB: last_error is used as a health flag within a probe. // While it's 0, execution continues @@ -5823,15 +5828,16 @@ translate_pass (systemtap_session& s) s.op->newline() << "#include \"loc2c-runtime.h\" "; s.op->newline() << "#include \"access_process_vm.h\" "; - s.up->emit_common_header (); // context etc. - - s.op->newline() << "#include \"probe_lock.h\" "; - + // Emit embeds ahead of time, in case they affect context layout for (unsigned i=0; inewline() << s.embeds[i]->code << "\n"; } + s.up->emit_common_header (); // context etc. + + s.op->newline() << "#include \"probe_lock.h\" "; + if (s.globals.size()>0) { s.op->newline() << "static struct {"; s.op->indent(1); -- 2.43.5