mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-20 12:58:08 +01:00
Remove dependency to CPP: added pre-defined macros
A number of macros are pre-defined by WindowMaker for CPP in the function 'MakeCPPArgs', they are now available in the internal parser too. CPP also had some predefined macros, a subset of them have been added. The definition have been split in two parts: - the macro that are dependant on WindowMaker parameters are defined by WindowMaker (src/rootmenu.c) - those that are independant, which can be defined by the parser itself (WINGs/menuparser_macros.c)
This commit is contained in:
committed by
Carlos R. Mafra
parent
aaa4517df7
commit
9b792369cb
@@ -874,6 +874,8 @@ typedef struct w_menu_parser *WMenuParser;
|
|||||||
|
|
||||||
WMenuParser WMenuParserCreate(const char *file_name, void *file, const char *include_default_paths);
|
WMenuParser WMenuParserCreate(const char *file_name, void *file, const char *include_default_paths);
|
||||||
|
|
||||||
|
void WMenuParserRegisterSimpleMacro(WMenuParser parser, const char *name, const char *value);
|
||||||
|
|
||||||
void WMenuParserError(WMenuParser parser, const char *msg, ...)
|
void WMenuParserError(WMenuParser parser, const char *msg, ...)
|
||||||
__attribute__ ((format (printf, 2, 3)));
|
__attribute__ ((format (printf, 2, 3)));
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ WMenuParser WMenuParserCreate(const char *file_name, void *file,
|
|||||||
WMenuParser parser;
|
WMenuParser parser;
|
||||||
|
|
||||||
parser = menu_parser_create_new(file_name, file, include_default_paths);
|
parser = menu_parser_create_new(file_name, file, include_default_paths);
|
||||||
|
menu_parser_register_preset_macros(parser);
|
||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ struct w_parser_macro {
|
|||||||
|
|
||||||
Bool menu_parser_skip_spaces_and_comments(WMenuParser parser);
|
Bool menu_parser_skip_spaces_and_comments(WMenuParser parser);
|
||||||
|
|
||||||
|
void menu_parser_register_preset_macros(WMenuParser parser);
|
||||||
|
|
||||||
void menu_parser_define_macro(WMenuParser parser);
|
void menu_parser_define_macro(WMenuParser parser);
|
||||||
|
|
||||||
void menu_parser_free_macros(WMenuParser parser);
|
void menu_parser_free_macros(WMenuParser parser);
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
#include <WINGs/WUtil.h>
|
#include <WINGs/WUtil.h>
|
||||||
|
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
This file contains the functions related to macros:
|
This file contains the functions related to macros:
|
||||||
- parse a macro being defined
|
- parse a macro being defined
|
||||||
- handle single macro expansion
|
- handle single macro expansion
|
||||||
|
- pre-defined parser's macros
|
||||||
|
|
||||||
Some design notes for macro internal storage:
|
Some design notes for macro internal storage:
|
||||||
|
|
||||||
@@ -56,6 +59,21 @@
|
|||||||
This structure allows to store any number and combination
|
This structure allows to store any number and combination
|
||||||
of text/parameter and still provide very fast generation
|
of text/parameter and still provide very fast generation
|
||||||
at macro replacement time.
|
at macro replacement time.
|
||||||
|
|
||||||
|
Predefined macros are using a call-back function mechanism
|
||||||
|
to generate the value on-demand. This value is generated
|
||||||
|
in the 'value' buffer of the structure.
|
||||||
|
Most of these call-backs will actually cache the value:
|
||||||
|
they generate it on the first use (inside a parser,
|
||||||
|
not globally) and reuse that value on next call(s).
|
||||||
|
|
||||||
|
Because none of these macros take parameters, the call-back
|
||||||
|
mechanism does not include passing of user arguments; the
|
||||||
|
complex storage mechanism for argument replacement being
|
||||||
|
not necessary the macro->value parameter is used as a
|
||||||
|
plain C string to be copied, this fact being recognised
|
||||||
|
by macro->function being non-null. It was chosen that the
|
||||||
|
call-back function would not have the possibility to fail.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static Bool menu_parser_read_macro_def(WMenuParser parser, WParserMacro *macro, char **argname);
|
static Bool menu_parser_read_macro_def(WMenuParser parser, WParserMacro *macro, char **argname);
|
||||||
@@ -512,3 +530,175 @@ static Bool menu_parser_read_macro_args(WMenuParser parser, WParserMacro *macro,
|
|||||||
macro->name);
|
macro->name);
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* Definition of pre-defined macros */
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void WMenuParserRegisterSimpleMacro(WMenuParser parser, const char *name, const char *value)
|
||||||
|
{
|
||||||
|
WParserMacro *macro;
|
||||||
|
size_t len;
|
||||||
|
unsigned char *wr;
|
||||||
|
|
||||||
|
macro = wmalloc(sizeof(*macro));
|
||||||
|
strncpy(macro->name, name, sizeof(macro->name)-1);
|
||||||
|
macro->arg_count = -1;
|
||||||
|
len = strlen(value);
|
||||||
|
if (len > sizeof(macro->value) - 3) {
|
||||||
|
wwarning(_("size of value for macro '%s' is too big, truncated"), name);
|
||||||
|
len = sizeof(macro->value) - 3;
|
||||||
|
}
|
||||||
|
macro->value[0] = (len >> 8) & 0xFF;
|
||||||
|
macro->value[1] = len & 0xFF;
|
||||||
|
wr = ¯o->value[2];
|
||||||
|
while (len-- > 0)
|
||||||
|
*wr++ = *value++;
|
||||||
|
*wr = 0xFF;
|
||||||
|
macro->next = parser->macros;
|
||||||
|
parser->macros = macro;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name of the originally loaded file (before #includes) */
|
||||||
|
static void mpm_base_file(WParserMacro *this, WMenuParser parser)
|
||||||
|
{
|
||||||
|
unsigned char *src, *dst;
|
||||||
|
|
||||||
|
if (this->value[0] != '\0') return; // Value already evaluated, re-use previous
|
||||||
|
|
||||||
|
while (parser->parent_file != NULL)
|
||||||
|
parser = parser->parent_file;
|
||||||
|
|
||||||
|
dst = this->value;
|
||||||
|
src = (unsigned char *) parser->file_name;
|
||||||
|
*dst++ = '\"';
|
||||||
|
while (*src != '\0')
|
||||||
|
if (dst < this->value + sizeof(this->value) - 2)
|
||||||
|
*dst++ = *src++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
*dst++ = '\"';
|
||||||
|
*dst = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Number of #include currently nested */
|
||||||
|
static void mpm_include_level(WParserMacro *this, WMenuParser parser)
|
||||||
|
{
|
||||||
|
int level = 0;
|
||||||
|
while (parser->parent_file != NULL) {
|
||||||
|
parser = parser->parent_file;
|
||||||
|
level++;
|
||||||
|
}
|
||||||
|
snprintf((char *) this->value, sizeof(this->value), "%d", level);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name of current file */
|
||||||
|
static void mpm_current_file(WParserMacro *this, WMenuParser parser)
|
||||||
|
{
|
||||||
|
unsigned char *src, *dst;
|
||||||
|
|
||||||
|
dst = this->value;
|
||||||
|
src = (unsigned char *) parser->file_name;
|
||||||
|
*dst++ = '\"';
|
||||||
|
while (*src != '\0')
|
||||||
|
if (dst < this->value + sizeof(this->value) - 2)
|
||||||
|
*dst++ = *src++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
*dst++ = '\"';
|
||||||
|
*dst = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Number of current line */
|
||||||
|
static void mpm_current_line(WParserMacro *this, WMenuParser parser)
|
||||||
|
{
|
||||||
|
snprintf((char *) this->value, sizeof(this->value), "%d", parser->line_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name of host on which we are running, not necessarily displaying */
|
||||||
|
static void mpm_get_hostname(WParserMacro *this, WMenuParser parser)
|
||||||
|
{
|
||||||
|
char *h;
|
||||||
|
|
||||||
|
if (this->value[0] != '\0') return; // Value already evaluated, re-use previous
|
||||||
|
|
||||||
|
h = getenv("HOSTNAME");
|
||||||
|
if (h == NULL) {
|
||||||
|
h = getenv("HOST");
|
||||||
|
if (h == NULL) {
|
||||||
|
if (gethostname((char *) this->value, sizeof(this->value) ) != 0) {
|
||||||
|
WMenuParserError(parser, _("could not determine %s"), "HOSTNAME");
|
||||||
|
this->value[0] = '?';
|
||||||
|
this->value[1] = '?';
|
||||||
|
this->value[2] = '?';
|
||||||
|
this->value[3] = '\0';
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wstrlcpy((char *) this->value, h, sizeof(this->value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name of the current user */
|
||||||
|
static void mpm_get_user_name(WParserMacro *this, WMenuParser parser)
|
||||||
|
{
|
||||||
|
char *user;
|
||||||
|
|
||||||
|
if (this->value[0] != '\0') return; // Value already evaluated, re-use previous
|
||||||
|
|
||||||
|
user = getlogin();
|
||||||
|
if (user == NULL) {
|
||||||
|
struct passwd *pw_user;
|
||||||
|
|
||||||
|
pw_user = getpwuid(getuid());
|
||||||
|
if (pw_user == NULL) {
|
||||||
|
error_no_username:
|
||||||
|
WMenuParserError(parser, _("could not determine %s"), "USER" );
|
||||||
|
/* Fall back on numeric id - better than nothing */
|
||||||
|
snprintf((char *) this->value, sizeof(this->value), "%d", getuid() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
user = pw_user->pw_name;
|
||||||
|
if (user == NULL) goto error_no_username;
|
||||||
|
}
|
||||||
|
wstrlcpy((char *) this->value, user, sizeof(this->value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Number id of the user under which we are running */
|
||||||
|
static void mpm_get_user_id(WParserMacro *this, WMenuParser parser)
|
||||||
|
{
|
||||||
|
if (this->value[0] != '\0') return; // Already evaluated, re-use previous
|
||||||
|
snprintf((char *) this->value, sizeof(this->value), "%d", getuid() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Small helper to automate creation of one pre-defined macro in the parser */
|
||||||
|
static void w_create_macro(WMenuParser parser, const char *name, WParserMacroFunction *handler)
|
||||||
|
{
|
||||||
|
WParserMacro *macro;
|
||||||
|
|
||||||
|
macro = wmalloc(sizeof(*macro));
|
||||||
|
strcpy(macro->name, name);
|
||||||
|
macro->function = handler;
|
||||||
|
macro->arg_count = -1;
|
||||||
|
macro->next = parser->macros;
|
||||||
|
parser->macros = macro;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Register all the pre-defined macros in the parser *****/
|
||||||
|
void menu_parser_register_preset_macros(WMenuParser parser)
|
||||||
|
{
|
||||||
|
/* Defined by CPP: common predefined macros (GNU C extension) */
|
||||||
|
w_create_macro(parser, "__BASE_FILE__", mpm_base_file);
|
||||||
|
w_create_macro(parser, "__INCLUDE_LEVEL__", mpm_include_level);
|
||||||
|
|
||||||
|
/* Defined by CPP: standard predefined macros */
|
||||||
|
w_create_macro(parser, "__FILE__", mpm_current_file);
|
||||||
|
w_create_macro(parser, "__LINE__", mpm_current_line);
|
||||||
|
// w_create_macro(parser, "__DATE__", NULL); [will be implemented only per user request]
|
||||||
|
// w_create_macro(parser, "__TIME__", NULL); [will be implemented only per user request]
|
||||||
|
|
||||||
|
/* Historically defined by WindowMaker */
|
||||||
|
w_create_macro(parser, "HOST", mpm_get_hostname);
|
||||||
|
w_create_macro(parser, "UID", mpm_get_user_id);
|
||||||
|
w_create_macro(parser, "USER", mpm_get_user_name);
|
||||||
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ static WMenu *readMenuPipe(WScreen * scr, char **file_name);
|
|||||||
static WMenu *readMenuFile(WScreen * scr, char *file_name);
|
static WMenu *readMenuFile(WScreen * scr, char *file_name);
|
||||||
static WMenu *readMenuDirectory(WScreen * scr, char *title, char **file_name, char *command);
|
static WMenu *readMenuDirectory(WScreen * scr, char *title, char **file_name, char *command);
|
||||||
static WMenu *configureMenu(WScreen * scr, WMPropList * definition, Bool includeGlobals);
|
static WMenu *configureMenu(WScreen * scr, WMPropList * definition, Bool includeGlobals);
|
||||||
|
static void menu_parser_register_macros(WMenuParser parser);
|
||||||
|
|
||||||
typedef struct Shortcut {
|
typedef struct Shortcut {
|
||||||
struct Shortcut *next;
|
struct Shortcut *next;
|
||||||
@@ -970,6 +971,7 @@ static WMenu *readMenuFile(WScreen * scr, char *file_name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
parser = WMenuParserCreate(file_name, file, DEF_CONFIG_PATHS);
|
parser = WMenuParserCreate(file_name, file, DEF_CONFIG_PATHS);
|
||||||
|
menu_parser_register_macros(parser);
|
||||||
|
|
||||||
while (WMenuParserGetLine(parser, &title, &command, ¶ms, &shortcut)) {
|
while (WMenuParserGetLine(parser, &title, &command, ¶ms, &shortcut)) {
|
||||||
|
|
||||||
@@ -1061,6 +1063,7 @@ static WMenu *readMenuPipe(WScreen * scr, char **file_name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
parser = WMenuParserCreate(flat_file, file, DEF_CONFIG_PATHS);
|
parser = WMenuParserCreate(flat_file, file, DEF_CONFIG_PATHS);
|
||||||
|
menu_parser_register_macros(parser);
|
||||||
|
|
||||||
while (WMenuParserGetLine(parser, &title, &command, ¶ms, &shortcut)) {
|
while (WMenuParserGetLine(parser, &title, &command, ¶ms, &shortcut)) {
|
||||||
|
|
||||||
@@ -1106,6 +1109,34 @@ static int myCompare(const void *d1, const void *d2)
|
|||||||
return strcmp(p1->name, p2->name);
|
return strcmp(p1->name, p2->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***** Preset some macro for file parser *****/
|
||||||
|
static void menu_parser_register_macros(WMenuParser parser)
|
||||||
|
{
|
||||||
|
Visual *visual;
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
// Used to return CPP verion, now returns wmaker's version
|
||||||
|
WMenuParserRegisterSimpleMacro(parser, "__VERSION__", VERSION);
|
||||||
|
|
||||||
|
// All macros below were historically defined by WindowMaker
|
||||||
|
visual = DefaultVisual(dpy, DefaultScreen(dpy));
|
||||||
|
snprintf(buf, sizeof(buf), "%d", visual->class);
|
||||||
|
WMenuParserRegisterSimpleMacro(parser, "VISUAL", buf);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%d", DefaultDepth(dpy, DefaultScreen(dpy)) );
|
||||||
|
WMenuParserRegisterSimpleMacro(parser, "DEPTH", buf);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%d", WidthOfScreen(DefaultScreenOfDisplay(dpy)) );
|
||||||
|
WMenuParserRegisterSimpleMacro(parser, "SCR_WIDTH", buf);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%d", HeightOfScreen(DefaultScreenOfDisplay(dpy)) );
|
||||||
|
WMenuParserRegisterSimpleMacro(parser, "SCR_HEIGHT", buf);
|
||||||
|
|
||||||
|
WMenuParserRegisterSimpleMacro(parser, "DISPLAY", XDisplayName(DisplayString(dpy)) );
|
||||||
|
|
||||||
|
WMenuParserRegisterSimpleMacro(parser, "WM_VERSION", "\"" VERSION "\"");
|
||||||
|
}
|
||||||
|
|
||||||
/************ Menu Configuration From Directory *************/
|
/************ Menu Configuration From Directory *************/
|
||||||
|
|
||||||
static Bool isFilePackage(char *file)
|
static Bool isFilePackage(char *file)
|
||||||
|
|||||||
Reference in New Issue
Block a user