|
I have similar code I used to swap between dark and light theme css file, selected via a checkbox:
function switchCssMode() {
var chkMode = gebi("chkSwitchTheme");
if (chkMode.checked) {
document.querySelector("link[href='css/lite.css']").href = "css/dark.css";
}
else {
document.querySelector("link[href='css/dark.css']").href = "css/lite.css";
}
}
function gebi(el) {
return document.getElementById(el);
}
There are no solutions, only trade-offs. - Thomas Sowell
A day can really slip by when you're deliberately avoiding what you're supposed to do. - Calvin (Bill Watterson, Calvin & Hobbes)
|
|
|
|
|
For modern browsers, you could do that without any JavaScript. Set up the colours to use as CSS variables / properties[^] in the :root context; use those variables throughout the stylesheet; and use the :has selector[^] to switch between dark and light themes.
:root {
--background-color: white;
--text-color: black;
}
body:has(input[id='chkSwitchTheme']:checked) {
--background-color: black;
--text-color: white;
} Demo[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Interesting, and good to know. I'm way behind on modern CSS.
There are no solutions, only trade-offs. - Thomas Sowell
A day can really slip by when you're deliberately avoiding what you're supposed to do. - Calvin (Bill Watterson, Calvin & Hobbes)
|
|
|
|
|
I'm going through a book right now which is fantastic!
It's the best intro to OSes (how they are designed/programmed) I believe you'll ever read.
First of all, you can read it for FREE online (PDFs).
Operating Systems: Three Easy Pieces[^]
Have you read the book? It's fantastic because it starts out with simple code examples (in C) that teach one specific point at a time. Amazing!
If you've never read it, please skip all the (intro nonsense) & go right for the meat (to get an idea of how great the book is). Read this chapter[^] (be aware this will open the PDF in your browser) & I believe you'll be convinced how great the book is too.
And Now For the Weird & Wonderful
While examining the common_threads.h file for the 3rd example I stumbled upon these lines:
#ifdef __linux__
#include <semaphore.h>
#endif
I always wonder about strange things like that and in this case I thought, "Where is the __linux__ defined?"
I looked it up and discovered Gnu docs for the C PreCompiler (cpp exe)[^].
I tried the command they suggested:
$ cpp -dM
But when I did I could see that cpp was running but just had an empty string.
You actually have to point it at an exe and it'll pull out all the preprocessor commands. What!?!
$ cpp -dM ./threadx
When I ran that I saw a huge list of PreProcess commands. Huge!
I then ran it thru grep like this:
$ cpp -dM ./iox | grep -i linux
I saw the following!!
#define __linux 1
#define __gnu_linux__ 1
#define linux 1
#define __linux__ 1
So, I can see that over the years the convention to determine which OS the compiler is running on has changed.
Wow, things get messy as time goes on, don't they.
BONUS
Here's my favorite pre-processor define I found in the list.
#define __FLT128_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966F128
|
|
|
|
|
raddevus wrote: First of all, you can read it for FREE online (PDFs).
Operating Systems: Three Easy Pieces[^] When I open the link, it tells me that the PDF version is USD 10. I am not that curious about the book.
Religious freedom is the freedom to say that two plus two make five.
|
|
|
|
|
It opened for me, no messages. What browser are you using??
__________________
Lord, grant me the serenity to accept that there are some things I just can’t keep up with, the determination to keep up with the things I must keep up with, and the wisdom to find a good RSS feed from someone who keeps up with what I’d like to, but just don’t have the damn bandwidth to handle right now.
© 2009, Rex Hammock
|
|
|
|
|
I re-tried both links (the one to the book's main web site) and the one directly to the PDF & both worked for me.
Honestly the book is free so I hope you get a chance to take a look.
Someone else has confirmed that they links worked too.
Try the link to the main site and then try clicking the chapters in the grid. Maybe you'll be able to get it there.
|
|
|
|
|
I've got the dead tree version on my shelf. It is a very good book.
|
|
|
|
|
Dave Kreskowiak wrote: I've got the dead tree version on my shelf.
Very cool that you've read it.
I am really enjoying the code samples, because they :
1. touch on very basic but very clear topics
2. are self contained & don't require a lot to get them compiled.
3. Touch on important topics like file i/o, simple threading ideas, etc.
Really amazing book so far.
|
|
|
|
|
You can get a list of the compiler Manifest Defines via
echo | cc -dM -E -
In my case, I get 442 #defines for c++, and 380 for cc. Interestingly, the C compiler and the pre-processor produce exactly the same manifest defines.
Messing around with different C/C++ standards gets different values for different standard versions e.g -std=c89 or -std=gnu17 or -std=gnu++11 , so might be worth inspecting, to see how you can tell whether you're compiling for C89, C99, or if you're using clang (#define __clang__ ), etc
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
Very cool. Thanks for sharing
|
|
|
|
|
In LVGL you can set an image source to either be a file path or a structure.
lv_obj_t* ui_img = lv_img_create(ui_screen);
lv_img_dsc_t img_dsc;
img_dsc.header.always_zero = 0;
img_dsc.header.cf = LV_IMG_CF_RAW;
img_dsc.header.w = 800;
img_dsc.header.h = 480;
img_dsc.data_size = 800*480*LV_COLOR_DEPTH/8;
uint8_t *img_mem = (uint8_t*)ps_malloc(img_dsc.data_size);
img_dsc.data = img_mem;
memset(img_mem,0,img_dsc.data_size);
lv_img_set_src(ui_img,&img_dsc);
That's one option.
Here's another
lv_obj_t* ui_img = lv_img_create(ui_screen);
lv_img_set_src(ui_img,"A:/minou_480.jpg");
The lv_img_set_src() function takes a void* for the second argument and either accepts an instance of a lv_img_dsc_t structure or a string!
Worse, there's no lv_img_dsc_init() function to set the struct to a known state (with for example, a magic cookie in it that can be used to flag it as the structure rather than a string)
Ultimately here's how it checks:
if(u8_p[0] >= 0x20 && u8_p[0] <= 0x7F) where u8_p[0] is the first byte of the source argument.
This is in battle tested production code used in many many devices in the real world.
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
img_dsc.header.always_zero = 0; I have no idea of the layout of the struct, but for example if this is at the start, it would discriminate it from a valid string, would it not? Then the range check would separate empty strings from real ones.
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
It is at the beginning of the struct and it is used as a discriminator.
And yet it seems extremely accident prone, and I should add the docs do not clarify this.
At worst there should be, IMO, a function to initialize the structure.
At best, there should actually be two lv_img_set_src() functions - one for paths, and one for lv_img_dsc_t structs.
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
Given
#include <string.h>
void swap(char foo[10][20], int i1, int i2)
{
if(i1 != i2)
{
char buff[20];
strcpy(buff, foo[i1]);
strcpy(foo[i1], foo[i2]);
strcpy(foo[i2], buff);
}
} when compiling with any optimization level above -O0, gcc complains about the second strcpy, saying
warning: ‘strcpy’ accessing 1 byte at offsets [-4611686018427387904, 4611686018427387903] and [-4611686018427387904, 4611686018427387903] overlaps 1 byte at offset [-4611686018427387904, 199] [-Wrestrict] clang doesn't complain, even at -O3. I think what gcc is trying to tell me is that there is an issue when i1 == i2 , even though there's a test to not swap if i1 == i2 ! If I replace i1, i2 with integer values (eg. 1, 2) the warning goes away! Weird.
So far, the only way I've found to stop gcc from issuing a warning is to use memcpy instead of strcpy . Though both have restrict qualifiers to both arguments.
Or maybe I'm missing something?
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
GCC's warnings are often way too strict (and in some cases, outright wrong).
What do you get when you cross a joke with a rhetorical question?
The metaphorical solid rear-end expulsions have impacted the metaphorical motorized bladed rotating air movement mechanism.
Do questions with multiple question marks annoy you???
|
|
|
|
|
Has anyone ever seen a DB stored procedure where the queries weren't written using SQL, but rather using string concatenation to build the queries, and then submitting the queries with the EXEC command?
I can't think of a more horrifically error-prone way of coding in T-SQL. But I see this from a prominent maker of Warehouse Management Systems.
The first time I ever saw that, I was taken aback because I couldn't understand why anyone would do that. But then I saw that it was done so that the queries could be written to target different databases, tables, and columns depending upon the values of local variables.
So even something as weird and wonderful as that has a use. I wonder if any other RDMS has a more elegant solution?
EDIT:
I realize that the queries could still be written using regular T-SQL, but in a more structured way. But I see that this strange practice waas done for the sake of simpler, straight-line code.
The difficult we do right away...
...the impossible takes slightly longer.
modified 30-Jun-24 16:00pm.
|
|
|
|
|
Richard Andrew x64 wrote: So even something as weird and wonderful as that has a use.
i think you are being far too generous & kind.
It's a terrible idea for numerous reasons. I know little about DBs & DBMS but there are a couple that seem glaringly wrong to me:
1) one of the big ideas of a SP is that it is precompiled. This build-string-query then exec would insure that wouldn't be true. Think about that. A SP is precompiled & knows the "execution path" but in this case that would never be true, so it makes entire no sense that this "dynamic" thing would be a SP.
2) built in query analyzer of SQL Server would not know what the execution would be & this probably causes performance issues & the inability to know if it is slow or not since the query is built on the fly
I'm going to assume that some dev with little experience got this "genius" idea for how to create dynamic queries and no one ever looked at it because "it works".
SQL Server is an amazing feat of true Engineering and will fix things for you so the dev is probably getting really lucky.
Plus hardware is probably handling this.
And probably if the thing really got serious traffic it would bog down to nothing.
Just another Lucky Dev -- they're 92% of all Devs anyways.
"That's not coding, that's typing."
|
|
|
|
|
raddevus wrote: built in query analyzer of SQL Server would not know what the execution would be & this probably causes performance issues
Actually, the opposite is more likely to be true.
If you have a single query with lots of conditional filtering based on the parameters - eg: (@x Is Null Or T.X = @x) - you'll get one execution plan based on the first set of parameters used, which can be sub-optimal for a different set of parameters.
Having a different query for each set of applied filters can allow the query optimiser to select the "best" execution plan to satisfy that set of filters.
You may end up with some query execution plan cache bloat, and very complicated queries might take slightly longer for the first compilation. But you may still end up with better performance.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I have done that very rarely, such as when the name of a table isn't known. For instance, writing a procedure which will di a TRUNCATE TABLE but fallback to DELETE if that fails.
Definitely not as a normal course of action.
Further, I have not trusted the input, but rather checked it against the sys.objects or similar table to be sure it is a reasonable value before proceeding.
|
|
|
|
|
They are used where I work. They are usually performing a reporting task. Building it dynamically allows changes to the actual select clause, as well as sorts, groups etc. They are a nightmare to debug...
|
|
|
|
|
Shane0103 wrote: They are a nightmare to debug...
|
|
|
|
|
Leaving aside the performance issues noted by @raddevus, this is a terrible security risk. While the legitimate code uses this e.g. to query the client table, what is stopping malicious code from querying the credit card table?
(Yes, I know that credit card Nos. should not be stored like that, but many databases do in order to provide a rolling subscription to their site.)
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
Richard Andrew x64 wrote: submitting the queries with the EXEC command?
For SQL Server, they should at least be using sp_executesql[^], and passing the parameters as parameters rather than concatenating them into the string.
In some rare situations, it may be worth doing this - for example, if your procedure has a lot of optional filters, building a query that only specifies the ones being used will allow the DBMS to select the most appropriate execution plan for the query. If you put them all in the same query - eg: (@x Is Null Or T.X = @x) - then the execution plan will be selected based on the first set of filters provided, which may be sub-optimal for a different set of filters.
But passing the string to EXEC rather than sp_executesql means they're introducing a SQL Injection[^] vulnerability into the code, which far outweighs any performance benefits.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
This type of crap used to be all the rage in the late 90s/early 00s. I'm pleased to say I haven't seen abominations like this in the last 20 years or so.
|
|
|
|