LibreOffice fejlesztés

LibreOffice programhibák (bugok) javítása

2019. január 07. - christo161

Ebben a leírásban arról lesz szó, hogy hogyan keressük meg a LibreOffice forráskódjának azt a részét, amiben módosításokat szeretnénk végezni annak érdekében, hogy egy adott hibát kijavíthassunk. Ez persze csak eszközök bemutatását jelenti, nem pedig recepteket, amikkel konkrét hibákat lehet javítani. Ebben a leírásban nem lesz szó unit tesztek írásáról és módosítások (patchek) beküldéséről (commitolás, pusholás).

A hibajegyek listája

Érdemes először áttekinteni a hibajegyek listáját, mely ezen a címen érhető el:

https://bugs.documentfoundation.org/

Természetesen a LibreOffice kódja óriási, érdemes ezért kiválasztani egy jól elkülöníthető részhalmazát (modulját), aminek a hibáival foglalkozni szeretnénk, és erre vonatkozó kulcsszavak alapján hibákat keresni.
Kezdőként például érdemes lehet az import és export hibák közül válogatni (ezekhez használjuk a fileopen és filesave kulcsszavakat a keresésnél). Érdemes azonban még ezen belül is egy adott dokumentumszabványra fókuszálni.
Például az OOXML (Office Open XML) szabvány a docx, xlsx, pptx, ... satöbbi formátumú fájlokat foglalja magában, az ODF (Open Document Format) szabvány pedig az odt, ods, odp, ... satöbbi formátumú fájlokat.

Tehát a hibalistában történő keresésnél használhatjuk például az oox vagy odf kulcsszót is.
https://bugs.documentfoundation.org/buglist.cgi?quicksearch=oox

libreoffice_bugzilla.png

Először nyugodtan kezdjük azzal, hogy elolvassuk egy hibajegy leírását, megnézzük a képernyőképeket és a példafájlokat, és megpróbáljuk reprodukálni a hibát.

Tekintsünk egy példát erre. Ez persze már egy kijavított hiba, de egyrészt a képernyőképből látható, hogy mi romlik el (a diagramok szegélyeinek vonalstílusa), másrészt a leírásból kiderül, hogy ez export hiba, azaz a tulajdonság (LibreOffice-szal történő, OOXML szabványú fájlba történő) mentést követően romlik el.
(A kép bal oldalán látható az MS Office-szal elmentett (hibát nem tartalmazó) dokumentum, a kép jobb oldalán pedig a LibreOffice-szal elmentett dokumentum, amelyben a diagram szegélyeinek vonalstílusai elvesztek).

ooxml_export_plot_area_chart_page_linestyle.png

Export hiba (filesave bug): létrehozunk LibreOfficeban egy dokumentumot valamilyen tartalommal (vagy megnyitunk egy MS Office-ban létrehozott dokumentumot), elmentjük LibreOffice-szal, és ha újra betöltjük, akkor hibásan fog megjelenni.

Import hiba (fileopen bug): megnyitunk LibreOfficeban egy nem hibásan elmentett dokumentumot, ami hibásan jelenik meg. (Ezt pl. úgy tudjuk ellenőrízni, ha megnyitjuk MS Officeban is, és ott nem hibásan jelenik meg).
Ezen belül két eset van:

  • a hibás importálás eredményeként rosszul jelenik meg valami a dokumentumban, de ez nem befolyásolja az exportálást (mentést)
  • a hibás importálás következtében nem csak rosszul jelennek meg dolgok, hanem a fájl további mentését követően még rosszabb lesz a helyzet

Sokat segíthet,ha egy adott dokumentumot megnyitunk MS Office-szal és LibreOffice-szal is, valamint ha megvizsgáljuk egy adott dokumentum XML fájljainak szerkezetét (erről a következő részben lesz szó).
Sajnos előfordulhat, hogy annak ellenére, hogy egy fájl XML szerkezete hibás, az MS Office vagy esetleg a LibreOffice megpróbálja kikövetkeztetni, hogy hogyan lehetne a hibás szerkezetű fáljból mégiscsak jól megjeleníteni a dokumentumot, ami megtévesztő lehet, hiszen ekkor azt hihetjük, hogy a dokumentum szerkezetében nincs hiba.

Annyit azért még mindenképp megemlítenék, hogy a hibajelenségből nem mindig lehet következtetni arra, hogy milyen könnyű vagy nehéz kijavítani a hibát, ezért könnyen meglehet, hogy valaki kiválaszt egy könnyűnek tűnő hibát, ami valójában mégsem könnyű, és ez elveszi az illető kedvét. Türelem kell ahhoz, hogy valakinek meglegyen az első hibajavítása, és nem biztos, hogy néhány óra alatt ez kivitelezhető, lehet, hogy napokig, akár hetekig is nézegetni kell a kódot (persze nem folyamatosan).
Vannak kifejezetten könnyűnek besorolt hibák, az úgynevezett EasyHackek, de még akár ezek között is előfordulhatnak nehezebbek.

Dokumentumok szerkezetének vizsgálata

Mind az OOXML, mind az ODF szabványú dokumentumfájlok technikailag egy tömörített könyvtár (mappa), amiben további XML fájlok találhatóak.

ooxml_docx_unzip.png

Tegyük fel, hogy van egy fajlnev.docx nevű fájlunk, amit átnevezünk fajlnev.zip-re, aztán kitömörítjük a tartalmát. A kitömörített mappában érdemes vizsgálni a document.xml fájl tartalmát, vagy ha diagram is szerepel a dokumentumban, akkor a például a chart1.xml tartalmát.

Előfordulhat, hogy az XML fájlok tartalma plain text szövegszerkesztőkkel (pl. notepad, notepad++, sublime text) megnyitva olvashatatlan lesz, az egyes XML tagek egymás után jelennek meg, nem pedig strukturáltan.

Érdemes használni az XML Copy és Open XML SDK programokat, mindkettő ingyenes, az előbbi több platformon (pl. Windowson és Linuxon) is elérhető.

Ha az XML Copyval nyitunk meg egy XML fájlt, akkor ott is egymás után jelennek meg az XML tagek, de ha megnyomjuk az F11-et, vagy az XML menüből kiválasztjuk a pretty-print menüpontot, akkor szépen strukturáltan jelennek majd meg ott is.

Az Open XML SDK-val összehasonlíthatjuk, hogy miben tér el két XML fájl. Például egy MS Office-szal létrehozott és egy LibreOffice-szal létrehozott dokumentum esetén.

open_xml_sdk.png

Dokumentumszabványok

Bár sokszor könnyű kikövetkeztetni, hogy a dokumentumok XML fájljainak tagjei mit jelentenek, hiszen tudjuk hogy néz ki egy dokumentum, és az alapján könnyebb megpróbálni kitalálni a jelentésüket, mégis szükség lehet arra, hogy valamelyik XML tag jelentésére rákeressünk. Ezeket a szabványokban találjuk meg. A szabványok többszáz oldalas dokumentumok, nyilván nem arra lettek kitalálva, hogy valaki elejétől a végéig elolvassa őket, hanem pont arra, hogy keresni lehessen bennük.

ODF (Open Document Format) szabvány (odt, ods, odp, ... formátumú fájlok)

ISO szabványok
az egyes fájlok (zipbe tömörítve): [1], [2], [3]

OASIS - letöltési linkek oldala
az egyes PDF fájlok: [1], [2], [3]

OOXML (Office Open XML) szabvány (docx, xlsx, pptx, ... formátumú fájlok)

ISO szabványok
az egyes fájlok (zipbe tömörítve): [1], [2], [3], [4]

ECMA - letöltési linkek oldala

http://officeopenxml.com

Keresés a LibreOffice forráskódjában kulcsszavak alapján

Természetesen ahhoz, hogy a LibreOffice működésében módosításokat végezzünk, a forráskódját kell módosítani. Eleinte nem biztos, hogy könnyű lesz megtalálni azt a kódrészletet, ami egy adott hibát okoz, és amit módosítani kell annak érdekében, hogy a hibát kijavíthassuk.

Online felületen történő keresésre néhány példa:

Amellett, hogy természetesen a gépünkön lévő fájlkezelő és fejlesztői környezet (pl. Visual Studio) segítségével is tudunk a forráskódban keresgélni, érdemes használni az opengrok.libreoffice.org címen elérhető kódkeresőt.

A keresés előtt a project(s) legördülő listában pipáljuk ki a core-t, mert alapból semmi nincs kiválasztva.

opengrok_core_checked.png

Általában egész jó keresési eredményt ad, ha a full search mezőt kitöltve keresünk, de például hasznos lehet elérési út (file path) alapján is keresni, esetleg függvények, osztályok definíciójára is rákereshetünk. Néhány példa:

Ha például a file path mezőbe beírjuk, hogy oox, akkor az Office Open XML szabványnyal (docx, xlsx, ...) kapcsolatos forrásfájlok tartalmát tekinthetjük meg.

https://opengrok.libreoffice.org/xref/core/oox/
https://opengrok.libreoffice.org/xref/core/include/oox/

opengrok_ooxml.png

(Az OOXML szabványon belül) diagramok importálására szolgál például a drawingml/chart alkönyvtár tartalma:

https://opengrok.libreoffice.org/xref/core/oox/source/drawingml/chart/

(Az OOXML szabványon belül) diagramok exportálására pedig például a chartexport és a drawingml fájlok:

https://opengrok.libreoffice.org/xref/core/oox/source/export/chartexport.cxx

https://opengrok.libreoffice.org/xref/core/oox/source/export/drawingml.cxx

Diagramok felépítéséről, belső működéséről itt találjuk a forrásfájlokat (dokumentumszabványoktól független):

https://opengrok.libreoffice.org/xref/core/chart2/

A LibreOffice által használt belső mértékegységek közti váltószámokat itt találhatjuk:

https://opengrok.libreoffice.org/xref/core/include/filter/msfilter/escherex.hxx#327

(Az OOXML szabványon belül) ezek között a mértékegységek közötti átváltások az itt definiált függvények segítségével történnek:

https://opengrok.libreoffice.org/xref/core/include/oox/drawingml/drawingmltypes.hxx
https://opengrok.libreoffice.org/xref/core/oox/source/drawingml/drawingmltypes.cxx

A C++ nyelvben sokszor találkozhatunk azzal a megoldással, hogy a deklarációk és a definíciók külön fájlokban szerepelnek. Itt például a hxx kiterjesztésű fájl tartalmazza a deklarációkat, a cxx pedig a definíciókat. (Ehelyett néha h, hpp, cpp is szerepelhet, illetve templatek esetén sok esetben csak header fájl van).

A fenti linkek elérési útjában jól látszik, hogy külön könyvtárban helyezkednek el a header fájlok, például ezért is hasznos lehet fájlnév alapján keresni, hogy a keresés eredményeként egyúttal megtekinthessük a hxx és a cxx fájlt.

opengrok_file_search_drawingmltypes.png

Az opengrokban a definíció alapján történő keresés úgy is lehetséges, ha valahol a kódban egy kifejezésre az egér jobb gombjával kattintunk, majd kiválasztjuk a megnyitás új lapon lehetőséget. Pl. a lineproperties.cxx fájlban található convertEmuToHmm függvény esetén:

opengrok_definition_new_tab.png

Előfordulhat, hogy bizonyos adatszerkezetek definícióját idl kiterjesztésű fájlokban találhatjuk, melyek tartalma eltérő a szokásos C++ fájlokétól, mivel az UNO API részei. Néhány példa:

XProperty.idl
PropertySet.idl
XPropertySet.idl
XModel.idl
Diagram.idl
XDiagram.idl
ScaleData.idl
XAxis.idl

Ezekről részletesebben olvashatunk az IDL referencia oldalakon ([1], [2]). Például:

XProperty [2]
XModel [2]

Talán érdemes még megemlíteni, hogy az opengrok fontos lehetőségei közé tartozik, egy fájl legutóbbi módosításait is listázhatjuk vele, illetve két állapot közötti eltéréseket is megnézhetjük.

opengrok_file_history.png

Parancssorban történő keresésre néhány példa:

(A parancsok futtatása előtt be kell lépni a LibreOffice könyvtárába).

Az XML_b kifejezést tartalmazó sorokat írja ki, az oox modulon belül:

git grep XML_b -- oox

Az axis kifejezést tartalmazó sorokat írja ki a writefilter modulon belül (kis- és nagybetűre való tekintet nélkül):

git grep -i axis -- writerfilter

A forráskód moduljainak felépítéséről

Hasznos lehet átnézni, átolvasni ezt a két linket:

https://wiki.documentfoundation.org/Development/Code_Overview

https://docs.libreoffice.org/

Ha itt lejjebb görgetünk, szintén találunk rövid leírásokat a főbb modulokról:

https://opengrok.libreoffice.org/xref/core/

Változók, adattagok értékeinek kiíratása

A legtöbb hibajegy esetén nyilvánvalóan nem elég azt vizsgálni, hogy mi szerepel rosszul az XML fájlokban, hanem a feldolgozás alatt lévő adatokat is nézegetni kell, azaz a köztes eredményt (az import és az export között). Illetve nyilván lehetnek olyan hibák is, ahol az XML fájlok nem is jönnek szóba (pl. vágólap hiba, ha kijelölünk egy bonyolultabb elemet, pl. egy táblázatot, vagy annak egy részét, és azt másoljuk, beillesztjük egy másik dokumentumba).

A legtöbb ember, aki számítógépet, okostelefont, vagy valamilyen hasonló eszközt használ, biztosan belegondolt már abba, hogy a felhasználók által használt szoftverek jelentős része úgy működik, hogy beolvas valamilyen adatokat (pl. fájlból vagy bekéri a felhasználótól), azokkal az adatokkal végez valamilyen műveletet, majd az eredményt valahová kiírja (pl. fájlba, grafikus felületre, parancssorba).
Ezeknek a köztes műveleteknek az eredményeit többnyire változókban, tömbökben, vagy objektumok adattagjaiban tárolják a programok.

A LibreOffice esetén a SAL_DEBUG("valami erteke: " << valami); utasítással írhatjuk ki a változók, vagy egyéb adatszerkezetek értékeit.

Egyrészt az ilyen jellegű utasítások csak akkor működnek, ha az adott fájlban az include preprocesszor direktívák között ez a sor is szerepel: #include <sal/log.hxx>, bár ez általában szerepelni szokott a forrásfájlokban, de előfordulnak olyanok is, amikben nem.
Másrészt csak a tesztelés ideje alatt szerepelhet a kódban ilyen jellegű utasítás, amikor a forráskódban végzett módosításunkat beküldjük (./logerrit submit master), akkor ezeket el kell távolítani a kódból.

Ha elhelyeztünk valahol a kódban egy ilyen utasítást, utána pedig nem felejtünk el fordítani (make vagy make build-nocheck futtatása a LibreOffice könyvtárába lépve), majd a LibreOffice-t elindítjuk parancssorból (./instdir/program/soffice futtatása a LibreOffice könyvtárába lépve), és olyan műveletet végzünk a LibreOffice-szal, amelynek köszönhetően az általunk elhelyezett SAL_DEBUG("valami"); utasítás lefut, akkor az értékek a parancssorba lesznek kiírva.

sal_debug.png

Esetleg zavaró lehet, hogy sok üzenet jelenik meg a LibreOffice működésével kapcsolatban is. Ha nem szeretnénk, hogy ezek megjelenjenek, tehát csak a SAL_DEBUG("valami"); típusú utasítások által visszaadott eredményt szeretnénk megjeleníteni, akkor így futtassuk a LibreOffice-t:

SAL_LOG=-INFO ./instdir/program/soffice

sal_debug_sal_log_minus_info.png

Ha exportálási hibákat vizsgálunk, akkor előfordulhat, hogy nem is kell elindítani a LibreOffice-t, hanem ezzel a paranccsal automatikusan elvégezhetjük egy fájl mentését/konvertálását:

SAL_LOG=-INFO ./instdir/program/soffice --convert-to docx ../fajlnev.docx

Néhány példa:

https://opengrok.libreoffice.org/xref/core/oox/source/export/drawingml.cxx#662

Például ha a drawingml.cxx fájl kb. 600-700. sora körül lévő (a pontos sorszám ugyebár változhat, ha valaki módosítja a fájl tartalmát) case drawing::LineStyle_DASH: után lévő if-else blokk után írjuk a következőket, akkor ha olyan dokumentumot nyitunk meg, amiben szerepel olyan alakzat/diagram, aminek vannak vonalstílusai (pl. pontozott, szaggatott), akkor az arra vonatkozó tulajdonságokat fognak parancssorba kiíródni, ha a LibreOffice-t a fenti módokon futtatjuk.

SAL_DEBUG("===oox/source/export/drawingml.cxx===");
SAL_DEBUG("==void DrawingML::WriteOutline(...)==");
SAL_DEBUG("linedashname: " << aLineDashName);
SAL_DEBUG("Dots: " << aLineDash.Dots);
SAL_DEBUG("DotLen: " << aLineDash.DotLen);
SAL_DEBUG("Dashes: " << aLineDash.Dashes);
SAL_DEBUG("DashLen: " << aLineDash.DashLen);
SAL_DEBUG("Distance: " << aLineDash.Distance);

Akár azt is tesztelhetjük, hogy a vezérlés eljut-e egy if vagy egy else ágba, ha oda beillesztünk például egy ilyen utasítást:

if( /*valami*/ ){
	SAL_DEBUG("==if==");
	//utasítások
} else {
	SAL_DEBUG("==else==");
	//utasítások
}

Mások patcheinek áttekintése

Nyilvánvalóan sokat lehet abból tanulni, ha áttekintjük, hogy mások hogyan oldottak meg a kiszemelt hibánkhoz hasonló hibát/hibákat, illetve az általunk módosítani kívánt fájlokon ezidáig milyen módosítások történtek.

Erre több eszköz is van. Egyrészt ott a gerrit, ahol megtekinthetjük például a beküldött (open) és az elfogadott (merged) patcheket. Ha kiválasztunk egy patchet, akkor láthatjuk, hogy ki küldte be, mit módosított a forrásfájlokon, és hogy milyen megjegyzések, visszajelzések érkeztek rá.

gerrit_open.png

Másrészt ott a cgit, ahol az elfogadott (merged) patcheket tekinthetjük meg, hasonlóan, mint a git log paranccsal.

cgit_log.png

Természetesen lehet keresni commit message alapján is, ha a legördülő listából kiválasztjuk a log msg-t, a textboxba pedig beírjuk a keresendő kifejezést, pl. crossref.

És persze parancssorban a git parancs segítségével is megtekinthetjük a legutóbbi elfogadott módosításokat.

Néhány példa:

Legutóbbi elfogadott (merged) módosítások (patchek):

git log

git_log.png

Ez nem fog magától frissülni, nekünk kell letöltenünk az újabb verziójú forráskódot a következő paranccsal:

git pull

Vagy ha esetleg nem a master branchben vagyunk, akkor:

git pull -r origin master

De a branchekről külön leírásban lesz szó bővebben.

Egy adott fájl legutóbbi módosításai:

git log -u ./writerfilter/source/ooxml/model.xml

git_log_u_writerfilter_model_xml.png

Egy adott fájl legutóbbi módosítása:

git log -u -1 ./writerfilter/source/ooxml/model.xml

git_log_u_minus_1_writerfilter_model_xml.png

A bejegyzés trackback címe:

https://libreoffice.blog.hu/api/trackback/id/tr6514502854

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Lehet Szoryi 2019.01.08. 10:23:48

Gratulálok, nagyon jó leírás lett. Remélem egyszer valaki azért kezd bele libre office fejlesztésébe mert ezt olvassa.

christo161 · http://itkezdoknek.blog.hu/ 2019.01.08. 11:37:08

@Lehet Szoryi: Ez igazából csak egy saját magamnak írt txt fájl kicsinosítása. Nyilván nem fognak emiatt tömegek LibreOffice-t fejleszteni, de gondoltam hátha esetleg valakinek segít majd.
süti beállítások módosítása