Deutsch   English   Français   Italiano  
<vovj7p$12c64$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: pozz <pozzugno@gmail.com>
Newsgroups: comp.arch.embedded
Subject: Re: How to add the second (or other) languages
Date: Mon, 17 Feb 2025 16:05:30 +0100
Organization: A noiseless patient Spider
Lines: 168
Message-ID: <vovj7p$12c64$1@dont-email.me>
References: <voii3i$28jmm$1@dont-email.me>
 <voioe3.598.1@stefan.msgid.phost.de> <voiu1q$2f5ap$1@dont-email.me>
 <votcl3$nc20$1@dont-email.me> <vout9p$12qr8$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Mon, 17 Feb 2025 16:05:30 +0100 (CET)
Injection-Info: dont-email.me; posting-host="ca4b41e55fa84924cb3859e07bb62aea";
	logging-data="1126596"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX18ssINYRGyT7WgQAeWd8ucLxX+0ft97Ajg="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:3T+95R+5+DDeUjzaQcA2i5bp5l8=
Content-Language: it
In-Reply-To: <vout9p$12qr8$1@dont-email.me>

Il 17/02/2025 09:51, David Brown ha scritto:
> On 16/02/2025 19:59, pozz wrote:
>> Il 12/02/2025 20:50, David Brown ha scritto:
> 
>>>
>>> You don't need a very fancy pre-processor to handle this yourself, if 
>>> you are happy to make a few changes to the code.  Have your code use 
>>> something like :
>>>
>>> #define DisplayPrintf(id, desc, args...) \
>>>      display_printf(strings[language][string_ ## id], ## x)
>>>
>>> Use it like :
>>>
>>>      DisplayPrintf(event_type_on, "Event on", ev->idx);
>>>
>>>
>>> A little Python preprocessor script can chew through all your C files 
>>> and identify each call to "DisplayPrintf". 
>>
>> Little... yes, it would be little, but not simple, at least for me. 
>> How to write a correct C preprocessor in Python?
> 
> You don't write a C preprocessor - that's the point.
> 
> Tools like gettext have to handle any C code.  That means they need to 
> deal with situations with complicated macros, include files, etc.
> 
> You don't need to do that when you make your own tools.  You make the 
> rules - /you/ decide what limitations you will accept in order to 
> simplify the pre-processing script.
> 
> So you would typically decide you only put these DisplayPrintf calls in 
> C files, not headers, that you ignore all normal C preprocessor stuff, 
> and that you keep each call entirely on one line, and that you'll never 
> use the sequence "DisplayPrintf" for anything else.  Then your Python 
> preprocessor becomes :
> 
>      for this_line in open(filename).readlines() :
>          if "DisplayPrintf" in line :
>              handle(line)
> 
> This is /vastly/ simpler than dealing with more general C code, without 
> significant restrictions to you as the programmer using the system.
> 
> If you /really/ want to handle include files, conditional compilation 
> and all rest of it, get the C compiler to handle that - use "gcc -E" and 
> use the output of that.  Trying to duplicate that in your own Python 
> code would be insane.

And this is the reason why it appeared to me a complex task :-)

You're right, this is my own tool and I decide the rules. Many times I 
try to solve the complete and general problem when, in the reality, the 
border of the the problem is much smaller.

The only drawback is that YOU (and all the developers that work on the 
project now and in the future) have to remember your own rules forever 
for that project.


>> This preprocessor should ingest a C source file after it is 
>> preprocessed by the standard C preprocessor for the specific build you 
>> are doing.
>>
>> For example, you could have a C source file that contains:
>>
>> #if BUILD == BUILD_FULL
>>    DisplayPrintf(msg, "Press (1) for simple process, (2) for advanced 
>> process");
>>    x = wait_keypress();
>>    if (x == '1') do_simple();
>>    if (x == '2') do_adv();
>> #elif BUILD == BUILD_LIGHT
>>    do_simple();
>> #endif
>>
> 
> The really simple answer is, don't do that.
> 
> 
>> If I'm building the project as BUILD_FULL, there's at least one 
>> additional string to translate.
> 
> The slightly more complex answer is that you end up with an extra string 
> in one build or the other.  Almost certainly, this is not worth 
> bothering about.  

Oh yes, but that was only an example. We can think of other scenarios 
where the preprocessor could change the string depending on the build.


> And if it is - say you have a large number of extra 
> strings in a debug test build - then I'm sure you can find convenient 
> ways to handle that.  At a minimum, you'd probably not bother having 
> translated versions but fall back to English.
> 
>>
>> Another big problem is the Python preprocessor should understand C 
>> syntax; it shouldn't simply search for DisplayPrintf occurrences.
> 
> Why not?
> 
>> For example:
>>
>> /* DisplayPrintf(old_string, "This is an old message"); */
>> DisplayPrintf(new_string, "This is a new message");
>>
>> Of course, only one string is present in the source file, but it's not 
>> simple to extract it.
> 
> It's extremely simple to extract it.  Remember - /you/ make the rules. 
> If you don't want to bother skipping such commented-out lines, /you/ 
> pick a convenient way to do so.  For example, you would decide that the 
> opening comment token must be at the start of the white-space stripped 
> line :
> 
>      if line.strip().startswith("/*") :
>          return False
> 
>      if line.strip().startswith("//") :
>          return False

I see, other rules: don't use multi-line comments, comments that start 
in the middle of a line...


> (I've been talking about Python here, because that's the language I use 
> for such tools, and it's a very common choice.  If you are not familiar 
> with Python then you can obviously use any other language you like.)

Python is fine for me too :-)


> Or alternatively, have :
> 
>      #define XDisplayPrintf(...)
> 
> And now your commenting system becomes :
> 
>      XDisplayPrintf(old_string, "This is an old message");
>      DisplayPrintf(new_string, "This is a new message");
> 
> The "XDisplayPrintf" can be inside comments or conditionally uncompiled 
> code if you like.  (You do have to filter out XDisplayPrintf bits from 
> the earlier check for DisplayPrintf.)

We are always talking about rules. In this case, if you comment 
DisplayPrintf() put a leading X.


>> Thanks for the suggestion, the idea is great. However I'm not able to 
>> write a Python preprocessor that works well.
>>
> Sure you can.  You just have to redefine what you mean by "works well" 
> to suit what you can write :-)
> 
> 
> For my own use, I probably wouldn't even bother handling commented-out 
> strings.  I have used this kind of technique for message translation and 
> a variety of other situations.
> 
> 
> For more fun, you could switch to modern C++ and use user-defined 
> literals combined with constexpr template variables to put together a 
> system that is all within the one source language and is fully checked 
> at compile-time.  I'm not sure it would be clearer, however!