Bleibt zu hoffen, dass die jeweiligen Generatoren etwas erzeugt haben, was nicht abmahnfähig ist. Mir persönlich gefällt insbesondere die Datenschutzerklärung nicht, denn laut DSGVO soll sie leicht verständlich sein, das was da drin steht, ist es aber nicht wirklich. Aber ich werde den Teufel tun, und jetzt an einem Schriftstück herumfummeln, das von dem Generator auf der Webseite eines Rechtsanwalts erzeugt wurde.
I have already spent too much time to make my site compliant with GDPR rules. I have disabled
- comments on all pages (also deleted existing comments)
- track backs
- options to like pages
- direct links to “social” media
- JetPack features, including site stats
I have also tried to find and remove any requests my site sends to anywhere else but dummzeuch.de.
I’m still not done and I already hate it. Many useful features are now gone, existing comments have been deleted, I will no longer get stats on which pages have been requested.
And I might still decide to shut down the whole thing. I like publishing and interacting with my users, but I don’t want to spend the time for bullshit. So, if on 2018-05-25 you come back here and find that all the content is gone, you can thank the EU and the German government.
Welcome to #neuland.
Meine Frau hat vor kurzem ein altes Familienrezept ausgegraben, das nicht nur ich sondern auch meine Arbeitskollegen sehr lecker fanden. Leider kann ich das für die derzeit in sog. Bäckereien verkauften Nussecken nicht sagen. Die sind in der Regel viel zu süß und werden dazu noch in Schokolade ertränkt (Löbliche Ausnahme: Die Nussecken der Bio-Bäckerei Barth in Koblenz). Dieses Rezept ist anders. Man schmeckt die Nüsse und die Aprikosenmarmelade, nicht nur die Schokolade.
Nuss- oder Kokosecken
(Rezept der Familie Bläsing)
Zutaten für ein Backblech
- 150g Mehl
- 1/2 getrichener Teelöffel Backpulver
- 65g Zucker
- 1 Päckchen Vanillinzucker
- 1 Ei
- 65g Butter
- zum Bestreichen: 2 Esslöffel Aprikosenkonfitüre
- 100g Butter oder Margarine
- 100g Zucker
- 1 Päckchen Vanillinzucker
- 2 Esslöffel Wasser
- 200g Haselnusskerne (halb gemahlen oder gehackt) oder 200g Kokosraspeln
(Die Zubereitung des Gusses ist nicht mehr lesbar, alternativ kann man einfach Schokoladenkuvertüre erwärmen. Oder auch einfach weglassen.)
- 50g (2 gut gehäufte Esslöffel) Puderzucker
- 2 gehäufte Teelöffel Kakao
- 2 Esslöffel heißes Wasser
- 10g Butter
Den Teig wie Mürbeteig verarbeiten, auf das Backblech ausrollen und mit der Konfitüre bestreichen.
Das Fett mit Zucker, Vanillinzucker und Wasser zerlassen und einmal aufkochen.
Die Nüsse daruntermengen und alles kalt stellen.
Die abgekühlte Masse auf dem Teig verteilen.
Vor den Teig einen geknickten Papierstreifen legen, damit die Masse nicht herunterläuft.
Ofen 10 Minuten vorheizen, dann bei 175°-195° 15 Minuten backen.
Das Gebäck etwas abkühlen lassen, in Vierecke schneiden und dann diese nochmals in Dreiecke teilen.
Schokolade erwärmen und sparsam(!) auf die Ecken gießen.
Alles abkühlen lassen und nicht zuviel probieren, die anderen wollen auch noch was ab.
Once you have set up an Embarcadero License Center (ELC) for your company (with network named user or concurrent licenses) you will need network access to it in order to start the Delphi IDE.
Usually the server will only be accessible from within your intranet (I for one would not trust the ELC security to be good enough to let that server directly face the Internet.). So, in order to access it from a remote computer (e.g. your notebook on a customer’s site or your PC in your home office), that computer must have access to your intranet. If the connection is not available, Delphi will revert to offline usage which will work fine until the offline usage period expires which by default is 7 days but can be configured to up to 30 days.
By default the ELC listens on port 5567 for clients to connect to it, that port is specified when importing a license into ELC and cannot be changed later. The license manager reads the server name and port from the .slip file you provided to it, so you need a way to
- Resolve the name to the IP address
- Tunnel the port to your intranet
Let’s say, the name of your server is elc.yourcompany.local, its internal IP address is 192.168.1.200 and it listens on the default port 5567.
Name resolution can easily be done by adding an entry to the hosts file, but which IP do put there? If you add the IP of the actual server, it will not work, because that IP is in the intranet and your computer is not, so routing will fail. But using ssh you can tunnel local ports to remote ports, so we add our localhost IP (127.0.0.1) to the hosts file:
# This file contains the mappings of IP addresses to host names. Each # entry should be kept on an individual line. The IP address should # be placed in the first column followed by the corresponding host name. # The IP address and the host name should be separated by at least one # space. # # Additionally, comments (such as these) may be inserted on individual # lines or following the machine name denoted by a '#' symbol. # # For example: # # 22.214.171.124 rhino.acme.com # source server # 126.96.36.199 x.acme.com # x client host # # localhost name resolution is handle within DNS itself. # 127.0.0.1 localhost # ::1 localhost 127.0.0.1 elc.yourcompany.local
This will tell the client to expect the server to be listening on 127.0.0.1:5567. Now we only need to tunnel that local port to the actual ELC server by adding an entry to Putty:
Don’t forget to save that session configuration in order for it to be available later.
Now, simply connect your ssh session, start Delphi and voila, it will connect to the ELC, request a license and you are done.
In Delphi, threads have traditionally been implemented as classes descending from TThread. While there have been quite a few improvements to multithreading, TThread is still the most compatible way. But TThread is not a normal class.
In a normal class, the constructor and destructor usually look like this:
constructor TSomeClass.Create; begin inherited; FSomeList := TStringList.Create; end; destructor TSomeClass.Destroy; begin FreeAndNil(FSomeList); inherited; end;
In the constructor, we first call inherited and afterwards add code to initialize additional fields of the object. In the destructor we first free any fields of the object and only then call inherited for the ancestor class to free its resources.
Now, TThread is peculiar because its constructor and destructor are usually executed in the program’s main thread, while its Execute method is executed in a different thread. But, when is that thread started?
It’s started when you call the inherited constructor. So any initialization that thread needs must be done before calling inherited!
Edit: Several people have pointed out that my claim is somewhat “outdated”, where “outdated” means that since Delphi 6 the thread is started in the AfterConstruction method rather than in Create. In Delphi 5 it was the last command in TThread.Create (here is a probably not authorized copy of that code, search for “Delphi5Thread” on the page).
What I wrote about the destructor is still true though.
constructor TMyThread.Create; begin FSomeList := TStringList.Create; inherited; end;
Otherwise the field FSomeList might not have been initialized when the thread tries to access it.
Similar, if the thread is still running, you must be sure that all the resources it requires are available until it has stopped. So, the first thing would be to tell the thread to terminate, wait for it to actually do that and only then destroy it.
MyThread := TMyThread.Create; // do something else while the thread does its thing // ... // now tell it to terminate (this is standard way of doing that // but it might not be the best) MyThread.Terminate; // and destroy it FreeAndNil(MyThread);
But that’s only half of it. The destructor must also take care not to destroy anything the thread still needs:
destructor TMyThread.Destroy; begin // first, wait for the thread to terminate // (the inherited destructor calls WaitFor) inherited; // now the thread has definitely terminated, so we can free the resources FreeAndNil(FSomeList); end;
Beware: These are just the simplest precautions to take when programming with multiple threads. As they say: "Creating threads is easy but multithreading is hard." If you can, use a library that does the ground work for you.
Why do I blog about this? I just fixed a few Access Violations in GExperts that were caused by TThread objects implemented the wrong way. (I have no idea who did that, it’s quite possible that I am myself to blame for that.)
… even though you can open and read it fine in an editor:
You should check its Linux access permissions. If it is not marked as executable, this might be the cause.
Change it with chmod like this:
root@server:/home/netlogon$ ls -la total 12 drwxrwxr-x+ 2 root root 4096 Apr 13 09:04 . drwxr-xr-x 46 root root 4096 Mar 6 12:08 .. -rw-rw-r-- 1 root root 2535 Mar 6 14:32 logon.cmd root@server:/home/netlogon$ chmod +x logon.cmd root@server:/home/netlogon$ ls -la total 12 drwxrwxr-x+ 2 root root 4096 Apr 13 09:04 . drwxr-xr-x 46 root root 4096 Mar 6 12:08 .. -rwxrwxr-x 1 root root 2535 Mar 6 14:32 logon.cmd
The same goes for other executables on Samba shares.
In my case this was the last known problem left from a recent server migration. It worked before, didn’t work after. Something changed with the Samba configuration or maybe it was a change in Samba itself.
Recently SourceForge’s service has declined to a point where it gets really annoying. Basically every time I tried to commit a change to the svn repository of one of my projects, I run into timeouts and other errors. I want to spend my time working on my projects, not convincing their infrastructure to accept my changes.
So I went looking for alternatives and discovered that basically every hosting service nowadays supports git, some add Mercurial and only very few also offer Subversion. Some claim to offer Subversion access to git repositories but whenever I actually tried that, it turned out that it either didn’t work at all or had limitations. Usually the limitation was that svn:external tags were not supported.
OK, this blog post was supposed to be about getting a dump of a remote svn repository, not about hosting services and their limitations…
The usual advice you find, when you google for “svn dump repository” is to use svnadmin. Unfortunately it turns out that svnadmin only works for local repositories so it is not suitable for dumping a repository on SourceForge. There are a few tools that claim to sync repositories but none of them worked for me. Eventually I found a reference to svnrdump, which is included in TortoisSVN and is exactly what I was looking for:
svnrdump dump http://svn.code.sf.net/p/dzlib/code > dzlib.svndump
creates a dump of the repository in the same format as svnadmin does. In theory it can also load that dump into a remote repository, but that requires that the target repository has been prepared for that operation.
Unfortunately, even that operation timed out just now why trying to download revision 162 (of 744), so I’m back to square one.
Edit: I eventually succeeded with the above command. But, as Ondrej Kelle pointed out in his comment on my Google+ post, for SourceForge there is a simpler and more robust way: Create a local copy of the repository.
rsync -a -v svn.code.sf.net::p/dzlib/code/ .
It’s even documented in the SourceForge support documentation (I only found it after I knew of this option). It requires the rsync tool, which is not available under Windows by default, but hey, are there any developers who don’t have access to a Linux computer or VM?
Once you have got that local copy, you can simply use svnadmin to create a dump from it:
svnadmin dump --incremental --deltas path\to\repository > repository.dump
I added the options –incremental and –deltas after initially loading the dump into a fresh repository failed when it encountered the first binary file. With these options, the problem did not occur.
svnadmin load --file repository.dump path\to\new\repository
Note: The following failed for me under Windows 8.1:
type repository.dump | svnadmin load path\to\new\repository
Starting with Delphi 2007 EmBorCodera switched to msbuild for the build system. The newly introduced .dproj file used since then is a valid build script for msbuild but unfortunately the format has changed between Delphi 2007 and 2009. This means that there is a difference if you want to make command line builds and specify the build configuration:
With Delphi 2007, you use:
msbuild /target:rebuild /p:Configuration=Release %dprname%
You might also want to add the -p:DCC_Quiet=true option to reduce the amount of empty lines output:
msbuild /target:rebuild /p:Configuration=Release -p:DCC_Quiet=true %dprname%
With Delphi 2009 and later, you use:
msbuild /target:rebuild /p:config=Release %dprname%
(Source: This answer on StackOverflow.)
Until today I wasn’t aware of this difference so my automated GExperts builds for Delphi 2007 always used the build configuration that was selected in the IDE, which probably means that I have released debug builds rather than release builds for that Delphi version.
Have you ever wondered which functions of GExperts you have used the most? Or how often at all? How much time it has saved you?
Now you can find out: I just added Usage Statistics to GExperts which tells you exactly how often you have called each of the experts, in the current session and also in total (data between sessions is saved in the registry). Currently it can be accessed via a button in the Configuration dialog, but I am not sure yet where to put it.
So far, it has told me nothing new: My most used functions are, in descending order:
- Editor Popup Menu (to quickly call other experts)
- Code Formatter
- Rename Components (which has become even more useful since it can set alignment and anchors)
- Uses Clause Manager
But this is just after a few minutes of actually using GExperts after I have added the statistics, so there might still be some surprises. I am wondering about the Code Proofreader for example.
I plan to do a new release shortly (oh my, the last one is over a year old!), maybe even during the Easter holidays, but don’t hold your breath. In the meantime, you can simply compile your own GExperts dll.