zaterdag 16 december 2023

Compiler: See compiler output

Go to https://godbolt.org/ and enter the following C++ code:

#include <stdio.h>
class MyClass {
  public:
    void* prop0;
    int prop1;
    void test() { prop1++; }
    MyClass() {
        prop0 = NULL;
        prop1 = 0;
    }
};
void meuk() {
    MyClass c;
    c.test();
    int i = 100;
}

https://www.geeksforgeeks.org/peephole-optimization-in-compiler-design

https://www.geeksforgeeks.org/loop-optimization-in-compiler-design

https://www.geeksforgeeks.org/symbol-table-compiler

vrijdag 15 december 2023

Postgresql: Number of sql statements per second

Check if the pg_stat_statements extension is active in Postgresql:

select * from pg_extension;

If not, then:
  execute in SQL:   create extension pg_stat_statements;
  in Postgresql.conf modify:  shared_preload_libraries = 'pg_stat_statements'

Restart server, and now you can see the sql statements per second:

-- queries per second
with
 t1 as (select sum(calls) n from pg_stat_statements),
 t2 as (select sum(calls) n from pg_stat_statements , pg_sleep(1))
select
 t2.n-t1.n the_num_of_queries_per_second
from
 t1,t2;
 
-- Top time consuming queries
select userid::regrole, dbid, query ,calls, 
(total_plan_time + total_exec_time) / 1000 as total_time_seconds, 
(min_plan_time + min_exec_time) / 1000 as min_time_seconds, 
(max_plan_time + max_exec_time) / 1000 as max_time_seconds, 
(mean_plan_time + mean_exec_time) / 1000 as mean_time_seconds
from pg_stat_statements
order by (mean_plan_time + mean_exec_time) desc
limit 10;
   
-- queries having high i/o activity
select userid::regrole, dbid, query,queryid,
   (mean_plan_time + mean_exec_time)/1000 as mean_time_seconds 
from pg_stat_statements
order by (blk_read_time+blk_write_time) desc
limit 10;

-- queries with high memory usage
select userid::regrole, dbid, queryid,query  from pg_stat_statements 
order by (shared_blks_hit+shared_blks_dirtied) desc
limit 10;

-- reset the stats
select pg_stat_statements_reset();

-- number of queries running at this moment
select * from pg_stat_activity;

-- number of queries running for more than 30 seconds
select * from pg_stat_activity
where (now() - query_start) > interval '30 seconds';

-- What is the replication server?
select * from pg_stat_replication;

-- The Usertables having a tablescan:
select relname, seq_scan from pg_stat_user_tables order by seq_scan desc;

-- Put the tablescan values in a separate tmp table for comparison at a later time
create table stats_snapshot_0938 as select relname, seq_scan from pg_stat_user_tables;
-- select * from stats_snapshot_0938;
-- drop table stats_snapshot_0938;

-- Compare the values with the old values...
select stats_now.relname, (stats_now.seq_scan - stats_old.seq_scan) difference
from pg_stat_user_tables stats_now
join stats_snapshot_0938 stats_old on stats_now.relname = stats_old.relname
order by difference desc;

woensdag 6 december 2023

C64: using $D000-$DFFF for a custom font

A good location for a custom C64 font is at location $D000-$DFFF.

> But wait! Are the VIC-II registers not mapped at $D000?

Yes, that is right, but it can be switched with the character ROM by clearing bit 2 on location $0001.

> But wait! Then you have character ROM at that location. How can you set a custom font?

When the font ROM is switched into area $D000-$DFFF and the CPU stores bytes at these locations between $D000-$DFFF, they will not be stored into the ROM but to the underlying RAM. So the CPU reads from ROM and writes to RAM in that situation.

When the I/O is activated into area $D000-$DFFF, the VIC-II registers are used in this area and the CPU will read and write to the VIC-II registers.

So, it is only possible to store values into the RAM area $D000-$DFFF when the font ROM is switched in. The CPU can never read a value from this RAM area. So what is the use? Well, the VIC-II will see the RAM, so you can put a custom charset at this location, or other VIC-II data. 

When the font ROM is switched into area $D000-$DFFF, only the CPU will see the ROM, not the VIC-II. The only locations where the VIC-II chip will see the character ROM is at the locations $1000-$1FFF and $9000-$9FFF. These are the so-called Shadow Font area's. Let this sink in, before you get confused.

We can conclude that the locations $1000-$1FFF and $9000-$9FFF are highly suitable for code, because the VIC-II will only see the character ROM at these locations and the CPU will only see the RAM.

The $D000-$DFFF RAM area can only contain VIC-II data, because the bytes cannot be loaded by the CPU. This makes this area suitable for a custom font. If the I/O is activated in this area, the CPU will return the VIC-II register values and if the character ROM is activated in this area, the CPU will return the character ROM bytes. So, you can only store values in this RAM area when the ROM is switched in, the CPU can never read values from this RAM. A custom font is static in most cases, so suitable for this area. However if you want 'rotating' characters, this area is not suitable.



maandag 4 december 2023

C64: Test kernal version

?peek(65408)

-> 170 = kernal version 1   (poke 1024,81 results in a white ball)
-> 0 = kernal version 2   (poke 1024,81 results in a blue ball which cannot be seen)
-> 3 = kernal version 3 (poke 1024, 81 results in a light-blue ball which is visible on screen)
Kernal version 3 is the one everyone uses. 

vlang: see the generated C output

To see the generated C output of the vlang compiler:
v -o - test.v > test.c

zondag 3 december 2023

donderdag 23 november 2023

vrijdag 17 november 2023

FASM: using printf easily in x86-64

format pe64 console
entry start
include 'win64a.inc'

section '.text' code readable executable
start:
  push	rbp  ; with this action, the rsp is 16 byte aligned. Needed for fastcall requirement.
  cinvoke printf, message, 42
  cinvoke getch
  pop   rbp
  ret

section '.idata' import data readable writeable
  library kernel32, 'kernel32.dll', \
          msvcrt, 'msvcrt.dll'
  import  msvcrt, \
          printf, 'printf', \
          getch, '_getch'
  include 'api\kernel32.inc'

section '.data' data readable writeable
message	db 'Hello World! %i',0

FASM: when to use invoke or cinvoke

  • call is a native CPU instruction in x86 Intel syntax
  • invoke is a macro that uses pascal calling convention and does an indirect call (i.e. it uses "call [...]")
  • stdcall is a macro that uses pascal calling convention and does a direct call (i.e. it uses "call ...")
  • cinvoke is a macro that uses C-call convention and and does an indirect call (i.e. it uses "call [...]")
  • ccall is a macro that uses C-call convention and and does a direct call (i.e. it uses "call ...")

  • Use call if you need just the native CPU instruction
  • Use invoke to call all Windows APIs (except wsprintf) and all DLL functions that use pascal convention
  • Use stdcall to call functions you have defined with the proc macro
  • Use cinvoke to call the Windows wsprintf API and all DLL functions that use C-call convention (e.g. MSVCRT)
  • Use ccall to call functions you have statically linked that use the C-call convention and functions you have defined with "proc <func> c ..."

How to you recognize in which calling convention a function is created?
If the symbol begins with a _ but has no @, then it's __cdecl. If it begins with _ and has a @ it's __stdcall. If it begins with @ and has another @, it's __fastcall.

64 bits:
On 64 bits, all calls are fastcall, so cinvoke is the same as invoke.

Using SDL2 in DLL causes crash and werfault.exe at Process exit

SDL2 has a serious issue with closing the load-time dynamic loaded SDL2.DLL on win32.

So, I have a DLL called ground.dll which uses SDL2 by using load-time DLL loading. This load-time linking is not fully dynamic, but still dynamic. This ground.dll is created with Visual Studio C++. In my main FASM generated assembly program, I load-time load this ground.dll. The is no problem loading the DLL, but ProcessExit gets an crash error. It causes an werfault.exe (Windows Error Reporting).
All this happens without calling a single SDL2 function yet.
So, I tested if fully dynamic loading of the ground.dll fixes the issue, using LoadLibrary and FreeLibrary. This did not solve the issue.

I was very suprised to find this bug, because SDL2 is a much used library.

What might be the problem? Is the FASM assembled main program not correctly closing the SDL2? Perhaps... I created a C program which load-time loads the ground.dll and that program does not crash. However, the fact that even fully dynamic loading and freeing the library also causes the exit-crash, without calling a SDL2 function whatsoever, makes me think I cannot put the blame on FASM. 

At this moment, I worked around the problem. I created a Visual Studio C++ program which loads the SDL2.dll. That program does not crash.

donderdag 16 november 2023

Update password with NuGet

dotnet nuget update source <repository name> -u <username without domain> -p <password> 

The nuget config is located in: c:\Users\<username>\AppData\Roaming\NuGet\NuGet.Config"

dinsdag 7 november 2023

Some common Visual Studio C++ errors and solutions in the settings

Unresolved external symbol _RTC_InitBase
Unresolved external symbol _RTC_Shutdown
-> Settings/C/C++/Code Generation/Basic Runtime Checks => Default

Unresolved external symbol __chkstk
-> Settings/C/C++/Command Line/Additional Options: /Gs0x100000
-> Settings/Linker/System/Stack Reserve Size => 0x100000
-> Settings/Linker/System/Stack Commit Size => 0x100000

Unresolved external symbol __imp___acrt_iob_func
Unresolved external symbol __imp___stdio_common_vfprintf
-> #define _NO_CRT_STDIO_INLINE
-> #include <stdio.h>

Unresolved external symbol _fltused
-> insert in the top of the code:   extern "C" int _fltused = 0;

Unresolved external symbol __security_check_cookie
-> Settings/C/C++/Code Generation/Security Check => Disable Security Check (/GS-) 

Visual Studio quirk:
Your own libraries should be on front of the Library Directories: So, $(SolutionDir)extern;$(SolutionDir)extern\sdl2\lib; $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)

Do this with all your directories, libraries. Put them in front of the rest.

If you "ignore all default libraries" in the link input. You must then change the main function in:

int mainCRTStartup(void)   --> console subsystem
int WINAPI WinMainCRTStartup(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmd, int nCmdShow)  --> windows subsystem

If you want to copy your compiled .exe file, create a custom post-build event and fill in the following commandline: copy /y "$(OutDir)Ground.exe" "$(ProjectDir)..\..\GroundOutput\Ground.exe"

Ofcourse, you can also set the outdir in de General properties of the project.

maandag 6 november 2023

unresolved external symbol "void * __cdecl operator new

When you do not use the default libraries with Visual Studio C++ you can come far with just linking to MSVCRT. However, you run into trouble when using C++ and classes. These use the new and delete operators.

According to the Internet it can be solved by just overloading the new and delete operators.

void* operator new(size_t size) { return malloc(size); }
void* operator new[](size_t size) { return malloc(size); }
void operator delete(void* what) { free(what); }
void operator delete[](void* what) { free(what); }

However, this did not work. I still got a error on the delete operator. So, what I did was transform the code:

GuiThread* guiThread = new GuiThread();
Became:
GuiThread* guiThread = (GuiThread*)calloc(1, sizeof(GuiThread));

guiThread->threadHandle = CreateThread(NULL, 0, GuiThread::StaticThreadStart, (void*)guiThread, 0, &guiThread->threadID);

delete guiThread;
Became:
free(guiThread);

Which process is using a port in Windows?

Start the  "Resource Monitor" on Windows 10/11 and go to the Network Tab. After that expand the Listening Ports Panel to see the processes and the ports they are using.

You can also use TCPView from the sysinternals suite. With the TCPView you can also terminate the process that is using the port. However, usually it is a service, so you might need extra effort to discover which service allocates the port.

zaterdag 4 november 2023

In 32-bit Totalcommander, you see 32-bit DLL's in System32

The windows\system32 folder contains some frequently used DLL's.
However, remember that when you use a 32-bit Totalcommander, the system32 folder contains 32-bit DLL's.

zaterdag 28 oktober 2023

C64: Border removal

// use the kickassembler to assemble this code
:BasicUpstart2(Main)	
.pc = * "Code Segment"
Main:
	sei
	lda #<Interrupt
	sta $0314
	lda #>Interrupt
	sta $0315
	lda #$f9
	sta $d012
	sta $dc0e
	lda #$01
	sta $d019
	sta $d01a
	lda $d011
	and #%01111111
	sta $d011
	cli
	rts
Interrupt:
	lda #$01
	sta $d019
	lda $d011
	and #$f7
	sta $d011
Loop:
	lda $d012
	bne Loop
	lda $d011
	and #$7f
	ora #$08
	sta $d011
	jmp $ea31

C64: Smoothscroller in an interrupt!

//use kickassembler to assemble
:BasicUpstart2(Main)	
.pc = * "Code Segment"
	
Main:
	sei
	lda $d011
	and #%01111111
	sta $d011	// clear top bit of raster register
	lda #$7f
	sta $d012	// raster register
	
	lda #<Interrupt
	sta $0314
	lda #>Interrupt
	sta $0315
	
	lda #$01	// current raster count = wanted position. We handle the interrupt.
	sta $d019	// interrupt status byte
	sta $d01a	// interrupt enable byte
	
	lda #$7f 
	sta $dc0d	// disable cia 1
	sta $dd0d   // disable cia 2
	
	ldx #39
!loop:
	lda #' '
	sta $400+$190-40, x	// regel erboven vullen met spaties
	sta $400+$190, x	// scrollregel zelf vullen met spaties
	sta $400+$190+40, x  	// regel eronder vullen met spaties
	lda #1
	sta $d800+$190,x	// kleuren zetten in de scrollregel
	dex
	bpl !loop-
	
	lda $d020
	sta old_colors
	lda $d021
	sta old_colors+1
	
	lda $dc0d	// acknowledge pending interrupts from CIA-1
	lda $dd0d	// acknowledge pending interrupts from CIA-2
	
	cli
	rts
	
	
Interrupt:
	ldx #3		// vertraging om de zwarte kleur niet midden in je scherm te krijgen
!loop:
	dex
	bne !loop-
	
	lda #0
	sta $d020
	sta $d021
	lda scrollposition
	sta $d016
	
!loop:
	lda $d012
	cmp #$8c	// wacht totdat het raster een aantal regels verder is.
	bne !loop-
	
	lda #$08	// scrolling weer uitzetten
	sta $d016
	
	ldx	#8	// vertraging om de zwarte kleur niet midden in je scherm te krijgen
!loop:
	dex
	bne !loop-
	
	lda old_colors
	sta $d020
	lda old_colors+1
	sta $d021
	
	dec scrollposition
	bpl no_scrollposition_reset
	
	lda #7		// de volgende scrollpositie wordt weer ver naar rechts
	sta scrollposition
	
	ldx #0
!loop:
	lda $591, x	// copy line to the left
	sta $590, x
	inx
	cpx #39
	bne !loop-	
	
	ldx scrolltext_needle	// scrolltext resetten?
	lda scrolltext, x
	cmp #0
	bne no_scrolltext_reset
	lda #0
	sta scrolltext_needle
	lda scrolltext
no_scrolltext_reset:
	sta $400+$190+39
	inc scrolltext_needle	
	
no_scrollposition_reset:
	lda #$01    	// current raster count = wanted position. We handle the interrupt.
	sta $d019	// interrupt status byte.  asl $d019 werkt ook, maar waarom weet ik niet.
	jmp $ea31


scrollposition:
	.byte 0
	
scrolltext:
	.text "jawel ouwe, een smoothscroller op de commodore 64 in een interrupt!                     "
	.byte 0

scrolltext_needle:
	.byte 0

old_colors:
	.byte 0,0

vrijdag 27 oktober 2023

C64: Border removal via basic

10 f=49152
20 read a
30 if a=255 then sys 49152:goto 170
40 poke f,a
50 f=f+1
60 goto 20
70 :
80 data 120,169,34,141,20,3,169,192
90 data 141,21,3,169,249,141,18,208
100 data 141,14,220,169,1,141,25,208
110 data 141,26,208,169,27,141,17,208
120 data 88,96,169,1,141,25,208
130 data 173,17,208,41,247,141
140 data 17,208,173,18,208,208,251,173
150 data 17,208,41,127,9,8,141,17
160 data 208,76,49,234,255
170 for x=832 to 832+63:pokex,255:next
180 poke 2040,13
190 v=53248:poke v+21,1:poke v+1,5
200 poke v+0,100:poke53280,0:poke53281,0
210 poke 646,rnd(1)*16:print "rene   ";
220 goto 210

By the way: the VICE commodore 64 emulator is very good!
You can insert lines in VICE by using alt-insert.
With alt-delete you copy the C64 screen in the clipboard.
Reset: sys64738
Cool effect:
0 print chr$(205.5+rnd(1));:goto

https://www.youtube.com/watch?v=caW7aiasrvs

Close a user connection to a database in Postgresql

select * from pg_catalog.pg_stat_activity;

select pg_terminate_backend(pid)
from pg_catalog.pg_stat_activity
where pid = [nr found in column pid from previous query]

zondag 15 oktober 2023

Create a Visual Studio C++ LIB file from a C file

Start the x64 Native Tools Command Prompt for VS 2022
cl.exe stb_image.c
lib.exe stb_image.obj

... and the stb_image.lib is generated...

donderdag 12 oktober 2023

Dependencies of a .dll

Do you want to see the load time dependencies of a random .dll?
The best free tool is: https://github.com/lucasg/Dependencies

Create a Visual Studio C++ .lib file from a .dll

 Start the x64 Native Tools Command Prompt for VS 2022:
> dumpbin.exe /EXPORTS SDL2.dll > SDL2.exports
> Copy only the names with the 'Alt'-key column selection in Notepad++. Paste the names list in a new file named SDL2.def and write EXPORTS as the first line.
> So the file contents of the SDL2.def is:
EXPORTS
SDL_AddEventWatch
SDL_AddHintCallback
SDL_AddTimer
...

> lib.exe /def:SDL2.def /machine:x64 /out:SDL2.lib

dinsdag 3 oktober 2023

Nexus E401 unable to authenticate problem

npm login --scope=@mycorp --registry=https://registry.mycorp.com

Check in the .npmrc in your user folder if the token is acurate. Remove the tokens if unsure.

donderdag 31 augustus 2023

WIN32 programming is not great.

Windows is a big operating system which is kept evergreen by windows updates. So, I would expect that the WIN32 API has a lot of strong libraries. For instance, a strong and easy to access JSON library is the least I expected. 

No. That is not available. WIN32 is only an operating system API.

It is a missed chance to say the least....

zondag 27 augustus 2023

FASM x86-64 example. Print string. Allocate memory.

format pe64 console
entry start

include 'win64a.inc'

section '.text' code readable executable
start:
  push	rbp  ; make stack 16 byte aligned. Needed for fastcall requirement.
  sub	rsp, 10*8  ; reserve stack for API use (for instance WriteFile needs 5 parameters)
  
  invoke GetStdHandle, STD_OUTPUT_HANDLE
  mov	[GetStdHandle_outputhandle], rax

  invoke GetProcessHeap
  mov	[processHeapHandle], rax

  invoke HeapAlloc, [processHeapHandle], HEAP_ZERO_MEMORY, 100*1024
  mov	[variableSpacePointer], rax

  invoke WriteFile, [GetStdHandle_outputhandle], str0, [str0Length], ResultBytesWritten, NULL
  invoke HeapFree, [processHeapHandle], 0, [variableSpacePointer]

  pop   rbp  ; 16-byte alignment lost here...
  invoke ExitProcess, 0


section '.idata' import data readable writeable
  library kernel32,'KERNEL32.DLL'
  include 'api\kernel32.inc'


section '.data' data readable writeable
processHeapHandle   dq  0
variableSpacePointer dq 0
GetStdHandle_outputhandle dq 0
ResultBytesWritten dd 0
str0 db 'Hello World!',0
str0Length dq $-str0

zondag 16 juli 2023

Executable formaten .com, .exe en PE(32+)

Als je het DOS tijdperk hebt meegemaakt, dan heb je 3 executable formats voorbij zien komen, namelijk:

.com -> maximaal 64 kb groot en bevatte geen header informatie.
.exe -> DOS MZ executables. Vanaf DOS 2.0.
.exe -> PE (PE32+). Vanaf Windows NT 3.1 is dit formaat gebruikt. Windows 95 en verder ondersteunde dit formaat ook.

https://en.wikipedia.org/wiki/COM_file
https://en.wikipedia.org/wiki/DOS_MZ_executable
https://en.wikipedia.org/wiki/Portable_Executable

De 64-bit variant van PE heet PE32+, wat een verwarrende naam is.
Verwarrend is ook de x64 fastcall calling convention, die een stack eist die 16 bytes aligned is.
https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention

Als je vreemde sections in FASM gedefinieerd ziet worden, zoals .idata, dan is dat vanwege het PE formaat.
https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#the-idata-section

Learning x86-64 assembly: https://gpfault.net/posts/asm-tut-0.txt.html
https://sonictk.github.io/asm_tutorial/#windows:thewindowtothehardware/themicrosoftx64callingconvention

https://github.com/justinstenning/SharpDisasm 

https://net.cs.uni-bonn.de/fileadmin/user_upload/plohmann/x86_opcode_structure_and_instruction_overview.pdf

donderdag 8 juni 2023

PostgreSQL: show UTC time in local time

PostgreSQL: show UTC time in local time

select (t.datecolumn at time zone 'UTC') from table t;

dinsdag 16 mei 2023

Update to Angular 16 (or other new Angular)

ng update

... and follow the instructions listed.

npm uninstall -g @angular/cli
npm install -g @angular/cli
or
npm install -g @angular/cli@17.2
See https://update.angular.io/?v=16.0-17.0

npm cache clean --force

ng update   (gives information on how to update)

Fasm "Hello World!" in x64.

format pe64 console
entry start

STD_OUTPUT_HANDLE       = -11

section '.text' code readable executable

start:
        sub     rsp,8*7         ; reserve stack for API use and make stack dqword aligned
        mov     rcx, STD_OUTPUT_HANDLE
        call    [GetStdHandle]
        mov     rcx,rax
        lea     rdx,[message]
        mov     r8d,message_length
        lea     r9,[rsp+4*8]
        mov     qword[rsp+4*8],0
        call    [WriteFile]
        mov     ecx,eax
        call    [ExitProcess]

section '.data' data readable writeable

message         db 'Hello World!',0
message_length  = $ - message

section '.idata' import data readable writeable

        dd      0,0,0,RVA kernel_name,RVA kernel_table
        dd      0,0,0,0,0

kernel_table:
        ExitProcess     dq RVA _ExitProcess
        GetStdHandle    dq RVA _GetStdHandle
        WriteFile       dq RVA _WriteFile
                        dq 0

kernel_name     db 'KERNEL32.DLL',0
user_name       db 'USER32.DLL',0

_ExitProcess    db 0,0,'ExitProcess',0
_GetStdHandle   db 0,0,'GetStdHandle',0
_WriteFile      db 0,0,'WriteFile',0  

maandag 15 mei 2023

Add authentication token to .npmrc

When you need to authenticate to a Nexus repository, than you must add an authentication token to .npmrc
Do it this way:
npm login --auth-type=legacy

However, if you have several repositories, do it this way
Doe dat als volgt:
npm login --scope=@scopeprefix --auth-type=legacy

Login, and the authentication token will be added to your .npmrc which is located in your user directory.

Also do:
npm adduser --auth-type=legacy

donderdag 11 mei 2023

woensdag 10 mei 2023

Blink with css

 .alerts-border {
    animation: blink 1s;
    animation-iteration-count: 10;
}

@keyframes blink { 50% { background-color: red; }  }
<div class="alerts-border" style="height:40px;width:40px">

</div>

zondag 23 april 2023

Small .exe for Hello World example in C

#include <windows.h>
#include <string.h>

int mainCRTStartup(void) {

    char str[] = "Hello World!";

    DWORD dummy;
    WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), (const void*)str, strlen(str), &dummy, NULL);

    ExitProcess(0);
}


In Visual Studio 2022:
> Go to Release Mode.
> Go to the properties of the project
> Go to C/C++ / Code Generation / Security Check : Disable Security Check (GS-)
> Go to C/C++ / Ouput Files / Assembler Output : Assembly; Machine Code and Source
> Go to Linker / Input / Ignore All Default Libraries : Yes (/NODEFAULTLIB)

The resulting .exe will be 3584 bytes.

maandag 17 april 2023

Lightweight Java installation on Windows

 Go to https://www.oracle.com/nl/java/technologies/downloads/ to download the JDK 2.0 x64 Compressed Archive

Unzip it in c:\prg\java\jdk20

Go to "This PC" and click "Advanced System Settings". Go to "Environment Variables..."

In System variables, create a variable JAVA_HOME with content C:\prg\java\jdk-20

In System variables, create a variable CLASSPATH with content C:\prg\java\antlr\antlr-4.12.0-complete.jar;%CLASSPATH%

In System variables edit the Path variable and add C:\prg\java\jdk-20\bin

vrijdag 31 maart 2023

Latlon afstand per eenheid berekenen

import geopy.distance

coords_1 = (53.219379, 6.575347)
coords_2 = (53.219396, 6.575226)

print(geopy.distance.geodesic(coords_1, coords_2).km)

Ouput: 0,008300847602651781 km


Distance in eenheid berekenen:
        public double DistanceBetween(Vector v1, Vector v2)
        {
            Vector diff = v2 - v1;

            var distance = Math.Sqrt((diff.Longitude * diff.Longitude) + (diff.Latitude * diff.Latitude));
            return distance;
        }

Ouput: 0,0001221883791528447 eenheid

Dus 1 eenheid = 67,93483685 km.
Dus 0,001 eenheid per seconde = 67,93483685 m/s * 60 * 60 = 245 km/h
1 km/h = 0,001 / 245 = 0,0000040888856
100 km/h = 0,00040888856

maandag 20 maart 2023

Postgresql version and extensions that are installed

To see the PostgreSQL version number:
select version();

To see which extensions are present:
select * from pg_extension;

zaterdag 4 maart 2023

rxjs

Rxjs is a great library for declarative programming. The main advantage of declarative programming, in my opinion, is the fact that related code is together glued in one place.

For instance, I wanted to buffer incoming messages and have them emitted every second. That was easy in Rxjs.

Angular:

public originalStream$: Subject<SpecificObj> = new Subject<SpecificObj>();
public bufferedStream$: Observable<SpecificObj[]> = this.originalStream$.pipe(bufferTime(500), filter(arr => arr.length >0));

in the init:
this.bufferedStream$.subscribe((values: SpecificObj[]) => {
for (let newObj of values) {
}
});
in the code: originalStream$.next(obj); Example pure javascript: let container = $(document.body);
function log(val) {
container.append(`<div>${val}</div>`);
}

const { of, interval } = rxjs;

//const stream = of(1,2,3,4);
const stream = interval(1000);

stream.subscribe(val => log(val));

https://dev.to/hssanbzlm/building-autocomplete-feature-rxjs-with-vanilla-javascript-c7
https://rxjs.dev/guide/overview
https://eliteionic.com/tutorials/imperative-vs-declarative-programming-with-rxjs-search-filter/#a-declarative-search-filter
https://lodash.com/
https://johnlindquist.com/rxjs-pipes/

zondag 19 februari 2023

masm x64 console printf example. DO NOT USE!

;Let's make a simple "Hello World" in x86-64 assembly:

includelib ucrt.lib
includelib legacy_stdio_definitions.lib
includelib libcmt.lib

extrn printf: PROC

.data
msg db 'Hello World!', 0dh, 0ah, 0

.code
main proc
  push	rbp
  mov	rbp, rsp
  
  lea	rcx, msg
  call	printf 

  mov	rsp, rbp
  pop	rbp
  ret  
main endp

End

; compile with: ml64.exe hello_world.asm /link /subsystem:console
; It results in an exe of 123904 bytes. It's clear that using the Microsoft toolchain results in byte obesity.
; I guess this is the reason that assemblers like FASM were created.
; MASM also has no interaction with the PE-format; the .exe that is generated when assembling and linking.
; So, DO NOT USE this example or MASM for small size executables, but a "Hello World" created with FASM that will be posted later.

zondag 12 februari 2023

Historie van C

Als je in 1985 bent begonnen met hobby-computers, dan weet je hoe weinig geheugen de computers toen hadden. Een buurjongen had een ZX-81 met 1024 "laden", dat is 1024 bytes. Die verkochten ze en kochten een Commodore-64. Die C64 kochten wij ook. Spelletjes kopiëren ging via cassette bandjes (TDK D90), waarbij je niet teveel mocht bewegen vanwege load-errors.

Anyway, in 1985 bestond de programmeertaal C al 12 jaar, want die kwam in 1973 uit.

De context van de programmeertaal C is dus weinig geheugen. De voorganger van C, dat is de programmeertaal B, die ook binnen Bell Labs is gemaakt door Ken Thompson en Dennis Ritchie, had maar 1 datatype, namelijk de natuurlijke grootte van één geheugen element (ook wel "woord" genoemd). In de nieuwe PDP-11 mini-computer was de woord grootte echter 16 bits. Aangezien ASCII (7 bits) populair werd en de PDP-11 daarvoor ondersteuning had, waren er meerdere datatypes nodig. Samen met andere verbeteringen werd dat C.

Het geheugen was zo krap, dat vrijwel alles via tape of disk verliep. Dat zie je ook aan de eerste versie van de C compiler van Ritchie. De transformatie van de C code naar assembly verliep via variabelen en kleine arrays die in het geheugen pasten. Structs of geheugen allocatie via malloc zie je nergens in de eerste C compiler. Ook in het C handboek zie je dezelfde opzet: kleine buffers en verder alles via stdin en stdout.

C heeft van die vervelende header files omdat vroeger de systemen veel te traag waren om alle code steeds te compileren. Je moest een manier hebben om te bepalen welke functies er allemaal in een gecompileerde, relocatable objectfile zaten die je kon linken. Iedere sourcefile moest apart gecompileerd kunnen worden naar een objectfile.

Waarom gebruikte men überhaupt C als compilatie lang duurde en de gegenereerde code traag was? Nou, omdat grote bedrijven formules duidelijk en goed uitgevoerd wilde hebben. C code is veel duidelijker en minder foutgevoelig dan assembly.

Mijn eerste kennismaking met C was via het Amiga boek "C für Einsteiger" van uitg. Data Becker. Compilatie op de Amiga 500 met Aztec C duurde meerdere minuten vanwege het wisselen van diskettes. Verder was de gegenereerde code traag ten opzichte van 68000 assembly. De taal was daarom niet populair bij mij en vele andere ontwikkelaars. Assembler was de beste keuze voor demo's en spellen. De reden om überhaupt met C bezig te zijn op de Amiga was het feit dat de Amiga GUI genaamd Intuition in C was ontwikkeld.
Een gecompileerde taal werd pas populair met de geïntegreerde ontwikkelomgeving Turbo Pascal van Borland voor MS-DOS. In 1987 werd Turbo C uitgebracht.

Als je deze historie van de programmeertaal C kent, dan begrijp je waarom unicode strings, async/await, multicore programming, virtual classes en memory management niet voorkomen in de taal. Over memory management gesproken: vroeger had je die niet. Op de C64, Amiga, IBM PC met MS-DOS kon je op ieder geheugenadres data neerzetten en uitvoeren. Die opzet gaf trouwens wel vastlopers als de processor de weg kwijtraakte.

De oorspronkelijke taal C is best mooi. Het monster C++ is pas ontstaan in de loop van de tijd na talloze uitbreidingen. Toen ik in 1996 voor school een WIN32 programma met event-loop maakte was C++ al een draak die memoryleaks in de hand werkte.

Als je tegenwoordig 16 gigabyte geheugen, een multicore CPU en textfiles in UTF-8 hebt, dan is C geen passende match meer. Gebruik liever C#, Rust of een andere nieuwe taal. De oorspronkelijke makers van C, Ken Thompson and Dennis Ritchie, zaten er ook niet mee om de programmeertaal B te dumpen toen C een betere match was.

How to reduce Rust executable size "hello world"

When you compile the "Hello World" for Rust, the executable is 11 mb in size.

fn main() {
    println!("Hello world");
}

You can decrease the size by using dynamic dlls:

rustc -C prefer-dynamic hello.rs

vrijdag 27 januari 2023

CSS trucs

Als je de grootte van alle elementen op je pagina wilt zien:
* { outline: 1px solid limegreen; }

Als je images op je pagina wilt lazy loaden:
<img loading="lazy"/>

Gradient color text:

.gradient-text {
background-image: (90deg, red, blue);
background-clip: text;
>color: transparent;
}

vrijdag 20 januari 2023

Bij belangrijke wijzigingen in PostgreSQL altijd transactions gebruiken

Bij wijzigingen in productie in PostgreSQL moet je altijd eerst bepalen hoeveel rijen worden geraakt door een statement. Dat kun je makkelijk doen door een transactie te gebruiken. Die kun je namelijk terugdraaien.

begin transaction;
delete from tabel where attr='waarde';
rollback;

En als alles volgens verwachting is, dan kun je rollback; veranderen in commit;

dinsdag 17 januari 2023

Angular traag bij websocket activiteit. Hoe kan dat?

Angular gebruikt zone.js om change detection te doen. Die zone.js heeft websockets gepatched om netwerk activiteit te detecteren. Bij het laden van ieder data gedeelte via de websocket wordt een change detection getriggerd. Daarom duurt het inladen van de gegevens zo lang als je websockets gebruikt en change detection niet goed is ingericht in je applicatie.
Zie https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/

De websocket functie "onmessage" moet je buiten de Angular Zone houden om te voorkomen dat bij iedere aanroep een change detection wordt getriggered:

Doe iets als:
    import { NgZone } from '@angular/core';
    constructor (private _ngZone : NgZone) {};

    await this._ngZone.runOutsideAngular(async () => {
        await this.websocketcode.open();
    });

zondag 15 januari 2023

Branching is slecht voor de kwaliteit van het software product

Why CI is BETTER Than Feature Branching.

Real Programmers commit to Master.

Branches moeten niet lang bestaan, want hoe langer ze bestaan hoe groter het verschil wordt. Ze mogen maar een paar dagen bestaan. Daarna wordt het mergen moeilijker en na een maand nog veel moeilijker.

NodeJS weer in de prullenbak.

Hebben jullie wel eens in de directory node_modules gekeken? Wat een ontzettende troep packages staan daar in.
Bijvoorbeeld een package "boolbase" van 8 code regels. Wrappy 28 regels. Has: 2 regels! Has-flag: 7 regels code. Abbrev: 60 regels met variabele namen zoals MonkeyPatch. Has-unicode: 7 regels. Humanize-ms: 11 regels gemaakt door dead-horse.
Deze mini-packages doen ook nog eens hele vreemde checks. Als je op Windows-NT zit dan heb je geen unicode volgens package Has-unicode.

Deze troep code is een grote reden voor mij om van NPM af te stappen. Daarom heb ik al m'n prive projecten gemaakt met NodeJS omgezet naar ASP.NET Core met top-levels minimal Web API statements. Waarom? Omdat ik het NodeJS moeras werd ingetrokken. Ik deed lelijke dingen zoals:

process.env.NODE_TLS_REJECT_UNAUTHORIZED="0";

Het is een manier om https certificaat error te negeren.
Datzelfde doen in ASP.NET Core is veel doordachter en mooier. NodeJS voelt bij mij als een snel in elkaar gezette hack. Dat is het ook eigenlijk, want NodeJS is gewoon de Chrome V8 Javascript Engine werkend gemaakt als standalone. Dat kon omdat het opensource was. Leuke hack. Maar het losse zand genaamd NPM packages ga ik niet gebruiken, want voor troep kies ik niet. NodeJS ligt er bij mij uit.

Wisten jullie dat de nieuwste Visual Studio 2022 ook hot-reload heeft? Samen met top-level statements en minimal web api levert het behoorlijk compacte code op. Je kunt eenvoudig een "ASP.NET Core Empty" project aanmaken en dan heb je een simpele webserver.

dinsdag 10 januari 2023

WSL 2. Een hele lichte manier om Linux op Windows te draaien.

WSL 2 is een manier om Ubuntu Linux te draaien in Windows. Het is een hele lichte VM. Die VM wordt afgesloten als er geen Bash meer een connectie heeft met de VM.
Een simpele manier om de Linux Sourcecode van een tool te compileren is, is om een command-prompt in Administrator mode te openen en naar de windows directory van de tool te gaan. Daar "wsl" te typen. Dan wordt WSL gestart en naar de actuele windows directory gegaan. Ideaal.

Tevens kan Dotnet 8.0 geinstalleerd worden op deze Ubuntu:
https://learn.microsoft.com/en-us/dotnet/core/install/linux-ubuntu#register-the-microsoft-package-repository

https://learn.microsoft.com/nl-nl/windows/wsl/setup/environment#set-up-your-linux-user-info
Commando's om de Linux te updaten:

sudo apt update
sudo apt upgrade
sudo apt install build-essential
sudo apt install rustc
sudo apt-get install -y dotnet-sdk-8.0

Welke ipadres heeft de localhost op de windows host gezien vanuit WSL 2?
ip route show | grep -i default | awk '{ print $3}'

Welk ipadres heeft de WSL 2 instantie gezien vanuit Windows?
ifconfig in de WSL 2.  Of op windows: wsl hostname -I

Welk linux zitten we? cat /etc/issue
Welke ipadressen hebben we? ifconfig
x86-64? uname -a

wsl afsluiten?  wsl --shutdown

maandag 9 januari 2023

Clear local nuget cache

dotnet nuget locals all --list
dotnet nuget locals all --clear

vrijdag 6 januari 2023

Remote compiling in Linux in Visual Studio Code

Met WSL kun je een Linux draaien in Windows. Visual Studio Code heeft een plugin om C++ code te laten compileren door die WSL linux en vervolgens het editten te doen in Visual Studio Code.

Zie:
https://code.visualstudio.com/docs/cpp/config-wsl

https://learn.microsoft.com/en-us/windows/wsl/faq 

donderdag 5 januari 2023

Text search in PostgreSQL

In PostgreSQL kun een ts_vector kolom maken waarop je kunt 
zoeken met een ts_query. Je gebruikt de @@ operator om te matchen.
select to_tsvector('fat cats ate fat rats');
select to_tsquery('fat & cat');
select to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat & cat');
Het kan zijn dat je de query moet fatsoeneren.
Gebruik onderstaande om bv. de streepjes te verwijderen uit een kenteken:
select regexp_replace('01-ABC-10', '[^\w]+', '', 'gi');