Monday 31 July 2023

More on attachable scopes

I previously called these braceless scopes, and ended up writing more in discussion with Jens that I did on my blog - but now I come to needed it, and further back in time than I expected I find this gem carbuncle below.

(By attachable-scope I mean a braced-scope that get's attached to the expansion of previous macro, perhaps as the body of a function definition, or a for loop, or even an else clause).

Hah! Your example there was the clue to propagating breaks.

Thanks to your tip on the gcc equivalence using BREAKOUT and BREAKIN I can contrive a bunch of macros that expand to this:

1
2
3
4
5
6
7
8
9
main() {
  int a;
  for (a=1; a<=2; a++) {
    printf("Main context a=%d\n", a);
 
    if (0) { break_line_6: break ; } else for (int o = 0; o >=0; ) if (o == 1) { printf("Detected break\n"); goto break_line_6; } else
      for (int i=0; !o && (o=1), i==0; o=-1, i=-1 ) { printf("Inner context\n"); break; }
  }
}

it does not require gcc-isms – sadly the C style is lacking but it functions as desired

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define GENSYM_CONCAT(name, salt) name ## salt
#define GENSYM2(name, salt) GENSYM_CONCAT(name, salt)
#define GENSYM(name) GENSYM2(name, __LINE__)
 
#define _BRACELESS_SCOPE(__label__, _declaration_) \
    if (0) { __label__: break ; } else for (int _o = 0; _o >=0; ) if (_o == 1) goto __label__; else \
      for (_declaration_; !_o && (_o=1); _o=-1) \
 
#define BRACELESS_SCOPE(_declaration_) _BRACELESS_SCOPE(GENSYM(break_line_) , _declaration_)
 
main() {
  int a;
  for (a=1; a<=2; a++) {
    printf("Main context a=%d\n", a);
 
    BRACELESS_SCOPE(char* message="hello") { printf("Inner context: %s\n", message); break; }
  }
}

The main deficiency is that a single macro cannot cannot ultimately expand to more than one of these constructs, nor can it be used twice on the same line, or the generated labels will conflict. __COUNTER__ where supported could be passed instead of __LINE__. I guess this is something you already addressed in P99 if I look again…

It's just what I needed as I convert a narrating block logger (that annotates progress through a block scope) from gcc-isms to clang-isms.


It originally expanded to a nested function forward definition, a setup block, a nested function invocation, a clean-up block, followed by a the first half of a nested function definition which sticks onto a following scope that becomes the body.


clang won't take nested functions (even without arguments) and clang's objective-C style blocks is no help as it can't access the variables in the calling scope as gcc does.


Knowing that I've passed this way before I look at this and this, before finally recovering the carbuncle above which is to be pressed into service.

Saturday 8 July 2023

Fixing Linuxmint Audio on HP Envy x360

 Install Linuxmint 21.1 with secure boot turned off and wifi turned off

On first boot turn on secure boot

Join wifi, get all updates

sudo apt install linux-oem-22.04c [https://wiki.ubuntu.com/Kernel/OEMKernel]

git clone https://github.com/xoocoon/hp-15-ew0xxx-snd-fix # see https://h30434.www3.hp.com/t5/Notebook-Audio/No-sound-from-internal-speakers-using-Linux/m-p/8678403/highlight/true#M121500

cat /sys/class/sound/hwC0D0/subsystem_id

0x103c8a28

edit setup_snd-hda-codec-realtek.sh to remove this line
+  SND_PCI_QUIRK(0x103c, 0x8a29, "HP Envy x360 15-ew0xxx", ALC287_FIXUP_CS35L41_I2C_2),
and add this line
+   SND_PCI_QUIRK(0x103c, 0x8a28, "HP ENVY x360 2-in-1 Laptop", ALC287_FIXUP_CS35L41_I2C_2),

bash setup_snd-hda-scodec-cs35l41.sh
bash setup_snd-hda-codec-realtek.sh