lvgl / lv_i18n

Internationalization (i18n) for LVGL
MIT License
57 stars 17 forks source link

Multiple calls to the _() macro on one line don't extract correctly #31

Closed Crazor closed 3 years ago

Crazor commented 3 years ago

If I have multiple _() calls on one source line, everything between the first opening _( and the last closing ) gets extracted into the .yml files.

Without looking at the source of the extraction tool, I'd guess that this could be caused by the greediness of the regex probably used for extraction.

puzrin commented 3 years ago

https://github.com/lvgl/lv_i18n/blob/master/test/js/fixtures/cli_extract/src_1.c there are tests for multiple calls.

Please, provide detailed description how to reproduce.

Crazor commented 3 years ago

I can't see any tests for multiple calls on the same line. Example: foo(_("BAR"), _("BAZ")); becomes 'BAR"), _("BAZ': ~ after extraction. My current workaround is to split the function call to multiple lines.

puzrin commented 3 years ago

https://github.com/lvgl/lv_i18n/blob/master/lib/parser.js

Current parser is simplified. Probably, it sucks with multiple entries in single line.

Is this use case from real project, worth to be fixed, or just a sandbox playground?

Crazor commented 3 years ago

I encountered the issue in a real project, passing the label and help text for a button into my own little UI toolkit (not using LittlevGL yet). TBH, I'm not really set up for JS development (nor do I have any clue what I'm doing, I'm a C/C++ guy). But from looking at the parser code (and my previous experience with regexs in other languages), I suggest switching from a greedy match to a lazy match.

E.g. in line 18 of parser.js, it should be as simple as adding a ? after the *: '(?:^|[ =+,;\(])' + _.escapeRegExp(fn_name) + '\\("(.*?)"\\)',

The regexp will then return (an array of?) multiple matches on a line like foo(_("BAR"), _("BAZ")); which needs to be handled accordingly in the calling code.

I tested this with a simplified version of the current regex to verify that JS does behave as I expect: https://regex101.com/r/EbFGRK/1 You can try removing the ? character to trigger the behaviour I originally encountered.

puzrin commented 3 years ago

Good catch! Thanks.

Published fix (0.2.1).

puzrin commented 3 years ago

BTW, if you have solid experience with C/CPP testing, look at https://github.com/lvgl/lvgl/issues/1853. Need help with good infrasruture setup.

I know testing well, but i'm not C/CPP developper. And core devs have opposite experience :).