Skip to content

Commit

Permalink
Introduce multiline strings using triple double-quoting
Browse files Browse the repository at this point in the history
Signed-off-by: Maxime Soulé <btik-git@scoubidou.com>
  • Loading branch information
maxatome committed Feb 13, 2023
1 parent f3e7ed7 commit e04ca3c
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 5 deletions.
20 changes: 18 additions & 2 deletions doc/manual/ctwm.1.adoc
Expand Up @@ -208,8 +208,24 @@ user-defined menus (containing functions to be invoked or
commands to be executed).

Variable names and keywords are case-insensitive. Strings must be
surrounded by double quote characters (e.g. ``blue'') and are
case-sensitive. A pound sign (&#35;) outside of a string causes the
surrounded by double quote characters (e.g. "blue") and are
case-sensitive. A string can contain newline characters (useful for
`f.exec` or `f.dynmenu`), but multiline strings are better achieved
using triple quoting as in:
------
f.dynmenu """
cat <<EOF
"$(hostname)" f.title
"*$(date)" !"daemon xterm"
EOF
"""
------
In double quoted strings, classic escape sequences are recognized
(`\b`, `\f`, `\n`, `\r`, `\t`, octal `\nnn`, hexadecimal `\0xnn` or
`\xnn`, `\"`, `\'` and `\\`). In multiline strings, no escape
sequences are allowed.

A pound sign (&#35;) outside of a string or a multiline strings causes the
remainder of the line in which the character appears to be treated as
a comment.

Expand Down
3 changes: 2 additions & 1 deletion gram.y
Expand Up @@ -97,7 +97,7 @@ int yylex(void);
%token <num> MONITOR_LAYOUT
%token <num> RPLAY_SOUNDS
%token <num> FORCE_FOCUS
%token <ptr> STRING
%token <ptr> STRING MLSTRING

%type <ptr> string
%type <num> action button number signed_number keyaction full fullkey
Expand Down Expand Up @@ -1129,6 +1129,7 @@ string : STRING { char *ptr = strdup($1);
RemoveDQuote(ptr);
$$ = ptr;
}
| MLSTRING { $$ = DupUnquoteMultilineString($1); }
;

number : NUMBER { $$ = $1; }
Expand Down
2 changes: 2 additions & 0 deletions lex.l
Expand Up @@ -49,6 +49,7 @@
%}

string \"([^"]|\\.)*\"
mlstring \"\"\"([^\"]+|\"[^\"]+|\"\"[^\"]+)*\"\"\"
number [0-9]+

/* Requires flex 2.5.1 (28Mar95) */
Expand Down Expand Up @@ -82,6 +83,7 @@ number [0-9]+
"!" { yylval.num = F_EXEC; return FSKEYWORD; }

{string} { yylval.ptr = yytext; return STRING; }
{mlstring} { yylval.ptr = yytext; return MLSTRING; }
{number} { sscanf(yytext, "%d", &yylval.num);
return NUMBER; }
\#[^\n]*\n {;}
Expand Down
15 changes: 13 additions & 2 deletions parse_menu.c
Expand Up @@ -14,6 +14,17 @@ extern int (*twmInputFunc)(void);
extern int yylex(void);
extern char *yytext;

static char *
strdupunquote(char *s, bool multiline)
{
if(multiline) {
return DupUnquoteMultilineString(s);
}
s = strdup(s);
RemoveDQuote(s);
return s;
}

static bool
ParseMenuEntry(MenuRoot *menu)
{
Expand Down Expand Up @@ -50,9 +61,9 @@ ParseMenuEntry(MenuRoot *menu)
step = STEP_ERROR;
break;

case MLSTRING:
case STRING:
str = strdup(yylval.ptr);
RemoveDQuote(str);
str = strdupunquote(yylval.ptr, token == MLSTRING);
switch(step) {
case STEP_START:
label = str;
Expand Down
14 changes: 14 additions & 0 deletions parse_yacc.c
Expand Up @@ -8,6 +8,7 @@
#include "ctwm.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

Expand Down Expand Up @@ -132,6 +133,19 @@ void RemoveDQuote(char *str)
*o = '\0';
}

char *DupUnquoteMultilineString(char *str)
{
char *ret;
int len;

str += 3;
len = strlen(str) - 3;
ret = malloc(len + 1);
memcpy(ret, str, len);
ret[len] = '\0';
return ret;
}

MenuRoot *GetRoot(char *name, char *fore, char *back, bool dynamic)
{
MenuRoot *tmp;
Expand Down
1 change: 1 addition & 0 deletions parse_yacc.h
Expand Up @@ -8,6 +8,7 @@ void yyerror(char *s);

void InitGramVariables(void);
void RemoveDQuote(char *str);
char *DupUnquoteMultilineString(char *str);

MenuRoot *GetRoot(char *name, char *fore, char *back, bool dynamic);

Expand Down

0 comments on commit e04ca3c

Please sign in to comment.