I de forløbne godt 3 måneder har jeg haft fornøjelsen af, at være lejet ud til et firma, hvor jeg har bistået med at portere en god klump gammel C-kode, der tilmed findes i utallige kundetilpassede varianter. Systemet ønskes nu flyttet fra SCO-unix til Linux. Det giver et par udfordringer.
Det umiddelbart nemme er, at det er et flyt fra et posix-miljø til et andet posix-miljø. Men pas på. En simpel funktion som f.eks. strcmp() er i SCO-udgaven af C-biblioteket implementeret, så den returnerer plus eller minus en afhængig om den ene streng er større end den anden. Posix standarden kræver blot, at returværdien er større eller mindre end 0. Dette er også hvad man kan forvente af glibc, som benyttet i Linux. Men hvad nu hvis den gamle kode udnytter SCO’s ide om at returnere plus/minus en og gange resultatet med et eller andet? glibc implementationen returnerer måske -405345 frem for -1. Med andre ord, det er nødvendigt, at lave nogle simple wrapper-funktioner, der kan redde gamle dages uvaner i koden. Havde koden kun eksisteret i en variant, så kunne man nok finde frem til uvanerne, men ikke i dette tilfælde, hvor koden findes i utallige kundetilpassede varianter i forskellige kode-generationer. Løsningen er selvfølgelig, at programmere sig ud af problemerne. Et større script, der kan manipulere C-koden og levere kode, der kan køre på den nye platform. Her har jeg benyttet objectorienteret Perl og store mængder regulære udtryk. Regulære udtryk er dog ikke optimale til alt.
Til Open Source Community Day 2009, var der et foredrag om Coccinelle med Julia Jawall, som jeg gerne ville have set. Jeg missede det dog, da jeg selv holdt foredrag samtidigt. Jeg fik dog læst op på hvad Coccinelle var for en størrelse, og fandt ud af, at det var netop hvad jeg havde brug for til min konsulentopgave. Coccinelle kan lave semantisk patchning af C-kode. Et helt simplet eksempel er, at skifte et funktionskald ud med et andet. Patchen ser således ud:
@@
@@
– foo
+ bar
Og det var så det. Hermed bliver alle instanser af foo skiftet ud med bar. Dette gælder også hvis foo benyttes som funktionspointer og der altså ikke står “foo(“, som man ellers ville have ledt efter med et regulært udtryk. Står der foo i printf-sætninger, ja så udskiftes de selvsagt heller ikke. Super fedt, at have en patch-funktionalitet, der forstår semantiken af den kode man manipulerer. Coccinelle er dog ikke de eneste rigtige værktøj til opgaven, men den har en fremtrædende plads i værktøjskurven.
Det bedste har faktisk været den super fornemme support, der er ydet på Coccinelle-mailinglisten. I flere tilfælde er mine nybegynder dummespørgsmål blevet besvaret med en løsning inden for 20 minutter. Den slags er ikke til at betale sig fra kommercielt, men det er der jo selvsagt heller ikke tale om her. Det er er dansk/fransk forskningssamarbejde og engagerede personer og i særdeleshed Julia Jawall. Tak for det.