For example:
str = "some weired chars: \"\\";
code = "variable newstr=\"" + quotemeta(str) + "\";";
eval(code);
What I am looking for is this unknown quotemeta() function which should
escape all "dangerous" characters. Is there already such a function?
--
-- Ullrich Horlacher --------------------- mailto:fram...@belwue.de --
BelWue Coordination phone: +49 711 685 65872
University of Stuttgart fax: +49 711 678 8363
-- Allmandring 3A, 70550 Stuttgart, Germany -- http://www.belwue.de/ --
A valid slang identifier consists of any alphanumeric character,
provided that the first character is not a digit. So, assuming you
are using slang-2, you can use strtrans to map other characters to an
underscore _:
str = strtrans (str, "\\w", "_");
Then you might want to remote repeated underscore characters using:
str = strcompress (str, "_");
Finally, ensure that the first character is not a digit:
if (isdigit (str))
str = "_" + str;
I hope this helps.
--John
> >I have a string which may contain any byte combination including control
> >characters. I want to build a legal slang variable assignment with this
> >string.
>
> A valid slang identifier consists of any alphanumeric character,
> provided that the first character is not a digit.
Yes, I know this, but this is not the point.
The variable name is fix (given), only the value (right side of =) is random.
Back to my example, I have now deleted the fictious function quotemeta():
variable str,code;
str = "some weired chars: \"\\";
code = "variable newstr=\"" + str + "\";";
eval(code);
when running this code (evalbuffer within jed) I get:
***string***:1: Invalid character: found '??'
No wonder, because the constructed code
variable newstr="some weired chars: "\";
is not valid. The assignment of the variable 'str' itself is legal, but not
if I use it to build and evaluate the variable 'code'.
This was only one example, the variable 'str' could contain also control
characters.
What I need is a function to transform any string into a legal slang
right-of-equal assignment part.
I hope you understand now my problem :-)
I understand now. You might try using str_quote_string"
str = str_quote_string (str, "\"", '\\');
(str,) = strreplace (str, "\n", "\\n", strlen (str));
The last line replaces literal newline characters by the escaped form
\n.
Also keep in mind that when you use
eval ("variable new_str = whatever");
then eval will be created in the global namespace. In that case, it
may be simpler to use:
eval ("variable new_str;");
variable ref = __get_reference ("new_str");
@new_str = "some weird chars....";
If I knew more about what you are trying to do, I might be able to
suggest something more convenient.
> I understand now. You might try using str_quote_string"
>
> str = str_quote_string (str, "\"", '\\');
> (str,) = strreplace (str, "\n", "\\n", strlen (str));
Ok, this will replace only known "problematic" characters.
But there are much more, like ASCII range 0-31.
> Also keep in mind that when you use
>
> eval ("variable new_str = whatever");
>
> then eval will be created in the global namespace.
Yes, this is a feature in my implementation :-)
> If I knew more about what you are trying to do, I might be able to
> suggest something more convenient.
Background problem:
I want to make some variables persistent in jed.
For example, I want to keep the variables edt_lbuf and USE_ANSI_COLORS
between different jed runs. I have already functions (originally written
by you some years ago as an answer to my questions then :-) ) which save
and restores some state information like last line number, editing mode
and which files/buffers are in use.
Such a state file contains slang code which is created and written when
jed terminates. The next jed run will evaluate this state file.
An example of such a state file is:
bofh:~/.jed/state: cat _sw_share_jedlib-0.99-17_jed_lib_.sl
define restoref(f,n){if(file_status(f)==1){if(strcmp(whatbuf(),"*scratch*"))splitwindow();()=find_file(f);goto_line(n);1;}else 0;}
if (restoref("/sw/share/jedlib-0.99-17/jed/lib/defaults.sl",596)) slang_mode();
if (restoref("/sw/share/jedlib-0.99-17/jed/lib/jed.rc",161)) slang_mode();
.()restoref
Adding the variable USE_ANSI_COLORS to the state file is no problem,
because it is an integer. But I have problems with edt_lbuf, which
contains the last deleted line in edt_mode (my main editing emulation).
This line can contain any character (byte), including quotes, backslashes
and of course trailing newline. I want to build at runtime a slang
code-line like:
edt_lbuf = "all characters...\n";
But for this I have to escape or trans-literate all problematic
characters. Using the simple approach
() = append_string_to_file("edt_lbuf = \"+edt_lbuf+"\";\n", state_file)
will fail.
As far as the parser is concerned, the others are not problematic,
with the exception of \0, which could be used in a binary string.
[...]
>But for this I have to escape or trans-literate all problematic
>characters. Using the simple approach
>
> () = append_string_to_file("edt_lbuf = \"+edt_lbuf+"\";\n", state_file)
The combination of str_quote_string/strreplace should be enough to
handle this. Let me know if this assertion proves incorrect.
Thanks,
--John
> >> str = str_quote_string (str, "\"", '\\');
> >> (str,) = strreplace (str, "\n", "\\n", strlen (str));
> >
> >Ok, this will replace only known "problematic" characters.
> >But there are much more, like ASCII range 0-31.
>
> As far as the parser is concerned, the others are not problematic,
> with the exception of \0, which could be used in a binary string.
Ohhh.. it is that easy?! Great! :-)
> The combination of str_quote_string/strreplace should be enough to
> handle this. Let me know if this assertion proves incorrect.
Ok, I have now my wanted function:
define quotemeta(str) {
variable quote;
quote = str_quote_string(str,"\"",'\\');
(quote,) = strreplace(quote,"\n","\\n",strlen(quote));
return(quote);
}
and it works so far without problems in creating slang variable assignment
code strings.
My initial problem with creating persistent jed string variables is
solved! Thanks!
For example, my actual jed state file contains:
bofh:~/.jed/state: cat _sw_share_jedlib-0.99-17_jed_lib_.sl
edt_lbuf=" str = \"edt_lbuf=\\\"\"+quotemeta(edt_lbuf)+\"\\\";\\n\";\n";
search_pat="return";
USE_ANSI_COLORS=1; secs("console");
define restoref(f,n){if(file_status(f)==1){if(strcmp(whatbuf(),"*scratch*"))splitwindow();()=find_file(f);goto_line(n);1;}else 0;}
if (restoref("/sw/share/jedlib-0.99-17/jed/lib/defaults.sl",1096)) slang_mode();
.()restoref
Only, one should look not so close at it, it could trigger headache :-)
(Standard with auto-generated code)