Namnsdagskommandot – en studie i Arexx

De var namnsdagsbarn dagen då detta inlägg skrevs i alla fall.

1997 lade vi till ett namnsdagskommando till basen som kördes vid inloggning och berättade vem som hade namnsdag när någon loggade in. Det skrevs från början 1994 av Mattias Appelqvist. Kommandot läste från en textfil som innehöll alla namnen.

En fråga till er som programmerar: hur skulle ni skapa ett kommando som ska hämta ett namn ur en lista med namn baserad på dess position? Personligen skulle jag trycka in dem i en array och sedan ta reda på vilket namn i ordningen som ska plockas fram. Man får hitta en lösning för skottår, men annars är det bara att plocka fram post 218 ur arrayen dag nummer 217 (arrayer börjar normalt på 0!) förutsatt att namnen är lagrade i ordning efter vilken dag på året de har namnsdag. Inget problem här.

Men 1994 fungerade det lite annorlunda. Först och främst var minnet begränsat. The ERICADE Network hade en Amiga med 6 MB minne. Detta minne skulle räcka för att köra basen och operativsystemet med hundratals användare. Så att läsa in alla namnen i minnet vara lite mer tveksamt. Det andra skälet är att Arexx arrayhantering var ganska primitiv.

Så hur löser man detta? Jo, kommandot måste läsa från disken. Detta är i sig ett problem, för diskar är slöa jämfört med minnet. Om man antar att man lägger alla namnsdagar i ordning efter dag, skulle arexx-programmet behöva stega ner 219 rader för att hitta namnet bundet till dag 219. Detta är inte effektivt och kommer att göra kommandot slött och resurskrävande.

När jag startade upp BBSen 2018, insåg efter några månaders drift att namnsdagskommandot ofta visade fel namn. Det visade sig bero på att det hade en del intressanta buggar och dessutom använde 1993 års namnlängd. Denna slutade gälla på 2000-talet. Så jag hämtade den senaste namnlängden från Wikipedia och gjorde den till en textfil. Men vi har fortfarande inte svarat på frågan hur kommandot hittade dagens namn.

Detta var inte helt uppenbart för mig när jag tittade på koden eller på textfilen den läste. I början av namnfilen såg det ut såhär:

0062 0451 0817 1216 1614 2026 2410 2817 3233 3619 4026 4425
*
SVEA SVERKER

filen fortsatte sedan med alla namnen.

Vad var alla dessa märkliga siffror? En titt i koden visade att den verkade koppla siffrorna till månaden.

dag = right(date(’s’),2)
man = substr(date(’s’),5,2)
sendstring lf lf
if ~exists(fil) then call fel(’Hittar inte ’fil)
if ~open(’t’,fil,’r’) then call fel(’Kunde inte läsa från ’fil)
mpos = readln(’t’)
mpos = word(mpos,man)
call seek(’t’,mpos,’b’)

Koden ovan tar fram månadens nummer i ordningen. Juni är t.ex. månad nummer 6 och januari är 1. Sen läser den in den första raden och plockar ur den siffergruppen som motsvarar månaden. För juni tar den alltså den sjätte siffergruppen. Men varför då? Jo, denna siffergrupp talar om hur många bytes in i textfilen som månadens namn börjar. Det är ett intressant sätt att göra det på!

Men det ger ju inte hela lösningen. Efter att den hittat första namnet för den aktuella månaden, stegar den fram till korrekt dag. Om det är den 10 juni, stegar den tio rader ner och hämtar namnet.

Detta kommando har krånglat rätt mycket redan innan jag skrev om det för den nya namnlängden. Vissa dagar kraschade skriptet för den inte riktigt hittade rätt. Och att räkna ut hur många bytes in i filen man gå för att hitta månadsstarten visade sig vara en utmaning. Dessutom var man tvungen att tänka på hur Amigan kodar radbrytningar när man gjorde jobbet. Jag skrev nämligen filen på en PC.

Så jag hittade en lösning till sist och fick allting att fungera.

Lämna en kommentar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *

Denna webbplats använder Akismet för att minska skräppost. Lär dig hur din kommentardata bearbetas.