From f6bed8590f8ec692a814d073cbce26bafc0327d0 Mon Sep 17 00:00:00 2001 From: smahot Date: Thu, 24 Sep 2020 10:14:57 +0200 Subject: [PATCH 001/141] Support for third party qt image plugins --- common/comic.cpp | 20 ++++++++++++++++++++ common/comic.h | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/common/comic.cpp b/common/comic.cpp index 514bc084a..4bc1fd5c7 100644 --- a/common/comic.cpp +++ b/common/comic.cpp @@ -23,6 +23,26 @@ enum YACReaderPageSortingMode { void comic_pages_sort(QList &pageNames, YACReaderPageSortingMode sortingMode); +QStringList Comic::getSupportedImageFormats() +{ + QList supportedImageFormats = QImageReader::supportedImageFormats(); + QStringList supportedImageFormatStrings; + for (QByteArray item : supportedImageFormats) { + supportedImageFormatStrings.append(QString::fromLocal8Bit("*." + item)); + } + return supportedImageFormatStrings; +} + +QStringList Comic::getSupportedImageLiteralFormats() +{ + QList supportedImageFormats = QImageReader::supportedImageFormats(); + QStringList supportedImageFormatStrings; + for (QByteArray item : supportedImageFormats) { + supportedImageFormatStrings.append(QString::fromLocal8Bit(item)); + } + return supportedImageFormatStrings; +} + const QStringList Comic::imageExtensions = QStringList() << "*.jpg" << "*.jpeg" << "*.png" diff --git a/common/comic.h b/common/comic.h index 44a4996da..3174746af 100644 --- a/common/comic.h +++ b/common/comic.h @@ -76,8 +76,8 @@ class Comic : public QObject //check if the comic has failed loading bool hasBeenAnErrorOpening(); - inline static QStringList getSupportedImageFormats() { return imageExtensions; } - inline static QStringList getSupportedImageLiteralFormats() { return literalImageExtensions; } + static QStringList getSupportedImageFormats(); + static QStringList getSupportedImageLiteralFormats(); static bool fileIsComic(const QString &path); static QList findValidComicFiles(const QList &list); From ccf1e4cb56616faf0c936f85455c98eb4b90ba07 Mon Sep 17 00:00:00 2001 From: Heimen Stoffels Date: Wed, 23 Sep 2020 20:17:24 +0200 Subject: [PATCH 002/141] Updated Dutch translation --- YACReader/yacreader_nl.ts | 376 ++++++------ YACReaderLibrary/yacreaderlibrary_nl.ts | 763 ++++++++++++------------ 2 files changed, 572 insertions(+), 567 deletions(-) diff --git a/YACReader/yacreader_nl.ts b/YACReader/yacreader_nl.ts index b22de12a6..9c6da0e2d 100644 --- a/YACReader/yacreader_nl.ts +++ b/YACReader/yacreader_nl.ts @@ -1,12 +1,12 @@ - + ActionsShortcutsModel None - + Geen @@ -14,23 +14,23 @@ Lastest Page - Laatste Pagina + Laatste pagina Close - Sluiten + Sluiten Click on any image to go to the bookmark - Klik op een afbeelding om naar de bladwijzer te gaan + Klik op een afbeelding om naar de bladwijzer te gaan Loading... - Inladen... + Bezig met laden... @@ -38,27 +38,27 @@ Restore defaults - + Standaardwaarden herstellen To change a shortcut, double click in the key combination and type the new keys. - + Sneltoets aanpassen? Dubbelklik op de huidige sneltoets en druk de nieuwe toetsen in. Shortcuts settings - + Sneltoetsinstellingen Shortcut in use - + Sneltoets is in gebruik The shortcut "%1" is already assigned to other function - + De sneltoets '%1' is al toegewezen aan een andere functie @@ -66,22 +66,22 @@ Unknown error opening the file - + Onbekende fout tijdens openen van bestand 7z not found - 7Z Archiefbestand niet gevonden + 7Z is niet aangetroffen Format not supported - + Dit formaat wordt niet ondersteund CRC error on page (%1): some of the pages will not be displayed correctly - + CRC-fout op pagina (%1): sommige pagina's worden niet goed getoond @@ -89,28 +89,28 @@ Page : - Pagina : + Pagina: Go To - Ga Naar + Ga naar Cancel - Annuleren + Annuleren Total pages : - Totaal aantal pagina's : + Totaal aantal pagina's: Go to... - Ga naar... + Ga naar... @@ -118,7 +118,7 @@ Page : - Pagina : + Pagina: @@ -126,12 +126,12 @@ About - Over + Over Help - Help + Hulp @@ -139,7 +139,7 @@ &Open - &Open + &Openen O @@ -148,12 +148,12 @@ Open a comic - Open een strip + Open een strip Open Folder - Map Openen + Map openen Ctrl+O @@ -162,98 +162,98 @@ Open image folder - Open afbeeldings map + Afbeeldingsmap openen Open latest comic - + Recentste strip openen Open the latest comic opened in the previous reading session - + Open de strip van de vorige leessessie Clear open recent list - + 'Onlangs geopend' wissen Save - Bewaar + Opslaan Save current page - Bewaren huidige pagina + Sla de huidige pagina op Previous Comic - Vorige Strip + Vorige strip Open previous comic - Open de vorige strip + Open de vorige strip Next Comic - Volgende Strip + Volgende strip Open next comic - Open volgende strip + Open de volgende strip &Previous - &Vorige + &Vorige Go to previous page - Ga naar de vorige pagina + Ga naar de vorige pagina &Next - &Volgende + &Volgende Go to next page - Ga naar de volgende pagina + Ga naar de volgende pagina Fit Width - Vensterbreedte aanpassen + Inpassen in breedte Fit image to height - Afbeelding aanpassen aan hoogte + Inpassen in hoogte Fit Height - + Inpassen in hoogte Fit image to width - Afbeelding aanpassen aan breedte + Inpassen in breedte Rotate image to the left - Links omdraaien + Naar links draaien L @@ -262,7 +262,7 @@ Rotate image to the right - Rechts omdraaien + Naar rechts draaien R @@ -271,12 +271,12 @@ Double page mode - Dubbele bladzijde modus + Dubbelebladzijdemodus Switch to double page mode - Naar dubbele bladzijde modus + Schakel over naar de dubbelebladzijdemodus D @@ -285,7 +285,7 @@ Go To - Ga Naar + Ga naar G @@ -294,12 +294,12 @@ Go to page ... - Ga naar bladzijde ... + Ga naar bladzijde... Options - Opties + Opties C @@ -308,28 +308,28 @@ YACReader options - YACReader opties + YACReader-opties Help - Help + Hulp Help, About YACReader - Help, Over YACReader + Hulp, Over YACReader Magnifying glass - Vergrootglas + Vergrootglas Switch Magnifying glass - Overschakelen naar Vergrootglas + Vergrootglas openen Z @@ -338,22 +338,22 @@ Set bookmark - Bladwijzer instellen + Bladwijzer instellen Set a bookmark on the current page - Een bladwijzer toevoegen aan de huidige pagina + Stel een bladwijzer in op de huidige pagina Show bookmarks - Bladwijzers weergeven + Bladwijzers tonen Show the bookmarks of the current comic - Toon de bladwijzers van de huidige strip + Toon de bladwijzers van de huidige strip M @@ -362,12 +362,12 @@ Show keyboard shortcuts - Toon de sneltoetsen + Sneltoetsen tonen Show Info - Info tonen + Informatie tonen I @@ -376,275 +376,275 @@ Close - Sluiten + Sluiten Show Dictionary - Woordenlijst weergeven + Woordenboek tonen Always on top - Altijd op voorgrond + Altijd op voorgrond Show full size - Volledig Scherm + Oorspronkelijke grootte Clear - + Wissen Fit to page - + Pagina inpassen Reset zoom - + Standaard zoomniveau Show zoom slider - + Zoomschuifbalk tonen Zoom+ - + Zoom+ Zoom- - + Zoom- Double page manga mode - + Dubbelebladzijdemangamodus Reverse reading order in double page mode - + Leesvolgorde omdraaien in dubbelebladzijdemodus Show go to flow - Toon ga naar de Omslagbrowser + Omslagverkenner tonen Edit shortcuts - + Sneltoetsen aanpassen &File - &Bestand + &Bestand Open recent - + Onlangs geopend bestand File - + Bestand Edit - + Bewerken View - + Beeld Go - + Ga Window - + Venster Open Comic - Open een Strip + Strip openen Comic files - Strip bestanden + Stripbestanden Open folder - Open een Map + Map openen Image files (*.jpg) - Afbeelding bestanden (*.jpg) + Afbeeldingsbestanden (*.jpg) page_%1.jpg - pagina_%1.jpg + pagina_%1.jpg Comics - + Strips Toggle fullscreen mode - + Beeldvullende modus aan/uit Hide/show toolbar - + Werkbalk tonen/verbergen General - Algemeen + Algemeen Size up magnifying glass - + Bladzijde vergroten Size down magnifying glass - + Bladzijde verkleinen Zoom in magnifying glass - + Inzoomen Zoom out magnifying glass - + Uitzoomen Magnifiying glass - + Vergrootglas Toggle between fit to width and fit to height - + Schakelen tussen inpassen in breedte en inpassen in hoogte Page adjustement - + Pagina inpassen Autoscroll down - + Automatisch omlaag scrollen Autoscroll up - + Automatisch omhoog scrollen Autoscroll forward, horizontal first - + Automatisch vooruit scrollen - eerst horizontaal Autoscroll backward, horizontal first - + Automatisch achteruit scrollen - eerst horizontaal Autoscroll forward, vertical first - + Automatisch vooruit scrollen - eerst verticaal Autoscroll backward, vertical first - + Automatisch achteruit scrollen - eerst verticaal Move down - + Omlaag Move up - + Omhoog Move left - + Naar links Move right - + Naar rechts Go to the first page - + Ga naar eerste bladzijde Go to the last page - + Ga naar laatste bladzijde Reading - + Lezen There is a new version available - Er is een nieuwe versie beschikbaar + Er is een nieuwe versie beschikbaar Do you want to download the new version? - Wilt u de nieuwe versie downloaden? + Wil je de nieuwe versie downloaden? Remind me in 14 days - + Herinner me over 14 dagen Not now - + Niet nu @@ -652,12 +652,12 @@ "Go to flow" size - "Naar Omslagbrowser" afmetingen + Afmetingen van omslagverkenner My comics path - Pad naar mijn strips + Pad naar mijn strips Page width stretch @@ -666,77 +666,77 @@ Background color - Achtergrondkleur + Achtergrondkleur Choose - Kies + Kiezen Quick Navigation Mode - + Snellenavigatiemodus Disable mouse over activation - + Activeren met muiszweving uitschakelen Restart is needed - Herstart is nodig + Herstart vereist Brightness - Helderheid + Helderheid Contrast - Contrast + Contrast Gamma - Gamma + Gamma Reset - Standaardwaarden terugzetten + Standaardwaarden Image options - Afbeelding opties + Afbeeldingsopties General - Algemeen + Algemeen Page Flow - Omslagbrowser + Omslagverkenner Image adjustment - Beeldaanpassing + Afbeeldingen inpassen Options - Opties + Opties Comics directory - Strips map + Stripsmap @@ -744,12 +744,12 @@ 7z lib not found - + 7Z is niet aangetroffen unable to load 7z lib from ./utils - + kan 7z niet laden uit ./utils @@ -757,17 +757,17 @@ YACReader keyboard shortcuts - YACReader sneltoetsen + YACReader-sneltoetsen Close - Sluiten + Sluiten Keyboard Shortcuts - Sneltoetsen + Sneltoetsen @@ -776,47 +776,47 @@ Press 'O' to open comic. - Druk 'O' om een strip te openen. + Druk op 'O' om een strip te openen. Not found - Niet gevonden + Niet aangetroffen Comic not found - Strip niet gevonden + Strip is niet aangetroffen Error opening comic - + Fout tijdens openen CRC Error - + CRC-fout Loading...please wait! - Inladen...even wachten! + Bezig met laden... Page not available! - + De bladzijde is niet beschikbaar! Cover! - Omslag! + Omslag! Last page! - Laatste pagina! + Laatste pagina! @@ -825,12 +825,12 @@ Click to overwrite - Klik hier om te overschrijven + Klik hier om te overschrijven Restore to default - Standaardwaarden herstellen + Standaardwaarden herstellen @@ -841,12 +841,12 @@ Click to overwrite - Klik hier om te overschrijven + Klik hier om te overschrijven Restore to default - Standaardwaarden herstellen + Standaardwaarden herstellen @@ -854,22 +854,22 @@ How to show covers: - Omslagbladen bekijken: + Omslagbladweergave: CoverFlow look - Omslagbrowser uiterlijk + Vormgeving van omslagverkenner Stripe look - Brede band + Strepen gebruiken Overlapped Stripe look - Overlappende band + Overlappende strepen gebruiken @@ -877,117 +877,117 @@ Presets: - Voorinstellingen: + Voorinstellingen: Classic look - Klassiek + Klassiek Stripe look - Brede band + Gestreept Overlapped Stripe look - Overlappende band + Overlappend gestreept Modern look - Modern + Modern Roulette look - Roulette + Roulette Show advanced settings - Toon geavanceerde instellingen + Geavanceerde instellingen tonen Custom: - Aangepast: + Aangepast: View angle - Kijkhoek + Kijkhoek Position - Positie + Positie Cover gap - Ruimte tss Omslag + Ruimte tussen omslagen Central gap - Centrale ruimte + Centrale ruimte Zoom - Zoom + Zoom Y offset - Y-positie + Y-positie Z offset - Z- positie + Z-positie Cover Angle - Omslag hoek + Omslaghoek Visibility - Zichtbaarheid + Zichtbaarheid Light - Licht + Licht Max angle - Maximale hoek + Maximale hoek Low Performance - Lage Prestaties + Lage prestaties High Performance - Hoge Prestaties + Hoge prestaties Use VSync (improve the image quality in fullscreen mode, worse performance) - Gebruik VSync (verbetering van de beeldkwaliteit in de modus volledig scherm, slechtere prestatie) + VSync gebruiken (verbetert de beeldkwaliteit in de beeldvullende modus, maar vermindert de prestaties) Performance: - Prestatie: + Prestaties: @@ -995,27 +995,27 @@ Save - Bewaar + Opslaan Cancel - Annuleren + Annuleren Edit shortcuts - + Sneltoetsen aanpassen Shortcuts - + Sneltoetsen Use hardware acceleration (restart needed) - Gebruik hardware versnelling (opnieuw opstarten vereist) + Hardwareversnelling gebruiken (herstart vereist) @@ -1023,7 +1023,7 @@ Reset - Standaardwaarden terugzetten + Standaardwaarden @@ -1031,23 +1031,23 @@ YACReader translator - + YACReader-vertaler Translation - + Vertaling clear - + wissen Service not available - + Dienst niet beschikbaar diff --git a/YACReaderLibrary/yacreaderlibrary_nl.ts b/YACReaderLibrary/yacreaderlibrary_nl.ts index 3823cc6ac..409b53757 100644 --- a/YACReaderLibrary/yacreaderlibrary_nl.ts +++ b/YACReaderLibrary/yacreaderlibrary_nl.ts @@ -1,12 +1,12 @@ - + ActionsShortcutsModel None - + Geen @@ -14,82 +14,82 @@ Label name: - + Labelnaam: Choose a color: - + Kies een kleur: red - + rood orange - + oranje yellow - + geel green - + groen cyan - + groenblauw blue - + blauw violet - + violet purple - + paars pink - + roze white - + wit light - + licht dark - + donker accept - + toepassen cancel - annuleren + annuleren @@ -97,28 +97,28 @@ Comics folder : - Strips map: + Stripsmap: Library name : Library Name : - Bibliotheek Naam : + Bibliotheeknaam: Add - Toevoegen + Toevoegen Cancel - Annuleren + Annuleren Add an existing library - Voeg een bestaand bibliotheek toe + Voeg een bestaande bibliotheek toe @@ -126,22 +126,22 @@ Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - + Om te verbinden met Comic Vine heb je je eigen api-sleutel nodig - die kun je <a href="http://www.comicvine.com/api/">hier</a> gratis genereren. Paste here your Comic Vine API key - + Plak hier de api-sleutel Accept - + Verbinden Cancel - Annuleren + Annuleren @@ -149,7 +149,7 @@ Hide comic flow - Sluit de Omslagbrowser + Omslagverkenner verbergen @@ -157,57 +157,57 @@ Authors - Auteurs + Auteurs writer - + schrijver penciller - + tekenaar inker - + inkter colorist - + inkleurder letterer - + letteraar cover artist - + omslagartiest Publisher - + Uitgever color - + kleur b/w - + z/w Characters - + Tekens @@ -215,47 +215,47 @@ yes - Ja + ja no - neen + nee Title - Titel + Titel File Name - Bestandsnaam + Bestandsnaam Pages - Pagina's + Pagina's Size - Grootte(MB) + Grootte Read - Gelezen + Gelezen Current Page - + Huidige pagina Rating - + Beoordeling @@ -263,27 +263,27 @@ skip - + overslaan back - + vorige next - + volgende search - + zoeken close - + sluiten @@ -292,39 +292,39 @@ Looking for volume... - + Bezig met zoeken... comic %1 of %2 - %3 - + strip %1 van %2 - %3 %1 comics selected - + %1 strips geselecteerd Error connecting to ComicVine - + Kan niet verbinden met ComicVine Retrieving tags for : %1 - + Bezig met ophalen van tags voor %1... Retrieving volume info... - + Bezig met ophalen van informatie... Looking for comic... - + Bezig met zoeken naar strip... @@ -332,42 +332,42 @@ Comics folder : - Strips map: + Stripsmap: Library Name : - Bibliotheek Naam : + Bibliotheeknaam: Create - Aanmaken + Aanmaken Cancel - Annuleren + Annuleren Create a library could take several minutes. You can stop the process and update the library later for completing the task. - Een bibliotheek aanmaken kan enkele minuten duren. U kunt het proces stoppen en de bibliotheek later voltooien. + Het aanmaken van een bibliotheek kan enkele minuten duren. Je kunt het proces afbreken en de bibliotheek later voltooien. Create new library - Een nieuwe Bibliotheek aanmaken + Bibliotheek aanmaken Path not found - Pad niet gevonden + Pad niet aangetroffen The selected path does not exist or is not a valid path. Be sure that you have write access to this folder - De geselecteerde pad bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map + Het gekozen pad bestaat niet of is ongeldig. Controleer of je schrijftoegang hebt op deze map. @@ -375,27 +375,27 @@ Restore defaults - + Standaardwaarden herstellen To change a shortcut, double click in the key combination and type the new keys. - + Dubbelklik op de toetscombinatie en dan op de nieuwe toetsen om de sneltoets te wijzigen. Shortcuts settings - + Sneltoetsinstellingen Shortcut in use - + Sneltoets is in gebruik The shortcut "%1" is already assigned to other function - + De sneltoets '%1' is al toegewezen aan een andere functie @@ -404,17 +404,17 @@ Subfolders in this folder - + Onderliggende mappen in deze map Empty folder - + Lege map Drag and drop folders and comics here - + Sleep mappen en strips hierheen @@ -422,7 +422,7 @@ This label doesn't contain comics yet - + Dit label bevat nog geen strips @@ -431,7 +431,7 @@ This reading list does not contain any comics yet This reading list doesn't contain comics yet - + Deze leeslijst bevat nog geen strips @@ -439,37 +439,37 @@ Output file : - Uitvoerbestand: + Uitvoerbestand: Create - Aanmaken + Aanmaken Cancel - Annuleren + Annuleren Export comics info - Strip info exporteren + Stripinformatie exporteren Destination database name - Bestemmingsdatabase naam + Naam van bestemmingsdatabank Problem found while writing - Probleem bij het schrijven + Probleem bij het wegschrijven The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Het gekozen pad voor het uitvoerbestand bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map + Het gekozen pad voor het uitvoerbestand bestaat niet of is ongeldig. Controleer of je schrijftoegang hebt op deze map. @@ -477,37 +477,37 @@ Output folder : - Uitvoermap : + Uitvoermap: Create - Aanmaken + Aanmaken Cancel - Annuleren + Annuleren Create covers package - Aanmaken omslag pakket + Omslagpakket samenstellen Problem found while writing - Probleem bij het schrijven + Probleem bij het wegschrijven The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Het gekozen pad voor het uitvoerbestand bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map + Het gekozen pad voor het uitvoerbestand bestaat niet of is ongeldig. Controleer of je schrijftoegang hebt op deze map. Destination directory - Doeldirectory + Bestemmingsmap @@ -515,22 +515,22 @@ Unknown error opening the file - + Onbekende fout tijdens openen van bestand 7z not found - 7Z Archiefbestand niet gevonden + 7z is niet aangetroffen Format not supported - + Dit formaat wordt niet ondersteund CRC error on page (%1): some of the pages will not be displayed correctly - + CRC-fout op pagina (%1): sommige pagina's worden niet goed getoond @@ -538,7 +538,7 @@ Show info - + Informatie tonen @@ -546,12 +546,12 @@ About - Over + Over Help - Help + Hulp @@ -559,27 +559,27 @@ Import comics info - Strip info Importeren + Stripinformatie importeren Info database location : - Info database locatie : + Locatie van informatiedatabank: Import - Importeren + Importeren Cancel - Annuleren + Annuleren Comics info file (*.ydb) - Strips info bestand ( * .ydb) + Stripinformatiebestand ( * .ydb) @@ -587,37 +587,37 @@ Library Name : - Bibliotheek Naam : + Bibliotheeknaam: Package location : - Arrangement locatie : + Pakketlocatie: Destination folder : - Doelmap: + Bestemmingsmap: Unpack - Uitpakken + Uitpakken Cancel - Annuleren + Annuleren Extract a catalog - Een catalogus uitpakken + Catalogus uitpakken Compresed library covers (*.clc) - Compresed omslag- bibliotheek ( * .clc) + Ingepakte bibliotheekomslagen ( * .clc) @@ -625,42 +625,42 @@ stop - stop + afbreken Some of the comics being added... - Enkele strips zijn toegevoegd ... + Bezig met toevoegen van enkele strips... Importing comics - Strips importeren + Bezig met importeren <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - <P>YACReaderLibrary maak nu een nieuwe bibliotheek. < /p> <p>Een bibliotheek aanmaken kan enkele minuten duren. U kunt het proces stoppen en de bibliotheek later voltooien. < /p> + <p>YACReaderLibrary maakt een nieuwe bibliotheek aan.</p><p>Dit kan enkele minuten duren. Je kunt het proces afbreken en de bibliotheek later nog bijwerken.</p> Updating the library - Actualisering van de bibliotheek + Bezig met bijwerken <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> - <P>De huidige bibliotheek wordt bijgewerkt. Voor snellere updates, update uw bibliotheken regelmatig. < /p> <p>u kunt het proces stoppen om later bij te werken. < /p> + <p>De huidige bibliotheek wordt bijgewerkt. Als je dit proces wilt bespoedigen, werk je bibliotheek dan regelmatig bij.</p><p>Je kunt het proces afbreken en later bijwerken.</p> Upgrading the library - + Bezig met opwaarderen <p>The current library is being upgraded, please wait.</p> - + <p>De huidige bibliotheek wordt opgewaardeerd - even geduld...</p> @@ -668,12 +668,12 @@ YACReader Library - YACReader Bibliotheek + YACReader-bibliotheek Library - Bibliotheek + Bibliotheek <font color='white'> press 'F' to close fullscreen mode </font> @@ -682,121 +682,121 @@ Create a new library - Maak een nieuwe Bibliotheek + Bibliotheek aanmaken Open an existing library - Open een bestaande Bibliotheek + Bestaande bibliotheek openen Export comics info - Exporteren van strip info + Stripinformatie exporteren Import comics info - Importeren van strip info + Stripinformatie importeren Pack covers - Inpakken strip voorbladen + Omslagen inpakken Pack the covers of the selected library - Inpakken alle strip voorbladen van de geselecteerde Bibliotheek + Pak de omslagen van de geselecteerde bibliotheek in Unpack covers - Uitpakken voorbladen + Omslagen uitpakken Unpack a catalog - Uitpaken van een catalogus + Catalogus uitpakken Update library - Bibliotheek bijwerken + Bibliotheek bijwerken Update current library - Huidige Bibliotheek bijwerken + Huidige bibliotheek bijwerken Rename library - Bibliotheek hernoemen + Bibliotheeknaam wijzigen Rename current library - Huidige Bibliotheek hernoemen + Huidige bibliotheeknaam wijzigen Remove library - Bibliotheek verwijderen + Bibliotheek verwijderen Remove current library from your collection - De huidige Bibliotheek verwijderen uit uw verzameling + Huidige bibliotheek verwijderen uit je verzameling Open current comic - Huidige strip openen + Huidige strip openen Open current comic on YACReader - Huidige strip openen in YACReader + Huidige strip openen in YACReader Save selected covers to... - + Geselecteerde omslagen opslaan in... Save covers of the selected comics as JPG files - + Omslagen opslaan als jpg-bestanden Set as read - Instellen als gelezen + Markeren als gelezen Set comic as read - Strip Instellen als gelezen + Strip markeren als gelezen Set as unread - Instellen als ongelezen + Markeren als ongelezen Set comic as unread - Strip Instellen als ongelezen + Strip markeren als ongelezen Show/Hide marks - Toon/Verberg markeringen + Markeringen tonen/verbergen Show or hide readed marks @@ -806,13 +806,13 @@ Library not available Library ' - Bibliotheek niet beschikbaar + Bibliotheek niet beschikbaar Fullscreen mode on/off - Volledig scherm modus aan/of + Beeldvullende modus aan/uit Fullscreen mode on/off (F) @@ -821,12 +821,12 @@ Help, About YACReader - Help, Over YACReader + Hulp, Over YACReader Select root node - Selecteer de hoofd categorie + Kies de hoofdcategorie + @@ -835,7 +835,7 @@ Expand all nodes - Alle categorieën uitklappen + Alle categorieën uitklappen - @@ -848,47 +848,47 @@ Show options dialog - Toon opties dialoog + Toon het optievenster Show comics server options dialog - Toon strips-server opties dialoog + Toon het strips-serveroptiesvenster Open folder... - Map openen ... + Map openen... Set as uncompleted - + Markeren als nog niet uitgelezen Set as completed - + Markeren als uitgelezen Open containing folder... - Open map ... + Bijbehorende map openen... Reset comic rating - + Beoordeling herstellen Select all comics - Selecteer alle strips + Alle strips selecteren Edit - Bewerken + Bewerken Asign current order to comics @@ -897,12 +897,12 @@ Update cover - Strip omslagen bijwerken + Omslag bijwerken Delete selected comics - Geselecteerde strips verwijderen + Geselecteerde strips verwijderen Hide comic flow @@ -911,107 +911,107 @@ Download tags from Comic Vine - + Labels ophalen van Comic Vine Edit shortcuts - + Sneltoetsen aanpassen Update folder - + Map bijwerken Update current folder - + Huidige map bijwerken Add new reading list - + Leeslijst toevoegen Add a new reading list to the current library - + Voeg een nieuwe leeslijst toe aan de huidige bibliotheek Remove reading list - + Leeslijst verwijderen Remove current reading list from the library - + Verwijder de huidige leeslijst uit de bibliotheek Add new label - + Label toevoegen Add a new label to this library - + Voeg een label toe aan deze bibliotheek Rename selected list - + Lijstnaam wijzigen Rename any selected labels or lists - + Label- of lijstnamen wijzigen Add to... - + Toevoegen aan... Favorites - + Favorieten Add selected comics to favorites list - + Voeg de geselecteerde strips toe aan je favorieten Folder - + Map Comic - + Strip Upgrade failed - + Opwaarderen mislukt There were errors during library upgrade in: - + Er zijn fouten opgetreden tijdens het opwaarderen van de bibliotheek: Update needed - Bijwerken is nodig + Bijwerken benodigd This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - Deze bibliotheek is gemaakt met een vorige versie van YACReaderLibrary. Het moet worden bijgewerkt. Nu bijwerken? + Deze bibliotheek is gemaakt met een vorige versie van YACReaderLibrary en moet worden bijgewerkt. Wil je dat nu doen? Update failed @@ -1024,110 +1024,110 @@ Download new version - Nieuwe versie ophalen + Nieuwe versie ophalen This library was created with a newer version of YACReaderLibrary. Download the new version now? - Deze bibliotheek is gemaakt met een nieuwere versie van YACReaderLibrary. Download de nieuwe versie? + Deze bibliotheek is gemaakt met een nieuwere versie van YACReaderLibrary. Wil je de nieuwe versie ophalen? Library '%1' is no longer available. Do you want to remove it? - Bibliotheek ' %1' is niet langer beschikbaar. Wilt u het verwijderen? + De bibliotheek ' %1' is niet meer beschikbaar. Wil je deze verwijderen? Old library - Oude Bibliotheek + Oude bibliotheek Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Bibliotheek ' %1' is gemaakt met een oudere versie van YACReaderLibrary. Zij moet opnieuw worden aangemaakt. Wilt u de bibliotheek nu aanmaken? + De bibliotheek '%1' is gemaakt met een oudere versie van YACReaderLibrary en moet opnieuw worden aangemaakt. Wil je dat nu doen? Copying comics... - + Bezig met kopiëren van strips... Moving comics... - + Bezig met verplaatsen van scripts... Folder name: - + Mapnaam: No folder selected - + Geen map geselecteerd Please, select a folder first - + Selecteer een map Error in path - + Fout in pad There was an error accessing the folder's path - + Er is een fout in het mappad The selected folder and all its contents will be deleted from your disk. Are you sure? - + De geselecteerde map en alle inhoud ervan wordt verwijderd van je schijf. Weet je het zeker? There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - + Er is een fout opgetreden tijdens het verwijderen van de geselecteerde mappen. Controleer of je schrijfrechten hebt en of ze niet in gebruik zijn door andere programma's. Add new reading lists - + Leeslijsten toevoegen List name: - + Lijstnaam: Delete list/label - + Lijst/Label verwijderen The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - + Het geselecteerde item wordt verwijderd, maar je strips en mappen niet. Weet je het zeker? Rename list name - + Lijstnaam wijzigen Save covers - + Omslagen opslaan You are adding too many libraries. - + Je voegt te veel bibliotheken toe. @@ -1136,117 +1136,121 @@ You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - + Je voegt te veel bibliotheken toe. + +Waarschijnlijk heb je slechts één bibliotheek nodig in de hoofdmap van je strips. Je kunt onderliggende mappen verkennen in de mappensectie in de linkerzijbalk.. + +YACReaderLibrary weerhoudt je er niet van meerdere bibliotheken aan te maken, maar maak er niet te veel aan. YACReader not found - + YACReader is niet aangetroffen Library not found - Bibliotheek niet gevonden + De bibliotheek is niet aangetroffen The selected folder doesn't contain any library. - De geselecteerde map bevat geen bibliotheek. + De geselecteerde map bevat geen bibliotheek. Are you sure? - Weet u het zeker? + Weet je het zeker? Do you want remove - Wilt u verwijderen + Wil je de library? - Bibliotheek? + bibliotheek verwijderen? Remove and delete metadata - Verwijder metagegevens + Verwijderen, inclusief metagegevens Assign comics numbers - + Stripnummers toekennen Assign numbers starting in: - + Toekennen vanaf: Unable to delete - + Verwijderen mislukt Show or hide read marks - + Leesmarkeringen tonen/verbergen Add new folder - + Map toevoegen Add new folder to the current library - + Voeg een nieuwe map toe aan de huidige bibliotheek Delete folder - + Map verwijderen Delete current folder from disk - + Verwijder de huidige map van de schijf Collapse all nodes - + Alles inklappen Change between comics views - + Andere stripweergave Assign current order to comics - + Huidige volgorde toepassen op strips YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - + YACReader is niet aangetroffen. YACReader dient te worden geïnstalleerd in dezelfde map als YACReaderLibrary. YACReader not found. There might be a problem with your YACReader installation. - + YACReader is niet aangetroffen. Mogelijk is er een probleem met je YACReader-installatie. There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - + Er is een probleem opgetreden tijdens het verwijderen. Controleer of je schrijfrechten hebt op de geselecteerde bestanden en bijbehorende map. Asign comics numbers @@ -1259,47 +1263,47 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Error creating the library - Fout bij aanmaken Bibliotheek + Fout bij aanmaken van bibliotheek Error updating the library - Fout bij bijwerken Bibliotheek + Fout bij bijwerken van bibliotheek Error opening the library - Fout bij openen Bibliotheek + Fout bij openen van bibliotheek Delete comics - Strips verwijderen + Strips verwijderen All the selected comics will be deleted from your disk. Are you sure? - Alle geselecteerde strips worden verwijderd van uw schijf. Weet u het zeker? + Alle geselecteerde strips worden verwijderd van de schijf. Weet je het zeker? Remove comics - + Strips verwijderen Comics will only be deleted from the current label/list. Are you sure? - + De strips worden alleen verwijderd het huidige label/de huidige lijst. Weet je het zeker? Library name already exists - Bibliotheek naam bestaat al + Bibliotheeknaam is al in gebruik There is another library with the name '%1'. - Er is al een bibliotheek met de naam ' %1 '. + Er is al een bibliotheek met de naam '%1'. @@ -1307,7 +1311,7 @@ YACReaderLibrary will not stop you from creating more libraries but you should k file name - + bestandsnaam @@ -1315,22 +1319,22 @@ YACReaderLibrary will not stop you from creating more libraries but you should k You don't have any libraries yet - Je hebt geen nog libraries + Je hebt nog geen nog bibliotheken <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> - <P>u kunt een bibliotheek maken in een willekeurige map, YACReaderLibrary importeert alle strips en mappen uit deze map. Alle bibliotheek aangemaakt in het verleden kan je openen. < /p> <p>vergeet niet dat u YACReader kan gebruiken als stand-alone applicatie voor het lezen van de strips op de computer. < /p> + <p>Je kunt een bibliotheek maken in een willekeurige map - YACReaderLibrary importeert alle strips en mappen uit deze map. Je kunt alle eerder gemaakte bibliotheken openen.</p><p>Je kunt YACReader gebruiken als losstaand programma voor het lezen van strips.</p> create your first library - Maak uw eerste bibliotheek + Maak je eerste bibliotheek add an existing one - voeg een bestaande bibliotheek toe + Voeg een bestaande bibliotheek toe @@ -1338,62 +1342,62 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Edit Comic Vine API key - + Comic Vine-api-sleutel aanpassen Comic Vine API key - + Comic Vine-api-sleutel Enable background image - + Achtergrondafbeelding gebruiken Opacity level - + Doorzichtigheidsniveau Blur level - + Vervaagintensiteit Use selected comic cover as background - + Geselecteerde omslag instellen als achtergrond Restore defautls - + Standaardwaarden herstellen Background - + Achtergrond Comic Flow - + Omslagverkenner Grid view - + Roosterweergave General - + Algemeen Options - Opties + Opties @@ -1401,174 +1405,174 @@ YACReaderLibrary will not stop you from creating more libraries but you should k General info - Algemene Info + Algemene informatie Authors - Auteurs + Auteurs Publishing - Uitgever + Uitgever Plot - Verhaal + Verhaal Cover page - Omslag + Omslagpagina Title: - Titel: + Titel: of: - + van: Issue number: - Ids: + Uitgavenummer: Volume: - Inhoud: + Inhoud: Arc number: - + Verhaallijnnummer: Story arc: - Verhaallijn: + Verhaallijn: Genre: Genere: - Genre: + Genre: Size: - Grootte(MB): + Grootte: Writer(s): - Schrijver(s): + Schrijver(s): Penciller(s): - Tekenaar(s): + Tekenaar(s): Inker(s): - Inker(s): + Inkter(s): Colorist(s): - Inkleurder(s): + Inkleurder(s): Letterer(s): - Letterzetter(s): + Letterzetter(s): Cover Artist(s): - Omslag ontwikkelaar(s): + Omslagartiest(en): Day: - Dag: + Dag: Month: - Maand: + Maand: Year: - Jaar: + Jaar: Publisher: - Uitgever: + Uitgever: Format: - Formaat: + Formaat: Color/BW: - Kleur/ZW: + Kleur/ZW: Age rating: - Leeftijdsbeperking: + Leeftijdsbeperking: Synopsis: - Synopsis: + Synopsis: Characters: - Personages: + Personages: Notes: - Opmerkingen: + Opmerkingen: Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - + Comic Vine-link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> bekijken </a> Not found - Niet gevonden + Niet gevonden Comic not found. You should update your library. - Strip niet gevonden. U moet uw bibliotheek.bijwerken. + Strip niet gevonden. Werk je bibliotheek bij. Edit selected comics information - Geselecteerde strip informatie bijwerken + Geselecteerde stripinformatie bijwerken Edit comic information - Strip informatie bijwerken + Stripinformatie bijwerken @@ -1576,12 +1580,12 @@ YACReaderLibrary will not stop you from creating more libraries but you should k 7z lib not found - + 7z-bibliotheek niet aangetroffen unable to load 7z lib from ./utils - + De 7z-bibliotheek kan niet worden geladen uit ./utils @@ -1589,22 +1593,22 @@ YACReaderLibrary will not stop you from creating more libraries but you should k New Library Name : - Nieuwe Bibliotheek Naam : + Nieuwe bibliotheeknaam: Rename - Hernoem + Naam wijzigen Cancel - Annuleren + Annuleren Rename current library - Hernoem de huidige bibiliotheek + Wijzig de naam van de huidige bibiliotheek @@ -1612,18 +1616,18 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Number of volumes found : %1 - + Aantal aangetroffen delen: %1 page %1 of %2 - + pagina %1 van %2 Number of %1 found : %2 - + Aantal gevonden %1: %2 @@ -1631,12 +1635,12 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Please provide some additional information. - + Voer aanvullende informatie in. Series: - + Serie: @@ -1644,12 +1648,12 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Please provide some additional information. - + Voer aanvullende informatie in. Series: - + Serie: @@ -1657,27 +1661,27 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Please, select the right comic info. - + Kies de juiste stripinformatie. comics - + strips loading cover - + bezig met laden van omslag loading description - + bezig met laden van omschrijving description unavailable - + geen omschrijving beschikbaar @@ -1685,27 +1689,27 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Please, select the right series for your comic. - + Kies de juiste stripserie. volumes - + delen loading cover - + bezig met laden van omslag loading description - + bezig met laden van omschrijving description unavailable - + geen omschrijving beschikbaar @@ -1713,17 +1717,17 @@ YACReaderLibrary will not stop you from creating more libraries but you should k You are trying to get information for various comics at once, are they part of the same series? - + Je probeert informatie van verschillende strips tegelijkertijd op te halen. Zijn ze uit dezelfde serie? yes - Ja + Ja no - neen + Nee @@ -1731,7 +1735,7 @@ YACReaderLibrary will not stop you from creating more libraries but you should k set port - Poort instellen + Poort instellen EASY SERVER CONNECTION @@ -1756,43 +1760,44 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Server connectivity information - + Serververbindingsinformatie Scan it! - + Scannen! YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - + YACReader is beschikbaar op iOS-apparaten. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Bekijk de app! </a> Choose an IP address - + Kies een ip-adres Port - Poort + Poort enable the server - De server instellen + server inschakelen display less information about folders in the browser to improve the performance - + toon minder mapinformatie in de verkenner om de +prestaties te verbeteren Could not load libqrencode. - + Kan libqrencode niet laden. QR generator error! @@ -1804,27 +1809,27 @@ to improve the performance Please, sort the list of comics on the left until it matches the comics' information. - + Sorteer de striplijst links zodat deze overeenkomt met de stripinformatie. sort comics to match comic information - + strips sorteren om overeen te komen met stripinformatie issues - + uitgaven remove selected comics - + geselecteerde strips verwijderen restore all removed comics - + alle verwijderde strips herstellen @@ -1863,7 +1868,7 @@ to improve the performance SEARCH - + ZOEKEN @@ -1871,17 +1876,17 @@ to improve the performance Updating.... - Bijwerken.... + Bezic met bijwerken.... Cancel - Annuleren + Annuleren Update library - Bibliotheek bijwerken + Bibliotheek bijwerken @@ -1889,7 +1894,7 @@ to improve the performance title - + titel @@ -1897,17 +1902,17 @@ to improve the performance year - + jaar issues - + uitgaven publisher - + uitgever @@ -1915,12 +1920,12 @@ to improve the performance Please wait, deleting in progress... - Even geduld, verwijderen ... + Bezig met verwijderen... cancel - annuleren + annuleren @@ -1929,12 +1934,12 @@ to improve the performance Click to overwrite - Klik hier om te overschrijven + Klik hier om te overschrijven Restore to default - Standaardwaarden herstellen + Standaardwaarden herstellen @@ -1945,12 +1950,12 @@ to improve the performance Click to overwrite - Klik hier om te overschrijven + Klik hier om te overschrijven Restore to default - Standaardwaarden herstellen + Standaardwaarden herstellen @@ -1958,22 +1963,22 @@ to improve the performance How to show covers: - Hoe omslagbladen bekijken: + Omslagbladweergave: CoverFlow look - Omslagbrowser uiterlijk + Vormgeving van omslagverkenner Stripe look - Brede band + Strepen gebruiken Overlapped Stripe look - Overlappende band + Overlappende strepen gebruiken @@ -1981,117 +1986,117 @@ to improve the performance Presets: - Voorinstellingen: + Voorinstellingen: Classic look - Klassiek + Klassiek Stripe look - Brede band + Gestreept Overlapped Stripe look - Overlappende band + Overlappend gestreept Modern look - Modern + Modern Roulette look - Roulette + Roulette Show advanced settings - Toon geavanceerde instellingen + Geavanceerde instellingen tonen Custom: - Aangepast: + Aangepast: View angle - Kijkhoek + Kijkhoek Position - Positie + Positie Cover gap - Ruimte tss Omslag + Ruimte tussen omslagen Central gap - Centrale ruimte + Centrale ruimte Zoom - Zoom + Zoom Y offset - Y-positie + Y-positie Z offset - Z- positie + Z-positie Cover Angle - Omslag hoek + Omslaghoek Visibility - Zichtbaarheid + Zichtbaarheid Light - Licht + Licht Max angle - Maximale hoek + Maximale hoek Low Performance - Lage Prestaties + Lage prestaties High Performance - Hoge Prestaties + Hoge prestaties Use VSync (improve the image quality in fullscreen mode, worse performance) - Gebruik VSync (verbetering van de beeldkwaliteit in de modus volledig scherm, slechtere prestatie) + VSync gebruiken (verbetert de beeldkwaliteit in de beeldvullende modus, maar zorgt voor slechtere prestatie) Performance: - Prestatie: + Prestaties: @@ -2099,12 +2104,12 @@ to improve the performance No favorites - + Geen favorieten You are not reading anything yet, come on!! - + Je bent nog niks aan het lezen. Open eens wat! @@ -2112,27 +2117,27 @@ to improve the performance Save - Bewaar + Opslaan Cancel - Annuleren + Annuleren Edit shortcuts - + Sneltoetsen aanpassen Shortcuts - + Sneltoetsen Use hardware acceleration (restart needed) - Gebruik hardware versnelling (opnieuw opstarten vereist) + Hardwareversnelling gebruiken (herstart vereist) @@ -2140,7 +2145,7 @@ to improve the performance type to search - + typ om te zoeken @@ -2148,32 +2153,32 @@ to improve the performance Libraries - + Bibliotheken Folders - + Mappen Reading Lists - + Leeslijsten LIBRARIES - BIBLIOTHEKEN + BIBLIOTHEKEN FOLDERS - MAPPEN + MAPPEN READING LISTS - + LEESLIJSTEN Search folders and comics From e79ea56d324c8743232afcf8340e9a87f9a9f9f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20A=CC=81ngel=20San=20Marti=CC=81n?= Date: Sat, 5 Dec 2020 14:49:54 +0100 Subject: [PATCH 003/141] Fix format --- YACReaderLibrary/properties_dialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YACReaderLibrary/properties_dialog.cpp b/YACReaderLibrary/properties_dialog.cpp index 3d8724969..5dee384e2 100644 --- a/YACReaderLibrary/properties_dialog.cpp +++ b/YACReaderLibrary/properties_dialog.cpp @@ -305,7 +305,7 @@ void PropertiesDialog::createButtonBox() QImage blurred(const QImage &image, const QRect &rect, int radius, bool alphaOnly = false) { int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 }; - int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius - 1]; + int alpha = (radius < 1) ? 16 : ((radius > 17) ? 1 : tab[radius - 1]); QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); int r1 = rect.top(); From c4f792bd4044cdc92a7f09ed29760c3c837374ab Mon Sep 17 00:00:00 2001 From: Felix Kauselmann Date: Wed, 25 Nov 2020 21:12:16 +0100 Subject: [PATCH 004/141] Fix port settings When setting ports, temporary or for good, we need to go via the config files and not QTcpServer or we get undefined behavior. To support temp ports, we need to back up the fixed port in the settings. --- YACReaderLibrary/server/startup.cpp | 38 +++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/YACReaderLibrary/server/startup.cpp b/YACReaderLibrary/server/startup.cpp index 93781a1c9..5afa00d05 100644 --- a/YACReaderLibrary/server/startup.cpp +++ b/YACReaderLibrary/server/startup.cpp @@ -110,20 +110,42 @@ void Startup::start(quint16 port) if (listenerSettings->value("minThreads").isNull()) listenerSettings->setValue("minThreads", 50); - listener = new HttpListener(listenerSettings, new RequestMapper(app), app); + if (listenerSettings->value("port").isNull()) + listenerSettings->setValue("port", 8080); + // start with a temporary port if (port != 0) { - if (listener->isListening()) { - listener->close(); + // cache saved port + if (!listenerSettings->contains("cachedPort")) { + listenerSettings->setValue("cachedPort", listenerSettings->value("port").toInt()); + } + listenerSettings->setValue("port", port); + } else { + // restore saved port + if (listenerSettings->contains("cachedPort")) { + listenerSettings->setValue("port", listenerSettings->value("cachedPort")); + listenerSettings->remove("cachedPort"); } - listener->QTcpServer::listen(QHostAddress::Any, port); } - // if the requested port is busy, use random port - if (!listener->isListening()) { - listener->QTcpServer::listen(QHostAddress::Any, 0); + // test if port is working + { + QTcpServer testServer; + if (!testServer.listen(QHostAddress::Any, listenerSettings->value("port").toInt())) { + qDebug("Port is busy."); + // get random port + testServer.listen(QHostAddress::Any, 0); + listenerSettings->setValue("port", testServer.serverPort()); + } + testServer.close(); } - qDebug("ServiceHelper: Service has started"); + listener = new HttpListener(listenerSettings, new RequestMapper(app), app); + + if (listener->isListening()) { + qDebug("ServiceHelper: Service has started"); + } else { + qDebug("ServiceHelper: Could not launch service"); + } } void Startup::stop() From d3de52ca82189421502c2fb53e53673480177cbc Mon Sep 17 00:00:00 2001 From: Iain Benson Date: Fri, 16 Nov 2018 22:34:49 +0000 Subject: [PATCH 005/141] Add commit 43aab01 of BenHanson/lexertl14 from github --- YACReaderLibrary/YACReaderLibrary.pro | 40 +- YACReaderLibrary/lexertl/char_traits.hpp | 45 + YACReaderLibrary/lexertl/debug.hpp | 311 ++ YACReaderLibrary/lexertl/dot.hpp | 293 ++ YACReaderLibrary/lexertl/enums.hpp | 25 + YACReaderLibrary/lexertl/generate_cpp.hpp | 1123 ++++++ YACReaderLibrary/lexertl/generator.hpp | 738 ++++ YACReaderLibrary/lexertl/internals.hpp | 75 + YACReaderLibrary/lexertl/iterator.hpp | 135 + YACReaderLibrary/lexertl/licence_1_0.txt | 24 + YACReaderLibrary/lexertl/lookup.hpp | 491 +++ YACReaderLibrary/lexertl/match_results.hpp | 171 + YACReaderLibrary/lexertl/memory_file.hpp | 138 + YACReaderLibrary/lexertl/narrow.hpp | 25 + YACReaderLibrary/lexertl/observer_ptr.hpp | 16 + YACReaderLibrary/lexertl/parser/parser.hpp | 926 +++++ .../lexertl/parser/tokeniser/re_token.hpp | 100 + .../lexertl/parser/tokeniser/re_tokeniser.hpp | 778 ++++ .../parser/tokeniser/re_tokeniser_helper.hpp | 3157 +++++++++++++++++ .../parser/tokeniser/re_tokeniser_state.hpp | 136 + .../lexertl/parser/tree/end_node.hpp | 111 + .../lexertl/parser/tree/iteration_node.hpp | 96 + .../lexertl/parser/tree/leaf_node.hpp | 110 + YACReaderLibrary/lexertl/parser/tree/node.hpp | 242 ++ .../lexertl/parser/tree/selection_node.hpp | 104 + .../lexertl/parser/tree/sequence_node.hpp | 121 + .../lexertl/partition/charset.hpp | 72 + .../lexertl/partition/equivset.hpp | 135 + YACReaderLibrary/lexertl/rules.hpp | 1018 ++++++ YACReaderLibrary/lexertl/runtime_error.hpp | 23 + YACReaderLibrary/lexertl/serialise.hpp | 28 + YACReaderLibrary/lexertl/sm_to_csm.hpp | 53 + YACReaderLibrary/lexertl/sm_traits.hpp | 44 + YACReaderLibrary/lexertl/state_machine.hpp | 521 +++ .../lexertl/stream_shared_iterator.hpp | 352 ++ YACReaderLibrary/lexertl/string_token.hpp | 439 +++ YACReaderLibrary/lexertl/utf_iterators.hpp | 508 +++ 37 files changed, 12723 insertions(+), 1 deletion(-) create mode 100644 YACReaderLibrary/lexertl/char_traits.hpp create mode 100644 YACReaderLibrary/lexertl/debug.hpp create mode 100644 YACReaderLibrary/lexertl/dot.hpp create mode 100644 YACReaderLibrary/lexertl/enums.hpp create mode 100644 YACReaderLibrary/lexertl/generate_cpp.hpp create mode 100644 YACReaderLibrary/lexertl/generator.hpp create mode 100644 YACReaderLibrary/lexertl/internals.hpp create mode 100644 YACReaderLibrary/lexertl/iterator.hpp create mode 100644 YACReaderLibrary/lexertl/licence_1_0.txt create mode 100644 YACReaderLibrary/lexertl/lookup.hpp create mode 100644 YACReaderLibrary/lexertl/match_results.hpp create mode 100644 YACReaderLibrary/lexertl/memory_file.hpp create mode 100644 YACReaderLibrary/lexertl/narrow.hpp create mode 100644 YACReaderLibrary/lexertl/observer_ptr.hpp create mode 100644 YACReaderLibrary/lexertl/parser/parser.hpp create mode 100644 YACReaderLibrary/lexertl/parser/tokeniser/re_token.hpp create mode 100644 YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser.hpp create mode 100644 YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_helper.hpp create mode 100644 YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_state.hpp create mode 100644 YACReaderLibrary/lexertl/parser/tree/end_node.hpp create mode 100644 YACReaderLibrary/lexertl/parser/tree/iteration_node.hpp create mode 100644 YACReaderLibrary/lexertl/parser/tree/leaf_node.hpp create mode 100644 YACReaderLibrary/lexertl/parser/tree/node.hpp create mode 100644 YACReaderLibrary/lexertl/parser/tree/selection_node.hpp create mode 100644 YACReaderLibrary/lexertl/parser/tree/sequence_node.hpp create mode 100644 YACReaderLibrary/lexertl/partition/charset.hpp create mode 100644 YACReaderLibrary/lexertl/partition/equivset.hpp create mode 100644 YACReaderLibrary/lexertl/rules.hpp create mode 100644 YACReaderLibrary/lexertl/runtime_error.hpp create mode 100644 YACReaderLibrary/lexertl/serialise.hpp create mode 100644 YACReaderLibrary/lexertl/sm_to_csm.hpp create mode 100644 YACReaderLibrary/lexertl/sm_traits.hpp create mode 100644 YACReaderLibrary/lexertl/state_machine.hpp create mode 100644 YACReaderLibrary/lexertl/stream_shared_iterator.hpp create mode 100644 YACReaderLibrary/lexertl/string_token.hpp create mode 100644 YACReaderLibrary/lexertl/utf_iterators.hpp diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 2e6d6888e..1ea60e8b0 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -147,7 +147,42 @@ HEADERS += comic_flow.h \ yacreader_comics_selection_helper.h \ yacreader_comic_info_helper.h \ db/reading_list.h \ - current_comic_view_helper.h + current_comic_view_helper.h \ + lexertl/parser/tokeniser/re_token.hpp \ + lexertl/parser/tokeniser/re_tokeniser.hpp \ + lexertl/parser/tokeniser/re_tokeniser_helper.hpp \ + lexertl/parser/tokeniser/re_tokeniser_state.hpp \ + lexertl/parser/tree/end_node.hpp \ + lexertl/parser/tree/iteration_node.hpp \ + lexertl/parser/tree/leaf_node.hpp \ + lexertl/parser/tree/node.hpp \ + lexertl/parser/tree/selection_node.hpp \ + lexertl/parser/tree/sequence_node.hpp \ + lexertl/parser/parser.hpp \ + lexertl/partition/charset.hpp \ + lexertl/partition/equivset.hpp \ + lexertl/char_traits.hpp \ + lexertl/debug.hpp \ + lexertl/dot.hpp \ + lexertl/enums.hpp \ + lexertl/generate_cpp.hpp \ + lexertl/generator.hpp \ + lexertl/internals.hpp \ + lexertl/iterator.hpp \ + lexertl/lookup.hpp \ + lexertl/match_results.hpp \ + lexertl/memory_file.hpp \ + lexertl/narrow.hpp \ + lexertl/observer_ptr.hpp \ + lexertl/rules.hpp \ + lexertl/runtime_error.hpp \ + lexertl/serialise.hpp \ + lexertl/sm_to_csm.hpp \ + lexertl/sm_traits.hpp \ + lexertl/state_machine.hpp \ + lexertl/stream_shared_iterator.hpp \ + lexertl/string_token.hpp \ + lexertl/utf_iterators.hpp !CONFIG(no_opengl) { HEADERS += ../common/gl/yacreader_flow_gl.h @@ -324,3 +359,6 @@ translation.files = ../release/languages/yacreaderlibrary_* manpage.path = $$DATADIR/man/man1 manpage.files = ../YACReaderLibrary.1 } + +DISTFILES += \ + lexertl/licence_1_0.txt diff --git a/YACReaderLibrary/lexertl/char_traits.hpp b/YACReaderLibrary/lexertl/char_traits.hpp new file mode 100644 index 000000000..e06f399a5 --- /dev/null +++ b/YACReaderLibrary/lexertl/char_traits.hpp @@ -0,0 +1,45 @@ +// char_traits.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_CHAR_TRAITS_HPP +#define LEXERTL_CHAR_TRAITS_HPP + +#include + +namespace lexertl +{ +template +struct basic_char_traits +{ + using char_type = ch_type; + using index_type = ch_type; + + static index_type max_val() + { + const std::uint32_t max_ = 0x10ffff; + + return sizeof(char_type) > 2 ? + max_ : (max_ & 0xffff); + } +}; + +template<> +struct basic_char_traits +{ + using char_type = char; + using index_type = unsigned char; + + static index_type max_val() + { + // Prevent annoying warning (VC++) + index_type zero_ = 0; + + return ~zero_; + } +}; +} + +#endif diff --git a/YACReaderLibrary/lexertl/debug.hpp b/YACReaderLibrary/lexertl/debug.hpp new file mode 100644 index 000000000..1405f3866 --- /dev/null +++ b/YACReaderLibrary/lexertl/debug.hpp @@ -0,0 +1,311 @@ +// debug.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_DEBUG_HPP +#define LEXERTL_DEBUG_HPP + +#include +#include +#include "rules.hpp" +#include "sm_to_csm.hpp" +#include "state_machine.hpp" +#include "string_token.hpp" +#include + +namespace lexertl +{ +template +class basic_debug +{ +public: + using char_state_machine = + basic_char_state_machine; + using ostream = std::basic_ostream; + using rules = basic_rules; + using string = std::basic_string; + + static void dump(const sm &sm_, rules &rules_, ostream &stream_) + { + char_state_machine csm_; + + sm_to_csm(sm_, csm_); + dump(csm_, rules_, stream_); + } + + static void dump(const sm &sm_, ostream &stream_) + { + char_state_machine csm_; + + sm_to_csm(sm_, csm_); + dump(csm_, stream_); + } + + static void dump(const char_state_machine &csm_, rules &rules_, + ostream &stream_) + { + for (std::size_t dfa_ = 0, dfas_ = csm_.size(); dfa_ < dfas_; ++dfa_) + { + lexer_state(stream_); + stream_ << rules_.state(dfa_) << std::endl << std::endl; + + dump_ex(csm_._sm_vector[dfa_], stream_); + } + } + + static void dump(const char_state_machine &csm_, ostream &stream_) + { + for (std::size_t dfa_ = 0, dfas_ = csm_.size(); dfa_ < dfas_; ++dfa_) + { + lexer_state(stream_); + stream_ << dfa_ << std::endl << std::endl; + + dump_ex(csm_._sm_vector[dfa_], stream_); + } + } + +protected: + using dfa_state = typename char_state_machine::state; + using string_token = typename dfa_state::string_token; + using stringstream = std::basic_stringstream; + + static void dump_ex(const typename char_state_machine::dfa &dfa_, + ostream &stream_) + { + const std::size_t states_ = dfa_._states.size(); + const id_type bol_index_ = dfa_._bol_index; + + for (std::size_t i_ = 0; i_ < states_; ++i_) + { + const dfa_state &state_ = dfa_._states[i_]; + + state(stream_); + stream_ << i_ << std::endl; + + if (state_._end_state) + { + end_state(stream_); + + if (state_._push_pop_dfa == dfa_state::push_dfa) + { + push(stream_); + stream_ << state_._push_dfa; + } + else if (state_._push_pop_dfa == dfa_state::pop_dfa) + { + pop(stream_); + } + + id(stream_); + stream_ << static_cast(state_._id); + user_id(stream_); + stream_ << static_cast(state_._user_id); + dfa(stream_); + stream_ << static_cast(state_._next_dfa); + stream_ << std::endl; + } + + if (i_ == 0 && bol_index_ != char_state_machine::npos()) + { + bol(stream_); + stream_ << static_cast(bol_index_) << std::endl; + } + + if (state_._eol_index != char_state_machine::npos()) + { + eol(stream_); + stream_ << static_cast(state_._eol_index) << + std::endl; + } + + for (const auto &tran_ : state_._transitions) + { + string_token token_ = tran_.second; + + open_bracket(stream_); + + if (!tran_.second.any() && tran_.second.negatable()) + { + token_.negate(); + negated(stream_); + } + + string chars_; + + for (const auto &range_ : token_._ranges) + { + if (range_.first == '-' || range_.first == '^' || + range_.first == ']') + { + stream_ << '\\'; + } + + chars_ = string_token::escape_char + (range_.first); + + if (range_.first != range_.second) + { + if (range_.first + 1 < range_.second) + { + chars_ += '-'; + } + + if (range_.second == '-' || range_.second == '^' || + range_.second == ']') + { + stream_ << '\\'; + } + + chars_ += string_token::escape_char(range_.second); + } + + stream_ << chars_; + } + + close_bracket(stream_); + stream_ << static_cast(tran_.first) << + std::endl; + } + + stream_ << std::endl; + } + } + + static void lexer_state(std::ostream &stream_) + { + stream_ << "Lexer state: "; + } + + static void lexer_state(std::wostream &stream_) + { + stream_ << L"Lexer state: "; + } + + static void state(std::ostream &stream_) + { + stream_ << "State: "; + } + + static void state(std::wostream &stream_) + { + stream_ << L"State: "; + } + + static void bol(std::ostream &stream_) + { + stream_ << " BOL -> "; + } + + static void bol(std::wostream &stream_) + { + stream_ << L" BOL -> "; + } + + static void eol(std::ostream &stream_) + { + stream_ << " EOL -> "; + } + + static void eol(std::wostream &stream_) + { + stream_ << L" EOL -> "; + } + + static void end_state(std::ostream &stream_) + { + stream_ << " END STATE"; + } + + static void end_state(std::wostream &stream_) + { + stream_ << L" END STATE"; + } + + static void id(std::ostream &stream_) + { + stream_ << ", Id = "; + } + + static void id(std::wostream &stream_) + { + stream_ << L", Id = "; + } + + static void push(std::ostream &stream_) + { + stream_ << ", PUSH "; + } + + static void push(std::wostream &stream_) + { + stream_ << L", PUSH "; + } + + static void pop(std::ostream &stream_) + { + stream_ << ", POP"; + } + + static void pop(std::wostream &stream_) + { + stream_ << L", POP"; + } + + static void user_id(std::ostream &stream_) + { + stream_ << ", User Id = "; + } + + static void user_id(std::wostream &stream_) + { + stream_ << L", User Id = "; + } + + static void open_bracket(std::ostream &stream_) + { + stream_ << " ["; + } + + static void open_bracket(std::wostream &stream_) + { + stream_ << L" ["; + } + + static void negated(std::ostream &stream_) + { + stream_ << "^"; + } + + static void negated(std::wostream &stream_) + { + stream_ << L"^"; + } + + static void close_bracket(std::ostream &stream_) + { + stream_ << "] -> "; + } + + static void close_bracket(std::wostream &stream_) + { + stream_ << L"] -> "; + } + + static void dfa(std::ostream &stream_) + { + stream_ << ", dfa = "; + } + + static void dfa(std::wostream &stream_) + { + stream_ << L", dfa = "; + } +}; + +using debug = basic_debug; +using wdebug = basic_debug; +} + +#endif diff --git a/YACReaderLibrary/lexertl/dot.hpp b/YACReaderLibrary/lexertl/dot.hpp new file mode 100644 index 000000000..cda4d6ac2 --- /dev/null +++ b/YACReaderLibrary/lexertl/dot.hpp @@ -0,0 +1,293 @@ +// dot.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// Copyright (c) 2013 Autodesk, Inc. All rights reserved. +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_DOT_HPP +#define LEXERTL_DOT_HPP + +#include +#include "rules.hpp" +#include "state_machine.hpp" +#include "sm_to_csm.hpp" + +namespace lexertl +{ +//! The class template basic_dot contains utility functions used to +//! dump a description of a finite state machine formatted in the +//! DOT language (http://www.graphviz.org/doc/info/lang.html). The +//! resulting directed graph can previewed by opening the ".dot" file +//! into the GraphViz application (http://www.graphviz.org). +template +class basic_dot +{ +public: + using char_state_machine = + basic_char_state_machine; + using rules = basic_rules; + using ostream = std::basic_ostream; + using string = std::basic_string; + + //! Dumps a description of the finite state machine expressed in + //! the DOT language to the given output stream. + static void dump(const sm &sm_, rules &rules_, ostream &stream_) + { + char_state_machine csm_; + + sm_to_csm(sm_, csm_); + dump(csm_, rules_, stream_); + } + + //! Dumps a description of the finite state machine expressed in + //! the DOT language to the given output stream. + static void dump(const char_state_machine &csm_, rules &rules_, + ostream &stream_) + { + header(stream_); + for (std::size_t dfa_ = 0, dfas_ = csm_.size(); dfa_ < dfas_; ++dfa_) + { + dump_ex(dfa_, csm_._sm_vector[dfa_], rules_, stream_); + } + trailer(stream_); + } + +protected: + using dfa_state = typename char_state_machine::state; + using string_token = typename dfa_state::string_token; + using stringstream = std::basic_stringstream; + + // Naming of nodes used in the DOT diagram. The naming is of the + // form: L_S. + static string node_name(id_type dfa_id_, id_type state_id_) + { + stringstream namestream_; + namestream_ << "L" << dfa_id_ << "_S" << state_id_; + return namestream_.str(); + } + + // Escape control characters twice. This is necessary when + // expressing character sets attached as to DOT nodes as + // labels. + static string double_escape_char(const id_type ch_) + { + stringstream out_; + + switch (ch_) + { + case '\0': + out_ << '\\'; + out_ << '\\'; + out_ << '0'; + break; + case '\a': + out_ << '\\'; + out_ << '\\'; + out_ << 'a'; + break; + case '\b': + out_ << '\\'; + out_ << '\\'; + out_ << 'b'; + break; + case '\f': + out_ << '\\'; + out_ << '\\'; + out_ << 'f'; + break; + case '\n': + out_ << '\\'; + out_ << '\\'; + out_ << 'n'; + break; + case '\r': + out_ << '\\'; + out_ << '\\'; + out_ << 'r'; + break; + case '\t': + out_ << '\\'; + out_ << '\\'; + out_ << 't'; + break; + case '\v': + out_ << '\\'; + out_ << '\\'; + out_ << 'v'; + break; + case '\\': + out_ << '\\'; + out_ << '\\'; + break; + case '"': + out_ << '\\'; + out_ << '\\'; + out_ << '"'; + break; + case '\'': + out_ << '\\'; + out_ << '\\'; + out_ << '\''; + break; + default: + { + if (ch_ < 32 || ch_ > 126) + { + out_ << '\\'; + out_ << 'x'; + out_ << std::hex << + static_cast(ch_); + } + else + { + out_ << char_type(ch_); + } + + break; + } + } + + return out_.str(); + } + + // Internal function actually performing the work of dumping the + // state machine in DOT. + static void dump_ex(id_type dfa_id_, + const typename char_state_machine::dfa &dfa_, + rules &rules_, + ostream &stream_) + { + const std::size_t states_ = dfa_._states.size(); + typename dfa_state::id_type_string_token_map::const_iterator iter_; + typename dfa_state::id_type_string_token_map::const_iterator end_; + + stream_ << std::endl; + + for (std::size_t i_ = 0; i_ < states_; ++i_) + { + const dfa_state &state_ = dfa_._states[i_]; + + const string name = node_name(dfa_id_, i_); + if (i_ == 0) + { + stream_ << " " << name << " [shape = doublecircle, xlabel=\"" + << rules_.state(dfa_id_) << "\"];" << std::endl; + } + else if (state_._end_state) + { + stream_ << " " << name << + " [shape = doublecircle, xlabel=\"id =" << + static_cast(state_._id) << "\"];" << + std::endl; + } + else { + stream_ << " " << name << " [shape = circle];" << std::endl; + } + } + + stream_ << std::endl; + + for (std::size_t i_ = 0; i_ < states_; ++i_) + { + const dfa_state &state_ = dfa_._states[i_]; + + iter_ = state_._transitions.begin(); + end_ = state_._transitions.end(); + + const string src_name = node_name(dfa_id_, i_); + + for (; iter_ != end_; ++iter_) + { + const string dst_name = node_name(dfa_id_, iter_->first); + stream_ << " " << src_name << " -> " << dst_name << + " [label = \""; + + string_token token_ = iter_->second; + + open_bracket(stream_); + + if (!iter_->second.any() && iter_->second.negatable()) + { + token_.negate(); + negated(stream_); + } + + string chars_; + auto ranges_iter_ = token_._ranges.cbegin(); + auto ranges_end_ = token_._ranges.cend(); + + for (; ranges_iter_ != ranges_end_; ++ranges_iter_) + { + if (ranges_iter_->first == '^' || + ranges_iter_->first == ']') + { + stream_ << "\\\\"; + } + + chars_ = double_escape_char(ranges_iter_->first); + + if (ranges_iter_->first != ranges_iter_->second) + { + if (ranges_iter_->first + 1 < ranges_iter_->second) + { + chars_ += '-'; + } + + if (ranges_iter_->second == '^' || + ranges_iter_->second == ']') + { + stream_ << "\\\\"; + } + + chars_ += double_escape_char(ranges_iter_->second); + } + + stream_ << chars_; + } + + close_bracket(stream_); + stream_ << "\"];" << std::endl; + } + + if (state_._end_state) { + const string dst_name = node_name(state_._next_dfa, 0); + stream_ << " " << src_name << " -> " << dst_name + << " [style = \"dashed\"];" << std::endl; + } + } + } + + static void header(ostream &stream_) + { + stream_ << "digraph DFAs {" << std::endl; + stream_ << " rankdir = LR;" << std::endl; + } + + static void trailer(ostream &stream_) + { + stream_ << "}" << std::endl; + } + + static void open_bracket(ostream &stream_) + { + stream_ << "["; + } + + static void negated(ostream &stream_) + { + stream_ << "^"; + } + + static void close_bracket(ostream &stream_) + { + stream_ << "]"; + } + +}; + +using dot = basic_dot, char>; +using wdot = basic_dot, wchar_t>; +} + +#endif diff --git a/YACReaderLibrary/lexertl/enums.hpp b/YACReaderLibrary/lexertl/enums.hpp new file mode 100644 index 000000000..31a6a9698 --- /dev/null +++ b/YACReaderLibrary/lexertl/enums.hpp @@ -0,0 +1,25 @@ +// enums.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_ENUMS_HPP +#define LEXERTL_ENUMS_HPP + +namespace lexertl +{ + enum regex_flags {icase = 1, dot_not_newline = 2, dot_not_cr_lf = 4, + skip_ws = 8, match_zero_len = 16}; + // 0 = end state, 1 = id, 2 = user id, 3 = push_dfa_index + // 4 = next dfa, 5 = dead state, 6 = dfa_start + enum {end_state_index, id_index, user_id_index, push_dfa_index, + next_dfa_index, eol_index, dead_state_index, transitions_index}; + // Rule flags: + enum feature_flags {bol_bit = 1, eol_bit = 2, skip_bit = 4, again_bit = 8, + multi_state_bit = 16, recursive_bit = 32, advance_bit = 64}; + // End state flags: + enum {end_state_bit = 1, pop_dfa_bit = 2}; +} + +#endif diff --git a/YACReaderLibrary/lexertl/generate_cpp.hpp b/YACReaderLibrary/lexertl/generate_cpp.hpp new file mode 100644 index 000000000..3e6b28a66 --- /dev/null +++ b/YACReaderLibrary/lexertl/generate_cpp.hpp @@ -0,0 +1,1123 @@ +// generate_cpp.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_GENERATE_CPP_HPP +#define LEXERTL_GENERATE_CPP_HPP + +#include "enums.hpp" +#include +#include "state_machine.hpp" + +namespace lexertl +{ +class table_based_cpp +{ +public: + template + static void generate_cpp + (const std::string &name_, + const basic_state_machine &sm_, + const bool pointers_, std::ostream &os_) + { + using sm = basic_state_machine; + using internals = typename sm::internals; + const internals &internals_ = sm_.data(); + std::size_t additional_tabs_ = 0; + + os_ << "template\n"; + os_ << "void " << name_ << " (lexertl::"; + + if (internals_._features & recursive_bit) + { + os_ << "recursive_match_results"; + } + else + { + os_ << "match_results"; + } + + os_ << " &results_)\n"; + os_ << "{\n"; + os_ << " using results = lexertl::"; + + if (internals_._features & recursive_bit) + { + os_ << "recursive_match_results"; + } + else + { + os_ << "match_results"; + } + + os_ << ";\n"; + os_ << " using char_type = typename results::char_type;\n"; + os_ << " typename results::iter_type end_token_ = " + "results_.second;\n"; + + if (internals_._features & skip_bit) + { + os_ << "skip:\n"; + } + + os_ << " typename results::iter_type curr_ = results_.second;\n\n"; + os_ << " results_.first = curr_;\n\n"; + + if (internals_._features & again_bit) + { + os_ << "again:\n"; + } + + os_ << " if (curr_ == results_.eoi)\n"; + os_ << " {\n"; + // We want a number regardless of id_type. + os_ << " results_.id = " << static_cast + (internals_._eoi) << ";\n"; + os_ << " results_.user_id = results::npos();\n"; + os_ << " return;\n"; + os_ << " }\n\n"; + + if (internals_._features & bol_bit) + { + os_ << " bool bol_ = results_.bol;\n"; + } + + dump_tables(sm_, 1, pointers_, os_); + + if (internals_._dfa.size() > 1) + { + os_ << " const id_type *lookup_ = lookups_[results_.state];\n"; + os_ << " const id_type dfa_alphabet_ = dfa_alphabets_" + "[results_.state];\n"; + os_ << " const "; + + if (pointers_) + { + os_ << "void * const"; + } + else + { + os_ << "id_type"; + } + + os_ << " *dfa_ = dfas_[results_.state];\n"; + } + + os_ << " const "; + + if (pointers_) + { + os_ << "void * const"; + } + else + { + os_ << "id_type"; + } + + os_ << " *ptr_ = dfa_ + dfa_alphabet_;\n"; + os_ << " bool end_state_ = *ptr_ != 0;\n"; + + if (internals_._features & recursive_bit) + { + os_ << " bool pop_ = ("; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*ptr_"; + + if (pointers_) + { + os_ << ')'; + } + + os_ <<" & " << pop_dfa_bit; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ") != 0;\n"; + } + + os_ << " id_type id_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << id_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + os_ << " id_type uid_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << user_id_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + + if (internals_._features & recursive_bit) + { + os_ << " id_type push_dfa_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << push_dfa_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + } + + if (internals_._dfa.size() > 1) + { + os_ << " id_type start_state_ = results_.state;\n"; + } + + if (internals_._features & bol_bit) + { + os_ << " bool end_bol_ = bol_;\n"; + } + + if (internals_._features & eol_bit) + { + os_ << " "; + + if (pointers_) + { + os_ << "const void * const *"; + } + else + { + os_ << "id_type "; + } + + os_ << "EOL_state_ = 0;\n"; + } + + os_ << '\n'; + + if (internals_._features & bol_bit) + { + os_ << " if (bol_)\n"; + os_ << " {\n"; + os_ << " const "; + + if (pointers_) + { + os_ << "void *"; + } + else + { + os_ << "id_type "; + } + + os_ << "state_ = *dfa_;\n\n"; + os_ << " if (state_)\n"; + os_ << " {\n"; + os_ << " ptr_ = "; + + if (pointers_) + { + os_ << "reinterpret_cast(state_);\n"; + } + else + { + os_ << "&dfa_[state_ * dfa_alphabet_];\n"; + } + + os_ << " }\n"; + os_ << " }\n\n"; + } + + os_ << " while (curr_ != results_.eoi)\n"; + os_ << " {\n"; + + if (internals_._features & eol_bit) + { + os_ << " EOL_state_ = "; + + if (pointers_) + { + os_ << "reinterpret_cast("; + } + + os_ << "ptr_[" << eol_index << ']'; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ";\n\n"; + os_ << " if (EOL_state_ && *curr_ == '\\n')\n"; + os_ << " {\n"; + os_ << " ptr_ = "; + + if (pointers_) + { + os_ << "EOL_state_"; + } + else + { + os_ << "&dfa_[EOL_state_ * dfa_alphabet_]"; + } + + os_ << ";\n"; + os_ << " }\n"; + os_ << " else\n"; + os_ << " {\n"; + ++additional_tabs_; + } + + output_char_loop(internals_._features, additional_tabs_, pointers_, + os_, std::integral_constant 1)>()); + + if (internals_._features & eol_bit) + { + output_tabs(additional_tabs_, os_); + os_ << " }\n"; + --additional_tabs_; + } + + os_ << '\n'; + os_ << " if (*ptr_)\n"; + os_ << " {\n"; + os_ << " end_state_ = true;\n"; + + + if (internals_._features & recursive_bit) + { + os_ << " pop_ = ("; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*ptr_"; + + if (pointers_) + { + os_ << ')'; + } + + os_ <<" & " << pop_dfa_bit; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ") != 0;\n"; + } + + os_ << " id_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << id_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + os_ << " uid_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << user_id_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + + if (internals_._features & recursive_bit) + { + os_ << " push_dfa_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << push_dfa_index << ')'; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + } + + if (internals_._dfa.size() > 1) + { + os_ << " start_state_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << next_dfa_index << ')'; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + } + + if (internals_._features & bol_bit) + { + os_ << " end_bol_ = bol_;\n"; + } + + os_ << " end_token_ = curr_;\n"; + os_ << " }\n"; + os_ << " }\n\n"; + output_quit(os_, std::integral_constant 1)>()); + + if (internals_._features & eol_bit) + { + os_ << " if (curr_ == results_.eoi)\n"; + os_ << " {\n"; + os_ << " EOL_state_ = "; + + if (pointers_) + { + os_ << "reinterpret_cast("; + } + + os_ << "ptr_[" << eol_index << ']'; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ";\n"; + os_ << "\n"; + os_ << " if (EOL_state_)\n"; + os_ << " {\n"; + os_ << " ptr_ = "; + + if (pointers_) + { + os_ << "EOL_state_"; + } + else + { + os_ << "&dfa_[EOL_state_ * dfa_alphabet_]"; + } + + os_ << ";\n\n"; + os_ << " if (*ptr_)\n"; + os_ << " {\n"; + os_ << " end_state_ = true;\n"; + + + if (internals_._features & recursive_bit) + { + os_ << " pop_ = ("; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*ptr_"; + + if (pointers_) + { + os_ << ')'; + } + + os_ <<" & " << pop_dfa_bit; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ") != 0;\n"; + } + + os_ << " id_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << id_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + os_ << " uid_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << user_id_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ <<";\n"; + + if (internals_._features & recursive_bit) + { + os_ << " push_dfa_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << push_dfa_index << ')'; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + } + + if (internals_._dfa.size() > 1) + { + os_ << " start_state_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << next_dfa_index << ')'; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + } + + if (internals_._features & bol_bit) + { + os_ << " end_bol_ = bol_;\n"; + } + + os_ << " end_token_ = curr_;\n"; + os_ << " }\n"; + os_ << " }\n"; + os_ << " }\n\n"; + } + + os_ << " if (end_state_)\n"; + os_ << " {\n"; + os_ << " // Return longest match\n"; + + if (internals_._features & recursive_bit) + { + os_ << " if (pop_)\n"; + os_ << " {\n"; + os_ << " start_state_ = results_." + "stack.top().first;\n"; + os_ << " results_.stack.pop();\n"; + os_ << " }\n"; + os_ << " else if (push_dfa_ != results_.npos())\n"; + os_ << " {\n"; + os_ << " results_.stack.push(typename results::" + "id_type_pair\n"; + os_ << " (push_dfa_, id_));\n"; + os_ << " }\n\n"; + } + + if (internals_._dfa.size() > 1) + { + os_ << " results_.state = start_state_;\n"; + } + + if (internals_._features & bol_bit) + { + os_ << " results_.bol = end_bol_;\n"; + } + + os_ << " results_.second = end_token_;\n"; + + if (internals_._features & skip_bit) + { + // We want a number regardless of id_type. + os_ << "\n if (id_ == results_.skip()) goto skip;\n"; + } + + if (internals_._features & again_bit) + { + // We want a number regardless of id_type. + os_ << "\n if (id_ == " + << static_cast(internals_._eoi); + + if (internals_._features & recursive_bit) + { + os_ << " || (pop_ && !results_.stack.empty() &&\n"; + // We want a number regardless of id_type. + os_ << " results_.stack.top().second == " + << static_cast(internals_._eoi) << ')'; + } + + os_ << ")\n"; + os_ << " {\n"; + os_ << " curr_ = end_token_;\n"; + os_ << " goto again;\n"; + os_ << " }\n"; + } + + os_ << " }\n"; + os_ << " else\n"; + os_ << " {\n"; + os_ << " // No match causes char to be skipped\n"; + os_ << " results_.second = end_token_;\n"; + + if (internals_._features & bol_bit) + { + os_ << " results_.bol = *results_.second == '\\n';\n"; + } + + os_ << " results_.first = results_.second;\n"; + os_ << " ++results_.second;\n"; + os_ << " id_ = results::npos();\n"; + os_ << " uid_ = results::npos();\n"; + os_ << " }\n\n"; + os_ << " results_.id = id_;\n"; + os_ << " results_.user_id = uid_;\n"; + os_ << "}\n"; + } + + template + static void dump_tables + (const basic_state_machine &sm_, + const std::size_t tabs_, const bool pointers_, std::ostream &os_) + { + const typename detail::basic_internals &internals_ = + sm_.data(); + const std::size_t lookup_divisor_ = 8; + // Lookup is always 256 entries long now + const std::size_t lookup_quotient_ = 256 / lookup_divisor_; + const std::size_t dfas_ = internals_._lookup.size(); + + output_tabs(tabs_, os_); + os_ << "static const id_type lookup"; + + if (dfas_ > 1) + { + os_ << "s_[][" << 256; + } + else + { + os_ << "_["; + } + + os_ << "] = \n"; + output_tabs(tabs_ + 1, os_); + + if (dfas_ > 1) + { + os_ << '{'; + } + + for (std::size_t l_ = 0; l_ < dfas_; ++l_) + { + const id_type *ptr_ = &internals_._lookup[l_].front(); + + // We want numbers regardless of id_type. + os_ << "{0x" << std::hex << static_cast(*ptr_++); + + for (std::size_t col_ = 1; col_ < lookup_divisor_; ++col_) + { + // We want numbers regardless of id_type. + os_ << ", 0x" << std::hex << static_cast(*ptr_++); + } + + for (std::size_t row_ = 1; row_ < lookup_quotient_; ++row_) + { + os_ << ",\n"; + output_tabs(tabs_ + 1, os_); + // We want numbers regardless of id_type. + os_ << "0x" << std::hex << static_cast(*ptr_++); + + for (std::size_t col_ = 1; col_ < lookup_divisor_; ++col_) + { + // We want numbers regardless of id_type. + os_ << ", 0x" << std::hex << + static_cast(*ptr_++); + } + } + + os_ << '}'; + + if (l_ + 1 < dfas_) + { + os_ << ",\n"; + output_tabs(tabs_ + 1, os_); + } + } + + if (dfas_ > 1) + { + os_ << '}'; + } + + os_ << ";\n"; + output_tabs(tabs_, os_); + os_ << "static const id_type dfa_alphabet"; + + if (dfas_ > 1) + { + os_ << "s_[" << std::dec << dfas_ << "] = {"; + } + else + { + os_ << "_ = "; + } + + // We want numbers regardless of id_type. + os_ << "0x" << std::hex << static_cast + (internals_._dfa_alphabet[0]); + + for (std::size_t col_ = 1; col_ < dfas_; ++col_) + { + // We want numbers regardless of id_type. + os_ << ", 0x" << std::hex << static_cast(internals_. + _dfa_alphabet[col_]); + } + + if (dfas_ > 1) + { + os_ << '}'; + } + + os_ << ";\n"; + + // DFAs are usually different sizes, so dump separately + for (std::size_t dfa_ = 0; dfa_ < dfas_; ++dfa_) + { + const id_type dfa_alphabet_ = internals_._dfa_alphabet[dfa_]; + const std::size_t rows_ = internals_._dfa[dfa_].size() / + dfa_alphabet_; + const id_type *ptr_ = &internals_._dfa[dfa_].front(); + std::string dfa_name_ = "dfa"; + + output_tabs(tabs_, os_); + os_ << "static const "; + + if (pointers_) + { + os_ << "void *"; + } + else + { + os_ << "id_type "; + } + + os_ << dfa_name_; + + if (dfas_ > 1) + { + std::ostringstream ss_; + + ss_ << dfa_; + dfa_name_ += ss_.str(); + os_ << dfa_; + } + + dfa_name_ += '_'; + os_ << "_[] = {"; + + for (std::size_t row_ = 0; row_ < rows_; ++row_) + { + dump_row(row_ == 0, ptr_, dfa_name_, dfa_alphabet_, + pointers_, os_); + + if (row_ + 1 < rows_) + { + os_ << ",\n"; + output_tabs(tabs_ + 1, os_); + } + } + + os_ << "};\n"; + } + + if (dfas_ > 1) + { + output_tabs(tabs_, os_); + os_ << "static const "; + + if (pointers_) + { + os_ << "void * const"; + } + else + { + os_ << "id_type"; + } + + os_ << " *dfas_[] = {dfa0_"; + + for (std::size_t col_ = 1; col_ < dfas_; ++col_) + { + os_ << ", dfa" << col_ << '_'; + } + + os_ << "};\n"; + } + + os_ << std::dec; + } + +protected: + template + static void dump_row(const bool first_, const id_type * &ptr_, + const std::string &dfa_name_, const id_type dfa_alphabet_, + const bool pointers_, std::ostream &os_) + { + if (pointers_) + { + bool zero_ = *ptr_ == 0; + + if (first_) + { + // We want numbers regardless of id_type. + os_ << dfa_name_ << " + 0x" << std::hex << + static_cast(*ptr_++) * dfa_alphabet_; + } + else if (!zero_) + { + os_ << "reinterpret_cast(0x" + // We want numbers regardless of id_type. + << std::hex << static_cast(*ptr_++) << ')'; + } + else + { + // We want numbers regardless of id_type. + os_ << "0x" << std::hex << static_cast(*ptr_++); + } + + for (id_type id_index_ = id_index; id_index_ < transitions_index; + ++id_index_, ++ptr_) + { + os_ << ", "; + zero_ = *ptr_ == 0; + + if (!zero_) + { + os_ << "reinterpret_cast("; + } + + // We want numbers regardless of id_type. + os_ << "0x" << std::hex << static_cast(*ptr_); + + if (!zero_) + { + os_ << ')'; + } + } + + for (id_type alphabet_ = transitions_index; + alphabet_ < dfa_alphabet_; ++alphabet_, ++ptr_) + { + // We want numbers regardless of id_type. + os_ << ", "; + + if (*ptr_ == 0) + { + os_ << 0; + } + else + { + // We want numbers regardless of id_type. + os_ << dfa_name_ + " + 0x" << std::hex << + static_cast(*ptr_) * dfa_alphabet_; + } + } + } + else + { + // We want numbers regardless of id_type. + os_ << "0x" << std::hex << static_cast(*ptr_++); + + for (id_type alphabet_ = 1; alphabet_ < dfa_alphabet_; + ++alphabet_, ++ptr_) + { + // We want numbers regardless of id_type. + os_ << ", 0x" << std::hex << static_cast(*ptr_); + } + } + } + + static void output_tabs(const std::size_t tabs_, std::ostream &os_) + { + for (std::size_t i_ = 0; i_ < tabs_; ++i_) + { + os_ << " "; + } + } + + template + static void output_char_loop(const id_type features_, + const std::size_t additional_tabs_, const bool pointers_, + std::ostream &os_, const std::false_type &) + { + output_tabs(additional_tabs_, os_); + os_ << " const typename results::char_type prev_char_ = " + "*curr_++;\n"; + output_tabs(additional_tabs_, os_); + os_ << " const "; + + if (pointers_) + { + os_ << "void * const *"; + } + else + { + os_ << "id_type "; + } + + os_ << "state_ = "; + + if (pointers_) + { + os_ << "reinterpret_cast\n "; + output_tabs(additional_tabs_, os_); + os_ << '('; + } + + os_ << "ptr_[lookup_"; + + if (!pointers_) + { + os_ << "\n "; + output_tabs(additional_tabs_, os_); + } + + os_ << "[static_cast"; + + if (pointers_) + { + os_ << "\n "; + output_tabs(additional_tabs_, os_); + } + + os_ << "(prev_char_)]]"; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ";\n\n"; + + if (features_ & bol_bit) + { + output_tabs(additional_tabs_, os_); + os_ << " bol_ = prev_char_ == '\\n';\n\n"; + } + + output_tabs(additional_tabs_, os_); + os_ << " if (state_ == 0)\n"; + output_tabs(additional_tabs_, os_); + os_ << " {\n"; + + if (features_ & eol_bit) + { + output_tabs(additional_tabs_, os_); + os_ << " EOL_state_ = 0;\n"; + } + + output_tabs(additional_tabs_, os_); + os_ << " break;\n"; + output_tabs(additional_tabs_, os_); + os_ << " }\n\n"; + output_tabs(additional_tabs_, os_); + os_ << " ptr_ = "; + + if (pointers_) + { + os_ << "state_"; + } + else + { + os_ << "&dfa_[state_ * dfa_alphabet_]"; + } + + os_ << ";\n"; + } + + template + static void output_char_loop(const id_type features_, + const std::size_t additional_tabs_, const bool pointers_, + std::ostream &os_, const std::true_type &) + { + output_tabs(additional_tabs_, os_); + os_ << " const std::size_t bytes_ =\n"; + output_tabs(additional_tabs_, os_); + os_ << " sizeof(typename results::char_type) < 3 ?\n"; + output_tabs(additional_tabs_, os_); + os_ << " sizeof(typename results::char_type) : 3;\n"; + output_tabs(additional_tabs_, os_); + os_ << " const std::size_t shift_[] = {0, 8, 16};\n"; + output_tabs(additional_tabs_, os_); + os_ << " typename results::char_type prev_char_ = " + "*curr_++;\n\n"; + + if (features_ & bol_bit) + { + output_tabs(additional_tabs_, os_); + os_ << " bol_ = prev_char_ == '\\n';\n\n"; + } + + output_tabs(additional_tabs_, os_); + os_ << " for (std::size_t i_ = 0; i_ < bytes_; ++i_)\n"; + output_tabs(additional_tabs_, os_); + os_ << " {\n"; + output_tabs(additional_tabs_, os_); + os_ << " const "; + + if (pointers_) + { + os_ << "void * const *"; + } + else + { + os_ << "id_type "; + } + + os_ << "state_ = "; + + if (pointers_) + { + os_ << "reinterpret_cast\n "; + output_tabs(additional_tabs_, os_); + os_ << '('; + } + + os_ << "ptr_[lookup_[static_cast\n"; + output_tabs(additional_tabs_, os_); + os_ << " ((prev_char_ >>\n" + " shift_[bytes_ - 1 - i_]) & 0xff)]]"; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ";\n\n"; + output_tabs(additional_tabs_, os_); + os_ << " if (state_ == 0)\n"; + output_tabs(additional_tabs_, os_); + os_ << " {\n"; + + if (features_ & eol_bit) + { + output_tabs(additional_tabs_, os_); + os_ << " EOL_state_ = 0;\n"; + } + + output_tabs(additional_tabs_, os_); + os_ << " goto quit;\n"; + output_tabs(additional_tabs_, os_); + os_ << " }\n\n"; + output_tabs(additional_tabs_, os_); + os_ << " ptr_ = "; + + if (pointers_) + { + os_ << "state_"; + } + else + { + os_ << "&dfa_[state_ * dfa_alphabet_]"; + } + + os_ << ";\n"; + output_tabs(additional_tabs_, os_); + os_ << " }\n"; + } + + static void output_quit(std::ostream &, const std::false_type &) + { + // Nothing to do + } + + static void output_quit(std::ostream &os_, const std::true_type &) + { + os_ << "quit:\n"; + } +}; +} + +#endif diff --git a/YACReaderLibrary/lexertl/generator.hpp b/YACReaderLibrary/lexertl/generator.hpp new file mode 100644 index 000000000..581cd6e92 --- /dev/null +++ b/YACReaderLibrary/lexertl/generator.hpp @@ -0,0 +1,738 @@ +// generator.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_GENERATOR_HPP +#define LEXERTL_GENERATOR_HPP + +#include +#include "partition/charset.hpp" +#include "char_traits.hpp" +#include "partition/equivset.hpp" +#include +#include +#include "parser/parser.hpp" +#include "rules.hpp" +#include "state_machine.hpp" +#include + +namespace lexertl +{ +template > +class basic_generator +{ +public: + using id_type = typename rules::id_type; + using rules_char_type = typename rules::rules_char_type; + using sm_traits = typename sm::traits; + using parser = detail::basic_parser; + using charset_map = typename parser::charset_map; + using node = typename parser::node; + using node_ptr_vector = typename parser::node_ptr_vector; + + static void build(const rules &rules_, sm &sm_) + { + const std::size_t size_ = rules_.statemap().size(); + // Strong exception guarantee + // http://www.boost.org/community/exception_safety.html + internals internals_; + sm temp_sm_; + node_ptr_vector node_ptr_vector_; + + internals_._eoi = rules_.eoi(); + internals_.add_states(size_); + + for (id_type index_ = 0; index_ < size_; ++index_) + { + if (rules_.regexes()[index_].empty()) + { + std::ostringstream ss_; + + ss_ << "Lexer states with no rules are not allowed " + "(lexer state " << index_ << ".)"; + throw runtime_error(ss_.str()); + } + else + { + // Note that the following variables are per DFA. + // Map of regex charset tokens (strings) to index + charset_map charset_map_; + // Used to fix up $ and \n clashes. + id_type nl_id_ = sm_traits::npos(); + // Regex syntax tree + observer_ptr root_ = build_tree(rules_, index_, + node_ptr_vector_, charset_map_, nl_id_); + + build_dfa(charset_map_, root_, internals_, temp_sm_, index_, + nl_id_); + + if (internals_._dfa[index_].size() / + internals_._dfa_alphabet[index_] >= sm_traits::npos()) + { + // Overflow + throw runtime_error("The data type you have chosen " + "cannot hold this many DFA rows."); + } + } + } + + // If you get a compile error here the id_type from rules and + // state machine do no match. + create(internals_, temp_sm_, rules_.features(), lookup()); + sm_.swap(temp_sm_); + } + + static observer_ptr build_tree(const rules &rules_, + const std::size_t dfa_, node_ptr_vector &node_ptr_vector_, + charset_map &charset_map_, id_type &nl_id_) + { + parser parser_(rules_.locale(), node_ptr_vector_, charset_map_, + rules_.eoi()); + const auto ®exes_ = rules_.regexes(); + auto regex_iter_ = regexes_[dfa_].cbegin(); + auto regex_iter_end_ = regexes_[dfa_].cend(); + const auto &ids_ = rules_.ids(); + const auto &user_ids_ = rules_.user_ids(); + auto id_iter_ = ids_[dfa_].cbegin(); + auto user_id_iter_ = user_ids_[dfa_].cbegin(); + const auto &next_dfas_ = rules_.next_dfas(); + const auto &pushes_ = rules_.pushes(); + const auto &pops_ = rules_.pops(); + auto next_dfa_iter_ = next_dfas_[dfa_].cbegin(); + auto push_dfa_iter_ = pushes_[dfa_].cbegin(); + auto pop_dfa_iter_ = pops_[dfa_].cbegin(); + const bool seen_bol_ = (rules_.features()[dfa_] & bol_bit) != 0; + observer_ptr root_ = nullptr; + + root_ = parser_.parse(*regex_iter_, *id_iter_, *user_id_iter_, + *next_dfa_iter_, *push_dfa_iter_, *pop_dfa_iter_, + rules_.flags(), nl_id_, seen_bol_); + ++regex_iter_; + ++id_iter_; + ++user_id_iter_; + ++next_dfa_iter_; + ++push_dfa_iter_; + ++pop_dfa_iter_; + + // Build syntax trees + while (regex_iter_ != regex_iter_end_) + { + observer_ptr rhs_ = parser_.parse(*regex_iter_, *id_iter_, + *user_id_iter_, *next_dfa_iter_, *push_dfa_iter_, + *pop_dfa_iter_, rules_.flags(), nl_id_, + (rules_.features()[dfa_] & bol_bit) != 0); + + node_ptr_vector_.emplace_back + (std::make_unique(root_, rhs_)); + root_ = node_ptr_vector_.back().get(); + + ++regex_iter_; + ++id_iter_; + ++user_id_iter_; + ++next_dfa_iter_; + ++push_dfa_iter_; + ++pop_dfa_iter_; + } + + return root_; + } + +protected: + using compressed = std::integral_constant; + using equivset = detail::basic_equivset; + using equivset_list = std::list>; + using equivset_ptr = std::unique_ptr; + using sm_char_type = typename sm_traits::char_type; + using charset = detail::basic_charset; + using charset_ptr = std::unique_ptr; + using charset_list = std::list>; + using internals = detail::basic_internals; + using id_type_set = typename std::set; + using id_type_vector = typename internals::id_type_vector; + using index_set = typename charset::index_set; + using index_set_vector = std::vector; + using is_dfa = std::integral_constant; + using lookup = std::integral_constant; + using node_set = std::set>; + using node_set_vector = std::vector>; + using node_vector = typename node::node_vector; + using node_vector_vector = std::vector>; + using selection_node = typename parser::selection_node; + using size_t_vector = typename std::vector; + using string_token = typename parser::string_token; + + static void build_dfa(const charset_map &charset_map_, + const observer_ptr root_, internals &internals_, sm &sm_, + const id_type dfa_index_, id_type &nl_id_) + { + // partitioned charset list + charset_list charset_list_; + // vector mapping token indexes to partitioned token index sets + index_set_vector set_mapping_; + auto &dfa_ = internals_._dfa[dfa_index_]; + std::size_t dfa_alphabet_ = 0; + const node_vector &followpos_ = root_->firstpos(); + node_set_vector seen_sets_; + node_vector_vector seen_vectors_; + size_t_vector hash_vector_; + id_type zero_id_ = sm_traits::npos(); + id_type_set eol_set_; + + set_mapping_.resize(charset_map_.size()); + partition_charsets(charset_map_, charset_list_, is_dfa()); + build_set_mapping(charset_list_, internals_, dfa_index_, + set_mapping_); + + if (nl_id_ != sm_traits::npos()) + { + nl_id_ = *set_mapping_[nl_id_].begin(); + zero_id_ = sm_traits::compressed ? + *set_mapping_[charset_map_.find(string_token(0, 0))-> + second].begin() : sm_traits::npos(); + } + + dfa_alphabet_ = charset_list_.size() + transitions_index + + (nl_id_ == sm_traits::npos() ? 0 : 1); + + if (dfa_alphabet_ > sm_traits::npos()) + { + // Overflow + throw runtime_error("The data type you have chosen cannot hold " + "the dfa alphabet."); + } + + internals_._dfa_alphabet[dfa_index_] = + static_cast(dfa_alphabet_); + // 'jam' state + dfa_.resize(dfa_alphabet_, 0); + closure(followpos_, seen_sets_, seen_vectors_, hash_vector_, + static_cast(dfa_alphabet_), dfa_); + + // Loop over states + for (id_type index_ = 0; index_ < static_cast + (seen_vectors_.size()); ++index_) + { + equivset_list equiv_list_; + + // Intersect charsets + build_equiv_list(*seen_vectors_[index_].get(), set_mapping_, + equiv_list_, is_dfa()); + + for (auto &equivset_ : equiv_list_) + { + const id_type transition_ = closure + (equivset_->_followpos, seen_sets_, seen_vectors_, + hash_vector_, static_cast(dfa_alphabet_), dfa_); + + if (transition_ != sm_traits::npos()) + { + observer_ptr ptr_ = &dfa_.front() + + ((index_ + 1) * dfa_alphabet_); + + // Prune abstemious transitions from end states. + if (*ptr_ && !equivset_->_greedy) continue; + + set_transitions(transition_, equivset_.get(), dfa_, ptr_, + index_, eol_set_); + } + } + } + + fix_clashes(eol_set_, nl_id_, zero_id_, dfa_, dfa_alphabet_, + compressed()); + append_dfa(charset_list_, internals_, sm_, dfa_index_, lookup()); + } + + static void set_transitions(const id_type transition_, equivset *equivset_, + typename internals::id_type_vector &dfa_, id_type *ptr_, + const id_type index_, id_type_set &eol_set_) + { + for (typename equivset::index_vector::const_iterator + equiv_iter_ = equivset_->_index_vector.begin(), + equiv_end_ = equivset_->_index_vector.end(); + equiv_iter_ != equiv_end_; ++equiv_iter_) + { + const id_type i_ = *equiv_iter_; + + if (i_ == parser::bol_token()) + { + dfa_.front() = transition_; + } + else if (i_ == parser::eol_token()) + { + ptr_[eol_index] = transition_; + eol_set_.insert(index_ + 1); + } + else + { + ptr_[i_ + transitions_index] = transition_; + } + } + } + + // Uncompressed + static void fix_clashes(const id_type_set &eol_set_, + const id_type nl_id_, const id_type /*zero_id_*/, + typename internals::id_type_vector &dfa_, + const std::size_t dfa_alphabet_, const std::false_type &) + { + for (const auto &eol_ : eol_set_) + { + observer_ptr ptr_ = &dfa_.front() + eol_ * dfa_alphabet_; + const id_type eol_state_ = ptr_[eol_index]; + const id_type nl_state_ = ptr_[nl_id_ + transitions_index]; + + if (nl_state_) + { + ptr_[transitions_index + nl_id_] = 0; + ptr_ = &dfa_.front() + eol_state_ * dfa_alphabet_; + + if (ptr_[transitions_index + nl_id_] == 0) + { + ptr_[transitions_index + nl_id_] = nl_state_; + } + } + } + } + + // Compressed + static void fix_clashes(const id_type_set &eol_set_, + const id_type nl_id_, const id_type zero_id_, + typename internals::id_type_vector &dfa_, + const std::size_t dfa_alphabet_, const std::true_type &) + { + std::size_t i_ = 0; + + for (const auto &eol_ : eol_set_) + { + observer_ptr ptr_ = &dfa_.front() + eol_ * dfa_alphabet_; + const id_type eol_state_ = ptr_[eol_index]; + id_type nl_state_ = 0; + + for (; i_ < (sm_traits::char_24_bit ? 2 : 1); ++i_) + { + ptr_ = &dfa_.front() + ptr_[transitions_index + zero_id_] * + dfa_alphabet_; + } + + nl_state_ = ptr_[transitions_index + nl_id_]; + + if (nl_state_) + { + ptr_ = &dfa_.front() + eol_state_ * dfa_alphabet_; + + if (ptr_[transitions_index + zero_id_] != 0) continue; + + ptr_[transitions_index + zero_id_] = + static_cast(dfa_.size() / dfa_alphabet_); + dfa_.resize(dfa_.size() + dfa_alphabet_, 0); + + for (i_ = 0; i_ < (sm_traits::char_24_bit ? 1 : 0); ++i_) + { + ptr_ = &dfa_.front() + dfa_.size() - dfa_alphabet_; + ptr_[transitions_index + zero_id_] = + static_cast(dfa_.size() / dfa_alphabet_); + dfa_.resize(dfa_.size() + dfa_alphabet_, 0); + } + + ptr_ = &dfa_.front() + dfa_.size() - dfa_alphabet_; + ptr_[transitions_index + nl_id_] = nl_state_; + } + } + } + + // char_state_machine version + static void append_dfa(const charset_list &charset_list_, + const internals &internals_, sm &sm_, const id_type dfa_index_, + const std::false_type &) + { + std::size_t size_ = charset_list_.size(); + typename sm::string_token_vector token_vector_; + + token_vector_.reserve(size_); + + for (const auto &charset_ : charset_list_) + { + token_vector_.push_back(charset_->_token); + } + + sm_.append(token_vector_, internals_, dfa_index_); + } + + // state_machine version + static void append_dfa(const charset_list &, const internals &, sm &, + const id_type, const std::true_type &) + { + // Nothing to do - will use create() instead + } + + // char_state_machine version + static void create(internals &, sm &, const id_type_vector &, + const std::false_type &) + { + // Nothing to do - will use append_dfa() instead + } + + // state_machine version + static void create(internals &internals_, sm &sm_, + const id_type_vector &features_, const std::true_type &) + { + for (std::size_t i_ = 0, size_ = internals_._dfa.size(); + i_ < size_; ++i_) + { + internals_._features |= features_[i_]; + } + + if (internals_._dfa.size() > 1) + { + internals_._features |= multi_state_bit; + } + + sm_.data().swap(internals_); + } + + // NFA version + static void partition_charsets(const charset_map &map_, + charset_list &lhs_, const std::false_type &) + { + fill_rhs_list(map_, lhs_); + } + + // DFA version + static void partition_charsets(const charset_map &map_, + charset_list &lhs_, const std::true_type &) + { + charset_list rhs_; + + fill_rhs_list(map_, rhs_); + + if (!rhs_.empty()) + { + typename charset_list::iterator iter_; + typename charset_list::iterator end_; + charset_ptr overlap_ = std::make_unique(); + + lhs_.emplace_back(std::move(rhs_.front())); + rhs_.pop_front(); + + while (!rhs_.empty()) + { + charset_ptr r_(rhs_.front().release()); + + rhs_.pop_front(); + iter_ = lhs_.begin(); + end_ = lhs_.end(); + + while (!r_->empty() && iter_ != end_) + { + auto l_iter_ = iter_; + + (*l_iter_)->intersect(*r_.get(), *overlap_.get()); + + if (overlap_->empty()) + { + ++iter_; + } + else if ((*l_iter_)->empty()) + { + l_iter_->reset(overlap_.release()); + overlap_ = std::make_unique(); + ++iter_; + } + else if (r_->empty()) + { + r_.reset(overlap_.release()); + overlap_ = std::make_unique(); + break; + } + else + { + iter_ = lhs_.insert(++iter_, charset_ptr()); + iter_->reset(overlap_.release()); + overlap_ = std::make_unique(); + ++iter_; + end_ = lhs_.end(); + } + } + + if (!r_->empty()) + { + lhs_.emplace_back(std::move(r_)); + } + } + } + } + + static void fill_rhs_list(const charset_map &map_, charset_list &list_) + { + for (const auto &pair_ : map_) + { + list_.emplace_back(std::make_unique + (pair_.first, pair_.second)); + } + } + + static void build_set_mapping(const charset_list &charset_list_, + internals &internals_, const id_type dfa_index_, + index_set_vector &set_mapping_) + { + auto iter_ = charset_list_.cbegin(); + auto end_ = charset_list_.cend(); + + for (id_type index_ = 0; iter_ != end_; ++iter_, ++index_) + { + observer_ptr cs_ = iter_->get(); + + fill_lookup(cs_->_token, &internals_._lookup[dfa_index_], + index_, lookup()); + + for (const id_type i_ : cs_->_index_set) + { + set_mapping_[i_].insert(index_); + } + } + } + + // char_state_machine version + static void fill_lookup(const string_token &, observer_ptr , + const id_type, const std::false_type &) + { + // Do nothing (lookup not used) + } + + // state_machine version + static void fill_lookup(const string_token &charset_, + observer_ptr lookup_, const id_type index_, + const std::true_type &) + { + observer_ptr ptr_ = &lookup_->front(); + + for (const auto &range_ : charset_._ranges) + { + for (typename char_traits::index_type char_ = range_.first; + char_ < range_.second; ++char_) + { + // Note char_ must be unsigned + ptr_[char_] = index_ + transitions_index; + } + + // Note range_.second must be unsigned + ptr_[range_.second] = index_ + transitions_index; + } + } + + static id_type closure(const node_vector &followpos_, + node_set_vector &seen_sets_, node_vector_vector &seen_vectors_, + size_t_vector &hash_vector_, const id_type size_, id_type_vector &dfa_) + { + bool end_state_ = false; + id_type id_ = 0; + id_type user_id_ = sm_traits::npos(); + id_type next_dfa_ = 0; + id_type push_dfa_ = sm_traits::npos(); + bool pop_dfa_ = false; + std::size_t hash_ = 0; + + if (followpos_.empty()) return sm_traits::npos(); + + id_type index_ = 0; + std::unique_ptr set_ptr_ = std::make_unique(); + std::unique_ptr vector_ptr_ = + std::make_unique(); + + for (observer_ptr node_ : followpos_) + { + closure_ex(node_, end_state_, id_, user_id_, next_dfa_, + push_dfa_, pop_dfa_, *set_ptr_.get(), + *vector_ptr_.get(), hash_); + } + + bool found_ = false; + auto hash_iter_ = hash_vector_.cbegin(); + auto hash_end_ = hash_vector_.cend(); + auto set_iter_ = seen_sets_.cbegin(); + + for (; hash_iter_ != hash_end_; ++hash_iter_, ++set_iter_) + { + found_ = *hash_iter_ == hash_ && *(*set_iter_) == *set_ptr_; + ++index_; + + if (found_) break; + } + + if (!found_) + { + seen_sets_.emplace_back(std::move(set_ptr_)); + seen_vectors_.emplace_back(std::move(vector_ptr_)); + hash_vector_.push_back(hash_); + // State 0 is the jam state... + index_ = static_cast(seen_sets_.size()); + + const std::size_t old_size_ = dfa_.size(); + + dfa_.resize(old_size_ + size_, 0); + + if (end_state_) + { + dfa_[old_size_] |= end_state_bit; + + if (pop_dfa_) + { + dfa_[old_size_] |= pop_dfa_bit; + } + + dfa_[old_size_ + id_index] = id_; + dfa_[old_size_ + user_id_index] = user_id_; + dfa_[old_size_ + push_dfa_index] = push_dfa_; + dfa_[old_size_ + next_dfa_index] = next_dfa_; + } + } + + return index_; + } + + static void closure_ex(observer_ptr node_, bool &end_state_, + id_type &id_, id_type &user_id_, id_type &next_dfa_, + id_type &push_dfa_, bool &pop_dfa_, node_set &set_ptr_, + node_vector &vector_ptr_, std::size_t &hash_) + { + const bool temp_end_state_ = node_->end_state(); + + if (temp_end_state_) + { + if (!end_state_) + { + end_state_ = true; + id_ = node_->id(); + user_id_ = node_->user_id(); + next_dfa_ = node_->next_dfa(); + push_dfa_ = node_->push_dfa(); + pop_dfa_ = node_->pop_dfa(); + } + } + + if (set_ptr_.insert(node_).second) + { + vector_ptr_.push_back(node_); + hash_ += reinterpret_cast(node_); + } + } + + // NFA version + static void build_equiv_list(const node_vector &vector_, + const index_set_vector &set_mapping_, equivset_list &lhs_, + const std::false_type &) + { + fill_rhs_list(vector_, set_mapping_, lhs_); + } + + // DFA version + static void build_equiv_list(const node_vector &vector_, + const index_set_vector &set_mapping_, equivset_list &lhs_, + const std::true_type &) + { + equivset_list rhs_; + + fill_rhs_list(vector_, set_mapping_, rhs_); + + if (!rhs_.empty()) + { + typename equivset_list::iterator iter_; + typename equivset_list::iterator end_; + equivset_ptr overlap_ = std::make_unique(); + + lhs_.emplace_back(std::move(rhs_.front())); + rhs_.pop_front(); + + while (!rhs_.empty()) + { + equivset_ptr r_(rhs_.front().release()); + + rhs_.pop_front(); + iter_ = lhs_.begin(); + end_ = lhs_.end(); + + while (!r_->empty() && iter_ != end_) + { + auto l_iter_ = iter_; + + (*l_iter_)->intersect(*r_.get(), *overlap_.get()); + + if (overlap_->empty()) + { + ++iter_; + } + else if ((*l_iter_)->empty()) + { + l_iter_->reset(overlap_.release()); + overlap_ = std::make_unique(); + ++iter_; + } + else if (r_->empty()) + { + r_.reset(overlap_.release()); + overlap_ = std::make_unique(); + break; + } + else + { + iter_ = lhs_.insert(++iter_, equivset_ptr()); + iter_->reset(overlap_.release()); + overlap_ = std::make_unique(); + ++iter_; + end_ = lhs_.end(); + } + } + + if (!r_->empty()) + { + lhs_.emplace_back(std::move(r_)); + } + } + } + } + + static void fill_rhs_list(const node_vector &vector_, + const index_set_vector &set_mapping_, equivset_list &list_) + { + for (observer_ptr node_ : vector_) + { + if (!node_->end_state()) + { + const id_type token_ = node_->token(); + + if (token_ != node::null_token()) + { + if (token_ == parser::bol_token() || + token_ == parser::eol_token()) + { + std::set index_set_; + + index_set_.insert(token_); + list_.emplace_back + (std::make_unique(index_set_, + token_, node_->greedy(), node_->followpos())); + } + else + { + list_.emplace_back(std::make_unique + (set_mapping_[token_], token_, node_->greedy(), + node_->followpos())); + } + } + } + } + } +}; + +using generator = basic_generator; +using wgenerator = basic_generator; +using u32generator = basic_generator; +using char_generator = basic_generator; +using wchar_generator = basic_generator; +using u32char_generator = basic_generator; +} + +#endif diff --git a/YACReaderLibrary/lexertl/internals.hpp b/YACReaderLibrary/lexertl/internals.hpp new file mode 100644 index 000000000..a5e1dfe0e --- /dev/null +++ b/YACReaderLibrary/lexertl/internals.hpp @@ -0,0 +1,75 @@ +// internals.hpp +// Copyright (c) 2009-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_INTERNALS_HPP +#define LEXERTL_INTERNALS_HPP + +#include "enums.hpp" +#include +#include + +namespace lexertl +{ +namespace detail +{ +template +struct basic_internals +{ + using id_type_vector = std::vector; + using id_type_vector_vector = std::vector; + + id_type _eoi; + id_type_vector_vector _lookup; + id_type_vector _dfa_alphabet; + id_type _features; + id_type_vector_vector _dfa; + + basic_internals() : + _eoi(0), + _lookup(), + _dfa_alphabet(), + _features(0), + _dfa() + { + } + + void clear() + { + _eoi = 0; + _lookup.clear(); + _dfa_alphabet.clear(); + _features = 0; + _dfa.clear(); + } + + bool empty() const + { + return _dfa.empty(); + } + + void add_states(const std::size_t num_) + { + for (std::size_t index_ = 0; index_ < num_; ++index_) + { + // lookup *always* has a size 256 now. + _lookup.push_back(id_type_vector(256, dead_state_index)); + _dfa_alphabet.push_back(0); + _dfa.push_back(id_type_vector()); + } + } + + void swap(basic_internals &internals_) + { + std::swap(_eoi, internals_._eoi); + _lookup.swap(internals_._lookup); + _dfa_alphabet.swap(internals_._dfa_alphabet); + std::swap(_features, internals_._features); + _dfa.swap(internals_._dfa); + } +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/iterator.hpp b/YACReaderLibrary/lexertl/iterator.hpp new file mode 100644 index 000000000..5820ee02b --- /dev/null +++ b/YACReaderLibrary/lexertl/iterator.hpp @@ -0,0 +1,135 @@ +// iterator.hpp +// Copyright (c) 2015-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_ITERATOR_HPP +#define LEXERTL_ITERATOR_HPP + +#include +#include "lookup.hpp" +#include "state_machine.hpp" + +namespace lexertl +{ +template +class iterator +{ +public: + using value_type = results; + using difference_type = ptrdiff_t; + using pointer = const value_type *; + using reference = const value_type &; + using iterator_category = std::forward_iterator_tag; + + iterator() : + _results(iter(), iter()), + _sm(nullptr) + { + } + + iterator(const iter &start_, const iter &end_, const sm_type &sm) : + _results(start_, end_), + _sm(&sm) + { + lookup(); + } + + // Only need this because of warnings with gcc with -Weffc++ + iterator(const iterator &rhs_) + { + _results = rhs_._results; + _sm = rhs_._sm; + } + + // Only need this because of warnings with gcc with -Weffc++ + iterator &operator =(const iterator &rhs_) + { + if (&rhs_ != this) + { + _results = rhs_._results; + _sm = rhs_._sm; + } + + return *this; + } + + iterator &operator ++() + { + lookup(); + return *this; + } + + iterator operator ++(int) + { + iterator iter_ = *this; + + lookup(); + return iter_; + } + + const value_type &operator *() const + { + return _results; + } + + const value_type *operator ->() const + { + return &_results; + } + + bool operator ==(const iterator &rhs_) const + { + return _sm == rhs_._sm && (_sm == nullptr ? true : + _results == rhs_._results); + } + + bool operator !=(const iterator &rhs_) const + { + return !(*this == rhs_); + } + + const sm_type &sm() const + { + return *_sm; + } + +private: + value_type _results; + const sm_type *_sm; + + void lookup() + { + lexertl::lookup(*_sm, _results); + + if (_results.first == _results.eoi) + { + _sm = nullptr; + } + } +}; + +using siterator = + iterator; +using citerator = iterator; +using wsiterator = + iterator; +using wciterator = iterator; +using u32siterator = iterator; +using u32citerator = iterator; + +using sriterator = + iterator; +using criterator = iterator; +using wsriterator = + iterator; +using wcriterator = + iterator; +using u32sriterator = iterator; +using u32criterator = iterator; +} + +#endif diff --git a/YACReaderLibrary/lexertl/licence_1_0.txt b/YACReaderLibrary/lexertl/licence_1_0.txt new file mode 100644 index 000000000..7925d62e6 --- /dev/null +++ b/YACReaderLibrary/lexertl/licence_1_0.txt @@ -0,0 +1,24 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + diff --git a/YACReaderLibrary/lexertl/lookup.hpp b/YACReaderLibrary/lexertl/lookup.hpp new file mode 100644 index 000000000..903413cd8 --- /dev/null +++ b/YACReaderLibrary/lexertl/lookup.hpp @@ -0,0 +1,491 @@ +// lookup.hpp +// Copyright (c) 2009-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_LOOKUP_HPP +#define LEXERTL_LOOKUP_HPP + +#include +#include "match_results.hpp" +#include + +namespace lexertl +{ +namespace detail +{ +template +struct bol_state +{ + bol_state(const bool) + { + } +}; + +template<> +struct bol_state +{ + bool _bol; + bool _end_bol; + + bol_state(const bool bol_) : + _bol(bol_), + _end_bol(bol_) + { + } +}; + +template +struct eol_state +{ +}; + +template +struct eol_state +{ + id_type _EOL_state; + + eol_state() : + _EOL_state(0) + { + } +}; + +template +struct multi_state_state +{ + multi_state_state(const id_type) + { + } +}; + +template +struct multi_state_state +{ + id_type _start_state; + + multi_state_state(const id_type state_) : + _start_state(state_) + { + } +}; + +template +struct recursive_state +{ + recursive_state(const id_type *) + { + } +}; + +template +struct recursive_state +{ + bool _pop; + id_type _push_dfa; + + recursive_state(const id_type *ptr_) : + _pop((*ptr_ & pop_dfa_bit) != 0), + _push_dfa(*(ptr_ + push_dfa_index)) + { + } +}; + +template +struct lookup_state +{ + const id_type *_lookup; + id_type _dfa_alphabet; + const id_type *_dfa; + const id_type *_ptr; + bool _end_state; + id_type _id; + id_type _uid; + bol_state<(flags & bol_bit) != 0> _bol_state; + eol_state _eol_state; + multi_state_state + _multi_state_state; + recursive_state _recursive_state; + + lookup_state(const internals &internals_, const bool bol_, + const id_type state_) : + _lookup(&internals_._lookup[state_][0]), + _dfa_alphabet(internals_._dfa_alphabet[state_]), + _dfa(&internals_._dfa[state_][0]), + _ptr(_dfa + _dfa_alphabet), + _end_state(*_ptr != 0), + _id(*(_ptr + id_index)), + _uid(*(_ptr + user_id_index)), + _bol_state(bol_), + _eol_state(), + _multi_state_state(state_), + _recursive_state(_ptr) + { + } + + void reset_recursive(const std::false_type &) + { + // Do nothing + } + + void reset_recursive(const std::true_type &) + { + _recursive_state._pop = (*_ptr & pop_dfa_bit) != 0; + _recursive_state._push_dfa = *(_ptr + push_dfa_index); + } + + void bol_start_state(const std::false_type &) + { + // Do nothing + } + + void bol_start_state(const std::true_type &) + { + if (_bol_state._bol) + { + const id_type state_ = *_dfa; + + if (state_) + { + _ptr = &_dfa[state_ * _dfa_alphabet]; + } + } + } + + template + bool is_eol(const char_type, const std::false_type &) + { + return false; + } + + template + bool is_eol(const char_type curr_, const std::true_type &) + { + bool ret_ = false; + + _eol_state._EOL_state = _ptr[eol_index]; + ret_ = _eol_state._EOL_state && (curr_ == '\r' || curr_ == '\n'); + + if (ret_) + { + _ptr = &_dfa[_eol_state._EOL_state * _dfa_alphabet]; + } + + return ret_; + } + + template + id_type next_char(const char_type prev_char_, const std::false_type &) + { + const id_type state_= _ptr[_lookup + [static_cast(prev_char_)]]; + + if (state_ != 0) + { + _ptr = &_dfa[state_ * _dfa_alphabet]; + } + + return state_; + } + + template + id_type next_char(const char_type prev_char_, const std::true_type &) + { + const std::size_t bytes_ = sizeof(char_type) < 3 ? + sizeof(char_type) : 3; + const std::size_t shift_[] = {0, 8, 16}; + id_type state_= 0; + + for (std::size_t i_ = 0; i_ < bytes_; ++i_) + { + state_ = _ptr[_lookup[static_cast((prev_char_ >> + shift_[bytes_ - 1 - i_]) & 0xff)]]; + + if (state_ == 0) + { + break; + } + + _ptr = &_dfa[state_ * _dfa_alphabet]; + } + + return state_; + } + + template + void bol(const char_type, const std::false_type &) + { + // Do nothing + } + + template + void bol(const char_type prev_char_, const std::true_type &) + { + _bol_state._bol = prev_char_ == '\n'; + } + + void eol(const id_type, const std::false_type &) + { + // Do nothing + } + + void eol(const id_type err_val_, const std::true_type &) + { + _eol_state._EOL_state = err_val_; + } + + void reset_start_state(const std::false_type &) + { + // Do nothing + } + + void reset_start_state(const std::true_type &) + { + _multi_state_state._start_state = *(_ptr + next_dfa_index); + } + + void reset_end_bol(const std::false_type &) + { + // Do nothing + } + + void reset_end_bol(const std::true_type &) + { + _bol_state._end_bol = _bol_state._bol; + } + + template + void end_state(iter_type &end_token_, iter_type &curr_) + { + if (*_ptr) + { + _end_state = true; + reset_end_bol + (std::integral_constant()); + _id = *(_ptr + id_index); + _uid = *(_ptr + user_id_index); + reset_recursive + (std::integral_constant()); + reset_start_state(std::integral_constant()); + end_token_ = curr_; + } + } + + template + void check_eol(iter_type &, iter_type &, const id_type, + const char_type, const std::false_type &) + { + // Do nothing + } + + template + void check_eol(iter_type &end_token_, iter_type &curr_, + const id_type npos, const char_type eoi_, const std::true_type &) + { + if (_eol_state._EOL_state != npos && curr_ == eoi_) + { + _eol_state._EOL_state = _ptr[eol_index]; + + if (_eol_state._EOL_state) + { + _ptr = &_dfa[_eol_state._EOL_state * _dfa_alphabet]; + end_state(end_token_, curr_); + } + } + } + + template + void pop(results &, const std::false_type &) + { + // Nothing to do + } + + template + void pop(results &results_, const std::true_type &) + { + if (_recursive_state._pop) + { + _multi_state_state._start_state = results_.stack.top().first; + results_.stack.pop(); + } + else if (_recursive_state._push_dfa != results::npos()) + { + results_.stack.push(typename results::id_type_pair + (_recursive_state._push_dfa, _id)); + } + } + + template + bool is_id_eoi(const id_type eoi_, const results &, const std::false_type &) + { + return _id == eoi_; + } + + template + bool is_id_eoi(const id_type eoi_, const results &results_, + const std::true_type &) + { + return _id == eoi_ || (_recursive_state._pop && + !results_.stack.empty() && results_.stack.top().second == eoi_); + } + + void start_state(id_type &, const std::false_type &) + { + // Do nothing + } + + void start_state(id_type &start_state_, const std::true_type &) + { + start_state_ = _multi_state_state._start_state; + } + + void bol(bool &, const std::false_type &) + { + // Do nothing + } + + void bol(bool &end_bol_, const std::true_type &) + { + end_bol_ = _bol_state._end_bol; + } +}; + +template +void inc_end(results &, const std::false_type &) +{ + // Do nothing +} + +template +void inc_end(results &results_, const std::true_type &) +{ + ++results_.second; +} + +template +void next(const sm_type &sm_, results &results_, + const std::integral_constant &compressed_, + const std::integral_constant &recursive_, + const std::forward_iterator_tag &) +{ + using id_type = typename sm_type::id_type; + const auto &internals_ = sm_.data(); + auto end_token_ = results_.second; + +skip: + auto curr_ = results_.second; + + results_.first = curr_; + +again: + if (curr_ == results_.eoi) + { + results_.id = internals_._eoi; + results_.user_id = results::npos(); + return; + } + + lookup_state lu_state_ + (internals_, results_.bol, results_.state); + lu_state_.bol_start_state + (std::integral_constant()); + + while (curr_ != results_.eoi) + { + if (!lu_state_.is_eol(*curr_, + std::integral_constant())) + { + const auto prev_char_ = *curr_; + const id_type state_ = lu_state_.next_char(prev_char_, + compressed_); + + ++curr_; + lu_state_.bol(prev_char_, + std::integral_constant()); + + if (state_ == 0) + { + lu_state_.is_eol(results::npos(), + std::integral_constant()); + break; + } + } + + lu_state_.end_state(end_token_, curr_); + } + + lu_state_.check_eol(end_token_, curr_, results::npos(), results_.eoi, + std::integral_constant()); + + if (lu_state_._end_state) + { + // Return longest match + lu_state_.pop(results_, recursive_); + + lu_state_.start_state(results_.state, + std::integral_constant()); + lu_state_.bol(results_.bol, + std::integral_constant()); + results_.second = end_token_; + + if (lu_state_._id == sm_.skip()) goto skip; + + if (lu_state_.is_id_eoi(internals_._eoi, results_, recursive_)) + { + curr_ = end_token_; + goto again; + } + } + else + { + results_.second = end_token_; + results_.bol = *results_.second == '\n'; + results_.first = results_.second; + // No match causes char to be skipped + inc_end(results_, + std::integral_constant()); + lu_state_._id = results::npos(); + lu_state_._uid = results::npos(); + } + + results_.id = lu_state_._id; + results_.user_id = lu_state_._uid; +} +} + +template +void lookup(const sm_type &sm_, match_results &results_) +{ + using value_type = typename std::iterator_traits::value_type; + using cat = typename std::iterator_traits::iterator_category; + + // If this asserts, you have either not defined all the correct + // flags, or you should be using recursive_match_results instead + // of match_results. + assert((sm_.data()._features & flags) == sm_.data()._features); + detail::next(sm_, results_, + std::integral_constant 1)>(), + std::false_type(), cat()); +} + +template +void lookup(const sm_type &sm_, recursive_match_results &results_) +{ + using value_type = typename std::iterator_traits::value_type; + using cat = typename std::iterator_traits::iterator_category; + + // If this asserts, you have not defined all the correct flags + assert((sm_.data()._features & flags) == sm_.data()._features); + detail::next(sm_, results_, + std::integral_constant 1)>(), + std::true_type(), cat()); +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/match_results.hpp b/YACReaderLibrary/lexertl/match_results.hpp new file mode 100644 index 000000000..078d8df11 --- /dev/null +++ b/YACReaderLibrary/lexertl/match_results.hpp @@ -0,0 +1,171 @@ +// match_results.hpp +// Copyright (c) 2015-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_MATCH_RESULTS_HPP +#define LEXERTL_MATCH_RESULTS_HPP + +#include "char_traits.hpp" +#include "enums.hpp" +#include +#include +#include + +namespace lexertl +{ +template +struct match_results +{ + using iter_type = iter; + using char_type = typename std::iterator_traits::value_type; + using index_type = typename basic_char_traits::index_type; + using string = std::basic_string; + + id_type id; + id_type user_id; + iter_type first; + iter_type second; + iter_type eoi; + bool bol; + id_type state; + + match_results() : + id(0), + user_id(npos()), + first(iter_type()), + second(iter_type()), + eoi(iter_type()), + bol(true), + state(0) + { + } + + match_results(const iter_type &start_, const iter_type &end_) : + id(0), + user_id(npos()), + first(start_), + second(start_), + eoi(end_), + bol(true), + state(0) + { + } + + virtual ~match_results() + { + } + + string str() const + { + return string(first, second); + } + + string substr(const std::size_t soffset_, const std::size_t eoffset_) const + { + return string(first + soffset_, second - eoffset_); + } + + virtual void clear() + { + id = 0; + user_id = npos(); + first = eoi; + second = eoi; + bol = true; + state = 0; + } + + virtual void reset(const iter_type &start_, const iter_type &end_) + { + id = 0; + user_id = npos(); + first = start_; + second = start_; + eoi = end_; + bol = true; + state = 0; + } + + static id_type npos() + { + return static_cast(~0); + } + + static id_type skip() + { + return static_cast(~1); + } + + bool operator ==(const match_results &rhs_) const + { + return id == rhs_.id && + user_id == rhs_.user_id && + first == rhs_.first && + second == rhs_.second && + eoi == rhs_.eoi && + bol == rhs_.bol && + state == rhs_.state; + } +}; + +template +struct recursive_match_results : public match_results +{ + using id_type_pair = std::pair; + std::stack stack; + + recursive_match_results() : + match_results(), + stack() + { + } + + recursive_match_results(const iter &start_, const iter &end_) : + match_results(start_, end_), + stack() + { + } + + virtual ~recursive_match_results() override + { + } + + virtual void clear() override + { + match_results::clear(); + + while (!stack.empty()) stack.pop(); + } + + virtual void reset(const iter &start_, const iter &end_) override + { + match_results::reset(start_, end_); + + while (!stack.empty()) stack.pop(); + } +}; + +using smatch = match_results; +using cmatch = match_results; +using wsmatch = match_results; +using wcmatch = match_results; +using u32smatch = match_results; +using u32cmatch = match_results; + +using srmatch = + recursive_match_results; +using crmatch = recursive_match_results; +using wsrmatch = + recursive_match_results; +using wcrmatch = recursive_match_results; +using u32srmatch = + recursive_match_results; +using u32crmatch = recursive_match_results; +} + +#endif diff --git a/YACReaderLibrary/lexertl/memory_file.hpp b/YACReaderLibrary/lexertl/memory_file.hpp new file mode 100644 index 000000000..4ea42a4d7 --- /dev/null +++ b/YACReaderLibrary/lexertl/memory_file.hpp @@ -0,0 +1,138 @@ +// memory_file.hpp +// Copyright (c) 2015-2018 Ben Hanson (http://www.benhanson.net/) +// Inspired by http://en.wikibooks.org/wiki/Optimizing_C%2B%2B/ +// General_optimization_techniques/Input/Output#Memory-mapped_file +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_MEMORY_FILE_HPP +#define LEXERTL_MEMORY_FILE_HPP + +#include + +#ifdef _WIN32 +#include +#else +#include +#include +#include +#include +#endif + +// Only files small enough to fit into memory are supported. +namespace lexertl +{ +template +class basic_memory_file +{ +public: + basic_memory_file() + { + } + + basic_memory_file(const char *pathname_) + { + open(pathname_); + } + + ~basic_memory_file() + { + close(); + } + + void open(const char *pathname_) + { + if (_data) close(); + +#ifdef _WIN32 + _fh = ::CreateFileA(pathname_, GENERIC_READ, FILE_SHARE_READ, 0, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + _fmh = 0; + + if (_fh != INVALID_HANDLE_VALUE) + { + _fmh = ::CreateFileMapping(_fh, 0, PAGE_READONLY, 0, 0, 0); + + if (_fmh != 0) + { + _data = static_cast(::MapViewOfFile + (_fmh, FILE_MAP_READ, 0, 0, 0)); + + if (_data) _size = ::GetFileSize(_fh, 0) / sizeof(char_type); + } + } +#else + _fh = ::open(pathname_, O_RDONLY); + + if (_fh > -1) + { + struct stat sbuf_; + + if (::fstat(_fh, &sbuf_) > -1) + { + _data = static_cast + (::mmap(0, sbuf_.st_size, PROT_READ, MAP_SHARED, _fh, 0)); + + if (_data == MAP_FAILED) + { + _data = nullptr; + } + else + { + _size = sbuf_.st_size / sizeof(char_type); + } + } + } +#endif + } + + const char_type *data() const + { + return _data; + } + + std::size_t size() const + { + return _size; + } + + void close() + { +#ifdef _WIN32 + ::UnmapViewOfFile(_data); + ::CloseHandle(_fmh); + ::CloseHandle(_fh); +#else + ::munmap(const_cast(_data), _size); + ::close(_fh); +#endif + _data = nullptr; + _size = 0; + _fh = 0; +#ifdef _WIN32 + _fmh = 0; +#endif + } + +private: + const char_type *_data = nullptr; + std::size_t _size = 0; +#ifdef _WIN32 + HANDLE _fh = 0; + HANDLE _fmh = 0; +#else + int _fh = 0; +#endif + + // No copy construction. + basic_memory_file(const basic_memory_file &) = delete; + // No assignment. + basic_memory_file &operator =(const basic_memory_file &) = delete; +}; + +using memory_file = basic_memory_file; +using wmemory_file = basic_memory_file; +} + +#endif diff --git a/YACReaderLibrary/lexertl/narrow.hpp b/YACReaderLibrary/lexertl/narrow.hpp new file mode 100644 index 000000000..94b2f6c2f --- /dev/null +++ b/YACReaderLibrary/lexertl/narrow.hpp @@ -0,0 +1,25 @@ +// narrow.hpp +// Copyright (c) 2015-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_NARROW_HPP +#define LEXERTL_NARROW_HPP + +#include + +namespace lexertl +{ +template +void narrow(const char_type *str_, std::ostringstream &ss_) +{ + while (*str_) + { + // Safe to simply cast to char. + // when string only contains ASCII. + ss_ << static_cast(*str_++); + } +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/observer_ptr.hpp b/YACReaderLibrary/lexertl/observer_ptr.hpp new file mode 100644 index 000000000..9ecd8255c --- /dev/null +++ b/YACReaderLibrary/lexertl/observer_ptr.hpp @@ -0,0 +1,16 @@ +// observer_ptr.hpp +// Copyright (c) 2017-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_OBSERVER_PTR_HPP +#define LEXERTL_OBSERVER_PTR_HPP + +namespace lexertl +{ + template + using observer_ptr = T *; +} + +#endif diff --git a/YACReaderLibrary/lexertl/parser/parser.hpp b/YACReaderLibrary/lexertl/parser/parser.hpp new file mode 100644 index 000000000..002f8d87c --- /dev/null +++ b/YACReaderLibrary/lexertl/parser/parser.hpp @@ -0,0 +1,926 @@ +// parser.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_PARSER_HPP +#define LEXERTL_PARSER_HPP + +#include +#include +#include "tree/end_node.hpp" +#include "tree/iteration_node.hpp" +#include "tree/leaf_node.hpp" +#include +#include "tokeniser/re_tokeniser.hpp" +#include "../runtime_error.hpp" +#include "tree/selection_node.hpp" +#include "tree/sequence_node.hpp" +#include +#include + +namespace lexertl +{ +namespace detail +{ +/* + General principles of regex parsing: + - Every regex is a sequence of sub-regexes. + - Regexes consist of operands and operators + - All operators decompose to sequence, selection ('|') and iteration ('*') + - Regex tokens are stored on a stack. + - When a complete sequence of regex tokens is on the stack it is processed. + +Grammar: + + -> + -> | '|' + -> + -> | + -> + -> charset | macro | '('')' | + -> '?' | '??' | '*' | '*?' | '+' | '+?' | '{n[,[m]]}' | + '{n[,[m]]}?' +*/ + +template +class basic_parser +{ +public: + enum {char_24_bit = sm_traits::char_24_bit}; + using char_type = typename sm_traits::char_type; + using id_type = typename sm_traits::id_type; + using end_node = basic_end_node; + using input_char_type = typename sm_traits::input_char_type; + using input_string_token = basic_string_token; + using iteration_node = basic_iteration_node; + using leaf_node = basic_leaf_node; + using tokeniser = + basic_re_tokeniser; + using node = basic_node; + using node_ptr_vector = typename node::node_ptr_vector; + using string = std::basic_string; + using string_token = basic_string_token; + using selection_node = basic_selection_node; + using sequence_node = basic_sequence_node; + using charset_map = std::map; + using charset_pair = std::pair; + using compressed = std::integral_constant; + using token = basic_re_token; + static_assert(std::is_move_assignable::value && + std::is_move_constructible::value, + "token is not movable."); + using token_vector = std::vector; + + basic_parser(const std::locale &locale_, + node_ptr_vector &node_ptr_vector_, + charset_map &charset_map_, const id_type eoi_) : + _locale(locale_), + _node_ptr_vector(node_ptr_vector_), + _charset_map(charset_map_), + _eoi(eoi_), + _token_stack(), + _tree_node_stack() + { + } + + observer_ptr parse(const token_vector ®ex_, const id_type id_, + const id_type user_id_, const id_type next_dfa_, + const id_type push_dfa_, const bool pop_dfa_, + const std::size_t flags_, id_type &nl_id_, const bool seen_bol_) + { + auto iter_ = regex_.cbegin(); + auto end_ = regex_.cend(); + observer_ptr root_ = nullptr; + observer_ptr lhs_token_ = nullptr; + // There cannot be less than 2 tokens + auto rhs_token_ = std::make_unique(*iter_++); + char action_ = 0; + + _token_stack.emplace(std::move(rhs_token_)); + rhs_token_ = std::make_unique(*iter_); + + if (iter_ + 1 != end_) ++iter_; + + do + { + lhs_token_ = _token_stack.top().get(); + action_ = lhs_token_->precedence(rhs_token_->_type); + + switch (action_) + { + case '<': + case '=': + _token_stack.emplace(std::move(rhs_token_)); + rhs_token_ = std::make_unique(*iter_); + + if (iter_ + 1 != end_) ++iter_; + + break; + case '>': + reduce(nl_id_); + break; + default: + { + std::ostringstream ss_; + + ss_ << "A syntax error occurred: '" << + lhs_token_->precedence_string() << + "' against '" << rhs_token_->precedence_string() << + " in rule id " << id_ << '.'; + throw runtime_error(ss_.str()); + break; + } + } + } while (!_token_stack.empty()); + + if (_tree_node_stack.empty()) + { + std::ostringstream ss_; + + ss_ << "Empty rules are not allowed in rule id " << + id_ << '.'; + throw runtime_error(ss_.str()); + } + + assert(_tree_node_stack.size() == 1); + + observer_ptr lhs_node_ = _tree_node_stack.top(); + + _tree_node_stack.pop(); + _node_ptr_vector.emplace_back(std::make_unique + (id_, user_id_, next_dfa_, push_dfa_, pop_dfa_)); + + observer_ptr rhs_node_ = _node_ptr_vector.back().get(); + + _node_ptr_vector.emplace_back(std::make_unique + (lhs_node_, rhs_node_)); + root_ = _node_ptr_vector.back().get(); + + if (seen_bol_) + { + fixup_bol(root_); + } + + if ((flags_ & match_zero_len) == 0) + { + const auto &firstpos_ = root_->firstpos(); + + for (observer_ptr node_ : firstpos_) + { + if (node_->end_state()) + { + std::ostringstream ss_; + + ss_ << "Rules that match zero characters are not allowed " + "as this can cause an infinite loop in user code. The " + "match_zero_len flag overrides this check. Rule id " << + id_ << '.'; + throw runtime_error(ss_.str()); + } + } + } + + return root_; + } + + static id_type bol_token() + { + return static_cast(~1); + } + + static id_type eol_token() + { + return static_cast(~2); + } + +private: + using input_range = typename input_string_token::range; + using range = typename string_token::range; + using string_token_vector = std::vector>; + using token_stack = std::stack>; + using tree_node_stack = typename node::node_stack; + + const std::locale &_locale; + node_ptr_vector &_node_ptr_vector; + charset_map &_charset_map; + id_type _eoi; + token_stack _token_stack; + tree_node_stack _tree_node_stack; + + void reduce(id_type &nl_id_) + { + observer_ptr lhs_ = nullptr; + observer_ptr rhs_ = nullptr; + token_stack handle_; + char action_ = 0; + + do + { + handle_.emplace(); + rhs_ = _token_stack.top().release(); + handle_.top().reset(rhs_); + _token_stack.pop(); + + if (!_token_stack.empty()) + { + lhs_ = _token_stack.top().get(); + action_ = lhs_->precedence(rhs_->_type); + } + } while (!_token_stack.empty() && action_ == '='); + + assert(_token_stack.empty() || action_ == '<'); + + switch (rhs_->_type) + { + case BEGIN: + // finished processing so exit + break; + case REGEX: + // finished parsing, nothing to do + break; + case OREXP: + orexp(handle_); + break; + case SEQUENCE: + _token_stack.emplace(std::make_unique(OREXP)); + break; + case SUB: + sub(handle_); + break; + case EXPRESSION: + _token_stack.emplace(std::make_unique(SUB)); + break; + case REPEAT: + repeat(handle_); + break; + case BOL: + bol(handle_); + break; + case EOL: + eol(handle_, nl_id_); + break; + case CHARSET: + charset(handle_, compressed()); + break; + case OPENPAREN: + openparen(handle_); + break; + case OPT: + case AOPT: + optional(rhs_->_type == OPT); + _token_stack.emplace(std::make_unique(DUP)); + break; + case ZEROORMORE: + case AZEROORMORE: + zero_or_more(rhs_->_type == ZEROORMORE); + _token_stack.emplace(std::make_unique(DUP)); + break; + case ONEORMORE: + case AONEORMORE: + one_or_more(rhs_->_type == ONEORMORE); + _token_stack.emplace(std::make_unique(DUP)); + break; + case REPEATN: + case AREPEATN: + repeatn(rhs_->_type == REPEATN, handle_.top().get()); + _token_stack.emplace(std::make_unique(DUP)); + break; + default: + throw runtime_error + ("Internal error in regex_parser::reduce."); + break; + } + } + + void orexp(token_stack &handle_) + { + assert(handle_.top()->_type == OREXP && + (handle_.size() == 1 || handle_.size() == 3)); + + if (handle_.size() == 1) + { + _token_stack.emplace(std::make_unique(REGEX)); + } + else + { + handle_.pop(); + assert(handle_.top()->_type == OR); + handle_.pop(); + assert(handle_.top()->_type == SEQUENCE); + perform_or(); + _token_stack.emplace(std::make_unique(OREXP)); + } + } + + void perform_or() + { + // perform or + observer_ptr rhs_ = _tree_node_stack.top(); + + _tree_node_stack.pop(); + + observer_ptr lhs_ = _tree_node_stack.top(); + + _node_ptr_vector.emplace_back + (std::make_unique(lhs_, rhs_)); + _tree_node_stack.top() = _node_ptr_vector.back().get(); + } + + void sub(token_stack &handle_) + { + assert((handle_.top()->_type == SUB && + handle_.size() == 1) || handle_.size() == 2); + + if (handle_.size() == 1) + { + _token_stack.emplace(std::make_unique(SEQUENCE)); + } + else + { + handle_.pop(); + assert(handle_.top()->_type == EXPRESSION); + // perform join + sequence(); + _token_stack.emplace(std::make_unique(SUB)); + } + } + + void repeat(token_stack &handle_) + { + assert(handle_.top()->_type == REPEAT && + handle_.size() >= 1 && handle_.size() <= 3); + + if (handle_.size() == 1) + { + _token_stack.emplace(std::make_unique(EXPRESSION)); + } + else + { + handle_.pop(); + assert(handle_.top()->_type == DUP); + _token_stack.emplace(std::make_unique(REPEAT)); + } + } + +#ifndef NDEBUG + void bol(token_stack &handle_) +#else + void bol(token_stack &) +#endif + { + assert(handle_.top()->_type == BOL && + handle_.size() == 1); + + // store charset + _node_ptr_vector.emplace_back + (std::make_unique(bol_token(), true)); + _tree_node_stack.push(_node_ptr_vector.back().get()); + _token_stack.emplace(std::make_unique(REPEAT)); + } + +#ifndef NDEBUG + void eol(token_stack &handle_, id_type &nl_id_) +#else + void eol(token_stack &, id_type &nl_id_) +#endif + { + const string_token nl_('\n'); + const id_type temp_nl_id_ = lookup(nl_); + + assert(handle_.top()->_type == EOL && + handle_.size() == 1); + + if (temp_nl_id_ != ~static_cast(0)) + { + nl_id_ = temp_nl_id_; + } + + // store charset + _node_ptr_vector.emplace_back + (std::make_unique(eol_token(), true)); + _tree_node_stack.push(_node_ptr_vector.back().get()); + _token_stack.emplace(std::make_unique(REPEAT)); + } + + // Uncompressed + void charset(token_stack &handle_, const std::false_type &) + { + assert(handle_.top()->_type == CHARSET && + handle_.size() == 1); + + const id_type id_ = lookup(handle_.top()->_str); + + // store charset + _node_ptr_vector.emplace_back(std::make_unique(id_, true)); + _tree_node_stack.push(_node_ptr_vector.back().get()); + _token_stack.emplace(std::make_unique(REPEAT)); + } + + // Compressed + void charset(token_stack &handle_, const std::true_type &) + { + assert(handle_.top()->_type == CHARSET && + handle_.size() == 1); + + std::unique_ptr token_(handle_.top().release()); + + handle_.pop(); + create_sequence(token_); + } + + // Slice wchar_t into sequence of char. + void create_sequence(std::unique_ptr &token_) + { + string_token_vector data_[char_24_bit ? 3 : 2]; + + for (const input_range &range_ : token_->_str._ranges) + { + slice_range(range_, data_, + std::integral_constant()); + } + + push_ranges(data_, std::integral_constant()); + + _token_stack.emplace(std::make_unique(OPENPAREN)); + _token_stack.emplace(std::make_unique(REGEX)); + _token_stack.emplace(std::make_unique(CLOSEPAREN)); + } + + // 16 bit unicode + void slice_range(const input_range &range_, string_token_vector data_[2], + const std::false_type &) + { + const unsigned char first_msb_ = static_cast + ((range_.first >> 8) & 0xff); + const unsigned char first_lsb_ = static_cast + (range_.first & 0xff); + const unsigned char second_msb_ = static_cast + ((range_.second >> 8) & 0xff); + const unsigned char second_lsb_ = static_cast + (range_.second & 0xff); + + if (first_msb_ == second_msb_) + { + insert_range(first_msb_, first_msb_, first_lsb_, + second_lsb_, data_); + } + else + { + insert_range(first_msb_, first_msb_, first_lsb_, 0xff, data_); + + if (second_msb_ > first_msb_ + 1) + { + insert_range(first_msb_ + 1, second_msb_ - 1, 0, 0xff, data_); + } + + insert_range(second_msb_, second_msb_, 0, second_lsb_, data_); + } + } + + // 24 bit unicode + void slice_range(const input_range &range_, string_token_vector data_[3], + const std::true_type &) + { + const unsigned char first_msb_ = static_cast + ((range_.first >> 16) & 0xff); + const unsigned char first_mid_ = static_cast + ((range_.first >> 8) & 0xff); + const unsigned char first_lsb_ = static_cast + (range_.first & 0xff); + const unsigned char second_msb_ = static_cast + ((range_.second >> 16) & 0xff); + const unsigned char second_mid_ = static_cast + ((range_.second >> 8) & 0xff); + const unsigned char second_lsb_ = static_cast + (range_.second & 0xff); + + if (first_msb_ == second_msb_) + { + string_token_vector data2_[2]; + + // Re-use 16 bit slice function + slice_range(range_, data2_, std::false_type()); + + for (std::size_t i_ = 0, size_ = data2_[0].size(); + i_ < size_; ++i_) + { + insert_range(string_token(first_msb_, first_msb_), + *data2_[0][i_], *data2_[1][i_], data_); + } + } + else + { + insert_range(first_msb_, first_msb_, + first_mid_, first_mid_, + first_lsb_, 0xff, data_); + + if (first_mid_ != 0xff) + { + insert_range(first_msb_, first_msb_, + first_mid_ + 1, 0xff, + 0, 0xff, data_); + } + + if (second_msb_ > first_msb_ + 1) + { + insert_range(first_mid_ + 1, second_mid_ - 1, + 0, 0xff, + 0, 0xff, data_); + } + + if (second_mid_ != 0) + { + insert_range(second_msb_, second_msb_, + 0, second_mid_ - 1, + 0, 0xff, data_); + insert_range(second_msb_, second_msb_, + second_mid_, second_mid_, + 0, second_lsb_, data_); + } + else + { + insert_range(second_msb_, second_msb_, + 0, second_mid_, + 0, second_lsb_, data_); + } + } + } + + // 16 bit unicode + void insert_range(const unsigned char first_, const unsigned char second_, + const unsigned char first2_, const unsigned char second2_, + string_token_vector data_[2]) + { + const string_token token_(first_ > second_ ? second_ : first_, + first_ > second_ ? first_ : second_); + const string_token token2_(first2_ > second2_ ? second2_ : first2_, + first2_ > second2_ ? first2_ : second2_); + + insert_range(token_, token2_, data_); + } + + void insert_range(const string_token &token_, const string_token &token2_, + string_token_vector data_[2]) + { + typename string_token_vector::const_iterator iter_ = + std::find_if(data_[0].begin(), data_[0].end(), + [&token_](const std::unique_ptr &rhs_) + { + return token_ == *rhs_.get(); + }); + + if (iter_ == data_[0].end()) + { + data_[0].emplace_back(std::make_unique(token_)); + data_[1].emplace_back(std::make_unique(token2_)); + } + else + { + const std::size_t index_ = iter_ - data_[0].begin(); + + data_[1][index_]->insert(token2_); + } + } + + // 24 bit unicode + void insert_range(const unsigned char first_, const unsigned char second_, + const unsigned char first2_, const unsigned char second2_, + const unsigned char first3_, const unsigned char second3_, + string_token_vector data_[3]) + { + const string_token token_(first_ > second_ ? second_ : first_, + first_ > second_ ? first_ : second_); + const string_token token2_(first2_ > second2_ ? second2_ : first2_, + first2_ > second2_ ? first2_ : second2_); + const string_token token3_(first3_ > second3_ ? second3_ : first3_, + first3_ > second3_ ? first3_ : second3_); + + insert_range(token_, token2_, token3_, data_); + } + + void insert_range(const string_token &token_, const string_token &token2_, + const string_token &token3_, string_token_vector data_[3]) + { + auto iter_ = data_[0].cbegin(); + auto end_ = data_[0].cend(); + bool finished_ = false; + + do + { + iter_ = std::find_if(iter_, end_, + [&token_](const std::unique_ptr &rhs_) + { + return token_ == *rhs_.get(); + }); + + if (iter_ == end_) + { + data_[0].emplace_back(std::make_unique(token_)); + data_[1].emplace_back(std::make_unique(token2_)); + data_[2].emplace_back(std::make_unique(token3_)); + finished_ = true; + } + else + { + const std::size_t index_ = iter_ - data_[0].begin(); + + if (*data_[1][index_] == token2_) + { + data_[2][index_]->insert(token3_); + finished_ = true; + } + else + { + ++iter_; + } + } + } while (!finished_); + } + + // 16 bit unicode + void push_ranges(string_token_vector data_[2], const std::false_type &) + { + auto viter_ = data_[0].cbegin(); + auto vend_ = data_[0].cend(); + auto viter2_ = data_[1].cbegin(); + + push_range(viter_++->get()); + push_range(viter2_++->get()); + sequence(); + + while (viter_ != vend_) + { + push_range(viter_++->get()); + push_range(viter2_++->get()); + sequence(); + perform_or(); + } + } + + // 24 bit unicode + void push_ranges(string_token_vector data_[3], const std::true_type &) + { + auto viter_ = data_[0].cbegin(); + auto vend_ = data_[0].cend(); + auto viter2_ = data_[1].cbegin(); + auto viter3_ = data_[2].cbegin(); + + push_range(viter_++->get()); + push_range(viter2_++->get()); + sequence(); + push_range(viter3_++->get()); + sequence(); + + while (viter_ != vend_) + { + push_range(viter_++->get()); + push_range(viter2_++->get()); + sequence(); + push_range(viter3_++->get()); + sequence(); + perform_or(); + } + } + + void push_range(observer_ptr token_) + { + const id_type id_ = lookup(*token_); + + _node_ptr_vector.emplace_back(std::make_unique(id_, true)); + _tree_node_stack.push(_node_ptr_vector.back().get()); + } + + id_type lookup(const string_token &charset_) + { + // Converted to id_type below. + std::size_t id_ = sm_traits::npos(); + + if (static_cast(id_) < id_) + { + throw runtime_error("id_type is not large enough " + "to hold all ids."); + } + + typename charset_map::const_iterator iter_ = + _charset_map.find(charset_); + + if (iter_ == _charset_map.end()) + { + id_ = _charset_map.size(); + _charset_map.insert(charset_pair(charset_, + static_cast(id_))); + } + else + { + id_ = iter_->second; + } + + return static_cast(id_); + } + + void openparen(token_stack &handle_) + { + assert(handle_.top()->_type == OPENPAREN && + handle_.size() == 3); + + handle_.pop(); + assert(handle_.top()->_type == REGEX); + handle_.pop(); + assert(handle_.top()->_type == CLOSEPAREN); + _token_stack.emplace(std::make_unique(REPEAT)); + } + + void sequence() + { + observer_ptr rhs_ = _tree_node_stack.top(); + + _tree_node_stack.pop(); + + observer_ptr lhs_ = _tree_node_stack.top(); + + _node_ptr_vector.emplace_back + (std::make_unique(lhs_, rhs_)); + _tree_node_stack.top() = _node_ptr_vector.back().get(); + } + + void optional(const bool greedy_) + { + // perform ? + observer_ptr lhs_ = _tree_node_stack.top(); + // Don't know if lhs_ is a leaf_node, so get firstpos. + auto &firstpos_ = lhs_->firstpos(); + + for (observer_ptr node_ : firstpos_) + { + // These are leaf_nodes! + node_->greedy(greedy_); + } + + _node_ptr_vector.emplace_back(std::make_unique + (node::null_token(), greedy_)); + + observer_ptr rhs_ = _node_ptr_vector.back().get(); + + _node_ptr_vector.emplace_back + (std::make_unique(lhs_, rhs_)); + _tree_node_stack.top() = _node_ptr_vector.back().get(); + } + + void zero_or_more(const bool greedy_) + { + // perform * + observer_ptr ptr_ = _tree_node_stack.top(); + + _node_ptr_vector.emplace_back + (std::make_unique(ptr_, greedy_)); + _tree_node_stack.top() = _node_ptr_vector.back().get(); + } + + void one_or_more(const bool greedy_) + { + // perform + + observer_ptr lhs_ = _tree_node_stack.top(); + observer_ptr copy_ = lhs_->copy(_node_ptr_vector); + + _node_ptr_vector.emplace_back(std::make_unique + (copy_, greedy_)); + + observer_ptr rhs_ = _node_ptr_vector.back().get(); + + _node_ptr_vector.emplace_back + (std::make_unique(lhs_, rhs_)); + _tree_node_stack.top() = _node_ptr_vector.back().get(); + } + + // perform {n[,[m]]} + // Semantic checks have already been performed. + // {0,} = * + // {0,1} = ? + // {1,} = + + // therefore we do not check for these cases. + void repeatn(const bool greedy_, observer_ptr token_) + { + const rules_char_type *str_ = token_->_extra.c_str(); + std::size_t min_ = 0; + bool comma_ = false; + std::size_t max_ = 0; + + while (*str_>= '0' && *str_ <= '9') + { + min_ *= 10; + min_ += *str_ - '0'; + ++str_; + } + + comma_ = *str_ == ','; + + if (comma_) ++str_; + + while (*str_>= '0' && *str_ <= '9') + { + max_ *= 10; + max_ += *str_ - '0'; + ++str_; + } + + if (!(min_ == 1 && !comma_)) + { + const std::size_t top_ = min_ > 0 ? min_ : max_; + + if (min_ == 0) + { + optional(greedy_); + } + + observer_ptr prev_ = _tree_node_stack.top()-> + copy(_node_ptr_vector); + observer_ptr curr_ = nullptr; + + for (std::size_t i_ = 2; i_ < top_; ++i_) + { + curr_ = prev_->copy(_node_ptr_vector); + _tree_node_stack.push(prev_); + sequence(); + prev_ = curr_; + } + + if (comma_ && min_ > 0) + { + if (min_ > 1) + { + curr_ = prev_->copy(_node_ptr_vector); + _tree_node_stack.push(prev_); + sequence(); + prev_ = curr_; + } + + if (comma_ && max_) + { + _tree_node_stack.push(prev_); + optional(greedy_); + prev_ = _tree_node_stack.top(); + _tree_node_stack.pop(); + + const std::size_t count_ = max_ - min_; + + for (std::size_t i_ = 1; i_ < count_; ++i_) + { + curr_ = prev_->copy(_node_ptr_vector); + _tree_node_stack.push(prev_); + sequence(); + prev_ = curr_; + } + } + else + { + _tree_node_stack.push(prev_); + zero_or_more(greedy_); + prev_ = _tree_node_stack.top(); + _tree_node_stack.pop(); + } + } + + _tree_node_stack.push(prev_); + sequence(); + } + } + + void fixup_bol(observer_ptr &root_)const + { + const auto &first_ = root_->firstpos(); + bool found_ = false; + + for (observer_ptr node_ : first_) + { + found_ = !node_->end_state() && node_->token() == bol_token(); + + if (found_) break; + } + + if (!found_) + { + _node_ptr_vector.emplace_back + (std::make_unique(bol_token(), true)); + + observer_ptr lhs_ = _node_ptr_vector.back().get(); + + _node_ptr_vector.emplace_back + (std::make_unique(node::null_token(), true)); + + observer_ptr rhs_ = _node_ptr_vector.back().get(); + + _node_ptr_vector.emplace_back + (std::make_unique(lhs_, rhs_)); + lhs_ = _node_ptr_vector.back().get(); + + _node_ptr_vector.emplace_back + (std::make_unique(lhs_, root_)); + root_ = _node_ptr_vector.back().get(); + } + } +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/parser/tokeniser/re_token.hpp b/YACReaderLibrary/lexertl/parser/tokeniser/re_token.hpp new file mode 100644 index 000000000..271a7b1a6 --- /dev/null +++ b/YACReaderLibrary/lexertl/parser/tokeniser/re_token.hpp @@ -0,0 +1,100 @@ +// re_token.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_RE_TOKEN_HPP +#define LEXERTL_RE_TOKEN_HPP + +#include "../../string_token.hpp" + +namespace lexertl +{ +namespace detail +{ +// Note that tokens following END are never seen by parser.hpp. +enum token_type {BEGIN, REGEX, OREXP, SEQUENCE, SUB, EXPRESSION, REPEAT, + DUP, OR, CHARSET, BOL, EOL, MACRO, OPENPAREN, CLOSEPAREN, OPT, AOPT, + ZEROORMORE, AZEROORMORE, ONEORMORE, AONEORMORE, REPEATN, AREPEATN, + END, DIFF}; + +template +struct basic_re_token +{ + using string_token = basic_string_token; + using string = std::basic_string; + + token_type _type; + string _extra; + string_token _str; + + basic_re_token(const token_type type_ = BEGIN) : + _type(type_), + _extra(), + _str() + { + } + + void clear() + { + _type = BEGIN; + _extra.clear(); + _str.clear(); + } + + void swap(basic_re_token &rhs_) + { + std::swap(_type, rhs_._type); + _extra.swap(rhs_._extra); + _str.swap(rhs_._str); + } + + char precedence(const token_type type_) const + { + // Moved in here for Solaris compiler. + static const char precedence_table_[END + 1][END + 1] = { +// BEG, REG, ORE, SEQ, SUB, EXP, RPT, DUP, | , CHR, BOL, EOL, MCR, ( , ) , ? , ?? , * , *? , + , +?, {n}?, {n}, END +/*BEGIN*/{ ' ', '<', '<', '<', '<', '<', '<', ' ', ' ', '<', '<', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/*REGEX*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/*OREXP*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', '>', '>', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* SEQ */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* SUB */{ ' ', ' ', ' ', ' ', ' ', '=', '<', ' ', '>', '<', '<', '<', '<', '<', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/*EXPRE*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* RPT */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', '>', '>', '>', '>', '>', '>', '>', '<', '<', '<', '<', '<', '<', '<', '<', '>' }, +/*DUPLI*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* | */{ ' ', ' ', ' ', '=', '<', '<', '<', ' ', ' ', '<', '<', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, +/*CHARA*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, +/* BOL */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, +/* EOL */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, +/*MACRO*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, +/* ( */{ ' ', '=', '<', '<', '<', '<', '<', ' ', ' ', '<', '<', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, +/* ) */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, +/* ? */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* ?? */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* * */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* *? */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* + */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* +? */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/*{n,m}*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/*{nm}?*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* END */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } +}; + + return precedence_table_[_type][type_]; + } + + const char *precedence_string() const + { + // Moved in here for Solaris compiler. + static const char *precedence_strings_[END + 1] = + {"BEGIN", "REGEX", "OREXP", "SEQUENCE", "SUB", "EXPRESSION", + "REPEAT", "DUPLICATE", "|", "CHARSET", "^", "$", "MACRO", "(", ")", + "?", "??", "*", "*?", "+", "+?", "{n[,[m]]}", "{n[,[m]]}?", "END"}; + + return precedence_strings_[_type]; + } +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser.hpp b/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser.hpp new file mode 100644 index 000000000..c7e1e52dc --- /dev/null +++ b/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser.hpp @@ -0,0 +1,778 @@ +// tokeniser.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_RE_TOKENISER_HPP +#define LEXERTL_RE_TOKENISER_HPP + +#include +#include "re_token.hpp" +#include "../../runtime_error.hpp" +#include +#include "../../string_token.hpp" +#include "re_tokeniser_helper.hpp" + +namespace lexertl +{ +namespace detail +{ +template +class basic_re_tokeniser +{ +public: + using re_token = basic_re_token; + using tokeniser_helper = + basic_re_tokeniser_helper; + using char_state = typename tokeniser_helper::char_state; + using state = typename tokeniser_helper::state; + using string_token = basic_string_token; + + static void next(re_token &lhs_, state &state_, re_token &token_) + { + rules_char_type ch_ = 0; + bool eos_ = state_.next(ch_); + bool skipped_ = false; + + token_.clear(); + + do + { + // string begin/end + while (!eos_ && ch_ == '"') + { + state_._in_string ^= 1; + eos_ = state_.next(ch_); + } + + if (eos_) break; + + // (?# ...) + skipped_ = comment(eos_, ch_, state_); + + if (eos_) break; + + // skip_ws set + skipped_ |= skip(eos_, ch_, state_); + } while (!eos_ && skipped_); + + if (eos_) + { + if (state_._in_string) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing '\"')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (state_._paren_count) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing ')')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + token_._type = END; + } + else + { + if (ch_ == '\\') + { + // Even if we are in a string, respect escape sequences... + token_._type = CHARSET; + escape(state_, token_._str); + } + else if (state_._in_string) + { + // All other meta characters lose their special meaning + // inside a string. + token_._type = CHARSET; + add_char(ch_, state_, token_._str); + } + else + { + // Not an escape sequence and not inside a string, so + // check for meta characters. + switch (ch_) + { + case '(': + token_._type = OPENPAREN; + ++state_._paren_count; + read_options(state_); + break; + case ')': + --state_._paren_count; + + if (state_._paren_count < 0) + { + std::ostringstream ss_; + + ss_ << "Number of open parenthesis < 0 " + "at index " << state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + token_._type = CLOSEPAREN; + + if (!state_._flags_stack.empty()) + { + state_._flags = state_._flags_stack.top(); + state_._flags_stack.pop(); + } + + break; + case '?': + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AOPT; + state_.increment(); + } + else + { + token_._type = OPT; + } + + break; + case '*': + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AZEROORMORE; + state_.increment(); + } + else + { + token_._type = ZEROORMORE; + } + + break; + case '+': + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AONEORMORE; + state_.increment(); + } + else + { + token_._type = ONEORMORE; + } + + break; + case '{': + open_curly(lhs_, state_, token_); + break; + case '|': + token_._type = OR; + break; + case '^': + if (!state_._macro_name && + state_._curr - 1 == state_._start) + { + token_._type = BOL; + } + else + { + token_._type = CHARSET; + token_._str.insert(range(ch_, ch_)); + } + + break; + case '$': + if (!state_._macro_name && state_._curr == state_._end) + { + token_._type = EOL; + } + else + { + token_._type = CHARSET; + token_._str.insert(range(ch_, ch_)); + } + + break; + case '.': + { + token_._type = CHARSET; + + if (state_._flags & dot_not_newline) + { + token_._str.insert(range('\n', '\n')); + } + else if (state_._flags & dot_not_cr_lf) + { + token_._str.insert(range('\n', '\n')); + token_._str.insert(range('\r', '\r')); + } + + token_._str.negate(); + break; + } + case '[': + { + token_._type = CHARSET; + tokeniser_helper::charset(state_, token_._str); + break; + } + case '/': + { + std::ostringstream ss_; + + ss_ << "Lookahead ('/') is not supported yet"; + state_.error(ss_); + throw runtime_error(ss_.str()); + break; + } + default: + token_._type = CHARSET; + add_char(ch_, state_, token_._str); + break; + } + } + } + } + +private: + using range = typename string_token::range; + + static bool comment(bool &eos_, rules_char_type &ch_, state &state_) + { + bool skipped_ = false; + + if (!state_._in_string && ch_ == '(' && !state_.eos() && + *state_._curr == '?' && state_._curr + 1 < state_._end && + *(state_._curr + 1) == '#') + { + std::size_t paren_count_ = 1; + + state_.increment(); + state_.increment(); + + do + { + eos_ = state_.next(ch_); + + if (ch_ == '(') + { + ++paren_count_; + } + else if (ch_ == ')') + { + --paren_count_; + } + } while (!eos_ && !(ch_ == ')' && paren_count_ == 0)); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (unterminated comment)"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + else + { + eos_ = state_.next(ch_); + } + + skipped_ = true; + } + + return skipped_; + } + + static bool skip(bool &eos_, rules_char_type &ch_, state &state_) + { + bool skipped_ = false; + + if ((state_._flags & skip_ws) && !state_._in_string) + { + bool c_comment_ = false; + bool skip_ws_ = false; + + do + { + c_comment_ = ch_ == '/' && !state_.eos() && + *state_._curr == '*'; + skip_ws_ = !c_comment_ && (ch_ == ' ' || ch_ == '\t' || + ch_ == '\n' || ch_ == '\r' || ch_ == '\f' || ch_ == '\v'); + + if (c_comment_) + { + state_.increment(); + eos_ = state_.next(ch_); + + while (!eos_ && !(ch_ == '*' && !state_.eos() && + *state_._curr == '/')) + { + eos_ = state_.next(ch_); + } + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (unterminated C style comment)"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + else + { + state_.increment(); + eos_ = state_.next(ch_); + } + + skipped_ = true; + } + else if (skip_ws_) + { + eos_ = state_.next(ch_); + skipped_ = true; + } + } while (!eos_ && (c_comment_ || skip_ws_)); + } + + return skipped_; + } + + static void read_options(state &state_) + { + if (!state_.eos() && *state_._curr == '?') + { + rules_char_type ch_ = 0; + bool eos_ = false; + bool negate_ = false; + + state_.increment(); + eos_ = state_.next(ch_); + state_._flags_stack.push(state_._flags); + + while (!eos_ && ch_ != ':') + { + switch (ch_) + { + case '-': + negate_ ^= 1; + break; + case 'i': + if (negate_) + { + state_._flags = state_._flags & ~icase; + } + else + { + state_._flags = state_._flags | icase; + } + + negate_ = false; + break; + case 's': + if (negate_) + { +#ifdef _WIN32 + state_._flags = state_._flags | dot_not_cr_lf; +#else + state_._flags = state_._flags | dot_not_newline; +#endif + } + else + { +#ifdef _WIN32 + state_._flags = state_._flags & ~dot_not_cr_lf; +#else + state_._flags = state_._flags & ~dot_not_newline; +#endif + } + + negate_ = false; + break; + case 'x': + if (negate_) + { + state_._flags = state_._flags & ~skip_ws; + } + else + { + state_._flags = state_._flags | skip_ws; + } + + negate_ = false; + break; + default: + { + std::ostringstream ss_; + + ss_ << "Unknown option at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + eos_ = state_.next(ch_); + } + + // End of string handler will handle early termination + } + else if (!state_._flags_stack.empty()) + { + state_._flags_stack.push(state_._flags); + } + } + + static void escape(state &state_, string_token &token_) + { + char_type ch_ = 0; + std::size_t str_len_ = 0; + const char *str_ = tokeniser_helper::escape_sequence(state_, + ch_, str_len_); + + if (str_) + { + char_state state2_(str_ + 1, str_ + str_len_, state_._id, + state_._flags, state_._locale, 0); + + tokeniser_helper::charset(state2_, token_); + } + else + { + add_char(ch_, state_, token_); + } + } + + static void add_char(const char_type ch_, const state &state_, + string_token &token_) + { + range range_(ch_, ch_); + + token_.insert(range_); + + if (state_._flags & icase) + { + string_token folded_; + + tokeniser_helper::fold(range_, state_._locale, + folded_, typename tokeniser_helper::template + size()); + + if (!folded_.empty()) + { + token_.insert(folded_); + } + } + } + + static void open_curly(re_token &lhs_, state &state_, + re_token &token_) + { + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing '}')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + else if (*state_._curr == '-' || *state_._curr == '+') + { + rules_char_type ch_ = 0; + + if (lhs_._type != CHARSET) + { + std::ostringstream ss_; + + ss_ << "CHARSET must precede {" << + state_._curr << "} at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + state_.next(ch_); + token_._type = DIFF; + token_._extra = ch_; + + if (state_.next(ch_)) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing '}')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (ch_ != '}') + { + std::ostringstream ss_; + + ss_ << "Missing '}' at index " << state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + else if (*state_._curr >= '0' && *state_._curr <= '9') + { + repeat_n(state_, token_); + } + else + { + macro(state_, token_); + } + } + + // SYNTAX: + // {n[,[n]]} + // SEMANTIC RULES: + // {0} - INVALID (throw exception) + // {0,} = * + // {0,0} - INVALID (throw exception) + // {0,1} = ? + // {1,} = + + // {min,max} where min == max - {min} + // {min,max} where max < min - INVALID (throw exception) + static void repeat_n(state &state_, re_token &token_) + { + rules_char_type ch_ = 0; + bool eos_ = state_.next(ch_); + std::size_t min_ = 0; + std::size_t max_ = 0; + + while (!eos_ && ch_ >= '0' && ch_ <= '9') + { + min_ *= 10; + min_ += ch_ - '0'; + token_._extra += ch_; + eos_ = state_.next(ch_); + } + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing repeat terminator '}')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + bool min_max_ = false; + bool repeatn_ = true; + + if (ch_ == ',') + { + token_._extra += ch_; + eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing repeat terminator '}')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (ch_ == '}') + { + // Small optimisation: Check for '*' equivalency. + if (min_ == 0) + { + token_._type = ZEROORMORE; + repeatn_ = false; + } + // Small optimisation: Check for '+' equivalency. + else if (min_ == 1) + { + token_._type = ONEORMORE; + repeatn_ = false; + } + } + else + { + if (ch_ < '0' || ch_ > '9') + { + std::ostringstream ss_; + + ss_ << "Missing repeat terminator '}' at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + min_max_ = true; + + do + { + max_ *= 10; + max_ += ch_ - '0'; + token_._extra += ch_; + eos_ = state_.next(ch_); + } while (!eos_ && ch_ >= '0' && ch_ <= '9'); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing repeat terminator '}')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + // Small optimisation: Check for '?' equivalency. + if (min_ == 0 && max_ == 1) + { + token_._type = OPT; + repeatn_ = false; + } + // Small optimisation: if min == max, then min. + else if (min_ == max_) + { + token_._extra.erase(token_._extra.find(',')); + min_max_ = false; + max_ = 0; + } + } + } + + if (ch_ != '}') + { + std::ostringstream ss_; + + ss_ << "Missing repeat terminator '}' at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (repeatn_) + { + // SEMANTIC VALIDATION follows: + // NOTE: {0,} has already become * + // therefore we don't check for a comma. + if (min_ == 0 && max_ == 0) + { + std::ostringstream ss_; + + ss_ << "Cannot have exactly zero repeats preceding index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (min_max_ && max_ < min_) + { + std::ostringstream ss_; + + ss_ << "Max less than min preceding index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AREPEATN; + state_.increment(); + } + else + { + token_._type = REPEATN; + } + } + else if (token_._type == ZEROORMORE) + { + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AZEROORMORE; + state_.increment(); + } + } + else if (token_._type == ONEORMORE) + { + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AONEORMORE; + state_.increment(); + } + } + else if (token_._type == OPT) + { + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AOPT; + state_.increment(); + } + } + } + + static void macro(state &state_, re_token &token_) + { + rules_char_type ch_ = 0; + bool eos_ = false; + + state_.next(ch_); + + if (ch_ != '_' && !(ch_ >= 'A' && ch_ <= 'Z') && + !(ch_ >= 'a' && ch_ <= 'z')) + { + std::ostringstream ss_; + + ss_ << "Invalid MACRO name at index " << state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + do + { + token_._extra += ch_; + eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing MACRO name terminator '}')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } while (ch_ == '_' || ch_ == '-' || (ch_ >= 'A' && ch_ <= 'Z') || + (ch_ >= 'a' && ch_ <= 'z') || (ch_ >= '0' && ch_ <= '9')); + + if (ch_ != '}') + { + std::ostringstream ss_; + + ss_ << "Missing MACRO name terminator '}' at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + token_._type = MACRO; + } +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_helper.hpp b/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_helper.hpp new file mode 100644 index 000000000..f9f40cfef --- /dev/null +++ b/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_helper.hpp @@ -0,0 +1,3157 @@ +// tokeniser_helper.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_RE_TOKENISER_HELPER_HPP +#define LEXERTL_RE_TOKENISER_HELPER_HPP + +#include "../../char_traits.hpp" +// strlen() +#include +#include "re_tokeniser_state.hpp" +#include "../../runtime_error.hpp" +#include +#include "../../string_token.hpp" + +namespace lexertl +{ +namespace detail +{ +template > +class basic_re_tokeniser_helper +{ +public: + using char_state = basic_re_tokeniser_state; + using state = basic_re_tokeniser_state; + using string_token = basic_string_token; + using index_type = typename string_token::index_type; + using range = typename string_token::range; + + template + struct size + { + }; + + using one = size<1>; + using two = size<2>; + using four = size<4>; + + template + static const char *escape_sequence(state_type &state_, + char_type &ch_, std::size_t &str_len_) + { + bool eos_ = state_.eos(); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following '\\'"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + const char *str_ = charset_shortcut(state_, str_len_); + + if (str_) + { + state_.increment(); + } + else + { + ch_ = chr(state_); + } + + return str_; + } + + // This function can call itself. + template + static void charset(state_type &state_, string_token &token_) + { + bool negated_ = false; + typename state_type::char_type ch_ = 0; + bool eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following '['"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + negated_ = ch_ == '^'; + + if (negated_) + { + eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following '^'"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + bool chset_ = false; + typename string_token::char_type prev_ = 0; + + do + { + if (ch_ == '\\') + { + std::size_t str_len_ = 0; + const char *str_ = escape_sequence(state_, prev_, + str_len_); + + chset_ = str_ != 0; + + if (chset_) + { + char_state temp_state_(str_ + 1, str_ + str_len_, + state_._id, state_._flags, state_._locale, 0); + string_token temp_token_; + + charset(temp_state_, temp_token_); + token_.insert(temp_token_); + } + } + else if (ch_ == '[' && !state_.eos() && *state_._curr == ':') + { + state_.increment(); + posix(state_, token_); + chset_ = true; + } + else + { + chset_ = false; + prev_ = ch_; + } + + eos_ = state_.next(ch_); + + // Covers preceding if, else if and else + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing ']')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (ch_ == '-' && *state_._curr != ']') + { + charset_range(chset_, state_, eos_, ch_, prev_, + token_); + } + else if (!chset_) + { + range range_(prev_, prev_); + + token_.insert(range_); + + if (state_._flags & icase) + { + string_token folded_; + + fold(range_, state_._locale, folded_, + size()); + + if (!folded_.empty()) + { + token_.insert(folded_); + } + } + } + } while (ch_ != ']'); + + if (negated_) + { + token_.negate(); + } + + if (token_.empty()) + { + std::ostringstream ss_; + + ss_ << "Empty charset not allowed preceding index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + static void fold(const range &range_, const std::locale &locale_, + string_token &out_, const one &) + { + // If string_token::char_type is 16 bit may overflow, + // so use std::size_t. + std::size_t start_ = range_.first; + std::size_t end_ = range_.second; + + // In 8 bit char mode, use locale and therefore consider every char + // individually. + for (; start_ <= end_; ++start_) + { + const input_char_type upper_ = std::toupper + (static_cast(start_), locale_); + const input_char_type lower_ = std::tolower + (static_cast(start_), locale_); + + if (upper_ != static_cast(start_)) + { + out_.insert(range(upper_, upper_)); + } + + if (lower_ != static_cast(start_)) + { + out_.insert(range(lower_, lower_)); + } + } + } + + // http://www.unicode.org/Public/8.0.0/ucd/UnicodeData.txt + static void fold(const range &range_, const std::locale &, + string_token &out_, const two &) + { + static const fold_pair mapping_[] = + {{{0x0041, 0x005a}, {0x0061, 0x007a}}, + {{0x0061, 0x007a}, {0x0041, 0x005a}}, + {{0x00b5, 0x00b5}, {0x039c, 0x039c}}, + {{0x00c0, 0x00d6}, {0x00e0, 0x00f6}}, + {{0x00d8, 0x00de}, {0x00f8, 0x00fe}}, + {{0x00e0, 0x00f6}, {0x00c0, 0x00d6}}, + {{0x00f8, 0x00fe}, {0x00d8, 0x00de}}, + {{0x00ff, 0x00ff}, {0x0178, 0x0178}}, + {{0x0100, 0x0101}, {0x0101, 0x0100}}, + {{0x0102, 0x0103}, {0x0103, 0x0102}}, + {{0x0104, 0x0105}, {0x0105, 0x0104}}, + {{0x0106, 0x0107}, {0x0107, 0x0106}}, + {{0x0108, 0x0109}, {0x0109, 0x0108}}, + {{0x010a, 0x010b}, {0x010b, 0x010a}}, + {{0x010c, 0x010d}, {0x010d, 0x010c}}, + {{0x010e, 0x010f}, {0x010f, 0x010e}}, + {{0x0110, 0x0111}, {0x0111, 0x0110}}, + {{0x0112, 0x0113}, {0x0113, 0x0112}}, + {{0x0114, 0x0115}, {0x0115, 0x0114}}, + {{0x0116, 0x0117}, {0x0117, 0x0116}}, + {{0x0118, 0x0119}, {0x0119, 0x0118}}, + {{0x011a, 0x011b}, {0x011b, 0x011a}}, + {{0x011c, 0x011d}, {0x011d, 0x011c}}, + {{0x011e, 0x011f}, {0x011f, 0x011e}}, + {{0x0120, 0x0121}, {0x0121, 0x0120}}, + {{0x0122, 0x0123}, {0x0123, 0x0122}}, + {{0x0124, 0x0125}, {0x0125, 0x0124}}, + {{0x0126, 0x0127}, {0x0127, 0x0126}}, + {{0x0128, 0x0129}, {0x0129, 0x0128}}, + {{0x012a, 0x012b}, {0x012b, 0x012a}}, + {{0x012c, 0x012d}, {0x012d, 0x012c}}, + {{0x012e, 0x012f}, {0x012f, 0x012e}}, + {{0x0130, 0x0130}, {0x0069, 0x0069}}, + {{0x0131, 0x0131}, {0x0049, 0x0049}}, + {{0x0132, 0x0133}, {0x0133, 0x0132}}, + {{0x0134, 0x0135}, {0x0135, 0x0134}}, + {{0x0136, 0x0137}, {0x0137, 0x0136}}, + {{0x0139, 0x013a}, {0x013a, 0x0139}}, + {{0x013b, 0x013c}, {0x013c, 0x013b}}, + {{0x013d, 0x013e}, {0x013e, 0x013d}}, + {{0x013f, 0x0140}, {0x0140, 0x013f}}, + {{0x0141, 0x0142}, {0x0142, 0x0141}}, + {{0x0143, 0x0144}, {0x0144, 0x0143}}, + {{0x0145, 0x0146}, {0x0146, 0x0145}}, + {{0x0147, 0x0148}, {0x0148, 0x0147}}, + {{0x014a, 0x014b}, {0x014b, 0x014a}}, + {{0x014c, 0x014d}, {0x014d, 0x014c}}, + {{0x014e, 0x014f}, {0x014f, 0x014e}}, + {{0x0150, 0x0151}, {0x0151, 0x0150}}, + {{0x0152, 0x0153}, {0x0153, 0x0152}}, + {{0x0154, 0x0155}, {0x0155, 0x0154}}, + {{0x0156, 0x0157}, {0x0157, 0x0156}}, + {{0x0158, 0x0159}, {0x0159, 0x0158}}, + {{0x015a, 0x015b}, {0x015b, 0x015a}}, + {{0x015c, 0x015d}, {0x015d, 0x015c}}, + {{0x015e, 0x015f}, {0x015f, 0x015e}}, + {{0x0160, 0x0161}, {0x0161, 0x0160}}, + {{0x0162, 0x0163}, {0x0163, 0x0162}}, + {{0x0164, 0x0165}, {0x0165, 0x0164}}, + {{0x0166, 0x0167}, {0x0167, 0x0166}}, + {{0x0168, 0x0169}, {0x0169, 0x0168}}, + {{0x016a, 0x016b}, {0x016b, 0x016a}}, + {{0x016c, 0x016d}, {0x016d, 0x016c}}, + {{0x016e, 0x016f}, {0x016f, 0x016e}}, + {{0x0170, 0x0171}, {0x0171, 0x0170}}, + {{0x0172, 0x0173}, {0x0173, 0x0172}}, + {{0x0174, 0x0175}, {0x0175, 0x0174}}, + {{0x0176, 0x0177}, {0x0177, 0x0176}}, + {{0x0178, 0x0178}, {0x00ff, 0x00ff}}, + {{0x0179, 0x017a}, {0x017a, 0x0179}}, + {{0x017b, 0x017c}, {0x017c, 0x017b}}, + {{0x017d, 0x017e}, {0x017e, 0x017d}}, + {{0x017f, 0x017f}, {0x0053, 0x0053}}, + {{0x0180, 0x0180}, {0x0243, 0x0243}}, + {{0x0181, 0x0181}, {0x0253, 0x0253}}, + {{0x0182, 0x0183}, {0x0183, 0x0182}}, + {{0x0184, 0x0185}, {0x0185, 0x0184}}, + {{0x0186, 0x0186}, {0x0254, 0x0254}}, + {{0x0187, 0x0188}, {0x0188, 0x0187}}, + {{0x0189, 0x018a}, {0x0256, 0x0257}}, + {{0x018b, 0x018c}, {0x018c, 0x018b}}, + {{0x018e, 0x018e}, {0x01dd, 0x01dd}}, + {{0x018f, 0x018f}, {0x0259, 0x0259}}, + {{0x0190, 0x0190}, {0x025b, 0x025b}}, + {{0x0191, 0x0192}, {0x0192, 0x0191}}, + {{0x0193, 0x0193}, {0x0260, 0x0260}}, + {{0x0194, 0x0194}, {0x0263, 0x0263}}, + {{0x0195, 0x0195}, {0x01f6, 0x01f6}}, + {{0x0196, 0x0196}, {0x0269, 0x0269}}, + {{0x0197, 0x0197}, {0x0268, 0x0268}}, + {{0x0198, 0x0199}, {0x0199, 0x0198}}, + {{0x019a, 0x019a}, {0x023d, 0x023d}}, + {{0x019c, 0x019c}, {0x026f, 0x026f}}, + {{0x019d, 0x019d}, {0x0272, 0x0272}}, + {{0x019e, 0x019e}, {0x0220, 0x0220}}, + {{0x019f, 0x019f}, {0x0275, 0x0275}}, + {{0x01a0, 0x01a1}, {0x01a1, 0x01a0}}, + {{0x01a2, 0x01a3}, {0x01a3, 0x01a2}}, + {{0x01a4, 0x01a5}, {0x01a5, 0x01a4}}, + {{0x01a6, 0x01a6}, {0x0280, 0x0280}}, + {{0x01a7, 0x01a8}, {0x01a8, 0x01a7}}, + {{0x01a9, 0x01a9}, {0x0283, 0x0283}}, + {{0x01ac, 0x01ad}, {0x01ad, 0x01ac}}, + {{0x01ae, 0x01ae}, {0x0288, 0x0288}}, + {{0x01af, 0x01b0}, {0x01b0, 0x01af}}, + {{0x01b1, 0x01b2}, {0x028a, 0x028b}}, + {{0x01b3, 0x01b4}, {0x01b4, 0x01b3}}, + {{0x01b5, 0x01b6}, {0x01b6, 0x01b5}}, + {{0x01b7, 0x01b7}, {0x0292, 0x0292}}, + {{0x01b8, 0x01b9}, {0x01b9, 0x01b8}}, + {{0x01bc, 0x01bd}, {0x01bd, 0x01bc}}, + {{0x01bf, 0x01bf}, {0x01f7, 0x01f7}}, + {{0x01c4, 0x01c4}, {0x01c6, 0x01c6}}, + {{0x01c6, 0x01c6}, {0x01c4, 0x01c4}}, + {{0x01c7, 0x01c7}, {0x01c9, 0x01c9}}, + {{0x01c9, 0x01c9}, {0x01c7, 0x01c7}}, + {{0x01ca, 0x01ca}, {0x01cc, 0x01cc}}, + {{0x01cc, 0x01cc}, {0x01ca, 0x01ca}}, + {{0x01cd, 0x01ce}, {0x01ce, 0x01cd}}, + {{0x01cf, 0x01d0}, {0x01d0, 0x01cf}}, + {{0x01d1, 0x01d2}, {0x01d2, 0x01d1}}, + {{0x01d3, 0x01d4}, {0x01d4, 0x01d3}}, + {{0x01d5, 0x01d6}, {0x01d6, 0x01d5}}, + {{0x01d7, 0x01d8}, {0x01d8, 0x01d7}}, + {{0x01d9, 0x01da}, {0x01da, 0x01d9}}, + {{0x01db, 0x01dc}, {0x01dc, 0x01db}}, + {{0x01dd, 0x01dd}, {0x018e, 0x018e}}, + {{0x01de, 0x01df}, {0x01df, 0x01de}}, + {{0x01e0, 0x01e1}, {0x01e1, 0x01e0}}, + {{0x01e2, 0x01e3}, {0x01e3, 0x01e2}}, + {{0x01e4, 0x01e5}, {0x01e5, 0x01e4}}, + {{0x01e6, 0x01e7}, {0x01e7, 0x01e6}}, + {{0x01e8, 0x01e9}, {0x01e9, 0x01e8}}, + {{0x01ea, 0x01eb}, {0x01eb, 0x01ea}}, + {{0x01ec, 0x01ed}, {0x01ed, 0x01ec}}, + {{0x01ee, 0x01ef}, {0x01ef, 0x01ee}}, + {{0x01f1, 0x01f1}, {0x01f3, 0x01f3}}, + {{0x01f3, 0x01f3}, {0x01f1, 0x01f1}}, + {{0x01f4, 0x01f5}, {0x01f5, 0x01f4}}, + {{0x01f6, 0x01f6}, {0x0195, 0x0195}}, + {{0x01f7, 0x01f7}, {0x01bf, 0x01bf}}, + {{0x01f8, 0x01f9}, {0x01f9, 0x01f8}}, + {{0x01fa, 0x01fb}, {0x01fb, 0x01fa}}, + {{0x01fc, 0x01fd}, {0x01fd, 0x01fc}}, + {{0x01fe, 0x01ff}, {0x01ff, 0x01fe}}, + {{0x0200, 0x0201}, {0x0201, 0x0200}}, + {{0x0202, 0x0203}, {0x0203, 0x0202}}, + {{0x0204, 0x0205}, {0x0205, 0x0204}}, + {{0x0206, 0x0207}, {0x0207, 0x0206}}, + {{0x0208, 0x0209}, {0x0209, 0x0208}}, + {{0x020a, 0x020b}, {0x020b, 0x020a}}, + {{0x020c, 0x020d}, {0x020d, 0x020c}}, + {{0x020e, 0x020f}, {0x020f, 0x020e}}, + {{0x0210, 0x0211}, {0x0211, 0x0210}}, + {{0x0212, 0x0213}, {0x0213, 0x0212}}, + {{0x0214, 0x0215}, {0x0215, 0x0214}}, + {{0x0216, 0x0217}, {0x0217, 0x0216}}, + {{0x0218, 0x0219}, {0x0219, 0x0218}}, + {{0x021a, 0x021b}, {0x021b, 0x021a}}, + {{0x021c, 0x021d}, {0x021d, 0x021c}}, + {{0x021e, 0x021f}, {0x021f, 0x021e}}, + {{0x0220, 0x0220}, {0x019e, 0x019e}}, + {{0x0222, 0x0223}, {0x0223, 0x0222}}, + {{0x0224, 0x0225}, {0x0225, 0x0224}}, + {{0x0226, 0x0227}, {0x0227, 0x0226}}, + {{0x0228, 0x0229}, {0x0229, 0x0228}}, + {{0x022a, 0x022b}, {0x022b, 0x022a}}, + {{0x022c, 0x022d}, {0x022d, 0x022c}}, + {{0x022e, 0x022f}, {0x022f, 0x022e}}, + {{0x0230, 0x0231}, {0x0231, 0x0230}}, + {{0x0232, 0x0233}, {0x0233, 0x0232}}, + {{0x023a, 0x023a}, {0x2c65, 0x2c65}}, + {{0x023b, 0x023c}, {0x023c, 0x023b}}, + {{0x023d, 0x023d}, {0x019a, 0x019a}}, + {{0x023e, 0x023e}, {0x2c66, 0x2c66}}, + {{0x023f, 0x0240}, {0x2c7e, 0x2c7f}}, + {{0x0241, 0x0242}, {0x0242, 0x0241}}, + {{0x0243, 0x0243}, {0x0180, 0x0180}}, + {{0x0244, 0x0244}, {0x0289, 0x0289}}, + {{0x0245, 0x0245}, {0x028c, 0x028c}}, + {{0x0246, 0x0247}, {0x0247, 0x0246}}, + {{0x0248, 0x0249}, {0x0249, 0x0248}}, + {{0x024a, 0x024b}, {0x024b, 0x024a}}, + {{0x024c, 0x024d}, {0x024d, 0x024c}}, + {{0x024e, 0x024f}, {0x024f, 0x024e}}, + {{0x0250, 0x0250}, {0x2c6f, 0x2c6f}}, + {{0x0251, 0x0251}, {0x2c6d, 0x2c6d}}, + {{0x0252, 0x0252}, {0x2c70, 0x2c70}}, + {{0x0253, 0x0253}, {0x0181, 0x0181}}, + {{0x0254, 0x0254}, {0x0186, 0x0186}}, + {{0x0256, 0x0257}, {0x0189, 0x018a}}, + {{0x0259, 0x0259}, {0x018f, 0x018f}}, + {{0x025b, 0x025b}, {0x0190, 0x0190}}, + {{0x025c, 0x025c}, {0xa7ab, 0xa7ab}}, + {{0x0260, 0x0260}, {0x0193, 0x0193}}, + {{0x0261, 0x0261}, {0xa7ac, 0xa7ac}}, + {{0x0263, 0x0263}, {0x0194, 0x0194}}, + {{0x0265, 0x0265}, {0xa78d, 0xa78d}}, + {{0x0266, 0x0266}, {0xa7aa, 0xa7aa}}, + {{0x0268, 0x0269}, {0x0197, 0x0196}}, + {{0x026b, 0x026b}, {0x2c62, 0x2c62}}, + {{0x026c, 0x026c}, {0xa7ad, 0xa7ad}}, + {{0x026f, 0x026f}, {0x019c, 0x019c}}, + {{0x0271, 0x0271}, {0x2c6e, 0x2c6e}}, + {{0x0272, 0x0272}, {0x019d, 0x019d}}, + {{0x0275, 0x0275}, {0x019f, 0x019f}}, + {{0x027d, 0x027d}, {0x2c64, 0x2c64}}, + {{0x0280, 0x0280}, {0x01a6, 0x01a6}}, + {{0x0283, 0x0283}, {0x01a9, 0x01a9}}, + {{0x0287, 0x0287}, {0xa7b1, 0xa7b1}}, + {{0x0288, 0x0288}, {0x01ae, 0x01ae}}, + {{0x0289, 0x0289}, {0x0244, 0x0244}}, + {{0x028a, 0x028b}, {0x01b1, 0x01b2}}, + {{0x028c, 0x028c}, {0x0245, 0x0245}}, + {{0x0292, 0x0292}, {0x01b7, 0x01b7}}, + {{0x029d, 0x029d}, {0xa7b2, 0xa7b2}}, + {{0x029e, 0x029e}, {0xa7b0, 0xa7b0}}, + {{0x0370, 0x0371}, {0x0371, 0x0370}}, + {{0x0372, 0x0373}, {0x0373, 0x0372}}, + {{0x0376, 0x0377}, {0x0377, 0x0376}}, + {{0x037b, 0x037d}, {0x03fd, 0x03ff}}, + {{0x037f, 0x037f}, {0x03f3, 0x03f3}}, + {{0x0386, 0x0386}, {0x03ac, 0x03ac}}, + {{0x0388, 0x038a}, {0x03ad, 0x03af}}, + {{0x038c, 0x038c}, {0x03cc, 0x03cc}}, + {{0x038e, 0x038f}, {0x03cd, 0x03ce}}, + {{0x0391, 0x03a1}, {0x03b1, 0x03c1}}, + {{0x03a3, 0x03ab}, {0x03c3, 0x03cb}}, + {{0x03ac, 0x03ac}, {0x0386, 0x0386}}, + {{0x03ad, 0x03af}, {0x0388, 0x038a}}, + {{0x03b1, 0x03c1}, {0x0391, 0x03a1}}, + {{0x03c2, 0x03c2}, {0x03a3, 0x03a3}}, + {{0x03c3, 0x03cb}, {0x03a3, 0x03ab}}, + {{0x03cc, 0x03cc}, {0x038c, 0x038c}}, + {{0x03cd, 0x03ce}, {0x038e, 0x038f}}, + {{0x03cf, 0x03cf}, {0x03d7, 0x03d7}}, + {{0x03d0, 0x03d0}, {0x0392, 0x0392}}, + {{0x03d1, 0x03d1}, {0x0398, 0x0398}}, + {{0x03d5, 0x03d5}, {0x03a6, 0x03a6}}, + {{0x03d6, 0x03d6}, {0x03a0, 0x03a0}}, + {{0x03d7, 0x03d7}, {0x03cf, 0x03cf}}, + {{0x03d8, 0x03d9}, {0x03d9, 0x03d8}}, + {{0x03da, 0x03db}, {0x03db, 0x03da}}, + {{0x03dc, 0x03dd}, {0x03dd, 0x03dc}}, + {{0x03de, 0x03df}, {0x03df, 0x03de}}, + {{0x03e0, 0x03e1}, {0x03e1, 0x03e0}}, + {{0x03e2, 0x03e3}, {0x03e3, 0x03e2}}, + {{0x03e4, 0x03e5}, {0x03e5, 0x03e4}}, + {{0x03e6, 0x03e7}, {0x03e7, 0x03e6}}, + {{0x03e8, 0x03e9}, {0x03e9, 0x03e8}}, + {{0x03ea, 0x03eb}, {0x03eb, 0x03ea}}, + {{0x03ec, 0x03ed}, {0x03ed, 0x03ec}}, + {{0x03ee, 0x03ef}, {0x03ef, 0x03ee}}, + {{0x03f0, 0x03f0}, {0x039a, 0x039a}}, + {{0x03f1, 0x03f1}, {0x03a1, 0x03a1}}, + {{0x03f2, 0x03f2}, {0x03f9, 0x03f9}}, + {{0x03f3, 0x03f3}, {0x037f, 0x037f}}, + {{0x03f4, 0x03f4}, {0x03b8, 0x03b8}}, + {{0x03f5, 0x03f5}, {0x0395, 0x0395}}, + {{0x03f7, 0x03f8}, {0x03f8, 0x03f7}}, + {{0x03f9, 0x03f9}, {0x03f2, 0x03f2}}, + {{0x03fa, 0x03fb}, {0x03fb, 0x03fa}}, + {{0x03fd, 0x03ff}, {0x037b, 0x037d}}, + {{0x0400, 0x040f}, {0x0450, 0x045f}}, + {{0x0410, 0x042f}, {0x0430, 0x044f}}, + {{0x0430, 0x044f}, {0x0410, 0x042f}}, + {{0x0450, 0x045f}, {0x0400, 0x040f}}, + {{0x0460, 0x0461}, {0x0461, 0x0460}}, + {{0x0462, 0x0463}, {0x0463, 0x0462}}, + {{0x0464, 0x0465}, {0x0465, 0x0464}}, + {{0x0466, 0x0467}, {0x0467, 0x0466}}, + {{0x0468, 0x0469}, {0x0469, 0x0468}}, + {{0x046a, 0x046b}, {0x046b, 0x046a}}, + {{0x046c, 0x046d}, {0x046d, 0x046c}}, + {{0x046e, 0x046f}, {0x046f, 0x046e}}, + {{0x0470, 0x0471}, {0x0471, 0x0470}}, + {{0x0472, 0x0473}, {0x0473, 0x0472}}, + {{0x0474, 0x0475}, {0x0475, 0x0474}}, + {{0x0476, 0x0477}, {0x0477, 0x0476}}, + {{0x0478, 0x0479}, {0x0479, 0x0478}}, + {{0x047a, 0x047b}, {0x047b, 0x047a}}, + {{0x047c, 0x047d}, {0x047d, 0x047c}}, + {{0x047e, 0x047f}, {0x047f, 0x047e}}, + {{0x0480, 0x0481}, {0x0481, 0x0480}}, + {{0x048a, 0x048b}, {0x048b, 0x048a}}, + {{0x048c, 0x048d}, {0x048d, 0x048c}}, + {{0x048e, 0x048f}, {0x048f, 0x048e}}, + {{0x0490, 0x0491}, {0x0491, 0x0490}}, + {{0x0492, 0x0493}, {0x0493, 0x0492}}, + {{0x0494, 0x0495}, {0x0495, 0x0494}}, + {{0x0496, 0x0497}, {0x0497, 0x0496}}, + {{0x0498, 0x0499}, {0x0499, 0x0498}}, + {{0x049a, 0x049b}, {0x049b, 0x049a}}, + {{0x049c, 0x049d}, {0x049d, 0x049c}}, + {{0x049e, 0x049f}, {0x049f, 0x049e}}, + {{0x04a0, 0x04a1}, {0x04a1, 0x04a0}}, + {{0x04a2, 0x04a3}, {0x04a3, 0x04a2}}, + {{0x04a4, 0x04a5}, {0x04a5, 0x04a4}}, + {{0x04a6, 0x04a7}, {0x04a7, 0x04a6}}, + {{0x04a8, 0x04a9}, {0x04a9, 0x04a8}}, + {{0x04aa, 0x04ab}, {0x04ab, 0x04aa}}, + {{0x04ac, 0x04ad}, {0x04ad, 0x04ac}}, + {{0x04ae, 0x04af}, {0x04af, 0x04ae}}, + {{0x04b0, 0x04b1}, {0x04b1, 0x04b0}}, + {{0x04b2, 0x04b3}, {0x04b3, 0x04b2}}, + {{0x04b4, 0x04b5}, {0x04b5, 0x04b4}}, + {{0x04b6, 0x04b7}, {0x04b7, 0x04b6}}, + {{0x04b8, 0x04b9}, {0x04b9, 0x04b8}}, + {{0x04ba, 0x04bb}, {0x04bb, 0x04ba}}, + {{0x04bc, 0x04bd}, {0x04bd, 0x04bc}}, + {{0x04be, 0x04bf}, {0x04bf, 0x04be}}, + {{0x04c0, 0x04c0}, {0x04cf, 0x04cf}}, + {{0x04c1, 0x04c2}, {0x04c2, 0x04c1}}, + {{0x04c3, 0x04c4}, {0x04c4, 0x04c3}}, + {{0x04c5, 0x04c6}, {0x04c6, 0x04c5}}, + {{0x04c7, 0x04c8}, {0x04c8, 0x04c7}}, + {{0x04c9, 0x04ca}, {0x04ca, 0x04c9}}, + {{0x04cb, 0x04cc}, {0x04cc, 0x04cb}}, + {{0x04cd, 0x04ce}, {0x04ce, 0x04cd}}, + {{0x04cf, 0x04cf}, {0x04c0, 0x04c0}}, + {{0x04d0, 0x04d1}, {0x04d1, 0x04d0}}, + {{0x04d2, 0x04d3}, {0x04d3, 0x04d2}}, + {{0x04d4, 0x04d5}, {0x04d5, 0x04d4}}, + {{0x04d6, 0x04d7}, {0x04d7, 0x04d6}}, + {{0x04d8, 0x04d9}, {0x04d9, 0x04d8}}, + {{0x04da, 0x04db}, {0x04db, 0x04da}}, + {{0x04dc, 0x04dd}, {0x04dd, 0x04dc}}, + {{0x04de, 0x04df}, {0x04df, 0x04de}}, + {{0x04e0, 0x04e1}, {0x04e1, 0x04e0}}, + {{0x04e2, 0x04e3}, {0x04e3, 0x04e2}}, + {{0x04e4, 0x04e5}, {0x04e5, 0x04e4}}, + {{0x04e6, 0x04e7}, {0x04e7, 0x04e6}}, + {{0x04e8, 0x04e9}, {0x04e9, 0x04e8}}, + {{0x04ea, 0x04eb}, {0x04eb, 0x04ea}}, + {{0x04ec, 0x04ed}, {0x04ed, 0x04ec}}, + {{0x04ee, 0x04ef}, {0x04ef, 0x04ee}}, + {{0x04f0, 0x04f1}, {0x04f1, 0x04f0}}, + {{0x04f2, 0x04f3}, {0x04f3, 0x04f2}}, + {{0x04f4, 0x04f5}, {0x04f5, 0x04f4}}, + {{0x04f6, 0x04f7}, {0x04f7, 0x04f6}}, + {{0x04f8, 0x04f9}, {0x04f9, 0x04f8}}, + {{0x04fa, 0x04fb}, {0x04fb, 0x04fa}}, + {{0x04fc, 0x04fd}, {0x04fd, 0x04fc}}, + {{0x04fe, 0x04ff}, {0x04ff, 0x04fe}}, + {{0x0500, 0x0501}, {0x0501, 0x0500}}, + {{0x0502, 0x0503}, {0x0503, 0x0502}}, + {{0x0504, 0x0505}, {0x0505, 0x0504}}, + {{0x0506, 0x0507}, {0x0507, 0x0506}}, + {{0x0508, 0x0509}, {0x0509, 0x0508}}, + {{0x050a, 0x050b}, {0x050b, 0x050a}}, + {{0x050c, 0x050d}, {0x050d, 0x050c}}, + {{0x050e, 0x050f}, {0x050f, 0x050e}}, + {{0x0510, 0x0511}, {0x0511, 0x0510}}, + {{0x0512, 0x0513}, {0x0513, 0x0512}}, + {{0x0514, 0x0515}, {0x0515, 0x0514}}, + {{0x0516, 0x0517}, {0x0517, 0x0516}}, + {{0x0518, 0x0519}, {0x0519, 0x0518}}, + {{0x051a, 0x051b}, {0x051b, 0x051a}}, + {{0x051c, 0x051d}, {0x051d, 0x051c}}, + {{0x051e, 0x051f}, {0x051f, 0x051e}}, + {{0x0520, 0x0521}, {0x0521, 0x0520}}, + {{0x0522, 0x0523}, {0x0523, 0x0522}}, + {{0x0524, 0x0525}, {0x0525, 0x0524}}, + {{0x0526, 0x0527}, {0x0527, 0x0526}}, + {{0x0528, 0x0529}, {0x0529, 0x0528}}, + {{0x052a, 0x052b}, {0x052b, 0x052a}}, + {{0x052c, 0x052d}, {0x052d, 0x052c}}, + {{0x052e, 0x052f}, {0x052f, 0x052e}}, + {{0x0531, 0x0556}, {0x0561, 0x0586}}, + {{0x0561, 0x0586}, {0x0531, 0x0556}}, + {{0x10a0, 0x10c5}, {0x2d00, 0x2d25}}, + {{0x10c7, 0x10c7}, {0x2d27, 0x2d27}}, + {{0x10cd, 0x10cd}, {0x2d2d, 0x2d2d}}, + {{0x13a0, 0x13ef}, {0xab70, 0xabbf}}, + {{0x13f0, 0x13f5}, {0x13f8, 0x13fd}}, + {{0x13f8, 0x13fd}, {0x13f0, 0x13f5}}, + {{0x1d79, 0x1d79}, {0xa77d, 0xa77d}}, + {{0x1d7d, 0x1d7d}, {0x2c63, 0x2c63}}, + {{0x1e00, 0x1e01}, {0x1e01, 0x1e00}}, + {{0x1e02, 0x1e03}, {0x1e03, 0x1e02}}, + {{0x1e04, 0x1e05}, {0x1e05, 0x1e04}}, + {{0x1e06, 0x1e07}, {0x1e07, 0x1e06}}, + {{0x1e08, 0x1e09}, {0x1e09, 0x1e08}}, + {{0x1e0a, 0x1e0b}, {0x1e0b, 0x1e0a}}, + {{0x1e0c, 0x1e0d}, {0x1e0d, 0x1e0c}}, + {{0x1e0e, 0x1e0f}, {0x1e0f, 0x1e0e}}, + {{0x1e10, 0x1e11}, {0x1e11, 0x1e10}}, + {{0x1e12, 0x1e13}, {0x1e13, 0x1e12}}, + {{0x1e14, 0x1e15}, {0x1e15, 0x1e14}}, + {{0x1e16, 0x1e17}, {0x1e17, 0x1e16}}, + {{0x1e18, 0x1e19}, {0x1e19, 0x1e18}}, + {{0x1e1a, 0x1e1b}, {0x1e1b, 0x1e1a}}, + {{0x1e1c, 0x1e1d}, {0x1e1d, 0x1e1c}}, + {{0x1e1e, 0x1e1f}, {0x1e1f, 0x1e1e}}, + {{0x1e20, 0x1e21}, {0x1e21, 0x1e20}}, + {{0x1e22, 0x1e23}, {0x1e23, 0x1e22}}, + {{0x1e24, 0x1e25}, {0x1e25, 0x1e24}}, + {{0x1e26, 0x1e27}, {0x1e27, 0x1e26}}, + {{0x1e28, 0x1e29}, {0x1e29, 0x1e28}}, + {{0x1e2a, 0x1e2b}, {0x1e2b, 0x1e2a}}, + {{0x1e2c, 0x1e2d}, {0x1e2d, 0x1e2c}}, + {{0x1e2e, 0x1e2f}, {0x1e2f, 0x1e2e}}, + {{0x1e30, 0x1e31}, {0x1e31, 0x1e30}}, + {{0x1e32, 0x1e33}, {0x1e33, 0x1e32}}, + {{0x1e34, 0x1e35}, {0x1e35, 0x1e34}}, + {{0x1e36, 0x1e37}, {0x1e37, 0x1e36}}, + {{0x1e38, 0x1e39}, {0x1e39, 0x1e38}}, + {{0x1e3a, 0x1e3b}, {0x1e3b, 0x1e3a}}, + {{0x1e3c, 0x1e3d}, {0x1e3d, 0x1e3c}}, + {{0x1e3e, 0x1e3f}, {0x1e3f, 0x1e3e}}, + {{0x1e40, 0x1e41}, {0x1e41, 0x1e40}}, + {{0x1e42, 0x1e43}, {0x1e43, 0x1e42}}, + {{0x1e44, 0x1e45}, {0x1e45, 0x1e44}}, + {{0x1e46, 0x1e47}, {0x1e47, 0x1e46}}, + {{0x1e48, 0x1e49}, {0x1e49, 0x1e48}}, + {{0x1e4a, 0x1e4b}, {0x1e4b, 0x1e4a}}, + {{0x1e4c, 0x1e4d}, {0x1e4d, 0x1e4c}}, + {{0x1e4e, 0x1e4f}, {0x1e4f, 0x1e4e}}, + {{0x1e50, 0x1e51}, {0x1e51, 0x1e50}}, + {{0x1e52, 0x1e53}, {0x1e53, 0x1e52}}, + {{0x1e54, 0x1e55}, {0x1e55, 0x1e54}}, + {{0x1e56, 0x1e57}, {0x1e57, 0x1e56}}, + {{0x1e58, 0x1e59}, {0x1e59, 0x1e58}}, + {{0x1e5a, 0x1e5b}, {0x1e5b, 0x1e5a}}, + {{0x1e5c, 0x1e5d}, {0x1e5d, 0x1e5c}}, + {{0x1e5e, 0x1e5f}, {0x1e5f, 0x1e5e}}, + {{0x1e60, 0x1e61}, {0x1e61, 0x1e60}}, + {{0x1e62, 0x1e63}, {0x1e63, 0x1e62}}, + {{0x1e64, 0x1e65}, {0x1e65, 0x1e64}}, + {{0x1e66, 0x1e67}, {0x1e67, 0x1e66}}, + {{0x1e68, 0x1e69}, {0x1e69, 0x1e68}}, + {{0x1e6a, 0x1e6b}, {0x1e6b, 0x1e6a}}, + {{0x1e6c, 0x1e6d}, {0x1e6d, 0x1e6c}}, + {{0x1e6e, 0x1e6f}, {0x1e6f, 0x1e6e}}, + {{0x1e70, 0x1e71}, {0x1e71, 0x1e70}}, + {{0x1e72, 0x1e73}, {0x1e73, 0x1e72}}, + {{0x1e74, 0x1e75}, {0x1e75, 0x1e74}}, + {{0x1e76, 0x1e77}, {0x1e77, 0x1e76}}, + {{0x1e78, 0x1e79}, {0x1e79, 0x1e78}}, + {{0x1e7a, 0x1e7b}, {0x1e7b, 0x1e7a}}, + {{0x1e7c, 0x1e7d}, {0x1e7d, 0x1e7c}}, + {{0x1e7e, 0x1e7f}, {0x1e7f, 0x1e7e}}, + {{0x1e80, 0x1e81}, {0x1e81, 0x1e80}}, + {{0x1e82, 0x1e83}, {0x1e83, 0x1e82}}, + {{0x1e84, 0x1e85}, {0x1e85, 0x1e84}}, + {{0x1e86, 0x1e87}, {0x1e87, 0x1e86}}, + {{0x1e88, 0x1e89}, {0x1e89, 0x1e88}}, + {{0x1e8a, 0x1e8b}, {0x1e8b, 0x1e8a}}, + {{0x1e8c, 0x1e8d}, {0x1e8d, 0x1e8c}}, + {{0x1e8e, 0x1e8f}, {0x1e8f, 0x1e8e}}, + {{0x1e90, 0x1e91}, {0x1e91, 0x1e90}}, + {{0x1e92, 0x1e93}, {0x1e93, 0x1e92}}, + {{0x1e94, 0x1e95}, {0x1e95, 0x1e94}}, + {{0x1e9b, 0x1e9b}, {0x1e60, 0x1e60}}, + {{0x1e9e, 0x1e9e}, {0x00df, 0x00df}}, + {{0x1ea0, 0x1ea1}, {0x1ea1, 0x1ea0}}, + {{0x1ea2, 0x1ea3}, {0x1ea3, 0x1ea2}}, + {{0x1ea4, 0x1ea5}, {0x1ea5, 0x1ea4}}, + {{0x1ea6, 0x1ea7}, {0x1ea7, 0x1ea6}}, + {{0x1ea8, 0x1ea9}, {0x1ea9, 0x1ea8}}, + {{0x1eaa, 0x1eab}, {0x1eab, 0x1eaa}}, + {{0x1eac, 0x1ead}, {0x1ead, 0x1eac}}, + {{0x1eae, 0x1eaf}, {0x1eaf, 0x1eae}}, + {{0x1eb0, 0x1eb1}, {0x1eb1, 0x1eb0}}, + {{0x1eb2, 0x1eb3}, {0x1eb3, 0x1eb2}}, + {{0x1eb4, 0x1eb5}, {0x1eb5, 0x1eb4}}, + {{0x1eb6, 0x1eb7}, {0x1eb7, 0x1eb6}}, + {{0x1eb8, 0x1eb9}, {0x1eb9, 0x1eb8}}, + {{0x1eba, 0x1ebb}, {0x1ebb, 0x1eba}}, + {{0x1ebc, 0x1ebd}, {0x1ebd, 0x1ebc}}, + {{0x1ebe, 0x1ebf}, {0x1ebf, 0x1ebe}}, + {{0x1ec0, 0x1ec1}, {0x1ec1, 0x1ec0}}, + {{0x1ec2, 0x1ec3}, {0x1ec3, 0x1ec2}}, + {{0x1ec4, 0x1ec5}, {0x1ec5, 0x1ec4}}, + {{0x1ec6, 0x1ec7}, {0x1ec7, 0x1ec6}}, + {{0x1ec8, 0x1ec9}, {0x1ec9, 0x1ec8}}, + {{0x1eca, 0x1ecb}, {0x1ecb, 0x1eca}}, + {{0x1ecc, 0x1ecd}, {0x1ecd, 0x1ecc}}, + {{0x1ece, 0x1ecf}, {0x1ecf, 0x1ece}}, + {{0x1ed0, 0x1ed1}, {0x1ed1, 0x1ed0}}, + {{0x1ed2, 0x1ed3}, {0x1ed3, 0x1ed2}}, + {{0x1ed4, 0x1ed5}, {0x1ed5, 0x1ed4}}, + {{0x1ed6, 0x1ed7}, {0x1ed7, 0x1ed6}}, + {{0x1ed8, 0x1ed9}, {0x1ed9, 0x1ed8}}, + {{0x1eda, 0x1edb}, {0x1edb, 0x1eda}}, + {{0x1edc, 0x1edd}, {0x1edd, 0x1edc}}, + {{0x1ede, 0x1edf}, {0x1edf, 0x1ede}}, + {{0x1ee0, 0x1ee1}, {0x1ee1, 0x1ee0}}, + {{0x1ee2, 0x1ee3}, {0x1ee3, 0x1ee2}}, + {{0x1ee4, 0x1ee5}, {0x1ee5, 0x1ee4}}, + {{0x1ee6, 0x1ee7}, {0x1ee7, 0x1ee6}}, + {{0x1ee8, 0x1ee9}, {0x1ee9, 0x1ee8}}, + {{0x1eea, 0x1eeb}, {0x1eeb, 0x1eea}}, + {{0x1eec, 0x1eed}, {0x1eed, 0x1eec}}, + {{0x1eee, 0x1eef}, {0x1eef, 0x1eee}}, + {{0x1ef0, 0x1ef1}, {0x1ef1, 0x1ef0}}, + {{0x1ef2, 0x1ef3}, {0x1ef3, 0x1ef2}}, + {{0x1ef4, 0x1ef5}, {0x1ef5, 0x1ef4}}, + {{0x1ef6, 0x1ef7}, {0x1ef7, 0x1ef6}}, + {{0x1ef8, 0x1ef9}, {0x1ef9, 0x1ef8}}, + {{0x1efa, 0x1efb}, {0x1efb, 0x1efa}}, + {{0x1efc, 0x1efd}, {0x1efd, 0x1efc}}, + {{0x1efe, 0x1eff}, {0x1eff, 0x1efe}}, + {{0x1f00, 0x1f07}, {0x1f08, 0x1f0f}}, + {{0x1f08, 0x1f0f}, {0x1f00, 0x1f07}}, + {{0x1f10, 0x1f15}, {0x1f18, 0x1f1d}}, + {{0x1f18, 0x1f1d}, {0x1f10, 0x1f15}}, + {{0x1f20, 0x1f27}, {0x1f28, 0x1f2f}}, + {{0x1f28, 0x1f2f}, {0x1f20, 0x1f27}}, + {{0x1f30, 0x1f37}, {0x1f38, 0x1f3f}}, + {{0x1f38, 0x1f3f}, {0x1f30, 0x1f37}}, + {{0x1f40, 0x1f45}, {0x1f48, 0x1f4d}}, + {{0x1f48, 0x1f4d}, {0x1f40, 0x1f45}}, + {{0x1f51, 0x1f51}, {0x1f59, 0x1f59}}, + {{0x1f53, 0x1f53}, {0x1f5b, 0x1f5b}}, + {{0x1f55, 0x1f55}, {0x1f5d, 0x1f5d}}, + {{0x1f57, 0x1f57}, {0x1f5f, 0x1f5f}}, + {{0x1f59, 0x1f59}, {0x1f51, 0x1f51}}, + {{0x1f5b, 0x1f5b}, {0x1f53, 0x1f53}}, + {{0x1f5d, 0x1f5d}, {0x1f55, 0x1f55}}, + {{0x1f5f, 0x1f5f}, {0x1f57, 0x1f57}}, + {{0x1f60, 0x1f67}, {0x1f68, 0x1f6f}}, + {{0x1f68, 0x1f6f}, {0x1f60, 0x1f67}}, + {{0x1f70, 0x1f71}, {0x1fba, 0x1fbb}}, + {{0x1f72, 0x1f75}, {0x1fc8, 0x1fcb}}, + {{0x1f76, 0x1f77}, {0x1fda, 0x1fdb}}, + {{0x1f78, 0x1f79}, {0x1ff8, 0x1ff9}}, + {{0x1f7a, 0x1f7b}, {0x1fea, 0x1feb}}, + {{0x1f7c, 0x1f7d}, {0x1ffa, 0x1ffb}}, + {{0x1f80, 0x1f87}, {0x1f88, 0x1f8f}}, + {{0x1f90, 0x1f97}, {0x1f98, 0x1f9f}}, + {{0x1fa0, 0x1fa7}, {0x1fa8, 0x1faf}}, + {{0x1fb0, 0x1fb1}, {0x1fb8, 0x1fb9}}, + {{0x1fb3, 0x1fb3}, {0x1fbc, 0x1fbc}}, + {{0x1fb8, 0x1fb9}, {0x1fb0, 0x1fb1}}, + {{0x1fba, 0x1fbb}, {0x1f70, 0x1f71}}, + {{0x1fbe, 0x1fbe}, {0x0399, 0x0399}}, + {{0x1fc3, 0x1fc3}, {0x1fcc, 0x1fcc}}, + {{0x1fc8, 0x1fcb}, {0x1f72, 0x1f75}}, + {{0x1fd0, 0x1fd1}, {0x1fd8, 0x1fd9}}, + {{0x1fd8, 0x1fd9}, {0x1fd0, 0x1fd1}}, + {{0x1fda, 0x1fdb}, {0x1f76, 0x1f77}}, + {{0x1fe0, 0x1fe1}, {0x1fe8, 0x1fe9}}, + {{0x1fe5, 0x1fe5}, {0x1fec, 0x1fec}}, + {{0x1fe8, 0x1fe9}, {0x1fe0, 0x1fe1}}, + {{0x1fea, 0x1feb}, {0x1f7a, 0x1f7b}}, + {{0x1fec, 0x1fec}, {0x1fe5, 0x1fe5}}, + {{0x1ff3, 0x1ff3}, {0x1ffc, 0x1ffc}}, + {{0x1ff8, 0x1ff9}, {0x1f78, 0x1f79}}, + {{0x1ffa, 0x1ffb}, {0x1f7c, 0x1f7d}}, + {{0x2126, 0x2126}, {0x03c9, 0x03c9}}, + {{0x212a, 0x212a}, {0x006b, 0x006b}}, + {{0x212b, 0x212b}, {0x00e5, 0x00e5}}, + {{0x2132, 0x2132}, {0x214e, 0x214e}}, + {{0x214e, 0x214e}, {0x2132, 0x2132}}, + {{0x2183, 0x2184}, {0x2184, 0x2183}}, + {{0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}}, + {{0x2c30, 0x2c5e}, {0x2c00, 0x2c2e}}, + {{0x2c60, 0x2c61}, {0x2c61, 0x2c60}}, + {{0x2c62, 0x2c62}, {0x026b, 0x026b}}, + {{0x2c63, 0x2c63}, {0x1d7d, 0x1d7d}}, + {{0x2c64, 0x2c64}, {0x027d, 0x027d}}, + {{0x2c65, 0x2c65}, {0x023a, 0x023a}}, + {{0x2c66, 0x2c66}, {0x023e, 0x023e}}, + {{0x2c67, 0x2c68}, {0x2c68, 0x2c67}}, + {{0x2c69, 0x2c6a}, {0x2c6a, 0x2c69}}, + {{0x2c6b, 0x2c6c}, {0x2c6c, 0x2c6b}}, + {{0x2c6d, 0x2c6d}, {0x0251, 0x0251}}, + {{0x2c6e, 0x2c6e}, {0x0271, 0x0271}}, + {{0x2c6f, 0x2c6f}, {0x0250, 0x0250}}, + {{0x2c70, 0x2c70}, {0x0252, 0x0252}}, + {{0x2c72, 0x2c73}, {0x2c73, 0x2c72}}, + {{0x2c75, 0x2c76}, {0x2c76, 0x2c75}}, + {{0x2c7e, 0x2c7f}, {0x023f, 0x0240}}, + {{0x2c80, 0x2c81}, {0x2c81, 0x2c80}}, + {{0x2c82, 0x2c83}, {0x2c83, 0x2c82}}, + {{0x2c84, 0x2c85}, {0x2c85, 0x2c84}}, + {{0x2c86, 0x2c87}, {0x2c87, 0x2c86}}, + {{0x2c88, 0x2c89}, {0x2c89, 0x2c88}}, + {{0x2c8a, 0x2c8b}, {0x2c8b, 0x2c8a}}, + {{0x2c8c, 0x2c8d}, {0x2c8d, 0x2c8c}}, + {{0x2c8e, 0x2c8f}, {0x2c8f, 0x2c8e}}, + {{0x2c90, 0x2c91}, {0x2c91, 0x2c90}}, + {{0x2c92, 0x2c93}, {0x2c93, 0x2c92}}, + {{0x2c94, 0x2c95}, {0x2c95, 0x2c94}}, + {{0x2c96, 0x2c97}, {0x2c97, 0x2c96}}, + {{0x2c98, 0x2c99}, {0x2c99, 0x2c98}}, + {{0x2c9a, 0x2c9b}, {0x2c9b, 0x2c9a}}, + {{0x2c9c, 0x2c9d}, {0x2c9d, 0x2c9c}}, + {{0x2c9e, 0x2c9f}, {0x2c9f, 0x2c9e}}, + {{0x2ca0, 0x2ca1}, {0x2ca1, 0x2ca0}}, + {{0x2ca2, 0x2ca3}, {0x2ca3, 0x2ca2}}, + {{0x2ca4, 0x2ca5}, {0x2ca5, 0x2ca4}}, + {{0x2ca6, 0x2ca7}, {0x2ca7, 0x2ca6}}, + {{0x2ca8, 0x2ca9}, {0x2ca9, 0x2ca8}}, + {{0x2caa, 0x2cab}, {0x2cab, 0x2caa}}, + {{0x2cac, 0x2cad}, {0x2cad, 0x2cac}}, + {{0x2cae, 0x2caf}, {0x2caf, 0x2cae}}, + {{0x2cb0, 0x2cb1}, {0x2cb1, 0x2cb0}}, + {{0x2cb2, 0x2cb3}, {0x2cb3, 0x2cb2}}, + {{0x2cb4, 0x2cb5}, {0x2cb5, 0x2cb4}}, + {{0x2cb6, 0x2cb7}, {0x2cb7, 0x2cb6}}, + {{0x2cb8, 0x2cb9}, {0x2cb9, 0x2cb8}}, + {{0x2cba, 0x2cbb}, {0x2cbb, 0x2cba}}, + {{0x2cbc, 0x2cbd}, {0x2cbd, 0x2cbc}}, + {{0x2cbe, 0x2cbf}, {0x2cbf, 0x2cbe}}, + {{0x2cc0, 0x2cc1}, {0x2cc1, 0x2cc0}}, + {{0x2cc2, 0x2cc3}, {0x2cc3, 0x2cc2}}, + {{0x2cc4, 0x2cc5}, {0x2cc5, 0x2cc4}}, + {{0x2cc6, 0x2cc7}, {0x2cc7, 0x2cc6}}, + {{0x2cc8, 0x2cc9}, {0x2cc9, 0x2cc8}}, + {{0x2cca, 0x2ccb}, {0x2ccb, 0x2cca}}, + {{0x2ccc, 0x2ccd}, {0x2ccd, 0x2ccc}}, + {{0x2cce, 0x2ccf}, {0x2ccf, 0x2cce}}, + {{0x2cd0, 0x2cd1}, {0x2cd1, 0x2cd0}}, + {{0x2cd2, 0x2cd3}, {0x2cd3, 0x2cd2}}, + {{0x2cd4, 0x2cd5}, {0x2cd5, 0x2cd4}}, + {{0x2cd6, 0x2cd7}, {0x2cd7, 0x2cd6}}, + {{0x2cd8, 0x2cd9}, {0x2cd9, 0x2cd8}}, + {{0x2cda, 0x2cdb}, {0x2cdb, 0x2cda}}, + {{0x2cdc, 0x2cdd}, {0x2cdd, 0x2cdc}}, + {{0x2cde, 0x2cdf}, {0x2cdf, 0x2cde}}, + {{0x2ce0, 0x2ce1}, {0x2ce1, 0x2ce0}}, + {{0x2ce2, 0x2ce3}, {0x2ce3, 0x2ce2}}, + {{0x2ceb, 0x2cec}, {0x2cec, 0x2ceb}}, + {{0x2ced, 0x2cee}, {0x2cee, 0x2ced}}, + {{0x2cf2, 0x2cf3}, {0x2cf3, 0x2cf2}}, + {{0x2d00, 0x2d25}, {0x10a0, 0x10c5}}, + {{0x2d27, 0x2d27}, {0x10c7, 0x10c7}}, + {{0x2d2d, 0x2d2d}, {0x10cd, 0x10cd}}, + {{0xa640, 0xa641}, {0xa641, 0xa640}}, + {{0xa642, 0xa643}, {0xa643, 0xa642}}, + {{0xa644, 0xa645}, {0xa645, 0xa644}}, + {{0xa646, 0xa647}, {0xa647, 0xa646}}, + {{0xa648, 0xa649}, {0xa649, 0xa648}}, + {{0xa64a, 0xa64b}, {0xa64b, 0xa64a}}, + {{0xa64c, 0xa64d}, {0xa64d, 0xa64c}}, + {{0xa64e, 0xa64f}, {0xa64f, 0xa64e}}, + {{0xa650, 0xa651}, {0xa651, 0xa650}}, + {{0xa652, 0xa653}, {0xa653, 0xa652}}, + {{0xa654, 0xa655}, {0xa655, 0xa654}}, + {{0xa656, 0xa657}, {0xa657, 0xa656}}, + {{0xa658, 0xa659}, {0xa659, 0xa658}}, + {{0xa65a, 0xa65b}, {0xa65b, 0xa65a}}, + {{0xa65c, 0xa65d}, {0xa65d, 0xa65c}}, + {{0xa65e, 0xa65f}, {0xa65f, 0xa65e}}, + {{0xa660, 0xa661}, {0xa661, 0xa660}}, + {{0xa662, 0xa663}, {0xa663, 0xa662}}, + {{0xa664, 0xa665}, {0xa665, 0xa664}}, + {{0xa666, 0xa667}, {0xa667, 0xa666}}, + {{0xa668, 0xa669}, {0xa669, 0xa668}}, + {{0xa66a, 0xa66b}, {0xa66b, 0xa66a}}, + {{0xa66c, 0xa66d}, {0xa66d, 0xa66c}}, + {{0xa680, 0xa681}, {0xa681, 0xa680}}, + {{0xa682, 0xa683}, {0xa683, 0xa682}}, + {{0xa684, 0xa685}, {0xa685, 0xa684}}, + {{0xa686, 0xa687}, {0xa687, 0xa686}}, + {{0xa688, 0xa689}, {0xa689, 0xa688}}, + {{0xa68a, 0xa68b}, {0xa68b, 0xa68a}}, + {{0xa68c, 0xa68d}, {0xa68d, 0xa68c}}, + {{0xa68e, 0xa68f}, {0xa68f, 0xa68e}}, + {{0xa690, 0xa691}, {0xa691, 0xa690}}, + {{0xa692, 0xa693}, {0xa693, 0xa692}}, + {{0xa694, 0xa695}, {0xa695, 0xa694}}, + {{0xa696, 0xa697}, {0xa697, 0xa696}}, + {{0xa698, 0xa699}, {0xa699, 0xa698}}, + {{0xa69a, 0xa69b}, {0xa69b, 0xa69a}}, + {{0xa722, 0xa723}, {0xa723, 0xa722}}, + {{0xa724, 0xa725}, {0xa725, 0xa724}}, + {{0xa726, 0xa727}, {0xa727, 0xa726}}, + {{0xa728, 0xa729}, {0xa729, 0xa728}}, + {{0xa72a, 0xa72b}, {0xa72b, 0xa72a}}, + {{0xa72c, 0xa72d}, {0xa72d, 0xa72c}}, + {{0xa72e, 0xa72f}, {0xa72f, 0xa72e}}, + {{0xa732, 0xa733}, {0xa733, 0xa732}}, + {{0xa734, 0xa735}, {0xa735, 0xa734}}, + {{0xa736, 0xa737}, {0xa737, 0xa736}}, + {{0xa738, 0xa739}, {0xa739, 0xa738}}, + {{0xa73a, 0xa73b}, {0xa73b, 0xa73a}}, + {{0xa73c, 0xa73d}, {0xa73d, 0xa73c}}, + {{0xa73e, 0xa73f}, {0xa73f, 0xa73e}}, + {{0xa740, 0xa741}, {0xa741, 0xa740}}, + {{0xa742, 0xa743}, {0xa743, 0xa742}}, + {{0xa744, 0xa745}, {0xa745, 0xa744}}, + {{0xa746, 0xa747}, {0xa747, 0xa746}}, + {{0xa748, 0xa749}, {0xa749, 0xa748}}, + {{0xa74a, 0xa74b}, {0xa74b, 0xa74a}}, + {{0xa74c, 0xa74d}, {0xa74d, 0xa74c}}, + {{0xa74e, 0xa74f}, {0xa74f, 0xa74e}}, + {{0xa750, 0xa751}, {0xa751, 0xa750}}, + {{0xa752, 0xa753}, {0xa753, 0xa752}}, + {{0xa754, 0xa755}, {0xa755, 0xa754}}, + {{0xa756, 0xa757}, {0xa757, 0xa756}}, + {{0xa758, 0xa759}, {0xa759, 0xa758}}, + {{0xa75a, 0xa75b}, {0xa75b, 0xa75a}}, + {{0xa75c, 0xa75d}, {0xa75d, 0xa75c}}, + {{0xa75e, 0xa75f}, {0xa75f, 0xa75e}}, + {{0xa760, 0xa761}, {0xa761, 0xa760}}, + {{0xa762, 0xa763}, {0xa763, 0xa762}}, + {{0xa764, 0xa765}, {0xa765, 0xa764}}, + {{0xa766, 0xa767}, {0xa767, 0xa766}}, + {{0xa768, 0xa769}, {0xa769, 0xa768}}, + {{0xa76a, 0xa76b}, {0xa76b, 0xa76a}}, + {{0xa76c, 0xa76d}, {0xa76d, 0xa76c}}, + {{0xa76e, 0xa76f}, {0xa76f, 0xa76e}}, + {{0xa779, 0xa77a}, {0xa77a, 0xa779}}, + {{0xa77b, 0xa77c}, {0xa77c, 0xa77b}}, + {{0xa77d, 0xa77d}, {0x1d79, 0x1d79}}, + {{0xa77e, 0xa77f}, {0xa77f, 0xa77e}}, + {{0xa780, 0xa781}, {0xa781, 0xa780}}, + {{0xa782, 0xa783}, {0xa783, 0xa782}}, + {{0xa784, 0xa785}, {0xa785, 0xa784}}, + {{0xa786, 0xa787}, {0xa787, 0xa786}}, + {{0xa78b, 0xa78c}, {0xa78c, 0xa78b}}, + {{0xa78d, 0xa78d}, {0x0265, 0x0265}}, + {{0xa790, 0xa791}, {0xa791, 0xa790}}, + {{0xa792, 0xa793}, {0xa793, 0xa792}}, + {{0xa796, 0xa797}, {0xa797, 0xa796}}, + {{0xa798, 0xa799}, {0xa799, 0xa798}}, + {{0xa79a, 0xa79b}, {0xa79b, 0xa79a}}, + {{0xa79c, 0xa79d}, {0xa79d, 0xa79c}}, + {{0xa79e, 0xa79f}, {0xa79f, 0xa79e}}, + {{0xa7a0, 0xa7a1}, {0xa7a1, 0xa7a0}}, + {{0xa7a2, 0xa7a3}, {0xa7a3, 0xa7a2}}, + {{0xa7a4, 0xa7a5}, {0xa7a5, 0xa7a4}}, + {{0xa7a6, 0xa7a7}, {0xa7a7, 0xa7a6}}, + {{0xa7a8, 0xa7a9}, {0xa7a9, 0xa7a8}}, + {{0xa7aa, 0xa7aa}, {0x0266, 0x0266}}, + {{0xa7ab, 0xa7ab}, {0x025c, 0x025c}}, + {{0xa7ac, 0xa7ac}, {0x0261, 0x0261}}, + {{0xa7ad, 0xa7ad}, {0x026c, 0x026c}}, + {{0xa7b0, 0xa7b0}, {0x029e, 0x029e}}, + {{0xa7b1, 0xa7b1}, {0x0287, 0x0287}}, + {{0xa7b2, 0xa7b2}, {0x029d, 0x029d}}, + {{0xa7b3, 0xa7b3}, {0xab53, 0xab53}}, + {{0xa7b4, 0xa7b5}, {0xa7b5, 0xa7b4}}, + {{0xa7b6, 0xa7b7}, {0xa7b7, 0xa7b6}}, + {{0xab53, 0xab53}, {0xa7b3, 0xa7b3}}, + {{0xab70, 0xabbf}, {0x13a0, 0x13ef}}, + {{0xff21, 0xff3a}, {0xff41, 0xff5a}}, + {{0xff41, 0xff5a}, {0xff21, 0xff3a}}, + {{0, 0}, {0, 0}}}; + const fold_pair *ptr_ = mapping_; + + for (; ptr_->from.first != 0; ++ptr_) + { + if (range_.second < ptr_->from.first) break; + + if (range_.first >= ptr_->from.first && + range_.first <= ptr_->from.second) + { + if (ptr_->to.first <= ptr_->to.second) + { + const index_type first_ = ptr_->to.first + + (range_.first - ptr_->from.first); + + out_.insert(range(first_, + range_.second > ptr_->from.second ? + ptr_->to.second : + static_cast(ptr_->to.first + + (range_.second - ptr_->from.first)))); + } + else + { + const index_type first_ = ptr_->to.second + + (range_.first - ptr_->from.first); + + out_.insert(range(first_, + range_.second > ptr_->from.second ? + ptr_->to.first : + static_cast(ptr_->to.second + + (range_.second - ptr_->from.first)))); + } + } + else if (range_.second >= ptr_->from.first && + range_.second <= ptr_->from.second) + { + if (ptr_->to.first <= ptr_->to.second) + { + const index_type second_ = ptr_->to.first + + (range_.second - ptr_->from.first); + + out_.insert(range(ptr_->to.first, second_)); + } + else + { + const index_type second_ = ptr_->to.second + + (range_.second - ptr_->from.first); + + out_.insert(range(ptr_->to.second, second_)); + } + } + // Either range fully encompasses from range or not at all. + else if (ptr_->from.first >= range_.first && + ptr_->from.first <= range_.second) + { + if (ptr_->to.first <= ptr_->to.second) + { + out_.insert(range(ptr_->to.first, ptr_->to.second)); + } + else + { + out_.insert(range(ptr_->to.second, ptr_->to.first)); + } + } + } + } + + static void fold(const range &range_, const std::locale &locale_, + string_token &out_, const four &) + { + if (range_.first < 0x10000) + { + fold(range_, locale_, out_, two()); + } + + static const fold_pair mapping_[] = + {{{0x10400, 0x10427}, {0x10428, 0x1044f}}, + {{0x10428, 0x1044f}, {0x10400, 0x10427}}, + {{0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}}, + {{0x10cc0, 0x10cf2}, {0x10c80, 0x10cb2}}, + {{0x118a0, 0x118bf}, {0x118c0, 0x118df}}, + {{0x118c0, 0x118df}, {0x118a0, 0x118bf}}, + {{0, 0}, {0, 0}}}; + const fold_pair *ptr_ = mapping_; + + for (; ptr_->from.first != 0; ++ptr_) + { + if (range_.second < ptr_->from.first) break; + + if (range_.first >= ptr_->from.first && + range_.first <= ptr_->from.second) + { + out_.insert(range(ptr_->to.first + + (range_.first - ptr_->from.first), + range_.second > ptr_->from.second ? + ptr_->to.second : + ptr_->to.first + (range_.second - ptr_->from.first))); + } + else if (range_.second >= ptr_->from.first && + range_.second <= ptr_->from.second) + { + out_.insert(range(ptr_->to.first, + ptr_->to.first + (range_.second - ptr_->from.first))); + } + // Either range fully encompasses from range or not at all. + else if (ptr_->from.first >= range_.first && + ptr_->from.first <= range_.second) + { + out_.insert(range(ptr_->to.first, ptr_->to.second)); + } + } + } + + template + static input_char_type chr(state_type &state_) + { + input_char_type ch_ = 0; + + // eos_ has already been checked for. + switch (*state_._curr) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + ch_ = decode_octal(state_); + break; + case 'a': + ch_ = '\a'; + state_.increment(); + break; + case 'b': + ch_ = '\b'; + state_.increment(); + break; + case 'c': + ch_ = decode_control_char(state_); + break; + case 'e': + ch_ = 27; // '\e' not recognised by compiler + state_.increment(); + break; + case 'f': + ch_ = '\f'; + state_.increment(); + break; + case 'n': + ch_ = '\n'; + state_.increment(); + break; + case 'r': + ch_ = '\r'; + state_.increment(); + break; + case 't': + ch_ = '\t'; + state_.increment(); + break; + case 'v': + ch_ = '\v'; + state_.increment(); + break; + case 'x': + ch_ = decode_hex(state_); + break; + default: + ch_ = *state_._curr; + state_.increment(); + break; + } + + return ch_; + } + +private: + struct char_pair + { + input_char_type first; + input_char_type second; + }; + + struct fold_pair + { + char_pair from; + char_pair to; + }; + + template + static void posix(state_type &state_, string_token &token_) + { + bool negate_ = false; + + if (!state_.eos() && *state_._curr == '^') + { + negate_ = true; + state_.increment(); + } + + if (state_.eos()) + { + unterminated_posix(state_); + } + else + { + switch (*state_._curr) + { + case 'a': + // alnum + // alpha + alnum_alpha(state_, token_, negate_); + break; + case 'b': + // blank + blank(state_, token_, negate_); + break; + case 'c': + // cntrl + cntrl(state_, token_, negate_); + break; + case 'd': + // digit + digit(state_, token_, negate_); + break; + case 'g': + // graph + graph(state_, token_, negate_); + break; + case 'l': + // lower + lower(state_, token_, negate_); + break; + case 'p': + // print + // punct + print_punct(state_, token_, negate_); + break; + case 's': + // space + space(state_, token_, negate_); + break; + case 'u': + // upper + upper(state_, token_, negate_); + break; + case 'x': + // xdigit + xdigit(state_, token_, negate_); + break; + default: + unknown_posix(state_); + break; + } + } + } + + template + static void alnum_alpha(state_type &state_, string_token &token_, + const bool negate_) + { + enum {unknown, alnum, alpha}; + std::size_t type_ = unknown; + + state_.increment(); + + if (!state_.eos() && *state_._curr == 'l') + { + state_.increment(); + + if (!state_.eos()) + { + if (*state_._curr == 'n') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'u') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'm') + { + state_.increment(); + type_ = alnum; + } + } + } + else if (*state_._curr == 'p') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'h') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'a') + { + state_.increment(); + type_ = alpha; + } + } + } + } + } + + if (type_ == unknown) + { + unknown_posix(state_); + } + else + { + std::string str_; + + check_posix_termination(state_); + + if (type_ == alnum) + { + // alnum + str_ = sizeof(input_char_type) == 1 ? + make_alnum(state_._locale) : + std::string("[\\p{Ll}\\p{Lu}\\p{Nd}]"); + } + else + { + // alpha + str_ = sizeof(input_char_type) == 1 ? + make_alpha(state_._locale) : + std::string("[\\p{Ll}\\p{Lu}]"); + } + + insert_charset(str_.c_str(), state_, token_, negate_); + } + } + + static std::string make_alnum(std::locale &locale_) + { + std::string str_(1, '['); + + for (std::size_t i_ = 0; i_ < 256; ++i_) + { + if (std::use_facet >(locale_). + is(std::ctype_base::alnum, static_cast(i_))) + { + str_ += static_cast(i_); + } + } + + str_ += ']'; + return str_; + } + + static std::string make_alpha(std::locale &locale_) + { + std::string str_(1, '['); + + for (std::size_t i_ = 0; i_ < 256; ++i_) + { + if (std::use_facet >(locale_). + is(std::ctype_base::alpha, static_cast(i_))) + { + str_ += static_cast(i_); + } + } + + str_ += ']'; + return str_; + } + + template + static void blank(state_type &state_, string_token &token_, + const bool negate_) + { + const char *blank_ = "lank"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *blank_ && + static_cast(*state_._curr) == + static_cast(*blank_)) + { + state_.increment(); + ++blank_; + } + + if (*blank_) + { + unknown_posix(state_); + } + else + { + const char *str_ = sizeof(input_char_type) == 1 ? + "[ \t]" : "[\\p{Zs}\t]"; + + check_posix_termination(state_); + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void cntrl(state_type &state_, string_token &token_, + const bool negate_) + { + const char *cntrl_ = "ntrl"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *cntrl_ && + static_cast(*state_._curr) == + static_cast(*cntrl_)) + { + state_.increment(); + ++cntrl_; + } + + if (*cntrl_) + { + unknown_posix(state_); + } + else + { + const char *str_ = sizeof(input_char_type) == 1 ? + "[\\x00-\x1f\x7f]" : "[\\p{Cc}]"; + + check_posix_termination(state_); + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void digit(state_type &state_, string_token &token_, + const bool negate_) + { + const char *digit_ = "igit"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *digit_ && + static_cast(*state_._curr) == + static_cast(*digit_)) + { + state_.increment(); + ++digit_; + } + + if (*digit_) + { + unknown_posix(state_); + } + else + { + const char *str_ = sizeof(input_char_type) == 1 ? + "[0-9]" : "[\\p{Nd}]"; + + check_posix_termination(state_); + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void graph(state_type &state_, string_token &token_, + const bool negate_) + { + const char *graph_ = "raph"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *graph_ && + static_cast(*state_._curr) == + static_cast(*graph_)) + { + state_.increment(); + ++graph_; + } + + if (*graph_) + { + unknown_posix(state_); + } + else + { + const char *str_ = sizeof(input_char_type) == 1 ? + "[\x21-\x7e]" : "[^\\p{Z}\\p{C}]"; + + check_posix_termination(state_); + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void lower(state_type &state_, string_token &token_, + const bool negate_) + { + const char *lower_ = "ower"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *lower_ && + static_cast(*state_._curr) == + static_cast(*lower_)) + { + state_.increment(); + ++lower_; + } + + if (*lower_) + { + unknown_posix(state_); + } + else + { + std::string str_ = sizeof(input_char_type) == 1 ? + create_lower(state_._locale) : + std::string("[\\p{Ll}]"); + + check_posix_termination(state_); + insert_charset(str_.c_str(), state_, token_, negate_); + } + } + + static std::string create_lower(std::locale &locale_) + { + std::string str_(1, '['); + + for (std::size_t i_ = 0; i_ < 256; ++i_) + { + if (std::use_facet >(locale_). + is(std::ctype_base::lower, static_cast(i_))) + { + str_ += static_cast(i_); + } + } + + str_ += ']'; + return str_; + } + + template + static void print_punct(state_type &state_, string_token &token_, + const bool negate_) + { + enum {unknown, print, punct}; + std::size_t type_ = unknown; + + state_.increment(); + + if (!state_.eos()) + { + if (*state_._curr == 'r') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'i') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'n') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 't') + { + state_.increment(); + type_ = print; + } + } + } + } + else if (*state_._curr == 'u') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'n') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'c') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 't') + { + state_.increment(); + type_ = punct; + } + } + } + } + } + + if (type_ == unknown) + { + unknown_posix(state_); + } + else + { + const char *str_ = nullptr; + + check_posix_termination(state_); + + if (type_ == print) + { + // print + str_ = sizeof(input_char_type) == 1 ? + "[\x20-\x7e]" : "[\\p{C}]"; + } + else + { + // punct + str_ = sizeof(input_char_type) == 1 ? + "[!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_`{|}~]" : + "[\\p{P}\\p{S}]"; + } + + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void space(state_type &state_, string_token &token_, + const bool negate_) + { + const char *space_ = "pace"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *space_ && + static_cast(*state_._curr) == + static_cast(*space_)) + { + state_.increment(); + ++space_; + } + + if (*space_) + { + unknown_posix(state_); + } + else + { + const char *str_ = sizeof(input_char_type) == 1 ? + "[ \t\r\n\v\f]" : "[\\p{Z}\t\r\n\v\f]"; + + check_posix_termination(state_); + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void upper(state_type &state_, string_token &token_, + const bool negate_) + { + const char *upper_ = "pper"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *upper_ && + static_cast(*state_._curr) == + static_cast(*upper_)) + { + state_.increment(); + ++upper_; + } + + if (*upper_) + { + unknown_posix(state_); + } + else + { + std::string str_ = sizeof(input_char_type) == 1 ? + create_upper(state_._locale) : + std::string("[\\p{Lu}]"); + + check_posix_termination(state_); + insert_charset(str_.c_str(), state_, token_, negate_); + } + } + + static std::string create_upper(std::locale &locale_) + { + std::string str_(1, '['); + + for (std::size_t i_ = 0; i_ < 256; ++i_) + { + if (std::use_facet >(locale_). + is(std::ctype_base::upper, static_cast(i_))) + { + str_ += static_cast(i_); + } + } + + str_ += ']'; + return str_; + } + + template + static void xdigit(state_type &state_, string_token &token_, + const bool negate_) + { + const char *xdigit_ = "digit"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *xdigit_ && + static_cast(*state_._curr) == + static_cast(*xdigit_)) + { + state_.increment(); + ++xdigit_; + } + + if (*xdigit_) + { + unknown_posix(state_); + } + else + { + const char *str_ = "[0-9A-Fa-f]"; + + check_posix_termination(state_); + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void check_posix_termination(state_type &state_) + { + if (state_.eos()) + { + unterminated_posix(state_); + } + + if (*state_._curr != ':') + { + std::ostringstream ss_; + + ss_ << "Missing ':' at index " << state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + state_.increment(); + + if (state_.eos()) + { + unterminated_posix(state_); + } + + if (*state_._curr != ']') + { + std::ostringstream ss_; + + ss_ << "Missing ']' at index " << state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + state_.increment(); + } + + template + static void unterminated_posix(state_type &state_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (unterminated POSIX charset)"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + template + static void unknown_posix(state_type &state_) + { + std::ostringstream ss_; + + ss_ << "Unknown POSIX charset at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + template + static void insert_charset(const char *str_, state_type &state_, + string_token &token_, const bool negate_) + { + // Some systems have strlen in namespace std. + using namespace std; + + char_state temp_state_(str_ + 1, str_ + strlen(str_), + state_._id, state_._flags, state_._locale, 0); + string_token temp_token_; + + charset(temp_state_, temp_token_); + + if (negate_) temp_token_.negate(); + + token_.insert(temp_token_); + } + + template + static const char *charset_shortcut + (state_type &state_, std::size_t &str_len_) + { + const char *str_ = nullptr; + + switch (*state_._curr) + { + case 'd': + str_ = "[0-9]"; + break; + case 'D': + str_ = "[^0-9]"; + break; + case 'p': + str_ = unicode_escape(state_); + break; + case 's': + str_ = "[ \t\n\r\f\v]"; + break; + case 'S': + str_ = "[^ \t\n\r\f\v]"; + break; + case 'w': + str_ = "[_0-9A-Za-z]"; + break; + case 'W': + str_ = "[^_0-9A-Za-z]"; + break; + } + + if (str_) + { + // Some systems have strlen in namespace std. + using namespace std; + + str_len_ = strlen(str_); + } + else + { + str_len_ = 0; + } + + return str_; + } + + template + static const char *unicode_escape(state_type &state_) + { + const char *str_ = nullptr; + + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (*state_._curr != '{') + { + std::ostringstream ss_; + + ss_ << "Missing '{' following \\p at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case 'C': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{C"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cs}]"; + break; + case 'c': + str_ = other_control(); + state_.increment(); + break; + case 'f': + str_ = other_format(); + state_.increment(); + break; +// case 'n': +// break; + case 'o': + str_ = other_private(); + state_.increment(); + break; + case 's': + str_ = other_surrogate(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{C at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + case 'L': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{L"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Ll}\\p{Lm}\\p{Lo}\\p{Lt}\\p{Lu}]"; + break; + case 'C': + str_ = "[\\p{Ll}\\p{Lt}\\p{Lu}]"; + state_.increment(); + break; + case 'l': + str_ = letter_lowercase(); + state_.increment(); + break; + case 'm': + str_ = letter_modifier(); + state_.increment(); + break; + case 'o': + str_ = letter_other(); + state_.increment(); + break; + case 't': + str_ = letter_titlecase(); + state_.increment(); + break; + case 'u': + str_ = letter_uppercase(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{L at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + case 'M': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{M"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Mc}\\p{Me}\\p{Mn}]"; + break; + case 'c': + str_ = mark_combining(); + state_.increment(); + break; + case 'e': + str_ = mark_enclosing(); + state_.increment(); + break; + case 'n': + str_ = mark_nonspacing(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{M at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + case 'N': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{N"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Nd}\\p{Nl}\\p{No}]"; + break; + case 'd': + str_ = number_decimal(); + state_.increment(); + break; + case 'l': + str_ = number_letter(); + state_.increment(); + break; + case 'o': + str_ = number_other(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{N at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + case 'P': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{P"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Pc}\\p{Pd}\\p{Pe}\\p{Pf}\\p{Pi}\\p{Po}" + "\\p{Ps}]"; + break; + case 'c': + str_ = punctuation_connector(); + state_.increment(); + break; + case 'd': + str_ = punctuation_dash(); + state_.increment(); + break; + case 'e': + str_ = punctuation_close(); + state_.increment(); + break; + case 'f': + str_ = punctuation_final(); + state_.increment(); + break; + case 'i': + str_ = punctuation_initial(); + state_.increment(); + break; + case 'o': + str_ = punctuation_other(); + state_.increment(); + break; + case 's': + str_ = punctuation_open(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{P at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + case 'S': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{S"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Sc}\\p{Sk}\\p{Sm}\\p{So}]"; + break; + case 'c': + str_ = symbol_currency(); + state_.increment(); + break; + case 'k': + str_ = symbol_modifier(); + state_.increment(); + break; + case 'm': + str_ = symbol_math(); + state_.increment(); + break; + case 'o': + str_ = symbol_other(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{S at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + case 'Z': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{Z"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Zl}\\p{Zp}\\p{Zs}]"; + break; + case 'l': + str_ = separator_line(); + state_.increment(); + break; + case 'p': + str_ = separator_paragraph(); + state_.increment(); + break; + case 's': + str_ = separator_space(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{Z at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{ at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + if (*state_._curr != '}') + { + std::ostringstream ss_; + + ss_ << "Missing '}' at index " << state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + return str_; + } + + static const char *other_control() + { + return "[\\x0-\\x1f\\x7f-\\x9f]"; + } + + static const char *other_format() + { + return "[\\xad\\x600-\\x605\\x61c\\x6dd\\x70f\\x180e\\x200b-\\x200f" + "\\x202a-\\x202e\\x2060-\\x2064\\x2066-\\x206f\\xfeff" + "\\xfff9-\\xfffb\\x110bd\\x1bca0-\\x1bca3\\x1d173-\\x1d17a\\xe0001" + "\\xe0020-\\xe007f]"; + } + + static const char *other_private() + { + return "[\\xe000\\xf8ff\\xf0000\\xffffd\\x100000\\x10fffd]"; + } + + static const char *other_surrogate() + { + return "[\\xd800\\xdb7f\\xdb80\\xdbff\\xdc00\\xdfff]"; + } + + static const char *letter_lowercase() + { + return "[\\x61-\\x7a\\xb5\\xdf-\\xf6\\xf8-\\xff\\x101\\x103\\x105\\x107" + "\\x109\\x10b\\x10d\\x10f\\x111\\x113\\x115\\x117\\x119\\x11b\\x11d" + "\\x11f\\x121\\x123\\x125\\x127\\x129\\x12b\\x12d\\x12f\\x131\\x133" + "\\x135\\x137\\x138\\x13a\\x13c\\x13e\\x140\\x142\\x144\\x146" + "\\x148\\x149\\x14b\\x14d\\x14f\\x151\\x153\\x155\\x157\\x159\\x15b" + "\\x15d\\x15f\\x161\\x163\\x165\\x167\\x169\\x16b\\x16d\\x16f\\x171" + "\\x173\\x175\\x177\\x17a\\x17c\\x17e-\\x180\\x183\\x185\\x188" + "\\x18c\\x18d\\x192\\x195\\x199-\\x19b\\x19e\\x1a1\\x1a3\\x1a5" + "\\x1a8\\x1aa\\x1ab\\x1ad\\x1b0\\x1b4\\x1b6\\x1b9\\x1ba" + "\\x1bd-\\x1bf\\x1c6\\x1c9\\x1cc\\x1ce\\x1d0\\x1d2\\x1d4\\x1d6" + "\\x1d8\\x1da\\x1dc\\x1dd\\x1df\\x1e1\\x1e3\\x1e5\\x1e7\\x1e9\\x1eb" + "\\x1ed\\x1ef\\x1f0\\x1f3\\x1f5\\x1f9\\x1fb\\x1fd\\x1ff\\x201\\x203" + "\\x205\\x207\\x209\\x20b\\x20d\\x20f\\x211\\x213\\x215\\x217\\x219" + "\\x21b\\x21d\\x21f\\x221\\x223\\x225\\x227\\x229\\x22b\\x22d\\x22f" + "\\x231\\x233-\\x239\\x23c\\x23f\\x240\\x242\\x247\\x249\\x24b" + "\\x24d\\x24f-\\x293\\x295-\\x2af\\x371\\x373\\x377\\x37b-\\x37d" + "\\x390\\x3ac-\\x3ce\\x3d0\\x3d1\\x3d5-\\x3d7\\x3d9\\x3db\\x3dd" + "\\x3df\\x3e1\\x3e3\\x3e5\\x3e7\\x3e9\\x3eb\\x3ed\\x3ef-\\x3f3" + "\\x3f5\\x3f8\\x3fb\\x3fc\\x430-\\x45f\\x461\\x463\\x465\\x467" + "\\x469\\x46b\\x46d\\x46f\\x471\\x473\\x475\\x477\\x479\\x47b\\x47d" + "\\x47f\\x481\\x48b\\x48d\\x48f\\x491\\x493\\x495\\x497\\x499\\x49b" + "\\x49d\\x49f\\x4a1\\x4a3\\x4a5\\x4a7\\x4a9\\x4ab\\x4ad\\x4af\\x4b1" + "\\x4b3\\x4b5\\x4b7\\x4b9\\x4bb\\x4bd\\x4bf\\x4c2\\x4c4\\x4c6\\x4c8" + "\\x4ca\\x4cc\\x4ce\\x4cf\\x4d1\\x4d3\\x4d5\\x4d7\\x4d9\\x4db\\x4dd" + "\\x4df\\x4e1\\x4e3\\x4e5\\x4e7\\x4e9\\x4eb\\x4ed\\x4ef\\x4f1\\x4f3" + "\\x4f5\\x4f7\\x4f9\\x4fb\\x4fd\\x4ff\\x501\\x503\\x505\\x507\\x509" + "\\x50b\\x50d\\x50f\\x511\\x513\\x515\\x517\\x519\\x51b\\x51d\\x51f" + "\\x521\\x523\\x525\\x527\\x529\\x52b\\x52d\\x52f\\x561-\\x587" + "\\x13f8-\\x13fd\\x1d00-\\x1d2b\\x1d6b-\\x1d77\\x1d79-\\x1d9a" + "\\x1e01\\x1e03\\x1e05\\x1e07\\x1e09\\x1e0b\\x1e0d\\x1e0f\\x1e11" + "\\x1e13\\x1e15\\x1e17\\x1e19\\x1e1b\\x1e1d\\x1e1f\\x1e21\\x1e23" + "\\x1e25\\x1e27\\x1e29\\x1e2b\\x1e2d\\x1e2f\\x1e31\\x1e33\\x1e35" + "\\x1e37\\x1e39\\x1e3b\\x1e3d\\x1e3f\\x1e41\\x1e43\\x1e45\\x1e47" + "\\x1e49\\x1e4b\\x1e4d\\x1e4f\\x1e51\\x1e53\\x1e55\\x1e57\\x1e59" + "\\x1e5b\\x1e5d\\x1e5f\\x1e61\\x1e63\\x1e65\\x1e67\\x1e69\\x1e6b" + "\\x1e6d\\x1e6f\\x1e71\\x1e73\\x1e75\\x1e77\\x1e79\\x1e7b\\x1e7d" + "\\x1e7f\\x1e81\\x1e83\\x1e85\\x1e87\\x1e89\\x1e8b\\x1e8d\\x1e8f" + "\\x1e91\\x1e93\\x1e95-\\x1e9d\\x1e9f\\x1ea1\\x1ea3\\x1ea5\\x1ea7" + "\\x1ea9\\x1eab\\x1ead\\x1eaf\\x1eb1\\x1eb3\\x1eb5\\x1eb7\\x1eb9" + "\\x1ebb\\x1ebd\\x1ebf\\x1ec1\\x1ec3\\x1ec5\\x1ec7\\x1ec9\\x1ecb" + "\\x1ecd\\x1ecf\\x1ed1\\x1ed3\\x1ed5\\x1ed7\\x1ed9\\x1edb\\x1edd" + "\\x1edf\\x1ee1\\x1ee3\\x1ee5\\x1ee7\\x1ee9\\x1eeb\\x1eed\\x1eef" + "\\x1ef1\\x1ef3\\x1ef5\\x1ef7\\x1ef9\\x1efb\\x1efd\\x1eff-\\x1f07" + "\\x1f10-\\x1f15\\x1f20-\\x1f27\\x1f30-\\x1f37\\x1f40-\\x1f45" + "\\x1f50-\\x1f57\\x1f60-\\x1f67\\x1f70-\\x1f7d\\x1f80-\\x1f87" + "\\x1f90-\\x1f97\\x1fa0-\\x1fa7\\x1fb0-\\x1fb4\\x1fb6\\x1fb7\\x1fbe" + "\\x1fc2-\\x1fc4\\x1fc6\\x1fc7\\x1fd0-\\x1fd3\\x1fd6\\x1fd7" + "\\x1fe0-\\x1fe7\\x1ff2-\\x1ff4\\x1ff6\\x1ff7\\x210a\\x210e\\x210f" + "\\x2113\\x212f\\x2134\\x2139\\x213c\\x213d\\x2146-\\x2149\\x214e" + "\\x2184\\x2c30-\\x2c5e\\x2c61\\x2c65\\x2c66\\x2c68\\x2c6a\\x2c6c" + "\\x2c71\\x2c73\\x2c74\\x2c76-\\x2c7b\\x2c81\\x2c83\\x2c85\\x2c87" + "\\x2c89\\x2c8b\\x2c8d\\x2c8f\\x2c91\\x2c93\\x2c95\\x2c97\\x2c99" + "\\x2c9b\\x2c9d\\x2c9f\\x2ca1\\x2ca3\\x2ca5\\x2ca7\\x2ca9\\x2cab" + "\\x2cad\\x2caf\\x2cb1\\x2cb3\\x2cb5\\x2cb7\\x2cb9\\x2cbb\\x2cbd" + "\\x2cbf\\x2cc1\\x2cc3\\x2cc5\\x2cc7\\x2cc9\\x2ccb\\x2ccd\\x2ccf" + "\\x2cd1\\x2cd3\\x2cd5\\x2cd7\\x2cd9\\x2cdb\\x2cdd\\x2cdf\\x2ce1" + "\\x2ce3\\x2ce4\\x2cec\\x2cee\\x2cf3\\x2d00-\\x2d25\\x2d27\\x2d2d" + "\\xa641\\xa643\\xa645\\xa647\\xa649\\xa64b\\xa64d\\xa64f\\xa651" + "\\xa653\\xa655\\xa657\\xa659\\xa65b\\xa65d\\xa65f\\xa661\\xa663" + "\\xa665\\xa667\\xa669\\xa66b\\xa66d\\xa681\\xa683\\xa685\\xa687" + "\\xa689\\xa68b\\xa68d\\xa68f\\xa691\\xa693\\xa695\\xa697\\xa699" + "\\xa69b\\xa723\\xa725\\xa727\\xa729\\xa72b\\xa72d\\xa72f-\\xa731" + "\\xa733\\xa735\\xa737\\xa739\\xa73b\\xa73d\\xa73f\\xa741\\xa743" + "\\xa745\\xa747\\xa749\\xa74b\\xa74d\\xa74f\\xa751\\xa753\\xa755" + "\\xa757\\xa759\\xa75b\\xa75d\\xa75f\\xa761\\xa763\\xa765\\xa767" + "\\xa769\\xa76b\\xa76d\\xa76f\\xa771-\\xa778\\xa77a\\xa77c\\xa77f" + "\\xa781\\xa783\\xa785\\xa787\\xa78c\\xa78e\\xa791\\xa793-\\xa795" + "\\xa797\\xa799\\xa79b\\xa79d\\xa79f\\xa7a1\\xa7a3\\xa7a5\\xa7a7" + "\\xa7a9\\xa7b5\\xa7b7\\xa7fa\\xab30-\\xab5a\\xab60-\\xab65" + "\\xab70-\\xabbf\\xfb00-\\xfb06\\xfb13-\\xfb17\\xff41-\\xff5a" + "\\x10428-\\x1044f\\x10cc0-\\x10cf2\\x118c0-\\x118df" + "\\x1d41a-\\x1d433\\x1d44e-\\x1d454\\x1d456-\\x1d467" + "\\x1d482-\\x1d49b\\x1d4b6-\\x1d4b9\\x1d4bb\\x1d4bd-\\x1d4c3" + "\\x1d4c5-\\x1d4cf\\x1d4ea-\\x1d503\\x1d51e-\\x1d537" + "\\x1d552-\\x1d56b\\x1d586-\\x1d59f\\x1d5ba-\\x1d5d3" + "\\x1d5ee-\\x1d607\\x1d622-\\x1d63b\\x1d656-\\x1d66f" + "\\x1d68a-\\x1d6a5\\x1d6c2-\\x1d6da\\x1d6dc-\\x1d6e1" + "\\x1d6fc-\\x1d714\\x1d716-\\x1d71b\\x1d736-\\x1d74e" + "\\x1d750-\\x1d755\\x1d770-\\x1d788\\x1d78a-\\x1d78f" + "\\x1d7aa-\\x1d7c2\\x1d7c4-\\x1d7c9\\x1d7cb]"; + } + + static const char *letter_modifier() + { + return "[\\x2b0-\\x2c1\\x2c6-\\x2d1\\x2e0-\\x2e4\\x2ec\\x2ee\\x374" + "\\x37a\\x559\\x640\\x6e5\\x6e6\\x7f4\\x7f5\\x7fa\\x81a\\x824\\x828" + "\\x971\\xe46\\xec6\\x10fc\\x17d7\\x1843\\x1aa7\\x1c78-\\x1c7d" + "\\x1d2c-\\x1d6a\\x1d78\\x1d9b-\\x1dbf\\x2071\\x207f\\x2090-\\x209c" + "\\x2c7c\\x2c7d\\x2d6f\\x2e2f\\x3005\\x3031-\\x3035\\x303b" + "\\x309d\\x309e\\x30fc-\\x30fe\\xa015\\xa4f8-\\xa4fd\\xa60c\\xa67f" + "\\xa69c\\xa69d\\xa717-\\xa71f\\xa770\\xa788\\xa7f8\\xa7f9\\xa9cf" + "\\xa9e6\\xaa70\\xaadd\\xaaf3\\xaaf4\\xab5c-\\xab5f\\xff70" + "\\xff9e\\xff9f\\x16b40-\\x16b43\\x16f93-\\x16f9f]"; + } + + static const char *letter_other() + { + return "[\\xaa\\xba\\x1bb\\x1c0-\\x1c3\\x294\\x5d0-\\x5ea\\x5f0-\\x5f2" + "\\x620-\\x63f\\x641-\\x64a\\x66e\\x66f\\x671-\\x6d3\\x6d5" + "\\x6ee\\x6ef\\x6fa-\\x6fc\\x6ff\\x710\\x712-\\x72f\\x74d-\\x7a5" + "\\x7b1\\x7ca-\\x7ea\\x800-\\x815\\x840-\\x858\\x8a0-\\x8b4" + "\\x904-\\x939\\x93d\\x950\\x958-\\x961\\x972-\\x980\\x985-\\x98c" + "\\x98f\\x990\\x993-\\x9a8\\x9aa-\\x9b0\\x9b2\\x9b6-\\x9b9\\x9bd" + "\\x9ce\\x9dc\\x9dd\\x9df-\\x9e1\\x9f0\\x9f1\\xa05-\\xa0a" + "\\xa0f\\xa10\\xa13-\\xa28\\xa2a-\\xa30\\xa32\\xa33\\xa35\\xa36" + "\\xa38\\xa39\\xa59-\\xa5c\\xa5e\\xa72-\\xa74\\xa85-\\xa8d" + "\\xa8f-\\xa91\\xa93-\\xaa8\\xaaa-\\xab0\\xab2\\xab3\\xab5-\\xab9" + "\\xabd\\xad0\\xae0\\xae1\\xaf9\\xb05-\\xb0c\\xb0f\\xb10" + "\\xb13-\\xb28\\xb2a-\\xb30\\xb32\\xb33\\xb35-\\xb39\\xb3d" + "\\xb5c\\xb5d\\xb5f-\\xb61\\xb71\\xb83\\xb85-\\xb8a\\xb8e-\\xb90" + "\\xb92-\\xb95\\xb99\\xb9a\\xb9c\\xb9e\\xb9f\\xba3\\xba4" + "\\xba8-\\xbaa\\xbae-\\xbb9\\xbd0\\xc05-\\xc0c\\xc0e-\\xc10" + "\\xc12-\\xc28\\xc2a-\\xc39\\xc3d\\xc58-\\xc5a\\xc60\\xc61" + "\\xc85-\\xc8c\\xc8e-\\xc90\\xc92-\\xca8\\xcaa-\\xcb3\\xcb5-\\xcb9" + "\\xcbd\\xcde\\xce0\\xce1\\xcf1\\xcf2\\xd05-\\xd0c\\xd0e-\\xd10" + "\\xd12-\\xd3a\\xd3d\\xd4e\\xd5f-\\xd61\\xd7a-\\xd7f\\xd85-\\xd96" + "\\xd9a-\\xdb1\\xdb3-\\xdbb\\xdbd\\xdc0-\\xdc6\\xe01-\\xe30" + "\\xe32\\xe33\\xe40-\\xe45\\xe81\\xe82\\xe84\\xe87\\xe88\\xe8a" + "\\xe8d\\xe94-\\xe97\\xe99-\\xe9f\\xea1-\\xea3\\xea5\\xea7" + "\\xeaa\\xeab\\xead-\\xeb0\\xeb2\\xeb3\\xebd\\xec0-\\xec4" + "\\xedc-\\xedf\\xf00\\xf40-\\xf47\\xf49-\\xf6c\\xf88-\\xf8c" + "\\x1000-\\x102a\\x103f\\x1050-\\x1055\\x105a-\\x105d\\x1061" + "\\x1065\\x1066\\x106e-\\x1070\\x1075-\\x1081\\x108e\\x10d0-\\x10fa" + "\\x10fd-\\x1248\\x124a-\\x124d\\x1250-\\x1256\\x1258" + "\\x125a-\\x125d\\x1260-\\x1288\\x128a-\\x128d\\x1290-\\x12b0" + "\\x12b2-\\x12b5\\x12b8-\\x12be\\x12c0\\x12c2-\\x12c5" + "\\x12c8-\\x12d6\\x12d8-\\x1310\\x1312-\\x1315\\x1318-\\x135a" + "\\x1380-\\x138f\\x1401-\\x166c\\x166f-\\x167f\\x1681-\\x169a" + "\\x16a0-\\x16ea\\x16f1-\\x16f8\\x1700-\\x170c\\x170e-\\x1711" + "\\x1720-\\x1731\\x1740-\\x1751\\x1760-\\x176c\\x176e-\\x1770" + "\\x1780-\\x17b3\\x17dc\\x1820-\\x1842\\x1844-\\x1877" + "\\x1880-\\x18a8\\x18aa\\x18b0-\\x18f5\\x1900-\\x191e" + "\\x1950-\\x196d\\x1970-\\x1974\\x1980-\\x19ab\\x19b0-\\x19c9" + "\\x1a00-\\x1a16\\x1a20-\\x1a54\\x1b05-\\x1b33\\x1b45-\\x1b4b" + "\\x1b83-\\x1ba0\\x1bae\\x1baf\\x1bba-\\x1be5\\x1c00-\\x1c23" + "\\x1c4d-\\x1c4f\\x1c5a-\\x1c77\\x1ce9-\\x1cec\\x1cee-\\x1cf1" + "\\x1cf5\\x1cf6\\x2135-\\x2138\\x2d30-\\x2d67\\x2d80-\\x2d96" + "\\x2da0-\\x2da6\\x2da8-\\x2dae\\x2db0-\\x2db6\\x2db8-\\x2dbe" + "\\x2dc0-\\x2dc6\\x2dc8-\\x2dce\\x2dd0-\\x2dd6\\x2dd8-\\x2dde" + "\\x3006\\x303c\\x3041-\\x3096\\x309f\\x30a1-\\x30fa\\x30ff" + "\\x3105-\\x312d\\x3131-\\x318e\\x31a0-\\x31ba\\x31f0-\\x31ff" + "\\x3400\\x4db5\\x4e00\\x9fd5\\xa000-\\xa014\\xa016-\\xa48c" + "\\xa4d0-\\xa4f7\\xa500-\\xa60b\\xa610-\\xa61f\\xa62a\\xa62b\\xa66e" + "\\xa6a0-\\xa6e5\\xa78f\\xa7f7\\xa7fb-\\xa801\\xa803-\\xa805" + "\\xa807-\\xa80a\\xa80c-\\xa822\\xa840-\\xa873\\xa882-\\xa8b3" + "\\xa8f2-\\xa8f7\\xa8fb\\xa8fd\\xa90a-\\xa925\\xa930-\\xa946" + "\\xa960-\\xa97c\\xa984-\\xa9b2\\xa9e0-\\xa9e4\\xa9e7-\\xa9ef" + "\\xa9fa-\\xa9fe\\xaa00-\\xaa28\\xaa40-\\xaa42\\xaa44-\\xaa4b" + "\\xaa60-\\xaa6f\\xaa71-\\xaa76\\xaa7a\\xaa7e-\\xaaaf\\xaab1" + "\\xaab5\\xaab6\\xaab9-\\xaabd\\xaac0\\xaac2\\xaadb\\xaadc" + "\\xaae0-\\xaaea\\xaaf2\\xab01-\\xab06\\xab09-\\xab0e" + "\\xab11-\\xab16\\xab20-\\xab26\\xab28-\\xab2e\\xabc0-\\xabe2" + "\\xac00\\xd7a3\\xd7b0-\\xd7c6\\xd7cb-\\xd7fb\\xf900-\\xfa6d" + "\\xfa70-\\xfad9\\xfb1d\\xfb1f-\\xfb28\\xfb2a-\\xfb36" + "\\xfb38-\\xfb3c\\xfb3e\\xfb40\\xfb41\\xfb43\\xfb44\\xfb46-\\xfbb1" + "\\xfbd3-\\xfd3d\\xfd50-\\xfd8f\\xfd92-\\xfdc7\\xfdf0-\\xfdfb" + "\\xfe70-\\xfe74\\xfe76-\\xfefc\\xff66-\\xff6f\\xff71-\\xff9d" + "\\xffa0-\\xffbe\\xffc2-\\xffc7\\xffca-\\xffcf\\xffd2-\\xffd7" + "\\xffda-\\xffdc\\x10000-\\x1000b\\x1000d-\\x10026\\x10028-\\x1003a" + "\\x1003c\\x1003d\\x1003f-\\x1004d\\x10050-\\x1005d" + "\\x10080-\\x100fa\\x10280-\\x1029c\\x102a0-\\x102d0" + "\\x10300-\\x1031f\\x10330-\\x10340\\x10342-\\x10349" + "\\x10350-\\x10375\\x10380-\\x1039d\\x103a0-\\x103c3" + "\\x103c8-\\x103cf\\x10450-\\x1049d\\x10500-\\x10527" + "\\x10530-\\x10563\\x10600-\\x10736\\x10740-\\x10755" + "\\x10760-\\x10767\\x10800-\\x10805\\x10808\\x1080a-\\x10835" + "\\x10837\\x10838\\x1083c\\x1083f-\\x10855\\x10860-\\x10876" + "\\x10880-\\x1089e\\x108e0-\\x108f2\\x108f4\\x108f5" + "\\x10900-\\x10915\\x10920-\\x10939\\x10980-\\x109b7" + "\\x109be\\x109bf\\x10a00\\x10a10-\\x10a13\\x10a15-\\x10a17" + "\\x10a19-\\x10a33\\x10a60-\\x10a7c\\x10a80-\\x10a9c" + "\\x10ac0-\\x10ac7\\x10ac9-\\x10ae4\\x10b00-\\x10b35" + "\\x10b40-\\x10b55\\x10b60-\\x10b72\\x10b80-\\x10b91" + "\\x10c00-\\x10c48\\x11003-\\x11037\\x11083-\\x110af" + "\\x110d0-\\x110e8\\x11103-\\x11126\\x11150-\\x11172\\x11176" + "\\x11183-\\x111b2\\x111c1-\\x111c4\\x111da\\x111dc" + "\\x11200-\\x11211\\x11213-\\x1122b\\x11280-\\x11286\\x11288" + "\\x1128a-\\x1128d\\x1128f-\\x1129d\\x1129f-\\x112a8" + "\\x112b0-\\x112de\\x11305-\\x1130c\\x1130f\\x11310" + "\\x11313-\\x11328\\x1132a-\\x11330\\x11332\\x11333" + "\\x11335-\\x11339\\x1133d\\x11350\\x1135d-\\x11361" + "\\x11480-\\x114af\\x114c4\\x114c5\\x114c7\\x11580-\\x115ae" + "\\x115d8-\\x115db\\x11600-\\x1162f\\x11644\\x11680-\\x116aa" + "\\x11700-\\x11719\\x118ff\\x11ac0-\\x11af8\\x12000-\\x12399" + "\\x12480-\\x12543\\x13000-\\x1342e\\x14400-\\x14646" + "\\x16800-\\x16a38\\x16a40-\\x16a5e\\x16ad0-\\x16aed" + "\\x16b00-\\x16b2f\\x16b63-\\x16b77\\x16b7d-\\x16b8f" + "\\x16f00-\\x16f44\\x16f50\\x1b000\\x1b001\\x1bc00-\\x1bc6a" + "\\x1bc70-\\x1bc7c\\x1bc80-\\x1bc88\\x1bc90-\\x1bc99" + "\\x1e800-\\x1e8c4\\x1ee00-\\x1ee03\\x1ee05-\\x1ee1f" + "\\x1ee21\\x1ee22\\x1ee24\\x1ee27\\x1ee29-\\x1ee32\\x1ee34-\\x1ee37" + "\\x1ee39\\x1ee3b\\x1ee42\\x1ee47\\x1ee49\\x1ee4b\\x1ee4d-\\x1ee4f" + "\\x1ee51\\x1ee52\\x1ee54\\x1ee57\\x1ee59\\x1ee5b\\x1ee5d\\x1ee5f" + "\\x1ee61\\x1ee62\\x1ee64\\x1ee67-\\x1ee6a\\x1ee6c-\\x1ee72" + "\\x1ee74-\\x1ee77\\x1ee79-\\x1ee7c\\x1ee7e\\x1ee80-\\x1ee89" + "\\x1ee8b-\\x1ee9b\\x1eea1-\\x1eea3\\x1eea5-\\x1eea9" + "\\x1eeab-\\x1eebb\\x20000\\x2a6d6\\x2a700\\x2b734\\x2b740\\x2b81d" + "\\x2b820\\x2cea1\\x2f800-\\x2fa1d]"; + } + + static const char *letter_titlecase() + { + return "[\\x1c5\\x1c8\\x1cb\\x1f2\\x1f88-\\x1f8f\\x1f98-\\x1f9f" + "\\x1fa8-\\x1faf\\x1fbc\\x1fcc\\x1ffc]"; + } + + static const char *letter_uppercase() + { + return "[\\x41-\\x5a\\xc0-\\xd6\\xd8-\\xde\\x100\\x102\\x104\\x106" + "\\x108\\x10a\\x10c\\x10e\\x110\\x112\\x114\\x116\\x118\\x11a\\x11c" + "\\x11e\\x120\\x122\\x124\\x126\\x128\\x12a\\x12c\\x12e\\x130\\x132" + "\\x134\\x136\\x139\\x13b\\x13d\\x13f\\x141\\x143\\x145\\x147\\x14a" + "\\x14c\\x14e\\x150\\x152\\x154\\x156\\x158\\x15a\\x15c\\x15e\\x160" + "\\x162\\x164\\x166\\x168\\x16a\\x16c\\x16e\\x170\\x172\\x174\\x176" + "\\x178\\x179\\x17b\\x17d\\x181\\x182\\x184\\x186\\x187" + "\\x189-\\x18b\\x18e-\\x191\\x193\\x194\\x196-\\x198\\x19c\\x19d" + "\\x19f\\x1a0\\x1a2\\x1a4\\x1a6\\x1a7\\x1a9\\x1ac\\x1ae\\x1af" + "\\x1b1-\\x1b3\\x1b5\\x1b7\\x1b8\\x1bc\\x1c4\\x1c7\\x1ca\\x1cd" + "\\x1cf\\x1d1\\x1d3\\x1d5\\x1d7\\x1d9\\x1db\\x1de\\x1e0\\x1e2\\x1e4" + "\\x1e6\\x1e8\\x1ea\\x1ec\\x1ee\\x1f1\\x1f4\\x1f6-\\x1f8\\x1fa" + "\\x1fc\\x1fe\\x200\\x202\\x204\\x206\\x208\\x20a\\x20c\\x20e\\x210" + "\\x212\\x214\\x216\\x218\\x21a\\x21c\\x21e\\x220\\x222\\x224\\x226" + "\\x228\\x22a\\x22c\\x22e\\x230\\x232\\x23a\\x23b\\x23d\\x23e\\x241" + "\\x243-\\x246\\x248\\x24a\\x24c\\x24e\\x370\\x372\\x376\\x37f" + "\\x386\\x388-\\x38a\\x38c\\x38e\\x38f\\x391-\\x3a1\\x3a3-\\x3ab" + "\\x3cf\\x3d2-\\x3d4\\x3d8\\x3da\\x3dc\\x3de\\x3e0\\x3e2\\x3e4" + "\\x3e6\\x3e8\\x3ea\\x3ec\\x3ee\\x3f4\\x3f7\\x3f9\\x3fa" + "\\x3fd-\\x42f\\x460\\x462\\x464\\x466\\x468\\x46a\\x46c\\x46e" + "\\x470\\x472\\x474\\x476\\x478\\x47a\\x47c\\x47e\\x480\\x48a\\x48c" + "\\x48e\\x490\\x492\\x494\\x496\\x498\\x49a\\x49c\\x49e\\x4a0\\x4a2" + "\\x4a4\\x4a6\\x4a8\\x4aa\\x4ac\\x4ae\\x4b0\\x4b2\\x4b4\\x4b6\\x4b8" + "\\x4ba\\x4bc\\x4be\\x4c0\\x4c1\\x4c3\\x4c5\\x4c7\\x4c9\\x4cb\\x4cd" + "\\x4d0\\x4d2\\x4d4\\x4d6\\x4d8\\x4da\\x4dc\\x4de\\x4e0\\x4e2\\x4e4" + "\\x4e6\\x4e8\\x4ea\\x4ec\\x4ee\\x4f0\\x4f2\\x4f4\\x4f6\\x4f8\\x4fa" + "\\x4fc\\x4fe\\x500\\x502\\x504\\x506\\x508\\x50a\\x50c\\x50e\\x510" + "\\x512\\x514\\x516\\x518\\x51a\\x51c\\x51e\\x520\\x522\\x524\\x526" + "\\x528\\x52a\\x52c\\x52e\\x531-\\x556\\x10a0-\\x10c5\\x10c7\\x10cd" + "\\x13a0-\\x13f5\\x1e00\\x1e02\\x1e04\\x1e06\\x1e08\\x1e0a\\x1e0c" + "\\x1e0e\\x1e10\\x1e12\\x1e14\\x1e16\\x1e18\\x1e1a\\x1e1c\\x1e1e" + "\\x1e20\\x1e22\\x1e24\\x1e26\\x1e28\\x1e2a\\x1e2c\\x1e2e\\x1e30" + "\\x1e32\\x1e34\\x1e36\\x1e38\\x1e3a\\x1e3c\\x1e3e\\x1e40\\x1e42" + "\\x1e44\\x1e46\\x1e48\\x1e4a\\x1e4c\\x1e4e\\x1e50\\x1e52\\x1e54" + "\\x1e56\\x1e58\\x1e5a\\x1e5c\\x1e5e\\x1e60\\x1e62\\x1e64\\x1e66" + "\\x1e68\\x1e6a\\x1e6c\\x1e6e\\x1e70\\x1e72\\x1e74\\x1e76\\x1e78" + "\\x1e7a\\x1e7c\\x1e7e\\x1e80\\x1e82\\x1e84\\x1e86\\x1e88\\x1e8a" + "\\x1e8c\\x1e8e\\x1e90\\x1e92\\x1e94\\x1e9e\\x1ea0\\x1ea2\\x1ea4" + "\\x1ea6\\x1ea8\\x1eaa\\x1eac\\x1eae\\x1eb0\\x1eb2\\x1eb4\\x1eb6" + "\\x1eb8\\x1eba\\x1ebc\\x1ebe\\x1ec0\\x1ec2\\x1ec4\\x1ec6\\x1ec8" + "\\x1eca\\x1ecc\\x1ece\\x1ed0\\x1ed2\\x1ed4\\x1ed6\\x1ed8\\x1eda" + "\\x1edc\\x1ede\\x1ee0\\x1ee2\\x1ee4\\x1ee6\\x1ee8\\x1eea\\x1eec" + "\\x1eee\\x1ef0\\x1ef2\\x1ef4\\x1ef6\\x1ef8\\x1efa\\x1efc\\x1efe" + "\\x1f08-\\x1f0f\\x1f18-\\x1f1d\\x1f28-\\x1f2f\\x1f38-\\x1f3f" + "\\x1f48-\\x1f4d\\x1f59\\x1f5b\\x1f5d\\x1f5f\\x1f68-\\x1f6f" + "\\x1fb8-\\x1fbb\\x1fc8-\\x1fcb\\x1fd8-\\x1fdb\\x1fe8-\\x1fec" + "\\x1ff8-\\x1ffb\\x2102\\x2107\\x210b-\\x210d\\x2110-\\x2112\\x2115" + "\\x2119-\\x211d\\x2124\\x2126\\x2128\\x212a-\\x212d\\x2130-\\x2133" + "\\x213e\\x213f\\x2145\\x2183\\x2c00-\\x2c2e\\x2c60\\x2c62-\\x2c64" + "\\x2c67\\x2c69\\x2c6b\\x2c6d-\\x2c70\\x2c72\\x2c75\\x2c7e-\\x2c80" + "\\x2c82\\x2c84\\x2c86\\x2c88\\x2c8a\\x2c8c\\x2c8e\\x2c90\\x2c92" + "\\x2c94\\x2c96\\x2c98\\x2c9a\\x2c9c\\x2c9e\\x2ca0\\x2ca2\\x2ca4" + "\\x2ca6\\x2ca8\\x2caa\\x2cac\\x2cae\\x2cb0\\x2cb2\\x2cb4\\x2cb6" + "\\x2cb8\\x2cba\\x2cbc\\x2cbe\\x2cc0\\x2cc2\\x2cc4\\x2cc6\\x2cc8" + "\\x2cca\\x2ccc\\x2cce\\x2cd0\\x2cd2\\x2cd4\\x2cd6\\x2cd8\\x2cda" + "\\x2cdc\\x2cde\\x2ce0\\x2ce2\\x2ceb\\x2ced\\x2cf2\\xa640\\xa642" + "\\xa644\\xa646\\xa648\\xa64a\\xa64c\\xa64e\\xa650\\xa652\\xa654" + "\\xa656\\xa658\\xa65a\\xa65c\\xa65e\\xa660\\xa662\\xa664\\xa666" + "\\xa668\\xa66a\\xa66c\\xa680\\xa682\\xa684\\xa686\\xa688\\xa68a" + "\\xa68c\\xa68e\\xa690\\xa692\\xa694\\xa696\\xa698\\xa69a\\xa722" + "\\xa724\\xa726\\xa728\\xa72a\\xa72c\\xa72e\\xa732\\xa734\\xa736" + "\\xa738\\xa73a\\xa73c\\xa73e\\xa740\\xa742\\xa744\\xa746\\xa748" + "\\xa74a\\xa74c\\xa74e\\xa750\\xa752\\xa754\\xa756\\xa758\\xa75a" + "\\xa75c\\xa75e\\xa760\\xa762\\xa764\\xa766\\xa768\\xa76a\\xa76c" + "\\xa76e\\xa779\\xa77b\\xa77d\\xa77e\\xa780\\xa782\\xa784\\xa786" + "\\xa78b\\xa78d\\xa790\\xa792\\xa796\\xa798\\xa79a\\xa79c\\xa79e" + "\\xa7a0\\xa7a2\\xa7a4\\xa7a6\\xa7a8\\xa7aa-\\xa7ad\\xa7b0-\\xa7b4" + "\\xa7b6\\xff21-\\xff3a\\x10400-\\x10427\\x10c80-\\x10cb2" + "\\x118a0-\\x118bf\\x1d400-\\x1d419\\x1d434-\\x1d44d" + "\\x1d468-\\x1d481\\x1d49c\\x1d49e\\x1d49f\\x1d4a2\\x1d4a5\\x1d4a6" + "\\x1d4a9-\\x1d4ac\\x1d4ae-\\x1d4b5\\x1d4d0-\\x1d4e9" + "\\x1d504\\x1d505\\x1d507-\\x1d50a\\x1d50d-\\x1d514" + "\\x1d516-\\x1d51c\\x1d538\\x1d539\\x1d53b-\\x1d53e" + "\\x1d540-\\x1d544\\x1d546\\x1d54a-\\x1d550\\x1d56c-\\x1d585" + "\\x1d5a0-\\x1d5b9\\x1d5d4-\\x1d5ed\\x1d608-\\x1d621" + "\\x1d63c-\\x1d655\\x1d670-\\x1d689\\x1d6a8-\\x1d6c0" + "\\x1d6e2-\\x1d6fa\\x1d71c-\\x1d734\\x1d756-\\x1d76e" + "\\x1d790-\\x1d7a8\\x1d7ca]"; + } + + static const char *mark_combining() + { + return "[\\x903\\x93b\\x93e-\\x940\\x949-\\x94c\\x94e\\x94f\\x982\\x983" + "\\x9be-\\x9c0\\x9c7\\x9c8\\x9cb\\x9cc\\x9d7\\xa03\\xa3e-\\xa40" + "\\xa83\\xabe-\\xac0\\xac9\\xacb\\xacc\\xb02\\xb03\\xb3e\\xb40" + "\\xb47\\xb48\\xb4b\\xb4c\\xb57\\xbbe\\xbbf\\xbc1\\xbc2" + "\\xbc6-\\xbc8\\xbca-\\xbcc\\xbd7\\xc01-\\xc03\\xc41-\\xc44" + "\\xc82\\xc83\\xcbe\\xcc0-\\xcc4\\xcc7\\xcc8\\xcca\\xccb" + "\\xcd5\\xcd6\\xd02\\xd03\\xd3e-\\xd40\\xd46-\\xd48\\xd4a-\\xd4c" + "\\xd57\\xd82\\xd83\\xdcf-\\xdd1\\xdd8-\\xddf\\xdf2\\xdf3" + "\\xf3e\\xf3f\\xf7f\\x102b\\x102c\\x1031\\x1038\\x103b\\x103c" + "\\x1056\\x1057\\x1062-\\x1064\\x1067-\\x106d\\x1083\\x1084" + "\\x1087-\\x108c\\x108f\\x109a-\\x109c\\x17b6\\x17be-\\x17c5" + "\\x17c7\\x17c8\\x1923-\\x1926\\x1929-\\x192b\\x1930\\x1931" + "\\x1933-\\x1938\\x1a19\\x1a1a\\x1a55\\x1a57\\x1a61\\x1a63\\x1a64" + "\\x1a6d-\\x1a72\\x1b04\\x1b35\\x1b3b\\x1b3d-\\x1b41\\x1b43\\x1b44" + "\\x1b82\\x1ba1\\x1ba6\\x1ba7\\x1baa\\x1be7\\x1bea-\\x1bec\\x1bee" + "\\x1bf2\\x1bf3\\x1c24-\\x1c2b\\x1c34\\x1c35\\x1ce1\\x1cf2\\x1cf3" + "\\x302e\\x302f\\xa823\\xa824\\xa827\\xa880\\xa881\\xa8b4-\\xa8c3" + "\\xa952\\xa953\\xa983\\xa9b4\\xa9b5\\xa9ba\\xa9bb\\xa9bd-\\xa9c0" + "\\xaa2f\\xaa30\\xaa33\\xaa34\\xaa4d\\xaa7b\\xaa7d\\xaaeb" + "\\xaaee\\xaaef\\xaaf5\\xabe3\\xabe4\\xabe6\\xabe7\\xabe9\\xabea" + "\\xabec\\x11000\\x11002\\x11082\\x110b0-\\x110b2\\x110b7\\x110b8" + "\\x1112c\\x11182\\x111b3-\\x111b5\\x111bf\\x111c0\\x1122c-\\x1122e" + "\\x11232\\x11233\\x11235\\x112e0-\\x112e2\\x11302\\x11303" + "\\x1133e\\x1133f\\x11341-\\x11344\\x11347\\x11348\\x1134b-\\x1134d" + "\\x11357\\x11362\\x11363\\x114b0-\\x114b2\\x114b9\\x114bb-\\x114be" + "\\x114c1\\x115af-\\x115b1\\x115b8-\\x115bb\\x115be" + "\\x11630-\\x11632\\x1163b\\x1163c\\x1163e\\x116ac\\x116ae\\x116af" + "\\x116b6\\x11720\\x11721\\x11726\\x16f51-\\x16f7e\\x1d165\\x1d166" + "\\x1d16d-\\x1d172]"; + } + + static const char *mark_enclosing() + { + return "[\\x488\\x489\\x1abe\\x20dd-\\x20e0\\x20e2-\\x20e4" + "\\xa670-\\xa672]"; + } + + static const char *mark_nonspacing() + { + return "[\\x300-\\x36f\\x483-\\x487\\x591-\\x5bd\\x5bf\\x5c1\\x5c2" + "\\x5c4\\x5c5\\x5c7\\x610-\\x61a\\x64b-\\x65f\\x670\\x6d6-\\x6dc" + "\\x6df-\\x6e4\\x6e7\\x6e8\\x6ea-\\x6ed\\x711\\x730-\\x74a" + "\\x7a6-\\x7b0\\x7eb-\\x7f3\\x816-\\x819\\x81b-\\x823\\x825-\\x827" + "\\x829-\\x82d\\x859-\\x85b\\x8e3-\\x902\\x93a\\x93c\\x941-\\x948" + "\\x94d\\x951-\\x957\\x962\\x963\\x981\\x9bc\\x9c1-\\x9c4\\x9cd" + "\\x9e2\\x9e3\\xa01\\xa02\\xa3c\\xa41\\xa42\\xa47\\xa48" + "\\xa4b-\\xa4d\\xa51\\xa70\\xa71\\xa75\\xa81\\xa82\\xabc" + "\\xac1-\\xac5\\xac7\\xac8\\xacd\\xae2\\xae3\\xb01\\xb3c\\xb3f" + "\\xb41-\\xb44\\xb4d\\xb56\\xb62\\xb63\\xb82\\xbc0\\xbcd\\xc00" + "\\xc3e-\\xc40\\xc46-\\xc48\\xc4a-\\xc4d\\xc55\\xc56\\xc62\\xc63" + "\\xc81\\xcbc\\xcbf\\xcc6\\xccc\\xccd\\xce2\\xce3\\xd01" + "\\xd41-\\xd44\\xd4d\\xd62\\xd63\\xdca\\xdd2-\\xdd4\\xdd6\\xe31" + "\\xe34-\\xe3a\\xe47-\\xe4e\\xeb1\\xeb4-\\xeb9\\xebb\\xebc" + "\\xec8-\\xecd\\xf18\\xf19\\xf35\\xf37\\xf39\\xf71-\\xf7e" + "\\xf80-\\xf84\\xf86\\xf87\\xf8d-\\xf97\\xf99-\\xfbc\\xfc6" + "\\x102d-\\x1030\\x1032-\\x1037\\x1039\\x103a\\x103d\\x103e" + "\\x1058\\x1059\\x105e-\\x1060\\x1071-\\x1074\\x1082\\x1085\\x1086" + "\\x108d\\x109d\\x135d-\\x135f\\x1712-\\x1714\\x1732-\\x1734" + "\\x1752\\x1753\\x1772\\x1773\\x17b4\\x17b5\\x17b7-\\x17bd\\x17c6" + "\\x17c9-\\x17d3\\x17dd\\x180b-\\x180d\\x18a9\\x1920-\\x1922" + "\\x1927\\x1928\\x1932\\x1939-\\x193b\\x1a17\\x1a18\\x1a1b\\x1a56" + "\\x1a58-\\x1a5e\\x1a60\\x1a62\\x1a65-\\x1a6c\\x1a73-\\x1a7c\\x1a7f" + "\\x1ab0-\\x1abd\\x1b00-\\x1b03\\x1b34\\x1b36-\\x1b3a\\x1b3c\\x1b42" + "\\x1b6b-\\x1b73\\x1b80\\x1b81\\x1ba2-\\x1ba5\\x1ba8\\x1ba9" + "\\x1bab-\\x1bad\\x1be6\\x1be8\\x1be9\\x1bed\\x1bef-\\x1bf1" + "\\x1c2c-\\x1c33\\x1c36\\x1c37\\x1cd0-\\x1cd2\\x1cd4-\\x1ce0" + "\\x1ce2-\\x1ce8\\x1ced\\x1cf4\\x1cf8\\x1cf9\\x1dc0-\\x1df5" + "\\x1dfc-\\x1dff\\x20d0-\\x20dc\\x20e1\\x20e5-\\x20f0" + "\\x2cef-\\x2cf1\\x2d7f\\x2de0-\\x2dff\\x302a-\\x302d\\x3099\\x309a" + "\\xa66f\\xa674-\\xa67d\\xa69e\\xa69f\\xa6f0\\xa6f1\\xa802\\xa806" + "\\xa80b\\xa825\\xa826\\xa8c4\\xa8e0-\\xa8f1\\xa926-\\xa92d" + "\\xa947-\\xa951\\xa980-\\xa982\\xa9b3\\xa9b6-\\xa9b9\\xa9bc\\xa9e5" + "\\xaa29-\\xaa2e\\xaa31\\xaa32\\xaa35\\xaa36\\xaa43\\xaa4c\\xaa7c" + "\\xaab0\\xaab2-\\xaab4\\xaab7\\xaab8\\xaabe\\xaabf\\xaac1" + "\\xaaec\\xaaed\\xaaf6\\xabe5\\xabe8\\xabed\\xfb1e\\xfe00-\\xfe0f" + "\\xfe20-\\xfe2f\\x101fd\\x102e0\\x10376-\\x1037a\\x10a01-\\x10a03" + "\\x10a05\\x10a06\\x10a0c-\\x10a0f\\x10a38-\\x10a3a\\x10a3f" + "\\x10ae5\\x10ae6\\x11001\\x11038-\\x11046\\x1107f-\\x11081" + "\\x110b3-\\x110b6\\x110b9\\x110ba\\x11100-\\x11102" + "\\x11127-\\x1112b\\x1112d-\\x11134\\x11173\\x11180\\x11181" + "\\x111b6-\\x111be\\x111ca-\\x111cc\\x1122f-\\x11231\\x11234" + "\\x11236\\x11237\\x112df\\x112e3-\\x112ea\\x11300\\x11301\\x1133c" + "\\x11340\\x11366-\\x1136c\\x11370-\\x11374\\x114b3-\\x114b8" + "\\x114ba\\x114bf\\x114c0\\x114c2\\x114c3\\x115b2-\\x115b5" + "\\x115bc\\x115bd\\x115bf\\x115c0\\x115dc\\x115dd\\x11633-\\x1163a" + "\\x1163d\\x1163f\\x11640\\x116ab\\x116ad\\x116b0-\\x116b5\\x116b7" + "\\x1171d-\\x1171f\\x11722-\\x11725\\x11727-\\x1172b" + "\\x16af0-\\x16af4\\x16b30-\\x16b36\\x16f8f-\\x16f92" + "\\x1bc9d\\x1bc9e\\x1d167-\\x1d169\\x1d17b-\\x1d182" + "\\x1d185-\\x1d18b\\x1d1aa-\\x1d1ad\\x1d242-\\x1d244" + "\\x1da00-\\x1da36\\x1da3b-\\x1da6c\\x1da75\\x1da84" + "\\x1da9b-\\x1da9f\\x1daa1-\\x1daaf\\x1e8d0-\\x1e8d6" + "\\xe0100-\\xe01ef]"; + } + + static const char *number_decimal() + { + return "[\\x30-\\x39\\x660-\\x669\\x6f0-\\x6f9\\x7c0-\\x7c9" + "\\x966-\\x96f\\x9e6-\\x9ef\\xa66-\\xa6f\\xae6-\\xaef\\xb66-\\xb6f" + "\\xbe6-\\xbef\\xc66-\\xc6f\\xce6-\\xcef\\xd66-\\xd6f\\xde6-\\xdef" + "\\xe50-\\xe59\\xed0-\\xed9\\xf20-\\xf29\\x1040-\\x1049" + "\\x1090-\\x1099\\x17e0-\\x17e9\\x1810-\\x1819\\x1946-\\x194f" + "\\x19d0-\\x19d9\\x1a80-\\x1a89\\x1a90-\\x1a99\\x1b50-\\x1b59" + "\\x1bb0-\\x1bb9\\x1c40-\\x1c49\\x1c50-\\x1c59\\xa620-\\xa629" + "\\xa8d0-\\xa8d9\\xa900-\\xa909\\xa9d0-\\xa9d9\\xa9f0-\\xa9f9" + "\\xaa50-\\xaa59\\xabf0-\\xabf9\\xff10-\\xff19\\x104a0-\\x104a9" + "\\x11066-\\x1106f\\x110f0-\\x110f9\\x11136-\\x1113f" + "\\x111d0-\\x111d9\\x112f0-\\x112f9\\x114d0-\\x114d9" + "\\x11650-\\x11659\\x116c0-\\x116c9\\x11730-\\x11739" + "\\x118e0-\\x118e9\\x16a60-\\x16a69\\x16b50-\\x16b59" + "\\x1d7ce-\\x1d7ff]"; + } + + static const char *number_letter() + { + return "[\\x16ee-\\x16f0\\x2160-\\x2182\\x2185-\\x2188\\x3007" + "\\x3021-\\x3029\\x3038-\\x303a\\xa6e6-\\xa6ef\\x10140-\\x10174" + "\\x10341\\x1034a\\x103d1-\\x103d5\\x12400-\\x1246e]"; + } + + static const char *number_other() + { + return "[\\xb2\\xb3\\xb9\\xbc-\\xbe\\x9f4-\\x9f9\\xb72-\\xb77" + "\\xbf0-\\xbf2\\xc78-\\xc7e\\xd70-\\xd75\\xf2a-\\xf33" + "\\x1369-\\x137c\\x17f0-\\x17f9\\x19da\\x2070\\x2074-\\x2079" + "\\x2080-\\x2089\\x2150-\\x215f\\x2189\\x2460-\\x249b" + "\\x24ea-\\x24ff\\x2776-\\x2793\\x2cfd\\x3192-\\x3195" + "\\x3220-\\x3229\\x3248-\\x324f\\x3251-\\x325f\\x3280-\\x3289" + "\\x32b1-\\x32bf\\xa830-\\xa835\\x10107-\\x10133\\x10175-\\x10178" + "\\x1018a\\x1018b\\x102e1-\\x102fb\\x10320-\\x10323" + "\\x10858-\\x1085f\\x10879-\\x1087f\\x108a7-\\x108af" + "\\x108fb-\\x108ff\\x10916-\\x1091b\\x109bc\\x109bd" + "\\x109c0-\\x109cf\\x109d2-\\x109ff\\x10a40-\\x10a47" + "\\x10a7d\\x10a7e\\x10a9d-\\x10a9f\\x10aeb-\\x10aef" + "\\x10b58-\\x10b5f\\x10b78-\\x10b7f\\x10ba9-\\x10baf" + "\\x10cfa-\\x10cff\\x10e60-\\x10e7e\\x11052-\\x11065" + "\\x111e1-\\x111f4\\x1173a\\x1173b\\x118ea-\\x118f2" + "\\x16b5b-\\x16b61\\x1d360-\\x1d371\\x1e8c7-\\x1e8cf" + "\\x1f100-\\x1f10c]"; + } + + static const char *punctuation_connector() + { + return "[\\x5f\\x203f\\x2040\\x2054\\xfe33\\xfe34\\xfe4d-\\xfe4f" + "\\xff3f]"; + } + + static const char *punctuation_dash() + { + return "[\\x2d\\x58a\\x5be\\x1400\\x1806\\x2010-\\x2015\\x2e17\\x2e1a" + "\\x2e3a\\x2e3b\\x2e40\\x301c\\x3030\\x30a0\\xfe31\\xfe32\\xfe58" + "\\xfe63\\xff0d]"; + } + + static const char *punctuation_close() + { + return "[\\x29\\x5d\\x7d\\xf3b\\xf3d\\x169c\\x2046\\x207e\\x208e\\x2309" + "\\x230b\\x232a\\x2769\\x276b\\x276d\\x276f\\x2771\\x2773\\x2775" + "\\x27c6\\x27e7\\x27e9\\x27eb\\x27ed\\x27ef\\x2984\\x2986\\x2988" + "\\x298a\\x298c\\x298e\\x2990\\x2992\\x2994\\x2996\\x2998\\x29d9" + "\\x29db\\x29fd\\x2e23\\x2e25\\x2e27\\x2e29\\x3009\\x300b\\x300d" + "\\x300f\\x3011\\x3015\\x3017\\x3019\\x301b\\x301e\\x301f\\xfd3e" + "\\xfe18\\xfe36\\xfe38\\xfe3a\\xfe3c\\xfe3e\\xfe40\\xfe42\\xfe44" + "\\xfe48\\xfe5a\\xfe5c\\xfe5e\\xff09\\xff3d\\xff5d\\xff60\\xff63]"; + } + + static const char *punctuation_final() + { + return "[\\xbb\\x2019\\x201d\\x203a\\x2e03\\x2e05\\x2e0a\\x2e0d\\x2e1d" + "\\x2e21]"; + } + + static const char *punctuation_initial() + { + return "[\\xab\\x2018\\x201b\\x201c\\x201f\\x2039\\x2e02\\x2e04\\x2e09" + "\\x2e0c\\x2e1c\\x2e20]"; + } + + static const char *punctuation_other() + { + return "[\\x21-\\x23\\x25-\\x27\\x2a\\x2c\\x2e\\x2f\\x3a\\x3b\\x3f\\x40" + "\\x5c\\xa1\\xa7\\xb6\\xb7\\xbf\\x37e\\x387\\x55a-\\x55f\\x589" + "\\x5c0\\x5c3\\x5c6\\x5f3\\x5f4\\x609\\x60a\\x60c\\x60d\\x61b" + "\\x61e\\x61f\\x66a-\\x66d\\x6d4\\x700-\\x70d\\x7f7-\\x7f9" + "\\x830-\\x83e\\x85e\\x964\\x965\\x970\\xaf0\\xdf4\\xe4f" + "\\xe5a\\xe5b\\xf04-\\xf12\\xf14\\xf85\\xfd0-\\xfd4\\xfd9\\xfda" + "\\x104a-\\x104f\\x10fb\\x1360-\\x1368\\x166d\\x166e\\x16eb-\\x16ed" + "\\x1735\\x1736\\x17d4-\\x17d6\\x17d8-\\x17da\\x1800-\\x1805" + "\\x1807-\\x180a\\x1944\\x1945\\x1a1e\\x1a1f\\x1aa0-\\x1aa6" + "\\x1aa8-\\x1aad\\x1b5a-\\x1b60\\x1bfc-\\x1bff\\x1c3b-\\x1c3f" + "\\x1c7e\\x1c7f\\x1cc0-\\x1cc7\\x1cd3\\x2016\\x2017\\x2020-\\x2027" + "\\x2030-\\x2038\\x203b-\\x203e\\x2041-\\x2043\\x2047-\\x2051" + "\\x2053\\x2055-\\x205e\\x2cf9-\\x2cfc\\x2cfe\\x2cff\\x2d70" + "\\x2e00\\x2e01\\x2e06-\\x2e08\\x2e0b\\x2e0e-\\x2e16\\x2e18\\x2e19" + "\\x2e1b\\x2e1e\\x2e1f\\x2e2a-\\x2e2e\\x2e30-\\x2e39\\x2e3c-\\x2e3f" + "\\x2e41\\x3001-\\x3003\\x303d\\x30fb\\xa4fe\\xa4ff\\xa60d-\\xa60f" + "\\xa673\\xa67e\\xa6f2-\\xa6f7\\xa874-\\xa877\\xa8ce\\xa8cf" + "\\xa8f8-\\xa8fa\\xa8fc\\xa92e\\xa92f\\xa95f\\xa9c1-\\xa9cd" + "\\xa9de\\xa9df\\xaa5c-\\xaa5f\\xaade\\xaadf\\xaaf0\\xaaf1\\xabeb" + "\\xfe10-\\xfe16\\xfe19\\xfe30\\xfe45\\xfe46\\xfe49-\\xfe4c" + "\\xfe50-\\xfe52\\xfe54-\\xfe57\\xfe5f-\\xfe61\\xfe68\\xfe6a\\xfe6b" + "\\xff01-\\xff03\\xff05-\\xff07\\xff0a\\xff0c\\xff0e\\xff0f" + "\\xff1a\\xff1b\\xff1f\\xff20\\xff3c\\xff61\\xff64\\xff65" + "\\x10100-\\x10102\\x1039f\\x103d0\\x1056f\\x10857\\x1091f\\x1093f" + "\\x10a50-\\x10a58\\x10a7f\\x10af0-\\x10af6\\x10b39-\\x10b3f" + "\\x10b99-\\x10b9c\\x11047-\\x1104d\\x110bb\\x110bc" + "\\x110be-\\x110c1\\x11140-\\x11143\\x11174\\x11175" + "\\x111c5-\\x111c9\\x111cd\\x111db\\x111dd-\\x111df" + "\\x11238-\\x1123d\\x112a9\\x114c6\\x115c1-\\x115d7" + "\\x11641-\\x11643\\x1173c-\\x1173e\\x12470-\\x12474" + "\\x16a6e\\x16a6f\\x16af5\\x16b37-\\x16b3b\\x16b44\\x1bc9f" + "\\x1da87-\\x1da8b]"; + } + + static const char *punctuation_open() + { + return "[\\x28\\x5b\\x7b\\xf3a\\xf3c\\x169b\\x201a\\x201e\\x2045\\x207d" + "\\x208d\\x2308\\x230a\\x2329\\x2768\\x276a\\x276c\\x276e\\x2770" + "\\x2772\\x2774\\x27c5\\x27e6\\x27e8\\x27ea\\x27ec\\x27ee\\x2983" + "\\x2985\\x2987\\x2989\\x298b\\x298d\\x298f\\x2991\\x2993\\x2995" + "\\x2997\\x29d8\\x29da\\x29fc\\x2e22\\x2e24\\x2e26\\x2e28\\x2e42" + "\\x3008\\x300a\\x300c\\x300e\\x3010\\x3014\\x3016\\x3018\\x301a" + "\\x301d\\xfd3f\\xfe17\\xfe35\\xfe37\\xfe39\\xfe3b\\xfe3d\\xfe3f" + "\\xfe41\\xfe43\\xfe47\\xfe59\\xfe5b\\xfe5d\\xff08\\xff3b\\xff5b" + "\\xff5f\\xff62]"; + } + + static const char *symbol_currency() + { + return "[\\x24\\xa2-\\xa5\\x58f\\x60b\\x9f2\\x9f3\\x9fb\\xaf1\\xbf9" + "\\xe3f\\x17db\\x20a0-\\x20be\\xa838\\xfdfc\\xfe69\\xff04" + "\\xffe0\\xffe1\\xffe5\\xffe6]"; + } + + static const char *symbol_modifier() + { + return "[\\x5e\\x60\\xa8\\xaf\\xb4\\xb8\\x2c2-\\x2c5\\x2d2-\\x2df" + "\\x2e5-\\x2eb\\x2ed\\x2ef-\\x2ff\\x375\\x384\\x385\\x1fbd" + "\\x1fbf-\\x1fc1\\x1fcd-\\x1fcf\\x1fdd-\\x1fdf\\x1fed-\\x1fef" + "\\x1ffd\\x1ffe\\x309b\\x309c\\xa700-\\xa716\\xa720\\xa721" + "\\xa789\\xa78a\\xab5b\\xfbb2-\\xfbc1\\xff3e\\xff40\\xffe3" + "\\x1f3fb-\\x1f3ff]"; + } + + static const char *symbol_math() + { + return "[\\x2b\\x3c-\\x3e\\x7c\\x7e\\xac\\xb1\\xd7\\xf7\\x3f6" + "\\x606-\\x608\\x2044\\x2052\\x207a-\\x207c\\x208a-\\x208c\\x2118" + "\\x2140-\\x2144\\x214b\\x2190-\\x2194\\x219a\\x219b\\x21a0\\x21a3" + "\\x21a6\\x21ae\\x21ce\\x21cf\\x21d2\\x21d4\\x21f4-\\x22ff" + "\\x2320\\x2321\\x237c\\x239b-\\x23b3\\x23dc-\\x23e1\\x25b7\\x25c1" + "\\x25f8-\\x25ff\\x266f\\x27c0-\\x27c4\\x27c7-\\x27e5" + "\\x27f0-\\x27ff\\x2900-\\x2982\\x2999-\\x29d7\\x29dc-\\x29fb" + "\\x29fe-\\x2aff\\x2b30-\\x2b44\\x2b47-\\x2b4c\\xfb29\\xfe62" + "\\xfe64-\\xfe66\\xff0b\\xff1c-\\xff1e\\xff5c\\xff5e\\xffe2" + "\\xffe9-\\xffec\\x1d6c1\\x1d6db\\x1d6fb\\x1d715\\x1d735\\x1d74f" + "\\x1d76f\\x1d789\\x1d7a9\\x1d7c3\\x1eef0\\x1eef1]"; + } + + static const char *symbol_other() + { + return "[\\xa6\\xa9\\xae\\xb0\\x482\\x58d\\x58e\\x60e\\x60f\\x6de\\x6e9" + "\\x6fd\\x6fe\\x7f6\\x9fa\\xb70\\xbf3-\\xbf8\\xbfa\\xc7f\\xd79" + "\\xf01-\\xf03\\xf13\\xf15-\\xf17\\xf1a-\\xf1f\\xf34\\xf36\\xf38" + "\\xfbe-\\xfc5\\xfc7-\\xfcc\\xfce\\xfcf\\xfd5-\\xfd8\\x109e\\x109f" + "\\x1390-\\x1399\\x1940\\x19de-\\x19ff\\x1b61-\\x1b6a" + "\\x1b74-\\x1b7c\\x2100\\x2101\\x2103-\\x2106\\x2108\\x2109\\x2114" + "\\x2116\\x2117\\x211e-\\x2123\\x2125\\x2127\\x2129\\x212e" + "\\x213a\\x213b\\x214a\\x214c\\x214d\\x214f\\x218a\\x218b" + "\\x2195-\\x2199\\x219c-\\x219f\\x21a1\\x21a2\\x21a4\\x21a5" + "\\x21a7-\\x21ad\\x21af-\\x21cd\\x21d0\\x21d1\\x21d3\\x21d5-\\x21f3" + "\\x2300-\\x2307\\x230c-\\x231f\\x2322-\\x2328\\x232b-\\x237b" + "\\x237d-\\x239a\\x23b4-\\x23db\\x23e2-\\x23fa\\x2400-\\x2426" + "\\x2440-\\x244a\\x249c-\\x24e9\\x2500-\\x25b6\\x25b8-\\x25c0" + "\\x25c2-\\x25f7\\x2600-\\x266e\\x2670-\\x2767\\x2794-\\x27bf" + "\\x2800-\\x28ff\\x2b00-\\x2b2f\\x2b45\\x2b46\\x2b4d-\\x2b73" + "\\x2b76-\\x2b95\\x2b98-\\x2bb9\\x2bbd-\\x2bc8\\x2bca-\\x2bd1" + "\\x2bec-\\x2bef\\x2ce5-\\x2cea\\x2e80-\\x2e99\\x2e9b-\\x2ef3" + "\\x2f00-\\x2fd5\\x2ff0-\\x2ffb\\x3004\\x3012\\x3013\\x3020" + "\\x3036\\x3037\\x303e\\x303f\\x3190\\x3191\\x3196-\\x319f" + "\\x31c0-\\x31e3\\x3200-\\x321e\\x322a-\\x3247\\x3250" + "\\x3260-\\x327f\\x328a-\\x32b0\\x32c0-\\x32fe\\x3300-\\x33ff" + "\\x4dc0-\\x4dff\\xa490-\\xa4c6\\xa828-\\xa82b\\xa836\\xa837\\xa839" + "\\xaa77-\\xaa79\\xfdfd\\xffe4\\xffe8\\xffed\\xffee\\xfffc\\xfffd" + "\\x10137-\\x1013f\\x10179-\\x10189\\x1018c\\x10190-\\x1019b" + "\\x101a0\\x101d0-\\x101fc\\x10877\\x10878\\x10ac8\\x1173f" + "\\x16b3c-\\x16b3f\\x16b45\\x1bc9c\\x1d000-\\x1d0f5" + "\\x1d100-\\x1d126\\x1d129-\\x1d164\\x1d16a-\\x1d16c" + "\\x1d183\\x1d184\\x1d18c-\\x1d1a9\\x1d1ae-\\x1d1e8" + "\\x1d200-\\x1d241\\x1d245\\x1d300-\\x1d356\\x1d800-\\x1d9ff" + "\\x1da37-\\x1da3a\\x1da6d-\\x1da74\\x1da76-\\x1da83" + "\\x1da85\\x1da86\\x1f000-\\x1f02b\\x1f030-\\x1f093" + "\\x1f0a0-\\x1f0ae\\x1f0b1-\\x1f0bf\\x1f0c1-\\x1f0cf" + "\\x1f0d1-\\x1f0f5\\x1f110-\\x1f12e\\x1f130-\\x1f16b" + "\\x1f170-\\x1f19a\\x1f1e6-\\x1f202\\x1f210-\\x1f23a" + "\\x1f240-\\x1f248\\x1f250\\x1f251\\x1f300-\\x1f3fa" + "\\x1f400-\\x1f579\\x1f57b-\\x1f5a3\\x1f5a5-\\x1f6d0" + "\\x1f6e0-\\x1f6ec\\x1f6f0-\\x1f6f3\\x1f700-\\x1f773" + "\\x1f780-\\x1f7d4\\x1f800-\\x1f80b\\x1f810-\\x1f847" + "\\x1f850-\\x1f859\\x1f860-\\x1f887\\x1f890-\\x1f8ad" + "\\x1f910-\\x1f918\\x1f980-\\x1f984\\x1f9c0]"; + } + + static const char *separator_line() + { + return "[\\x2028]"; + } + + static const char *separator_paragraph() + { + return "[\\x2029]"; + } + + static const char *separator_space() + { + return "[\\x20\\xa0\\x1680\\x2000-\\x200a\\x202f\\x205f\\x3000]"; + } + + template + static input_char_type decode_octal(state_type &state_) + { + std::size_t oct_ = 0; + auto ch_ = *state_._curr; + unsigned short count_ = 3; + bool eos_ = false; + + for (;;) + { + oct_ *= 8; + oct_ += ch_ - '0'; + --count_; + state_.increment(); + eos_ = state_.eos(); + + if (!count_ || eos_) break; + + ch_ = *state_._curr; + + // Don't consume invalid chars! + if (ch_ < '0' || ch_ > '7') + { + break; + } + } + + if (oct_ > static_cast(char_traits::max_val())) + { + std::ostringstream ss_; + + ss_ << "Escape \\" << std::oct << oct_ << + " is too big for the state machine char type " + "preceding index " << std::dec << state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + return static_cast(oct_); + } + + template + static input_char_type decode_control_char(state_type &state_) + { + // Skip over 'c' + state_.increment(); + + typename state_type::char_type ch_ = 0; + bool eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\c"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + else + { + if (ch_ >= 'a' && ch_ <= 'z') + { + ch_ -= 'a' - 1; + } + else if (ch_ >= 'A' && ch_ <= 'Z') + { + ch_ -= 'A' - 1; + } + else if (ch_ == '@') + { + // Apparently... + ch_ = 0; + } + else + { + std::ostringstream ss_; + + ss_ << "Invalid control char at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + return ch_; + } + + template + static input_char_type decode_hex(state_type &state_) + { + // Skip over 'x' + state_.increment(); + + typename state_type::char_type ch_ = 0; + bool eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\x"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (!((ch_ >= '0' && ch_ <= '9') || (ch_ >= 'a' && ch_ <= 'f') || + (ch_ >= 'A' && ch_ <= 'F'))) + { + std::ostringstream ss_; + + ss_ << "Illegal char following \\x at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + std::size_t hex_ = 0; + + do + { + hex_ *= 16; + + if (ch_ >= '0' && ch_ <= '9') + { + hex_ += ch_ - '0'; + } + else if (ch_ >= 'a' && ch_ <= 'f') + { + hex_ += 10 + (ch_ - 'a'); + } + else + { + hex_ += 10 + (ch_ - 'A'); + } + + eos_ = state_.eos(); + + if (!eos_) + { + ch_ = *state_._curr; + + // Don't consume invalid chars! + if (((ch_ >= '0' && ch_ <= '9') || + (ch_ >= 'a' && ch_ <= 'f') || (ch_ >= 'A' && ch_ <= 'F'))) + { + state_.increment(); + } + else + { + eos_ = true; + } + } + } while (!eos_); + + if (hex_ > static_cast(char_traits::max_val())) + { + std::ostringstream ss_; + + ss_ << "Escape \\x" << std::hex << hex_ << + " is too big for the state machine char type " << + "preceding index " << + std::dec << state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + return static_cast(hex_); + } + + template + static void charset_range(const bool chset_, state_type &state_, + bool &eos_, typename state_type::char_type &ch_, + const input_char_type prev_, string_token &chars_) + { + if (chset_) + { + std::ostringstream ss_; + + ss_ << "Charset cannot form start of range preceding " + "index " << state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following '-'"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + input_char_type curr_ = 0; + + if (ch_ == '\\') + { + std::size_t str_len_ = 0; + + if (escape_sequence(state_, curr_, str_len_)) + { + std::ostringstream ss_; + + ss_ << "Charset cannot form end of range preceding index " + << state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + else if (ch_ == '[' && !state_.eos() && *state_._curr == ':') + { + std::ostringstream ss_; + + ss_ << "POSIX char class cannot form end of range at " + "index " << state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + else + { + curr_ = ch_; + } + + eos_ = state_.next(ch_); + + // Covers preceding if and else + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing ']')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + // Use index_type as char is generally signed + // and we want to ignore signedness. + auto start_ = static_cast(prev_); + auto end_ = static_cast(curr_); + + // Semanic check + if (end_ < start_) + { + std::ostringstream ss_; + + ss_ << "Max less than Min in charset range preceding index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + // Even though ranges are used now, we still need to consider + // each character if icase is set. + if (state_._flags & icase) + { + range range_(start_, end_); + string_token folded_; + + chars_.insert(range_); + fold(range_, state_._locale, folded_, + size()); + + if (!folded_.empty()) + { + chars_.insert(folded_); + } + } + else + { + chars_.insert(range(prev_, curr_)); + } + } +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_state.hpp b/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_state.hpp new file mode 100644 index 000000000..1d41ea5ca --- /dev/null +++ b/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_state.hpp @@ -0,0 +1,136 @@ +// tokeniser_state.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_RE_TOKENISER_STATE_HPP +#define LEXERTL_RE_TOKENISER_STATE_HPP + +#include "../../char_traits.hpp" +#include "../../enums.hpp" +#include +#include "../../narrow.hpp" +#include + +namespace lexertl +{ +namespace detail +{ +template +struct basic_re_tokeniser_state +{ + using char_type = ch_type; + using index_type = typename basic_char_traits::index_type; + + const char_type * const _start; + const char_type * const _end; + const char_type *_curr; + id_type _id; + std::size_t _flags; + std::stack _flags_stack; + std::locale _locale; + const char_type *_macro_name; + long _paren_count; + bool _in_string; + id_type _nl_id; + + basic_re_tokeniser_state(const char_type *start_, + const char_type * const end_, id_type id_, const std::size_t flags_, + const std::locale locale_, const char_type *macro_name_) : + _start(start_), + _end(end_), + _curr(start_), + _id(id_), + _flags(flags_), + _flags_stack(), + _locale(locale_), + _macro_name(macro_name_), + _paren_count(0), + _in_string(false), + _nl_id(static_cast(~0)) + { + } + + basic_re_tokeniser_state(const basic_re_tokeniser_state &rhs_) + { + assign(rhs_); + } + + // prevent VC++ 7.1 warning: + const basic_re_tokeniser_state &operator = + (const basic_re_tokeniser_state &rhs_) + { + return assign(rhs_); + } + + basic_re_tokeniser_state &assign(const basic_re_tokeniser_state &rhs_) + { + _start = rhs_._start; + _end = rhs_._end; + _curr = rhs_._curr; + _id = rhs_._id; + _flags = rhs_._flags; + _flags_stack = rhs_._flags_stack; + _locale = rhs_._locale; + _macro_name = rhs_._macro_name; + _paren_count = rhs_._paren_count; + _in_string = rhs_._in_string; + _nl_id = rhs_._nl_id; + return *this; + } + + inline bool next(char_type &ch_) + { + if (_curr >= _end) + { + ch_ = 0; + return true; + } + else + { + ch_ = *_curr; + increment(); + return false; + } + } + + inline void increment() + { + ++_curr; + } + + inline std::size_t index() + { + return _curr - _start; + } + + inline bool eos() + { + return _curr >= _end; + } + + inline void unexpected_end(std::ostringstream &ss_) + { + ss_ << "Unexpected end of regex"; + } + + inline void error(std::ostringstream &ss_) + { + ss_ << " in "; + + if (_macro_name) + { + ss_ << "MACRO '"; + narrow(_macro_name, ss_); + ss_ << "'."; + } + else + { + ss_ << "rule id " << _id << '.'; + } + } +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/parser/tree/end_node.hpp b/YACReaderLibrary/lexertl/parser/tree/end_node.hpp new file mode 100644 index 000000000..c485fca52 --- /dev/null +++ b/YACReaderLibrary/lexertl/parser/tree/end_node.hpp @@ -0,0 +1,111 @@ +// end_node.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_END_NODE_HPP +#define LEXERTL_END_NODE_HPP + +#include "node.hpp" + +namespace lexertl +{ +namespace detail +{ +template +class basic_end_node : public basic_node +{ +public: + using node = basic_node; + using bool_stack = typename node::bool_stack; + using const_node_stack = typename node::const_node_stack; + using node_ptr_vector = typename node::node_ptr_vector; + using node_stack = typename node::node_stack; + using node_type = typename node::node_type; + using node_vector = typename node::node_vector; + + basic_end_node(const id_type id_, const id_type user_id_, + const id_type next_dfa_, const id_type push_dfa_, + const bool pop_dfa_) : + node(false), + _id(id_), + _user_id(user_id_), + _next_dfa(next_dfa_), + _push_dfa(push_dfa_), + _pop_dfa(pop_dfa_), + _followpos() + { + node::_firstpos.push_back(this); + node::_lastpos.push_back(this); + } + + virtual ~basic_end_node() override + { + } + + virtual node_type what_type() const override + { + return node::END; + } + + virtual bool traverse(const_node_stack &/*node_stack_*/, + bool_stack &/*perform_op_stack_*/) const override + { + return false; + } + + virtual const node_vector &followpos() const override + { + // _followpos is always empty..! + return _followpos; + } + + virtual bool end_state() const override + { + return true; + } + + virtual id_type id() const override + { + return _id; + } + + virtual id_type user_id() const override + { + return _user_id; + } + + virtual id_type next_dfa() const override + { + return _next_dfa; + } + + virtual id_type push_dfa() const override + { + return _push_dfa; + } + + virtual bool pop_dfa() const override + { + return _pop_dfa; + } + +private: + id_type _id; + id_type _user_id; + id_type _next_dfa; + id_type _push_dfa; + bool _pop_dfa; + node_vector _followpos; + + virtual void copy_node(node_ptr_vector &/*node_ptr_vector_*/, + node_stack &/*new_node_stack_*/, bool_stack &/*perform_op_stack_*/, + bool &/*down_*/) const override + { + // Nothing to do, as end_nodes are not copied. + } +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/parser/tree/iteration_node.hpp b/YACReaderLibrary/lexertl/parser/tree/iteration_node.hpp new file mode 100644 index 000000000..41baba7e3 --- /dev/null +++ b/YACReaderLibrary/lexertl/parser/tree/iteration_node.hpp @@ -0,0 +1,96 @@ +// iteration_node.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_ITERATION_NODE_HPP +#define LEXERTL_ITERATION_NODE_HPP + +#include "node.hpp" + +namespace lexertl +{ +namespace detail +{ +template +class basic_iteration_node : public basic_node +{ +public: + using node = basic_node; + using bool_stack = typename node::bool_stack; + using const_node_stack = typename node::const_node_stack; + using node_ptr_vector = typename node::node_ptr_vector; + using node_stack = typename node::node_stack; + using node_type = typename node::node_type; + using node_vector = typename node::node_vector; + + basic_iteration_node(observer_ptr next_, const bool greedy_) : + node(true), + _next(next_), + _greedy(greedy_) + { + _next->append_firstpos(node::_firstpos); + _next->append_lastpos(node::_lastpos); + + for (observer_ptr node_ : node::_lastpos) + { + node_->append_followpos(node::_firstpos); + } + + for (observer_ptr node_ : node::_firstpos) + { + node_->greedy(greedy_); + } + } + + virtual ~basic_iteration_node() override + { + } + + virtual node_type what_type() const override + { + return node::ITERATION; + } + + virtual bool traverse(const_node_stack &node_stack_, + bool_stack &perform_op_stack_) const override + { + perform_op_stack_.push(true); + node_stack_.push(_next); + return true; + } + +private: + observer_ptr _next; + bool _greedy; + + virtual void copy_node(node_ptr_vector &node_ptr_vector_, + node_stack &new_node_stack_, bool_stack &perform_op_stack_, + bool &down_) const override + { + if (perform_op_stack_.top()) + { + observer_ptr ptr_ = new_node_stack_.top(); + + node_ptr_vector_.emplace_back + (std::make_unique(ptr_, _greedy)); + new_node_stack_.top() = node_ptr_vector_.back().get(); + } + else + { + down_ = true; + } + + perform_op_stack_.pop(); + } + + // No copy construction. + basic_iteration_node(const basic_iteration_node &) = delete; + // No assignment. + const basic_iteration_node &operator = + (const basic_iteration_node &) = delete; +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/parser/tree/leaf_node.hpp b/YACReaderLibrary/lexertl/parser/tree/leaf_node.hpp new file mode 100644 index 000000000..ef1b485e4 --- /dev/null +++ b/YACReaderLibrary/lexertl/parser/tree/leaf_node.hpp @@ -0,0 +1,110 @@ +// leaf_node.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_LEAF_NODE_HPP +#define LEXERTL_LEAF_NODE_HPP + +#include "../../enums.hpp" // null_token +#include "node.hpp" + +namespace lexertl +{ +namespace detail +{ +template +class basic_leaf_node : public basic_node +{ +public: + using node = basic_node; + using bool_stack = typename node::bool_stack; + using const_node_stack = typename node::const_node_stack; + using node_ptr_vector = typename node::node_ptr_vector; + using node_stack = typename node::node_stack; + using node_type = typename node::node_type; + using node_vector = typename node::node_vector; + + basic_leaf_node(const id_type token_, const bool greedy_) : + node(token_ == node::null_token()), + _token(token_), + _set_greedy(!greedy_), + _greedy(greedy_), + _followpos() + { + if (!node::_nullable) + { + node::_firstpos.push_back(this); + node::_lastpos.push_back(this); + } + } + + virtual ~basic_leaf_node() override + { + } + + virtual void append_followpos(const node_vector &followpos_) override + { + _followpos.insert(_followpos.end(), + followpos_.begin(), followpos_.end()); + } + + virtual node_type what_type() const override + { + return node::LEAF; + } + + virtual bool traverse(const_node_stack &/*node_stack_*/, + bool_stack &/*perform_op_stack_*/) const override + { + return false; + } + + virtual id_type token() const override + { + return _token; + } + + virtual void greedy(const bool greedy_) override + { + if (!_set_greedy) + { + _greedy = greedy_; + _set_greedy = true; + } + } + + virtual bool greedy() const override + { + return _greedy; + } + + virtual const node_vector &followpos() const override + { + return _followpos; + } + + virtual node_vector &followpos() override + { + return _followpos; + } + +private: + id_type _token; + bool _set_greedy; + bool _greedy; + node_vector _followpos; + + virtual void copy_node(node_ptr_vector &node_ptr_vector_, + node_stack &new_node_stack_, bool_stack &/*perform_op_stack_*/, + bool &/*down_*/) const override + { + node_ptr_vector_.emplace_back(std::make_unique + (_token, _greedy)); + new_node_stack_.push(node_ptr_vector_.back().get()); + } +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/parser/tree/node.hpp b/YACReaderLibrary/lexertl/parser/tree/node.hpp new file mode 100644 index 000000000..cee7729a3 --- /dev/null +++ b/YACReaderLibrary/lexertl/parser/tree/node.hpp @@ -0,0 +1,242 @@ +// node.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_NODE_HPP +#define LEXERTL_NODE_HPP + +#include +#include +#include "../../observer_ptr.hpp" +#include "../../runtime_error.hpp" +#include +#include + +namespace lexertl +{ +namespace detail +{ +template +class basic_node +{ +public: + enum node_type {LEAF, SEQUENCE, SELECTION, ITERATION, END}; + + using bool_stack = std::stack; + using node_stack = std::stack>; + using const_node_stack = std::stack>; + using node_vector = std::vector>; + using node_ptr_vector = std::vector>; + + basic_node() : + _nullable(false), + _firstpos(), + _lastpos() + { + } + + basic_node(const bool nullable_) : + _nullable(nullable_), + _firstpos(), + _lastpos() + { + } + + virtual ~basic_node() + { + } + + static id_type null_token() + { + return static_cast(~0); + } + + bool nullable() const + { + return _nullable; + } + + void append_firstpos(node_vector &firstpos_) const + { + firstpos_.insert(firstpos_.end(), + _firstpos.begin(), _firstpos.end()); + } + + void append_lastpos(node_vector &lastpos_) const + { + lastpos_.insert(lastpos_.end(), + _lastpos.begin(), _lastpos.end()); + } + + virtual void append_followpos(const node_vector &/*followpos_*/) + { + throw runtime_error("Internal error node::append_followpos()."); + } + + observer_ptr copy(node_ptr_vector &node_ptr_vector_) const + { + observer_ptr new_root_ = nullptr; + const_node_stack node_stack_; + bool_stack perform_op_stack_; + bool down_ = true; + node_stack new_node_stack_; + + node_stack_.push(this); + + while (!node_stack_.empty()) + { + while (down_) + { + down_ = node_stack_.top()->traverse(node_stack_, + perform_op_stack_); + } + + while (!down_ && !node_stack_.empty()) + { + observer_ptr top_ = node_stack_.top(); + + top_->copy_node(node_ptr_vector_, new_node_stack_, + perform_op_stack_, down_); + + if (!down_) node_stack_.pop(); + } + } + + assert(new_node_stack_.size() == 1); + new_root_ = new_node_stack_.top(); + new_node_stack_.pop(); + return new_root_; + } + + virtual node_type what_type() const = 0; + + virtual bool traverse(const_node_stack &node_stack_, + bool_stack &perform_op_stack_) const = 0; + + node_vector &firstpos() + { + return _firstpos; + } + + const node_vector &firstpos() const + { + return _firstpos; + } + + // _lastpos modified externally, so not const & + node_vector &lastpos() + { + return _lastpos; + } + + virtual bool end_state() const + { + return false; + } + + virtual id_type id() const + { + throw runtime_error("Internal error node::id()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return id_type(); +#endif + } + + virtual id_type user_id() const + { + throw runtime_error("Internal error node::user_id()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return id_type(); +#endif + } + + virtual id_type next_dfa() const + { + throw runtime_error("Internal error node::next_dfa()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return id_type(); +#endif + } + + virtual id_type push_dfa() const + { + throw runtime_error("Internal error node::push_dfa()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return id_type(); +#endif + } + + virtual bool pop_dfa() const + { + throw runtime_error("Internal error node::pop_dfa()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return false; +#endif + } + + virtual id_type token() const + { + throw runtime_error("Internal error node::token()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return id_type(); +#endif + } + + virtual void greedy(const bool /*greedy_*/) + { + throw runtime_error("Internal error node::greedy(bool)."); + } + + virtual bool greedy() const + { + throw runtime_error("Internal error node::greedy()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return false; +#endif + } + + virtual const node_vector &followpos() const + { + throw runtime_error("Internal error node::followpos()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return firstpos; +#endif + } + + virtual node_vector &followpos() + { + throw runtime_error("Internal error node::followpos()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return firstpos; +#endif + } + +protected: + const bool _nullable; + node_vector _firstpos; + node_vector _lastpos; + + virtual void copy_node(node_ptr_vector &node_ptr_vector_, + node_stack &new_node_stack_, bool_stack &perform_op_stack_, + bool &down_) const = 0; + +private: + // No copy construction. + basic_node(const basic_node &) = delete; + // No assignment. + const basic_node &operator =(const basic_node &) = delete; +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/parser/tree/selection_node.hpp b/YACReaderLibrary/lexertl/parser/tree/selection_node.hpp new file mode 100644 index 000000000..603bbc68d --- /dev/null +++ b/YACReaderLibrary/lexertl/parser/tree/selection_node.hpp @@ -0,0 +1,104 @@ +// selection_node.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_SELECTION_NODE_HPP +#define LEXERTL_SELECTION_NODE_HPP + +#include "node.hpp" + +namespace lexertl +{ +namespace detail +{ +template +class basic_selection_node : public basic_node +{ +public: + using node = basic_node; + using bool_stack = typename node::bool_stack; + using const_node_stack = typename node::const_node_stack; + using node_ptr_vector = typename node::node_ptr_vector; + using node_stack = typename node::node_stack; + using node_type = typename node::node_type; + + basic_selection_node(observer_ptr left_, observer_ptr right_) : + node(left_->nullable() || right_->nullable()), + _left(left_), + _right(right_) + { + _left->append_firstpos(node::_firstpos); + _right->append_firstpos(node::_firstpos); + _left->append_lastpos(node::_lastpos); + _right->append_lastpos(node::_lastpos); + } + + virtual ~basic_selection_node() override + { + } + + virtual node_type what_type() const override + { + return node::SELECTION; + } + + virtual bool traverse(const_node_stack &node_stack_, + bool_stack &perform_op_stack_) const override + { + perform_op_stack_.push(true); + + switch (_right->what_type()) + { + case node::SEQUENCE: + case node::SELECTION: + case node::ITERATION: + perform_op_stack_.push(false); + break; + default: + break; + } + + node_stack_.push(_right); + node_stack_.push(_left); + return true; + } + +private: + observer_ptr _left; + observer_ptr _right; + + virtual void copy_node(node_ptr_vector &node_ptr_vector_, + node_stack &new_node_stack_, bool_stack &perform_op_stack_, + bool &down_) const override + { + if (perform_op_stack_.top()) + { + observer_ptr rhs_ = new_node_stack_.top(); + + new_node_stack_.pop(); + + observer_ptr lhs_ = new_node_stack_.top(); + + node_ptr_vector_.emplace_back + (std::make_unique(lhs_, rhs_)); + new_node_stack_.top() = node_ptr_vector_.back().get(); + } + else + { + down_ = true; + } + + perform_op_stack_.pop(); + } + + // No copy construction. + basic_selection_node(const basic_selection_node &) = delete; + // No assignment. + const basic_selection_node &operator = + (const basic_selection_node &) = delete; +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/parser/tree/sequence_node.hpp b/YACReaderLibrary/lexertl/parser/tree/sequence_node.hpp new file mode 100644 index 000000000..222767350 --- /dev/null +++ b/YACReaderLibrary/lexertl/parser/tree/sequence_node.hpp @@ -0,0 +1,121 @@ +// sequence_node.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_SEQUENCE_NODE_HPP +#define LEXERTL_SEQUENCE_NODE_HPP + +#include "node.hpp" + +namespace lexertl +{ +namespace detail +{ +template +class basic_sequence_node : public basic_node +{ +public: + using node = basic_node; + using bool_stack = typename node::bool_stack; + using const_node_stack = typename node::const_node_stack; + using node_ptr_vector = typename node::node_ptr_vector; + using node_stack = typename node::node_stack; + using node_type = typename node::node_type; + using node_vector = typename node::node_vector; + + basic_sequence_node(observer_ptr left_, observer_ptr right_) : + node(left_->nullable() && right_->nullable()), + _left(left_), + _right(right_) + { + _left->append_firstpos(node::_firstpos); + + if (_left->nullable()) + { + _right->append_firstpos(node::_firstpos); + } + + if (_right->nullable()) + { + _left->append_lastpos(node::_lastpos); + } + + _right->append_lastpos(node::_lastpos); + + node_vector &lastpos_ = _left->lastpos(); + const node_vector &firstpos_ = _right->firstpos(); + + for (observer_ptr node_ : lastpos_) + { + node_->append_followpos(firstpos_); + } + } + + virtual ~basic_sequence_node() override + { + } + + virtual node_type what_type() const override + { + return node::SEQUENCE; + } + + virtual bool traverse(const_node_stack &node_stack_, + bool_stack &perform_op_stack_) const override + { + perform_op_stack_.push(true); + + switch (_right->what_type()) + { + case node::SEQUENCE: + case node::SELECTION: + case node::ITERATION: + perform_op_stack_.push(false); + break; + default: + break; + } + + node_stack_.push(_right); + node_stack_.push(_left); + return true; + } + +private: + observer_ptr _left; + observer_ptr _right; + + virtual void copy_node(node_ptr_vector &node_ptr_vector_, + node_stack &new_node_stack_, bool_stack &perform_op_stack_, + bool &down_) const override + { + if (perform_op_stack_.top()) + { + observer_ptr rhs_ = new_node_stack_.top(); + + new_node_stack_.pop(); + + observer_ptr lhs_ = new_node_stack_.top(); + + node_ptr_vector_.emplace_back + (std::make_unique(lhs_, rhs_)); + new_node_stack_.top() = node_ptr_vector_.back().get(); + } + else + { + down_ = true; + } + + perform_op_stack_.pop(); + } + + // No copy construction. + basic_sequence_node(const basic_sequence_node &) = delete; + // No assignment. + const basic_sequence_node &operator =(const basic_sequence_node &) = delete; +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/partition/charset.hpp b/YACReaderLibrary/lexertl/partition/charset.hpp new file mode 100644 index 000000000..2bfbd3358 --- /dev/null +++ b/YACReaderLibrary/lexertl/partition/charset.hpp @@ -0,0 +1,72 @@ +// charset.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_CHARSET_HPP +#define LEXERTL_CHARSET_HPP + +#include +#include +#include +#include "../string_token.hpp" + +namespace lexertl +{ +namespace detail +{ +template +struct basic_charset +{ + using token = basic_string_token; + using index_set = std::set; + + token _token; + index_set _index_set; + + basic_charset() : + _token(), + _index_set() + { + } + + basic_charset(const token &token_, const id_type index_) : + _token(token_), + _index_set() + { + _index_set.insert(index_); + } + + bool empty() const + { + return _token.empty() && _index_set.empty(); + } + + void intersect(basic_charset &rhs_, basic_charset &overlap_) + { + _token.intersect(rhs_._token, overlap_._token); + + if (!overlap_._token.empty()) + { + std::merge(_index_set.begin(), _index_set.end(), + rhs_._index_set.begin(), rhs_._index_set.end(), + std::inserter(overlap_._index_set, + overlap_._index_set.end())); + + if (_token.empty()) + { + _index_set.clear(); + } + + if (rhs_._token.empty()) + { + rhs_._index_set.clear(); + } + } + } +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/partition/equivset.hpp b/YACReaderLibrary/lexertl/partition/equivset.hpp new file mode 100644 index 000000000..af709b03f --- /dev/null +++ b/YACReaderLibrary/lexertl/partition/equivset.hpp @@ -0,0 +1,135 @@ +// equivset.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_EQUIVSET_HPP +#define LEXERTL_EQUIVSET_HPP + +#include +#include "../parser/tree/node.hpp" +#include + +namespace lexertl +{ +namespace detail +{ +template +struct basic_equivset +{ + using index_set = std::set; + using index_vector = std::vector; + using node = basic_node; + using node_vector = std::vector>; + + index_vector _index_vector; + id_type _id; + bool _greedy; + node_vector _followpos; + + basic_equivset() : + _index_vector(), + _id(0), + _greedy(true), + _followpos() + { + } + + basic_equivset(const index_set &index_set_, const id_type id_, + const bool greedy_, const node_vector &followpos_) : + _index_vector(index_set_.begin(), index_set_.end()), + _id(id_), + _greedy(greedy_), + _followpos(followpos_) + { + } + + bool empty() const + { + return _index_vector.empty() && _followpos.empty(); + } + + void intersect(basic_equivset &rhs_, basic_equivset &overlap_) + { + intersect_indexes(rhs_._index_vector, overlap_._index_vector); + + if (!overlap_._index_vector.empty()) + { + // Note that the LHS takes priority in order to + // respect rule ordering priority in the lex spec. + overlap_._id = _id; + overlap_._greedy = _greedy; + overlap_._followpos = _followpos; + + auto overlap_begin_ = overlap_._followpos.cbegin(); + auto overlap_end_ = overlap_._followpos.cend(); + + for (observer_ptr node_ : rhs_._followpos) + { + if (std::find(overlap_begin_, overlap_end_, node_) == + overlap_end_) + { + overlap_._followpos.push_back(node_); + overlap_begin_ = overlap_._followpos.begin(); + overlap_end_ = overlap_._followpos.end(); + } + } + + if (_index_vector.empty()) + { + _followpos.clear(); + } + + if (rhs_._index_vector.empty()) + { + rhs_._followpos.clear(); + } + } + } + +private: + void intersect_indexes(index_vector &rhs_, index_vector &overlap_) + { + std::set_intersection(_index_vector.begin(), _index_vector.end(), + rhs_.begin(), rhs_.end(), std::back_inserter(overlap_)); + + if (!overlap_.empty()) + { + remove(overlap_, _index_vector); + remove(overlap_, rhs_); + } + } + + void remove(const index_vector &source_, index_vector &dest_) + { + auto inter_ = source_.begin(); + auto inter_end_ = source_.end(); + auto reader_ = std::find(dest_.begin(), dest_.end(), *inter_); + auto writer_ = reader_; + auto dest_end_ = dest_.end(); + + while (writer_ != dest_end_ && inter_ != inter_end_) + { + if (*reader_ == *inter_) + { + ++inter_; + ++reader_; + } + else + { + *writer_++ = *reader_++; + } + } + + while (reader_ != dest_end_) + { + *writer_++ = *reader_++; + } + + dest_.resize(dest_.size() - source_.size()); + } +}; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/rules.hpp b/YACReaderLibrary/lexertl/rules.hpp new file mode 100644 index 000000000..c5b29e0bd --- /dev/null +++ b/YACReaderLibrary/lexertl/rules.hpp @@ -0,0 +1,1018 @@ +// rules.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_RULES_HPP +#define LEXERTL_RULES_HPP + +#include "enums.hpp" +#include +#include +#include "narrow.hpp" +#include "observer_ptr.hpp" +#include "parser/tokeniser/re_tokeniser.hpp" +#include "runtime_error.hpp" +#include +#include +#include +#include + +namespace lexertl +{ +template +class basic_rules +{ +public: + using bool_vector = std::vector; + using bool_vector_vector = std::vector; + using char_type = ch_type; + using rules_char_type = r_ch_type; + using id_type = id_ty; + using id_vector = std::vector; + using id_vector_vector = std::vector; + using re_state = detail::basic_re_tokeniser_state; + using string = std::basic_string; + using string_token = basic_string_token; + using string_vector = std::vector; + using string_set = std::set; + using string_pair = std::pair; + using string_id_type_map = std::map; + using string_id_type_pair = std::pair; + using token = detail::basic_re_token; + using token_vector = std::vector; + using token_vector_vector = std::vector; + using token_vector_vector_vector = std::vector; + using macro_map = std::map; + using macro_pair = std::pair; + using tokeniser = + detail::basic_re_tokeniser; + + // If you get a compile error here you have + // failed to define an unsigned id type. + static_assert(std::is_unsigned::value, "Your id type is signed"); + +#ifdef _WIN32 + basic_rules(const std::size_t flags_ = dot_not_cr_lf) : +#else + basic_rules(const std::size_t flags_ = dot_not_newline) : +#endif + _statemap(), + _macro_map(), + _regexes(), + _features(), + _ids(), + _user_ids(), + _next_dfas(), + _pushes(), + _pops(), + _flags(flags_), + _locale(), + _lexer_state_names() + { + push_state(initial()); + } + + void clear() + { + _statemap.clear(); + _macro_map.clear(); + _regexes.clear(); + _features.clear(); + _ids.clear(); + _user_ids.clear(); + _next_dfas.clear(); + _pushes.clear(); + _pops.clear(); +#ifdef _WIN32 + _flags = dot_not_cr_lf; +#else + _flags = dot_not_newline; +#endif + _locale = std::locale(); + _lexer_state_names.clear(); + push_state(initial()); + } + + void clear(const id_type dfa_) + { + if (_regexes.size() > dfa_) + { + _regexes[dfa_].clear(); + _features[dfa_] = 0; + _ids[dfa_].clear(); + _user_ids[dfa_].clear(); + _next_dfas[dfa_].clear(); + _pushes[dfa_].clear(); + _pops[dfa_].clear(); + } + } + + void flags(const std::size_t flags_) + { + _flags = flags_; + } + + std::size_t flags() const + { + return _flags; + } + + static id_type skip() + { + return static_cast(~1); + } + + id_type eoi() const + { + return 0; + } + + static id_type npos() + { + return static_cast(~0); + } + + std::locale imbue(const std::locale &locale_) + { + std::locale loc_ = _locale; + + _locale = locale_; + return loc_; + } + + const std::locale &locale() const + { + return _locale; + } + + const rules_char_type *state(const id_type index_) const + { + if (index_ == 0) + { + return initial(); + } + else + { + const id_type i_ = index_ - 1; + + if (_lexer_state_names.size() > i_) + { + return _lexer_state_names[i_].c_str(); + } + else + { + return 0; + } + } + } + + id_type state(const rules_char_type *name_) const + { + typename string_id_type_map::const_iterator iter_ = + _statemap.find(name_); + + if (iter_ == _statemap.end()) + { + return npos(); + } + else + { + return iter_->second; + } + } + + id_type push_state(const rules_char_type *name_) + { + validate(name_); + + if (_statemap.insert(string_id_type_pair(name_, + static_cast(_statemap.size()))).second) + { + _regexes.push_back(token_vector_vector()); + _features.push_back(0); + _ids.push_back(id_vector()); + _user_ids.push_back(id_vector()); + _next_dfas.push_back(id_vector()); + _pushes.push_back(id_vector()); + _pops.push_back(bool_vector()); + + if (string(name_) != initial()) + { + _lexer_state_names.push_back(name_); + } + } + else + { + return _statemap.find(name_)->second; + } + + if (_next_dfas.size() > npos()) + { + // Overflow + throw runtime_error("The data type you have chosen cannot hold " + "this many lexer start states."); + } + + // Initial is not stored, so no need to - 1. + return static_cast(_lexer_state_names.size()); + } + + void insert_macro(const rules_char_type *name_, + const rules_char_type *regex_) + { + insert_macro(name_, string(regex_)); + } + + void insert_macro(const rules_char_type *name_, + const rules_char_type *regex_start_, + const rules_char_type *regex_end_) + { + insert_macro(name_, string(regex_start_, regex_end_)); + } + + void insert_macro(const rules_char_type *name_, const string ®ex_) + { + validate(name_); + + typename macro_map::const_iterator iter_ = _macro_map.find(name_); + + if (iter_ == _macro_map.end()) + { + auto pair_ = _macro_map.insert(macro_pair(name_, token_vector())); + + tokenise(regex_, pair_.first->second, npos(), name_); + } + else + { + std::ostringstream ss_; + + ss_ << "Attempt to redefine MACRO '"; + narrow(name_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + } + + // Add rule to INITIAL + void push(const rules_char_type *regex_, const id_type id_, + const id_type user_id_ = npos()) + { + push(string(regex_), id_, user_id_); + } + + void push(const rules_char_type *regex_start_, + const rules_char_type *regex_end_, + const id_type id_, const id_type user_id_ = npos()) + { + push(string(regex_start_, regex_end_), id_, user_id_); + } + + void push(const string ®ex_, const id_type id_, + const id_type user_id_ = npos()) + { + check_for_invalid_id(id_); + _regexes.front().push_back(token_vector()); + tokenise(regex_, _regexes.front().back(), id_, 0); + + if (regex_[0] == '^') + { + _features.front() |= bol_bit; + } + + if (regex_.size() > 0 && regex_[regex_.size() - 1] == '$') + { + _features.front() |= eol_bit; + } + + if (id_ == skip()) + { + _features.front() |= skip_bit; + } + else if (id_ == eoi()) + { + _features.front() |= again_bit; + } + + _ids.front().push_back(id_); + _user_ids.front().push_back(user_id_); + _next_dfas.front().push_back(0); + _pushes.front().push_back(npos()); + _pops.front().push_back(false); + } + + // Add rule with no id + void push(const rules_char_type *curr_dfa_, + const rules_char_type *regex_, const rules_char_type *new_dfa_) + { + push(curr_dfa_, string(regex_), new_dfa_); + } + + void push(const rules_char_type *curr_dfa_, + const rules_char_type *regex_start_, const rules_char_type *regex_end_, + const rules_char_type *new_dfa_) + { + push(curr_dfa_, string(regex_start_, regex_end_), new_dfa_); + } + + void push(const rules_char_type *curr_dfa_, const string ®ex_, + const rules_char_type *new_dfa_) + { + push(curr_dfa_, regex_, eoi(), new_dfa_, false); + } + + // Add rule with id + void push(const rules_char_type *curr_dfa_, + const rules_char_type *regex_, const id_type id_, + const rules_char_type *new_dfa_, const id_type user_id_ = npos()) + { + push(curr_dfa_, string(regex_), id_, new_dfa_, user_id_); + } + + void push(const rules_char_type *curr_dfa_, + const rules_char_type *regex_start_, + const rules_char_type *regex_end_, const id_type id_, + const rules_char_type *new_dfa_, const id_type user_id_ = npos()) + { + push(curr_dfa_, string(regex_start_, regex_end_), + id_, new_dfa_, user_id_); + } + + void push(const rules_char_type *curr_dfa_, const string ®ex_, + const id_type id_, const rules_char_type *new_dfa_, + const id_type user_id_ = npos()) + { + push(curr_dfa_, regex_, id_, new_dfa_, true, user_id_); + } + + void reverse() + { + for (auto &state_ : _regexes) + { + for (auto ®ex_ : state_) + { + reverse(regex_); + } + } + + for (auto &pair_ : _macro_map) + { + reverse(pair_.second); + } + } + + const string_id_type_map &statemap() const + { + return _statemap; + } + + const token_vector_vector_vector ®exes() const + { + return _regexes; + } + + const id_vector &features() const + { + return _features; + } + + const id_vector_vector &ids() const + { + return _ids; + } + + const id_vector_vector &user_ids() const + { + return _user_ids; + } + + const id_vector_vector &next_dfas() const + { + return _next_dfas; + } + + const id_vector_vector &pushes() const + { + return _pushes; + } + + const bool_vector_vector &pops() const + { + return _pops; + } + + bool empty() const + { + bool empty_ = true; + + for (const auto ®ex_ : _regexes) + { + if (!regex_.empty()) + { + empty_ = false; + break; + } + } + + return empty_; + } + + static const rules_char_type *initial() + { + static const rules_char_type initial_ [] = + { 'I', 'N', 'I', 'T', 'I', 'A', 'L', 0 }; + + return initial_; + } + + static const rules_char_type *dot() + { + static const rules_char_type dot_ [] = { '.', 0 }; + + return dot_; + } + + static const rules_char_type *all_states() + { + static const rules_char_type star_ [] = { '*', 0 }; + + return star_; + } + +private: + string_id_type_map _statemap; + macro_map _macro_map; + token_vector_vector_vector _regexes; + id_vector _features; + id_vector_vector _ids; + id_vector_vector _user_ids; + id_vector_vector _next_dfas; + id_vector_vector _pushes; + bool_vector_vector _pops; + std::size_t _flags; + std::locale _locale; + string_vector _lexer_state_names; + + void tokenise(const string ®ex_, token_vector &tokens_, + const id_type id_, const rules_char_type *name_) + { + re_state state_(regex_.c_str(), regex_.c_str() + regex_.size(), id_, + _flags, _locale, name_); + string macro_; + rules_char_type diff_ = 0; + + tokens_.push_back(token()); + + do + { + observer_ptr lhs_ = &tokens_.back(); + token rhs_; + + tokeniser::next(*lhs_, state_, rhs_); + + if (rhs_._type != detail::DIFF && + lhs_->precedence(rhs_._type) == ' ') + { + std::ostringstream ss_; + + ss_ << "A syntax error occurred: '" << + lhs_->precedence_string() << + "' against '" << rhs_.precedence_string() << + "' preceding index " << state_.index() << + " in "; + + if (name_ != 0) + { + ss_ << "macro "; + narrow(name_, ss_); + } + else + { + ss_ << "rule id " << state_._id; + } + + ss_ << '.'; + throw runtime_error(ss_.str()); + } + + if (rhs_._type == detail::MACRO) + { + typename macro_map::const_iterator iter_ = + _macro_map.find(rhs_._extra); + + macro_ = rhs_._extra; + + if (iter_ == _macro_map.end()) + { + const rules_char_type *rhs_name_ = rhs_._extra.c_str(); + std::ostringstream ss_; + + ss_ << "Unknown MACRO name '"; + narrow(rhs_name_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + else + { + const bool multiple_ = iter_->second.size() > 3; + + if (diff_) + { + if (multiple_) + { + std::ostringstream ss_; + + ss_ << "Single CHARSET must follow {-} or {+} at " + "index " << state_.index() - 1 << " in "; + + if (name_ != 0) + { + ss_ << "macro "; + narrow(name_, ss_); + } + else + { + ss_ << "rule id " << state_._id; + } + + ss_ << '.'; + throw runtime_error(ss_.str()); + } + else + { + rhs_ = iter_->second[1]; + } + } + + // Any macro with more than one charset (or quantifiers) + // requires bracketing. + if (multiple_) + { + token open_; + + open_._type = detail::OPENPAREN; + open_._str.insert('('); + tokens_.push_back(open_); + } + + // Don't need to store token if it is diff. + if (!diff_) + { + // Don't insert BEGIN or END tokens + tokens_.insert(tokens_.end(), iter_->second.begin() + 1, + iter_->second.end() - 1); + lhs_ = &tokens_.back(); + } + + if (multiple_) + { + token close_; + + close_._type = detail::CLOSEPAREN; + close_._str.insert(')'); + tokens_.push_back(close_); + } + } + } + else if (rhs_._type == detail::DIFF) + { + if (!macro_.empty()) + { + typename macro_map::const_iterator iter_ = + _macro_map.find(macro_); + + if (iter_->second.size() > 3) + { + std::ostringstream ss_; + + ss_ << "Single CHARSET must precede {-} or {+} at " + "index " << state_.index() - 1 << " in "; + + if (name_ != 0) + { + ss_ << "macro "; + narrow(name_, ss_); + } + else + { + ss_ << "rule id " << state_._id; + } + + ss_ << '.'; + throw runtime_error(ss_.str()); + } + } + + diff_ = rhs_._extra[0]; + macro_.clear(); + continue; + } + else if (!diff_) + { + tokens_.push_back(rhs_); + lhs_ = &tokens_.back(); + macro_.clear(); + } + + // diff_ may have been set by previous conditional. + if (diff_) + { + if (rhs_._type != detail::CHARSET) + { + std::ostringstream ss_; + + ss_ << "CHARSET must follow {-} or {+} at index " << + state_.index() - 1 << " in "; + + if (name_ != 0) + { + ss_ << "macro "; + narrow(name_, ss_); + } + else + { + ss_ << "rule id " << state_._id; + } + + ss_ << '.'; + throw runtime_error(ss_.str()); + } + + switch (diff_) + { + case '-': + lhs_->_str.remove(rhs_._str); + + if (lhs_->_str.empty()) + { + std::ostringstream ss_; + + ss_ << "Empty charset created by {-} at index " << + state_.index() - 1 << " in "; + + if (name_ != 0) + { + ss_ << "macro "; + narrow(name_, ss_); + } + else + { + ss_ << "rule id " << state_._id; + } + + ss_ << '.'; + throw runtime_error(ss_.str()); + } + + break; + case '+': + lhs_->_str.insert(rhs_._str); + break; + } + + diff_ = 0; + } + } while (tokens_.back()._type != detail::END); + + if (tokens_.size() == 2) + { + std::ostringstream ss_; + + ss_ << "Empty regex in "; + + if (name_ != 0) + { + ss_ << "macro "; + narrow(name_, ss_); + } + else + { + ss_ << "rule id " << state_._id; + } + + ss_ << " is not allowed."; + throw runtime_error(ss_.str()); + } + } + + void reverse(token_vector &vector_) + { + token_vector new_vector_(vector_.size(), token()); + auto iter_ = vector_.rbegin(); + auto end_ = vector_.rend(); + auto dest_ = new_vector_.begin(); + std::stack stack_; + + for (; iter_ != end_; ++iter_, ++dest_) + { + switch (iter_->_type) + { + case detail::BEGIN: + iter_->swap(*dest_); + dest_->_type = detail::END; + break; + case detail::BOL: + iter_->swap(*dest_); + dest_->_type = detail::EOL; + break; + case detail::EOL: + iter_->swap(*dest_); + dest_->_type = detail::BOL; + break; + case detail::OPENPAREN: + iter_->swap(*dest_); + dest_->_type = detail::CLOSEPAREN; + + if (stack_.top() != end_) + { + ++dest_; + dest_->swap(*stack_.top()); + } + + stack_.pop(); + break; + case detail::CLOSEPAREN: + iter_->swap(*dest_); + dest_->_type = detail::OPENPAREN; + stack_.push(end_); + break; + case detail::OPT: + case detail::AOPT: + case detail::ZEROORMORE: + case detail::AZEROORMORE: + case detail::ONEORMORE: + case detail::AONEORMORE: + case detail::REPEATN: + case detail::AREPEATN: + { + auto temp_ = iter_ + 1; + + if (temp_->_type == detail::CLOSEPAREN) + { + stack_.push(iter_); + ++iter_; + iter_->swap(*dest_); + dest_->_type = detail::OPENPAREN; + } + else + { + dest_->swap(*temp_); + ++dest_; + dest_->swap(*iter_); + ++iter_; + } + + break; + } + case detail::END: + iter_->swap(*dest_); + dest_->_type = detail::BEGIN; + break; + default: + // detail::OR + // detail::CHARSET + iter_->swap(*dest_); + break; + } + } + + new_vector_.swap(vector_); + } + + void push(const rules_char_type *curr_dfa_, const string ®ex_, + const id_type id_, const rules_char_type *new_dfa_, + const bool check_, const id_type user_id_ = npos()) + { + const bool star_ = *curr_dfa_ == '*' && *(curr_dfa_ + 1) == 0; + const bool dot_ = *new_dfa_ == '.' && *(new_dfa_ + 1) == 0; + const bool push_ = *new_dfa_ == '>'; + const rules_char_type *push_dfa_ = nullptr; + const bool pop_ = *new_dfa_ == '<'; + + if (push_ || pop_) + { + ++new_dfa_; + } + + if (check_) + { + check_for_invalid_id(id_); + } + + if (!dot_ && !pop_) + { + const rules_char_type *temp_ = new_dfa_; + + while (*temp_ && *temp_ != ':') + { + ++temp_; + } + + if (*temp_) push_dfa_ = temp_ + 1; + + validate(new_dfa_, *temp_ ? temp_ : 0); + + if (push_dfa_) + { + validate(push_dfa_); + } + } + + // npos means pop here + id_type new_dfa_id_ = npos(); + id_type push_dfa_id_ = npos(); + typename string_id_type_map::const_iterator iter_; + auto end_ = _statemap.cend(); + id_vector next_dfas_; + + if (!dot_ && !pop_) + { + if (push_dfa_) + { + iter_ = _statemap.find(string(new_dfa_, push_dfa_ - 1)); + } + else + { + iter_ = _statemap.find(new_dfa_); + } + + if (iter_ == end_) + { + std::ostringstream ss_; + + ss_ << "Unknown state name '"; + narrow(new_dfa_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + + new_dfa_id_ = iter_->second; + + if (push_dfa_) + { + iter_ = _statemap.find(push_dfa_); + + if (iter_ == end_) + { + std::ostringstream ss_; + + ss_ << "Unknown state name '"; + narrow(push_dfa_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + + push_dfa_id_ = iter_->second; + } + } + + if (star_) + { + const std::size_t size_ = _statemap.size(); + + for (id_type i_ = 0; i_ < size_; ++i_) + { + next_dfas_.push_back(i_); + } + } + else + { + const rules_char_type *start_ = curr_dfa_; + string next_dfa_; + + while (*curr_dfa_) + { + while (*curr_dfa_ && *curr_dfa_ != ',') + { + ++curr_dfa_; + } + + next_dfa_.assign(start_, curr_dfa_); + + if (*curr_dfa_) + { + ++curr_dfa_; + start_ = curr_dfa_; + } + + validate(next_dfa_.c_str()); + iter_ = _statemap.find(next_dfa_.c_str()); + + if (iter_ == end_) + { + std::ostringstream ss_; + + ss_ << "Unknown state name '"; + curr_dfa_ = next_dfa_.c_str(); + narrow(curr_dfa_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + + next_dfas_.push_back(iter_->second); + } + } + + for (std::size_t i_ = 0, size_ = next_dfas_.size(); + i_ < size_; ++i_) + { + const id_type curr_ = next_dfas_[i_]; + + _regexes[curr_].push_back(token_vector()); + tokenise(regex_, _regexes[curr_].back(), id_, 0); + + if (regex_[0] == '^') + { + _features[curr_] |= bol_bit; + } + + if (regex_[regex_.size() - 1] == '$') + { + _features[curr_] |= eol_bit; + } + + if (id_ == skip()) + { + _features[curr_] |= skip_bit; + } + else if (id_ == eoi()) + { + _features[curr_] |= again_bit; + } + + if (push_ || pop_) + { + _features[curr_] |= recursive_bit; + } + + _ids[curr_].push_back(id_); + _user_ids[curr_].push_back(user_id_); + _next_dfas[curr_].push_back(dot_ ? curr_ : new_dfa_id_); + _pushes[curr_].push_back(push_ ? (push_dfa_ ? + push_dfa_id_ : curr_) : npos()); + _pops[curr_].push_back(pop_); + } + } + + void validate(const rules_char_type *name_, + const rules_char_type *end_ = nullptr) const + { + const rules_char_type *start_ = name_; + + if (*name_ != '_' && !(*name_ >= 'A' && *name_ <= 'Z') && + !(*name_ >= 'a' && *name_ <= 'z')) + { + std::ostringstream ss_; + + ss_ << "Invalid name '"; + narrow(name_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + else if (*name_) + { + ++name_; + } + + while (*name_ && name_ != end_) + { + if (*name_ != '_' && *name_ != '-' && + !(*name_ >= 'A' && *name_ <= 'Z') && + !(*name_ >= 'a' && *name_ <= 'z') && + !(*name_ >= '0' && *name_ <= '9')) + { + std::ostringstream ss_; + + ss_ << "Invalid name '"; + name_ = start_; + narrow(name_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + + ++name_; + } + } + + void check_for_invalid_id(const id_type id_) const + { + if (id_ == eoi()) + { + throw runtime_error("Cannot resuse the id for eoi."); + } + + if (id_ == npos()) + { + throw runtime_error("The id npos is reserved for the " + "UNKNOWN token."); + } + } +}; + +using rules = basic_rules; +using wrules = basic_rules; +using u32rules = basic_rules; +} + +#endif diff --git a/YACReaderLibrary/lexertl/runtime_error.hpp b/YACReaderLibrary/lexertl/runtime_error.hpp new file mode 100644 index 000000000..7c240118d --- /dev/null +++ b/YACReaderLibrary/lexertl/runtime_error.hpp @@ -0,0 +1,23 @@ +// runtime_error.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_RUNTIME_ERROR_HPP +#define LEXERTL_RUNTIME_ERROR_HPP + +#include + +namespace lexertl +{ +class runtime_error : public std::runtime_error +{ +public: + runtime_error(const std::string &what_arg_) : + std::runtime_error(what_arg_) + { + } +}; +} + +#endif diff --git a/YACReaderLibrary/lexertl/serialise.hpp b/YACReaderLibrary/lexertl/serialise.hpp new file mode 100644 index 000000000..931f519b9 --- /dev/null +++ b/YACReaderLibrary/lexertl/serialise.hpp @@ -0,0 +1,28 @@ +// serialise.hpp +// Copyright (c) 2007-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_SERIALISE_HPP +#define LEXERTL_SERIALISE_HPP + +#include "state_machine.hpp" +#include + +namespace lexertl +{ +// IMPORTANT! This won't work if you don't enable RTTI! +template +void serialise(basic_state_machine &sm_, Archive &ar_) +{ + detail::basic_internals &internals_ = sm_.data(); + + ar_ & internals_._eoi; + ar_ & *internals_._lookup; + ar_ & internals_._dfa_alphabet; + ar_ & internals_._features; + ar_ & *internals_._dfa; +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/sm_to_csm.hpp b/YACReaderLibrary/lexertl/sm_to_csm.hpp new file mode 100644 index 000000000..5ffe69fee --- /dev/null +++ b/YACReaderLibrary/lexertl/sm_to_csm.hpp @@ -0,0 +1,53 @@ +// sm_to_csm.hpp +// Copyright (c) 2015-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_SM_TO_CSM_HPP +#define LEXERTL_SM_TO_CSM_HPP + +#include "enums.hpp" +#include "observer_ptr.hpp" +#include + +namespace lexertl +{ +template +void sm_to_csm(const sm &sm_, char_state_machine &csm_) +{ + using id_type = typename sm::traits::id_type; + using internals = typename sm::internals; + using string_token = typename char_state_machine::state::string_token; + using index_type = typename string_token::index_type; + using string_token_vector = + typename char_state_machine::string_token_vector; + const internals &internals_ = sm_.data(); + const std::size_t dfas_ = internals_._dfa.size(); + + for (id_type i_ = 0; i_ < dfas_; ++i_) + { + if (internals_._dfa_alphabet[i_] == 0) continue; + + const std::size_t alphabet_ = internals_._dfa_alphabet[i_] - + transitions_index; + string_token_vector token_vector_(alphabet_, string_token()); + observer_ptr ptr_ = &internals_._lookup[i_].front(); + + for (std::size_t c_ = 0; c_ < 256; ++c_, ++ptr_) + { + if (*ptr_ >= transitions_index) + { + string_token &token_ = token_vector_ + [*ptr_ - transitions_index]; + + token_.insert(typename string_token::range + (index_type(c_), index_type(c_))); + } + } + + csm_.append(token_vector_, internals_, i_); + } +} +} + +#endif diff --git a/YACReaderLibrary/lexertl/sm_traits.hpp b/YACReaderLibrary/lexertl/sm_traits.hpp new file mode 100644 index 000000000..161b29c9c --- /dev/null +++ b/YACReaderLibrary/lexertl/sm_traits.hpp @@ -0,0 +1,44 @@ +// sm_traits.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_SM_TRAITS_HPP +#define LEXERTL_SM_TRAITS_HPP + +namespace lexertl +{ +template +struct basic_sm_traits +{ + enum {char_24_bit = sizeof(ch_type) > 2, compressed = comp, lookup = look, + is_dfa = dfa_nfa}; + using input_char_type = ch_type; + using char_type = ch_type; + using id_type = sm_type; + + static id_type npos() + { + return static_cast(~0); + } +}; + +template +struct basic_sm_traits +{ + enum {char_24_bit = sizeof(ch_type) > 2, compressed = true, lookup = look, + is_dfa = dfa_nfa}; + using input_char_type = ch_type; + using char_type = unsigned char; + using id_type = sm_type; + + static id_type npos() + { + return static_cast(~0); + } +}; +} + +#endif diff --git a/YACReaderLibrary/lexertl/state_machine.hpp b/YACReaderLibrary/lexertl/state_machine.hpp new file mode 100644 index 000000000..76e7bc31c --- /dev/null +++ b/YACReaderLibrary/lexertl/state_machine.hpp @@ -0,0 +1,521 @@ +// state_machine.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_STATE_MACHINE_HPP +#define LEXERTL_STATE_MACHINE_HPP + +// memcmp() +#include +#include "internals.hpp" +#include +#include "observer_ptr.hpp" +#include +#include "sm_traits.hpp" +#include "string_token.hpp" + +namespace lexertl +{ +template +class basic_state_machine +{ +public: + using id_type = id_ty; + using traits = + basic_sm_traits 1), true, true>; + using internals = detail::basic_internals; + + // If you get a compile error here you have + // failed to define an unsigned id type. + static_assert(std::is_unsigned::value, "Your id type is signed"); + + basic_state_machine() : + _internals() + { + } + + void clear() + { + _internals.clear(); + } + + internals &data() + { + return _internals; + } + + const internals &data() const + { + return _internals; + } + + bool empty() const + { + return _internals.empty(); + } + + id_type eoi() const + { + return _internals._eoi; + } + + void minimise() + { + const id_type dfas_ = static_cast(_internals._dfa.size()); + + for (id_type i_ = 0; i_ < dfas_; ++i_) + { + const id_type dfa_alphabet_ = _internals._dfa_alphabet[i_]; + id_type_vector &dfa_ = _internals._dfa[i_]; + + if (dfa_alphabet_ != 0) + { + std::size_t size_ = 0; + + do + { + size_ = dfa_.size(); + minimise_dfa(dfa_alphabet_, dfa_, size_); + } while (dfa_.size() != size_); + } + } + } + + static id_type npos() + { + return static_cast(~0); + } + + static id_type skip() + { + return static_cast(~1); + } + + void swap(basic_state_machine &rhs_) + { + _internals.swap(rhs_._internals); + } + +private: + using id_type_vector = typename internals::id_type_vector; + using index_set = std::set; + internals _internals; + + void minimise_dfa(const id_type dfa_alphabet_, + id_type_vector &dfa_, std::size_t size_) + { + observer_ptr first_ = &dfa_.front(); + observer_ptr end_ = first_ + size_; + id_type index_ = 1; + id_type new_index_ = 1; + id_type_vector lookup_(size_ / dfa_alphabet_, npos()); + observer_ptr lookup_ptr_ = &lookup_.front(); + index_set index_set_; + const id_type bol_index_ = dfa_.front(); + + *lookup_ptr_ = 0; + // Only one 'jam' state, so skip it. + first_ += dfa_alphabet_; + + for (; first_ < end_; first_ += dfa_alphabet_, ++index_) + { + observer_ptr second_ = first_ + dfa_alphabet_; + + for (id_type curr_index_ = index_ + 1; second_ < end_; + ++curr_index_, second_ += dfa_alphabet_) + { + if (index_set_.find(curr_index_) != index_set_.end()) + { + continue; + } + + // Some systems have memcmp in namespace std. + using namespace std; + + if (memcmp(first_, second_, sizeof(id_type) * + dfa_alphabet_) == 0) + { + index_set_.insert(curr_index_); + lookup_ptr_[curr_index_] = new_index_; + } + } + + if (lookup_ptr_[index_] == npos()) + { + lookup_ptr_[index_] = new_index_; + ++new_index_; + } + } + + if (!index_set_.empty()) + { + observer_ptr front_ = &dfa_.front(); + id_type_vector new_dfa_(front_, front_ + dfa_alphabet_); + auto set_end_ = index_set_.cend(); + observer_ptr ptr_ = front_ + dfa_alphabet_; + observer_ptr new_ptr_ = nullptr; + + new_dfa_.resize(size_ - index_set_.size() * dfa_alphabet_, 0); + new_ptr_ = &new_dfa_.front() + dfa_alphabet_; + size_ /= dfa_alphabet_; + + if (bol_index_) + { + new_dfa_.front() = lookup_ptr_[bol_index_]; + } + + for (index_ = 1; index_ < size_; ++index_) + { + if (index_set_.find(index_) != set_end_) + { + ptr_ += dfa_alphabet_; + continue; + } + + new_ptr_[end_state_index] = ptr_[end_state_index]; + new_ptr_[id_index] = ptr_[id_index]; + new_ptr_[user_id_index] = ptr_[user_id_index]; + new_ptr_[push_dfa_index] = ptr_[push_dfa_index]; + new_ptr_[next_dfa_index] = ptr_[next_dfa_index]; + new_ptr_[eol_index] = lookup_ptr_[ptr_[eol_index]]; + new_ptr_ += transitions_index; + ptr_ += transitions_index; + + for (id_type i_ = transitions_index; i_ < dfa_alphabet_; ++i_) + { + *new_ptr_++ = lookup_ptr_[*ptr_++]; + } + } + + dfa_.swap(new_dfa_); + } + } +}; + +using state_machine = basic_state_machine; +using wstate_machine = basic_state_machine; +using u32state_machine = basic_state_machine; + +template +struct basic_char_state_machine +{ + using id_type = id_ty; + using traits = basic_sm_traits; + using internals = detail::basic_internals; + using id_type_vector = typename internals::id_type_vector; + + struct state + { + using string_token = basic_string_token; + using id_type_string_token_map = std::map; + using id_type_string_token_pair = std::pair; + enum push_pop_dfa {neither, push_dfa, pop_dfa}; + + bool _end_state; + push_pop_dfa _push_pop_dfa; + id_type _id; + id_type _user_id; + id_type _push_dfa; + id_type _next_dfa; + id_type _eol_index; + id_type_string_token_map _transitions; + + state() : + _end_state(false), + _push_pop_dfa(neither), + _id(0), + _user_id(traits::npos()), + _push_dfa(traits::npos()), + _next_dfa(0), + _eol_index(traits::npos()), + _transitions() + { + } + + bool operator ==(const state rhs_) const + { + return _end_state == rhs_._end_state && + _push_pop_dfa == rhs_._push_pop_dfa && + _id == rhs_._id && + _user_id == rhs_._user_id && + _push_dfa == rhs_._push_dfa && + _next_dfa == rhs_._next_dfa && + _eol_index == rhs_._eol_index && + _transitions == rhs_._transitions; + } + }; + + using string_token = typename state::string_token; + using state_vector = std::vector; + using string_token_vector = std::vector; + using id_type_string_token_pair = + typename state::id_type_string_token_pair; + + struct dfa + { + id_type _bol_index; + state_vector _states; + + dfa(const std::size_t size_) : + _bol_index(traits::npos()), + _states(state_vector(size_)) + { + } + + std::size_t size() const + { + return _states.size(); + } + + void swap(dfa &rhs_) + { + std::swap(_bol_index, rhs_._bol_index); + _states.swap(rhs_._states); + } + }; + + static_assert(std::is_move_assignable::value && + std::is_move_constructible::value, "dfa is not movable."); + using dfa_vector = std::vector; + + static_assert(std::is_unsigned::value, "Your id type is signed"); + dfa_vector _sm_vector; + + basic_char_state_machine() : + _sm_vector() + { + } + + void append(const string_token_vector &token_vector_, + const internals &internals_, const id_type dfa_index_) + { + const std::size_t dfa_alphabet_ = internals_._dfa_alphabet[dfa_index_]; + const std::size_t alphabet_ = dfa_alphabet_ - transitions_index; + const id_type_vector &source_dfa_ = internals_._dfa[dfa_index_]; + observer_ptr ptr_ = &source_dfa_.front(); + const std::size_t size_ = (source_dfa_.size() - dfa_alphabet_) / + dfa_alphabet_; + typename state::id_type_string_token_map::iterator trans_iter_; + + _sm_vector.push_back(dfa(size_)); + + dfa &dest_dfa_ = _sm_vector.back(); + + if (*ptr_) + { + dest_dfa_._bol_index = *ptr_ - 1; + } + + ptr_ += dfa_alphabet_; + + for (id_type i_ = 0; i_ < size_; ++i_) + { + state &state_ = dest_dfa_._states[i_]; + + state_._end_state = ptr_[end_state_index] != 0; + + if (ptr_[push_dfa_index] != npos()) + { + state_._push_pop_dfa = state::push_dfa; + } + else if (ptr_[end_state_index] & pop_dfa_bit) + { + state_._push_pop_dfa = state::pop_dfa; + } + + state_._id = ptr_[id_index]; + state_._user_id = ptr_[user_id_index]; + state_._push_dfa = ptr_[push_dfa_index]; + state_._next_dfa = ptr_[next_dfa_index]; + + if (ptr_[eol_index]) + { + state_._eol_index = ptr_[eol_index] - 1; + } + + ptr_ += transitions_index; + + for (id_type col_index_ = 0; col_index_ < alphabet_; + ++col_index_, ++ptr_) + { + const id_type next_ = *ptr_; + + if (next_ > 0) + { + trans_iter_ = state_._transitions.find(next_ - 1); + + if (trans_iter_ == state_._transitions.end()) + { + trans_iter_ = state_._transitions.insert + (id_type_string_token_pair(static_cast + (next_ - 1), token_vector_[col_index_])).first; + } + else + { + trans_iter_->second.insert(token_vector_[col_index_]); + } + } + } + } + } + + void clear() + { + _sm_vector.clear(); + } + + bool empty() const + { + return _sm_vector.empty(); + } + + void minimise() + { + const id_type dfas_ = static_cast(_sm_vector.size()); + + for (id_type i_ = 0; i_ < dfas_; ++i_) + { + observer_ptr dfa_ = &_sm_vector[i_]; + + if (dfa_->size() > 0) + { + std::size_t size_ = 0; + + do + { + size_ = dfa_->size(); + minimise_dfa(*dfa_, size_); + } while (dfa_->size() != size_); + } + } + } + + static id_type npos() + { + return traits::npos(); + } + + id_type size() const + { + return static_cast(_sm_vector.size()); + } + + static id_type skip() + { + return ~static_cast(1); + } + + void swap(basic_char_state_machine &csm_) + { + _sm_vector.swap(csm_._sm_vector); + } + +private: + using index_set = std::set; + + void minimise_dfa(dfa &dfa_, std::size_t size_) + { + observer_ptr first_ = &dfa_._states.front(); + observer_ptr end_ = first_ + size_; + id_type index_ = 0; + id_type new_index_ = 0; + id_type_vector lookup_(size_, npos()); + observer_ptr lookup_ptr_ = &lookup_.front(); + index_set index_set_; + + for (; first_ != end_; ++first_, ++index_) + { + observer_ptr second_ = first_ + 1; + + for (id_type curr_index_ = index_ + 1; second_ != end_; + ++curr_index_, ++second_) + { + if (index_set_.find(curr_index_) != index_set_.end()) + { + continue; + } + + if (*first_ == *second_) + { + index_set_.insert(curr_index_); + lookup_ptr_[curr_index_] = new_index_; + } + } + + if (lookup_ptr_[index_] == npos()) + { + lookup_ptr_[index_] = new_index_; + ++new_index_; + } + } + + if (!index_set_.empty()) + { + observer_ptr front_ = &dfa_._states.front(); + dfa new_dfa_(new_index_); + auto set_end_ = index_set_.cend(); + observer_ptr ptr_ = front_; + observer_ptr new_ptr_ = &new_dfa_._states.front(); + + if (dfa_._bol_index != npos()) + { + new_dfa_._bol_index = lookup_ptr_[dfa_._bol_index]; + } + + for (index_ = 0; index_ < size_; ++index_) + { + if (index_set_.find(index_) != set_end_) + { + ++ptr_; + continue; + } + + new_ptr_->_end_state = ptr_->_end_state; + new_ptr_->_id = ptr_->_end_state; + new_ptr_->_user_id = ptr_->_user_id; + new_ptr_->_next_dfa = ptr_->_next_dfa; + + if (ptr_->_eol_index != npos()) + { + new_ptr_->_eol_index = lookup_ptr_[ptr_->_eol_index]; + } + + auto iter_ = ptr_->_transitions.cbegin(); + auto end_ = ptr_->_transitions.cend(); + typename state::id_type_string_token_map::iterator find_; + + for (; iter_ != end_; ++iter_) + { + find_ = new_ptr_->_transitions.find + (lookup_ptr_[iter_->first]); + + if (find_ == new_ptr_->_transitions.end()) + { + new_ptr_->_transitions.insert + (id_type_string_token_pair + (lookup_ptr_[iter_->first], iter_->second)); + } + else + { + find_->second.insert(iter_->second); + } + } + + ++ptr_; + ++new_ptr_; + } + + dfa_.swap(new_dfa_); + } + } +}; + +using char_state_machine = basic_char_state_machine; +using wchar_state_machine = basic_char_state_machine; +using u32char_state_machine = basic_char_state_machine; +} + +#endif diff --git a/YACReaderLibrary/lexertl/stream_shared_iterator.hpp b/YACReaderLibrary/lexertl/stream_shared_iterator.hpp new file mode 100644 index 000000000..7946390f2 --- /dev/null +++ b/YACReaderLibrary/lexertl/stream_shared_iterator.hpp @@ -0,0 +1,352 @@ +// stream_shared_iterator.hpp +// Copyright (c) 2010-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_STREAM_SHARED_ITERATOR_HPP +#define LEXERTL_STREAM_SHARED_ITERATOR_HPP + +#include +// memcpy +#include +#include +#include +#include "runtime_error.hpp" +#include + +namespace lexertl +{ +template +class basic_stream_shared_iterator +{ +public: + using istream = std::basic_istream; + using iterator_category = std::forward_iterator_tag; + using difference_type = std::size_t; + using value_type = char_type; + using pointer = char_type *; + using reference = char_type &; + + basic_stream_shared_iterator() : + _master(false), + _live(false), + _index(shared::npos()), + _shared(nullptr) + { + } + + basic_stream_shared_iterator(istream &stream_, + const std::size_t buff_size_ = 1024, + const std::size_t increment_ = 1024) : + _master(true), + _live(false), + _index(shared::npos()), + // For exception safety don't call new yet + _shared(nullptr) + { + // Safe to call potentially throwing new now. + _shared = new shared(stream_, buff_size_, increment_); + ++_shared->_ref_count; + _shared->_clients.push_back(this); + } + + basic_stream_shared_iterator(const basic_stream_shared_iterator &rhs_) : + _master(false), + _live(false), + _index(rhs_._master ? rhs_._shared->lowest() : rhs_._index), + _shared(rhs_._shared) + { + if (_shared) + { + // New copy of an iterator. + // The assumption is that any copy must be live + // even if the rhs is not (otherwise we will never + // have a record of the start of the current range!) + ++_shared->_ref_count; + _shared->_clients.push_back(this); + _live = true; + } + } + + ~basic_stream_shared_iterator() + { + if (_shared) + { + --_shared->_ref_count; + _shared->erase(this); + + if (_shared->_ref_count == 0) + { + delete _shared; + _shared = nullptr; + } + } + } + + basic_stream_shared_iterator &operator = + (const basic_stream_shared_iterator &rhs_) + { + if (this != &rhs_) + { + _master = false; + _index = rhs_._master ? rhs_._shared->lowest() : rhs_._index; + + if (!_live && !rhs_._live) + { + if (rhs_._shared) + { + ++rhs_._shared->_ref_count; + } + } + else if (!_live && rhs_._live) + { + rhs_._shared->_clients.push_back(this); + + if (!_shared) + { + ++rhs_._shared->_ref_count; + } + } + else if (_live && !rhs_._live) + { + _shared->erase(this); + + if (!rhs_._shared) + { + --_shared->_ref_count; + } + } + + _live = rhs_._live; + _shared = rhs_._shared; + } + + return *this; + } + + bool operator ==(const basic_stream_shared_iterator &rhs_) const + { + return _index == rhs_._index && + (_shared == rhs_._shared || + (_index == shared::npos() || rhs_._index == shared::npos()) && + (!_shared || !rhs_._shared)); + } + + bool operator !=(const basic_stream_shared_iterator &rhs_) const + { + return !(*this == rhs_); + } + + const char_type &operator *() + { + check_master(); + return _shared->_buffer[_index]; + } + + basic_stream_shared_iterator &operator ++() + { + check_master(); + ++_index; + update_state(); + return *this; + } + + basic_stream_shared_iterator operator ++(int) + { + basic_stream_shared_iterator iter_ = *this; + + check_master(); + ++_index; + update_state(); + return iter_; + } + +private: + class shared + { + public: + std::size_t _ref_count; + using char_vector = std::vector; + using iter_list = std::vector; + istream &_stream; + std::size_t _increment; + std::size_t _len; + char_vector _buffer; + iter_list _clients; + + shared(istream &stream_, const std::size_t buff_size_, + const std::size_t increment_) : + _ref_count(0), + _increment(increment_), + _stream(stream_) + { + _buffer.resize(buff_size_); + _stream.read(&_buffer.front(), _buffer.size()); + _len = static_cast(_stream.gcount()); + } + + bool reload_buffer() + { + const std::size_t lowest_ = lowest(); + std::size_t read_ = 0; + + if (lowest_ == 0) + { + // Resize buffer + const std::size_t old_size_ = _buffer.size(); + const std::size_t new_size_ = old_size_ + _increment; + + _buffer.resize(new_size_); + _stream.read(&_buffer.front() + old_size_, _increment); + read_ = static_cast(_stream.gcount()); + + if (read_) + { + read_ += old_size_; + _len = read_; + } + } + else + { + // Some systems have memcpy in namespace std + using namespace std; + const size_t start_ = _buffer.size() - lowest_; + const size_t len_ = _buffer.size() - start_; + + memcpy(&_buffer.front(), &_buffer[lowest_], start_ * + sizeof(char_type)); + _stream.read(&_buffer.front() + start_, len_); + read_ = static_cast(_stream.gcount()); + subtract(lowest_); + + if (read_) + { + read_ += start_; + _len = read_; + } + else + { + _len = highest(); + } + } + + return read_ != 0; + } + + void erase(basic_stream_shared_iterator *ptr_) + { + auto iter_ = std::find(_clients.begin(), _clients.end(), ptr_); + + if (iter_ != _clients.end()) + _clients.erase(iter_); + } + + std::size_t lowest() const + { + std::size_t lowest_ = npos(); + auto iter_ = _clients.cbegin(); + auto end_ = _clients.cend(); + + for (; iter_ != end_; ++iter_) + { + const basic_stream_shared_iterator *ptr_ = *iter_; + + if (ptr_->_index < lowest_) + { + lowest_ = ptr_->_index; + } + } + + if (lowest_ == npos()) + { + lowest_ = 0; + } + + return lowest_; + } + + std::size_t highest() const + { + std::size_t highest_ = 0; + auto iter_ = _clients.cbegin(); + auto end_ = _clients.cend(); + + for (; iter_ != end_; ++iter_) + { + const basic_stream_shared_iterator *ptr_ = *iter_; + + if (ptr_->_index != npos() && ptr_->_index > highest_) + { + highest_ = ptr_->_index; + } + } + + return highest_; + } + + void subtract(const std::size_t lowest_) + { + auto iter_ = _clients.begin(); + auto end_ = _clients.end(); + + for (; iter_ != end_; ++iter_) + { + basic_stream_shared_iterator *ptr_ = *iter_; + + if (ptr_->_index != npos()) + { + ptr_->_index -= lowest_; + } + } + } + + static std::size_t npos() + { + return ~static_cast(0); + } + + private: + shared &operator =(const shared &rhs_); + }; + + bool _master; + bool _live; + std::size_t _index; + shared *_shared; + + void check_master() + { + if (!_shared) + { + throw runtime_error("Cannot manipulate null (end) " + "stream_shared_iterators."); + } + + if (_master) + { + _master = false; + _live = true; + _index = _shared->lowest(); + } + } + + void update_state() + { + if (_index >= _shared->_len) + { + if (!_shared->reload_buffer()) + { + _shared->erase(this); + _index = shared::npos(); + _live = false; + } + } + } +}; + +using stream_shared_iterator = basic_stream_shared_iterator; +using wstream_shared_iterator = basic_stream_shared_iterator; +} + +#endif diff --git a/YACReaderLibrary/lexertl/string_token.hpp b/YACReaderLibrary/lexertl/string_token.hpp new file mode 100644 index 000000000..e108bd124 --- /dev/null +++ b/YACReaderLibrary/lexertl/string_token.hpp @@ -0,0 +1,439 @@ +// string_token.hpp +// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_STRING_TOKEN_HPP +#define LEXERTL_STRING_TOKEN_HPP + +#include "char_traits.hpp" +#include // Needed by GCC 4.4 +#include +#include +#include +#include + +namespace lexertl +{ +template +struct basic_string_token +{ + using char_type = ch_type; + using char_traits = basic_char_traits; + using index_type = typename char_traits::index_type; + using range = std::pair; + using range_vector = std::vector; + using string = std::basic_string; + using string_token = basic_string_token; + + range_vector _ranges; + + basic_string_token() : + _ranges() + { + } + + basic_string_token(char_type ch_) : + _ranges() + { + insert(range(ch_, ch_)); + } + + basic_string_token(char_type first_, char_type second_) : + _ranges() + { + insert(range(first_, second_)); + } + + void clear() + { + _ranges.clear(); + } + + bool empty() const + { + return _ranges.empty(); + } + + bool any() const + { + return _ranges.size() == 1 && _ranges.front().first == 0 && + _ranges.front().second == char_traits::max_val(); + } + + bool operator <(const basic_string_token &rhs_) const + { + return _ranges < rhs_._ranges; + } + + bool operator ==(const basic_string_token &rhs_) const + { + return _ranges == rhs_._ranges; + } + + bool negatable() const + { + std::size_t size_ = 0; + auto iter_ = _ranges.cbegin(); + auto end_ = _ranges.cend(); + + for (; iter_ != end_; ++iter_) + { + size_ += static_cast(iter_->second) + 1 - + static_cast(iter_->first); + } + + return size_ > static_cast(char_traits::max_val()) / 2; + } + + void swap(basic_string_token &rhs_) + { + _ranges.swap(rhs_._ranges); + } + + void insert(const basic_string_token &rhs_) + { + auto iter_ = rhs_._ranges.cbegin(); + auto end_ = rhs_._ranges.cend(); + + for (; iter_ != end_; ++iter_) + { + insert(*iter_); + } + } + + // Deliberately pass by value - may modify + typename range_vector::iterator insert(range rhs_) + { + bool insert_ = true; + auto iter_ = _ranges.begin(); + auto end_ = _ranges.end(); + auto erase_iter_ = end_; + + while (iter_ != end_) + { + // follows current item + if (rhs_.first > iter_->second) + { + if (rhs_.first == iter_->second + 1) + { + // Auto normalise + rhs_.first = iter_->first; + } + else + { + // No intersection, consider next + ++iter_; + continue; + } + } + // Precedes current item + else if (rhs_.second < iter_->first) + { + if (rhs_.second == iter_->first - 1) + { + // Auto normalise + rhs_.second = iter_->second; + } + else + { + // insert here + break; + } + } + else + { + // overlap (under) + if (rhs_.first < iter_->first) + { + if (rhs_.second < iter_->second) + { + rhs_.second = iter_->second; + } + } + // overlap (over) + else if (rhs_.second > iter_->second) + { + if (rhs_.first > iter_->first) + { + rhs_.first = iter_->first; + } + } + // subset + else + { + insert_ = false; + iter_ = _ranges.end(); + break; + } + } + + // Code minimisation: this always applies unless we have already + // exited the loop, or "continue" executed. + if (erase_iter_ == end_) + { + erase_iter_ = iter_; + } + + ++iter_; + } + + if (erase_iter_ != end_) + { + if (insert_) + { + // Re-use obsolete location + *erase_iter_ = rhs_; + ++erase_iter_; + } + + iter_ = _ranges.erase(erase_iter_, iter_); + } + else if (insert_) + { + iter_ = _ranges.insert(iter_, rhs_); + } + + return iter_; + } + + void negate() + { + index_type next_ = 0; + const index_type max_ = char_traits::max_val(); + string_token temp_; + auto iter_ = _ranges.cbegin(); + auto end_ = _ranges.cend(); + bool finished_ = false; + + for (; iter_ != end_; ++iter_) + { + if (next_ < iter_->first) + { + temp_.insert(range(next_, + static_cast(iter_->first - 1))); + } + + if (iter_->second < max_) + { + next_ = iter_->second + 1; + } + else + { + finished_ = true; + break; + } + } + + if (!finished_) + { + temp_.insert(range(next_, max_)); + } + + swap(temp_); + } + + void intersect(basic_string_token &rhs_, basic_string_token &overlap_) + { + auto lhs_iter_ = _ranges.begin(); + auto lhs_end_ = _ranges.end(); + auto rhs_iter_ = rhs_._ranges.begin(); + auto rhs_end_ = rhs_._ranges.end(); + + while (lhs_iter_ != lhs_end_ && rhs_iter_ != rhs_end_) + { + if (rhs_iter_->first > lhs_iter_->second) + { + ++lhs_iter_; + } + else if (rhs_iter_->second < lhs_iter_->first) + { + ++rhs_iter_; + } + else + { + range range_; + + if (rhs_iter_->first > lhs_iter_->first) + { + range_.first = rhs_iter_->first; + } + else + { + range_.first = lhs_iter_->first; + } + + if (rhs_iter_->second < lhs_iter_->second) + { + range_.second = rhs_iter_->second; + } + else + { + range_.second = lhs_iter_->second; + } + + adjust(range_, *this, lhs_iter_, lhs_end_); + adjust(range_, rhs_, rhs_iter_, rhs_end_); + overlap_.insert(range_); + } + } + } + + void remove(basic_string_token &rhs_) + { + auto lhs_iter_ = _ranges.begin(); + auto lhs_end_ = _ranges.end(); + auto rhs_iter_ = rhs_._ranges.begin(); + auto rhs_end_ = rhs_._ranges.end(); + + while (lhs_iter_ != lhs_end_ && rhs_iter_ != rhs_end_) + { + if (rhs_iter_->first > lhs_iter_->second) + { + ++lhs_iter_; + } + else if (rhs_iter_->second < lhs_iter_->first) + { + ++rhs_iter_; + } + else + { + range range_; + + if (rhs_iter_->first > lhs_iter_->first) + { + range_.first = rhs_iter_->first; + } + else + { + range_.first = lhs_iter_->first; + } + + if (rhs_iter_->second < lhs_iter_->second) + { + range_.second = rhs_iter_->second; + } + else + { + range_.second = lhs_iter_->second; + } + + adjust(range_, *this, lhs_iter_, lhs_end_); + } + } + } + + static string escape_char(const typename char_traits::index_type ch_) + { + string out_; + + switch (ch_) + { + case '\0': + out_ += '\\'; + out_ += '0'; + break; + case '\a': + out_ += '\\'; + out_ += 'a'; + break; + case '\b': + out_ += '\\'; + out_ += 'b'; + break; + case 27: + out_ += '\\'; + out_ += 'x'; + out_ += '1'; + out_ += 'b'; + break; + case '\f': + out_ += '\\'; + out_ += 'f'; + break; + case '\n': + out_ += '\\'; + out_ += 'n'; + break; + case '\r': + out_ += '\\'; + out_ += 'r'; + break; + case '\t': + out_ += '\\'; + out_ += 't'; + break; + case '\v': + out_ += '\\'; + out_ += 'v'; + break; + case '\\': + out_ += '\\'; + out_ += '\\'; + break; + case '"': + out_ += '\\'; + out_ += '"'; + break; + case '\'': + out_ += '\\'; + out_ += '\''; + break; + default: + { + if (ch_ < 32 || ch_ > 126) + { + std::basic_stringstream ss_; + + out_ += '\\'; + out_ += 'x'; + ss_ << std::hex << + static_cast(ch_); + out_ += ss_.str(); + } + else + { + out_ += ch_; + } + + break; + } + } + + return out_; + } + +private: + void adjust(const range &range_, basic_string_token &token_, + typename range_vector::iterator &iter_, + typename range_vector::iterator &end_) + { + if (range_.first > iter_->first) + { + const index_type second_ = iter_->second; + + iter_->second = range_.first - 1; + + if (range_.second < second_) + { + range new_range_(static_cast(range_.second + 1), + second_); + + iter_ = token_.insert(new_range_); + end_ = token_._ranges.end(); + } + } + else if (range_.second < iter_->second) + { + iter_->first = range_.second + 1; + } + else + { + iter_ = token_._ranges.erase(iter_); + end_ = token_._ranges.end(); + } + } +}; +} + +#endif diff --git a/YACReaderLibrary/lexertl/utf_iterators.hpp b/YACReaderLibrary/lexertl/utf_iterators.hpp new file mode 100644 index 000000000..0bd64e7cb --- /dev/null +++ b/YACReaderLibrary/lexertl/utf_iterators.hpp @@ -0,0 +1,508 @@ +// utf_iterators.hpp +// Copyright (c) 2015-2018 Ben Hanson (http://www.benhanson.net/) +// Inspired by http://utfcpp.sourceforge.net/ +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_UTF_ITERATORS_HPP +#define LEXERTL_UTF_ITERATORS_HPP + +#include + +namespace lexertl +{ +template +class basic_utf8_in_iterator : + public std::iterator +{ +public: + using value_type = char_type; + using difference_type = + typename std::iterator_traits::difference_type; + using iterator_category = std::forward_iterator_tag; + + basic_utf8_in_iterator() : + _it(char_iterator()), + _end(char_iterator()), + _char(0) + { + } + + explicit basic_utf8_in_iterator(const char_iterator &it_, + const char_iterator &end_) : + _it(it_), + _end(it_), + _char(0) + { + if (it_ != end_) + { + next(); + } + } + + char_type operator *() const + { + return _char; + } + + bool operator ==(const basic_utf8_in_iterator &rhs_) const + { + return _it == rhs_._it; + } + + bool operator !=(const basic_utf8_in_iterator &rhs_) const + { + return _it != rhs_._it; + } + + basic_utf8_in_iterator &operator ++() + { + _it = _end; + next(); + return *this; + } + + basic_utf8_in_iterator operator ++(int) + { + basic_utf8_in_iterator temp_ = *this; + + _it = _end; + next(); + return temp_; + } + + basic_utf8_in_iterator operator +(const std::size_t count_) const + { + basic_utf8_in_iterator temp_ = *this; + + for (std::size_t i_ = 0; i_ < count_; ++i_) + { + ++temp_; + } + + return temp_; + } + + basic_utf8_in_iterator operator -(const std::size_t count_) const + { + basic_utf8_in_iterator temp_ = *this; + + for (std::size_t i_ = 0; i_ < count_; ++i_) + { + temp_._end = temp_._it; + --temp_._it; + + while ((*temp_._it & 0xc0) == 0x80) --temp_._it; + } + + temp_.next(); + return temp_; + } + +private: + char_iterator _it; + char_iterator _end; + char_type _char; + + void next() + { + const char len_ = len(_it); + char_type ch_ = *_it & 0xff; + + switch (len_) + { + case 1: + _end = _it; + ++_end; + break; + case 2: + _end = _it; + ++_end; + + if ((*_end & 0xc0) != 0x80) break; + + ch_ = (ch_ << 6 & 0x7ff) | (*_end & 0x3f); + ++_end; + break; + case 3: + _end = _it; + ++_end; + + if ((*_end & 0xc0) != 0x80) break; + + ch_ = (ch_ << 12 & 0xffff) | ((*_end & 0xff) << 6 & 0xfff); + ++_end; + + if ((*_end & 0xc0) != 0x80) break; + + ch_ |= *_end & 0x3f; + ++_end; + break; + case 4: + _end = _it; + ++_end; + + if ((*_end & 0xc0) != 0x80) break; + + ch_ = (ch_ << 18 & 0x1fffff) | ((*_end & 0xff) << 12 & 0x3ffff); + ++_end; + + if ((*_end & 0xc0) != 0x80) break; + + ch_ |= (*_end & 0xff) << 6 & 0xfff; + ++_end; + + if ((*_end & 0xc0) != 0x80) break; + + ch_ |= *_end & 0x3f; + ++_end; + break; + } + + _char = ch_; + } + + char len(const char_iterator &it_) const + { + const unsigned char ch_ = *it_; + + return ch_ < 0x80 ? 1 : + ch_ >> 5 == 0x06 ? 2 : + ch_ >> 4 == 0x0e ? 3 : + ch_ >> 3 == 0x1e ? 4 : + 1; + } +}; + +template +class basic_utf8_out_iterator : + public std::iterator +{ +public: + using value_type = char; + using difference_type = + typename std::iterator_traits::difference_type; + using iterator_category = std::forward_iterator_tag; + + basic_utf8_out_iterator() : + _count(0), + _index(0) + { + } + + explicit basic_utf8_out_iterator(const char_iterator &it_, + const char_iterator &end_) : + _it(it_), + _count(0), + _index(0) + { + if (it_ != end_) + { + next(); + } + } + + char operator *() const + { + return _bytes[_index]; + } + + bool operator ==(const basic_utf8_out_iterator &rhs_) const + { + return _it == rhs_._it; + } + + bool operator !=(const basic_utf8_out_iterator &rhs_) const + { + return _it != rhs_._it; + } + + basic_utf8_out_iterator &operator ++() + { + ++_index; + + if (_index >= _count) + { + ++_it; + next(); + } + + return *this; + } + + basic_utf8_out_iterator operator ++(int) + { + basic_utf8_out_iterator temp_ = *this; + + ++_index; + + if (_index >= _count) + { + ++_it; + next(); + } + + return temp_; + } + +private: + char_iterator _it; + char _bytes[4]; + unsigned char _count; + unsigned char _index; + + void next() + { + const std::size_t ch_ = *_it; + + _count = len(ch_); + _index = 0; + + switch (_count) + { + case 1: + _bytes[0] = static_cast(ch_); + break; + case 2: + _bytes[0] = static_cast((ch_ >> 6) | 0xc0); + _bytes[1] = (ch_ & 0x3f) | 0x80; + break; + case 3: + _bytes[0] = static_cast((ch_ >> 12) | 0xe0); + _bytes[1] = ((ch_ >> 6) & 0x3f) | 0x80; + _bytes[2] = (ch_ & 0x3f) | 0x80; + break; + case 4: + _bytes[0] = static_cast((ch_ >> 18) | 0xf0); + _bytes[1] = ((ch_ >> 12) & 0x3f) | 0x80; + _bytes[2] = ((ch_ >> 6) & 0x3f) | 0x80; + _bytes[3] = (ch_ & 0x3f) | 0x80; + break; + } + } + + char len(const std::size_t ch_) const + { + return ch_ < 0x80 ? 1 : + ch_ < 0x800 ? 2 : + ch_ < 0x10000 ? 3 : + 4; + } +}; + +template +class basic_utf16_in_iterator : + public std::iterator +{ +public: + using value_type = char_type; + using difference_type = + typename std::iterator_traits::difference_type; + using iterator_category = std::forward_iterator_tag; + + basic_utf16_in_iterator() : + _it(char_iterator()), + _end(char_iterator()), + _char(0) + { + } + + explicit basic_utf16_in_iterator(const char_iterator &it_, + const char_iterator &end_) : + _it(it_), + _end(it_), + _char(0) + { + if (it_ != end_) + { + next(); + } + } + + char_type operator *() const + { + return _char; + } + + bool operator ==(const basic_utf16_in_iterator &rhs_) const + { + return _it == rhs_._it; + } + + bool operator !=(const basic_utf16_in_iterator &rhs_) const + { + return _it != rhs_._it; + } + + basic_utf16_in_iterator &operator ++() + { + _it = _end; + next(); + return *this; + } + + basic_utf16_in_iterator operator ++(int) + { + basic_utf16_in_iterator temp_ = *this; + + _it = _end; + next(); + return temp_; + } + + basic_utf16_in_iterator operator +(const std::size_t count_) const + { + basic_utf16_in_iterator temp_ = *this; + + for (std::size_t i_ = 0; i_ < count_; ++i_) + { + ++temp_; + } + + return temp_; + } + + basic_utf16_in_iterator operator -(const std::size_t count_) const + { + basic_utf16_in_iterator temp_ = *this; + + for (std::size_t i_ = 0; i_ < count_; ++i_) + { + temp_._end = temp_._it; + --temp_._it; + + if (*temp_._it >= 0xdc00 && *temp_._it <= 0xdfff) --temp_._it; + } + + temp_.next(); + return temp_; + } + +private: + char_iterator _it; + char_iterator _end; + char_type _char; + + void next() + { + char_type ch_ = *_it & 0xffff; + + _end = _it; + + if (ch_ >= 0xd800 && ch_ <= 0xdbff) + { + const char_type surrogate_ = *++_end & 0xffff; + + ch_ = (((ch_ - 0xd800) << 10) | (surrogate_ - 0xdc00)) + 0x10000; + } + + _char = ch_; + ++_end; + } +}; + +template +class basic_utf16_out_iterator : + public std::iterator +{ +public: + using value_type = wchar_t; + using difference_type = + typename std::iterator_traits::difference_type; + using iterator_category = std::forward_iterator_tag; + + basic_utf16_out_iterator() : + _count(0), + _index(0) + { + } + + explicit basic_utf16_out_iterator(const char_iterator &it_, + const char_iterator &end_) : + _it(it_), + _count(0), + _index(0) + { + if (it_ != end_) + { + next(); + } + } + + wchar_t operator *() const + { + return _chars[_index]; + } + + bool operator ==(const basic_utf16_out_iterator &rhs_) const + { + return _it == rhs_._it; + } + + bool operator !=(const basic_utf16_out_iterator &rhs_) const + { + return _it != rhs_._it; + } + + basic_utf16_out_iterator &operator ++() + { + ++_index; + + if (_index >= _count) + { + ++_it; + next(); + } + + return *this; + } + + basic_utf16_out_iterator operator ++(int) + { + basic_utf16_out_iterator temp_ = *this; + + ++_index; + + if (_index >= _count) + { + ++_it; + next(); + } + + return temp_; + } + +private: + char_iterator _it; + wchar_t _chars[2]; + unsigned char _count; + unsigned char _index; + + void next() + { + const std::size_t ch_ = *_it; + + _count = len(ch_); + _index = 0; + + switch (_count) + { + case 1: + _chars[0] = static_cast(ch_); + break; + case 2: + _chars[0] = static_cast((ch_ >> 10) + 0xdc00u - + (0x10000 >> 10)); + _chars[1] = static_cast((ch_ & 0x3ff) + 0xdc00u); + break; + } + } + + char len(const std::size_t ch_) const + { + return ch_ > 0xffff ? 2 : 1; + } +}; +} + +#endif From 4a50d438d037fad28835fe2f2bd32b72c8bd37fb Mon Sep 17 00:00:00 2001 From: Iain Benson Date: Sun, 18 Nov 2018 21:25:36 +0000 Subject: [PATCH 006/141] Add query parser class --- YACReaderLibrary/YACReaderLibrary.pro | 8 +- YACReaderLibrary/db/query_parser.cpp | 237 ++++++++++++++++++++++++++ YACReaderLibrary/db/query_parser.h | 63 +++++++ 3 files changed, 305 insertions(+), 3 deletions(-) create mode 100644 YACReaderLibrary/db/query_parser.cpp create mode 100644 YACReaderLibrary/db/query_parser.h diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 1ea60e8b0..8f79b7066 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -67,8 +67,8 @@ macx { QT += macextras gui-private } -unix:!macx { - CONFIG += c++11 +unix { + CONFIG += c++1z } #CONFIG += release @@ -147,6 +147,7 @@ HEADERS += comic_flow.h \ yacreader_comics_selection_helper.h \ yacreader_comic_info_helper.h \ db/reading_list.h \ + db/query_parser.h \ current_comic_view_helper.h \ lexertl/parser/tokeniser/re_token.hpp \ lexertl/parser/tokeniser/re_tokeniser.hpp \ @@ -254,7 +255,8 @@ SOURCES += comic_flow.cpp \ yacreader_comics_selection_helper.cpp \ yacreader_comic_info_helper.cpp\ db/reading_list.cpp \ - current_comic_view_helper.cpp + current_comic_view_helper.cpp \ + db/query_parser.cpp !CONFIG(no_opengl) { SOURCES += ../common/gl/yacreader_flow_gl.cpp diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp new file mode 100644 index 000000000..f5b1adee1 --- /dev/null +++ b/YACReaderLibrary/db/query_parser.cpp @@ -0,0 +1,237 @@ +#include "query_parser.h" + +#include +#include +#include +#include + + +const std::map> QueryParser::fieldNames { + {FieldType::numeric, {"numpages", "number", "count", "arcnumber", "arccount"}}, + {FieldType::text, {"title", "volume", "storyarc", "genere", "writer", "penciller", "inker", "colorist", "letterer", + "coverartist", "publisher", "format", "agerating", "synopsis", "characters", "notes"}}, + {FieldType::boolean, {"isbis", "color"}}, + {FieldType::date, {"date"} } }; + +int QueryParser::TreeNode::buildSqlString(std::string& sqlString, int bindPosition) const { + if (t == "token") { + ++bindPosition; + std::ostringstream oss; + if (children[0].t == "all") { + oss << "("; + for (const auto& field: fieldNames.at(FieldType::text)) { + oss << "UPPER(ci." << field << ") LIKE UPPER(:bindPosition" << bindPosition << ") OR "; + } + oss << "UPPER(c.fileName) LIKE UPPER(:bindPosition" << bindPosition << ")) "; + } else if (isIn(fieldType(children[0].t), FieldType::numeric, FieldType::boolean)) { + oss << "ci." << children[0].t << " = :bindPosition" << bindPosition << " "; + } else { + oss << "(UPPER(ci." << children[0].t << ") LIKE UPPER(:bindPosition" << bindPosition << ")) "; + } + sqlString += oss.str(); + } else if (t == "not") { + sqlString += "(NOT "; + bindPosition = children[0].buildSqlString(sqlString, bindPosition); + sqlString += ")"; + } else { + sqlString += "("; + bindPosition = children[0].buildSqlString(sqlString, bindPosition); + sqlString += " " + t + " "; + bindPosition = children[1].buildSqlString(sqlString, bindPosition); + sqlString += ")"; + } + + return bindPosition; + } + + int QueryParser::TreeNode::bindValues(QSqlQuery& selectQuery, int bindPosition) const { + if (t == "token") { + std::ostringstream oss; + oss << ":bindPosition" << ++bindPosition; + if (isIn(fieldType(children[0].t), FieldType::numeric, FieldType::boolean)) { + selectQuery.bindValue(oss.str().c_str(), std::stoi(children[1].t)); + } else { + selectQuery.bindValue(oss.str().c_str(), ("%%"+children[1].t+"%%").c_str()); + } + } else if (t == "not") { + bindPosition = children[0].bindValues(selectQuery, bindPosition); + } else { + bindPosition = children[0].bindValues(selectQuery, bindPosition); + bindPosition = children[1].bindValues(selectQuery, bindPosition); + } + + return bindPosition; + } + + +QueryParser::QueryParser(): lexScanner(0) { + + lexScanner.push("[()]", static_cast::type>(TokenType::opcode)); + lexScanner.push("@[^:]+:[^\\\")\\s]+", static_cast::type>(TokenType::atWord)); + lexScanner.push("[^\\\"()\\s]+", static_cast::type>(TokenType::word)); + lexScanner.push("\\\".*?\\\"", static_cast::type>(TokenType::quotedWord)); + lexScanner.push("\\s+", static_cast::type>(TokenType::space)); + + lexertl::generator::build(lexScanner, sm); +} + +QueryParser::TreeNode QueryParser::parse(const std::string& expr) { + tokenize(expr); + auto prog = orExpression(); + + if (!isEof()) { + throw std::invalid_argument("Extra characters at end of search"); + } + + return prog; +} + +std::string QueryParser::toLower(const std::string& string) { + std::string res(string); + std::transform(res.begin(), res.end(), res.begin(), ::tolower); + return res; +} + +std::string QueryParser::token(bool advance) { + if (isEof()) { + return ""; + } + auto res = (tokenType() == TokenType::quotedWord)?iter->substr(1,1):iter->str(); + if (advance) { + this->advance(); + } + return res; +} + +std::string QueryParser::lcaseToken(bool advance) { + if (isEof()) { + return ""; + } + auto res = (tokenType() == TokenType::quotedWord)?iter->substr(1,1):iter->str(); + if (advance) { + this->advance(); + } + return toLower(res); +} + +QueryParser::TokenType QueryParser::tokenType() { + if (isEof()) { + return TokenType::eof; + } + return TokenType(iter->id); +} + +bool QueryParser::isEof() const { + return iter == end; +} + +void QueryParser::advance() { + ++iter; + if (tokenType() == TokenType::space) advance(); +} + +QueryParser::FieldType QueryParser::fieldType(const std::string& str) { + for (const auto& names : fieldNames) { + if (std::find(names.second.begin(), names.second.end(), toLower(str)) != names.second.end()) { + return names.first; + } + } + + return FieldType::unknown; +} + +void QueryParser::tokenize (const std::string& expr) { + // TODO: Strip out escaped backslashes, quotes and parens so that the + // lex scanner doesn't get confused. We put them back later. + + iter = lexertl::siterator(expr.begin(), expr.end(), sm); + + /* for (; !isEof() ; advance()) + { + std::cout << "Id: " << iter->id << ", Token: '" << token() << "'\n"; + } + iter = lexertl::siterator(expr.begin(), expr.end(), sm); + */ +} + +std::string QueryParser::join(const std::vector& strings, const std::string& delim) { + return std::accumulate(strings.begin(), strings.end(), std::string(), + [&delim](const std::string& a, const std::string& b) -> std::string { + return a + (a.length() > 0 && b.length() > 0 ? delim : "") + b; + } ); +} + +std::vector QueryParser::split(const std::string& string, char delim) { + std::istringstream iss(string); + std::vector words; + while(iss) { + std::string substr; + std::getline(iss, substr, delim); + words.push_back(substr); + } + return words; +} + +QueryParser::TreeNode QueryParser::orExpression() { + auto lhs = andExpression(); + if (lcaseToken() == "or") { + advance(); + return {"or", {lhs, orExpression()}}; + } + return lhs; +} + +QueryParser::TreeNode QueryParser::andExpression() { + auto lhs = notExpression(); + if (lcaseToken() == "and") { + advance(); + return {"and", {lhs, andExpression()}}; + } + + if ((isIn(tokenType(), TokenType::atWord, TokenType::word, TokenType::quotedWord) || token() == "(") && lcaseToken() != "or") { + return {"and", {lhs, andExpression()}}; + } + + return lhs; +} + +QueryParser::TreeNode QueryParser::notExpression() { + if (lcaseToken() == "not") { + advance(); + return {"not", {notExpression()}}; + } + return locationExpression(); +} + +QueryParser::TreeNode QueryParser::locationExpression() { + if (tokenType() == TokenType::opcode && token() == "(") { + advance(); + auto res = orExpression(); + if (tokenType() != TokenType::opcode || token(true) != ")") { + throw std::invalid_argument("missing )'"); + } + return res; + } + if (!isIn(tokenType(), TokenType::atWord, TokenType::word, TokenType::quotedWord)) { + throw std::invalid_argument("Invalid syntax. Expected a lookup name or a word"); + } + return baseToken(); +} + +QueryParser::TreeNode QueryParser::baseToken() { + if (tokenType() == TokenType::quotedWord) { + return {"token", {{"all", {}}, {token(true), {}}}}; + } + + auto words(split(token(true), ':')); + + if (words.size() > 1 && fieldType(words[0]) != FieldType::unknown) { + auto loc(toLower(words[0])); + words.erase(words.begin()); + if (words.size() == 1 && tokenType() == TokenType::quotedWord) { + return {"token", {{loc, {}}, {token(true), {}}}}; + } + return {"token", {{loc, {}}, {join(words, ":"), {}}}}; + } + return {"token", {{"all", {}}, {join(words, ":"), {}}}}; +} diff --git a/YACReaderLibrary/db/query_parser.h b/YACReaderLibrary/db/query_parser.h new file mode 100644 index 000000000..868d2b971 --- /dev/null +++ b/YACReaderLibrary/db/query_parser.h @@ -0,0 +1,63 @@ +#ifndef QUERY_PARSER_H +#define QUERY_PARSER_H + +#include "lexertl/generator.hpp" +#include "lexertl/iterator.hpp" + +#include +#include +#include +#include + +class QSqlQuery; + +class QueryParser { +public: + + enum class TokenType {eof, opcode, atWord, word, quotedWord, space}; + + struct TreeNode { + std::string t; + std::vector children; + + int buildSqlString(std::string& sqlString, int bindPosition = 0) const; + int bindValues(QSqlQuery& selectQuery, int bindPosition = 0) const; + }; + + explicit QueryParser(); + TreeNode parse(const std::string& expr); + +private: + static std::string toLower(const std::string& string); + + std::string token(bool advance = false); + std::string lcaseToken(bool advance = false); + TokenType tokenType(); + bool isEof() const; + void advance(); + + template + static bool isIn(First &&first, T && ... t) {return ((first == t) || ...);} + + enum class FieldType {unknown, numeric, text, boolean, date}; + static FieldType fieldType(const std::string& str); + + void tokenize (const std::string& expr); + static std::string join(const std::vector& strings, const std::string& delim); + static std::vector split(const std::string& string, char delim); + + TreeNode orExpression(); + TreeNode andExpression(); + TreeNode notExpression(); + TreeNode locationExpression(); + TreeNode baseToken(); + + lexertl::rules lexScanner; + lexertl::state_machine sm; + lexertl::siterator iter; + const lexertl::siterator end; + + static const std::map> fieldNames; +}; + +#endif // QUERY_PARSER_H From 5fa7da1e4660ab64b6e62ed038c0d28746f519dc Mon Sep 17 00:00:00 2001 From: Iain Benson Date: Sat, 24 Nov 2018 09:54:31 +0000 Subject: [PATCH 007/141] Add folder into the query parser --- YACReaderLibrary/db/query_parser.cpp | 13 ++++++++++--- YACReaderLibrary/db/query_parser.h | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index f5b1adee1..e69c8b81e 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -11,20 +11,27 @@ const std::map> QueryParser::fi {FieldType::text, {"title", "volume", "storyarc", "genere", "writer", "penciller", "inker", "colorist", "letterer", "coverartist", "publisher", "format", "agerating", "synopsis", "characters", "notes"}}, {FieldType::boolean, {"isbis", "color"}}, - {FieldType::date, {"date"} } }; + {FieldType::date, {"date"}}, + {FieldType::filename, {"filename"}}, + {FieldType::folder, {"folder"}} }; int QueryParser::TreeNode::buildSqlString(std::string& sqlString, int bindPosition) const { if (t == "token") { ++bindPosition; std::ostringstream oss; - if (children[0].t == "all") { + if (toLower(children[0].t) == "all") { oss << "("; for (const auto& field: fieldNames.at(FieldType::text)) { oss << "UPPER(ci." << field << ") LIKE UPPER(:bindPosition" << bindPosition << ") OR "; } - oss << "UPPER(c.fileName) LIKE UPPER(:bindPosition" << bindPosition << ")) "; + oss << "UPPER(c.filename) LIKE UPPER(:bindPosition" << bindPosition << ") OR "; + oss << "UPPER(f.name) LIKE UPPER(:bindPosition" << bindPosition << ")) "; } else if (isIn(fieldType(children[0].t), FieldType::numeric, FieldType::boolean)) { oss << "ci." << children[0].t << " = :bindPosition" << bindPosition << " "; + } else if (fieldType(children[0].t) == FieldType::filename) { + oss << "(UPPER(c." << children[0].t << ") LIKE UPPER(:bindPosition" << bindPosition << ")) "; + } else if (fieldType(children[0].t) == FieldType::folder) { + oss << "(UPPER(f.name) LIKE UPPER(:bindPosition" << bindPosition << ")) "; } else { oss << "(UPPER(ci." << children[0].t << ") LIKE UPPER(:bindPosition" << bindPosition << ")) "; } diff --git a/YACReaderLibrary/db/query_parser.h b/YACReaderLibrary/db/query_parser.h index 868d2b971..d77e12435 100644 --- a/YACReaderLibrary/db/query_parser.h +++ b/YACReaderLibrary/db/query_parser.h @@ -39,7 +39,7 @@ class QueryParser { template static bool isIn(First &&first, T && ... t) {return ((first == t) || ...);} - enum class FieldType {unknown, numeric, text, boolean, date}; + enum class FieldType {unknown, numeric, text, boolean, date, folder, filename}; static FieldType fieldType(const std::string& str); void tokenize (const std::string& expr); From 673ee1f067a7052422f9e56c9ebc3d290c809f69 Mon Sep 17 00:00:00 2001 From: Iain Benson Date: Sat, 24 Nov 2018 09:54:59 +0000 Subject: [PATCH 008/141] Use the query parser in the comic and folder model --- YACReaderLibrary/db/comic_model.cpp | 57 +++++++++++++------------- YACReaderLibrary/db/folder_model.cpp | 61 ++++++++++++++++------------ 2 files changed, 63 insertions(+), 55 deletions(-) diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index 7fee8000a..5f795e6a7 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -9,6 +9,7 @@ #include "qnaturalsorting.h" #include "comic_db.h" #include "db_helper.h" +#include "query_parser.h" //ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read #include "QsLog.h" @@ -607,39 +608,39 @@ void ComicModel::setupModelData(const SearchModifiers modifier, const QString &f QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath); QSqlQuery selectQuery(db); - switch (modifier) { - case YACReader::NoModifiers: - selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened " - "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) " - "WHERE UPPER(ci.title) LIKE UPPER(:filter) OR UPPER(c.fileName) LIKE UPPER(:filter) LIMIT :limit"); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - selectQuery.bindValue(":limit", 500); //TODO, load this value from settings - break; + std::string queryString("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened " + "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) LEFT JOIN folder f ON (f.id == c.parentId) WHERE "); - case YACReader::OnlyRead: - selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened " - "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) " - "WHERE (UPPER(ci.title) LIKE UPPER(:filter) OR UPPER(c.fileName) LIKE UPPER(:filter)) AND ci.read = 1 LIMIT :limit"); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - selectQuery.bindValue(":limit", 500); //TODO, load this value from settings - break; + try { + QueryParser parser; + auto result = parser.parse(filter.toStdString()); + result.buildSqlString(queryString); - case YACReader::OnlyUnread: - selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened " - "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) " - "WHERE (UPPER(ci.title) LIKE UPPER(:filter) OR UPPER(c.fileName) LIKE UPPER(:filter)) AND ci.read = 0 LIMIT :limit"); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - selectQuery.bindValue(":limit", 500); //TODO, load this value from settings - break; + switch (modifier) { + case YACReader::NoModifiers: + queryString += "LIMIT :limit"; + break; - default: - QLOG_ERROR() << "not implemented"; - break; - } + case YACReader::OnlyRead: + queryString += "AND ci.read = 1 LIMIT :limit"; + break; - selectQuery.exec(); + case YACReader::OnlyUnread: + queryString += "AND ci.read = 0 LIMIT :limit"; + break; - QLOG_DEBUG() << selectQuery.lastError() << "--"; + default: + queryString += "LIMIT :limit"; + QLOG_ERROR() << "not implemented"; + break; + } + selectQuery.prepare(QString(queryString.c_str())); + selectQuery.bindValue(":limit", 500); //TODO, load this value from settings + result.bindValues(selectQuery); + } catch (const std::exception &e) { + QLOG_ERROR() << "Unable to parse query: " << e.what(); + } + selectQuery.exec(); setupModelData(selectQuery); connectionName = db.connectionName(); diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 640462d7a..902ada19e 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -55,6 +55,7 @@ #include "qnaturalsorting.h" #include "yacreader_global_gui.h" #include "QsLog.h" +#include "query_parser.h" #ifdef Q_OS_MAC #include @@ -689,37 +690,43 @@ void FolderModelProxy::setupFilteredModelData() selectQuery.prepare("select * from folder where id <> 1 and upper(name) like upper(:filter) order by parentId,name "); selectQuery.bindValue(":filter", "%%" + filter + "%%"); } else { - switch (modifier) { - case YACReader::NoModifiers: - selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed " + std::string queryString("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed " "FROM folder f LEFT JOIN comic c ON (f.id = c.parentId) " - "WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) ORDER BY f.parentId,f.name"); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - selectQuery.bindValue(":filter2", "%%" + filter + "%%"); - break; - - case YACReader::OnlyRead: - selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed " - "FROM folder f LEFT JOIN (comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id)) ON (f.id = c.parentId) " - "WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) AND ci.read = 1 ORDER BY f.parentId,f.name;"); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - selectQuery.bindValue(":filter2", "%%" + filter + "%%"); - break; - - case YACReader::OnlyUnread: - selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed " - "FROM folder f LEFT JOIN (comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id)) ON (f.id = c.parentId) " - "WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) AND ci.read = 0 ORDER BY f.parentId,f.name;"); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - selectQuery.bindValue(":filter2", "%%" + filter + "%%"); - break; - - default: - QLOG_ERROR() << "not implemented"; - break; + "INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) WHERE "); + + try { + QueryParser parser; + auto result = parser.parse(filter.toStdString()); + result.buildSqlString(queryString); + + switch (modifier) { + case YACReader::NoModifiers: + queryString += "AND f.id <> 1 ORDER BY f.parentId,f.name"; + break; + + case YACReader::OnlyRead: + queryString += "AND f.id <> 1 AND ci.read = 1 ORDER BY f.parentId,f.name"; + break; + + case YACReader::OnlyUnread: + queryString += "AND f.id <> 1 AND ci.read = 0 ORDER BY f.parentId,f.name"; + break; + + default: + queryString += "AND f.id <> 1 ORDER BY f.parentId,f.name"; + QLOG_ERROR() << "not implemented"; + break; + } + + selectQuery.prepare(QString(queryString.c_str())); + result.bindValues(selectQuery); + + } catch (const std::exception &e) { + QLOG_ERROR() << "Unable to parse query: " << e.what(); } } selectQuery.exec(); + QLOG_DEBUG() << selectQuery.lastError() << "--"; setupFilteredModelData(selectQuery, rootItem); connectionName = db.connectionName(); From 30529dca4329d32ecc70a50eedccd0ba4e0038ab Mon Sep 17 00:00:00 2001 From: Iain Benson Date: Sat, 24 Nov 2018 10:27:09 +0000 Subject: [PATCH 009/141] Some small tidy ups --- YACReaderLibrary/db/comic_model.cpp | 10 +++++----- YACReaderLibrary/db/folder_model.cpp | 28 +++++++++++++--------------- YACReaderLibrary/db/query_parser.cpp | 10 ---------- 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index 5f795e6a7..d41b78060 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -618,23 +618,23 @@ void ComicModel::setupModelData(const SearchModifiers modifier, const QString &f switch (modifier) { case YACReader::NoModifiers: - queryString += "LIMIT :limit"; + queryString += " LIMIT :limit"; break; case YACReader::OnlyRead: - queryString += "AND ci.read = 1 LIMIT :limit"; + queryString += " AND ci.read = 1 LIMIT :limit"; break; case YACReader::OnlyUnread: - queryString += "AND ci.read = 0 LIMIT :limit"; + queryString += " AND ci.read = 0 LIMIT :limit"; break; default: - queryString += "LIMIT :limit"; + queryString += " LIMIT :limit"; QLOG_ERROR() << "not implemented"; break; } - selectQuery.prepare(QString(queryString.c_str())); + selectQuery.prepare(queryString.c_str()); selectQuery.bindValue(":limit", 500); //TODO, load this value from settings result.bindValues(selectQuery); } catch (const std::exception &e) { diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 902ada19e..76a82ec26 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -701,39 +701,37 @@ void FolderModelProxy::setupFilteredModelData() switch (modifier) { case YACReader::NoModifiers: - queryString += "AND f.id <> 1 ORDER BY f.parentId,f.name"; + queryString += " AND f.id <> 1 ORDER BY f.parentId,f.name"; break; case YACReader::OnlyRead: - queryString += "AND f.id <> 1 AND ci.read = 1 ORDER BY f.parentId,f.name"; + queryString += " AND f.id <> 1 AND ci.read = 1 ORDER BY f.parentId,f.name"; break; case YACReader::OnlyUnread: - queryString += "AND f.id <> 1 AND ci.read = 0 ORDER BY f.parentId,f.name"; + queryString += " AND f.id <> 1 AND ci.read = 0 ORDER BY f.parentId,f.name"; break; default: - queryString += "AND f.id <> 1 ORDER BY f.parentId,f.name"; + queryString += " AND f.id <> 1 ORDER BY f.parentId,f.name"; QLOG_ERROR() << "not implemented"; break; - } - - selectQuery.prepare(QString(queryString.c_str())); - result.bindValues(selectQuery); + selectQuery.prepare(queryString.c_str()); + result.bindValues(selectQuery); + } } catch (const std::exception &e) { QLOG_ERROR() << "Unable to parse query: " << e.what(); } + selectQuery.exec(); + QLOG_DEBUG() << selectQuery.lastError() << "--"; + + setupFilteredModelData(selectQuery, rootItem); } - selectQuery.exec(); - QLOG_DEBUG() << selectQuery.lastError() << "--"; + QSqlDatabase::removeDatabase(db.connectionName()); - setupFilteredModelData(selectQuery, rootItem); - connectionName = db.connectionName(); + endResetModel(); } - QSqlDatabase::removeDatabase(connectionName); - - endResetModel(); } void FolderModelProxy::clear() diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index e69c8b81e..7cd578978 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -148,17 +148,7 @@ QueryParser::FieldType QueryParser::fieldType(const std::string& str) { } void QueryParser::tokenize (const std::string& expr) { - // TODO: Strip out escaped backslashes, quotes and parens so that the - // lex scanner doesn't get confused. We put them back later. - - iter = lexertl::siterator(expr.begin(), expr.end(), sm); - - /* for (; !isEof() ; advance()) - { - std::cout << "Id: " << iter->id << ", Token: '" << token() << "'\n"; - } iter = lexertl::siterator(expr.begin(), expr.end(), sm); - */ } std::string QueryParser::join(const std::vector& strings, const std::string& delim) { From 9a660350d23ac81e78234466d675b820906051b5 Mon Sep 17 00:00:00 2001 From: Iain Benson Date: Sat, 24 Nov 2018 10:27:29 +0000 Subject: [PATCH 010/141] Add some documentation and attribution to the query parser --- YACReaderLibrary/db/query_parser.h | 31 ++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/YACReaderLibrary/db/query_parser.h b/YACReaderLibrary/db/query_parser.h index d77e12435..628c1beba 100644 --- a/YACReaderLibrary/db/query_parser.h +++ b/YACReaderLibrary/db/query_parser.h @@ -9,8 +9,35 @@ #include #include -class QSqlQuery; - +/** + * This class is used to generate an SQL query string from a search expression, + * with a syntax very similar to that used by the Google search engine. + * + * The code herin is based upon the SearchQueryParser python class written by + * Kovid Goyal as part of the Calibre eBook manager (https://calibre-ebook.com) + * + * Grammar: + * prog ::= or_expression + * or_expression ::= and_expression [ 'or' or_expression ] + * and_expression ::= not_expression [ [ 'and' ] and_expression ] + * not_expression ::= [ 'not' ] location_expression + * location_expression ::= base_token | ( '(' or_expression ')' ) + * base_token ::= a sequence of letters and colons, perhaps quoted + * + * Usage Example: + * QSqlQuery selectQuery(db); + * std::string queryString("SELECT ... FROM ... WHERE "); + * + * QueryParser parser; // Create the parser object + * TreeNode result = parser.parse(expr); // Parse the query expression + * + * result.buildSqlString(queryString); // Append the SQL query to a string + * + * selectQuery.prepare(queryString.c_str()); // Convert the string to a query + * result.bindValues(selectQuery); // Populate the SQL query variables + * + * selectQuery.exec(); + */ class QueryParser { public: From 7ccb3384554ece0672218a80a3603a1ef1e51e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Mon, 23 Sep 2019 18:02:23 +0200 Subject: [PATCH 011/141] Apply clang-format --- YACReaderLibrary/db/query_parser.cpp | 199 +++++++++++++++------------ YACReaderLibrary/db/query_parser.h | 46 ++++--- 2 files changed, 139 insertions(+), 106 deletions(-) diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index 7cd578978..c68502dbd 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -5,73 +5,75 @@ #include #include - const std::map> QueryParser::fieldNames { - {FieldType::numeric, {"numpages", "number", "count", "arcnumber", "arccount"}}, - {FieldType::text, {"title", "volume", "storyarc", "genere", "writer", "penciller", "inker", "colorist", "letterer", - "coverartist", "publisher", "format", "agerating", "synopsis", "characters", "notes"}}, - {FieldType::boolean, {"isbis", "color"}}, - {FieldType::date, {"date"}}, - {FieldType::filename, {"filename"}}, - {FieldType::folder, {"folder"}} }; - -int QueryParser::TreeNode::buildSqlString(std::string& sqlString, int bindPosition) const { - if (t == "token") { - ++bindPosition; - std::ostringstream oss; - if (toLower(children[0].t) == "all") { - oss << "("; - for (const auto& field: fieldNames.at(FieldType::text)) { - oss << "UPPER(ci." << field << ") LIKE UPPER(:bindPosition" << bindPosition << ") OR "; - } - oss << "UPPER(c.filename) LIKE UPPER(:bindPosition" << bindPosition << ") OR "; - oss << "UPPER(f.name) LIKE UPPER(:bindPosition" << bindPosition << ")) "; - } else if (isIn(fieldType(children[0].t), FieldType::numeric, FieldType::boolean)) { - oss << "ci." << children[0].t << " = :bindPosition" << bindPosition << " "; - } else if (fieldType(children[0].t) == FieldType::filename) { - oss << "(UPPER(c." << children[0].t << ") LIKE UPPER(:bindPosition" << bindPosition << ")) "; - } else if (fieldType(children[0].t) == FieldType::folder) { - oss << "(UPPER(f.name) LIKE UPPER(:bindPosition" << bindPosition << ")) "; - } else { - oss << "(UPPER(ci." << children[0].t << ") LIKE UPPER(:bindPosition" << bindPosition << ")) "; + { FieldType::numeric, { "numpages", "number", "count", "arcnumber", "arccount" } }, + { FieldType::text, { "title", "volume", "storyarc", "genere", "writer", "penciller", "inker", "colorist", "letterer", "coverartist", "publisher", "format", "agerating", "synopsis", "characters", "notes" } }, + { FieldType::boolean, { "isbis", "color" } }, + { FieldType::date, { "date" } }, + { FieldType::filename, { "filename" } }, + { FieldType::folder, { "folder" } } +}; + +int QueryParser::TreeNode::buildSqlString(std::string &sqlString, int bindPosition) const +{ + if (t == "token") { + ++bindPosition; + std::ostringstream oss; + if (toLower(children[0].t) == "all") { + oss << "("; + for (const auto &field : fieldNames.at(FieldType::text)) { + oss << "UPPER(ci." << field << ") LIKE UPPER(:bindPosition" << bindPosition << ") OR "; } - sqlString += oss.str(); - } else if (t == "not") { - sqlString += "(NOT "; - bindPosition = children[0].buildSqlString(sqlString, bindPosition); - sqlString += ")"; + oss << "UPPER(c.filename) LIKE UPPER(:bindPosition" << bindPosition << ") OR "; + oss << "UPPER(f.name) LIKE UPPER(:bindPosition" << bindPosition << ")) "; + } else if (isIn(fieldType(children[0].t), FieldType::numeric, FieldType::boolean)) { + oss << "ci." << children[0].t << " = :bindPosition" << bindPosition << " "; + } else if (fieldType(children[0].t) == FieldType::filename) { + oss << "(UPPER(c." << children[0].t << ") LIKE UPPER(:bindPosition" << bindPosition << ")) "; + } else if (fieldType(children[0].t) == FieldType::folder) { + oss << "(UPPER(f.name) LIKE UPPER(:bindPosition" << bindPosition << ")) "; } else { - sqlString += "("; - bindPosition = children[0].buildSqlString(sqlString, bindPosition); - sqlString += " " + t + " "; - bindPosition = children[1].buildSqlString(sqlString, bindPosition); - sqlString += ")"; + oss << "(UPPER(ci." << children[0].t << ") LIKE UPPER(:bindPosition" << bindPosition << ")) "; } - - return bindPosition; - } - - int QueryParser::TreeNode::bindValues(QSqlQuery& selectQuery, int bindPosition) const { - if (t == "token") { - std::ostringstream oss; - oss << ":bindPosition" << ++bindPosition; - if (isIn(fieldType(children[0].t), FieldType::numeric, FieldType::boolean)) { - selectQuery.bindValue(oss.str().c_str(), std::stoi(children[1].t)); - } else { - selectQuery.bindValue(oss.str().c_str(), ("%%"+children[1].t+"%%").c_str()); - } - } else if (t == "not") { - bindPosition = children[0].bindValues(selectQuery, bindPosition); + sqlString += oss.str(); + } else if (t == "not") { + sqlString += "(NOT "; + bindPosition = children[0].buildSqlString(sqlString, bindPosition); + sqlString += ")"; + } else { + sqlString += "("; + bindPosition = children[0].buildSqlString(sqlString, bindPosition); + sqlString += " " + t + " "; + bindPosition = children[1].buildSqlString(sqlString, bindPosition); + sqlString += ")"; + } + + return bindPosition; +} + +int QueryParser::TreeNode::bindValues(QSqlQuery &selectQuery, int bindPosition) const +{ + if (t == "token") { + std::ostringstream oss; + oss << ":bindPosition" << ++bindPosition; + if (isIn(fieldType(children[0].t), FieldType::numeric, FieldType::boolean)) { + selectQuery.bindValue(oss.str().c_str(), std::stoi(children[1].t)); } else { - bindPosition = children[0].bindValues(selectQuery, bindPosition); - bindPosition = children[1].bindValues(selectQuery, bindPosition); + selectQuery.bindValue(oss.str().c_str(), ("%%" + children[1].t + "%%").c_str()); } - - return bindPosition; + } else if (t == "not") { + bindPosition = children[0].bindValues(selectQuery, bindPosition); + } else { + bindPosition = children[0].bindValues(selectQuery, bindPosition); + bindPosition = children[1].bindValues(selectQuery, bindPosition); } + return bindPosition; +} -QueryParser::QueryParser(): lexScanner(0) { +QueryParser::QueryParser() + : lexScanner(0) +{ lexScanner.push("[()]", static_cast::type>(TokenType::opcode)); lexScanner.push("@[^:]+:[^\\\")\\s]+", static_cast::type>(TokenType::atWord)); @@ -82,7 +84,8 @@ QueryParser::QueryParser(): lexScanner(0) { lexertl::generator::build(lexScanner, sm); } -QueryParser::TreeNode QueryParser::parse(const std::string& expr) { +QueryParser::TreeNode QueryParser::parse(const std::string &expr) +{ tokenize(expr); auto prog = orExpression(); @@ -93,52 +96,60 @@ QueryParser::TreeNode QueryParser::parse(const std::string& expr) { return prog; } -std::string QueryParser::toLower(const std::string& string) { +std::string QueryParser::toLower(const std::string &string) +{ std::string res(string); std::transform(res.begin(), res.end(), res.begin(), ::tolower); return res; } -std::string QueryParser::token(bool advance) { +std::string QueryParser::token(bool advance) +{ if (isEof()) { return ""; } - auto res = (tokenType() == TokenType::quotedWord)?iter->substr(1,1):iter->str(); + auto res = (tokenType() == TokenType::quotedWord) ? iter->substr(1, 1) : iter->str(); if (advance) { this->advance(); } return res; } -std::string QueryParser::lcaseToken(bool advance) { +std::string QueryParser::lcaseToken(bool advance) +{ if (isEof()) { return ""; } - auto res = (tokenType() == TokenType::quotedWord)?iter->substr(1,1):iter->str(); + auto res = (tokenType() == TokenType::quotedWord) ? iter->substr(1, 1) : iter->str(); if (advance) { this->advance(); } return toLower(res); } -QueryParser::TokenType QueryParser::tokenType() { +QueryParser::TokenType QueryParser::tokenType() +{ if (isEof()) { return TokenType::eof; } return TokenType(iter->id); } -bool QueryParser::isEof() const { +bool QueryParser::isEof() const +{ return iter == end; } -void QueryParser::advance() { +void QueryParser::advance() +{ ++iter; - if (tokenType() == TokenType::space) advance(); + if (tokenType() == TokenType::space) + advance(); } -QueryParser::FieldType QueryParser::fieldType(const std::string& str) { - for (const auto& names : fieldNames) { +QueryParser::FieldType QueryParser::fieldType(const std::string &str) +{ + for (const auto &names : fieldNames) { if (std::find(names.second.begin(), names.second.end(), toLower(str)) != names.second.end()) { return names.first; } @@ -147,21 +158,24 @@ QueryParser::FieldType QueryParser::fieldType(const std::string& str) { return FieldType::unknown; } -void QueryParser::tokenize (const std::string& expr) { +void QueryParser::tokenize(const std::string &expr) +{ iter = lexertl::siterator(expr.begin(), expr.end(), sm); } -std::string QueryParser::join(const std::vector& strings, const std::string& delim) { +std::string QueryParser::join(const std::vector &strings, const std::string &delim) +{ return std::accumulate(strings.begin(), strings.end(), std::string(), - [&delim](const std::string& a, const std::string& b) -> std::string { - return a + (a.length() > 0 && b.length() > 0 ? delim : "") + b; - } ); + [&delim](const std::string &a, const std::string &b) -> std::string { + return a + (a.length() > 0 && b.length() > 0 ? delim : "") + b; + }); } -std::vector QueryParser::split(const std::string& string, char delim) { +std::vector QueryParser::split(const std::string &string, char delim) +{ std::istringstream iss(string); std::vector words; - while(iss) { + while (iss) { std::string substr; std::getline(iss, substr, delim); words.push_back(substr); @@ -169,38 +183,42 @@ std::vector QueryParser::split(const std::string& string, char deli return words; } -QueryParser::TreeNode QueryParser::orExpression() { +QueryParser::TreeNode QueryParser::orExpression() +{ auto lhs = andExpression(); if (lcaseToken() == "or") { advance(); - return {"or", {lhs, orExpression()}}; + return { "or", { lhs, orExpression() } }; } return lhs; } -QueryParser::TreeNode QueryParser::andExpression() { +QueryParser::TreeNode QueryParser::andExpression() +{ auto lhs = notExpression(); if (lcaseToken() == "and") { advance(); - return {"and", {lhs, andExpression()}}; + return { "and", { lhs, andExpression() } }; } if ((isIn(tokenType(), TokenType::atWord, TokenType::word, TokenType::quotedWord) || token() == "(") && lcaseToken() != "or") { - return {"and", {lhs, andExpression()}}; + return { "and", { lhs, andExpression() } }; } return lhs; } -QueryParser::TreeNode QueryParser::notExpression() { +QueryParser::TreeNode QueryParser::notExpression() +{ if (lcaseToken() == "not") { advance(); - return {"not", {notExpression()}}; + return { "not", { notExpression() } }; } return locationExpression(); } -QueryParser::TreeNode QueryParser::locationExpression() { +QueryParser::TreeNode QueryParser::locationExpression() +{ if (tokenType() == TokenType::opcode && token() == "(") { advance(); auto res = orExpression(); @@ -215,9 +233,10 @@ QueryParser::TreeNode QueryParser::locationExpression() { return baseToken(); } -QueryParser::TreeNode QueryParser::baseToken() { +QueryParser::TreeNode QueryParser::baseToken() +{ if (tokenType() == TokenType::quotedWord) { - return {"token", {{"all", {}}, {token(true), {}}}}; + return { "token", { { "all", {} }, { token(true), {} } } }; } auto words(split(token(true), ':')); @@ -226,9 +245,9 @@ QueryParser::TreeNode QueryParser::baseToken() { auto loc(toLower(words[0])); words.erase(words.begin()); if (words.size() == 1 && tokenType() == TokenType::quotedWord) { - return {"token", {{loc, {}}, {token(true), {}}}}; + return { "token", { { loc, {} }, { token(true), {} } } }; } - return {"token", {{loc, {}}, {join(words, ":"), {}}}}; + return { "token", { { loc, {} }, { join(words, ":"), {} } } }; } - return {"token", {{"all", {}}, {join(words, ":"), {}}}}; + return { "token", { { "all", {} }, { join(words, ":"), {} } } }; } diff --git a/YACReaderLibrary/db/query_parser.h b/YACReaderLibrary/db/query_parser.h index 628c1beba..427cda306 100644 --- a/YACReaderLibrary/db/query_parser.h +++ b/YACReaderLibrary/db/query_parser.h @@ -38,24 +38,29 @@ * * selectQuery.exec(); */ -class QueryParser { +class QueryParser +{ public: - - enum class TokenType {eof, opcode, atWord, word, quotedWord, space}; + enum class TokenType { eof, + opcode, + atWord, + word, + quotedWord, + space }; struct TreeNode { std::string t; std::vector children; - int buildSqlString(std::string& sqlString, int bindPosition = 0) const; - int bindValues(QSqlQuery& selectQuery, int bindPosition = 0) const; + int buildSqlString(std::string &sqlString, int bindPosition = 0) const; + int bindValues(QSqlQuery &selectQuery, int bindPosition = 0) const; }; explicit QueryParser(); - TreeNode parse(const std::string& expr); + TreeNode parse(const std::string &expr); private: - static std::string toLower(const std::string& string); + static std::string toLower(const std::string &string); std::string token(bool advance = false); std::string lcaseToken(bool advance = false); @@ -63,15 +68,24 @@ class QueryParser { bool isEof() const; void advance(); - template - static bool isIn(First &&first, T && ... t) {return ((first == t) || ...);} - - enum class FieldType {unknown, numeric, text, boolean, date, folder, filename}; - static FieldType fieldType(const std::string& str); - - void tokenize (const std::string& expr); - static std::string join(const std::vector& strings, const std::string& delim); - static std::vector split(const std::string& string, char delim); + template + static bool isIn(First &&first, T &&... t) + { + return ((first == t) || ...); + } + + enum class FieldType { unknown, + numeric, + text, + boolean, + date, + folder, + filename }; + static FieldType fieldType(const std::string &str); + + void tokenize(const std::string &expr); + static std::string join(const std::vector &strings, const std::string &delim); + static std::vector split(const std::string &string, char delim); TreeNode orExpression(); TreeNode andExpression(); From 2d3888b4b463d2d71cbd997456ae90d67e6ea23c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Mon, 23 Sep 2019 18:32:25 +0200 Subject: [PATCH 012/141] Fix scopes --- YACReaderLibrary/db/folder_model.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 76a82ec26..42f13aad3 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -716,13 +716,14 @@ void FolderModelProxy::setupFilteredModelData() queryString += " AND f.id <> 1 ORDER BY f.parentId,f.name"; QLOG_ERROR() << "not implemented"; break; - - selectQuery.prepare(queryString.c_str()); - result.bindValues(selectQuery); } } catch (const std::exception &e) { QLOG_ERROR() << "Unable to parse query: " << e.what(); } + + selectQuery.prepare(queryString.c_str()); + selectQuery.bindValues(selectQuery); + selectQuery.exec(); QLOG_DEBUG() << selectQuery.lastError() << "--"; From 4990093e3dfa01313c99555f24e687da10554da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Mon, 23 Sep 2019 19:55:00 +0200 Subject: [PATCH 013/141] Remove c++17 dependency --- YACReaderLibrary/YACReaderLibrary.pro | 4 ---- YACReaderLibrary/db/query_parser.cpp | 8 ++++---- YACReaderLibrary/db/query_parser.h | 6 +++--- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 8f79b7066..e6d86252a 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -67,10 +67,6 @@ macx { QT += macextras gui-private } -unix { - CONFIG += c++1z -} - #CONFIG += release CONFIG -= flat QT += sql network widgets script diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index c68502dbd..802c11b83 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -26,7 +26,7 @@ int QueryParser::TreeNode::buildSqlString(std::string &sqlString, int bindPositi } oss << "UPPER(c.filename) LIKE UPPER(:bindPosition" << bindPosition << ") OR "; oss << "UPPER(f.name) LIKE UPPER(:bindPosition" << bindPosition << ")) "; - } else if (isIn(fieldType(children[0].t), FieldType::numeric, FieldType::boolean)) { + } else if (isIn(fieldType(children[0].t), { FieldType::numeric, FieldType::boolean })) { oss << "ci." << children[0].t << " = :bindPosition" << bindPosition << " "; } else if (fieldType(children[0].t) == FieldType::filename) { oss << "(UPPER(c." << children[0].t << ") LIKE UPPER(:bindPosition" << bindPosition << ")) "; @@ -56,7 +56,7 @@ int QueryParser::TreeNode::bindValues(QSqlQuery &selectQuery, int bindPosition) if (t == "token") { std::ostringstream oss; oss << ":bindPosition" << ++bindPosition; - if (isIn(fieldType(children[0].t), FieldType::numeric, FieldType::boolean)) { + if (isIn(fieldType(children[0].t), { FieldType::numeric, FieldType::boolean })) { selectQuery.bindValue(oss.str().c_str(), std::stoi(children[1].t)); } else { selectQuery.bindValue(oss.str().c_str(), ("%%" + children[1].t + "%%").c_str()); @@ -201,7 +201,7 @@ QueryParser::TreeNode QueryParser::andExpression() return { "and", { lhs, andExpression() } }; } - if ((isIn(tokenType(), TokenType::atWord, TokenType::word, TokenType::quotedWord) || token() == "(") && lcaseToken() != "or") { + if ((isIn(tokenType(), { TokenType::atWord, TokenType::word, TokenType::quotedWord }) || token() == "(") && lcaseToken() != "or") { return { "and", { lhs, andExpression() } }; } @@ -227,7 +227,7 @@ QueryParser::TreeNode QueryParser::locationExpression() } return res; } - if (!isIn(tokenType(), TokenType::atWord, TokenType::word, TokenType::quotedWord)) { + if (!isIn(tokenType(), { TokenType::atWord, TokenType::word, TokenType::quotedWord })) { throw std::invalid_argument("Invalid syntax. Expected a lookup name or a word"); } return baseToken(); diff --git a/YACReaderLibrary/db/query_parser.h b/YACReaderLibrary/db/query_parser.h index 427cda306..0d0320368 100644 --- a/YACReaderLibrary/db/query_parser.h +++ b/YACReaderLibrary/db/query_parser.h @@ -68,10 +68,10 @@ class QueryParser bool isEof() const; void advance(); - template - static bool isIn(First &&first, T &&... t) + template + static bool isIn(const T &e, const std::list &v) { - return ((first == t) || ...); + return std::find(v.begin(), v.end(), e) != v.end(); } enum class FieldType { unknown, From 8efb9912ee07200e84bf91601d1d2336152bdb02 Mon Sep 17 00:00:00 2001 From: Iain Benson Date: Thu, 24 Oct 2019 20:39:43 +0100 Subject: [PATCH 014/141] Use concatenation, rather than ostringstream --- YACReaderLibrary/db/query_parser.cpp | 46 +++++++++++----------------- YACReaderLibrary/db/query_parser.h | 4 +-- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index 802c11b83..f08d08727 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -1,7 +1,6 @@ #include "query_parser.h" #include -#include #include #include @@ -18,24 +17,22 @@ int QueryParser::TreeNode::buildSqlString(std::string &sqlString, int bindPositi { if (t == "token") { ++bindPosition; - std::ostringstream oss; if (toLower(children[0].t) == "all") { - oss << "("; + sqlString += "("; for (const auto &field : fieldNames.at(FieldType::text)) { - oss << "UPPER(ci." << field << ") LIKE UPPER(:bindPosition" << bindPosition << ") OR "; + sqlString += "UPPER(ci." + field + ") LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ") OR "; } - oss << "UPPER(c.filename) LIKE UPPER(:bindPosition" << bindPosition << ") OR "; - oss << "UPPER(f.name) LIKE UPPER(:bindPosition" << bindPosition << ")) "; + sqlString += "UPPER(c.filename) LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ") OR "; + sqlString += "UPPER(f.name) LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; } else if (isIn(fieldType(children[0].t), { FieldType::numeric, FieldType::boolean })) { - oss << "ci." << children[0].t << " = :bindPosition" << bindPosition << " "; + sqlString += "ci." + children[0].t + " = :bindPosition" + std::to_string(bindPosition) + " "; } else if (fieldType(children[0].t) == FieldType::filename) { - oss << "(UPPER(c." << children[0].t << ") LIKE UPPER(:bindPosition" << bindPosition << ")) "; + sqlString += "(UPPER(c." + children[0].t + ") LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; } else if (fieldType(children[0].t) == FieldType::folder) { - oss << "(UPPER(f.name) LIKE UPPER(:bindPosition" << bindPosition << ")) "; + sqlString += "(UPPER(f.name) LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; } else { - oss << "(UPPER(ci." << children[0].t << ") LIKE UPPER(:bindPosition" << bindPosition << ")) "; + sqlString += "(UPPER(ci." + children[0].t + ") LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; } - sqlString += oss.str(); } else if (t == "not") { sqlString += "(NOT "; bindPosition = children[0].buildSqlString(sqlString, bindPosition); @@ -54,12 +51,11 @@ int QueryParser::TreeNode::buildSqlString(std::string &sqlString, int bindPositi int QueryParser::TreeNode::bindValues(QSqlQuery &selectQuery, int bindPosition) const { if (t == "token") { - std::ostringstream oss; - oss << ":bindPosition" << ++bindPosition; + std::string bind_string(":bindPosition" + std::to_string(++bindPosition)); if (isIn(fieldType(children[0].t), { FieldType::numeric, FieldType::boolean })) { - selectQuery.bindValue(oss.str().c_str(), std::stoi(children[1].t)); + selectQuery.bindValue(bind_string.c_str(), std::stoi(children[1].t)); } else { - selectQuery.bindValue(oss.str().c_str(), ("%%" + children[1].t + "%%").c_str()); + selectQuery.bindValue(bind_string.c_str(), ("%%" + children[1].t + "%%").c_str()); } } else if (t == "not") { bindPosition = children[0].bindValues(selectQuery, bindPosition); @@ -163,23 +159,17 @@ void QueryParser::tokenize(const std::string &expr) iter = lexertl::siterator(expr.begin(), expr.end(), sm); } -std::string QueryParser::join(const std::vector &strings, const std::string &delim) +std::string QueryParser::join(const QStringList &strings, const std::string &delim) { return std::accumulate(strings.begin(), strings.end(), std::string(), - [&delim](const std::string &a, const std::string &b) -> std::string { - return a + (a.length() > 0 && b.length() > 0 ? delim : "") + b; + [&delim](const std::string &a, const QString &b) -> std::string { + return a + (a.length() > 0 && b.length() > 0 ? delim : "") + b.toStdString(); }); } -std::vector QueryParser::split(const std::string &string, char delim) +QStringList QueryParser::split(const std::string &string, char delim) { - std::istringstream iss(string); - std::vector words; - while (iss) { - std::string substr; - std::getline(iss, substr, delim); - words.push_back(substr); - } + auto words = QString(string.c_str()).split(delim); return words; } @@ -241,8 +231,8 @@ QueryParser::TreeNode QueryParser::baseToken() auto words(split(token(true), ':')); - if (words.size() > 1 && fieldType(words[0]) != FieldType::unknown) { - auto loc(toLower(words[0])); + if (words.size() > 1 && fieldType(words[0].toStdString()) != FieldType::unknown) { + auto loc(toLower(words[0].toStdString())); words.erase(words.begin()); if (words.size() == 1 && tokenType() == TokenType::quotedWord) { return { "token", { { loc, {} }, { token(true), {} } } }; diff --git a/YACReaderLibrary/db/query_parser.h b/YACReaderLibrary/db/query_parser.h index 0d0320368..f23a74704 100644 --- a/YACReaderLibrary/db/query_parser.h +++ b/YACReaderLibrary/db/query_parser.h @@ -84,8 +84,8 @@ class QueryParser static FieldType fieldType(const std::string &str); void tokenize(const std::string &expr); - static std::string join(const std::vector &strings, const std::string &delim); - static std::vector split(const std::string &string, char delim); + static std::string join(const QStringList &strings, const std::string &delim); + static QStringList split(const std::string &string, char delim); TreeNode orExpression(); TreeNode andExpression(); From 255e51da865f6b83e77248a44e0804fac9582b88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Fri, 8 Jan 2021 16:59:17 +0100 Subject: [PATCH 015/141] Fix binding values to search query This was broken while doing a rebase --- YACReaderLibrary/db/folder_model.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 42f13aad3..f454e599d 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -717,17 +717,17 @@ void FolderModelProxy::setupFilteredModelData() QLOG_ERROR() << "not implemented"; break; } - } catch (const std::exception &e) { - QLOG_ERROR() << "Unable to parse query: " << e.what(); - } - selectQuery.prepare(queryString.c_str()); - selectQuery.bindValues(selectQuery); + selectQuery.prepare(queryString.c_str()); + result.bindValues(selectQuery); - selectQuery.exec(); - QLOG_DEBUG() << selectQuery.lastError() << "--"; + selectQuery.exec(); + QLOG_DEBUG() << selectQuery.lastError() << "--"; - setupFilteredModelData(selectQuery, rootItem); + setupFilteredModelData(selectQuery, rootItem); + } catch (const std::exception &e) { + QLOG_ERROR() << "Unable to parse query: " << e.what(); + } } QSqlDatabase::removeDatabase(db.connectionName()); From 6438c9210f2103c7a9b8e9b297bf913fe0197689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Tue, 12 Jan 2021 18:41:09 +0100 Subject: [PATCH 016/141] Move query execution and model setup to the right scope --- YACReaderLibrary/db/comic_model.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index d41b78060..59fa9887a 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -637,6 +637,10 @@ void ComicModel::setupModelData(const SearchModifiers modifier, const QString &f selectQuery.prepare(queryString.c_str()); selectQuery.bindValue(":limit", 500); //TODO, load this value from settings result.bindValues(selectQuery); + + selectQuery.exec(); + + setupModelData(selectQuery); } catch (const std::exception &e) { QLOG_ERROR() << "Unable to parse query: " << e.what(); } From 5037f3ac9259d7b7b63f86a0e23c69c4e470d4ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Tue, 12 Jan 2021 18:41:57 +0100 Subject: [PATCH 017/141] Fix data base removal in FolderModel --- YACReaderLibrary/db/folder_model.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index f454e599d..1944e1e19 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -729,10 +729,13 @@ void FolderModelProxy::setupFilteredModelData() QLOG_ERROR() << "Unable to parse query: " << e.what(); } } - QSqlDatabase::removeDatabase(db.connectionName()); + + connectionName = db.connectionName(); endResetModel(); } + + QSqlDatabase::removeDatabase(connectionName); } void FolderModelProxy::clear() From a777aa3fe8941f63c27fb6ea944874a8bb5fdcba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Tue, 12 Jan 2021 18:56:59 +0100 Subject: [PATCH 018/141] Replace lexertl with a custom lexeter implementation QueryLexeter does not parse "atWord" because I couldn't find what it is used for. --- YACReaderLibrary/YACReaderLibrary.pro | 39 +- YACReaderLibrary/db/query_lexer.cpp | 94 + YACReaderLibrary/db/query_lexer.h | 59 + YACReaderLibrary/db/query_parser.cpp | 55 +- YACReaderLibrary/db/query_parser.h | 24 +- YACReaderLibrary/lexertl/char_traits.hpp | 45 - YACReaderLibrary/lexertl/debug.hpp | 311 -- YACReaderLibrary/lexertl/dot.hpp | 293 -- YACReaderLibrary/lexertl/enums.hpp | 25 - YACReaderLibrary/lexertl/generate_cpp.hpp | 1123 ------ YACReaderLibrary/lexertl/generator.hpp | 738 ---- YACReaderLibrary/lexertl/internals.hpp | 75 - YACReaderLibrary/lexertl/iterator.hpp | 135 - YACReaderLibrary/lexertl/licence_1_0.txt | 24 - YACReaderLibrary/lexertl/lookup.hpp | 491 --- YACReaderLibrary/lexertl/match_results.hpp | 171 - YACReaderLibrary/lexertl/memory_file.hpp | 138 - YACReaderLibrary/lexertl/narrow.hpp | 25 - YACReaderLibrary/lexertl/observer_ptr.hpp | 16 - YACReaderLibrary/lexertl/parser/parser.hpp | 926 ----- .../lexertl/parser/tokeniser/re_token.hpp | 100 - .../lexertl/parser/tokeniser/re_tokeniser.hpp | 778 ---- .../parser/tokeniser/re_tokeniser_helper.hpp | 3157 ----------------- .../parser/tokeniser/re_tokeniser_state.hpp | 136 - .../lexertl/parser/tree/end_node.hpp | 111 - .../lexertl/parser/tree/iteration_node.hpp | 96 - .../lexertl/parser/tree/leaf_node.hpp | 110 - YACReaderLibrary/lexertl/parser/tree/node.hpp | 242 -- .../lexertl/parser/tree/selection_node.hpp | 104 - .../lexertl/parser/tree/sequence_node.hpp | 121 - .../lexertl/partition/charset.hpp | 72 - .../lexertl/partition/equivset.hpp | 135 - YACReaderLibrary/lexertl/rules.hpp | 1018 ------ YACReaderLibrary/lexertl/runtime_error.hpp | 23 - YACReaderLibrary/lexertl/serialise.hpp | 28 - YACReaderLibrary/lexertl/sm_to_csm.hpp | 53 - YACReaderLibrary/lexertl/sm_traits.hpp | 44 - YACReaderLibrary/lexertl/state_machine.hpp | 521 --- .../lexertl/stream_shared_iterator.hpp | 352 -- YACReaderLibrary/lexertl/string_token.hpp | 439 --- YACReaderLibrary/lexertl/utf_iterators.hpp | 508 --- 41 files changed, 187 insertions(+), 12768 deletions(-) create mode 100644 YACReaderLibrary/db/query_lexer.cpp create mode 100644 YACReaderLibrary/db/query_lexer.h delete mode 100644 YACReaderLibrary/lexertl/char_traits.hpp delete mode 100644 YACReaderLibrary/lexertl/debug.hpp delete mode 100644 YACReaderLibrary/lexertl/dot.hpp delete mode 100644 YACReaderLibrary/lexertl/enums.hpp delete mode 100644 YACReaderLibrary/lexertl/generate_cpp.hpp delete mode 100644 YACReaderLibrary/lexertl/generator.hpp delete mode 100644 YACReaderLibrary/lexertl/internals.hpp delete mode 100644 YACReaderLibrary/lexertl/iterator.hpp delete mode 100644 YACReaderLibrary/lexertl/licence_1_0.txt delete mode 100644 YACReaderLibrary/lexertl/lookup.hpp delete mode 100644 YACReaderLibrary/lexertl/match_results.hpp delete mode 100644 YACReaderLibrary/lexertl/memory_file.hpp delete mode 100644 YACReaderLibrary/lexertl/narrow.hpp delete mode 100644 YACReaderLibrary/lexertl/observer_ptr.hpp delete mode 100644 YACReaderLibrary/lexertl/parser/parser.hpp delete mode 100644 YACReaderLibrary/lexertl/parser/tokeniser/re_token.hpp delete mode 100644 YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser.hpp delete mode 100644 YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_helper.hpp delete mode 100644 YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_state.hpp delete mode 100644 YACReaderLibrary/lexertl/parser/tree/end_node.hpp delete mode 100644 YACReaderLibrary/lexertl/parser/tree/iteration_node.hpp delete mode 100644 YACReaderLibrary/lexertl/parser/tree/leaf_node.hpp delete mode 100644 YACReaderLibrary/lexertl/parser/tree/node.hpp delete mode 100644 YACReaderLibrary/lexertl/parser/tree/selection_node.hpp delete mode 100644 YACReaderLibrary/lexertl/parser/tree/sequence_node.hpp delete mode 100644 YACReaderLibrary/lexertl/partition/charset.hpp delete mode 100644 YACReaderLibrary/lexertl/partition/equivset.hpp delete mode 100644 YACReaderLibrary/lexertl/rules.hpp delete mode 100644 YACReaderLibrary/lexertl/runtime_error.hpp delete mode 100644 YACReaderLibrary/lexertl/serialise.hpp delete mode 100644 YACReaderLibrary/lexertl/sm_to_csm.hpp delete mode 100644 YACReaderLibrary/lexertl/sm_traits.hpp delete mode 100644 YACReaderLibrary/lexertl/state_machine.hpp delete mode 100644 YACReaderLibrary/lexertl/stream_shared_iterator.hpp delete mode 100644 YACReaderLibrary/lexertl/string_token.hpp delete mode 100644 YACReaderLibrary/lexertl/utf_iterators.hpp diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index e6d86252a..156056dfe 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -77,6 +77,7 @@ QT += sql network widgets script # Input HEADERS += comic_flow.h \ create_library_dialog.h \ + db/query_lexer.h \ library_creator.h \ library_window.h \ add_library_dialog.h \ @@ -144,42 +145,7 @@ HEADERS += comic_flow.h \ yacreader_comic_info_helper.h \ db/reading_list.h \ db/query_parser.h \ - current_comic_view_helper.h \ - lexertl/parser/tokeniser/re_token.hpp \ - lexertl/parser/tokeniser/re_tokeniser.hpp \ - lexertl/parser/tokeniser/re_tokeniser_helper.hpp \ - lexertl/parser/tokeniser/re_tokeniser_state.hpp \ - lexertl/parser/tree/end_node.hpp \ - lexertl/parser/tree/iteration_node.hpp \ - lexertl/parser/tree/leaf_node.hpp \ - lexertl/parser/tree/node.hpp \ - lexertl/parser/tree/selection_node.hpp \ - lexertl/parser/tree/sequence_node.hpp \ - lexertl/parser/parser.hpp \ - lexertl/partition/charset.hpp \ - lexertl/partition/equivset.hpp \ - lexertl/char_traits.hpp \ - lexertl/debug.hpp \ - lexertl/dot.hpp \ - lexertl/enums.hpp \ - lexertl/generate_cpp.hpp \ - lexertl/generator.hpp \ - lexertl/internals.hpp \ - lexertl/iterator.hpp \ - lexertl/lookup.hpp \ - lexertl/match_results.hpp \ - lexertl/memory_file.hpp \ - lexertl/narrow.hpp \ - lexertl/observer_ptr.hpp \ - lexertl/rules.hpp \ - lexertl/runtime_error.hpp \ - lexertl/serialise.hpp \ - lexertl/sm_to_csm.hpp \ - lexertl/sm_traits.hpp \ - lexertl/state_machine.hpp \ - lexertl/stream_shared_iterator.hpp \ - lexertl/string_token.hpp \ - lexertl/utf_iterators.hpp + current_comic_view_helper.h !CONFIG(no_opengl) { HEADERS += ../common/gl/yacreader_flow_gl.h @@ -187,6 +153,7 @@ HEADERS += comic_flow.h \ SOURCES += comic_flow.cpp \ create_library_dialog.cpp \ + db/query_lexer.cpp \ library_creator.cpp \ library_window.cpp \ main.cpp \ diff --git a/YACReaderLibrary/db/query_lexer.cpp b/YACReaderLibrary/db/query_lexer.cpp new file mode 100644 index 000000000..27944ff41 --- /dev/null +++ b/YACReaderLibrary/db/query_lexer.cpp @@ -0,0 +1,94 @@ +#include "query_lexer.h" + +QueryLexer::QueryLexer(const std::string &input) + : input(input) +{ +} + +Token QueryLexer::next() +{ + switch (peek()) { + case '\0': + return Token(Token::Type::eof); + case '(': + case ')': + return single(Token::Type::opcode); + case ' ': + case '\t': + case '\r': + case '\n': + return space(); + case '"': + return quotedWord(); + default: + return word(); + } +} + +char QueryLexer::peek() +{ + return input[index]; +} + +char QueryLexer::get() +{ + return input[index++]; +} + +Token QueryLexer::single(Token::Type type) +{ + return Token(type, input.substr(index++, 1)); +} + +Token QueryLexer::space() +{ + auto start = index; + get(); + while (isSpace(peek())) + get(); + return Token(Token::Type::space, input.substr(start, index - start)); +} + +Token QueryLexer::word() +{ + auto start = index; + get(); + auto current = peek(); + while (current != '\0' && !isSpace(current) && current != '"' && current != '(' && current != ')') { + get(); + current = peek(); + } + return Token(Token::Type::word, input.substr(start, index - start)); +} + +Token QueryLexer::quotedWord() +{ + auto start = index; + get(); + auto current = peek(); + while (current != '\0' && current != '"') { + get(); + current = peek(); + } + + if (current == '"') { + get(); + return Token(Token::Type::quotedWord, input.substr(start, index - start)); + } + + //This should be a lexical error, but the grammar doesn't support it + return Token(Token::Type::eof); +} + +bool QueryLexer::isSpace(char c) +{ + switch (c) { + case ' ': + case '\t': + case '\r': + case '\n': + return true; + default: + return false; + } +} diff --git a/YACReaderLibrary/db/query_lexer.h b/YACReaderLibrary/db/query_lexer.h new file mode 100644 index 000000000..b2c892f65 --- /dev/null +++ b/YACReaderLibrary/db/query_lexer.h @@ -0,0 +1,59 @@ +#ifndef QUERY_LEXER_H +#define QUERY_LEXER_H + +#include + +class Token +{ +public: + enum class Type { + eof, + opcode, + atWord, + word, + quotedWord, + space + }; + + Token(Type type, std::string lexeme = "") + : _type(type), _lexeme(std::move(lexeme)) + { + } + + Type type() const + { + return _type; + } + + std::string lexeme() const + { + return _lexeme; + } + +private: + Type _type {}; + std::string _lexeme {}; +}; + +class QueryLexer +{ +public: + QueryLexer(const std::string &input); + Token next(); + +private: + std::string input; + int index = 0; + + char peek(); + char get(); + + Token single(Token::Type type); + Token space(); + Token word(); + Token quotedWord(); + + bool isSpace(char c); +}; + +#endif // QUERY_LEXER_H diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index f08d08727..de9dc39e2 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -68,21 +68,14 @@ int QueryParser::TreeNode::bindValues(QSqlQuery &selectQuery, int bindPosition) } QueryParser::QueryParser() - : lexScanner(0) { - - lexScanner.push("[()]", static_cast::type>(TokenType::opcode)); - lexScanner.push("@[^:]+:[^\\\")\\s]+", static_cast::type>(TokenType::atWord)); - lexScanner.push("[^\\\"()\\s]+", static_cast::type>(TokenType::word)); - lexScanner.push("\\\".*?\\\"", static_cast::type>(TokenType::quotedWord)); - lexScanner.push("\\s+", static_cast::type>(TokenType::space)); - - lexertl::generator::build(lexScanner, sm); } QueryParser::TreeNode QueryParser::parse(const std::string &expr) { - tokenize(expr); + lexer = QueryLexer(expr); + advance(); + auto prog = orExpression(); if (!isEof()) { @@ -104,7 +97,10 @@ std::string QueryParser::token(bool advance) if (isEof()) { return ""; } - auto res = (tokenType() == TokenType::quotedWord) ? iter->substr(1, 1) : iter->str(); + + auto lexeme = currentToken.lexeme(); + + auto res = (tokenType() == Token::Type::quotedWord) ? currentToken.lexeme().substr(1, lexeme.size() - 2) : lexeme; //TODO process quotedWordDiferently? if (advance) { this->advance(); } @@ -116,30 +112,32 @@ std::string QueryParser::lcaseToken(bool advance) if (isEof()) { return ""; } - auto res = (tokenType() == TokenType::quotedWord) ? iter->substr(1, 1) : iter->str(); + + auto lexeme = currentToken.lexeme(); + + auto res = (tokenType() == Token::Type::quotedWord) ? currentToken.lexeme().substr(1, lexeme.size() - 2) : lexeme; + if (advance) { this->advance(); } return toLower(res); } -QueryParser::TokenType QueryParser::tokenType() +Token::Type QueryParser::tokenType() { - if (isEof()) { - return TokenType::eof; - } - return TokenType(iter->id); + return currentToken.type(); } bool QueryParser::isEof() const { - return iter == end; + return currentToken.type() == Token::Type::eof; } void QueryParser::advance() { - ++iter; - if (tokenType() == TokenType::space) + currentToken = lexer.next(); + + if (tokenType() == Token::Type::space) advance(); } @@ -154,11 +152,6 @@ QueryParser::FieldType QueryParser::fieldType(const std::string &str) return FieldType::unknown; } -void QueryParser::tokenize(const std::string &expr) -{ - iter = lexertl::siterator(expr.begin(), expr.end(), sm); -} - std::string QueryParser::join(const QStringList &strings, const std::string &delim) { return std::accumulate(strings.begin(), strings.end(), std::string(), @@ -191,7 +184,7 @@ QueryParser::TreeNode QueryParser::andExpression() return { "and", { lhs, andExpression() } }; } - if ((isIn(tokenType(), { TokenType::atWord, TokenType::word, TokenType::quotedWord }) || token() == "(") && lcaseToken() != "or") { + if ((isIn(tokenType(), { Token::Type::atWord, Token::Type::word, Token::Type::quotedWord }) || token() == "(") && lcaseToken() != "or") { return { "and", { lhs, andExpression() } }; } @@ -209,15 +202,15 @@ QueryParser::TreeNode QueryParser::notExpression() QueryParser::TreeNode QueryParser::locationExpression() { - if (tokenType() == TokenType::opcode && token() == "(") { + if (tokenType() == Token::Type::opcode && token() == "(") { advance(); auto res = orExpression(); - if (tokenType() != TokenType::opcode || token(true) != ")") { + if (tokenType() != Token::Type::opcode || token(true) != ")") { throw std::invalid_argument("missing )'"); } return res; } - if (!isIn(tokenType(), { TokenType::atWord, TokenType::word, TokenType::quotedWord })) { + if (!isIn(tokenType(), { Token::Type::atWord, Token::Type::word, Token::Type::quotedWord })) { throw std::invalid_argument("Invalid syntax. Expected a lookup name or a word"); } return baseToken(); @@ -225,7 +218,7 @@ QueryParser::TreeNode QueryParser::locationExpression() QueryParser::TreeNode QueryParser::baseToken() { - if (tokenType() == TokenType::quotedWord) { + if (tokenType() == Token::Type::quotedWord) { return { "token", { { "all", {} }, { token(true), {} } } }; } @@ -234,7 +227,7 @@ QueryParser::TreeNode QueryParser::baseToken() if (words.size() > 1 && fieldType(words[0].toStdString()) != FieldType::unknown) { auto loc(toLower(words[0].toStdString())); words.erase(words.begin()); - if (words.size() == 1 && tokenType() == TokenType::quotedWord) { + if (words.size() == 1 && tokenType() == Token::Type::quotedWord) { return { "token", { { loc, {} }, { token(true), {} } } }; } return { "token", { { loc, {} }, { join(words, ":"), {} } } }; diff --git a/YACReaderLibrary/db/query_parser.h b/YACReaderLibrary/db/query_parser.h index f23a74704..95fd48c8c 100644 --- a/YACReaderLibrary/db/query_parser.h +++ b/YACReaderLibrary/db/query_parser.h @@ -1,19 +1,19 @@ #ifndef QUERY_PARSER_H #define QUERY_PARSER_H -#include "lexertl/generator.hpp" -#include "lexertl/iterator.hpp" +#include "query_lexer.h" #include #include #include #include +#include /** * This class is used to generate an SQL query string from a search expression, * with a syntax very similar to that used by the Google search engine. * - * The code herin is based upon the SearchQueryParser python class written by + * The code herein is based upon the SearchQueryParser python class written by * Kovid Goyal as part of the Calibre eBook manager (https://calibre-ebook.com) * * Grammar: @@ -41,13 +41,6 @@ class QueryParser { public: - enum class TokenType { eof, - opcode, - atWord, - word, - quotedWord, - space }; - struct TreeNode { std::string t; std::vector children; @@ -64,10 +57,13 @@ class QueryParser std::string token(bool advance = false); std::string lcaseToken(bool advance = false); - TokenType tokenType(); + Token::Type tokenType(); bool isEof() const; void advance(); + QueryLexer lexer = QueryLexer(""); + Token currentToken = Token(Token::Type::eof); + template static bool isIn(const T &e, const std::list &v) { @@ -83,7 +79,6 @@ class QueryParser filename }; static FieldType fieldType(const std::string &str); - void tokenize(const std::string &expr); static std::string join(const QStringList &strings, const std::string &delim); static QStringList split(const std::string &string, char delim); @@ -93,11 +88,6 @@ class QueryParser TreeNode locationExpression(); TreeNode baseToken(); - lexertl::rules lexScanner; - lexertl::state_machine sm; - lexertl::siterator iter; - const lexertl::siterator end; - static const std::map> fieldNames; }; diff --git a/YACReaderLibrary/lexertl/char_traits.hpp b/YACReaderLibrary/lexertl/char_traits.hpp deleted file mode 100644 index e06f399a5..000000000 --- a/YACReaderLibrary/lexertl/char_traits.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// char_traits.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LEXERTL_CHAR_TRAITS_HPP -#define LEXERTL_CHAR_TRAITS_HPP - -#include - -namespace lexertl -{ -template -struct basic_char_traits -{ - using char_type = ch_type; - using index_type = ch_type; - - static index_type max_val() - { - const std::uint32_t max_ = 0x10ffff; - - return sizeof(char_type) > 2 ? - max_ : (max_ & 0xffff); - } -}; - -template<> -struct basic_char_traits -{ - using char_type = char; - using index_type = unsigned char; - - static index_type max_val() - { - // Prevent annoying warning (VC++) - index_type zero_ = 0; - - return ~zero_; - } -}; -} - -#endif diff --git a/YACReaderLibrary/lexertl/debug.hpp b/YACReaderLibrary/lexertl/debug.hpp deleted file mode 100644 index 1405f3866..000000000 --- a/YACReaderLibrary/lexertl/debug.hpp +++ /dev/null @@ -1,311 +0,0 @@ -// debug.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_DEBUG_HPP -#define LEXERTL_DEBUG_HPP - -#include -#include -#include "rules.hpp" -#include "sm_to_csm.hpp" -#include "state_machine.hpp" -#include "string_token.hpp" -#include - -namespace lexertl -{ -template -class basic_debug -{ -public: - using char_state_machine = - basic_char_state_machine; - using ostream = std::basic_ostream; - using rules = basic_rules; - using string = std::basic_string; - - static void dump(const sm &sm_, rules &rules_, ostream &stream_) - { - char_state_machine csm_; - - sm_to_csm(sm_, csm_); - dump(csm_, rules_, stream_); - } - - static void dump(const sm &sm_, ostream &stream_) - { - char_state_machine csm_; - - sm_to_csm(sm_, csm_); - dump(csm_, stream_); - } - - static void dump(const char_state_machine &csm_, rules &rules_, - ostream &stream_) - { - for (std::size_t dfa_ = 0, dfas_ = csm_.size(); dfa_ < dfas_; ++dfa_) - { - lexer_state(stream_); - stream_ << rules_.state(dfa_) << std::endl << std::endl; - - dump_ex(csm_._sm_vector[dfa_], stream_); - } - } - - static void dump(const char_state_machine &csm_, ostream &stream_) - { - for (std::size_t dfa_ = 0, dfas_ = csm_.size(); dfa_ < dfas_; ++dfa_) - { - lexer_state(stream_); - stream_ << dfa_ << std::endl << std::endl; - - dump_ex(csm_._sm_vector[dfa_], stream_); - } - } - -protected: - using dfa_state = typename char_state_machine::state; - using string_token = typename dfa_state::string_token; - using stringstream = std::basic_stringstream; - - static void dump_ex(const typename char_state_machine::dfa &dfa_, - ostream &stream_) - { - const std::size_t states_ = dfa_._states.size(); - const id_type bol_index_ = dfa_._bol_index; - - for (std::size_t i_ = 0; i_ < states_; ++i_) - { - const dfa_state &state_ = dfa_._states[i_]; - - state(stream_); - stream_ << i_ << std::endl; - - if (state_._end_state) - { - end_state(stream_); - - if (state_._push_pop_dfa == dfa_state::push_dfa) - { - push(stream_); - stream_ << state_._push_dfa; - } - else if (state_._push_pop_dfa == dfa_state::pop_dfa) - { - pop(stream_); - } - - id(stream_); - stream_ << static_cast(state_._id); - user_id(stream_); - stream_ << static_cast(state_._user_id); - dfa(stream_); - stream_ << static_cast(state_._next_dfa); - stream_ << std::endl; - } - - if (i_ == 0 && bol_index_ != char_state_machine::npos()) - { - bol(stream_); - stream_ << static_cast(bol_index_) << std::endl; - } - - if (state_._eol_index != char_state_machine::npos()) - { - eol(stream_); - stream_ << static_cast(state_._eol_index) << - std::endl; - } - - for (const auto &tran_ : state_._transitions) - { - string_token token_ = tran_.second; - - open_bracket(stream_); - - if (!tran_.second.any() && tran_.second.negatable()) - { - token_.negate(); - negated(stream_); - } - - string chars_; - - for (const auto &range_ : token_._ranges) - { - if (range_.first == '-' || range_.first == '^' || - range_.first == ']') - { - stream_ << '\\'; - } - - chars_ = string_token::escape_char - (range_.first); - - if (range_.first != range_.second) - { - if (range_.first + 1 < range_.second) - { - chars_ += '-'; - } - - if (range_.second == '-' || range_.second == '^' || - range_.second == ']') - { - stream_ << '\\'; - } - - chars_ += string_token::escape_char(range_.second); - } - - stream_ << chars_; - } - - close_bracket(stream_); - stream_ << static_cast(tran_.first) << - std::endl; - } - - stream_ << std::endl; - } - } - - static void lexer_state(std::ostream &stream_) - { - stream_ << "Lexer state: "; - } - - static void lexer_state(std::wostream &stream_) - { - stream_ << L"Lexer state: "; - } - - static void state(std::ostream &stream_) - { - stream_ << "State: "; - } - - static void state(std::wostream &stream_) - { - stream_ << L"State: "; - } - - static void bol(std::ostream &stream_) - { - stream_ << " BOL -> "; - } - - static void bol(std::wostream &stream_) - { - stream_ << L" BOL -> "; - } - - static void eol(std::ostream &stream_) - { - stream_ << " EOL -> "; - } - - static void eol(std::wostream &stream_) - { - stream_ << L" EOL -> "; - } - - static void end_state(std::ostream &stream_) - { - stream_ << " END STATE"; - } - - static void end_state(std::wostream &stream_) - { - stream_ << L" END STATE"; - } - - static void id(std::ostream &stream_) - { - stream_ << ", Id = "; - } - - static void id(std::wostream &stream_) - { - stream_ << L", Id = "; - } - - static void push(std::ostream &stream_) - { - stream_ << ", PUSH "; - } - - static void push(std::wostream &stream_) - { - stream_ << L", PUSH "; - } - - static void pop(std::ostream &stream_) - { - stream_ << ", POP"; - } - - static void pop(std::wostream &stream_) - { - stream_ << L", POP"; - } - - static void user_id(std::ostream &stream_) - { - stream_ << ", User Id = "; - } - - static void user_id(std::wostream &stream_) - { - stream_ << L", User Id = "; - } - - static void open_bracket(std::ostream &stream_) - { - stream_ << " ["; - } - - static void open_bracket(std::wostream &stream_) - { - stream_ << L" ["; - } - - static void negated(std::ostream &stream_) - { - stream_ << "^"; - } - - static void negated(std::wostream &stream_) - { - stream_ << L"^"; - } - - static void close_bracket(std::ostream &stream_) - { - stream_ << "] -> "; - } - - static void close_bracket(std::wostream &stream_) - { - stream_ << L"] -> "; - } - - static void dfa(std::ostream &stream_) - { - stream_ << ", dfa = "; - } - - static void dfa(std::wostream &stream_) - { - stream_ << L", dfa = "; - } -}; - -using debug = basic_debug; -using wdebug = basic_debug; -} - -#endif diff --git a/YACReaderLibrary/lexertl/dot.hpp b/YACReaderLibrary/lexertl/dot.hpp deleted file mode 100644 index cda4d6ac2..000000000 --- a/YACReaderLibrary/lexertl/dot.hpp +++ /dev/null @@ -1,293 +0,0 @@ -// dot.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// Copyright (c) 2013 Autodesk, Inc. All rights reserved. -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_DOT_HPP -#define LEXERTL_DOT_HPP - -#include -#include "rules.hpp" -#include "state_machine.hpp" -#include "sm_to_csm.hpp" - -namespace lexertl -{ -//! The class template basic_dot contains utility functions used to -//! dump a description of a finite state machine formatted in the -//! DOT language (http://www.graphviz.org/doc/info/lang.html). The -//! resulting directed graph can previewed by opening the ".dot" file -//! into the GraphViz application (http://www.graphviz.org). -template -class basic_dot -{ -public: - using char_state_machine = - basic_char_state_machine; - using rules = basic_rules; - using ostream = std::basic_ostream; - using string = std::basic_string; - - //! Dumps a description of the finite state machine expressed in - //! the DOT language to the given output stream. - static void dump(const sm &sm_, rules &rules_, ostream &stream_) - { - char_state_machine csm_; - - sm_to_csm(sm_, csm_); - dump(csm_, rules_, stream_); - } - - //! Dumps a description of the finite state machine expressed in - //! the DOT language to the given output stream. - static void dump(const char_state_machine &csm_, rules &rules_, - ostream &stream_) - { - header(stream_); - for (std::size_t dfa_ = 0, dfas_ = csm_.size(); dfa_ < dfas_; ++dfa_) - { - dump_ex(dfa_, csm_._sm_vector[dfa_], rules_, stream_); - } - trailer(stream_); - } - -protected: - using dfa_state = typename char_state_machine::state; - using string_token = typename dfa_state::string_token; - using stringstream = std::basic_stringstream; - - // Naming of nodes used in the DOT diagram. The naming is of the - // form: L_S. - static string node_name(id_type dfa_id_, id_type state_id_) - { - stringstream namestream_; - namestream_ << "L" << dfa_id_ << "_S" << state_id_; - return namestream_.str(); - } - - // Escape control characters twice. This is necessary when - // expressing character sets attached as to DOT nodes as - // labels. - static string double_escape_char(const id_type ch_) - { - stringstream out_; - - switch (ch_) - { - case '\0': - out_ << '\\'; - out_ << '\\'; - out_ << '0'; - break; - case '\a': - out_ << '\\'; - out_ << '\\'; - out_ << 'a'; - break; - case '\b': - out_ << '\\'; - out_ << '\\'; - out_ << 'b'; - break; - case '\f': - out_ << '\\'; - out_ << '\\'; - out_ << 'f'; - break; - case '\n': - out_ << '\\'; - out_ << '\\'; - out_ << 'n'; - break; - case '\r': - out_ << '\\'; - out_ << '\\'; - out_ << 'r'; - break; - case '\t': - out_ << '\\'; - out_ << '\\'; - out_ << 't'; - break; - case '\v': - out_ << '\\'; - out_ << '\\'; - out_ << 'v'; - break; - case '\\': - out_ << '\\'; - out_ << '\\'; - break; - case '"': - out_ << '\\'; - out_ << '\\'; - out_ << '"'; - break; - case '\'': - out_ << '\\'; - out_ << '\\'; - out_ << '\''; - break; - default: - { - if (ch_ < 32 || ch_ > 126) - { - out_ << '\\'; - out_ << 'x'; - out_ << std::hex << - static_cast(ch_); - } - else - { - out_ << char_type(ch_); - } - - break; - } - } - - return out_.str(); - } - - // Internal function actually performing the work of dumping the - // state machine in DOT. - static void dump_ex(id_type dfa_id_, - const typename char_state_machine::dfa &dfa_, - rules &rules_, - ostream &stream_) - { - const std::size_t states_ = dfa_._states.size(); - typename dfa_state::id_type_string_token_map::const_iterator iter_; - typename dfa_state::id_type_string_token_map::const_iterator end_; - - stream_ << std::endl; - - for (std::size_t i_ = 0; i_ < states_; ++i_) - { - const dfa_state &state_ = dfa_._states[i_]; - - const string name = node_name(dfa_id_, i_); - if (i_ == 0) - { - stream_ << " " << name << " [shape = doublecircle, xlabel=\"" - << rules_.state(dfa_id_) << "\"];" << std::endl; - } - else if (state_._end_state) - { - stream_ << " " << name << - " [shape = doublecircle, xlabel=\"id =" << - static_cast(state_._id) << "\"];" << - std::endl; - } - else { - stream_ << " " << name << " [shape = circle];" << std::endl; - } - } - - stream_ << std::endl; - - for (std::size_t i_ = 0; i_ < states_; ++i_) - { - const dfa_state &state_ = dfa_._states[i_]; - - iter_ = state_._transitions.begin(); - end_ = state_._transitions.end(); - - const string src_name = node_name(dfa_id_, i_); - - for (; iter_ != end_; ++iter_) - { - const string dst_name = node_name(dfa_id_, iter_->first); - stream_ << " " << src_name << " -> " << dst_name << - " [label = \""; - - string_token token_ = iter_->second; - - open_bracket(stream_); - - if (!iter_->second.any() && iter_->second.negatable()) - { - token_.negate(); - negated(stream_); - } - - string chars_; - auto ranges_iter_ = token_._ranges.cbegin(); - auto ranges_end_ = token_._ranges.cend(); - - for (; ranges_iter_ != ranges_end_; ++ranges_iter_) - { - if (ranges_iter_->first == '^' || - ranges_iter_->first == ']') - { - stream_ << "\\\\"; - } - - chars_ = double_escape_char(ranges_iter_->first); - - if (ranges_iter_->first != ranges_iter_->second) - { - if (ranges_iter_->first + 1 < ranges_iter_->second) - { - chars_ += '-'; - } - - if (ranges_iter_->second == '^' || - ranges_iter_->second == ']') - { - stream_ << "\\\\"; - } - - chars_ += double_escape_char(ranges_iter_->second); - } - - stream_ << chars_; - } - - close_bracket(stream_); - stream_ << "\"];" << std::endl; - } - - if (state_._end_state) { - const string dst_name = node_name(state_._next_dfa, 0); - stream_ << " " << src_name << " -> " << dst_name - << " [style = \"dashed\"];" << std::endl; - } - } - } - - static void header(ostream &stream_) - { - stream_ << "digraph DFAs {" << std::endl; - stream_ << " rankdir = LR;" << std::endl; - } - - static void trailer(ostream &stream_) - { - stream_ << "}" << std::endl; - } - - static void open_bracket(ostream &stream_) - { - stream_ << "["; - } - - static void negated(ostream &stream_) - { - stream_ << "^"; - } - - static void close_bracket(ostream &stream_) - { - stream_ << "]"; - } - -}; - -using dot = basic_dot, char>; -using wdot = basic_dot, wchar_t>; -} - -#endif diff --git a/YACReaderLibrary/lexertl/enums.hpp b/YACReaderLibrary/lexertl/enums.hpp deleted file mode 100644 index 31a6a9698..000000000 --- a/YACReaderLibrary/lexertl/enums.hpp +++ /dev/null @@ -1,25 +0,0 @@ -// enums.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LEXERTL_ENUMS_HPP -#define LEXERTL_ENUMS_HPP - -namespace lexertl -{ - enum regex_flags {icase = 1, dot_not_newline = 2, dot_not_cr_lf = 4, - skip_ws = 8, match_zero_len = 16}; - // 0 = end state, 1 = id, 2 = user id, 3 = push_dfa_index - // 4 = next dfa, 5 = dead state, 6 = dfa_start - enum {end_state_index, id_index, user_id_index, push_dfa_index, - next_dfa_index, eol_index, dead_state_index, transitions_index}; - // Rule flags: - enum feature_flags {bol_bit = 1, eol_bit = 2, skip_bit = 4, again_bit = 8, - multi_state_bit = 16, recursive_bit = 32, advance_bit = 64}; - // End state flags: - enum {end_state_bit = 1, pop_dfa_bit = 2}; -} - -#endif diff --git a/YACReaderLibrary/lexertl/generate_cpp.hpp b/YACReaderLibrary/lexertl/generate_cpp.hpp deleted file mode 100644 index 3e6b28a66..000000000 --- a/YACReaderLibrary/lexertl/generate_cpp.hpp +++ /dev/null @@ -1,1123 +0,0 @@ -// generate_cpp.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_GENERATE_CPP_HPP -#define LEXERTL_GENERATE_CPP_HPP - -#include "enums.hpp" -#include -#include "state_machine.hpp" - -namespace lexertl -{ -class table_based_cpp -{ -public: - template - static void generate_cpp - (const std::string &name_, - const basic_state_machine &sm_, - const bool pointers_, std::ostream &os_) - { - using sm = basic_state_machine; - using internals = typename sm::internals; - const internals &internals_ = sm_.data(); - std::size_t additional_tabs_ = 0; - - os_ << "template\n"; - os_ << "void " << name_ << " (lexertl::"; - - if (internals_._features & recursive_bit) - { - os_ << "recursive_match_results"; - } - else - { - os_ << "match_results"; - } - - os_ << " &results_)\n"; - os_ << "{\n"; - os_ << " using results = lexertl::"; - - if (internals_._features & recursive_bit) - { - os_ << "recursive_match_results"; - } - else - { - os_ << "match_results"; - } - - os_ << ";\n"; - os_ << " using char_type = typename results::char_type;\n"; - os_ << " typename results::iter_type end_token_ = " - "results_.second;\n"; - - if (internals_._features & skip_bit) - { - os_ << "skip:\n"; - } - - os_ << " typename results::iter_type curr_ = results_.second;\n\n"; - os_ << " results_.first = curr_;\n\n"; - - if (internals_._features & again_bit) - { - os_ << "again:\n"; - } - - os_ << " if (curr_ == results_.eoi)\n"; - os_ << " {\n"; - // We want a number regardless of id_type. - os_ << " results_.id = " << static_cast - (internals_._eoi) << ";\n"; - os_ << " results_.user_id = results::npos();\n"; - os_ << " return;\n"; - os_ << " }\n\n"; - - if (internals_._features & bol_bit) - { - os_ << " bool bol_ = results_.bol;\n"; - } - - dump_tables(sm_, 1, pointers_, os_); - - if (internals_._dfa.size() > 1) - { - os_ << " const id_type *lookup_ = lookups_[results_.state];\n"; - os_ << " const id_type dfa_alphabet_ = dfa_alphabets_" - "[results_.state];\n"; - os_ << " const "; - - if (pointers_) - { - os_ << "void * const"; - } - else - { - os_ << "id_type"; - } - - os_ << " *dfa_ = dfas_[results_.state];\n"; - } - - os_ << " const "; - - if (pointers_) - { - os_ << "void * const"; - } - else - { - os_ << "id_type"; - } - - os_ << " *ptr_ = dfa_ + dfa_alphabet_;\n"; - os_ << " bool end_state_ = *ptr_ != 0;\n"; - - if (internals_._features & recursive_bit) - { - os_ << " bool pop_ = ("; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*ptr_"; - - if (pointers_) - { - os_ << ')'; - } - - os_ <<" & " << pop_dfa_bit; - - if (pointers_) - { - os_ << ')'; - } - - os_ << ") != 0;\n"; - } - - os_ << " id_type id_ = "; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*(ptr_ + " << id_index << ")"; - - if (pointers_) - { - os_ << "))"; - } - - os_ << ";\n"; - os_ << " id_type uid_ = "; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*(ptr_ + " << user_id_index << ")"; - - if (pointers_) - { - os_ << "))"; - } - - os_ << ";\n"; - - if (internals_._features & recursive_bit) - { - os_ << " id_type push_dfa_ = "; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*(ptr_ + " << push_dfa_index << ")"; - - if (pointers_) - { - os_ << "))"; - } - - os_ << ";\n"; - } - - if (internals_._dfa.size() > 1) - { - os_ << " id_type start_state_ = results_.state;\n"; - } - - if (internals_._features & bol_bit) - { - os_ << " bool end_bol_ = bol_;\n"; - } - - if (internals_._features & eol_bit) - { - os_ << " "; - - if (pointers_) - { - os_ << "const void * const *"; - } - else - { - os_ << "id_type "; - } - - os_ << "EOL_state_ = 0;\n"; - } - - os_ << '\n'; - - if (internals_._features & bol_bit) - { - os_ << " if (bol_)\n"; - os_ << " {\n"; - os_ << " const "; - - if (pointers_) - { - os_ << "void *"; - } - else - { - os_ << "id_type "; - } - - os_ << "state_ = *dfa_;\n\n"; - os_ << " if (state_)\n"; - os_ << " {\n"; - os_ << " ptr_ = "; - - if (pointers_) - { - os_ << "reinterpret_cast(state_);\n"; - } - else - { - os_ << "&dfa_[state_ * dfa_alphabet_];\n"; - } - - os_ << " }\n"; - os_ << " }\n\n"; - } - - os_ << " while (curr_ != results_.eoi)\n"; - os_ << " {\n"; - - if (internals_._features & eol_bit) - { - os_ << " EOL_state_ = "; - - if (pointers_) - { - os_ << "reinterpret_cast("; - } - - os_ << "ptr_[" << eol_index << ']'; - - if (pointers_) - { - os_ << ')'; - } - - os_ << ";\n\n"; - os_ << " if (EOL_state_ && *curr_ == '\\n')\n"; - os_ << " {\n"; - os_ << " ptr_ = "; - - if (pointers_) - { - os_ << "EOL_state_"; - } - else - { - os_ << "&dfa_[EOL_state_ * dfa_alphabet_]"; - } - - os_ << ";\n"; - os_ << " }\n"; - os_ << " else\n"; - os_ << " {\n"; - ++additional_tabs_; - } - - output_char_loop(internals_._features, additional_tabs_, pointers_, - os_, std::integral_constant 1)>()); - - if (internals_._features & eol_bit) - { - output_tabs(additional_tabs_, os_); - os_ << " }\n"; - --additional_tabs_; - } - - os_ << '\n'; - os_ << " if (*ptr_)\n"; - os_ << " {\n"; - os_ << " end_state_ = true;\n"; - - - if (internals_._features & recursive_bit) - { - os_ << " pop_ = ("; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*ptr_"; - - if (pointers_) - { - os_ << ')'; - } - - os_ <<" & " << pop_dfa_bit; - - if (pointers_) - { - os_ << ')'; - } - - os_ << ") != 0;\n"; - } - - os_ << " id_ = "; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*(ptr_ + " << id_index << ")"; - - if (pointers_) - { - os_ << "))"; - } - - os_ << ";\n"; - os_ << " uid_ = "; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*(ptr_ + " << user_id_index << ")"; - - if (pointers_) - { - os_ << "))"; - } - - os_ << ";\n"; - - if (internals_._features & recursive_bit) - { - os_ << " push_dfa_ = "; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*(ptr_ + " << push_dfa_index << ')'; - - if (pointers_) - { - os_ << "))"; - } - - os_ << ";\n"; - } - - if (internals_._dfa.size() > 1) - { - os_ << " start_state_ = "; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*(ptr_ + " << next_dfa_index << ')'; - - if (pointers_) - { - os_ << "))"; - } - - os_ << ";\n"; - } - - if (internals_._features & bol_bit) - { - os_ << " end_bol_ = bol_;\n"; - } - - os_ << " end_token_ = curr_;\n"; - os_ << " }\n"; - os_ << " }\n\n"; - output_quit(os_, std::integral_constant 1)>()); - - if (internals_._features & eol_bit) - { - os_ << " if (curr_ == results_.eoi)\n"; - os_ << " {\n"; - os_ << " EOL_state_ = "; - - if (pointers_) - { - os_ << "reinterpret_cast("; - } - - os_ << "ptr_[" << eol_index << ']'; - - if (pointers_) - { - os_ << ')'; - } - - os_ << ";\n"; - os_ << "\n"; - os_ << " if (EOL_state_)\n"; - os_ << " {\n"; - os_ << " ptr_ = "; - - if (pointers_) - { - os_ << "EOL_state_"; - } - else - { - os_ << "&dfa_[EOL_state_ * dfa_alphabet_]"; - } - - os_ << ";\n\n"; - os_ << " if (*ptr_)\n"; - os_ << " {\n"; - os_ << " end_state_ = true;\n"; - - - if (internals_._features & recursive_bit) - { - os_ << " pop_ = ("; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*ptr_"; - - if (pointers_) - { - os_ << ')'; - } - - os_ <<" & " << pop_dfa_bit; - - if (pointers_) - { - os_ << ')'; - } - - os_ << ") != 0;\n"; - } - - os_ << " id_ = "; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*(ptr_ + " << id_index << ")"; - - if (pointers_) - { - os_ << "))"; - } - - os_ << ";\n"; - os_ << " uid_ = "; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*(ptr_ + " << user_id_index << ")"; - - if (pointers_) - { - os_ << "))"; - } - - os_ <<";\n"; - - if (internals_._features & recursive_bit) - { - os_ << " push_dfa_ = "; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*(ptr_ + " << push_dfa_index << ')'; - - if (pointers_) - { - os_ << "))"; - } - - os_ << ";\n"; - } - - if (internals_._dfa.size() > 1) - { - os_ << " start_state_ = "; - - if (pointers_) - { - // Done this way for GCC: - os_ << "static_cast(reinterpret_cast("; - } - - os_ << "*(ptr_ + " << next_dfa_index << ')'; - - if (pointers_) - { - os_ << "))"; - } - - os_ << ";\n"; - } - - if (internals_._features & bol_bit) - { - os_ << " end_bol_ = bol_;\n"; - } - - os_ << " end_token_ = curr_;\n"; - os_ << " }\n"; - os_ << " }\n"; - os_ << " }\n\n"; - } - - os_ << " if (end_state_)\n"; - os_ << " {\n"; - os_ << " // Return longest match\n"; - - if (internals_._features & recursive_bit) - { - os_ << " if (pop_)\n"; - os_ << " {\n"; - os_ << " start_state_ = results_." - "stack.top().first;\n"; - os_ << " results_.stack.pop();\n"; - os_ << " }\n"; - os_ << " else if (push_dfa_ != results_.npos())\n"; - os_ << " {\n"; - os_ << " results_.stack.push(typename results::" - "id_type_pair\n"; - os_ << " (push_dfa_, id_));\n"; - os_ << " }\n\n"; - } - - if (internals_._dfa.size() > 1) - { - os_ << " results_.state = start_state_;\n"; - } - - if (internals_._features & bol_bit) - { - os_ << " results_.bol = end_bol_;\n"; - } - - os_ << " results_.second = end_token_;\n"; - - if (internals_._features & skip_bit) - { - // We want a number regardless of id_type. - os_ << "\n if (id_ == results_.skip()) goto skip;\n"; - } - - if (internals_._features & again_bit) - { - // We want a number regardless of id_type. - os_ << "\n if (id_ == " - << static_cast(internals_._eoi); - - if (internals_._features & recursive_bit) - { - os_ << " || (pop_ && !results_.stack.empty() &&\n"; - // We want a number regardless of id_type. - os_ << " results_.stack.top().second == " - << static_cast(internals_._eoi) << ')'; - } - - os_ << ")\n"; - os_ << " {\n"; - os_ << " curr_ = end_token_;\n"; - os_ << " goto again;\n"; - os_ << " }\n"; - } - - os_ << " }\n"; - os_ << " else\n"; - os_ << " {\n"; - os_ << " // No match causes char to be skipped\n"; - os_ << " results_.second = end_token_;\n"; - - if (internals_._features & bol_bit) - { - os_ << " results_.bol = *results_.second == '\\n';\n"; - } - - os_ << " results_.first = results_.second;\n"; - os_ << " ++results_.second;\n"; - os_ << " id_ = results::npos();\n"; - os_ << " uid_ = results::npos();\n"; - os_ << " }\n\n"; - os_ << " results_.id = id_;\n"; - os_ << " results_.user_id = uid_;\n"; - os_ << "}\n"; - } - - template - static void dump_tables - (const basic_state_machine &sm_, - const std::size_t tabs_, const bool pointers_, std::ostream &os_) - { - const typename detail::basic_internals &internals_ = - sm_.data(); - const std::size_t lookup_divisor_ = 8; - // Lookup is always 256 entries long now - const std::size_t lookup_quotient_ = 256 / lookup_divisor_; - const std::size_t dfas_ = internals_._lookup.size(); - - output_tabs(tabs_, os_); - os_ << "static const id_type lookup"; - - if (dfas_ > 1) - { - os_ << "s_[][" << 256; - } - else - { - os_ << "_["; - } - - os_ << "] = \n"; - output_tabs(tabs_ + 1, os_); - - if (dfas_ > 1) - { - os_ << '{'; - } - - for (std::size_t l_ = 0; l_ < dfas_; ++l_) - { - const id_type *ptr_ = &internals_._lookup[l_].front(); - - // We want numbers regardless of id_type. - os_ << "{0x" << std::hex << static_cast(*ptr_++); - - for (std::size_t col_ = 1; col_ < lookup_divisor_; ++col_) - { - // We want numbers regardless of id_type. - os_ << ", 0x" << std::hex << static_cast(*ptr_++); - } - - for (std::size_t row_ = 1; row_ < lookup_quotient_; ++row_) - { - os_ << ",\n"; - output_tabs(tabs_ + 1, os_); - // We want numbers regardless of id_type. - os_ << "0x" << std::hex << static_cast(*ptr_++); - - for (std::size_t col_ = 1; col_ < lookup_divisor_; ++col_) - { - // We want numbers regardless of id_type. - os_ << ", 0x" << std::hex << - static_cast(*ptr_++); - } - } - - os_ << '}'; - - if (l_ + 1 < dfas_) - { - os_ << ",\n"; - output_tabs(tabs_ + 1, os_); - } - } - - if (dfas_ > 1) - { - os_ << '}'; - } - - os_ << ";\n"; - output_tabs(tabs_, os_); - os_ << "static const id_type dfa_alphabet"; - - if (dfas_ > 1) - { - os_ << "s_[" << std::dec << dfas_ << "] = {"; - } - else - { - os_ << "_ = "; - } - - // We want numbers regardless of id_type. - os_ << "0x" << std::hex << static_cast - (internals_._dfa_alphabet[0]); - - for (std::size_t col_ = 1; col_ < dfas_; ++col_) - { - // We want numbers regardless of id_type. - os_ << ", 0x" << std::hex << static_cast(internals_. - _dfa_alphabet[col_]); - } - - if (dfas_ > 1) - { - os_ << '}'; - } - - os_ << ";\n"; - - // DFAs are usually different sizes, so dump separately - for (std::size_t dfa_ = 0; dfa_ < dfas_; ++dfa_) - { - const id_type dfa_alphabet_ = internals_._dfa_alphabet[dfa_]; - const std::size_t rows_ = internals_._dfa[dfa_].size() / - dfa_alphabet_; - const id_type *ptr_ = &internals_._dfa[dfa_].front(); - std::string dfa_name_ = "dfa"; - - output_tabs(tabs_, os_); - os_ << "static const "; - - if (pointers_) - { - os_ << "void *"; - } - else - { - os_ << "id_type "; - } - - os_ << dfa_name_; - - if (dfas_ > 1) - { - std::ostringstream ss_; - - ss_ << dfa_; - dfa_name_ += ss_.str(); - os_ << dfa_; - } - - dfa_name_ += '_'; - os_ << "_[] = {"; - - for (std::size_t row_ = 0; row_ < rows_; ++row_) - { - dump_row(row_ == 0, ptr_, dfa_name_, dfa_alphabet_, - pointers_, os_); - - if (row_ + 1 < rows_) - { - os_ << ",\n"; - output_tabs(tabs_ + 1, os_); - } - } - - os_ << "};\n"; - } - - if (dfas_ > 1) - { - output_tabs(tabs_, os_); - os_ << "static const "; - - if (pointers_) - { - os_ << "void * const"; - } - else - { - os_ << "id_type"; - } - - os_ << " *dfas_[] = {dfa0_"; - - for (std::size_t col_ = 1; col_ < dfas_; ++col_) - { - os_ << ", dfa" << col_ << '_'; - } - - os_ << "};\n"; - } - - os_ << std::dec; - } - -protected: - template - static void dump_row(const bool first_, const id_type * &ptr_, - const std::string &dfa_name_, const id_type dfa_alphabet_, - const bool pointers_, std::ostream &os_) - { - if (pointers_) - { - bool zero_ = *ptr_ == 0; - - if (first_) - { - // We want numbers regardless of id_type. - os_ << dfa_name_ << " + 0x" << std::hex << - static_cast(*ptr_++) * dfa_alphabet_; - } - else if (!zero_) - { - os_ << "reinterpret_cast(0x" - // We want numbers regardless of id_type. - << std::hex << static_cast(*ptr_++) << ')'; - } - else - { - // We want numbers regardless of id_type. - os_ << "0x" << std::hex << static_cast(*ptr_++); - } - - for (id_type id_index_ = id_index; id_index_ < transitions_index; - ++id_index_, ++ptr_) - { - os_ << ", "; - zero_ = *ptr_ == 0; - - if (!zero_) - { - os_ << "reinterpret_cast("; - } - - // We want numbers regardless of id_type. - os_ << "0x" << std::hex << static_cast(*ptr_); - - if (!zero_) - { - os_ << ')'; - } - } - - for (id_type alphabet_ = transitions_index; - alphabet_ < dfa_alphabet_; ++alphabet_, ++ptr_) - { - // We want numbers regardless of id_type. - os_ << ", "; - - if (*ptr_ == 0) - { - os_ << 0; - } - else - { - // We want numbers regardless of id_type. - os_ << dfa_name_ + " + 0x" << std::hex << - static_cast(*ptr_) * dfa_alphabet_; - } - } - } - else - { - // We want numbers regardless of id_type. - os_ << "0x" << std::hex << static_cast(*ptr_++); - - for (id_type alphabet_ = 1; alphabet_ < dfa_alphabet_; - ++alphabet_, ++ptr_) - { - // We want numbers regardless of id_type. - os_ << ", 0x" << std::hex << static_cast(*ptr_); - } - } - } - - static void output_tabs(const std::size_t tabs_, std::ostream &os_) - { - for (std::size_t i_ = 0; i_ < tabs_; ++i_) - { - os_ << " "; - } - } - - template - static void output_char_loop(const id_type features_, - const std::size_t additional_tabs_, const bool pointers_, - std::ostream &os_, const std::false_type &) - { - output_tabs(additional_tabs_, os_); - os_ << " const typename results::char_type prev_char_ = " - "*curr_++;\n"; - output_tabs(additional_tabs_, os_); - os_ << " const "; - - if (pointers_) - { - os_ << "void * const *"; - } - else - { - os_ << "id_type "; - } - - os_ << "state_ = "; - - if (pointers_) - { - os_ << "reinterpret_cast\n "; - output_tabs(additional_tabs_, os_); - os_ << '('; - } - - os_ << "ptr_[lookup_"; - - if (!pointers_) - { - os_ << "\n "; - output_tabs(additional_tabs_, os_); - } - - os_ << "[static_cast"; - - if (pointers_) - { - os_ << "\n "; - output_tabs(additional_tabs_, os_); - } - - os_ << "(prev_char_)]]"; - - if (pointers_) - { - os_ << ')'; - } - - os_ << ";\n\n"; - - if (features_ & bol_bit) - { - output_tabs(additional_tabs_, os_); - os_ << " bol_ = prev_char_ == '\\n';\n\n"; - } - - output_tabs(additional_tabs_, os_); - os_ << " if (state_ == 0)\n"; - output_tabs(additional_tabs_, os_); - os_ << " {\n"; - - if (features_ & eol_bit) - { - output_tabs(additional_tabs_, os_); - os_ << " EOL_state_ = 0;\n"; - } - - output_tabs(additional_tabs_, os_); - os_ << " break;\n"; - output_tabs(additional_tabs_, os_); - os_ << " }\n\n"; - output_tabs(additional_tabs_, os_); - os_ << " ptr_ = "; - - if (pointers_) - { - os_ << "state_"; - } - else - { - os_ << "&dfa_[state_ * dfa_alphabet_]"; - } - - os_ << ";\n"; - } - - template - static void output_char_loop(const id_type features_, - const std::size_t additional_tabs_, const bool pointers_, - std::ostream &os_, const std::true_type &) - { - output_tabs(additional_tabs_, os_); - os_ << " const std::size_t bytes_ =\n"; - output_tabs(additional_tabs_, os_); - os_ << " sizeof(typename results::char_type) < 3 ?\n"; - output_tabs(additional_tabs_, os_); - os_ << " sizeof(typename results::char_type) : 3;\n"; - output_tabs(additional_tabs_, os_); - os_ << " const std::size_t shift_[] = {0, 8, 16};\n"; - output_tabs(additional_tabs_, os_); - os_ << " typename results::char_type prev_char_ = " - "*curr_++;\n\n"; - - if (features_ & bol_bit) - { - output_tabs(additional_tabs_, os_); - os_ << " bol_ = prev_char_ == '\\n';\n\n"; - } - - output_tabs(additional_tabs_, os_); - os_ << " for (std::size_t i_ = 0; i_ < bytes_; ++i_)\n"; - output_tabs(additional_tabs_, os_); - os_ << " {\n"; - output_tabs(additional_tabs_, os_); - os_ << " const "; - - if (pointers_) - { - os_ << "void * const *"; - } - else - { - os_ << "id_type "; - } - - os_ << "state_ = "; - - if (pointers_) - { - os_ << "reinterpret_cast\n "; - output_tabs(additional_tabs_, os_); - os_ << '('; - } - - os_ << "ptr_[lookup_[static_cast\n"; - output_tabs(additional_tabs_, os_); - os_ << " ((prev_char_ >>\n" - " shift_[bytes_ - 1 - i_]) & 0xff)]]"; - - if (pointers_) - { - os_ << ')'; - } - - os_ << ";\n\n"; - output_tabs(additional_tabs_, os_); - os_ << " if (state_ == 0)\n"; - output_tabs(additional_tabs_, os_); - os_ << " {\n"; - - if (features_ & eol_bit) - { - output_tabs(additional_tabs_, os_); - os_ << " EOL_state_ = 0;\n"; - } - - output_tabs(additional_tabs_, os_); - os_ << " goto quit;\n"; - output_tabs(additional_tabs_, os_); - os_ << " }\n\n"; - output_tabs(additional_tabs_, os_); - os_ << " ptr_ = "; - - if (pointers_) - { - os_ << "state_"; - } - else - { - os_ << "&dfa_[state_ * dfa_alphabet_]"; - } - - os_ << ";\n"; - output_tabs(additional_tabs_, os_); - os_ << " }\n"; - } - - static void output_quit(std::ostream &, const std::false_type &) - { - // Nothing to do - } - - static void output_quit(std::ostream &os_, const std::true_type &) - { - os_ << "quit:\n"; - } -}; -} - -#endif diff --git a/YACReaderLibrary/lexertl/generator.hpp b/YACReaderLibrary/lexertl/generator.hpp deleted file mode 100644 index 581cd6e92..000000000 --- a/YACReaderLibrary/lexertl/generator.hpp +++ /dev/null @@ -1,738 +0,0 @@ -// generator.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_GENERATOR_HPP -#define LEXERTL_GENERATOR_HPP - -#include -#include "partition/charset.hpp" -#include "char_traits.hpp" -#include "partition/equivset.hpp" -#include -#include -#include "parser/parser.hpp" -#include "rules.hpp" -#include "state_machine.hpp" -#include - -namespace lexertl -{ -template > -class basic_generator -{ -public: - using id_type = typename rules::id_type; - using rules_char_type = typename rules::rules_char_type; - using sm_traits = typename sm::traits; - using parser = detail::basic_parser; - using charset_map = typename parser::charset_map; - using node = typename parser::node; - using node_ptr_vector = typename parser::node_ptr_vector; - - static void build(const rules &rules_, sm &sm_) - { - const std::size_t size_ = rules_.statemap().size(); - // Strong exception guarantee - // http://www.boost.org/community/exception_safety.html - internals internals_; - sm temp_sm_; - node_ptr_vector node_ptr_vector_; - - internals_._eoi = rules_.eoi(); - internals_.add_states(size_); - - for (id_type index_ = 0; index_ < size_; ++index_) - { - if (rules_.regexes()[index_].empty()) - { - std::ostringstream ss_; - - ss_ << "Lexer states with no rules are not allowed " - "(lexer state " << index_ << ".)"; - throw runtime_error(ss_.str()); - } - else - { - // Note that the following variables are per DFA. - // Map of regex charset tokens (strings) to index - charset_map charset_map_; - // Used to fix up $ and \n clashes. - id_type nl_id_ = sm_traits::npos(); - // Regex syntax tree - observer_ptr root_ = build_tree(rules_, index_, - node_ptr_vector_, charset_map_, nl_id_); - - build_dfa(charset_map_, root_, internals_, temp_sm_, index_, - nl_id_); - - if (internals_._dfa[index_].size() / - internals_._dfa_alphabet[index_] >= sm_traits::npos()) - { - // Overflow - throw runtime_error("The data type you have chosen " - "cannot hold this many DFA rows."); - } - } - } - - // If you get a compile error here the id_type from rules and - // state machine do no match. - create(internals_, temp_sm_, rules_.features(), lookup()); - sm_.swap(temp_sm_); - } - - static observer_ptr build_tree(const rules &rules_, - const std::size_t dfa_, node_ptr_vector &node_ptr_vector_, - charset_map &charset_map_, id_type &nl_id_) - { - parser parser_(rules_.locale(), node_ptr_vector_, charset_map_, - rules_.eoi()); - const auto ®exes_ = rules_.regexes(); - auto regex_iter_ = regexes_[dfa_].cbegin(); - auto regex_iter_end_ = regexes_[dfa_].cend(); - const auto &ids_ = rules_.ids(); - const auto &user_ids_ = rules_.user_ids(); - auto id_iter_ = ids_[dfa_].cbegin(); - auto user_id_iter_ = user_ids_[dfa_].cbegin(); - const auto &next_dfas_ = rules_.next_dfas(); - const auto &pushes_ = rules_.pushes(); - const auto &pops_ = rules_.pops(); - auto next_dfa_iter_ = next_dfas_[dfa_].cbegin(); - auto push_dfa_iter_ = pushes_[dfa_].cbegin(); - auto pop_dfa_iter_ = pops_[dfa_].cbegin(); - const bool seen_bol_ = (rules_.features()[dfa_] & bol_bit) != 0; - observer_ptr root_ = nullptr; - - root_ = parser_.parse(*regex_iter_, *id_iter_, *user_id_iter_, - *next_dfa_iter_, *push_dfa_iter_, *pop_dfa_iter_, - rules_.flags(), nl_id_, seen_bol_); - ++regex_iter_; - ++id_iter_; - ++user_id_iter_; - ++next_dfa_iter_; - ++push_dfa_iter_; - ++pop_dfa_iter_; - - // Build syntax trees - while (regex_iter_ != regex_iter_end_) - { - observer_ptr rhs_ = parser_.parse(*regex_iter_, *id_iter_, - *user_id_iter_, *next_dfa_iter_, *push_dfa_iter_, - *pop_dfa_iter_, rules_.flags(), nl_id_, - (rules_.features()[dfa_] & bol_bit) != 0); - - node_ptr_vector_.emplace_back - (std::make_unique(root_, rhs_)); - root_ = node_ptr_vector_.back().get(); - - ++regex_iter_; - ++id_iter_; - ++user_id_iter_; - ++next_dfa_iter_; - ++push_dfa_iter_; - ++pop_dfa_iter_; - } - - return root_; - } - -protected: - using compressed = std::integral_constant; - using equivset = detail::basic_equivset; - using equivset_list = std::list>; - using equivset_ptr = std::unique_ptr; - using sm_char_type = typename sm_traits::char_type; - using charset = detail::basic_charset; - using charset_ptr = std::unique_ptr; - using charset_list = std::list>; - using internals = detail::basic_internals; - using id_type_set = typename std::set; - using id_type_vector = typename internals::id_type_vector; - using index_set = typename charset::index_set; - using index_set_vector = std::vector; - using is_dfa = std::integral_constant; - using lookup = std::integral_constant; - using node_set = std::set>; - using node_set_vector = std::vector>; - using node_vector = typename node::node_vector; - using node_vector_vector = std::vector>; - using selection_node = typename parser::selection_node; - using size_t_vector = typename std::vector; - using string_token = typename parser::string_token; - - static void build_dfa(const charset_map &charset_map_, - const observer_ptr root_, internals &internals_, sm &sm_, - const id_type dfa_index_, id_type &nl_id_) - { - // partitioned charset list - charset_list charset_list_; - // vector mapping token indexes to partitioned token index sets - index_set_vector set_mapping_; - auto &dfa_ = internals_._dfa[dfa_index_]; - std::size_t dfa_alphabet_ = 0; - const node_vector &followpos_ = root_->firstpos(); - node_set_vector seen_sets_; - node_vector_vector seen_vectors_; - size_t_vector hash_vector_; - id_type zero_id_ = sm_traits::npos(); - id_type_set eol_set_; - - set_mapping_.resize(charset_map_.size()); - partition_charsets(charset_map_, charset_list_, is_dfa()); - build_set_mapping(charset_list_, internals_, dfa_index_, - set_mapping_); - - if (nl_id_ != sm_traits::npos()) - { - nl_id_ = *set_mapping_[nl_id_].begin(); - zero_id_ = sm_traits::compressed ? - *set_mapping_[charset_map_.find(string_token(0, 0))-> - second].begin() : sm_traits::npos(); - } - - dfa_alphabet_ = charset_list_.size() + transitions_index + - (nl_id_ == sm_traits::npos() ? 0 : 1); - - if (dfa_alphabet_ > sm_traits::npos()) - { - // Overflow - throw runtime_error("The data type you have chosen cannot hold " - "the dfa alphabet."); - } - - internals_._dfa_alphabet[dfa_index_] = - static_cast(dfa_alphabet_); - // 'jam' state - dfa_.resize(dfa_alphabet_, 0); - closure(followpos_, seen_sets_, seen_vectors_, hash_vector_, - static_cast(dfa_alphabet_), dfa_); - - // Loop over states - for (id_type index_ = 0; index_ < static_cast - (seen_vectors_.size()); ++index_) - { - equivset_list equiv_list_; - - // Intersect charsets - build_equiv_list(*seen_vectors_[index_].get(), set_mapping_, - equiv_list_, is_dfa()); - - for (auto &equivset_ : equiv_list_) - { - const id_type transition_ = closure - (equivset_->_followpos, seen_sets_, seen_vectors_, - hash_vector_, static_cast(dfa_alphabet_), dfa_); - - if (transition_ != sm_traits::npos()) - { - observer_ptr ptr_ = &dfa_.front() + - ((index_ + 1) * dfa_alphabet_); - - // Prune abstemious transitions from end states. - if (*ptr_ && !equivset_->_greedy) continue; - - set_transitions(transition_, equivset_.get(), dfa_, ptr_, - index_, eol_set_); - } - } - } - - fix_clashes(eol_set_, nl_id_, zero_id_, dfa_, dfa_alphabet_, - compressed()); - append_dfa(charset_list_, internals_, sm_, dfa_index_, lookup()); - } - - static void set_transitions(const id_type transition_, equivset *equivset_, - typename internals::id_type_vector &dfa_, id_type *ptr_, - const id_type index_, id_type_set &eol_set_) - { - for (typename equivset::index_vector::const_iterator - equiv_iter_ = equivset_->_index_vector.begin(), - equiv_end_ = equivset_->_index_vector.end(); - equiv_iter_ != equiv_end_; ++equiv_iter_) - { - const id_type i_ = *equiv_iter_; - - if (i_ == parser::bol_token()) - { - dfa_.front() = transition_; - } - else if (i_ == parser::eol_token()) - { - ptr_[eol_index] = transition_; - eol_set_.insert(index_ + 1); - } - else - { - ptr_[i_ + transitions_index] = transition_; - } - } - } - - // Uncompressed - static void fix_clashes(const id_type_set &eol_set_, - const id_type nl_id_, const id_type /*zero_id_*/, - typename internals::id_type_vector &dfa_, - const std::size_t dfa_alphabet_, const std::false_type &) - { - for (const auto &eol_ : eol_set_) - { - observer_ptr ptr_ = &dfa_.front() + eol_ * dfa_alphabet_; - const id_type eol_state_ = ptr_[eol_index]; - const id_type nl_state_ = ptr_[nl_id_ + transitions_index]; - - if (nl_state_) - { - ptr_[transitions_index + nl_id_] = 0; - ptr_ = &dfa_.front() + eol_state_ * dfa_alphabet_; - - if (ptr_[transitions_index + nl_id_] == 0) - { - ptr_[transitions_index + nl_id_] = nl_state_; - } - } - } - } - - // Compressed - static void fix_clashes(const id_type_set &eol_set_, - const id_type nl_id_, const id_type zero_id_, - typename internals::id_type_vector &dfa_, - const std::size_t dfa_alphabet_, const std::true_type &) - { - std::size_t i_ = 0; - - for (const auto &eol_ : eol_set_) - { - observer_ptr ptr_ = &dfa_.front() + eol_ * dfa_alphabet_; - const id_type eol_state_ = ptr_[eol_index]; - id_type nl_state_ = 0; - - for (; i_ < (sm_traits::char_24_bit ? 2 : 1); ++i_) - { - ptr_ = &dfa_.front() + ptr_[transitions_index + zero_id_] * - dfa_alphabet_; - } - - nl_state_ = ptr_[transitions_index + nl_id_]; - - if (nl_state_) - { - ptr_ = &dfa_.front() + eol_state_ * dfa_alphabet_; - - if (ptr_[transitions_index + zero_id_] != 0) continue; - - ptr_[transitions_index + zero_id_] = - static_cast(dfa_.size() / dfa_alphabet_); - dfa_.resize(dfa_.size() + dfa_alphabet_, 0); - - for (i_ = 0; i_ < (sm_traits::char_24_bit ? 1 : 0); ++i_) - { - ptr_ = &dfa_.front() + dfa_.size() - dfa_alphabet_; - ptr_[transitions_index + zero_id_] = - static_cast(dfa_.size() / dfa_alphabet_); - dfa_.resize(dfa_.size() + dfa_alphabet_, 0); - } - - ptr_ = &dfa_.front() + dfa_.size() - dfa_alphabet_; - ptr_[transitions_index + nl_id_] = nl_state_; - } - } - } - - // char_state_machine version - static void append_dfa(const charset_list &charset_list_, - const internals &internals_, sm &sm_, const id_type dfa_index_, - const std::false_type &) - { - std::size_t size_ = charset_list_.size(); - typename sm::string_token_vector token_vector_; - - token_vector_.reserve(size_); - - for (const auto &charset_ : charset_list_) - { - token_vector_.push_back(charset_->_token); - } - - sm_.append(token_vector_, internals_, dfa_index_); - } - - // state_machine version - static void append_dfa(const charset_list &, const internals &, sm &, - const id_type, const std::true_type &) - { - // Nothing to do - will use create() instead - } - - // char_state_machine version - static void create(internals &, sm &, const id_type_vector &, - const std::false_type &) - { - // Nothing to do - will use append_dfa() instead - } - - // state_machine version - static void create(internals &internals_, sm &sm_, - const id_type_vector &features_, const std::true_type &) - { - for (std::size_t i_ = 0, size_ = internals_._dfa.size(); - i_ < size_; ++i_) - { - internals_._features |= features_[i_]; - } - - if (internals_._dfa.size() > 1) - { - internals_._features |= multi_state_bit; - } - - sm_.data().swap(internals_); - } - - // NFA version - static void partition_charsets(const charset_map &map_, - charset_list &lhs_, const std::false_type &) - { - fill_rhs_list(map_, lhs_); - } - - // DFA version - static void partition_charsets(const charset_map &map_, - charset_list &lhs_, const std::true_type &) - { - charset_list rhs_; - - fill_rhs_list(map_, rhs_); - - if (!rhs_.empty()) - { - typename charset_list::iterator iter_; - typename charset_list::iterator end_; - charset_ptr overlap_ = std::make_unique(); - - lhs_.emplace_back(std::move(rhs_.front())); - rhs_.pop_front(); - - while (!rhs_.empty()) - { - charset_ptr r_(rhs_.front().release()); - - rhs_.pop_front(); - iter_ = lhs_.begin(); - end_ = lhs_.end(); - - while (!r_->empty() && iter_ != end_) - { - auto l_iter_ = iter_; - - (*l_iter_)->intersect(*r_.get(), *overlap_.get()); - - if (overlap_->empty()) - { - ++iter_; - } - else if ((*l_iter_)->empty()) - { - l_iter_->reset(overlap_.release()); - overlap_ = std::make_unique(); - ++iter_; - } - else if (r_->empty()) - { - r_.reset(overlap_.release()); - overlap_ = std::make_unique(); - break; - } - else - { - iter_ = lhs_.insert(++iter_, charset_ptr()); - iter_->reset(overlap_.release()); - overlap_ = std::make_unique(); - ++iter_; - end_ = lhs_.end(); - } - } - - if (!r_->empty()) - { - lhs_.emplace_back(std::move(r_)); - } - } - } - } - - static void fill_rhs_list(const charset_map &map_, charset_list &list_) - { - for (const auto &pair_ : map_) - { - list_.emplace_back(std::make_unique - (pair_.first, pair_.second)); - } - } - - static void build_set_mapping(const charset_list &charset_list_, - internals &internals_, const id_type dfa_index_, - index_set_vector &set_mapping_) - { - auto iter_ = charset_list_.cbegin(); - auto end_ = charset_list_.cend(); - - for (id_type index_ = 0; iter_ != end_; ++iter_, ++index_) - { - observer_ptr cs_ = iter_->get(); - - fill_lookup(cs_->_token, &internals_._lookup[dfa_index_], - index_, lookup()); - - for (const id_type i_ : cs_->_index_set) - { - set_mapping_[i_].insert(index_); - } - } - } - - // char_state_machine version - static void fill_lookup(const string_token &, observer_ptr , - const id_type, const std::false_type &) - { - // Do nothing (lookup not used) - } - - // state_machine version - static void fill_lookup(const string_token &charset_, - observer_ptr lookup_, const id_type index_, - const std::true_type &) - { - observer_ptr ptr_ = &lookup_->front(); - - for (const auto &range_ : charset_._ranges) - { - for (typename char_traits::index_type char_ = range_.first; - char_ < range_.second; ++char_) - { - // Note char_ must be unsigned - ptr_[char_] = index_ + transitions_index; - } - - // Note range_.second must be unsigned - ptr_[range_.second] = index_ + transitions_index; - } - } - - static id_type closure(const node_vector &followpos_, - node_set_vector &seen_sets_, node_vector_vector &seen_vectors_, - size_t_vector &hash_vector_, const id_type size_, id_type_vector &dfa_) - { - bool end_state_ = false; - id_type id_ = 0; - id_type user_id_ = sm_traits::npos(); - id_type next_dfa_ = 0; - id_type push_dfa_ = sm_traits::npos(); - bool pop_dfa_ = false; - std::size_t hash_ = 0; - - if (followpos_.empty()) return sm_traits::npos(); - - id_type index_ = 0; - std::unique_ptr set_ptr_ = std::make_unique(); - std::unique_ptr vector_ptr_ = - std::make_unique(); - - for (observer_ptr node_ : followpos_) - { - closure_ex(node_, end_state_, id_, user_id_, next_dfa_, - push_dfa_, pop_dfa_, *set_ptr_.get(), - *vector_ptr_.get(), hash_); - } - - bool found_ = false; - auto hash_iter_ = hash_vector_.cbegin(); - auto hash_end_ = hash_vector_.cend(); - auto set_iter_ = seen_sets_.cbegin(); - - for (; hash_iter_ != hash_end_; ++hash_iter_, ++set_iter_) - { - found_ = *hash_iter_ == hash_ && *(*set_iter_) == *set_ptr_; - ++index_; - - if (found_) break; - } - - if (!found_) - { - seen_sets_.emplace_back(std::move(set_ptr_)); - seen_vectors_.emplace_back(std::move(vector_ptr_)); - hash_vector_.push_back(hash_); - // State 0 is the jam state... - index_ = static_cast(seen_sets_.size()); - - const std::size_t old_size_ = dfa_.size(); - - dfa_.resize(old_size_ + size_, 0); - - if (end_state_) - { - dfa_[old_size_] |= end_state_bit; - - if (pop_dfa_) - { - dfa_[old_size_] |= pop_dfa_bit; - } - - dfa_[old_size_ + id_index] = id_; - dfa_[old_size_ + user_id_index] = user_id_; - dfa_[old_size_ + push_dfa_index] = push_dfa_; - dfa_[old_size_ + next_dfa_index] = next_dfa_; - } - } - - return index_; - } - - static void closure_ex(observer_ptr node_, bool &end_state_, - id_type &id_, id_type &user_id_, id_type &next_dfa_, - id_type &push_dfa_, bool &pop_dfa_, node_set &set_ptr_, - node_vector &vector_ptr_, std::size_t &hash_) - { - const bool temp_end_state_ = node_->end_state(); - - if (temp_end_state_) - { - if (!end_state_) - { - end_state_ = true; - id_ = node_->id(); - user_id_ = node_->user_id(); - next_dfa_ = node_->next_dfa(); - push_dfa_ = node_->push_dfa(); - pop_dfa_ = node_->pop_dfa(); - } - } - - if (set_ptr_.insert(node_).second) - { - vector_ptr_.push_back(node_); - hash_ += reinterpret_cast(node_); - } - } - - // NFA version - static void build_equiv_list(const node_vector &vector_, - const index_set_vector &set_mapping_, equivset_list &lhs_, - const std::false_type &) - { - fill_rhs_list(vector_, set_mapping_, lhs_); - } - - // DFA version - static void build_equiv_list(const node_vector &vector_, - const index_set_vector &set_mapping_, equivset_list &lhs_, - const std::true_type &) - { - equivset_list rhs_; - - fill_rhs_list(vector_, set_mapping_, rhs_); - - if (!rhs_.empty()) - { - typename equivset_list::iterator iter_; - typename equivset_list::iterator end_; - equivset_ptr overlap_ = std::make_unique(); - - lhs_.emplace_back(std::move(rhs_.front())); - rhs_.pop_front(); - - while (!rhs_.empty()) - { - equivset_ptr r_(rhs_.front().release()); - - rhs_.pop_front(); - iter_ = lhs_.begin(); - end_ = lhs_.end(); - - while (!r_->empty() && iter_ != end_) - { - auto l_iter_ = iter_; - - (*l_iter_)->intersect(*r_.get(), *overlap_.get()); - - if (overlap_->empty()) - { - ++iter_; - } - else if ((*l_iter_)->empty()) - { - l_iter_->reset(overlap_.release()); - overlap_ = std::make_unique(); - ++iter_; - } - else if (r_->empty()) - { - r_.reset(overlap_.release()); - overlap_ = std::make_unique(); - break; - } - else - { - iter_ = lhs_.insert(++iter_, equivset_ptr()); - iter_->reset(overlap_.release()); - overlap_ = std::make_unique(); - ++iter_; - end_ = lhs_.end(); - } - } - - if (!r_->empty()) - { - lhs_.emplace_back(std::move(r_)); - } - } - } - } - - static void fill_rhs_list(const node_vector &vector_, - const index_set_vector &set_mapping_, equivset_list &list_) - { - for (observer_ptr node_ : vector_) - { - if (!node_->end_state()) - { - const id_type token_ = node_->token(); - - if (token_ != node::null_token()) - { - if (token_ == parser::bol_token() || - token_ == parser::eol_token()) - { - std::set index_set_; - - index_set_.insert(token_); - list_.emplace_back - (std::make_unique(index_set_, - token_, node_->greedy(), node_->followpos())); - } - else - { - list_.emplace_back(std::make_unique - (set_mapping_[token_], token_, node_->greedy(), - node_->followpos())); - } - } - } - } - } -}; - -using generator = basic_generator; -using wgenerator = basic_generator; -using u32generator = basic_generator; -using char_generator = basic_generator; -using wchar_generator = basic_generator; -using u32char_generator = basic_generator; -} - -#endif diff --git a/YACReaderLibrary/lexertl/internals.hpp b/YACReaderLibrary/lexertl/internals.hpp deleted file mode 100644 index a5e1dfe0e..000000000 --- a/YACReaderLibrary/lexertl/internals.hpp +++ /dev/null @@ -1,75 +0,0 @@ -// internals.hpp -// Copyright (c) 2009-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_INTERNALS_HPP -#define LEXERTL_INTERNALS_HPP - -#include "enums.hpp" -#include -#include - -namespace lexertl -{ -namespace detail -{ -template -struct basic_internals -{ - using id_type_vector = std::vector; - using id_type_vector_vector = std::vector; - - id_type _eoi; - id_type_vector_vector _lookup; - id_type_vector _dfa_alphabet; - id_type _features; - id_type_vector_vector _dfa; - - basic_internals() : - _eoi(0), - _lookup(), - _dfa_alphabet(), - _features(0), - _dfa() - { - } - - void clear() - { - _eoi = 0; - _lookup.clear(); - _dfa_alphabet.clear(); - _features = 0; - _dfa.clear(); - } - - bool empty() const - { - return _dfa.empty(); - } - - void add_states(const std::size_t num_) - { - for (std::size_t index_ = 0; index_ < num_; ++index_) - { - // lookup *always* has a size 256 now. - _lookup.push_back(id_type_vector(256, dead_state_index)); - _dfa_alphabet.push_back(0); - _dfa.push_back(id_type_vector()); - } - } - - void swap(basic_internals &internals_) - { - std::swap(_eoi, internals_._eoi); - _lookup.swap(internals_._lookup); - _dfa_alphabet.swap(internals_._dfa_alphabet); - std::swap(_features, internals_._features); - _dfa.swap(internals_._dfa); - } -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/iterator.hpp b/YACReaderLibrary/lexertl/iterator.hpp deleted file mode 100644 index 5820ee02b..000000000 --- a/YACReaderLibrary/lexertl/iterator.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// iterator.hpp -// Copyright (c) 2015-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LEXERTL_ITERATOR_HPP -#define LEXERTL_ITERATOR_HPP - -#include -#include "lookup.hpp" -#include "state_machine.hpp" - -namespace lexertl -{ -template -class iterator -{ -public: - using value_type = results; - using difference_type = ptrdiff_t; - using pointer = const value_type *; - using reference = const value_type &; - using iterator_category = std::forward_iterator_tag; - - iterator() : - _results(iter(), iter()), - _sm(nullptr) - { - } - - iterator(const iter &start_, const iter &end_, const sm_type &sm) : - _results(start_, end_), - _sm(&sm) - { - lookup(); - } - - // Only need this because of warnings with gcc with -Weffc++ - iterator(const iterator &rhs_) - { - _results = rhs_._results; - _sm = rhs_._sm; - } - - // Only need this because of warnings with gcc with -Weffc++ - iterator &operator =(const iterator &rhs_) - { - if (&rhs_ != this) - { - _results = rhs_._results; - _sm = rhs_._sm; - } - - return *this; - } - - iterator &operator ++() - { - lookup(); - return *this; - } - - iterator operator ++(int) - { - iterator iter_ = *this; - - lookup(); - return iter_; - } - - const value_type &operator *() const - { - return _results; - } - - const value_type *operator ->() const - { - return &_results; - } - - bool operator ==(const iterator &rhs_) const - { - return _sm == rhs_._sm && (_sm == nullptr ? true : - _results == rhs_._results); - } - - bool operator !=(const iterator &rhs_) const - { - return !(*this == rhs_); - } - - const sm_type &sm() const - { - return *_sm; - } - -private: - value_type _results; - const sm_type *_sm; - - void lookup() - { - lexertl::lookup(*_sm, _results); - - if (_results.first == _results.eoi) - { - _sm = nullptr; - } - } -}; - -using siterator = - iterator; -using citerator = iterator; -using wsiterator = - iterator; -using wciterator = iterator; -using u32siterator = iterator; -using u32citerator = iterator; - -using sriterator = - iterator; -using criterator = iterator; -using wsriterator = - iterator; -using wcriterator = - iterator; -using u32sriterator = iterator; -using u32criterator = iterator; -} - -#endif diff --git a/YACReaderLibrary/lexertl/licence_1_0.txt b/YACReaderLibrary/lexertl/licence_1_0.txt deleted file mode 100644 index 7925d62e6..000000000 --- a/YACReaderLibrary/lexertl/licence_1_0.txt +++ /dev/null @@ -1,24 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - diff --git a/YACReaderLibrary/lexertl/lookup.hpp b/YACReaderLibrary/lexertl/lookup.hpp deleted file mode 100644 index 903413cd8..000000000 --- a/YACReaderLibrary/lexertl/lookup.hpp +++ /dev/null @@ -1,491 +0,0 @@ -// lookup.hpp -// Copyright (c) 2009-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_LOOKUP_HPP -#define LEXERTL_LOOKUP_HPP - -#include -#include "match_results.hpp" -#include - -namespace lexertl -{ -namespace detail -{ -template -struct bol_state -{ - bol_state(const bool) - { - } -}; - -template<> -struct bol_state -{ - bool _bol; - bool _end_bol; - - bol_state(const bool bol_) : - _bol(bol_), - _end_bol(bol_) - { - } -}; - -template -struct eol_state -{ -}; - -template -struct eol_state -{ - id_type _EOL_state; - - eol_state() : - _EOL_state(0) - { - } -}; - -template -struct multi_state_state -{ - multi_state_state(const id_type) - { - } -}; - -template -struct multi_state_state -{ - id_type _start_state; - - multi_state_state(const id_type state_) : - _start_state(state_) - { - } -}; - -template -struct recursive_state -{ - recursive_state(const id_type *) - { - } -}; - -template -struct recursive_state -{ - bool _pop; - id_type _push_dfa; - - recursive_state(const id_type *ptr_) : - _pop((*ptr_ & pop_dfa_bit) != 0), - _push_dfa(*(ptr_ + push_dfa_index)) - { - } -}; - -template -struct lookup_state -{ - const id_type *_lookup; - id_type _dfa_alphabet; - const id_type *_dfa; - const id_type *_ptr; - bool _end_state; - id_type _id; - id_type _uid; - bol_state<(flags & bol_bit) != 0> _bol_state; - eol_state _eol_state; - multi_state_state - _multi_state_state; - recursive_state _recursive_state; - - lookup_state(const internals &internals_, const bool bol_, - const id_type state_) : - _lookup(&internals_._lookup[state_][0]), - _dfa_alphabet(internals_._dfa_alphabet[state_]), - _dfa(&internals_._dfa[state_][0]), - _ptr(_dfa + _dfa_alphabet), - _end_state(*_ptr != 0), - _id(*(_ptr + id_index)), - _uid(*(_ptr + user_id_index)), - _bol_state(bol_), - _eol_state(), - _multi_state_state(state_), - _recursive_state(_ptr) - { - } - - void reset_recursive(const std::false_type &) - { - // Do nothing - } - - void reset_recursive(const std::true_type &) - { - _recursive_state._pop = (*_ptr & pop_dfa_bit) != 0; - _recursive_state._push_dfa = *(_ptr + push_dfa_index); - } - - void bol_start_state(const std::false_type &) - { - // Do nothing - } - - void bol_start_state(const std::true_type &) - { - if (_bol_state._bol) - { - const id_type state_ = *_dfa; - - if (state_) - { - _ptr = &_dfa[state_ * _dfa_alphabet]; - } - } - } - - template - bool is_eol(const char_type, const std::false_type &) - { - return false; - } - - template - bool is_eol(const char_type curr_, const std::true_type &) - { - bool ret_ = false; - - _eol_state._EOL_state = _ptr[eol_index]; - ret_ = _eol_state._EOL_state && (curr_ == '\r' || curr_ == '\n'); - - if (ret_) - { - _ptr = &_dfa[_eol_state._EOL_state * _dfa_alphabet]; - } - - return ret_; - } - - template - id_type next_char(const char_type prev_char_, const std::false_type &) - { - const id_type state_= _ptr[_lookup - [static_cast(prev_char_)]]; - - if (state_ != 0) - { - _ptr = &_dfa[state_ * _dfa_alphabet]; - } - - return state_; - } - - template - id_type next_char(const char_type prev_char_, const std::true_type &) - { - const std::size_t bytes_ = sizeof(char_type) < 3 ? - sizeof(char_type) : 3; - const std::size_t shift_[] = {0, 8, 16}; - id_type state_= 0; - - for (std::size_t i_ = 0; i_ < bytes_; ++i_) - { - state_ = _ptr[_lookup[static_cast((prev_char_ >> - shift_[bytes_ - 1 - i_]) & 0xff)]]; - - if (state_ == 0) - { - break; - } - - _ptr = &_dfa[state_ * _dfa_alphabet]; - } - - return state_; - } - - template - void bol(const char_type, const std::false_type &) - { - // Do nothing - } - - template - void bol(const char_type prev_char_, const std::true_type &) - { - _bol_state._bol = prev_char_ == '\n'; - } - - void eol(const id_type, const std::false_type &) - { - // Do nothing - } - - void eol(const id_type err_val_, const std::true_type &) - { - _eol_state._EOL_state = err_val_; - } - - void reset_start_state(const std::false_type &) - { - // Do nothing - } - - void reset_start_state(const std::true_type &) - { - _multi_state_state._start_state = *(_ptr + next_dfa_index); - } - - void reset_end_bol(const std::false_type &) - { - // Do nothing - } - - void reset_end_bol(const std::true_type &) - { - _bol_state._end_bol = _bol_state._bol; - } - - template - void end_state(iter_type &end_token_, iter_type &curr_) - { - if (*_ptr) - { - _end_state = true; - reset_end_bol - (std::integral_constant()); - _id = *(_ptr + id_index); - _uid = *(_ptr + user_id_index); - reset_recursive - (std::integral_constant()); - reset_start_state(std::integral_constant()); - end_token_ = curr_; - } - } - - template - void check_eol(iter_type &, iter_type &, const id_type, - const char_type, const std::false_type &) - { - // Do nothing - } - - template - void check_eol(iter_type &end_token_, iter_type &curr_, - const id_type npos, const char_type eoi_, const std::true_type &) - { - if (_eol_state._EOL_state != npos && curr_ == eoi_) - { - _eol_state._EOL_state = _ptr[eol_index]; - - if (_eol_state._EOL_state) - { - _ptr = &_dfa[_eol_state._EOL_state * _dfa_alphabet]; - end_state(end_token_, curr_); - } - } - } - - template - void pop(results &, const std::false_type &) - { - // Nothing to do - } - - template - void pop(results &results_, const std::true_type &) - { - if (_recursive_state._pop) - { - _multi_state_state._start_state = results_.stack.top().first; - results_.stack.pop(); - } - else if (_recursive_state._push_dfa != results::npos()) - { - results_.stack.push(typename results::id_type_pair - (_recursive_state._push_dfa, _id)); - } - } - - template - bool is_id_eoi(const id_type eoi_, const results &, const std::false_type &) - { - return _id == eoi_; - } - - template - bool is_id_eoi(const id_type eoi_, const results &results_, - const std::true_type &) - { - return _id == eoi_ || (_recursive_state._pop && - !results_.stack.empty() && results_.stack.top().second == eoi_); - } - - void start_state(id_type &, const std::false_type &) - { - // Do nothing - } - - void start_state(id_type &start_state_, const std::true_type &) - { - start_state_ = _multi_state_state._start_state; - } - - void bol(bool &, const std::false_type &) - { - // Do nothing - } - - void bol(bool &end_bol_, const std::true_type &) - { - end_bol_ = _bol_state._end_bol; - } -}; - -template -void inc_end(results &, const std::false_type &) -{ - // Do nothing -} - -template -void inc_end(results &results_, const std::true_type &) -{ - ++results_.second; -} - -template -void next(const sm_type &sm_, results &results_, - const std::integral_constant &compressed_, - const std::integral_constant &recursive_, - const std::forward_iterator_tag &) -{ - using id_type = typename sm_type::id_type; - const auto &internals_ = sm_.data(); - auto end_token_ = results_.second; - -skip: - auto curr_ = results_.second; - - results_.first = curr_; - -again: - if (curr_ == results_.eoi) - { - results_.id = internals_._eoi; - results_.user_id = results::npos(); - return; - } - - lookup_state lu_state_ - (internals_, results_.bol, results_.state); - lu_state_.bol_start_state - (std::integral_constant()); - - while (curr_ != results_.eoi) - { - if (!lu_state_.is_eol(*curr_, - std::integral_constant())) - { - const auto prev_char_ = *curr_; - const id_type state_ = lu_state_.next_char(prev_char_, - compressed_); - - ++curr_; - lu_state_.bol(prev_char_, - std::integral_constant()); - - if (state_ == 0) - { - lu_state_.is_eol(results::npos(), - std::integral_constant()); - break; - } - } - - lu_state_.end_state(end_token_, curr_); - } - - lu_state_.check_eol(end_token_, curr_, results::npos(), results_.eoi, - std::integral_constant()); - - if (lu_state_._end_state) - { - // Return longest match - lu_state_.pop(results_, recursive_); - - lu_state_.start_state(results_.state, - std::integral_constant()); - lu_state_.bol(results_.bol, - std::integral_constant()); - results_.second = end_token_; - - if (lu_state_._id == sm_.skip()) goto skip; - - if (lu_state_.is_id_eoi(internals_._eoi, results_, recursive_)) - { - curr_ = end_token_; - goto again; - } - } - else - { - results_.second = end_token_; - results_.bol = *results_.second == '\n'; - results_.first = results_.second; - // No match causes char to be skipped - inc_end(results_, - std::integral_constant()); - lu_state_._id = results::npos(); - lu_state_._uid = results::npos(); - } - - results_.id = lu_state_._id; - results_.user_id = lu_state_._uid; -} -} - -template -void lookup(const sm_type &sm_, match_results &results_) -{ - using value_type = typename std::iterator_traits::value_type; - using cat = typename std::iterator_traits::iterator_category; - - // If this asserts, you have either not defined all the correct - // flags, or you should be using recursive_match_results instead - // of match_results. - assert((sm_.data()._features & flags) == sm_.data()._features); - detail::next(sm_, results_, - std::integral_constant 1)>(), - std::false_type(), cat()); -} - -template -void lookup(const sm_type &sm_, recursive_match_results &results_) -{ - using value_type = typename std::iterator_traits::value_type; - using cat = typename std::iterator_traits::iterator_category; - - // If this asserts, you have not defined all the correct flags - assert((sm_.data()._features & flags) == sm_.data()._features); - detail::next(sm_, results_, - std::integral_constant 1)>(), - std::true_type(), cat()); -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/match_results.hpp b/YACReaderLibrary/lexertl/match_results.hpp deleted file mode 100644 index 078d8df11..000000000 --- a/YACReaderLibrary/lexertl/match_results.hpp +++ /dev/null @@ -1,171 +0,0 @@ -// match_results.hpp -// Copyright (c) 2015-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_MATCH_RESULTS_HPP -#define LEXERTL_MATCH_RESULTS_HPP - -#include "char_traits.hpp" -#include "enums.hpp" -#include -#include -#include - -namespace lexertl -{ -template -struct match_results -{ - using iter_type = iter; - using char_type = typename std::iterator_traits::value_type; - using index_type = typename basic_char_traits::index_type; - using string = std::basic_string; - - id_type id; - id_type user_id; - iter_type first; - iter_type second; - iter_type eoi; - bool bol; - id_type state; - - match_results() : - id(0), - user_id(npos()), - first(iter_type()), - second(iter_type()), - eoi(iter_type()), - bol(true), - state(0) - { - } - - match_results(const iter_type &start_, const iter_type &end_) : - id(0), - user_id(npos()), - first(start_), - second(start_), - eoi(end_), - bol(true), - state(0) - { - } - - virtual ~match_results() - { - } - - string str() const - { - return string(first, second); - } - - string substr(const std::size_t soffset_, const std::size_t eoffset_) const - { - return string(first + soffset_, second - eoffset_); - } - - virtual void clear() - { - id = 0; - user_id = npos(); - first = eoi; - second = eoi; - bol = true; - state = 0; - } - - virtual void reset(const iter_type &start_, const iter_type &end_) - { - id = 0; - user_id = npos(); - first = start_; - second = start_; - eoi = end_; - bol = true; - state = 0; - } - - static id_type npos() - { - return static_cast(~0); - } - - static id_type skip() - { - return static_cast(~1); - } - - bool operator ==(const match_results &rhs_) const - { - return id == rhs_.id && - user_id == rhs_.user_id && - first == rhs_.first && - second == rhs_.second && - eoi == rhs_.eoi && - bol == rhs_.bol && - state == rhs_.state; - } -}; - -template -struct recursive_match_results : public match_results -{ - using id_type_pair = std::pair; - std::stack stack; - - recursive_match_results() : - match_results(), - stack() - { - } - - recursive_match_results(const iter &start_, const iter &end_) : - match_results(start_, end_), - stack() - { - } - - virtual ~recursive_match_results() override - { - } - - virtual void clear() override - { - match_results::clear(); - - while (!stack.empty()) stack.pop(); - } - - virtual void reset(const iter &start_, const iter &end_) override - { - match_results::reset(start_, end_); - - while (!stack.empty()) stack.pop(); - } -}; - -using smatch = match_results; -using cmatch = match_results; -using wsmatch = match_results; -using wcmatch = match_results; -using u32smatch = match_results; -using u32cmatch = match_results; - -using srmatch = - recursive_match_results; -using crmatch = recursive_match_results; -using wsrmatch = - recursive_match_results; -using wcrmatch = recursive_match_results; -using u32srmatch = - recursive_match_results; -using u32crmatch = recursive_match_results; -} - -#endif diff --git a/YACReaderLibrary/lexertl/memory_file.hpp b/YACReaderLibrary/lexertl/memory_file.hpp deleted file mode 100644 index 4ea42a4d7..000000000 --- a/YACReaderLibrary/lexertl/memory_file.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// memory_file.hpp -// Copyright (c) 2015-2018 Ben Hanson (http://www.benhanson.net/) -// Inspired by http://en.wikibooks.org/wiki/Optimizing_C%2B%2B/ -// General_optimization_techniques/Input/Output#Memory-mapped_file -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LEXERTL_MEMORY_FILE_HPP -#define LEXERTL_MEMORY_FILE_HPP - -#include - -#ifdef _WIN32 -#include -#else -#include -#include -#include -#include -#endif - -// Only files small enough to fit into memory are supported. -namespace lexertl -{ -template -class basic_memory_file -{ -public: - basic_memory_file() - { - } - - basic_memory_file(const char *pathname_) - { - open(pathname_); - } - - ~basic_memory_file() - { - close(); - } - - void open(const char *pathname_) - { - if (_data) close(); - -#ifdef _WIN32 - _fh = ::CreateFileA(pathname_, GENERIC_READ, FILE_SHARE_READ, 0, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - _fmh = 0; - - if (_fh != INVALID_HANDLE_VALUE) - { - _fmh = ::CreateFileMapping(_fh, 0, PAGE_READONLY, 0, 0, 0); - - if (_fmh != 0) - { - _data = static_cast(::MapViewOfFile - (_fmh, FILE_MAP_READ, 0, 0, 0)); - - if (_data) _size = ::GetFileSize(_fh, 0) / sizeof(char_type); - } - } -#else - _fh = ::open(pathname_, O_RDONLY); - - if (_fh > -1) - { - struct stat sbuf_; - - if (::fstat(_fh, &sbuf_) > -1) - { - _data = static_cast - (::mmap(0, sbuf_.st_size, PROT_READ, MAP_SHARED, _fh, 0)); - - if (_data == MAP_FAILED) - { - _data = nullptr; - } - else - { - _size = sbuf_.st_size / sizeof(char_type); - } - } - } -#endif - } - - const char_type *data() const - { - return _data; - } - - std::size_t size() const - { - return _size; - } - - void close() - { -#ifdef _WIN32 - ::UnmapViewOfFile(_data); - ::CloseHandle(_fmh); - ::CloseHandle(_fh); -#else - ::munmap(const_cast(_data), _size); - ::close(_fh); -#endif - _data = nullptr; - _size = 0; - _fh = 0; -#ifdef _WIN32 - _fmh = 0; -#endif - } - -private: - const char_type *_data = nullptr; - std::size_t _size = 0; -#ifdef _WIN32 - HANDLE _fh = 0; - HANDLE _fmh = 0; -#else - int _fh = 0; -#endif - - // No copy construction. - basic_memory_file(const basic_memory_file &) = delete; - // No assignment. - basic_memory_file &operator =(const basic_memory_file &) = delete; -}; - -using memory_file = basic_memory_file; -using wmemory_file = basic_memory_file; -} - -#endif diff --git a/YACReaderLibrary/lexertl/narrow.hpp b/YACReaderLibrary/lexertl/narrow.hpp deleted file mode 100644 index 94b2f6c2f..000000000 --- a/YACReaderLibrary/lexertl/narrow.hpp +++ /dev/null @@ -1,25 +0,0 @@ -// narrow.hpp -// Copyright (c) 2015-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_NARROW_HPP -#define LEXERTL_NARROW_HPP - -#include - -namespace lexertl -{ -template -void narrow(const char_type *str_, std::ostringstream &ss_) -{ - while (*str_) - { - // Safe to simply cast to char. - // when string only contains ASCII. - ss_ << static_cast(*str_++); - } -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/observer_ptr.hpp b/YACReaderLibrary/lexertl/observer_ptr.hpp deleted file mode 100644 index 9ecd8255c..000000000 --- a/YACReaderLibrary/lexertl/observer_ptr.hpp +++ /dev/null @@ -1,16 +0,0 @@ -// observer_ptr.hpp -// Copyright (c) 2017-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LEXERTL_OBSERVER_PTR_HPP -#define LEXERTL_OBSERVER_PTR_HPP - -namespace lexertl -{ - template - using observer_ptr = T *; -} - -#endif diff --git a/YACReaderLibrary/lexertl/parser/parser.hpp b/YACReaderLibrary/lexertl/parser/parser.hpp deleted file mode 100644 index 002f8d87c..000000000 --- a/YACReaderLibrary/lexertl/parser/parser.hpp +++ /dev/null @@ -1,926 +0,0 @@ -// parser.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_PARSER_HPP -#define LEXERTL_PARSER_HPP - -#include -#include -#include "tree/end_node.hpp" -#include "tree/iteration_node.hpp" -#include "tree/leaf_node.hpp" -#include -#include "tokeniser/re_tokeniser.hpp" -#include "../runtime_error.hpp" -#include "tree/selection_node.hpp" -#include "tree/sequence_node.hpp" -#include -#include - -namespace lexertl -{ -namespace detail -{ -/* - General principles of regex parsing: - - Every regex is a sequence of sub-regexes. - - Regexes consist of operands and operators - - All operators decompose to sequence, selection ('|') and iteration ('*') - - Regex tokens are stored on a stack. - - When a complete sequence of regex tokens is on the stack it is processed. - -Grammar: - - -> - -> | '|' - -> - -> | - -> - -> charset | macro | '('')' | - -> '?' | '??' | '*' | '*?' | '+' | '+?' | '{n[,[m]]}' | - '{n[,[m]]}?' -*/ - -template -class basic_parser -{ -public: - enum {char_24_bit = sm_traits::char_24_bit}; - using char_type = typename sm_traits::char_type; - using id_type = typename sm_traits::id_type; - using end_node = basic_end_node; - using input_char_type = typename sm_traits::input_char_type; - using input_string_token = basic_string_token; - using iteration_node = basic_iteration_node; - using leaf_node = basic_leaf_node; - using tokeniser = - basic_re_tokeniser; - using node = basic_node; - using node_ptr_vector = typename node::node_ptr_vector; - using string = std::basic_string; - using string_token = basic_string_token; - using selection_node = basic_selection_node; - using sequence_node = basic_sequence_node; - using charset_map = std::map; - using charset_pair = std::pair; - using compressed = std::integral_constant; - using token = basic_re_token; - static_assert(std::is_move_assignable::value && - std::is_move_constructible::value, - "token is not movable."); - using token_vector = std::vector; - - basic_parser(const std::locale &locale_, - node_ptr_vector &node_ptr_vector_, - charset_map &charset_map_, const id_type eoi_) : - _locale(locale_), - _node_ptr_vector(node_ptr_vector_), - _charset_map(charset_map_), - _eoi(eoi_), - _token_stack(), - _tree_node_stack() - { - } - - observer_ptr parse(const token_vector ®ex_, const id_type id_, - const id_type user_id_, const id_type next_dfa_, - const id_type push_dfa_, const bool pop_dfa_, - const std::size_t flags_, id_type &nl_id_, const bool seen_bol_) - { - auto iter_ = regex_.cbegin(); - auto end_ = regex_.cend(); - observer_ptr root_ = nullptr; - observer_ptr lhs_token_ = nullptr; - // There cannot be less than 2 tokens - auto rhs_token_ = std::make_unique(*iter_++); - char action_ = 0; - - _token_stack.emplace(std::move(rhs_token_)); - rhs_token_ = std::make_unique(*iter_); - - if (iter_ + 1 != end_) ++iter_; - - do - { - lhs_token_ = _token_stack.top().get(); - action_ = lhs_token_->precedence(rhs_token_->_type); - - switch (action_) - { - case '<': - case '=': - _token_stack.emplace(std::move(rhs_token_)); - rhs_token_ = std::make_unique(*iter_); - - if (iter_ + 1 != end_) ++iter_; - - break; - case '>': - reduce(nl_id_); - break; - default: - { - std::ostringstream ss_; - - ss_ << "A syntax error occurred: '" << - lhs_token_->precedence_string() << - "' against '" << rhs_token_->precedence_string() << - " in rule id " << id_ << '.'; - throw runtime_error(ss_.str()); - break; - } - } - } while (!_token_stack.empty()); - - if (_tree_node_stack.empty()) - { - std::ostringstream ss_; - - ss_ << "Empty rules are not allowed in rule id " << - id_ << '.'; - throw runtime_error(ss_.str()); - } - - assert(_tree_node_stack.size() == 1); - - observer_ptr lhs_node_ = _tree_node_stack.top(); - - _tree_node_stack.pop(); - _node_ptr_vector.emplace_back(std::make_unique - (id_, user_id_, next_dfa_, push_dfa_, pop_dfa_)); - - observer_ptr rhs_node_ = _node_ptr_vector.back().get(); - - _node_ptr_vector.emplace_back(std::make_unique - (lhs_node_, rhs_node_)); - root_ = _node_ptr_vector.back().get(); - - if (seen_bol_) - { - fixup_bol(root_); - } - - if ((flags_ & match_zero_len) == 0) - { - const auto &firstpos_ = root_->firstpos(); - - for (observer_ptr node_ : firstpos_) - { - if (node_->end_state()) - { - std::ostringstream ss_; - - ss_ << "Rules that match zero characters are not allowed " - "as this can cause an infinite loop in user code. The " - "match_zero_len flag overrides this check. Rule id " << - id_ << '.'; - throw runtime_error(ss_.str()); - } - } - } - - return root_; - } - - static id_type bol_token() - { - return static_cast(~1); - } - - static id_type eol_token() - { - return static_cast(~2); - } - -private: - using input_range = typename input_string_token::range; - using range = typename string_token::range; - using string_token_vector = std::vector>; - using token_stack = std::stack>; - using tree_node_stack = typename node::node_stack; - - const std::locale &_locale; - node_ptr_vector &_node_ptr_vector; - charset_map &_charset_map; - id_type _eoi; - token_stack _token_stack; - tree_node_stack _tree_node_stack; - - void reduce(id_type &nl_id_) - { - observer_ptr lhs_ = nullptr; - observer_ptr rhs_ = nullptr; - token_stack handle_; - char action_ = 0; - - do - { - handle_.emplace(); - rhs_ = _token_stack.top().release(); - handle_.top().reset(rhs_); - _token_stack.pop(); - - if (!_token_stack.empty()) - { - lhs_ = _token_stack.top().get(); - action_ = lhs_->precedence(rhs_->_type); - } - } while (!_token_stack.empty() && action_ == '='); - - assert(_token_stack.empty() || action_ == '<'); - - switch (rhs_->_type) - { - case BEGIN: - // finished processing so exit - break; - case REGEX: - // finished parsing, nothing to do - break; - case OREXP: - orexp(handle_); - break; - case SEQUENCE: - _token_stack.emplace(std::make_unique(OREXP)); - break; - case SUB: - sub(handle_); - break; - case EXPRESSION: - _token_stack.emplace(std::make_unique(SUB)); - break; - case REPEAT: - repeat(handle_); - break; - case BOL: - bol(handle_); - break; - case EOL: - eol(handle_, nl_id_); - break; - case CHARSET: - charset(handle_, compressed()); - break; - case OPENPAREN: - openparen(handle_); - break; - case OPT: - case AOPT: - optional(rhs_->_type == OPT); - _token_stack.emplace(std::make_unique(DUP)); - break; - case ZEROORMORE: - case AZEROORMORE: - zero_or_more(rhs_->_type == ZEROORMORE); - _token_stack.emplace(std::make_unique(DUP)); - break; - case ONEORMORE: - case AONEORMORE: - one_or_more(rhs_->_type == ONEORMORE); - _token_stack.emplace(std::make_unique(DUP)); - break; - case REPEATN: - case AREPEATN: - repeatn(rhs_->_type == REPEATN, handle_.top().get()); - _token_stack.emplace(std::make_unique(DUP)); - break; - default: - throw runtime_error - ("Internal error in regex_parser::reduce."); - break; - } - } - - void orexp(token_stack &handle_) - { - assert(handle_.top()->_type == OREXP && - (handle_.size() == 1 || handle_.size() == 3)); - - if (handle_.size() == 1) - { - _token_stack.emplace(std::make_unique(REGEX)); - } - else - { - handle_.pop(); - assert(handle_.top()->_type == OR); - handle_.pop(); - assert(handle_.top()->_type == SEQUENCE); - perform_or(); - _token_stack.emplace(std::make_unique(OREXP)); - } - } - - void perform_or() - { - // perform or - observer_ptr rhs_ = _tree_node_stack.top(); - - _tree_node_stack.pop(); - - observer_ptr lhs_ = _tree_node_stack.top(); - - _node_ptr_vector.emplace_back - (std::make_unique(lhs_, rhs_)); - _tree_node_stack.top() = _node_ptr_vector.back().get(); - } - - void sub(token_stack &handle_) - { - assert((handle_.top()->_type == SUB && - handle_.size() == 1) || handle_.size() == 2); - - if (handle_.size() == 1) - { - _token_stack.emplace(std::make_unique(SEQUENCE)); - } - else - { - handle_.pop(); - assert(handle_.top()->_type == EXPRESSION); - // perform join - sequence(); - _token_stack.emplace(std::make_unique(SUB)); - } - } - - void repeat(token_stack &handle_) - { - assert(handle_.top()->_type == REPEAT && - handle_.size() >= 1 && handle_.size() <= 3); - - if (handle_.size() == 1) - { - _token_stack.emplace(std::make_unique(EXPRESSION)); - } - else - { - handle_.pop(); - assert(handle_.top()->_type == DUP); - _token_stack.emplace(std::make_unique(REPEAT)); - } - } - -#ifndef NDEBUG - void bol(token_stack &handle_) -#else - void bol(token_stack &) -#endif - { - assert(handle_.top()->_type == BOL && - handle_.size() == 1); - - // store charset - _node_ptr_vector.emplace_back - (std::make_unique(bol_token(), true)); - _tree_node_stack.push(_node_ptr_vector.back().get()); - _token_stack.emplace(std::make_unique(REPEAT)); - } - -#ifndef NDEBUG - void eol(token_stack &handle_, id_type &nl_id_) -#else - void eol(token_stack &, id_type &nl_id_) -#endif - { - const string_token nl_('\n'); - const id_type temp_nl_id_ = lookup(nl_); - - assert(handle_.top()->_type == EOL && - handle_.size() == 1); - - if (temp_nl_id_ != ~static_cast(0)) - { - nl_id_ = temp_nl_id_; - } - - // store charset - _node_ptr_vector.emplace_back - (std::make_unique(eol_token(), true)); - _tree_node_stack.push(_node_ptr_vector.back().get()); - _token_stack.emplace(std::make_unique(REPEAT)); - } - - // Uncompressed - void charset(token_stack &handle_, const std::false_type &) - { - assert(handle_.top()->_type == CHARSET && - handle_.size() == 1); - - const id_type id_ = lookup(handle_.top()->_str); - - // store charset - _node_ptr_vector.emplace_back(std::make_unique(id_, true)); - _tree_node_stack.push(_node_ptr_vector.back().get()); - _token_stack.emplace(std::make_unique(REPEAT)); - } - - // Compressed - void charset(token_stack &handle_, const std::true_type &) - { - assert(handle_.top()->_type == CHARSET && - handle_.size() == 1); - - std::unique_ptr token_(handle_.top().release()); - - handle_.pop(); - create_sequence(token_); - } - - // Slice wchar_t into sequence of char. - void create_sequence(std::unique_ptr &token_) - { - string_token_vector data_[char_24_bit ? 3 : 2]; - - for (const input_range &range_ : token_->_str._ranges) - { - slice_range(range_, data_, - std::integral_constant()); - } - - push_ranges(data_, std::integral_constant()); - - _token_stack.emplace(std::make_unique(OPENPAREN)); - _token_stack.emplace(std::make_unique(REGEX)); - _token_stack.emplace(std::make_unique(CLOSEPAREN)); - } - - // 16 bit unicode - void slice_range(const input_range &range_, string_token_vector data_[2], - const std::false_type &) - { - const unsigned char first_msb_ = static_cast - ((range_.first >> 8) & 0xff); - const unsigned char first_lsb_ = static_cast - (range_.first & 0xff); - const unsigned char second_msb_ = static_cast - ((range_.second >> 8) & 0xff); - const unsigned char second_lsb_ = static_cast - (range_.second & 0xff); - - if (first_msb_ == second_msb_) - { - insert_range(first_msb_, first_msb_, first_lsb_, - second_lsb_, data_); - } - else - { - insert_range(first_msb_, first_msb_, first_lsb_, 0xff, data_); - - if (second_msb_ > first_msb_ + 1) - { - insert_range(first_msb_ + 1, second_msb_ - 1, 0, 0xff, data_); - } - - insert_range(second_msb_, second_msb_, 0, second_lsb_, data_); - } - } - - // 24 bit unicode - void slice_range(const input_range &range_, string_token_vector data_[3], - const std::true_type &) - { - const unsigned char first_msb_ = static_cast - ((range_.first >> 16) & 0xff); - const unsigned char first_mid_ = static_cast - ((range_.first >> 8) & 0xff); - const unsigned char first_lsb_ = static_cast - (range_.first & 0xff); - const unsigned char second_msb_ = static_cast - ((range_.second >> 16) & 0xff); - const unsigned char second_mid_ = static_cast - ((range_.second >> 8) & 0xff); - const unsigned char second_lsb_ = static_cast - (range_.second & 0xff); - - if (first_msb_ == second_msb_) - { - string_token_vector data2_[2]; - - // Re-use 16 bit slice function - slice_range(range_, data2_, std::false_type()); - - for (std::size_t i_ = 0, size_ = data2_[0].size(); - i_ < size_; ++i_) - { - insert_range(string_token(first_msb_, first_msb_), - *data2_[0][i_], *data2_[1][i_], data_); - } - } - else - { - insert_range(first_msb_, first_msb_, - first_mid_, first_mid_, - first_lsb_, 0xff, data_); - - if (first_mid_ != 0xff) - { - insert_range(first_msb_, first_msb_, - first_mid_ + 1, 0xff, - 0, 0xff, data_); - } - - if (second_msb_ > first_msb_ + 1) - { - insert_range(first_mid_ + 1, second_mid_ - 1, - 0, 0xff, - 0, 0xff, data_); - } - - if (second_mid_ != 0) - { - insert_range(second_msb_, second_msb_, - 0, second_mid_ - 1, - 0, 0xff, data_); - insert_range(second_msb_, second_msb_, - second_mid_, second_mid_, - 0, second_lsb_, data_); - } - else - { - insert_range(second_msb_, second_msb_, - 0, second_mid_, - 0, second_lsb_, data_); - } - } - } - - // 16 bit unicode - void insert_range(const unsigned char first_, const unsigned char second_, - const unsigned char first2_, const unsigned char second2_, - string_token_vector data_[2]) - { - const string_token token_(first_ > second_ ? second_ : first_, - first_ > second_ ? first_ : second_); - const string_token token2_(first2_ > second2_ ? second2_ : first2_, - first2_ > second2_ ? first2_ : second2_); - - insert_range(token_, token2_, data_); - } - - void insert_range(const string_token &token_, const string_token &token2_, - string_token_vector data_[2]) - { - typename string_token_vector::const_iterator iter_ = - std::find_if(data_[0].begin(), data_[0].end(), - [&token_](const std::unique_ptr &rhs_) - { - return token_ == *rhs_.get(); - }); - - if (iter_ == data_[0].end()) - { - data_[0].emplace_back(std::make_unique(token_)); - data_[1].emplace_back(std::make_unique(token2_)); - } - else - { - const std::size_t index_ = iter_ - data_[0].begin(); - - data_[1][index_]->insert(token2_); - } - } - - // 24 bit unicode - void insert_range(const unsigned char first_, const unsigned char second_, - const unsigned char first2_, const unsigned char second2_, - const unsigned char first3_, const unsigned char second3_, - string_token_vector data_[3]) - { - const string_token token_(first_ > second_ ? second_ : first_, - first_ > second_ ? first_ : second_); - const string_token token2_(first2_ > second2_ ? second2_ : first2_, - first2_ > second2_ ? first2_ : second2_); - const string_token token3_(first3_ > second3_ ? second3_ : first3_, - first3_ > second3_ ? first3_ : second3_); - - insert_range(token_, token2_, token3_, data_); - } - - void insert_range(const string_token &token_, const string_token &token2_, - const string_token &token3_, string_token_vector data_[3]) - { - auto iter_ = data_[0].cbegin(); - auto end_ = data_[0].cend(); - bool finished_ = false; - - do - { - iter_ = std::find_if(iter_, end_, - [&token_](const std::unique_ptr &rhs_) - { - return token_ == *rhs_.get(); - }); - - if (iter_ == end_) - { - data_[0].emplace_back(std::make_unique(token_)); - data_[1].emplace_back(std::make_unique(token2_)); - data_[2].emplace_back(std::make_unique(token3_)); - finished_ = true; - } - else - { - const std::size_t index_ = iter_ - data_[0].begin(); - - if (*data_[1][index_] == token2_) - { - data_[2][index_]->insert(token3_); - finished_ = true; - } - else - { - ++iter_; - } - } - } while (!finished_); - } - - // 16 bit unicode - void push_ranges(string_token_vector data_[2], const std::false_type &) - { - auto viter_ = data_[0].cbegin(); - auto vend_ = data_[0].cend(); - auto viter2_ = data_[1].cbegin(); - - push_range(viter_++->get()); - push_range(viter2_++->get()); - sequence(); - - while (viter_ != vend_) - { - push_range(viter_++->get()); - push_range(viter2_++->get()); - sequence(); - perform_or(); - } - } - - // 24 bit unicode - void push_ranges(string_token_vector data_[3], const std::true_type &) - { - auto viter_ = data_[0].cbegin(); - auto vend_ = data_[0].cend(); - auto viter2_ = data_[1].cbegin(); - auto viter3_ = data_[2].cbegin(); - - push_range(viter_++->get()); - push_range(viter2_++->get()); - sequence(); - push_range(viter3_++->get()); - sequence(); - - while (viter_ != vend_) - { - push_range(viter_++->get()); - push_range(viter2_++->get()); - sequence(); - push_range(viter3_++->get()); - sequence(); - perform_or(); - } - } - - void push_range(observer_ptr token_) - { - const id_type id_ = lookup(*token_); - - _node_ptr_vector.emplace_back(std::make_unique(id_, true)); - _tree_node_stack.push(_node_ptr_vector.back().get()); - } - - id_type lookup(const string_token &charset_) - { - // Converted to id_type below. - std::size_t id_ = sm_traits::npos(); - - if (static_cast(id_) < id_) - { - throw runtime_error("id_type is not large enough " - "to hold all ids."); - } - - typename charset_map::const_iterator iter_ = - _charset_map.find(charset_); - - if (iter_ == _charset_map.end()) - { - id_ = _charset_map.size(); - _charset_map.insert(charset_pair(charset_, - static_cast(id_))); - } - else - { - id_ = iter_->second; - } - - return static_cast(id_); - } - - void openparen(token_stack &handle_) - { - assert(handle_.top()->_type == OPENPAREN && - handle_.size() == 3); - - handle_.pop(); - assert(handle_.top()->_type == REGEX); - handle_.pop(); - assert(handle_.top()->_type == CLOSEPAREN); - _token_stack.emplace(std::make_unique(REPEAT)); - } - - void sequence() - { - observer_ptr rhs_ = _tree_node_stack.top(); - - _tree_node_stack.pop(); - - observer_ptr lhs_ = _tree_node_stack.top(); - - _node_ptr_vector.emplace_back - (std::make_unique(lhs_, rhs_)); - _tree_node_stack.top() = _node_ptr_vector.back().get(); - } - - void optional(const bool greedy_) - { - // perform ? - observer_ptr lhs_ = _tree_node_stack.top(); - // Don't know if lhs_ is a leaf_node, so get firstpos. - auto &firstpos_ = lhs_->firstpos(); - - for (observer_ptr node_ : firstpos_) - { - // These are leaf_nodes! - node_->greedy(greedy_); - } - - _node_ptr_vector.emplace_back(std::make_unique - (node::null_token(), greedy_)); - - observer_ptr rhs_ = _node_ptr_vector.back().get(); - - _node_ptr_vector.emplace_back - (std::make_unique(lhs_, rhs_)); - _tree_node_stack.top() = _node_ptr_vector.back().get(); - } - - void zero_or_more(const bool greedy_) - { - // perform * - observer_ptr ptr_ = _tree_node_stack.top(); - - _node_ptr_vector.emplace_back - (std::make_unique(ptr_, greedy_)); - _tree_node_stack.top() = _node_ptr_vector.back().get(); - } - - void one_or_more(const bool greedy_) - { - // perform + - observer_ptr lhs_ = _tree_node_stack.top(); - observer_ptr copy_ = lhs_->copy(_node_ptr_vector); - - _node_ptr_vector.emplace_back(std::make_unique - (copy_, greedy_)); - - observer_ptr rhs_ = _node_ptr_vector.back().get(); - - _node_ptr_vector.emplace_back - (std::make_unique(lhs_, rhs_)); - _tree_node_stack.top() = _node_ptr_vector.back().get(); - } - - // perform {n[,[m]]} - // Semantic checks have already been performed. - // {0,} = * - // {0,1} = ? - // {1,} = + - // therefore we do not check for these cases. - void repeatn(const bool greedy_, observer_ptr token_) - { - const rules_char_type *str_ = token_->_extra.c_str(); - std::size_t min_ = 0; - bool comma_ = false; - std::size_t max_ = 0; - - while (*str_>= '0' && *str_ <= '9') - { - min_ *= 10; - min_ += *str_ - '0'; - ++str_; - } - - comma_ = *str_ == ','; - - if (comma_) ++str_; - - while (*str_>= '0' && *str_ <= '9') - { - max_ *= 10; - max_ += *str_ - '0'; - ++str_; - } - - if (!(min_ == 1 && !comma_)) - { - const std::size_t top_ = min_ > 0 ? min_ : max_; - - if (min_ == 0) - { - optional(greedy_); - } - - observer_ptr prev_ = _tree_node_stack.top()-> - copy(_node_ptr_vector); - observer_ptr curr_ = nullptr; - - for (std::size_t i_ = 2; i_ < top_; ++i_) - { - curr_ = prev_->copy(_node_ptr_vector); - _tree_node_stack.push(prev_); - sequence(); - prev_ = curr_; - } - - if (comma_ && min_ > 0) - { - if (min_ > 1) - { - curr_ = prev_->copy(_node_ptr_vector); - _tree_node_stack.push(prev_); - sequence(); - prev_ = curr_; - } - - if (comma_ && max_) - { - _tree_node_stack.push(prev_); - optional(greedy_); - prev_ = _tree_node_stack.top(); - _tree_node_stack.pop(); - - const std::size_t count_ = max_ - min_; - - for (std::size_t i_ = 1; i_ < count_; ++i_) - { - curr_ = prev_->copy(_node_ptr_vector); - _tree_node_stack.push(prev_); - sequence(); - prev_ = curr_; - } - } - else - { - _tree_node_stack.push(prev_); - zero_or_more(greedy_); - prev_ = _tree_node_stack.top(); - _tree_node_stack.pop(); - } - } - - _tree_node_stack.push(prev_); - sequence(); - } - } - - void fixup_bol(observer_ptr &root_)const - { - const auto &first_ = root_->firstpos(); - bool found_ = false; - - for (observer_ptr node_ : first_) - { - found_ = !node_->end_state() && node_->token() == bol_token(); - - if (found_) break; - } - - if (!found_) - { - _node_ptr_vector.emplace_back - (std::make_unique(bol_token(), true)); - - observer_ptr lhs_ = _node_ptr_vector.back().get(); - - _node_ptr_vector.emplace_back - (std::make_unique(node::null_token(), true)); - - observer_ptr rhs_ = _node_ptr_vector.back().get(); - - _node_ptr_vector.emplace_back - (std::make_unique(lhs_, rhs_)); - lhs_ = _node_ptr_vector.back().get(); - - _node_ptr_vector.emplace_back - (std::make_unique(lhs_, root_)); - root_ = _node_ptr_vector.back().get(); - } - } -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/parser/tokeniser/re_token.hpp b/YACReaderLibrary/lexertl/parser/tokeniser/re_token.hpp deleted file mode 100644 index 271a7b1a6..000000000 --- a/YACReaderLibrary/lexertl/parser/tokeniser/re_token.hpp +++ /dev/null @@ -1,100 +0,0 @@ -// re_token.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_RE_TOKEN_HPP -#define LEXERTL_RE_TOKEN_HPP - -#include "../../string_token.hpp" - -namespace lexertl -{ -namespace detail -{ -// Note that tokens following END are never seen by parser.hpp. -enum token_type {BEGIN, REGEX, OREXP, SEQUENCE, SUB, EXPRESSION, REPEAT, - DUP, OR, CHARSET, BOL, EOL, MACRO, OPENPAREN, CLOSEPAREN, OPT, AOPT, - ZEROORMORE, AZEROORMORE, ONEORMORE, AONEORMORE, REPEATN, AREPEATN, - END, DIFF}; - -template -struct basic_re_token -{ - using string_token = basic_string_token; - using string = std::basic_string; - - token_type _type; - string _extra; - string_token _str; - - basic_re_token(const token_type type_ = BEGIN) : - _type(type_), - _extra(), - _str() - { - } - - void clear() - { - _type = BEGIN; - _extra.clear(); - _str.clear(); - } - - void swap(basic_re_token &rhs_) - { - std::swap(_type, rhs_._type); - _extra.swap(rhs_._extra); - _str.swap(rhs_._str); - } - - char precedence(const token_type type_) const - { - // Moved in here for Solaris compiler. - static const char precedence_table_[END + 1][END + 1] = { -// BEG, REG, ORE, SEQ, SUB, EXP, RPT, DUP, | , CHR, BOL, EOL, MCR, ( , ) , ? , ?? , * , *? , + , +?, {n}?, {n}, END -/*BEGIN*/{ ' ', '<', '<', '<', '<', '<', '<', ' ', ' ', '<', '<', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/*REGEX*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/*OREXP*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', '>', '>', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/* SEQ */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/* SUB */{ ' ', ' ', ' ', ' ', ' ', '=', '<', ' ', '>', '<', '<', '<', '<', '<', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/*EXPRE*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/* RPT */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', '>', '>', '>', '>', '>', '>', '>', '<', '<', '<', '<', '<', '<', '<', '<', '>' }, -/*DUPLI*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/* | */{ ' ', ' ', ' ', '=', '<', '<', '<', ' ', ' ', '<', '<', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, -/*CHARA*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, -/* BOL */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, -/* EOL */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, -/*MACRO*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, -/* ( */{ ' ', '=', '<', '<', '<', '<', '<', ' ', ' ', '<', '<', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, -/* ) */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, -/* ? */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/* ?? */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/* * */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/* *? */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/* + */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/* +? */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/*{n,m}*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/*{nm}?*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, -/* END */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } -}; - - return precedence_table_[_type][type_]; - } - - const char *precedence_string() const - { - // Moved in here for Solaris compiler. - static const char *precedence_strings_[END + 1] = - {"BEGIN", "REGEX", "OREXP", "SEQUENCE", "SUB", "EXPRESSION", - "REPEAT", "DUPLICATE", "|", "CHARSET", "^", "$", "MACRO", "(", ")", - "?", "??", "*", "*?", "+", "+?", "{n[,[m]]}", "{n[,[m]]}?", "END"}; - - return precedence_strings_[_type]; - } -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser.hpp b/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser.hpp deleted file mode 100644 index c7e1e52dc..000000000 --- a/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser.hpp +++ /dev/null @@ -1,778 +0,0 @@ -// tokeniser.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_RE_TOKENISER_HPP -#define LEXERTL_RE_TOKENISER_HPP - -#include -#include "re_token.hpp" -#include "../../runtime_error.hpp" -#include -#include "../../string_token.hpp" -#include "re_tokeniser_helper.hpp" - -namespace lexertl -{ -namespace detail -{ -template -class basic_re_tokeniser -{ -public: - using re_token = basic_re_token; - using tokeniser_helper = - basic_re_tokeniser_helper; - using char_state = typename tokeniser_helper::char_state; - using state = typename tokeniser_helper::state; - using string_token = basic_string_token; - - static void next(re_token &lhs_, state &state_, re_token &token_) - { - rules_char_type ch_ = 0; - bool eos_ = state_.next(ch_); - bool skipped_ = false; - - token_.clear(); - - do - { - // string begin/end - while (!eos_ && ch_ == '"') - { - state_._in_string ^= 1; - eos_ = state_.next(ch_); - } - - if (eos_) break; - - // (?# ...) - skipped_ = comment(eos_, ch_, state_); - - if (eos_) break; - - // skip_ws set - skipped_ |= skip(eos_, ch_, state_); - } while (!eos_ && skipped_); - - if (eos_) - { - if (state_._in_string) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (missing '\"')"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - if (state_._paren_count) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (missing ')')"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - token_._type = END; - } - else - { - if (ch_ == '\\') - { - // Even if we are in a string, respect escape sequences... - token_._type = CHARSET; - escape(state_, token_._str); - } - else if (state_._in_string) - { - // All other meta characters lose their special meaning - // inside a string. - token_._type = CHARSET; - add_char(ch_, state_, token_._str); - } - else - { - // Not an escape sequence and not inside a string, so - // check for meta characters. - switch (ch_) - { - case '(': - token_._type = OPENPAREN; - ++state_._paren_count; - read_options(state_); - break; - case ')': - --state_._paren_count; - - if (state_._paren_count < 0) - { - std::ostringstream ss_; - - ss_ << "Number of open parenthesis < 0 " - "at index " << state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - token_._type = CLOSEPAREN; - - if (!state_._flags_stack.empty()) - { - state_._flags = state_._flags_stack.top(); - state_._flags_stack.pop(); - } - - break; - case '?': - if (!state_.eos() && *state_._curr == '?') - { - token_._type = AOPT; - state_.increment(); - } - else - { - token_._type = OPT; - } - - break; - case '*': - if (!state_.eos() && *state_._curr == '?') - { - token_._type = AZEROORMORE; - state_.increment(); - } - else - { - token_._type = ZEROORMORE; - } - - break; - case '+': - if (!state_.eos() && *state_._curr == '?') - { - token_._type = AONEORMORE; - state_.increment(); - } - else - { - token_._type = ONEORMORE; - } - - break; - case '{': - open_curly(lhs_, state_, token_); - break; - case '|': - token_._type = OR; - break; - case '^': - if (!state_._macro_name && - state_._curr - 1 == state_._start) - { - token_._type = BOL; - } - else - { - token_._type = CHARSET; - token_._str.insert(range(ch_, ch_)); - } - - break; - case '$': - if (!state_._macro_name && state_._curr == state_._end) - { - token_._type = EOL; - } - else - { - token_._type = CHARSET; - token_._str.insert(range(ch_, ch_)); - } - - break; - case '.': - { - token_._type = CHARSET; - - if (state_._flags & dot_not_newline) - { - token_._str.insert(range('\n', '\n')); - } - else if (state_._flags & dot_not_cr_lf) - { - token_._str.insert(range('\n', '\n')); - token_._str.insert(range('\r', '\r')); - } - - token_._str.negate(); - break; - } - case '[': - { - token_._type = CHARSET; - tokeniser_helper::charset(state_, token_._str); - break; - } - case '/': - { - std::ostringstream ss_; - - ss_ << "Lookahead ('/') is not supported yet"; - state_.error(ss_); - throw runtime_error(ss_.str()); - break; - } - default: - token_._type = CHARSET; - add_char(ch_, state_, token_._str); - break; - } - } - } - } - -private: - using range = typename string_token::range; - - static bool comment(bool &eos_, rules_char_type &ch_, state &state_) - { - bool skipped_ = false; - - if (!state_._in_string && ch_ == '(' && !state_.eos() && - *state_._curr == '?' && state_._curr + 1 < state_._end && - *(state_._curr + 1) == '#') - { - std::size_t paren_count_ = 1; - - state_.increment(); - state_.increment(); - - do - { - eos_ = state_.next(ch_); - - if (ch_ == '(') - { - ++paren_count_; - } - else if (ch_ == ')') - { - --paren_count_; - } - } while (!eos_ && !(ch_ == ')' && paren_count_ == 0)); - - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (unterminated comment)"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - else - { - eos_ = state_.next(ch_); - } - - skipped_ = true; - } - - return skipped_; - } - - static bool skip(bool &eos_, rules_char_type &ch_, state &state_) - { - bool skipped_ = false; - - if ((state_._flags & skip_ws) && !state_._in_string) - { - bool c_comment_ = false; - bool skip_ws_ = false; - - do - { - c_comment_ = ch_ == '/' && !state_.eos() && - *state_._curr == '*'; - skip_ws_ = !c_comment_ && (ch_ == ' ' || ch_ == '\t' || - ch_ == '\n' || ch_ == '\r' || ch_ == '\f' || ch_ == '\v'); - - if (c_comment_) - { - state_.increment(); - eos_ = state_.next(ch_); - - while (!eos_ && !(ch_ == '*' && !state_.eos() && - *state_._curr == '/')) - { - eos_ = state_.next(ch_); - } - - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (unterminated C style comment)"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - else - { - state_.increment(); - eos_ = state_.next(ch_); - } - - skipped_ = true; - } - else if (skip_ws_) - { - eos_ = state_.next(ch_); - skipped_ = true; - } - } while (!eos_ && (c_comment_ || skip_ws_)); - } - - return skipped_; - } - - static void read_options(state &state_) - { - if (!state_.eos() && *state_._curr == '?') - { - rules_char_type ch_ = 0; - bool eos_ = false; - bool negate_ = false; - - state_.increment(); - eos_ = state_.next(ch_); - state_._flags_stack.push(state_._flags); - - while (!eos_ && ch_ != ':') - { - switch (ch_) - { - case '-': - negate_ ^= 1; - break; - case 'i': - if (negate_) - { - state_._flags = state_._flags & ~icase; - } - else - { - state_._flags = state_._flags | icase; - } - - negate_ = false; - break; - case 's': - if (negate_) - { -#ifdef _WIN32 - state_._flags = state_._flags | dot_not_cr_lf; -#else - state_._flags = state_._flags | dot_not_newline; -#endif - } - else - { -#ifdef _WIN32 - state_._flags = state_._flags & ~dot_not_cr_lf; -#else - state_._flags = state_._flags & ~dot_not_newline; -#endif - } - - negate_ = false; - break; - case 'x': - if (negate_) - { - state_._flags = state_._flags & ~skip_ws; - } - else - { - state_._flags = state_._flags | skip_ws; - } - - negate_ = false; - break; - default: - { - std::ostringstream ss_; - - ss_ << "Unknown option at index " << - state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - - eos_ = state_.next(ch_); - } - - // End of string handler will handle early termination - } - else if (!state_._flags_stack.empty()) - { - state_._flags_stack.push(state_._flags); - } - } - - static void escape(state &state_, string_token &token_) - { - char_type ch_ = 0; - std::size_t str_len_ = 0; - const char *str_ = tokeniser_helper::escape_sequence(state_, - ch_, str_len_); - - if (str_) - { - char_state state2_(str_ + 1, str_ + str_len_, state_._id, - state_._flags, state_._locale, 0); - - tokeniser_helper::charset(state2_, token_); - } - else - { - add_char(ch_, state_, token_); - } - } - - static void add_char(const char_type ch_, const state &state_, - string_token &token_) - { - range range_(ch_, ch_); - - token_.insert(range_); - - if (state_._flags & icase) - { - string_token folded_; - - tokeniser_helper::fold(range_, state_._locale, - folded_, typename tokeniser_helper::template - size()); - - if (!folded_.empty()) - { - token_.insert(folded_); - } - } - } - - static void open_curly(re_token &lhs_, state &state_, - re_token &token_) - { - if (state_.eos()) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (missing '}')"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - else if (*state_._curr == '-' || *state_._curr == '+') - { - rules_char_type ch_ = 0; - - if (lhs_._type != CHARSET) - { - std::ostringstream ss_; - - ss_ << "CHARSET must precede {" << - state_._curr << "} at index " << - state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - state_.next(ch_); - token_._type = DIFF; - token_._extra = ch_; - - if (state_.next(ch_)) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (missing '}')"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - if (ch_ != '}') - { - std::ostringstream ss_; - - ss_ << "Missing '}' at index " << state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - else if (*state_._curr >= '0' && *state_._curr <= '9') - { - repeat_n(state_, token_); - } - else - { - macro(state_, token_); - } - } - - // SYNTAX: - // {n[,[n]]} - // SEMANTIC RULES: - // {0} - INVALID (throw exception) - // {0,} = * - // {0,0} - INVALID (throw exception) - // {0,1} = ? - // {1,} = + - // {min,max} where min == max - {min} - // {min,max} where max < min - INVALID (throw exception) - static void repeat_n(state &state_, re_token &token_) - { - rules_char_type ch_ = 0; - bool eos_ = state_.next(ch_); - std::size_t min_ = 0; - std::size_t max_ = 0; - - while (!eos_ && ch_ >= '0' && ch_ <= '9') - { - min_ *= 10; - min_ += ch_ - '0'; - token_._extra += ch_; - eos_ = state_.next(ch_); - } - - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (missing repeat terminator '}')"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - bool min_max_ = false; - bool repeatn_ = true; - - if (ch_ == ',') - { - token_._extra += ch_; - eos_ = state_.next(ch_); - - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (missing repeat terminator '}')"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - if (ch_ == '}') - { - // Small optimisation: Check for '*' equivalency. - if (min_ == 0) - { - token_._type = ZEROORMORE; - repeatn_ = false; - } - // Small optimisation: Check for '+' equivalency. - else if (min_ == 1) - { - token_._type = ONEORMORE; - repeatn_ = false; - } - } - else - { - if (ch_ < '0' || ch_ > '9') - { - std::ostringstream ss_; - - ss_ << "Missing repeat terminator '}' at index " << - state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - min_max_ = true; - - do - { - max_ *= 10; - max_ += ch_ - '0'; - token_._extra += ch_; - eos_ = state_.next(ch_); - } while (!eos_ && ch_ >= '0' && ch_ <= '9'); - - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (missing repeat terminator '}')"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - // Small optimisation: Check for '?' equivalency. - if (min_ == 0 && max_ == 1) - { - token_._type = OPT; - repeatn_ = false; - } - // Small optimisation: if min == max, then min. - else if (min_ == max_) - { - token_._extra.erase(token_._extra.find(',')); - min_max_ = false; - max_ = 0; - } - } - } - - if (ch_ != '}') - { - std::ostringstream ss_; - - ss_ << "Missing repeat terminator '}' at index " << - state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - if (repeatn_) - { - // SEMANTIC VALIDATION follows: - // NOTE: {0,} has already become * - // therefore we don't check for a comma. - if (min_ == 0 && max_ == 0) - { - std::ostringstream ss_; - - ss_ << "Cannot have exactly zero repeats preceding index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - if (min_max_ && max_ < min_) - { - std::ostringstream ss_; - - ss_ << "Max less than min preceding index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - if (!state_.eos() && *state_._curr == '?') - { - token_._type = AREPEATN; - state_.increment(); - } - else - { - token_._type = REPEATN; - } - } - else if (token_._type == ZEROORMORE) - { - if (!state_.eos() && *state_._curr == '?') - { - token_._type = AZEROORMORE; - state_.increment(); - } - } - else if (token_._type == ONEORMORE) - { - if (!state_.eos() && *state_._curr == '?') - { - token_._type = AONEORMORE; - state_.increment(); - } - } - else if (token_._type == OPT) - { - if (!state_.eos() && *state_._curr == '?') - { - token_._type = AOPT; - state_.increment(); - } - } - } - - static void macro(state &state_, re_token &token_) - { - rules_char_type ch_ = 0; - bool eos_ = false; - - state_.next(ch_); - - if (ch_ != '_' && !(ch_ >= 'A' && ch_ <= 'Z') && - !(ch_ >= 'a' && ch_ <= 'z')) - { - std::ostringstream ss_; - - ss_ << "Invalid MACRO name at index " << state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - do - { - token_._extra += ch_; - eos_ = state_.next(ch_); - - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (missing MACRO name terminator '}')"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } while (ch_ == '_' || ch_ == '-' || (ch_ >= 'A' && ch_ <= 'Z') || - (ch_ >= 'a' && ch_ <= 'z') || (ch_ >= '0' && ch_ <= '9')); - - if (ch_ != '}') - { - std::ostringstream ss_; - - ss_ << "Missing MACRO name terminator '}' at index " << - state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - token_._type = MACRO; - } -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_helper.hpp b/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_helper.hpp deleted file mode 100644 index f9f40cfef..000000000 --- a/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_helper.hpp +++ /dev/null @@ -1,3157 +0,0 @@ -// tokeniser_helper.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_RE_TOKENISER_HELPER_HPP -#define LEXERTL_RE_TOKENISER_HELPER_HPP - -#include "../../char_traits.hpp" -// strlen() -#include -#include "re_tokeniser_state.hpp" -#include "../../runtime_error.hpp" -#include -#include "../../string_token.hpp" - -namespace lexertl -{ -namespace detail -{ -template > -class basic_re_tokeniser_helper -{ -public: - using char_state = basic_re_tokeniser_state; - using state = basic_re_tokeniser_state; - using string_token = basic_string_token; - using index_type = typename string_token::index_type; - using range = typename string_token::range; - - template - struct size - { - }; - - using one = size<1>; - using two = size<2>; - using four = size<4>; - - template - static const char *escape_sequence(state_type &state_, - char_type &ch_, std::size_t &str_len_) - { - bool eos_ = state_.eos(); - - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following '\\'"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - const char *str_ = charset_shortcut(state_, str_len_); - - if (str_) - { - state_.increment(); - } - else - { - ch_ = chr(state_); - } - - return str_; - } - - // This function can call itself. - template - static void charset(state_type &state_, string_token &token_) - { - bool negated_ = false; - typename state_type::char_type ch_ = 0; - bool eos_ = state_.next(ch_); - - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following '['"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - negated_ = ch_ == '^'; - - if (negated_) - { - eos_ = state_.next(ch_); - - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following '^'"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - - bool chset_ = false; - typename string_token::char_type prev_ = 0; - - do - { - if (ch_ == '\\') - { - std::size_t str_len_ = 0; - const char *str_ = escape_sequence(state_, prev_, - str_len_); - - chset_ = str_ != 0; - - if (chset_) - { - char_state temp_state_(str_ + 1, str_ + str_len_, - state_._id, state_._flags, state_._locale, 0); - string_token temp_token_; - - charset(temp_state_, temp_token_); - token_.insert(temp_token_); - } - } - else if (ch_ == '[' && !state_.eos() && *state_._curr == ':') - { - state_.increment(); - posix(state_, token_); - chset_ = true; - } - else - { - chset_ = false; - prev_ = ch_; - } - - eos_ = state_.next(ch_); - - // Covers preceding if, else if and else - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (missing ']')"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - if (ch_ == '-' && *state_._curr != ']') - { - charset_range(chset_, state_, eos_, ch_, prev_, - token_); - } - else if (!chset_) - { - range range_(prev_, prev_); - - token_.insert(range_); - - if (state_._flags & icase) - { - string_token folded_; - - fold(range_, state_._locale, folded_, - size()); - - if (!folded_.empty()) - { - token_.insert(folded_); - } - } - } - } while (ch_ != ']'); - - if (negated_) - { - token_.negate(); - } - - if (token_.empty()) - { - std::ostringstream ss_; - - ss_ << "Empty charset not allowed preceding index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - - static void fold(const range &range_, const std::locale &locale_, - string_token &out_, const one &) - { - // If string_token::char_type is 16 bit may overflow, - // so use std::size_t. - std::size_t start_ = range_.first; - std::size_t end_ = range_.second; - - // In 8 bit char mode, use locale and therefore consider every char - // individually. - for (; start_ <= end_; ++start_) - { - const input_char_type upper_ = std::toupper - (static_cast(start_), locale_); - const input_char_type lower_ = std::tolower - (static_cast(start_), locale_); - - if (upper_ != static_cast(start_)) - { - out_.insert(range(upper_, upper_)); - } - - if (lower_ != static_cast(start_)) - { - out_.insert(range(lower_, lower_)); - } - } - } - - // http://www.unicode.org/Public/8.0.0/ucd/UnicodeData.txt - static void fold(const range &range_, const std::locale &, - string_token &out_, const two &) - { - static const fold_pair mapping_[] = - {{{0x0041, 0x005a}, {0x0061, 0x007a}}, - {{0x0061, 0x007a}, {0x0041, 0x005a}}, - {{0x00b5, 0x00b5}, {0x039c, 0x039c}}, - {{0x00c0, 0x00d6}, {0x00e0, 0x00f6}}, - {{0x00d8, 0x00de}, {0x00f8, 0x00fe}}, - {{0x00e0, 0x00f6}, {0x00c0, 0x00d6}}, - {{0x00f8, 0x00fe}, {0x00d8, 0x00de}}, - {{0x00ff, 0x00ff}, {0x0178, 0x0178}}, - {{0x0100, 0x0101}, {0x0101, 0x0100}}, - {{0x0102, 0x0103}, {0x0103, 0x0102}}, - {{0x0104, 0x0105}, {0x0105, 0x0104}}, - {{0x0106, 0x0107}, {0x0107, 0x0106}}, - {{0x0108, 0x0109}, {0x0109, 0x0108}}, - {{0x010a, 0x010b}, {0x010b, 0x010a}}, - {{0x010c, 0x010d}, {0x010d, 0x010c}}, - {{0x010e, 0x010f}, {0x010f, 0x010e}}, - {{0x0110, 0x0111}, {0x0111, 0x0110}}, - {{0x0112, 0x0113}, {0x0113, 0x0112}}, - {{0x0114, 0x0115}, {0x0115, 0x0114}}, - {{0x0116, 0x0117}, {0x0117, 0x0116}}, - {{0x0118, 0x0119}, {0x0119, 0x0118}}, - {{0x011a, 0x011b}, {0x011b, 0x011a}}, - {{0x011c, 0x011d}, {0x011d, 0x011c}}, - {{0x011e, 0x011f}, {0x011f, 0x011e}}, - {{0x0120, 0x0121}, {0x0121, 0x0120}}, - {{0x0122, 0x0123}, {0x0123, 0x0122}}, - {{0x0124, 0x0125}, {0x0125, 0x0124}}, - {{0x0126, 0x0127}, {0x0127, 0x0126}}, - {{0x0128, 0x0129}, {0x0129, 0x0128}}, - {{0x012a, 0x012b}, {0x012b, 0x012a}}, - {{0x012c, 0x012d}, {0x012d, 0x012c}}, - {{0x012e, 0x012f}, {0x012f, 0x012e}}, - {{0x0130, 0x0130}, {0x0069, 0x0069}}, - {{0x0131, 0x0131}, {0x0049, 0x0049}}, - {{0x0132, 0x0133}, {0x0133, 0x0132}}, - {{0x0134, 0x0135}, {0x0135, 0x0134}}, - {{0x0136, 0x0137}, {0x0137, 0x0136}}, - {{0x0139, 0x013a}, {0x013a, 0x0139}}, - {{0x013b, 0x013c}, {0x013c, 0x013b}}, - {{0x013d, 0x013e}, {0x013e, 0x013d}}, - {{0x013f, 0x0140}, {0x0140, 0x013f}}, - {{0x0141, 0x0142}, {0x0142, 0x0141}}, - {{0x0143, 0x0144}, {0x0144, 0x0143}}, - {{0x0145, 0x0146}, {0x0146, 0x0145}}, - {{0x0147, 0x0148}, {0x0148, 0x0147}}, - {{0x014a, 0x014b}, {0x014b, 0x014a}}, - {{0x014c, 0x014d}, {0x014d, 0x014c}}, - {{0x014e, 0x014f}, {0x014f, 0x014e}}, - {{0x0150, 0x0151}, {0x0151, 0x0150}}, - {{0x0152, 0x0153}, {0x0153, 0x0152}}, - {{0x0154, 0x0155}, {0x0155, 0x0154}}, - {{0x0156, 0x0157}, {0x0157, 0x0156}}, - {{0x0158, 0x0159}, {0x0159, 0x0158}}, - {{0x015a, 0x015b}, {0x015b, 0x015a}}, - {{0x015c, 0x015d}, {0x015d, 0x015c}}, - {{0x015e, 0x015f}, {0x015f, 0x015e}}, - {{0x0160, 0x0161}, {0x0161, 0x0160}}, - {{0x0162, 0x0163}, {0x0163, 0x0162}}, - {{0x0164, 0x0165}, {0x0165, 0x0164}}, - {{0x0166, 0x0167}, {0x0167, 0x0166}}, - {{0x0168, 0x0169}, {0x0169, 0x0168}}, - {{0x016a, 0x016b}, {0x016b, 0x016a}}, - {{0x016c, 0x016d}, {0x016d, 0x016c}}, - {{0x016e, 0x016f}, {0x016f, 0x016e}}, - {{0x0170, 0x0171}, {0x0171, 0x0170}}, - {{0x0172, 0x0173}, {0x0173, 0x0172}}, - {{0x0174, 0x0175}, {0x0175, 0x0174}}, - {{0x0176, 0x0177}, {0x0177, 0x0176}}, - {{0x0178, 0x0178}, {0x00ff, 0x00ff}}, - {{0x0179, 0x017a}, {0x017a, 0x0179}}, - {{0x017b, 0x017c}, {0x017c, 0x017b}}, - {{0x017d, 0x017e}, {0x017e, 0x017d}}, - {{0x017f, 0x017f}, {0x0053, 0x0053}}, - {{0x0180, 0x0180}, {0x0243, 0x0243}}, - {{0x0181, 0x0181}, {0x0253, 0x0253}}, - {{0x0182, 0x0183}, {0x0183, 0x0182}}, - {{0x0184, 0x0185}, {0x0185, 0x0184}}, - {{0x0186, 0x0186}, {0x0254, 0x0254}}, - {{0x0187, 0x0188}, {0x0188, 0x0187}}, - {{0x0189, 0x018a}, {0x0256, 0x0257}}, - {{0x018b, 0x018c}, {0x018c, 0x018b}}, - {{0x018e, 0x018e}, {0x01dd, 0x01dd}}, - {{0x018f, 0x018f}, {0x0259, 0x0259}}, - {{0x0190, 0x0190}, {0x025b, 0x025b}}, - {{0x0191, 0x0192}, {0x0192, 0x0191}}, - {{0x0193, 0x0193}, {0x0260, 0x0260}}, - {{0x0194, 0x0194}, {0x0263, 0x0263}}, - {{0x0195, 0x0195}, {0x01f6, 0x01f6}}, - {{0x0196, 0x0196}, {0x0269, 0x0269}}, - {{0x0197, 0x0197}, {0x0268, 0x0268}}, - {{0x0198, 0x0199}, {0x0199, 0x0198}}, - {{0x019a, 0x019a}, {0x023d, 0x023d}}, - {{0x019c, 0x019c}, {0x026f, 0x026f}}, - {{0x019d, 0x019d}, {0x0272, 0x0272}}, - {{0x019e, 0x019e}, {0x0220, 0x0220}}, - {{0x019f, 0x019f}, {0x0275, 0x0275}}, - {{0x01a0, 0x01a1}, {0x01a1, 0x01a0}}, - {{0x01a2, 0x01a3}, {0x01a3, 0x01a2}}, - {{0x01a4, 0x01a5}, {0x01a5, 0x01a4}}, - {{0x01a6, 0x01a6}, {0x0280, 0x0280}}, - {{0x01a7, 0x01a8}, {0x01a8, 0x01a7}}, - {{0x01a9, 0x01a9}, {0x0283, 0x0283}}, - {{0x01ac, 0x01ad}, {0x01ad, 0x01ac}}, - {{0x01ae, 0x01ae}, {0x0288, 0x0288}}, - {{0x01af, 0x01b0}, {0x01b0, 0x01af}}, - {{0x01b1, 0x01b2}, {0x028a, 0x028b}}, - {{0x01b3, 0x01b4}, {0x01b4, 0x01b3}}, - {{0x01b5, 0x01b6}, {0x01b6, 0x01b5}}, - {{0x01b7, 0x01b7}, {0x0292, 0x0292}}, - {{0x01b8, 0x01b9}, {0x01b9, 0x01b8}}, - {{0x01bc, 0x01bd}, {0x01bd, 0x01bc}}, - {{0x01bf, 0x01bf}, {0x01f7, 0x01f7}}, - {{0x01c4, 0x01c4}, {0x01c6, 0x01c6}}, - {{0x01c6, 0x01c6}, {0x01c4, 0x01c4}}, - {{0x01c7, 0x01c7}, {0x01c9, 0x01c9}}, - {{0x01c9, 0x01c9}, {0x01c7, 0x01c7}}, - {{0x01ca, 0x01ca}, {0x01cc, 0x01cc}}, - {{0x01cc, 0x01cc}, {0x01ca, 0x01ca}}, - {{0x01cd, 0x01ce}, {0x01ce, 0x01cd}}, - {{0x01cf, 0x01d0}, {0x01d0, 0x01cf}}, - {{0x01d1, 0x01d2}, {0x01d2, 0x01d1}}, - {{0x01d3, 0x01d4}, {0x01d4, 0x01d3}}, - {{0x01d5, 0x01d6}, {0x01d6, 0x01d5}}, - {{0x01d7, 0x01d8}, {0x01d8, 0x01d7}}, - {{0x01d9, 0x01da}, {0x01da, 0x01d9}}, - {{0x01db, 0x01dc}, {0x01dc, 0x01db}}, - {{0x01dd, 0x01dd}, {0x018e, 0x018e}}, - {{0x01de, 0x01df}, {0x01df, 0x01de}}, - {{0x01e0, 0x01e1}, {0x01e1, 0x01e0}}, - {{0x01e2, 0x01e3}, {0x01e3, 0x01e2}}, - {{0x01e4, 0x01e5}, {0x01e5, 0x01e4}}, - {{0x01e6, 0x01e7}, {0x01e7, 0x01e6}}, - {{0x01e8, 0x01e9}, {0x01e9, 0x01e8}}, - {{0x01ea, 0x01eb}, {0x01eb, 0x01ea}}, - {{0x01ec, 0x01ed}, {0x01ed, 0x01ec}}, - {{0x01ee, 0x01ef}, {0x01ef, 0x01ee}}, - {{0x01f1, 0x01f1}, {0x01f3, 0x01f3}}, - {{0x01f3, 0x01f3}, {0x01f1, 0x01f1}}, - {{0x01f4, 0x01f5}, {0x01f5, 0x01f4}}, - {{0x01f6, 0x01f6}, {0x0195, 0x0195}}, - {{0x01f7, 0x01f7}, {0x01bf, 0x01bf}}, - {{0x01f8, 0x01f9}, {0x01f9, 0x01f8}}, - {{0x01fa, 0x01fb}, {0x01fb, 0x01fa}}, - {{0x01fc, 0x01fd}, {0x01fd, 0x01fc}}, - {{0x01fe, 0x01ff}, {0x01ff, 0x01fe}}, - {{0x0200, 0x0201}, {0x0201, 0x0200}}, - {{0x0202, 0x0203}, {0x0203, 0x0202}}, - {{0x0204, 0x0205}, {0x0205, 0x0204}}, - {{0x0206, 0x0207}, {0x0207, 0x0206}}, - {{0x0208, 0x0209}, {0x0209, 0x0208}}, - {{0x020a, 0x020b}, {0x020b, 0x020a}}, - {{0x020c, 0x020d}, {0x020d, 0x020c}}, - {{0x020e, 0x020f}, {0x020f, 0x020e}}, - {{0x0210, 0x0211}, {0x0211, 0x0210}}, - {{0x0212, 0x0213}, {0x0213, 0x0212}}, - {{0x0214, 0x0215}, {0x0215, 0x0214}}, - {{0x0216, 0x0217}, {0x0217, 0x0216}}, - {{0x0218, 0x0219}, {0x0219, 0x0218}}, - {{0x021a, 0x021b}, {0x021b, 0x021a}}, - {{0x021c, 0x021d}, {0x021d, 0x021c}}, - {{0x021e, 0x021f}, {0x021f, 0x021e}}, - {{0x0220, 0x0220}, {0x019e, 0x019e}}, - {{0x0222, 0x0223}, {0x0223, 0x0222}}, - {{0x0224, 0x0225}, {0x0225, 0x0224}}, - {{0x0226, 0x0227}, {0x0227, 0x0226}}, - {{0x0228, 0x0229}, {0x0229, 0x0228}}, - {{0x022a, 0x022b}, {0x022b, 0x022a}}, - {{0x022c, 0x022d}, {0x022d, 0x022c}}, - {{0x022e, 0x022f}, {0x022f, 0x022e}}, - {{0x0230, 0x0231}, {0x0231, 0x0230}}, - {{0x0232, 0x0233}, {0x0233, 0x0232}}, - {{0x023a, 0x023a}, {0x2c65, 0x2c65}}, - {{0x023b, 0x023c}, {0x023c, 0x023b}}, - {{0x023d, 0x023d}, {0x019a, 0x019a}}, - {{0x023e, 0x023e}, {0x2c66, 0x2c66}}, - {{0x023f, 0x0240}, {0x2c7e, 0x2c7f}}, - {{0x0241, 0x0242}, {0x0242, 0x0241}}, - {{0x0243, 0x0243}, {0x0180, 0x0180}}, - {{0x0244, 0x0244}, {0x0289, 0x0289}}, - {{0x0245, 0x0245}, {0x028c, 0x028c}}, - {{0x0246, 0x0247}, {0x0247, 0x0246}}, - {{0x0248, 0x0249}, {0x0249, 0x0248}}, - {{0x024a, 0x024b}, {0x024b, 0x024a}}, - {{0x024c, 0x024d}, {0x024d, 0x024c}}, - {{0x024e, 0x024f}, {0x024f, 0x024e}}, - {{0x0250, 0x0250}, {0x2c6f, 0x2c6f}}, - {{0x0251, 0x0251}, {0x2c6d, 0x2c6d}}, - {{0x0252, 0x0252}, {0x2c70, 0x2c70}}, - {{0x0253, 0x0253}, {0x0181, 0x0181}}, - {{0x0254, 0x0254}, {0x0186, 0x0186}}, - {{0x0256, 0x0257}, {0x0189, 0x018a}}, - {{0x0259, 0x0259}, {0x018f, 0x018f}}, - {{0x025b, 0x025b}, {0x0190, 0x0190}}, - {{0x025c, 0x025c}, {0xa7ab, 0xa7ab}}, - {{0x0260, 0x0260}, {0x0193, 0x0193}}, - {{0x0261, 0x0261}, {0xa7ac, 0xa7ac}}, - {{0x0263, 0x0263}, {0x0194, 0x0194}}, - {{0x0265, 0x0265}, {0xa78d, 0xa78d}}, - {{0x0266, 0x0266}, {0xa7aa, 0xa7aa}}, - {{0x0268, 0x0269}, {0x0197, 0x0196}}, - {{0x026b, 0x026b}, {0x2c62, 0x2c62}}, - {{0x026c, 0x026c}, {0xa7ad, 0xa7ad}}, - {{0x026f, 0x026f}, {0x019c, 0x019c}}, - {{0x0271, 0x0271}, {0x2c6e, 0x2c6e}}, - {{0x0272, 0x0272}, {0x019d, 0x019d}}, - {{0x0275, 0x0275}, {0x019f, 0x019f}}, - {{0x027d, 0x027d}, {0x2c64, 0x2c64}}, - {{0x0280, 0x0280}, {0x01a6, 0x01a6}}, - {{0x0283, 0x0283}, {0x01a9, 0x01a9}}, - {{0x0287, 0x0287}, {0xa7b1, 0xa7b1}}, - {{0x0288, 0x0288}, {0x01ae, 0x01ae}}, - {{0x0289, 0x0289}, {0x0244, 0x0244}}, - {{0x028a, 0x028b}, {0x01b1, 0x01b2}}, - {{0x028c, 0x028c}, {0x0245, 0x0245}}, - {{0x0292, 0x0292}, {0x01b7, 0x01b7}}, - {{0x029d, 0x029d}, {0xa7b2, 0xa7b2}}, - {{0x029e, 0x029e}, {0xa7b0, 0xa7b0}}, - {{0x0370, 0x0371}, {0x0371, 0x0370}}, - {{0x0372, 0x0373}, {0x0373, 0x0372}}, - {{0x0376, 0x0377}, {0x0377, 0x0376}}, - {{0x037b, 0x037d}, {0x03fd, 0x03ff}}, - {{0x037f, 0x037f}, {0x03f3, 0x03f3}}, - {{0x0386, 0x0386}, {0x03ac, 0x03ac}}, - {{0x0388, 0x038a}, {0x03ad, 0x03af}}, - {{0x038c, 0x038c}, {0x03cc, 0x03cc}}, - {{0x038e, 0x038f}, {0x03cd, 0x03ce}}, - {{0x0391, 0x03a1}, {0x03b1, 0x03c1}}, - {{0x03a3, 0x03ab}, {0x03c3, 0x03cb}}, - {{0x03ac, 0x03ac}, {0x0386, 0x0386}}, - {{0x03ad, 0x03af}, {0x0388, 0x038a}}, - {{0x03b1, 0x03c1}, {0x0391, 0x03a1}}, - {{0x03c2, 0x03c2}, {0x03a3, 0x03a3}}, - {{0x03c3, 0x03cb}, {0x03a3, 0x03ab}}, - {{0x03cc, 0x03cc}, {0x038c, 0x038c}}, - {{0x03cd, 0x03ce}, {0x038e, 0x038f}}, - {{0x03cf, 0x03cf}, {0x03d7, 0x03d7}}, - {{0x03d0, 0x03d0}, {0x0392, 0x0392}}, - {{0x03d1, 0x03d1}, {0x0398, 0x0398}}, - {{0x03d5, 0x03d5}, {0x03a6, 0x03a6}}, - {{0x03d6, 0x03d6}, {0x03a0, 0x03a0}}, - {{0x03d7, 0x03d7}, {0x03cf, 0x03cf}}, - {{0x03d8, 0x03d9}, {0x03d9, 0x03d8}}, - {{0x03da, 0x03db}, {0x03db, 0x03da}}, - {{0x03dc, 0x03dd}, {0x03dd, 0x03dc}}, - {{0x03de, 0x03df}, {0x03df, 0x03de}}, - {{0x03e0, 0x03e1}, {0x03e1, 0x03e0}}, - {{0x03e2, 0x03e3}, {0x03e3, 0x03e2}}, - {{0x03e4, 0x03e5}, {0x03e5, 0x03e4}}, - {{0x03e6, 0x03e7}, {0x03e7, 0x03e6}}, - {{0x03e8, 0x03e9}, {0x03e9, 0x03e8}}, - {{0x03ea, 0x03eb}, {0x03eb, 0x03ea}}, - {{0x03ec, 0x03ed}, {0x03ed, 0x03ec}}, - {{0x03ee, 0x03ef}, {0x03ef, 0x03ee}}, - {{0x03f0, 0x03f0}, {0x039a, 0x039a}}, - {{0x03f1, 0x03f1}, {0x03a1, 0x03a1}}, - {{0x03f2, 0x03f2}, {0x03f9, 0x03f9}}, - {{0x03f3, 0x03f3}, {0x037f, 0x037f}}, - {{0x03f4, 0x03f4}, {0x03b8, 0x03b8}}, - {{0x03f5, 0x03f5}, {0x0395, 0x0395}}, - {{0x03f7, 0x03f8}, {0x03f8, 0x03f7}}, - {{0x03f9, 0x03f9}, {0x03f2, 0x03f2}}, - {{0x03fa, 0x03fb}, {0x03fb, 0x03fa}}, - {{0x03fd, 0x03ff}, {0x037b, 0x037d}}, - {{0x0400, 0x040f}, {0x0450, 0x045f}}, - {{0x0410, 0x042f}, {0x0430, 0x044f}}, - {{0x0430, 0x044f}, {0x0410, 0x042f}}, - {{0x0450, 0x045f}, {0x0400, 0x040f}}, - {{0x0460, 0x0461}, {0x0461, 0x0460}}, - {{0x0462, 0x0463}, {0x0463, 0x0462}}, - {{0x0464, 0x0465}, {0x0465, 0x0464}}, - {{0x0466, 0x0467}, {0x0467, 0x0466}}, - {{0x0468, 0x0469}, {0x0469, 0x0468}}, - {{0x046a, 0x046b}, {0x046b, 0x046a}}, - {{0x046c, 0x046d}, {0x046d, 0x046c}}, - {{0x046e, 0x046f}, {0x046f, 0x046e}}, - {{0x0470, 0x0471}, {0x0471, 0x0470}}, - {{0x0472, 0x0473}, {0x0473, 0x0472}}, - {{0x0474, 0x0475}, {0x0475, 0x0474}}, - {{0x0476, 0x0477}, {0x0477, 0x0476}}, - {{0x0478, 0x0479}, {0x0479, 0x0478}}, - {{0x047a, 0x047b}, {0x047b, 0x047a}}, - {{0x047c, 0x047d}, {0x047d, 0x047c}}, - {{0x047e, 0x047f}, {0x047f, 0x047e}}, - {{0x0480, 0x0481}, {0x0481, 0x0480}}, - {{0x048a, 0x048b}, {0x048b, 0x048a}}, - {{0x048c, 0x048d}, {0x048d, 0x048c}}, - {{0x048e, 0x048f}, {0x048f, 0x048e}}, - {{0x0490, 0x0491}, {0x0491, 0x0490}}, - {{0x0492, 0x0493}, {0x0493, 0x0492}}, - {{0x0494, 0x0495}, {0x0495, 0x0494}}, - {{0x0496, 0x0497}, {0x0497, 0x0496}}, - {{0x0498, 0x0499}, {0x0499, 0x0498}}, - {{0x049a, 0x049b}, {0x049b, 0x049a}}, - {{0x049c, 0x049d}, {0x049d, 0x049c}}, - {{0x049e, 0x049f}, {0x049f, 0x049e}}, - {{0x04a0, 0x04a1}, {0x04a1, 0x04a0}}, - {{0x04a2, 0x04a3}, {0x04a3, 0x04a2}}, - {{0x04a4, 0x04a5}, {0x04a5, 0x04a4}}, - {{0x04a6, 0x04a7}, {0x04a7, 0x04a6}}, - {{0x04a8, 0x04a9}, {0x04a9, 0x04a8}}, - {{0x04aa, 0x04ab}, {0x04ab, 0x04aa}}, - {{0x04ac, 0x04ad}, {0x04ad, 0x04ac}}, - {{0x04ae, 0x04af}, {0x04af, 0x04ae}}, - {{0x04b0, 0x04b1}, {0x04b1, 0x04b0}}, - {{0x04b2, 0x04b3}, {0x04b3, 0x04b2}}, - {{0x04b4, 0x04b5}, {0x04b5, 0x04b4}}, - {{0x04b6, 0x04b7}, {0x04b7, 0x04b6}}, - {{0x04b8, 0x04b9}, {0x04b9, 0x04b8}}, - {{0x04ba, 0x04bb}, {0x04bb, 0x04ba}}, - {{0x04bc, 0x04bd}, {0x04bd, 0x04bc}}, - {{0x04be, 0x04bf}, {0x04bf, 0x04be}}, - {{0x04c0, 0x04c0}, {0x04cf, 0x04cf}}, - {{0x04c1, 0x04c2}, {0x04c2, 0x04c1}}, - {{0x04c3, 0x04c4}, {0x04c4, 0x04c3}}, - {{0x04c5, 0x04c6}, {0x04c6, 0x04c5}}, - {{0x04c7, 0x04c8}, {0x04c8, 0x04c7}}, - {{0x04c9, 0x04ca}, {0x04ca, 0x04c9}}, - {{0x04cb, 0x04cc}, {0x04cc, 0x04cb}}, - {{0x04cd, 0x04ce}, {0x04ce, 0x04cd}}, - {{0x04cf, 0x04cf}, {0x04c0, 0x04c0}}, - {{0x04d0, 0x04d1}, {0x04d1, 0x04d0}}, - {{0x04d2, 0x04d3}, {0x04d3, 0x04d2}}, - {{0x04d4, 0x04d5}, {0x04d5, 0x04d4}}, - {{0x04d6, 0x04d7}, {0x04d7, 0x04d6}}, - {{0x04d8, 0x04d9}, {0x04d9, 0x04d8}}, - {{0x04da, 0x04db}, {0x04db, 0x04da}}, - {{0x04dc, 0x04dd}, {0x04dd, 0x04dc}}, - {{0x04de, 0x04df}, {0x04df, 0x04de}}, - {{0x04e0, 0x04e1}, {0x04e1, 0x04e0}}, - {{0x04e2, 0x04e3}, {0x04e3, 0x04e2}}, - {{0x04e4, 0x04e5}, {0x04e5, 0x04e4}}, - {{0x04e6, 0x04e7}, {0x04e7, 0x04e6}}, - {{0x04e8, 0x04e9}, {0x04e9, 0x04e8}}, - {{0x04ea, 0x04eb}, {0x04eb, 0x04ea}}, - {{0x04ec, 0x04ed}, {0x04ed, 0x04ec}}, - {{0x04ee, 0x04ef}, {0x04ef, 0x04ee}}, - {{0x04f0, 0x04f1}, {0x04f1, 0x04f0}}, - {{0x04f2, 0x04f3}, {0x04f3, 0x04f2}}, - {{0x04f4, 0x04f5}, {0x04f5, 0x04f4}}, - {{0x04f6, 0x04f7}, {0x04f7, 0x04f6}}, - {{0x04f8, 0x04f9}, {0x04f9, 0x04f8}}, - {{0x04fa, 0x04fb}, {0x04fb, 0x04fa}}, - {{0x04fc, 0x04fd}, {0x04fd, 0x04fc}}, - {{0x04fe, 0x04ff}, {0x04ff, 0x04fe}}, - {{0x0500, 0x0501}, {0x0501, 0x0500}}, - {{0x0502, 0x0503}, {0x0503, 0x0502}}, - {{0x0504, 0x0505}, {0x0505, 0x0504}}, - {{0x0506, 0x0507}, {0x0507, 0x0506}}, - {{0x0508, 0x0509}, {0x0509, 0x0508}}, - {{0x050a, 0x050b}, {0x050b, 0x050a}}, - {{0x050c, 0x050d}, {0x050d, 0x050c}}, - {{0x050e, 0x050f}, {0x050f, 0x050e}}, - {{0x0510, 0x0511}, {0x0511, 0x0510}}, - {{0x0512, 0x0513}, {0x0513, 0x0512}}, - {{0x0514, 0x0515}, {0x0515, 0x0514}}, - {{0x0516, 0x0517}, {0x0517, 0x0516}}, - {{0x0518, 0x0519}, {0x0519, 0x0518}}, - {{0x051a, 0x051b}, {0x051b, 0x051a}}, - {{0x051c, 0x051d}, {0x051d, 0x051c}}, - {{0x051e, 0x051f}, {0x051f, 0x051e}}, - {{0x0520, 0x0521}, {0x0521, 0x0520}}, - {{0x0522, 0x0523}, {0x0523, 0x0522}}, - {{0x0524, 0x0525}, {0x0525, 0x0524}}, - {{0x0526, 0x0527}, {0x0527, 0x0526}}, - {{0x0528, 0x0529}, {0x0529, 0x0528}}, - {{0x052a, 0x052b}, {0x052b, 0x052a}}, - {{0x052c, 0x052d}, {0x052d, 0x052c}}, - {{0x052e, 0x052f}, {0x052f, 0x052e}}, - {{0x0531, 0x0556}, {0x0561, 0x0586}}, - {{0x0561, 0x0586}, {0x0531, 0x0556}}, - {{0x10a0, 0x10c5}, {0x2d00, 0x2d25}}, - {{0x10c7, 0x10c7}, {0x2d27, 0x2d27}}, - {{0x10cd, 0x10cd}, {0x2d2d, 0x2d2d}}, - {{0x13a0, 0x13ef}, {0xab70, 0xabbf}}, - {{0x13f0, 0x13f5}, {0x13f8, 0x13fd}}, - {{0x13f8, 0x13fd}, {0x13f0, 0x13f5}}, - {{0x1d79, 0x1d79}, {0xa77d, 0xa77d}}, - {{0x1d7d, 0x1d7d}, {0x2c63, 0x2c63}}, - {{0x1e00, 0x1e01}, {0x1e01, 0x1e00}}, - {{0x1e02, 0x1e03}, {0x1e03, 0x1e02}}, - {{0x1e04, 0x1e05}, {0x1e05, 0x1e04}}, - {{0x1e06, 0x1e07}, {0x1e07, 0x1e06}}, - {{0x1e08, 0x1e09}, {0x1e09, 0x1e08}}, - {{0x1e0a, 0x1e0b}, {0x1e0b, 0x1e0a}}, - {{0x1e0c, 0x1e0d}, {0x1e0d, 0x1e0c}}, - {{0x1e0e, 0x1e0f}, {0x1e0f, 0x1e0e}}, - {{0x1e10, 0x1e11}, {0x1e11, 0x1e10}}, - {{0x1e12, 0x1e13}, {0x1e13, 0x1e12}}, - {{0x1e14, 0x1e15}, {0x1e15, 0x1e14}}, - {{0x1e16, 0x1e17}, {0x1e17, 0x1e16}}, - {{0x1e18, 0x1e19}, {0x1e19, 0x1e18}}, - {{0x1e1a, 0x1e1b}, {0x1e1b, 0x1e1a}}, - {{0x1e1c, 0x1e1d}, {0x1e1d, 0x1e1c}}, - {{0x1e1e, 0x1e1f}, {0x1e1f, 0x1e1e}}, - {{0x1e20, 0x1e21}, {0x1e21, 0x1e20}}, - {{0x1e22, 0x1e23}, {0x1e23, 0x1e22}}, - {{0x1e24, 0x1e25}, {0x1e25, 0x1e24}}, - {{0x1e26, 0x1e27}, {0x1e27, 0x1e26}}, - {{0x1e28, 0x1e29}, {0x1e29, 0x1e28}}, - {{0x1e2a, 0x1e2b}, {0x1e2b, 0x1e2a}}, - {{0x1e2c, 0x1e2d}, {0x1e2d, 0x1e2c}}, - {{0x1e2e, 0x1e2f}, {0x1e2f, 0x1e2e}}, - {{0x1e30, 0x1e31}, {0x1e31, 0x1e30}}, - {{0x1e32, 0x1e33}, {0x1e33, 0x1e32}}, - {{0x1e34, 0x1e35}, {0x1e35, 0x1e34}}, - {{0x1e36, 0x1e37}, {0x1e37, 0x1e36}}, - {{0x1e38, 0x1e39}, {0x1e39, 0x1e38}}, - {{0x1e3a, 0x1e3b}, {0x1e3b, 0x1e3a}}, - {{0x1e3c, 0x1e3d}, {0x1e3d, 0x1e3c}}, - {{0x1e3e, 0x1e3f}, {0x1e3f, 0x1e3e}}, - {{0x1e40, 0x1e41}, {0x1e41, 0x1e40}}, - {{0x1e42, 0x1e43}, {0x1e43, 0x1e42}}, - {{0x1e44, 0x1e45}, {0x1e45, 0x1e44}}, - {{0x1e46, 0x1e47}, {0x1e47, 0x1e46}}, - {{0x1e48, 0x1e49}, {0x1e49, 0x1e48}}, - {{0x1e4a, 0x1e4b}, {0x1e4b, 0x1e4a}}, - {{0x1e4c, 0x1e4d}, {0x1e4d, 0x1e4c}}, - {{0x1e4e, 0x1e4f}, {0x1e4f, 0x1e4e}}, - {{0x1e50, 0x1e51}, {0x1e51, 0x1e50}}, - {{0x1e52, 0x1e53}, {0x1e53, 0x1e52}}, - {{0x1e54, 0x1e55}, {0x1e55, 0x1e54}}, - {{0x1e56, 0x1e57}, {0x1e57, 0x1e56}}, - {{0x1e58, 0x1e59}, {0x1e59, 0x1e58}}, - {{0x1e5a, 0x1e5b}, {0x1e5b, 0x1e5a}}, - {{0x1e5c, 0x1e5d}, {0x1e5d, 0x1e5c}}, - {{0x1e5e, 0x1e5f}, {0x1e5f, 0x1e5e}}, - {{0x1e60, 0x1e61}, {0x1e61, 0x1e60}}, - {{0x1e62, 0x1e63}, {0x1e63, 0x1e62}}, - {{0x1e64, 0x1e65}, {0x1e65, 0x1e64}}, - {{0x1e66, 0x1e67}, {0x1e67, 0x1e66}}, - {{0x1e68, 0x1e69}, {0x1e69, 0x1e68}}, - {{0x1e6a, 0x1e6b}, {0x1e6b, 0x1e6a}}, - {{0x1e6c, 0x1e6d}, {0x1e6d, 0x1e6c}}, - {{0x1e6e, 0x1e6f}, {0x1e6f, 0x1e6e}}, - {{0x1e70, 0x1e71}, {0x1e71, 0x1e70}}, - {{0x1e72, 0x1e73}, {0x1e73, 0x1e72}}, - {{0x1e74, 0x1e75}, {0x1e75, 0x1e74}}, - {{0x1e76, 0x1e77}, {0x1e77, 0x1e76}}, - {{0x1e78, 0x1e79}, {0x1e79, 0x1e78}}, - {{0x1e7a, 0x1e7b}, {0x1e7b, 0x1e7a}}, - {{0x1e7c, 0x1e7d}, {0x1e7d, 0x1e7c}}, - {{0x1e7e, 0x1e7f}, {0x1e7f, 0x1e7e}}, - {{0x1e80, 0x1e81}, {0x1e81, 0x1e80}}, - {{0x1e82, 0x1e83}, {0x1e83, 0x1e82}}, - {{0x1e84, 0x1e85}, {0x1e85, 0x1e84}}, - {{0x1e86, 0x1e87}, {0x1e87, 0x1e86}}, - {{0x1e88, 0x1e89}, {0x1e89, 0x1e88}}, - {{0x1e8a, 0x1e8b}, {0x1e8b, 0x1e8a}}, - {{0x1e8c, 0x1e8d}, {0x1e8d, 0x1e8c}}, - {{0x1e8e, 0x1e8f}, {0x1e8f, 0x1e8e}}, - {{0x1e90, 0x1e91}, {0x1e91, 0x1e90}}, - {{0x1e92, 0x1e93}, {0x1e93, 0x1e92}}, - {{0x1e94, 0x1e95}, {0x1e95, 0x1e94}}, - {{0x1e9b, 0x1e9b}, {0x1e60, 0x1e60}}, - {{0x1e9e, 0x1e9e}, {0x00df, 0x00df}}, - {{0x1ea0, 0x1ea1}, {0x1ea1, 0x1ea0}}, - {{0x1ea2, 0x1ea3}, {0x1ea3, 0x1ea2}}, - {{0x1ea4, 0x1ea5}, {0x1ea5, 0x1ea4}}, - {{0x1ea6, 0x1ea7}, {0x1ea7, 0x1ea6}}, - {{0x1ea8, 0x1ea9}, {0x1ea9, 0x1ea8}}, - {{0x1eaa, 0x1eab}, {0x1eab, 0x1eaa}}, - {{0x1eac, 0x1ead}, {0x1ead, 0x1eac}}, - {{0x1eae, 0x1eaf}, {0x1eaf, 0x1eae}}, - {{0x1eb0, 0x1eb1}, {0x1eb1, 0x1eb0}}, - {{0x1eb2, 0x1eb3}, {0x1eb3, 0x1eb2}}, - {{0x1eb4, 0x1eb5}, {0x1eb5, 0x1eb4}}, - {{0x1eb6, 0x1eb7}, {0x1eb7, 0x1eb6}}, - {{0x1eb8, 0x1eb9}, {0x1eb9, 0x1eb8}}, - {{0x1eba, 0x1ebb}, {0x1ebb, 0x1eba}}, - {{0x1ebc, 0x1ebd}, {0x1ebd, 0x1ebc}}, - {{0x1ebe, 0x1ebf}, {0x1ebf, 0x1ebe}}, - {{0x1ec0, 0x1ec1}, {0x1ec1, 0x1ec0}}, - {{0x1ec2, 0x1ec3}, {0x1ec3, 0x1ec2}}, - {{0x1ec4, 0x1ec5}, {0x1ec5, 0x1ec4}}, - {{0x1ec6, 0x1ec7}, {0x1ec7, 0x1ec6}}, - {{0x1ec8, 0x1ec9}, {0x1ec9, 0x1ec8}}, - {{0x1eca, 0x1ecb}, {0x1ecb, 0x1eca}}, - {{0x1ecc, 0x1ecd}, {0x1ecd, 0x1ecc}}, - {{0x1ece, 0x1ecf}, {0x1ecf, 0x1ece}}, - {{0x1ed0, 0x1ed1}, {0x1ed1, 0x1ed0}}, - {{0x1ed2, 0x1ed3}, {0x1ed3, 0x1ed2}}, - {{0x1ed4, 0x1ed5}, {0x1ed5, 0x1ed4}}, - {{0x1ed6, 0x1ed7}, {0x1ed7, 0x1ed6}}, - {{0x1ed8, 0x1ed9}, {0x1ed9, 0x1ed8}}, - {{0x1eda, 0x1edb}, {0x1edb, 0x1eda}}, - {{0x1edc, 0x1edd}, {0x1edd, 0x1edc}}, - {{0x1ede, 0x1edf}, {0x1edf, 0x1ede}}, - {{0x1ee0, 0x1ee1}, {0x1ee1, 0x1ee0}}, - {{0x1ee2, 0x1ee3}, {0x1ee3, 0x1ee2}}, - {{0x1ee4, 0x1ee5}, {0x1ee5, 0x1ee4}}, - {{0x1ee6, 0x1ee7}, {0x1ee7, 0x1ee6}}, - {{0x1ee8, 0x1ee9}, {0x1ee9, 0x1ee8}}, - {{0x1eea, 0x1eeb}, {0x1eeb, 0x1eea}}, - {{0x1eec, 0x1eed}, {0x1eed, 0x1eec}}, - {{0x1eee, 0x1eef}, {0x1eef, 0x1eee}}, - {{0x1ef0, 0x1ef1}, {0x1ef1, 0x1ef0}}, - {{0x1ef2, 0x1ef3}, {0x1ef3, 0x1ef2}}, - {{0x1ef4, 0x1ef5}, {0x1ef5, 0x1ef4}}, - {{0x1ef6, 0x1ef7}, {0x1ef7, 0x1ef6}}, - {{0x1ef8, 0x1ef9}, {0x1ef9, 0x1ef8}}, - {{0x1efa, 0x1efb}, {0x1efb, 0x1efa}}, - {{0x1efc, 0x1efd}, {0x1efd, 0x1efc}}, - {{0x1efe, 0x1eff}, {0x1eff, 0x1efe}}, - {{0x1f00, 0x1f07}, {0x1f08, 0x1f0f}}, - {{0x1f08, 0x1f0f}, {0x1f00, 0x1f07}}, - {{0x1f10, 0x1f15}, {0x1f18, 0x1f1d}}, - {{0x1f18, 0x1f1d}, {0x1f10, 0x1f15}}, - {{0x1f20, 0x1f27}, {0x1f28, 0x1f2f}}, - {{0x1f28, 0x1f2f}, {0x1f20, 0x1f27}}, - {{0x1f30, 0x1f37}, {0x1f38, 0x1f3f}}, - {{0x1f38, 0x1f3f}, {0x1f30, 0x1f37}}, - {{0x1f40, 0x1f45}, {0x1f48, 0x1f4d}}, - {{0x1f48, 0x1f4d}, {0x1f40, 0x1f45}}, - {{0x1f51, 0x1f51}, {0x1f59, 0x1f59}}, - {{0x1f53, 0x1f53}, {0x1f5b, 0x1f5b}}, - {{0x1f55, 0x1f55}, {0x1f5d, 0x1f5d}}, - {{0x1f57, 0x1f57}, {0x1f5f, 0x1f5f}}, - {{0x1f59, 0x1f59}, {0x1f51, 0x1f51}}, - {{0x1f5b, 0x1f5b}, {0x1f53, 0x1f53}}, - {{0x1f5d, 0x1f5d}, {0x1f55, 0x1f55}}, - {{0x1f5f, 0x1f5f}, {0x1f57, 0x1f57}}, - {{0x1f60, 0x1f67}, {0x1f68, 0x1f6f}}, - {{0x1f68, 0x1f6f}, {0x1f60, 0x1f67}}, - {{0x1f70, 0x1f71}, {0x1fba, 0x1fbb}}, - {{0x1f72, 0x1f75}, {0x1fc8, 0x1fcb}}, - {{0x1f76, 0x1f77}, {0x1fda, 0x1fdb}}, - {{0x1f78, 0x1f79}, {0x1ff8, 0x1ff9}}, - {{0x1f7a, 0x1f7b}, {0x1fea, 0x1feb}}, - {{0x1f7c, 0x1f7d}, {0x1ffa, 0x1ffb}}, - {{0x1f80, 0x1f87}, {0x1f88, 0x1f8f}}, - {{0x1f90, 0x1f97}, {0x1f98, 0x1f9f}}, - {{0x1fa0, 0x1fa7}, {0x1fa8, 0x1faf}}, - {{0x1fb0, 0x1fb1}, {0x1fb8, 0x1fb9}}, - {{0x1fb3, 0x1fb3}, {0x1fbc, 0x1fbc}}, - {{0x1fb8, 0x1fb9}, {0x1fb0, 0x1fb1}}, - {{0x1fba, 0x1fbb}, {0x1f70, 0x1f71}}, - {{0x1fbe, 0x1fbe}, {0x0399, 0x0399}}, - {{0x1fc3, 0x1fc3}, {0x1fcc, 0x1fcc}}, - {{0x1fc8, 0x1fcb}, {0x1f72, 0x1f75}}, - {{0x1fd0, 0x1fd1}, {0x1fd8, 0x1fd9}}, - {{0x1fd8, 0x1fd9}, {0x1fd0, 0x1fd1}}, - {{0x1fda, 0x1fdb}, {0x1f76, 0x1f77}}, - {{0x1fe0, 0x1fe1}, {0x1fe8, 0x1fe9}}, - {{0x1fe5, 0x1fe5}, {0x1fec, 0x1fec}}, - {{0x1fe8, 0x1fe9}, {0x1fe0, 0x1fe1}}, - {{0x1fea, 0x1feb}, {0x1f7a, 0x1f7b}}, - {{0x1fec, 0x1fec}, {0x1fe5, 0x1fe5}}, - {{0x1ff3, 0x1ff3}, {0x1ffc, 0x1ffc}}, - {{0x1ff8, 0x1ff9}, {0x1f78, 0x1f79}}, - {{0x1ffa, 0x1ffb}, {0x1f7c, 0x1f7d}}, - {{0x2126, 0x2126}, {0x03c9, 0x03c9}}, - {{0x212a, 0x212a}, {0x006b, 0x006b}}, - {{0x212b, 0x212b}, {0x00e5, 0x00e5}}, - {{0x2132, 0x2132}, {0x214e, 0x214e}}, - {{0x214e, 0x214e}, {0x2132, 0x2132}}, - {{0x2183, 0x2184}, {0x2184, 0x2183}}, - {{0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}}, - {{0x2c30, 0x2c5e}, {0x2c00, 0x2c2e}}, - {{0x2c60, 0x2c61}, {0x2c61, 0x2c60}}, - {{0x2c62, 0x2c62}, {0x026b, 0x026b}}, - {{0x2c63, 0x2c63}, {0x1d7d, 0x1d7d}}, - {{0x2c64, 0x2c64}, {0x027d, 0x027d}}, - {{0x2c65, 0x2c65}, {0x023a, 0x023a}}, - {{0x2c66, 0x2c66}, {0x023e, 0x023e}}, - {{0x2c67, 0x2c68}, {0x2c68, 0x2c67}}, - {{0x2c69, 0x2c6a}, {0x2c6a, 0x2c69}}, - {{0x2c6b, 0x2c6c}, {0x2c6c, 0x2c6b}}, - {{0x2c6d, 0x2c6d}, {0x0251, 0x0251}}, - {{0x2c6e, 0x2c6e}, {0x0271, 0x0271}}, - {{0x2c6f, 0x2c6f}, {0x0250, 0x0250}}, - {{0x2c70, 0x2c70}, {0x0252, 0x0252}}, - {{0x2c72, 0x2c73}, {0x2c73, 0x2c72}}, - {{0x2c75, 0x2c76}, {0x2c76, 0x2c75}}, - {{0x2c7e, 0x2c7f}, {0x023f, 0x0240}}, - {{0x2c80, 0x2c81}, {0x2c81, 0x2c80}}, - {{0x2c82, 0x2c83}, {0x2c83, 0x2c82}}, - {{0x2c84, 0x2c85}, {0x2c85, 0x2c84}}, - {{0x2c86, 0x2c87}, {0x2c87, 0x2c86}}, - {{0x2c88, 0x2c89}, {0x2c89, 0x2c88}}, - {{0x2c8a, 0x2c8b}, {0x2c8b, 0x2c8a}}, - {{0x2c8c, 0x2c8d}, {0x2c8d, 0x2c8c}}, - {{0x2c8e, 0x2c8f}, {0x2c8f, 0x2c8e}}, - {{0x2c90, 0x2c91}, {0x2c91, 0x2c90}}, - {{0x2c92, 0x2c93}, {0x2c93, 0x2c92}}, - {{0x2c94, 0x2c95}, {0x2c95, 0x2c94}}, - {{0x2c96, 0x2c97}, {0x2c97, 0x2c96}}, - {{0x2c98, 0x2c99}, {0x2c99, 0x2c98}}, - {{0x2c9a, 0x2c9b}, {0x2c9b, 0x2c9a}}, - {{0x2c9c, 0x2c9d}, {0x2c9d, 0x2c9c}}, - {{0x2c9e, 0x2c9f}, {0x2c9f, 0x2c9e}}, - {{0x2ca0, 0x2ca1}, {0x2ca1, 0x2ca0}}, - {{0x2ca2, 0x2ca3}, {0x2ca3, 0x2ca2}}, - {{0x2ca4, 0x2ca5}, {0x2ca5, 0x2ca4}}, - {{0x2ca6, 0x2ca7}, {0x2ca7, 0x2ca6}}, - {{0x2ca8, 0x2ca9}, {0x2ca9, 0x2ca8}}, - {{0x2caa, 0x2cab}, {0x2cab, 0x2caa}}, - {{0x2cac, 0x2cad}, {0x2cad, 0x2cac}}, - {{0x2cae, 0x2caf}, {0x2caf, 0x2cae}}, - {{0x2cb0, 0x2cb1}, {0x2cb1, 0x2cb0}}, - {{0x2cb2, 0x2cb3}, {0x2cb3, 0x2cb2}}, - {{0x2cb4, 0x2cb5}, {0x2cb5, 0x2cb4}}, - {{0x2cb6, 0x2cb7}, {0x2cb7, 0x2cb6}}, - {{0x2cb8, 0x2cb9}, {0x2cb9, 0x2cb8}}, - {{0x2cba, 0x2cbb}, {0x2cbb, 0x2cba}}, - {{0x2cbc, 0x2cbd}, {0x2cbd, 0x2cbc}}, - {{0x2cbe, 0x2cbf}, {0x2cbf, 0x2cbe}}, - {{0x2cc0, 0x2cc1}, {0x2cc1, 0x2cc0}}, - {{0x2cc2, 0x2cc3}, {0x2cc3, 0x2cc2}}, - {{0x2cc4, 0x2cc5}, {0x2cc5, 0x2cc4}}, - {{0x2cc6, 0x2cc7}, {0x2cc7, 0x2cc6}}, - {{0x2cc8, 0x2cc9}, {0x2cc9, 0x2cc8}}, - {{0x2cca, 0x2ccb}, {0x2ccb, 0x2cca}}, - {{0x2ccc, 0x2ccd}, {0x2ccd, 0x2ccc}}, - {{0x2cce, 0x2ccf}, {0x2ccf, 0x2cce}}, - {{0x2cd0, 0x2cd1}, {0x2cd1, 0x2cd0}}, - {{0x2cd2, 0x2cd3}, {0x2cd3, 0x2cd2}}, - {{0x2cd4, 0x2cd5}, {0x2cd5, 0x2cd4}}, - {{0x2cd6, 0x2cd7}, {0x2cd7, 0x2cd6}}, - {{0x2cd8, 0x2cd9}, {0x2cd9, 0x2cd8}}, - {{0x2cda, 0x2cdb}, {0x2cdb, 0x2cda}}, - {{0x2cdc, 0x2cdd}, {0x2cdd, 0x2cdc}}, - {{0x2cde, 0x2cdf}, {0x2cdf, 0x2cde}}, - {{0x2ce0, 0x2ce1}, {0x2ce1, 0x2ce0}}, - {{0x2ce2, 0x2ce3}, {0x2ce3, 0x2ce2}}, - {{0x2ceb, 0x2cec}, {0x2cec, 0x2ceb}}, - {{0x2ced, 0x2cee}, {0x2cee, 0x2ced}}, - {{0x2cf2, 0x2cf3}, {0x2cf3, 0x2cf2}}, - {{0x2d00, 0x2d25}, {0x10a0, 0x10c5}}, - {{0x2d27, 0x2d27}, {0x10c7, 0x10c7}}, - {{0x2d2d, 0x2d2d}, {0x10cd, 0x10cd}}, - {{0xa640, 0xa641}, {0xa641, 0xa640}}, - {{0xa642, 0xa643}, {0xa643, 0xa642}}, - {{0xa644, 0xa645}, {0xa645, 0xa644}}, - {{0xa646, 0xa647}, {0xa647, 0xa646}}, - {{0xa648, 0xa649}, {0xa649, 0xa648}}, - {{0xa64a, 0xa64b}, {0xa64b, 0xa64a}}, - {{0xa64c, 0xa64d}, {0xa64d, 0xa64c}}, - {{0xa64e, 0xa64f}, {0xa64f, 0xa64e}}, - {{0xa650, 0xa651}, {0xa651, 0xa650}}, - {{0xa652, 0xa653}, {0xa653, 0xa652}}, - {{0xa654, 0xa655}, {0xa655, 0xa654}}, - {{0xa656, 0xa657}, {0xa657, 0xa656}}, - {{0xa658, 0xa659}, {0xa659, 0xa658}}, - {{0xa65a, 0xa65b}, {0xa65b, 0xa65a}}, - {{0xa65c, 0xa65d}, {0xa65d, 0xa65c}}, - {{0xa65e, 0xa65f}, {0xa65f, 0xa65e}}, - {{0xa660, 0xa661}, {0xa661, 0xa660}}, - {{0xa662, 0xa663}, {0xa663, 0xa662}}, - {{0xa664, 0xa665}, {0xa665, 0xa664}}, - {{0xa666, 0xa667}, {0xa667, 0xa666}}, - {{0xa668, 0xa669}, {0xa669, 0xa668}}, - {{0xa66a, 0xa66b}, {0xa66b, 0xa66a}}, - {{0xa66c, 0xa66d}, {0xa66d, 0xa66c}}, - {{0xa680, 0xa681}, {0xa681, 0xa680}}, - {{0xa682, 0xa683}, {0xa683, 0xa682}}, - {{0xa684, 0xa685}, {0xa685, 0xa684}}, - {{0xa686, 0xa687}, {0xa687, 0xa686}}, - {{0xa688, 0xa689}, {0xa689, 0xa688}}, - {{0xa68a, 0xa68b}, {0xa68b, 0xa68a}}, - {{0xa68c, 0xa68d}, {0xa68d, 0xa68c}}, - {{0xa68e, 0xa68f}, {0xa68f, 0xa68e}}, - {{0xa690, 0xa691}, {0xa691, 0xa690}}, - {{0xa692, 0xa693}, {0xa693, 0xa692}}, - {{0xa694, 0xa695}, {0xa695, 0xa694}}, - {{0xa696, 0xa697}, {0xa697, 0xa696}}, - {{0xa698, 0xa699}, {0xa699, 0xa698}}, - {{0xa69a, 0xa69b}, {0xa69b, 0xa69a}}, - {{0xa722, 0xa723}, {0xa723, 0xa722}}, - {{0xa724, 0xa725}, {0xa725, 0xa724}}, - {{0xa726, 0xa727}, {0xa727, 0xa726}}, - {{0xa728, 0xa729}, {0xa729, 0xa728}}, - {{0xa72a, 0xa72b}, {0xa72b, 0xa72a}}, - {{0xa72c, 0xa72d}, {0xa72d, 0xa72c}}, - {{0xa72e, 0xa72f}, {0xa72f, 0xa72e}}, - {{0xa732, 0xa733}, {0xa733, 0xa732}}, - {{0xa734, 0xa735}, {0xa735, 0xa734}}, - {{0xa736, 0xa737}, {0xa737, 0xa736}}, - {{0xa738, 0xa739}, {0xa739, 0xa738}}, - {{0xa73a, 0xa73b}, {0xa73b, 0xa73a}}, - {{0xa73c, 0xa73d}, {0xa73d, 0xa73c}}, - {{0xa73e, 0xa73f}, {0xa73f, 0xa73e}}, - {{0xa740, 0xa741}, {0xa741, 0xa740}}, - {{0xa742, 0xa743}, {0xa743, 0xa742}}, - {{0xa744, 0xa745}, {0xa745, 0xa744}}, - {{0xa746, 0xa747}, {0xa747, 0xa746}}, - {{0xa748, 0xa749}, {0xa749, 0xa748}}, - {{0xa74a, 0xa74b}, {0xa74b, 0xa74a}}, - {{0xa74c, 0xa74d}, {0xa74d, 0xa74c}}, - {{0xa74e, 0xa74f}, {0xa74f, 0xa74e}}, - {{0xa750, 0xa751}, {0xa751, 0xa750}}, - {{0xa752, 0xa753}, {0xa753, 0xa752}}, - {{0xa754, 0xa755}, {0xa755, 0xa754}}, - {{0xa756, 0xa757}, {0xa757, 0xa756}}, - {{0xa758, 0xa759}, {0xa759, 0xa758}}, - {{0xa75a, 0xa75b}, {0xa75b, 0xa75a}}, - {{0xa75c, 0xa75d}, {0xa75d, 0xa75c}}, - {{0xa75e, 0xa75f}, {0xa75f, 0xa75e}}, - {{0xa760, 0xa761}, {0xa761, 0xa760}}, - {{0xa762, 0xa763}, {0xa763, 0xa762}}, - {{0xa764, 0xa765}, {0xa765, 0xa764}}, - {{0xa766, 0xa767}, {0xa767, 0xa766}}, - {{0xa768, 0xa769}, {0xa769, 0xa768}}, - {{0xa76a, 0xa76b}, {0xa76b, 0xa76a}}, - {{0xa76c, 0xa76d}, {0xa76d, 0xa76c}}, - {{0xa76e, 0xa76f}, {0xa76f, 0xa76e}}, - {{0xa779, 0xa77a}, {0xa77a, 0xa779}}, - {{0xa77b, 0xa77c}, {0xa77c, 0xa77b}}, - {{0xa77d, 0xa77d}, {0x1d79, 0x1d79}}, - {{0xa77e, 0xa77f}, {0xa77f, 0xa77e}}, - {{0xa780, 0xa781}, {0xa781, 0xa780}}, - {{0xa782, 0xa783}, {0xa783, 0xa782}}, - {{0xa784, 0xa785}, {0xa785, 0xa784}}, - {{0xa786, 0xa787}, {0xa787, 0xa786}}, - {{0xa78b, 0xa78c}, {0xa78c, 0xa78b}}, - {{0xa78d, 0xa78d}, {0x0265, 0x0265}}, - {{0xa790, 0xa791}, {0xa791, 0xa790}}, - {{0xa792, 0xa793}, {0xa793, 0xa792}}, - {{0xa796, 0xa797}, {0xa797, 0xa796}}, - {{0xa798, 0xa799}, {0xa799, 0xa798}}, - {{0xa79a, 0xa79b}, {0xa79b, 0xa79a}}, - {{0xa79c, 0xa79d}, {0xa79d, 0xa79c}}, - {{0xa79e, 0xa79f}, {0xa79f, 0xa79e}}, - {{0xa7a0, 0xa7a1}, {0xa7a1, 0xa7a0}}, - {{0xa7a2, 0xa7a3}, {0xa7a3, 0xa7a2}}, - {{0xa7a4, 0xa7a5}, {0xa7a5, 0xa7a4}}, - {{0xa7a6, 0xa7a7}, {0xa7a7, 0xa7a6}}, - {{0xa7a8, 0xa7a9}, {0xa7a9, 0xa7a8}}, - {{0xa7aa, 0xa7aa}, {0x0266, 0x0266}}, - {{0xa7ab, 0xa7ab}, {0x025c, 0x025c}}, - {{0xa7ac, 0xa7ac}, {0x0261, 0x0261}}, - {{0xa7ad, 0xa7ad}, {0x026c, 0x026c}}, - {{0xa7b0, 0xa7b0}, {0x029e, 0x029e}}, - {{0xa7b1, 0xa7b1}, {0x0287, 0x0287}}, - {{0xa7b2, 0xa7b2}, {0x029d, 0x029d}}, - {{0xa7b3, 0xa7b3}, {0xab53, 0xab53}}, - {{0xa7b4, 0xa7b5}, {0xa7b5, 0xa7b4}}, - {{0xa7b6, 0xa7b7}, {0xa7b7, 0xa7b6}}, - {{0xab53, 0xab53}, {0xa7b3, 0xa7b3}}, - {{0xab70, 0xabbf}, {0x13a0, 0x13ef}}, - {{0xff21, 0xff3a}, {0xff41, 0xff5a}}, - {{0xff41, 0xff5a}, {0xff21, 0xff3a}}, - {{0, 0}, {0, 0}}}; - const fold_pair *ptr_ = mapping_; - - for (; ptr_->from.first != 0; ++ptr_) - { - if (range_.second < ptr_->from.first) break; - - if (range_.first >= ptr_->from.first && - range_.first <= ptr_->from.second) - { - if (ptr_->to.first <= ptr_->to.second) - { - const index_type first_ = ptr_->to.first + - (range_.first - ptr_->from.first); - - out_.insert(range(first_, - range_.second > ptr_->from.second ? - ptr_->to.second : - static_cast(ptr_->to.first + - (range_.second - ptr_->from.first)))); - } - else - { - const index_type first_ = ptr_->to.second + - (range_.first - ptr_->from.first); - - out_.insert(range(first_, - range_.second > ptr_->from.second ? - ptr_->to.first : - static_cast(ptr_->to.second + - (range_.second - ptr_->from.first)))); - } - } - else if (range_.second >= ptr_->from.first && - range_.second <= ptr_->from.second) - { - if (ptr_->to.first <= ptr_->to.second) - { - const index_type second_ = ptr_->to.first + - (range_.second - ptr_->from.first); - - out_.insert(range(ptr_->to.first, second_)); - } - else - { - const index_type second_ = ptr_->to.second + - (range_.second - ptr_->from.first); - - out_.insert(range(ptr_->to.second, second_)); - } - } - // Either range fully encompasses from range or not at all. - else if (ptr_->from.first >= range_.first && - ptr_->from.first <= range_.second) - { - if (ptr_->to.first <= ptr_->to.second) - { - out_.insert(range(ptr_->to.first, ptr_->to.second)); - } - else - { - out_.insert(range(ptr_->to.second, ptr_->to.first)); - } - } - } - } - - static void fold(const range &range_, const std::locale &locale_, - string_token &out_, const four &) - { - if (range_.first < 0x10000) - { - fold(range_, locale_, out_, two()); - } - - static const fold_pair mapping_[] = - {{{0x10400, 0x10427}, {0x10428, 0x1044f}}, - {{0x10428, 0x1044f}, {0x10400, 0x10427}}, - {{0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}}, - {{0x10cc0, 0x10cf2}, {0x10c80, 0x10cb2}}, - {{0x118a0, 0x118bf}, {0x118c0, 0x118df}}, - {{0x118c0, 0x118df}, {0x118a0, 0x118bf}}, - {{0, 0}, {0, 0}}}; - const fold_pair *ptr_ = mapping_; - - for (; ptr_->from.first != 0; ++ptr_) - { - if (range_.second < ptr_->from.first) break; - - if (range_.first >= ptr_->from.first && - range_.first <= ptr_->from.second) - { - out_.insert(range(ptr_->to.first + - (range_.first - ptr_->from.first), - range_.second > ptr_->from.second ? - ptr_->to.second : - ptr_->to.first + (range_.second - ptr_->from.first))); - } - else if (range_.second >= ptr_->from.first && - range_.second <= ptr_->from.second) - { - out_.insert(range(ptr_->to.first, - ptr_->to.first + (range_.second - ptr_->from.first))); - } - // Either range fully encompasses from range or not at all. - else if (ptr_->from.first >= range_.first && - ptr_->from.first <= range_.second) - { - out_.insert(range(ptr_->to.first, ptr_->to.second)); - } - } - } - - template - static input_char_type chr(state_type &state_) - { - input_char_type ch_ = 0; - - // eos_ has already been checked for. - switch (*state_._curr) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - ch_ = decode_octal(state_); - break; - case 'a': - ch_ = '\a'; - state_.increment(); - break; - case 'b': - ch_ = '\b'; - state_.increment(); - break; - case 'c': - ch_ = decode_control_char(state_); - break; - case 'e': - ch_ = 27; // '\e' not recognised by compiler - state_.increment(); - break; - case 'f': - ch_ = '\f'; - state_.increment(); - break; - case 'n': - ch_ = '\n'; - state_.increment(); - break; - case 'r': - ch_ = '\r'; - state_.increment(); - break; - case 't': - ch_ = '\t'; - state_.increment(); - break; - case 'v': - ch_ = '\v'; - state_.increment(); - break; - case 'x': - ch_ = decode_hex(state_); - break; - default: - ch_ = *state_._curr; - state_.increment(); - break; - } - - return ch_; - } - -private: - struct char_pair - { - input_char_type first; - input_char_type second; - }; - - struct fold_pair - { - char_pair from; - char_pair to; - }; - - template - static void posix(state_type &state_, string_token &token_) - { - bool negate_ = false; - - if (!state_.eos() && *state_._curr == '^') - { - negate_ = true; - state_.increment(); - } - - if (state_.eos()) - { - unterminated_posix(state_); - } - else - { - switch (*state_._curr) - { - case 'a': - // alnum - // alpha - alnum_alpha(state_, token_, negate_); - break; - case 'b': - // blank - blank(state_, token_, negate_); - break; - case 'c': - // cntrl - cntrl(state_, token_, negate_); - break; - case 'd': - // digit - digit(state_, token_, negate_); - break; - case 'g': - // graph - graph(state_, token_, negate_); - break; - case 'l': - // lower - lower(state_, token_, negate_); - break; - case 'p': - // print - // punct - print_punct(state_, token_, negate_); - break; - case 's': - // space - space(state_, token_, negate_); - break; - case 'u': - // upper - upper(state_, token_, negate_); - break; - case 'x': - // xdigit - xdigit(state_, token_, negate_); - break; - default: - unknown_posix(state_); - break; - } - } - } - - template - static void alnum_alpha(state_type &state_, string_token &token_, - const bool negate_) - { - enum {unknown, alnum, alpha}; - std::size_t type_ = unknown; - - state_.increment(); - - if (!state_.eos() && *state_._curr == 'l') - { - state_.increment(); - - if (!state_.eos()) - { - if (*state_._curr == 'n') - { - state_.increment(); - - if (!state_.eos() && *state_._curr == 'u') - { - state_.increment(); - - if (!state_.eos() && *state_._curr == 'm') - { - state_.increment(); - type_ = alnum; - } - } - } - else if (*state_._curr == 'p') - { - state_.increment(); - - if (!state_.eos() && *state_._curr == 'h') - { - state_.increment(); - - if (!state_.eos() && *state_._curr == 'a') - { - state_.increment(); - type_ = alpha; - } - } - } - } - } - - if (type_ == unknown) - { - unknown_posix(state_); - } - else - { - std::string str_; - - check_posix_termination(state_); - - if (type_ == alnum) - { - // alnum - str_ = sizeof(input_char_type) == 1 ? - make_alnum(state_._locale) : - std::string("[\\p{Ll}\\p{Lu}\\p{Nd}]"); - } - else - { - // alpha - str_ = sizeof(input_char_type) == 1 ? - make_alpha(state_._locale) : - std::string("[\\p{Ll}\\p{Lu}]"); - } - - insert_charset(str_.c_str(), state_, token_, negate_); - } - } - - static std::string make_alnum(std::locale &locale_) - { - std::string str_(1, '['); - - for (std::size_t i_ = 0; i_ < 256; ++i_) - { - if (std::use_facet >(locale_). - is(std::ctype_base::alnum, static_cast(i_))) - { - str_ += static_cast(i_); - } - } - - str_ += ']'; - return str_; - } - - static std::string make_alpha(std::locale &locale_) - { - std::string str_(1, '['); - - for (std::size_t i_ = 0; i_ < 256; ++i_) - { - if (std::use_facet >(locale_). - is(std::ctype_base::alpha, static_cast(i_))) - { - str_ += static_cast(i_); - } - } - - str_ += ']'; - return str_; - } - - template - static void blank(state_type &state_, string_token &token_, - const bool negate_) - { - const char *blank_ = "lank"; - - state_.increment(); - - // Casts to prevent warnings (VC++ 2012) - while (!state_.eos() && *blank_ && - static_cast(*state_._curr) == - static_cast(*blank_)) - { - state_.increment(); - ++blank_; - } - - if (*blank_) - { - unknown_posix(state_); - } - else - { - const char *str_ = sizeof(input_char_type) == 1 ? - "[ \t]" : "[\\p{Zs}\t]"; - - check_posix_termination(state_); - insert_charset(str_, state_, token_, negate_); - } - } - - template - static void cntrl(state_type &state_, string_token &token_, - const bool negate_) - { - const char *cntrl_ = "ntrl"; - - state_.increment(); - - // Casts to prevent warnings (VC++ 2012) - while (!state_.eos() && *cntrl_ && - static_cast(*state_._curr) == - static_cast(*cntrl_)) - { - state_.increment(); - ++cntrl_; - } - - if (*cntrl_) - { - unknown_posix(state_); - } - else - { - const char *str_ = sizeof(input_char_type) == 1 ? - "[\\x00-\x1f\x7f]" : "[\\p{Cc}]"; - - check_posix_termination(state_); - insert_charset(str_, state_, token_, negate_); - } - } - - template - static void digit(state_type &state_, string_token &token_, - const bool negate_) - { - const char *digit_ = "igit"; - - state_.increment(); - - // Casts to prevent warnings (VC++ 2012) - while (!state_.eos() && *digit_ && - static_cast(*state_._curr) == - static_cast(*digit_)) - { - state_.increment(); - ++digit_; - } - - if (*digit_) - { - unknown_posix(state_); - } - else - { - const char *str_ = sizeof(input_char_type) == 1 ? - "[0-9]" : "[\\p{Nd}]"; - - check_posix_termination(state_); - insert_charset(str_, state_, token_, negate_); - } - } - - template - static void graph(state_type &state_, string_token &token_, - const bool negate_) - { - const char *graph_ = "raph"; - - state_.increment(); - - // Casts to prevent warnings (VC++ 2012) - while (!state_.eos() && *graph_ && - static_cast(*state_._curr) == - static_cast(*graph_)) - { - state_.increment(); - ++graph_; - } - - if (*graph_) - { - unknown_posix(state_); - } - else - { - const char *str_ = sizeof(input_char_type) == 1 ? - "[\x21-\x7e]" : "[^\\p{Z}\\p{C}]"; - - check_posix_termination(state_); - insert_charset(str_, state_, token_, negate_); - } - } - - template - static void lower(state_type &state_, string_token &token_, - const bool negate_) - { - const char *lower_ = "ower"; - - state_.increment(); - - // Casts to prevent warnings (VC++ 2012) - while (!state_.eos() && *lower_ && - static_cast(*state_._curr) == - static_cast(*lower_)) - { - state_.increment(); - ++lower_; - } - - if (*lower_) - { - unknown_posix(state_); - } - else - { - std::string str_ = sizeof(input_char_type) == 1 ? - create_lower(state_._locale) : - std::string("[\\p{Ll}]"); - - check_posix_termination(state_); - insert_charset(str_.c_str(), state_, token_, negate_); - } - } - - static std::string create_lower(std::locale &locale_) - { - std::string str_(1, '['); - - for (std::size_t i_ = 0; i_ < 256; ++i_) - { - if (std::use_facet >(locale_). - is(std::ctype_base::lower, static_cast(i_))) - { - str_ += static_cast(i_); - } - } - - str_ += ']'; - return str_; - } - - template - static void print_punct(state_type &state_, string_token &token_, - const bool negate_) - { - enum {unknown, print, punct}; - std::size_t type_ = unknown; - - state_.increment(); - - if (!state_.eos()) - { - if (*state_._curr == 'r') - { - state_.increment(); - - if (!state_.eos() && *state_._curr == 'i') - { - state_.increment(); - - if (!state_.eos() && *state_._curr == 'n') - { - state_.increment(); - - if (!state_.eos() && *state_._curr == 't') - { - state_.increment(); - type_ = print; - } - } - } - } - else if (*state_._curr == 'u') - { - state_.increment(); - - if (!state_.eos() && *state_._curr == 'n') - { - state_.increment(); - - if (!state_.eos() && *state_._curr == 'c') - { - state_.increment(); - - if (!state_.eos() && *state_._curr == 't') - { - state_.increment(); - type_ = punct; - } - } - } - } - } - - if (type_ == unknown) - { - unknown_posix(state_); - } - else - { - const char *str_ = nullptr; - - check_posix_termination(state_); - - if (type_ == print) - { - // print - str_ = sizeof(input_char_type) == 1 ? - "[\x20-\x7e]" : "[\\p{C}]"; - } - else - { - // punct - str_ = sizeof(input_char_type) == 1 ? - "[!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_`{|}~]" : - "[\\p{P}\\p{S}]"; - } - - insert_charset(str_, state_, token_, negate_); - } - } - - template - static void space(state_type &state_, string_token &token_, - const bool negate_) - { - const char *space_ = "pace"; - - state_.increment(); - - // Casts to prevent warnings (VC++ 2012) - while (!state_.eos() && *space_ && - static_cast(*state_._curr) == - static_cast(*space_)) - { - state_.increment(); - ++space_; - } - - if (*space_) - { - unknown_posix(state_); - } - else - { - const char *str_ = sizeof(input_char_type) == 1 ? - "[ \t\r\n\v\f]" : "[\\p{Z}\t\r\n\v\f]"; - - check_posix_termination(state_); - insert_charset(str_, state_, token_, negate_); - } - } - - template - static void upper(state_type &state_, string_token &token_, - const bool negate_) - { - const char *upper_ = "pper"; - - state_.increment(); - - // Casts to prevent warnings (VC++ 2012) - while (!state_.eos() && *upper_ && - static_cast(*state_._curr) == - static_cast(*upper_)) - { - state_.increment(); - ++upper_; - } - - if (*upper_) - { - unknown_posix(state_); - } - else - { - std::string str_ = sizeof(input_char_type) == 1 ? - create_upper(state_._locale) : - std::string("[\\p{Lu}]"); - - check_posix_termination(state_); - insert_charset(str_.c_str(), state_, token_, negate_); - } - } - - static std::string create_upper(std::locale &locale_) - { - std::string str_(1, '['); - - for (std::size_t i_ = 0; i_ < 256; ++i_) - { - if (std::use_facet >(locale_). - is(std::ctype_base::upper, static_cast(i_))) - { - str_ += static_cast(i_); - } - } - - str_ += ']'; - return str_; - } - - template - static void xdigit(state_type &state_, string_token &token_, - const bool negate_) - { - const char *xdigit_ = "digit"; - - state_.increment(); - - // Casts to prevent warnings (VC++ 2012) - while (!state_.eos() && *xdigit_ && - static_cast(*state_._curr) == - static_cast(*xdigit_)) - { - state_.increment(); - ++xdigit_; - } - - if (*xdigit_) - { - unknown_posix(state_); - } - else - { - const char *str_ = "[0-9A-Fa-f]"; - - check_posix_termination(state_); - insert_charset(str_, state_, token_, negate_); - } - } - - template - static void check_posix_termination(state_type &state_) - { - if (state_.eos()) - { - unterminated_posix(state_); - } - - if (*state_._curr != ':') - { - std::ostringstream ss_; - - ss_ << "Missing ':' at index " << state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - state_.increment(); - - if (state_.eos()) - { - unterminated_posix(state_); - } - - if (*state_._curr != ']') - { - std::ostringstream ss_; - - ss_ << "Missing ']' at index " << state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - state_.increment(); - } - - template - static void unterminated_posix(state_type &state_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (unterminated POSIX charset)"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - template - static void unknown_posix(state_type &state_) - { - std::ostringstream ss_; - - ss_ << "Unknown POSIX charset at index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - template - static void insert_charset(const char *str_, state_type &state_, - string_token &token_, const bool negate_) - { - // Some systems have strlen in namespace std. - using namespace std; - - char_state temp_state_(str_ + 1, str_ + strlen(str_), - state_._id, state_._flags, state_._locale, 0); - string_token temp_token_; - - charset(temp_state_, temp_token_); - - if (negate_) temp_token_.negate(); - - token_.insert(temp_token_); - } - - template - static const char *charset_shortcut - (state_type &state_, std::size_t &str_len_) - { - const char *str_ = nullptr; - - switch (*state_._curr) - { - case 'd': - str_ = "[0-9]"; - break; - case 'D': - str_ = "[^0-9]"; - break; - case 'p': - str_ = unicode_escape(state_); - break; - case 's': - str_ = "[ \t\n\r\f\v]"; - break; - case 'S': - str_ = "[^ \t\n\r\f\v]"; - break; - case 'w': - str_ = "[_0-9A-Za-z]"; - break; - case 'W': - str_ = "[^_0-9A-Za-z]"; - break; - } - - if (str_) - { - // Some systems have strlen in namespace std. - using namespace std; - - str_len_ = strlen(str_); - } - else - { - str_len_ = 0; - } - - return str_; - } - - template - static const char *unicode_escape(state_type &state_) - { - const char *str_ = nullptr; - - state_.increment(); - - if (state_.eos()) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following \\p"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - if (*state_._curr != '{') - { - std::ostringstream ss_; - - ss_ << "Missing '{' following \\p at index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - state_.increment(); - - if (state_.eos()) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following \\p{"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - switch (*state_._curr) - { - case 'C': - state_.increment(); - - if (state_.eos()) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following \\p{C"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - switch (*state_._curr) - { - case '}': - str_ = "[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cs}]"; - break; - case 'c': - str_ = other_control(); - state_.increment(); - break; - case 'f': - str_ = other_format(); - state_.increment(); - break; -// case 'n': -// break; - case 'o': - str_ = other_private(); - state_.increment(); - break; - case 's': - str_ = other_surrogate(); - state_.increment(); - break; - default: - { - std::ostringstream ss_; - - ss_ << "Syntax error following \\p{C at index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - - break; - case 'L': - state_.increment(); - - if (state_.eos()) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following \\p{L"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - switch (*state_._curr) - { - case '}': - str_ = "[\\p{Ll}\\p{Lm}\\p{Lo}\\p{Lt}\\p{Lu}]"; - break; - case 'C': - str_ = "[\\p{Ll}\\p{Lt}\\p{Lu}]"; - state_.increment(); - break; - case 'l': - str_ = letter_lowercase(); - state_.increment(); - break; - case 'm': - str_ = letter_modifier(); - state_.increment(); - break; - case 'o': - str_ = letter_other(); - state_.increment(); - break; - case 't': - str_ = letter_titlecase(); - state_.increment(); - break; - case 'u': - str_ = letter_uppercase(); - state_.increment(); - break; - default: - { - std::ostringstream ss_; - - ss_ << "Syntax error following \\p{L at index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - - break; - case 'M': - state_.increment(); - - if (state_.eos()) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following \\p{M"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - switch (*state_._curr) - { - case '}': - str_ = "[\\p{Mc}\\p{Me}\\p{Mn}]"; - break; - case 'c': - str_ = mark_combining(); - state_.increment(); - break; - case 'e': - str_ = mark_enclosing(); - state_.increment(); - break; - case 'n': - str_ = mark_nonspacing(); - state_.increment(); - break; - default: - { - std::ostringstream ss_; - - ss_ << "Syntax error following \\p{M at index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - - break; - case 'N': - state_.increment(); - - if (state_.eos()) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following \\p{N"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - switch (*state_._curr) - { - case '}': - str_ = "[\\p{Nd}\\p{Nl}\\p{No}]"; - break; - case 'd': - str_ = number_decimal(); - state_.increment(); - break; - case 'l': - str_ = number_letter(); - state_.increment(); - break; - case 'o': - str_ = number_other(); - state_.increment(); - break; - default: - { - std::ostringstream ss_; - - ss_ << "Syntax error following \\p{N at index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - - break; - case 'P': - state_.increment(); - - if (state_.eos()) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following \\p{P"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - switch (*state_._curr) - { - case '}': - str_ = "[\\p{Pc}\\p{Pd}\\p{Pe}\\p{Pf}\\p{Pi}\\p{Po}" - "\\p{Ps}]"; - break; - case 'c': - str_ = punctuation_connector(); - state_.increment(); - break; - case 'd': - str_ = punctuation_dash(); - state_.increment(); - break; - case 'e': - str_ = punctuation_close(); - state_.increment(); - break; - case 'f': - str_ = punctuation_final(); - state_.increment(); - break; - case 'i': - str_ = punctuation_initial(); - state_.increment(); - break; - case 'o': - str_ = punctuation_other(); - state_.increment(); - break; - case 's': - str_ = punctuation_open(); - state_.increment(); - break; - default: - { - std::ostringstream ss_; - - ss_ << "Syntax error following \\p{P at index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - - break; - case 'S': - state_.increment(); - - if (state_.eos()) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following \\p{S"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - switch (*state_._curr) - { - case '}': - str_ = "[\\p{Sc}\\p{Sk}\\p{Sm}\\p{So}]"; - break; - case 'c': - str_ = symbol_currency(); - state_.increment(); - break; - case 'k': - str_ = symbol_modifier(); - state_.increment(); - break; - case 'm': - str_ = symbol_math(); - state_.increment(); - break; - case 'o': - str_ = symbol_other(); - state_.increment(); - break; - default: - { - std::ostringstream ss_; - - ss_ << "Syntax error following \\p{S at index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - - break; - case 'Z': - state_.increment(); - - if (state_.eos()) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following \\p{Z"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - switch (*state_._curr) - { - case '}': - str_ = "[\\p{Zl}\\p{Zp}\\p{Zs}]"; - break; - case 'l': - str_ = separator_line(); - state_.increment(); - break; - case 'p': - str_ = separator_paragraph(); - state_.increment(); - break; - case 's': - str_ = separator_space(); - state_.increment(); - break; - default: - { - std::ostringstream ss_; - - ss_ << "Syntax error following \\p{Z at index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - - break; - default: - { - std::ostringstream ss_; - - ss_ << "Syntax error following \\p{ at index " << - state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - - if (*state_._curr != '}') - { - std::ostringstream ss_; - - ss_ << "Missing '}' at index " << state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - return str_; - } - - static const char *other_control() - { - return "[\\x0-\\x1f\\x7f-\\x9f]"; - } - - static const char *other_format() - { - return "[\\xad\\x600-\\x605\\x61c\\x6dd\\x70f\\x180e\\x200b-\\x200f" - "\\x202a-\\x202e\\x2060-\\x2064\\x2066-\\x206f\\xfeff" - "\\xfff9-\\xfffb\\x110bd\\x1bca0-\\x1bca3\\x1d173-\\x1d17a\\xe0001" - "\\xe0020-\\xe007f]"; - } - - static const char *other_private() - { - return "[\\xe000\\xf8ff\\xf0000\\xffffd\\x100000\\x10fffd]"; - } - - static const char *other_surrogate() - { - return "[\\xd800\\xdb7f\\xdb80\\xdbff\\xdc00\\xdfff]"; - } - - static const char *letter_lowercase() - { - return "[\\x61-\\x7a\\xb5\\xdf-\\xf6\\xf8-\\xff\\x101\\x103\\x105\\x107" - "\\x109\\x10b\\x10d\\x10f\\x111\\x113\\x115\\x117\\x119\\x11b\\x11d" - "\\x11f\\x121\\x123\\x125\\x127\\x129\\x12b\\x12d\\x12f\\x131\\x133" - "\\x135\\x137\\x138\\x13a\\x13c\\x13e\\x140\\x142\\x144\\x146" - "\\x148\\x149\\x14b\\x14d\\x14f\\x151\\x153\\x155\\x157\\x159\\x15b" - "\\x15d\\x15f\\x161\\x163\\x165\\x167\\x169\\x16b\\x16d\\x16f\\x171" - "\\x173\\x175\\x177\\x17a\\x17c\\x17e-\\x180\\x183\\x185\\x188" - "\\x18c\\x18d\\x192\\x195\\x199-\\x19b\\x19e\\x1a1\\x1a3\\x1a5" - "\\x1a8\\x1aa\\x1ab\\x1ad\\x1b0\\x1b4\\x1b6\\x1b9\\x1ba" - "\\x1bd-\\x1bf\\x1c6\\x1c9\\x1cc\\x1ce\\x1d0\\x1d2\\x1d4\\x1d6" - "\\x1d8\\x1da\\x1dc\\x1dd\\x1df\\x1e1\\x1e3\\x1e5\\x1e7\\x1e9\\x1eb" - "\\x1ed\\x1ef\\x1f0\\x1f3\\x1f5\\x1f9\\x1fb\\x1fd\\x1ff\\x201\\x203" - "\\x205\\x207\\x209\\x20b\\x20d\\x20f\\x211\\x213\\x215\\x217\\x219" - "\\x21b\\x21d\\x21f\\x221\\x223\\x225\\x227\\x229\\x22b\\x22d\\x22f" - "\\x231\\x233-\\x239\\x23c\\x23f\\x240\\x242\\x247\\x249\\x24b" - "\\x24d\\x24f-\\x293\\x295-\\x2af\\x371\\x373\\x377\\x37b-\\x37d" - "\\x390\\x3ac-\\x3ce\\x3d0\\x3d1\\x3d5-\\x3d7\\x3d9\\x3db\\x3dd" - "\\x3df\\x3e1\\x3e3\\x3e5\\x3e7\\x3e9\\x3eb\\x3ed\\x3ef-\\x3f3" - "\\x3f5\\x3f8\\x3fb\\x3fc\\x430-\\x45f\\x461\\x463\\x465\\x467" - "\\x469\\x46b\\x46d\\x46f\\x471\\x473\\x475\\x477\\x479\\x47b\\x47d" - "\\x47f\\x481\\x48b\\x48d\\x48f\\x491\\x493\\x495\\x497\\x499\\x49b" - "\\x49d\\x49f\\x4a1\\x4a3\\x4a5\\x4a7\\x4a9\\x4ab\\x4ad\\x4af\\x4b1" - "\\x4b3\\x4b5\\x4b7\\x4b9\\x4bb\\x4bd\\x4bf\\x4c2\\x4c4\\x4c6\\x4c8" - "\\x4ca\\x4cc\\x4ce\\x4cf\\x4d1\\x4d3\\x4d5\\x4d7\\x4d9\\x4db\\x4dd" - "\\x4df\\x4e1\\x4e3\\x4e5\\x4e7\\x4e9\\x4eb\\x4ed\\x4ef\\x4f1\\x4f3" - "\\x4f5\\x4f7\\x4f9\\x4fb\\x4fd\\x4ff\\x501\\x503\\x505\\x507\\x509" - "\\x50b\\x50d\\x50f\\x511\\x513\\x515\\x517\\x519\\x51b\\x51d\\x51f" - "\\x521\\x523\\x525\\x527\\x529\\x52b\\x52d\\x52f\\x561-\\x587" - "\\x13f8-\\x13fd\\x1d00-\\x1d2b\\x1d6b-\\x1d77\\x1d79-\\x1d9a" - "\\x1e01\\x1e03\\x1e05\\x1e07\\x1e09\\x1e0b\\x1e0d\\x1e0f\\x1e11" - "\\x1e13\\x1e15\\x1e17\\x1e19\\x1e1b\\x1e1d\\x1e1f\\x1e21\\x1e23" - "\\x1e25\\x1e27\\x1e29\\x1e2b\\x1e2d\\x1e2f\\x1e31\\x1e33\\x1e35" - "\\x1e37\\x1e39\\x1e3b\\x1e3d\\x1e3f\\x1e41\\x1e43\\x1e45\\x1e47" - "\\x1e49\\x1e4b\\x1e4d\\x1e4f\\x1e51\\x1e53\\x1e55\\x1e57\\x1e59" - "\\x1e5b\\x1e5d\\x1e5f\\x1e61\\x1e63\\x1e65\\x1e67\\x1e69\\x1e6b" - "\\x1e6d\\x1e6f\\x1e71\\x1e73\\x1e75\\x1e77\\x1e79\\x1e7b\\x1e7d" - "\\x1e7f\\x1e81\\x1e83\\x1e85\\x1e87\\x1e89\\x1e8b\\x1e8d\\x1e8f" - "\\x1e91\\x1e93\\x1e95-\\x1e9d\\x1e9f\\x1ea1\\x1ea3\\x1ea5\\x1ea7" - "\\x1ea9\\x1eab\\x1ead\\x1eaf\\x1eb1\\x1eb3\\x1eb5\\x1eb7\\x1eb9" - "\\x1ebb\\x1ebd\\x1ebf\\x1ec1\\x1ec3\\x1ec5\\x1ec7\\x1ec9\\x1ecb" - "\\x1ecd\\x1ecf\\x1ed1\\x1ed3\\x1ed5\\x1ed7\\x1ed9\\x1edb\\x1edd" - "\\x1edf\\x1ee1\\x1ee3\\x1ee5\\x1ee7\\x1ee9\\x1eeb\\x1eed\\x1eef" - "\\x1ef1\\x1ef3\\x1ef5\\x1ef7\\x1ef9\\x1efb\\x1efd\\x1eff-\\x1f07" - "\\x1f10-\\x1f15\\x1f20-\\x1f27\\x1f30-\\x1f37\\x1f40-\\x1f45" - "\\x1f50-\\x1f57\\x1f60-\\x1f67\\x1f70-\\x1f7d\\x1f80-\\x1f87" - "\\x1f90-\\x1f97\\x1fa0-\\x1fa7\\x1fb0-\\x1fb4\\x1fb6\\x1fb7\\x1fbe" - "\\x1fc2-\\x1fc4\\x1fc6\\x1fc7\\x1fd0-\\x1fd3\\x1fd6\\x1fd7" - "\\x1fe0-\\x1fe7\\x1ff2-\\x1ff4\\x1ff6\\x1ff7\\x210a\\x210e\\x210f" - "\\x2113\\x212f\\x2134\\x2139\\x213c\\x213d\\x2146-\\x2149\\x214e" - "\\x2184\\x2c30-\\x2c5e\\x2c61\\x2c65\\x2c66\\x2c68\\x2c6a\\x2c6c" - "\\x2c71\\x2c73\\x2c74\\x2c76-\\x2c7b\\x2c81\\x2c83\\x2c85\\x2c87" - "\\x2c89\\x2c8b\\x2c8d\\x2c8f\\x2c91\\x2c93\\x2c95\\x2c97\\x2c99" - "\\x2c9b\\x2c9d\\x2c9f\\x2ca1\\x2ca3\\x2ca5\\x2ca7\\x2ca9\\x2cab" - "\\x2cad\\x2caf\\x2cb1\\x2cb3\\x2cb5\\x2cb7\\x2cb9\\x2cbb\\x2cbd" - "\\x2cbf\\x2cc1\\x2cc3\\x2cc5\\x2cc7\\x2cc9\\x2ccb\\x2ccd\\x2ccf" - "\\x2cd1\\x2cd3\\x2cd5\\x2cd7\\x2cd9\\x2cdb\\x2cdd\\x2cdf\\x2ce1" - "\\x2ce3\\x2ce4\\x2cec\\x2cee\\x2cf3\\x2d00-\\x2d25\\x2d27\\x2d2d" - "\\xa641\\xa643\\xa645\\xa647\\xa649\\xa64b\\xa64d\\xa64f\\xa651" - "\\xa653\\xa655\\xa657\\xa659\\xa65b\\xa65d\\xa65f\\xa661\\xa663" - "\\xa665\\xa667\\xa669\\xa66b\\xa66d\\xa681\\xa683\\xa685\\xa687" - "\\xa689\\xa68b\\xa68d\\xa68f\\xa691\\xa693\\xa695\\xa697\\xa699" - "\\xa69b\\xa723\\xa725\\xa727\\xa729\\xa72b\\xa72d\\xa72f-\\xa731" - "\\xa733\\xa735\\xa737\\xa739\\xa73b\\xa73d\\xa73f\\xa741\\xa743" - "\\xa745\\xa747\\xa749\\xa74b\\xa74d\\xa74f\\xa751\\xa753\\xa755" - "\\xa757\\xa759\\xa75b\\xa75d\\xa75f\\xa761\\xa763\\xa765\\xa767" - "\\xa769\\xa76b\\xa76d\\xa76f\\xa771-\\xa778\\xa77a\\xa77c\\xa77f" - "\\xa781\\xa783\\xa785\\xa787\\xa78c\\xa78e\\xa791\\xa793-\\xa795" - "\\xa797\\xa799\\xa79b\\xa79d\\xa79f\\xa7a1\\xa7a3\\xa7a5\\xa7a7" - "\\xa7a9\\xa7b5\\xa7b7\\xa7fa\\xab30-\\xab5a\\xab60-\\xab65" - "\\xab70-\\xabbf\\xfb00-\\xfb06\\xfb13-\\xfb17\\xff41-\\xff5a" - "\\x10428-\\x1044f\\x10cc0-\\x10cf2\\x118c0-\\x118df" - "\\x1d41a-\\x1d433\\x1d44e-\\x1d454\\x1d456-\\x1d467" - "\\x1d482-\\x1d49b\\x1d4b6-\\x1d4b9\\x1d4bb\\x1d4bd-\\x1d4c3" - "\\x1d4c5-\\x1d4cf\\x1d4ea-\\x1d503\\x1d51e-\\x1d537" - "\\x1d552-\\x1d56b\\x1d586-\\x1d59f\\x1d5ba-\\x1d5d3" - "\\x1d5ee-\\x1d607\\x1d622-\\x1d63b\\x1d656-\\x1d66f" - "\\x1d68a-\\x1d6a5\\x1d6c2-\\x1d6da\\x1d6dc-\\x1d6e1" - "\\x1d6fc-\\x1d714\\x1d716-\\x1d71b\\x1d736-\\x1d74e" - "\\x1d750-\\x1d755\\x1d770-\\x1d788\\x1d78a-\\x1d78f" - "\\x1d7aa-\\x1d7c2\\x1d7c4-\\x1d7c9\\x1d7cb]"; - } - - static const char *letter_modifier() - { - return "[\\x2b0-\\x2c1\\x2c6-\\x2d1\\x2e0-\\x2e4\\x2ec\\x2ee\\x374" - "\\x37a\\x559\\x640\\x6e5\\x6e6\\x7f4\\x7f5\\x7fa\\x81a\\x824\\x828" - "\\x971\\xe46\\xec6\\x10fc\\x17d7\\x1843\\x1aa7\\x1c78-\\x1c7d" - "\\x1d2c-\\x1d6a\\x1d78\\x1d9b-\\x1dbf\\x2071\\x207f\\x2090-\\x209c" - "\\x2c7c\\x2c7d\\x2d6f\\x2e2f\\x3005\\x3031-\\x3035\\x303b" - "\\x309d\\x309e\\x30fc-\\x30fe\\xa015\\xa4f8-\\xa4fd\\xa60c\\xa67f" - "\\xa69c\\xa69d\\xa717-\\xa71f\\xa770\\xa788\\xa7f8\\xa7f9\\xa9cf" - "\\xa9e6\\xaa70\\xaadd\\xaaf3\\xaaf4\\xab5c-\\xab5f\\xff70" - "\\xff9e\\xff9f\\x16b40-\\x16b43\\x16f93-\\x16f9f]"; - } - - static const char *letter_other() - { - return "[\\xaa\\xba\\x1bb\\x1c0-\\x1c3\\x294\\x5d0-\\x5ea\\x5f0-\\x5f2" - "\\x620-\\x63f\\x641-\\x64a\\x66e\\x66f\\x671-\\x6d3\\x6d5" - "\\x6ee\\x6ef\\x6fa-\\x6fc\\x6ff\\x710\\x712-\\x72f\\x74d-\\x7a5" - "\\x7b1\\x7ca-\\x7ea\\x800-\\x815\\x840-\\x858\\x8a0-\\x8b4" - "\\x904-\\x939\\x93d\\x950\\x958-\\x961\\x972-\\x980\\x985-\\x98c" - "\\x98f\\x990\\x993-\\x9a8\\x9aa-\\x9b0\\x9b2\\x9b6-\\x9b9\\x9bd" - "\\x9ce\\x9dc\\x9dd\\x9df-\\x9e1\\x9f0\\x9f1\\xa05-\\xa0a" - "\\xa0f\\xa10\\xa13-\\xa28\\xa2a-\\xa30\\xa32\\xa33\\xa35\\xa36" - "\\xa38\\xa39\\xa59-\\xa5c\\xa5e\\xa72-\\xa74\\xa85-\\xa8d" - "\\xa8f-\\xa91\\xa93-\\xaa8\\xaaa-\\xab0\\xab2\\xab3\\xab5-\\xab9" - "\\xabd\\xad0\\xae0\\xae1\\xaf9\\xb05-\\xb0c\\xb0f\\xb10" - "\\xb13-\\xb28\\xb2a-\\xb30\\xb32\\xb33\\xb35-\\xb39\\xb3d" - "\\xb5c\\xb5d\\xb5f-\\xb61\\xb71\\xb83\\xb85-\\xb8a\\xb8e-\\xb90" - "\\xb92-\\xb95\\xb99\\xb9a\\xb9c\\xb9e\\xb9f\\xba3\\xba4" - "\\xba8-\\xbaa\\xbae-\\xbb9\\xbd0\\xc05-\\xc0c\\xc0e-\\xc10" - "\\xc12-\\xc28\\xc2a-\\xc39\\xc3d\\xc58-\\xc5a\\xc60\\xc61" - "\\xc85-\\xc8c\\xc8e-\\xc90\\xc92-\\xca8\\xcaa-\\xcb3\\xcb5-\\xcb9" - "\\xcbd\\xcde\\xce0\\xce1\\xcf1\\xcf2\\xd05-\\xd0c\\xd0e-\\xd10" - "\\xd12-\\xd3a\\xd3d\\xd4e\\xd5f-\\xd61\\xd7a-\\xd7f\\xd85-\\xd96" - "\\xd9a-\\xdb1\\xdb3-\\xdbb\\xdbd\\xdc0-\\xdc6\\xe01-\\xe30" - "\\xe32\\xe33\\xe40-\\xe45\\xe81\\xe82\\xe84\\xe87\\xe88\\xe8a" - "\\xe8d\\xe94-\\xe97\\xe99-\\xe9f\\xea1-\\xea3\\xea5\\xea7" - "\\xeaa\\xeab\\xead-\\xeb0\\xeb2\\xeb3\\xebd\\xec0-\\xec4" - "\\xedc-\\xedf\\xf00\\xf40-\\xf47\\xf49-\\xf6c\\xf88-\\xf8c" - "\\x1000-\\x102a\\x103f\\x1050-\\x1055\\x105a-\\x105d\\x1061" - "\\x1065\\x1066\\x106e-\\x1070\\x1075-\\x1081\\x108e\\x10d0-\\x10fa" - "\\x10fd-\\x1248\\x124a-\\x124d\\x1250-\\x1256\\x1258" - "\\x125a-\\x125d\\x1260-\\x1288\\x128a-\\x128d\\x1290-\\x12b0" - "\\x12b2-\\x12b5\\x12b8-\\x12be\\x12c0\\x12c2-\\x12c5" - "\\x12c8-\\x12d6\\x12d8-\\x1310\\x1312-\\x1315\\x1318-\\x135a" - "\\x1380-\\x138f\\x1401-\\x166c\\x166f-\\x167f\\x1681-\\x169a" - "\\x16a0-\\x16ea\\x16f1-\\x16f8\\x1700-\\x170c\\x170e-\\x1711" - "\\x1720-\\x1731\\x1740-\\x1751\\x1760-\\x176c\\x176e-\\x1770" - "\\x1780-\\x17b3\\x17dc\\x1820-\\x1842\\x1844-\\x1877" - "\\x1880-\\x18a8\\x18aa\\x18b0-\\x18f5\\x1900-\\x191e" - "\\x1950-\\x196d\\x1970-\\x1974\\x1980-\\x19ab\\x19b0-\\x19c9" - "\\x1a00-\\x1a16\\x1a20-\\x1a54\\x1b05-\\x1b33\\x1b45-\\x1b4b" - "\\x1b83-\\x1ba0\\x1bae\\x1baf\\x1bba-\\x1be5\\x1c00-\\x1c23" - "\\x1c4d-\\x1c4f\\x1c5a-\\x1c77\\x1ce9-\\x1cec\\x1cee-\\x1cf1" - "\\x1cf5\\x1cf6\\x2135-\\x2138\\x2d30-\\x2d67\\x2d80-\\x2d96" - "\\x2da0-\\x2da6\\x2da8-\\x2dae\\x2db0-\\x2db6\\x2db8-\\x2dbe" - "\\x2dc0-\\x2dc6\\x2dc8-\\x2dce\\x2dd0-\\x2dd6\\x2dd8-\\x2dde" - "\\x3006\\x303c\\x3041-\\x3096\\x309f\\x30a1-\\x30fa\\x30ff" - "\\x3105-\\x312d\\x3131-\\x318e\\x31a0-\\x31ba\\x31f0-\\x31ff" - "\\x3400\\x4db5\\x4e00\\x9fd5\\xa000-\\xa014\\xa016-\\xa48c" - "\\xa4d0-\\xa4f7\\xa500-\\xa60b\\xa610-\\xa61f\\xa62a\\xa62b\\xa66e" - "\\xa6a0-\\xa6e5\\xa78f\\xa7f7\\xa7fb-\\xa801\\xa803-\\xa805" - "\\xa807-\\xa80a\\xa80c-\\xa822\\xa840-\\xa873\\xa882-\\xa8b3" - "\\xa8f2-\\xa8f7\\xa8fb\\xa8fd\\xa90a-\\xa925\\xa930-\\xa946" - "\\xa960-\\xa97c\\xa984-\\xa9b2\\xa9e0-\\xa9e4\\xa9e7-\\xa9ef" - "\\xa9fa-\\xa9fe\\xaa00-\\xaa28\\xaa40-\\xaa42\\xaa44-\\xaa4b" - "\\xaa60-\\xaa6f\\xaa71-\\xaa76\\xaa7a\\xaa7e-\\xaaaf\\xaab1" - "\\xaab5\\xaab6\\xaab9-\\xaabd\\xaac0\\xaac2\\xaadb\\xaadc" - "\\xaae0-\\xaaea\\xaaf2\\xab01-\\xab06\\xab09-\\xab0e" - "\\xab11-\\xab16\\xab20-\\xab26\\xab28-\\xab2e\\xabc0-\\xabe2" - "\\xac00\\xd7a3\\xd7b0-\\xd7c6\\xd7cb-\\xd7fb\\xf900-\\xfa6d" - "\\xfa70-\\xfad9\\xfb1d\\xfb1f-\\xfb28\\xfb2a-\\xfb36" - "\\xfb38-\\xfb3c\\xfb3e\\xfb40\\xfb41\\xfb43\\xfb44\\xfb46-\\xfbb1" - "\\xfbd3-\\xfd3d\\xfd50-\\xfd8f\\xfd92-\\xfdc7\\xfdf0-\\xfdfb" - "\\xfe70-\\xfe74\\xfe76-\\xfefc\\xff66-\\xff6f\\xff71-\\xff9d" - "\\xffa0-\\xffbe\\xffc2-\\xffc7\\xffca-\\xffcf\\xffd2-\\xffd7" - "\\xffda-\\xffdc\\x10000-\\x1000b\\x1000d-\\x10026\\x10028-\\x1003a" - "\\x1003c\\x1003d\\x1003f-\\x1004d\\x10050-\\x1005d" - "\\x10080-\\x100fa\\x10280-\\x1029c\\x102a0-\\x102d0" - "\\x10300-\\x1031f\\x10330-\\x10340\\x10342-\\x10349" - "\\x10350-\\x10375\\x10380-\\x1039d\\x103a0-\\x103c3" - "\\x103c8-\\x103cf\\x10450-\\x1049d\\x10500-\\x10527" - "\\x10530-\\x10563\\x10600-\\x10736\\x10740-\\x10755" - "\\x10760-\\x10767\\x10800-\\x10805\\x10808\\x1080a-\\x10835" - "\\x10837\\x10838\\x1083c\\x1083f-\\x10855\\x10860-\\x10876" - "\\x10880-\\x1089e\\x108e0-\\x108f2\\x108f4\\x108f5" - "\\x10900-\\x10915\\x10920-\\x10939\\x10980-\\x109b7" - "\\x109be\\x109bf\\x10a00\\x10a10-\\x10a13\\x10a15-\\x10a17" - "\\x10a19-\\x10a33\\x10a60-\\x10a7c\\x10a80-\\x10a9c" - "\\x10ac0-\\x10ac7\\x10ac9-\\x10ae4\\x10b00-\\x10b35" - "\\x10b40-\\x10b55\\x10b60-\\x10b72\\x10b80-\\x10b91" - "\\x10c00-\\x10c48\\x11003-\\x11037\\x11083-\\x110af" - "\\x110d0-\\x110e8\\x11103-\\x11126\\x11150-\\x11172\\x11176" - "\\x11183-\\x111b2\\x111c1-\\x111c4\\x111da\\x111dc" - "\\x11200-\\x11211\\x11213-\\x1122b\\x11280-\\x11286\\x11288" - "\\x1128a-\\x1128d\\x1128f-\\x1129d\\x1129f-\\x112a8" - "\\x112b0-\\x112de\\x11305-\\x1130c\\x1130f\\x11310" - "\\x11313-\\x11328\\x1132a-\\x11330\\x11332\\x11333" - "\\x11335-\\x11339\\x1133d\\x11350\\x1135d-\\x11361" - "\\x11480-\\x114af\\x114c4\\x114c5\\x114c7\\x11580-\\x115ae" - "\\x115d8-\\x115db\\x11600-\\x1162f\\x11644\\x11680-\\x116aa" - "\\x11700-\\x11719\\x118ff\\x11ac0-\\x11af8\\x12000-\\x12399" - "\\x12480-\\x12543\\x13000-\\x1342e\\x14400-\\x14646" - "\\x16800-\\x16a38\\x16a40-\\x16a5e\\x16ad0-\\x16aed" - "\\x16b00-\\x16b2f\\x16b63-\\x16b77\\x16b7d-\\x16b8f" - "\\x16f00-\\x16f44\\x16f50\\x1b000\\x1b001\\x1bc00-\\x1bc6a" - "\\x1bc70-\\x1bc7c\\x1bc80-\\x1bc88\\x1bc90-\\x1bc99" - "\\x1e800-\\x1e8c4\\x1ee00-\\x1ee03\\x1ee05-\\x1ee1f" - "\\x1ee21\\x1ee22\\x1ee24\\x1ee27\\x1ee29-\\x1ee32\\x1ee34-\\x1ee37" - "\\x1ee39\\x1ee3b\\x1ee42\\x1ee47\\x1ee49\\x1ee4b\\x1ee4d-\\x1ee4f" - "\\x1ee51\\x1ee52\\x1ee54\\x1ee57\\x1ee59\\x1ee5b\\x1ee5d\\x1ee5f" - "\\x1ee61\\x1ee62\\x1ee64\\x1ee67-\\x1ee6a\\x1ee6c-\\x1ee72" - "\\x1ee74-\\x1ee77\\x1ee79-\\x1ee7c\\x1ee7e\\x1ee80-\\x1ee89" - "\\x1ee8b-\\x1ee9b\\x1eea1-\\x1eea3\\x1eea5-\\x1eea9" - "\\x1eeab-\\x1eebb\\x20000\\x2a6d6\\x2a700\\x2b734\\x2b740\\x2b81d" - "\\x2b820\\x2cea1\\x2f800-\\x2fa1d]"; - } - - static const char *letter_titlecase() - { - return "[\\x1c5\\x1c8\\x1cb\\x1f2\\x1f88-\\x1f8f\\x1f98-\\x1f9f" - "\\x1fa8-\\x1faf\\x1fbc\\x1fcc\\x1ffc]"; - } - - static const char *letter_uppercase() - { - return "[\\x41-\\x5a\\xc0-\\xd6\\xd8-\\xde\\x100\\x102\\x104\\x106" - "\\x108\\x10a\\x10c\\x10e\\x110\\x112\\x114\\x116\\x118\\x11a\\x11c" - "\\x11e\\x120\\x122\\x124\\x126\\x128\\x12a\\x12c\\x12e\\x130\\x132" - "\\x134\\x136\\x139\\x13b\\x13d\\x13f\\x141\\x143\\x145\\x147\\x14a" - "\\x14c\\x14e\\x150\\x152\\x154\\x156\\x158\\x15a\\x15c\\x15e\\x160" - "\\x162\\x164\\x166\\x168\\x16a\\x16c\\x16e\\x170\\x172\\x174\\x176" - "\\x178\\x179\\x17b\\x17d\\x181\\x182\\x184\\x186\\x187" - "\\x189-\\x18b\\x18e-\\x191\\x193\\x194\\x196-\\x198\\x19c\\x19d" - "\\x19f\\x1a0\\x1a2\\x1a4\\x1a6\\x1a7\\x1a9\\x1ac\\x1ae\\x1af" - "\\x1b1-\\x1b3\\x1b5\\x1b7\\x1b8\\x1bc\\x1c4\\x1c7\\x1ca\\x1cd" - "\\x1cf\\x1d1\\x1d3\\x1d5\\x1d7\\x1d9\\x1db\\x1de\\x1e0\\x1e2\\x1e4" - "\\x1e6\\x1e8\\x1ea\\x1ec\\x1ee\\x1f1\\x1f4\\x1f6-\\x1f8\\x1fa" - "\\x1fc\\x1fe\\x200\\x202\\x204\\x206\\x208\\x20a\\x20c\\x20e\\x210" - "\\x212\\x214\\x216\\x218\\x21a\\x21c\\x21e\\x220\\x222\\x224\\x226" - "\\x228\\x22a\\x22c\\x22e\\x230\\x232\\x23a\\x23b\\x23d\\x23e\\x241" - "\\x243-\\x246\\x248\\x24a\\x24c\\x24e\\x370\\x372\\x376\\x37f" - "\\x386\\x388-\\x38a\\x38c\\x38e\\x38f\\x391-\\x3a1\\x3a3-\\x3ab" - "\\x3cf\\x3d2-\\x3d4\\x3d8\\x3da\\x3dc\\x3de\\x3e0\\x3e2\\x3e4" - "\\x3e6\\x3e8\\x3ea\\x3ec\\x3ee\\x3f4\\x3f7\\x3f9\\x3fa" - "\\x3fd-\\x42f\\x460\\x462\\x464\\x466\\x468\\x46a\\x46c\\x46e" - "\\x470\\x472\\x474\\x476\\x478\\x47a\\x47c\\x47e\\x480\\x48a\\x48c" - "\\x48e\\x490\\x492\\x494\\x496\\x498\\x49a\\x49c\\x49e\\x4a0\\x4a2" - "\\x4a4\\x4a6\\x4a8\\x4aa\\x4ac\\x4ae\\x4b0\\x4b2\\x4b4\\x4b6\\x4b8" - "\\x4ba\\x4bc\\x4be\\x4c0\\x4c1\\x4c3\\x4c5\\x4c7\\x4c9\\x4cb\\x4cd" - "\\x4d0\\x4d2\\x4d4\\x4d6\\x4d8\\x4da\\x4dc\\x4de\\x4e0\\x4e2\\x4e4" - "\\x4e6\\x4e8\\x4ea\\x4ec\\x4ee\\x4f0\\x4f2\\x4f4\\x4f6\\x4f8\\x4fa" - "\\x4fc\\x4fe\\x500\\x502\\x504\\x506\\x508\\x50a\\x50c\\x50e\\x510" - "\\x512\\x514\\x516\\x518\\x51a\\x51c\\x51e\\x520\\x522\\x524\\x526" - "\\x528\\x52a\\x52c\\x52e\\x531-\\x556\\x10a0-\\x10c5\\x10c7\\x10cd" - "\\x13a0-\\x13f5\\x1e00\\x1e02\\x1e04\\x1e06\\x1e08\\x1e0a\\x1e0c" - "\\x1e0e\\x1e10\\x1e12\\x1e14\\x1e16\\x1e18\\x1e1a\\x1e1c\\x1e1e" - "\\x1e20\\x1e22\\x1e24\\x1e26\\x1e28\\x1e2a\\x1e2c\\x1e2e\\x1e30" - "\\x1e32\\x1e34\\x1e36\\x1e38\\x1e3a\\x1e3c\\x1e3e\\x1e40\\x1e42" - "\\x1e44\\x1e46\\x1e48\\x1e4a\\x1e4c\\x1e4e\\x1e50\\x1e52\\x1e54" - "\\x1e56\\x1e58\\x1e5a\\x1e5c\\x1e5e\\x1e60\\x1e62\\x1e64\\x1e66" - "\\x1e68\\x1e6a\\x1e6c\\x1e6e\\x1e70\\x1e72\\x1e74\\x1e76\\x1e78" - "\\x1e7a\\x1e7c\\x1e7e\\x1e80\\x1e82\\x1e84\\x1e86\\x1e88\\x1e8a" - "\\x1e8c\\x1e8e\\x1e90\\x1e92\\x1e94\\x1e9e\\x1ea0\\x1ea2\\x1ea4" - "\\x1ea6\\x1ea8\\x1eaa\\x1eac\\x1eae\\x1eb0\\x1eb2\\x1eb4\\x1eb6" - "\\x1eb8\\x1eba\\x1ebc\\x1ebe\\x1ec0\\x1ec2\\x1ec4\\x1ec6\\x1ec8" - "\\x1eca\\x1ecc\\x1ece\\x1ed0\\x1ed2\\x1ed4\\x1ed6\\x1ed8\\x1eda" - "\\x1edc\\x1ede\\x1ee0\\x1ee2\\x1ee4\\x1ee6\\x1ee8\\x1eea\\x1eec" - "\\x1eee\\x1ef0\\x1ef2\\x1ef4\\x1ef6\\x1ef8\\x1efa\\x1efc\\x1efe" - "\\x1f08-\\x1f0f\\x1f18-\\x1f1d\\x1f28-\\x1f2f\\x1f38-\\x1f3f" - "\\x1f48-\\x1f4d\\x1f59\\x1f5b\\x1f5d\\x1f5f\\x1f68-\\x1f6f" - "\\x1fb8-\\x1fbb\\x1fc8-\\x1fcb\\x1fd8-\\x1fdb\\x1fe8-\\x1fec" - "\\x1ff8-\\x1ffb\\x2102\\x2107\\x210b-\\x210d\\x2110-\\x2112\\x2115" - "\\x2119-\\x211d\\x2124\\x2126\\x2128\\x212a-\\x212d\\x2130-\\x2133" - "\\x213e\\x213f\\x2145\\x2183\\x2c00-\\x2c2e\\x2c60\\x2c62-\\x2c64" - "\\x2c67\\x2c69\\x2c6b\\x2c6d-\\x2c70\\x2c72\\x2c75\\x2c7e-\\x2c80" - "\\x2c82\\x2c84\\x2c86\\x2c88\\x2c8a\\x2c8c\\x2c8e\\x2c90\\x2c92" - "\\x2c94\\x2c96\\x2c98\\x2c9a\\x2c9c\\x2c9e\\x2ca0\\x2ca2\\x2ca4" - "\\x2ca6\\x2ca8\\x2caa\\x2cac\\x2cae\\x2cb0\\x2cb2\\x2cb4\\x2cb6" - "\\x2cb8\\x2cba\\x2cbc\\x2cbe\\x2cc0\\x2cc2\\x2cc4\\x2cc6\\x2cc8" - "\\x2cca\\x2ccc\\x2cce\\x2cd0\\x2cd2\\x2cd4\\x2cd6\\x2cd8\\x2cda" - "\\x2cdc\\x2cde\\x2ce0\\x2ce2\\x2ceb\\x2ced\\x2cf2\\xa640\\xa642" - "\\xa644\\xa646\\xa648\\xa64a\\xa64c\\xa64e\\xa650\\xa652\\xa654" - "\\xa656\\xa658\\xa65a\\xa65c\\xa65e\\xa660\\xa662\\xa664\\xa666" - "\\xa668\\xa66a\\xa66c\\xa680\\xa682\\xa684\\xa686\\xa688\\xa68a" - "\\xa68c\\xa68e\\xa690\\xa692\\xa694\\xa696\\xa698\\xa69a\\xa722" - "\\xa724\\xa726\\xa728\\xa72a\\xa72c\\xa72e\\xa732\\xa734\\xa736" - "\\xa738\\xa73a\\xa73c\\xa73e\\xa740\\xa742\\xa744\\xa746\\xa748" - "\\xa74a\\xa74c\\xa74e\\xa750\\xa752\\xa754\\xa756\\xa758\\xa75a" - "\\xa75c\\xa75e\\xa760\\xa762\\xa764\\xa766\\xa768\\xa76a\\xa76c" - "\\xa76e\\xa779\\xa77b\\xa77d\\xa77e\\xa780\\xa782\\xa784\\xa786" - "\\xa78b\\xa78d\\xa790\\xa792\\xa796\\xa798\\xa79a\\xa79c\\xa79e" - "\\xa7a0\\xa7a2\\xa7a4\\xa7a6\\xa7a8\\xa7aa-\\xa7ad\\xa7b0-\\xa7b4" - "\\xa7b6\\xff21-\\xff3a\\x10400-\\x10427\\x10c80-\\x10cb2" - "\\x118a0-\\x118bf\\x1d400-\\x1d419\\x1d434-\\x1d44d" - "\\x1d468-\\x1d481\\x1d49c\\x1d49e\\x1d49f\\x1d4a2\\x1d4a5\\x1d4a6" - "\\x1d4a9-\\x1d4ac\\x1d4ae-\\x1d4b5\\x1d4d0-\\x1d4e9" - "\\x1d504\\x1d505\\x1d507-\\x1d50a\\x1d50d-\\x1d514" - "\\x1d516-\\x1d51c\\x1d538\\x1d539\\x1d53b-\\x1d53e" - "\\x1d540-\\x1d544\\x1d546\\x1d54a-\\x1d550\\x1d56c-\\x1d585" - "\\x1d5a0-\\x1d5b9\\x1d5d4-\\x1d5ed\\x1d608-\\x1d621" - "\\x1d63c-\\x1d655\\x1d670-\\x1d689\\x1d6a8-\\x1d6c0" - "\\x1d6e2-\\x1d6fa\\x1d71c-\\x1d734\\x1d756-\\x1d76e" - "\\x1d790-\\x1d7a8\\x1d7ca]"; - } - - static const char *mark_combining() - { - return "[\\x903\\x93b\\x93e-\\x940\\x949-\\x94c\\x94e\\x94f\\x982\\x983" - "\\x9be-\\x9c0\\x9c7\\x9c8\\x9cb\\x9cc\\x9d7\\xa03\\xa3e-\\xa40" - "\\xa83\\xabe-\\xac0\\xac9\\xacb\\xacc\\xb02\\xb03\\xb3e\\xb40" - "\\xb47\\xb48\\xb4b\\xb4c\\xb57\\xbbe\\xbbf\\xbc1\\xbc2" - "\\xbc6-\\xbc8\\xbca-\\xbcc\\xbd7\\xc01-\\xc03\\xc41-\\xc44" - "\\xc82\\xc83\\xcbe\\xcc0-\\xcc4\\xcc7\\xcc8\\xcca\\xccb" - "\\xcd5\\xcd6\\xd02\\xd03\\xd3e-\\xd40\\xd46-\\xd48\\xd4a-\\xd4c" - "\\xd57\\xd82\\xd83\\xdcf-\\xdd1\\xdd8-\\xddf\\xdf2\\xdf3" - "\\xf3e\\xf3f\\xf7f\\x102b\\x102c\\x1031\\x1038\\x103b\\x103c" - "\\x1056\\x1057\\x1062-\\x1064\\x1067-\\x106d\\x1083\\x1084" - "\\x1087-\\x108c\\x108f\\x109a-\\x109c\\x17b6\\x17be-\\x17c5" - "\\x17c7\\x17c8\\x1923-\\x1926\\x1929-\\x192b\\x1930\\x1931" - "\\x1933-\\x1938\\x1a19\\x1a1a\\x1a55\\x1a57\\x1a61\\x1a63\\x1a64" - "\\x1a6d-\\x1a72\\x1b04\\x1b35\\x1b3b\\x1b3d-\\x1b41\\x1b43\\x1b44" - "\\x1b82\\x1ba1\\x1ba6\\x1ba7\\x1baa\\x1be7\\x1bea-\\x1bec\\x1bee" - "\\x1bf2\\x1bf3\\x1c24-\\x1c2b\\x1c34\\x1c35\\x1ce1\\x1cf2\\x1cf3" - "\\x302e\\x302f\\xa823\\xa824\\xa827\\xa880\\xa881\\xa8b4-\\xa8c3" - "\\xa952\\xa953\\xa983\\xa9b4\\xa9b5\\xa9ba\\xa9bb\\xa9bd-\\xa9c0" - "\\xaa2f\\xaa30\\xaa33\\xaa34\\xaa4d\\xaa7b\\xaa7d\\xaaeb" - "\\xaaee\\xaaef\\xaaf5\\xabe3\\xabe4\\xabe6\\xabe7\\xabe9\\xabea" - "\\xabec\\x11000\\x11002\\x11082\\x110b0-\\x110b2\\x110b7\\x110b8" - "\\x1112c\\x11182\\x111b3-\\x111b5\\x111bf\\x111c0\\x1122c-\\x1122e" - "\\x11232\\x11233\\x11235\\x112e0-\\x112e2\\x11302\\x11303" - "\\x1133e\\x1133f\\x11341-\\x11344\\x11347\\x11348\\x1134b-\\x1134d" - "\\x11357\\x11362\\x11363\\x114b0-\\x114b2\\x114b9\\x114bb-\\x114be" - "\\x114c1\\x115af-\\x115b1\\x115b8-\\x115bb\\x115be" - "\\x11630-\\x11632\\x1163b\\x1163c\\x1163e\\x116ac\\x116ae\\x116af" - "\\x116b6\\x11720\\x11721\\x11726\\x16f51-\\x16f7e\\x1d165\\x1d166" - "\\x1d16d-\\x1d172]"; - } - - static const char *mark_enclosing() - { - return "[\\x488\\x489\\x1abe\\x20dd-\\x20e0\\x20e2-\\x20e4" - "\\xa670-\\xa672]"; - } - - static const char *mark_nonspacing() - { - return "[\\x300-\\x36f\\x483-\\x487\\x591-\\x5bd\\x5bf\\x5c1\\x5c2" - "\\x5c4\\x5c5\\x5c7\\x610-\\x61a\\x64b-\\x65f\\x670\\x6d6-\\x6dc" - "\\x6df-\\x6e4\\x6e7\\x6e8\\x6ea-\\x6ed\\x711\\x730-\\x74a" - "\\x7a6-\\x7b0\\x7eb-\\x7f3\\x816-\\x819\\x81b-\\x823\\x825-\\x827" - "\\x829-\\x82d\\x859-\\x85b\\x8e3-\\x902\\x93a\\x93c\\x941-\\x948" - "\\x94d\\x951-\\x957\\x962\\x963\\x981\\x9bc\\x9c1-\\x9c4\\x9cd" - "\\x9e2\\x9e3\\xa01\\xa02\\xa3c\\xa41\\xa42\\xa47\\xa48" - "\\xa4b-\\xa4d\\xa51\\xa70\\xa71\\xa75\\xa81\\xa82\\xabc" - "\\xac1-\\xac5\\xac7\\xac8\\xacd\\xae2\\xae3\\xb01\\xb3c\\xb3f" - "\\xb41-\\xb44\\xb4d\\xb56\\xb62\\xb63\\xb82\\xbc0\\xbcd\\xc00" - "\\xc3e-\\xc40\\xc46-\\xc48\\xc4a-\\xc4d\\xc55\\xc56\\xc62\\xc63" - "\\xc81\\xcbc\\xcbf\\xcc6\\xccc\\xccd\\xce2\\xce3\\xd01" - "\\xd41-\\xd44\\xd4d\\xd62\\xd63\\xdca\\xdd2-\\xdd4\\xdd6\\xe31" - "\\xe34-\\xe3a\\xe47-\\xe4e\\xeb1\\xeb4-\\xeb9\\xebb\\xebc" - "\\xec8-\\xecd\\xf18\\xf19\\xf35\\xf37\\xf39\\xf71-\\xf7e" - "\\xf80-\\xf84\\xf86\\xf87\\xf8d-\\xf97\\xf99-\\xfbc\\xfc6" - "\\x102d-\\x1030\\x1032-\\x1037\\x1039\\x103a\\x103d\\x103e" - "\\x1058\\x1059\\x105e-\\x1060\\x1071-\\x1074\\x1082\\x1085\\x1086" - "\\x108d\\x109d\\x135d-\\x135f\\x1712-\\x1714\\x1732-\\x1734" - "\\x1752\\x1753\\x1772\\x1773\\x17b4\\x17b5\\x17b7-\\x17bd\\x17c6" - "\\x17c9-\\x17d3\\x17dd\\x180b-\\x180d\\x18a9\\x1920-\\x1922" - "\\x1927\\x1928\\x1932\\x1939-\\x193b\\x1a17\\x1a18\\x1a1b\\x1a56" - "\\x1a58-\\x1a5e\\x1a60\\x1a62\\x1a65-\\x1a6c\\x1a73-\\x1a7c\\x1a7f" - "\\x1ab0-\\x1abd\\x1b00-\\x1b03\\x1b34\\x1b36-\\x1b3a\\x1b3c\\x1b42" - "\\x1b6b-\\x1b73\\x1b80\\x1b81\\x1ba2-\\x1ba5\\x1ba8\\x1ba9" - "\\x1bab-\\x1bad\\x1be6\\x1be8\\x1be9\\x1bed\\x1bef-\\x1bf1" - "\\x1c2c-\\x1c33\\x1c36\\x1c37\\x1cd0-\\x1cd2\\x1cd4-\\x1ce0" - "\\x1ce2-\\x1ce8\\x1ced\\x1cf4\\x1cf8\\x1cf9\\x1dc0-\\x1df5" - "\\x1dfc-\\x1dff\\x20d0-\\x20dc\\x20e1\\x20e5-\\x20f0" - "\\x2cef-\\x2cf1\\x2d7f\\x2de0-\\x2dff\\x302a-\\x302d\\x3099\\x309a" - "\\xa66f\\xa674-\\xa67d\\xa69e\\xa69f\\xa6f0\\xa6f1\\xa802\\xa806" - "\\xa80b\\xa825\\xa826\\xa8c4\\xa8e0-\\xa8f1\\xa926-\\xa92d" - "\\xa947-\\xa951\\xa980-\\xa982\\xa9b3\\xa9b6-\\xa9b9\\xa9bc\\xa9e5" - "\\xaa29-\\xaa2e\\xaa31\\xaa32\\xaa35\\xaa36\\xaa43\\xaa4c\\xaa7c" - "\\xaab0\\xaab2-\\xaab4\\xaab7\\xaab8\\xaabe\\xaabf\\xaac1" - "\\xaaec\\xaaed\\xaaf6\\xabe5\\xabe8\\xabed\\xfb1e\\xfe00-\\xfe0f" - "\\xfe20-\\xfe2f\\x101fd\\x102e0\\x10376-\\x1037a\\x10a01-\\x10a03" - "\\x10a05\\x10a06\\x10a0c-\\x10a0f\\x10a38-\\x10a3a\\x10a3f" - "\\x10ae5\\x10ae6\\x11001\\x11038-\\x11046\\x1107f-\\x11081" - "\\x110b3-\\x110b6\\x110b9\\x110ba\\x11100-\\x11102" - "\\x11127-\\x1112b\\x1112d-\\x11134\\x11173\\x11180\\x11181" - "\\x111b6-\\x111be\\x111ca-\\x111cc\\x1122f-\\x11231\\x11234" - "\\x11236\\x11237\\x112df\\x112e3-\\x112ea\\x11300\\x11301\\x1133c" - "\\x11340\\x11366-\\x1136c\\x11370-\\x11374\\x114b3-\\x114b8" - "\\x114ba\\x114bf\\x114c0\\x114c2\\x114c3\\x115b2-\\x115b5" - "\\x115bc\\x115bd\\x115bf\\x115c0\\x115dc\\x115dd\\x11633-\\x1163a" - "\\x1163d\\x1163f\\x11640\\x116ab\\x116ad\\x116b0-\\x116b5\\x116b7" - "\\x1171d-\\x1171f\\x11722-\\x11725\\x11727-\\x1172b" - "\\x16af0-\\x16af4\\x16b30-\\x16b36\\x16f8f-\\x16f92" - "\\x1bc9d\\x1bc9e\\x1d167-\\x1d169\\x1d17b-\\x1d182" - "\\x1d185-\\x1d18b\\x1d1aa-\\x1d1ad\\x1d242-\\x1d244" - "\\x1da00-\\x1da36\\x1da3b-\\x1da6c\\x1da75\\x1da84" - "\\x1da9b-\\x1da9f\\x1daa1-\\x1daaf\\x1e8d0-\\x1e8d6" - "\\xe0100-\\xe01ef]"; - } - - static const char *number_decimal() - { - return "[\\x30-\\x39\\x660-\\x669\\x6f0-\\x6f9\\x7c0-\\x7c9" - "\\x966-\\x96f\\x9e6-\\x9ef\\xa66-\\xa6f\\xae6-\\xaef\\xb66-\\xb6f" - "\\xbe6-\\xbef\\xc66-\\xc6f\\xce6-\\xcef\\xd66-\\xd6f\\xde6-\\xdef" - "\\xe50-\\xe59\\xed0-\\xed9\\xf20-\\xf29\\x1040-\\x1049" - "\\x1090-\\x1099\\x17e0-\\x17e9\\x1810-\\x1819\\x1946-\\x194f" - "\\x19d0-\\x19d9\\x1a80-\\x1a89\\x1a90-\\x1a99\\x1b50-\\x1b59" - "\\x1bb0-\\x1bb9\\x1c40-\\x1c49\\x1c50-\\x1c59\\xa620-\\xa629" - "\\xa8d0-\\xa8d9\\xa900-\\xa909\\xa9d0-\\xa9d9\\xa9f0-\\xa9f9" - "\\xaa50-\\xaa59\\xabf0-\\xabf9\\xff10-\\xff19\\x104a0-\\x104a9" - "\\x11066-\\x1106f\\x110f0-\\x110f9\\x11136-\\x1113f" - "\\x111d0-\\x111d9\\x112f0-\\x112f9\\x114d0-\\x114d9" - "\\x11650-\\x11659\\x116c0-\\x116c9\\x11730-\\x11739" - "\\x118e0-\\x118e9\\x16a60-\\x16a69\\x16b50-\\x16b59" - "\\x1d7ce-\\x1d7ff]"; - } - - static const char *number_letter() - { - return "[\\x16ee-\\x16f0\\x2160-\\x2182\\x2185-\\x2188\\x3007" - "\\x3021-\\x3029\\x3038-\\x303a\\xa6e6-\\xa6ef\\x10140-\\x10174" - "\\x10341\\x1034a\\x103d1-\\x103d5\\x12400-\\x1246e]"; - } - - static const char *number_other() - { - return "[\\xb2\\xb3\\xb9\\xbc-\\xbe\\x9f4-\\x9f9\\xb72-\\xb77" - "\\xbf0-\\xbf2\\xc78-\\xc7e\\xd70-\\xd75\\xf2a-\\xf33" - "\\x1369-\\x137c\\x17f0-\\x17f9\\x19da\\x2070\\x2074-\\x2079" - "\\x2080-\\x2089\\x2150-\\x215f\\x2189\\x2460-\\x249b" - "\\x24ea-\\x24ff\\x2776-\\x2793\\x2cfd\\x3192-\\x3195" - "\\x3220-\\x3229\\x3248-\\x324f\\x3251-\\x325f\\x3280-\\x3289" - "\\x32b1-\\x32bf\\xa830-\\xa835\\x10107-\\x10133\\x10175-\\x10178" - "\\x1018a\\x1018b\\x102e1-\\x102fb\\x10320-\\x10323" - "\\x10858-\\x1085f\\x10879-\\x1087f\\x108a7-\\x108af" - "\\x108fb-\\x108ff\\x10916-\\x1091b\\x109bc\\x109bd" - "\\x109c0-\\x109cf\\x109d2-\\x109ff\\x10a40-\\x10a47" - "\\x10a7d\\x10a7e\\x10a9d-\\x10a9f\\x10aeb-\\x10aef" - "\\x10b58-\\x10b5f\\x10b78-\\x10b7f\\x10ba9-\\x10baf" - "\\x10cfa-\\x10cff\\x10e60-\\x10e7e\\x11052-\\x11065" - "\\x111e1-\\x111f4\\x1173a\\x1173b\\x118ea-\\x118f2" - "\\x16b5b-\\x16b61\\x1d360-\\x1d371\\x1e8c7-\\x1e8cf" - "\\x1f100-\\x1f10c]"; - } - - static const char *punctuation_connector() - { - return "[\\x5f\\x203f\\x2040\\x2054\\xfe33\\xfe34\\xfe4d-\\xfe4f" - "\\xff3f]"; - } - - static const char *punctuation_dash() - { - return "[\\x2d\\x58a\\x5be\\x1400\\x1806\\x2010-\\x2015\\x2e17\\x2e1a" - "\\x2e3a\\x2e3b\\x2e40\\x301c\\x3030\\x30a0\\xfe31\\xfe32\\xfe58" - "\\xfe63\\xff0d]"; - } - - static const char *punctuation_close() - { - return "[\\x29\\x5d\\x7d\\xf3b\\xf3d\\x169c\\x2046\\x207e\\x208e\\x2309" - "\\x230b\\x232a\\x2769\\x276b\\x276d\\x276f\\x2771\\x2773\\x2775" - "\\x27c6\\x27e7\\x27e9\\x27eb\\x27ed\\x27ef\\x2984\\x2986\\x2988" - "\\x298a\\x298c\\x298e\\x2990\\x2992\\x2994\\x2996\\x2998\\x29d9" - "\\x29db\\x29fd\\x2e23\\x2e25\\x2e27\\x2e29\\x3009\\x300b\\x300d" - "\\x300f\\x3011\\x3015\\x3017\\x3019\\x301b\\x301e\\x301f\\xfd3e" - "\\xfe18\\xfe36\\xfe38\\xfe3a\\xfe3c\\xfe3e\\xfe40\\xfe42\\xfe44" - "\\xfe48\\xfe5a\\xfe5c\\xfe5e\\xff09\\xff3d\\xff5d\\xff60\\xff63]"; - } - - static const char *punctuation_final() - { - return "[\\xbb\\x2019\\x201d\\x203a\\x2e03\\x2e05\\x2e0a\\x2e0d\\x2e1d" - "\\x2e21]"; - } - - static const char *punctuation_initial() - { - return "[\\xab\\x2018\\x201b\\x201c\\x201f\\x2039\\x2e02\\x2e04\\x2e09" - "\\x2e0c\\x2e1c\\x2e20]"; - } - - static const char *punctuation_other() - { - return "[\\x21-\\x23\\x25-\\x27\\x2a\\x2c\\x2e\\x2f\\x3a\\x3b\\x3f\\x40" - "\\x5c\\xa1\\xa7\\xb6\\xb7\\xbf\\x37e\\x387\\x55a-\\x55f\\x589" - "\\x5c0\\x5c3\\x5c6\\x5f3\\x5f4\\x609\\x60a\\x60c\\x60d\\x61b" - "\\x61e\\x61f\\x66a-\\x66d\\x6d4\\x700-\\x70d\\x7f7-\\x7f9" - "\\x830-\\x83e\\x85e\\x964\\x965\\x970\\xaf0\\xdf4\\xe4f" - "\\xe5a\\xe5b\\xf04-\\xf12\\xf14\\xf85\\xfd0-\\xfd4\\xfd9\\xfda" - "\\x104a-\\x104f\\x10fb\\x1360-\\x1368\\x166d\\x166e\\x16eb-\\x16ed" - "\\x1735\\x1736\\x17d4-\\x17d6\\x17d8-\\x17da\\x1800-\\x1805" - "\\x1807-\\x180a\\x1944\\x1945\\x1a1e\\x1a1f\\x1aa0-\\x1aa6" - "\\x1aa8-\\x1aad\\x1b5a-\\x1b60\\x1bfc-\\x1bff\\x1c3b-\\x1c3f" - "\\x1c7e\\x1c7f\\x1cc0-\\x1cc7\\x1cd3\\x2016\\x2017\\x2020-\\x2027" - "\\x2030-\\x2038\\x203b-\\x203e\\x2041-\\x2043\\x2047-\\x2051" - "\\x2053\\x2055-\\x205e\\x2cf9-\\x2cfc\\x2cfe\\x2cff\\x2d70" - "\\x2e00\\x2e01\\x2e06-\\x2e08\\x2e0b\\x2e0e-\\x2e16\\x2e18\\x2e19" - "\\x2e1b\\x2e1e\\x2e1f\\x2e2a-\\x2e2e\\x2e30-\\x2e39\\x2e3c-\\x2e3f" - "\\x2e41\\x3001-\\x3003\\x303d\\x30fb\\xa4fe\\xa4ff\\xa60d-\\xa60f" - "\\xa673\\xa67e\\xa6f2-\\xa6f7\\xa874-\\xa877\\xa8ce\\xa8cf" - "\\xa8f8-\\xa8fa\\xa8fc\\xa92e\\xa92f\\xa95f\\xa9c1-\\xa9cd" - "\\xa9de\\xa9df\\xaa5c-\\xaa5f\\xaade\\xaadf\\xaaf0\\xaaf1\\xabeb" - "\\xfe10-\\xfe16\\xfe19\\xfe30\\xfe45\\xfe46\\xfe49-\\xfe4c" - "\\xfe50-\\xfe52\\xfe54-\\xfe57\\xfe5f-\\xfe61\\xfe68\\xfe6a\\xfe6b" - "\\xff01-\\xff03\\xff05-\\xff07\\xff0a\\xff0c\\xff0e\\xff0f" - "\\xff1a\\xff1b\\xff1f\\xff20\\xff3c\\xff61\\xff64\\xff65" - "\\x10100-\\x10102\\x1039f\\x103d0\\x1056f\\x10857\\x1091f\\x1093f" - "\\x10a50-\\x10a58\\x10a7f\\x10af0-\\x10af6\\x10b39-\\x10b3f" - "\\x10b99-\\x10b9c\\x11047-\\x1104d\\x110bb\\x110bc" - "\\x110be-\\x110c1\\x11140-\\x11143\\x11174\\x11175" - "\\x111c5-\\x111c9\\x111cd\\x111db\\x111dd-\\x111df" - "\\x11238-\\x1123d\\x112a9\\x114c6\\x115c1-\\x115d7" - "\\x11641-\\x11643\\x1173c-\\x1173e\\x12470-\\x12474" - "\\x16a6e\\x16a6f\\x16af5\\x16b37-\\x16b3b\\x16b44\\x1bc9f" - "\\x1da87-\\x1da8b]"; - } - - static const char *punctuation_open() - { - return "[\\x28\\x5b\\x7b\\xf3a\\xf3c\\x169b\\x201a\\x201e\\x2045\\x207d" - "\\x208d\\x2308\\x230a\\x2329\\x2768\\x276a\\x276c\\x276e\\x2770" - "\\x2772\\x2774\\x27c5\\x27e6\\x27e8\\x27ea\\x27ec\\x27ee\\x2983" - "\\x2985\\x2987\\x2989\\x298b\\x298d\\x298f\\x2991\\x2993\\x2995" - "\\x2997\\x29d8\\x29da\\x29fc\\x2e22\\x2e24\\x2e26\\x2e28\\x2e42" - "\\x3008\\x300a\\x300c\\x300e\\x3010\\x3014\\x3016\\x3018\\x301a" - "\\x301d\\xfd3f\\xfe17\\xfe35\\xfe37\\xfe39\\xfe3b\\xfe3d\\xfe3f" - "\\xfe41\\xfe43\\xfe47\\xfe59\\xfe5b\\xfe5d\\xff08\\xff3b\\xff5b" - "\\xff5f\\xff62]"; - } - - static const char *symbol_currency() - { - return "[\\x24\\xa2-\\xa5\\x58f\\x60b\\x9f2\\x9f3\\x9fb\\xaf1\\xbf9" - "\\xe3f\\x17db\\x20a0-\\x20be\\xa838\\xfdfc\\xfe69\\xff04" - "\\xffe0\\xffe1\\xffe5\\xffe6]"; - } - - static const char *symbol_modifier() - { - return "[\\x5e\\x60\\xa8\\xaf\\xb4\\xb8\\x2c2-\\x2c5\\x2d2-\\x2df" - "\\x2e5-\\x2eb\\x2ed\\x2ef-\\x2ff\\x375\\x384\\x385\\x1fbd" - "\\x1fbf-\\x1fc1\\x1fcd-\\x1fcf\\x1fdd-\\x1fdf\\x1fed-\\x1fef" - "\\x1ffd\\x1ffe\\x309b\\x309c\\xa700-\\xa716\\xa720\\xa721" - "\\xa789\\xa78a\\xab5b\\xfbb2-\\xfbc1\\xff3e\\xff40\\xffe3" - "\\x1f3fb-\\x1f3ff]"; - } - - static const char *symbol_math() - { - return "[\\x2b\\x3c-\\x3e\\x7c\\x7e\\xac\\xb1\\xd7\\xf7\\x3f6" - "\\x606-\\x608\\x2044\\x2052\\x207a-\\x207c\\x208a-\\x208c\\x2118" - "\\x2140-\\x2144\\x214b\\x2190-\\x2194\\x219a\\x219b\\x21a0\\x21a3" - "\\x21a6\\x21ae\\x21ce\\x21cf\\x21d2\\x21d4\\x21f4-\\x22ff" - "\\x2320\\x2321\\x237c\\x239b-\\x23b3\\x23dc-\\x23e1\\x25b7\\x25c1" - "\\x25f8-\\x25ff\\x266f\\x27c0-\\x27c4\\x27c7-\\x27e5" - "\\x27f0-\\x27ff\\x2900-\\x2982\\x2999-\\x29d7\\x29dc-\\x29fb" - "\\x29fe-\\x2aff\\x2b30-\\x2b44\\x2b47-\\x2b4c\\xfb29\\xfe62" - "\\xfe64-\\xfe66\\xff0b\\xff1c-\\xff1e\\xff5c\\xff5e\\xffe2" - "\\xffe9-\\xffec\\x1d6c1\\x1d6db\\x1d6fb\\x1d715\\x1d735\\x1d74f" - "\\x1d76f\\x1d789\\x1d7a9\\x1d7c3\\x1eef0\\x1eef1]"; - } - - static const char *symbol_other() - { - return "[\\xa6\\xa9\\xae\\xb0\\x482\\x58d\\x58e\\x60e\\x60f\\x6de\\x6e9" - "\\x6fd\\x6fe\\x7f6\\x9fa\\xb70\\xbf3-\\xbf8\\xbfa\\xc7f\\xd79" - "\\xf01-\\xf03\\xf13\\xf15-\\xf17\\xf1a-\\xf1f\\xf34\\xf36\\xf38" - "\\xfbe-\\xfc5\\xfc7-\\xfcc\\xfce\\xfcf\\xfd5-\\xfd8\\x109e\\x109f" - "\\x1390-\\x1399\\x1940\\x19de-\\x19ff\\x1b61-\\x1b6a" - "\\x1b74-\\x1b7c\\x2100\\x2101\\x2103-\\x2106\\x2108\\x2109\\x2114" - "\\x2116\\x2117\\x211e-\\x2123\\x2125\\x2127\\x2129\\x212e" - "\\x213a\\x213b\\x214a\\x214c\\x214d\\x214f\\x218a\\x218b" - "\\x2195-\\x2199\\x219c-\\x219f\\x21a1\\x21a2\\x21a4\\x21a5" - "\\x21a7-\\x21ad\\x21af-\\x21cd\\x21d0\\x21d1\\x21d3\\x21d5-\\x21f3" - "\\x2300-\\x2307\\x230c-\\x231f\\x2322-\\x2328\\x232b-\\x237b" - "\\x237d-\\x239a\\x23b4-\\x23db\\x23e2-\\x23fa\\x2400-\\x2426" - "\\x2440-\\x244a\\x249c-\\x24e9\\x2500-\\x25b6\\x25b8-\\x25c0" - "\\x25c2-\\x25f7\\x2600-\\x266e\\x2670-\\x2767\\x2794-\\x27bf" - "\\x2800-\\x28ff\\x2b00-\\x2b2f\\x2b45\\x2b46\\x2b4d-\\x2b73" - "\\x2b76-\\x2b95\\x2b98-\\x2bb9\\x2bbd-\\x2bc8\\x2bca-\\x2bd1" - "\\x2bec-\\x2bef\\x2ce5-\\x2cea\\x2e80-\\x2e99\\x2e9b-\\x2ef3" - "\\x2f00-\\x2fd5\\x2ff0-\\x2ffb\\x3004\\x3012\\x3013\\x3020" - "\\x3036\\x3037\\x303e\\x303f\\x3190\\x3191\\x3196-\\x319f" - "\\x31c0-\\x31e3\\x3200-\\x321e\\x322a-\\x3247\\x3250" - "\\x3260-\\x327f\\x328a-\\x32b0\\x32c0-\\x32fe\\x3300-\\x33ff" - "\\x4dc0-\\x4dff\\xa490-\\xa4c6\\xa828-\\xa82b\\xa836\\xa837\\xa839" - "\\xaa77-\\xaa79\\xfdfd\\xffe4\\xffe8\\xffed\\xffee\\xfffc\\xfffd" - "\\x10137-\\x1013f\\x10179-\\x10189\\x1018c\\x10190-\\x1019b" - "\\x101a0\\x101d0-\\x101fc\\x10877\\x10878\\x10ac8\\x1173f" - "\\x16b3c-\\x16b3f\\x16b45\\x1bc9c\\x1d000-\\x1d0f5" - "\\x1d100-\\x1d126\\x1d129-\\x1d164\\x1d16a-\\x1d16c" - "\\x1d183\\x1d184\\x1d18c-\\x1d1a9\\x1d1ae-\\x1d1e8" - "\\x1d200-\\x1d241\\x1d245\\x1d300-\\x1d356\\x1d800-\\x1d9ff" - "\\x1da37-\\x1da3a\\x1da6d-\\x1da74\\x1da76-\\x1da83" - "\\x1da85\\x1da86\\x1f000-\\x1f02b\\x1f030-\\x1f093" - "\\x1f0a0-\\x1f0ae\\x1f0b1-\\x1f0bf\\x1f0c1-\\x1f0cf" - "\\x1f0d1-\\x1f0f5\\x1f110-\\x1f12e\\x1f130-\\x1f16b" - "\\x1f170-\\x1f19a\\x1f1e6-\\x1f202\\x1f210-\\x1f23a" - "\\x1f240-\\x1f248\\x1f250\\x1f251\\x1f300-\\x1f3fa" - "\\x1f400-\\x1f579\\x1f57b-\\x1f5a3\\x1f5a5-\\x1f6d0" - "\\x1f6e0-\\x1f6ec\\x1f6f0-\\x1f6f3\\x1f700-\\x1f773" - "\\x1f780-\\x1f7d4\\x1f800-\\x1f80b\\x1f810-\\x1f847" - "\\x1f850-\\x1f859\\x1f860-\\x1f887\\x1f890-\\x1f8ad" - "\\x1f910-\\x1f918\\x1f980-\\x1f984\\x1f9c0]"; - } - - static const char *separator_line() - { - return "[\\x2028]"; - } - - static const char *separator_paragraph() - { - return "[\\x2029]"; - } - - static const char *separator_space() - { - return "[\\x20\\xa0\\x1680\\x2000-\\x200a\\x202f\\x205f\\x3000]"; - } - - template - static input_char_type decode_octal(state_type &state_) - { - std::size_t oct_ = 0; - auto ch_ = *state_._curr; - unsigned short count_ = 3; - bool eos_ = false; - - for (;;) - { - oct_ *= 8; - oct_ += ch_ - '0'; - --count_; - state_.increment(); - eos_ = state_.eos(); - - if (!count_ || eos_) break; - - ch_ = *state_._curr; - - // Don't consume invalid chars! - if (ch_ < '0' || ch_ > '7') - { - break; - } - } - - if (oct_ > static_cast(char_traits::max_val())) - { - std::ostringstream ss_; - - ss_ << "Escape \\" << std::oct << oct_ << - " is too big for the state machine char type " - "preceding index " << std::dec << state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - return static_cast(oct_); - } - - template - static input_char_type decode_control_char(state_type &state_) - { - // Skip over 'c' - state_.increment(); - - typename state_type::char_type ch_ = 0; - bool eos_ = state_.next(ch_); - - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following \\c"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - else - { - if (ch_ >= 'a' && ch_ <= 'z') - { - ch_ -= 'a' - 1; - } - else if (ch_ >= 'A' && ch_ <= 'Z') - { - ch_ -= 'A' - 1; - } - else if (ch_ == '@') - { - // Apparently... - ch_ = 0; - } - else - { - std::ostringstream ss_; - - ss_ << "Invalid control char at index " << - state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - - return ch_; - } - - template - static input_char_type decode_hex(state_type &state_) - { - // Skip over 'x' - state_.increment(); - - typename state_type::char_type ch_ = 0; - bool eos_ = state_.next(ch_); - - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following \\x"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - if (!((ch_ >= '0' && ch_ <= '9') || (ch_ >= 'a' && ch_ <= 'f') || - (ch_ >= 'A' && ch_ <= 'F'))) - { - std::ostringstream ss_; - - ss_ << "Illegal char following \\x at index " << - state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - std::size_t hex_ = 0; - - do - { - hex_ *= 16; - - if (ch_ >= '0' && ch_ <= '9') - { - hex_ += ch_ - '0'; - } - else if (ch_ >= 'a' && ch_ <= 'f') - { - hex_ += 10 + (ch_ - 'a'); - } - else - { - hex_ += 10 + (ch_ - 'A'); - } - - eos_ = state_.eos(); - - if (!eos_) - { - ch_ = *state_._curr; - - // Don't consume invalid chars! - if (((ch_ >= '0' && ch_ <= '9') || - (ch_ >= 'a' && ch_ <= 'f') || (ch_ >= 'A' && ch_ <= 'F'))) - { - state_.increment(); - } - else - { - eos_ = true; - } - } - } while (!eos_); - - if (hex_ > static_cast(char_traits::max_val())) - { - std::ostringstream ss_; - - ss_ << "Escape \\x" << std::hex << hex_ << - " is too big for the state machine char type " << - "preceding index " << - std::dec << state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - return static_cast(hex_); - } - - template - static void charset_range(const bool chset_, state_type &state_, - bool &eos_, typename state_type::char_type &ch_, - const input_char_type prev_, string_token &chars_) - { - if (chset_) - { - std::ostringstream ss_; - - ss_ << "Charset cannot form start of range preceding " - "index " << state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - eos_ = state_.next(ch_); - - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " following '-'"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - input_char_type curr_ = 0; - - if (ch_ == '\\') - { - std::size_t str_len_ = 0; - - if (escape_sequence(state_, curr_, str_len_)) - { - std::ostringstream ss_; - - ss_ << "Charset cannot form end of range preceding index " - << state_.index(); - state_.error(ss_); - throw runtime_error(ss_.str()); - } - } - else if (ch_ == '[' && !state_.eos() && *state_._curr == ':') - { - std::ostringstream ss_; - - ss_ << "POSIX char class cannot form end of range at " - "index " << state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - else - { - curr_ = ch_; - } - - eos_ = state_.next(ch_); - - // Covers preceding if and else - if (eos_) - { - std::ostringstream ss_; - - // Pointless returning index if at end of string - state_.unexpected_end(ss_); - ss_ << " (missing ']')"; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - // Use index_type as char is generally signed - // and we want to ignore signedness. - auto start_ = static_cast(prev_); - auto end_ = static_cast(curr_); - - // Semanic check - if (end_ < start_) - { - std::ostringstream ss_; - - ss_ << "Max less than Min in charset range preceding index " << - state_.index() - 1; - state_.error(ss_); - throw runtime_error(ss_.str()); - } - - // Even though ranges are used now, we still need to consider - // each character if icase is set. - if (state_._flags & icase) - { - range range_(start_, end_); - string_token folded_; - - chars_.insert(range_); - fold(range_, state_._locale, folded_, - size()); - - if (!folded_.empty()) - { - chars_.insert(folded_); - } - } - else - { - chars_.insert(range(prev_, curr_)); - } - } -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_state.hpp b/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_state.hpp deleted file mode 100644 index 1d41ea5ca..000000000 --- a/YACReaderLibrary/lexertl/parser/tokeniser/re_tokeniser_state.hpp +++ /dev/null @@ -1,136 +0,0 @@ -// tokeniser_state.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_RE_TOKENISER_STATE_HPP -#define LEXERTL_RE_TOKENISER_STATE_HPP - -#include "../../char_traits.hpp" -#include "../../enums.hpp" -#include -#include "../../narrow.hpp" -#include - -namespace lexertl -{ -namespace detail -{ -template -struct basic_re_tokeniser_state -{ - using char_type = ch_type; - using index_type = typename basic_char_traits::index_type; - - const char_type * const _start; - const char_type * const _end; - const char_type *_curr; - id_type _id; - std::size_t _flags; - std::stack _flags_stack; - std::locale _locale; - const char_type *_macro_name; - long _paren_count; - bool _in_string; - id_type _nl_id; - - basic_re_tokeniser_state(const char_type *start_, - const char_type * const end_, id_type id_, const std::size_t flags_, - const std::locale locale_, const char_type *macro_name_) : - _start(start_), - _end(end_), - _curr(start_), - _id(id_), - _flags(flags_), - _flags_stack(), - _locale(locale_), - _macro_name(macro_name_), - _paren_count(0), - _in_string(false), - _nl_id(static_cast(~0)) - { - } - - basic_re_tokeniser_state(const basic_re_tokeniser_state &rhs_) - { - assign(rhs_); - } - - // prevent VC++ 7.1 warning: - const basic_re_tokeniser_state &operator = - (const basic_re_tokeniser_state &rhs_) - { - return assign(rhs_); - } - - basic_re_tokeniser_state &assign(const basic_re_tokeniser_state &rhs_) - { - _start = rhs_._start; - _end = rhs_._end; - _curr = rhs_._curr; - _id = rhs_._id; - _flags = rhs_._flags; - _flags_stack = rhs_._flags_stack; - _locale = rhs_._locale; - _macro_name = rhs_._macro_name; - _paren_count = rhs_._paren_count; - _in_string = rhs_._in_string; - _nl_id = rhs_._nl_id; - return *this; - } - - inline bool next(char_type &ch_) - { - if (_curr >= _end) - { - ch_ = 0; - return true; - } - else - { - ch_ = *_curr; - increment(); - return false; - } - } - - inline void increment() - { - ++_curr; - } - - inline std::size_t index() - { - return _curr - _start; - } - - inline bool eos() - { - return _curr >= _end; - } - - inline void unexpected_end(std::ostringstream &ss_) - { - ss_ << "Unexpected end of regex"; - } - - inline void error(std::ostringstream &ss_) - { - ss_ << " in "; - - if (_macro_name) - { - ss_ << "MACRO '"; - narrow(_macro_name, ss_); - ss_ << "'."; - } - else - { - ss_ << "rule id " << _id << '.'; - } - } -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/parser/tree/end_node.hpp b/YACReaderLibrary/lexertl/parser/tree/end_node.hpp deleted file mode 100644 index c485fca52..000000000 --- a/YACReaderLibrary/lexertl/parser/tree/end_node.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// end_node.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_END_NODE_HPP -#define LEXERTL_END_NODE_HPP - -#include "node.hpp" - -namespace lexertl -{ -namespace detail -{ -template -class basic_end_node : public basic_node -{ -public: - using node = basic_node; - using bool_stack = typename node::bool_stack; - using const_node_stack = typename node::const_node_stack; - using node_ptr_vector = typename node::node_ptr_vector; - using node_stack = typename node::node_stack; - using node_type = typename node::node_type; - using node_vector = typename node::node_vector; - - basic_end_node(const id_type id_, const id_type user_id_, - const id_type next_dfa_, const id_type push_dfa_, - const bool pop_dfa_) : - node(false), - _id(id_), - _user_id(user_id_), - _next_dfa(next_dfa_), - _push_dfa(push_dfa_), - _pop_dfa(pop_dfa_), - _followpos() - { - node::_firstpos.push_back(this); - node::_lastpos.push_back(this); - } - - virtual ~basic_end_node() override - { - } - - virtual node_type what_type() const override - { - return node::END; - } - - virtual bool traverse(const_node_stack &/*node_stack_*/, - bool_stack &/*perform_op_stack_*/) const override - { - return false; - } - - virtual const node_vector &followpos() const override - { - // _followpos is always empty..! - return _followpos; - } - - virtual bool end_state() const override - { - return true; - } - - virtual id_type id() const override - { - return _id; - } - - virtual id_type user_id() const override - { - return _user_id; - } - - virtual id_type next_dfa() const override - { - return _next_dfa; - } - - virtual id_type push_dfa() const override - { - return _push_dfa; - } - - virtual bool pop_dfa() const override - { - return _pop_dfa; - } - -private: - id_type _id; - id_type _user_id; - id_type _next_dfa; - id_type _push_dfa; - bool _pop_dfa; - node_vector _followpos; - - virtual void copy_node(node_ptr_vector &/*node_ptr_vector_*/, - node_stack &/*new_node_stack_*/, bool_stack &/*perform_op_stack_*/, - bool &/*down_*/) const override - { - // Nothing to do, as end_nodes are not copied. - } -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/parser/tree/iteration_node.hpp b/YACReaderLibrary/lexertl/parser/tree/iteration_node.hpp deleted file mode 100644 index 41baba7e3..000000000 --- a/YACReaderLibrary/lexertl/parser/tree/iteration_node.hpp +++ /dev/null @@ -1,96 +0,0 @@ -// iteration_node.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_ITERATION_NODE_HPP -#define LEXERTL_ITERATION_NODE_HPP - -#include "node.hpp" - -namespace lexertl -{ -namespace detail -{ -template -class basic_iteration_node : public basic_node -{ -public: - using node = basic_node; - using bool_stack = typename node::bool_stack; - using const_node_stack = typename node::const_node_stack; - using node_ptr_vector = typename node::node_ptr_vector; - using node_stack = typename node::node_stack; - using node_type = typename node::node_type; - using node_vector = typename node::node_vector; - - basic_iteration_node(observer_ptr next_, const bool greedy_) : - node(true), - _next(next_), - _greedy(greedy_) - { - _next->append_firstpos(node::_firstpos); - _next->append_lastpos(node::_lastpos); - - for (observer_ptr node_ : node::_lastpos) - { - node_->append_followpos(node::_firstpos); - } - - for (observer_ptr node_ : node::_firstpos) - { - node_->greedy(greedy_); - } - } - - virtual ~basic_iteration_node() override - { - } - - virtual node_type what_type() const override - { - return node::ITERATION; - } - - virtual bool traverse(const_node_stack &node_stack_, - bool_stack &perform_op_stack_) const override - { - perform_op_stack_.push(true); - node_stack_.push(_next); - return true; - } - -private: - observer_ptr _next; - bool _greedy; - - virtual void copy_node(node_ptr_vector &node_ptr_vector_, - node_stack &new_node_stack_, bool_stack &perform_op_stack_, - bool &down_) const override - { - if (perform_op_stack_.top()) - { - observer_ptr ptr_ = new_node_stack_.top(); - - node_ptr_vector_.emplace_back - (std::make_unique(ptr_, _greedy)); - new_node_stack_.top() = node_ptr_vector_.back().get(); - } - else - { - down_ = true; - } - - perform_op_stack_.pop(); - } - - // No copy construction. - basic_iteration_node(const basic_iteration_node &) = delete; - // No assignment. - const basic_iteration_node &operator = - (const basic_iteration_node &) = delete; -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/parser/tree/leaf_node.hpp b/YACReaderLibrary/lexertl/parser/tree/leaf_node.hpp deleted file mode 100644 index ef1b485e4..000000000 --- a/YACReaderLibrary/lexertl/parser/tree/leaf_node.hpp +++ /dev/null @@ -1,110 +0,0 @@ -// leaf_node.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_LEAF_NODE_HPP -#define LEXERTL_LEAF_NODE_HPP - -#include "../../enums.hpp" // null_token -#include "node.hpp" - -namespace lexertl -{ -namespace detail -{ -template -class basic_leaf_node : public basic_node -{ -public: - using node = basic_node; - using bool_stack = typename node::bool_stack; - using const_node_stack = typename node::const_node_stack; - using node_ptr_vector = typename node::node_ptr_vector; - using node_stack = typename node::node_stack; - using node_type = typename node::node_type; - using node_vector = typename node::node_vector; - - basic_leaf_node(const id_type token_, const bool greedy_) : - node(token_ == node::null_token()), - _token(token_), - _set_greedy(!greedy_), - _greedy(greedy_), - _followpos() - { - if (!node::_nullable) - { - node::_firstpos.push_back(this); - node::_lastpos.push_back(this); - } - } - - virtual ~basic_leaf_node() override - { - } - - virtual void append_followpos(const node_vector &followpos_) override - { - _followpos.insert(_followpos.end(), - followpos_.begin(), followpos_.end()); - } - - virtual node_type what_type() const override - { - return node::LEAF; - } - - virtual bool traverse(const_node_stack &/*node_stack_*/, - bool_stack &/*perform_op_stack_*/) const override - { - return false; - } - - virtual id_type token() const override - { - return _token; - } - - virtual void greedy(const bool greedy_) override - { - if (!_set_greedy) - { - _greedy = greedy_; - _set_greedy = true; - } - } - - virtual bool greedy() const override - { - return _greedy; - } - - virtual const node_vector &followpos() const override - { - return _followpos; - } - - virtual node_vector &followpos() override - { - return _followpos; - } - -private: - id_type _token; - bool _set_greedy; - bool _greedy; - node_vector _followpos; - - virtual void copy_node(node_ptr_vector &node_ptr_vector_, - node_stack &new_node_stack_, bool_stack &/*perform_op_stack_*/, - bool &/*down_*/) const override - { - node_ptr_vector_.emplace_back(std::make_unique - (_token, _greedy)); - new_node_stack_.push(node_ptr_vector_.back().get()); - } -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/parser/tree/node.hpp b/YACReaderLibrary/lexertl/parser/tree/node.hpp deleted file mode 100644 index cee7729a3..000000000 --- a/YACReaderLibrary/lexertl/parser/tree/node.hpp +++ /dev/null @@ -1,242 +0,0 @@ -// node.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_NODE_HPP -#define LEXERTL_NODE_HPP - -#include -#include -#include "../../observer_ptr.hpp" -#include "../../runtime_error.hpp" -#include -#include - -namespace lexertl -{ -namespace detail -{ -template -class basic_node -{ -public: - enum node_type {LEAF, SEQUENCE, SELECTION, ITERATION, END}; - - using bool_stack = std::stack; - using node_stack = std::stack>; - using const_node_stack = std::stack>; - using node_vector = std::vector>; - using node_ptr_vector = std::vector>; - - basic_node() : - _nullable(false), - _firstpos(), - _lastpos() - { - } - - basic_node(const bool nullable_) : - _nullable(nullable_), - _firstpos(), - _lastpos() - { - } - - virtual ~basic_node() - { - } - - static id_type null_token() - { - return static_cast(~0); - } - - bool nullable() const - { - return _nullable; - } - - void append_firstpos(node_vector &firstpos_) const - { - firstpos_.insert(firstpos_.end(), - _firstpos.begin(), _firstpos.end()); - } - - void append_lastpos(node_vector &lastpos_) const - { - lastpos_.insert(lastpos_.end(), - _lastpos.begin(), _lastpos.end()); - } - - virtual void append_followpos(const node_vector &/*followpos_*/) - { - throw runtime_error("Internal error node::append_followpos()."); - } - - observer_ptr copy(node_ptr_vector &node_ptr_vector_) const - { - observer_ptr new_root_ = nullptr; - const_node_stack node_stack_; - bool_stack perform_op_stack_; - bool down_ = true; - node_stack new_node_stack_; - - node_stack_.push(this); - - while (!node_stack_.empty()) - { - while (down_) - { - down_ = node_stack_.top()->traverse(node_stack_, - perform_op_stack_); - } - - while (!down_ && !node_stack_.empty()) - { - observer_ptr top_ = node_stack_.top(); - - top_->copy_node(node_ptr_vector_, new_node_stack_, - perform_op_stack_, down_); - - if (!down_) node_stack_.pop(); - } - } - - assert(new_node_stack_.size() == 1); - new_root_ = new_node_stack_.top(); - new_node_stack_.pop(); - return new_root_; - } - - virtual node_type what_type() const = 0; - - virtual bool traverse(const_node_stack &node_stack_, - bool_stack &perform_op_stack_) const = 0; - - node_vector &firstpos() - { - return _firstpos; - } - - const node_vector &firstpos() const - { - return _firstpos; - } - - // _lastpos modified externally, so not const & - node_vector &lastpos() - { - return _lastpos; - } - - virtual bool end_state() const - { - return false; - } - - virtual id_type id() const - { - throw runtime_error("Internal error node::id()."); -#ifdef __SUNPRO_CC - // Stop bogus Solaris compiler warning - return id_type(); -#endif - } - - virtual id_type user_id() const - { - throw runtime_error("Internal error node::user_id()."); -#ifdef __SUNPRO_CC - // Stop bogus Solaris compiler warning - return id_type(); -#endif - } - - virtual id_type next_dfa() const - { - throw runtime_error("Internal error node::next_dfa()."); -#ifdef __SUNPRO_CC - // Stop bogus Solaris compiler warning - return id_type(); -#endif - } - - virtual id_type push_dfa() const - { - throw runtime_error("Internal error node::push_dfa()."); -#ifdef __SUNPRO_CC - // Stop bogus Solaris compiler warning - return id_type(); -#endif - } - - virtual bool pop_dfa() const - { - throw runtime_error("Internal error node::pop_dfa()."); -#ifdef __SUNPRO_CC - // Stop bogus Solaris compiler warning - return false; -#endif - } - - virtual id_type token() const - { - throw runtime_error("Internal error node::token()."); -#ifdef __SUNPRO_CC - // Stop bogus Solaris compiler warning - return id_type(); -#endif - } - - virtual void greedy(const bool /*greedy_*/) - { - throw runtime_error("Internal error node::greedy(bool)."); - } - - virtual bool greedy() const - { - throw runtime_error("Internal error node::greedy()."); -#ifdef __SUNPRO_CC - // Stop bogus Solaris compiler warning - return false; -#endif - } - - virtual const node_vector &followpos() const - { - throw runtime_error("Internal error node::followpos()."); -#ifdef __SUNPRO_CC - // Stop bogus Solaris compiler warning - return firstpos; -#endif - } - - virtual node_vector &followpos() - { - throw runtime_error("Internal error node::followpos()."); -#ifdef __SUNPRO_CC - // Stop bogus Solaris compiler warning - return firstpos; -#endif - } - -protected: - const bool _nullable; - node_vector _firstpos; - node_vector _lastpos; - - virtual void copy_node(node_ptr_vector &node_ptr_vector_, - node_stack &new_node_stack_, bool_stack &perform_op_stack_, - bool &down_) const = 0; - -private: - // No copy construction. - basic_node(const basic_node &) = delete; - // No assignment. - const basic_node &operator =(const basic_node &) = delete; -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/parser/tree/selection_node.hpp b/YACReaderLibrary/lexertl/parser/tree/selection_node.hpp deleted file mode 100644 index 603bbc68d..000000000 --- a/YACReaderLibrary/lexertl/parser/tree/selection_node.hpp +++ /dev/null @@ -1,104 +0,0 @@ -// selection_node.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_SELECTION_NODE_HPP -#define LEXERTL_SELECTION_NODE_HPP - -#include "node.hpp" - -namespace lexertl -{ -namespace detail -{ -template -class basic_selection_node : public basic_node -{ -public: - using node = basic_node; - using bool_stack = typename node::bool_stack; - using const_node_stack = typename node::const_node_stack; - using node_ptr_vector = typename node::node_ptr_vector; - using node_stack = typename node::node_stack; - using node_type = typename node::node_type; - - basic_selection_node(observer_ptr left_, observer_ptr right_) : - node(left_->nullable() || right_->nullable()), - _left(left_), - _right(right_) - { - _left->append_firstpos(node::_firstpos); - _right->append_firstpos(node::_firstpos); - _left->append_lastpos(node::_lastpos); - _right->append_lastpos(node::_lastpos); - } - - virtual ~basic_selection_node() override - { - } - - virtual node_type what_type() const override - { - return node::SELECTION; - } - - virtual bool traverse(const_node_stack &node_stack_, - bool_stack &perform_op_stack_) const override - { - perform_op_stack_.push(true); - - switch (_right->what_type()) - { - case node::SEQUENCE: - case node::SELECTION: - case node::ITERATION: - perform_op_stack_.push(false); - break; - default: - break; - } - - node_stack_.push(_right); - node_stack_.push(_left); - return true; - } - -private: - observer_ptr _left; - observer_ptr _right; - - virtual void copy_node(node_ptr_vector &node_ptr_vector_, - node_stack &new_node_stack_, bool_stack &perform_op_stack_, - bool &down_) const override - { - if (perform_op_stack_.top()) - { - observer_ptr rhs_ = new_node_stack_.top(); - - new_node_stack_.pop(); - - observer_ptr lhs_ = new_node_stack_.top(); - - node_ptr_vector_.emplace_back - (std::make_unique(lhs_, rhs_)); - new_node_stack_.top() = node_ptr_vector_.back().get(); - } - else - { - down_ = true; - } - - perform_op_stack_.pop(); - } - - // No copy construction. - basic_selection_node(const basic_selection_node &) = delete; - // No assignment. - const basic_selection_node &operator = - (const basic_selection_node &) = delete; -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/parser/tree/sequence_node.hpp b/YACReaderLibrary/lexertl/parser/tree/sequence_node.hpp deleted file mode 100644 index 222767350..000000000 --- a/YACReaderLibrary/lexertl/parser/tree/sequence_node.hpp +++ /dev/null @@ -1,121 +0,0 @@ -// sequence_node.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_SEQUENCE_NODE_HPP -#define LEXERTL_SEQUENCE_NODE_HPP - -#include "node.hpp" - -namespace lexertl -{ -namespace detail -{ -template -class basic_sequence_node : public basic_node -{ -public: - using node = basic_node; - using bool_stack = typename node::bool_stack; - using const_node_stack = typename node::const_node_stack; - using node_ptr_vector = typename node::node_ptr_vector; - using node_stack = typename node::node_stack; - using node_type = typename node::node_type; - using node_vector = typename node::node_vector; - - basic_sequence_node(observer_ptr left_, observer_ptr right_) : - node(left_->nullable() && right_->nullable()), - _left(left_), - _right(right_) - { - _left->append_firstpos(node::_firstpos); - - if (_left->nullable()) - { - _right->append_firstpos(node::_firstpos); - } - - if (_right->nullable()) - { - _left->append_lastpos(node::_lastpos); - } - - _right->append_lastpos(node::_lastpos); - - node_vector &lastpos_ = _left->lastpos(); - const node_vector &firstpos_ = _right->firstpos(); - - for (observer_ptr node_ : lastpos_) - { - node_->append_followpos(firstpos_); - } - } - - virtual ~basic_sequence_node() override - { - } - - virtual node_type what_type() const override - { - return node::SEQUENCE; - } - - virtual bool traverse(const_node_stack &node_stack_, - bool_stack &perform_op_stack_) const override - { - perform_op_stack_.push(true); - - switch (_right->what_type()) - { - case node::SEQUENCE: - case node::SELECTION: - case node::ITERATION: - perform_op_stack_.push(false); - break; - default: - break; - } - - node_stack_.push(_right); - node_stack_.push(_left); - return true; - } - -private: - observer_ptr _left; - observer_ptr _right; - - virtual void copy_node(node_ptr_vector &node_ptr_vector_, - node_stack &new_node_stack_, bool_stack &perform_op_stack_, - bool &down_) const override - { - if (perform_op_stack_.top()) - { - observer_ptr rhs_ = new_node_stack_.top(); - - new_node_stack_.pop(); - - observer_ptr lhs_ = new_node_stack_.top(); - - node_ptr_vector_.emplace_back - (std::make_unique(lhs_, rhs_)); - new_node_stack_.top() = node_ptr_vector_.back().get(); - } - else - { - down_ = true; - } - - perform_op_stack_.pop(); - } - - // No copy construction. - basic_sequence_node(const basic_sequence_node &) = delete; - // No assignment. - const basic_sequence_node &operator =(const basic_sequence_node &) = delete; -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/partition/charset.hpp b/YACReaderLibrary/lexertl/partition/charset.hpp deleted file mode 100644 index 2bfbd3358..000000000 --- a/YACReaderLibrary/lexertl/partition/charset.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// charset.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LEXERTL_CHARSET_HPP -#define LEXERTL_CHARSET_HPP - -#include -#include -#include -#include "../string_token.hpp" - -namespace lexertl -{ -namespace detail -{ -template -struct basic_charset -{ - using token = basic_string_token; - using index_set = std::set; - - token _token; - index_set _index_set; - - basic_charset() : - _token(), - _index_set() - { - } - - basic_charset(const token &token_, const id_type index_) : - _token(token_), - _index_set() - { - _index_set.insert(index_); - } - - bool empty() const - { - return _token.empty() && _index_set.empty(); - } - - void intersect(basic_charset &rhs_, basic_charset &overlap_) - { - _token.intersect(rhs_._token, overlap_._token); - - if (!overlap_._token.empty()) - { - std::merge(_index_set.begin(), _index_set.end(), - rhs_._index_set.begin(), rhs_._index_set.end(), - std::inserter(overlap_._index_set, - overlap_._index_set.end())); - - if (_token.empty()) - { - _index_set.clear(); - } - - if (rhs_._token.empty()) - { - rhs_._index_set.clear(); - } - } - } -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/partition/equivset.hpp b/YACReaderLibrary/lexertl/partition/equivset.hpp deleted file mode 100644 index af709b03f..000000000 --- a/YACReaderLibrary/lexertl/partition/equivset.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// equivset.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_EQUIVSET_HPP -#define LEXERTL_EQUIVSET_HPP - -#include -#include "../parser/tree/node.hpp" -#include - -namespace lexertl -{ -namespace detail -{ -template -struct basic_equivset -{ - using index_set = std::set; - using index_vector = std::vector; - using node = basic_node; - using node_vector = std::vector>; - - index_vector _index_vector; - id_type _id; - bool _greedy; - node_vector _followpos; - - basic_equivset() : - _index_vector(), - _id(0), - _greedy(true), - _followpos() - { - } - - basic_equivset(const index_set &index_set_, const id_type id_, - const bool greedy_, const node_vector &followpos_) : - _index_vector(index_set_.begin(), index_set_.end()), - _id(id_), - _greedy(greedy_), - _followpos(followpos_) - { - } - - bool empty() const - { - return _index_vector.empty() && _followpos.empty(); - } - - void intersect(basic_equivset &rhs_, basic_equivset &overlap_) - { - intersect_indexes(rhs_._index_vector, overlap_._index_vector); - - if (!overlap_._index_vector.empty()) - { - // Note that the LHS takes priority in order to - // respect rule ordering priority in the lex spec. - overlap_._id = _id; - overlap_._greedy = _greedy; - overlap_._followpos = _followpos; - - auto overlap_begin_ = overlap_._followpos.cbegin(); - auto overlap_end_ = overlap_._followpos.cend(); - - for (observer_ptr node_ : rhs_._followpos) - { - if (std::find(overlap_begin_, overlap_end_, node_) == - overlap_end_) - { - overlap_._followpos.push_back(node_); - overlap_begin_ = overlap_._followpos.begin(); - overlap_end_ = overlap_._followpos.end(); - } - } - - if (_index_vector.empty()) - { - _followpos.clear(); - } - - if (rhs_._index_vector.empty()) - { - rhs_._followpos.clear(); - } - } - } - -private: - void intersect_indexes(index_vector &rhs_, index_vector &overlap_) - { - std::set_intersection(_index_vector.begin(), _index_vector.end(), - rhs_.begin(), rhs_.end(), std::back_inserter(overlap_)); - - if (!overlap_.empty()) - { - remove(overlap_, _index_vector); - remove(overlap_, rhs_); - } - } - - void remove(const index_vector &source_, index_vector &dest_) - { - auto inter_ = source_.begin(); - auto inter_end_ = source_.end(); - auto reader_ = std::find(dest_.begin(), dest_.end(), *inter_); - auto writer_ = reader_; - auto dest_end_ = dest_.end(); - - while (writer_ != dest_end_ && inter_ != inter_end_) - { - if (*reader_ == *inter_) - { - ++inter_; - ++reader_; - } - else - { - *writer_++ = *reader_++; - } - } - - while (reader_ != dest_end_) - { - *writer_++ = *reader_++; - } - - dest_.resize(dest_.size() - source_.size()); - } -}; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/rules.hpp b/YACReaderLibrary/lexertl/rules.hpp deleted file mode 100644 index c5b29e0bd..000000000 --- a/YACReaderLibrary/lexertl/rules.hpp +++ /dev/null @@ -1,1018 +0,0 @@ -// rules.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_RULES_HPP -#define LEXERTL_RULES_HPP - -#include "enums.hpp" -#include -#include -#include "narrow.hpp" -#include "observer_ptr.hpp" -#include "parser/tokeniser/re_tokeniser.hpp" -#include "runtime_error.hpp" -#include -#include -#include -#include - -namespace lexertl -{ -template -class basic_rules -{ -public: - using bool_vector = std::vector; - using bool_vector_vector = std::vector; - using char_type = ch_type; - using rules_char_type = r_ch_type; - using id_type = id_ty; - using id_vector = std::vector; - using id_vector_vector = std::vector; - using re_state = detail::basic_re_tokeniser_state; - using string = std::basic_string; - using string_token = basic_string_token; - using string_vector = std::vector; - using string_set = std::set; - using string_pair = std::pair; - using string_id_type_map = std::map; - using string_id_type_pair = std::pair; - using token = detail::basic_re_token; - using token_vector = std::vector; - using token_vector_vector = std::vector; - using token_vector_vector_vector = std::vector; - using macro_map = std::map; - using macro_pair = std::pair; - using tokeniser = - detail::basic_re_tokeniser; - - // If you get a compile error here you have - // failed to define an unsigned id type. - static_assert(std::is_unsigned::value, "Your id type is signed"); - -#ifdef _WIN32 - basic_rules(const std::size_t flags_ = dot_not_cr_lf) : -#else - basic_rules(const std::size_t flags_ = dot_not_newline) : -#endif - _statemap(), - _macro_map(), - _regexes(), - _features(), - _ids(), - _user_ids(), - _next_dfas(), - _pushes(), - _pops(), - _flags(flags_), - _locale(), - _lexer_state_names() - { - push_state(initial()); - } - - void clear() - { - _statemap.clear(); - _macro_map.clear(); - _regexes.clear(); - _features.clear(); - _ids.clear(); - _user_ids.clear(); - _next_dfas.clear(); - _pushes.clear(); - _pops.clear(); -#ifdef _WIN32 - _flags = dot_not_cr_lf; -#else - _flags = dot_not_newline; -#endif - _locale = std::locale(); - _lexer_state_names.clear(); - push_state(initial()); - } - - void clear(const id_type dfa_) - { - if (_regexes.size() > dfa_) - { - _regexes[dfa_].clear(); - _features[dfa_] = 0; - _ids[dfa_].clear(); - _user_ids[dfa_].clear(); - _next_dfas[dfa_].clear(); - _pushes[dfa_].clear(); - _pops[dfa_].clear(); - } - } - - void flags(const std::size_t flags_) - { - _flags = flags_; - } - - std::size_t flags() const - { - return _flags; - } - - static id_type skip() - { - return static_cast(~1); - } - - id_type eoi() const - { - return 0; - } - - static id_type npos() - { - return static_cast(~0); - } - - std::locale imbue(const std::locale &locale_) - { - std::locale loc_ = _locale; - - _locale = locale_; - return loc_; - } - - const std::locale &locale() const - { - return _locale; - } - - const rules_char_type *state(const id_type index_) const - { - if (index_ == 0) - { - return initial(); - } - else - { - const id_type i_ = index_ - 1; - - if (_lexer_state_names.size() > i_) - { - return _lexer_state_names[i_].c_str(); - } - else - { - return 0; - } - } - } - - id_type state(const rules_char_type *name_) const - { - typename string_id_type_map::const_iterator iter_ = - _statemap.find(name_); - - if (iter_ == _statemap.end()) - { - return npos(); - } - else - { - return iter_->second; - } - } - - id_type push_state(const rules_char_type *name_) - { - validate(name_); - - if (_statemap.insert(string_id_type_pair(name_, - static_cast(_statemap.size()))).second) - { - _regexes.push_back(token_vector_vector()); - _features.push_back(0); - _ids.push_back(id_vector()); - _user_ids.push_back(id_vector()); - _next_dfas.push_back(id_vector()); - _pushes.push_back(id_vector()); - _pops.push_back(bool_vector()); - - if (string(name_) != initial()) - { - _lexer_state_names.push_back(name_); - } - } - else - { - return _statemap.find(name_)->second; - } - - if (_next_dfas.size() > npos()) - { - // Overflow - throw runtime_error("The data type you have chosen cannot hold " - "this many lexer start states."); - } - - // Initial is not stored, so no need to - 1. - return static_cast(_lexer_state_names.size()); - } - - void insert_macro(const rules_char_type *name_, - const rules_char_type *regex_) - { - insert_macro(name_, string(regex_)); - } - - void insert_macro(const rules_char_type *name_, - const rules_char_type *regex_start_, - const rules_char_type *regex_end_) - { - insert_macro(name_, string(regex_start_, regex_end_)); - } - - void insert_macro(const rules_char_type *name_, const string ®ex_) - { - validate(name_); - - typename macro_map::const_iterator iter_ = _macro_map.find(name_); - - if (iter_ == _macro_map.end()) - { - auto pair_ = _macro_map.insert(macro_pair(name_, token_vector())); - - tokenise(regex_, pair_.first->second, npos(), name_); - } - else - { - std::ostringstream ss_; - - ss_ << "Attempt to redefine MACRO '"; - narrow(name_, ss_); - ss_ << "'."; - throw runtime_error(ss_.str()); - } - } - - // Add rule to INITIAL - void push(const rules_char_type *regex_, const id_type id_, - const id_type user_id_ = npos()) - { - push(string(regex_), id_, user_id_); - } - - void push(const rules_char_type *regex_start_, - const rules_char_type *regex_end_, - const id_type id_, const id_type user_id_ = npos()) - { - push(string(regex_start_, regex_end_), id_, user_id_); - } - - void push(const string ®ex_, const id_type id_, - const id_type user_id_ = npos()) - { - check_for_invalid_id(id_); - _regexes.front().push_back(token_vector()); - tokenise(regex_, _regexes.front().back(), id_, 0); - - if (regex_[0] == '^') - { - _features.front() |= bol_bit; - } - - if (regex_.size() > 0 && regex_[regex_.size() - 1] == '$') - { - _features.front() |= eol_bit; - } - - if (id_ == skip()) - { - _features.front() |= skip_bit; - } - else if (id_ == eoi()) - { - _features.front() |= again_bit; - } - - _ids.front().push_back(id_); - _user_ids.front().push_back(user_id_); - _next_dfas.front().push_back(0); - _pushes.front().push_back(npos()); - _pops.front().push_back(false); - } - - // Add rule with no id - void push(const rules_char_type *curr_dfa_, - const rules_char_type *regex_, const rules_char_type *new_dfa_) - { - push(curr_dfa_, string(regex_), new_dfa_); - } - - void push(const rules_char_type *curr_dfa_, - const rules_char_type *regex_start_, const rules_char_type *regex_end_, - const rules_char_type *new_dfa_) - { - push(curr_dfa_, string(regex_start_, regex_end_), new_dfa_); - } - - void push(const rules_char_type *curr_dfa_, const string ®ex_, - const rules_char_type *new_dfa_) - { - push(curr_dfa_, regex_, eoi(), new_dfa_, false); - } - - // Add rule with id - void push(const rules_char_type *curr_dfa_, - const rules_char_type *regex_, const id_type id_, - const rules_char_type *new_dfa_, const id_type user_id_ = npos()) - { - push(curr_dfa_, string(regex_), id_, new_dfa_, user_id_); - } - - void push(const rules_char_type *curr_dfa_, - const rules_char_type *regex_start_, - const rules_char_type *regex_end_, const id_type id_, - const rules_char_type *new_dfa_, const id_type user_id_ = npos()) - { - push(curr_dfa_, string(regex_start_, regex_end_), - id_, new_dfa_, user_id_); - } - - void push(const rules_char_type *curr_dfa_, const string ®ex_, - const id_type id_, const rules_char_type *new_dfa_, - const id_type user_id_ = npos()) - { - push(curr_dfa_, regex_, id_, new_dfa_, true, user_id_); - } - - void reverse() - { - for (auto &state_ : _regexes) - { - for (auto ®ex_ : state_) - { - reverse(regex_); - } - } - - for (auto &pair_ : _macro_map) - { - reverse(pair_.second); - } - } - - const string_id_type_map &statemap() const - { - return _statemap; - } - - const token_vector_vector_vector ®exes() const - { - return _regexes; - } - - const id_vector &features() const - { - return _features; - } - - const id_vector_vector &ids() const - { - return _ids; - } - - const id_vector_vector &user_ids() const - { - return _user_ids; - } - - const id_vector_vector &next_dfas() const - { - return _next_dfas; - } - - const id_vector_vector &pushes() const - { - return _pushes; - } - - const bool_vector_vector &pops() const - { - return _pops; - } - - bool empty() const - { - bool empty_ = true; - - for (const auto ®ex_ : _regexes) - { - if (!regex_.empty()) - { - empty_ = false; - break; - } - } - - return empty_; - } - - static const rules_char_type *initial() - { - static const rules_char_type initial_ [] = - { 'I', 'N', 'I', 'T', 'I', 'A', 'L', 0 }; - - return initial_; - } - - static const rules_char_type *dot() - { - static const rules_char_type dot_ [] = { '.', 0 }; - - return dot_; - } - - static const rules_char_type *all_states() - { - static const rules_char_type star_ [] = { '*', 0 }; - - return star_; - } - -private: - string_id_type_map _statemap; - macro_map _macro_map; - token_vector_vector_vector _regexes; - id_vector _features; - id_vector_vector _ids; - id_vector_vector _user_ids; - id_vector_vector _next_dfas; - id_vector_vector _pushes; - bool_vector_vector _pops; - std::size_t _flags; - std::locale _locale; - string_vector _lexer_state_names; - - void tokenise(const string ®ex_, token_vector &tokens_, - const id_type id_, const rules_char_type *name_) - { - re_state state_(regex_.c_str(), regex_.c_str() + regex_.size(), id_, - _flags, _locale, name_); - string macro_; - rules_char_type diff_ = 0; - - tokens_.push_back(token()); - - do - { - observer_ptr lhs_ = &tokens_.back(); - token rhs_; - - tokeniser::next(*lhs_, state_, rhs_); - - if (rhs_._type != detail::DIFF && - lhs_->precedence(rhs_._type) == ' ') - { - std::ostringstream ss_; - - ss_ << "A syntax error occurred: '" << - lhs_->precedence_string() << - "' against '" << rhs_.precedence_string() << - "' preceding index " << state_.index() << - " in "; - - if (name_ != 0) - { - ss_ << "macro "; - narrow(name_, ss_); - } - else - { - ss_ << "rule id " << state_._id; - } - - ss_ << '.'; - throw runtime_error(ss_.str()); - } - - if (rhs_._type == detail::MACRO) - { - typename macro_map::const_iterator iter_ = - _macro_map.find(rhs_._extra); - - macro_ = rhs_._extra; - - if (iter_ == _macro_map.end()) - { - const rules_char_type *rhs_name_ = rhs_._extra.c_str(); - std::ostringstream ss_; - - ss_ << "Unknown MACRO name '"; - narrow(rhs_name_, ss_); - ss_ << "'."; - throw runtime_error(ss_.str()); - } - else - { - const bool multiple_ = iter_->second.size() > 3; - - if (diff_) - { - if (multiple_) - { - std::ostringstream ss_; - - ss_ << "Single CHARSET must follow {-} or {+} at " - "index " << state_.index() - 1 << " in "; - - if (name_ != 0) - { - ss_ << "macro "; - narrow(name_, ss_); - } - else - { - ss_ << "rule id " << state_._id; - } - - ss_ << '.'; - throw runtime_error(ss_.str()); - } - else - { - rhs_ = iter_->second[1]; - } - } - - // Any macro with more than one charset (or quantifiers) - // requires bracketing. - if (multiple_) - { - token open_; - - open_._type = detail::OPENPAREN; - open_._str.insert('('); - tokens_.push_back(open_); - } - - // Don't need to store token if it is diff. - if (!diff_) - { - // Don't insert BEGIN or END tokens - tokens_.insert(tokens_.end(), iter_->second.begin() + 1, - iter_->second.end() - 1); - lhs_ = &tokens_.back(); - } - - if (multiple_) - { - token close_; - - close_._type = detail::CLOSEPAREN; - close_._str.insert(')'); - tokens_.push_back(close_); - } - } - } - else if (rhs_._type == detail::DIFF) - { - if (!macro_.empty()) - { - typename macro_map::const_iterator iter_ = - _macro_map.find(macro_); - - if (iter_->second.size() > 3) - { - std::ostringstream ss_; - - ss_ << "Single CHARSET must precede {-} or {+} at " - "index " << state_.index() - 1 << " in "; - - if (name_ != 0) - { - ss_ << "macro "; - narrow(name_, ss_); - } - else - { - ss_ << "rule id " << state_._id; - } - - ss_ << '.'; - throw runtime_error(ss_.str()); - } - } - - diff_ = rhs_._extra[0]; - macro_.clear(); - continue; - } - else if (!diff_) - { - tokens_.push_back(rhs_); - lhs_ = &tokens_.back(); - macro_.clear(); - } - - // diff_ may have been set by previous conditional. - if (diff_) - { - if (rhs_._type != detail::CHARSET) - { - std::ostringstream ss_; - - ss_ << "CHARSET must follow {-} or {+} at index " << - state_.index() - 1 << " in "; - - if (name_ != 0) - { - ss_ << "macro "; - narrow(name_, ss_); - } - else - { - ss_ << "rule id " << state_._id; - } - - ss_ << '.'; - throw runtime_error(ss_.str()); - } - - switch (diff_) - { - case '-': - lhs_->_str.remove(rhs_._str); - - if (lhs_->_str.empty()) - { - std::ostringstream ss_; - - ss_ << "Empty charset created by {-} at index " << - state_.index() - 1 << " in "; - - if (name_ != 0) - { - ss_ << "macro "; - narrow(name_, ss_); - } - else - { - ss_ << "rule id " << state_._id; - } - - ss_ << '.'; - throw runtime_error(ss_.str()); - } - - break; - case '+': - lhs_->_str.insert(rhs_._str); - break; - } - - diff_ = 0; - } - } while (tokens_.back()._type != detail::END); - - if (tokens_.size() == 2) - { - std::ostringstream ss_; - - ss_ << "Empty regex in "; - - if (name_ != 0) - { - ss_ << "macro "; - narrow(name_, ss_); - } - else - { - ss_ << "rule id " << state_._id; - } - - ss_ << " is not allowed."; - throw runtime_error(ss_.str()); - } - } - - void reverse(token_vector &vector_) - { - token_vector new_vector_(vector_.size(), token()); - auto iter_ = vector_.rbegin(); - auto end_ = vector_.rend(); - auto dest_ = new_vector_.begin(); - std::stack stack_; - - for (; iter_ != end_; ++iter_, ++dest_) - { - switch (iter_->_type) - { - case detail::BEGIN: - iter_->swap(*dest_); - dest_->_type = detail::END; - break; - case detail::BOL: - iter_->swap(*dest_); - dest_->_type = detail::EOL; - break; - case detail::EOL: - iter_->swap(*dest_); - dest_->_type = detail::BOL; - break; - case detail::OPENPAREN: - iter_->swap(*dest_); - dest_->_type = detail::CLOSEPAREN; - - if (stack_.top() != end_) - { - ++dest_; - dest_->swap(*stack_.top()); - } - - stack_.pop(); - break; - case detail::CLOSEPAREN: - iter_->swap(*dest_); - dest_->_type = detail::OPENPAREN; - stack_.push(end_); - break; - case detail::OPT: - case detail::AOPT: - case detail::ZEROORMORE: - case detail::AZEROORMORE: - case detail::ONEORMORE: - case detail::AONEORMORE: - case detail::REPEATN: - case detail::AREPEATN: - { - auto temp_ = iter_ + 1; - - if (temp_->_type == detail::CLOSEPAREN) - { - stack_.push(iter_); - ++iter_; - iter_->swap(*dest_); - dest_->_type = detail::OPENPAREN; - } - else - { - dest_->swap(*temp_); - ++dest_; - dest_->swap(*iter_); - ++iter_; - } - - break; - } - case detail::END: - iter_->swap(*dest_); - dest_->_type = detail::BEGIN; - break; - default: - // detail::OR - // detail::CHARSET - iter_->swap(*dest_); - break; - } - } - - new_vector_.swap(vector_); - } - - void push(const rules_char_type *curr_dfa_, const string ®ex_, - const id_type id_, const rules_char_type *new_dfa_, - const bool check_, const id_type user_id_ = npos()) - { - const bool star_ = *curr_dfa_ == '*' && *(curr_dfa_ + 1) == 0; - const bool dot_ = *new_dfa_ == '.' && *(new_dfa_ + 1) == 0; - const bool push_ = *new_dfa_ == '>'; - const rules_char_type *push_dfa_ = nullptr; - const bool pop_ = *new_dfa_ == '<'; - - if (push_ || pop_) - { - ++new_dfa_; - } - - if (check_) - { - check_for_invalid_id(id_); - } - - if (!dot_ && !pop_) - { - const rules_char_type *temp_ = new_dfa_; - - while (*temp_ && *temp_ != ':') - { - ++temp_; - } - - if (*temp_) push_dfa_ = temp_ + 1; - - validate(new_dfa_, *temp_ ? temp_ : 0); - - if (push_dfa_) - { - validate(push_dfa_); - } - } - - // npos means pop here - id_type new_dfa_id_ = npos(); - id_type push_dfa_id_ = npos(); - typename string_id_type_map::const_iterator iter_; - auto end_ = _statemap.cend(); - id_vector next_dfas_; - - if (!dot_ && !pop_) - { - if (push_dfa_) - { - iter_ = _statemap.find(string(new_dfa_, push_dfa_ - 1)); - } - else - { - iter_ = _statemap.find(new_dfa_); - } - - if (iter_ == end_) - { - std::ostringstream ss_; - - ss_ << "Unknown state name '"; - narrow(new_dfa_, ss_); - ss_ << "'."; - throw runtime_error(ss_.str()); - } - - new_dfa_id_ = iter_->second; - - if (push_dfa_) - { - iter_ = _statemap.find(push_dfa_); - - if (iter_ == end_) - { - std::ostringstream ss_; - - ss_ << "Unknown state name '"; - narrow(push_dfa_, ss_); - ss_ << "'."; - throw runtime_error(ss_.str()); - } - - push_dfa_id_ = iter_->second; - } - } - - if (star_) - { - const std::size_t size_ = _statemap.size(); - - for (id_type i_ = 0; i_ < size_; ++i_) - { - next_dfas_.push_back(i_); - } - } - else - { - const rules_char_type *start_ = curr_dfa_; - string next_dfa_; - - while (*curr_dfa_) - { - while (*curr_dfa_ && *curr_dfa_ != ',') - { - ++curr_dfa_; - } - - next_dfa_.assign(start_, curr_dfa_); - - if (*curr_dfa_) - { - ++curr_dfa_; - start_ = curr_dfa_; - } - - validate(next_dfa_.c_str()); - iter_ = _statemap.find(next_dfa_.c_str()); - - if (iter_ == end_) - { - std::ostringstream ss_; - - ss_ << "Unknown state name '"; - curr_dfa_ = next_dfa_.c_str(); - narrow(curr_dfa_, ss_); - ss_ << "'."; - throw runtime_error(ss_.str()); - } - - next_dfas_.push_back(iter_->second); - } - } - - for (std::size_t i_ = 0, size_ = next_dfas_.size(); - i_ < size_; ++i_) - { - const id_type curr_ = next_dfas_[i_]; - - _regexes[curr_].push_back(token_vector()); - tokenise(regex_, _regexes[curr_].back(), id_, 0); - - if (regex_[0] == '^') - { - _features[curr_] |= bol_bit; - } - - if (regex_[regex_.size() - 1] == '$') - { - _features[curr_] |= eol_bit; - } - - if (id_ == skip()) - { - _features[curr_] |= skip_bit; - } - else if (id_ == eoi()) - { - _features[curr_] |= again_bit; - } - - if (push_ || pop_) - { - _features[curr_] |= recursive_bit; - } - - _ids[curr_].push_back(id_); - _user_ids[curr_].push_back(user_id_); - _next_dfas[curr_].push_back(dot_ ? curr_ : new_dfa_id_); - _pushes[curr_].push_back(push_ ? (push_dfa_ ? - push_dfa_id_ : curr_) : npos()); - _pops[curr_].push_back(pop_); - } - } - - void validate(const rules_char_type *name_, - const rules_char_type *end_ = nullptr) const - { - const rules_char_type *start_ = name_; - - if (*name_ != '_' && !(*name_ >= 'A' && *name_ <= 'Z') && - !(*name_ >= 'a' && *name_ <= 'z')) - { - std::ostringstream ss_; - - ss_ << "Invalid name '"; - narrow(name_, ss_); - ss_ << "'."; - throw runtime_error(ss_.str()); - } - else if (*name_) - { - ++name_; - } - - while (*name_ && name_ != end_) - { - if (*name_ != '_' && *name_ != '-' && - !(*name_ >= 'A' && *name_ <= 'Z') && - !(*name_ >= 'a' && *name_ <= 'z') && - !(*name_ >= '0' && *name_ <= '9')) - { - std::ostringstream ss_; - - ss_ << "Invalid name '"; - name_ = start_; - narrow(name_, ss_); - ss_ << "'."; - throw runtime_error(ss_.str()); - } - - ++name_; - } - } - - void check_for_invalid_id(const id_type id_) const - { - if (id_ == eoi()) - { - throw runtime_error("Cannot resuse the id for eoi."); - } - - if (id_ == npos()) - { - throw runtime_error("The id npos is reserved for the " - "UNKNOWN token."); - } - } -}; - -using rules = basic_rules; -using wrules = basic_rules; -using u32rules = basic_rules; -} - -#endif diff --git a/YACReaderLibrary/lexertl/runtime_error.hpp b/YACReaderLibrary/lexertl/runtime_error.hpp deleted file mode 100644 index 7c240118d..000000000 --- a/YACReaderLibrary/lexertl/runtime_error.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// runtime_error.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_RUNTIME_ERROR_HPP -#define LEXERTL_RUNTIME_ERROR_HPP - -#include - -namespace lexertl -{ -class runtime_error : public std::runtime_error -{ -public: - runtime_error(const std::string &what_arg_) : - std::runtime_error(what_arg_) - { - } -}; -} - -#endif diff --git a/YACReaderLibrary/lexertl/serialise.hpp b/YACReaderLibrary/lexertl/serialise.hpp deleted file mode 100644 index 931f519b9..000000000 --- a/YACReaderLibrary/lexertl/serialise.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// serialise.hpp -// Copyright (c) 2007-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_SERIALISE_HPP -#define LEXERTL_SERIALISE_HPP - -#include "state_machine.hpp" -#include - -namespace lexertl -{ -// IMPORTANT! This won't work if you don't enable RTTI! -template -void serialise(basic_state_machine &sm_, Archive &ar_) -{ - detail::basic_internals &internals_ = sm_.data(); - - ar_ & internals_._eoi; - ar_ & *internals_._lookup; - ar_ & internals_._dfa_alphabet; - ar_ & internals_._features; - ar_ & *internals_._dfa; -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/sm_to_csm.hpp b/YACReaderLibrary/lexertl/sm_to_csm.hpp deleted file mode 100644 index 5ffe69fee..000000000 --- a/YACReaderLibrary/lexertl/sm_to_csm.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// sm_to_csm.hpp -// Copyright (c) 2015-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_SM_TO_CSM_HPP -#define LEXERTL_SM_TO_CSM_HPP - -#include "enums.hpp" -#include "observer_ptr.hpp" -#include - -namespace lexertl -{ -template -void sm_to_csm(const sm &sm_, char_state_machine &csm_) -{ - using id_type = typename sm::traits::id_type; - using internals = typename sm::internals; - using string_token = typename char_state_machine::state::string_token; - using index_type = typename string_token::index_type; - using string_token_vector = - typename char_state_machine::string_token_vector; - const internals &internals_ = sm_.data(); - const std::size_t dfas_ = internals_._dfa.size(); - - for (id_type i_ = 0; i_ < dfas_; ++i_) - { - if (internals_._dfa_alphabet[i_] == 0) continue; - - const std::size_t alphabet_ = internals_._dfa_alphabet[i_] - - transitions_index; - string_token_vector token_vector_(alphabet_, string_token()); - observer_ptr ptr_ = &internals_._lookup[i_].front(); - - for (std::size_t c_ = 0; c_ < 256; ++c_, ++ptr_) - { - if (*ptr_ >= transitions_index) - { - string_token &token_ = token_vector_ - [*ptr_ - transitions_index]; - - token_.insert(typename string_token::range - (index_type(c_), index_type(c_))); - } - } - - csm_.append(token_vector_, internals_, i_); - } -} -} - -#endif diff --git a/YACReaderLibrary/lexertl/sm_traits.hpp b/YACReaderLibrary/lexertl/sm_traits.hpp deleted file mode 100644 index 161b29c9c..000000000 --- a/YACReaderLibrary/lexertl/sm_traits.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// sm_traits.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LEXERTL_SM_TRAITS_HPP -#define LEXERTL_SM_TRAITS_HPP - -namespace lexertl -{ -template -struct basic_sm_traits -{ - enum {char_24_bit = sizeof(ch_type) > 2, compressed = comp, lookup = look, - is_dfa = dfa_nfa}; - using input_char_type = ch_type; - using char_type = ch_type; - using id_type = sm_type; - - static id_type npos() - { - return static_cast(~0); - } -}; - -template -struct basic_sm_traits -{ - enum {char_24_bit = sizeof(ch_type) > 2, compressed = true, lookup = look, - is_dfa = dfa_nfa}; - using input_char_type = ch_type; - using char_type = unsigned char; - using id_type = sm_type; - - static id_type npos() - { - return static_cast(~0); - } -}; -} - -#endif diff --git a/YACReaderLibrary/lexertl/state_machine.hpp b/YACReaderLibrary/lexertl/state_machine.hpp deleted file mode 100644 index 76e7bc31c..000000000 --- a/YACReaderLibrary/lexertl/state_machine.hpp +++ /dev/null @@ -1,521 +0,0 @@ -// state_machine.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_STATE_MACHINE_HPP -#define LEXERTL_STATE_MACHINE_HPP - -// memcmp() -#include -#include "internals.hpp" -#include -#include "observer_ptr.hpp" -#include -#include "sm_traits.hpp" -#include "string_token.hpp" - -namespace lexertl -{ -template -class basic_state_machine -{ -public: - using id_type = id_ty; - using traits = - basic_sm_traits 1), true, true>; - using internals = detail::basic_internals; - - // If you get a compile error here you have - // failed to define an unsigned id type. - static_assert(std::is_unsigned::value, "Your id type is signed"); - - basic_state_machine() : - _internals() - { - } - - void clear() - { - _internals.clear(); - } - - internals &data() - { - return _internals; - } - - const internals &data() const - { - return _internals; - } - - bool empty() const - { - return _internals.empty(); - } - - id_type eoi() const - { - return _internals._eoi; - } - - void minimise() - { - const id_type dfas_ = static_cast(_internals._dfa.size()); - - for (id_type i_ = 0; i_ < dfas_; ++i_) - { - const id_type dfa_alphabet_ = _internals._dfa_alphabet[i_]; - id_type_vector &dfa_ = _internals._dfa[i_]; - - if (dfa_alphabet_ != 0) - { - std::size_t size_ = 0; - - do - { - size_ = dfa_.size(); - minimise_dfa(dfa_alphabet_, dfa_, size_); - } while (dfa_.size() != size_); - } - } - } - - static id_type npos() - { - return static_cast(~0); - } - - static id_type skip() - { - return static_cast(~1); - } - - void swap(basic_state_machine &rhs_) - { - _internals.swap(rhs_._internals); - } - -private: - using id_type_vector = typename internals::id_type_vector; - using index_set = std::set; - internals _internals; - - void minimise_dfa(const id_type dfa_alphabet_, - id_type_vector &dfa_, std::size_t size_) - { - observer_ptr first_ = &dfa_.front(); - observer_ptr end_ = first_ + size_; - id_type index_ = 1; - id_type new_index_ = 1; - id_type_vector lookup_(size_ / dfa_alphabet_, npos()); - observer_ptr lookup_ptr_ = &lookup_.front(); - index_set index_set_; - const id_type bol_index_ = dfa_.front(); - - *lookup_ptr_ = 0; - // Only one 'jam' state, so skip it. - first_ += dfa_alphabet_; - - for (; first_ < end_; first_ += dfa_alphabet_, ++index_) - { - observer_ptr second_ = first_ + dfa_alphabet_; - - for (id_type curr_index_ = index_ + 1; second_ < end_; - ++curr_index_, second_ += dfa_alphabet_) - { - if (index_set_.find(curr_index_) != index_set_.end()) - { - continue; - } - - // Some systems have memcmp in namespace std. - using namespace std; - - if (memcmp(first_, second_, sizeof(id_type) * - dfa_alphabet_) == 0) - { - index_set_.insert(curr_index_); - lookup_ptr_[curr_index_] = new_index_; - } - } - - if (lookup_ptr_[index_] == npos()) - { - lookup_ptr_[index_] = new_index_; - ++new_index_; - } - } - - if (!index_set_.empty()) - { - observer_ptr front_ = &dfa_.front(); - id_type_vector new_dfa_(front_, front_ + dfa_alphabet_); - auto set_end_ = index_set_.cend(); - observer_ptr ptr_ = front_ + dfa_alphabet_; - observer_ptr new_ptr_ = nullptr; - - new_dfa_.resize(size_ - index_set_.size() * dfa_alphabet_, 0); - new_ptr_ = &new_dfa_.front() + dfa_alphabet_; - size_ /= dfa_alphabet_; - - if (bol_index_) - { - new_dfa_.front() = lookup_ptr_[bol_index_]; - } - - for (index_ = 1; index_ < size_; ++index_) - { - if (index_set_.find(index_) != set_end_) - { - ptr_ += dfa_alphabet_; - continue; - } - - new_ptr_[end_state_index] = ptr_[end_state_index]; - new_ptr_[id_index] = ptr_[id_index]; - new_ptr_[user_id_index] = ptr_[user_id_index]; - new_ptr_[push_dfa_index] = ptr_[push_dfa_index]; - new_ptr_[next_dfa_index] = ptr_[next_dfa_index]; - new_ptr_[eol_index] = lookup_ptr_[ptr_[eol_index]]; - new_ptr_ += transitions_index; - ptr_ += transitions_index; - - for (id_type i_ = transitions_index; i_ < dfa_alphabet_; ++i_) - { - *new_ptr_++ = lookup_ptr_[*ptr_++]; - } - } - - dfa_.swap(new_dfa_); - } - } -}; - -using state_machine = basic_state_machine; -using wstate_machine = basic_state_machine; -using u32state_machine = basic_state_machine; - -template -struct basic_char_state_machine -{ - using id_type = id_ty; - using traits = basic_sm_traits; - using internals = detail::basic_internals; - using id_type_vector = typename internals::id_type_vector; - - struct state - { - using string_token = basic_string_token; - using id_type_string_token_map = std::map; - using id_type_string_token_pair = std::pair; - enum push_pop_dfa {neither, push_dfa, pop_dfa}; - - bool _end_state; - push_pop_dfa _push_pop_dfa; - id_type _id; - id_type _user_id; - id_type _push_dfa; - id_type _next_dfa; - id_type _eol_index; - id_type_string_token_map _transitions; - - state() : - _end_state(false), - _push_pop_dfa(neither), - _id(0), - _user_id(traits::npos()), - _push_dfa(traits::npos()), - _next_dfa(0), - _eol_index(traits::npos()), - _transitions() - { - } - - bool operator ==(const state rhs_) const - { - return _end_state == rhs_._end_state && - _push_pop_dfa == rhs_._push_pop_dfa && - _id == rhs_._id && - _user_id == rhs_._user_id && - _push_dfa == rhs_._push_dfa && - _next_dfa == rhs_._next_dfa && - _eol_index == rhs_._eol_index && - _transitions == rhs_._transitions; - } - }; - - using string_token = typename state::string_token; - using state_vector = std::vector; - using string_token_vector = std::vector; - using id_type_string_token_pair = - typename state::id_type_string_token_pair; - - struct dfa - { - id_type _bol_index; - state_vector _states; - - dfa(const std::size_t size_) : - _bol_index(traits::npos()), - _states(state_vector(size_)) - { - } - - std::size_t size() const - { - return _states.size(); - } - - void swap(dfa &rhs_) - { - std::swap(_bol_index, rhs_._bol_index); - _states.swap(rhs_._states); - } - }; - - static_assert(std::is_move_assignable::value && - std::is_move_constructible::value, "dfa is not movable."); - using dfa_vector = std::vector; - - static_assert(std::is_unsigned::value, "Your id type is signed"); - dfa_vector _sm_vector; - - basic_char_state_machine() : - _sm_vector() - { - } - - void append(const string_token_vector &token_vector_, - const internals &internals_, const id_type dfa_index_) - { - const std::size_t dfa_alphabet_ = internals_._dfa_alphabet[dfa_index_]; - const std::size_t alphabet_ = dfa_alphabet_ - transitions_index; - const id_type_vector &source_dfa_ = internals_._dfa[dfa_index_]; - observer_ptr ptr_ = &source_dfa_.front(); - const std::size_t size_ = (source_dfa_.size() - dfa_alphabet_) / - dfa_alphabet_; - typename state::id_type_string_token_map::iterator trans_iter_; - - _sm_vector.push_back(dfa(size_)); - - dfa &dest_dfa_ = _sm_vector.back(); - - if (*ptr_) - { - dest_dfa_._bol_index = *ptr_ - 1; - } - - ptr_ += dfa_alphabet_; - - for (id_type i_ = 0; i_ < size_; ++i_) - { - state &state_ = dest_dfa_._states[i_]; - - state_._end_state = ptr_[end_state_index] != 0; - - if (ptr_[push_dfa_index] != npos()) - { - state_._push_pop_dfa = state::push_dfa; - } - else if (ptr_[end_state_index] & pop_dfa_bit) - { - state_._push_pop_dfa = state::pop_dfa; - } - - state_._id = ptr_[id_index]; - state_._user_id = ptr_[user_id_index]; - state_._push_dfa = ptr_[push_dfa_index]; - state_._next_dfa = ptr_[next_dfa_index]; - - if (ptr_[eol_index]) - { - state_._eol_index = ptr_[eol_index] - 1; - } - - ptr_ += transitions_index; - - for (id_type col_index_ = 0; col_index_ < alphabet_; - ++col_index_, ++ptr_) - { - const id_type next_ = *ptr_; - - if (next_ > 0) - { - trans_iter_ = state_._transitions.find(next_ - 1); - - if (trans_iter_ == state_._transitions.end()) - { - trans_iter_ = state_._transitions.insert - (id_type_string_token_pair(static_cast - (next_ - 1), token_vector_[col_index_])).first; - } - else - { - trans_iter_->second.insert(token_vector_[col_index_]); - } - } - } - } - } - - void clear() - { - _sm_vector.clear(); - } - - bool empty() const - { - return _sm_vector.empty(); - } - - void minimise() - { - const id_type dfas_ = static_cast(_sm_vector.size()); - - for (id_type i_ = 0; i_ < dfas_; ++i_) - { - observer_ptr dfa_ = &_sm_vector[i_]; - - if (dfa_->size() > 0) - { - std::size_t size_ = 0; - - do - { - size_ = dfa_->size(); - minimise_dfa(*dfa_, size_); - } while (dfa_->size() != size_); - } - } - } - - static id_type npos() - { - return traits::npos(); - } - - id_type size() const - { - return static_cast(_sm_vector.size()); - } - - static id_type skip() - { - return ~static_cast(1); - } - - void swap(basic_char_state_machine &csm_) - { - _sm_vector.swap(csm_._sm_vector); - } - -private: - using index_set = std::set; - - void minimise_dfa(dfa &dfa_, std::size_t size_) - { - observer_ptr first_ = &dfa_._states.front(); - observer_ptr end_ = first_ + size_; - id_type index_ = 0; - id_type new_index_ = 0; - id_type_vector lookup_(size_, npos()); - observer_ptr lookup_ptr_ = &lookup_.front(); - index_set index_set_; - - for (; first_ != end_; ++first_, ++index_) - { - observer_ptr second_ = first_ + 1; - - for (id_type curr_index_ = index_ + 1; second_ != end_; - ++curr_index_, ++second_) - { - if (index_set_.find(curr_index_) != index_set_.end()) - { - continue; - } - - if (*first_ == *second_) - { - index_set_.insert(curr_index_); - lookup_ptr_[curr_index_] = new_index_; - } - } - - if (lookup_ptr_[index_] == npos()) - { - lookup_ptr_[index_] = new_index_; - ++new_index_; - } - } - - if (!index_set_.empty()) - { - observer_ptr front_ = &dfa_._states.front(); - dfa new_dfa_(new_index_); - auto set_end_ = index_set_.cend(); - observer_ptr ptr_ = front_; - observer_ptr new_ptr_ = &new_dfa_._states.front(); - - if (dfa_._bol_index != npos()) - { - new_dfa_._bol_index = lookup_ptr_[dfa_._bol_index]; - } - - for (index_ = 0; index_ < size_; ++index_) - { - if (index_set_.find(index_) != set_end_) - { - ++ptr_; - continue; - } - - new_ptr_->_end_state = ptr_->_end_state; - new_ptr_->_id = ptr_->_end_state; - new_ptr_->_user_id = ptr_->_user_id; - new_ptr_->_next_dfa = ptr_->_next_dfa; - - if (ptr_->_eol_index != npos()) - { - new_ptr_->_eol_index = lookup_ptr_[ptr_->_eol_index]; - } - - auto iter_ = ptr_->_transitions.cbegin(); - auto end_ = ptr_->_transitions.cend(); - typename state::id_type_string_token_map::iterator find_; - - for (; iter_ != end_; ++iter_) - { - find_ = new_ptr_->_transitions.find - (lookup_ptr_[iter_->first]); - - if (find_ == new_ptr_->_transitions.end()) - { - new_ptr_->_transitions.insert - (id_type_string_token_pair - (lookup_ptr_[iter_->first], iter_->second)); - } - else - { - find_->second.insert(iter_->second); - } - } - - ++ptr_; - ++new_ptr_; - } - - dfa_.swap(new_dfa_); - } - } -}; - -using char_state_machine = basic_char_state_machine; -using wchar_state_machine = basic_char_state_machine; -using u32char_state_machine = basic_char_state_machine; -} - -#endif diff --git a/YACReaderLibrary/lexertl/stream_shared_iterator.hpp b/YACReaderLibrary/lexertl/stream_shared_iterator.hpp deleted file mode 100644 index 7946390f2..000000000 --- a/YACReaderLibrary/lexertl/stream_shared_iterator.hpp +++ /dev/null @@ -1,352 +0,0 @@ -// stream_shared_iterator.hpp -// Copyright (c) 2010-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LEXERTL_STREAM_SHARED_ITERATOR_HPP -#define LEXERTL_STREAM_SHARED_ITERATOR_HPP - -#include -// memcpy -#include -#include -#include -#include "runtime_error.hpp" -#include - -namespace lexertl -{ -template -class basic_stream_shared_iterator -{ -public: - using istream = std::basic_istream; - using iterator_category = std::forward_iterator_tag; - using difference_type = std::size_t; - using value_type = char_type; - using pointer = char_type *; - using reference = char_type &; - - basic_stream_shared_iterator() : - _master(false), - _live(false), - _index(shared::npos()), - _shared(nullptr) - { - } - - basic_stream_shared_iterator(istream &stream_, - const std::size_t buff_size_ = 1024, - const std::size_t increment_ = 1024) : - _master(true), - _live(false), - _index(shared::npos()), - // For exception safety don't call new yet - _shared(nullptr) - { - // Safe to call potentially throwing new now. - _shared = new shared(stream_, buff_size_, increment_); - ++_shared->_ref_count; - _shared->_clients.push_back(this); - } - - basic_stream_shared_iterator(const basic_stream_shared_iterator &rhs_) : - _master(false), - _live(false), - _index(rhs_._master ? rhs_._shared->lowest() : rhs_._index), - _shared(rhs_._shared) - { - if (_shared) - { - // New copy of an iterator. - // The assumption is that any copy must be live - // even if the rhs is not (otherwise we will never - // have a record of the start of the current range!) - ++_shared->_ref_count; - _shared->_clients.push_back(this); - _live = true; - } - } - - ~basic_stream_shared_iterator() - { - if (_shared) - { - --_shared->_ref_count; - _shared->erase(this); - - if (_shared->_ref_count == 0) - { - delete _shared; - _shared = nullptr; - } - } - } - - basic_stream_shared_iterator &operator = - (const basic_stream_shared_iterator &rhs_) - { - if (this != &rhs_) - { - _master = false; - _index = rhs_._master ? rhs_._shared->lowest() : rhs_._index; - - if (!_live && !rhs_._live) - { - if (rhs_._shared) - { - ++rhs_._shared->_ref_count; - } - } - else if (!_live && rhs_._live) - { - rhs_._shared->_clients.push_back(this); - - if (!_shared) - { - ++rhs_._shared->_ref_count; - } - } - else if (_live && !rhs_._live) - { - _shared->erase(this); - - if (!rhs_._shared) - { - --_shared->_ref_count; - } - } - - _live = rhs_._live; - _shared = rhs_._shared; - } - - return *this; - } - - bool operator ==(const basic_stream_shared_iterator &rhs_) const - { - return _index == rhs_._index && - (_shared == rhs_._shared || - (_index == shared::npos() || rhs_._index == shared::npos()) && - (!_shared || !rhs_._shared)); - } - - bool operator !=(const basic_stream_shared_iterator &rhs_) const - { - return !(*this == rhs_); - } - - const char_type &operator *() - { - check_master(); - return _shared->_buffer[_index]; - } - - basic_stream_shared_iterator &operator ++() - { - check_master(); - ++_index; - update_state(); - return *this; - } - - basic_stream_shared_iterator operator ++(int) - { - basic_stream_shared_iterator iter_ = *this; - - check_master(); - ++_index; - update_state(); - return iter_; - } - -private: - class shared - { - public: - std::size_t _ref_count; - using char_vector = std::vector; - using iter_list = std::vector; - istream &_stream; - std::size_t _increment; - std::size_t _len; - char_vector _buffer; - iter_list _clients; - - shared(istream &stream_, const std::size_t buff_size_, - const std::size_t increment_) : - _ref_count(0), - _increment(increment_), - _stream(stream_) - { - _buffer.resize(buff_size_); - _stream.read(&_buffer.front(), _buffer.size()); - _len = static_cast(_stream.gcount()); - } - - bool reload_buffer() - { - const std::size_t lowest_ = lowest(); - std::size_t read_ = 0; - - if (lowest_ == 0) - { - // Resize buffer - const std::size_t old_size_ = _buffer.size(); - const std::size_t new_size_ = old_size_ + _increment; - - _buffer.resize(new_size_); - _stream.read(&_buffer.front() + old_size_, _increment); - read_ = static_cast(_stream.gcount()); - - if (read_) - { - read_ += old_size_; - _len = read_; - } - } - else - { - // Some systems have memcpy in namespace std - using namespace std; - const size_t start_ = _buffer.size() - lowest_; - const size_t len_ = _buffer.size() - start_; - - memcpy(&_buffer.front(), &_buffer[lowest_], start_ * - sizeof(char_type)); - _stream.read(&_buffer.front() + start_, len_); - read_ = static_cast(_stream.gcount()); - subtract(lowest_); - - if (read_) - { - read_ += start_; - _len = read_; - } - else - { - _len = highest(); - } - } - - return read_ != 0; - } - - void erase(basic_stream_shared_iterator *ptr_) - { - auto iter_ = std::find(_clients.begin(), _clients.end(), ptr_); - - if (iter_ != _clients.end()) - _clients.erase(iter_); - } - - std::size_t lowest() const - { - std::size_t lowest_ = npos(); - auto iter_ = _clients.cbegin(); - auto end_ = _clients.cend(); - - for (; iter_ != end_; ++iter_) - { - const basic_stream_shared_iterator *ptr_ = *iter_; - - if (ptr_->_index < lowest_) - { - lowest_ = ptr_->_index; - } - } - - if (lowest_ == npos()) - { - lowest_ = 0; - } - - return lowest_; - } - - std::size_t highest() const - { - std::size_t highest_ = 0; - auto iter_ = _clients.cbegin(); - auto end_ = _clients.cend(); - - for (; iter_ != end_; ++iter_) - { - const basic_stream_shared_iterator *ptr_ = *iter_; - - if (ptr_->_index != npos() && ptr_->_index > highest_) - { - highest_ = ptr_->_index; - } - } - - return highest_; - } - - void subtract(const std::size_t lowest_) - { - auto iter_ = _clients.begin(); - auto end_ = _clients.end(); - - for (; iter_ != end_; ++iter_) - { - basic_stream_shared_iterator *ptr_ = *iter_; - - if (ptr_->_index != npos()) - { - ptr_->_index -= lowest_; - } - } - } - - static std::size_t npos() - { - return ~static_cast(0); - } - - private: - shared &operator =(const shared &rhs_); - }; - - bool _master; - bool _live; - std::size_t _index; - shared *_shared; - - void check_master() - { - if (!_shared) - { - throw runtime_error("Cannot manipulate null (end) " - "stream_shared_iterators."); - } - - if (_master) - { - _master = false; - _live = true; - _index = _shared->lowest(); - } - } - - void update_state() - { - if (_index >= _shared->_len) - { - if (!_shared->reload_buffer()) - { - _shared->erase(this); - _index = shared::npos(); - _live = false; - } - } - } -}; - -using stream_shared_iterator = basic_stream_shared_iterator; -using wstream_shared_iterator = basic_stream_shared_iterator; -} - -#endif diff --git a/YACReaderLibrary/lexertl/string_token.hpp b/YACReaderLibrary/lexertl/string_token.hpp deleted file mode 100644 index e108bd124..000000000 --- a/YACReaderLibrary/lexertl/string_token.hpp +++ /dev/null @@ -1,439 +0,0 @@ -// string_token.hpp -// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_STRING_TOKEN_HPP -#define LEXERTL_STRING_TOKEN_HPP - -#include "char_traits.hpp" -#include // Needed by GCC 4.4 -#include -#include -#include -#include - -namespace lexertl -{ -template -struct basic_string_token -{ - using char_type = ch_type; - using char_traits = basic_char_traits; - using index_type = typename char_traits::index_type; - using range = std::pair; - using range_vector = std::vector; - using string = std::basic_string; - using string_token = basic_string_token; - - range_vector _ranges; - - basic_string_token() : - _ranges() - { - } - - basic_string_token(char_type ch_) : - _ranges() - { - insert(range(ch_, ch_)); - } - - basic_string_token(char_type first_, char_type second_) : - _ranges() - { - insert(range(first_, second_)); - } - - void clear() - { - _ranges.clear(); - } - - bool empty() const - { - return _ranges.empty(); - } - - bool any() const - { - return _ranges.size() == 1 && _ranges.front().first == 0 && - _ranges.front().second == char_traits::max_val(); - } - - bool operator <(const basic_string_token &rhs_) const - { - return _ranges < rhs_._ranges; - } - - bool operator ==(const basic_string_token &rhs_) const - { - return _ranges == rhs_._ranges; - } - - bool negatable() const - { - std::size_t size_ = 0; - auto iter_ = _ranges.cbegin(); - auto end_ = _ranges.cend(); - - for (; iter_ != end_; ++iter_) - { - size_ += static_cast(iter_->second) + 1 - - static_cast(iter_->first); - } - - return size_ > static_cast(char_traits::max_val()) / 2; - } - - void swap(basic_string_token &rhs_) - { - _ranges.swap(rhs_._ranges); - } - - void insert(const basic_string_token &rhs_) - { - auto iter_ = rhs_._ranges.cbegin(); - auto end_ = rhs_._ranges.cend(); - - for (; iter_ != end_; ++iter_) - { - insert(*iter_); - } - } - - // Deliberately pass by value - may modify - typename range_vector::iterator insert(range rhs_) - { - bool insert_ = true; - auto iter_ = _ranges.begin(); - auto end_ = _ranges.end(); - auto erase_iter_ = end_; - - while (iter_ != end_) - { - // follows current item - if (rhs_.first > iter_->second) - { - if (rhs_.first == iter_->second + 1) - { - // Auto normalise - rhs_.first = iter_->first; - } - else - { - // No intersection, consider next - ++iter_; - continue; - } - } - // Precedes current item - else if (rhs_.second < iter_->first) - { - if (rhs_.second == iter_->first - 1) - { - // Auto normalise - rhs_.second = iter_->second; - } - else - { - // insert here - break; - } - } - else - { - // overlap (under) - if (rhs_.first < iter_->first) - { - if (rhs_.second < iter_->second) - { - rhs_.second = iter_->second; - } - } - // overlap (over) - else if (rhs_.second > iter_->second) - { - if (rhs_.first > iter_->first) - { - rhs_.first = iter_->first; - } - } - // subset - else - { - insert_ = false; - iter_ = _ranges.end(); - break; - } - } - - // Code minimisation: this always applies unless we have already - // exited the loop, or "continue" executed. - if (erase_iter_ == end_) - { - erase_iter_ = iter_; - } - - ++iter_; - } - - if (erase_iter_ != end_) - { - if (insert_) - { - // Re-use obsolete location - *erase_iter_ = rhs_; - ++erase_iter_; - } - - iter_ = _ranges.erase(erase_iter_, iter_); - } - else if (insert_) - { - iter_ = _ranges.insert(iter_, rhs_); - } - - return iter_; - } - - void negate() - { - index_type next_ = 0; - const index_type max_ = char_traits::max_val(); - string_token temp_; - auto iter_ = _ranges.cbegin(); - auto end_ = _ranges.cend(); - bool finished_ = false; - - for (; iter_ != end_; ++iter_) - { - if (next_ < iter_->first) - { - temp_.insert(range(next_, - static_cast(iter_->first - 1))); - } - - if (iter_->second < max_) - { - next_ = iter_->second + 1; - } - else - { - finished_ = true; - break; - } - } - - if (!finished_) - { - temp_.insert(range(next_, max_)); - } - - swap(temp_); - } - - void intersect(basic_string_token &rhs_, basic_string_token &overlap_) - { - auto lhs_iter_ = _ranges.begin(); - auto lhs_end_ = _ranges.end(); - auto rhs_iter_ = rhs_._ranges.begin(); - auto rhs_end_ = rhs_._ranges.end(); - - while (lhs_iter_ != lhs_end_ && rhs_iter_ != rhs_end_) - { - if (rhs_iter_->first > lhs_iter_->second) - { - ++lhs_iter_; - } - else if (rhs_iter_->second < lhs_iter_->first) - { - ++rhs_iter_; - } - else - { - range range_; - - if (rhs_iter_->first > lhs_iter_->first) - { - range_.first = rhs_iter_->first; - } - else - { - range_.first = lhs_iter_->first; - } - - if (rhs_iter_->second < lhs_iter_->second) - { - range_.second = rhs_iter_->second; - } - else - { - range_.second = lhs_iter_->second; - } - - adjust(range_, *this, lhs_iter_, lhs_end_); - adjust(range_, rhs_, rhs_iter_, rhs_end_); - overlap_.insert(range_); - } - } - } - - void remove(basic_string_token &rhs_) - { - auto lhs_iter_ = _ranges.begin(); - auto lhs_end_ = _ranges.end(); - auto rhs_iter_ = rhs_._ranges.begin(); - auto rhs_end_ = rhs_._ranges.end(); - - while (lhs_iter_ != lhs_end_ && rhs_iter_ != rhs_end_) - { - if (rhs_iter_->first > lhs_iter_->second) - { - ++lhs_iter_; - } - else if (rhs_iter_->second < lhs_iter_->first) - { - ++rhs_iter_; - } - else - { - range range_; - - if (rhs_iter_->first > lhs_iter_->first) - { - range_.first = rhs_iter_->first; - } - else - { - range_.first = lhs_iter_->first; - } - - if (rhs_iter_->second < lhs_iter_->second) - { - range_.second = rhs_iter_->second; - } - else - { - range_.second = lhs_iter_->second; - } - - adjust(range_, *this, lhs_iter_, lhs_end_); - } - } - } - - static string escape_char(const typename char_traits::index_type ch_) - { - string out_; - - switch (ch_) - { - case '\0': - out_ += '\\'; - out_ += '0'; - break; - case '\a': - out_ += '\\'; - out_ += 'a'; - break; - case '\b': - out_ += '\\'; - out_ += 'b'; - break; - case 27: - out_ += '\\'; - out_ += 'x'; - out_ += '1'; - out_ += 'b'; - break; - case '\f': - out_ += '\\'; - out_ += 'f'; - break; - case '\n': - out_ += '\\'; - out_ += 'n'; - break; - case '\r': - out_ += '\\'; - out_ += 'r'; - break; - case '\t': - out_ += '\\'; - out_ += 't'; - break; - case '\v': - out_ += '\\'; - out_ += 'v'; - break; - case '\\': - out_ += '\\'; - out_ += '\\'; - break; - case '"': - out_ += '\\'; - out_ += '"'; - break; - case '\'': - out_ += '\\'; - out_ += '\''; - break; - default: - { - if (ch_ < 32 || ch_ > 126) - { - std::basic_stringstream ss_; - - out_ += '\\'; - out_ += 'x'; - ss_ << std::hex << - static_cast(ch_); - out_ += ss_.str(); - } - else - { - out_ += ch_; - } - - break; - } - } - - return out_; - } - -private: - void adjust(const range &range_, basic_string_token &token_, - typename range_vector::iterator &iter_, - typename range_vector::iterator &end_) - { - if (range_.first > iter_->first) - { - const index_type second_ = iter_->second; - - iter_->second = range_.first - 1; - - if (range_.second < second_) - { - range new_range_(static_cast(range_.second + 1), - second_); - - iter_ = token_.insert(new_range_); - end_ = token_._ranges.end(); - } - } - else if (range_.second < iter_->second) - { - iter_->first = range_.second + 1; - } - else - { - iter_ = token_._ranges.erase(iter_); - end_ = token_._ranges.end(); - } - } -}; -} - -#endif diff --git a/YACReaderLibrary/lexertl/utf_iterators.hpp b/YACReaderLibrary/lexertl/utf_iterators.hpp deleted file mode 100644 index 0bd64e7cb..000000000 --- a/YACReaderLibrary/lexertl/utf_iterators.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// utf_iterators.hpp -// Copyright (c) 2015-2018 Ben Hanson (http://www.benhanson.net/) -// Inspired by http://utfcpp.sourceforge.net/ -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef LEXERTL_UTF_ITERATORS_HPP -#define LEXERTL_UTF_ITERATORS_HPP - -#include - -namespace lexertl -{ -template -class basic_utf8_in_iterator : - public std::iterator -{ -public: - using value_type = char_type; - using difference_type = - typename std::iterator_traits::difference_type; - using iterator_category = std::forward_iterator_tag; - - basic_utf8_in_iterator() : - _it(char_iterator()), - _end(char_iterator()), - _char(0) - { - } - - explicit basic_utf8_in_iterator(const char_iterator &it_, - const char_iterator &end_) : - _it(it_), - _end(it_), - _char(0) - { - if (it_ != end_) - { - next(); - } - } - - char_type operator *() const - { - return _char; - } - - bool operator ==(const basic_utf8_in_iterator &rhs_) const - { - return _it == rhs_._it; - } - - bool operator !=(const basic_utf8_in_iterator &rhs_) const - { - return _it != rhs_._it; - } - - basic_utf8_in_iterator &operator ++() - { - _it = _end; - next(); - return *this; - } - - basic_utf8_in_iterator operator ++(int) - { - basic_utf8_in_iterator temp_ = *this; - - _it = _end; - next(); - return temp_; - } - - basic_utf8_in_iterator operator +(const std::size_t count_) const - { - basic_utf8_in_iterator temp_ = *this; - - for (std::size_t i_ = 0; i_ < count_; ++i_) - { - ++temp_; - } - - return temp_; - } - - basic_utf8_in_iterator operator -(const std::size_t count_) const - { - basic_utf8_in_iterator temp_ = *this; - - for (std::size_t i_ = 0; i_ < count_; ++i_) - { - temp_._end = temp_._it; - --temp_._it; - - while ((*temp_._it & 0xc0) == 0x80) --temp_._it; - } - - temp_.next(); - return temp_; - } - -private: - char_iterator _it; - char_iterator _end; - char_type _char; - - void next() - { - const char len_ = len(_it); - char_type ch_ = *_it & 0xff; - - switch (len_) - { - case 1: - _end = _it; - ++_end; - break; - case 2: - _end = _it; - ++_end; - - if ((*_end & 0xc0) != 0x80) break; - - ch_ = (ch_ << 6 & 0x7ff) | (*_end & 0x3f); - ++_end; - break; - case 3: - _end = _it; - ++_end; - - if ((*_end & 0xc0) != 0x80) break; - - ch_ = (ch_ << 12 & 0xffff) | ((*_end & 0xff) << 6 & 0xfff); - ++_end; - - if ((*_end & 0xc0) != 0x80) break; - - ch_ |= *_end & 0x3f; - ++_end; - break; - case 4: - _end = _it; - ++_end; - - if ((*_end & 0xc0) != 0x80) break; - - ch_ = (ch_ << 18 & 0x1fffff) | ((*_end & 0xff) << 12 & 0x3ffff); - ++_end; - - if ((*_end & 0xc0) != 0x80) break; - - ch_ |= (*_end & 0xff) << 6 & 0xfff; - ++_end; - - if ((*_end & 0xc0) != 0x80) break; - - ch_ |= *_end & 0x3f; - ++_end; - break; - } - - _char = ch_; - } - - char len(const char_iterator &it_) const - { - const unsigned char ch_ = *it_; - - return ch_ < 0x80 ? 1 : - ch_ >> 5 == 0x06 ? 2 : - ch_ >> 4 == 0x0e ? 3 : - ch_ >> 3 == 0x1e ? 4 : - 1; - } -}; - -template -class basic_utf8_out_iterator : - public std::iterator -{ -public: - using value_type = char; - using difference_type = - typename std::iterator_traits::difference_type; - using iterator_category = std::forward_iterator_tag; - - basic_utf8_out_iterator() : - _count(0), - _index(0) - { - } - - explicit basic_utf8_out_iterator(const char_iterator &it_, - const char_iterator &end_) : - _it(it_), - _count(0), - _index(0) - { - if (it_ != end_) - { - next(); - } - } - - char operator *() const - { - return _bytes[_index]; - } - - bool operator ==(const basic_utf8_out_iterator &rhs_) const - { - return _it == rhs_._it; - } - - bool operator !=(const basic_utf8_out_iterator &rhs_) const - { - return _it != rhs_._it; - } - - basic_utf8_out_iterator &operator ++() - { - ++_index; - - if (_index >= _count) - { - ++_it; - next(); - } - - return *this; - } - - basic_utf8_out_iterator operator ++(int) - { - basic_utf8_out_iterator temp_ = *this; - - ++_index; - - if (_index >= _count) - { - ++_it; - next(); - } - - return temp_; - } - -private: - char_iterator _it; - char _bytes[4]; - unsigned char _count; - unsigned char _index; - - void next() - { - const std::size_t ch_ = *_it; - - _count = len(ch_); - _index = 0; - - switch (_count) - { - case 1: - _bytes[0] = static_cast(ch_); - break; - case 2: - _bytes[0] = static_cast((ch_ >> 6) | 0xc0); - _bytes[1] = (ch_ & 0x3f) | 0x80; - break; - case 3: - _bytes[0] = static_cast((ch_ >> 12) | 0xe0); - _bytes[1] = ((ch_ >> 6) & 0x3f) | 0x80; - _bytes[2] = (ch_ & 0x3f) | 0x80; - break; - case 4: - _bytes[0] = static_cast((ch_ >> 18) | 0xf0); - _bytes[1] = ((ch_ >> 12) & 0x3f) | 0x80; - _bytes[2] = ((ch_ >> 6) & 0x3f) | 0x80; - _bytes[3] = (ch_ & 0x3f) | 0x80; - break; - } - } - - char len(const std::size_t ch_) const - { - return ch_ < 0x80 ? 1 : - ch_ < 0x800 ? 2 : - ch_ < 0x10000 ? 3 : - 4; - } -}; - -template -class basic_utf16_in_iterator : - public std::iterator -{ -public: - using value_type = char_type; - using difference_type = - typename std::iterator_traits::difference_type; - using iterator_category = std::forward_iterator_tag; - - basic_utf16_in_iterator() : - _it(char_iterator()), - _end(char_iterator()), - _char(0) - { - } - - explicit basic_utf16_in_iterator(const char_iterator &it_, - const char_iterator &end_) : - _it(it_), - _end(it_), - _char(0) - { - if (it_ != end_) - { - next(); - } - } - - char_type operator *() const - { - return _char; - } - - bool operator ==(const basic_utf16_in_iterator &rhs_) const - { - return _it == rhs_._it; - } - - bool operator !=(const basic_utf16_in_iterator &rhs_) const - { - return _it != rhs_._it; - } - - basic_utf16_in_iterator &operator ++() - { - _it = _end; - next(); - return *this; - } - - basic_utf16_in_iterator operator ++(int) - { - basic_utf16_in_iterator temp_ = *this; - - _it = _end; - next(); - return temp_; - } - - basic_utf16_in_iterator operator +(const std::size_t count_) const - { - basic_utf16_in_iterator temp_ = *this; - - for (std::size_t i_ = 0; i_ < count_; ++i_) - { - ++temp_; - } - - return temp_; - } - - basic_utf16_in_iterator operator -(const std::size_t count_) const - { - basic_utf16_in_iterator temp_ = *this; - - for (std::size_t i_ = 0; i_ < count_; ++i_) - { - temp_._end = temp_._it; - --temp_._it; - - if (*temp_._it >= 0xdc00 && *temp_._it <= 0xdfff) --temp_._it; - } - - temp_.next(); - return temp_; - } - -private: - char_iterator _it; - char_iterator _end; - char_type _char; - - void next() - { - char_type ch_ = *_it & 0xffff; - - _end = _it; - - if (ch_ >= 0xd800 && ch_ <= 0xdbff) - { - const char_type surrogate_ = *++_end & 0xffff; - - ch_ = (((ch_ - 0xd800) << 10) | (surrogate_ - 0xdc00)) + 0x10000; - } - - _char = ch_; - ++_end; - } -}; - -template -class basic_utf16_out_iterator : - public std::iterator -{ -public: - using value_type = wchar_t; - using difference_type = - typename std::iterator_traits::difference_type; - using iterator_category = std::forward_iterator_tag; - - basic_utf16_out_iterator() : - _count(0), - _index(0) - { - } - - explicit basic_utf16_out_iterator(const char_iterator &it_, - const char_iterator &end_) : - _it(it_), - _count(0), - _index(0) - { - if (it_ != end_) - { - next(); - } - } - - wchar_t operator *() const - { - return _chars[_index]; - } - - bool operator ==(const basic_utf16_out_iterator &rhs_) const - { - return _it == rhs_._it; - } - - bool operator !=(const basic_utf16_out_iterator &rhs_) const - { - return _it != rhs_._it; - } - - basic_utf16_out_iterator &operator ++() - { - ++_index; - - if (_index >= _count) - { - ++_it; - next(); - } - - return *this; - } - - basic_utf16_out_iterator operator ++(int) - { - basic_utf16_out_iterator temp_ = *this; - - ++_index; - - if (_index >= _count) - { - ++_it; - next(); - } - - return temp_; - } - -private: - char_iterator _it; - wchar_t _chars[2]; - unsigned char _count; - unsigned char _index; - - void next() - { - const std::size_t ch_ = *_it; - - _count = len(ch_); - _index = 0; - - switch (_count) - { - case 1: - _chars[0] = static_cast(ch_); - break; - case 2: - _chars[0] = static_cast((ch_ >> 10) + 0xdc00u - - (0x10000 >> 10)); - _chars[1] = static_cast((ch_ & 0x3ff) + 0xdc00u); - break; - } - } - - char len(const std::size_t ch_) const - { - return ch_ > 0xffff ? 2 : 1; - } -}; -} - -#endif From ddb140d4307aba896eeaf7f87d3d9f0d83c90ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Tue, 12 Jan 2021 18:57:25 +0100 Subject: [PATCH 019/141] Remove misplaced code --- YACReaderLibrary/db/comic_model.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index 59fa9887a..abfa2affd 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -644,9 +644,7 @@ void ComicModel::setupModelData(const SearchModifiers modifier, const QString &f } catch (const std::exception &e) { QLOG_ERROR() << "Unable to parse query: " << e.what(); } - selectQuery.exec(); - setupModelData(selectQuery); connectionName = db.connectionName(); } QSqlDatabase::removeDatabase(connectionName); From f09c5955d8967078b2caa13feaf9607ed66a3e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 08:39:16 +0100 Subject: [PATCH 020/141] Remove space and atWord tokens `atWord` wasn't used at all and spaces should be eaten by the lexer And added `unspecified` token --- YACReaderLibrary/db/query_lexer.cpp | 18 ++++-------------- YACReaderLibrary/db/query_lexer.h | 4 +--- YACReaderLibrary/db/query_parser.cpp | 7 ++----- YACReaderLibrary/db/query_parser.h | 2 +- 4 files changed, 8 insertions(+), 23 deletions(-) diff --git a/YACReaderLibrary/db/query_lexer.cpp b/YACReaderLibrary/db/query_lexer.cpp index 27944ff41..832b49782 100644 --- a/YACReaderLibrary/db/query_lexer.cpp +++ b/YACReaderLibrary/db/query_lexer.cpp @@ -7,17 +7,16 @@ QueryLexer::QueryLexer(const std::string &input) Token QueryLexer::next() { + while (isSpace(peek())) { + get(); + } + switch (peek()) { case '\0': return Token(Token::Type::eof); case '(': case ')': return single(Token::Type::opcode); - case ' ': - case '\t': - case '\r': - case '\n': - return space(); case '"': return quotedWord(); default: @@ -40,15 +39,6 @@ Token QueryLexer::single(Token::Type type) return Token(type, input.substr(index++, 1)); } -Token QueryLexer::space() -{ - auto start = index; - get(); - while (isSpace(peek())) - get(); - return Token(Token::Type::space, input.substr(start, index - start)); -} - Token QueryLexer::word() { auto start = index; diff --git a/YACReaderLibrary/db/query_lexer.h b/YACReaderLibrary/db/query_lexer.h index b2c892f65..4cc2b61f1 100644 --- a/YACReaderLibrary/db/query_lexer.h +++ b/YACReaderLibrary/db/query_lexer.h @@ -9,10 +9,9 @@ class Token enum class Type { eof, opcode, - atWord, word, quotedWord, - space + undefined }; Token(Type type, std::string lexeme = "") @@ -49,7 +48,6 @@ class QueryLexer char get(); Token single(Token::Type type); - Token space(); Token word(); Token quotedWord(); diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index de9dc39e2..5a10d238e 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -136,9 +136,6 @@ bool QueryParser::isEof() const void QueryParser::advance() { currentToken = lexer.next(); - - if (tokenType() == Token::Type::space) - advance(); } QueryParser::FieldType QueryParser::fieldType(const std::string &str) @@ -184,7 +181,7 @@ QueryParser::TreeNode QueryParser::andExpression() return { "and", { lhs, andExpression() } }; } - if ((isIn(tokenType(), { Token::Type::atWord, Token::Type::word, Token::Type::quotedWord }) || token() == "(") && lcaseToken() != "or") { + if ((isIn(tokenType(), { Token::Type::word, Token::Type::quotedWord }) || token() == "(") && lcaseToken() != "or") { return { "and", { lhs, andExpression() } }; } @@ -210,7 +207,7 @@ QueryParser::TreeNode QueryParser::locationExpression() } return res; } - if (!isIn(tokenType(), { Token::Type::atWord, Token::Type::word, Token::Type::quotedWord })) { + if (!isIn(tokenType(), { Token::Type::word, Token::Type::quotedWord })) { throw std::invalid_argument("Invalid syntax. Expected a lookup name or a word"); } return baseToken(); diff --git a/YACReaderLibrary/db/query_parser.h b/YACReaderLibrary/db/query_parser.h index 95fd48c8c..aa688fc26 100644 --- a/YACReaderLibrary/db/query_parser.h +++ b/YACReaderLibrary/db/query_parser.h @@ -62,7 +62,7 @@ class QueryParser void advance(); QueryLexer lexer = QueryLexer(""); - Token currentToken = Token(Token::Type::eof); + Token currentToken = Token(Token::Type::undefined); template static bool isIn(const T &e, const std::list &v) From 260f538de3ab24ac8768fa66892b41984fe6aacd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 08:49:48 +0100 Subject: [PATCH 021/141] Use an explicit constructor for TreeNode List initialization ended using movable constructors which surprisingly caused data troubles in release mode, at least in VC2019 compiler. The tree being messed up caused crashes while SQL was generated. I have no explanation for it. --- YACReaderLibrary/db/query_parser.cpp | 17 +++++++++-------- YACReaderLibrary/db/query_parser.h | 5 +++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index 5a10d238e..38381e5c0 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -168,7 +168,7 @@ QueryParser::TreeNode QueryParser::orExpression() auto lhs = andExpression(); if (lcaseToken() == "or") { advance(); - return { "or", { lhs, orExpression() } }; + return TreeNode("or", { lhs, orExpression() }); } return lhs; } @@ -178,11 +178,11 @@ QueryParser::TreeNode QueryParser::andExpression() auto lhs = notExpression(); if (lcaseToken() == "and") { advance(); - return { "and", { lhs, andExpression() } }; + return TreeNode("and", { lhs, andExpression() }); } if ((isIn(tokenType(), { Token::Type::word, Token::Type::quotedWord }) || token() == "(") && lcaseToken() != "or") { - return { "and", { lhs, andExpression() } }; + return TreeNode("and", { lhs, andExpression() }); } return lhs; @@ -192,7 +192,7 @@ QueryParser::TreeNode QueryParser::notExpression() { if (lcaseToken() == "not") { advance(); - return { "not", { notExpression() } }; + return TreeNode("not", { notExpression() }); } return locationExpression(); } @@ -216,7 +216,7 @@ QueryParser::TreeNode QueryParser::locationExpression() QueryParser::TreeNode QueryParser::baseToken() { if (tokenType() == Token::Type::quotedWord) { - return { "token", { { "all", {} }, { token(true), {} } } }; + return TreeNode("token", { TreeNode("all", {}), TreeNode(token(true), {}) }); } auto words(split(token(true), ':')); @@ -225,9 +225,10 @@ QueryParser::TreeNode QueryParser::baseToken() auto loc(toLower(words[0].toStdString())); words.erase(words.begin()); if (words.size() == 1 && tokenType() == Token::Type::quotedWord) { - return { "token", { { loc, {} }, { token(true), {} } } }; + return TreeNode("token", { TreeNode(loc, {}), TreeNode(token(true), {}) }); } - return { "token", { { loc, {} }, { join(words, ":"), {} } } }; + return TreeNode("token", { TreeNode(loc, {}), TreeNode(join(words, ":"), {}) }); } - return { "token", { { "all", {} }, { join(words, ":"), {} } } }; + + return TreeNode("token", { TreeNode("all", {}), TreeNode(join(words, ":"), {}) }); } diff --git a/YACReaderLibrary/db/query_parser.h b/YACReaderLibrary/db/query_parser.h index aa688fc26..7aca5ca95 100644 --- a/YACReaderLibrary/db/query_parser.h +++ b/YACReaderLibrary/db/query_parser.h @@ -45,6 +45,11 @@ class QueryParser std::string t; std::vector children; + explicit TreeNode(std::string t, std::vector children) + : t(t), children(children) + { + } + int buildSqlString(std::string &sqlString, int bindPosition = 0) const; int bindValues(QSqlQuery &selectQuery, int bindPosition = 0) const; }; From 7b361004589d144776eaed704a5b31d93cc91616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 08:51:08 +0100 Subject: [PATCH 022/141] Use QString::fromStdString Just to keep things consistent in the whole round trip conversion --- YACReaderLibrary/db/query_parser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index 38381e5c0..36916b53b 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -53,9 +53,9 @@ int QueryParser::TreeNode::bindValues(QSqlQuery &selectQuery, int bindPosition) if (t == "token") { std::string bind_string(":bindPosition" + std::to_string(++bindPosition)); if (isIn(fieldType(children[0].t), { FieldType::numeric, FieldType::boolean })) { - selectQuery.bindValue(bind_string.c_str(), std::stoi(children[1].t)); + selectQuery.bindValue(QString::fromStdString(bind_string), std::stoi(children[1].t)); } else { - selectQuery.bindValue(bind_string.c_str(), ("%%" + children[1].t + "%%").c_str()); + selectQuery.bindValue(QString::fromStdString(bind_string), QString::fromStdString("%%" + children[1].t + "%%")); } } else if (t == "not") { bindPosition = children[0].bindValues(selectQuery, bindPosition); @@ -159,7 +159,7 @@ std::string QueryParser::join(const QStringList &strings, const std::string &del QStringList QueryParser::split(const std::string &string, char delim) { - auto words = QString(string.c_str()).split(delim); + auto words = QString::fromStdString(string).split(delim); return words; } From fa5ce254253041e9d3e506a568f64a2db7c0c07d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 09:03:17 +0100 Subject: [PATCH 023/141] Add concurrent queue based on lambdas --- YACReaderLibrary/YACReaderLibrary.pro | 1 + common/concurrent_queue.h | 132 ++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 common/concurrent_queue.h diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 156056dfe..6a81ad519 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -76,6 +76,7 @@ QT += sql network widgets script # Input HEADERS += comic_flow.h \ + ../common/concurrent_queue.h \ create_library_dialog.h \ db/query_lexer.h \ library_creator.h \ diff --git a/common/concurrent_queue.h b/common/concurrent_queue.h new file mode 100644 index 000000000..5b92f6f1a --- /dev/null +++ b/common/concurrent_queue.h @@ -0,0 +1,132 @@ +#ifndef CONCURRENT_QUEUE_H +#define CONCURRENT_QUEUE_H + +#include +#include +#include +#include +#include + +namespace YACReader { +class ConcurrentQueue +{ +public: + explicit ConcurrentQueue(int threadCount) + : jobsLeft(0), + bailout(false) + { + threads = std::vector(threadCount); + for (int index = 0; index < threadCount; ++index) { + threads[index] = std::thread([this] { + this->nextJob(); + }); + } + } + + ~ConcurrentQueue() + { + joinAll(); + } + + void enqueue(std::function job) + { + { + std::lock_guard lock(queueMutex); + _queue.emplace(job); + } + + { + std::lock_guard lock(jobsLeftMutex); + ++jobsLeft; + } + + jobAvailableVar.notify_one(); + } + + void cancellPending() + { + std::unique_lock lock(jobsLeftMutex); + _queue = std::queue>(); + jobsLeft = 0; + } + + void waitAll() + { + std::unique_lock lock(jobsLeftMutex); + if (jobsLeft > 0) { + _waitVar.wait(lock, [this] { + return jobsLeft == 0; + }); + } + } + +private: + std::vector threads; + std::queue> _queue; + int jobsLeft; + bool bailout; + std::condition_variable jobAvailableVar; + std::condition_variable _waitVar; + std::mutex jobsLeftMutex; + std::mutex queueMutex; + + void nextJob() + { + while (true) { + std::function job; + + { + std::unique_lock lock(queueMutex); + + if (bailout) { + return; + } + + jobAvailableVar.wait(lock, [this] { + return _queue.size() > 0 || bailout; + }); + + if (bailout) { + return; + } + + job = _queue.front(); + _queue.pop(); + } + + job(); + + { + std::lock_guard lock(jobsLeftMutex); + --jobsLeft; + } + + _waitVar.notify_one(); + } + } + + void joinAll() + { + { + std::lock_guard lock(queueMutex); + + if (bailout) { + return; + } + + bailout = true; + } + + jobAvailableVar.notify_all(); + + for (auto &x : threads) { + if (x.joinable()) { + x.join(); + } + } + } +}; + +} + +#endif // CONCURRENT_QUEUE_H From dbdc7bd965b6ab0e6e48afcba708198e2b8f78f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 09:10:58 +0100 Subject: [PATCH 024/141] Add a class for processing search queries and create the comics model data --- YACReaderLibrary/YACReaderLibrary.pro | 2 + .../db/comic_query_result_procesor.cpp | 112 ++++++++++++++++++ .../db/comic_query_result_procesor.h | 32 +++++ 3 files changed, 146 insertions(+) create mode 100644 YACReaderLibrary/db/comic_query_result_procesor.cpp create mode 100644 YACReaderLibrary/db/comic_query_result_procesor.h diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 6a81ad519..4162cb36c 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -78,6 +78,7 @@ QT += sql network widgets script HEADERS += comic_flow.h \ ../common/concurrent_queue.h \ create_library_dialog.h \ + db/comic_query_result_procesor.h \ db/query_lexer.h \ library_creator.h \ library_window.h \ @@ -154,6 +155,7 @@ HEADERS += comic_flow.h \ SOURCES += comic_flow.cpp \ create_library_dialog.cpp \ + db/comic_query_result_procesor.cpp \ db/query_lexer.cpp \ library_creator.cpp \ library_window.cpp \ diff --git a/YACReaderLibrary/db/comic_query_result_procesor.cpp b/YACReaderLibrary/db/comic_query_result_procesor.cpp new file mode 100644 index 000000000..270075aa2 --- /dev/null +++ b/YACReaderLibrary/db/comic_query_result_procesor.cpp @@ -0,0 +1,112 @@ +#include "comic_query_result_procesor.h" + +#include "comic_item.h" +#include "comic_model.h" +#include "data_base_management.h" +#include "qnaturalsorting.h" +#include "db_helper.h" +#include "query_parser.h" + +#include "QsLog.h" + +QString getLastExecutedQuery(const QSqlQuery &query) +{ + QString str = query.lastQuery(); + QMapIterator it(query.boundValues()); + while (it.hasNext()) { + it.next(); + str.replace(it.key(), it.value().toString()); + } + return str; +} + +YACReader::ComicQueryResultProcesor::ComicQueryResultProcesor() + : querySearchQueue(1) +{ +} + +void YACReader::ComicQueryResultProcesor::createModelData(const YACReader::SearchModifiers modifier, const QString &filter, const QString &databasePath) +{ + querySearchQueue.cancellPending(); + + querySearchQueue.enqueue([=] { + QString connectionName = ""; + { + QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath); + QSqlQuery selectQuery(db); + + std::string queryString("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened " + "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) LEFT JOIN folder f ON (f.id == c.parentId) WHERE "); + + try { + QueryParser parser; + auto result = parser.parse(filter.toStdString()); + result.buildSqlString(queryString); + + switch (modifier) { + case YACReader::NoModifiers: + queryString += " LIMIT :limit"; + break; + + case YACReader::OnlyRead: + queryString += " AND ci.read = 1 LIMIT :limit"; + break; + + case YACReader::OnlyUnread: + queryString += " AND ci.read = 0 LIMIT :limit"; + break; + + default: + queryString += " LIMIT :limit"; + QLOG_ERROR() << "not implemented"; + break; + } + selectQuery.prepare(queryString.c_str()); + selectQuery.bindValue(":limit", 500); //TODO, load this value from settings + result.bindValues(selectQuery); + + selectQuery.exec(); + + auto data = modelData(selectQuery); + + emit newData(data, databasePath); + } catch (const std::exception &e) { + //Do nothing, uncomplete search string will end here and it is part of how the QueryParser works + //I don't like the idea of using exceptions for this though + } + + connectionName = db.connectionName(); + } + QSqlDatabase::removeDatabase(connectionName); + }); +} + +QList *YACReader::ComicQueryResultProcesor::modelData(QSqlQuery &sqlquery) +{ + auto list = new QList(); + + int numColumns = sqlquery.record().count(); + + while (sqlquery.next()) { + QList data; + + for (int i = 0; i < numColumns; i++) + data << sqlquery.value(i); + + list->append(new ComicItem(data)); + } + + std::sort(list->begin(), list->end(), [](const ComicItem *c1, const ComicItem *c2) { + if (c1->data(ComicModel::Number).isNull() && c2->data(ComicModel::Number).isNull()) { + return naturalSortLessThanCI(c1->data(ComicModel::FileName).toString(), c2->data(ComicModel::FileName).toString()); + } else { + if (c1->data(ComicModel::Number).isNull() == false && c2->data(ComicModel::Number).isNull() == false) { + return c1->data(ComicModel::Number).toInt() < c2->data(ComicModel::Number).toInt(); + } else { + return c2->data(ComicModel::Number).isNull(); + } + } + }); + + return list; +} diff --git a/YACReaderLibrary/db/comic_query_result_procesor.h b/YACReaderLibrary/db/comic_query_result_procesor.h new file mode 100644 index 000000000..ba71da99b --- /dev/null +++ b/YACReaderLibrary/db/comic_query_result_procesor.h @@ -0,0 +1,32 @@ +#ifndef COMIC_QUERY_RESULT_PROCESOR_H +#define COMIC_QUERY_RESULT_PROCESOR_H + +#include +#include + +#include "yacreader_global_gui.h" +#include "concurrent_queue.h" + +class ComicItem; + +namespace YACReader { + +class ComicQueryResultProcesor : public QObject +{ + Q_OBJECT +public: + ComicQueryResultProcesor(); + +public slots: + void createModelData(const SearchModifiers modifier, const QString &filter, const QString &databasePath); +signals: + void newData(QList *, const QString &); + +private: + ConcurrentQueue querySearchQueue; + + QList *modelData(QSqlQuery &sqlquery); +}; +}; + +#endif // COMIC_QUERY_RESULT_PROCESOR_H From ccc382df7d3bf82df0a39e0a879255cb0d55d92e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 09:17:18 +0100 Subject: [PATCH 025/141] Use ComicQueryResultProcesor --- YACReaderLibrary/db/comic_model.cpp | 52 +++++------------------------ YACReaderLibrary/db/comic_model.h | 4 +-- YACReaderLibrary/library_window.cpp | 34 +++++++++++-------- YACReaderLibrary/library_window.h | 3 ++ 4 files changed, 33 insertions(+), 60 deletions(-) diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index abfa2affd..ea03a6177 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -596,61 +596,25 @@ void ComicModel::setupReadingModelData(const QString &databasePath) endResetModel(); } -void ComicModel::setupModelData(const SearchModifiers modifier, const QString &filter, const QString &databasePath) +void ComicModel::setModelData(QList *data, const QString &databasePath) { - beginResetModel(); - qDeleteAll(_data); - _data.clear(); _databasePath = databasePath; - QString connectionName = ""; - { - QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath); - QSqlQuery selectQuery(db); - - std::string queryString("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened " - "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) LEFT JOIN folder f ON (f.id == c.parentId) WHERE "); - - try { - QueryParser parser; - auto result = parser.parse(filter.toStdString()); - result.buildSqlString(queryString); - - switch (modifier) { - case YACReader::NoModifiers: - queryString += " LIMIT :limit"; - break; - - case YACReader::OnlyRead: - queryString += " AND ci.read = 1 LIMIT :limit"; - break; + beginResetModel(); - case YACReader::OnlyUnread: - queryString += " AND ci.read = 0 LIMIT :limit"; - break; + qDeleteAll(_data); - default: - queryString += " LIMIT :limit"; - QLOG_ERROR() << "not implemented"; - break; - } - selectQuery.prepare(queryString.c_str()); - selectQuery.bindValue(":limit", 500); //TODO, load this value from settings - result.bindValues(selectQuery); + _data.clear(); - selectQuery.exec(); + QLOG_ERROR() << "-d2>" << data->size(); - setupModelData(selectQuery); - } catch (const std::exception &e) { - QLOG_ERROR() << "Unable to parse query: " << e.what(); - } + _data.append(*data); - connectionName = db.connectionName(); - } - QSqlDatabase::removeDatabase(connectionName); endResetModel(); emit searchNumResults(_data.length()); + + delete data; } QString ComicModel::getComicPath(QModelIndex mi) diff --git a/YACReaderLibrary/db/comic_model.h b/YACReaderLibrary/db/comic_model.h index 263eaa43c..b15e50e74 100644 --- a/YACReaderLibrary/db/comic_model.h +++ b/YACReaderLibrary/db/comic_model.h @@ -89,8 +89,6 @@ class ComicModel : public QAbstractItemModel void setupReadingListModelData(unsigned long long int parentReadingList, const QString &databasePath); void setupFavoritesModelData(const QString &databasePath); void setupReadingModelData(const QString &databasePath); - //configures the model for showing the comics matching the filter criteria. - void setupModelData(const SearchModifiers modifier, const QString &filter, const QString &databasePath); //Métodos de conveniencia QStringList getPaths(const QString &_source); @@ -142,6 +140,8 @@ public slots: void addComicsToLabel(const QList &comicIds, qulonglong labelId); void addComicsToReadingList(const QList &comicIds, qulonglong readingListId); + void setModelData(QList *data, const QString &databasePath); + protected: private: void setupModelData(QSqlQuery &sqlquery); diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 8da72b0ca..aad471a75 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -92,7 +92,7 @@ using namespace YACReader; LibraryWindow::LibraryWindow() - : QMainWindow(), fullscreen(false), previousFilter(""), fetching(false), status(LibraryWindow::Normal), removeError(false) + : QMainWindow(), fullscreen(false), previousFilter(""), fetching(false), status(LibraryWindow::Normal), removeError(false), comicQueryResultProcesor() { setupUI(); @@ -1053,10 +1053,9 @@ void LibraryWindow::createConnections() connect(optionsDialog, SIGNAL(optionsChanged()), this, SLOT(reloadOptions())); connect(optionsDialog, SIGNAL(editShortcuts()), editShortcutsDialog, SLOT(show())); - //Folders filter - //connect(clearFoldersFilter,SIGNAL(clicked()),foldersFilter,SLOT(clear())); + //Search filter connect(searchEdit, SIGNAL(filterChanged(YACReader::SearchModifiers, QString)), this, SLOT(setSearchFilter(YACReader::SearchModifiers, QString))); - //connect(includeComicsCheckBox,SIGNAL(stateChanged(int)),this,SLOT(searchInFiles(int))); + connect(&comicQueryResultProcesor, &ComicQueryResultProcesor::newData, this, &LibraryWindow::setComicSearchFilterData); //ContextMenus connect(openContainingFolderComicAction, SIGNAL(triggered()), this, SLOT(openContainingFolderComic())); @@ -2070,23 +2069,30 @@ void LibraryWindow::toNormal() void LibraryWindow::setSearchFilter(const YACReader::SearchModifiers modifier, QString filter) { if (!filter.isEmpty()) { - status = LibraryWindow::Searching; + //TODO move search query for folders to its own async processor foldersModelProxy->setFilter(modifier, filter, true); //includeComicsCheckBox->isChecked()); - comicsModel->setupModelData(modifier, filter, foldersModel->getDatabase()); - comicsViewsManager->comicsView->enableFilterMode(true); - comicsViewsManager->comicsView->setModel(comicsModel); //TODO, columns are messed up after ResetModel some times, this shouldn't be necesary - foldersView->expandAll(); - - if (comicsModel->rowCount() == 0) - comicsViewsManager->showNoSearchResultsView(); - else - comicsViewsManager->showComicsView(); + comicQueryResultProcesor.createModelData(modifier, filter, foldersModel->getDatabase()); } else if (status == LibraryWindow::Searching) { //if no searching, then ignore this clearSearchFilter(); navigationController->loadPreviousStatus(); } } +void LibraryWindow::setComicSearchFilterData(QList *data, const QString &databasePath) +{ + status = LibraryWindow::Searching; + + comicsModel->setModelData(data, databasePath); + comicsViewsManager->comicsView->enableFilterMode(true); + comicsViewsManager->comicsView->setModel(comicsModel); //TODO, columns are messed up after ResetModel some times, this shouldn't be necesary + foldersView->expandAll(); + + if (comicsModel->rowCount() == 0) + comicsViewsManager->showNoSearchResultsView(); + else + comicsViewsManager->showComicsView(); +} + void LibraryWindow::clearSearchFilter() { foldersModelProxy->clear(); diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index 993b58b9c..e4ebeda7e 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -10,6 +10,7 @@ #include "yacreader_libraries.h" #include "yacreader_navigation_controller.h" +#include "comic_query_result_procesor.h" #include @@ -327,6 +328,7 @@ public slots: void toNormal(); void toFullScreen(); void setSearchFilter(const YACReader::SearchModifiers modifier, QString filter); + void setComicSearchFilterData(QList *, const QString &); void clearSearchFilter(); void showProperties(); void exportLibrary(QString destPath); @@ -399,6 +401,7 @@ public slots: std::future upgradeLibraryFuture; TrayIconController *trayIconController; + ComicQueryResultProcesor comicQueryResultProcesor; }; #endif From 047fd246094102c2683171fa4d2b73ba6678e606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 09:17:49 +0100 Subject: [PATCH 026/141] Make the search line edit bigger --- custom_widgets/yacreader_search_line_edit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_widgets/yacreader_search_line_edit.cpp b/custom_widgets/yacreader_search_line_edit.cpp index 3a209a274..0232184e3 100644 --- a/custom_widgets/yacreader_search_line_edit.cpp +++ b/custom_widgets/yacreader_search_line_edit.cpp @@ -40,7 +40,7 @@ YACReaderSearchLineEdit::YACReaderSearchLineEdit(QWidget *parent) #ifdef Q_OS_MAC setMaximumWidth(212); #else - setMaximumWidth(173); + setMaximumWidth(255); setFixedHeight(26); #endif From 5343d24f26e88fbaaf18324806f41a9181e97372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 11:37:17 +0100 Subject: [PATCH 027/141] Run folder search filtering in the background It uses the same approach used by the comics search filter --- YACReaderLibrary/YACReaderLibrary.pro | 2 + YACReaderLibrary/db/folder_model.cpp | 268 +----------------- YACReaderLibrary/db/folder_model.h | 50 +--- .../db/folder_query_result_processor.cpp | 176 ++++++++++++ .../db/folder_query_result_processor.h | 36 +++ YACReaderLibrary/library_window.cpp | 12 +- YACReaderLibrary/library_window.h | 3 + 7 files changed, 238 insertions(+), 309 deletions(-) create mode 100644 YACReaderLibrary/db/folder_query_result_processor.cpp create mode 100644 YACReaderLibrary/db/folder_query_result_processor.h diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 4162cb36c..d0f0f0d33 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -79,6 +79,7 @@ HEADERS += comic_flow.h \ ../common/concurrent_queue.h \ create_library_dialog.h \ db/comic_query_result_procesor.h \ + db/folder_query_result_processor.h \ db/query_lexer.h \ library_creator.h \ library_window.h \ @@ -156,6 +157,7 @@ HEADERS += comic_flow.h \ SOURCES += comic_flow.cpp \ create_library_dialog.cpp \ db/comic_query_result_procesor.cpp \ + db/folder_query_result_processor.cpp \ db/query_lexer.cpp \ library_creator.cpp \ library_window.cpp \ diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 1944e1e19..b20ff402c 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -1,54 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor -** the names of its contributors may be used to endorse or promote -** products derived from this software without specific prior written -** permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - treemodel.cpp - - Provides a simple tree model to show how to create and use hierarchical - models. -*/ - -#include +#include "folder_model.h" #include "folder_item.h" -#include "folder_model.h" #include "data_base_management.h" #include "folder.h" #include "db_helper.h" @@ -57,6 +9,8 @@ #include "QsLog.h" #include "query_parser.h" +#include + #ifdef Q_OS_MAC #include QIcon finishedFolderIcon; @@ -104,7 +58,6 @@ FolderModel::FolderModel(QObject *parent) connect(this, SIGNAL(reset()), this, SIGNAL(modelReset())); } -//! [0] FolderModel::FolderModel(QSqlQuery &sqlquery, QObject *parent) : QAbstractItemModel(parent), rootItem(0) { @@ -117,17 +70,13 @@ FolderModel::FolderModel(QSqlQuery &sqlquery, QObject *parent) setupModelData(sqlquery, rootItem); //sqlquery.finish(); } -//! [0] -//! [1] FolderModel::~FolderModel() { if (rootItem != 0) delete rootItem; } -//! [1] -//! [2] int FolderModel::columnCount(const QModelIndex &parent) const { if (parent.isValid()) @@ -135,9 +84,7 @@ int FolderModel::columnCount(const QModelIndex &parent) const else return rootItem->columnCount(); } -//! [2] -//! [3] QVariant FolderModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) @@ -188,9 +135,7 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const return item->data(index.column()); } -//! [3] -//! [4] Qt::ItemFlags FolderModel::flags(const QModelIndex &index) const { if (!index.isValid()) @@ -198,9 +143,7 @@ Qt::ItemFlags FolderModel::flags(const QModelIndex &index) const return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled; } -//! [4] -//! [5] QVariant FolderModel::headerData(int section, Qt::Orientation orientation, int role) const { @@ -209,9 +152,7 @@ QVariant FolderModel::headerData(int section, Qt::Orientation orientation, return QVariant(); } -//! [5] -//! [6] QModelIndex FolderModel::index(int row, int column, const QModelIndex &parent) const { @@ -231,9 +172,7 @@ QModelIndex FolderModel::index(int row, int column, const QModelIndex &parent) else return QModelIndex(); } -//! [6] -//! [7] QModelIndex FolderModel::parent(const QModelIndex &index) const { if (!index.isValid()) @@ -247,19 +186,7 @@ QModelIndex FolderModel::parent(const QModelIndex &index) const return createIndex(parentItem->row(), 0, parentItem); } -//! [7] -/* -QModelIndex FolderModel::indexFromItem(FolderItem * item,int column) -{ - //if(item->parent() != 0) - // return index(item->row(),column,parent(indexFromItem(item->parent(),column-1))); - //else - // return index(item->row(),0,QModelIndex()); - return createIndex(item->row(), column, item); -}*/ - -//! [8] int FolderModel::rowCount(const QModelIndex &parent) const { FolderItem *parentItem; @@ -273,7 +200,6 @@ int FolderModel::rowCount(const QModelIndex &parent) const return parentItem->childCount(); } -//! [8] void FolderModel::setupModelData(QString path) { @@ -386,27 +312,6 @@ QString FolderModel::getFolderPath(const QModelIndex &folder) return static_cast(folder.internalPointer())->data(FolderModel::Path).toString(); } -/* -void FolderModel::resetFilter() -{ - beginResetModel(); - filter = ""; - includeComics = false; - //TODO hay que liberar la memoria reservada para el filtrado - //items.clear(); - filteredItems.clear(); - FolderItem * root = rootItem; - rootItem = rootBeforeFilter; //TODO si no se aplica el filtro previamente, esto invalidar�a en modelo - if(root !=0) - delete root; - - rootBeforeFilter = 0; - filterEnabled = false; - endResetModel(); - - -}*/ - void FolderModel::updateFolderCompletedStatus(const QModelIndexList &list, bool status) { QString connectionName = ""; @@ -626,7 +531,7 @@ void FolderModel::updateFolderChildrenInfo(qulonglong folderId) //PROXY FolderModelProxy::FolderModelProxy(QObject *parent) - : QSortFilterProxyModel(parent), rootItem(0), includeComics(true), filter(""), filterEnabled(false) + : QSortFilterProxyModel(parent), rootItem(0), filterEnabled(false) { } @@ -649,93 +554,23 @@ bool FolderModelProxy::filterAcceptsRow(int source_row, const QModelIndex &sourc return filteredItems.contains(item->id); } -void FolderModelProxy::setFilter(const YACReader::SearchModifiers modifier, QString filter, bool includeComics) +void FolderModelProxy::setFilterData(QMap *filteredItems, FolderItem *root) { clear(); - this->filter = filter; - this->includeComics = includeComics; - this->modifier = modifier; filterEnabled = true; - setupFilteredModelData(); -} -void FolderModelProxy::setupFilteredModelData() -{ beginResetModel(); - //TODO hay que liberar memoria de anteriores filtrados - - //inicializar el nodo ra�z - if (rootItem != 0) delete rootItem; //TODO comprobar que se libera bien la memoria - rootItem = 0; - - //inicializar el nodo ra�z - QList rootData; - rootData << "root"; - rootItem = new FolderItem(rootData); - rootItem->id = ROOT; - rootItem->parentItem = 0; + rootItem = root; - auto model = static_cast(sourceModel()); - - QString connectionName = ""; - { - QSqlDatabase db = DataBaseManagement::loadDatabase(model->_databasePath); - - QSqlQuery selectQuery(db); //TODO check - if (!includeComics) { - selectQuery.prepare("select * from folder where id <> 1 and upper(name) like upper(:filter) order by parentId,name "); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - } else { - std::string queryString("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed " - "FROM folder f LEFT JOIN comic c ON (f.id = c.parentId) " - "INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) WHERE "); - - try { - QueryParser parser; - auto result = parser.parse(filter.toStdString()); - result.buildSqlString(queryString); - - switch (modifier) { - case YACReader::NoModifiers: - queryString += " AND f.id <> 1 ORDER BY f.parentId,f.name"; - break; - - case YACReader::OnlyRead: - queryString += " AND f.id <> 1 AND ci.read = 1 ORDER BY f.parentId,f.name"; - break; - - case YACReader::OnlyUnread: - queryString += " AND f.id <> 1 AND ci.read = 0 ORDER BY f.parentId,f.name"; - break; - - default: - queryString += " AND f.id <> 1 ORDER BY f.parentId,f.name"; - QLOG_ERROR() << "not implemented"; - break; - } - - selectQuery.prepare(queryString.c_str()); - result.bindValues(selectQuery); - - selectQuery.exec(); - QLOG_DEBUG() << selectQuery.lastError() << "--"; - - setupFilteredModelData(selectQuery, rootItem); - } catch (const std::exception &e) { - QLOG_ERROR() << "Unable to parse query: " << e.what(); - } - } - - connectionName = db.connectionName(); + this->filteredItems.insert(*filteredItems); - endResetModel(); - } + endResetModel(); - QSqlDatabase::removeDatabase(connectionName); + delete filteredItems; } void FolderModelProxy::clear() @@ -746,88 +581,3 @@ void FolderModelProxy::clear() QSortFilterProxyModel::clear(); } - -void FolderModelProxy::setupFilteredModelData(QSqlQuery &sqlquery, FolderItem *parent) -{ - auto model = static_cast(sourceModel()); - - //64 bits para la primary key, es decir la misma precisi�n que soporta sqlit 2^64 - filteredItems.clear(); - - //se a�ade el nodo 0 al modelo que representa el arbol de elementos que cumplen con el filtro - filteredItems.insert(parent->id, parent); - - QSqlRecord record = sqlquery.record(); - - int name = record.indexOf("name"); - int path = record.indexOf("path"); - int finished = record.indexOf("finished"); - int completed = record.indexOf("completed"); - int parentIdIndex = record.indexOf("parentId"); - - while (sqlquery.next()) { //se procesan todos los folders que cumplen con el filtro - //datos de la base de datos - QList data; - - data << sqlquery.value(name).toString(); - data << sqlquery.value(path).toString(); - data << sqlquery.value(finished).toBool(); - data << sqlquery.value(completed).toBool(); - - auto item = new FolderItem(data); - item->id = sqlquery.value(0).toULongLong(); - - //id del padre - quint64 parentId = sqlquery.value(parentIdIndex).toULongLong(); - - //se a�ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones - if (!filteredItems.contains(item->id)) - filteredItems.insert(item->id, item); - - //es necesario conocer las coordenadas de origen para poder realizar scroll autom�tico en la vista - item->originalItem = model->items.value(item->id); - - //si el padre ya existe en el modelo, el item se a�ade como hijo - if (filteredItems.contains(parentId)) - filteredItems.value(parentId)->appendChild(item); - else //si el padre a�n no se ha a�adido, hay que a�adirlo a �l y todos los padres hasta el nodo ra�z - { - //comprobamos con esta variable si el �ltimo de los padres (antes del nodo ra�z) ya exist�a en el modelo - bool parentPreviousInserted = false; - - //mientras no se alcance el nodo ra�z se procesan todos los padres (de abajo a arriba) - while (parentId != ROOT) { - //el padre no estaba en el modelo filtrado, as� que se rescata del modelo original - FolderItem *parentItem = model->items.value(parentId); - //se debe crear un nuevo nodo (para no compartir los hijos con el nodo original) - FolderItem *newparentItem = new FolderItem(parentItem->getData()); //padre que se a�adir� a la estructura de directorios filtrados - newparentItem->id = parentId; - - newparentItem->originalItem = parentItem; - - //si el modelo contiene al padre, se a�ade el item actual como hijo - if (filteredItems.contains(parentId)) { - filteredItems.value(parentId)->appendChild(item); - parentPreviousInserted = true; - } - //sino se registra el nodo para poder encontrarlo con posterioridad y se a�ade el item actual como hijo - else { - newparentItem->appendChild(item); - filteredItems.insert(newparentItem->id, newparentItem); - parentPreviousInserted = false; - } - - //variables de control del bucle, se avanza hacia el nodo padre - item = newparentItem; - parentId = parentItem->parentItem->id; - } - - //si el nodo es hijo de 1 y no hab�a sido previamente insertado como hijo, se a�ade como tal - if (!parentPreviousInserted) { - filteredItems.value(ROOT)->appendChild(item); - } else { - delete item; - } - } - } -} diff --git a/YACReaderLibrary/db/folder_model.h b/YACReaderLibrary/db/folder_model.h index ecac40ee2..9597d07ca 100644 --- a/YACReaderLibrary/db/folder_model.h +++ b/YACReaderLibrary/db/folder_model.h @@ -1,43 +1,3 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor -** the names of its contributors may be used to endorse or promote -** products derived from this software without specific prior written -** permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** $QT_END_LICENSE$ -** -****************************************************************************/ - #ifndef TREEMODEL_H #define TREEMODEL_H @@ -49,6 +9,7 @@ #include #include "yacreader_global.h" +#include "folder_query_result_processor.h" class FolderItem; @@ -59,9 +20,7 @@ class FolderModelProxy : public QSortFilterProxyModel explicit FolderModelProxy(QObject *parent = 0); ~FolderModelProxy() override; - void setFilter(const YACReader::SearchModifiers modifier, QString filter, bool includeComics); - void setupFilteredModelData(QSqlQuery &sqlquery, FolderItem *parent); - void setupFilteredModelData(); + void setFilterData(QMap *filteredItems, FolderItem *root); void clear(); bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; @@ -70,8 +29,6 @@ class FolderModelProxy : public QSortFilterProxyModel FolderItem *rootItem; QMap filteredItems; //relación entre folders - bool includeComics; - QString filter; bool filterEnabled; YACReader::SearchModifiers modifier; @@ -79,10 +36,10 @@ class FolderModelProxy : public QSortFilterProxyModel class FolderModel : public QAbstractItemModel { - Q_OBJECT friend class FolderModelProxy; + friend class YACReader::FolderQueryResultProcessor; public: FolderModel(QObject *parent = 0); @@ -147,6 +104,5 @@ public slots: void beforeReset(); void reset(); }; -//! [0] #endif diff --git a/YACReaderLibrary/db/folder_query_result_processor.cpp b/YACReaderLibrary/db/folder_query_result_processor.cpp new file mode 100644 index 000000000..e0b6050d3 --- /dev/null +++ b/YACReaderLibrary/db/folder_query_result_processor.cpp @@ -0,0 +1,176 @@ +#include "folder_query_result_processor.h" + +#include "folder_item.h" +#include "qnaturalsorting.h" +#include "yacreader_global_gui.h" +#include "query_parser.h" +#include "folder_model.h" +#include "data_base_management.h" + +#include "QsLog.h" + +#include +#include + +//Copy/pasted from "folder_model.cpp" +#define ROOT 1 + +YACReader::FolderQueryResultProcessor::FolderQueryResultProcessor(FolderModel *model) + : querySearchQueue(1), model(model) +{ +} + +void YACReader::FolderQueryResultProcessor::createModelData(const YACReader::SearchModifiers modifier, const QString &filter, bool includeComics) +{ + querySearchQueue.cancellPending(); + + QString connectionName = ""; + { + QSqlDatabase db = DataBaseManagement::loadDatabase(model->getDatabase()); + + QSqlQuery selectQuery(db); //TODO check + if (!includeComics) { + selectQuery.prepare("select * from folder where id <> 1 and upper(name) like upper(:filter) order by parentId,name "); + selectQuery.bindValue(":filter", "%%" + filter + "%%"); + } else { + std::string queryString("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed " + "FROM folder f LEFT JOIN comic c ON (f.id = c.parentId) " + "INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) WHERE "); + + try { + QueryParser parser; + auto result = parser.parse(filter.toStdString()); + result.buildSqlString(queryString); + + switch (modifier) { + case YACReader::NoModifiers: + queryString += " AND f.id <> 1 ORDER BY f.parentId,f.name"; + break; + + case YACReader::OnlyRead: + queryString += " AND f.id <> 1 AND ci.read = 1 ORDER BY f.parentId,f.name"; + break; + + case YACReader::OnlyUnread: + queryString += " AND f.id <> 1 AND ci.read = 0 ORDER BY f.parentId,f.name"; + break; + + default: + queryString += " AND f.id <> 1 ORDER BY f.parentId,f.name"; + QLOG_ERROR() << "not implemented"; + break; + } + + selectQuery.prepare(queryString.c_str()); + result.bindValues(selectQuery); + + selectQuery.exec(); + QLOG_DEBUG() << selectQuery.lastError() << "--"; + + setupFilteredModelData(selectQuery); + } catch (const std::exception &e) { + //Do nothing, uncomplete search string will end here and it is part of how the QueryParser works + //I don't like the idea of using exceptions for this though + } + } + + connectionName = db.connectionName(); + } + + QSqlDatabase::removeDatabase(connectionName); +} + +void YACReader::FolderQueryResultProcessor::setupFilteredModelData(QSqlQuery &sqlquery) +{ + FolderItem *rootItem = 0; + + //inicializar el nodo ra�z + QList rootData; + rootData << "root"; + rootItem = new FolderItem(rootData); + rootItem->id = ROOT; + rootItem->parentItem = 0; + + FolderItem *parent = rootItem; + + QMap *filteredItems = new QMap(); + + //add tree root node + filteredItems->insert(parent->id, parent); + + QSqlRecord record = sqlquery.record(); + + int name = record.indexOf("name"); + int path = record.indexOf("path"); + int finished = record.indexOf("finished"); + int completed = record.indexOf("completed"); + int parentIdIndex = record.indexOf("parentId"); + + while (sqlquery.next()) { //se procesan todos los folders que cumplen con el filtro + //datos de la base de datos + QList data; + + data << sqlquery.value(name).toString(); + data << sqlquery.value(path).toString(); + data << sqlquery.value(finished).toBool(); + data << sqlquery.value(completed).toBool(); + + auto item = new FolderItem(data); + item->id = sqlquery.value(0).toULongLong(); + + //id del padre + quint64 parentId = sqlquery.value(parentIdIndex).toULongLong(); + + //se a�ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones + if (!filteredItems->contains(item->id)) + filteredItems->insert(item->id, item); + + //es necesario conocer las coordenadas de origen para poder realizar scroll autom�tico en la vista + item->originalItem = model->items.value(item->id); + + //si el padre ya existe en el modelo, el item se a�ade como hijo + if (filteredItems->contains(parentId)) + filteredItems->value(parentId)->appendChild(item); + else //si el padre a�n no se ha a�adido, hay que a�adirlo a �l y todos los padres hasta el nodo ra�z + { + //comprobamos con esta variable si el �ltimo de los padres (antes del nodo ra�z) ya exist�a en el modelo + bool parentPreviousInserted = false; + + //mientras no se alcance el nodo ra�z se procesan todos los padres (de abajo a arriba) + while (parentId != ROOT) { + //el padre no estaba en el modelo filtrado, as� que se rescata del modelo original + FolderItem *parentItem = model->items.value(parentId); + //se debe crear un nuevo nodo (para no compartir los hijos con el nodo original) + FolderItem *newparentItem = new FolderItem(parentItem->getData()); //padre que se a�adir� a la estructura de directorios filtrados + newparentItem->id = parentId; + + newparentItem->originalItem = parentItem; + + //si el modelo contiene al padre, se a�ade el item actual como hijo + if (filteredItems->contains(parentId)) { + filteredItems->value(parentId)->appendChild(item); + parentPreviousInserted = true; + } + //sino se registra el nodo para poder encontrarlo con posterioridad y se a�ade el item actual como hijo + else { + newparentItem->appendChild(item); + filteredItems->insert(newparentItem->id, newparentItem); + parentPreviousInserted = false; + } + + //variables de control del bucle, se avanza hacia el nodo padre + item = newparentItem; + parentId = parentItem->parentItem->id; + } + + //si el nodo es hijo de 1 y no hab�a sido previamente insertado como hijo, se a�ade como tal + if (!parentPreviousInserted) { + filteredItems->value(ROOT)->appendChild(item); + } else { + delete item; + } + } + } + + emit newData(filteredItems, rootItem); +} diff --git a/YACReaderLibrary/db/folder_query_result_processor.h b/YACReaderLibrary/db/folder_query_result_processor.h new file mode 100644 index 000000000..a5612080a --- /dev/null +++ b/YACReaderLibrary/db/folder_query_result_processor.h @@ -0,0 +1,36 @@ +#ifndef FOLDER_QUERY_RESULT_PROCESSOR_H +#define FOLDER_QUERY_RESULT_PROCESSOR_H + +#include + +#include "yacreader_global_gui.h" +#include "concurrent_queue.h" + +class FolderItem; +class FolderModel; +class QSqlQuery; + +namespace YACReader { + +class FolderQueryResultProcessor : public QObject +{ + Q_OBJECT +public: + FolderQueryResultProcessor(FolderModel *model); + +public slots: + void createModelData(const SearchModifiers modifier, const QString &filter, bool includeComics); + +signals: + void newData(QMap *filteredItems, FolderItem *root); + +private: + ConcurrentQueue querySearchQueue; + + FolderModel *model; + + void setupFilteredModelData(QSqlQuery &sqlquery); +}; +}; + +#endif // FOLDER_QUERY_RESULT_PROCESSOR_H diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index aad471a75..65f66b615 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -400,6 +400,7 @@ void LibraryWindow::doModels() //folders foldersModel = new FolderModel(); foldersModelProxy = new FolderModelProxy(); + folderQueryResultProcessor = new FolderQueryResultProcessor(foldersModel); //foldersModelProxy->setSourceModel(foldersModel); //comics comicsModel = new ComicModel(this); @@ -1056,6 +1057,7 @@ void LibraryWindow::createConnections() //Search filter connect(searchEdit, SIGNAL(filterChanged(YACReader::SearchModifiers, QString)), this, SLOT(setSearchFilter(YACReader::SearchModifiers, QString))); connect(&comicQueryResultProcesor, &ComicQueryResultProcesor::newData, this, &LibraryWindow::setComicSearchFilterData); + connect(folderQueryResultProcessor, &FolderQueryResultProcessor::newData, this, &LibraryWindow::setFolderSearchFilterData); //ContextMenus connect(openContainingFolderComicAction, SIGNAL(triggered()), this, SLOT(openContainingFolderComic())); @@ -2069,8 +2071,7 @@ void LibraryWindow::toNormal() void LibraryWindow::setSearchFilter(const YACReader::SearchModifiers modifier, QString filter) { if (!filter.isEmpty()) { - //TODO move search query for folders to its own async processor - foldersModelProxy->setFilter(modifier, filter, true); //includeComicsCheckBox->isChecked()); + folderQueryResultProcessor->createModelData(modifier, filter, true); comicQueryResultProcesor.createModelData(modifier, filter, foldersModel->getDatabase()); } else if (status == LibraryWindow::Searching) { //if no searching, then ignore this clearSearchFilter(); @@ -2085,7 +2086,6 @@ void LibraryWindow::setComicSearchFilterData(QList *data, const QSt comicsModel->setModelData(data, databasePath); comicsViewsManager->comicsView->enableFilterMode(true); comicsViewsManager->comicsView->setModel(comicsModel); //TODO, columns are messed up after ResetModel some times, this shouldn't be necesary - foldersView->expandAll(); if (comicsModel->rowCount() == 0) comicsViewsManager->showNoSearchResultsView(); @@ -2093,6 +2093,12 @@ void LibraryWindow::setComicSearchFilterData(QList *data, const QSt comicsViewsManager->showComicsView(); } +void LibraryWindow::setFolderSearchFilterData(QMap *filteredItems, FolderItem *root) +{ + foldersModelProxy->setFilterData(filteredItems, root); + foldersView->expandAll(); +} + void LibraryWindow::clearSearchFilter() { foldersModelProxy->clear(); diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index e4ebeda7e..4e626cf38 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -11,6 +11,7 @@ #include "yacreader_navigation_controller.h" #include "comic_query_result_procesor.h" +#include "folder_query_result_processor.h" #include @@ -329,6 +330,7 @@ public slots: void toFullScreen(); void setSearchFilter(const YACReader::SearchModifiers modifier, QString filter); void setComicSearchFilterData(QList *, const QString &); + void setFolderSearchFilterData(QMap *filteredItems, FolderItem *root); void clearSearchFilter(); void showProperties(); void exportLibrary(QString destPath); @@ -402,6 +404,7 @@ public slots: TrayIconController *trayIconController; ComicQueryResultProcesor comicQueryResultProcesor; + FolderQueryResultProcessor *folderQueryResultProcessor; }; #endif From c3b0780e03e062a580184a0d826e503a7dcf9f4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 11:37:37 +0100 Subject: [PATCH 028/141] Remove unused constant --- common/yacreader_global.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/yacreader_global.h b/common/yacreader_global.h index e52d73a7a..770e35e9f 100644 --- a/common/yacreader_global.h +++ b/common/yacreader_global.h @@ -36,8 +36,7 @@ enum YACReaderErrors { enum SearchModifiers { NoModifiers = 0, OnlyRead, - OnlyUnread, - ByAuthor + OnlyUnread }; enum LabelColors { From dde60b78eae8f87c4821eeb455dda534656bfa59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 11:38:45 +0100 Subject: [PATCH 029/141] YACReaderLibrary compiles using c++11 just fine It is probably worth to bump this to c++14 and ideally use c++17, but it will be done in a separate branch. --- YACReaderLibrary/YACReaderLibrary.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index d0f0f0d33..a3b20ab4d 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -14,6 +14,8 @@ INCLUDEPATH += . \ DEFINES += SERVER_RELEASE NOMINMAX YACREADER_LIBRARY +CONFIG += c++11 + # load default build flags include (../config.pri) include (../dependencies/pdf_backend.pri) From f803b54f2ed76cdadd6de831c88142f5fdc5dec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 12:25:24 +0100 Subject: [PATCH 030/141] Add support for boolean folder fields --- YACReaderLibrary/db/query_parser.cpp | 9 ++++++--- YACReaderLibrary/db/query_parser.h | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index 36916b53b..2620a81b6 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -7,10 +7,11 @@ const std::map> QueryParser::fieldNames { { FieldType::numeric, { "numpages", "number", "count", "arcnumber", "arccount" } }, { FieldType::text, { "title", "volume", "storyarc", "genere", "writer", "penciller", "inker", "colorist", "letterer", "coverartist", "publisher", "format", "agerating", "synopsis", "characters", "notes" } }, - { FieldType::boolean, { "isbis", "color" } }, + { FieldType::boolean, { "isbis", "color", "read" } }, { FieldType::date, { "date" } }, { FieldType::filename, { "filename" } }, - { FieldType::folder, { "folder" } } + { FieldType::folder, { "folder" } }, + { FieldType::booleanFolder, { "completed", "finished" } }, }; int QueryParser::TreeNode::buildSqlString(std::string &sqlString, int bindPosition) const @@ -30,6 +31,8 @@ int QueryParser::TreeNode::buildSqlString(std::string &sqlString, int bindPositi sqlString += "(UPPER(c." + children[0].t + ") LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; } else if (fieldType(children[0].t) == FieldType::folder) { sqlString += "(UPPER(f.name) LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; + } else if (fieldType(children[0].t) == FieldType::booleanFolder) { + sqlString += "f." + children[0].t + " = :bindPosition" + std::to_string(bindPosition) + " "; } else { sqlString += "(UPPER(ci." + children[0].t + ") LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; } @@ -52,7 +55,7 @@ int QueryParser::TreeNode::bindValues(QSqlQuery &selectQuery, int bindPosition) { if (t == "token") { std::string bind_string(":bindPosition" + std::to_string(++bindPosition)); - if (isIn(fieldType(children[0].t), { FieldType::numeric, FieldType::boolean })) { + if (isIn(fieldType(children[0].t), { FieldType::numeric, FieldType::boolean, FieldType::booleanFolder })) { selectQuery.bindValue(QString::fromStdString(bind_string), std::stoi(children[1].t)); } else { selectQuery.bindValue(QString::fromStdString(bind_string), QString::fromStdString("%%" + children[1].t + "%%")); diff --git a/YACReaderLibrary/db/query_parser.h b/YACReaderLibrary/db/query_parser.h index 7aca5ca95..4b8f0c4e5 100644 --- a/YACReaderLibrary/db/query_parser.h +++ b/YACReaderLibrary/db/query_parser.h @@ -81,6 +81,7 @@ class QueryParser boolean, date, folder, + booleanFolder, filename }; static FieldType fieldType(const std::string &str); From f03ad848cbf8f6b580bac5bc9af312ee3259fd79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 15:32:20 +0100 Subject: [PATCH 031/141] Add support for `true` and `false` literals to be used with bool fields The lexer itself should be responsible for parsing those values but it will require a bigger refactoring. --- YACReaderLibrary/db/query_parser.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index 2620a81b6..5a45160bc 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -55,8 +55,17 @@ int QueryParser::TreeNode::bindValues(QSqlQuery &selectQuery, int bindPosition) { if (t == "token") { std::string bind_string(":bindPosition" + std::to_string(++bindPosition)); - if (isIn(fieldType(children[0].t), { FieldType::numeric, FieldType::boolean, FieldType::booleanFolder })) { + if (isIn(fieldType(children[0].t), { FieldType::numeric })) { selectQuery.bindValue(QString::fromStdString(bind_string), std::stoi(children[1].t)); + } else if (isIn(fieldType(children[0].t), { FieldType::boolean, FieldType::booleanFolder })) { + auto value = toLower(children[1].t); + if (value == "true") { + selectQuery.bindValue(QString::fromStdString(bind_string), 1); + } else if (value == "false") { + selectQuery.bindValue(QString::fromStdString(bind_string), 0); + } else { + selectQuery.bindValue(QString::fromStdString(bind_string), std::stoi(value)); + } } else { selectQuery.bindValue(QString::fromStdString(bind_string), QString::fromStdString("%%" + children[1].t + "%%")); } From 82eb5c0a8bfe2142cccfd13472b50209bb9322e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 15:51:20 +0100 Subject: [PATCH 032/141] Add fallback for qt < 5.15 --- YACReaderLibrary/db/folder_model.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index b20ff402c..288a7dde1 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -566,7 +566,13 @@ void FolderModelProxy::setFilterData(QMap *fil rootItem = root; +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + QMap::iterator i; + for (i = filteredItems->begin(); i != filteredItems->end(); ++i) + this->filteredItems.insert(i.key(), i.value()); +#else this->filteredItems.insert(*filteredItems); +#endif endResetModel(); From 24c0a783de42ed1bac7d4d4930c107bfb5f42ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 18:42:21 +0100 Subject: [PATCH 033/141] Remove reference to lexertl's license --- YACReaderLibrary/YACReaderLibrary.pro | 3 --- 1 file changed, 3 deletions(-) diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index a3b20ab4d..4af13332d 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -331,6 +331,3 @@ translation.files = ../release/languages/yacreaderlibrary_* manpage.path = $$DATADIR/man/man1 manpage.files = ../YACReaderLibrary.1 } - -DISTFILES += \ - lexertl/licence_1_0.txt From 6bb64c54678804b5e8dc559da0bddfb524896944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 18:42:51 +0100 Subject: [PATCH 034/141] Import non-gui global header --- YACReaderLibrary/db/comic_query_result_procesor.h | 2 +- YACReaderLibrary/db/folder_query_result_processor.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/YACReaderLibrary/db/comic_query_result_procesor.h b/YACReaderLibrary/db/comic_query_result_procesor.h index ba71da99b..a948611c2 100644 --- a/YACReaderLibrary/db/comic_query_result_procesor.h +++ b/YACReaderLibrary/db/comic_query_result_procesor.h @@ -4,7 +4,7 @@ #include #include -#include "yacreader_global_gui.h" +#include "yacreader_global.h" #include "concurrent_queue.h" class ComicItem; diff --git a/YACReaderLibrary/db/folder_query_result_processor.h b/YACReaderLibrary/db/folder_query_result_processor.h index a5612080a..faa590462 100644 --- a/YACReaderLibrary/db/folder_query_result_processor.h +++ b/YACReaderLibrary/db/folder_query_result_processor.h @@ -3,7 +3,7 @@ #include -#include "yacreader_global_gui.h" +#include "yacreader_global.h" #include "concurrent_queue.h" class FolderItem; From 76a307d0d82e23679602aec81258fb83faf37100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 19:11:25 +0100 Subject: [PATCH 035/141] Remove comments --- YACReaderLibrary/db/comic_model.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/YACReaderLibrary/db/comic_model.h b/YACReaderLibrary/db/comic_model.h index b15e50e74..40f145175 100644 --- a/YACReaderLibrary/db/comic_model.h +++ b/YACReaderLibrary/db/comic_model.h @@ -16,7 +16,6 @@ class ComicItem; using namespace YACReader; -//! [0] class ComicModel : public QAbstractItemModel { Q_OBJECT @@ -164,6 +163,5 @@ public slots: void resortedIndexes(QList); void newSelectedIndex(const QModelIndex &); }; -//! [0] #endif From 7e72c8b691ae2402c9f3a16a0456e6f801aa8290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 14 Jan 2021 21:38:30 +0100 Subject: [PATCH 036/141] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e76a49788..c8c6f393a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ spanish only. Sorry for the mess. Version counting is based on semantic versioning (Major.Feature.Patch) ## WIP +### YACReaderLibrary +* New search engine. ## 9.7.1 ### YACReader From 3ab05c6777d0900a1f7fe4ce122a4da3100265c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 14:23:59 +0100 Subject: [PATCH 037/141] Add a new boolean field for tagging comics as manga --- YACReaderLibrary/db/data_base_management.cpp | 19 ++++++++++++++++++- YACReaderLibrary/db_helper.cpp | 14 +++++++++++++- common/comic_db.cpp | 6 ++++++ common/comic_db.h | 2 ++ common/yacreader_global.h | 2 +- 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/YACReaderLibrary/db/data_base_management.cpp b/YACReaderLibrary/db/data_base_management.cpp index eb7606dee..58de1b35b 100644 --- a/YACReaderLibrary/db/data_base_management.cpp +++ b/YACReaderLibrary/db/data_base_management.cpp @@ -181,7 +181,9 @@ bool DataBaseManagement::createTables(QSqlDatabase &database) //new 9.5 fields "lastTimeOpened INTEGER," "coverSizeRatio REAL," - "originalCoverSize STRING" //h/w + "originalCoverSize STRING," //h/w + //new 9.8 fields + "manga BOOLEAN DEFAULT 0" ")"); success = success && queryComicInfo.exec(); @@ -402,6 +404,7 @@ bool DataBaseManagement::importComicsInfo(QString source, QString dest) "format = :format," "color = :color," "ageRating = :ageRating," + "manga = :manga" "synopsis = :synopsis," "characters = :characters," @@ -478,6 +481,7 @@ bool DataBaseManagement::importComicsInfo(QString source, QString dest) ":format," ":color," ":ageRating," + ":manga," ":synopsis," ":characters," @@ -580,6 +584,7 @@ void DataBaseManagement::bindValuesFromRecord(const QSqlRecord &record, QSqlQuer bindString("format", record, query); bindInt("color", record, query); bindString("ageRating", record, query); + bindInt("manga", record, query); bindString("synopsis", record, query); bindString("characters", record, query); @@ -707,6 +712,7 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &path) bool pre7_1 = false; bool pre8 = false; bool pre9_5 = false; + bool pre9_8 = false; QString fullPath = path + "/library.ydb"; @@ -718,6 +724,8 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &path) pre8 = true; if (compareVersions(DataBaseManagement::checkValidDB(fullPath), "9.5.0") < 0) pre9_5 = true; + if (compareVersions(DataBaseManagement::checkValidDB(fullPath), "9.8.0") < 0) + pre9_8 = true; QString connectionName = ""; bool returnValue = false; @@ -828,6 +836,15 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &path) db.commit(); } } + + if (pre9_8) { + { //comic_info + QStringList columnDefs; + columnDefs << "manga BOOLEAN DEFAULT 0"; + bool successAddingColumns = addColumns("comic_info", columnDefs, db); + returnValue = returnValue && successAddingColumns; + } + } } connectionName = db.connectionName(); } diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index 47fdc68c6..942dc4f0b 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -564,7 +564,11 @@ void DBHelper::update(ComicInfo *comicInfo, QSqlDatabase &db) "lastTimeOpened = :lastTimeOpened," "coverSizeRatio = :coverSizeRatio," - "originalCoverSize = :originalCoverSize" + "originalCoverSize = :originalCoverSize," + //-- + + //new 9.8 fields + "manga = :manga" //-- " WHERE id = :id "); @@ -596,6 +600,7 @@ void DBHelper::update(ComicInfo *comicInfo, QSqlDatabase &db) updateComicInfo.bindValue(":format", comicInfo->format); updateComicInfo.bindValue(":color", comicInfo->color); updateComicInfo.bindValue(":ageRating", comicInfo->ageRating); + updateComicInfo.bindValue(":manga", comicInfo->manga); updateComicInfo.bindValue(":synopsis", comicInfo->synopsis); updateComicInfo.bindValue(":characters", comicInfo->characters); @@ -1330,6 +1335,7 @@ QList DBHelper::getSortedComicsFromParent(qulonglong parentId, QSqlData int format = record.indexOf("format"); int color = record.indexOf("color"); int ageRating = record.indexOf("ageRating"); + int manga = record.indexOf("manga"); int synopsis = record.indexOf("synopsis"); int characters = record.indexOf("characters"); @@ -1394,6 +1400,7 @@ QList DBHelper::getSortedComicsFromParent(qulonglong parentId, QSqlData currentItem.info.format = selectQuery.value(format); currentItem.info.color = selectQuery.value(color); currentItem.info.ageRating = selectQuery.value(ageRating); + currentItem.info.manga = selectQuery.value(manga); currentItem.info.synopsis = selectQuery.value(synopsis); currentItem.info.characters = selectQuery.value(characters); @@ -1696,6 +1703,7 @@ ComicInfo DBHelper::loadComicInfo(QString hash, QSqlDatabase &db) int format = record.indexOf("format"); int color = record.indexOf("color"); int ageRating = record.indexOf("ageRating"); + int manga = record.indexOf("manga"); int synopsis = record.indexOf("synopsis"); int characters = record.indexOf("characters"); @@ -1767,6 +1775,10 @@ ComicInfo DBHelper::loadComicInfo(QString hash, QSqlDatabase &db) comicInfo.originalCoverSize = findComicInfo.value(originalCoverSize); //-- + //new 9.8 fields + comicInfo.manga = findComicInfo.value(manga); + //-- + comicInfo.existOnDb = true; } else comicInfo.existOnDb = false; diff --git a/common/comic_db.cpp b/common/comic_db.cpp index 617c335d4..d508783dd 100644 --- a/common/comic_db.cpp +++ b/common/comic_db.cpp @@ -102,6 +102,9 @@ QString ComicDB::toTXT() if (!info.ageRating.isNull()) txt.append(QString("ageRating:%1\r\n").arg(info.ageRating.toString())); + + if (!info.manga.isNull()) + txt.append(QString("manga:%1\r\n").arg(info.manga.toString())); //Argumento if (!info.synopsis.isNull()) txt.append(QString("synopsis:%1\r\n").arg(info.synopsis.toString())); @@ -232,6 +235,7 @@ ComicInfo &ComicInfo::operator=(const ComicInfo &comicInfo) publisher = comicInfo.publisher; format = comicInfo.format; color = comicInfo.color; + manga = comicInfo.manga; ageRating = comicInfo.ageRating; synopsis = comicInfo.synopsis; characters = comicInfo.characters; @@ -537,6 +541,7 @@ QDataStream &operator<<(QDataStream &stream, const ComicInfo &comicInfo) stream << comicInfo.format; stream << comicInfo.color; stream << comicInfo.ageRating; + stream << comicInfo.manga; stream << comicInfo.synopsis; stream << comicInfo.characters; @@ -598,6 +603,7 @@ QDataStream &operator>>(QDataStream &stream, ComicInfo &comicInfo) stream >> comicInfo.format; stream >> comicInfo.color; stream >> comicInfo.ageRating; + stream >> comicInfo.manga; stream >> comicInfo.synopsis; stream >> comicInfo.characters; diff --git a/common/comic_db.h b/common/comic_db.h index 4dd5507c3..3f8a33ce8 100644 --- a/common/comic_db.h +++ b/common/comic_db.h @@ -73,6 +73,7 @@ class ComicInfo : public QObject QVariant format; //string QVariant color; //bool QVariant ageRating; //string + QVariant manga; //bool QVariant synopsis; //string QVariant characters; //string @@ -180,6 +181,7 @@ class ComicInfo : public QObject Q_PROPERTY(QVariant format MEMBER format CONSTANT) Q_PROPERTY(QVariant color MEMBER color CONSTANT) Q_PROPERTY(QVariant ageRating MEMBER ageRating CONSTANT) + Q_PROPERTY(QVariant manga MEMBER manga CONSTANT) Q_PROPERTY(QVariant synopsis MEMBER synopsis CONSTANT) Q_PROPERTY(QVariant characters MEMBER characters CONSTANT) diff --git a/common/yacreader_global.h b/common/yacreader_global.h index 770e35e9f..e35dca6e1 100644 --- a/common/yacreader_global.h +++ b/common/yacreader_global.h @@ -3,7 +3,7 @@ #include -#define VERSION "9.7.1" +#define VERSION "9.8.0" #define REMOTE_BROWSE_PERFORMANCE_WORKAROUND "REMOTE_BROWSE_PERFORMANCE_WORKAROUND" From 52953633e5c1eee354fbc81fa6e6e43949b34322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 14:24:14 +0100 Subject: [PATCH 038/141] Send manga field through the server --- YACReaderLibrary/server/yacreader_server_data_helper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/YACReaderLibrary/server/yacreader_server_data_helper.cpp b/YACReaderLibrary/server/yacreader_server_data_helper.cpp index 5af2389d2..f82030df4 100644 --- a/YACReaderLibrary/server/yacreader_server_data_helper.cpp +++ b/YACReaderLibrary/server/yacreader_server_data_helper.cpp @@ -54,6 +54,7 @@ QJsonObject YACReaderServerDataHelper::comicToJSON(const qulonglong libraryId, c json["title"] = comic.info.title.toString(); json["number"] = comic.info.number.toInt(); json["last_time_opened"] = comic.info.lastTimeOpened.toLongLong(); + json["manga"] = comic.info.manga.toBool(); return json; } From 97c7723b17284b1b1d8595ba85c6b11bd0011afe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 14:25:47 +0100 Subject: [PATCH 039/141] Add support for setting issues as manga/normal in the comics view --- YACReaderLibrary/db/comic_model.cpp | 18 +++++++++ YACReaderLibrary/db/comic_model.h | 1 + YACReaderLibrary/images.qrc | 4 ++ YACReaderLibrary/library_window.cpp | 39 ++++++++++++++++++++ YACReaderLibrary/library_window.h | 6 +++ images/comics_view_toolbar/setManga.png | Bin 0 -> 217 bytes images/comics_view_toolbar/setManga@2x.png | Bin 0 -> 334 bytes images/comics_view_toolbar/setNormal.png | Bin 0 -> 205 bytes images/comics_view_toolbar/setNormal@2x.png | Bin 0 -> 315 bytes shortcuts_management/shortcuts_manager.h | 2 + 10 files changed, 70 insertions(+) create mode 100644 images/comics_view_toolbar/setManga.png create mode 100644 images/comics_view_toolbar/setManga@2x.png create mode 100644 images/comics_view_toolbar/setNormal.png create mode 100644 images/comics_view_toolbar/setNormal@2x.png diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index ea03a6177..eb6bc40a3 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -778,6 +778,24 @@ QVector ComicModel::setComicsRead(QList l return getReadList(); } + +void ComicModel::setComicsManga(QList list, bool isManga) +{ + QString connectionName = ""; + { + QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); + db.transaction(); + foreach (QModelIndex mi, list) { + ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db); + c.info.manga = isManga; + DBHelper::update(&(c.info), db); + } + db.commit(); + connectionName = db.connectionName(); + } + QSqlDatabase::removeDatabase(connectionName); +} + qint64 ComicModel::asignNumbers(QList list, int startingNumber) { qint64 idFirst; diff --git a/YACReaderLibrary/db/comic_model.h b/YACReaderLibrary/db/comic_model.h index 40f145175..5d7f95bc4 100644 --- a/YACReaderLibrary/db/comic_model.h +++ b/YACReaderLibrary/db/comic_model.h @@ -105,6 +105,7 @@ class ComicModel : public QAbstractItemModel //setComicInfoForAllComics(); --> inserta la información común a todos los cómics de una sola vez. //setComicInfoForSelectedComis(QList list); -->inserta la información común para los comics seleccionados QVector setComicsRead(QList list, YACReaderComicReadStatus read); + void setComicsManga(QList list, bool isManga); qint64 asignNumbers(QList list, int startingNumber); //void remove(ComicDB * comic, int row); void removeInTransaction(int row); diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index 07aa91bcf..09366f1b6 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -38,6 +38,10 @@ ../images/comics_view_toolbar/trash@2x.png ../images/comics_view_toolbar/show_comic_info.png ../images/comics_view_toolbar/show_comic_info@2x.png + ../images/comics_view_toolbar/setManga.png + ../images/comics_view_toolbar/setManga@2x.png + ../images/comics_view_toolbar/setNormal.png + ../images/comics_view_toolbar/setNormal@2x.png ../images/coversPackage.png ../images/db.png ../images/defaultCover.png diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 65f66b615..892887351 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -324,6 +324,8 @@ void LibraryWindow::setUpShortcutsManagement() << saveCoversToAction << setAsReadAction << setAsNonReadAction + << setMangaAction + << setNormalAction << openContainingFolderComicAction << resetComicRatingAction << selectAllComicsAction @@ -508,6 +510,18 @@ void LibraryWindow::createActions() setAsNonReadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_NON_READ_ACTION_YL)); setAsNonReadAction->setIcon(QIcon(":/images/comics_view_toolbar/setUnread.png")); + setMangaAction = new QAction(tr("Set as manga"), this); + setMangaAction->setToolTip(tr("Set issue as manga")); + setMangaAction->setData(SET_AS_MANGA_ACTION_YL); + setMangaAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_MANGA_ACTION_YL)); + setMangaAction->setIcon(QIcon(":/images/comics_view_toolbar/setManga.png")); + + setNormalAction = new QAction(tr("Set as normal"), this); + setNormalAction->setToolTip(tr("Set issue as normal")); + setNormalAction->setData(SET_AS_NORMAL_ACTION_YL); + setNormalAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_NORMAL_ACTION_YL)); + setNormalAction->setIcon(QIcon(":/images/comics_view_toolbar/setNormal.png")); + /*setAllAsReadAction = new QAction(tr("Set all as read"),this); setAllAsReadAction->setToolTip(tr("Set all comics as read")); setAllAsReadAction->setIcon(QIcon(":/images/comics_view_toolbar/setAllRead.png")); @@ -753,6 +767,8 @@ void LibraryWindow::disableComicsActions(bool disabled) asignOrderAction->setDisabled(disabled); setAsReadAction->setDisabled(disabled); setAsNonReadAction->setDisabled(disabled); + setNormalAction->setDisabled(disabled); + setMangaAction->setDisabled(disabled); //setAllAsReadAction->setDisabled(disabled); //setAllAsNonReadAction->setDisabled(disabled); showHideMarksAction->setDisabled(disabled); @@ -870,6 +886,11 @@ void LibraryWindow::createToolBars() editInfoToolBar->addSeparator(); + editInfoToolBar->addAction(setNormalAction); + editInfoToolBar->addAction(setMangaAction); + + editInfoToolBar->addSeparator(); + editInfoToolBar->addAction(deleteComicsAction); comicsViewsManager->comicsView->setToolBar(editInfoToolBar); @@ -1019,6 +1040,8 @@ void LibraryWindow::createConnections() connect(openLibraryAction, SIGNAL(triggered()), this, SLOT(showAddLibrary())); connect(setAsReadAction, SIGNAL(triggered()), this, SLOT(setCurrentComicReaded())); connect(setAsNonReadAction, SIGNAL(triggered()), this, SLOT(setCurrentComicUnreaded())); + connect(setNormalAction, &QAction::triggered, this, &LibraryWindow::setSelectedComicsAsNormal); + connect(setMangaAction, &QAction::triggered, this, &LibraryWindow::setSelectedComicsAsManga); //connect(setAllAsReadAction,SIGNAL(triggered()),this,SLOT(setComicsReaded())); //connect(setAllAsNonReadAction,SIGNAL(triggered()),this,SLOT(setComicsUnreaded())); @@ -1594,6 +1617,9 @@ void LibraryWindow::showComicsViewContextMenu(const QPoint &point) menu.addAction(setAsReadAction); menu.addAction(setAsNonReadAction); menu.addSeparator(); + menu.addAction(setNormalAction); + menu.addAction(setMangaAction); + menu.addSeparator(); menu.addAction(deleteComicsAction); menu.addSeparator(); menu.addAction(addToMenuAction); @@ -1627,6 +1653,9 @@ void LibraryWindow::showComicsItemContextMenu(const QPoint &point) menu.addAction(setAsReadAction); menu.addAction(setAsNonReadAction); menu.addSeparator(); + menu.addAction(setNormalAction); + menu.addAction(setMangaAction); + menu.addSeparator(); menu.addAction(deleteComicsAction); menu.addSeparator(); menu.addAction(addToMenuAction); @@ -1793,6 +1822,16 @@ void LibraryWindow::setCurrentComicUnreaded() this->setCurrentComicsStatusReaded(YACReader::Unread); } +void LibraryWindow::setSelectedComicsAsNormal() +{ + comicsModel->setComicsManga(getSelectedComics(), false); +} + +void LibraryWindow::setSelectedComicsAsManga() +{ + comicsModel->setComicsManga(getSelectedComics(), true); +} + void LibraryWindow::createLibrary() { checkMaxNumLibraries(); diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index 4e626cf38..72f983cd7 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -193,6 +193,10 @@ class LibraryWindow : public QMainWindow QAction *openContainingFolderComicAction; QAction *setAsReadAction; QAction *setAsNonReadAction; + + QAction *setMangaAction; + QAction *setNormalAction; + //QAction * setAllAsReadAction; //QAction * setAllAsNonReadAction; QAction *showHideMarksAction; @@ -339,6 +343,8 @@ public slots: void setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus); void setCurrentComicReaded(); void setCurrentComicUnreaded(); + void setSelectedComicsAsNormal(); + void setSelectedComicsAsManga(); void showExportComicsInfo(); void showImportComicsInfo(); void asignNumbers(); diff --git a/images/comics_view_toolbar/setManga.png b/images/comics_view_toolbar/setManga.png new file mode 100644 index 0000000000000000000000000000000000000000..01b4631d0f2003b295ba5ac45d6be7521f403fe6 GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|&H|6fVg?3opai!Ne3C)x1^plZnN8d@lalE8DpqPWrLdMU+Dmwld=;^qo?U4 z2k-R!Z>@D@VvOvUZ;#H(hB_MDkdE!WR@rz*rk1T&UNZXr`G3j`+-LfAn=Bkl>VVE- N@O1TaS?83{1OQxKOl<%F literal 0 HcmV?d00001 diff --git a/images/comics_view_toolbar/setManga@2x.png b/images/comics_view_toolbar/setManga@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..aaf105969f9fca3a6d33a70c2d04f24f7ef12390 GIT binary patch literal 334 zcmV-U0kQsxP)1~&^ExB&(% z1luAlrbkKo{A_@GavzkEbzO&;I7MZXgd8~AE+L{DfC|9X^+C*>se65zvIS5w^K)D< zGNfc0ADKVsV>BwJT}Wj{n#w9fL>HmV=u9!=9(!hf?Wgh~y%^WnDpbcLR5SBEfXjfd zP*53o3I&(J(q3l4kQw(bouzf1r9ICjLn4_OIpo+EMD!4F8F1~PUJCQl={>OVd&t12 zWFndJ?V;dOt|gl@lrI!pr>uxgC>Tj-jY9~vJ9tbnZ9=82%XdseNF8f)p-lBL^7&CZ g{U2H*3H=1X8*}tarW7KxWB>pF07*qoM6N<$f_|lef&c&j literal 0 HcmV?d00001 diff --git a/images/comics_view_toolbar/setNormal.png b/images/comics_view_toolbar/setNormal.png new file mode 100644 index 0000000000000000000000000000000000000000..a7e8ae38600c979098fd7c60562bb3dd61ac9eb8 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|&H|6fVg?3opai!Nlu}$Ec{6!b^YzjcC5Lv4wDwKO7|YTz|gYFeUkg!J8o<5^sK2~ z`ToV5?A*sjn-ugWuzqYhvxmvc&+X>#oAoRS?5Dyt6*ONZOanTF!PC{xWt~$(69DUj BOAr76 literal 0 HcmV?d00001 diff --git a/images/comics_view_toolbar/setNormal@2x.png b/images/comics_view_toolbar/setNormal@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8cafb93045cfe8a0936793a834e124f92cf5eb25 GIT binary patch literal 315 zcmV-B0mS}^P)}bzwlw7eU}WaU>&7Ob z3^TXD{GjA9XU{TFPR3f(9*{*cRZm~`k{n2q1<<`KAZEU{K$%Qg3zS(8X`zbWvaf+c zqj9x9K@m~9ywqyUSDBQQzlVtEwl`&B4{7%|wf)e#rz99yCZvIZ6_6GN7CEt@)*`fY5zYY$$@qS;0a%AM??UMlfM7} N002ovPDHLkV1f@td({8{ literal 0 HcmV?d00001 diff --git a/shortcuts_management/shortcuts_manager.h b/shortcuts_management/shortcuts_manager.h index 2aee76a59..e831822f3 100644 --- a/shortcuts_management/shortcuts_manager.h +++ b/shortcuts_management/shortcuts_manager.h @@ -48,6 +48,8 @@ class ShortcutsManager #define OPEN_COMIC_ACTION_YL "OPEN_COMIC_ACTION_YL" #define SET_AS_READ_ACTION_YL "SET_AS_READ_ACTION_YL" #define SET_AS_NON_READ_ACTION_YL "SET_AS_NON_READ_ACTION_YL" +#define SET_AS_MANGA_ACTION_YL "SET_AS_MANGA_ACTION_YL" +#define SET_AS_NORMAL_ACTION_YL "SET_AS_MANGA_ACTION_YL" #define SHOW_HIDE_MARKS_ACTION_YL "SHOW_HIDE_MARKS_ACTION_YL" #define TOGGLE_FULL_SCREEN_ACTION_YL "TOGGLE_FULL_SCREEN_ACTION_YL" #define HELP_ABOUT_ACTION_YL "HELP_ABOUT_ACTION_YL" From bc82078ec90b697a8ab608d1618b690658bf3ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 14:26:07 +0100 Subject: [PATCH 040/141] Add new manga field to the edit comic dialog --- YACReaderLibrary/properties_dialog.cpp | 12 ++++++++++++ YACReaderLibrary/properties_dialog.h | 1 + 2 files changed, 13 insertions(+) diff --git a/YACReaderLibrary/properties_dialog.cpp b/YACReaderLibrary/properties_dialog.cpp index 5dee384e2..3cf177d4d 100644 --- a/YACReaderLibrary/properties_dialog.cpp +++ b/YACReaderLibrary/properties_dialog.cpp @@ -270,6 +270,7 @@ void PropertiesDialog::createPublishingBox() publishingLayout->addRow(tr("Format:"), formatEdit = new YACReaderFieldEdit()); publishingLayout->addRow(tr("Color/BW:"), colorCheck = new QCheckBox()); publishingLayout->addRow(tr("Age rating:"), ageRatingEdit = new YACReaderFieldEdit()); + publishingLayout->addRow(tr("Manga:"), mangaCheck = new QCheckBox()); publishingBox->setLayout(publishingLayout); } @@ -466,6 +467,8 @@ void PropertiesDialog::setComics(QList comics) else colorCheck->setCheckState(Qt::PartiallyChecked); + mangaCheck->setChecked(comic.info.manga.toBool()); + if (!comic.info.ageRating.isNull()) ageRatingEdit->setText(comic.info.ageRating.toString()); @@ -534,6 +537,8 @@ void PropertiesDialog::setComics(QList comics) formatEdit->clear(); if (itr->info.color.isNull() || itr->info.color.toBool() != colorCheck->isChecked()) colorCheck->setCheckState(Qt::PartiallyChecked); + if (itr->info.manga.toBool() != colorCheck->isChecked()) + mangaCheck->setCheckState(Qt::PartiallyChecked); if (itr->info.ageRating.isNull() || itr->info.ageRating.toString() != ageRatingEdit->text()) ageRatingEdit->clear(); @@ -699,6 +704,12 @@ void PropertiesDialog::save() itr->info.color = colorCheck->isChecked(); edited = true; } + + if (mangaCheck->checkState() != Qt::PartiallyChecked) { + itr->info.manga = mangaCheck->isChecked(); + edited = true; + } + if (ageRatingEdit->isModified()) { itr->info.ageRating = ageRatingEdit->text(); edited = true; @@ -778,6 +789,7 @@ void PropertiesDialog::closeEvent(QCloseEvent *e) publisherEdit->clear(); formatEdit->clear(); colorCheck->setCheckState(Qt::PartiallyChecked); + mangaCheck->setChecked(false); ageRatingEdit->clear(); synopsis->clear(); characters->clear(); diff --git a/YACReaderLibrary/properties_dialog.h b/YACReaderLibrary/properties_dialog.h index 6aa953d7b..ad32320f4 100644 --- a/YACReaderLibrary/properties_dialog.h +++ b/YACReaderLibrary/properties_dialog.h @@ -76,6 +76,7 @@ class PropertiesDialog : public QDialog YACReaderFieldEdit *formatEdit; QCheckBox *colorCheck; YACReaderFieldEdit *ageRatingEdit; + QCheckBox *mangaCheck; YACReaderFieldPlainTextEdit *synopsis; YACReaderFieldPlainTextEdit *characters; From 9643274b39300d2c7a0cb0f602799d467f536094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 14:26:37 +0100 Subject: [PATCH 041/141] Enable `manga` in the search engine --- YACReaderLibrary/db/query_parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index 5a45160bc..1ce645f7c 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -7,7 +7,7 @@ const std::map> QueryParser::fieldNames { { FieldType::numeric, { "numpages", "number", "count", "arcnumber", "arccount" } }, { FieldType::text, { "title", "volume", "storyarc", "genere", "writer", "penciller", "inker", "colorist", "letterer", "coverartist", "publisher", "format", "agerating", "synopsis", "characters", "notes" } }, - { FieldType::boolean, { "isbis", "color", "read" } }, + { FieldType::boolean, { "isbis", "color", "read", "manga" } }, { FieldType::date, { "date" } }, { FieldType::filename, { "filename" } }, { FieldType::folder, { "folder" } }, From 611d4c5e266fd759b0ebdfded0b7c8a8ef9e7e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 14:29:00 +0100 Subject: [PATCH 042/141] Add support for detecting manga issues in YACReader When an issues is open from YACReaderLibrary we can check if it is a manga an update the UI to enable manga reading. This also fixes going previous/next from the ui/shortcuts --- YACReader/main_window_viewer.cpp | 103 +++++++++++++++++++++++-------- YACReader/main_window_viewer.h | 4 ++ YACReader/render.cpp | 9 +++ YACReader/render.h | 1 + YACReader/viewer.cpp | 31 ++++++++++ YACReader/viewer.h | 4 ++ 6 files changed, 125 insertions(+), 27 deletions(-) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 3d7de60ff..50e795b76 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -265,7 +265,7 @@ void MainWindowViewer::createActions() openPreviousComicAction->setDisabled(true); openPreviousComicAction->setData(OPEN_PREVIOUS_COMIC_ACTION_Y); openPreviousComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_PREVIOUS_COMIC_ACTION_Y)); - connect(openPreviousComicAction, SIGNAL(triggered()), this, SLOT(openPreviousComic())); + connect(openPreviousComicAction, &QAction::triggered, this, &MainWindowViewer::openLeftComic); openNextComicAction = new QAction(tr("Next Comic"), this); openNextComicAction->setIcon(QIcon(":/images/viewer_toolbar/openNext.png")); @@ -273,7 +273,7 @@ void MainWindowViewer::createActions() openNextComicAction->setDisabled(true); openNextComicAction->setData(OPEN_NEXT_COMIC_ACTION_Y); openNextComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_NEXT_COMIC_ACTION_Y)); - connect(openNextComicAction, SIGNAL(triggered()), this, SLOT(openNextComic())); + connect(openNextComicAction, &QAction::triggered, this, &MainWindowViewer::openRightComic); prevAction = new QAction(tr("&Previous"), this); prevAction->setIcon(QIcon(":/images/viewer_toolbar/previous.png")); @@ -282,7 +282,7 @@ void MainWindowViewer::createActions() prevAction->setDisabled(true); prevAction->setData(PREV_ACTION_Y); prevAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(PREV_ACTION_Y)); - connect(prevAction, SIGNAL(triggered()), viewer, SLOT(prev())); + connect(prevAction, SIGNAL(triggered()), viewer, SLOT(left())); nextAction = new QAction(tr("&Next"), this); nextAction->setIcon(QIcon(":/images/viewer_toolbar/next.png")); @@ -291,7 +291,7 @@ void MainWindowViewer::createActions() nextAction->setDisabled(true); nextAction->setData(NEXT_ACTION_Y); nextAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(NEXT_ACTION_Y)); - connect(nextAction, SIGNAL(triggered()), viewer, SLOT(next())); + connect(nextAction, SIGNAL(triggered()), viewer, SLOT(right())); adjustHeightAction = new QAction(tr("Fit Height"), this); adjustHeightAction->setIcon(QIcon(":/images/viewer_toolbar/toHeight.png")); @@ -412,6 +412,7 @@ void MainWindowViewer::createActions() doubleMangaPageAction->setData(DOUBLE_MANGA_PAGE_ACTION_Y); doubleMangaPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(DOUBLE_MANGA_PAGE_ACTION_Y)); connect(doubleMangaPageAction, SIGNAL(triggered()), viewer, SLOT(doubleMangaPageSwitch())); + connect(doubleMangaPageAction, &QAction::triggered, this, &MainWindowViewer::doubleMangaPageSwitch); goToPageAction = new QAction(tr("Go To"), this); goToPageAction->setIcon(QIcon(":/images/viewer_toolbar/goto.png")); @@ -822,9 +823,6 @@ void MainWindowViewer::open() void MainWindowViewer::open(QString path, ComicDB &comic, QList &siblings) { - //currentComicDB = comic; - //siblingComics = siblings; - QFileInfo fi(path); if (!comic.info.title.isNull() && !comic.info.title.toString().isEmpty()) @@ -832,31 +830,22 @@ void MainWindowViewer::open(QString path, ComicDB &comic, QList &siblin else setWindowTitle("YACReader - " + fi.fileName()); + viewer->setMangaWithoutStoringSetting(comic.info.manga.toBool()); + doubleMangaPageAction->setChecked(comic.info.manga.toBool()); + viewer->open(path, comic); enableActions(); int index = siblings.indexOf(comic); + updateOpenPrevNextActions(index > 0, index + 1 < siblings.count()); optionsDialog->setFilters(currentComicDB.info.brightness, currentComicDB.info.contrast, currentComicDB.info.gamma); - - if (index > 0) - openPreviousComicAction->setDisabled(false); - else - openPreviousComicAction->setDisabled(true); - - if (index + 1 < siblings.count()) - openNextComicAction->setDisabled(false); - else - openNextComicAction->setDisabled(true); } void MainWindowViewer::open(QString path, qint64 comicId, qint64 libraryId) { - //QString pathFile = QCoreApplication::arguments().at(1); currentDirectory = path; - //quint64 comicId = QCoreApplication::arguments().at(2).split("=").at(1).toULongLong(); - //libraryId = QCoreApplication::arguments().at(3).split("=").at(1).toULongLong(); + this->libraryId = libraryId; - // this->path=path; enableActions(); @@ -881,8 +870,10 @@ void MainWindowViewer::open(QString path, qint64 comicId, qint64 libraryId) void MainWindowViewer::openComicFromPath(QString pathFile) { + doubleMangaPageAction->setChecked(Configuration::getConfiguration().getDoubleMangaPage()); openComic(pathFile); isClient = false; //this method is used for direct openings + updateOpenPrevNextActions(!previousComicPath.isEmpty(), !nextComicPath.isEmpty()); } //isClient shouldn't be modified when a siblinig comic is opened @@ -1406,6 +1397,16 @@ void MainWindowViewer::setUpShortcutsManagement() ShortcutsManager::getShortcutsManager().registerActions(allActions); } +void MainWindowViewer::doubleMangaPageSwitch() +{ + if (isClient) { + int index = siblingComics.indexOf(currentComicDB); + updateOpenPrevNextActions(index > 0, index + 1 < siblingComics.size()); + } else { + updateOpenPrevNextActions(!previousComicPath.isEmpty(), !nextComicPath.isEmpty()); + } +} + void MainWindowViewer::toggleFitToWidthSlider() { int y; @@ -1497,6 +1498,7 @@ void MainWindowViewer::openNextComic() currentComicDB = siblingComics.at(currentIndex + 1); open(currentDirectory + currentComicDB.path, currentComicDB, siblingComics); } + return; } if (!nextComicPath.isEmpty()) { @@ -1504,6 +1506,24 @@ void MainWindowViewer::openNextComic() } } +void MainWindowViewer::openLeftComic() +{ + if (viewer->getIsMangaMode()) { + openNextComic(); + } else { + openPreviousComic(); + } +} + +void MainWindowViewer::openRightComic() +{ + if (viewer->getIsMangaMode()) { + openPreviousComic(); + } else { + openNextComic(); + } +} + void MainWindowViewer::getSiblingComics(QString path, QString currentComic) { QDir d(path); @@ -1558,15 +1578,13 @@ void MainWindowViewer::getSiblingComics(QString path, QString currentComic) previousComicPath = nextComicPath = ""; if (index > 0) { previousComicPath = path + "/" + list.at(index - 1); - openPreviousComicAction->setDisabled(false); - } else - openPreviousComicAction->setDisabled(true); + } if (index + 1 < list.count()) { nextComicPath = path + "/" + list.at(index + 1); - openNextComicAction->setDisabled(false); - } else - openNextComicAction->setDisabled(true); + } + + updateOpenPrevNextActions(index > 0, index + 1 < list.count()); } void MainWindowViewer::dropEvent(QDropEvent *event) @@ -1671,3 +1689,34 @@ void MainWindowViewer::sendComic() retries--; } } + +void MainWindowViewer::updateOpenPrevNextActions(bool thereIsPrevious, bool thereIsNext) +{ + if (thereIsPrevious) { + if (viewer->getIsMangaMode()) { + openNextComicAction->setDisabled(false); + } else { + openPreviousComicAction->setDisabled(false); + } + } else { + if (viewer->getIsMangaMode()) { + openNextComicAction->setDisabled(true); + } else { + openPreviousComicAction->setDisabled(true); + } + } + + if (thereIsNext) { + if (viewer->getIsMangaMode()) { + openPreviousComicAction->setDisabled(false); + } else { + openNextComicAction->setDisabled(false); + } + } else { + if (viewer->getIsMangaMode()) { + openPreviousComicAction->setDisabled(true); + } else { + openNextComicAction->setDisabled(true); + } + } +} diff --git a/YACReader/main_window_viewer.h b/YACReader/main_window_viewer.h index 21ad8cdd6..6acf05cd3 100644 --- a/YACReader/main_window_viewer.h +++ b/YACReader/main_window_viewer.h @@ -50,6 +50,8 @@ public slots: void newVersion(); void openPreviousComic(); void openNextComic(); + void openLeftComic(); + void openRightComic(); void openComicFromPath(QString pathFile); void openSiblingComic(QString pathFile); void openComic(QString pathFile); @@ -68,6 +70,7 @@ public slots: void checkNewVersion(); void processReset(); void setUpShortcutsManagement(); + void doubleMangaPageSwitch(); void toggleFitToWidthSlider(); @@ -181,6 +184,7 @@ public slots: protected: void closeEvent(QCloseEvent *event) override; void sendComic(); + void updateOpenPrevNextActions(bool thereIsPrevious, bool thereIsNext); public: MainWindowViewer(); diff --git a/YACReader/render.cpp b/YACReader/render.cpp index 58501767e..ef9370887 100644 --- a/YACReader/render.cpp +++ b/YACReader/render.cpp @@ -1028,6 +1028,15 @@ void Render::doublePageSwitch() } } +void Render::setManga(bool manga) +{ + doubleMangaPage = manga; + if (comic && doublePage) { + //invalidate(); + update(); + } +} + void Render::doubleMangaPageSwitch() { doubleMangaPage = !doubleMangaPage; diff --git a/YACReader/render.h b/YACReader/render.h index e852cd647..6cf3bb6ce 100644 --- a/YACReader/render.h +++ b/YACReader/render.h @@ -144,6 +144,7 @@ public slots: bool previousPageIsDoublePage(); void goTo(int index); void doublePageSwitch(); + void setManga(bool manga); void doubleMangaPageSwitch(); void setRotation(int degrees); void setComic(Comic *c); diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index dd9e27bd2..08fa0914e 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -253,6 +253,24 @@ void Viewer::next() shouldOpenPrevious = false; } +void Viewer::left() +{ + if (doubleMangaPage) { + next(); + } else { + prev(); + } +} + +void Viewer::right() +{ + if (doubleMangaPage) { + prev(); + } else { + next(); + } +} + void Viewer::prev() { direction = -1; @@ -889,6 +907,14 @@ void Viewer::doublePageSwitch() Configuration::getConfiguration().setDoublePage(doublePage); } +void Viewer::setMangaWithoutStoringSetting(bool manga) +{ + doubleMangaPage = manga; + render->setManga(manga); + goToFlow->setFlowRightToLeft(doubleMangaPage); + //goToFlow->updateConfig(config.getSettings()); +} + void Viewer::doubleMangaPageSwitch() { doubleMangaPage = !doubleMangaPage; @@ -1026,6 +1052,11 @@ void Viewer::updateZoomRatio(int ratio) updateContentSize(); } +bool Viewer::getIsMangaMode() +{ + return doubleMangaPage; +} + void Viewer::updateConfig(QSettings *settings) { goToFlow->updateConfig(settings); diff --git a/YACReader/viewer.h b/YACReader/viewer.h index 75bc5dc8f..4c959a7c8 100644 --- a/YACReader/viewer.h +++ b/YACReader/viewer.h @@ -48,6 +48,8 @@ public slots: void open(QString pathFile, const ComicDB &comic); void prev(); void next(); + void left(); + void right(); void showGoToDialog(); void goTo(unsigned int page); void updatePage(); @@ -76,6 +78,7 @@ public slots: void setBookmark(bool); void save(); void doublePageSwitch(); + void setMangaWithoutStoringSetting(bool manga); void doubleMangaPageSwitch(); void resetContent(); void setLoadingMessage(); @@ -102,6 +105,7 @@ public slots: void showIsLastMessage(); int getCurrentPageNumber(); void updateZoomRatio(int ratio); + bool getIsMangaMode(); private: bool information; From c7cf012d519a754568517ffb920bbe875e91ee2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 14:34:28 +0100 Subject: [PATCH 043/141] Remove commented code --- YACReader/viewer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index 08fa0914e..e5bd5a870 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -912,7 +912,6 @@ void Viewer::setMangaWithoutStoringSetting(bool manga) doubleMangaPage = manga; render->setManga(manga); goToFlow->setFlowRightToLeft(doubleMangaPage); - //goToFlow->updateConfig(config.getSettings()); } void Viewer::doubleMangaPageSwitch() From d07de8fb2ed8649eff75e22bc13fc0f6c5f7a3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 14:59:37 +0100 Subject: [PATCH 044/141] Rename prev/next actions to reflect its positional behaviour --- YACReader/main_window_viewer.cpp | 146 +++++++++++++++++-------------- YACReader/main_window_viewer.h | 8 +- 2 files changed, 83 insertions(+), 71 deletions(-) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 50e795b76..c988259b3 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -86,10 +86,10 @@ MainWindowViewer::~MainWindowViewer() delete openFolderAction; delete openLatestComicAction; delete saveImageAction; - delete openPreviousComicAction; - delete openNextComicAction; - delete prevAction; - delete nextAction; + delete openComicOnTheLeftAction; + delete openComicOnTheRightAction; + delete goToPageOnTheLeftAction; + delete goToPageOnTheRightAction; delete adjustHeightAction; delete adjustWidthAction; delete leftRotationAction; @@ -259,39 +259,39 @@ void MainWindowViewer::createActions() saveImageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SAVE_IMAGE_ACTION_Y)); connect(saveImageAction, SIGNAL(triggered()), this, SLOT(saveImage())); - openPreviousComicAction = new QAction(tr("Previous Comic"), this); - openPreviousComicAction->setIcon(QIcon(":/images/viewer_toolbar/openPrevious.png")); - openPreviousComicAction->setToolTip(tr("Open previous comic")); - openPreviousComicAction->setDisabled(true); - openPreviousComicAction->setData(OPEN_PREVIOUS_COMIC_ACTION_Y); - openPreviousComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_PREVIOUS_COMIC_ACTION_Y)); - connect(openPreviousComicAction, &QAction::triggered, this, &MainWindowViewer::openLeftComic); - - openNextComicAction = new QAction(tr("Next Comic"), this); - openNextComicAction->setIcon(QIcon(":/images/viewer_toolbar/openNext.png")); - openNextComicAction->setToolTip(tr("Open next comic")); - openNextComicAction->setDisabled(true); - openNextComicAction->setData(OPEN_NEXT_COMIC_ACTION_Y); - openNextComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_NEXT_COMIC_ACTION_Y)); - connect(openNextComicAction, &QAction::triggered, this, &MainWindowViewer::openRightComic); - - prevAction = new QAction(tr("&Previous"), this); - prevAction->setIcon(QIcon(":/images/viewer_toolbar/previous.png")); - prevAction->setShortcutContext(Qt::WidgetShortcut); - prevAction->setToolTip(tr("Go to previous page")); - prevAction->setDisabled(true); - prevAction->setData(PREV_ACTION_Y); - prevAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(PREV_ACTION_Y)); - connect(prevAction, SIGNAL(triggered()), viewer, SLOT(left())); - - nextAction = new QAction(tr("&Next"), this); - nextAction->setIcon(QIcon(":/images/viewer_toolbar/next.png")); - nextAction->setShortcutContext(Qt::WidgetShortcut); - nextAction->setToolTip(tr("Go to next page")); - nextAction->setDisabled(true); - nextAction->setData(NEXT_ACTION_Y); - nextAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(NEXT_ACTION_Y)); - connect(nextAction, SIGNAL(triggered()), viewer, SLOT(right())); + openComicOnTheLeftAction = new QAction(tr("Previous Comic"), this); + openComicOnTheLeftAction->setIcon(QIcon(":/images/viewer_toolbar/openPrevious.png")); + openComicOnTheLeftAction->setToolTip(tr("Open previous comic")); + openComicOnTheLeftAction->setDisabled(true); + openComicOnTheLeftAction->setData(OPEN_PREVIOUS_COMIC_ACTION_Y); + openComicOnTheLeftAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_PREVIOUS_COMIC_ACTION_Y)); + connect(openComicOnTheLeftAction, &QAction::triggered, this, &MainWindowViewer::openLeftComic); + + openComicOnTheRightAction = new QAction(tr("Next Comic"), this); + openComicOnTheRightAction->setIcon(QIcon(":/images/viewer_toolbar/openNext.png")); + openComicOnTheRightAction->setToolTip(tr("Open next comic")); + openComicOnTheRightAction->setDisabled(true); + openComicOnTheRightAction->setData(OPEN_NEXT_COMIC_ACTION_Y); + openComicOnTheRightAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_NEXT_COMIC_ACTION_Y)); + connect(openComicOnTheRightAction, &QAction::triggered, this, &MainWindowViewer::openRightComic); + + goToPageOnTheLeftAction = new QAction(tr("&Previous"), this); + goToPageOnTheLeftAction->setIcon(QIcon(":/images/viewer_toolbar/previous.png")); + goToPageOnTheLeftAction->setShortcutContext(Qt::WidgetShortcut); + goToPageOnTheLeftAction->setToolTip(tr("Go to previous page")); + goToPageOnTheLeftAction->setDisabled(true); + goToPageOnTheLeftAction->setData(PREV_ACTION_Y); + goToPageOnTheLeftAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(PREV_ACTION_Y)); + connect(goToPageOnTheLeftAction, SIGNAL(triggered()), viewer, SLOT(left())); + + goToPageOnTheRightAction = new QAction(tr("&Next"), this); + goToPageOnTheRightAction->setIcon(QIcon(":/images/viewer_toolbar/next.png")); + goToPageOnTheRightAction->setShortcutContext(Qt::WidgetShortcut); + goToPageOnTheRightAction->setToolTip(tr("Go to next page")); + goToPageOnTheRightAction->setDisabled(true); + goToPageOnTheRightAction->setData(NEXT_ACTION_Y); + goToPageOnTheRightAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(NEXT_ACTION_Y)); + connect(goToPageOnTheRightAction, SIGNAL(triggered()), viewer, SLOT(right())); adjustHeightAction = new QAction(tr("Fit Height"), this); adjustHeightAction->setIcon(QIcon(":/images/viewer_toolbar/toHeight.png")); @@ -553,13 +553,13 @@ void MainWindowViewer::createToolBars() #endif comicToolBar->addAction(saveImageAction); - comicToolBar->addAction(openPreviousComicAction); - comicToolBar->addAction(openNextComicAction); + comicToolBar->addAction(openComicOnTheLeftAction); + comicToolBar->addAction(openComicOnTheRightAction); comicToolBar->addSeparator(); - comicToolBar->addAction(prevAction); - comicToolBar->addAction(nextAction); + comicToolBar->addAction(goToPageOnTheLeftAction); + comicToolBar->addAction(goToPageOnTheRightAction); comicToolBar->addAction(goToPageAction); comicToolBar->addSeparator(); @@ -616,12 +616,12 @@ void MainWindowViewer::createToolBars() viewer->addAction(openAction); viewer->addAction(openFolderAction); viewer->addAction(saveImageAction); - viewer->addAction(openPreviousComicAction); - viewer->addAction(openNextComicAction); + viewer->addAction(openComicOnTheLeftAction); + viewer->addAction(openComicOnTheRightAction); YACReader::addSperator(viewer); - viewer->addAction(prevAction); - viewer->addAction(nextAction); + viewer->addAction(goToPageOnTheLeftAction); + viewer->addAction(goToPageOnTheRightAction); viewer->addAction(goToPageAction); viewer->addAction(adjustHeightAction); viewer->addAction(adjustWidthAction); @@ -969,8 +969,8 @@ void MainWindowViewer::saveImage() void MainWindowViewer::enableActions() { saveImageAction->setDisabled(false); - prevAction->setDisabled(false); - nextAction->setDisabled(false); + goToPageOnTheLeftAction->setDisabled(false); + goToPageOnTheRightAction->setDisabled(false); adjustHeightAction->setDisabled(false); adjustWidthAction->setDisabled(false); goToPageAction->setDisabled(false); @@ -1001,8 +1001,8 @@ void MainWindowViewer::enableActions() void MainWindowViewer::disableActions() { saveImageAction->setDisabled(true); - prevAction->setDisabled(true); - nextAction->setDisabled(true); + goToPageOnTheLeftAction->setDisabled(true); + goToPageOnTheRightAction->setDisabled(true); adjustHeightAction->setDisabled(true); adjustWidthAction->setDisabled(true); goToPageAction->setDisabled(true); @@ -1021,8 +1021,8 @@ void MainWindowViewer::disableActions() setBookmarkAction->setDisabled(true); showBookmarksAction->setDisabled(true); showInfoAction->setDisabled(true); //TODO enable goTo and showInfo (or update) when numPages emited - openPreviousComicAction->setDisabled(true); - openNextComicAction->setDisabled(true); + openComicOnTheLeftAction->setDisabled(true); + openComicOnTheRightAction->setDisabled(true); showDictionaryAction->setDisabled(true); showFlowAction->setDisabled(true); } @@ -1219,11 +1219,11 @@ void MainWindowViewer::processReset() { if (isClient) { if (siblingComics.count() > 1) { - bool openNextB = openNextComicAction->isEnabled(); - bool openPrevB = openPreviousComicAction->isEnabled(); + bool openNextB = openComicOnTheRightAction->isEnabled(); + bool openPrevB = openComicOnTheLeftAction->isEnabled(); disableActions(); - openNextComicAction->setEnabled(openNextB); - openPreviousComicAction->setEnabled(openPrevB); + openComicOnTheRightAction->setEnabled(openNextB); + openComicOnTheLeftAction->setEnabled(openPrevB); } else disableActions(); } else @@ -1243,8 +1243,8 @@ void MainWindowViewer::setUpShortcutsManagement() openLatestComicAction, openFolderAction, saveImageAction, - openPreviousComicAction, - openNextComicAction }); + openComicOnTheLeftAction, + openComicOnTheRightAction }); allActions << tmpList; @@ -1374,8 +1374,8 @@ void MainWindowViewer::setUpShortcutsManagement() editShortcutsDialog->addActionsGroup(tr("Reading"), QIcon(":/images/shortcuts_group_reading.png"), tmpList = QList() - << nextAction - << prevAction + << goToPageOnTheRightAction + << goToPageOnTheLeftAction << setBookmarkAction << showBookmarksAction << autoScrollForwardAction @@ -1694,29 +1694,41 @@ void MainWindowViewer::updateOpenPrevNextActions(bool thereIsPrevious, bool ther { if (thereIsPrevious) { if (viewer->getIsMangaMode()) { - openNextComicAction->setDisabled(false); + openComicOnTheRightAction->setDisabled(false); } else { - openPreviousComicAction->setDisabled(false); + openComicOnTheLeftAction->setDisabled(false); } } else { if (viewer->getIsMangaMode()) { - openNextComicAction->setDisabled(true); + openComicOnTheRightAction->setDisabled(true); } else { - openPreviousComicAction->setDisabled(true); + openComicOnTheLeftAction->setDisabled(true); } } if (thereIsNext) { if (viewer->getIsMangaMode()) { - openPreviousComicAction->setDisabled(false); + openComicOnTheLeftAction->setDisabled(false); } else { - openNextComicAction->setDisabled(false); + openComicOnTheRightAction->setDisabled(false); } } else { if (viewer->getIsMangaMode()) { - openPreviousComicAction->setDisabled(true); + openComicOnTheLeftAction->setDisabled(true); } else { - openNextComicAction->setDisabled(true); + openComicOnTheRightAction->setDisabled(true); } } + + if (viewer->getIsMangaMode()) { + openComicOnTheLeftAction->setToolTip(tr("Open next comic")); + openComicOnTheRightAction->setToolTip(tr("Open previous comic")); + goToPageOnTheLeftAction->setToolTip(tr("Go to next page")); + goToPageOnTheRightAction->setToolTip(tr("Go to previous page")); + } else { + openComicOnTheLeftAction->setToolTip(tr("Open previous comic")); + openComicOnTheRightAction->setToolTip(tr("Open next comic")); + goToPageOnTheLeftAction->setToolTip(tr("Go to previous page")); + goToPageOnTheRightAction->setToolTip(tr("Go to next page")); + } } diff --git a/YACReader/main_window_viewer.h b/YACReader/main_window_viewer.h index 6acf05cd3..9d945969a 100644 --- a/YACReader/main_window_viewer.h +++ b/YACReader/main_window_viewer.h @@ -117,10 +117,10 @@ public slots: QList recentFilesActionList; QAction *clearRecentFilesAction; QAction *saveImageAction; - QAction *openPreviousComicAction; - QAction *openNextComicAction; - QAction *nextAction; - QAction *prevAction; + QAction *openComicOnTheLeftAction; + QAction *openComicOnTheRightAction; + QAction *goToPageOnTheRightAction; + QAction *goToPageOnTheLeftAction; QAction *adjustWidthAction; QAction *adjustHeightAction; QAction *goToPageAction; From a077434c7816e3f0f760cdfb1de6138cec22c69b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 15:04:20 +0100 Subject: [PATCH 045/141] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8c6f393a..7b3b2cadb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,11 @@ spanish only. Sorry for the mess. Version counting is based on semantic versioning (Major.Feature.Patch) ## WIP +### YACReader +* Add support for full manga mode. ### YACReaderLibrary * New search engine. +* New `manga` field added to comics to tag comics as manga. ## 9.7.1 ### YACReader From 2a3f7668ba75f01bc20b5fa0745eaef0136c98f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 18:27:16 +0100 Subject: [PATCH 046/141] Rename method --- YACReader/main_window_viewer.cpp | 12 ++++++------ YACReader/main_window_viewer.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index c988259b3..fc8a7695f 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -836,7 +836,7 @@ void MainWindowViewer::open(QString path, ComicDB &comic, QList &siblin viewer->open(path, comic); enableActions(); int index = siblings.indexOf(comic); - updateOpenPrevNextActions(index > 0, index + 1 < siblings.count()); + updatePrevNextActions(index > 0, index + 1 < siblings.count()); optionsDialog->setFilters(currentComicDB.info.brightness, currentComicDB.info.contrast, currentComicDB.info.gamma); } @@ -873,7 +873,7 @@ void MainWindowViewer::openComicFromPath(QString pathFile) doubleMangaPageAction->setChecked(Configuration::getConfiguration().getDoubleMangaPage()); openComic(pathFile); isClient = false; //this method is used for direct openings - updateOpenPrevNextActions(!previousComicPath.isEmpty(), !nextComicPath.isEmpty()); + updatePrevNextActions(!previousComicPath.isEmpty(), !nextComicPath.isEmpty()); } //isClient shouldn't be modified when a siblinig comic is opened @@ -1401,9 +1401,9 @@ void MainWindowViewer::doubleMangaPageSwitch() { if (isClient) { int index = siblingComics.indexOf(currentComicDB); - updateOpenPrevNextActions(index > 0, index + 1 < siblingComics.size()); + updatePrevNextActions(index > 0, index + 1 < siblingComics.size()); } else { - updateOpenPrevNextActions(!previousComicPath.isEmpty(), !nextComicPath.isEmpty()); + updatePrevNextActions(!previousComicPath.isEmpty(), !nextComicPath.isEmpty()); } } @@ -1584,7 +1584,7 @@ void MainWindowViewer::getSiblingComics(QString path, QString currentComic) nextComicPath = path + "/" + list.at(index + 1); } - updateOpenPrevNextActions(index > 0, index + 1 < list.count()); + updatePrevNextActions(index > 0, index + 1 < list.count()); } void MainWindowViewer::dropEvent(QDropEvent *event) @@ -1690,7 +1690,7 @@ void MainWindowViewer::sendComic() } } -void MainWindowViewer::updateOpenPrevNextActions(bool thereIsPrevious, bool thereIsNext) +void MainWindowViewer::updatePrevNextActions(bool thereIsPrevious, bool thereIsNext) { if (thereIsPrevious) { if (viewer->getIsMangaMode()) { diff --git a/YACReader/main_window_viewer.h b/YACReader/main_window_viewer.h index 9d945969a..466575c76 100644 --- a/YACReader/main_window_viewer.h +++ b/YACReader/main_window_viewer.h @@ -184,7 +184,7 @@ public slots: protected: void closeEvent(QCloseEvent *event) override; void sendComic(); - void updateOpenPrevNextActions(bool thereIsPrevious, bool thereIsNext); + void updatePrevNextActions(bool thereIsPrevious, bool thereIsNext); public: MainWindowViewer(); From f7fa4adbd03c880b6c9e98154d749c1008094172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 18:29:22 +0100 Subject: [PATCH 047/141] Add `manga` field to folders too This way we can tell the app that a folder contains mangas so the user doesn't have to constantly set comics as manga when new issues are added. And it should be easier to set all the content in a folder as manga from the folder tree. --- YACReaderLibrary/db/data_base_management.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/YACReaderLibrary/db/data_base_management.cpp b/YACReaderLibrary/db/data_base_management.cpp index 58de1b35b..3e41d77df 100644 --- a/YACReaderLibrary/db/data_base_management.cpp +++ b/YACReaderLibrary/db/data_base_management.cpp @@ -266,6 +266,7 @@ bool DataBaseManagement::createV8Tables(QSqlDatabase &database) "name TEXT NOT NULL, " "finished BOOLEAN DEFAULT 0, " "completed BOOLEAN DEFAULT 1, " + "manga BOOLEAN DEFAULT 0, " "FOREIGN KEY(parentId) REFERENCES reading_list(id) ON DELETE CASCADE)"); QSqlQuery queryIndexReadingList(database); @@ -844,6 +845,12 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &path) bool successAddingColumns = addColumns("comic_info", columnDefs, db); returnValue = returnValue && successAddingColumns; } + { //folder + QStringList columnDefs; + columnDefs << "manga BOOLEAN DEFAULT 0"; + bool successAddingColumns = addColumns("folder", columnDefs, db); + returnValue = returnValue && successAddingColumns; + } } } connectionName = db.connectionName(); From 60de69635b200f386ebd2d331c2ad9f42febaca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 18:30:25 +0100 Subject: [PATCH 048/141] Get/set new manga field from/to the db --- YACReaderLibrary/db_helper.cpp | 12 +++++++++++- common/folder.cpp | 1 + common/folder.h | 11 +++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index 942dc4f0b..c73233672 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -649,10 +649,12 @@ void DBHelper::update(const Folder &folder, QSqlDatabase &db) QSqlQuery updateFolderInfo(db); updateFolderInfo.prepare("UPDATE folder SET " "finished = :finished, " - "completed = :completed " + "completed = :completed, " + "manga = :manga " "WHERE id = :id "); updateFolderInfo.bindValue(":finished", folder.isFinished() ? 1 : 0); updateFolderInfo.bindValue(":completed", folder.isCompleted() ? 1 : 0); + updateFolderInfo.bindValue(":manga", folder.isManga() ? 1 : 0); updateFolderInfo.bindValue(":id", folder.id); updateFolderInfo.exec(); } @@ -1535,6 +1537,7 @@ Folder DBHelper::loadFolder(qulonglong id, QSqlDatabase &db) int path = record.indexOf("path"); int finished = record.indexOf("finished"); int completed = record.indexOf("completed"); + int manga = record.indexOf("manga"); int numChildren = record.indexOf("numChildren"); int firstChildHash = record.indexOf("firstChildHash"); int customImage = record.indexOf("customImage"); @@ -1554,6 +1557,9 @@ Folder DBHelper::loadFolder(qulonglong id, QSqlDatabase &db) folder.setNumChildren(query.value(numChildren).toInt()); folder.setFirstChildHash(query.value(firstChildHash).toString()); folder.setCustomImage(query.value(customImage).toString()); + + //new 9.8 + folder.setManga(query.value(manga).toBool()); } return folder; @@ -1576,6 +1582,7 @@ Folder DBHelper::loadFolder(const QString &folderName, qulonglong parentId, QSql int path = record.indexOf("path"); int finished = record.indexOf("finished"); int completed = record.indexOf("completed"); + int manga = record.indexOf("manga"); int numChildren = record.indexOf("numChildren"); int firstChildHash = record.indexOf("firstChildHash"); int customImage = record.indexOf("customImage"); @@ -1596,6 +1603,9 @@ Folder DBHelper::loadFolder(const QString &folderName, qulonglong parentId, QSql folder.setNumChildren(query.value(numChildren).toInt()); folder.setFirstChildHash(query.value(firstChildHash).toString()); folder.setCustomImage(query.value(customImage).toString()); + + //new 9.8 + folder.setManga(query.value(manga).toBool()); } return folder; diff --git a/common/folder.cpp b/common/folder.cpp index 8f66f76dd..27c58b2aa 100644 --- a/common/folder.cpp +++ b/common/folder.cpp @@ -31,6 +31,7 @@ Folder &Folder::operator=(const Folder &other) this->knownId = other.knownId; this->finished = other.finished; this->completed = other.completed; + this->manga = other.manga; return *this; } diff --git a/common/folder.h b/common/folder.h index 040a181fb..25d03d9ae 100644 --- a/common/folder.h +++ b/common/folder.h @@ -43,6 +43,11 @@ class Folder : public LibraryItem return completed; } + inline bool isManga() const + { + return manga; + } + inline void setFinished(bool b) { finished = b; @@ -53,6 +58,11 @@ class Folder : public LibraryItem completed = b; } + inline void setManga(bool b) + { + manga = b; + } + inline qint32 getNumChildren() const { return numChildren; @@ -86,6 +96,7 @@ class Folder : public LibraryItem private: bool finished; bool completed; + bool manga; qint32 numChildren; //-1 for unknown number of children QString firstChildHash; //empty for unknown first child From d40299999109d2c36338b308a231e4dfa735def8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 18:31:13 +0100 Subject: [PATCH 049/141] Set all new imported comics and folders as manga if the parent folder is manga --- YACReaderLibrary/library_creator.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/YACReaderLibrary/library_creator.cpp b/YACReaderLibrary/library_creator.cpp index 0ee8a493f..7318bce81 100644 --- a/YACReaderLibrary/library_creator.cpp +++ b/YACReaderLibrary/library_creator.cpp @@ -223,14 +223,18 @@ qulonglong LibraryCreator::insertFolders() auto _database = QSqlDatabase::database(_databaseConnection); QList::iterator i; int currentId = 0; + Folder currentParent; for (i = _currentPathFolders.begin(); i != _currentPathFolders.end(); ++i) { if (!(i->knownId)) { i->setFather(currentId); + i->setManga(currentParent.isManga()); currentId = DBHelper::insert(&(*i), _database); //insertFolder(currentId,*i); i->setId(currentId); } else { currentId = i->id; } + + currentParent = *i; } return currentId; } @@ -311,6 +315,7 @@ void LibraryCreator::insertComic(const QString &relativePath, const QFileInfo &f } comic.parentId = _currentPathFolders.last().id; + comic.info.manga = _currentPathFolders.last().isManga(); DBHelper::insert(&comic, _database); } } From 6461a4014ea48ebb2c740e013fc22b1abdc3710a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 16 Jan 2021 18:31:48 +0100 Subject: [PATCH 050/141] Add actions for setting folders as manga/normal --- YACReaderLibrary/db/folder_model.cpp | 41 +++++++++++++++++++++- YACReaderLibrary/db/folder_model.h | 7 ++-- YACReaderLibrary/db_helper.cpp | 31 +++++++++++++++++ YACReaderLibrary/db_helper.h | 2 ++ YACReaderLibrary/library_window.cpp | 44 ++++++++++++++++++++++++ YACReaderLibrary/library_window.h | 4 +++ shortcuts_management/shortcuts_manager.h | 2 ++ 7 files changed, 128 insertions(+), 3 deletions(-) diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 288a7dde1..576ebbedb 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -127,6 +127,9 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const if (role == FolderModel::FinishedRole) return item->data(FolderModel::Finished); + if (role == FolderModel::MangaRole) + return item->data(FolderModel::Manga); + if (role == FolderModel::IdRole) return item->id; @@ -246,6 +249,7 @@ void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent) int path = record.indexOf("path"); int finished = record.indexOf("finished"); int completed = record.indexOf("completed"); + int manga = record.indexOf("manga"); int id = record.indexOf("id"); int parentId = record.indexOf("parentId"); @@ -256,6 +260,7 @@ void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent) data << sqlquery.value(path).toString(); data << sqlquery.value(finished).toBool(); data << sqlquery.value(completed).toBool(); + data << sqlquery.value(manga).toBool(); auto item = new FolderItem(data); item->id = sqlquery.value(id).toULongLong(); @@ -278,6 +283,7 @@ void FolderModel::updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent) int path = record.indexOf("path"); int finished = record.indexOf("finished"); int completed = record.indexOf("completed"); + int manga = record.indexOf("manga"); int id = record.indexOf("id"); int parentId = record.indexOf("parentId"); @@ -288,6 +294,7 @@ void FolderModel::updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent) data << sqlquery.value(path).toString(); data << sqlquery.value(finished).toBool(); data << sqlquery.value(completed).toBool(); + data << sqlquery.value(manga).toBool(); auto item = new FolderItem(data); item->id = sqlquery.value(id).toULongLong(); @@ -356,6 +363,36 @@ void FolderModel::updateFolderFinishedStatus(const QModelIndexList &list, bool s emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Completed)); } +void FolderModel::updateFolderManga(const QModelIndexList &list, bool manga) +{ + QString connectionName = ""; + { + QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); + db.transaction(); + foreach (QModelIndex mi, list) { + auto item = static_cast(mi.internalPointer()); + + std::function setManga; + setManga = [&setManga](FolderItem *item, bool manga) -> void { + item->setData(FolderModel::Manga, manga); + + for (auto child : item->children()) { + setManga(child, manga); + } + }; + + setManga(item, manga); + + DBHelper::updateFolderTreeManga(item->id, db, manga); + } + db.commit(); + connectionName = db.connectionName(); + } + QSqlDatabase::removeDatabase(connectionName); + + emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Manga)); +} + QStringList FolderModel::getSubfoldersNames(const QModelIndex &mi) { QStringList result; @@ -461,7 +498,8 @@ QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QMod Folder newFolder; newFolder.name = folderName; newFolder.parentId = parentItem->id; - newFolder.path = parentItem->data(1).toString() + "/" + folderName; + newFolder.path = parentItem->data(Columns::Path).toString() + "/" + folderName; + newFolder.setManga(parentItem->data(Columns::Manga).toBool()); QString connectionName = ""; { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); @@ -478,6 +516,7 @@ QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QMod data << newFolder.path; data << false; //finished data << true; //completed + data << newFolder.isManga(); auto item = new FolderItem(data); item->id = newFolder.id; diff --git a/YACReaderLibrary/db/folder_model.h b/YACReaderLibrary/db/folder_model.h index 9597d07ca..cb49cddad 100644 --- a/YACReaderLibrary/db/folder_model.h +++ b/YACReaderLibrary/db/folder_model.h @@ -67,6 +67,7 @@ class FolderModel : public QAbstractItemModel void updateFolderCompletedStatus(const QModelIndexList &list, bool status); void updateFolderFinishedStatus(const QModelIndexList &list, bool status); + void updateFolderManga(const QModelIndexList &list, bool manga); QStringList getSubfoldersNames(const QModelIndex &mi); @@ -78,13 +79,15 @@ class FolderModel : public QAbstractItemModel Name = 0, Path = 1, Finished = 2, - Completed = 3 + Completed = 3, + Manga = 4 }; //id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, name TEXT NOT NULL, path TEXT NOT NULL enum Roles { FinishedRole = Qt::UserRole + 1, CompletedRole, - IdRole + IdRole, + MangaRole }; public slots: diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index c73233672..833122ee0 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -1518,6 +1518,37 @@ QList diff --git a/YACReader/yacreader_es.ts b/YACReader/yacreader_es.ts index b93544494..da6980a3f 100644 --- a/YACReader/yacreader_es.ts +++ b/YACReader/yacreader_es.ts @@ -4,7 +4,6 @@ ActionsShortcutsModel - None @@ -12,51 +11,41 @@ BookmarksDialog - - Lastest Page - Última página - - - Close Cerrar - + Loading... + Cargando... + + Click on any image to go to the bookmark Pulsa en cualquier imagen para ir al marcador - - - Loading... - Cargando... + Lastest Page + Última página EditShortcutsDialog - Restore defaults - To change a shortcut, double click in the key combination and type the new keys. - Shortcuts settings - Shortcut in use - The shortcut "%1" is already assigned to other function @@ -64,22 +53,18 @@ FileComic - - Unknown error opening the file - Error desconocido abriendo el archivo + Format not supported + Formato no soportado - 7z not found 7z no encontrado - - Format not supported - Formato no soportado + Unknown error opening the file + Error desconocido abriendo el archivo - CRC error on page (%1): some of the pages will not be displayed correctly Error CRC en la página (%1): algunas de las páginas no se mostrarán correctamente @@ -87,36 +72,29 @@ GoToDialog - - Page : - Página : - - - Go To Ir a - - Cancel - Cancelar + Go to... + Ir a... - - Total pages : Páginas totales: - - Go to... - Ir a... + Cancel + Cancelar + + + Page : + Página : GoToFlowToolBar - Page : Página : @@ -124,649 +102,591 @@ HelpAboutDialog - - About - Acerca de - - - Help Ayuda + + About + Acerca de + - MainWindowViewer + LogWindow - - &Open - &Abrir + Log window + - O - O + &Pause + - - Open a comic - Abrir cómic + &Save + - - Open Folder - Abrir carpeta + C&lear + - Ctrl+O - Ctrl+O + &Copy + - - Open image folder - Open images in a folder - Abrir carpeta de imágenes + Level: + - - Clear + &Auto scroll + + + MainWindowViewer + + File + Archivo + + + Help + Ayuda + - Save Guardar - - - Save current page - Guardar la página actual + &File + &Archivo - - Previous Comic - Cómic anterior + &Next + Siguie&nte - - Open previous comic - Abrir cómic anterior + &Open + &Abrir - - Next Comic - Siguiente Cómic + Close + Cerrar - - Open next comic - Abrir siguiente cómic + Open Comic + Abrir cómic - - &Previous - A&nterior + Go To + Ir a - - Go to previous page - Ir a la página anterior + Open image folder + Abrir carpeta de imágenes - - &Next - Siguie&nte + Set bookmark + Añadir marcador - - Go to next page - Ir a la página siguiente + page_%1.jpg + página_%1.jpg - - Fit Width - Ajustar anchura + Switch to double page mode + Cambiar a modo de doble página - - Fit image to height - Ajustar página a lo alto + Save current page + Guardar la página actual + + + Double page mode + Modo a doble página + + + Switch Magnifying glass + Lupa On/Off + + + Open Folder + Abrir carpeta - Fit Height Ajustar altura - - Fit image to width - Ajustar página a lo ancho + Comic files + Archivos de cómic - - Rotate image to the left - Rotar imagen a la izquierda + Not now + Ahora no - L - L + Go to previous page + Ir a la página anterior - - Rotate image to the right - Rotar imagen a la derecha + Open a comic + Abrir cómic - R - R + Image files (*.jpg) + Archivos de imagen (*.jpg) - - Double page mode - Modo a doble página + Next Comic + Siguiente Cómic - - Switch to double page mode - Cambiar a modo de doble página + Fit Width + Ajustar anchura - D - D + Options + Opciones - - Go To - Ir a + Show Info + Mostrar información - G - G + Open folder + Abrir carpeta - Go to page ... Ir a página... - - Options - Opciones + Fit image to width + Ajustar página a lo ancho - C - C + &Previous + A&nterior - - YACReader options - Opciones de YACReader + Go to next page + Ir a la página siguiente - - - Help - Ayuda + Show keyboard shortcuts + Mostrar atajos de teclado - - Help, About YACReader - Ayuda, Sobre YACReader + There is a new version available + Hay una nueva versión disponible - - Magnifying glass - Lupa + Open next comic + Abrir siguiente cómic - - Switch Magnifying glass - Lupa On/Off + Remind me in 14 days + Recordar en 14 días - Z - Z + Show bookmarks + Mostrar marcadores - - Set bookmark - Añadir marcador + Open previous comic + Abrir cómic anterior - - Set a bookmark on the current page - Añadir un marcador en la página actual + Rotate image to the left + Rotar imagen a la izquierda - - Show bookmarks - Mostrar marcadores + Fit image to height + Ajustar página a lo alto - Show the bookmarks of the current comic Mostrar los marcadores del cómic actual - M - M + Show Dictionary + Mostrar diccionario - - Show keyboard shortcuts - Mostrar atajos de teclado + YACReader options + Opciones de YACReader - - Show Info - Mostrar información + Help, About YACReader + Ayuda, Sobre YACReader - I - I + Show go to flow + Mostrar flow ir a - - Close - Cerrar + Previous Comic + Cómic anterior - - Show Dictionary - Mostrar diccionario + Show full size + Mostrar a tamaño original + + + Magnifying glass + Lupa + + + General + General + + + Set a bookmark on the current page + Añadir un marcador en la página actual + + + Do you want to download the new version? + ¿Desea descargar la nueva versión? + + + Rotate image to the right + Rotar imagen a la derecha - Always on top Siempre visible - - Show full size - Mostrar a tamaño original + New instance + - Open latest comic - Open the latest comic opened in the previous reading session - + Clear + + + Clear open recent list - Fit to page - Reset zoom - Show zoom slider - Zoom+ - Zoom- - Double page manga mode - Reverse reading order in double page mode - - Show go to flow - Mostrar flow ir a - - - Edit shortcuts - - &File - &Archivo + Open recent + - - - Open recent + Edit - - File - Archivo - - - - Edit - - - - View - Go - Window - - - Open Comic - Abrir cómic - - - - - Comic files - Archivos de cómic - - - Comics - Toggle fullscreen mode - Hide/show toolbar - - General - General - - - Size up magnifying glass - Size down magnifying glass - Zoom in magnifying glass - Zoom out magnifying glass - Magnifiying glass - Toggle between fit to width and fit to height - Page adjustement - Autoscroll down - Autoscroll up - Autoscroll forward, horizontal first - Autoscroll backward, horizontal first - Autoscroll forward, vertical first - Autoscroll backward, vertical first - Move down - Move up - Move left - Move right - Go to the first page - Go to the last page - Reading + + + OptionsDialog - - Remind me in 14 days - Recordar en 14 días + Gamma + Gamma - - Not now - Ahora no + Reset + Reset - - Open folder - Abrir carpeta + My comics path + Ruta a mis cómics - - Image files (*.jpg) - Archivos de imagen (*.jpg) + Image adjustment + Ajustes de imagen - - page_%1.jpg - página_%1.jpg + "Go to flow" size + Tamaño de "Go to flow" - - There is a new version available - Hay una nueva versión disponible + Choose + Elegir - - Do you want to download the new version? - ¿Desea descargar la nueva versión? + Image options + Opciones de imagen - - - OptionsDialog - - "Go to flow" size - Tamaño de "Go to flow" + Contrast + Contraste - - My comics path - Ruta a mis cómics + Options + Opciones - Page width stretch - Ajuste en anchura de la página + Comics directory + Directorio de cómics - Background color Color de fondo - - Choose - Elegir + Page Flow + Page Flow + + + General + General + + + Brightness + Brillo + + + Restart is needed + Es necesario reiniciar - Quick Navigation Mode - Disable mouse over activation - - Restart is needed - Es necesario reiniciar + Fit options + - - Brightness - Brillo + Enlarge images to fit width/height + - - Contrast - Contraste + Double Page options + - - Gamma - Gamma + Show covers as single page + + + + QObject - - Reset - Reset + 7z lib not found + 7z lib no encontrado - - Image options - Opciones de imagen + unable to load 7z lib from ./utils + imposible cargar 7z lib de ./utils - - General - General + Trace + - - Page Flow - Page Flow + Debug + - - Image adjustment - Ajustes de imagen + Info + - - Options - Opciones + Warning + - - Comics directory - Directorio de cómics + Error + + + + Fatal + - QObject + QsLogging::LogWindowModel - - 7z lib not found - 7z lib no encontrado + Time + - - unable to load 7z lib from ./utils - imposible cargar 7z lib de ./utils + Level + + + + Message + - ShortcutsDialog + QsLogging::Window - - YACReader keyboard shortcuts - Atajos de teclado de YACReader + &Pause + + + + &Resume + + + + Save log + - + Log file (*.log) + + + + + ShortcutsDialog + Close Cerrar - + YACReader keyboard shortcuts + Atajos de teclado de YACReader + + Keyboard Shortcuts Atajos de teclado @@ -774,101 +694,86 @@ Viewer - - - Press 'O' to open comic. - Pulsa 'O' para abrir un fichero. - - - - Not found - No encontrado + Page not available! + ¡Página no disponible! - - Comic not found - Cómic no encontrado + Press 'O' to open comic. + Pulsa 'O' para abrir un fichero. - Error opening comic Error abriendo cómic - + Cover! + ¡Portada! + + CRC Error Error CRC - - Page not available! - ¡Página no disponible! + Comic not found + Cómic no encontrado - - Cover! - ¡Portada! + Not found + No encontrado - Last page! ¡Última página! - Loading...please wait! Cargando...espere, por favor! - YACReaderFieldEdit + YACReader::WhatsNewDialog - - - Click to overwrite - Click para sobreescribir + Close + Cerrar + + + YACReaderFieldEdit - Restore to default Restaurar valor por defecto - - - YACReaderFieldPlainTextEdit - - - - Click to overwrite Click para sobreescribir + + + YACReaderFieldPlainTextEdit - Restore to default Restaurar valor por defecto + + Click to overwrite + Click para sobreescribir + YACReaderFlowConfigWidget - - How to show covers: - Cómo mostrar las portadas: - - - CoverFlow look Tipo CoverFlow - + How to show covers: + Cómo mostrar las portadas: + + Stripe look Tipo tira - Overlapped Stripe look Tipo tira solapada @@ -876,179 +781,145 @@ YACReaderGLFlowConfigWidget - - Presets: - Predefinidos: - - - - Classic look - Tipo clásico - - - - Stripe look - Tipo tira + Zoom + Zoom - - Overlapped Stripe look - Tipo tira solapada + Light + Luz - - Modern look - Tipo moderno + Show advanced settings + Opciones avanzadas - Roulette look Tipo ruleta - - Show advanced settings - Opciones avanzadas - - - - Custom: - Personalizado: + Cover Angle + Ángulo de las portadas - - View angle - Ángulo de vista + Stripe look + Tipo tira - Position Posición - - Cover gap - Hueco entre portadas + Z offset + Desplazamiento en Z + + + Y offset + Desplazamiento en Y - Central gap Hueco central - - Zoom - Zoom + Presets: + Predefinidos: - - Y offset - Desplazamiento en Y + Overlapped Stripe look + Tipo tira solapada - - Z offset - Desplazamiento en Z + Modern look + Tipo moderno - - Cover Angle - Ángulo de las portadas + View angle + Ángulo de vista - - Visibility - Visibilidad + Max angle + Ángulo máximo - - Light - Luz + Custom: + Personalizado: - - Max angle - Ángulo máximo + Classic look + Tipo clásico - - Low Performance - Rendimiento bajo + Cover gap + Hueco entre portadas - High Performance Alto rendimiento - + Performance: + Rendimiento: + + Use VSync (improve the image quality in fullscreen mode, worse performance) Utilizar VSync (mejora la calidad de imagen en pantalla completa, peor rendimiento) - - Performance: - Rendimiento: + Visibility + Visibilidad + + + Low Performance + Rendimiento bajo YACReaderOptionsDialog - Save Guardar - + Use hardware acceleration (restart needed) + Utilizar aceleración por hardware (necesario reiniciar) + + Cancel Cancelar - Edit shortcuts - Shortcuts - - - Use hardware acceleration (restart needed) - Utilizar aceleración por hardware (necesario reiniciar) - YACReaderSlider - Reset - Reset + Reset YACReaderTranslator - - YACReader translator - Traductor YACReader - - - - - Translation - Traducción - - - clear limpiar - Service not available Servicio no disponible + + Translation + Traducción + + + YACReader translator + Traductor YACReader + diff --git a/YACReader/yacreader_fr.ts b/YACReader/yacreader_fr.ts old mode 100755 new mode 100644 index c9e6c16bf..4dd7574d4 --- a/YACReader/yacreader_fr.ts +++ b/YACReader/yacreader_fr.ts @@ -1,122 +1,100 @@ - + ActionsShortcutsModel - None - Rien + Rien BookmarksDialog - - Lastest Page - Aller à la dernière page - - - Close Fermer - + Loading... + Chargement... + + Click on any image to go to the bookmark Cliquez sur une image pour aller au marque-page - - - Loading... - Chargement... + Lastest Page + Aller à la dernière page EditShortcutsDialog - - Restore defaults - Réinitialiser + Shortcut in use + Raccourci en cours d'utilisation - - To change a shortcut, double click in the key combination and type the new keys. - Pour modifier un raccourci, double-cliquez sur la combinaison de touches et tapez les nouvelles clés. + Restore defaults + Réinitialiser - Shortcuts settings - Paramètres de raccourcis + Paramètres de raccourcis - - Shortcut in use - Raccourci en cours d'utilisation + The shortcut "%1" is already assigned to other function + Le raccourci "%1" est déjà affecté à une autre fonction - - The shortcut "%1" is already assigned to other function - Le raccourci "%1" est déjà affecté à une autre fonction + To change a shortcut, double click in the key combination and type the new keys. + Pour modifier un raccourci, double-cliquez sur la combinaison de touches et tapez les nouvelles clés. FileComic - - Unknown error opening the file - Erreur inconnue lors de l'ouverture du fichier + Format not supported + Format non supporté - 7z not found - 7z introuvable + 7z introuvable - - Format not supported - Format non supporté + Unknown error opening the file + Erreur inconnue lors de l'ouverture du fichier - CRC error on page (%1): some of the pages will not be displayed correctly - Erreur CRC sur la page (%1): certaines pages ne s'afficheront pas correctement + Erreur CRC sur la page (%1): certaines pages ne s'afficheront pas correctement GoToDialog - - Page : - Page : - - - Go To Aller à - - Cancel - Annuler + Go to... + Aller à... - - Total pages : Nombre de pages : - - Go to... - Aller à... + Cancel + Annuler + + + Page : + Page : GoToFlowToolBar - Page : Page : @@ -124,648 +102,591 @@ HelpAboutDialog - - About - A propos - - - Help Aide + + About + A propos + - MainWindowViewer + LogWindow - - &Open - &Ouvrir + Log window + - O - O + &Pause + - - Open a comic - Ouvrir une bande dessinée + &Save + - - Open Folder - Ouvrir un dossier + C&lear + - Ctrl+O - Ctrl+O + &Copy + - - Open image folder - Ouvrir un dossier d'images + Level: + - - Open latest comic - Ouvrir la dernière bande dessinée + &Auto scroll + + + + MainWindowViewer - - Open the latest comic opened in the previous reading session - Ouvrir la dernière bande dessinée ouverte lors de la session de lecture précédente + Go + Aller - - Clear open recent list - Vider la liste d'ouverture récente + Edit + Editer - - Save - Sauvegarder + File + Fichier - - - Save current page - Sauvegarder la page actuelle + Help + Aide - - Previous Comic - Bande dessinée précédente + Save + Sauvegarder - - Open previous comic - Ouvrir la bande dessiné précédente + View + Vue - - Next Comic - Bande dessinée suivante + &File + &Fichier - - Open next comic - Ouvrir la bande dessinée suivante + &Next + &Suivant - - &Previous - &Précédent + &Open + &Ouvrir - - Go to previous page - Aller à la page précédente + Close + Fermer - - &Next - &Suivant + Open Comic + Ouvrir la bande dessinée - - Go to next page - Aller à la page suivante + Go To + Aller à - - Fit Width - Ajuster la largeur + Zoom+ + Zoom+ - - Fit image to height - Ajuster l'image à la hauteur + Zoom- + Zoom- - - Fit Height - Ajuster la hauteur + Open image folder + Ouvrir un dossier d'images - - Fit image to width - Ajuster l'image à la largeur + Size down magnifying glass + Réduire la taille de la loupe - - Rotate image to the left - Rotation à gauche + Zoom out magnifying glass + Dézoomer - L - L + Open latest comic + Ouvrir la dernière bande dessinée - - Rotate image to the right - Rotation à droite + Autoscroll up + Défilement automatique vers le haut - R - R + Set bookmark + Placer un marque-page - - Double page mode - Mode double page + page_%1.jpg + page_%1.jpg + + + Autoscroll forward, vertical first + Défilement automatique en avant, vertical - Switch to double page mode Passer en mode double page - D - D + Save current page + Sauvegarder la page actuelle - - Go To - Aller à + Size up magnifying glass + Augmenter la taille de la loupe - G - G + Double page mode + Mode double page - - Go to page ... - Aller à la page ... + Move up + Monter - - Options - Options + Switch Magnifying glass + Utiliser la loupe - C - C + Open Folder + Ouvrir un dossier - - YACReader options - Options de YACReader + Comics + Bandes dessinées - - - Help - Aide + Fit Height + Ajuster la hauteur - - Help, About YACReader - Aide, à propos de YACReader + Autoscroll backward, vertical first + Défilement automatique en arrière, verticak - - Magnifying glass - Loupe + Comic files + Bande dessinée - - Switch Magnifying glass - Utiliser la loupe + Not now + Pas maintenant - Z - Z + Go to the first page + Aller à la première page - - Set bookmark - Placer un marque-page + Go to previous page + Aller à la page précédente - - Set a bookmark on the current page - Placer un marque-page sur la page actuelle + Window + Fenêtre - - Show bookmarks - Voir les marque-pages + Open the latest comic opened in the previous reading session + Ouvrir la dernière bande dessinée ouverte lors de la session de lecture précédente - - Show the bookmarks of the current comic - Voir les marque-pages de cette bande dessinée + Open a comic + Ouvrir une bande dessinée - M - M + Image files (*.jpg) + Image(*.jpg) - - Show keyboard shortcuts - Voir les raccourcis + Next Comic + Bande dessinée suivante - - Show Info - Voir les infos + Fit Width + Ajuster la largeur - I - I + Options + Options - - Close - Fermer + Show Info + Voir les infos - - Show Dictionary - Dictionnaire + Open folder + Ouvirir le dossier - - Always on top - Toujours au dessus + Go to page ... + Aller à la page ... - - Show full size - Plein écran + Magnifiying glass + Loupe - - Clear - + Fit image to width + Ajuster l'image à la largeur - - Fit to page - Ajuster à la page + Toggle fullscreen mode + Basculer en mode plein écran - - Reset zoom - Réinitialiser le zoom + Toggle between fit to width and fit to height + Basculer entre adapter à la largeur et adapter à la hauteur - - Show zoom slider - Afficher le curseur de zoom + Move right + Déplacer à droite - - Zoom+ - Zoom+ + Zoom in magnifying glass + Zoomer - - Zoom- - Zoom- + Open recent + Ouvrir récent - - Double page manga mode - Mode manga en double page + Reading + Lecture - - Reverse reading order in double page mode - Ordre de lecture inversée en mode double page + &Previous + &Précédent - - Show go to flow - Afficher le flux + Autoscroll forward, horizontal first + Défilement automatique en avant, horizontal - - Edit shortcuts - Modifier les raccourcis + Go to next page + Aller à la page suivante - - &File - &Fichier + Show keyboard shortcuts + Voir les raccourcis - - - Open recent - Ouvrir récent + Double page manga mode + Mode manga en double page - - File - Fichier + There is a new version available + Une nouvelle version est disponible - - Edit - Editer + Autoscroll down + Défilement automatique vers le bas - - View - Vue + Open next comic + Ouvrir la bande dessinée suivante - - Go - Aller + Remind me in 14 days + Rappelez-moi dans 14 jours - - Window - Fenêtre + Fit to page + Ajuster à la page - - - Open Comic - Ouvrir la bande dessinée + Show bookmarks + Voir les marque-pages - - - Comic files - Bande dessinée + Open previous comic + Ouvrir la bande dessiné précédente - - Open folder - Ouvirir le dossier + Rotate image to the left + Rotation à gauche - - Image files (*.jpg) - Image(*.jpg) + Fit image to height + Ajuster l'image à la hauteur - - page_%1.jpg - page_%1.jpg + Reset zoom + Réinitialiser le zoom - - Comics - Bandes dessinées + Show the bookmarks of the current comic + Voir les marque-pages de cette bande dessinée - - Toggle fullscreen mode - Basculer en mode plein écran - - - - Hide/show toolbar - Masquer / afficher la barre d'outils - - - - General - Général - - - - Size up magnifying glass - Augmenter la taille de la loupe + Show Dictionary + Dictionnaire - - Size down magnifying glass - Réduire la taille de la loupe + Move down + Descendre - - Zoom in magnifying glass - Zoomer + Move left + Déplacer à gauche - - Zoom out magnifying glass - Dézoomer + Reverse reading order in double page mode + Ordre de lecture inversée en mode double page - - Magnifiying glass - Loupe + YACReader options + Options de YACReader - - Toggle between fit to width and fit to height - Basculer entre adapter à la largeur et adapter à la hauteur + Clear open recent list + Vider la liste d'ouverture récente - - Page adjustement - Ajustement de la page + Help, About YACReader + Aide, à propos de YACReader - - Autoscroll down - Défilement automatique vers le bas + Show go to flow + Afficher le flux - - Autoscroll up - Défilement automatique vers le haut + Previous Comic + Bande dessinée précédente - - Autoscroll forward, horizontal first - Défilement automatique en avant, horizontal + Show full size + Plein écran - - Autoscroll backward, horizontal first - Défilement automatique en arrière horizontal + Hide/show toolbar + Masquer / afficher la barre d'outils - - Autoscroll forward, vertical first - Défilement automatique en avant, vertical + Magnifying glass + Loupe - - Autoscroll backward, vertical first - Défilement automatique en arrière, verticak + Edit shortcuts + Modifier les raccourcis - - Move down - Descendre + General + Général - - Move up - Monter + Set a bookmark on the current page + Placer un marque-page sur la page actuelle - - Move left - Déplacer à gauche + Page adjustement + Ajustement de la page - - Move right - Déplacer à droite + Show zoom slider + Afficher le curseur de zoom - - Go to the first page - Aller à la première page + Go to the last page + Aller à la dernière page - - Go to the last page - Aller à la dernière page + Do you want to download the new version? + Voulez-vous télécharger la nouvelle version? - - Reading - Lecture + Rotate image to the right + Rotation à droite - - There is a new version available - Une nouvelle version est disponible + Always on top + Toujours au dessus - - Do you want to download the new version? - Voulez-vous télécharger la nouvelle version? + Autoscroll backward, horizontal first + Défilement automatique en arrière horizontal - - Remind me in 14 days - Rappelez-moi dans 14 jours + New instance + - - Not now - Pas maintenant + Clear + OptionsDialog - - "Go to flow" size - Taille du flux + Gamma + Gamma + + + Reset + Remise à zéro - My comics path - Chemin de mes bandes dessinées + Chemin de mes bandes dessinées - Page width stretch - Etirer la page + Image adjustment + Ajustement de l'image - - Background color - Couleur d'arrière plan + "Go to flow" size + Taille du flux - Choose Choisir - - Quick Navigation Mode - Mode navigation rapide + Image options + Option de l'image - - Disable mouse over activation - Désactiver la souris sur l'activation + Contrast + Contraste - - Restart is needed - Redémarrage nécessaire + Options + Options - - Brightness - Luminosité + Comics directory + Répertoire des bandes dessinées - - Contrast - Contraste + Quick Navigation Mode + Mode navigation rapide - - Gamma - Gamma + Background color + Couleur d'arrière plan - - Reset - Remise à zéro + Disable mouse over activation + Désactiver la souris sur l'activation - - Image options - Option de l'image + Page Flow + Flux des pages - General Général - - Page Flow - Flux des pages + Brightness + Luminosité - - Image adjustment - Ajustement de l'image + Restart is needed + Redémarrage nécessaire - - Options - Options + Fit options + - - Comics directory - Répertoire des bandes dessinées + Enlarge images to fit width/height + + + + Double Page options + + + + Show covers as single page + QObject - 7z lib not found - lib 7z introuvable + lib 7z introuvable - unable to load 7z lib from ./utils - impossible de charger 7z depuis ./utils + impossible de charger 7z depuis ./utils + + + Trace + + + + Debug + + + + Info + + + + Warning + + + + Error + + + + Fatal + - ShortcutsDialog + QsLogging::LogWindowModel - - YACReader keyboard shortcuts - Raccourcis clavier de YACReader + Time + + + + Level + + + + Message + + + + + QsLogging::Window + + &Pause + + + + &Resume + - + Save log + + + + Log file (*.log) + + + + + ShortcutsDialog + Close Fermer - + YACReader keyboard shortcuts + Raccourcis clavier de YACReader + + Keyboard Shortcuts Raccourcis clavier @@ -773,101 +694,86 @@ Viewer - - - Press 'O' to open comic. - Appuyez sur "O" pour ouvrir une bande dessinée. - - - - Not found - Introuvable + Page not available! + Page non disponible ! - - Comic not found - Bande dessinée introuvable + Press 'O' to open comic. + Appuyez sur "O" pour ouvrir une bande dessinée. - Error opening comic - Erreur d'ouverture de la bande dessinée + Erreur d'ouverture de la bande dessinée - - CRC Error - Erreur CRC + Cover! + Couverture! - - Loading...please wait! - Chargement... Patientez + CRC Error + Erreur CRC - - Page not available! - Page non disponible ! + Comic not found + Bande dessinée introuvable - - Cover! - Couverture! + Not found + Introuvable - Last page! Dernière page! + + Loading...please wait! + Chargement... Patientez + - YACReaderFieldEdit + YACReader::WhatsNewDialog - - - Click to overwrite - Cliquez pour remplacer + Close + Fermer + + + YACReaderFieldEdit - Restore to default Rétablir les paramètres par défaut - - - YACReaderFieldPlainTextEdit - - - - Click to overwrite - Cliquez pour remplacer + Cliquez pour remplacer + + + YACReaderFieldPlainTextEdit - Restore to default Rétablir les paramètres par défaut + + Click to overwrite + Cliquez pour remplacer + YACReaderFlowConfigWidget - - How to show covers: - Comment voir les couvertures: - - - CoverFlow look Vue CoverFlow - + How to show covers: + Comment voir les couvertures: + + Stripe look Vue alignée - Overlapped Stripe look Vue superposée @@ -875,179 +781,145 @@ YACReaderGLFlowConfigWidget - - Presets: - Réglages: - - - - Classic look - Vue classique - - - - Stripe look - Vue alignée + Zoom + Zoom - - Overlapped Stripe look - Vue superposée + Light + Lumière - - Modern look - Vue moderne + Show advanced settings + Voir les paramètres avancés - Roulette look Vue roulette - - Show advanced settings - Voir les paramètres avancés - - - - Custom: - Personnalisation: + Cover Angle + Angle des couvertures - - View angle - Angle de vue + Stripe look + Vue alignée - Position Position - - Cover gap - Espace entre les couvertures + Z offset + Axe Z + + + Y offset + Axe Y - Central gap Espace couverture centrale - - Zoom - Zoom + Presets: + Réglages: - - Y offset - Axe Y + Overlapped Stripe look + Vue superposée - - Z offset - Axe Z + Modern look + Vue moderne - - Cover Angle - Angle des couvertures + View angle + Angle de vue - - Visibility - Visibilité + Max angle + Angle Maximum - - Light - Lumière + Custom: + Personnalisation: - - Max angle - Angle Maximum + Classic look + Vue classique - - Low Performance - Faible performance + Cover gap + Espace entre les couvertures - High Performance Haute performance - + Performance: + Performance: + + Use VSync (improve the image quality in fullscreen mode, worse performance) Utiliser VSync (Améliore la qualité d'image en mode plein écran, ralentit la performance) - - Performance: - Performance: + Visibility + Visibilité + + + Low Performance + Faible performance YACReaderOptionsDialog - Save Sauvegarder - - Cancel - Annuler + Use hardware acceleration (restart needed) + Utiliser accélération hardware (redémarrage nécessaire) - - Edit shortcuts - Modifier les raccourcis + Cancel + Annuler - Shortcuts - Raccourcis + Raccourcis - - Use hardware acceleration (restart needed) - Utiliser accélération hardware (redémarrage nécessaire) + Edit shortcuts + Modifier les raccourcis YACReaderSlider - Reset - Remise à zéro + Remise à zéro YACReaderTranslator - - YACReader translator - Traducteur YACReader + clear + effacer - - - Translation - Traduction + Service not available + Service non disponible - - clear - effacer + Translation + Traduction - - Service not available - Service non disponible + YACReader translator + Traducteur YACReader diff --git a/YACReader/yacreader_it.ts b/YACReader/yacreader_it.ts new file mode 100644 index 000000000..32d73b598 --- /dev/null +++ b/YACReader/yacreader_it.ts @@ -0,0 +1,925 @@ + + + + + ActionsShortcutsModel + + None + Nessuno + + + + BookmarksDialog + + Close + Chiudi + + + Loading... + Caricamento... + + + Click on any image to go to the bookmark + Click su qualsiasi immagine per andare al bookmark + + + Lastest Page + Ultima Pagina + + + + EditShortcutsDialog + + Shortcut in use + Scorciatoia in uso + + + Restore defaults + Resetta al default + + + Shortcuts settings + impostazione scorciatoie + + + The shortcut "%1" is already assigned to other function + La scorciatoia "%1" è già assegnata ad un'altra funzione + + + To change a shortcut, double click in the key combination and type the new keys. + Per cambiare una scorciatoia doppio click sulla combinazione tasti e digita la nuova combinazione. + + + + FileComic + + Format not supported + Formato non supportato + + + 7z not found + 7z non trovato + + + Unknown error opening the file + Errore sconosciuto aprendo il file + + + CRC error on page (%1): some of the pages will not be displayed correctly + Errore CRC alla pagina (%1): alcune pagine non saranno visualizzate correttamente + + + + GoToDialog + + Go To + Vai a + + + Go to... + Vai a... + + + Total pages : + Pagine totali: + + + Cancel + Annulla + + + Page : + Pagina: + + + + GoToFlowToolBar + + Page : + Pagina: + + + + HelpAboutDialog + + Help + Aiuto + + + About + About + + + + LogWindow + + Log window + + + + &Pause + + + + &Save + + + + C&lear + + + + &Copy + + + + Level: + + + + &Auto scroll + + + + + MainWindowViewer + + Go + Vai + + + Edit + Edit + + + File + File + + + Help + Aiuto + + + Save + Salva + + + View + Mostra + + + &File + &File + + + &Next + &Prossimo + + + &Open + &Apri + + + Clear + Cancella + + + Close + Chiudi + + + Open Comic + Apri Fumetto + + + Go To + Vai a + + + Zoom+ + Zoom+ + + + Zoom- + Zoom- + + + Open image folder + Apri la crettal immagini + + + Size down magnifying glass + Riduci lente ingrandimento + + + Zoom out magnifying glass + Riduci in lente di ingrandimento + + + Open latest comic + Apri l'ultimo fumetto + + + Autoscroll up + Autoscorri Sù + + + Set bookmark + Imposta Segnalibro + + + page_%1.jpg + Pagina_%1.jpg + + + Autoscroll forward, vertical first + Autoscorri avanti, priorità Verticale + + + Switch to double page mode + Passa alla modalità doppia pagina + + + Save current page + Salva la pagina corrente + + + Size up magnifying glass + Ingrandisci lente ingrandimento + + + Double page mode + Modalita doppia pagina + + + Move up + Muovi Sù + + + Switch Magnifying glass + Passa a lente ingrandimento + + + Open Folder + Apri una cartella + + + Comics + Fumetto + + + Fit Height + Adatta altezza + + + Autoscroll backward, vertical first + Autoscorri indietro, priorità Verticale + + + Comic files + File Fumetto + + + Not now + Non ora + + + Go to the first page + Vai alla pagina iniziale + + + Go to previous page + Vai alla pagina precedente + + + Window + Finestra + + + Open the latest comic opened in the previous reading session + Apri l'ultimo fumetto aperto nella sessione precedente + + + Open a comic + Apri un Fumetto + + + Image files (*.jpg) + File immagine (*.jpg) + + + Next Comic + Prossimo fumetto + + + Fit Width + Adatta Larghezza + + + Options + Opzioni + + + Show Info + Mostra info + + + Open folder + Apri cartella + + + Go to page ... + Vai a Pagina ... + + + Magnifiying glass + Lente ingrandimento + + + Fit image to width + Adatta immagine in larghezza + + + Toggle fullscreen mode + Attiva/Disattiva schermo intero + + + Toggle between fit to width and fit to height + Passa tra adatta in larghezza ad altezza + + + Move right + Muovi Destra + + + Zoom in magnifying glass + Ingrandisci in lente di ingrandimento + + + Open recent + Apri i recenti + + + Reading + Leggi + + + &Previous + &Precedente + + + Autoscroll forward, horizontal first + Autoscorri avanti, priorità Orizzontale + + + Go to next page + Vai alla prossima Pagina + + + Show keyboard shortcuts + Mostra scorciatoie da tastiera + + + Double page manga mode + Modalità doppia pagina Manga + + + There is a new version available + Nuova versione disponibile + + + Autoscroll down + Autoscorri Giù + + + Open next comic + Apri il prossimo fumetto + + + Remind me in 14 days + Ricordamelo in 14 giorni + + + Fit to page + Adatta alla pagina + + + Show bookmarks + Mostra segnalibro + + + Open previous comic + Apri il fumetto precendente + + + Rotate image to the left + Ruota immagine a sinistra + + + Fit image to height + Adatta immagine all'altezza + + + Reset zoom + Resetta Zoom + + + Show the bookmarks of the current comic + Mostra il segnalibro del fumetto corrente + + + Show Dictionary + Mostra dizionario + + + Move down + Muovi Giù + + + Move left + Muovi Sinistra + + + Reverse reading order in double page mode + Ordine lettura inverso in modo doppia pagina + + + YACReader options + Opzioni YACReader + + + Clear open recent list + Svuota la lista degli aperti + + + Help, About YACReader + Aiuto, crediti YACReader + + + Show go to flow + Mostra vai all'elenco + + + Previous Comic + Fumetto precendente + + + Show full size + Mostra dimesioni reali + + + Hide/show toolbar + Mostra/Nascondi Barra strumenti + + + Magnifying glass + Lente ingrandimento + + + Edit shortcuts + Edita scorciatoie + + + General + Generale + + + Set a bookmark on the current page + Imposta segnalibro a pagina corrente + + + Page adjustement + Correzioni di pagna + + + Show zoom slider + Mostra cursore di zoom + + + Go to the last page + Vai all'ultima pagina + + + Do you want to download the new version? + Vuoi scaricare la nuova versione? + + + Rotate image to the right + Ruota immagine a destra + + + Always on top + Sempre in primo piano + + + Autoscroll backward, horizontal first + Autoscorri indietro, priorità Orizzontale + + + New instance + + + + + OptionsDialog + + Gamma + Gamma + + + Reset + Reset + + + My comics path + Percorso dei miei fumetti + + + Image adjustment + Correzioni immagine + + + "Go to flow" size + Dimensione "Vai all'elenco" + + + Choose + Scegli + + + Image options + Opzione immagine + + + Contrast + Contrasto + + + Options + Opzioni + + + Comics directory + Cartella Fumetti + + + Quick Navigation Mode + Modo navigazione rapida + + + Background color + Colore di sfondo + + + Disable mouse over activation + Disabilita il mouse all'attivazione + + + Page Flow + Flusso pagine + + + General + Generale + + + Brightness + Luminosità + + + Restart is needed + Riavvio Necessario + + + Fit options + + + + Enlarge images to fit width/height + + + + Double Page options + + + + Show covers as single page + + + + + QObject + + 7z lib not found + Libreria 7z non trovata + + + unable to load 7z lib from ./utils + Impossibile caricare 7z da ./utils + + + Trace + + + + Debug + + + + Info + + + + Warning + + + + Error + + + + Fatal + + + + + QsLogging::LogWindowModel + + Time + + + + Level + + + + Message + + + + + QsLogging::Window + + &Pause + + + + &Resume + + + + Save log + + + + Log file (*.log) + + + + + ShortcutsDialog + + Close + Chiudi + + + YACReader keyboard shortcuts + Scorciatoie da tastiera di YACReader + + + Keyboard Shortcuts + Scorciatoia da tastiera + + + + Viewer + + Page not available! + Pagina non disponibile! + + + Press 'O' to open comic. + Premi "O" per aprire il fumettto. + + + Error opening comic + Errore nell'apertura + + + Cover! + Copertina! + + + CRC Error + Errore CRC + + + Comic not found + Fumetto non trovato + + + Not found + Non trovato + + + Last page! + Ultima pagina! + + + Loading...please wait! + In caricamento...Attendi! + + + + YACReader::WhatsNewDialog + + Close + Chiudi + + + + YACReaderFieldEdit + + Restore to default + Resetta al default + + + Click to overwrite + Click per sovrascrivere + + + + YACReaderFieldPlainTextEdit + + Restore to default + Resetta al default + + + Click to overwrite + Click per sovrascrivere + + + + YACReaderFlowConfigWidget + + CoverFlow look + Aspetto flusso Copertine + + + How to show covers: + Come mostrare le copertine: + + + Stripe look + Aspetto a strisce + + + Overlapped Stripe look + Aspetto a strisce sovrapposto + + + + YACReaderGLFlowConfigWidget + + Zoom + Zoom + + + Light + Luce + + + Show advanced settings + Mostra opzioni avanzate + + + Roulette look + Aspetto Roulette + + + Cover Angle + Angolo copertine + + + Stripe look + Aspetto a strisce + + + Position + Posizione + + + Z offset + Compensazione Z + + + Y offset + Compensazione Y + + + Central gap + Distanza centrale + + + Presets: + Preselezioni: + + + Overlapped Stripe look + Aspetto a strisce sovrapposto + + + Modern look + Aspetto moderno + + + View angle + Angolo di vista + + + Max angle + Angolo massimo + + + Custom: + Personalizzazione: + + + Classic look + Aspetto Classico + + + Cover gap + Distanza Copertine + + + High Performance + Prestazioni Alte + + + Performance: + Prestazioni: + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Usa VSync (migliora la qualtà a tutto schermo, peggiora le prestazioni) + + + Visibility + Visibilità + + + Low Performance + Prestazioni Basse + + + + YACReaderOptionsDialog + + Save + Salva + + + Use hardware acceleration (restart needed) + Usa accelerazione Hardware (necessita restart) + + + Cancel + Cancella + + + Shortcuts + Scorciatoia + + + Edit shortcuts + Edita Scorciatoia + + + + YACReaderSlider + + Reset + Resetta + + + + YACReaderTranslator + + clear + Cancella + + + Service not available + Servizio non disponibile + + + Translation + Traduzione + + + YACReader translator + Traduttore YACReader + + + diff --git a/YACReader/yacreader_nl.ts b/YACReader/yacreader_nl.ts index 9c6da0e2d..f19541b06 100644 --- a/YACReader/yacreader_nl.ts +++ b/YACReader/yacreader_nl.ts @@ -1,771 +1,692 @@ - + ActionsShortcutsModel - None - Geen + BookmarksDialog - - Lastest Page - Laatste pagina - - - Close Sluiten - + Loading... + Inladen... + + Click on any image to go to the bookmark - Klik op een afbeelding om naar de bladwijzer te gaan + Klik op een afbeelding om naar de bladwijzer te gaan - - - Loading... - Bezig met laden... + Lastest Page + Laatste Pagina EditShortcutsDialog - Restore defaults - Standaardwaarden herstellen + - To change a shortcut, double click in the key combination and type the new keys. - Sneltoets aanpassen? Dubbelklik op de huidige sneltoets en druk de nieuwe toetsen in. + - Shortcuts settings - Sneltoetsinstellingen + - Shortcut in use - Sneltoets is in gebruik + - The shortcut "%1" is already assigned to other function - De sneltoets '%1' is al toegewezen aan een andere functie + FileComic - - Unknown error opening the file - Onbekende fout tijdens openen van bestand + 7z not found + 7Z Archiefbestand niet gevonden - - 7z not found - 7Z is niet aangetroffen + CRC error on page (%1): some of the pages will not be displayed correctly + - - Format not supported - Dit formaat wordt niet ondersteund + Unknown error opening the file + - - CRC error on page (%1): some of the pages will not be displayed correctly - CRC-fout op pagina (%1): sommige pagina's worden niet goed getoond + Format not supported + GoToDialog - - Page : - Pagina: - - - Go To - Ga naar + Ga Naar - - Cancel - Annuleren + Go to... + Ga naar... - - Total pages : - Totaal aantal pagina's: + Totaal aantal pagina's : - - Go to... - Ga naar... + Cancel + Annuleren + + + Page : + Pagina : GoToFlowToolBar - Page : - Pagina: + Pagina : HelpAboutDialog - + Help + Help + + About Over + + + LogWindow + + Log window + + - - Help - Hulp + &Pause + + + + &Save + + + + C&lear + + + + &Copy + + + + Level: + + + + &Auto scroll + MainWindowViewer - - &Open - &Openen + Help + Help - O - O + Save + Bewaar - - Open a comic - Open een strip + &File + &Bestand - - Open Folder - Map openen + &Next + &Volgende - Ctrl+O - Ctrl+O + &Open + &Open - - Open image folder - Afbeeldingsmap openen + Close + Sluiten - - Open latest comic - Recentste strip openen + Open Comic + Open een Strip - - Open the latest comic opened in the previous reading session - Open de strip van de vorige leessessie + Go To + Ga Naar - - Clear open recent list - 'Onlangs geopend' wissen + Open image folder + Open afbeeldings map - - Save - Opslaan + Set bookmark + Bladwijzer instellen - - - Save current page - Sla de huidige pagina op + page_%1.jpg + pagina_%1.jpg - - Previous Comic - Vorige strip + Switch to double page mode + Naar dubbele bladzijde modus - - Open previous comic - Open de vorige strip + Save current page + Bewaren huidige pagina - - Next Comic - Volgende strip + Double page mode + Dubbele bladzijde modus - - Open next comic - Open de volgende strip + Switch Magnifying glass + Overschakelen naar Vergrootglas - - &Previous - &Vorige + Open Folder + Map Openen + + + Comic files + Strip bestanden - Go to previous page Ga naar de vorige pagina - - &Next - &Volgende + Open a comic + Open een strip - - Go to next page - Ga naar de volgende pagina + Image files (*.jpg) + Afbeelding bestanden (*.jpg) - - Fit Width - Inpassen in breedte + Next Comic + Volgende Strip - - Fit image to height - Inpassen in hoogte + Fit Width + Vensterbreedte aanpassen - - Fit Height - Inpassen in hoogte + Options + Opties - - Fit image to width - Inpassen in breedte + Show Info + Info tonen - - Rotate image to the left - Naar links draaien + Open folder + Open een Map - L - L + Go to page ... + Ga naar bladzijde ... - - Rotate image to the right - Naar rechts draaien + Fit image to width + Afbeelding aanpassen aan breedte - R - R + &Previous + &Vorige - - Double page mode - Dubbelebladzijdemodus + Go to next page + Ga naar de volgende pagina - - Switch to double page mode - Schakel over naar de dubbelebladzijdemodus + Show keyboard shortcuts + Toon de sneltoetsen - D - D + There is a new version available + Er is een nieuwe versie beschikbaar - - Go To - Ga naar + Open next comic + Open volgende strip - G - G + Show bookmarks + Bladwijzers weergeven - - Go to page ... - Ga naar bladzijde... + Open previous comic + Open de vorige strip - - Options - Opties + Rotate image to the left + Links omdraaien - C - C + Fit image to height + Afbeelding aanpassen aan hoogte - - YACReader options - YACReader-opties + Show the bookmarks of the current comic + Toon de bladwijzers van de huidige strip - - - Help - Hulp + Show Dictionary + Woordenlijst weergeven - - Help, About YACReader - Hulp, Over YACReader + YACReader options + YACReader opties - - Magnifying glass - Vergrootglas + Help, About YACReader + Help, Over YACReader - - Switch Magnifying glass - Vergrootglas openen + Show go to flow + Toon ga naar de Omslagbrowser - Z - Z + Previous Comic + Vorige Strip - - Set bookmark - Bladwijzer instellen + Show full size + Volledig Scherm - - Set a bookmark on the current page - Stel een bladwijzer in op de huidige pagina + Magnifying glass + Vergrootglas - - Show bookmarks - Bladwijzers tonen + General + Algemeen - - Show the bookmarks of the current comic - Toon de bladwijzers van de huidige strip + Set a bookmark on the current page + Een bladwijzer toevoegen aan de huidige pagina - M - M + Do you want to download the new version? + Wilt u de nieuwe versie downloaden? - - Show keyboard shortcuts - Sneltoetsen tonen + Rotate image to the right + Rechts omdraaien - - Show Info - Informatie tonen + Always on top + Altijd op voorgrond - I - I + New instance + - - Close - Sluiten + Open latest comic + - - Show Dictionary - Woordenboek tonen + Open the latest comic opened in the previous reading session + - - Always on top - Altijd op voorgrond + Clear + - - Show full size - Oorspronkelijke grootte + Clear open recent list + - - Clear - Wissen + Fit Height + - Fit to page - Pagina inpassen + - Reset zoom - Standaard zoomniveau + - Show zoom slider - Zoomschuifbalk tonen + - Zoom+ - Zoom+ + - Zoom- - Zoom- + - Double page manga mode - Dubbelebladzijdemangamodus + - Reverse reading order in double page mode - Leesvolgorde omdraaien in dubbelebladzijdemodus - - - - Show go to flow - Omslagverkenner tonen + - Edit shortcuts - Sneltoetsen aanpassen + - - &File - &Bestand - - - - Open recent - Onlangs geopend bestand + - File - Bestand + - Edit - Bewerken + - View - Beeld + - Go - Ga + - Window - Venster - - - - - Open Comic - Strip openen - - - - - Comic files - Stripbestanden - - - - Open folder - Map openen + - - Image files (*.jpg) - Afbeeldingsbestanden (*.jpg) - - - - page_%1.jpg - pagina_%1.jpg - - - Comics - Strips + - Toggle fullscreen mode - Beeldvullende modus aan/uit + - Hide/show toolbar - Werkbalk tonen/verbergen - - - - General - Algemeen + - Size up magnifying glass - Bladzijde vergroten + - Size down magnifying glass - Bladzijde verkleinen + - Zoom in magnifying glass - Inzoomen + - Zoom out magnifying glass - Uitzoomen + - Magnifiying glass - Vergrootglas + - Toggle between fit to width and fit to height - Schakelen tussen inpassen in breedte en inpassen in hoogte + - Page adjustement - Pagina inpassen + - Autoscroll down - Automatisch omlaag scrollen + - Autoscroll up - Automatisch omhoog scrollen + - Autoscroll forward, horizontal first - Automatisch vooruit scrollen - eerst horizontaal + - Autoscroll backward, horizontal first - Automatisch achteruit scrollen - eerst horizontaal + - Autoscroll forward, vertical first - Automatisch vooruit scrollen - eerst verticaal + - Autoscroll backward, vertical first - Automatisch achteruit scrollen - eerst verticaal + - Move down - Omlaag + - Move up - Omhoog + - Move left - Naar links + - Move right - Naar rechts + - Go to the first page - Ga naar eerste bladzijde + - Go to the last page - Ga naar laatste bladzijde + - Reading - Lezen + - - There is a new version available - Er is een nieuwe versie beschikbaar - - - - Do you want to download the new version? - Wil je de nieuwe versie downloaden? - - - Remind me in 14 days - Herinner me over 14 dagen + - Not now - Niet nu + OptionsDialog - - "Go to flow" size - Afmetingen van omslagverkenner + Gamma + Gamma + + + Reset + Standaardwaarden terugzetten - My comics path Pad naar mijn strips - Page width stretch - Pagina breedte + Image adjustment + Beeldaanpassing - - Background color - Achtergrondkleur + "Go to flow" size + "Naar Omslagbrowser" afmetingen - Choose - Kiezen + Kies - - Quick Navigation Mode - Snellenavigatiemodus + Image options + Afbeelding opties - - Disable mouse over activation - Activeren met muiszweving uitschakelen + Contrast + Contrast - - Restart is needed - Herstart vereist + Options + Opties - - Brightness - Helderheid + Comics directory + Strips map - - Contrast - Contrast + Background color + Achtergrondkleur - - Gamma - Gamma + Page Flow + Omslagbrowser - - Reset - Standaardwaarden + General + Algemeen - - Image options - Afbeeldingsopties + Brightness + Helderheid - - General - Algemeen + Restart is needed + Herstart is nodig - - Page Flow - Omslagverkenner + Quick Navigation Mode + - - Image adjustment - Afbeeldingen inpassen + Disable mouse over activation + - - Options - Opties + Fit options + - - Comics directory - Stripsmap + Enlarge images to fit width/height + + + + Double Page options + + + + Show covers as single page + QObject - 7z lib not found - 7Z is niet aangetroffen + - unable to load 7z lib from ./utils - kan 7z niet laden uit ./utils + + + + Trace + + + + Debug + + + + Info + + + + Warning + + + + Error + + + + Fatal + - ShortcutsDialog + QsLogging::LogWindowModel - - YACReader keyboard shortcuts - YACReader-sneltoetsen + Time + + + + Level + + + + Message + + + + + QsLogging::Window + + &Pause + + + + &Resume + - + Save log + + + + Log file (*.log) + + + + + ShortcutsDialog + Close Sluiten - + YACReader keyboard shortcuts + YACReader sneltoetsen + + Keyboard Shortcuts Sneltoetsen @@ -773,281 +694,232 @@ Viewer - - Press 'O' to open comic. - Druk op 'O' om een strip te openen. + Druk 'O' om een strip te openen. - - Not found - Niet aangetroffen + Cover! + Omslag! - Comic not found - Strip is niet aangetroffen + Strip niet gevonden - - Error opening comic - Fout tijdens openen + Not found + Niet gevonden - - CRC Error - CRC-fout + Last page! + Laatste pagina! - Loading...please wait! - Bezig met laden... + Inladen...even wachten! - - Page not available! - De bladzijde is niet beschikbaar! + Error opening comic + - - Cover! - Omslag! + CRC Error + - - Last page! - Laatste pagina! + Page not available! + - YACReaderFieldEdit + YACReader::WhatsNewDialog - - - Click to overwrite - Klik hier om te overschrijven + Close + Sluiten + + + YACReaderFieldEdit - Restore to default Standaardwaarden herstellen - - - YACReaderFieldPlainTextEdit - - - - Click to overwrite Klik hier om te overschrijven + + + YACReaderFieldPlainTextEdit - Restore to default Standaardwaarden herstellen + + Click to overwrite + Klik hier om te overschrijven + YACReaderFlowConfigWidget - - How to show covers: - Omslagbladweergave: + CoverFlow look + Omslagbrowser uiterlijk - - CoverFlow look - Vormgeving van omslagverkenner + How to show covers: + Omslagbladen bekijken: - Stripe look - Strepen gebruiken + Brede band - Overlapped Stripe look - Overlappende strepen gebruiken + Overlappende band YACReaderGLFlowConfigWidget - - Presets: - Voorinstellingen: - - - - Classic look - Klassiek - - - - Stripe look - Gestreept + Zoom + Zoom - - Overlapped Stripe look - Overlappend gestreept + Light + Licht - - Modern look - Modern + Show advanced settings + Toon geavanceerde instellingen - Roulette look Roulette - - Show advanced settings - Geavanceerde instellingen tonen - - - - Custom: - Aangepast: + Cover Angle + Omslag hoek - - View angle - Kijkhoek + Stripe look + Brede band - Position Positie - - Cover gap - Ruimte tussen omslagen + Z offset + Z- positie + + + Y offset + Y-positie - Central gap Centrale ruimte - - Zoom - Zoom + Presets: + Voorinstellingen: - - Y offset - Y-positie + Overlapped Stripe look + Overlappende band - - Z offset - Z-positie + Modern look + Modern - - Cover Angle - Omslaghoek + View angle + Kijkhoek - - Visibility - Zichtbaarheid + Max angle + Maximale hoek - - Light - Licht + Custom: + Aangepast: - - Max angle - Maximale hoek + Classic look + Klassiek - - Low Performance - Lage prestaties + Cover gap + Ruimte tss Omslag - High Performance - Hoge prestaties + Hoge Prestaties + + + Performance: + Prestatie: - Use VSync (improve the image quality in fullscreen mode, worse performance) - VSync gebruiken (verbetert de beeldkwaliteit in de beeldvullende modus, maar vermindert de prestaties) + Gebruik VSync (verbetering van de beeldkwaliteit in de modus volledig scherm, slechtere prestatie) - - Performance: - Prestaties: + Visibility + Zichtbaarheid + + + Low Performance + Lage Prestaties YACReaderOptionsDialog - Save - Opslaan + Bewaar + + + Use hardware acceleration (restart needed) + Gebruik hardware versnelling (opnieuw opstarten vereist) - Cancel Annuleren - Edit shortcuts - Sneltoetsen aanpassen + - Shortcuts - Sneltoetsen - - - - Use hardware acceleration (restart needed) - Hardwareversnelling gebruiken (herstart vereist) + YACReaderSlider - Reset - Standaardwaarden + Standaardwaarden terugzetten YACReaderTranslator - YACReader translator - YACReader-vertaler + - - Translation - Vertaling + - clear - wissen + - Service not available - Dienst niet beschikbaar + diff --git a/YACReader/yacreader_pt.ts b/YACReader/yacreader_pt.ts index 56d03d620..de0d5191c 100644 --- a/YACReader/yacreader_pt.ts +++ b/YACReader/yacreader_pt.ts @@ -4,7 +4,6 @@ ActionsShortcutsModel - None @@ -12,51 +11,41 @@ BookmarksDialog - - Lastest Page - Última Página - - - Close Fechar - + Loading... + Carregando... + + Click on any image to go to the bookmark Clique em qualquer imagem para ir para o marcador - - - Loading... - Carregando... + Lastest Page + Última Página EditShortcutsDialog - Restore defaults - To change a shortcut, double click in the key combination and type the new keys. - Shortcuts settings - Shortcut in use - The shortcut "%1" is already assigned to other function @@ -64,59 +53,48 @@ FileComic - - Unknown error opening the file - + 7z not found + 7z não encontrado - - 7z not found - 7z não encontrado + CRC error on page (%1): some of the pages will not be displayed correctly + - - Format not supported + Unknown error opening the file - - CRC error on page (%1): some of the pages will not be displayed correctly + Format not supported GoToDialog - - Page : - Página : - - - Go To Ir Para - - Cancel - Cancelar + Go to... + Ir para... - - Total pages : Total de páginas : - - Go to... - Ir para... + Cancel + Cancelar + + + Page : + Página : GoToFlowToolBar - Page : Página : @@ -124,648 +102,591 @@ HelpAboutDialog - - About - - - - Help Ajuda + + About + + - MainWindowViewer + LogWindow - - &Open - &Abrir + Log window + - O - O + &Pause + - - Open a comic - Abrir um quadrinho + &Save + - - Open Folder - Abrir Pasta + C&lear + - Ctrl+O - Ctrl+O + &Copy + - - Open image folder + Level: - - Clear + &Auto scroll + + + MainWindowViewer + + Help + Ajuda + - Save Salvar - - - Save current page - Salvar página atual + &File + &Arquivo - - Previous Comic - Quadrinho Anterior + &Next + &Próxima - - Open previous comic - Abrir quadrinho anterior + &Open + &Abrir - - Next Comic - Próximo Quadrinho + Close + Fechar - - Open next comic - Abrir próximo quadrinho + Open Comic + Abrir Quadrinho - - &Previous - A&nterior + Go To + Ir Para - - Go to previous page - Ir para a página anterior + Set bookmark + Definir marcador - - &Next - &Próxima + Switch to double page mode + Alternar para o modo dupla página - - Go to next page - Ir para a próxima página + Save current page + Salvar página atual - - Fit Width - Ajustar à Largura + Double page mode + Modo dupla página - - Fit image to height - + Switch Magnifying glass + Alternar Lupa - - Fit Height - + Open Folder + Abrir Pasta - - Fit image to width - + Go to previous page + Ir para a página anterior - - Rotate image to the left - Girar imagem à esquerda + Open a comic + Abrir um quadrinho - L - L + Image files (*.jpg) + Arquivos de imagem (*.jpg) - - Rotate image to the right - Girar imagem à direita + Next Comic + Próximo Quadrinho - R - R + Fit Width + Ajustar à Largura - - Double page mode - Modo dupla página + Options + Opções - - Switch to double page mode - Alternar para o modo dupla página + Show Info + Mostrar Informações - D - D + Open folder + Abrir pasta - - Go To - Ir Para + Go to page ... + Ir para a página... - G - G + &Previous + A&nterior - - Go to page ... - Ir para a página... + Go to next page + Ir para a próxima página - - Options - Opções + Show keyboard shortcuts + Mostrar teclas de atalhos - C - C + There is a new version available + Há uma nova versão disponível - - YACReader options - Opções do YACReader + Open next comic + Abrir próximo quadrinho - - - Help - Ajuda + Show bookmarks + Mostrar marcadores - - Help, About YACReader - Ajuda, Sobre o YACReader + Open previous comic + Abrir quadrinho anterior - - Magnifying glass - Lupa + Rotate image to the left + Girar imagem à esquerda - - Switch Magnifying glass - Alternar Lupa + Show the bookmarks of the current comic + Mostrar os marcadores do quadrinho atual - Z - Z + YACReader options + Opções do YACReader - - Set bookmark - Definir marcador + Help, About YACReader + Ajuda, Sobre o YACReader - - Set a bookmark on the current page - Definir um marcador na página atual + Previous Comic + Quadrinho Anterior - - Show bookmarks - Mostrar marcadores + Magnifying glass + Lupa - - Show the bookmarks of the current comic - Mostrar os marcadores do quadrinho atual + Set a bookmark on the current page + Definir um marcador na página atual - M - M + Do you want to download the new version? + Você deseja baixar a nova versão? - - Show keyboard shortcuts - Mostrar teclas de atalhos + Rotate image to the right + Girar imagem à direita - - Show Info - Mostrar Informações + New instance + - I - I + Open image folder + - - Close - Fechar + Open latest comic + - - Show Dictionary + Open the latest comic opened in the previous reading session - - Always on top + Clear - - Show full size + Clear open recent list - - Open latest comic + Fit Height - - Open the latest comic opened in the previous reading session + Fit image to height - - Clear open recent list + Fit image to width + + + + Show full size - Fit to page - Reset zoom - Show zoom slider - Zoom+ - Zoom- - Double page manga mode - Reverse reading order in double page mode - - Show go to flow + Show Dictionary - - Edit shortcuts + Always on top - - &File - &Arquivo + Show go to flow + + + + Edit shortcuts + - - Open recent - File - Edit - View - Go - Window - - - Open Comic - Abrir Quadrinho + Comic files + - - - Comic files + page_%1.jpg - Comics - Toggle fullscreen mode - Hide/show toolbar - General - Size up magnifying glass - Size down magnifying glass - Zoom in magnifying glass - Zoom out magnifying glass - Magnifiying glass - Toggle between fit to width and fit to height - Page adjustement - Autoscroll down - Autoscroll up - Autoscroll forward, horizontal first - Autoscroll backward, horizontal first - Autoscroll forward, vertical first - Autoscroll backward, vertical first - Move down - Move up - Move left - Move right - Go to the first page - Go to the last page - Reading - Remind me in 14 days - Not now - - - Open folder - Abrir pasta - - - - Image files (*.jpg) - Arquivos de imagem (*.jpg) - - - - page_%1.jpg - - - - - There is a new version available - Há uma nova versão disponível - - - - Do you want to download the new version? - Você deseja baixar a nova versão? - OptionsDialog - + My comics path + Meu caminho de quadrinhos + + "Go to flow" size Tamanho do "Ir para cheia" - - My comics path - Meu caminho de quadrinhos + Options + Opções - Page width stretch - Trecho da largura da página + Comics directory + Diretório de quadrinhos + + + Restart is needed + Reiniciar é necessário - Background color - Choose - Quick Navigation Mode - Disable mouse over activation - - Restart is needed - Reiniciar é necessário - - - Brightness - Contrast - Gamma - Reset - Image options - - General + Fit options - - Page Flow + Enlarge images to fit width/height - - Image adjustment + Double Page options - - Options - Opções + Show covers as single page + - - Comics directory - Diretório de quadrinhos + General + + + + Page Flow + + + + Image adjustment + QObject - 7z lib not found - unable to load 7z lib from ./utils + + Trace + + + + Debug + + + + Info + + + + Warning + + + + Error + + + + Fatal + + - ShortcutsDialog + QsLogging::LogWindowModel - - YACReader keyboard shortcuts - Teclas de atalhos do YACReader + Time + + + + Level + + + + Message + + + + + QsLogging::Window + + &Pause + + + + &Resume + + + + Save log + + + + Log file (*.log) + + + + ShortcutsDialog - Close Fechar - + YACReader keyboard shortcuts + Teclas de atalhos do YACReader + + Keyboard Shortcuts @@ -773,62 +694,56 @@ Viewer - - Press 'O' to open comic. Pressione 'O' para abrir um quadrinho. - + Loading...please wait! + Carregando... por favor, aguarde! + + Not found - Comic not found - Error opening comic - CRC Error - - Loading...please wait! - Carregando... por favor, aguarde! - - - Page not available! - Cover! - Last page! + + YACReader::WhatsNewDialog + + Close + Fechar + + YACReaderFieldEdit - - Click to overwrite - Restore to default @@ -836,15 +751,10 @@ YACReaderFieldPlainTextEdit - - - - Click to overwrite - Restore to default @@ -852,140 +762,113 @@ YACReaderFlowConfigWidget - - How to show covers: - - - - CoverFlow look Olhar capa cheia - Stripe look Olhar lista - Overlapped Stripe look Olhar lista sobreposta - - - YACReaderGLFlowConfigWidget - - - Presets: - - - - Classic look + How to show covers: + + + YACReaderGLFlowConfigWidget - Stripe look Olhar lista - Overlapped Stripe look Olhar lista sobreposta - + Presets: + + + + Classic look + + + Modern look - Roulette look - Show advanced settings - Custom: - View angle - Position - Cover gap - Central gap - Zoom - Y offset - Z offset - Cover Angle - Visibility - Light - Max angle - Low Performance - High Performance - Use VSync (improve the image quality in fullscreen mode, worse performance) - Performance: @@ -993,27 +876,22 @@ YACReaderOptionsDialog - Save Salvar - Cancel Cancelar - Edit shortcuts - Shortcuts - Use hardware acceleration (restart needed) @@ -1021,7 +899,6 @@ YACReaderSlider - Reset @@ -1029,23 +906,18 @@ YACReaderTranslator - YACReader translator - - Translation - clear - Service not available diff --git a/YACReader/yacreader_ru.ts b/YACReader/yacreader_ru.ts index 96fb536fa..87e18703a 100644 --- a/YACReader/yacreader_ru.ts +++ b/YACReader/yacreader_ru.ts @@ -1,10 +1,9 @@ - + ActionsShortcutsModel - None @@ -12,74 +11,60 @@ BookmarksDialog - - Lastest Page - Последняя страница - - - Close Закрыть - + Loading... + Загрузка... + + Click on any image to go to the bookmark Нажмите на любое изображение чтобы перейти к закладке - - - Loading... - Загрузка... + Lastest Page + Последняя страница EditShortcutsDialog - - Restore defaults - Восстановить значения по умолчанию + Shortcut in use + Горячая клавиша уже занята - - To change a shortcut, double click in the key combination and type the new keys. - Чтобы изменить горячую клавишу дважды щелкните по выбранной комбинации клавиш и введите новые сочетания клавиш. + Restore defaults + Восстановить значения по умолчанию - Shortcuts settings Горячие клавиши - - Shortcut in use - Горячая клавиша уже занята - - - The shortcut "%1" is already assigned to other function Сочетание клавиш "%1" уже назначено для другой функции + + To change a shortcut, double click in the key combination and type the new keys. + Чтобы изменить горячую клавишу дважды щелкните по выбранной комбинации клавиш и введите новые сочетания клавиш. + FileComic - - Unknown error opening the file - Неизвестная ошибка при открытии файла + Format not supported + Формат не поддерживается - 7z not found 7z не найден - - Format not supported - Формат не поддерживается + Unknown error opening the file + Неизвестная ошибка при открытии файла - CRC error on page (%1): some of the pages will not be displayed correctly Ошибка контрольной суммы CRC на странице (%1): некоторые страницы будут отображаться неправильно @@ -87,36 +72,29 @@ GoToDialog - - Page : - Страница : - - - Go To Перейти к странице... - - Cancel - Отмена + Go to... + Перейти к странице... - - Total pages : Общее количество страниц : - - Go to... - Перейти к странице... + Cancel + Отмена + + + Page : + Страница : GoToFlowToolBar - Page : Страница : @@ -124,648 +102,591 @@ HelpAboutDialog - - About - О программе - - - Help Справка + + About + О программе + - MainWindowViewer + LogWindow - - &Open - &Открыть + Log window + - O - О + &Pause + - - Open a comic - Открыть комикс + &Save + - - Open Folder - Открыть папку + C&lear + - Ctrl+O - Ctrl+О + &Copy + - - Open image folder - Открыть папку с изображениями + Level: + - - Open latest comic - Открыть последний комикс + &Auto scroll + + + + MainWindowViewer - - Open the latest comic opened in the previous reading session - Открыть комикс открытый в предыдущем сеансе чтения + Go + Перейти - - Clear open recent list - Очистить список недавно открытых файлов + Edit + Редактировать + + + File + Файл + + + Help + Справка - Save Сохранить - - - Save current page - Сохранить текущию страницу + View + Посмотреть - - Previous Comic - Предыдущий комикс + &File + &Отображать панель инструментов - - Open previous comic - Открыть предыдуший комикс + &Next + &Следующий - - Next Comic - Следующий комикс + &Open + &Открыть - - Open next comic - Открыть следующий комикс + Clear + Очистить - - &Previous - &Предыдущий + Close + Закрыть - - Go to previous page - Перейти к предыдущей странице + Open Comic + Открыть комикс - - &Next - &Следующий + Go To + Перейти к странице... - - Go to next page - Перейти к следующей странице + Zoom+ + Увеличить масштаб - - Fit Width - Подогнать по ширине + Zoom- + Уменьшить масштаб - - Fit image to height - Подогнать по высоте + Open image folder + Открыть папку с изображениями - - Fit Height - Подогнать по высоте + Size down magnifying glass + Уменьшение размера окошка увеличительного стекла - - Fit image to width - Подогнать по ширине + Zoom out magnifying glass + Уменьшить - - Rotate image to the left - Повернуть изображение против часовой стрелки + Open latest comic + Открыть последний комикс - L - L + Autoscroll up + Автопрокрутка вверх - - Rotate image to the right - Повернуть изображение по часовой стрелке + Set bookmark + Установить закладку - R - R + page_%1.jpg + страница_%1.jpg - - Double page mode - Двухстраничный режим + Autoscroll forward, vertical first + Автопрокрутка вперед, вертикальная - Switch to double page mode Двухстраничный режим - D - D + Save current page + Сохранить текущию страницу - - Go To - Перейти к странице... + Size up magnifying glass + Увеличение размера окошка увеличительного стекла - G - G + Double page mode + Двухстраничный режим - - Go to page ... - Перейти к странице... + Move up + Переместить вверх - - Options - Настройки + Switch Magnifying glass + Увеличительное стекло - C - С + Open Folder + Открыть папку - - YACReader options - Настройки + Comics + Комикс - - - Help - Справка + Fit Height + Подогнать по высоте - - Help, About YACReader - Справка + Autoscroll backward, vertical first + Автопрокрутка назад, вертикальная - - Magnifying glass - Увеличительное стекло + Comic files + Файлы комикса - - Switch Magnifying glass - Увеличительное стекло + Not now + Не сейчас - Z - Z + Go to the first page + Перейти к первой странице - - Set bookmark - Установить закладку + Go to previous page + Перейти к предыдущей странице - - Set a bookmark on the current page - Установить закладку на текущей странице + Window + Окно - - Show bookmarks - Показать закладки + Open the latest comic opened in the previous reading session + Открыть комикс открытый в предыдущем сеансе чтения - - Show the bookmarks of the current comic - Показать закладки в текущем комиксе + Open a comic + Открыть комикс - M - M + Image files (*.jpg) + Файлы изображений (*.jpg) - - Show keyboard shortcuts - Показать горячие клавиши + Next Comic + Следующий комикс + + + Fit Width + Подогнать по ширине + + + Options + Настройки - Show Info Показать/скрыть номер страницы и текущее время - I - I + Open folder + Открыть папку + + + Go to page ... + Перейти к странице... - - Close - Закрыть + Magnifiying glass + Увеличительное стекло - - Show Dictionary - Переводчик YACreader + Fit image to width + Подогнать по ширине - - Always on top - Всегда сверху + Toggle fullscreen mode + Полноэкранный режим включить/выключить - - Show full size - Показать в полном размере + Toggle between fit to width and fit to height + Переключение режима подгонки страницы по ширине/высоте - - Clear - Очистить + Move right + Переместить вправо - - Fit to page - Подогнать под размер страницы + Zoom in magnifying glass + Увеличить - - Reset zoom - Сбросить масштаб + Open recent + Открыть недавние - - Show zoom slider - Показать ползунок масштабирования + Reading + Чтение - - Zoom+ - Увеличить масштаб + &Previous + &Предыдущий - - Zoom- - Уменьшить масштаб + Autoscroll forward, horizontal first + Автопрокрутка вперед, горизонтальная - - Double page manga mode - Двухстраничный режим манги + Go to next page + Перейти к следующей странице - - Reverse reading order in double page mode + Show keyboard shortcuts + Показать горячие клавиши + + + Double page manga mode Двухстраничный режим манги - - Show go to flow - Показать поток страниц + There is a new version available + Доступна новая версия - - Edit shortcuts - Редактировать горячие клавиши + Autoscroll down + Автопрокрутка вниз - - &File - &Отображать панель инструментов + Open next comic + Открыть следующий комикс - - - Open recent - Открыть недавние + Remind me in 14 days + Напомнить через 14 дней - - File - Файл + Fit to page + Подогнать под размер страницы - - Edit - Редактировать + Show bookmarks + Показать закладки - - View - Посмотреть + Open previous comic + Открыть предыдуший комикс - - Go - Перейти + Rotate image to the left + Повернуть изображение против часовой стрелки - - Window - Окно + Fit image to height + Подогнать по высоте - - - Open Comic - Открыть комикс + Reset zoom + Сбросить масштаб - - - Comic files - Файлы комикса + Show the bookmarks of the current comic + Показать закладки в текущем комиксе - - Open folder - Открыть папку + Show Dictionary + Переводчик YACreader - - Image files (*.jpg) - Файлы изображений (*.jpg) + Move down + Переместить вниз - - page_%1.jpg - страница_%1.jpg + Move left + Переместить влево - - Comics - Комикс + Reverse reading order in double page mode + Двухстраничный режим манги - - Toggle fullscreen mode - Полноэкранный режим включить/выключить + YACReader options + Настройки - - Hide/show toolbar - Показать/скрыть панель инструментов + Clear open recent list + Очистить список недавно открытых файлов - - General - Общие + Help, About YACReader + Справка - - Size up magnifying glass - Увеличение размера окошка увеличительного стекла + Show go to flow + Показать поток страниц - - Size down magnifying glass - Уменьшение размера окошка увеличительного стекла + Previous Comic + Предыдущий комикс - - Zoom in magnifying glass - Увеличить + Show full size + Показать в полном размере - - Zoom out magnifying glass - Уменьшить + Hide/show toolbar + Показать/скрыть панель инструментов - - Magnifiying glass + Magnifying glass Увеличительное стекло - - Toggle between fit to width and fit to height - Переключение режима подгонки страницы по ширине/высоте + Edit shortcuts + Редактировать горячие клавиши + + + General + Общие + + + Set a bookmark on the current page + Установить закладку на текущей странице - Page adjustement Настройка страницы - - Autoscroll down - Автопрокрутка вниз + Show zoom slider + Показать ползунок масштабирования - - Autoscroll up - Автопрокрутка вверх + Go to the last page + Перейти к последней странице - - Autoscroll forward, horizontal first - Автопрокрутка вперед, горизонтальная + Do you want to download the new version? + Хотите загрузить новую версию ? + + + Rotate image to the right + Повернуть изображение по часовой стрелке + + + Always on top + Всегда сверху - Autoscroll backward, horizontal first Автопрокрутка назад, горизонтальная - - Autoscroll forward, vertical first - Автопрокрутка вперед, вертикальная + New instance + + + + OptionsDialog - - Autoscroll backward, vertical first - Автопрокрутка назад, вертикальная + Gamma + Гамма - - Move down - Переместить вниз + Reset + Вернуть к первоначальным значениям - - Move up - Переместить вверх + My comics path + Папка комиксов - - Move left - Переместить влево + Image adjustment + Настройка изображения - - Move right - Переместить вправо + "Go to flow" size + Размер потока страниц - - Go to the first page - Перейти к первой странице + Choose + Выбрать - - Go to the last page - Перейти к последней странице + Image options + Настройки изображения - - Reading - Чтение + Contrast + Контраст - - There is a new version available - Доступна новая версия + Options + Настройки - - Do you want to download the new version? - Хотите загрузить новую версию ? + Comics directory + Папка комиксов - - Remind me in 14 days - Напомнить через 14 дней + Quick Navigation Mode + Ползунок для быстрой навигации по страницам - - Not now - Не сейчас + Background color + Фоновый цвет + + + Disable mouse over activation + Отключить активацию потока при наведении мыши + + + Page Flow + Поток Страниц - - - OptionsDialog - - "Go to flow" size - Размер потока страниц + General + Общие - - My comics path - Папка комиксов + Brightness + Яркость - Page width stretch - Растянуть страницу в ширину + Restart is needed + - - Background color - Фоновый цвет + Fit options + - - Choose - Выбрать + Enlarge images to fit width/height + - - Quick Navigation Mode - Ползунок для быстрой навигации по страницам + Double Page options + - - Disable mouse over activation - Отключить активацию потока при наведении мыши + Show covers as single page + + + + QObject - - Restart is needed - + 7z lib not found + Библиотека распаковщика 7z не найдена - - Brightness - Яркость + unable to load 7z lib from ./utils + не удается загрузить 7z lib из ./ utils - - Contrast - Контраст + Trace + - - Gamma - Гамма + Debug + - - Reset - Вернуть к первоначальным значениям + Info + - - Image options - Настройки изображения + Warning + - - General - Общие + Error + - - Page Flow - Поток Страниц + Fatal + + + + QsLogging::LogWindowModel - - Image adjustment - Настройка изображения + Time + - - Options - Настройки + Level + - - Comics directory - Папка комиксов + Message + - QObject + QsLogging::Window - - 7z lib not found - Библиотека распаковщика 7z не найдена + &Pause + - - unable to load 7z lib from ./utils - не удается загрузить 7z lib из ./ utils + &Resume + + + + Save log + + + + Log file (*.log) + ShortcutsDialog - - YACReader keyboard shortcuts - Клавиатурные комбинации YACReader - - - Close Закрыть - + YACReader keyboard shortcuts + Клавиатурные комбинации YACReader + + Keyboard Shortcuts Клавиатурные комбинации @@ -773,101 +694,86 @@ Viewer - - - Press 'O' to open comic. - Нажмите "O" чтобы открыть комикс. - - - - Not found - Не найдено + Page not available! + Страница недоступна! - - Comic not found - Комикс не найден + Press 'O' to open comic. + Нажмите "O" чтобы открыть комикс. - Error opening comic Ошибка открытия комикса - - CRC Error - Ошибка CRC + Cover! + Начало! - - Loading...please wait! - Загрузка... Пожалуйста подождите! + CRC Error + Ошибка CRC - - Page not available! - Страница недоступна! + Comic not found + Комикс не найден - - Cover! - Начало! + Not found + Не найдено - Last page! Конец! + + Loading...please wait! + Загрузка... Пожалуйста подождите! + - YACReaderFieldEdit + YACReader::WhatsNewDialog - - - Click to overwrite - Изменить + Close + Закрыть + + + YACReaderFieldEdit - Restore to default Восстановить значения по умолчанию - - - YACReaderFieldPlainTextEdit - - - - Click to overwrite Изменить + + + YACReaderFieldPlainTextEdit - Restore to default Вернуть начальные установки + + Click to overwrite + Изменить + YACReaderFlowConfigWidget - - How to show covers: - Как отображать обложки: - - - CoverFlow look Вид рулеткой - + How to show covers: + Как отображать обложки: + + Stripe look Вид полосами - Overlapped Stripe look Вид перекрывающимися полосами @@ -875,153 +781,124 @@ YACReaderGLFlowConfigWidget - - Presets: - Предустановки: - - - - Classic look - Классический вид - - - - Stripe look - Вид полосами + Zoom + Масштабировать - - Overlapped Stripe look - Вид перекрывающимися полосами + Light + Осветить - - Modern look - Современный вид + Show advanced settings + Показать дополнительные настройки - Roulette look Вид рулеткой - - Show advanced settings - Показать дополнительные настройки - - - - Custom: - Пользовательский: + Cover Angle + Охватить угол - - View angle - Угол зрения + Stripe look + Вид полосами - Position Позиция - - Cover gap - Осветить разрыв + Z offset + Смещение по Z + + + Y offset + Смещение по Y - Central gap Сфокусировать разрыв - - Zoom - Масштабировать + Presets: + Предустановки: - - Y offset - Смещение по Y + Overlapped Stripe look + Вид перекрывающимися полосами - - Z offset - Смещение по Z + Modern look + Современный вид - - Cover Angle - Охватить угол + View angle + Угол зрения - - Visibility - Прозрачность + Max angle + Максимальный угол - - Light - Осветить + Custom: + Пользовательский: - - Max angle - Максимальный угол + Classic look + Классический вид - - Low Performance - Минимальная производительность + Cover gap + Осветить разрыв - High Performance Максимальная производительность - + Performance: + Производительность: + + Use VSync (improve the image quality in fullscreen mode, worse performance) Использовать VSync (повысить формат изображения в полноэкранном режиме , хуже производительность) - - Performance: - Производительность: + Visibility + Прозрачность + + + Low Performance + Минимальная производительность YACReaderOptionsDialog - Save Сохранить - - Cancel - Отмена + Use hardware acceleration (restart needed) + Использовать аппаратное ускорение (Требуется перезагрузка) - - Edit shortcuts - Редактировать горячие клавиши + Cancel + Отмена - Shortcuts Горячие клавиши - - Use hardware acceleration (restart needed) - Использовать аппаратное ускорение (Требуется перезагрузка) + Edit shortcuts + Редактировать горячие клавиши YACReaderSlider - Reset Сброс мастштаба @@ -1029,25 +906,20 @@ YACReaderTranslator - - YACReader translator - Переводчик YACReader - - - - - Translation - Перевод - - - clear очистить - Service not available Сервис недоступен + + Translation + Перевод + + + YACReader translator + Переводчик YACReader + diff --git a/YACReader/yacreader_source.ts b/YACReader/yacreader_source.ts index 5c9fa2ed4..dcbd94001 100644 --- a/YACReader/yacreader_source.ts +++ b/YACReader/yacreader_source.ts @@ -4,7 +4,7 @@ ActionsShortcutsModel - + None @@ -17,18 +17,18 @@ - + Close - + Click on any image to go to the bookmark - - + + Loading... @@ -46,17 +46,17 @@ - + Shortcuts settings - + Shortcut in use - + The shortcut "%1" is already assigned to other function @@ -64,22 +64,22 @@ FileComic - + CRC error on page (%1): some of the pages will not be displayed correctly - + Unknown error opening the file - + 7z not found - + Format not supported @@ -87,28 +87,28 @@ GoToDialog - + Page : - + Go To - + Cancel - - + + Total pages : - + Go to... @@ -116,7 +116,7 @@ GoToFlowToolBar - + Page : @@ -134,475 +134,526 @@ + + LogWindow + + + Log window + + + + + &Pause + + + + + &Save + + + + + C&lear + + + + + &Copy + + + + + Level: + + + + + &Auto scroll + + + MainWindowViewer - + &Open - + Open a comic - + Open Folder - + Open image folder - + Save - - + + Save current page - + Previous Comic - + + + Open previous comic - + Next Comic - + + + Open next comic - + &Previous - + + + Go to previous page - + &Next - + + + Go to next page - + Fit Width - + Fit image to height - + Open latest comic - + Open the latest comic opened in the previous reading session - + Clear open recent list - + Fit Height - + Fit image to width - + Rotate image to the left - + Rotate image to the right - + Double page mode - + Switch to double page mode - + Go To - + Go to page ... - + Options - + YACReader options - - + + Help - + Help, About YACReader - + Magnifying glass - + Switch Magnifying glass - + Set bookmark - + Set a bookmark on the current page - + Show bookmarks - + Show the bookmarks of the current comic - + Show keyboard shortcuts - + Show Info - + Close - + Show Dictionary - + Always on top - + Show full size - + + New instance + + + + Clear - + Fit to page - + Reset zoom - + Show zoom slider - + Zoom+ - + Zoom- - + Double page manga mode - + Reverse reading order in double page mode - + Show go to flow - + Edit shortcuts - + &File - - + + Open recent - + File - + Edit - + View - + Go - + Window - - + + Open Comic - - + + Comic files - + Open folder - + Image files (*.jpg) - + page_%1.jpg - + Comics - + Toggle fullscreen mode - + Hide/show toolbar - + General - + Size up magnifying glass - + Size down magnifying glass - + Zoom in magnifying glass - + Zoom out magnifying glass - + Magnifiying glass - + Toggle between fit to width and fit to height - + Page adjustement - + Autoscroll down - + Autoscroll up - + Autoscroll forward, horizontal first - + Autoscroll backward, horizontal first - + Autoscroll forward, vertical first - + Autoscroll backward, vertical first - + Move down - + Move up - + Move left - + Move right - + Go to the first page - + Go to the last page - + Reading - + There is a new version available - + Do you want to download the new version? - + Remind me in 14 days - + Not now @@ -620,77 +671,97 @@ - + Background color - + Choose - + Quick Navigation Mode - + Disable mouse over activation - + Restart is needed - + Brightness - + Contrast - + Gamma - + Reset - + Image options - + + Fit options + + + + + Enlarge images to fit width/height + + + + + Double Page options + + + + + Show covers as single page + + + + General - + Page Flow - + Image adjustment - + Options - + Comics directory @@ -698,15 +769,86 @@ QObject - + 7z lib not found - + unable to load 7z lib from ./utils + + + Trace + + + + + Debug + + + + + Info + + + + + Warning + + + + + Error + + + + + Fatal + + + + + QsLogging::LogWindowModel + + + Time + + + + + Level + + + + + Message + + + + + QsLogging::Window + + + &Pause + + + + + &Resume + + + + + Save log + + + + + Log file (*.log) + + ShortcutsDialog @@ -730,56 +872,64 @@ Viewer - + Press 'O' to open comic. - + Not found - + Comic not found - + Error opening comic - + CRC Error - + Loading...please wait! - + Page not available! - + Cover! - + Last page! + + YACReader::WhatsNewDialog + + + Close + + + YACReaderFieldEdit - + Click to overwrite @@ -793,9 +943,9 @@ YACReaderFieldPlainTextEdit - - - + + + Click to overwrite @@ -831,117 +981,117 @@ YACReaderGLFlowConfigWidget - + Presets: - + Classic look - + Stripe look - + Overlapped Stripe look - + Modern look - + Roulette look - + Show advanced settings - + Custom: - + View angle - + Position - + Cover gap - + Central gap - + Zoom - + Y offset - + Z offset - + Cover Angle - + Visibility - + Light - + Max angle - + Low Performance - + High Performance - + Use VSync (improve the image quality in fullscreen mode, worse performance) - + Performance: @@ -959,17 +1109,17 @@ - + Edit shortcuts - + Shortcuts - + Use hardware acceleration (restart needed) @@ -977,7 +1127,7 @@ YACReaderSlider - + Reset @@ -990,18 +1140,18 @@ - - + + Translation - + clear - + Service not available diff --git a/YACReader/yacreader_tr.ts b/YACReader/yacreader_tr.ts index 9d4d6e752..9cee38f46 100644 --- a/YACReader/yacreader_tr.ts +++ b/YACReader/yacreader_tr.ts @@ -27,17 +27,6 @@ Son Sayfa - - Configuration - - There was a problem saving YACReader configuration. Please, check if you have enough permissions in the YACReader root folder. - Yeni ayarlar kaydedilirken bir problem çıktı. Lütfen YACReader dosyasını açın. - - - Saving config file.... - Config dosyası kaydediliyor... - - EditShortcutsDialog @@ -63,54 +52,10 @@ FileComic - - File not found or not images in file - Dosya bulunamadı yada dosyada resim yok - 7z not found 7z bulunamadı - - Comic not found - Çizgi roman bulunamadı - - - Not found - Bulunamadı - - - File error - Dosya hatası - - - 7z problem - 7z Problemli - - - 7z reading - 7z Okunuyor - - - 7z crashed. - 7z Bozulmuş. - - - problem reading from 7z - 7z Okunurken Problem Oluştu - - - 7z crashed - 7z Bozulması - - - Unknown error 7z - Bilinmeyen 7z hatası - - - 7z wasn't found in your PATH. - 7z Yolu Bulunamadı. - CRC error on page (%1): some of the pages will not be displayed correctly @@ -166,43 +111,38 @@ - MainWindowViewer - - C - C - + LogWindow - D - D - - - G - G + Log window + - I - I + &Pause + - L - L + &Save + - M - M + C&lear + - O - O + &Copy + - R - R + Level: + - Z - Z + &Auto scroll + + + + MainWindowViewer Help Yardım @@ -267,10 +207,6 @@ Open Folder Dosyayı Aç - - Ctrl+O - Ctrl+O - Comic files Çizgi Roman Dosyaları @@ -291,10 +227,6 @@ Next Comic Sırada ki çizgi roman - - Saving error log file.... - Hata dosyasını kaydet... - Fit Width Uygun Genişlik @@ -331,14 +263,14 @@ Show keyboard shortcuts Kılavye kısayollarını göster - - Open next comic - Sıradaki çizgi romanı aç - There is a new version available Yeni versiyon mevcut + + Open next comic + Sıradaki çizgi romanı aç + Show bookmarks Yer imlerini göster @@ -387,6 +319,10 @@ Magnifying glass Büyüteç + + General + Genel + Set a bookmark on the current page Sayfayı yer imi olarak ayarla @@ -395,10 +331,6 @@ Do you want to download the new version? Yeni versiyonu indirmek ister misin ? - - There was a problem saving YACReader error log file. Please, check if you have enough permissions in the YACReader root folder. - Kaydederken bir problem çıktı YACReader hata kayıt dosyası. Lütfen YACReader root dosyasını ziyaret edin. - Rotate image to the right Sayfayı sağa yator @@ -408,23 +340,27 @@ Her zaman üstte - Remind me in 14 days + New instance - Not now + Open latest comic - Fit Height + Open the latest comic opened in the previous reading session - File + Clear - Clear + Clear open recent list + + + + Fit Height @@ -464,127 +400,123 @@ - Comics + File - Toggle fullscreen mode + Edit - Hide/show toolbar + View - General - Genel - - - Size up magnifying glass + Go - Size down magnifying glass + Window - Zoom in magnifying glass + Comics - Zoom out magnifying glass + Toggle fullscreen mode - Magnifiying glass + Hide/show toolbar - Toggle between fit to width and fit to height + Size up magnifying glass - Page adjustement + Size down magnifying glass - Autoscroll down + Zoom in magnifying glass - Autoscroll up + Zoom out magnifying glass - Move down + Magnifiying glass - Move up + Toggle between fit to width and fit to height - Move left + Page adjustement - Move right + Autoscroll down - Go to the first page + Autoscroll up - Go to the last page + Autoscroll forward, horizontal first - Reading + Autoscroll backward, horizontal first - Open latest comic + Autoscroll forward, vertical first - Open the latest comic opened in the previous reading session + Autoscroll backward, vertical first - Clear open recent list + Move down - Edit + Move up - View + Move left - Go + Move right - Window + Go to the first page - Autoscroll forward, horizontal first + Go to the last page - Autoscroll backward, horizontal first + Reading - Autoscroll forward, vertical first + Remind me in 14 days - Autoscroll backward, vertical first + Not now @@ -606,10 +538,6 @@ Image adjustment Resim ayarları - - Page width stretch - Sayfayı uzat - "Go to flow" size Akış görünümüne git @@ -662,6 +590,22 @@ Disable mouse over activation + + Fit options + + + + Enlarge images to fit width/height + + + + Double Page options + + + + Show covers as single page + + QObject @@ -673,6 +617,64 @@ unable to load 7z lib from ./utils + + Trace + + + + Debug + + + + Info + + + + Warning + + + + Error + + + + Fatal + + + + + QsLogging::LogWindowModel + + Time + + + + Level + + + + Message + + + + + QsLogging::Window + + &Pause + + + + &Resume + + + + Save log + + + + Log file (*.log) + + ShortcutsDialog @@ -729,14 +731,10 @@ - YACReaderDeletingProgress - - cancel - vazgeç - + YACReader::WhatsNewDialog - Please wait, deleting in progress... - Lütfen bekle silme işlemi gerçekleştiriliyor... + Close + Kapat @@ -898,26 +896,11 @@ - - YACReaderSideBar - - Search folders and comics - Dosyaları ve çizgi romanları ara - - - LIBRARIES - KÜTÜPHANELER - - - FOLDERS - DOSYALAR - - YACReaderSlider Reset - Yeniden başlat + Yeniden başlat diff --git a/YACReader/yacreader_zh.ts b/YACReader/yacreader_zh.ts new file mode 100644 index 000000000..ccc4774a1 --- /dev/null +++ b/YACReader/yacreader_zh.ts @@ -0,0 +1,925 @@ + + + + + ActionsShortcutsModel + + None + 不存在 + + + + BookmarksDialog + + Close + 关闭 + + + Loading... + 加载中... + + + Click on any image to go to the bookmark + 单击任何图像即可转到书签 + + + Lastest Page + 最后一页 + + + + EditShortcutsDialog + + Shortcut in use + 快捷键使用中 + + + Restore defaults + 恢复默认设置 + + + Shortcuts settings + 快捷键设置 + + + The shortcut "%1" is already assigned to other function + 快捷键“%1”已被其他功能占用 + + + To change a shortcut, double click in the key combination and type the new keys. + 要更改快捷方式,请双击组合键并键入新键。 + + + + FileComic + + Format not supported + 不支持的文件格式 + + + 7z not found + 7z 未找到 + + + Unknown error opening the file + 打开文件出现未知错误 + + + CRC error on page (%1): some of the pages will not be displayed correctly + 页面(%1)上CRC错误:某些页面无法正确显示 + + + + GoToDialog + + Go To + + + + Go to... + 到... + + + Total pages : + 总页码: + + + Cancel + 取消 + + + Page : + 页码: + + + + GoToFlowToolBar + + Page : + 页码: + + + + HelpAboutDialog + + Help + 帮助 + + + About + 关于 + + + + LogWindow + + Log window + + + + &Pause + + + + &Save + + + + C&lear + + + + &Copy + + + + Level: + + + + &Auto scroll + + + + + MainWindowViewer + + Go + 转到 + + + Edit + 编辑 + + + File + 文件 + + + Help + 帮助 + + + Save + 保存 + + + View + 视图 + + + &File + &文件 + + + &Next + &下一个 + + + &Open + &打开 + + + Clear + 清除 + + + Close + 关闭 + + + Open Comic + 打开漫画 + + + Go To + 转到 + + + Zoom+ + 放大 + + + Zoom- + 缩小 + + + Open image folder + 打开图片文件夹 + + + Size down magnifying glass + 放大镜缩小 + + + Zoom out magnifying glass + 缩小放大镜 + + + Open latest comic + 打开最新的漫画 + + + Autoscroll up + 向上自动滚动 + + + Set bookmark + 设置书签 + + + page_%1.jpg + + + + Autoscroll forward, vertical first + 向前自动滚动,垂直优先 + + + Switch to double page mode + 切换到双页模式 + + + Save current page + 保存当前页面 + + + Size up magnifying glass + 放大镜放大 + + + Double page mode + 双页模式 + + + Move up + 向上移动 + + + Switch Magnifying glass + 切换放大镜 + + + Open Folder + 打开文件夹 + + + Comics + 漫画 + + + Fit Height + 适合高度 + + + Autoscroll backward, vertical first + 向后自动滚动,垂直优先 + + + Comic files + 漫画文件 + + + Not now + 现在不要 + + + Go to the first page + 转到第一页 + + + Go to previous page + 转到上一页 + + + Window + 窗口 + + + Open the latest comic opened in the previous reading session + 打开上一个阅读环节中最新的漫画 + + + Open a comic + 打开一本漫画 + + + Image files (*.jpg) + 图片文件(*.jpg) + + + Next Comic + 下一本漫画 + + + Fit Width + 适合宽度 + + + Options + 选项 + + + Show Info + 显示信息 + + + Open folder + 打开文件夹 + + + Go to page ... + 转到页面... + + + Magnifiying glass + 放大镜 + + + Fit image to width + 使图像适合宽度度 + + + Toggle fullscreen mode + 切换全屏模式 + + + Toggle between fit to width and fit to height + 在适合宽度和适合高度之间切换 + + + Move right + 向右移动 + + + Zoom in magnifying glass + 放大放大镜 + + + Open recent + 打开最近 + + + Reading + 阅读 + + + &Previous + &上一个 + + + Autoscroll forward, horizontal first + 向前自动滚动,水平优先 + + + Go to next page + 转到下一页 + + + Show keyboard shortcuts + 显示键盘快捷键 + + + Double page manga mode + 双页漫画模式 + + + There is a new version available + 发现新版本 + + + Autoscroll down + 向下自动滚动 + + + Open next comic + 打开下一本曼胡 + + + Remind me in 14 days + 在14天内提醒我 + + + Fit to page + 适合页面 + + + Show bookmarks + 显示书签 + + + Open previous comic + 打开上一本漫画 + + + Rotate image to the left + 向左旋转图像 + + + Fit image to height + 使图像适合高度 + + + Reset zoom + 重置缩放 + + + Show the bookmarks of the current comic + 显示当前漫画的书签 + + + Show Dictionary + 显示字典 + + + Move down + 向下移动 + + + Move left + 向左移动 + + + Reverse reading order in double page mode + 双页模式下反向阅读 + + + YACReader options + YACReader 选项 + + + Clear open recent list + 清除最近的清单 + + + Help, About YACReader + 帮助,关于YACReader + + + Show go to flow + 显示流动展示 + + + Previous Comic + 上一本漫画 + + + Show full size + 显示完整尺寸 + + + Hide/show toolbar + 隐藏/显示工具栏 + + + Magnifying glass + 放大镜 + + + Edit shortcuts + 编辑快捷键 + + + General + 常规 + + + Set a bookmark on the current page + 在当前页面上设置书签 + + + Page adjustement + 页面调整 + + + Show zoom slider + 显示缩放滑块 + + + Go to the last page + 转到最后一页 + + + Do you want to download the new version? + 你要下载新版本吗? + + + Rotate image to the right + 向右旋转图像 + + + Always on top + 总在最前面 + + + Autoscroll backward, horizontal first + 向后自动滚动,水平优先 + + + New instance + + + + + OptionsDialog + + Gamma + 伽玛 + + + Reset + 重置 + + + My comics path + 我的漫画路径 + + + Image adjustment + 图片调整 + + + "Go to flow" size + “流动展示”尺寸 + + + Choose + 选择 + + + Image options + 图片选项 + + + Contrast + 对比 + + + Options + 选项 + + + Comics directory + 漫画目录 + + + Quick Navigation Mode + 快速导航模式 + + + Background color + 背景颜色 + + + Disable mouse over activation + 禁用鼠标活动 + + + Page Flow + 页面流 + + + General + 常规 + + + Brightness + 亮度 + + + Restart is needed + 需要重启 + + + Fit options + + + + Enlarge images to fit width/height + + + + Double Page options + + + + Show covers as single page + + + + + QObject + + 7z lib not found + 未找到 7z lib + + + unable to load 7z lib from ./utils + 无法从./utils加载7z lib + + + Trace + + + + Debug + + + + Info + + + + Warning + + + + Error + + + + Fatal + + + + + QsLogging::LogWindowModel + + Time + + + + Level + + + + Message + + + + + QsLogging::Window + + &Pause + + + + &Resume + + + + Save log + + + + Log file (*.log) + + + + + ShortcutsDialog + + Close + 关闭 + + + YACReader keyboard shortcuts + YACReader 键盘快捷键 + + + Keyboard Shortcuts + 键盘快捷键 + + + + Viewer + + Page not available! + 页面不可用! + + + Press 'O' to open comic. + 按下 'O' 键打开漫画。 + + + Error opening comic + 打开漫画出错 + + + Cover! + 封面! + + + CRC Error + CRC 出错 + + + Comic not found + 未找到漫画 + + + Not found + 未找到 + + + Last page! + 最后一页! + + + Loading...please wait! + 加载中...请稍后! + + + + YACReader::WhatsNewDialog + + Close + 关闭 + + + + YACReaderFieldEdit + + Restore to default + 恢复默认设置 + + + Click to overwrite + 点击覆盖 + + + + YACReaderFieldPlainTextEdit + + Restore to default + 恢复默认设置 + + + Click to overwrite + 点击覆盖 + + + + YACReaderFlowConfigWidget + + CoverFlow look + 封面流动展示 + + + How to show covers: + 封面显示: + + + Stripe look + 条状 + + + Overlapped Stripe look + 重叠条状 + + + + YACReaderGLFlowConfigWidget + + Zoom + 缩放 + + + Light + 亮度 + + + Show advanced settings + 高级设置 + + + Roulette look + 轮盘 + + + Cover Angle + 封面角度 + + + Stripe look + 条状 + + + Position + 位置 + + + Z offset + Z位移 + + + Y offset + Y位移 + + + Central gap + 展示区间距 + + + Presets: + 预设: + + + Overlapped Stripe look + 重叠条状 + + + Modern look + 现代 + + + View angle + 视角 + + + Max angle + 最大角度 + + + Custom: + 自定义: + + + Classic look + 经典 + + + Cover gap + 封面间距 + + + High Performance + + + + Performance: + 性能: + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + 使用VSync(在全屏模式下提高图像质量,性能更差) + + + Visibility + 透明度 + + + Low Performance + + + + + YACReaderOptionsDialog + + Save + 保存 + + + Use hardware acceleration (restart needed) + 使用硬件加速(需要重启) + + + Cancel + 取消 + + + Shortcuts + 快捷键 + + + Edit shortcuts + 编辑快捷键 + + + + YACReaderSlider + + Reset + 重置 + + + + YACReaderTranslator + + clear + 清除 + + + Service not available + 服务器无响应 + + + Translation + 翻译 + + + YACReader translator + YACReader 翻译工具 + + + diff --git a/YACReaderLibrary/yacreaderlibrary_de.ts b/YACReaderLibrary/yacreaderlibrary_de.ts index 21f6d13ea..725b7a130 100644 --- a/YACReaderLibrary/yacreaderlibrary_de.ts +++ b/YACReaderLibrary/yacreaderlibrary_de.ts @@ -4,7 +4,6 @@ ActionsShortcutsModel - None @@ -12,134 +11,108 @@ AddLabelDialog - + cancel + Abbrechen + + Label name: - Choose a color: - red - orange - yellow - green - cyan - blue - violet - purple - pink - white - light - dark - accept - - - cancel - Abbrechen - AddLibraryDialog - - Comics folder : - Comics Ordner : - - - - Library name : - Library Name : - Bibliothek Name : - - - Add Hinzufügen - + Add an existing library + Eine existierende Bibliothek hinzufügen + + Cancel Cancel - - Add an existing library - Eine existierende Bibliothek hinzufügen + Comics folder : + Comics Ordner : + + + Library name : + Bibliothek Name : ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Paste here your Comic Vine API key - Accept - Cancel @@ -147,65 +120,53 @@ ClassicComicsView - Hide comic flow - Comic "Flow" verstecken + Comic "Flow" verstecken ComicInfoView - Authors - Autoren + Autoren - writer - penciller - inker - colorist - letterer - cover artist - Publisher - color - b/w - Characters @@ -213,191 +174,147 @@ ComicModel - - yes - Ja + no + Nein - - no - Nein + yes + Ja - - Title - Titel + Read + Lesen - - File Name - File Name + Size + Größe - Pages - Seiten + Seiten - - Size - Größe + Title + Titel - - Read - Lesen + Current Page + Aktuelle Seite - - Current Page - Aktuelle Seite + File Name + File Name - Rating - Bewertung + Bewertung ComicVineDialog - - skip - überspringen - - - back zurück - next nächste - - search - suche + skip + überspringen - close schliessen - - - - - + Retrieving tags for : %1 + Runterladen von Tags für : %1 + + + Looking for comic... + Suche nach Comic... + + + search + suche + + Looking for volume... Suche nach Band.... - - comic %1 of %2 - %3 Comic %1 von %2 - %3 - %1 comics selected %1 Comic ausgewählt - Error connecting to ComicVine Fehler bei Verbindung zu ComicVine - unknown error - unbekannter Fehler - - - - - Retrieving tags for : %1 - Runterladen von Tags für : %1 - - - Retrieving volume info... Runterladen von Ausgabe Info... - - - Looking for comic... - Suche nach Comic... - CreateLibraryDialog - - Comics folder : - Comics Ordner : + Create new library + Kreiere eine neue Bibliothek - - Library Name : - Bibliothek Name : + Cancel + Abbrechen - Create Neu erzeugen - - Cancel - Abbrechen - - - Create a library could take several minutes. You can stop the process and update the library later for completing the task. Eine neue Bibliothek erzeugen kann einige Minuten dauern. Sie können den Prozess abbrechen und die Bibliothek später updaten um den Prozess zu vervollständigen. - - Create new library - Kreiere eine neue Bibliothek + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben - - Path not found - Pfad nicht gefunden + Comics folder : + Comics Ordner : - - The selected path does not exist or is not a valid path. Be sure that you have write access to this folder - Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben + Library Name : + Bibliothek Name : + + + Path not found + Pfad nicht gefunden EditShortcutsDialog - Restore defaults - To change a shortcut, double click in the key combination and type the new keys. - Shortcuts settings - Shortcut in use - The shortcut "%1" is already assigned to other function @@ -405,18 +322,14 @@ EmptyFolderWidget - - Subfolders in this folder - Empty folder - Drag and drop folders and comics here @@ -424,7 +337,6 @@ EmptyLabelWidget - This label doesn't contain comics yet @@ -432,84 +344,68 @@ EmptyReadingListWidget - This reading list does not contain any comics yet - This reading list doesn't contain comics yet ExportComicsInfoDialog - Output file : Ziel File : - - Create - Neu erzeugen + Destination database name + Ziel Datenbasis Name - Cancel Abbrechen - - Export comics info - Export Comic Info + Create + Neu erzeugen - - Destination database name - Ziel Datenbasis Name + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben - - Problem found while writing - Problem gefunden beim Schreiben + Export comics info + Export Comic Info - - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben + Problem found while writing + Problem gefunden beim Schreiben ExportLibraryDialog - - Output folder : - Ziel Ordner : + Cancel + Abbrechen - Create Erzeuge - - Cancel - Abbrechen + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben - - Create covers package - Erzeuge Titelbild Paket + Output folder : + Ziel Ordner : - Problem found while writing Problem gefunden beim Schreiben - - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben + Create covers package + Erzeuge Titelbild Paket - Destination directory Ziel Verzeichnis @@ -517,30 +413,25 @@ FileComic - - CRC error on page (%1): some of the pages will not be displayed correctly - CRC Fehler auf Seite (%1): einige Seiten werden nicht korrekt dargestellt werden - - - - Unknown error opening the file - Unbekannter Fehler beim Öffnen des Files + Format not supported + Format wird nicht unterstützt - 7z not found 7z nicht gefunden - - Format not supported - Format wird nicht unterstützt + Unknown error opening the file + Unbekannter Fehler beim Öffnen des Files + + + CRC error on page (%1): some of the pages will not be displayed correctly + CRC Fehler auf Seite (%1): einige Seiten werden nicht korrekt dargestellt werden GridComicsView - Show info @@ -548,40 +439,33 @@ HelpAboutDialog - - About - Über - - - Help Hilfe + + About + Über + ImportComicsInfoDialog - - Import comics info - Importiere Comic Info - - - - Info database location : - Info Datenbasis Speicherort : + Cancel + Abbrechen - Import Importiere - - Cancel - Abbrechen + Info database location : + Info Datenbasis Speicherort : + + + Import comics info + Importiere Comic Info - Comics info file (*.ydb) Comics Info File (*.ydb) @@ -589,80 +473,65 @@ ImportLibraryDialog - - Library Name : - Bibliothek Name : - - - - Package location : - Paket Ort : - - - Destination folder : Zielordner : - - Unpack - Entpacken - - - Cancel Abbrechen - - Extract a catalog - Einen Katalog Extrahieren + Unpack + Entpacken - Compresed library covers (*.clc) Komprimierte Bibliotheks Bilder (*.clc) + + Package location : + Paket Ort : + + + Library Name : + Bibliothek Name : + + + Extract a catalog + Einen Katalog Extrahieren + ImportWidget - stop Stop - - Some of the comics being added... - Einige der Comics werden hinzugefügt... - - - Importing comics Comics werden importiert - <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <p>YACReaderLibrary kreiert nun eine neue Bibliothek. </p><p>Eine neue Bibliothek erzeugen kann einige Minuten dauern. Sie können den Prozess stoppen und die Bibliothek später aktualisieren um den Prozess zu vervollständigen.</p> - + Some of the comics being added... + Einige der Comics werden hinzugefügt... + + Updating the library Aktualisierung der Bibliothek - <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <p>Die gerade benutzte Bibliothek wird aktualisiert. Für eine schnellere Aktualisierung aktualisieren Sie bitte die Bibliothek regelmäßig.</p><p>Sie können den Prozess abbrechen und mit der Aktualisierung später fortfahren.<p> - Upgrading the library - <p>The current library is being upgraded, please wait.</p> @@ -670,674 +539,539 @@ LibraryWindow - - YACReader Library - YACReader Bibliothek + Edit + Editieren - - Library - Bibliothek + The selected folder doesn't contain any library. + Der ausgewählte Ordner enthält keine Bibliothek. - <font color='white'> press 'F' to close fullscreen mode </font> - <font color='white'> drücke 'F' um Vollbildmodus zu schließen </font> + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Diese Bibliothek wurde mit einer vorherigen Version von YACReader erzeugt. Sie muss geupdated werden. Jetzt updaten? - - Create a new library - Neue Bibliothek erzeugen + Comic + Comic - - Open an existing library - Eine existierende Bibliothek öffnen + Error opening the library + Fehler beim Öffnen der Bibliothek - - - Export comics info - Export Comics Info + Show/Hide marks + Zeige/Verstecke Markierungen - - - Import comics info - Import Comics Info + YACReader not found + YACReader nicht gefunden - - Pack covers - Titelbild Paket erzeugen + Show comics server options dialog + Zeige den Comics Optionen Dialog - - Pack the covers of the selected library - Packe die Titelbilder der ausgewählten Bibliothek in ein Paket + Remove current library from your collection + Aktuelle Bibliothek aus der Sammlung entfernen - - Unpack covers - Titelbilder entpacken + Set comic as read + Comic als gelesen markieren - - Unpack a catalog - Katalog entpacken - + Remove and delete metadata + Entferne und lösche Metadaten + - - Update library - Bibliothek updaten + Old library + Alte Bibliothek - - Update current library - Aktuelle Bibliothek updaten + Update cover + Titelbild updaten - - Rename library - Bibliothek umbenennen + Set as completed + Als gelesen markieren - - Rename current library - Aktuelle Bibliothek umbenennen + Library + Bibliothek - - Remove library - Bibliothek entfernen + Rename current library + Aktuelle Bibliothek umbenennen - - Remove current library from your collection - Aktuelle Bibliothek aus der Sammlung entfernen + Fullscreen mode on/off + Vollbildmodus an/aus - - Open current comic - Aktuellen Comic öffnen + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Die Bibliothek wurde mit einer neueren Version von YACReader erzeugt. Die neue Version jetzt herunterladen? - Open current comic on YACReader Aktuellen Comic mit YACReader öffnen - - Save selected covers to... - + Update current library + Aktuelle Bibliothek updaten - - Save covers of the selected comics as JPG files - + Library '%1' is no longer available. Do you want to remove it? + Bibliothek '%1' ist nicht länger verfügbar. Wollen Sie sie entfernen? - - - Set as read - Als gelesen markieren + Update library + Bibliothek updaten - - Set comic as read - Comic als gelesen markieren + Open folder... + Öffne Ordner... - - - Set as unread - Als ungelesen markieren + Do you want remove + Möchten Sie entfernen - - Set comic as unread - Comic als ungelesen markieren + Set as uncompleted + Als nicht gelesen markieren - - Show/Hide marks - Zeige/Verstecke Markierungen + Reset comic rating + Comic Bewertung zurücksetzen - Show or hide readed marks - Zeige oder verstecke gelesene Markierungen + Error updating the library + Fehler beim Updaten der Bibliothek - - Library not available - Library ' - Bibliothek nicht verfügbar + Folder + Ordner - - - Fullscreen mode on/off - Vollbildmodus an/aus + Expand all nodes + Unterordner anzeigen - Fullscreen mode on/off (F) - Vollbildmodus an/aus (F) + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Bibliothek '%1' ist mit einer älteren Version von YACREader erzeugt worden. Sie muss neu erzeugt werden. Wollen Sie die Bibliothek jetzt erzeugen? - - Help, About YACReader - Hilfe, Über YACReader + Pack covers + Titelbild Paket erzeugen - - Select root node - Root Knoten auswählen + Set as read + Als gelesen markieren - + - + + Delete selected comics + Ausgewählte Comics löschen - - Expand all nodes - Unterordner anzeigen + Export comics info + Export Comics Info - - - - - + Show options dialog + Zeige den Optionen Dialog - Colapse all nodes - Unterordner verstecken + Create a new library + Neue Bibliothek erzeugen - - Show options dialog - Zeige den Optionen Dialog + Library not available + Bibliothek nicht verfügbar - - Show comics server options dialog - Zeige den Comics Optionen Dialog + Import comics info + Import Comics Info - - Open folder... - Öffne Ordner... + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Es gab ein Problem beim löschen der ausgewählten Comics. Überprüfen Sie bitte die Schreibberechtigung für die ausgewählten Files oder Ordner. - - Set as uncompleted - Als nicht gelesen markieren + Open current comic + Aktuellen Comic öffnen - - Set as completed - Als gelesen markieren + YACReader Library + YACReader Bibliothek - - Open containing folder... - Öffne aktuellen Ordner... + Error creating the library + Fehler beim Erzeugen der Bibliothek - - Reset comic rating - Comic Bewertung zurücksetzen + Unpack covers + Titelbilder entpacken - - Select all comics - Alle Comics auswählen + Update needed + Update benötigt - - Edit - Editieren + Open an existing library + Eine existierende Bibliothek öffnen - Asign current order to comics - Bestimme die Abfolge der Comics + Library name already exists + Bibliothek Name existiert bereits - - Update cover - Titelbild updaten + There is another library with the name '%1'. + Es gibt eine andere Bibliothek mit dem Namen '%1'. - - Delete selected comics - Ausgewählte Comics löschen + Download new version + Neue Version herunterladen - Hide comic flow - Comic "Flow" verstecken + Delete comics + Comics löschen - - Download tags from Comic Vine - Tags von Comic Vine herunterladen + Select all comics + Alle Comics auswählen - - Edit shortcuts - + Pack the covers of the selected library + Packe die Titelbilder der ausgewählten Bibliothek in ein Paket - - Update folder - + Help, About YACReader + Hilfe, Über YACReader - - Update current folder - + Set comic as unread + Comic als ungelesen markieren - - Add new reading list - + Select root node + Root Knoten auswählen - - Add a new reading list to the current library - + Unpack a catalog + Katalog entpacken - - Remove reading list - + All the selected comics will be deleted from your disk. Are you sure? + Alle ausgewählten Comics werden von Ihrer Festplatte gelöscht. Sind Sie sicher? - - Remove current reading list from the library - + Download tags from Comic Vine + Tags von Comic Vine herunterladen - - Add new label - + Set as unread + Als ungelesen markieren - - Add a new label to this library - + Library not found + Bibliothek nicht gefunden - - Rename selected list - + Rename library + Bibliothek umbenennen - - Rename any selected labels or lists - + Remove library + Bibliothek entfernen - - Add to... - + Open containing folder... + Öffne aktuellen Ordner... - - Favorites - + Unable to delete + Löschen nicht möglich - - Add selected comics to favorites list - + library? + die Bibliothek? - - Folder - Ordner + Are you sure? + Sind Sie sicher? - - Comic - Comic + Save selected covers to... + - - Upgrade failed + Save covers of the selected comics as JPG files - - There were errors during library upgrade in: + Set as manga - - Update needed - Update benötigt + Set issue as manga + - - This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - Diese Bibliothek wurde mit einer vorherigen Version von YACReader erzeugt. Sie muss geupdated werden. Jetzt updaten? + Set as normal + - Update failed - Update fehlgeschlagen + Set issue as normal + - The current library can't be udpated. Check for write write permissions on: - Die aktuelle Bibliothek kann nicht geupdated werden. Überprüfen Sie die Schreibrechte auf: + Show or hide read marks + - - Download new version - Neue Version herunterladen + Add new folder + - - This library was created with a newer version of YACReaderLibrary. Download the new version now? - Die Bibliothek wurde mit einer neueren Version von YACReader erzeugt. Die neue Version jetzt herunterladen? + Add new folder to the current library + - - Library '%1' is no longer available. Do you want to remove it? - Bibliothek '%1' ist nicht länger verfügbar. Wollen Sie sie entfernen? + Delete folder + - - Old library - Alte Bibliothek + Delete current folder from disk + - - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Bibliothek '%1' ist mit einer älteren Version von YACREader erzeugt worden. Sie muss neu erzeugt werden. Wollen Sie die Bibliothek jetzt erzeugen? + Collapse all nodes + - - - Copying comics... + Change between comics views - - - Moving comics... + Set as comic - - Folder name: + Assign current order to comics - - No folder selected + Edit shortcuts - - Please, select a folder first + Update folder - - Error in path + Update current folder - - There was an error accessing the folder's path + Add new reading list - - The selected folder and all its contents will be deleted from your disk. Are you sure? + Add a new reading list to the current library - - There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Remove reading list - - Add new reading lists + Remove current reading list from the library - - - List name: + Add new label - - Delete list/label + Add a new label to this library - - The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + Rename selected list - - Rename list name + Rename any selected labels or lists - - Save covers + Add to... - - You are adding too many libraries. + Favorites - - You are adding too many libraries. - -You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. - -YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Add selected comics to favorites list - - - YACReader not found - YACReader nicht gefunden + Upgrade failed + - YACReader not found, YACReader should be installed in the same folder as YACReaderLibrary. - YACReader nicht gefunden. YACReader sollte in demselben Ordner installiert werden wie YACReaderLibrary. + There were errors during library upgrade in: + - - Library not found - Bibliothek nicht gefunden + Copying comics... + - - The selected folder doesn't contain any library. - Der ausgewählte Ordner enthält keine Bibliothek. + Moving comics... + - - Are you sure? - Sind Sie sicher? + Folder name: + - - Do you want remove - Möchten Sie entfernen + No folder selected + - - library? - die Bibliothek? + Please, select a folder first + - - Remove and delete metadata - Entferne und lösche Metadaten + Error in path + - - Assign comics numbers + There was an error accessing the folder's path - - Assign numbers starting in: + The selected folder and all its contents will be deleted from your disk. Are you sure? - - - Unable to delete - Löschen nicht möglich + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + - - Show or hide read marks + Add new reading lists - - - Add new folder + List name: - - Add new folder to the current library + Delete list/label - - - Delete folder + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - - Delete current folder from disk + Rename list name - - Collapse all nodes + Save covers - - - Change between comics views + You are adding too many libraries. - - Assign current order to comics + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - YACReader not found. There might be a problem with your YACReader installation. - - There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - Es gab ein Problem beim löschen der ausgewählten Comics. Überprüfen Sie bitte die Schreibberechtigung für die ausgewählten Files oder Ordner. + Assign comics numbers + - Asign comics numbers - Comic Nummer setzen + Assign numbers starting in: + - Asign numbers starting in: - Nummern setzen angefangen mit: + Remove comics + - - Error creating the library - Fehler beim Erzeugen der Bibliothek + Comics will only be deleted from the current label/list. Are you sure? + + + + LocalComicListModel - - Error updating the library - Fehler beim Updaten der Bibliothek + file name + File Name + + + LogWindow - - Error opening the library - Fehler beim Öffnen der Bibliothek + Log window + - - Delete comics - Comics löschen + &Pause + - - All the selected comics will be deleted from your disk. Are you sure? - Alle ausgewählten Comics werden von Ihrer Festplatte gelöscht. Sind Sie sicher? + &Save + - - Remove comics + C&lear - - Comics will only be deleted from the current label/list. Are you sure? + &Copy - - Library name already exists - Bibliothek Name existiert bereits + Level: + - - There is another library with the name '%1'. - Es gibt eine andere Bibliothek mit dem Namen '%1'. + &Auto scroll + - LocalComicListModel + NoLibrariesWidget - - file name - File Name + create your first library + Erzeugen Sie Ihre erste Bibliothek - - - NoLibrariesWidget - You don't have any libraries yet Sie haben im Augenblick keine Bibliothek - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Sie können eine Bibliothek in einem bliebigen Ordner erzeugen, YACReaderLibrary wird alle Comics und Unterordner von diesem Ordner importieren. Wenn Sie in der Vergangenheit eine Bibliothek erzeugt haben, können Sie sie öffnen.</p><p>Vergessen Sie nicht, Sie können YACReader als unabhängige Anwendung benutzen, um Comics auf Ihrem Computer zu lesen.</p> - - create your first library - Erzeugen Sie Ihre erste Bibliothek - - - add an existing one Fügen Sie eine existierende hinzu @@ -1345,306 +1079,327 @@ YACReaderLibrary will not stop you from creating more libraries but you should k OptionsDialog - + Options + Optionen + + + Tray icon settings (experimental) + + + + Close to tray + + + + Start into the system tray + + + Edit Comic Vine API key - Comic Vine API key - Enable background image - Opacity level - Blur level - Use selected comic cover as background - Restore defautls - Background - + Display continue reading banner + + + + Continue reading + + + Comic Flow - Grid view - General - - - Options - Optionen - PropertiesDialog - - General info - Generelle Info + Day: + Tag: - - Authors - Autoren + Plot + Inhalt + + + Size: + Größe: + + + Year: + + + + Inker(s): + Tinte: - Publishing Publishing - - Plot - Inhalt + Publisher: + Verlag: - - Cover page - Titelbild + General info + Generelle Info - - Title: - Titel: + Color/BW: + Farbe/BW: - - - of: - + Edit selected comics information + Ausgewählte Comic Informationen editieren + + + Penciller(s): + Zeichner: + + + Colorist(s): + Farbe: + + + Genre: + Genre: - Issue number: Ausgabe Nummer: - - Volume: - Band: + Month: + Monat: - - Arc number: - + Notes: + Notizen: - - Story arc: - Handlung: + Synopsis: + Übersicht: - - Genre: - Genere: - Genre: + Title: + Titel: - - Size: - Größe: + Not found + Nicht gefunden - - Writer(s): - Author(en): + Characters: + Charaktere: - - Penciller(s): - Zeichner: + Authors + Autoren - - Inker(s): - Tinte: + Age rating: + Alterhinweis: - - Colorist(s): - Farbe: + Story arc: + Handlung: - - Letterer(s): - Schrift: + Writer(s): + Author(en): - - Cover Artist(s): - Titelbild Künstler: + Comic not found. You should update your library. + Comic nicht gefunden. Sie sollten Ihre Bibliothek updaten. - - Day: - Tag: + Edit comic information + Comic Informationen editieren - - Month: - Monat: + Cover page + Titelbild - - Year: + Cover Artist(s): + Titelbild Künstler: + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - - Publisher: - Verlag: + Volume: + Band: - Format: Format: - - Color/BW: - Farbe/BW: + Letterer(s): + Schrift: - - Age rating: - Alterhinweis: + of: + - - Synopsis: - Übersicht: + Arc number: + - - Characters: - Charaktere: + Manga: + + + + QObject - - Notes: - Notizen: + 7z lib not found + 7z Bibliothek nicht gefunden - - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - + unable to load 7z lib from ./utils + 7z Bibliothek kann von ./utils nicht geladen werden - - Not found - Nicht gefunden + Trace + - - Comic not found. You should update your library. - Comic nicht gefunden. Sie sollten Ihre Bibliothek updaten. + Debug + - - Edit selected comics information - Ausgewählte Comic Informationen editieren + Info + - - Edit comic information - Comic Informationen editieren + Warning + + + + Error + + + + Fatal + - QObject + QsLogging::LogWindowModel - - 7z lib not found - 7z Bibliothek nicht gefunden + Time + - - unable to load 7z lib from ./utils - 7z Bibliothek kann von ./utils nicht geladen werden + Level + + + + Message + - RenameLibraryDialog + QsLogging::Window - - New Library Name : - Neuer Bibliotheks Name : + &Pause + - - Rename - Namen ändern + &Resume + - - Cancel - Abbrechen + Save log + - + Log file (*.log) + + + + + RenameLibraryDialog + Rename current library Namen der Bibliothek ändern + + Cancel + Abbrechen + + + Rename + Namen ändern + + + New Library Name : + Neuer Bibliotheks Name : + ScraperResultsPaginator - - Number of volumes found : %1 - Anzahl der gefundenen Bände: %1 + Number of %1 found : %2 + Anzahl von %1 gefunden : %2 - - page %1 of %2 Seite %1 von %2 - - Number of %1 found : %2 - Anzahl von %1 gefunden : %2 + Number of volumes found : %1 + Anzahl der gefundenen Bände: %1 SearchSingleComic - Please provide some additional information. - Please provide some aditional information. - Bitte einige zusätzliche Informationen. + Bitte einige zusätzliche Informationen. - Series: Serie: @@ -1652,14 +1407,10 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SearchVolume - Please provide some additional information. - Please provide some aditional information. - Serie: - Bitte einige zusätzliche Informationen. + Bitte einige zusätzliche Informationen. - Series: Serie: @@ -1667,27 +1418,22 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SelectComic - - Please, select the right comic info. - Bitte wählen Sie die richtige Comic Information. + loading description + Beschreibung laden - comics Comics - loading cover Cover laden - - loading description - Beschreibung laden + Please, select the right comic info. + Bitte wählen Sie die richtige Comic Information. - description unavailable Beschreibung nicht verfügbar @@ -1695,27 +1441,22 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SelectVolume - - Please, select the right series for your comic. - Bitte wählen Sie die richtige Serie für Ihre Comics. + loading description + Beschreibung lädt - - volumes - Bände + Please, select the right series for your comic. + Bitte wählen Sie die richtige Serie für Ihre Comics. - loading cover Titelbilder werden geladen - - loading description - Beschreibung lädt + volumes + Bände - description unavailable Beschreibung nicht verfügbar @@ -1723,166 +1464,84 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SeriesQuestion - - You are trying to get information for various comics at once, are they part of the same series? - Sie versuchen Informationen zu mehreren Comics auf einmal zu laden, sind sie Teil einer Serie? + no + Nein - yes Ja - - no - Nein + You are trying to get information for various comics at once, are they part of the same series? + Sie versuchen Informationen zu mehreren Comics auf einmal zu laden, sind sie Teil einer Serie? ServerConfigDialog - - set port - Port setzen - - - EASY SERVER CONNECTION - Einfache Server Verbindung - - - SERVER ADDRESS - SERVER Adresse - - - just scan the code with your device!! - Einfach den Code scannen!! + Port + Port - YACReader is now available for iOS devices, the best comic reading experience now in your iPad, iPhone or iPod touch. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader ist nun verfügbar für IOS Geräte, die beste Comic Lese Erfahrung für Ihr IPAD, IPhone oder IPod Touch. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'>Discover it! </a> + enable the server + Server aktivieren - IP address - IP Adresse + set port + Port setzen - Server connectivity information - Scan it! - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - Choose an IP address - - Port - Port - - - - enable the server - Server aktivieren - - - display less information about folders in the browser to improve the performance - Could not load libqrencode. - - QR generator error! - QR Generator Fehler! - SortVolumeComics - - Please, sort the list of comics on the left until it matches the comics' information. - Sortieren Sie bitte die Comic Informationen links, bis die Informationen für die Comics übereinstimmen. + remove selected comics + Löschen der ausgewählten Comics - sort comics to match comic information Sortieren Sie die Comics um die Informationen zur Übereinstimmung zu bringen - - issues - Ausgaben - - - - remove selected comics - Löschen der ausgewählten Comics - - - restore all removed comics - Wiederherstellung der gelöschten Comics Wiederherstellen aller gelöschten Comics - - - TableModel - - yes - Ja - - - no - Nein - - - Title - Titel - - - File Name - File Name - - - Pages - Seiten - - - Size - Größe - - - Read - Lesen - - Current Page - Aktuelle Seite + issues + Ausgaben - Rating - Bewertung + Please, sort the list of comics on the left until it matches the comics' information. + Sortieren Sie bitte die Comic Informationen links, bis die Informationen für die Comics übereinstimmen. TitleHeader - SEARCH Suche @@ -1890,25 +1549,21 @@ to improve the performance UpdateLibraryDialog - - Updating.... - Aktualisierung... + Update library + Aktualisierung der Bibliothek - Cancel Abbrechen - - Update library - Aktualisierung der Bibliothek + Updating.... + Aktualisierung... VolumeComicsModel - title Titel @@ -1916,83 +1571,92 @@ to improve the performance VolumesModel - year Jahr - issues Bände - publisher Herausgeber - YACReaderDeletingProgress + YACReader::TrayIconController - - Please wait, deleting in progress... - Bitte warten, Löschvorgang läuft... + &Restore + + + + &Quit + + + + Systray + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + + + + YACReader::WhatsNewDialog + + Close + + + + + YACReaderDeletingProgress - cancel Abbrechen + + Please wait, deleting in progress... + Bitte warten, Löschvorgang läuft... + YACReaderFieldEdit - - - Click to overwrite - Drücken zum Überschreiben - - - Restore to default Ursprungseinstellungen wiederherstellen - - - YACReaderFieldPlainTextEdit - - - - Click to overwrite Drücken zum Überschreiben + + + YACReaderFieldPlainTextEdit - Restore to default Ursprungseinstellungen wiederherstellen + + Click to overwrite + Drücken zum Überschreiben + YACReaderFlowConfigWidget - - How to show covers: - Wie zeige ich Titelseiten an: - - - CoverFlow look CoverFlow Ansicht - + How to show covers: + Wie zeige ich Titelseiten an: + + Stripe look Streifen Ansicht - Overlapped Stripe look Überlappende Streifen Ansicht @@ -2000,130 +1664,105 @@ to improve the performance YACReaderGLFlowConfigWidget - - Presets: - Voreinstellungen: - - - - Classic look - Klassische Darstellung - - - - Stripe look - + Zoom + Vergößern - - Overlapped Stripe look - Überlappende Streifen Darstellung + Light + Helligkeit - - Modern look - Moderne Drstellung + Show advanced settings + Zeige Fortgeschrittenen Einstellungen - Roulette look Zufällige Darstellung - - Show advanced settings - Zeige Fortgeschrittenen Einstellungen - - - - Custom: - Benutzerdefiniert: + Cover Angle + Titelbild Winkel - - View angle - Zeige Winkel + Stripe look + - Position Position - - Cover gap - Titelbild Abstand + Z offset + Z Abstand + + + Y offset + Y Abstand - Central gap Zentral Abstand - - Zoom - Vergößern + Presets: + Voreinstellungen: - - Y offset - Y Abstand + Overlapped Stripe look + Überlappende Streifen Darstellung - - Z offset - Z Abstand + Modern look + Moderne Drstellung - - Cover Angle - Titelbild Winkel + View angle + Zeige Winkel - - Visibility - Sichtbarkeit + Max angle + Max Winkel - - Light - Helligkeit + Custom: + Benutzerdefiniert: - - Max angle - Max Winkel + Classic look + Klassische Darstellung - - Low Performance - Niedrige Leistung + Cover gap + Titelbild Abstand - High Performance Hohe Leistung - + Performance: + Leistung: + + Use VSync (improve the image quality in fullscreen mode, worse performance) Benutze VSync (verbessert die Darstellung im Vollbild Modus, schlechtere Leistung) - - Performance: - Leistung: + Visibility + Sichtbarkeit + + + Low Performance + Niedrige Leistung YACReaderNavigationController - No favorites - You are not reading anything yet, come on!! @@ -2131,35 +1770,29 @@ to improve the performance YACReaderOptionsDialog - Save Speichern - + Use hardware acceleration (restart needed) + Hardwarebeschleunigung benutzen (Neustart erforderlich) + + Cancel Cancel - Edit shortcuts - Shortcuts - - - Use hardware acceleration (restart needed) - Hardwarebeschleunigung benutzen (Neustart erforderlich) - YACReaderSearchLineEdit - type to search @@ -2167,38 +1800,28 @@ to improve the performance YACReaderSideBar - + LIBRARIES + Bibliotheken + + + FOLDERS + ORDNER + + Libraries - Folders - Reading Lists - - LIBRARIES - Bibliotheken - - - - FOLDERS - ORDNER - - - READING LISTS - - Search folders and comics - Ordner und Comics durchsuchen - diff --git a/YACReaderLibrary/yacreaderlibrary_es.ts b/YACReaderLibrary/yacreaderlibrary_es.ts index d12190a33..b6bfa4e42 100644 --- a/YACReaderLibrary/yacreaderlibrary_es.ts +++ b/YACReaderLibrary/yacreaderlibrary_es.ts @@ -4,7 +4,6 @@ ActionsShortcutsModel - None @@ -12,200 +11,162 @@ AddLabelDialog - + cancel + cancelar + + Label name: - Choose a color: - red - orange - yellow - green - cyan - blue - violet - purple - pink - white - light - dark - accept - - - cancel - cancelar - AddLibraryDialog - - Comics folder : - Carpeta de cómics: - - - - Library name : - Library Name : - Nombre de la biblioteca: - - - Add Añadir - + Add an existing library + Añadir una biblioteca existente + + Cancel Cancelar - - Add an existing library - Añadir una biblioteca existente + Comics folder : + Carpeta de cómics: + + + Library name : + Nombre de la biblioteca: ApiKeyDialog - + Cancel + Cancelar + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Paste here your Comic Vine API key - Accept - - - Cancel - Cancelar - ClassicComicsView - Hide comic flow - Ocultar cómic flow + Ocultar cómic flow ComicInfoView - Authors - Autores + Autores - writer - penciller - inker - colorist - letterer - cover artist - Publisher - color - b/w - Characters @@ -213,191 +174,147 @@ ComicModel - - yes - + no + no - - no - no + yes + - - Title - Título + Read + Leído - - File Name - Nombre de archivo + Size + Tamaño - Pages - Páginas + Páginas - - Size - Tamaño + Title + Título - - Read - Leído + Current Page + Página Actual - - Current Page - Página Actual + File Name + Nombre de archivo - Rating - Nota + Nota ComicVineDialog - - skip - omitir - - - back atrás - next siguiente - - search - buscar + skip + omitir - close cerrar - - - - - + Retrieving tags for : %1 + Recuperando etiquetas para : %1 + + + Looking for comic... + Buscando cómic... + + + search + buscar + + Looking for volume... Buscando volumen... - - comic %1 of %2 - %3 cómic %1 de %2 - %3 - %1 comics selected %1 comics seleccionados - Error connecting to ComicVine Error conectando a ComicVine - unknown error - error desconocido - - - - - Retrieving tags for : %1 - Recuperando etiquetas para : %1 - - - Retrieving volume info... Recuperando imformación del volumen... - - - Looking for comic... - Buscando cómic... - CreateLibraryDialog - - Comics folder : - Carpeta de cómics: + Create new library + Crear la nueva biblioteca - - Library Name : - Nombre de la biblioteca: + Cancel + Cancelar - Create Crear - - Cancel - Cancelar - - - Create a library could take several minutes. You can stop the process and update the library later for completing the task. Crear una biblioteca puede llevar varios minutos. Puedes parar el proceso en cualquier momento y completar la tarea más tarde. - - Create new library - Crear la nueva biblioteca + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + La ruta seleccionada no existe o no es válida. Asegúrate de que tienes privilegios de escritura en esta carpeta - - Path not found - Ruta no encontrada + Comics folder : + Carpeta de cómics: - - The selected path does not exist or is not a valid path. Be sure that you have write access to this folder - La ruta seleccionada no existe o no es válida. Asegúrate de que tienes privilegios de escritura en esta carpeta + Library Name : + Nombre de la biblioteca: + + + Path not found + Ruta no encontrada EditShortcutsDialog - Restore defaults - To change a shortcut, double click in the key combination and type the new keys. - Shortcuts settings - Shortcut in use - The shortcut "%1" is already assigned to other function @@ -405,18 +322,14 @@ EmptyFolderWidget - - Subfolders in this folder - Empty folder - Drag and drop folders and comics here @@ -424,7 +337,6 @@ EmptyLabelWidget - This label doesn't contain comics yet @@ -432,84 +344,68 @@ EmptyReadingListWidget - This reading list does not contain any comics yet - This reading list doesn't contain comics yet ExportComicsInfoDialog - Output file : Archivo de salida : - - Create - Crear + Destination database name + Nombre de la base de datos de destino - Cancel Cancelar - - Export comics info - Exportar información de los cómics + Create + Crear - - Destination database name - Nombre de la base de datos de destino + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + La ruta seleccionada para el archivo de salida no existe o no es una ruta válida. Asegúrate de que tienes permisos de escritura en esta carpeta - - Problem found while writing - Problema encontrado mientras se escribía + Export comics info + Exportar información de los cómics - - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - La ruta seleccionada para el archivo de salida no existe o no es una ruta válida. Asegúrate de que tienes permisos de escritura en esta carpeta + Problem found while writing + Problema encontrado mientras se escribía ExportLibraryDialog - - Output folder : - Carpeta de destino: + Cancel + Cancelar - Create Crear - - Cancel - Cancelar + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + La ruta seleccionada para el archivo de salida no existe o no es una ruta válida. Asegúrate de que tienes permisos de escritura en esta carpeta - - Create covers package - Crear paquete de portadas + Output folder : + Carpeta de destino: - Problem found while writing Problema encontrado mientras se escribía - - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - La ruta seleccionada para el archivo de salida no existe o no es una ruta válida. Asegúrate de que tienes permisos de escritura en esta carpeta + Create covers package + Crear paquete de portadas - Destination directory Carpeta de destino @@ -517,22 +413,18 @@ FileComic - - Unknown error opening the file - Error desconocido abriendo el archivo + Format not supported + Formato no soportado - 7z not found 7z no encontrado - - Format not supported - Formato no soportado + Unknown error opening the file + Error desconocido abriendo el archivo - CRC error on page (%1): some of the pages will not be displayed correctly Error CRC en la página (%1): algunas de las páginas no se mostrarán correctamente @@ -540,7 +432,6 @@ GridComicsView - Show info @@ -548,40 +439,33 @@ HelpAboutDialog - - About - Acerca de - - - Help Ayuda + + About + Acerca de + ImportComicsInfoDialog - - Import comics info - Importar información de cómics - - - - Info database location : - Ubicación de la base de datos de información : + Cancel + Cancelar - Import Importar - - Cancel - Cancelar + Info database location : + Ubicación de la base de datos de información : + + + Import comics info + Importar información de cómics - Comics info file (*.ydb) Archivo de información de cómics (*.ydb) @@ -589,82 +473,65 @@ ImportLibraryDialog - - Library Name : - Nombre de la biblioteca : - - - - Package location : - Ubicación del paquete: - - - Destination folder : Directorio de destino: - - Unpack - Desempaquetar - - - Cancel Cancelar - - Extract a catalog - Extraer un catálogo + Unpack + Desempaquetar - Compresed library covers (*.clc) Compresed library covers (*.clc) + + Package location : + Ubicación del paquete: + + + Library Name : + Nombre de la biblioteca : + + + Extract a catalog + Extraer un catálogo + ImportWidget - - Importing comics - Importando cómics - - - stop parar - - Some of the comics being added... - Algunos de los cómics que estan siendo añadidos.... + Importing comics + Importando cómics - <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - Create a library could take several minutes. You can stop the process and update the library later for completing the task. <p>YACReaderLibrary está creando una nueva biblioteca.</p><p>Crear una biblioteca puede llevar varios minutos. Puedes parar el proceso en cualquier momento y actualizar la biblioteca más tarde para completar el proceso.</p> - + Some of the comics being added... + Algunos de los cómics que estan siendo añadidos.... + + Updating the library Actualizando la biblioteca - <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> - <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later. <p>La biblioteca actual está siendo actualizada. Para actualizaciones más rápidas, por favor, actualiza tus bibliotecas frecuentemente.</p><p>Puedes parar el proceso y continunar la actualización más tarde.</p> - Upgrading the library - <p>The current library is being upgraded, please wait.</p> @@ -672,590 +539,454 @@ LibraryWindow - <font color='white'> press 'F' to close fullscreen mode </font> - <font color='white'> presiona 'F' para salir de pantalla completa </font> + Edit + Editar - - YACReader Library - YACReader Library + The selected folder doesn't contain any library. + La carpeta seleccionada no contiene ninguna biblioteca. - - Create a new library - Crear una nueva biblioteca + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Esta biblioteca fue creada con una versión anterior de YACReaderLibrary. Es necesario que se actualice. ¿Deseas hacerlo ahora? - - Open an existing library - Abrir una biblioteca existente + Comic + Cómic - - - Export comics info - Exportar información de los cómics + Error opening the library + Error abriendo la biblioteca - - - Import comics info - Importar información de cómics + Show/Hide marks + Mostrar/Ocultar marcas - - Pack covers - Empaquetar portadas + YACReader not found + YACReader no encontrado - - Pack the covers of the selected library - Empaquetar las portadas de la biblioteca seleccionada + Show comics server options dialog + - - Unpack covers - Desempaquetar portadas + Remove current library from your collection + Eliminar biblioteca de la colección - - Unpack a catalog - Desempaquetar un catálogo + Set comic as read + Marcar cómic como leído - - Update library - Actualizar biblioteca + Remove and delete metadata + Eliminar y borrar metadatos - - Update current library - Actualizar la biblioteca seleccionada + Old library + Biblioteca antigua - - Rename library - Renombrar biblioteca + Update cover + Actualizar portada + + + Set as completed + Marcar como completo + + + Library + Librería - Rename current library Renombrar la biblioteca seleccionada - - Remove current library from your collection - Eliminar biblioteca de la colección + Fullscreen mode on/off + Modo a pantalla completa on/off - - Open current comic - Abrir cómic actual + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Esta biblioteca fue creada con una versión más nueva de YACReaderLibrary. ¿Deseas descargar la nueva versión ahora? - Open current comic on YACReader Abrir el cómic actual en YACReader - - Save selected covers to... - - - - - Save covers of the selected comics as JPG files - + Update current library + Actualizar la biblioteca seleccionada - - - Set as read - Marcar como leído + Library '%1' is no longer available. Do you want to remove it? + La biblioteca '%1' no está disponible. ¿Deseas eliminarla? - - Set comic as read - Marcar cómic como leído + Update library + Actualizar biblioteca - - - Set as unread - Marcar como no leído + Open folder... + Abrir carpeta... - - Set comic as unread - Marcar cómic como no leído + Do you want remove + ¿Deseas eliminar la biblioteca - - Show/Hide marks - Mostrar/Ocultar marcas + Set as uncompleted + Marcar como incompleto - Show or hide readed marks - Mostrar u ocultar marcas + Reset comic rating + Reseteal cómic rating - - - Fullscreen mode on/off - Modo a pantalla completa on/off + Error updating the library + Error actualizando la biblioteca - Fullscreen mode on/off (F) - Activar/desactivar modo a pantalla completa (F) + Folder + Carpeta - - Help, About YACReader - Ayuda, A cerca de... YACReader + Expand all nodes + Expandir todos los nodos - - Select root node - Seleccionar el nodo raíz + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La biblioteca '%1' ha sido creada con una versión más antigua de YACReaderLibrary y debe ser creada de nuevo. ¿Deseas crear la biblioteca ahora? - + - + + Pack covers + Empaquetar portadas - - Expand all nodes - Expandir todos los nodos + Set as read + Marcar como leído - - - - + Delete selected comics + Borrar los cómics seleccionados - Colapse all nodes - Contraer todos los nodos + Export comics info + Exportar información de los cómics - Show options dialog Mostrar opciones - - Show comics server options dialog - + Create a new library + Crear una nueva biblioteca - - Open folder... - Abrir carpeta... + Library not available + Biblioteca no disponible - - Set as uncompleted - Marcar como incompleto + Import comics info + Importar información de cómics - - Set as completed - Marcar como completo + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Ha habido algún problema intentando borrar los cómics selecionados. Por favor, verifica los permisos de escritura en los arhicovs seleccionados o los directorios que los conienen. - - Open containing folder... - Abrir carpeta contenedora... + Open current comic + Abrir cómic actual - - Reset comic rating - Reseteal cómic rating + YACReader Library + YACReader Library - - Select all comics - Seleccionar todos los cómics + Error creating the library + Errar creando la biblioteca - - Edit - Editar + Unpack covers + Desempaquetar portadas - Asign current order to comics - Asignar el orden actual a los cómics + Update needed + Se necesita actualizar - - Update cover - Actualizar portada + Open an existing library + Abrir una biblioteca existente - - Delete selected comics - Borrar los cómics seleccionados + Library name already exists + Ya existe el nombre de la biblioteca - Hide comic flow - Ocultar cómic flow + There is another library with the name '%1'. + Hay otra biblioteca con el nombre '%1'. - - Download tags from Comic Vine - Descargar etiquetas de Comic Vine + Download new version + Descargar la nueva versión - - Folder - Carpeta + Delete comics + Borrar cómics - - Comic - Cómic + Select all comics + Seleccionar todos los cómics - - Library not available - Library ' - Biblioteca no disponible + Pack the covers of the selected library + Empaquetar las portadas de la biblioteca seleccionada - - Library '%1' is no longer available. Do you want to remove it? - La biblioteca '%1' no está disponible. ¿Deseas eliminarla? + Help, About YACReader + Ayuda, A cerca de... YACReader - - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - La biblioteca '%1' ha sido creada con una versión más antigua de YACReaderLibrary y debe ser creada de nuevo. ¿Deseas crear la biblioteca ahora? + Set comic as unread + Marcar cómic como no leído - - Old library - Biblioteca antigua + Select root node + Seleccionar el nodo raíz - - - YACReader not found - YACReader no encontrado + Unpack a catalog + Desempaquetar un catálogo - YACReader not found, YACReader should be installed in the same folder as YACReaderLibrary. - YACReader no encontrado, YACReader debe estar instalado en el mismo directorio que YACReaderLibrary. + All the selected comics will be deleted from your disk. Are you sure? + Todos los cómics seleccionados serán borrados de tu disco. ¿Estás seguro? - - - Unable to delete - No se ha podido borrar + Download tags from Comic Vine + Descargar etiquetas de Comic Vine - - There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - Ha habido algún problema intentando borrar los cómics selecionados. Por favor, verifica los permisos de escritura en los arhicovs seleccionados o los directorios que los conienen. + Set as unread + Marcar como no leído - - Assign comics numbers - + Library not found + Biblioteca no encontrada - - Assign numbers starting in: - + Rename library + Renombrar biblioteca - - Error creating the library - Errar creando la biblioteca + Remove library + Eliminar biblioteca - - Error updating the library - Error actualizando la biblioteca + Open containing folder... + Abrir carpeta contenedora... - - Error opening the library - Error abriendo la biblioteca + Unable to delete + No se ha podido borrar - - Delete comics - Borrar cómics + library? + ? - - All the selected comics will be deleted from your disk. Are you sure? - Todos los cómics seleccionados serán borrados de tu disco. ¿Estás seguro? + Are you sure? + ¿Estás seguro? - - Remove comics + Save selected covers to... - - Comics will only be deleted from the current label/list. Are you sure? + Save covers of the selected comics as JPG files - - Library name already exists - Ya existe el nombre de la biblioteca + Set as manga + - - There is another library with the name '%1'. - Hay otra biblioteca con el nombre '%1'. + Set issue as manga + - - Library - Librería + Set as normal + - - Remove library - Eliminar biblioteca + Set issue as normal + - Show or hide read marks - - Add new folder - Add new folder to the current library - - Delete folder - Delete current folder from disk - Collapse all nodes - - Change between comics views - + Set as comic + + + Assign current order to comics - Edit shortcuts - Update folder - Update current folder - Add new reading list - Add a new reading list to the current library - Remove reading list - Remove current reading list from the library - Add new label - Add a new label to this library - Rename selected list - Rename any selected labels or lists - Add to... - Favorites - Add selected comics to favorites list - Upgrade failed - There were errors during library upgrade in: - - Update needed - Se necesita actualizar - - - - This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - Esta biblioteca fue creada con una versión anterior de YACReaderLibrary. Es necesario que se actualice. ¿Deseas hacerlo ahora? - - - Update failed - La actualización ha fallado - - - The current library can't be udpated. Check for write write permissions on: - La librería actual no ha podido ser actualizada. Verifica que posees permisos de escritura en: - - - - Download new version - Descargar la nueva versión - - - - This library was created with a newer version of YACReaderLibrary. Download the new version now? - Esta biblioteca fue creada con una versión más nueva de YACReaderLibrary. ¿Deseas descargar la nueva versión ahora? - - - - Copying comics... - - Moving comics... - Folder name: - No folder selected - Please, select a folder first - Error in path - There was an error accessing the folder's path - The selected folder and all its contents will be deleted from your disk. Are you sure? - There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - Add new reading lists - - List name: - Delete list/label - The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - Rename list name - Save covers - You are adding too many libraries. - You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. @@ -1264,81 +995,83 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - YACReader not found. There might be a problem with your YACReader installation. - - Library not found - Biblioteca no encontrada + Assign comics numbers + - - The selected folder doesn't contain any library. - La carpeta seleccionada no contiene ninguna biblioteca. + Assign numbers starting in: + - - Are you sure? - ¿Estás seguro? + Remove comics + - - library? - ? + Comics will only be deleted from the current label/list. Are you sure? + + + + LocalComicListModel - - Remove and delete metadata - Eliminar y borrar metadatos - + file name + nombre de archivo + + + + LogWindow - - Do you want remove - ¿Deseas eliminar la biblioteca + Log window + - Asign comics numbers - Asignar números de cómic + &Pause + - Asign numbers starting in: - Asignar números empezando en: + &Save + - - - LocalComicListModel - - file name - nombre de archivo + C&lear + + + + &Copy + + + + Level: + + + + &Auto scroll + NoLibrariesWidget - + create your first library + crea tu primera biblioteca + + You don't have any libraries yet Aún no tienes ninguna biblioteca - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Puedes crear una biblioteca en cualquier carpeta, YACReaderLibrary importará todos las carpetas y cómics de esa carpeta. Si has creado alguna biblioteca anteriormente, puedes abrirla sin volver a crearla.</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> - - create your first library - crea tu primera biblioteca - - - add an existing one añade una existente @@ -1346,306 +1079,327 @@ YACReaderLibrary will not stop you from creating more libraries but you should k OptionsDialog - + Options + Opciones + + + Tray icon settings (experimental) + + + + Close to tray + + + + Start into the system tray + + + Edit Comic Vine API key - Comic Vine API key - Enable background image - Opacity level - Blur level - Use selected comic cover as background - Restore defautls - Background - + Display continue reading banner + + + + Continue reading + + + Comic Flow - Grid view - General - - - Options - Opciones - PropertiesDialog - - General info - Información general + Day: + Día: - - Authors - Autores + Plot + Argumento - - Publishing - Publicación + Size: + Tamaño: - - Plot - Argumento + Year: + Año: - - Cover page - Página de portada + Inker(s): + Entintador(es): - - Title: - Título: + Publishing + Publicación - - - of: - + Publisher: + Editorial: - - Issue number: - Número: + General info + Información general - - Volume: - Volumen: + Color/BW: + Color/BN: - - Arc number: - + Edit selected comics information + Editar la información de los cómics seleccionados - - Story arc: - Arco argumental: + Penciller(s): + Dibujant(es): + + + Colorist(s): + Color: - Genre: - Genere: - Género: + Género: - - Size: - Tamaño: + Issue number: + Número: - - Writer(s): - Guionista(s): + Month: + Mes: - - Penciller(s): - Dibujant(es): + Notes: + Notas: - - Inker(s): - Entintador(es): + Synopsis: + Sinopsis: - - Colorist(s): - Color: + Title: + Título: - - Letterer(s): - Letterer(es): - Rotulista(s): + Not found + No encontrado - - Cover Artist(s): - Artista(s) portada: + Characters: + Personajes: - - Day: - Día: + Authors + Autores - - Month: - Mes: + Age rating: + Casificación edades: - - Year: - Año: + Story arc: + Arco argumental: - - Publisher: - Editorial: + Writer(s): + Guionista(s): - - Format: - Formato: + Comic not found. You should update your library. + Cómic no encontrado. Deberias actualizar tu biblioteca. - - Color/BW: - Color/BN: + Edit comic information + Editar la información del cócmic - - Age rating: - Casificación edades: + Cover page + Página de portada - - Synopsis: - Sinopsis: + Cover Artist(s): + Artista(s) portada: - - Characters: - Personajes: + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ver </a> - - Notes: - Notas: + Volume: + Volumen: - - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ver </a> + Format: + Formato: - - Not found - No encontrado + Letterer(s): + Rotulista(s): - - Comic not found. You should update your library. - Cómic no encontrado. Deberias actualizar tu biblioteca. + of: + - - Edit selected comics information - Editar la información de los cómics seleccionados + Arc number: + - - Edit comic information - Editar la información del cócmic + Manga: + QObject - 7z lib not found 7z lib no encontrado - unable to load 7z lib from ./utils imposible cargar 7z lib de ./utils + + Trace + + + + Debug + + + + Info + + + + Warning + + + + Error + + + + Fatal + + - RenameLibraryDialog + QsLogging::LogWindowModel - - New Library Name : - Nuevo nombre de la biblioteca : + Time + - - Rename - Renombrar + Level + - - Cancel - Cancelar + Message + + + + + QsLogging::Window + + &Pause + - + &Resume + + + + Save log + + + + Log file (*.log) + + + + + RenameLibraryDialog + Rename current library Renombrar la biblioteca seleccionada + + Cancel + Cancelar + + + Rename + Renombrar + + + New Library Name : + Nuevo nombre de la biblioteca : + ScraperResultsPaginator - - Number of volumes found : %1 - Número de volúmenes encontrados : %1 + Number of %1 found : %2 + Número de %1 encontrados : %2 - - page %1 of %2 página %1 de %2 - - Number of %1 found : %2 - Número de %1 encontrados : %2 + Number of volumes found : %1 + Número de volúmenes encontrados : %1 SearchSingleComic - Please provide some additional information. Por favor, proporciona alguna información adicional. - Series: Series: @@ -1653,12 +1407,10 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SearchVolume - Please provide some additional information. Por favor, proporciona alguna informacion adicional. - Series: Series: @@ -1666,27 +1418,22 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SelectComic - - Please, select the right comic info. - Por favor, selecciona la información correcta. + loading description + cargando descripción - comics cómics - loading cover cargando portada - - loading description - cargando descripción + Please, select the right comic info. + Por favor, selecciona la información correcta. - description unavailable descripción no disponible @@ -1694,27 +1441,22 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SelectVolume - - Please, select the right series for your comic. - Por favor, seleciona la serie correcta para tu cómic. + loading description + cargando descripción - - volumes - volúmenes + Please, select the right series for your comic. + Por favor, seleciona la serie correcta para tu cómic. - loading cover cargando portada - - loading description - cargando descripción + volumes + volúmenes - description unavailable descripción no disponible @@ -1722,170 +1464,84 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SeriesQuestion - - You are trying to get information for various comics at once, are they part of the same series? - Estás intentando obtener información de varios cómics a la vez, ¿son parte de la misma serie? + no + no - yes - - no - no + You are trying to get information for various comics at once, are they part of the same series? + Estás intentando obtener información de varios cómics a la vez, ¿son parte de la misma serie? ServerConfigDialog - - set port - fijar puerto - - - EASY SERVER CONNECTION - CONEXIÓN AL SERVIDOR FÁCILMENTE - - - SERVER ADDRESS - DATOS SERVIDOR - - - just scan the code with your device!! - ¡simplemente escanea el código con tu dispositivo! + Port + Puerto - YACReader is now available for iOS devices, the best comic reading experience now in your iPad, iPhone or iPod touch. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader is now available for iOS devices, the best comic reading experience now in your iPad, iPhone or iPod touch. <a href='http://ios.yacreader.com'> Discover it! </a> - YACReader está ahora disponible para dispositivos iOS, la mejor experiencia de lectura de cómics ahora en tu iPad, iPhone o iPod touch. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> ¡Descúbrelo! </a> + enable the server + activar el servidor - IP address - IP usada + set port + fijar puerto - Server connectivity information - Scan it! - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - Choose an IP address - - Port - Puerto - - - - enable the server - activar el servidor - - - display less information about folders in the browser to improve the performance - Could not load libqrencode. - - QR generator error! - ¡Error del generador QR! - SortVolumeComics - - Please, sort the list of comics on the left until it matches the comics' information. - Por favor, ordena la lista de cómics en la izquiera hasta que coincida con la información adecuada. + remove selected comics + eliminar cómics seleccionados - sort comics to match comic information ordena los cómics para coincidir con la información - - issues - números - - - - remove selected comics - eliminar cómics seleccionados - - - restore all removed comics restaurar todos los cómics eliminados - restore removed comics - restaurar cómics eliminados - - - - TableModel - - yes - - - - no - no - - - Title - Título - - - File Name - Nombre de archivo - - - Pages - Páginas - - - Size - Tamaño - - - Read - Leído - - - Current Page - Página Actual + issues + números - Rating - Nota + Please, sort the list of comics on the left until it matches the comics' information. + Por favor, ordena la lista de cómics en la izquiera hasta que coincida con la información adecuada. TitleHeader - SEARCH BUSCAR @@ -1893,25 +1549,21 @@ to improve the performance UpdateLibraryDialog - - Updating.... - Actualizado... + Update library + Actualizar biblioteca - Cancel Cancelar - - Update library - Actualizar biblioteca + Updating.... + Actualizado... VolumeComicsModel - title título @@ -1919,83 +1571,92 @@ to improve the performance VolumesModel - year año - issues números - publisher editor - YACReaderDeletingProgress + YACReader::TrayIconController - - Please wait, deleting in progress... - Borrando, por favor espera... + &Restore + + + + &Quit + + + + Systray + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + + + + YACReader::WhatsNewDialog + + Close + + + + + YACReaderDeletingProgress - cancel cancelar + + Please wait, deleting in progress... + Borrando, por favor espera... + YACReaderFieldEdit - - - Click to overwrite - Click para sobreescribir - - - Restore to default Restaurar valor por defecto - - - YACReaderFieldPlainTextEdit - - - - Click to overwrite Click para sobreescribir + + + YACReaderFieldPlainTextEdit - Restore to default Restaurar valor por defecto + + Click to overwrite + Click para sobreescribir + YACReaderFlowConfigWidget - - How to show covers: - Cómo mostrar las portadas: - - - CoverFlow look Tipo CoverFlow - + How to show covers: + Cómo mostrar las portadas: + + Stripe look Tipo tira - Overlapped Stripe look Tipo tira solapada @@ -2003,130 +1664,105 @@ to improve the performance YACReaderGLFlowConfigWidget - - Presets: - Predeterminados: - - - - Classic look - Tipo clásico - - - - Stripe look - Tipo tira + Zoom + Zoom - - Overlapped Stripe look - Tipo tira solapada + Light + Luz - - Modern look - Tipo moderno + Show advanced settings + Opciones avanzadas - Roulette look Tipo ruleta - - Show advanced settings - Opciones avanzadas - - - - Custom: - Personalizado: + Cover Angle + Ángulo de las portadas - - View angle - Ángulo de vista + Stripe look + Tipo tira - Position Posición - - Cover gap - Hueco entre portadas + Z offset + Desplazamiento en Z + + + Y offset + Desplazamiento en Y - Central gap Hueco central - - Zoom - Zoom + Presets: + Predeterminados: - - Y offset - Desplazamiento en Y + Overlapped Stripe look + Tipo tira solapada - - Z offset - Desplazamiento en Z + Modern look + Tipo moderno - - Cover Angle - Ángulo de las portadas + View angle + Ángulo de vista - - Visibility - Visibilidad + Max angle + Ángulo máximo - - Light - Luz + Custom: + Personalizado: - - Max angle - Ángulo máximo + Classic look + Tipo clásico - - Low Performance - Rendimiento bajo + Cover gap + Hueco entre portadas - High Performance Alto rendimiento - + Performance: + Rendimiento: + + Use VSync (improve the image quality in fullscreen mode, worse performance) Usar VSync (mejora la calidad de imagen en pantalla completa, peor rendimiento) - - Performance: - Rendimiento: + Visibility + Visibilidad + + + Low Performance + Rendimiento bajo YACReaderNavigationController - No favorites - You are not reading anything yet, come on!! @@ -2134,35 +1770,29 @@ to improve the performance YACReaderOptionsDialog - Save Guardar - + Use hardware acceleration (restart needed) + Usar aceleración por hardware (necesario reiniciar) + + Cancel Cancelar - Edit shortcuts - Shortcuts - - - Use hardware acceleration (restart needed) - Usar aceleración por hardware (necesario reiniciar) - YACReaderSearchLineEdit - type to search @@ -2170,38 +1800,28 @@ to improve the performance YACReaderSideBar - + LIBRARIES + BIBLIOTECAS + + + FOLDERS + CARPETAS + + Libraries - Folders - Reading Lists - - LIBRARIES - BIBLIOTECAS - - - - FOLDERS - CARPETAS - - - READING LISTS - - Search folders and comics - Buscar carpetas y cómics - diff --git a/YACReaderLibrary/yacreaderlibrary_fr.ts b/YACReaderLibrary/yacreaderlibrary_fr.ts old mode 100755 new mode 100644 index 6faebbb64..b1524fa5f --- a/YACReaderLibrary/yacreaderlibrary_fr.ts +++ b/YACReaderLibrary/yacreaderlibrary_fr.ts @@ -1,399 +1,320 @@ - + ActionsShortcutsModel - None - Rien + Rien AddLabelDialog - - Label name: - + red + rouge - - Choose a color: - Choisissez une couleur: + blue + bleu - - red - rouge + dark + foncé - - orange - orange + cyan + cyan - - yellow - jaune + pink + rose - green - vert + vert - - cyan - cyan + light + clair - - blue - bleu + white + blanc - - violet - violet + Choose a color: + Choisissez une couleur: - - purple - violet + accept + accepter - - pink - rose + cancel + Annuler - - white - blanc + orange + orange - - light - clair + purple + violet - - dark - foncé + violet + violet - - accept - accepter + yellow + jaune - - cancel - Annuler + Label name: + AddLibraryDialog - - Comics folder : - Dossier des bandes dessinées : - - - - Library name : - Library Name : - Nom de la librairie : - - - Add Ajouter - + Add an existing library + Ajouter une librairie existante + + Cancel Annuler - - Add an existing library - Ajouter une librairie existante + Comics folder : + Dossier des bandes dessinées : + + + Library name : + Nom de la librairie : ApiKeyDialog - - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Avant de pouvoir vous connecter à Comic Vine, vous avez besoin de votre propre clé API. Veuillez en obtenir une gratuitement ici: <a href="http://www.comicvine.com/api/"></a> + Accept + Accepter - - Paste here your Comic Vine API key - Collez ici votre clé API Comic Vine + Cancel + Annuler - - Accept - Accepter + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Avant de pouvoir vous connecter à Comic Vine, vous avez besoin de votre propre clé API. Veuillez en obtenir une gratuitement ici: <a href="http://www.comicvine.com/api/"></a> - - Cancel - Annuler + Paste here your Comic Vine API key + Collez ici votre clé API Comic Vine ClassicComicsView - Hide comic flow - Cacher le flux de bande dessinée + Cacher le flux de bande dessinée ComicInfoView - - Authors - Auteurs + b/w + noir et blanc - - writer - scénario + cover artist + couverture - - penciller - dessin + color + couleur - inker encre - - colorist - couleur + penciller + dessin - - letterer - lettreur + colorist + couleur - - cover artist - couverture + writer + scénario - - Publisher - Editeur + Characters + Personnages - - color - couleur + Authors + Auteurs - - b/w - noir et blanc + Publisher + Editeur - - Characters - Personnages + letterer + lettreur ComicModel - - yes - oui + no + non - - no - non + yes + oui - - Title - Titre + Read + Lu - - File Name - Nom du fichier + Size + Taille - Pages - Pages + Pages - - Size - Taille + Title + Titre - - Read - Lu + Current Page + Page en cours - - Current Page - Page en cours + File Name + Nom du fichier - Rating - Note + Note ComicVineDialog - - skip - passer - - - back - retour + retour - next - suivant + suivant - - search - chercher + skip + passer - close - fermer + fermer - - - - - - Looking for volume... - + Retrieving tags for : %1 + Retrouver les infomartions de: %1 + + + Looking for comic... + Vous cherchez une bande dessinée ... + + + search + chercher - - comic %1 of %2 - %3 - bande dessinée %1 sur %2 - %3 + bande dessinée %1 sur %2 - %3 - %1 comics selected - %1 bande(s) dessinnée(s) sélectionnée(s) + %1 bande(s) dessinnée(s) sélectionnée(s) - Error connecting to ComicVine - Erreur de connexion à Comic Vine + Erreur de connexion à Comic Vine - - - Retrieving tags for : %1 - Retrouver les infomartions de: %1 + Looking for volume... + - Retrieving volume info... - - - Looking for comic... - Vous cherchez une bande dessinée ... - CreateLibraryDialog - - Comics folder : - Dossier des bandes dessinées : + Create new library + Créer une nouvelle librairie - - Library Name : - Nom de la librairie : + Cancel + Annuler - Create Créer - - Cancel - Annuler - - - Create a library could take several minutes. You can stop the process and update the library later for completing the task. La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et continuer plus tard. - - Create new library - Créer une nouvelle librairie + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Le chemin sélectionné n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier - - Path not found - Chemin introuvable + Comics folder : + Dossier des bandes dessinées : - - The selected path does not exist or is not a valid path. Be sure that you have write access to this folder - Le chemin sélectionné n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + Library Name : + Nom de la librairie : + + + Path not found + Chemin introuvable EditShortcutsDialog - Restore defaults - To change a shortcut, double click in the key combination and type the new keys. - Shortcuts settings - Shortcut in use - The shortcut "%1" is already assigned to other function @@ -401,111 +322,90 @@ EmptyFolderWidget - - Subfolders in this folder - Sous-dossiers dans ce dossier + Sous-dossiers dans ce dossier - - Empty folder - + Drag and drop folders and comics here + Glissez et déposez les dossiers et les bandes dessinées ici - - Drag and drop folders and comics here - Glissez et déposez les dossiers et les bandes dessinées ici + Empty folder + EmptyLabelWidget - This label doesn't contain comics yet - Ce dossier ne contient pas encore de bandes dessinées + Ce dossier ne contient pas encore de bandes dessinées EmptyReadingListWidget - This reading list does not contain any comics yet - This reading list doesn't contain comics yet - Cette liste de lecture ne contient aucune bande dessinée + Cette liste de lecture ne contient aucune bande dessinée ExportComicsInfoDialog - Output file : Fichier de sortie : - - Create - Créer + Destination database name + Nom de la base de données de destination - Cancel Annuler - - Export comics info - Exporter les infos des bandes dessinées + Create + Créer - - Destination database name - Nom de la base de données de destination + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier - - Problem found while writing - Problème durant l'écriture + Export comics info + Exporter les infos des bandes dessinées - - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + Problem found while writing + Problème durant l'écriture ExportLibraryDialog - - Output folder : - Dossier de sortie : + Cancel + Annuler - Create Créer - - Cancel - Annuler + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier - - Create covers package - Créer un pack de couvertures + Output folder : + Dossier de sortie : - Problem found while writing Problème durant l'écriture - - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + Create covers package + Créer un pack de couvertures - Destination directory Répertoire de destination @@ -513,30 +413,25 @@ FileComic - - Unknown error opening the file - + 7z not found + 7z introuvable - - 7z not found - 7z introuvable + CRC error on page (%1): some of the pages will not be displayed correctly + - - Format not supported + Unknown error opening the file - - CRC error on page (%1): some of the pages will not be displayed correctly + Format not supported GridComicsView - Show info @@ -544,121 +439,99 @@ HelpAboutDialog - - About - A propos - - - Help Aide + + About + A propos + ImportComicsInfoDialog - - Import comics info - Importer les infos des bandes dessinées - - - - Info database location : - Emplacement des infos: + Cancel + Annuler - Import Importer - - Cancel - Annuler + Info database location : + Emplacement des infos: + + + Import comics info + Importer les infos des bandes dessinées - Comics info file (*.ydb) - Fichier infos BD (*.ydb) + Fichier infos BD (*.ydb) ImportLibraryDialog - - Library Name : - Nom de la librairie : - - - - Package location : - Emplacement : - - - Destination folder : Dossier de destination : - - Unpack - Désarchiver - - - Cancel Annuler - - Extract a catalog - Extraire un catalogue + Unpack + Désarchiver - Compresed library covers (*.clc) Compresed library covers (*.clc) - - - ImportWidget - - stop - Stop + Package location : + Emplacement : - - Some of the comics being added... - Ajout de bande dessinée... - + Library Name : + Nom de la librairie : + + + Extract a catalog + Extraire un catalogue + + + + ImportWidget + + stop + Stop + - Importing comics - Importation de bande dessinée + Importation de bande dessinée - <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <p>YACReaderLibrary est en train de créer une nouvelle librairie.</p><p>La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et poursuivre plus tard.</p> - + Some of the comics being added... + Ajout de bande dessinée... + + Updating the library Mise à jour de la librairie - <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <p>Mise à jour de la librairie. Pour plus de rapidité lors de la mise à jour, veuillez effectuer cette dernière régulièrement.</p><p>Vous pouvez arrêter le processus et poursuivre plus tard.</p> - Upgrading the library - <p>The current library is being upgraded, please wait.</p> @@ -666,673 +539,543 @@ LibraryWindow - - YACReader Library - Librairie de YACReader + Edit + Editer - - Library - Librairie + The selected folder doesn't contain any library. + Le dossier sélectionné ne contient aucune librairie. - <font color='white'> press 'F' to close fullscreen mode </font> - <font color='white'> appuyez sur 'F' pour quitter le mode plein écran </font> + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Cette librairie a été créée avec une ancienne version de YACReaderLibrary. Mise à jour necessaire. Mettre à jour? - - Create a new library - Créer une nouvelle librairie + Comic + Bande dessinée - - Open an existing library - Ouvrir une librairie existante + Update current folder + Mettre à jour ce dossier - - - Export comics info - Exporter les infos des bandes dessinées + Error opening the library + Erreur lors de l'ouverture de la librairie - - - Import comics info - Importer les infos des bandes dessinées + Show/Hide marks + Afficher/Cacher les marqueurs - - Pack covers - Archiver les couvertures + Show comics server options dialog + Ouvrir la boite de dialogue du serveur - - Pack the covers of the selected library - Archiver les couvertures de la librairie sélectionnée + Remove current library from your collection + Enlever cette librairie de votre collection - - Unpack covers - Désarchiver les couvertures + Set comic as read + Marquer cette bande dessinée comme lu - - Unpack a catalog - Désarchiver un catalogue + Add selected comics to favorites list + Ajouter la bande dessinée sélectionnée à la liste des favoris - - Update library - Mettre la librairie à jour + Remove and delete metadata + Supprimer les métadata - - Update current library - Mettre à jour la librairie actuelle + Old library + Ancienne librairie - - Rename library - Renommer la librairie + Update cover + Mise à jour des couvertures + + + Set as completed + Marquer comme complet + + + Library + Librairie - Rename current library Renommer la librairie actuelle - - Remove library - Supprimer la librairie + Fullscreen mode on/off + Mode plein écran activé/désactivé - - Remove current library from your collection - Enlever cette librairie de votre collection + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Cette librairie a été créée avec une version plus récente de YACReaderLibrary. Télécharger la nouvelle version? - - Open current comic - Ouvrir cette bande dessinée + Moving comics... + Déplacer la bande dessinée... - Open current comic on YACReader - Ouvrir cette bande dessinée dans YACReader - - - - Save selected covers to... - Exporter la couverture vers... + Ouvrir cette bande dessinée dans YACReader - - Save covers of the selected comics as JPG files - Enregistrer les couvertures des bandes dessinées sélectionnées en tant que fichiers JPG + Update current library + Mettre à jour la librairie actuelle - - - Set as read - Marquer comme lu + Copying comics... + Copier la bande dessinée... - - Set comic as read - Marquer cette bande dessinée comme lu + Library '%1' is no longer available. Do you want to remove it? + La librarie '%1' n'est plus disponible. Voulez-vous la supprimer? - - - Set as unread - Marquer comme non-lu + Update library + Mettre la librairie à jour - - Set comic as unread - Marquer cette bande dessinée comme non-lu + Open folder... + Ouvrir le dossier... - - Show/Hide marks - Afficher/Cacher les marqueurs + Do you want remove + Voulez-vous supprimer - Show or hide readed marks - Afficher ou cacher les marqueurs pour les livres lus + Set as uncompleted + Marquer comme incomplet - - Library not available - Library ' - Librairie non disponible + Reset comic rating + Supprimer la note d'évaluation - - - Fullscreen mode on/off - Mode plein écran activé/désactivé + Error updating the library + Erreur lors de la mise à jour de la librairie - Fullscreen mode on/off (F) - Mode plein écran activé/désactivé (F) + Folder + Dossier - - Help, About YACReader - Aide, à propos de YACReader + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + L'élément sélectionné sera supprimé, vos bandes dessinées ou dossiers ne seront pas supprimés de votre disque. Êtes-vous sûr? - - Select root node - Allerà la racine + Expand all nodes + Afficher tous les noeuds - + - + + Add to... + Ajouter à... - - Expand all nodes - Afficher tous les noeuds + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La librarie '%1' a été créée avec une ancienne version de YACReaderLibrary. Elle doit être re-créée. Voulez-vous créer la librairie? - - - - + Pack covers + Archiver les couvertures - Colapse all nodes - Masquer tous les noeuds + Remove current reading list from the library + Supprimer la liste de lecture actuelle de la bibliothèque - - Show options dialog - Ouvrir la boite de dialogue + Add new reading lists + Ajouter de nouvelles listes de lecture - - Show comics server options dialog - Ouvrir la boite de dialogue du serveur + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Vous ajoutez trop de bibliothèques. + +Vous n'avez probablement besoin que d'une bibliothèque dans votre dossier BD de niveau supérieur, vous pouvez parcourir les sous-dossiers en utilisant la section des dossiers dans la barre latérale gauche. + +YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais vous devriez garder le nombre de bibliothèques bas. - - Open folder... - Ouvrir le dossier... + Set as read + Marquer comme lu - - Set as uncompleted - Marquer comme incomplet + Delete selected comics + Supprimer la bande dessinée sélectionnée - - Set as completed - Marquer comme complet + Export comics info + Exporter les infos des bandes dessinées - - Open containing folder... - Ouvrir le dossier... + Show options dialog + Ouvrir la boite de dialogue - - Reset comic rating - Supprimer la note d'évaluation + Create a new library + Créer une nouvelle librairie - - Select all comics - Sélectionner toutes les bandes dessinées + Library not available + Librairie non disponible - - Edit - Editer + Import comics info + Importer les infos des bandes dessinées - Asign current order to comics - Assigner l'ordre actuel à vos comics + Add new reading list + Ajouter une nouvelle liste de lecture - - Update cover - Mise à jour des couvertures + Save selected covers to... + Exporter la couverture vers... - - Delete selected comics - Supprimer la bande dessinée sélectionnée + Open current comic + Ouvrir cette bande dessinée - Hide comic flow - Cacher le comic flow + YACReader Library + Librairie de YACReader - - Download tags from Comic Vine - Télécharger les informations de Comic Vine + Add a new reading list to the current library + Ajouter une nouvelle liste de lecture à la bibliothèque actuelle - - Edit shortcuts - + Error creating the library + Erreur lors de la création de la librairie - Update folder - Mettre à jour le dossier + Mettre à jour le dossier - - Update current folder - Mettre à jour ce dossier + Unpack covers + Désarchiver les couvertures - - Add new reading list - Ajouter une nouvelle liste de lecture + Update needed + Mise à jour requise - - Add a new reading list to the current library - Ajouter une nouvelle liste de lecture à la bibliothèque actuelle + Open an existing library + Ouvrir une librairie existante - - Remove reading list - Supprimer la liste de lecture + Show or hide read marks + Afficher ou masquer les marques de lecture - - Remove current reading list from the library - Supprimer la liste de lecture actuelle de la bibliothèque + Library name already exists + Le nom de la librairie existe déjà - - Add new label - + There is another library with the name '%1'. + Une autre librairie a le nom '%1'. - - Add a new label to this library - + Remove reading list + Supprimer la liste de lecture - - Rename selected list - + Download new version + Téléchrger la nouvelle version - - Rename any selected labels or lists - + Delete comics + Supprimer les comics - - Add to... - Ajouter à... + Select all comics + Sélectionner toutes les bandes dessinées - - Favorites - Favoris + Assign current order to comics + Assigner l'ordre actuel aux bandes dessinées - - Add selected comics to favorites list - Ajouter la bande dessinée sélectionnée à la liste des favoris + Pack the covers of the selected library + Archiver les couvertures de la librairie sélectionnée - - Folder - Dossier + Help, About YACReader + Aide, à propos de YACReader - - Comic - Bande dessinée + Favorites + Favoris - - Upgrade failed - + Set comic as unread + Marquer cette bande dessinée comme non-lu - - There were errors during library upgrade in: - + Select root node + Allerà la racine - - Update needed - Mise à jour requise + Unpack a catalog + Désarchiver un catalogue - - This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - Cette librairie a été créée avec une ancienne version de YACReaderLibrary. Mise à jour necessaire. Mettre à jour? + All the selected comics will be deleted from your disk. Are you sure? + Tous les comics sélectionnés vont être supprimés de votre disque. Êtes-vous sûr? - Update failed - Echec de la mise à jour + Download tags from Comic Vine + Télécharger les informations de Comic Vine - The current library can't be udpated. Check for write write permissions on: - Cette librairie ne peut pas être mise à jour. Vérifiez les droits d'accès: + Set as unread + Marquer comme non-lu - - Download new version - Téléchrger la nouvelle version + Library not found + Librairie introuvable - - This library was created with a newer version of YACReaderLibrary. Download the new version now? - Cette librairie a été créée avec une version plus récente de YACReaderLibrary. Télécharger la nouvelle version? + Rename library + Renommer la librairie - - Library '%1' is no longer available. Do you want to remove it? - La librarie '%1' n'est plus disponible. Voulez-vous la supprimer? + Remove library + Supprimer la librairie - - Old library - Ancienne librairie + Open containing folder... + Ouvrir le dossier... - - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - La librarie '%1' a été créée avec une ancienne version de YACReaderLibrary. Elle doit être re-créée. Voulez-vous créer la librairie? + library? + la librairie? - - - Copying comics... - Copier la bande dessinée... + Save covers of the selected comics as JPG files + Enregistrer les couvertures des bandes dessinées sélectionnées en tant que fichiers JPG - - - Moving comics... - Déplacer la bande dessinée... + Are you sure? + Êtes-vous sûr? - - Folder name: + Set as manga - - No folder selected + Set issue as manga - - Please, select a folder first + Set as normal - - Error in path + Set issue as normal - - There was an error accessing the folder's path + Add new folder - - The selected folder and all its contents will be deleted from your disk. Are you sure? + Add new folder to the current library - - There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Delete folder - - Add new reading lists - Ajouter de nouvelles listes de lecture + Delete current folder from disk + - - - List name: + Collapse all nodes - - Delete list/label + Change between comics views - - The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - L'élément sélectionné sera supprimé, vos bandes dessinées ou dossiers ne seront pas supprimés de votre disque. Êtes-vous sûr? + Set as comic + - - Rename list name + Edit shortcuts - - Save covers + Add new label - - You are adding too many libraries. + Add a new label to this library - - You are adding too many libraries. - -You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. - -YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - Vous ajoutez trop de bibliothèques. - -Vous n'avez probablement besoin que d'une bibliothèque dans votre dossier BD de niveau supérieur, vous pouvez parcourir les sous-dossiers en utilisant la section des dossiers dans la barre latérale gauche. - -YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais vous devriez garder le nombre de bibliothèques bas. + Rename selected list + - - - YACReader not found + Rename any selected labels or lists - - Library not found - Librairie introuvable + Upgrade failed + - - The selected folder doesn't contain any library. - Le dossier sélectionné ne contient aucune librairie. + There were errors during library upgrade in: + - - Are you sure? - Êtes-vous sûr? + Folder name: + - - Do you want remove - Voulez-vous supprimer + No folder selected + - - library? - la librairie? + Please, select a folder first + - - Remove and delete metadata - Supprimer les métadata + Error in path + - - Assign comics numbers + There was an error accessing the folder's path - - Assign numbers starting in: + The selected folder and all its contents will be deleted from your disk. Are you sure? - - Unable to delete - - Show or hide read marks - Afficher ou masquer les marques de lecture - - - - - Add new folder + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - - Add new folder to the current library + List name: - - - Delete folder + Delete list/label - - Delete current folder from disk + Rename list name - - Collapse all nodes + Save covers - - - Change between comics views + You are adding too many libraries. - - Assign current order to comics - Assigner l'ordre actuel aux bandes dessinées + YACReader not found + - YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - YACReader not found. There might be a problem with your YACReader installation. - There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - Asign comics numbers - Assigner les numéros aux comics + Assign comics numbers + - Asign numbers starting in: - Assigner les numéros: + Assign numbers starting in: + - - Error creating the library - Erreur lors de la création de la librairie + Remove comics + - - Error updating the library - Erreur lors de la mise à jour de la librairie + Comics will only be deleted from the current label/list. Are you sure? + + + + LocalComicListModel - - Error opening the library - Erreur lors de l'ouverture de la librairie + file name + + + + LogWindow - - Delete comics - Supprimer les comics + Log window + - - All the selected comics will be deleted from your disk. Are you sure? - Tous les comics sélectionnés vont être supprimés de votre disque. Êtes-vous sûr? + &Pause + - - Remove comics + &Save - - Comics will only be deleted from the current label/list. Are you sure? + C&lear - - Library name already exists - Le nom de la librairie existe déjà + &Copy + - - There is another library with the name '%1'. - Une autre librairie a le nom '%1'. + Level: + - - - LocalComicListModel - - file name + &Auto scroll NoLibrariesWidget - + create your first library + Créez votre première librairie + + You don't have any libraries yet Vous n'avez pas encore de librairie - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> - <p>Vous pouvez creer une librairie dans n'importe quel dossierr, YACReaderLibrary importera les dossiers et les bandes dessinées contenus dans ce dossier. Si vous avez déjà crer des librairies, vous pouvez les ouvrir.</p><p>N'oubliez pas que vous pouvez utiliser YACReader en tant que stand alone pour lire vos bandes dessinées sur votre ordinateur.</p> - - - - create your first library - Créez votre première librairie + <p>Vous pouvez creer une librairie dans n'importe quel dossierr, YACReaderLibrary importera les dossiers et les bandes dessinées contenus dans ce dossier. Si vous avez déjà crer des librairies, vous pouvez les ouvrir.</p><p>N'oubliez pas que vous pouvez utiliser YACReader en tant que stand alone pour lire vos bandes dessinées sur votre ordinateur.</p> - add an existing one Ajouter une librairie existante @@ -1340,292 +1083,316 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v OptionsDialog - + Options + Options + + + Tray icon settings (experimental) + + + + Close to tray + + + + Start into the system tray + + + Edit Comic Vine API key - Comic Vine API key - Enable background image - Opacity level - Blur level - Use selected comic cover as background - Restore defautls - Background - + Display continue reading banner + + + + Continue reading + + + Comic Flow - Grid view - General - - - Options - Options - PropertiesDialog - - General info - Infos générales + of: + sur: - - Authors - Auteurs + Day: + Jour: + + + Plot + Intrigue + + + Size: + Taille: + + + Year: + Année: + + + Inker(s): + Encreur(s): - Publishing Publication - - Plot - Intrigue + Publisher: + Editeur: - - Cover page - Couverture + General info + Infos générales - - Title: - Titre: + Color/BW: + Couleur/Noir et blanc: - - - of: - sur: + Edit selected comics information + Editer les informations du comic sélectionné + + + Penciller(s): + Dessinateur(s): + + + Colorist(s): + Coloriste(s): + + + Genre: + Genre: - Issue number: Numéro: - - Volume: - Volume: + Month: + Mois: + + + Notes: + Notes: + + + Synopsis: + Synopsis: + + + Title: + Titre: - Arc number: Arc numéro: - - Story arc: - Arc narratif: + Not found + Introuvable - - Genre: - Genere: - Genre: + Characters: + Personnages: - - Size: - Taille: + Authors + Auteurs - - Writer(s): - Scénariste(s): + Age rating: + Limite d'âge: - - Penciller(s): - Dessinateur(s): + Story arc: + Arc narratif: - - Inker(s): - Encreur(s): + Writer(s): + Scénariste(s): - - Colorist(s): - Coloriste(s): + Comic not found. You should update your library. + Comic introuvable. Vous devriez mettre à jour votre librairie. - - Letterer(s): - Lettreur(s): + Edit comic information + Editer les informations du comic + + + Cover page + Couverture - Cover Artist(s): Artiste(s) de couverture: - - Day: - Jour: + Volume: + Volume: - - Month: - Mois: + Format: + Format: - - Year: - Année: + Letterer(s): + Lettreur(s): - - Publisher: - Editeur: + Manga: + - - Format: - Format: + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + + + + QObject - - Color/BW: - Couleur/Noir et blanc: + 7z lib not found + - - Age rating: - Limite d'âge: + unable to load 7z lib from ./utils + - - Synopsis: - Synopsis: + Trace + - - Characters: - Personnages: + Debug + - - Notes: - Notes: + Info + + + + Warning + - - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Error + + + + Fatal + + + + + QsLogging::LogWindowModel + + Time - - Not found - Introuvable + Level + - - Comic not found. You should update your library. - Comic introuvable. Vous devriez mettre à jour votre librairie. + Message + + + + QsLogging::Window - - Edit selected comics information - Editer les informations du comic sélectionné + &Pause + - - Edit comic information - Editer les informations du comic + &Resume + - - - QObject - - 7z lib not found + Save log - - unable to load 7z lib from ./utils + Log file (*.log) RenameLibraryDialog - - New Library Name : - Nouveau nom de librairie: - - - - Rename - Renommer + Rename current library + Renommer la librairie actuelle - Cancel Annuler - - Rename current library - Renommer la librairie actuelle + Rename + Renommer + + + New Library Name : + Nouveau nom de librairie: ScraperResultsPaginator - Number of volumes found : %1 - - page %1 of %2 - Number of %1 found : %2 @@ -1633,12 +1400,10 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v SearchSingleComic - Please provide some additional information. - Series: @@ -1646,12 +1411,10 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v SearchVolume - Please provide some additional information. - Series: @@ -1659,27 +1422,22 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v SelectComic - Please, select the right comic info. - comics - loading cover - loading description - description unavailable @@ -1687,27 +1445,22 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v SelectVolume - Please, select the right series for your comic. - volumes - loading cover - loading description - description unavailable @@ -1715,157 +1468,84 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v SeriesQuestion - - You are trying to get information for various comics at once, are they part of the same series? - + no + non - yes - oui + oui - - no - non + You are trying to get information for various comics at once, are they part of the same series? + ServerConfigDialog - - set port - Configurer le port - - - EASY SERVER CONNECTION - CONNECTION AU SERVEUR - - - SERVER ADDRESS - ADRESSE DU SERVEUR - - - just scan the code with your device!! - Scannez simplement le code!! + Port + Port - YACReader is now available for iOS devices, the best comic reading experience now in your iPad, iPhone or iPod touch. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader est désormais disponible sur iOS, la meilleur manière de lire sur iPad, iPhone ou iPod touch. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Essayez-le! </a> + enable the server + Autoriser le serveur - IP address - Adresse IP + set port + Configurer le port - Server connectivity information - Scan it! - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - Choose an IP address - - Port - Port - - - - enable the server - Autoriser le serveur - - - display less information about folders in the browser to improve the performance - Could not load libqrencode. - - QR generator error! - QR generator error! - SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. - sort comics to match comic information - issues - remove selected comics - restore all removed comics - - TableModel - - yes - oui - - - no - non - - - Title - Titre - - - File Name - Nom du fichier - - - Pages - Pages - - - Size - Taille - - - Read - Lu - - TitleHeader - SEARCH @@ -1873,25 +1553,21 @@ to improve the performance UpdateLibraryDialog - - Updating.... - Mise à jour... + Update library + Mettre la librairie à jour - Cancel Annuler - - Update library - Mettre la librairie à jour + Updating.... + Mise à jour... VolumeComicsModel - title @@ -1899,83 +1575,92 @@ to improve the performance VolumesModel - + publisher + éditeur + + year - issues + + + YACReader::TrayIconController - - publisher - éditeur + &Restore + + + + &Quit + + + + Systray + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + - YACReaderDeletingProgress + YACReader::WhatsNewDialog - - Please wait, deleting in progress... - Attendez, suppression en cours... + Close + + + + YACReaderDeletingProgress - cancel Annuler + + Please wait, deleting in progress... + Attendez, suppression en cours... + YACReaderFieldEdit - - - Click to overwrite - Cliquer pour modifier - - - Restore to default Restaurer les paramètres par défaut - - - YACReaderFieldPlainTextEdit - - - - Click to overwrite Cliquer pour modifier + + + YACReaderFieldPlainTextEdit - Restore to default Restaurer les paramètres par défaut + + Click to overwrite + Cliquer pour modifier + YACReaderFlowConfigWidget - - How to show covers: - Comment voir les couvertures: - - - CoverFlow look Vue CoverFlow - + How to show covers: + Comment voir les couvertures: + + Stripe look Vue alignée - Overlapped Stripe look Vue superposée @@ -1983,166 +1668,135 @@ to improve the performance YACReaderGLFlowConfigWidget - - Presets: - Réglages: - - - - Classic look - Vue classique - - - - Stripe look - Vue alignée + Zoom + Zoom - - Overlapped Stripe look - Vue superposée + Light + Lumière - - Modern look - Vue moderne + Show advanced settings + Réglages avancés - Roulette look Vue roulette - - Show advanced settings - Réglages avancés - - - - Custom: - Personnalisation: + Cover Angle + Angle des couvertures - - View angle - Angle de vue + Stripe look + Vue alignée - Position Position - - Cover gap - Espace entre les couvertures + Z offset + Axe Z + + + Y offset + Axe Y - Central gap Espace central - - Zoom - Zoom + Presets: + Réglages: - - Y offset - Axe Y + Overlapped Stripe look + Vue superposée - - Z offset - Axe Z + Modern look + Vue moderne - - Cover Angle - Angle des couvertures + View angle + Angle de vue - - Visibility - Visibilité + Max angle + Angle maximum - - Light - Lumière + Custom: + Personnalisation: - - Max angle - Angle maximum + Classic look + Vue classique - - Low Performance - Basse performance + Cover gap + Espace entre les couvertures - High Performance Haute performance - + Performance: + Performance: + + Use VSync (improve the image quality in fullscreen mode, worse performance) Utiliser VSync (améliore la qualité de l'image en plein écran, diminue la performance) - - Performance: - Performance: + Visibility + Visibilité + + + Low Performance + Basse performance YACReaderNavigationController - - No favorites - Pas de favoris + You are not reading anything yet, come on!! + Vous ne lisez rien encore, allez !! - - You are not reading anything yet, come on!! - Vous ne lisez rien encore, allez !! + No favorites + Pas de favoris YACReaderOptionsDialog - Save Sauvegarder - + Use hardware acceleration (restart needed) + Utiliser l'accélération hardware (redémarrage nécessaire) + + Cancel Annuler - Edit shortcuts - Shortcuts - - - Use hardware acceleration (restart needed) - Utiliser l'accélération hardware (redémarrage nécessaire) - YACReaderSearchLineEdit - type to search @@ -2150,38 +1804,28 @@ to improve the performance YACReaderSideBar - - Libraries - - - - - Folders - - - - Reading Lists - Listes de lecture + Listes de lecture - LIBRARIES LIBRAIRIES - FOLDERS DOSSIERS - READING LISTS - Listes de lecture + Listes de lecture + + + Libraries + - Search folders and comics - Recherche de dossiers et de comics + Folders + diff --git a/YACReaderLibrary/yacreaderlibrary_it.ts b/YACReaderLibrary/yacreaderlibrary_it.ts new file mode 100644 index 000000000..faec6a886 --- /dev/null +++ b/YACReaderLibrary/yacreaderlibrary_it.ts @@ -0,0 +1,1856 @@ + + + + + ActionsShortcutsModel + + None + Nessuno + + + + AddLabelDialog + + red + Rosso + + + blue + Blu + + + dark + Scuro + + + cyan + Azzurro + + + pink + Rosa + + + green + Verde + + + light + Luminoso + + + white + Bianco + + + Choose a color: + Seleziona un colore: + + + accept + Accetta + + + cancel + Cancella + + + orange + Arancione + + + purple + Porpora + + + violet + Viola + + + yellow + Giallo + + + Label name: + Nome etichetta: + + + + AddLibraryDialog + + Add + Aggiungi + + + Add an existing library + Aggiungi ad una libreria esistente + + + Cancel + Cancella + + + Comics folder : + Cartella fumetti: + + + Library Name : + Nome libreria: + + + Library name : + + + + + ApiKeyDialog + + Accept + Accetta + + + Cancel + Cancella + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Prima di conneterti a "Comic Vine" devi avere la tua chiave API. Per favore recuperane una da <a href="http://www.comicvine.com/api/">QUI</a + + + Paste here your Comic Vine API key + Incolla qui la tua chiave API di "Comic Vine" + + + + ClassicComicsView + + Hide comic flow + Nascondi il flusso dei fumetti + + + + ComicInfoView + + Authors + Autori + + + writer + + + + penciller + + + + inker + + + + colorist + + + + letterer + + + + cover artist + + + + Publisher + + + + color + + + + b/w + + + + Characters + + + + + ComicModel + + no + No + + + yes + Si + + + Read + Leggi + + + Size + Dimensione + + + Pages + Pagine + + + Title + Titolo + + + Current Page + Pagina corrente + + + File Name + Nome file + + + Rating + Valutazione + + + + ComicVineDialog + + back + Indietro + + + next + Prossimo + + + skip + Salta + + + close + Chiudi + + + Retrieving tags for : %1 + Ricezione tag per: %1 + + + Looking for comic... + Sto cercando il fumetto... + + + search + Cerca + + + Looking for volume... + Sto cercando il fumetto... + + + comic %1 of %2 - %3 + Fumetto %1 di %2 - %3 + + + %1 comics selected + Fumetto %1 selezionato + + + Error connecting to ComicVine + Errore durante la connessione a ComicVine + + + Retrieving volume info... + Sto ricevendo le informazioni per l'abum... + + + + CreateLibraryDialog + + Create new library + Crea una nuova libreria + + + Cancel + Cancella + + + Create + Crea + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Creare una Libreria può aver bisogno di alcuni minuti. Puoi fermare il processo ed aggiornare la libreria più tardi. + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Il percorso selezionato non esiste oppure non è valido. Controlla di avere i permessi di scrittura per questa cartella + + + Comics folder : + Cartella fumetti: + + + Library Name : + Nome libreria: + + + Path not found + Percorso non trovato + + + + EditShortcutsDialog + + Shortcut in use + Scorciatoia in uso + + + Restore defaults + Resetta al Default + + + Shortcuts settings + Impostazioni scorciatoie + + + The shortcut "%1" is already assigned to other function + La scorciatoia "%1" è già assegnata ad un' altra funzione + + + To change a shortcut, double click in the key combination and type the new keys. + Per cambiare una sorciatoia fai doppio click sulla combinazione tasti e digita la nuova combinazione. + + + + EmptyFolderWidget + + Empty folder + Cartella vuota + + + Subfolders in this folder + Sottocartelle in questa cartella + + + Drag and drop folders and comics here + Prendi e sposta le cartelle qui + + + + EmptyLabelWidget + + This label doesn't contain comics yet + Per ora questa etichetta non contiene fumetti + + + + EmptyReadingListWidget + + This reading list does not contain any comics yet + Per ora questa lista non contiene fumetti + + + + ExportComicsInfoDialog + + Output file : + File di Output: + + + Destination database name + Nome database di destinazione + + + Cancel + Cancella + + + Create + Crea + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Il percorso selezionato per il file di Output non esiste oppure non è valido. Controlla di avere i permessi di scrittura per questa cartella + + + Export comics info + Esporta informazioni fumetto + + + Problem found while writing + Trovato problema durante la scrittura + + + + ExportLibraryDialog + + Cancel + Cancella + + + Create + Crea + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Il percorso selezionato per il file di Output non esiste oppure non è valido. Controlla di avere i permessi di scrittura per questa cartella + + + Output folder : + Cartella di Output: + + + Problem found while writing + Trovato problema durante la scrittura + + + Create covers package + Crea pacchetto delle copertine + + + Destination directory + Cartella di destinazione + + + + FileComic + + Format not supported + Formato non supportato + + + 7z not found + 7z non trovato + + + Unknown error opening the file + Errore sconosciuto all'apertura del file + + + CRC error on page (%1): some of the pages will not be displayed correctly + Errore CRC alla pagina (%1): alcune pagine potrebbero non essere visualizzate correttamente + + + + GridComicsView + + Show info + Mostra informazioni + + + + HelpAboutDialog + + Help + Aiuto + + + About + Informazioni + + + + ImportComicsInfoDialog + + Cancel + Cancella + + + Import + Importa + + + Info database location : + Informazioni posizione database: + + + Import comics info + Importa informazioni fumetto + + + Comics info file (*.ydb) + File informazioni fumetto (*.ydb) + + + + ImportLibraryDialog + + Destination folder : + Cartella di destinazione: + + + Cancel + Cancella + + + Unpack + Decomprimi + + + Compresed library covers (*.clc) + Libreria di copertine compresse (*.clc) + + + Package location : + Posizione PAcchetto: + + + Library Name : + Nome libreria: + + + Extract a catalog + Estrai un catalogo + + + + ImportWidget + + stop + Ferma + + + Importing comics + Sto importando i fumetti + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YacReader sta creando una nuova libreria.</p><p>La creazione di una libreria può durare diversi minuti. Puoi fermare l'attività ed aggiornare la libreria più tardi, completando l'attività</p> + + + Some of the comics being added... + Alcuni fumetti che sto aggiungendo... + + + Updating the library + Sto aggiornando la Libreria + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>Quest alibreria si sta aggiornando. Per aggiornamenti più veloci aggiorna la tua libreria di frequente.</p><p>Puoi fermare il processo ed aggiornare la libreria più tardi.</p> + + + Upgrading the library + + + + <p>The current library is being upgraded, please wait.</p> + + + + + LibraryWindow + + Edit + Edita + + + The selected folder doesn't contain any library. + La cartella selezionata non contiene nessuna Libreria. + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Questa libreria è stata creata con una versione precedente di YACREaderLibrary. Deve essere aggiornata. Aggiorno ora? + + + Comic + Fumetto + + + Folder name: + Nome della cartella: + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + La cartella seleziona e tutto il suo contenuto verranno cancellati dal tuo disco. Sei sicuro? + + + Update current folder + Aggiorna la cartella corrente + + + Error opening the library + Errore nell'apertura della libreria + + + Show/Hide marks + Mostra/Nascondi + + + YACReader not found + YACReader non trovato + + + Show comics server options dialog + Mostra le opzioni per il server dei fumetti + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + C'è stato un problema cancellando le cartelle selezionate. Per favore controlla i tuoi permessi di scrittura e sii sicuro che non ci siano altre applicazioni che usano le stesse cartelle. + + + Remove current library from your collection + Rimuovi la libreria corrente dalla tua collezione + + + Set comic as read + Setta il fumetto come letto + + + Rename list name + Rinomina la lista + + + Add selected comics to favorites list + Aggiungi i fumetti selezionati alla lista dei favoriti + + + Remove and delete metadata + Rimuovi e cancella i Metadati + + + YACReader not found, YACReader should be installed in the same folder as YACReaderLibrary. + YACReader non trovato, YACReader deve esere installato nella stessa cartella di YACReaderLibrary. + + + Old library + Vecchia libreria + + + Update cover + Aggiorna copertina + + + Rename any selected labels or lists + Rinomina qualsiasi etichetta o lista selezionata + + + Set as completed + Segna come completo + + + There was an error accessing the folder's path + C'è stato un errore nell'accesso al percorso della cartella + + + Library + Libreria + + + Add new folder to the current library + Aggiungi una nuova cartella alla libreria corrente + + + Comics will only be deleted from the current label/list. Are you sure? + I fumetti verranno cancellati dall'etichetta/lista corrente. Sei sicuro? + + + Rename current library + Rinomina la libreria corrente + + + Fullscreen mode on/off + Modalità a schermo interno on/off + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Questa libreria è stata creata con una verisone più recente di YACReaderLibrary. Scarico la versione aggiornata ora? + + + Moving comics... + Sto muovendo i fumetti... + + + Open current comic on YACReader + Apri il fumetto corrente con YACReader + + + Update current library + Aggiorna la Libreria corrente + + + Copying comics... + Sto copiando i fumetti... + + + Library '%1' is no longer available. Do you want to remove it? + La libreria '%1' non è più disponibile, la vuoi cancellare? + + + Update library + Aggiorna Libreria + + + Open folder... + Apri Cartella... + + + Do you want remove + Vuoi rimuovere + + + Set as uncompleted + Segna come non completo + + + Error in path + Errore nel percorso + + + Reset comic rating + Resetta la valutazione dei fumetti + + + Error updating the library + Errore aggiornando la libreria + + + Folder + Cartella + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + Gli elementi selezionati verranno cancellati, i tuoi fumetti o cartella NON verranno cancellati dal tuo disco. Sei sicuro? + + + Expand all nodes + Espandi tutti i nodi + + + Delete current folder from disk + Cancella la cartella corrente dal disco + + + List name: + Nome lista: + + + Add to... + Aggiungi a... + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La libreria '%1' è stata creata con una versione precedente di YACREaderLibrary. Deve essere ricreata. Lo vuoi fare ora? + + + Pack covers + Compatta Copertine + + + Save covers + Salva Copertine + + + Change between comics views + Cambia tra i modi di visualizzazione dei fumetti + + + Remove current reading list from the library + Rimuovi la lista di lettura dalla libreria + + + Add new reading lists + Aggiungi una lista di lettura + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Stai aggiungendo troppe Libreire + +Hai probabilemnte bisogno di una sola Libreria al livello superiore, puoi poi navigare qualsiasi sotto cartella usando la selezione delle cartella a sinistra + +YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il numero di librerie basso. + + + Set as read + Setta come letto + + + Assign comics numbers + Assegna un numero ai fumetti + + + Delete selected comics + Cancella i fumetti selezionati + + + Export comics info + Esporta informazioni fumetto + + + Show options dialog + Mostra le opzioni + + + Please, select a folder first + Per cortesia prima seleziona una cartella + + + Create a new library + Crea una nuova libreria + + + Library not available + Libreria non disponibile + + + Import comics info + Importa informazioni fumetto + + + The current library can't be udpated. Check for write write permissions on: + La libreria corrente non può essere aggiornata. Controlla i tuoi permessi di scrittura su: + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + C'è un problema nel cancellare i fumetti selezionati. Per favore controlla i tuoi permessi di scrittura sui file o sulla cartella. + + + Add new reading list + Aggiorna la lista di lettura + + + Save selected covers to... + Salva le copertine selezionate in... + + + Open current comic + Apri il fumetto corrente + + + YACReader Library + Libreria YACReader + + + Add a new reading list to the current library + Aggiungi una lista di lettura alla libreria corrente + + + Error creating the library + Errore creando la libreria + + + Update failed + Aggiornamento fallito + + + You are adding too many libraries. + Stai aggiungendto troppe librerie. + + + Update folder + Aggiorna Cartella + + + Unpack covers + Scompatta le Copertine + + + Update needed + Devi aggiornarmi + + + Open an existing library + Apri una libreria esistente + + + Show or hide read marks + Mostra o nascondi lo stato di lettura + + + Library name already exists + Esiste già una libreria con lo stesso nome + + + There is another library with the name '%1'. + Esiste già una libreria con il nome '%1'. + + + Remove reading list + Rimuovi la lista di lettura + + + Delete folder + Cancella Cartella + + + Assign numbers starting in: + Assegna numeri partendo da: + + + Download new version + Scarica la nuova versione + + + Delete comics + Cancella i fumetti + + + Add new folder + Aggiungi una nuova cartella + + + Select all comics + Seleziona tutti i fumetti + + + Assign current order to comics + Assegna l'ordinamento corrente ai fumetti + + + Pack the covers of the selected library + Compatta le copertine della libreria selezionata + + + Help, About YACReader + Aiuto, Crediti YACReader + + + Collapse all nodes + Compatta tutti i nodi + + + Favorites + Favoriti + + + Rename selected list + Rinomina la lista selezionata + + + Delete list/label + Cancella Lista/Etichetta + + + Set comic as unread + Setta il fumetto come non letto + + + Edit shortcuts + Edita scorciatoie + + + Select root node + Seleziona il nodo principale + + + No folder selected + Nessuna cartella selezionata + + + Unpack a catalog + Scompatta un catalogo + + + All the selected comics will be deleted from your disk. Are you sure? + Tutti i fumetti selezionati saranno cancellati dal tuo disco. Sei sicuro? + + + Download tags from Comic Vine + Scarica i Tag da Comic Vine + + + Remove comics + Rimuovi i fumetti + + + Add a new label to this library + Aggiungi una nuova etichetta a questa libreria + + + Set as unread + Setta come non letto + + + Library not found + Libreria non trovata + + + Rename library + Rinomina la libreria + + + Remove library + Rimuovi la libreria + + + Open containing folder... + Apri la cartella dei contenuti... + + + Add new label + Aggiungi una nuova etichetta + + + Unable to delete + Non posso cancellare + + + library? + Libreria? + + + Save covers of the selected comics as JPG files + Salva le copertine dei fumetti selezionati come file JPG + + + Are you sure? + Sei sicuro? + + + Set as manga + + + + Set issue as manga + + + + Set as normal + + + + Set issue as normal + + + + Set as comic + + + + Upgrade failed + + + + There were errors during library upgrade in: + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + + + + + LocalComicListModel + + file name + Nome file + + + + LogWindow + + Log window + + + + &Pause + + + + &Save + + + + C&lear + + + + &Copy + + + + Level: + + + + &Auto scroll + + + + + NoLibrariesWidget + + create your first library + Crea la tua prima libreria + + + You don't have any libraries yet + Per ora non hai ancora nessuna libreria + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Puoi creare una libreria in qualsiasi cartella, YACReader importerà tutti i fumetti e struttura da questa certella. Se hai creato una qualsiasia libreria nel passato la puoi aprire. </p><p>Non dimenticare che puoi usare YACReader come applicazione stand alone per leggere i fumetti sul tuo PC.</p> + + + add an existing one + Aggiungine una esistente + + + + OptionsDialog + + Restore defautls + Resetta al Default + + + Background + Sfondo + + + Blur level + Livello di sfumatura + + + Enable background image + Abilita l'immagine di sfondo + + + Options + Opzioni + + + Comic Vine API key + API di ComicVine + + + Edit Comic Vine API key + Edita l'API di ComicVine + + + Opacity level + Livello di opacità + + + General + Generale + + + Use selected comic cover as background + Usa la cover del fumetto selezionato come sfondo + + + Comic Flow + Flusso dei fumetti + + + Grid view + Vista a Griglia + + + Tray icon settings (experimental) + + + + Close to tray + + + + Start into the system tray + + + + Display continue reading banner + + + + Continue reading + + + + + PropertiesDialog + + Day: + Giorno: + + + Plot + Trama + + + Size: + Dimesioni: + + + Year: + Anno: + + + Inker(s): + Inchiostratore(i): + + + Publishing + Pubblicazione + + + Publisher: + Editore: + + + General info + Informazioni generali + + + Color/BW: + Colore o B/N: + + + Edit selected comics information + Edita le informazioni del fumetto selezionato + + + Penciller(s): + Mine: + + + Colorist(s): + Colorista(i): + + + Genre: + Genere: + + + Issue number: + Numeri emessi: + + + Month: + Mese: + + + Notes: + Note: + + + Synopsis: + Sinossi: + + + Title: + Titolo: + + + Not found + Non trovato + + + Characters: + Personaggi: + + + Authors + Autori + + + Age rating: + Valutazione età: + + + Story arc: + Arco Narrativo: + + + Writer(s): + Scrittore(i): + + + Comic not found. You should update your library. + Fumetto non trovato, dovresti aggiornare la Libreria. + + + Edit comic information + Edita le informazioni del fumetto + + + Cover page + Pagina Copertina + + + Cover Artist(s): + Artista(i) copertina: + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Vai </a> + + + Volume: + Album: + + + Format: + Formato: + + + Letterer(s): + Letterista(i): + + + of: + + + + Arc number: + + + + Manga: + + + + + QObject + + 7z lib not found + Libreria 7z non trovata + + + unable to load 7z lib from ./utils + Impossibile caricare la libreria 7z da ./utils + + + Trace + + + + Debug + + + + Info + + + + Warning + + + + Error + + + + Fatal + + + + + QsLogging::LogWindowModel + + Time + + + + Level + + + + Message + + + + + QsLogging::Window + + &Pause + + + + &Resume + + + + Save log + + + + Log file (*.log) + + + + + RenameLibraryDialog + + Rename current library + Rinomina la libreria corrente + + + Cancel + Cancella + + + Rename + Rinomina + + + New Library Name : + Nome della nuova libreria: + + + + ScraperResultsPaginator + + Number of %1 found : %2 + Numero di %1 trovati; %2 + + + page %1 of %2 + pagina %1 di %2 + + + Number of volumes found : %1 + Numero di volumi trovati: %1 + + + + SearchSingleComic + + Please provide some additional information. + Per favore aggiugi informazioni addizionali. + + + Series: + Serie: + + + + SearchVolume + + Please provide some additional information. + Per favore aggiugi informazioni addizionali. + + + Series: + Serie: + + + + SelectComic + + loading description + Caricamento descrizione + + + comics + Fumetti + + + loading cover + Caricamento copertine + + + Please, select the right comic info. + Per favore seleziona le informazioni corrette per il fumetto. + + + description unavailable + Descrizione non disponibile + + + + SelectVolume + + loading description + Caricamento descrizione + + + Please, select the right series for your comic. + Per favore seleziona la serie corretta per il fumetto. + + + loading cover + Caricamento copertine + + + volumes + Volumi + + + description unavailable + Descrizione non disponibile + + + + SeriesQuestion + + no + No + + + yes + Si + + + You are trying to get information for various comics at once, are they part of the same series? + Stai cercando di recuperare informazioni per diversi fumetti in una sola volta, sono parte della stessa serie? + + + + ServerConfigDialog + + Port + Porta + + + YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> + YACReader è disponibile per dispositivi iOS. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Provalo! </a> + + + enable the server + Abilita il server + + + Server connectivity information + Informazioni sulla connettività del server + + + display less information about folders in the browser +to improve the performance + Mostra meno informazioni sulle cartelle nel Browser. +Migliora le prestazioni! + + + Scan it! + Scansiona! + + + QR generator error! + Errore nel generatore QR! + + + set port + Configura porta + + + Choose an IP address + Scegli un indirizzo IP + + + Could not load libqrencode. + + + + + SortVolumeComics + + remove selected comics + Rimuovi i fumetti selezionati + + + sort comics to match comic information + Ordina i fumetti per far corrispondere le informazioni + + + restore all removed comics + Ripristina tutti i fumetti rimossi + + + issues + Emissione + + + Please, sort the list of comics on the left until it matches the comics' information. + Per favore ordina la lista dei fumetti a sinistra sino a che corrisponde alle informazioni dei fumetti. + + + restore removed comics + Ripristina i fumetti rimossi + + + + TitleHeader + + SEARCH + CERCA + + + + UpdateLibraryDialog + + Update library + Aggiorna Libreria + + + Cancel + Cancella + + + Updating.... + Aggiornamento... + + + + VolumeComicsModel + + title + Titolo + + + + VolumesModel + + year + Anno + + + issues + Emissione + + + publisher + Pubblicato da + + + + YACReader::TrayIconController + + &Restore + + + + &Quit + + + + Systray + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + + + + + YACReader::WhatsNewDialog + + Close + + + + + YACReaderDeletingProgress + + cancel + Cancella + + + Please wait, deleting in progress... + Aspetta, cancellazione in corso... + + + + YACReaderFieldEdit + + Restore to default + Resetta al Default + + + Click to overwrite + Clikka per sovrascrivere + + + + YACReaderFieldPlainTextEdit + + Restore to default + Resetta al Default + + + Click to overwrite + Clikka per sovrascrivere + + + + YACReaderFlowConfigWidget + + CoverFlow look + Aspetto del flusso copertine + + + How to show covers: + Come mostrare le copertine: + + + Stripe look + Aspetto a striscia + + + Overlapped Stripe look + Aspetto a striscia sovrapposta + + + + YACReaderGLFlowConfigWidget + + Zoom + Zoom + + + Light + Luminoso + + + Show advanced settings + Mostra le impostazioni avanzate + + + Roulette look + Aspetto a Roulette + + + Cover Angle + Angolo copertine + + + Stripe look + Aspetto a striscia + + + Position + Posizione + + + Z offset + Traslazione Z + + + Y offset + Traslazione Y + + + Central gap + Distanza centrale + + + Presets: + Preselezione: + + + Overlapped Stripe look + Aspetto a Striscia sovrapposto + + + Modern look + Aspetto moderno + + + View angle + Vista ad Angolo + + + Max angle + Angolo massimo + + + Custom: + Personalizza: + + + Classic look + Aspetto Classico + + + Cover gap + Distanza tra le Cover + + + High Performance + Alte Prestazioni + + + Performance: + Prestazioni: + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + UIsa VSync. (Migliora la qualità dell'immagine a modalità tutto schermo, peggiora le prestazioni) + + + Visibility + Visibilità + + + Low Performance + Basse Prestazioni + + + + YACReaderNavigationController + + You are not reading anything yet, come on!! + Non stai ancora leggendo nulla, Forza!! + + + No favorites + Nessun Favorito + + + + YACReaderOptionsDialog + + Save + Salva + + + Use hardware acceleration (restart needed) + Usa accelerazione hardware (necessita riavvio) + + + Cancel + Cancella + + + Shortcuts + Scorciatoie + + + Edit shortcuts + Modifica scorciatoia + + + + YACReaderSearchLineEdit + + type to search + Digita per cercare + + + + YACReaderSideBar + + Reading Lists + Lista di lettura + + + LIBRARIES + LIBRERIE + + + Libraries + Librerie + + + FOLDERS + CARTELLE + + + Folders + Cartelle + + + READING LISTS + LISTA DI LETTURA + + + diff --git a/YACReaderLibrary/yacreaderlibrary_nl.ts b/YACReaderLibrary/yacreaderlibrary_nl.ts index 409b53757..527c563ee 100644 --- a/YACReaderLibrary/yacreaderlibrary_nl.ts +++ b/YACReaderLibrary/yacreaderlibrary_nl.ts @@ -1,2188 +1,1827 @@ - + ActionsShortcutsModel - None - Geen + AddLabelDialog - + cancel + annuleren + + Label name: - Labelnaam: + - Choose a color: - Kies een kleur: + - red - rood + - orange - oranje + - yellow - geel + - green - groen + - cyan - groenblauw + - blue - blauw + - violet - violet + - purple - paars + - pink - roze + - white - wit + - light - licht + - dark - donker + - accept - toepassen - - - - cancel - annuleren + AddLibraryDialog - - Comics folder : - Stripsmap: - - - - Library name : - Library Name : - Bibliotheeknaam: - - - Add Toevoegen - + Add an existing library + Voeg een bestaand bibliotheek toe + + Cancel Annuleren - - Add an existing library - Voeg een bestaande bibliotheek toe + Comics folder : + Strips map: + + + Library name : + Bibliotheek Naam : ApiKeyDialog - + Cancel + Annuleren + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Om te verbinden met Comic Vine heb je je eigen api-sleutel nodig - die kun je <a href="http://www.comicvine.com/api/">hier</a> gratis genereren. + - Paste here your Comic Vine API key - Plak hier de api-sleutel + - Accept - Verbinden - - - - Cancel - Annuleren + ClassicComicsView - Hide comic flow - Omslagverkenner verbergen + Sluit de Omslagbrowser ComicInfoView - Authors Auteurs - writer - schrijver + - penciller - tekenaar + - inker - inkter + - colorist - inkleurder + - letterer - letteraar + - cover artist - omslagartiest + - Publisher - Uitgever + - color - kleur + - b/w - z/w + - Characters - Tekens + ComicModel - - yes - ja + no + neen - - no - nee + yes + Ja - - Title - Titel + Read + Gelezen - - File Name - Bestandsnaam + Size + Grootte(MB) - Pages Pagina's - - Size - Grootte + Title + Titel - - Read - Gelezen + File Name + Bestandsnaam - Current Page - Huidige pagina + - Rating - Beoordeling + ComicVineDialog - skip - overslaan + - back - vorige + - next - volgende + - search - zoeken + - close - sluiten + - - - - - Looking for volume... - Bezig met zoeken... + - - comic %1 of %2 - %3 - strip %1 van %2 - %3 + - %1 comics selected - %1 strips geselecteerd + - Error connecting to ComicVine - Kan niet verbinden met ComicVine + - - Retrieving tags for : %1 - Bezig met ophalen van tags voor %1... + - Retrieving volume info... - Bezig met ophalen van informatie... + - Looking for comic... - Bezig met zoeken naar strip... + CreateLibraryDialog - - Comics folder : - Stripsmap: + Create new library + Een nieuwe Bibliotheek aanmaken - - Library Name : - Bibliotheeknaam: + Cancel + Annuleren - Create Aanmaken - - Cancel - Annuleren + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Een bibliotheek aanmaken kan enkele minuten duren. U kunt het proces stoppen en de bibliotheek later voltooien. - - Create a library could take several minutes. You can stop the process and update the library later for completing the task. - Het aanmaken van een bibliotheek kan enkele minuten duren. Je kunt het proces afbreken en de bibliotheek later voltooien. + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + De geselecteerde pad bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map - - Create new library - Bibliotheek aanmaken + Comics folder : + Strips map: - - Path not found - Pad niet aangetroffen + Library Name : + Bibliotheek Naam : - - The selected path does not exist or is not a valid path. Be sure that you have write access to this folder - Het gekozen pad bestaat niet of is ongeldig. Controleer of je schrijftoegang hebt op deze map. + Path not found + Pad niet gevonden EditShortcutsDialog - Restore defaults - Standaardwaarden herstellen + - To change a shortcut, double click in the key combination and type the new keys. - Dubbelklik op de toetscombinatie en dan op de nieuwe toetsen om de sneltoets te wijzigen. + - Shortcuts settings - Sneltoetsinstellingen + - Shortcut in use - Sneltoets is in gebruik + - The shortcut "%1" is already assigned to other function - De sneltoets '%1' is al toegewezen aan een andere functie + EmptyFolderWidget - - Subfolders in this folder - Onderliggende mappen in deze map + - Empty folder - Lege map + - Drag and drop folders and comics here - Sleep mappen en strips hierheen + EmptyLabelWidget - This label doesn't contain comics yet - Dit label bevat nog geen strips + EmptyReadingListWidget - This reading list does not contain any comics yet - This reading list doesn't contain comics yet - Deze leeslijst bevat nog geen strips + ExportComicsInfoDialog - Output file : - Uitvoerbestand: + Uitvoerbestand: - - Create - Aanmaken + Destination database name + Bestemmingsdatabase naam - Cancel Annuleren - - Export comics info - Stripinformatie exporteren + Create + Aanmaken - - Destination database name - Naam van bestemmingsdatabank + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Het gekozen pad voor het uitvoerbestand bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map - - Problem found while writing - Probleem bij het wegschrijven + Export comics info + Strip info exporteren - - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Het gekozen pad voor het uitvoerbestand bestaat niet of is ongeldig. Controleer of je schrijftoegang hebt op deze map. + Problem found while writing + Probleem bij het schrijven ExportLibraryDialog - - Output folder : - Uitvoermap: + Cancel + Annuleren - Create Aanmaken - - Cancel - Annuleren + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Het gekozen pad voor het uitvoerbestand bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map - - Create covers package - Omslagpakket samenstellen + Output folder : + Uitvoermap : - Problem found while writing - Probleem bij het wegschrijven + Probleem bij het schrijven - - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Het gekozen pad voor het uitvoerbestand bestaat niet of is ongeldig. Controleer of je schrijftoegang hebt op deze map. + Create covers package + Aanmaken omslag pakket - Destination directory - Bestemmingsmap + Doeldirectory FileComic - - Unknown error opening the file - Onbekende fout tijdens openen van bestand + 7z not found + 7Z Archiefbestand niet gevonden - - 7z not found - 7z is niet aangetroffen + CRC error on page (%1): some of the pages will not be displayed correctly + - - Format not supported - Dit formaat wordt niet ondersteund + Unknown error opening the file + - - CRC error on page (%1): some of the pages will not be displayed correctly - CRC-fout op pagina (%1): sommige pagina's worden niet goed getoond + Format not supported + GridComicsView - Show info - Informatie tonen + HelpAboutDialog - - About - Over + Help + Help - - Help - Hulp + About + Over ImportComicsInfoDialog - - Import comics info - Stripinformatie importeren - - - - Info database location : - Locatie van informatiedatabank: + Cancel + Annuleren - Import Importeren - - Cancel - Annuleren + Info database location : + Info database locatie : + + + Import comics info + Strip info Importeren - Comics info file (*.ydb) - Stripinformatiebestand ( * .ydb) + Strips info bestand ( * .ydb) ImportLibraryDialog - - Library Name : - Bibliotheeknaam: - - - - Package location : - Pakketlocatie: + Destination folder : + Doelmap: - - Destination folder : - Bestemmingsmap: + Cancel + Annuleren - Unpack Uitpakken - - Cancel - Annuleren + Compresed library covers (*.clc) + Compresed omslag- bibliotheek ( * .clc) - - Extract a catalog - Catalogus uitpakken + Package location : + Arrangement locatie : - - Compresed library covers (*.clc) - Ingepakte bibliotheekomslagen ( * .clc) + Library Name : + Bibliotheek Naam : + + + Extract a catalog + Een catalogus uitpakken ImportWidget - stop - afbreken - - - - Some of the comics being added... - Bezig met toevoegen van enkele strips... + stop - Importing comics - Bezig met importeren + Strips importeren - <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - <p>YACReaderLibrary maakt een nieuwe bibliotheek aan.</p><p>Dit kan enkele minuten duren. Je kunt het proces afbreken en de bibliotheek later nog bijwerken.</p> + <P>YACReaderLibrary maak nu een nieuwe bibliotheek. < /p> <p>Een bibliotheek aanmaken kan enkele minuten duren. U kunt het proces stoppen en de bibliotheek later voltooien. < /p> + + + Some of the comics being added... + Enkele strips zijn toegevoegd ... - Updating the library - Bezig met bijwerken + Actualisering van de bibliotheek - <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> - <p>De huidige bibliotheek wordt bijgewerkt. Als je dit proces wilt bespoedigen, werk je bibliotheek dan regelmatig bij.</p><p>Je kunt het proces afbreken en later bijwerken.</p> + <P>De huidige bibliotheek wordt bijgewerkt. Voor snellere updates, update uw bibliotheken regelmatig. < /p> <p>u kunt het proces stoppen om later bij te werken. < /p> - Upgrading the library - Bezig met opwaarderen + - <p>The current library is being upgraded, please wait.</p> - <p>De huidige bibliotheek wordt opgewaardeerd - even geduld...</p> + LibraryWindow - - YACReader Library - YACReader-bibliotheek - - - - Library - Bibliotheek - - - <font color='white'> press 'F' to close fullscreen mode </font> - <font color='white'>Druk op "F" om 'volledig scherm modus' te sluiten </font> + Edit + Bewerken - - Create a new library - Bibliotheek aanmaken + The selected folder doesn't contain any library. + De geselecteerde map bevat geen bibliotheek. - - Open an existing library - Bestaande bibliotheek openen + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Deze bibliotheek is gemaakt met een vorige versie van YACReaderLibrary. Het moet worden bijgewerkt. Nu bijwerken? - - - Export comics info - Stripinformatie exporteren + Error opening the library + Fout bij openen Bibliotheek - - - Import comics info - Stripinformatie importeren + Show/Hide marks + Toon/Verberg markeringen - - Pack covers - Omslagen inpakken + Show comics server options dialog + Toon strips-server opties dialoog - - Pack the covers of the selected library - Pak de omslagen van de geselecteerde bibliotheek in + Remove current library from your collection + De huidige Bibliotheek verwijderen uit uw verzameling - - Unpack covers - Omslagen uitpakken + Set comic as read + Strip Instellen als gelezen - - Unpack a catalog - Catalogus uitpakken + Remove and delete metadata + Verwijder metagegevens - - Update library - Bibliotheek bijwerken + Old library + Oude Bibliotheek - - Update current library - Huidige bibliotheek bijwerken + Update cover + Strip omslagen bijwerken - - Rename library - Bibliotheeknaam wijzigen + Library + Bibliotheek - Rename current library - Huidige bibliotheeknaam wijzigen - - - - Remove library - Bibliotheek verwijderen + Huidige Bibliotheek hernoemen - - Remove current library from your collection - Huidige bibliotheek verwijderen uit je verzameling + Fullscreen mode on/off + Volledig scherm modus aan/of - - Open current comic - Huidige strip openen + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Deze bibliotheek is gemaakt met een nieuwere versie van YACReaderLibrary. Download de nieuwe versie? - Open current comic on YACReader Huidige strip openen in YACReader - - Save selected covers to... - Geselecteerde omslagen opslaan in... + Update current library + Huidige Bibliotheek bijwerken - - Save covers of the selected comics as JPG files - Omslagen opslaan als jpg-bestanden + Library '%1' is no longer available. Do you want to remove it? + Bibliotheek ' %1' is niet langer beschikbaar. Wilt u het verwijderen? - - - Set as read - Markeren als gelezen + Update library + Bibliotheek bijwerken - - Set comic as read - Strip markeren als gelezen + Open folder... + Map openen ... - - - Set as unread - Markeren als ongelezen + Do you want remove + Wilt u verwijderen - - Set comic as unread - Strip markeren als ongelezen + Error updating the library + Fout bij bijwerken Bibliotheek - - Show/Hide marks - Markeringen tonen/verbergen + Expand all nodes + Alle categorieën uitklappen - Show or hide readed marks - Toon of Verberg gelezen markeringen + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Bibliotheek ' %1' is gemaakt met een oudere versie van YACReaderLibrary. Zij moet opnieuw worden aangemaakt. Wilt u de bibliotheek nu aanmaken? - - Library not available - Library ' - Bibliotheek niet beschikbaar + Pack covers + Inpakken strip voorbladen - - - Fullscreen mode on/off - Beeldvullende modus aan/uit + Set as read + Instellen als gelezen - Fullscreen mode on/off (F) - Volledig scherm modus aan/of (F) + Delete selected comics + Geselecteerde strips verwijderen - - Help, About YACReader - Hulp, Over YACReader + Export comics info + Exporteren van strip info - - Select root node - Kies de hoofdcategorie + Show options dialog + Toon opties dialoog - + - + + Create a new library + Maak een nieuwe Bibliotheek - - Expand all nodes - Alle categorieën uitklappen + Library not available + Bibliotheek niet beschikbaar - - - - + Import comics info + Importeren van strip info - Colapse all nodes - Alle categorieën inklappen + Open current comic + Huidige strip openen - - Show options dialog - Toon het optievenster + YACReader Library + YACReader Bibliotheek - - Show comics server options dialog - Toon het strips-serveroptiesvenster + Error creating the library + Fout bij aanmaken Bibliotheek - - Open folder... - Map openen... + Unpack covers + Uitpakken voorbladen - - Set as uncompleted - Markeren als nog niet uitgelezen + Update needed + Bijwerken is nodig - - Set as completed - Markeren als uitgelezen + Open an existing library + Open een bestaande Bibliotheek - - Open containing folder... - Bijbehorende map openen... + Library name already exists + Bibliotheek naam bestaat al - - Reset comic rating - Beoordeling herstellen + There is another library with the name '%1'. + Er is al een bibliotheek met de naam ' %1 '. - - Select all comics - Alle strips selecteren + Download new version + Nieuwe versie ophalen - - Edit - Bewerken + Delete comics + Strips verwijderen - Asign current order to comics - Nummeren van strips + Select all comics + Selecteer alle strips - - Update cover - Omslag bijwerken + Pack the covers of the selected library + Inpakken alle strip voorbladen van de geselecteerde Bibliotheek - - Delete selected comics - Geselecteerde strips verwijderen + Help, About YACReader + Help, Over YACReader - Hide comic flow - Sluit de Omslagbrowser + Set comic as unread + Strip Instellen als ongelezen - - Download tags from Comic Vine - Labels ophalen van Comic Vine + Select root node + Selecteer de hoofd categorie - - Edit shortcuts - Sneltoetsen aanpassen + Unpack a catalog + Uitpaken van een catalogus - - Update folder - Map bijwerken + All the selected comics will be deleted from your disk. Are you sure? + Alle geselecteerde strips worden verwijderd van uw schijf. Weet u het zeker? - - Update current folder - Huidige map bijwerken + Set as unread + Instellen als ongelezen - - Add new reading list - Leeslijst toevoegen + Library not found + Bibliotheek niet gevonden - - Add a new reading list to the current library - Voeg een nieuwe leeslijst toe aan de huidige bibliotheek + Rename library + Bibliotheek hernoemen - - Remove reading list - Leeslijst verwijderen + Remove library + Bibliotheek verwijderen - - Remove current reading list from the library - Verwijder de huidige leeslijst uit de bibliotheek + Open containing folder... + Open map ... - - Add new label - Label toevoegen + library? + Bibliotheek? - - Add a new label to this library - Voeg een label toe aan deze bibliotheek + Are you sure? + Weet u het zeker? - - Rename selected list - Lijstnaam wijzigen + Save selected covers to... + - - Rename any selected labels or lists - Label- of lijstnamen wijzigen + Save covers of the selected comics as JPG files + - - Add to... - Toevoegen aan... + Set as manga + - - Favorites - Favorieten + Set issue as manga + - - Add selected comics to favorites list - Voeg de geselecteerde strips toe aan je favorieten + Set as normal + - - Folder - Map + Set issue as normal + - - Comic - Strip + Show or hide read marks + - - Upgrade failed - Opwaarderen mislukt + Add new folder + - - There were errors during library upgrade in: - Er zijn fouten opgetreden tijdens het opwaarderen van de bibliotheek: + Add new folder to the current library + - - Update needed - Bijwerken benodigd + Delete folder + - - This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - Deze bibliotheek is gemaakt met een vorige versie van YACReaderLibrary en moet worden bijgewerkt. Wil je dat nu doen? + Delete current folder from disk + - Update failed - Bijwerken mislukt + Collapse all nodes + - The current library can't be udpated. Check for write write permissions on: - De huidige bibliotheek kan niet worden bijgewerkt. Controleer bij of u schrijfbevoegdheid hebt: + Change between comics views + - - Download new version - Nieuwe versie ophalen + Set as uncompleted + - - This library was created with a newer version of YACReaderLibrary. Download the new version now? - Deze bibliotheek is gemaakt met een nieuwere versie van YACReaderLibrary. Wil je de nieuwe versie ophalen? + Set as completed + - - Library '%1' is no longer available. Do you want to remove it? - De bibliotheek ' %1' is niet meer beschikbaar. Wil je deze verwijderen? + Set as comic + - - Old library - Oude bibliotheek + Reset comic rating + - - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - De bibliotheek '%1' is gemaakt met een oudere versie van YACReaderLibrary en moet opnieuw worden aangemaakt. Wil je dat nu doen? + Assign current order to comics + - - - Copying comics... - Bezig met kopiëren van strips... + Download tags from Comic Vine + - - - Moving comics... - Bezig met verplaatsen van scripts... + Edit shortcuts + - - Folder name: - Mapnaam: + Update folder + - - No folder selected - Geen map geselecteerd + Update current folder + - - Please, select a folder first - Selecteer een map + Add new reading list + - - Error in path - Fout in pad + Add a new reading list to the current library + - - There was an error accessing the folder's path - Er is een fout in het mappad + Remove reading list + - - The selected folder and all its contents will be deleted from your disk. Are you sure? - De geselecteerde map en alle inhoud ervan wordt verwijderd van je schijf. Weet je het zeker? + Remove current reading list from the library + - - There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - Er is een fout opgetreden tijdens het verwijderen van de geselecteerde mappen. Controleer of je schrijfrechten hebt en of ze niet in gebruik zijn door andere programma's. + Add new label + - - Add new reading lists - Leeslijsten toevoegen + Add a new label to this library + - - - List name: - Lijstnaam: + Rename selected list + - - Delete list/label - Lijst/Label verwijderen + Rename any selected labels or lists + - - The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - Het geselecteerde item wordt verwijderd, maar je strips en mappen niet. Weet je het zeker? + Add to... + - - Rename list name - Lijstnaam wijzigen + Favorites + - - Save covers - Omslagen opslaan + Add selected comics to favorites list + - - You are adding too many libraries. - Je voegt te veel bibliotheken toe. + Folder + - - You are adding too many libraries. - -You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. - -YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - Je voegt te veel bibliotheken toe. - -Waarschijnlijk heb je slechts één bibliotheek nodig in de hoofdmap van je strips. Je kunt onderliggende mappen verkennen in de mappensectie in de linkerzijbalk.. - -YACReaderLibrary weerhoudt je er niet van meerdere bibliotheken aan te maken, maar maak er niet te veel aan. + Comic + - - - YACReader not found - YACReader is niet aangetroffen + Upgrade failed + - - Library not found - De bibliotheek is niet aangetroffen + There were errors during library upgrade in: + - - The selected folder doesn't contain any library. - De geselecteerde map bevat geen bibliotheek. + Copying comics... + - - Are you sure? - Weet je het zeker? + Moving comics... + - - Do you want remove - Wil je de + Folder name: + - - library? - bibliotheek verwijderen? + No folder selected + - - Remove and delete metadata - Verwijderen, inclusief metagegevens + Please, select a folder first + - - Assign comics numbers - Stripnummers toekennen + Error in path + - - Assign numbers starting in: - Toekennen vanaf: + There was an error accessing the folder's path + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + - - Unable to delete - Verwijderen mislukt + - - Show or hide read marks - Leesmarkeringen tonen/verbergen + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + - - - Add new folder - Map toevoegen + Add new reading lists + - - Add new folder to the current library - Voeg een nieuwe map toe aan de huidige bibliotheek + List name: + - - - Delete folder - Map verwijderen + Delete list/label + - - Delete current folder from disk - Verwijder de huidige map van de schijf + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + - - Collapse all nodes - Alles inklappen + Rename list name + - - - Change between comics views - Andere stripweergave + Save covers + - - Assign current order to comics - Huidige volgorde toepassen op strips + You are adding too many libraries. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + + + + YACReader not found + - YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - YACReader is niet aangetroffen. YACReader dient te worden geïnstalleerd in dezelfde map als YACReaderLibrary. + - YACReader not found. There might be a problem with your YACReader installation. - YACReader is niet aangetroffen. Mogelijk is er een probleem met je YACReader-installatie. + - There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - Er is een probleem opgetreden tijdens het verwijderen. Controleer of je schrijfrechten hebt op de geselecteerde bestanden en bijbehorende map. + - Asign comics numbers - Strips nummeren + Assign comics numbers + - Asign numbers starting in: - Strips nummeren beginnen bij: + Assign numbers starting in: + - - Error creating the library - Fout bij aanmaken van bibliotheek + Remove comics + - - Error updating the library - Fout bij bijwerken van bibliotheek + Comics will only be deleted from the current label/list. Are you sure? + + + + LocalComicListModel - - Error opening the library - Fout bij openen van bibliotheek + file name + + + + LogWindow - - Delete comics - Strips verwijderen + Log window + - - All the selected comics will be deleted from your disk. Are you sure? - Alle geselecteerde strips worden verwijderd van de schijf. Weet je het zeker? + &Pause + - - Remove comics - Strips verwijderen + &Save + - - Comics will only be deleted from the current label/list. Are you sure? - De strips worden alleen verwijderd het huidige label/de huidige lijst. Weet je het zeker? + C&lear + - - Library name already exists - Bibliotheeknaam is al in gebruik + &Copy + - - There is another library with the name '%1'. - Er is al een bibliotheek met de naam '%1'. + Level: + - - - LocalComicListModel - - file name - bestandsnaam + &Auto scroll + NoLibrariesWidget - - You don't have any libraries yet - Je hebt nog geen nog bibliotheken + create your first library + Maak uw eerste bibliotheek - - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> - <p>Je kunt een bibliotheek maken in een willekeurige map - YACReaderLibrary importeert alle strips en mappen uit deze map. Je kunt alle eerder gemaakte bibliotheken openen.</p><p>Je kunt YACReader gebruiken als losstaand programma voor het lezen van strips.</p> + You don't have any libraries yet + Je hebt geen nog libraries - - create your first library - Maak je eerste bibliotheek + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <P>u kunt een bibliotheek maken in een willekeurige map, YACReaderLibrary importeert alle strips en mappen uit deze map. Alle bibliotheek aangemaakt in het verleden kan je openen. < /p> <p>vergeet niet dat u YACReader kan gebruiken als stand-alone applicatie voor het lezen van de strips op de computer. < /p> - add an existing one - Voeg een bestaande bibliotheek toe + voeg een bestaande bibliotheek toe OptionsDialog - + Options + Opties + + + Tray icon settings (experimental) + + + + Close to tray + + + + Start into the system tray + + + Edit Comic Vine API key - Comic Vine-api-sleutel aanpassen + - Comic Vine API key - Comic Vine-api-sleutel + - Enable background image - Achtergrondafbeelding gebruiken + - Opacity level - Doorzichtigheidsniveau + - Blur level - Vervaagintensiteit + - Use selected comic cover as background - Geselecteerde omslag instellen als achtergrond + - Restore defautls - Standaardwaarden herstellen + - Background - Achtergrond + + + + Display continue reading banner + + + + Continue reading + - Comic Flow - Omslagverkenner + - Grid view - Roosterweergave + - General - Algemeen - - - - Options - Opties + PropertiesDialog - - General info - Algemene informatie + Day: + Dag: - - Authors - Auteurs + Plot + Verhaal - - Publishing - Uitgever + Size: + Grootte(MB): - - Plot - Verhaal + Year: + Jaar: - - Cover page - Omslagpagina + Inker(s): + Inker(s): - - Title: - Titel: + Publishing + Uitgever - - - of: - van: + Publisher: + Uitgever: - - Issue number: - Uitgavenummer: + General info + Algemene Info - - Volume: - Inhoud: + Color/BW: + Kleur/ZW: - - Arc number: - Verhaallijnnummer: + Edit selected comics information + Geselecteerde strip informatie bijwerken - - Story arc: - Verhaallijn: + Penciller(s): + Tekenaar(s): + + + Colorist(s): + Inkleurder(s): - Genre: - Genere: Genre: - - Size: - Grootte: + Issue number: + Ids: - - Writer(s): - Schrijver(s): + Month: + Maand: - - Penciller(s): - Tekenaar(s): + Notes: + Opmerkingen: - - Inker(s): - Inkter(s): + Synopsis: + Synopsis: - - Colorist(s): - Inkleurder(s): + Title: + Titel: - - Letterer(s): - Letterzetter(s): + Not found + Niet gevonden - - Cover Artist(s): - Omslagartiest(en): + Characters: + Personages: - - Day: - Dag: + Authors + Auteurs - - Month: - Maand: + Age rating: + Leeftijdsbeperking: - - Year: - Jaar: + Story arc: + Verhaallijn: - - Publisher: - Uitgever: + Writer(s): + Schrijver(s): - - Format: - Formaat: + Comic not found. You should update your library. + Strip niet gevonden. U moet uw bibliotheek.bijwerken. - - Color/BW: - Kleur/ZW: + Edit comic information + Strip informatie bijwerken - - Age rating: - Leeftijdsbeperking: + Cover page + Omslag - - Synopsis: - Synopsis: + Cover Artist(s): + Omslag ontwikkelaar(s): - - Characters: - Personages: + Volume: + Inhoud: - - Notes: - Opmerkingen: + Format: + Formaat: - - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine-link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> bekijken </a> + Letterer(s): + Letterzetter(s): - - Not found - Niet gevonden + of: + - - Comic not found. You should update your library. - Strip niet gevonden. Werk je bibliotheek bij. + Arc number: + - - Edit selected comics information - Geselecteerde stripinformatie bijwerken + Manga: + - - Edit comic information - Stripinformatie bijwerken + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + QObject - 7z lib not found - 7z-bibliotheek niet aangetroffen + - unable to load 7z lib from ./utils - De 7z-bibliotheek kan niet worden geladen uit ./utils + + + + Trace + + + + Debug + + + + Info + + + + Warning + + + + Error + + + + Fatal + - RenameLibraryDialog + QsLogging::LogWindowModel - - New Library Name : - Nieuwe bibliotheeknaam: + Time + - - Rename - Naam wijzigen + Level + + + + Message + + + + + QsLogging::Window + + &Pause + + + + &Resume + + + + Save log + + + + Log file (*.log) + + + + + RenameLibraryDialog + + Rename current library + Hernoem de huidige bibiliotheek - Cancel Annuleren - - Rename current library - Wijzig de naam van de huidige bibiliotheek + Rename + Hernoem + + + New Library Name : + Nieuwe Bibliotheek Naam : ScraperResultsPaginator - Number of volumes found : %1 - Aantal aangetroffen delen: %1 + - - page %1 of %2 - pagina %1 van %2 + - Number of %1 found : %2 - Aantal gevonden %1: %2 + SearchSingleComic - Please provide some additional information. - Voer aanvullende informatie in. + - Series: - Serie: + SearchVolume - Please provide some additional information. - Voer aanvullende informatie in. + - Series: - Serie: + SelectComic - Please, select the right comic info. - Kies de juiste stripinformatie. + - comics - strips + - loading cover - bezig met laden van omslag + - loading description - bezig met laden van omschrijving + - description unavailable - geen omschrijving beschikbaar + SelectVolume - Please, select the right series for your comic. - Kies de juiste stripserie. + - volumes - delen + - loading cover - bezig met laden van omslag + - loading description - bezig met laden van omschrijving + - description unavailable - geen omschrijving beschikbaar + SeriesQuestion - - You are trying to get information for various comics at once, are they part of the same series? - Je probeert informatie van verschillende strips tegelijkertijd op te halen. Zijn ze uit dezelfde serie? + no + neen - yes Ja - - no - Nee + You are trying to get information for various comics at once, are they part of the same series? + ServerConfigDialog - - set port - Poort instellen - - - EASY SERVER CONNECTION - GEMAKKELIJKE VERBINDING MET DE SERVER - - - SERVER ADDRESS - SERVERADRES - - - just scan the code with your device!! - Scan de code met uw apparaat! + Port + Poort - YACReader is now available for iOS devices, the best comic reading experience now in your iPad, iPhone or iPod touch. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader is nu beschikbaar voor iOS apparaten, de beste strip leeservaring nu op uw iPad, iPhone of iPod touch. <A href= "http://ios.yacreader.com' style= "color:rgb(193, 148, 65) "> Ontdek het zelf! < /A> + enable the server + De server instellen - IP address - IP-adres + set port + Poort instellen - Server connectivity information - Serververbindingsinformatie + - Scan it! - Scannen! + - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader is beschikbaar op iOS-apparaten. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Bekijk de app! </a> + - Choose an IP address - Kies een ip-adres - - - - Port - Poort - - - - enable the server - server inschakelen + - display less information about folders in the browser to improve the performance - toon minder mapinformatie in de verkenner om de -prestaties te verbeteren + - Could not load libqrencode. - Kan libqrencode niet laden. - - - QR generator error! - QR generator fout! + SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. - Sorteer de striplijst links zodat deze overeenkomt met de stripinformatie. + - sort comics to match comic information - strips sorteren om overeen te komen met stripinformatie + - issues - uitgaven + - remove selected comics - geselecteerde strips verwijderen + - restore all removed comics - alle verwijderde strips herstellen - - - - TableModel - - yes - Ja - - - no - neen - - - Title - Titel - - - File Name - Bestandsnaam - - - Pages - Pagina's - - - Size - Grootte(MB) - - - Read - Gelezen + TitleHeader - SEARCH - ZOEKEN + UpdateLibraryDialog - - Updating.... - Bezic met bijwerken.... + Update library + Bibliotheek bijwerken - Cancel Annuleren - - Update library - Bibliotheek bijwerken + Updating.... + Bijwerken.... VolumeComicsModel - title - titel + VolumesModel - year - jaar + - issues - uitgaven + - publisher - uitgever + - YACReaderDeletingProgress + YACReader::TrayIconController - - Please wait, deleting in progress... - Bezig met verwijderen... + &Restore + + + + &Quit + + + + Systray + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + + + + YACReader::WhatsNewDialog + + Close + + + + + YACReaderDeletingProgress - cancel annuleren + + Please wait, deleting in progress... + Even geduld, verwijderen ... + YACReaderFieldEdit - - - Click to overwrite - Klik hier om te overschrijven - - - Restore to default Standaardwaarden herstellen - - - YACReaderFieldPlainTextEdit - - - - Click to overwrite Klik hier om te overschrijven + + + YACReaderFieldPlainTextEdit - Restore to default Standaardwaarden herstellen + + Click to overwrite + Klik hier om te overschrijven + YACReaderFlowConfigWidget - - How to show covers: - Omslagbladweergave: + CoverFlow look + Omslagbrowser uiterlijk - - CoverFlow look - Vormgeving van omslagverkenner + How to show covers: + Hoe omslagbladen bekijken: - Stripe look - Strepen gebruiken + Brede band - Overlapped Stripe look - Overlappende strepen gebruiken + Overlappende band YACReaderGLFlowConfigWidget - - Presets: - Voorinstellingen: - - - - Classic look - Klassiek - - - - Stripe look - Gestreept + Zoom + Zoom - - Overlapped Stripe look - Overlappend gestreept + Light + Licht - - Modern look - Modern + Show advanced settings + Toon geavanceerde instellingen - Roulette look Roulette - - Show advanced settings - Geavanceerde instellingen tonen - - - - Custom: - Aangepast: + Cover Angle + Omslag hoek - - View angle - Kijkhoek + Stripe look + Brede band - Position Positie - - Cover gap - Ruimte tussen omslagen + Z offset + Z- positie + + + Y offset + Y-positie - Central gap Centrale ruimte - - Zoom - Zoom + Presets: + Voorinstellingen: - - Y offset - Y-positie + Overlapped Stripe look + Overlappende band - - Z offset - Z-positie + Modern look + Modern - - Cover Angle - Omslaghoek + View angle + Kijkhoek - - Visibility - Zichtbaarheid + Max angle + Maximale hoek - - Light - Licht + Custom: + Aangepast: - - Max angle - Maximale hoek + Classic look + Klassiek - - Low Performance - Lage prestaties + Cover gap + Ruimte tss Omslag - High Performance - Hoge prestaties + Hoge Prestaties + + + Performance: + Prestatie: - Use VSync (improve the image quality in fullscreen mode, worse performance) - VSync gebruiken (verbetert de beeldkwaliteit in de beeldvullende modus, maar zorgt voor slechtere prestatie) + Gebruik VSync (verbetering van de beeldkwaliteit in de modus volledig scherm, slechtere prestatie) - - Performance: - Prestaties: + Visibility + Zichtbaarheid + + + Low Performance + Lage Prestaties YACReaderNavigationController - No favorites - Geen favorieten + - You are not reading anything yet, come on!! - Je bent nog niks aan het lezen. Open eens wat! + YACReaderOptionsDialog - Save - Opslaan + Bewaar + + + Use hardware acceleration (restart needed) + Gebruik hardware versnelling (opnieuw opstarten vereist) - Cancel Annuleren - Edit shortcuts - Sneltoetsen aanpassen + - Shortcuts - Sneltoetsen - - - - Use hardware acceleration (restart needed) - Hardwareversnelling gebruiken (herstart vereist) + YACReaderSearchLineEdit - type to search - typ om te zoeken + YACReaderSideBar - - Libraries - Bibliotheken + LIBRARIES + BIBLIOTHEKEN - - Folders - Mappen + FOLDERS + MAPPEN - - Reading Lists - Leeslijsten + Libraries + - - LIBRARIES - BIBLIOTHEKEN + Folders + - - FOLDERS - MAPPEN + Reading Lists + - READING LISTS - LEESLIJSTEN - - - Search folders and comics - Zoeken in mappen en strips + diff --git a/YACReaderLibrary/yacreaderlibrary_pt.ts b/YACReaderLibrary/yacreaderlibrary_pt.ts index aea19095c..f5199410e 100644 --- a/YACReaderLibrary/yacreaderlibrary_pt.ts +++ b/YACReaderLibrary/yacreaderlibrary_pt.ts @@ -4,7 +4,6 @@ ActionsShortcutsModel - None @@ -12,82 +11,66 @@ AddLabelDialog - Label name: - Choose a color: - red - orange - yellow - green - cyan - blue - violet - purple - pink - white - light - dark - accept - cancel @@ -95,59 +78,48 @@ AddLibraryDialog - - Comics folder : - Pasta dos quadrinhos : - - - - Library name : - Library Name : - Nome da Biblioteca : - - - Add Adicionar - + Add an existing library + Adicionar uma biblioteca existente + + Cancel Cancelar - - Add an existing library - Adicionar uma biblioteca existente + Comics folder : + Pasta dos quadrinhos : + + + Library name : + Nome da Biblioteca : ApiKeyDialog - + Cancel + Cancelar + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Paste here your Comic Vine API key - Accept - - - Cancel - Cancelar - ClassicComicsView - Hide comic flow @@ -155,57 +127,46 @@ ComicInfoView - Authors - writer - penciller - inker - colorist - letterer - cover artist - Publisher - color - b/w - Characters @@ -213,47 +174,38 @@ ComicModel - yes - no - Title - File Name - Pages - Size - Read - Current Page - Rating @@ -261,68 +213,50 @@ ComicVineDialog - skip - back - next - search - close - - - - - Looking for volume... - - comic %1 of %2 - %3 - %1 comics selected - Error connecting to ComicVine - - Retrieving tags for : %1 - Retrieving volume info... - Looking for comic... @@ -330,42 +264,34 @@ CreateLibraryDialog - - Comics folder : - Pasta dos quadrinhos : + Create new library + Criar uma nova biblioteca - - Library Name : - Nome da Biblioteca : + Cancel + Cancelar - Create Criar - - Cancel - Cancelar + Comics folder : + Pasta dos quadrinhos : - - Create a library could take several minutes. You can stop the process and update the library later for completing the task. - + Library Name : + Nome da Biblioteca : - - Create new library - Criar uma nova biblioteca + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + - Path not found - The selected path does not exist or is not a valid path. Be sure that you have write access to this folder @@ -373,27 +299,22 @@ EditShortcutsDialog - Restore defaults - To change a shortcut, double click in the key combination and type the new keys. - Shortcuts settings - Shortcut in use - The shortcut "%1" is already assigned to other function @@ -401,18 +322,14 @@ EmptyFolderWidget - - Subfolders in this folder - Empty folder - Drag and drop folders and comics here @@ -420,7 +337,6 @@ EmptyLabelWidget - This label doesn't contain comics yet @@ -428,46 +344,37 @@ EmptyReadingListWidget - This reading list does not contain any comics yet - This reading list doesn't contain comics yet ExportComicsInfoDialog - - Output file : - + Cancel + Cancelar - Create Criar - - Cancel - Cancelar + Output file : + - Export comics info - Destination database name - Problem found while writing - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder @@ -475,68 +382,56 @@ ExportLibraryDialog - - Output folder : - Pasta de saída : + Cancel + Cancelar - Create Criar - - Cancel - Cancelar + Output folder : + Pasta de saída : - Create covers package Criar pacote de capas - + Destination directory + Diretório de destino + + Problem found while writing - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - - - Destination directory - Diretório de destino - FileComic - - Unknown error opening the file - + 7z not found + 7z não encontrado - - 7z not found - 7z não encontrado + CRC error on page (%1): some of the pages will not be displayed correctly + - - Format not supported + Unknown error opening the file - - CRC error on page (%1): some of the pages will not be displayed correctly + Format not supported GridComicsView - Show info @@ -544,12 +439,10 @@ HelpAboutDialog - About - Help @@ -557,27 +450,22 @@ ImportComicsInfoDialog - + Cancel + Cancelar + + Import comics info - Info database location : - Import - - Cancel - Cancelar - - - Comics info file (*.ydb) @@ -585,82 +473,65 @@ ImportLibraryDialog - - Library Name : - Nome da Biblioteca : - - - - Package location : - Local do pacote : - - - Destination folder : Pasta de destino : - - Unpack - Desempacotar - - - Cancel Cancelar - - Extract a catalog - Extrair um catálogo + Unpack + Desempacotar - Compresed library covers (*.clc) Capas da biblioteca compactada (*.clc) + + Package location : + Local do pacote : + + + Library Name : + Nome da Biblioteca : + + + Extract a catalog + Extrair um catálogo + ImportWidget - - Importing comics + stop - - stop + Some of the comics being added... - - Some of the comics being added... + Importing comics - <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - Create a library could take several minutes. You can stop the process and update the library later for completing the task. - Updating the library - <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> - <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later. - Upgrading the library - <p>The current library is being upgraded, please wait.</p> @@ -668,558 +539,402 @@ LibraryWindow - <font color='white'> press 'F' to close fullscreen mode </font> - <font color='white'> pressione 'F' para fechar o modo tela cheia </font> - - - - YACReader Library - Biblioteca YACReader - - - - Create a new library - Criar uma nova biblioteca - - - - Open an existing library - Abrir uma biblioteca existente - - - - - Export comics info - - - - - - Import comics info - - - - - Pack covers - - - - - Pack the covers of the selected library - Pacote de capas da biblioteca selecionada - - - - Unpack covers - - - - - Unpack a catalog - Desempacotar um catálogo - - - - Update current library - Atualizar biblioteca atual + Remove current library from your collection + Remover biblioteca atual da sua coleção - - Rename library - + Library + Biblioteca - Rename current library Renomear biblioteca atual - - Remove current library from your collection - Remover biblioteca atual da sua coleção - - - - Open current comic - - - - Open current comic on YACReader Abrir quadrinho atual no YACReader - - Save selected covers to... - + Update current library + Atualizar biblioteca atual - - Save covers of the selected comics as JPG files - + Open folder... + Abrir pasta... - - - Set as read - + Do you want remove + Você deseja remover - - Set comic as read - + Expand all nodes + Expandir todos - - - Set as unread - + Show options dialog + Mostrar opções - - Set comic as unread - + Create a new library + Criar uma nova biblioteca - - Show/Hide marks - + YACReader Library + Biblioteca YACReader - - - Fullscreen mode on/off - + Open an existing library + Abrir uma biblioteca existente - Fullscreen mode on/off (F) - Modo tela cheia ligar/desligar (F) + Pack the covers of the selected library + Pacote de capas da biblioteca selecionada - Help, About YACReader Ajuda, Sobre o YACReader - Select root node Selecionar raiz - - Expand all nodes - Expandir todos + Unpack a catalog + Desempacotar um catálogo - Colapse all nodes - Contrair todos + Open containing folder... + Abrir a pasta contendo... - - Show options dialog - Mostrar opções + Are you sure? + Você tem certeza? - - Show comics server options dialog + Export comics info - - Open folder... - Abrir pasta... - - - - Set as uncompleted + Import comics info - - Set as completed + Pack covers - - Open containing folder... - Abrir a pasta contendo... - - - - Reset comic rating + Unpack covers - - Select all comics + Update library - - Edit + Rename library - - Update cover + Remove library - - Delete selected comics + Open current comic - - Download tags from Comic Vine + Save selected covers to... - - Folder + Save covers of the selected comics as JPG files - - Comic + Set as read - - Library not available - Library ' + Set comic as read - - Old library + Set as unread - - - YACReader not found + Set comic as unread - - - Unable to delete + Set as manga - - There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Set issue as manga - - Assign comics numbers + Set as normal - - Assign numbers starting in: + Set issue as normal - - Error creating the library + Show/Hide marks - - Error updating the library + Show or hide read marks - - Error opening the library + Fullscreen mode on/off - - Delete comics + Add new folder - - All the selected comics will be deleted from your disk. Are you sure? + Add new folder to the current library - - Remove comics + Delete folder - - Comics will only be deleted from the current label/list. Are you sure? + Delete current folder from disk - - Library name already exists + Collapse all nodes - - There is another library with the name '%1'. + Show comics server options dialog - - Library - Biblioteca + Change between comics views + - - Update library + Set as uncompleted - - Remove library + Set as completed - - Show or hide read marks + Set as comic - - - Add new folder + Reset comic rating - - Add new folder to the current library + Select all comics - - - Delete folder + Edit - - Delete current folder from disk + Assign current order to comics - - Collapse all nodes + Update cover - - - Change between comics views + Delete selected comics - - Assign current order to comics + Download tags from Comic Vine - Edit shortcuts - Update folder - Update current folder - Add new reading list - Add a new reading list to the current library - Remove reading list - Remove current reading list from the library - Add new label - Add a new label to this library - Rename selected list - Rename any selected labels or lists - Add to... - Favorites - Add selected comics to favorites list - + Folder + + + + Comic + + + Upgrade failed - There were errors during library upgrade in: - Update needed - This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - Download new version - This library was created with a newer version of YACReaderLibrary. Download the new version now? - + Library not available + + + Library '%1' is no longer available. Do you want to remove it? - + Old library + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - - Copying comics... - - Moving comics... - Folder name: - No folder selected - Please, select a folder first - Error in path - There was an error accessing the folder's path - The selected folder and all its contents will be deleted from your disk. Are you sure? - + Unable to delete + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - Add new reading lists - - List name: - Delete list/label - The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - Rename list name - Save covers - You are adding too many libraries. - You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. @@ -1228,73 +943,135 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - + YACReader not found + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - YACReader not found. There might be a problem with your YACReader installation. - Library not found - The selected folder doesn't contain any library. - - Are you sure? - Você tem certeza? - - - library? - Remove and delete metadata - - Do you want remove - Você deseja remover + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + + + + Assign comics numbers + + + + Assign numbers starting in: + + + + Error creating the library + + + + Error updating the library + + + + Error opening the library + + + + Delete comics + + + + All the selected comics will be deleted from your disk. Are you sure? + + + + Remove comics + + + + Comics will only be deleted from the current label/list. Are you sure? + + + + Library name already exists + + + + There is another library with the name '%1'. + LocalComicListModel - file name + + LogWindow + + Log window + + + + &Pause + + + + &Save + + + + C&lear + + + + &Copy + + + + Level: + + + + &Auto scroll + + + NoLibrariesWidget - You don't have any libraries yet - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> - create your first library - add an existing one @@ -1302,62 +1079,70 @@ YACReaderLibrary will not stop you from creating more libraries but you should k OptionsDialog - + Tray icon settings (experimental) + + + + Close to tray + + + + Start into the system tray + + + Edit Comic Vine API key - Comic Vine API key - Enable background image - Opacity level - Blur level - Use selected comic cover as background - Restore defautls - Background - + Display continue reading banner + + + + Continue reading + + + Comic Flow - Grid view - General - Options @@ -1365,174 +1150,142 @@ YACReaderLibrary will not stop you from creating more libraries but you should k PropertiesDialog - General info - Authors - Publishing - Plot - Cover page - Title: - - of: - Issue number: - Volume: - Arc number: - Story arc: - Genre: - Genere: - Size: - Writer(s): - Penciller(s): - Inker(s): - Colorist(s): - Letterer(s): - Cover Artist(s): - Day: - Month: - Year: - Publisher: - Format: - Color/BW: - Age rating: - + Manga: + + + Synopsis: - Characters: - Notes: - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Not found - Comic not found. You should update your library. - Edit selected comics information - Edit comic information @@ -1540,54 +1293,102 @@ YACReaderLibrary will not stop you from creating more libraries but you should k QObject - 7z lib not found - unable to load 7z lib from ./utils + + Trace + + + + Debug + + + + Info + + + + Warning + + + + Error + + + + Fatal + + - RenameLibraryDialog + QsLogging::LogWindowModel - - New Library Name : - Novo nome da biblioteca : + Time + - - Rename - Renomear + Level + - - Cancel - Cancelar + Message + + + + QsLogging::Window + + &Pause + + + + &Resume + + + + Save log + + + + Log file (*.log) + + + + + RenameLibraryDialog - Rename current library Renomear biblioteca atual + + Cancel + Cancelar + + + Rename + Renomear + + + New Library Name : + Novo nome da biblioteca : + ScraperResultsPaginator - Number of volumes found : %1 - - page %1 of %2 - Number of %1 found : %2 @@ -1595,12 +1396,10 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SearchSingleComic - Please provide some additional information. - Series: @@ -1608,12 +1407,10 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SearchVolume - Please provide some additional information. - Series: @@ -1621,27 +1418,22 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SelectComic - Please, select the right comic info. - comics - loading cover - loading description - description unavailable @@ -1649,27 +1441,22 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SelectVolume - Please, select the right series for your comic. - volumes - loading cover - loading description - description unavailable @@ -1677,17 +1464,14 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SeriesQuestion - You are trying to get information for various comics at once, are they part of the same series? - yes - no @@ -1695,48 +1479,39 @@ YACReaderLibrary will not stop you from creating more libraries but you should k ServerConfigDialog - set port - Server connectivity information - Scan it! - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - Choose an IP address - Port - enable the server - display less information about folders in the browser to improve the performance - Could not load libqrencode. @@ -1744,27 +1519,22 @@ to improve the performance SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. - sort comics to match comic information - issues - remove selected comics - restore all removed comics @@ -1772,7 +1542,6 @@ to improve the performance TitleHeader - SEARCH @@ -1780,17 +1549,14 @@ to improve the performance UpdateLibraryDialog - - Updating.... - Atualizando.... - - - Cancel Cancelar - + Updating.... + Atualizando.... + + Update library @@ -1798,7 +1564,6 @@ to improve the performance VolumeComicsModel - title @@ -1806,30 +1571,51 @@ to improve the performance VolumesModel - year - issues - publisher + + YACReader::TrayIconController + + &Restore + + + + &Quit + + + + Systray + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + + + + + YACReader::WhatsNewDialog + + Close + + + YACReaderDeletingProgress - Please wait, deleting in progress... - cancel @@ -1837,13 +1623,10 @@ to improve the performance YACReaderFieldEdit - - Click to overwrite - Restore to default @@ -1851,15 +1634,10 @@ to improve the performance YACReaderFieldPlainTextEdit - - - - Click to overwrite - Restore to default @@ -1867,22 +1645,18 @@ to improve the performance YACReaderFlowConfigWidget - - How to show covers: - Como mostrar capas: - - - CoverFlow look Olhar capa cheia - + How to show covers: + Como mostrar capas: + + Stripe look Olhar lista - Overlapped Stripe look Olhar lista sobreposta @@ -1890,117 +1664,94 @@ to improve the performance YACReaderGLFlowConfigWidget - - Presets: - - - - - Classic look - - - - Stripe look Olhar lista - Overlapped Stripe look Olhar lista sobreposta - + Presets: + + + + Classic look + + + Modern look - Roulette look - Show advanced settings - Custom: - View angle - Position - Cover gap - Central gap - Zoom - Y offset - Z offset - Cover Angle - Visibility - Light - Max angle - Low Performance - High Performance - Use VSync (improve the image quality in fullscreen mode, worse performance) - Performance: @@ -2008,12 +1759,10 @@ to improve the performance YACReaderNavigationController - No favorites - You are not reading anything yet, come on!! @@ -2021,27 +1770,22 @@ to improve the performance YACReaderOptionsDialog - Save Salvar - Cancel Cancelar - Edit shortcuts - Shortcuts - Use hardware acceleration (restart needed) @@ -2049,7 +1793,6 @@ to improve the performance YACReaderSearchLineEdit - type to search @@ -2057,32 +1800,26 @@ to improve the performance YACReaderSideBar - Libraries - Folders - Reading Lists - LIBRARIES - FOLDERS - READING LISTS diff --git a/YACReaderLibrary/yacreaderlibrary_ru.ts b/YACReaderLibrary/yacreaderlibrary_ru.ts index 9940ab54d..795a85f88 100644 --- a/YACReaderLibrary/yacreaderlibrary_ru.ts +++ b/YACReaderLibrary/yacreaderlibrary_ru.ts @@ -4,7 +4,6 @@ ActionsShortcutsModel - None @@ -12,142 +11,115 @@ AddLabelDialog - - Label name: - Название ярлыка: + red + красный - - Choose a color: - Выбрать цвет: + blue + синий - - red - красный + dark + темный - - orange - оранжевый + cyan + голубой - - yellow - желтый + pink + розовый - green зеленый - - cyan - голубой + light + серый - - blue - синий + white + белый - - violet - фиолетовый + Choose a color: + Выбрать цвет: - - purple - пурпурный + accept + добавить - - pink - розовый + cancel + отменить - - white - белый + orange + оранжевый - - light - серый + purple + пурпурный - - dark - темный + violet + фиолетовый - - accept - добавить + yellow + желтый - - cancel - отменить + Label name: + Название ярлыка: AddLibraryDialog - + Add + Добавить + + + Add an existing library + Добавить в существующую библиотеку + + + Cancel + Отмена + + Comics folder : Папка комиксов : - Library name : - Library Name : Имя библиотеки : + + + ApiKeyDialog - - Add - Добавить + Accept + Принять - Cancel Отмена - - Add an existing library - Добавить в существующую библиотеку - - - - ApiKeyDialog - - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> Для подключения к Comic Vine вам потребуется ваш личный API ключ. Приобретите его бесплатно вот <a href="http://www.comicvine.com/api/">здесь</a> - Paste here your Comic Vine API key Вставьте сюда ваш Comic Vine API ключ - - - Accept - Принять - - - - Cancel - Отмена - ClassicComicsView - Hide comic flow Показать/скрыть поток комиксов @@ -155,57 +127,46 @@ ComicInfoView - Authors Авторы - writer - penciller - inker - colorist - letterer - cover artist - Publisher - color - b/w - Characters @@ -213,47 +174,38 @@ ComicModel - - yes - да - - - no нет - - Title - Заголовок - - - - File Name - Имя файла + yes + да - - Pages - Всего страниц + Read + Прочитано - Size Размер - - Read - Прочитано + Pages + Всего страниц + + + Title + Заголовок - Current Page Текущая страница - + File Name + Имя файла + + Rating Рейтинг @@ -261,158 +213,123 @@ ComicVineDialog - - skip - пропустить - - - back назад - next дальше - - search - искать + skip + пропустить - close закрыть - - - - - + Retrieving tags for : %1 + Получение тегов для : %1 + + + Looking for comic... + Поиск комикса... + + + search + искать + + Looking for volume... Поиск информации... - - comic %1 of %2 - %3 комикс %1 of %2 - %3 - %1 comics selected %1 было выбрано - Error connecting to ComicVine Ошибка поключения к ComicVine - - - Retrieving tags for : %1 - Получение тегов для : %1 - - - Retrieving volume info... Получение информации... - - - Looking for comic... - Поиск комикса... - CreateLibraryDialog - - Comics folder : - Папка комиксов : + Create new library + Создать новую библиотеку - - Library Name : - Имя библиотеки: + Cancel + Отмена - Create Создать - - Cancel - Отмена - - - Create a library could take several minutes. You can stop the process and update the library later for completing the task. Создание библиотеки может занять несколько минут. Вы можете остановить процесс и обновить библиотеку позже для завершения задачи. - - Create new library - Создать новую библиотеку + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Выбранный путь отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке - - Path not found - Путь не найден + Comics folder : + Папка комиксов : - - The selected path does not exist or is not a valid path. Be sure that you have write access to this folder - Выбранный путь отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке + Library Name : + Имя библиотеки: + + + Path not found + Путь не найден EditShortcutsDialog - - Restore defaults - Вернуть к первоначальным значениям + Shortcut in use + Горячая клавиша уже занята - - To change a shortcut, double click in the key combination and type the new keys. - Чтобы изменить горячую клавишу щелкните дважды по выбранной комбинации клавиш и введите новые сочетания клавиш. + Restore defaults + Вернуть к первоначальным значениям - Shortcuts settings Горячие клавиши - - Shortcut in use - Горячая клавиша уже занята - - - The shortcut "%1" is already assigned to other function Сочетание клавиш "%1" уже назначено для другой функции + + To change a shortcut, double click in the key combination and type the new keys. + Чтобы изменить горячую клавишу щелкните дважды по выбранной комбинации клавиш и введите новые сочетания клавиш. + EmptyFolderWidget - - - Subfolders in this folder - Подпапки в этой папке - - - Empty folder Пустая папка - + Subfolders in this folder + Подпапки в этой папке + + Drag and drop folders and comics here Перетащите папки и комиксы сюда @@ -420,7 +337,6 @@ EmptyLabelWidget - This label doesn't contain comics yet Этот ярлык пока ничего не содержит @@ -428,84 +344,68 @@ EmptyReadingListWidget - This reading list does not contain any comics yet - This reading list doesn't contain comics yet Этот список чтения пока ничего не содержит ExportComicsInfoDialog - Output file : - Путь сохранения : + Выходной файл (*.ydb) : - - Create - Создать + Destination database name + Имя этой базы данных - Cancel Отмена - - Export comics info - Экспортировать информацию комикса + Create + Создать - - Destination database name - Имя этой базы данных + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Выбранный путь для импортируемого файла отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке - - Problem found while writing - Обнаружена Ошибка записи + Export comics info + Экспортировать информацию комикса - - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Выбранный путь для импортируемого файла отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке + Problem found while writing + Обнаружена Ошибка записи ExportLibraryDialog - - Output folder : - Папка вывода : + Cancel + Отменить - Create Создать - - Cancel - Отменить + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Выбранный путь для импортируемого файла отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке - - Create covers package - Создать комплект обложек + Output folder : + Папка вывода : - Problem found while writing Проблема при написании - - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Выбранный путь для импортируемого файла отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке + Create covers package + Создать комплект обложек - Destination directory Назначенная директория @@ -513,22 +413,18 @@ FileComic - - Unknown error opening the file - Неизвестная ошибка при открытии файла + Format not supported + Формат не поддерживается - 7z not found 7z не найден - - Format not supported - Формат не поддерживается + Unknown error opening the file + Неизвестная ошибка при открытии файла - CRC error on page (%1): some of the pages will not be displayed correctly Ошибка контрольной суммы CRC на странице (%1): некоторые страницы будут отображаться неправильно @@ -536,7 +432,6 @@ GridComicsView - Show info Показать информацию @@ -544,40 +439,33 @@ HelpAboutDialog - - About - О программе - - - Help Настройки + + About + О программе + ImportComicsInfoDialog - - Import comics info - Импортировать информацию комикса - - - - Info database location : - Путь к файлу : + Cancel + Отмена - Import Импортировать - - Cancel - Отмена + Info database location : + Путь к файлу (*.ydb) : + + + Import comics info + Импортировать информацию комикса - Comics info file (*.ydb) Инфо файл комикса (*.ydb) @@ -585,1048 +473,937 @@ ImportLibraryDialog - - Library Name : - Имя библиотеки : - - - - Package location : - Местоположение комплекта : - - - Destination folder : Папка назначения : - - Unpack - Распаковать - - - Cancel Отмена - - Extract a catalog - Извлечь каталог + Unpack + Распаковать - Compresed library covers (*.clc) Сжатая библиотека обложек (*.clc) + + Package location : + Местоположение комплекта : + + + Library Name : + Имя библиотеки : + + + Extract a catalog + Извлечь каталог + ImportWidget - - Importing comics - Импорт комиксов - - - stop Остановить - - Some of the comics being added... - Поиск новых комиксов... + Importing comics + Импорт комиксов - <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - Create a library could take several minutes. You can stop the process and update the library later for completing the task. <p>YACReaderLibrary сейчас создает библиотеку.</p><p> Создание библиотеки может занять несколько минут. Вы можете остановить процесс и обновить библиотеку позже для завершения задачи.</p> - + Some of the comics being added... + Поиск новых комиксов... + + Updating the library Обновление библиотеки - <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> - <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later. - <p>Для сокращения времени этого процесса периодически обновляйте вашу библиотеку после добавления новых комиксов. -Вы можете остановить этот процесс и продолжить обновление этой библиотеки позже.</p> + <p>Текущая библиотека обновляется. Для более быстрого обновления в дальнейшем старайтесь почаще обновлять вашу библиотеку после добавления новых комиксов.</p><p>Вы можете остановить этот процесс и продолжить обновление этой библиотеки позже.</p> - Upgrading the library - Обновление библиотеки + - <p>The current library is being upgraded, please wait.</p> - <p>Библиотека обновляется, пожалуйста подождите.</p> + LibraryWindow - - YACReader Library - Библиотека YACReader - - - <font color='white'> press 'F' to close fullscreen mode </font> - <font color='white'> нажмите 'F' чтобы выйте из Полноэкранного режима </font> - - - - Create a new library - Создать новую библиотеку + Edit + Редактировать информацию - - Open an existing library - Открыть существующую библиотеку + The selected folder doesn't contain any library. + Выбранная папка не содержит ни одной библиотеки. - - - Export comics info - Экспортировать данные комиксов + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Эта библиотека была создана с предыдущей версией YACReaderLibrary. Она должна быть обновлена. Обновить сейчас? - - - Import comics info - Импортировать данные комиксов + Comic + Комикс - - Pack covers - Запаковать обложки + Folder name: + Имя папки: - - Pack the covers of the selected library - Запаковать обложки выбранной библиотеки + The selected folder and all its contents will be deleted from your disk. Are you sure? + Выбранная папка и все ее содержимое будет удалено с вашего жёсткого диска. Вы уверены? - - Unpack covers - Распаковать обложки + Update current folder + Обновить выбранную папку - - Unpack a catalog - Распаковать каталог + Error opening the library + Ошибка открытия библиотеки - - Update library - Обновить библиотеку + Show/Hide marks + Показать/Спрятать пометки - - Update current library - Обновить эту библиотеку + YACReader not found + YACReader не найден - - Rename library - Переименовать библиотеку + Show comics server options dialog + Настройки сервера YACReader - - Rename current library - Переименовать эту библиотеку + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Возникла проблема при удалении выбранных папок. Пожалуйста, проверьте права на запись и убедитесь что другие приложения не используют эти папки или файлы. - Remove current library from your collection Удалить эту библиотеку из своей коллекции - - Open current comic - Открыть выбранный комикс + Set comic as read + Отметить комикс как прочитано - - Open current comic on YACReader - Открыть комикс в YACReader + Rename list name + Изменить имя списка - - Save selected covers to... - Сохранить выбранные обложки в... + Add selected comics to favorites list + Добавить выбранные комиксы в список избранного - - Save covers of the selected comics as JPG files - Сохранить обложки выбранных комиксов как JPG файлы + Remove and delete metadata + Удаление метаданных - - - Set as read - Отметить как прочитано + Old library + Библиотека из старой версии YACreader - - Set comic as read - Отметить комикс как прочитано + Update cover + Обновить обложки - - - Set as unread - Отметить как не прочитано + Rename any selected labels or lists + Переименовать выбранный ярлык/список чтения - - Set comic as unread - Отметить комикс как не прочитано + Set as completed + Отметить как завершено - - Show/Hide marks - Показать/Спрятать пометки + There was an error accessing the folder's path + Ошибка доступа к пути папки - - - Fullscreen mode on/off - Полноэкранный режим включить/выключить + Library + Библиотека - Fullscreen mode on/off (F) - полноекранный режим включить/выключить(F) + Add new folder to the current library + Добавить новую папку в текущую библиотеку - - Help, About YACReader - О программе + Comics will only be deleted from the current label/list. Are you sure? + Комиксы будут удалены только из выбранного списка/ярлыка. Вы уверены? - - Select root node - Домашняя папка + Rename current library + Переименовать эту библиотеку - - Expand all nodes - Раскрыть все папки + Fullscreen mode on/off + Полноэкранный режим включить/выключить - - Show options dialog - Настройки + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Эта библиотека была создана новой версией YACReaderLibrary. Скачать новую версию сейчас? - - Show comics server options dialog - Настройки сервера YACReader + Moving comics... + Переместить комиксы... - - Open folder... - Открыть папку... + Open current comic on YACReader + Открыть комикс в YACReader - - Set as uncompleted - Отметить как не завершено + Update current library + Обновить эту библиотеку - - Set as completed - Отметить как завершено + Copying comics... + Скопировать комиксы... - - Open containing folder... - Открыть выбранную папку... + Library '%1' is no longer available. Do you want to remove it? + Библиотека '%1' больше не доступна. Вы хотите удалить ее? - - Reset comic rating - Сбросить рейтинг комикса + Update library + Обновить библиотеку - - Select all comics - Выбрать все комиксы + Open folder... + Открыть папку... - - Edit - Редактировать информацию + Do you want remove + Вы хотите удалить библиотеку - - Update cover - Обновить обложки + Set as uncompleted + Отметить как не завершено - - Delete selected comics - Удалить выбранное + Error in path + Ошибка в пути - Hide comic flow - Не показывать поток комиксов + Reset comic rating + Сбросить рейтинг комикса - - Download tags from Comic Vine - Скачать теги из Comic Vine + Error updating the library + Ошибка обновления библиотеки - Folder Папка - - Comic - Комикс + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + Выбранные элементы будут удалены, ваши комиксы или папки НЕ БУДУТ удалены с вашего жёсткого диска. Вы уверены? - - Library not available - Library ' - Библиотека не доступна + Expand all nodes + Раскрыть все папки - - Library '%1' is no longer available. Do you want to remove it? - Библиотека '%1' больше не доступна. Вы хотите удалить ее? + Delete current folder from disk + Удалить выбранную папку с жёсткого диска - - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Библиотека '%1' была создана старой версией YACReaderLibrary. Она должна быть вновь создана. Вы хотите создать библиотеку сейчас? + List name: + Имя списка: - - Old library - Библиотека из старой версии YACreader + Add to... + Добавить в... - - - YACReader not found - YACReader не найден + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Библиотека '%1' была создана старой версией YACReaderLibrary. Она должна быть вновь создана. Вы хотите создать библиотеку сейчас? - YACReader not found, YACReader should be installed in the same folder as YACReaderLibrary. - YACReader не найден, YACReader должен быть установлен в ту же папку что и YACReaderLibrary. + Pack covers + Запаковать обложки - - - Unable to delete - Не удалось удалить + Save covers + Сохранить обложки - - There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - Возникла проблема при удалении выбранных комиксов. Пожалуйста, проверьте права на запись для выбранных файлов или содержащую их папку. + Change between comics views + Изменение внешнего вида потока комиксов - - Assign comics numbers - Порядковый номер + Remove current reading list from the library + Удалить выбранный ярлык/список чтения - - Assign numbers starting in: - Назначить порядковый номер начиная с: + Add new reading lists + Добавить новый список чтения - - Error creating the library - Ошибка создания библиотеки - + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Вы добавляете слишком много библиотек. + +Вероятно, вам нужна только одна библиотека в папке комиксов верхнего уровня, вы можете просматривать любые подпапки, используя раздел папок на левой боковой панели. + +YACReaderLibrary не помешает вам создать больше библиотек, но вы должны иметь не большое количество библиотек. + - - Error updating the library - Ошибка обновления библиотеки + Set as read + Отметить как прочитано - - Error opening the library - Ошибка открытия библиотеки + Assign comics numbers + Порядковый номер - - Delete comics - Удалить комиксы + Delete selected comics + Удалить выбранное - - All the selected comics will be deleted from your disk. Are you sure? - Все выбранные комиксы будут удалены с вашего жёсткого диска. Вы уверены? + Export comics info + Экспортировать информацию комикса - - Remove comics - Убрать комиксы + Show options dialog + Настройки - - Comics will only be deleted from the current label/list. Are you sure? - Комиксы будут удалены только из выбранного списка/ярлыка. Вы уверены? + Please, select a folder first + Пожалуйста, сначала выберите папку + + + Create a new library + Создать новую библиотеку + + + Library not available + Библиотека не доступна + + + Import comics info + Импортировать информацию комикса + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Возникла проблема при удалении выбранных комиксов. Пожалуйста, проверьте права на запись для выбранных файлов или содержащую их папку. + + + Add new reading list + Создать новый список чтения + + + Save selected covers to... + Сохранить выбранные обложки в... + + + Open current comic + Открыть выбранный комикс + + + YACReader Library + Библиотека YACReader + + + Add a new reading list to the current library + Создать новый список чтения + + + Error creating the library + Ошибка создания библиотеки + + + You are adding too many libraries. + Вы добавляете слишком много библиотек. + + + Update folder + Обновить папку + + + Unpack covers + Распаковать обложки + + + Update needed + Необходимо обновление + + + Open an existing library + Открыть существующую библиотеку + + + Show or hide read marks + Показать или спрятать отметку прочтено - Library name already exists Имя папки уже используется - There is another library with the name '%1'. Уже существует другая папка с именем '%1'. - - Library - Библиотека + Remove reading list + Удалить список чтения - - Remove library - Удалить библиотеку + Delete folder + Удалить папку - - Show or hide read marks - Показать или спрятать отметку прочтено + Assign numbers starting in: + Назначить порядковый номер начиная с: + + + Download new version + Загрузить новую версию + + + Delete comics + Удалить комиксы - - Add new folder Добавить новую папку - - Add new folder to the current library - Добавить новую папку в текущую библиотеку + Select all comics + Выбрать все комиксы - - - Delete folder - Удалить папку + Assign current order to comics + Назначить порядковый номер - - Delete current folder from disk - Удалить выбранную папку с жёсткого диска + Pack the covers of the selected library + Запаковать обложки выбранной библиотеки + + + Help, About YACReader + О программе - Collapse all nodes Свернуть все папки - - - Change between comics views - Может нужно поменять на другое выражение. - Изменение внешнего вида потока комиксов + Favorites + Избранное - - Assign current order to comics - Назначить порядковый номер + Rename selected list + Переименовать выбранный список + + + Delete list/label + Удалить список/ярлык + + + Set comic as unread + Отметить комикс как не прочитано - Edit shortcuts Редактировать горячие клавиши - - Update folder - Обновить папку + Select root node + Домашняя папка - - Update current folder - Обновить выбранную папку + No folder selected + Ни одна папка не была выбрана - - Add new reading list - Создать новый список чтения + Unpack a catalog + Распаковать каталог - - Add a new reading list to the current library - Создать новый список чтения + All the selected comics will be deleted from your disk. Are you sure? + Все выбранные комиксы будут удалены с вашего жёсткого диска. Вы уверены? - - Remove reading list - Удалить список чтения + Download tags from Comic Vine + Скачать теги из Comic Vine - - Remove current reading list from the library - Удалить выбранный ярлык/список чтения + Remove comics + Убрать комиксы - - Add new label + Add a new label to this library Создать новый ярлык - - Add a new label to this library - Создать новый ярлык + Set as unread + Отметить как не прочитано - - Rename selected list - Переименовать выбранный список + Library not found + Библиотека не найдена - - Rename any selected labels or lists - Переименовать выбранный ярлык/список чтения + Rename library + Переименовать библиотеку - - Add to... - Добавить в... + Remove library + Удалить библиотеку - - Favorites - Избранное + Open containing folder... + Открыть выбранную папку... - - Add selected comics to favorites list - Добавить выбранные комиксы в список избранного + Add new label + Создать новый ярлык - - Upgrade failed - Обновить не удалось + Unable to delete + Не удалось удалить - - There were errors during library upgrade in: - При обновлении библиотеки произошли ошибки: + library? + ? - - Update needed - Необходимо обновление + Save covers of the selected comics as JPG files + Сохранить обложки выбранных комиксов как JPG файлы - - This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - Эта библиотека была создана в предыдущей версии YACReaderLibrary. Требуется обновление. Обновить сейчас? + Are you sure? + Вы уверены? - Update failed - Обновить не удалось + Set as manga + - The current library can't be udpated. Check for write write permissions on: - В настоящее время библиотека не может быть обновлена. Проверьте права на чтение/запись: + Set issue as manga + - - Download new version - Загрузить новую версию + Set as normal + - - This library was created with a newer version of YACReaderLibrary. Download the new version now? - Эта библиотека была создана новой версией YACReaderLibrary. Скачать новую версию сейчас? + Set issue as normal + - - - Copying comics... - Скопировать комиксы... + Set as comic + - - - Moving comics... - Переместить комиксы... + Upgrade failed + - - Folder name: - Имя папки: + There were errors during library upgrade in: + - - No folder selected - Ни одна папка не была выбрана + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + - - Please, select a folder first - Пожалуйста, сначала выберите папку + YACReader not found. There might be a problem with your YACReader installation. + + + + LocalComicListModel - - Error in path - Ошибка в пути + file name + имя файла + + + LogWindow - - There was an error accessing the folder's path - Ошибка доступа к пути папки + Log window + - - The selected folder and all its contents will be deleted from your disk. Are you sure? - Выбранная папка и все ее содержимое будет удалено с вашего жёсткого диска. Вы уверены? + &Pause + - - There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - Возникла проблема при удалении выбранных папок. Пожалуйста, проверьте права на запись и убедитесь что другие приложения не используют эти папки или файлы. + &Save + - - Add new reading lists - Добавить новый список чтения + C&lear + - - - List name: - Имя списка: + &Copy + - - Delete list/label - Удалить список/ярлык + Level: + - - The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - Выбранные элементы будут удалены, ваши комиксы или папки НЕ БУДУТ удалены с вашего жёсткого диска. Вы уверены? + &Auto scroll + + + + NoLibrariesWidget - - Rename list name - Изменить имя списка + create your first library + создайте свою первую библиотеку - - Save covers - Сохранить обложки + You don't have any libraries yet + У вас нет ни одной библиотеки - - You are adding too many libraries. - Вы добавляете слишком много библиотек. + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Вы можете создать библиотеку в любой папке, YACReaderLibrary будет импортировать все комиксы и папки из этой папки. Если вы уже ранее создавали библиотеки, их можно будет открыть.< / p > <p>Не забывайте, что Вы можете использовать YACReader в качестве отдельного приложения для чтения комиксов на вашем компьютере.</п> - - You are adding too many libraries. - -You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. - -YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - Вы добавляете слишком много библиотек. - -Вероятно, вам нужна только одна библиотека в папке комиксов верхнего уровня, вы можете просматривать любые подпапки, используя раздел папок на левой боковой панели. - -YACReaderLibrary не помешает вам создать больше библиотек, но вы должны иметь не большое количество библиотек. + add an existing one + добавить уже существующую + + + OptionsDialog - - YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - YACReader не найден, YACReader должен быть установлен в ту же папку что и YACReaderLibrary. + Restore defautls + Вернуть к первоначальным значениям - - YACReader not found. There might be a problem with your YACReader installation. - YACReader не найден. Возможно, повреждены системные файлы YACReader. Переустановите YACReader. + Background + Фоновое изображение - - Library not found - Библиотека не найдена + Blur level + Уровень размытия - - The selected folder doesn't contain any library. - Выбранная папка не содержит ни одной библиотеки. + Enable background image + Включить фоновое изображение - - Are you sure? - Вы уверены? + Options + Настройки - - library? - ? + Comic Vine API key + Comic Vine API ключ + + + Edit Comic Vine API key + Редактировать Comic Vine API ключ + + + Opacity level + Уровень непрозрачности - - Remove and delete metadata - Удаление метаданных + General + Основные - - Do you want remove - Вы хотите удалить библиотеку + Use selected comic cover as background + Обложка комикса фоновое изображение - Asign comics numbers - Назначение номеров комикса + Comic Flow + Поток комиксов - Asign numbers starting in: - Назначьте номера, начинающиеся на: + Grid view + Фоновое изображение - - - LocalComicListModel - - file name - имя файла + Tray icon settings (experimental) + - - - NoLibrariesWidget - - You don't have any libraries yet - У вас нет ни одной библиотеки + Close to tray + - - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> - <p>Вы можете создать библиотеку в любой папке, YACReaderLibrary будет импортировать все комиксы и папки из этой папки. Если вы уже ранее создавали библиотеки, их можно будет открыть.< / p > <p>Не забывайте, что Вы можете использовать YACReader в качестве отдельного приложения для чтения комиксов на вашем компьютере.</п> + Start into the system tray + - - create your first library - создайте свою первую библиотеку + Display continue reading banner + - - add an existing one - добавить уже существующую + Continue reading + - OptionsDialog + PropertiesDialog - - Edit Comic Vine API key - Редактировать Comic Vine API ключ + Day: + День: - - Comic Vine API key - Comic Vine API ключ + Plot + Сюжет - - Enable background image - Включить фоновое изображение + Size: + Размер: - - Opacity level - Уровень непрозрачности + Year: + Год: - - Blur level - Уровень размытия + Inker(s): + Контуровщик(и): - - Use selected comic cover as background - Обложка комикса фоновое изображение + Publishing + Издатели - - Restore defautls - Вернуть к первоначальным значениям + Publisher: + Издатель: - - Background - Фоновое изображение + General info + Общая информация - - Comic Flow - Поток комиксов + Color/BW: + Цвет/BW: - - Grid view - Фоновое изображение + Edit selected comics information + Редактировать информацию выбранного комикса - - General - Основные + Penciller(s): + Художник(и): - - Options - Настройки + Colorist(s): + Колорист(ы): - - - PropertiesDialog - - General info - Общая информация + Genre: + Жанр: - - Authors - Авторы + Issue number: + Номер выпуска - - Publishing - Издатели + Month: + Месяц: - - Plot - Сюжет + Notes: + Заметки: - - Cover page - Страница обложки + Synopsis: + Описание: - Title: Заголовок: - - - of: - + Not found + Не найдено - - Issue number: - Номер выпуска + Characters: + Персонажи: - - Volume: - Объём : + Authors + Авторы - - Arc number: - + Age rating: + Возрастной рейтинг: - Story arc: Сюжетная арка: - - Genre: - Genere: - Жанр: + Writer(s): + Писатель(и): - - Size: - Размер: + Comic not found. You should update your library. + Комикс не найден. Обновите вашу библиотеку. - - Writer(s): - Писатель(и): + Edit comic information + Редактировать информацию комикса - - Penciller(s): - Художник(и): + Cover page + Страница обложки - - Inker(s): - Контуровщик(и): + Cover Artist(s): + Художник(и) Обложки: - - Colorist(s): - Колорист(ы): + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + <a style='color: ##666666; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Открыть страницу этого комикса на сайте Comic Vine </a> - - Letterer(s): - Гравёр-шрифтовик(и): + Volume: + Объём : - - Cover Artist(s): - Художник(и) Обложки: + Format: + Формат: - - Day: - День: + Letterer(s): + Гравёр-шрифтовик(и): - - Month: - Месяц: + of: + - - Year: - Год: + Arc number: + - - Publisher: - Издатель: + Manga: + + + + QObject - - Format: - Формат: + 7z lib not found + Библиотека распаковщика 7z не найдена - - Color/BW: - Цвет/BW: + unable to load 7z lib from ./utils + Не удается загрузить библиотеку распаковщика 7z из ./utils - - Age rating: - Возрастной рейтинг: + Trace + - - Synopsis: - Описание: + Debug + - - Characters: - Персонажи: + Info + - - Notes: - Заметки: + Warning + - - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - <a style='color: ##666666; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Открыть страницу этого комикса на сайте Comic Vine </a> + Error + - - Not found - Не найдено + Fatal + + + + QsLogging::LogWindowModel - - Comic not found. You should update your library. - Комикс не найден. Обновите вашу библиотеку. + Time + - - Edit selected comics information - Редактировать информацию выбранного комикса + Level + - - Edit comic information - Редактировать информацию комикса + Message + - QObject + QsLogging::Window - - 7z lib not found - Библиотека распаковщика 7z не найдена + &Pause + - - unable to load 7z lib from ./utils - Не удается загрузить библиотеку распаковщика 7z из ./utils + &Resume + + + + Save log + + + + Log file (*.log) + RenameLibraryDialog - - New Library Name : - Новое имя библиотеки: - - - - Rename - Переименовать + Rename current library + Переименовать эту библиотеку - Cancel Отмена - - Rename current library - Переименовать эту библиотеку + Rename + Переименовать + + + New Library Name : + Новое имя библиотеки: ScraperResultsPaginator - - Number of volumes found : %1 - Количество найденных томов : %1 + Number of %1 found : %2 + Количество из %1 найдено : %2 - - page %1 of %2 страница %1 из %2 - - Number of %1 found : %2 - Количество из %1 найдено : %2 + Number of volumes found : %1 + Количество найденных томов : %1 SearchSingleComic - Please provide some additional information. Пожалуйста, введите инфомарцию для поиска. - Series: Серия: @@ -1634,12 +1411,10 @@ YACReaderLibrary не помешает вам создать больше биб SearchVolume - Please provide some additional information. Пожалуйста, введите инфомарцию для поиска. - Series: Серия: @@ -1647,27 +1422,22 @@ YACReaderLibrary не помешает вам создать больше биб SelectComic - - Please, select the right comic info. - Пожалуйста, выберите правильную информацию об комиксе. + loading description + загрузка описания - comics комиксы - loading cover загрузка обложки - - loading description - загрузка описания + Please, select the right comic info. + Пожалуйста, выберите правильную информацию об комиксе. - description unavailable описание недоступно @@ -1675,27 +1445,22 @@ YACReaderLibrary не помешает вам создать больше биб SelectVolume - + loading description + загрузка описания + + Please, select the right series for your comic. Пожалуйста, выберите правильную серию для вашего комикса. - - volumes - тома - - - loading cover загрузка обложки - - loading description - загрузка описания + volumes + тома - description unavailable описание недоступно @@ -1703,126 +1468,85 @@ YACReaderLibrary не помешает вам создать больше биб SeriesQuestion - - You are trying to get information for various comics at once, are they part of the same series? - Вы пытаетесь получить информацию для нескольких комиксов одновременно, являются ли они все частью одной серии? + no + нет - yes да - - no - нет + You are trying to get information for various comics at once, are they part of the same series? + Вы пытаетесь получить информацию для нескольких комиксов одновременно, являются ли они все частью одной серии? ServerConfigDialog - - set port - указать порт - - - - Server connectivity information - Информация о подключении - - - - Scan it! - Сканируйте! + Port + Порт - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> <a href='http://ios.yacreader.com' style='color:rgb(102,102,102)'>YACReader доступен для устройств с iOS.</a> - - Choose an IP address - Выбрать IP адрес - - - - Port - Порт - - - enable the server активировать сервер - + Server connectivity information + Информация о подключении + + display less information about folders in the browser to improve the performance отображать меньше информации о папках в браузере для улучшения производительности - - Could not load libqrencode. - + Scan it! + Сканируйте! + + + set port + указать порт + + + Choose an IP address + Выбрать IP адрес - QR generator error! - Ошибка QR генератора! + Could not load libqrencode. + SortVolumeComics - - Please, sort the list of comics on the left until it matches the comics' information. - Пожалуйста, отсортируйте список комиксов слева, пока он не будет соответствовать информации комикса. + remove selected comics + удалить выбранные комиксы - sort comics to match comic information сортировать комиксы, чтобы соответствовать информации комиксов - - issues - выпуск - - - - remove selected comics - удалить выбранные комиксы - - - restore all removed comics восстановить все удаленные комиксы - restore removed comics - восстановить удаленные комиксы - - - - TableModel - - Title - Заголовок - - - File Name - Имя файла + issues + выпуск - Pages - Страницы + Please, sort the list of comics on the left until it matches the comics' information. + Пожалуйста, отсортируйте список комиксов слева, пока он не будет соответствовать информации комикса. TitleHeader - SEARCH ПОИСК @@ -1830,25 +1554,21 @@ to improve the performance UpdateLibraryDialog - - Updating.... - Обновление... + Update library + Обновить библиотеку - Cancel Отмена - - Update library - Обновить библиотеку + Updating.... + Обновление... VolumeComicsModel - title название @@ -1856,83 +1576,92 @@ to improve the performance VolumesModel - year год - issues выпуск - publisher издатель - YACReaderDeletingProgress + YACReader::TrayIconController - - Please wait, deleting in progress... - Пожалуйста подождите, удаление в процессе... + &Restore + + + + &Quit + - + Systray + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + + + + + YACReader::WhatsNewDialog + + Close + + + + + YACReaderDeletingProgress + cancel отменить + + Please wait, deleting in progress... + Пожалуйста подождите, удаление в процессе... + YACReaderFieldEdit - - - Click to overwrite - Изменить - - - Restore to default Вернуть к первоначальным значениям - - - YACReaderFieldPlainTextEdit - - - - Click to overwrite Изменить + + + YACReaderFieldPlainTextEdit - Restore to default Вернуть к первоначальным значениям + + Click to overwrite + Изменить + YACReaderFlowConfigWidget - - How to show covers: - Выбрать внешний вид потока обложек: - - - CoverFlow look Рулеткой - + How to show covers: + Выбрать внешний вид потока обложек: + + Stripe look Вид полосами - Overlapped Stripe look Вид перекрывающимися полосами @@ -1940,166 +1669,135 @@ to improve the performance YACReaderGLFlowConfigWidget - - Presets: - Предустановки: - - - - Classic look - Классический вид - - - - Stripe look - Вид полосами + Zoom + Масштабировать - - Overlapped Stripe look - Вид перекрывающимися полосами + Light + Осветить - - Modern look - Современный вид + Show advanced settings + Показать дополнительные настройки - Roulette look Вид рулеткой - - Show advanced settings - Показать дополнительные настройки - - - - Custom: - Пользовательский: + Cover Angle + Охватить угол - - View angle - Угол зрения + Stripe look + Вид полосами - Position Позиция - - Cover gap - Охватить разрыв + Z offset + Смещение по Z + + + Y offset + Смещение по Y - Central gap Сфокусировать разрыв - - Zoom - Масштабировать + Presets: + Предустановки: - - Y offset - Смещение по Y + Overlapped Stripe look + Вид перекрывающимися полосами - - Z offset - Смещение по Z + Modern look + Современный вид - - Cover Angle - Охватить угол + View angle + Угол зрения - - Visibility - Прозрачность + Max angle + Максимальный угол - - Light - Осветить + Custom: + Пользовательский: - - Max angle - Максимальный угол + Classic look + Классический вид - - Low Performance - Минимальная производительность + Cover gap + Охватить разрыв - High Performance Максимальная производительность - + Performance: + Производительность: + + Use VSync (improve the image quality in fullscreen mode, worse performance) Использовать VSync (повысить качество изображения в полноэкранном режиме , хуже производительность) - - Performance: - Производительность: + Visibility + Прозрачность + + + Low Performance + Минимальная производительность YACReaderNavigationController - - No favorites - Нет избранного - - - You are not reading anything yet, come on!! Вы пока ничего не читаете. Может самое время почитать? + + No favorites + Нет избранного + YACReaderOptionsDialog - Save Сохранить - - Cancel - Отмена + Use hardware acceleration (restart needed) + Использовать аппаратное ускорение (необходима перезагрузка) - - Edit shortcuts - Редактировать горячие клавиши + Cancel + Отмена - Shortcuts Горячие клавиши - - Use hardware acceleration (restart needed) - Использовать аппаратное ускорение (необходима перезагрузка) + Edit shortcuts + Редактировать горячие клавиши YACReaderSearchLineEdit - type to search Начать поиск @@ -2107,32 +1805,26 @@ to improve the performance YACReaderSideBar - - Libraries - Библиотеки - - - - Folders - Папки - - - Reading Lists Списки чтения - LIBRARIES БИБЛИОТЕКИ - + Libraries + Библиотеки + + FOLDERS ПАПКИ - + Folders + Папки + + READING LISTS СПИСКИ ЧТЕНИЯ diff --git a/YACReaderLibrary/yacreaderlibrary_source.ts b/YACReaderLibrary/yacreaderlibrary_source.ts index f757b11c3..87e652144 100644 --- a/YACReaderLibrary/yacreaderlibrary_source.ts +++ b/YACReaderLibrary/yacreaderlibrary_source.ts @@ -4,7 +4,7 @@ ActionsShortcutsModel - + None @@ -95,28 +95,28 @@ AddLibraryDialog - + Comics folder : - + Library name : Library Name : - + Add - + Cancel - + Add an existing library @@ -147,7 +147,7 @@ ClassicComicsView - + Hide comic flow @@ -155,57 +155,57 @@ ComicInfoView - + Authors - + writer - + penciller - + inker - + colorist - + letterer - + cover artist - + Publisher - + color - + b/w - + Characters @@ -213,47 +213,47 @@ ComicModel - + yes - + no - + Title - + File Name - + Pages - + Size - + Read - + Current Page - + Rating @@ -261,68 +261,68 @@ ComicVineDialog - + skip - + back - + next - + search - + close - - - - - + + + + + Looking for volume... - - + + comic %1 of %2 - %3 - + %1 comics selected - + Error connecting to ComicVine - - + + Retrieving tags for : %1 - + Retrieving volume info... - + Looking for comic... @@ -360,12 +360,12 @@ - + Path not found - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder @@ -383,17 +383,17 @@ - + Shortcuts settings - + Shortcut in use - + The shortcut "%1" is already assigned to other function @@ -401,18 +401,18 @@ EmptyFolderWidget - - + + Subfolders in this folder - + Empty folder - + Drag and drop folders and comics here @@ -457,17 +457,17 @@ - + Destination database name - + Problem found while writing - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder @@ -495,17 +495,17 @@ - + Problem found while writing - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - + Destination directory @@ -513,22 +513,22 @@ FileComic - + CRC error on page (%1): some of the pages will not be displayed correctly - + Unknown error opening the file - + 7z not found - + Format not supported @@ -536,7 +536,7 @@ GridComicsView - + Show info @@ -562,22 +562,22 @@ - + Info database location : - + Import - + Cancel - + Comics info file (*.ydb) @@ -615,7 +615,7 @@ - + Compresed library covers (*.clc) @@ -623,42 +623,42 @@ ImportWidget - + stop - + Some of the comics being added... - + Importing comics - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - + Updating the library - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> - + Upgrading the library - + <p>The current library is being upgraded, please wait.</p> @@ -666,12 +666,12 @@ LibraryWindow - + YACReader Library - + Library @@ -769,7 +769,7 @@ - + Set as read @@ -780,7 +780,7 @@ - + Set as unread @@ -790,323 +790,349 @@ - + Show/Hide marks - + Collapse all nodes - + Assign current order to comics - + Library not available Library ' - - + + Fullscreen mode on/off - + + + Set as manga + + + + + Set issue as manga + + + + + Set as normal + + + + + Set issue as normal + + + + Help, About YACReader - - + + Delete folder - + Select root node - + Expand all nodes - + Show options dialog - + Show comics server options dialog - + Open folder... - + Set as uncompleted - + Set as completed - + + Set as comic + + + + Open containing folder... - + Reset comic rating - + Select all comics - + Edit - + Update cover - + Delete selected comics - + Download tags from Comic Vine - + Edit shortcuts - + Update folder - + Update current folder - + Add new reading list - + Add a new reading list to the current library - + Remove reading list - + Remove current reading list from the library - + Add new label - + Add a new label to this library - + Rename selected list - + Rename any selected labels or lists - + Add to... - + Favorites - + Add selected comics to favorites list - + Folder - + Comic - + Upgrade failed - + There were errors during library upgrade in: - + Update needed - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - + Download new version - + This library was created with a newer version of YACReaderLibrary. Download the new version now? - + Library '%1' is no longer available. Do you want to remove it? - + Old library - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - - + + Copying comics... - - + + Moving comics... - + Folder name: - + No folder selected - + Please, select a folder first - + Error in path - + There was an error accessing the folder's path - + The selected folder and all its contents will be deleted from your disk. Are you sure? - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - + Add new reading lists - - + + List name: - + Delete list/label - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - + Rename list name - + Save covers - + You are adding too many libraries. - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. @@ -1115,141 +1141,141 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - - + + YACReader not found - + Library not found - + The selected folder doesn't contain any library. - + Are you sure? - + Do you want remove - + library? - + Remove and delete metadata - + Assign comics numbers - + Assign numbers starting in: - - + + Unable to delete - + Show or hide read marks - - + + Add new folder - + Add new folder to the current library - + Delete current folder from disk - - + + Change between comics views - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - + YACReader not found. There might be a problem with your YACReader installation. - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - + Error creating the library - + Error updating the library - + Error opening the library - + Delete comics - + All the selected comics will be deleted from your disk. Are you sure? - + Remove comics - + Comics will only be deleted from the current label/list. Are you sure? - + Library name already exists - + There is another library with the name '%1'. @@ -1257,11 +1283,49 @@ YACReaderLibrary will not stop you from creating more libraries but you should k LocalComicListModel - + file name + + LogWindow + + + Log window + + + + + &Pause + + + + + &Save + + + + + C&lear + + + + + &Copy + + + + + Level: + + + + + &Auto scroll + + + NoLibrariesWidget @@ -1288,62 +1352,87 @@ YACReaderLibrary will not stop you from creating more libraries but you should k OptionsDialog - + + Tray icon settings (experimental) + + + + + Close to tray + + + + + Start into the system tray + + + + Edit Comic Vine API key - + Comic Vine API key - + Enable background image - + Opacity level - + Blur level - + Use selected comic cover as background - + Restore defautls - + Background - + + Display continue reading banner + + + + + Continue reading + + + + Comic Flow - + Grid view - + General - + Options @@ -1376,149 +1465,154 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - + Title: - - + + of: - + Issue number: - + Volume: - + Arc number: - + Story arc: - + Genre: Genere: - + Size: - + Writer(s): - + Penciller(s): - + Inker(s): - + Colorist(s): - + Letterer(s): - + Cover Artist(s): - + Day: - + Month: - + Year: - + Publisher: - + Format: - + Color/BW: - + Age rating: - + + Manga: + + + + Synopsis: - + Characters: - + Notes: - + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - + Not found - + Comic not found. You should update your library. - + Edit selected comics information - + Edit comic information @@ -1526,35 +1620,106 @@ YACReaderLibrary will not stop you from creating more libraries but you should k QObject - + 7z lib not found - + unable to load 7z lib from ./utils + + + Trace + + + + + Debug + + + + + Info + + + + + Warning + + + + + Error + + + + + Fatal + + + + + QsLogging::LogWindowModel + + + Time + + + + + Level + + + + + Message + + + + + QsLogging::Window + + + &Pause + + + + + &Resume + + + + + Save log + + + + + Log file (*.log) + + RenameLibraryDialog - + New Library Name : - + Rename - + Cancel - + Rename current library @@ -1562,18 +1727,18 @@ YACReaderLibrary will not stop you from creating more libraries but you should k ScraperResultsPaginator - + Number of volumes found : %1 - - + + page %1 of %2 - + Number of %1 found : %2 @@ -1607,27 +1772,27 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SelectComic - + Please, select the right comic info. - + comics - + loading cover - + loading description - + description unavailable @@ -1645,17 +1810,17 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - + loading cover - + loading description - + description unavailable @@ -1663,17 +1828,17 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SeriesQuestion - + You are trying to get information for various comics at once, are they part of the same series? - + yes - + no @@ -1681,32 +1846,32 @@ YACReaderLibrary will not stop you from creating more libraries but you should k ServerConfigDialog - + set port - + Server connectivity information - + Scan it! - + YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - + Choose an IP address - + Port @@ -1722,7 +1887,7 @@ to improve the performance - + Could not load libqrencode. @@ -1766,17 +1931,17 @@ to improve the performance UpdateLibraryDialog - + Updating.... - + Cancel - + Update library @@ -1784,7 +1949,7 @@ to improve the performance VolumeComicsModel - + title @@ -1792,21 +1957,52 @@ to improve the performance VolumesModel - + year - + issues - + publisher + + YACReader::TrayIconController + + + &Restore + + + + + &Quit + + + + + Systray + + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + + + + + YACReader::WhatsNewDialog + + + Close + + + YACReaderDeletingProgress @@ -1824,7 +2020,7 @@ to improve the performance YACReaderFieldEdit - + Click to overwrite @@ -1838,9 +2034,9 @@ to improve the performance YACReaderFieldPlainTextEdit - - - + + + Click to overwrite @@ -1876,117 +2072,117 @@ to improve the performance YACReaderGLFlowConfigWidget - + Presets: - + Classic look - + Stripe look - + Overlapped Stripe look - + Modern look - + Roulette look - + Show advanced settings - + Custom: - + View angle - + Position - + Cover gap - + Central gap - + Zoom - + Y offset - + Z offset - + Cover Angle - + Visibility - + Light - + Max angle - + Low Performance - + High Performance - + Use VSync (improve the image quality in fullscreen mode, worse performance) - + Performance: @@ -1994,12 +2190,12 @@ to improve the performance YACReaderNavigationController - + No favorites - + You are not reading anything yet, come on!! @@ -2017,17 +2213,17 @@ to improve the performance - + Edit shortcuts - + Shortcuts - + Use hardware acceleration (restart needed) diff --git a/YACReaderLibrary/yacreaderlibrary_tr.ts b/YACReaderLibrary/yacreaderlibrary_tr.ts index fa34e572c..c7554caf0 100644 --- a/YACReaderLibrary/yacreaderlibrary_tr.ts +++ b/YACReaderLibrary/yacreaderlibrary_tr.ts @@ -10,6 +10,10 @@ AddLabelDialog + + cancel + vazgeç + Label name: @@ -70,10 +74,6 @@ accept - - cancel - vazgeç - AddLibraryDialog @@ -93,10 +93,6 @@ Comics folder : Çizfi roman dosyası : - - Library Name : - Kütüphane adı : - Library name : @@ -104,6 +100,10 @@ ApiKeyDialog + + Cancel + Vazgeç + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> @@ -116,23 +116,19 @@ Accept - - Cancel - Vazgeç - ClassicComicsView Hide comic flow - Çizgi roman akışını gizle + Çizgi roman akışını gizle ComicInfoView Authors - Yazarlar + Yazarlar writer @@ -178,32 +174,32 @@ ComicModel - yes - evet + no + hayır - no - hayır + yes + evet - Title - Başlık + Read + Oku - File Name - Dosya Adı + Size + Boyut Pages - Sayfalar + Sayfalar - Size - Boyut + Title + Başlık - Read - Oku + File Name + Dosya Adı Current Page @@ -416,54 +412,10 @@ FileComic - - File not found or not images in file - Dosya bulunamadı yada dosyada resim yok - 7z not found 7z bulunamadı - - Comic not found - Çizgi roman bulunamadı - - - Not found - Bulunamadı - - - File error - Dosya hatası - - - 7z problem - 7z Problemli - - - 7z reading - 7z Okuyor - - - 7z crashed. - 7z Bozulmuş. - - - problem reading from 7z - 7z Dosyası Okunamıyor - - - 7z crashed - 7z Bozulmuş - - - Unknown error 7z - Bilinmeyen 7z hatası - - - 7z wasn't found in your PATH. - 7z Dosya Yolu Bulunamadı. - CRC error on page (%1): some of the pages will not be displayed correctly @@ -587,14 +539,6 @@ LibraryWindow - - + - + - - - - - - - Edit Düzenle @@ -607,14 +551,6 @@ This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? Bu kütüphane YACReaderKütüphabenin bir önceki versiyonun oluşturulmuş, güncellemeye ihtiyacın var. Şimdi güncellemek ister misin ? - - <font color='white'> press 'F' to close fullscreen mode </font> - <font color='white'> 'F'ye basarak tam ekran modundan çıkabilirsin </font> - - - Asign current order to comics - Asignar el orden actual a los cómics - Error opening the library Haa kütüphanesini aç @@ -692,10 +628,6 @@ Error updating the library Kütüphane güncelleme sorunu - - Hide comic flow - Çizgi roman akışını gizle - Expand all nodes Tüm düğümleri büyüt @@ -704,10 +636,6 @@ Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? Kütüphane '%1 YACRKütüphanenin eski bir sürümünde oluşturulmuş, Kütüphaneyi yeniden oluşturmak ister misin? - - There was a problem saving YACReaderLibrary libraries file. Please, check if you have enough permissions in the YACReader root folder. - YACRKütüphane kütüphane dosyaları kaydedilirken bir sorun çıktı. Lütfen, YACReader root dosyalarını kontrol edin. - Pack covers Paket kapakları @@ -716,18 +644,6 @@ Set as read Okundu olarak işaretle - - Fullscreen mode on/off (F) - Tam ekran modunu aç/kapa(F) - - - Saving libraries file.... - Kütüphane dosyalarını kaydet... - - - Asign comics numbers - Çizgi roman numaralarını değiştir - Delete selected comics Seçili çizgi romanları sil @@ -752,18 +668,10 @@ Import comics info Çizgi roman bilgilerini içe aktar - - The current library can't be udpated. Check for write write permissions on: - Kütüphane güncellenmemiş. Lütfen yazım izinlerini kontrol et: - Open current comic Seçili çizgi romanı aç - - Colapse all nodes - Tüm düğümleri daralt - YACReader Library YACReader Kütüphane @@ -772,10 +680,6 @@ Error creating the library Kütüphane oluşturma sorunu - - Update failed - Güncelleme başarısız - Unpack covers Kapakları aç @@ -796,10 +700,6 @@ There is another library with the name '%1'. Bu başka bir kütüphanenin adı '%1'. - - Asign numbers starting in: - Başlangıç sayılarını düzenle: - Download new version Yeni versiyonu indir @@ -808,18 +708,10 @@ Delete comics Çizgi romanları sil - - Show or hide readed marks - Okunmuş işaretleri göster yada gizle - Select all comics Tüm çizgi romanları seç - - Set all comics as read - Tüm çizgi romanları okundu olarak ayarla - Pack the covers of the selected library Kütüphanede ki kapakları paketle @@ -844,10 +736,6 @@ All the selected comics will be deleted from your disk. Are you sure? Seçilen tüm çizgi romanlar diskten silinecek emin misin ? - - Set all as read - Hepsini okundu işaretle - Set as unread Hepsini okunmadı işaretle @@ -868,88 +756,88 @@ Open containing folder... Klasör açılıyor... - - Set all comics as unread - Tüm çizgiromanları okunmadı olarak işaretle - library? kütüphane? - - Set all as unread - Hepsini okunmadı olarak ayarla - Are you sure? Emin misin? - Download tags from Comic Vine + Save selected covers to... - YACReader not found + Save covers of the selected comics as JPG files - Unable to delete + Set as manga - There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Set issue as manga - Set as uncompleted + Set as normal - Set as completed + Set issue as normal - Reset comic rating + Show or hide read marks - Folder + Add new folder - Comic + Add new folder to the current library - Save selected covers to... + Delete folder - Save covers of the selected comics as JPG files + Delete current folder from disk - Show or hide read marks + Collapse all nodes - Add new folder + Change between comics views - Add new folder to the current library + Set as uncompleted - Delete folder + Set as completed - Delete current folder from disk + Set as comic - Change between comics views + Reset comic rating + + + + Assign current order to comics + + + + Download tags from Comic Vine @@ -1008,6 +896,22 @@ Add selected comics to favorites list + + Folder + + + + Comic + + + + Upgrade failed + + + + There were errors during library upgrade in: + + Copying comics... @@ -1040,6 +944,10 @@ The selected folder and all its contents will be deleted from your disk. Are you sure? + + Unable to delete + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. @@ -1068,14 +976,6 @@ Save covers - - Remove comics - - - - Comics will only be deleted from the current label/list. Are you sure? - - You are adding too many libraries. @@ -1089,35 +989,35 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - Collapse all nodes + YACReader not found - Assign current order to comics + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - Assign comics numbers + YACReader not found. There might be a problem with your YACReader installation. - Assign numbers starting in: + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - Upgrade failed + Assign comics numbers - There were errors during library upgrade in: + Assign numbers starting in: - YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + Remove comics - YACReader not found. There might be a problem with your YACReader installation. + Comics will only be deleted from the current label/list. Are you sure? @@ -1128,6 +1028,37 @@ YACReaderLibrary will not stop you from creating more libraries but you should k + + LogWindow + + Log window + + + + &Pause + + + + &Save + + + + C&lear + + + + &Copy + + + + Level: + + + + &Auto scroll + + + NoLibrariesWidget @@ -1153,6 +1084,18 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Options Ayarlar + + Tray icon settings (experimental) + + + + Close to tray + + + + Start into the system tray + + Edit Comic Vine API key @@ -1185,6 +1128,14 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Background + + Display continue reading banner + + + + Continue reading + + Comic Flow @@ -1316,16 +1267,16 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Format: Formato: - - Genere: - Tür: - Letterer(s): Mesaj(lar): - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + of: + + + + Arc number: @@ -1333,11 +1284,11 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - of: + Manga: - Arc number: + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> @@ -1351,6 +1302,64 @@ YACReaderLibrary will not stop you from creating more libraries but you should k unable to load 7z lib from ./utils + + Trace + + + + Debug + + + + Info + + + + Warning + + + + Error + + + + Fatal + + + + + QsLogging::LogWindowModel + + Time + + + + Level + + + + Message + + + + + QsLogging::Window + + &Pause + + + + &Resume + + + + Save log + + + + Log file (*.log) + + RenameLibraryDialog @@ -1457,16 +1466,16 @@ YACReaderLibrary will not stop you from creating more libraries but you should k SeriesQuestion - You are trying to get information for various comics at once, are they part of the same series? - + no + hayır yes - evet + evet - no - hayır + You are trying to get information for various comics at once, are they part of the same series? + @@ -1475,38 +1484,14 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Port Port - - EASY SERVER CONNECTION - KOLAY SERVER BAĞLANTISI - - - just scan the code with your device!! - Sadece kodu cihaza tarat !! - enable the server erişilebilir server - - IP address - IP adres - - - YACReader is now available for iOS devices, the best comic reading experience now in your iPad, iPhone or iPod touch. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader şimdi iOS cihazlarda Hemen iPad, iPhone veya iPod Touch'ına kapmak için tıkla (Çevirisi yapılmayacak) <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> ¡Descúbrelo! </a> - - - QR generator error! - QR kod oluşturma hatası! - set port Port Ayarla - - SERVER ADDRESS - Server Adres - Server connectivity information @@ -1556,37 +1541,6 @@ to improve the performance - - TableModel - - no - hayır - - - yes - evet - - - Read - Oku - - - Size - Boyut - - - Pages - Sayfalar - - - Title - Başlık - - - File Name - Dosya Adı - - TitleHeader @@ -1631,6 +1585,32 @@ to improve the performance + + YACReader::TrayIconController + + &Restore + + + + &Quit + + + + Systray + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + + + + + YACReader::WhatsNewDialog + + Close + + + YACReaderDeletingProgress @@ -1821,10 +1801,6 @@ to improve the performance YACReaderSideBar - - Search folders and comics - Klasörleri ve çizgi romanları ara - LIBRARIES KÜTÜPHANELER @@ -1850,19 +1826,4 @@ to improve the performance - - YACReaderSocialDialog - - I am reading %1 using YACReader. - YACReader ile okuyorum %1. - - - send to: - Gönder: - - - Follow YACReader! - YACReader'ı takip et ! - - diff --git a/YACReaderLibrary/yacreaderlibrary_zh.ts b/YACReaderLibrary/yacreaderlibrary_zh.ts new file mode 100644 index 000000000..4d85a1b4a --- /dev/null +++ b/YACReaderLibrary/yacreaderlibrary_zh.ts @@ -0,0 +1,1856 @@ + + + + + ActionsShortcutsModel + + None + 不存在 + + + + AddLabelDialog + + red + + + + blue + + + + dark + 深色 + + + cyan + + + + pink + + + + green + 绿 + + + light + 浅色 + + + white + + + + Choose a color: + 选择标签颜色: + + + accept + 接受 + + + cancel + 取消 + + + orange + + + + purple + + + + violet + 紫罗兰 + + + yellow + + + + Label name: + 标签名称: + + + + AddLibraryDialog + + Add + 添加 + + + Add an existing library + 添加一个现有库 + + + Cancel + 取消 + + + Comics folder : + 漫画文件夹: + + + Library Name : + 库名: + + + Library name : + + + + + ApiKeyDialog + + Accept + 接受 + + + Cancel + 取消 + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要拥有自己的API密匙才能够连接Comic Vine. 你可以通过这个链接获得一个免费的<a href="http://www.comicvine.com/api/">API</a>密匙 + + + Paste here your Comic Vine API key + 在此粘贴你的Comic Vine API + + + + ClassicComicsView + + Hide comic flow + 隐藏漫画流动预览 + + + + ComicInfoView + + Authors + 作者 + + + writer + + + + penciller + + + + inker + + + + colorist + + + + letterer + + + + cover artist + + + + Publisher + + + + color + + + + b/w + + + + Characters + + + + + ComicModel + + no + + + + yes + + + + Read + 阅读 + + + Size + 大小 + + + Pages + 页码 + + + Title + 标题 + + + Current Page + 当前页 + + + File Name + 文件名 + + + Rating + 评分 + + + + ComicVineDialog + + back + 返回 + + + next + 下一步 + + + skip + 忽略 + + + close + 关闭 + + + Retrieving tags for : %1 + 正在检索标签: %1 + + + Looking for comic... + 搜索中... + + + search + 搜索 + + + Looking for volume... + 搜索中... + + + comic %1 of %2 - %3 + 第 %1 本 共 %2 本 - %3 + + + %1 comics selected + 已选择 %1 本漫画 + + + Error connecting to ComicVine + ComicVine 连接错误 + + + Retrieving volume info... + 正在检索卷信息... + + + + CreateLibraryDialog + + Create new library + 创建新的文库 + + + Cancel + 取消 + + + Create + 创建 + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + 创建一个新的文件库可能需要几分钟时间,您可以先停止该进程,稍后可以通过更新文件库选项来更新数据。 + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + 所选路径不存在或不是有效路径. 确保您具有此文件夹的写入权限 + + + Comics folder : + 漫画文件夹: + + + Library Name : + 库名: + + + Path not found + 未找到路径 + + + + EditShortcutsDialog + + Shortcut in use + 快捷键已使用 + + + Restore defaults + 恢复默认设置 + + + Shortcuts settings + 编辑快捷键 + + + The shortcut "%1" is already assigned to other function + 快捷键 "%1" 已分配给其他功能 + + + To change a shortcut, double click in the key combination and type the new keys. + 要更改快捷键,请双击组合键并键入新键。 + + + + EmptyFolderWidget + + Empty folder + 空文件夹 + + + Subfolders in this folder + 建立子文件夹 + + + Drag and drop folders and comics here + 拖动文件夹或者漫画到这里 + + + + EmptyLabelWidget + + This label doesn't contain comics yet + 此标签尚未包含漫画 + + + + EmptyReadingListWidget + + This reading list does not contain any comics yet + 此阅读列表尚未包含任何漫画 + + + + ExportComicsInfoDialog + + Output file : + 输出文件: + + + Destination database name + 目标数据库名称 + + + Cancel + 取消 + + + Create + 创建 + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 输出文件的选定路径不存在或不是有效路径. 确保您具有此文件夹的写入权限 + + + Export comics info + 导出漫画信息 + + + Problem found while writing + 数据库导出失败 + + + + ExportLibraryDialog + + Cancel + 取消 + + + Create + 创建 + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 输出文件的选定路径不存在或不是有效路径. 确保您具有此文件夹的写入权限 + + + Output folder : + 输出文件夹: + + + Problem found while writing + 导出失败 + + + Create covers package + 创建封面包 + + + Destination directory + 目标目录 + + + + FileComic + + Format not supported + 不支持的格式 + + + 7z not found + 未找到7z文件 + + + Unknown error opening the file + 未知错误 + + + CRC error on page (%1): some of the pages will not be displayed correctly + 页面(%1)CRC错误:某些页面无法正确显示 + + + + GridComicsView + + Show info + 显示信息 + + + + HelpAboutDialog + + Help + 帮助 + + + About + 关于 + + + + ImportComicsInfoDialog + + Cancel + 取消 + + + Import + 导入 + + + Info database location : + 数据库地址: + + + Import comics info + 导入漫画信息 + + + Comics info file (*.ydb) + 漫画信息文件(*.ydb) + + + + ImportLibraryDialog + + Destination folder : + 目标文件夹: + + + Cancel + 取消 + + + Unpack + 解压 + + + Compresed library covers (*.clc) + 文件库封面压缩(*.clc) + + + Package location : + 打包地址: + + + Library Name : + 库名: + + + Extract a catalog + 提取目录 + + + + ImportWidget + + stop + 停止 + + + Importing comics + 正在导入漫画 + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary现在正在创建一个新库。</p><p>这可能需要几分钟时间,您可以先停止该进程,稍后可以通过更新文件库选项来更新数据。</p> + + + Some of the comics being added... + 正在添加漫画... + + + Updating the library + 正在更新文库 + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>正在更新当前文件库。要获得更快的更新,请经常更新您的文件库。</p><p>您可以停止该进程,稍后继续更新操作。</p> + + + Upgrading the library + + + + <p>The current library is being upgraded, please wait.</p> + + + + + LibraryWindow + + Edit + 编辑 + + + The selected folder doesn't contain any library. + 所选文件夹不包含任何库。 + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + 此库是使用旧版本的YACReaderLibrary创建的. 它需要更新. 现在更新? + + + Comic + 漫画 + + + Folder name: + 文件夹名称: + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + 所选文件夹及其所有内容将从磁盘中删除。 你确定吗? + + + Update current folder + 更新当前文件夹 + + + Error opening the library + 打开库时出错 + + + Show/Hide marks + 显示/隐藏标记 + + + YACReader not found + YACReader 未找到 + + + Show comics server options dialog + 显示漫画服务器选项对话框 + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + 尝试删除所选文件夹时出现问题。 请检查写入权限,并确保没有其他应用程序在使用这些文件夹或文件。 + + + Remove current library from your collection + 从您的集合中移除当前库 + + + Set comic as read + 漫画设为已读 + + + Rename list name + 重命名列表 + + + Add selected comics to favorites list + 将所选漫画添加到收藏夹列表 + + + Remove and delete metadata + 移除并删除元数据 + + + YACReader not found, YACReader should be installed in the same folder as YACReaderLibrary. + 未找到YACReader,YACReader应安装在与YACReaderLibrary相同的文件夹中。 + + + Old library + 旧的库 + + + Update cover + 更新封面 + + + Rename any selected labels or lists + 重命名任何选定的标签或列表 + + + Set as completed + 设为已完成 + + + There was an error accessing the folder's path + 访问文件夹的路径时出错 + + + Library + + + + Add new folder to the current library + 在当前库下添加新的文件夹 + + + Comics will only be deleted from the current label/list. Are you sure? + 漫画只会从当前标签/列表中删除。 你确定吗? + + + Rename current library + 重命名当前库 + + + Fullscreen mode on/off + 全屏模式 开/关 + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + 此库是使用较新版本的YACReaderLibrary创建的。 立即下载新版本? + + + Moving comics... + 移动漫画中... + + + Open current comic on YACReader + 用YACReader打开漫画 + + + Update current library + 更新当前库 + + + Copying comics... + 复制漫画中... + + + Library '%1' is no longer available. Do you want to remove it? + 库 '%1' 不再可用。 你想删除它吗? + + + Update library + 更新库 + + + Open folder... + 打开文件夹... + + + Do you want remove + 你想要删除 + + + Set as uncompleted + 设为未完成 + + + Error in path + 路径错误 + + + Reset comic rating + 重置漫画评分 + + + Error updating the library + 更新库时出错 + + + Folder + 文件夹 + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + 所选项目将被删除,您的漫画或文件夹将不会从您的磁盘中删除。 你确定吗? + + + Expand all nodes + 展开所有节点 + + + Delete current folder from disk + 从磁盘上删除当前文件夹 + + + List name: + 列表名称: + + + Add to... + 添加到... + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 库 '%1' 是通过旧版本的YACReaderLibrary创建的。 必须再次创建。 你想现在创建吗? + + + Pack covers + 打包封面 + + + Save covers + 保存封面 + + + Change between comics views + 漫画视图之间的变化 + + + Remove current reading list from the library + 从当前库移除阅读列表 + + + Add new reading lists + 添加新的阅读列表 + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + 您添加的库太多了。 + +一般情况只需要一个顶级的库,您可以使用左侧边栏中的文件夹功能来进行分类管理。 + +YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低的库数量来提升性能。 + + + Set as read + 设为已读 + + + Assign comics numbers + 分配漫画编号 + + + Delete selected comics + 删除所选的漫画 + + + Export comics info + 导出漫画信息 + + + Show options dialog + 显示选项对话框 + + + Please, select a folder first + 请先选择一个文件夹 + + + Create a new library + 创建一个新的库 + + + Library not available + 库不可用 + + + Import comics info + 导入漫画信息 + + + The current library can't be udpated. Check for write write permissions on: + 无法更新当前库。 检查读写权限: + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + 尝试删除所选漫画时出现问题。 请检查所选文件或包含文件夹中的写入权限。 + + + Add new reading list + 添加新的阅读列表 + + + Save selected covers to... + 选中的封面保存到... + + + Open current comic + 打开当前漫画 + + + YACReader Library + YACReader库 + + + Add a new reading list to the current library + 在当前库添加新的阅读列表 + + + Error creating the library + 创建库时出错 + + + Update failed + 更新失败 + + + You are adding too many libraries. + 您添加的库太多了。 + + + Update folder + 更新文件夹 + + + Unpack covers + 解压封面 + + + Update needed + 需要更新 + + + Open an existing library + 打开现有的库 + + + Show or hide read marks + 显示或隐藏阅读标记 + + + Library name already exists + 库名已存在 + + + There is another library with the name '%1'. + 已存在另一个名为'%1'的库。 + + + Remove reading list + 移除阅读列表 + + + Delete folder + 删除文件夹 + + + Assign numbers starting in: + 从以下位置开始分配编号: + + + Download new version + 下载新版本 + + + Delete comics + 删除漫画 + + + Add new folder + 添加新的文件夹 + + + Select all comics + 全选漫画 + + + Assign current order to comics + 将当前序号分配给漫画 + + + Pack the covers of the selected library + 打包所选库的封面 + + + Help, About YACReader + 帮助, 关于YACReader + + + Collapse all nodes + 折叠所有节点 + + + Favorites + 收藏夹 + + + Rename selected list + 重命名列表 + + + Delete list/label + 删除 列表/标签 + + + Set comic as unread + 漫画设为未读 + + + Edit shortcuts + 编辑快捷键 + + + Select root node + 选择根节点 + + + No folder selected + 没有选中的文件夹 + + + Unpack a catalog + 解压目录 + + + All the selected comics will be deleted from your disk. Are you sure? + 所有选定的漫画都将从您的磁盘中删除。你确定吗? + + + Download tags from Comic Vine + 从 Comic Vine 下载标签 + + + Remove comics + 移除漫画 + + + Add a new label to this library + 在当前库添加标签 + + + Set as unread + 设为未读 + + + Library not found + 未找到库 + + + Rename library + 重命名库 + + + Remove library + 移除库 + + + Open containing folder... + 打开包含文件夹... + + + Add new label + 添加新标签 + + + Unable to delete + 无法删除 + + + library? + 库? + + + Save covers of the selected comics as JPG files + 保存所选的封面为jpg + + + Are you sure? + 你确定吗? + + + Set as manga + + + + Set issue as manga + + + + Set as normal + + + + Set issue as normal + + + + Set as comic + + + + Upgrade failed + + + + There were errors during library upgrade in: + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + + + + + LocalComicListModel + + file name + 文件名 + + + + LogWindow + + Log window + + + + &Pause + + + + &Save + + + + C&lear + + + + &Copy + + + + Level: + + + + &Auto scroll + + + + + NoLibrariesWidget + + create your first library + 创建一个文库 + + + You don't have any libraries yet + 你还没有文件库 + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>您可以在任何文件夹中创建文件库,YACReaderLibrary将导入此文件夹中的所有漫画和文件夹。如果已有文件库,则可以打开它们。</p><p>您可以把YACReader当初独立应用来阅读计算机上的漫画。</p> + + + add an existing one + 现有基础上添加 + + + + OptionsDialog + + Restore defautls + 恢复默认值 + + + Background + 背景 + + + Blur level + 模糊 + + + Enable background image + 启用背景图片 + + + Options + 设置 + + + Comic Vine API key + Comic Vine API 密匙 + + + Edit Comic Vine API key + 编辑Comic Vine API 密匙 + + + Opacity level + 透明度 + + + General + 常规 + + + Use selected comic cover as background + 使用漫画封面做背景 + + + Comic Flow + 漫画流展示 + + + Grid view + 网格视图 + + + Tray icon settings (experimental) + + + + Close to tray + + + + Start into the system tray + + + + Display continue reading banner + + + + Continue reading + + + + + PropertiesDialog + + Day: + 日: + + + Plot + 情节 + + + Size: + 大小: + + + Year: + 年: + + + Inker(s): + 墨稿: + + + Publishing + 出版 + + + Publisher: + 发行人: + + + General info + 基本信息 + + + Color/BW: + 颜色/BW: + + + Edit selected comics information + 编辑选中的漫画信息 + + + Penciller(s): + 线稿: + + + Colorist(s): + 上色: + + + Genre: + 类型: + + + Issue number: + 发行数量: + + + Month: + 月: + + + Notes: + 笔记: + + + Synopsis: + 概要: + + + Title: + 标题: + + + Not found + 未找到 + + + Characters: + 特点: + + + Authors + 作者 + + + Age rating: + 年龄等级: + + + Story arc: + 故事线: + + + Writer(s): + 作者: + + + Comic not found. You should update your library. + 未找到漫画,请先更新您的文件库. + + + Edit comic information + 编辑漫画信息 + + + Cover page + 封面 + + + Cover Artist(s): + 封面设计: + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 连接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + + + Volume: + 卷: + + + Format: + 格式: + + + Letterer(s): + 文本: + + + of: + + + + Arc number: + + + + Manga: + + + + + QObject + + 7z lib not found + + + + unable to load 7z lib from ./utils + 无法从./utils加载7z lib + + + Trace + + + + Debug + + + + Info + + + + Warning + + + + Error + + + + Fatal + + + + + QsLogging::LogWindowModel + + Time + + + + Level + + + + Message + + + + + QsLogging::Window + + &Pause + + + + &Resume + + + + Save log + + + + Log file (*.log) + + + + + RenameLibraryDialog + + Rename current library + 重命名当前库 + + + Cancel + 取消 + + + Rename + 重命名 + + + New Library Name : + 新库名: + + + + ScraperResultsPaginator + + Number of %1 found : %2 + 第 %1 页 共: %2 条 + + + page %1 of %2 + 第 %1 页 共 %2 页 + + + Number of volumes found : %1 + 搜索结果: %1 + + + + SearchSingleComic + + Please provide some additional information. + 请提供一些其他信息。 + + + Series: + 系列: + + + + SearchVolume + + Please provide some additional information. + 请提供一些其他信息。 + + + Series: + 系列: + + + + SelectComic + + loading description + 加载描述: + + + comics + 漫画 + + + loading cover + 加载封面 + + + Please, select the right comic info. + 请正确选择漫画信息。 + + + description unavailable + 描述不可用 + + + + SelectVolume + + loading description + 加载描述 + + + Please, select the right series for your comic. + 请选择正确的漫画系列。 + + + loading cover + 加载封面 + + + volumes + + + + description unavailable + 描述不可用 + + + + SeriesQuestion + + no + + + + yes + + + + You are trying to get information for various comics at once, are they part of the same series? + 您正在尝试同时获取各种漫画的信息,它们是同一系列的吗? + + + + ServerConfigDialog + + Port + 端口 + + + YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> + YACReader适用于iOS设备。 <a href='http://ios.yacreader.com'style ='color:rgb(193,148,65)'>下载</a> + + + enable the server + 启用服务器 + + + Server connectivity information + 服务器连接信息 + + + display less information about folders in the browser +to improve the performance + 在浏览器中尽量少显示显示文件夹的有关信息 +这样能提升浏览效果 + + + Scan it! + 扫一扫! + + + QR generator error! + 二维码出错! + + + set port + 设置端口 + + + Choose an IP address + 选择IP地址 + + + Could not load libqrencode. + + + + + SortVolumeComics + + remove selected comics + 移除所选漫画 + + + sort comics to match comic information + 排序漫画以匹配漫画信息 + + + restore all removed comics + 恢复所有移除的漫画 + + + issues + 发行 + + + Please, sort the list of comics on the left until it matches the comics' information. + 请在左侧对漫画列表进行排序,直到它与漫画的信息相符。 + + + restore removed comics + 恢复移除的漫画 + + + + TitleHeader + + SEARCH + 搜索 + + + + UpdateLibraryDialog + + Update library + 更新库 + + + Cancel + 取消 + + + Updating.... + 更新中... + + + + VolumeComicsModel + + title + 标题 + + + + VolumesModel + + year + + + + issues + 发行 + + + publisher + 发行人 + + + + YACReader::TrayIconController + + &Restore + + + + &Quit + + + + Systray + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + + + + + YACReader::WhatsNewDialog + + Close + + + + + YACReaderDeletingProgress + + cancel + 取消 + + + Please wait, deleting in progress... + 请稍候,正在删除... + + + + YACReaderFieldEdit + + Restore to default + 恢复默认值 + + + Click to overwrite + 点击覆盖 + + + + YACReaderFieldPlainTextEdit + + Restore to default + 恢复默认值 + + + Click to overwrite + 点击覆盖 + + + + YACReaderFlowConfigWidget + + CoverFlow look + 封面流动展示 + + + How to show covers: + 封面显示: + + + Stripe look + 条状 + + + Overlapped Stripe look + 重叠条状 + + + + YACReaderGLFlowConfigWidget + + Zoom + 缩放 + + + Light + 亮度 + + + Show advanced settings + 高级设置 + + + Roulette look + 轮盘 + + + Cover Angle + 封面角度 + + + Stripe look + 条状 + + + Position + 位置 + + + Z offset + Z位移 + + + Y offset + Y位移 + + + Central gap + 展示区间距 + + + Presets: + 预设: + + + Overlapped Stripe look + 重叠条状 + + + Modern look + 现代 + + + View angle + 视角 + + + Max angle + 最大角度 + + + Custom: + 自定义: + + + Classic look + 经典 + + + Cover gap + 封面间距 + + + High Performance + + + + Performance: + 性能: + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + 使用VSync(在全屏模式下提高图像质量,性能更差) + + + Visibility + 透明度 + + + Low Performance + + + + + YACReaderNavigationController + + You are not reading anything yet, come on!! + 你还没有读任何东西,加油!! + + + No favorites + 没有收藏 + + + + YACReaderOptionsDialog + + Save + 保存 + + + Use hardware acceleration (restart needed) + 使用硬件加速(需要重启) + + + Cancel + 取消 + + + Shortcuts + 快捷方式 + + + Edit shortcuts + 编辑快捷方式 + + + + YACReaderSearchLineEdit + + type to search + 搜索类型 + + + + YACReaderSideBar + + Reading Lists + 阅读列表 + + + LIBRARIES + + + + Libraries + + + + FOLDERS + 文件夹 + + + Folders + 文件夹 + + + READING LISTS + 阅读列表 + + + From 81b4d25b5c29acd58a8135f23fd2ec0460667467 Mon Sep 17 00:00:00 2001 From: Felix Kauselmann Date: Mon, 8 Mar 2021 09:49:40 +0100 Subject: [PATCH 103/141] Remove unneeded QtOpenGL dependency Qt OpenGL in Qt5 is a deprecated module that is discouraged for new code usage. We have been including this module in our builds despite not relying on its functionality for a long time now - probably an oversight from porting to the newer functions. Time to remove it. IMPORTANT INFORMATION: In Qt6, a lot of functionality that was provided by Qt GUI was moved into the 'new' Qt6 Qt OpenGL module. Thus, even if it makes perfectly sense to remove it for Qt5 builds we will likely have to restore it for Qt6 builds at a later time. --- YACReader/YACReader.pro | 3 --- YACReaderLibrary/YACReaderLibrary.pro | 3 --- common/gl/yacreader_flow_gl.cpp | 1 - 3 files changed, 7 deletions(-) diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index 1404b98d1..067e78e37 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -69,9 +69,6 @@ macx { } QT += network widgets core multimedia svg -!CONFIG(no_opengl) { - QT += opengl -} #CONFIG += release CONFIG -= flat diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index b17f27ac5..c86a5c167 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -70,9 +70,6 @@ macx { #CONFIG += release CONFIG -= flat QT += sql network widgets svg -!CONFIG(no_opengl) { - QT += opengl -} # Input HEADERS += comic_flow.h \ diff --git a/common/gl/yacreader_flow_gl.cpp b/common/gl/yacreader_flow_gl.cpp index ad59daf73..57643c74e 100644 --- a/common/gl/yacreader_flow_gl.cpp +++ b/common/gl/yacreader_flow_gl.cpp @@ -1,7 +1,6 @@ #include "yacreader_flow_gl.h" #include -#include #include #include From 70287994ddf83a2984256d1d022992a28b1a051a Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Fri, 5 Feb 2021 16:29:07 +0200 Subject: [PATCH 104/141] Remove duplicate resource image alias --- YACReaderLibrary/images.qrc | 1 - 1 file changed, 1 deletion(-) diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index 3b117b640..56759398f 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -7,7 +7,6 @@ ../images/comic_vine/previousPage.png ../images/comic_vine/radioChecked.png ../images/comic_vine/radioUnchecked.png - ../images/comic_vine/radioUnchecked.png ../images/comic_vine/rowDown.png ../images/comic_vine/rowUp.png ../images/comic_vine/upArrow.png From 3c9ed6ef8fd263615fe6352ab757d3d0236992fc Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Fri, 5 Feb 2021 17:38:08 +0200 Subject: [PATCH 105/141] Deprecated qSort => std::sort This change gets rid of some GCC's -Wdeprecated-declarations warnings. --- YACReader/main_window_viewer.cpp | 5 ++--- YACReaderLibrary/db/folder_model.cpp | 5 +++-- YACReaderLibrary/db_helper.cpp | 3 ++- YACReaderLibrary/library_creator.cpp | 10 +++++----- YACReaderLibrary/library_window.cpp | 3 ++- .../server/controllers/v1/foldercontroller.cpp | 6 ++++-- 6 files changed, 18 insertions(+), 14 deletions(-) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index b86056bf3..5f351935f 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -948,7 +948,7 @@ void MainWindowViewer::openFolderFromPath(QString pathDir, QString atFileName) d.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware); QStringList list = d.entryList(); - qSort(list.begin(), list.end(), naturalSortLessThanCI); + std::sort(list.begin(), list.end(), naturalSortLessThanCI); int i = 0; foreach (QString path, list) { if (path.endsWith(atFileName)) @@ -1560,8 +1560,7 @@ void MainWindowViewer::getSiblingComics(QString path, QString currentComic) #endif d.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware); QStringList list = d.entryList(); - qSort(list.begin(), list.end(), naturalSortLessThanCI); - //std::sort(list.begin(),list.end(),naturalSortLessThanCI); + std::sort(list.begin(), list.end(), naturalSortLessThanCI); int index = list.indexOf(currentComic); if (index == -1) //comic not found { diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 576ebbedb..4464dc995 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -11,6 +11,8 @@ #include +#include + #ifdef Q_OS_MAC #include QIcon finishedFolderIcon; @@ -413,8 +415,7 @@ QStringList FolderModel::getSubfoldersNames(const QModelIndex &mi) } QSqlDatabase::removeDatabase(connectionName); - //TODO sort result)) - qSort(result.begin(), result.end(), naturalSortLessThanCI); + std::sort(result.begin(), result.end(), naturalSortLessThanCI); return result; } diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index dae8a979f..341ea50e2 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include "reading_list.h" @@ -166,7 +167,7 @@ QString DBHelper::getFolderName(qulonglong libraryId, qulonglong id) QList DBHelper::getLibrariesNames() { QStringList names = getLibraries().getNames(); - qSort(names.begin(), names.end(), naturalSortLessThanCI); + std::sort(names.begin(), names.end(), naturalSortLessThanCI); return names; } QString DBHelper::getLibraryName(int id) diff --git a/YACReaderLibrary/library_creator.cpp b/YACReaderLibrary/library_creator.cpp index 7318bce81..fc4265134 100644 --- a/YACReaderLibrary/library_creator.cpp +++ b/YACReaderLibrary/library_creator.cpp @@ -333,8 +333,8 @@ void LibraryCreator::update(QDir dirS) dirS.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware); QFileInfoList listSFiles = dirS.entryInfoList(); - qSort(listSFolders.begin(), listSFolders.end(), naturalSortLessThanCIFileInfo); - qSort(listSFiles.begin(), listSFiles.end(), naturalSortLessThanCIFileInfo); + std::sort(listSFolders.begin(), listSFolders.end(), naturalSortLessThanCIFileInfo); + std::sort(listSFiles.begin(), listSFiles.end(), naturalSortLessThanCIFileInfo); QFileInfoList listS; listS.append(listSFolders); @@ -351,8 +351,8 @@ void LibraryCreator::update(QDir dirS) //QLOG_TRACE() << "END Getting info from DB" << dirS.absolutePath(); QList listD; - qSort(folders.begin(), folders.end(), naturalSortLessThanCILibraryItem); - qSort(comics.begin(), comics.end(), naturalSortLessThanCILibraryItem); + std::sort(folders.begin(), folders.end(), naturalSortLessThanCILibraryItem); + std::sort(comics.begin(), comics.end(), naturalSortLessThanCILibraryItem); listD.append(folders); listD.append(comics); //QLOG_DEBUG() << "---------------------------------------------------------"; @@ -651,7 +651,7 @@ void ThumbnailCreator::create() if (_coverPage > _numPages) { _coverPage = 1; } - qSort(fileNames.begin(), fileNames.end(), naturalSortLessThanCI); + std::sort(fileNames.begin(), fileNames.end(), naturalSortLessThanCI); int index = order.indexOf(fileNames.at(_coverPage - 1)); if (_target == "") { diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index a605bc5bd..65f5a76b9 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -2494,7 +2495,7 @@ QModelIndexList LibraryWindow::getSelectedComics() //avoid selection.count()==0 forcing selection in comicsView QModelIndexList selection = comicsViewsManager->comicsView->selectionModel()->selectedRows(); QLOG_TRACE() << "selection count " << selection.length(); - qSort(selection.begin(), selection.end(), lessThanModelIndexRow); + std::sort(selection.begin(), selection.end(), lessThanModelIndexRow); if (selection.count() == 0) { comicsViewsManager->comicsView->selectIndex(0); diff --git a/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp b/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp index 8da40c951..e31485430 100644 --- a/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp +++ b/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp @@ -16,6 +16,8 @@ #include "QsLog.h" +#include + using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; using stefanfrings::HttpSession; @@ -79,7 +81,7 @@ void FolderController::service(HttpRequest &request, HttpResponse &response) folderContent.append(folderComics); - qSort(folderContent.begin(), folderContent.end(), LibraryItemSorter()); + std::sort(folderContent.begin(), folderContent.end(), LibraryItemSorter()); folderComics.clear(); //qulonglong backId = DBHelper::getParentFromComicFolderId(libraryName,folderId); @@ -265,7 +267,7 @@ void FolderController::service(HttpRequest &request, HttpResponse &response) if (index.length() > 1) { t.setCondition("alphaIndex", true); - qSort(index.begin(), index.end(), naturalSortLessThanCI); + std::sort(index.begin(), index.end(), naturalSortLessThanCI); t.loop("index", index.length()); int i = 0; int count = 0; From 4dcbb958dcaccc0342cac3031a036f79fe12ade1 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Fri, 5 Feb 2021 21:49:45 +0200 Subject: [PATCH 106/141] Eliminate QStringList <=> QList conversions The conversions prevented return value optimization and caused a -Wreturn-std-move Clang warning. --- YACReaderLibrary/db_helper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index 341ea50e2..3a0107560 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -166,7 +166,7 @@ QString DBHelper::getFolderName(qulonglong libraryId, qulonglong id) } QList DBHelper::getLibrariesNames() { - QStringList names = getLibraries().getNames(); + auto names = getLibraries().getNames(); std::sort(names.begin(), names.end(), naturalSortLessThanCI); return names; } From 8af4c01a035b18b5ecd0b42feac36ac612f63705 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Fri, 5 Feb 2021 21:34:55 +0200 Subject: [PATCH 107/141] Port away from deprecated QFlags(Zero) constructor This change gets rid of a few GCC's -Wdeprecated-declarations warnings. --- YACReaderLibrary/db/comic_model.cpp | 2 +- YACReaderLibrary/db/folder_model.cpp | 2 +- YACReaderLibrary/db/reading_list_model.cpp | 4 ++-- shortcuts_management/actions_shortcuts_model.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index 247e2e788..da6c8a46a 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -317,7 +317,7 @@ QVariant ComicModel::data(const QModelIndex &index, int role) const Qt::ItemFlags ComicModel::flags(const QModelIndex &index) const { if (!index.isValid()) - return 0; + return {}; if (index.column() == ComicModel::Rating) return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 4464dc995..2a3afdb22 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -144,7 +144,7 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const Qt::ItemFlags FolderModel::flags(const QModelIndex &index) const { if (!index.isValid()) - return 0; + return {}; return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled; } diff --git a/YACReaderLibrary/db/reading_list_model.cpp b/YACReaderLibrary/db/reading_list_model.cpp index b1991d4de..5f3012572 100644 --- a/YACReaderLibrary/db/reading_list_model.cpp +++ b/YACReaderLibrary/db/reading_list_model.cpp @@ -101,11 +101,11 @@ QVariant ReadingListModel::data(const QModelIndex &index, int role) const Qt::ItemFlags ReadingListModel::flags(const QModelIndex &index) const { if (!index.isValid()) - return 0; + return {}; auto item = static_cast(index.internalPointer()); if (typeid(*item) == typeid(ReadingListSeparatorItem)) - return 0; + return {}; if (typeid(*item) == typeid(ReadingListItem) && static_cast(item)->parent->getId() != 0) return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled; //only sublists are dragable diff --git a/shortcuts_management/actions_shortcuts_model.cpp b/shortcuts_management/actions_shortcuts_model.cpp index eee5961e6..914472319 100644 --- a/shortcuts_management/actions_shortcuts_model.cpp +++ b/shortcuts_management/actions_shortcuts_model.cpp @@ -33,7 +33,7 @@ QModelIndex ActionsShortcutsModel::index(int row, int column, const QModelIndex Qt::ItemFlags ActionsShortcutsModel::flags(const QModelIndex &index) const { if (!index.isValid()) - return 0; + return {}; if (index.column() == KEYS) return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; return Qt::ItemIsEnabled | Qt::ItemIsSelectable; From b87be810373dbac4a836f2d92c21a7aec5f40927 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Fri, 5 Feb 2021 22:08:17 +0200 Subject: [PATCH 108/141] Deprecated QSortFilterProxyModel::clear() => invalidate() --- YACReaderLibrary/db/folder_model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 2a3afdb22..35271125a 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -625,5 +625,5 @@ void FolderModelProxy::clear() filteredItems.clear(); - QSortFilterProxyModel::clear(); + QSortFilterProxyModel::invalidate(); } From 21c3bda5d41642c4ee8ab5275d6b96b0ced12041 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Fri, 5 Feb 2021 17:42:56 +0200 Subject: [PATCH 109/141] YACReaderFlowGL: initialize data member texture pointers Moving the initialization of defaultTexture out of the member initializer list gets rid of a GCC's -Wreorder warning. Initialize other texture pointers to improve safety and consistency. --- common/gl/yacreader_flow_gl.cpp | 2 +- common/gl/yacreader_flow_gl.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/gl/yacreader_flow_gl.cpp b/common/gl/yacreader_flow_gl.cpp index 57643c74e..e468e5319 100644 --- a/common/gl/yacreader_flow_gl.cpp +++ b/common/gl/yacreader_flow_gl.cpp @@ -190,7 +190,7 @@ struct Preset pressetYACReaderFlowDownConfig = { }; /*Constructor*/ YACReaderFlowGL::YACReaderFlowGL(QWidget *parent, struct Preset p) - : QOpenGLWidget(/*QOpenGLWidget migration QGLFormat(QGL::SampleBuffers),*/ parent), numObjects(0), lazyPopulateObjects(-1), defaultTexture(nullptr), hasBeenInitialized(false), bUseVSync(false), flowRightToLeft(false) + : QOpenGLWidget(/*QOpenGLWidget migration QGLFormat(QGL::SampleBuffers),*/ parent), numObjects(0), lazyPopulateObjects(-1), hasBeenInitialized(false), bUseVSync(false), flowRightToLeft(false) { updateCount = 0; config = p; diff --git a/common/gl/yacreader_flow_gl.h b/common/gl/yacreader_flow_gl.h index 6fc965a78..c47345d86 100644 --- a/common/gl/yacreader_flow_gl.h +++ b/common/gl/yacreader_flow_gl.h @@ -119,9 +119,9 @@ class YACReaderFlowGL : public QOpenGLWidget, public ScrollManagement int updateCount; int fontSize; - QOpenGLTexture *defaultTexture; - QOpenGLTexture *markTexture; - QOpenGLTexture *readingTexture; + QOpenGLTexture *defaultTexture = nullptr; + QOpenGLTexture *markTexture = nullptr; + QOpenGLTexture *readingTexture = nullptr; void initializeGL(); void paintGL(); void timerEvent(QTimerEvent *); From 497894c5bfcb35d0cfae26fabf0803cf9dae4285 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Tue, 9 Mar 2021 10:59:02 +0200 Subject: [PATCH 110/141] Allow to configure Fit to page action shortcut in the UI --- YACReader/main_window_viewer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 5f351935f..4c893ef0a 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -1328,6 +1328,7 @@ void MainWindowViewer::setUpShortcutsManagement() << doublePageAction << doubleMangaPageAction << adjustToFullSizeAction + << fitToPageAction << increasePageZoomAction << decreasePageZoomAction << resetZoomAction); From f60e17674e54fd5db408a9b30f8776d398154e85 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Fri, 5 Feb 2021 17:40:58 +0200 Subject: [PATCH 111/141] Server controllers: remove unused libraryName variable --- .../server/controllers/v1/folderinfocontroller.cpp | 1 - YACReaderLibrary/server/controllers/v1/pagecontroller.cpp | 3 --- .../server/controllers/v2/folderinfocontroller_v2.cpp | 1 - YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp | 3 --- .../server/controllers/v2/readinglistinfocontroller_v2.cpp | 1 - .../server/controllers/v2/taginfocontroller_v2.cpp | 1 - .../server/controllers/v2/updatecomiccontroller_v2.cpp | 1 - 7 files changed, 11 deletions(-) diff --git a/YACReaderLibrary/server/controllers/v1/folderinfocontroller.cpp b/YACReaderLibrary/server/controllers/v1/folderinfocontroller.cpp index 558018107..18189b8b3 100644 --- a/YACReaderLibrary/server/controllers/v1/folderinfocontroller.cpp +++ b/YACReaderLibrary/server/controllers/v1/folderinfocontroller.cpp @@ -19,7 +19,6 @@ void FolderInfoController::service(HttpRequest &request, HttpResponse &response) QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); QStringList pathElements = path.split('/'); int libraryId = pathElements.at(2).toInt(); - QString libraryName = DBHelper::getLibraryName(libraryId); qulonglong parentId = pathElements.at(4).toULongLong(); serviceComics(libraryId, parentId, response); diff --git a/YACReaderLibrary/server/controllers/v1/pagecontroller.cpp b/YACReaderLibrary/server/controllers/v1/pagecontroller.cpp index 5d0cfe570..610ec5663 100644 --- a/YACReaderLibrary/server/controllers/v1/pagecontroller.cpp +++ b/YACReaderLibrary/server/controllers/v1/pagecontroller.cpp @@ -11,8 +11,6 @@ #include -#include "db_helper.h" - using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; using stefanfrings::HttpSession; @@ -31,7 +29,6 @@ void PageController::service(HttpRequest &request, HttpResponse &response) //qDebug("PageController: request to -> %s ",path2.data()); QStringList pathElements = path.split('/'); - QString libraryName = DBHelper::getLibraryName(pathElements.at(2).toInt()); qulonglong comicId = pathElements.at(4).toULongLong(); unsigned int page = pathElements.at(6).toUInt(); diff --git a/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.cpp index 77801673b..c6988435e 100644 --- a/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.cpp @@ -19,7 +19,6 @@ void FolderInfoControllerV2::service(HttpRequest &request, HttpResponse &respons QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); QStringList pathElements = path.split('/'); int libraryId = pathElements.at(3).toInt(); - QString libraryName = DBHelper::getLibraryName(libraryId); qulonglong parentId = pathElements.at(5).toULongLong(); serviceComics(libraryId, parentId, response); diff --git a/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp index 9366624ef..2163cde0e 100644 --- a/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp @@ -11,8 +11,6 @@ #include -#include "db_helper.h" - using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; @@ -33,7 +31,6 @@ void PageControllerV2::service(HttpRequest &request, HttpResponse &response) bool remote = path.endsWith("remote"); QStringList pathElements = path.split('/'); - QString libraryName = DBHelper::getLibraryName(pathElements.at(2).toInt()); qulonglong comicId = pathElements.at(5).toULongLong(); unsigned int page = pathElements.at(7).toUInt(); diff --git a/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.cpp index f95cf498f..6145cf63d 100644 --- a/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.cpp @@ -20,7 +20,6 @@ void ReadingListInfoControllerV2::service(HttpRequest &request, HttpResponse &re QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); QStringList pathElements = path.split('/'); int libraryId = pathElements.at(3).toInt(); - QString libraryName = DBHelper::getLibraryName(libraryId); qulonglong listId = pathElements.at(5).toULongLong(); serviceComics(libraryId, listId, response); diff --git a/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.cpp index 3d87235fc..29dad28cb 100644 --- a/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.cpp @@ -20,7 +20,6 @@ void TagInfoControllerV2::service(HttpRequest &request, HttpResponse &response) QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); QStringList pathElements = path.split('/'); int libraryId = pathElements.at(3).toInt(); - QString libraryName = DBHelper::getLibraryName(libraryId); qulonglong listId = pathElements.at(5).toULongLong(); serviceComics(libraryId, listId, response); diff --git a/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp index 2773608e8..b7b24ed8b 100644 --- a/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp @@ -21,7 +21,6 @@ void UpdateComicControllerV2::service(HttpRequest &request, HttpResponse &respon QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); QStringList pathElements = path.split('/'); qulonglong libraryId = pathElements.at(3).toULongLong(); - QString libraryName = DBHelper::getLibraryName(libraryId); qulonglong comicId = pathElements.at(5).toULongLong(); QString postData = QString::fromUtf8(request.getBody()); From 14d9ba9de5aec1f80c98fa6472f6edbb8ed3fb96 Mon Sep 17 00:00:00 2001 From: Felix Kauselmann Date: Fri, 12 Mar 2021 17:01:42 +0100 Subject: [PATCH 112/141] Update qmake version check for Qt 5.9 and Qt 6 The old way to check for the Qt version was a bit of a hack and not very flexible. For Qt 6, it was broken and produced false positives. This commit fixes this by replacing the check function with a proper implementation imported from QtCreator's qmake files and updates the minimum requirements to reflect the new situation. --- config.pri | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/config.pri b/config.pri index 3c6d5620f..64b23da45 100644 --- a/config.pri +++ b/config.pri @@ -8,17 +8,36 @@ unix:QMAKE_CXXFLAGS_RELEASE += -DNDEBUG win32:QMAKE_CXXFLAGS_RELEASE += /DNDEBUG # check Qt version -QT_VERSION = $$[QT_VERSION] -QT_VERSION = $$split(QT_VERSION, ".") -QT_VER_MAJ = $$member(QT_VERSION, 0) -QT_VER_MIN = $$member(QT_VERSION, 1) - -lessThan(QT_VER_MAJ, 5) { -error(YACReader requires Qt 5 or newer but Qt $$[QT_VERSION] was detected.) +defineTest(minQtVersion) { + maj = $$1 + min = $$2 + patch = $$3 + isEqual(QT_MAJOR_VERSION, $$maj) { + isEqual(QT_MINOR_VERSION, $$min) { + isEqual(QT_PATCH_VERSION, $$patch) { + return(true) + } + greaterThan(QT_PATCH_VERSION, $$patch) { + return(true) + } + } + greaterThan(QT_MINOR_VERSION, $$min) { + return(true) + } } -lessThan(QT_VER_MIN, 6):!CONFIG(no_opengl) { - error ("You need at least Qt 5.6 to compile YACReader or YACReaderLibrary.") + greaterThan(QT_MAJOR_VERSION, $$maj) { + return(true) } + return(false) +} + +!minQtVersion(5, 9, 0) { + error(YACReader requires Qt 5.9 or newer but $$[QT_VERSION] was detected) +} + +minQtVersion(6, 0, 0) { + error(YACReader does not support building with Qt6 (yet)) +} # reduce log pollution CONFIG += silent From 75c2618effc06ccfdd3990dcd4e7c8e63aef17e6 Mon Sep 17 00:00:00 2001 From: Felix Kauselmann Date: Fri, 12 Mar 2021 17:06:47 +0100 Subject: [PATCH 113/141] Qmake: Introduce Qt deprecation macros As the minimum build requirements are now Qt 5.9, enable the QT_DEPRECATED_SINCE macro and set the deprecation target to 5.9 and earlier. This will make our build fail if functions deprecated in Qt 5.9 or earlier are used. Also, enable the QT_DEPRECATED_WARNINGS macro so our build system warns us when we are using functions deprecated in newer versions of Qt so we can port away from those too. --- config.pri | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config.pri b/config.pri index 64b23da45..3b14f8c20 100644 --- a/config.pri +++ b/config.pri @@ -39,6 +39,9 @@ minQtVersion(6, 0, 0) { error(YACReader does not support building with Qt6 (yet)) } +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050900 +DEFINES += QT_DEPRECATED_WARNINGS + # reduce log pollution CONFIG += silent From 97377cdcf4cff95555243e4e645f9b8209c317c1 Mon Sep 17 00:00:00 2001 From: Felix Kauselmann Date: Fri, 12 Mar 2021 17:38:36 +0100 Subject: [PATCH 114/141] Eliminate qsort, use std::sort --- YACReaderLibrary/comic_vine/model/volume_comics_model.cpp | 2 +- .../server/controllers/v2/foldercontentcontroller_v2.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/YACReaderLibrary/comic_vine/model/volume_comics_model.cpp b/YACReaderLibrary/comic_vine/model/volume_comics_model.cpp index 01357d8e2..f490454cb 100644 --- a/YACReaderLibrary/comic_vine/model/volume_comics_model.cpp +++ b/YACReaderLibrary/comic_vine/model/volume_comics_model.cpp @@ -41,7 +41,7 @@ void VolumeComicsModel::load(const QString &json) _data.push_back(l); } - qSort(_data.begin(), _data.end(), lessThan); + std::sort(_data.begin(), _data.end(), lessThan); } /*void VolumeComicsModel::load(const QStringList &jsonList) diff --git a/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp index bda1c46b6..dd3d8918c 100644 --- a/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp @@ -52,7 +52,7 @@ void FolderContentControllerV2::serviceContent(const int &library, const qulongl QList folderComics = DBHelper::getFolderComicsFromLibrary(library, folderId); folderContent.append(folderComics); - qSort(folderContent.begin(), folderContent.end(), LibraryItemSorter()); + std::sort(folderContent.begin(), folderContent.end(), LibraryItemSorter()); folderComics.clear(); From 18506c21cc6081c8507908aa3d936e862b01912e Mon Sep 17 00:00:00 2001 From: Felix Kauselmann Date: Fri, 12 Mar 2021 19:35:23 +0100 Subject: [PATCH 115/141] Treeview: Remove QSysInfo QSysInfo::MacVersion is deprecated in Qt 5.9 and the code it was used in is effectively dead code as it is specific to macOS versions no longer supported by Qt 5.9. Remove it. --- custom_widgets/yacreader_treeview.cpp | 43 ++++----------------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/custom_widgets/yacreader_treeview.cpp b/custom_widgets/yacreader_treeview.cpp index 14a6dd24b..c6dd9d9db 100644 --- a/custom_widgets/yacreader_treeview.cpp +++ b/custom_widgets/yacreader_treeview.cpp @@ -20,44 +20,13 @@ YACReaderTreeView::YACReaderTreeView(QWidget *parent) #ifdef Q_OS_MAC - bool oldStyle = true; - switch (QSysInfo::MacVersion()) { - case QSysInfo::MV_SNOWLEOPARD: - case QSysInfo::MV_LION: - case QSysInfo::MV_MOUNTAINLION: - case QSysInfo::MV_MAVERICKS: - oldStyle = true; //TODO fix this - break; - default: - oldStyle = false; - break; - } + setStyleSheet("QTreeView {background-color:transparent; border: none;}" + "QTreeView::item:selected {background-color:#91c4f4; border-top: 1px solid #91c4f4; border-left:none;border-right:none;border-bottom:1px solid #91c4f4;}" + "QTreeView::branch:selected {background-color:#91c4f4; border-top: 1px solid #91c4f4; border-left:none;border-right:none;border-bottom:1px solid #91c4f4;}" + "QTreeView::branch:open:selected:has-children {image: url(':/images/sidebar/expanded_branch_osx.png');}" + "QTreeView::branch:closed:selected:has-children {image: url(':/images/sidebar/collapsed_branch_osx.png');}" - if (oldStyle) { - setStyleSheet("QTreeView {background-color:transparent; border: none;}" - "QTreeView::item:selected {background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6BAFE4, stop: 1 #3984D2); border-top: 2px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #5EA3DF, stop: 1 #73B8EA); border-left:none;border-right:none;border-bottom:1px solid #3577C2;}" - "QTreeView::branch:selected {background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6BAFE4, stop: 1 #3984D2); border-top: 2px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #5EA3DF, stop: 1 #73B8EA); border-left:none;border-right:none;border-bottom:1px solid #3577C2;}" - "QTreeView::branch:open:selected:has-children {image: url(':/images/sidebar/expanded_branch_osx.png');}" - "QTreeView::branch:closed:selected:has-children {image: url(':/images/sidebar/collapsed_branch_osx.png');}" - - "QScrollBar:vertical { border: none; background: #EFEFEF; width: 9px; margin: 0 3px 0 0; }" - "QScrollBar::handle:vertical { background: #DDDDDD; width: 7px; min-height: 20px; margin: 1px; border: 1px solid #D0D0D0; }" - "QScrollBar::add-line:vertical { border: none; background: #EFEFEF; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" - - "QScrollBar::sub-line:vertical { border: none; background: #EFEFEF; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" - "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" - - "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }"); - } else { - setStyleSheet("QTreeView {background-color:transparent; border: none;}" - "QTreeView::item:selected {background-color:#91c4f4; border-top: 1px solid #91c4f4; border-left:none;border-right:none;border-bottom:1px solid #91c4f4;}" - "QTreeView::branch:selected {background-color:#91c4f4; border-top: 1px solid #91c4f4; border-left:none;border-right:none;border-bottom:1px solid #91c4f4;}" - "QTreeView::branch:open:selected:has-children {image: url(':/images/sidebar/expanded_branch_osx.png');}" - "QTreeView::branch:closed:selected:has-children {image: url(':/images/sidebar/collapsed_branch_osx.png');}" - - ); - } + ); #else setStyleSheet("QTreeView {background-color:transparent; border: none; color:#DDDFDF; outline:0; show-decoration-selected: 0;}" From 81e40dabec18c050b6762f46422078df9acad156 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Sun, 19 May 2019 15:54:59 +0300 Subject: [PATCH 116/141] Library: add a shortcut to focus search line The Ctrl+F shortcut gives focus to a search bar in many applications. In this case it allows to search the library without touching a mouse. YACReaderMacOSXSearchLineEdit::setFocus() will have to be implemented to make the shortcut work on macOS. --- YACReaderLibrary/library_window.cpp | 8 ++++++++ YACReaderLibrary/library_window.h | 1 + custom_widgets/yacreader_macosx_toolbar.h | 1 + custom_widgets/yacreader_macosx_toolbar.mm | 6 ++++++ shortcuts_management/shortcuts_manager.cpp | 1 + shortcuts_management/shortcuts_manager.h | 1 + 6 files changed, 18 insertions(+) diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 65f5a76b9..3a5b67f41 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -377,6 +377,7 @@ void LibraryWindow::setUpShortcutsManagement() tmpList = QList() << backAction << forwardAction + << focusSearchLineAction << helpAboutAction << optionsAction << serverConfigAction @@ -719,6 +720,12 @@ void LibraryWindow::createActions() getInfoAction->setIcon(QIcon(":/images/comics_view_toolbar/getInfo.png")); //------------------------------------------------------------------------- + focusSearchLineAction = new QAction(tr("Focus search line"), this); + focusSearchLineAction->setData(FOCUS_SEARCH_LINE_ACTION_YL); + focusSearchLineAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FOCUS_SEARCH_LINE_ACTION_YL)); + focusSearchLineAction->setIcon(QIcon(":/images/iconSearch.png")); + addAction(focusSearchLineAction); + showEditShortcutsAction = new QAction(tr("Edit shortcuts"), this); showEditShortcutsAction->setData(SHOW_EDIT_SHORTCUTS_ACTION_YL); showEditShortcutsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_EDIT_SHORTCUTS_ACTION_YL)); @@ -1147,6 +1154,7 @@ void LibraryWindow::createConnections() //connect(comicsModel,SIGNAL(searchNumResults(int)),this,SLOT(checkSearchNumResults(int))); //connect(emptyFolderWidget,SIGNAL(subfolderSelected(QModelIndex,int)),this,SLOT(selectSubfolder(QModelIndex,int))); + connect(focusSearchLineAction, &QAction::triggered, searchEdit, [this] { searchEdit->setFocus(Qt::ShortcutFocusReason); }); connect(showEditShortcutsAction, SIGNAL(triggered()), editShortcutsDialog, SLOT(show())); //update folders (partial updates) diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index af9664e2c..8a88f1f0f 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -213,6 +213,7 @@ class LibraryWindow : public QMainWindow QAction *forceCoverExtractedAction; QAction *deleteComicsAction; + QAction *focusSearchLineAction; QAction *showEditShortcutsAction; QAction *updateFolderAction; diff --git a/custom_widgets/yacreader_macosx_toolbar.h b/custom_widgets/yacreader_macosx_toolbar.h index c6fe90003..b49e6e8bb 100644 --- a/custom_widgets/yacreader_macosx_toolbar.h +++ b/custom_widgets/yacreader_macosx_toolbar.h @@ -12,6 +12,7 @@ class YACReaderMacOSXSearchLineEdit : public QObject Q_OBJECT public: YACReaderMacOSXSearchLineEdit(); + void setFocus(Qt::FocusReason reason); void *getNSTextField(); public slots: diff --git a/custom_widgets/yacreader_macosx_toolbar.mm b/custom_widgets/yacreader_macosx_toolbar.mm index 229e825ae..3e9d786a7 100644 --- a/custom_widgets/yacreader_macosx_toolbar.mm +++ b/custom_widgets/yacreader_macosx_toolbar.mm @@ -316,6 +316,12 @@ - (void)controlTextDidChange:(NSNotification *)notification nstextfield = searchEdit; } +void YACReaderMacOSXSearchLineEdit::setFocus(Qt::FocusReason reason) +{ + Q_UNUSED(reason) + // TODO: implement +} + void *YACReaderMacOSXSearchLineEdit::getNSTextField() { return nstextfield; diff --git a/shortcuts_management/shortcuts_manager.cpp b/shortcuts_management/shortcuts_manager.cpp index 541e4efd7..67e645e4f 100644 --- a/shortcuts_management/shortcuts_manager.cpp +++ b/shortcuts_management/shortcuts_manager.cpp @@ -13,6 +13,7 @@ void ShortcutsManager::initDefaultShorcuts() { #ifdef YACREADER_LIBRARY //ACTIONS + defaultShorcuts.insert(FOCUS_SEARCH_LINE_ACTION_YL, Qt::CTRL | Qt::Key_F); defaultShorcuts.insert(CREATE_LIBRARY_ACTION_YL, Qt::Key_A); defaultShorcuts.insert(OPEN_LIBRARY_ACTION_YL, Qt::Key_O); defaultShorcuts.insert(UPDATE_LIBRARY_ACTION_YL, Qt::Key_U); diff --git a/shortcuts_management/shortcuts_manager.h b/shortcuts_management/shortcuts_manager.h index d07a926c4..dbcd8eb00 100644 --- a/shortcuts_management/shortcuts_manager.h +++ b/shortcuts_management/shortcuts_manager.h @@ -75,6 +75,7 @@ class ShortcutsManager #define DELETE_COMICS_ACTION_YL "DELETE_COMICS_ACTION_YL" #define HIDE_COMIC_VIEW_ACTION_YL "HIDE_COMIC_VIEW_ACTION_YL" #define GET_INFO_ACTION_YL "GET_INFO_ACTION_YL" +#define FOCUS_SEARCH_LINE_ACTION_YL "FOCUS_SEARCH_LINE_ACTION_YL" #define SHOW_EDIT_SHORTCUTS_ACTION_YL "SHOW_EDIT_SHORTCUTS_ACTION_YL" #define UPDATE_CURRENT_FOLDER_ACTION_YL "UPDATE_CURRENT_FOLDER_ACTION_YL" #define ADD_FOLDER_ACTION_YL "ADD_FOLDER_ACTION_YL" From 8a541008042ab0b21cb18bc3382918d3dee2df0e Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Wed, 22 May 2019 14:12:31 +0300 Subject: [PATCH 117/141] Library: allow configuring a shortcut to focus comics view Focusing the current comics view allows to use keyboard arrow keys to choose among the visible comics. The shortcut for this new action should not be a single character without modifiers because it won't work when the search line has focus. The Qt::FocusReason parameter in ComicsView::focusComicsNavigation() allows to reuse this function for other keyboard navigation features. For instance the search line can transfer focus to comics navigation when the user presses Return or Enter key. In this case Qt::OtherFocusReason can be used (an application-specific reason). --- YACReaderLibrary/classic_comics_view.cpp | 9 +++++++++ YACReaderLibrary/classic_comics_view.h | 1 + YACReaderLibrary/comics_view.h | 1 + YACReaderLibrary/grid_comics_view.cpp | 5 +++++ YACReaderLibrary/grid_comics_view.h | 1 + YACReaderLibrary/info_comics_view.cpp | 5 +++++ YACReaderLibrary/info_comics_view.h | 1 + YACReaderLibrary/library_window.cpp | 8 ++++++++ YACReaderLibrary/library_window.h | 2 ++ YACReaderLibrary/yacreader_comics_views_manager.cpp | 5 +++++ YACReaderLibrary/yacreader_comics_views_manager.h | 1 + shortcuts_management/shortcuts_manager.h | 1 + 12 files changed, 40 insertions(+) diff --git a/YACReaderLibrary/classic_comics_view.cpp b/YACReaderLibrary/classic_comics_view.cpp index 56d35fc1f..113a63819 100644 --- a/YACReaderLibrary/classic_comics_view.cpp +++ b/YACReaderLibrary/classic_comics_view.cpp @@ -258,6 +258,15 @@ void ClassicComicsView::updateCurrentComicView() { } +void ClassicComicsView::focusComicsNavigation(Qt::FocusReason reason) +{ + const bool comicFlowVisible = stack->currentWidget() == comicFlow && sVertical->sizes().constFirst() != 0; + if (comicFlowVisible) + comicFlow->setFocus(reason); + else // Let the user navigate the table. + tableView->setFocus(reason); +} + void ClassicComicsView::selectAll() { tableView->selectAll(); diff --git a/YACReaderLibrary/classic_comics_view.h b/YACReaderLibrary/classic_comics_view.h index a5d51f147..4b09ca961 100644 --- a/YACReaderLibrary/classic_comics_view.h +++ b/YACReaderLibrary/classic_comics_view.h @@ -32,6 +32,7 @@ class ClassicComicsView : public ComicsView void enableFilterMode(bool enabled) override; void selectIndex(int index) override; void updateCurrentComicView() override; + void focusComicsNavigation(Qt::FocusReason reason) override; public slots: void setCurrentIndex(const QModelIndex &index) override; diff --git a/YACReaderLibrary/comics_view.h b/YACReaderLibrary/comics_view.h index 54e49ee60..9b98eee7e 100644 --- a/YACReaderLibrary/comics_view.h +++ b/YACReaderLibrary/comics_view.h @@ -29,6 +29,7 @@ class ComicsView : public QWidget virtual void enableFilterMode(bool enabled) = 0; virtual void selectIndex(int index) = 0; virtual void updateCurrentComicView() = 0; + virtual void focusComicsNavigation(Qt::FocusReason reason) = 0; public slots: virtual void updateInfoForIndex(int index); diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index cfeadb85a..feb24ae2d 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -491,6 +491,11 @@ void GridComicsView::updateCurrentComicView() setCurrentComicIfNeeded(); } +void GridComicsView::focusComicsNavigation(Qt::FocusReason reason) +{ + view->setFocus(reason); +} + void GridComicsView::startDrag() { auto drag = new QDrag(this); diff --git a/YACReaderLibrary/grid_comics_view.h b/YACReaderLibrary/grid_comics_view.h index 73e0e2b68..1d7ca65e4 100644 --- a/YACReaderLibrary/grid_comics_view.h +++ b/YACReaderLibrary/grid_comics_view.h @@ -34,6 +34,7 @@ class GridComicsView : public ComicsView QSize sizeHint(); QByteArray getMimeDataFromSelection(); void updateCurrentComicView() override; + void focusComicsNavigation(Qt::FocusReason reason) override; public slots: //ComicsView diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index f4d0c87e2..5aa5191c9 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -208,6 +208,11 @@ void InfoComicsView::updateCurrentComicView() { } +void InfoComicsView::focusComicsNavigation(Qt::FocusReason reason) +{ + view->setFocus(reason); +} + void InfoComicsView::setShowMarks(bool show) { QQmlContext *ctxt = view->rootContext(); diff --git a/YACReaderLibrary/info_comics_view.h b/YACReaderLibrary/info_comics_view.h index a3f8c2889..d4fe38d6c 100644 --- a/YACReaderLibrary/info_comics_view.h +++ b/YACReaderLibrary/info_comics_view.h @@ -26,6 +26,7 @@ class InfoComicsView : public ComicsView void enableFilterMode(bool enabled) override; void selectIndex(int index) override; void updateCurrentComicView() override; + void focusComicsNavigation(Qt::FocusReason reason) override; public slots: void setShowMarks(bool show); diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 3a5b67f41..c13df18bc 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -378,6 +378,7 @@ void LibraryWindow::setUpShortcutsManagement() << backAction << forwardAction << focusSearchLineAction + << focusComicsViewAction << helpAboutAction << optionsAction << serverConfigAction @@ -726,6 +727,11 @@ void LibraryWindow::createActions() focusSearchLineAction->setIcon(QIcon(":/images/iconSearch.png")); addAction(focusSearchLineAction); + focusComicsViewAction = new QAction(tr("Focus comics view"), this); + focusComicsViewAction->setData(FOCUS_COMICS_VIEW_ACTION_YL); + focusComicsViewAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FOCUS_COMICS_VIEW_ACTION_YL)); + addAction(focusComicsViewAction); + showEditShortcutsAction = new QAction(tr("Edit shortcuts"), this); showEditShortcutsAction->setData(SHOW_EDIT_SHORTCUTS_ACTION_YL); showEditShortcutsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_EDIT_SHORTCUTS_ACTION_YL)); @@ -1155,6 +1161,8 @@ void LibraryWindow::createConnections() //connect(emptyFolderWidget,SIGNAL(subfolderSelected(QModelIndex,int)),this,SLOT(selectSubfolder(QModelIndex,int))); connect(focusSearchLineAction, &QAction::triggered, searchEdit, [this] { searchEdit->setFocus(Qt::ShortcutFocusReason); }); + connect(focusComicsViewAction, &QAction::triggered, comicsViewsManager, &YACReaderComicsViewsManager::focusComicsViewViaShortcut); + connect(showEditShortcutsAction, SIGNAL(triggered()), editShortcutsDialog, SLOT(show())); //update folders (partial updates) diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index 8a88f1f0f..7a433004d 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -214,6 +214,8 @@ class LibraryWindow : public QMainWindow QAction *deleteComicsAction; QAction *focusSearchLineAction; + QAction *focusComicsViewAction; + QAction *showEditShortcutsAction; QAction *updateFolderAction; diff --git a/YACReaderLibrary/yacreader_comics_views_manager.cpp b/YACReaderLibrary/yacreader_comics_views_manager.cpp index 63ff90dbe..453018312 100644 --- a/YACReaderLibrary/yacreader_comics_views_manager.cpp +++ b/YACReaderLibrary/yacreader_comics_views_manager.cpp @@ -121,6 +121,11 @@ void YACReaderComicsViewsManager::toggleComicsView() } } +void YACReaderComicsViewsManager::focusComicsViewViaShortcut() +{ + comicsView->focusComicsNavigation(Qt::ShortcutFocusReason); +} + //PROTECTED void YACReaderComicsViewsManager::disconnectComicsViewConnections(ComicsView *widget) diff --git a/YACReaderLibrary/yacreader_comics_views_manager.h b/YACReaderLibrary/yacreader_comics_views_manager.h index b93fed053..4e79dd252 100644 --- a/YACReaderLibrary/yacreader_comics_views_manager.h +++ b/YACReaderLibrary/yacreader_comics_views_manager.h @@ -55,6 +55,7 @@ class YACReaderComicsViewsManager : public QObject public slots: void toggleComicsView(); + void focusComicsViewViaShortcut(); void showComicsView(); void showEmptyFolderView(); diff --git a/shortcuts_management/shortcuts_manager.h b/shortcuts_management/shortcuts_manager.h index dbcd8eb00..787eee2af 100644 --- a/shortcuts_management/shortcuts_manager.h +++ b/shortcuts_management/shortcuts_manager.h @@ -76,6 +76,7 @@ class ShortcutsManager #define HIDE_COMIC_VIEW_ACTION_YL "HIDE_COMIC_VIEW_ACTION_YL" #define GET_INFO_ACTION_YL "GET_INFO_ACTION_YL" #define FOCUS_SEARCH_LINE_ACTION_YL "FOCUS_SEARCH_LINE_ACTION_YL" +#define FOCUS_COMICS_VIEW_ACTION_YL "FOCUS_COMICS_VIEW_ACTION_YL" #define SHOW_EDIT_SHORTCUTS_ACTION_YL "SHOW_EDIT_SHORTCUTS_ACTION_YL" #define UPDATE_CURRENT_FOLDER_ACTION_YL "UPDATE_CURRENT_FOLDER_ACTION_YL" #define ADD_FOLDER_ACTION_YL "ADD_FOLDER_ACTION_YL" From fc57378a85469e9dd51701b0cde5a157f2130e15 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Thu, 11 Feb 2021 17:28:39 +0200 Subject: [PATCH 118/141] Remove unused sizeHint() from GridComicsView and ComicsViewTransition QWidget::sizeHint() is const-qualified, so Clang warns that non-const sizeHint() member functions merely hide the virtual function of the base class. 664dac34010c946db4477065abd077a7f7145bcd and 9f53ae6efcfb63c90308f86d4d30230c8750e66c introduced these member functions in 2014 without const qualifiers. QWidget::sizeHint() was const-qualified even in Qt 3. Since these member functions have never had any effect, they should be removed rather than const-qualified to preserve the long-standing behaviors of the two classes. Add a TODO for a similar but less straightforward issue with PropertiesDialog::sizeHint(). --- YACReaderLibrary/comics_view_transition.cpp | 5 ----- YACReaderLibrary/comics_view_transition.h | 1 - YACReaderLibrary/grid_comics_view.cpp | 5 ----- YACReaderLibrary/grid_comics_view.h | 1 - YACReaderLibrary/properties_dialog.h | 3 +++ 5 files changed, 3 insertions(+), 12 deletions(-) diff --git a/YACReaderLibrary/comics_view_transition.cpp b/YACReaderLibrary/comics_view_transition.cpp index c22bbc8ae..447e86cc0 100644 --- a/YACReaderLibrary/comics_view_transition.cpp +++ b/YACReaderLibrary/comics_view_transition.cpp @@ -20,11 +20,6 @@ ComicsViewTransition::ComicsViewTransition(QWidget *parent) #endif } -QSize ComicsViewTransition::sizeHint() -{ - return QSize(450, 350); -} - void ComicsViewTransition::paintEvent(QPaintEvent *) { QPainter painter(this); diff --git a/YACReaderLibrary/comics_view_transition.h b/YACReaderLibrary/comics_view_transition.h index 7f2cc7b02..78a08c3e3 100644 --- a/YACReaderLibrary/comics_view_transition.h +++ b/YACReaderLibrary/comics_view_transition.h @@ -8,7 +8,6 @@ class ComicsViewTransition : public QWidget Q_OBJECT public: explicit ComicsViewTransition(QWidget *parent = nullptr); - QSize sizeHint(); protected: void paintEvent(QPaintEvent *) override; diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index feb24ae2d..f442becee 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -469,11 +469,6 @@ void GridComicsView::resetScroll() QMetaObject::invokeMethod(scrollView, "scrollToOrigin"); } -QSize GridComicsView::sizeHint() -{ - return QSize(1280, 768); -} - QByteArray GridComicsView::getMimeDataFromSelection() { QByteArray data; diff --git a/YACReaderLibrary/grid_comics_view.h b/YACReaderLibrary/grid_comics_view.h index 1d7ca65e4..8b39f1d3a 100644 --- a/YACReaderLibrary/grid_comics_view.h +++ b/YACReaderLibrary/grid_comics_view.h @@ -31,7 +31,6 @@ class GridComicsView : public ComicsView void toNormal() override; void updateConfig(QSettings *settings) override; void enableFilterMode(bool enabled) override; - QSize sizeHint(); QByteArray getMimeDataFromSelection(); void updateCurrentComicView() override; void focusComicsNavigation(Qt::FocusReason reason) override; diff --git a/YACReaderLibrary/properties_dialog.h b/YACReaderLibrary/properties_dialog.h index ad32320f4..56505dcf9 100644 --- a/YACReaderLibrary/properties_dialog.h +++ b/YACReaderLibrary/properties_dialog.h @@ -122,6 +122,9 @@ class PropertiesDialog : public QDialog PropertiesDialog(QWidget *parent = nullptr); QString databasePath; QString basePath; + // TODO: this non-const member function hides rather than overrides + // QWidget::sizeHint(). But the function cannot be simply removed as it is used + // in our constructor. Will have to investigate and decide how to fix this. QSize sizeHint(); void paintEvent(QPaintEvent *event) override; From 288b9cbec6fe460a6653427d3b3ab2cec50dd612 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Thu, 11 Feb 2021 17:40:24 +0200 Subject: [PATCH 119/141] ComicsView's derived classes: use explicit, nullptr, override --- YACReaderLibrary/classic_comics_view.h | 2 +- YACReaderLibrary/grid_comics_view.h | 4 ++-- YACReaderLibrary/info_comics_view.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/YACReaderLibrary/classic_comics_view.h b/YACReaderLibrary/classic_comics_view.h index 4b09ca961..87122dc71 100644 --- a/YACReaderLibrary/classic_comics_view.h +++ b/YACReaderLibrary/classic_comics_view.h @@ -19,7 +19,7 @@ class ClassicComicsView : public ComicsView { Q_OBJECT public: - ClassicComicsView(QWidget *parent = 0); + explicit ClassicComicsView(QWidget *parent = nullptr); void setToolBar(QToolBar *toolBar) override; void setModel(ComicModel *model) override; diff --git a/YACReaderLibrary/grid_comics_view.h b/YACReaderLibrary/grid_comics_view.h index 8b39f1d3a..7ff0e7023 100644 --- a/YACReaderLibrary/grid_comics_view.h +++ b/YACReaderLibrary/grid_comics_view.h @@ -19,8 +19,8 @@ class GridComicsView : public ComicsView { Q_OBJECT public: - explicit GridComicsView(QWidget *parent = 0); - virtual ~GridComicsView(); + explicit GridComicsView(QWidget *parent = nullptr); + ~GridComicsView() override; void setToolBar(QToolBar *toolBar) override; void setModel(ComicModel *model) override; void setCurrentIndex(const QModelIndex &index) override; diff --git a/YACReaderLibrary/info_comics_view.h b/YACReaderLibrary/info_comics_view.h index d4fe38d6c..3cc925c86 100644 --- a/YACReaderLibrary/info_comics_view.h +++ b/YACReaderLibrary/info_comics_view.h @@ -29,7 +29,7 @@ class InfoComicsView : public ComicsView void focusComicsNavigation(Qt::FocusReason reason) override; public slots: - void setShowMarks(bool show); + void setShowMarks(bool show) override; void selectAll() override; protected slots: From efd9f478caafc6cd5e5b16959561c5dbfd95113b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 13 Mar 2021 16:32:27 +0100 Subject: [PATCH 120/141] Make underlying NSTextField the first responder on setFocus --- custom_widgets/yacreader_macosx_toolbar.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/custom_widgets/yacreader_macosx_toolbar.mm b/custom_widgets/yacreader_macosx_toolbar.mm index 3e9d786a7..51ea4d76d 100644 --- a/custom_widgets/yacreader_macosx_toolbar.mm +++ b/custom_widgets/yacreader_macosx_toolbar.mm @@ -319,7 +319,8 @@ - (void)controlTextDidChange:(NSNotification *)notification void YACReaderMacOSXSearchLineEdit::setFocus(Qt::FocusReason reason) { Q_UNUSED(reason) - // TODO: implement + + [((NSTextField *)nstextfield) becomeFirstResponder]; } void *YACReaderMacOSXSearchLineEdit::getNSTextField() From 2e0785e3a5bf647a8994ec7f10eb2e4674b9f041 Mon Sep 17 00:00:00 2001 From: Felix Kauselmann Date: Sun, 14 Mar 2021 14:56:17 +0100 Subject: [PATCH 121/141] Azure: Update Windows builds to use VS 2019 and Qt 5.15.2 Qt 5.15.2 and VS 2019 support all Windows platforms still supported by YACReader. Update the build to take advantage of it. --- azure-pipelines-windows-template.yml | 12 ++++++------ azure-pipelines.yml | 16 ++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/azure-pipelines-windows-template.yml b/azure-pipelines-windows-template.yml index cd6d226e3..54171f47b 100644 --- a/azure-pipelines-windows-template.yml +++ b/azure-pipelines-windows-template.yml @@ -1,10 +1,10 @@ parameters: name: Windows_x64 architecture: 'x64' - qt_version: '5.12.6' - qt_spec: 'msvc2017_64' - qt_aqt_spec: 'win64_msvc2017_64' - vc_redist_url: 'https://go.microsoft.com/fwlink/?LinkId=746572' + qt_version: '5.15.2' + qt_spec: 'msvc2019_64' + qt_aqt_spec: 'win64_msvc2019_64' + vc_redist_url: 'https://aka.ms/vs/16/release/vc_redist.x64.exe' vc_redist_file_name: 'vc_redist.x64.exe' vc_vars: 'vcvars64.bat' @@ -12,7 +12,7 @@ jobs: - job: ${{ parameters.name }} dependsOn: CodeFormatValidation pool: - vmImage: 'vs2017-win2016' + vmImage: 'windows-2019' steps: - script: | pip install aqtinstall @@ -26,7 +26,7 @@ jobs: wget "${{ parameters.vc_redist_url }}" -O $(Build.SourcesDirectory)\${{ parameters.vc_redist_file_name }} displayName: 'Install dependencies' - script: | - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\${{ parameters.vc_vars }}" + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ parameters.vc_vars }}" set PATH=C:\Qt\${{ parameters.qt_version }}\${{ parameters.qt_spec }}\bin;%PATH% set DEFINES_VAR=DEFINES+="BUILD_NUMBER=\\\\\\\"$(Build.BuildNumber)\\\\\\\"" qmake CONFIG+="7zip" %DEFINES_VAR% diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b2aa00bce..35f15369e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -103,20 +103,20 @@ jobs: parameters: name: Windows_x64 architecture: 'x64' - qt_version: '5.12.6' - qt_spec: 'msvc2017_64' - qt_aqt_spec: 'win64_msvc2017_64' - vc_redist_url: 'https://go.microsoft.com/fwlink/?LinkId=746572' + qt_version: '5.15.2' + qt_spec: 'msvc2019_64' + qt_aqt_spec: 'win64_msvc2019_64' + vc_redist_url: 'https://aka.ms/vs/16/release/vc_redist.x64.exe' vc_redist_file_name: 'vc_redist.x64.exe' vc_vars: 'vcvars64.bat' - template: azure-pipelines-windows-template.yml parameters: name: Windows_x86 architecture: 'x86' - qt_version: '5.12.6' - qt_spec: 'msvc2017' - qt_aqt_spec: 'win32_msvc2017' - vc_redist_url: 'https://go.microsoft.com/fwlink/?LinkId=746571' + qt_version: '5.15.2' + qt_spec: 'msvc2019' + qt_aqt_spec: 'win32_msvc2019' + vc_redist_url: 'https://aka.ms/vs/16/release/vc_redist.x86.exe' vc_redist_file_name: 'vc_redist.x86.exe' vc_vars: 'vcvars32.bat' From 8c81f263843aadff5550e97298836493b29aa96b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 14 Mar 2021 19:44:47 +0100 Subject: [PATCH 122/141] Update vc redist params in inno setup --- ci/win/build_installer.iss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/win/build_installer.iss b/ci/win/build_installer.iss index a9f08f695..8bad138b7 100644 --- a/ci/win/build_installer.iss +++ b/ci/win/build_installer.iss @@ -106,7 +106,7 @@ LaunchYACReader=Start YACreader after finishing installation [Run] Filename: {tmp}\vc_redist.{#PLATFORM}.exe; \ -Parameters: "/q /passive /norestart /Q:a /c:""msiexec /q /i vcredist.msi"""; \ +Parameters: "/install /quiet /norestart"; \ StatusMsg: "Installing VC++ Redistributables..." Filename: {app}\{cm:AppLibrary}.exe; Description: {cm:LaunchYACReaderLibrary,{cm:AppLibrary}}; Flags: nowait postinstall skipifsilent From b447226bc129015ae0419b5c80cecdd704eb0f9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 10 Apr 2021 09:51:14 +0200 Subject: [PATCH 123/141] Avoid indexes out of range when processing v1 updated session data --- YACReaderLibrary/server/requestmapper.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/YACReaderLibrary/server/requestmapper.cpp b/YACReaderLibrary/server/requestmapper.cpp index e4c6a4210..d208ab04d 100644 --- a/YACReaderLibrary/server/requestmapper.cpp +++ b/YACReaderLibrary/server/requestmapper.cpp @@ -102,11 +102,22 @@ void RequestMapper::loadSessionV1(HttpRequest &request, HttpResponse &response) QList data = postData.split("\n"); if (data.length() > 2) { - ySession->setDeviceType(data.at(0).split(":").at(1)); - ySession->setDisplayType(data.at(1).split(":").at(1)); - QList comics = data.at(2).split(":").at(1).split("\t"); - foreach (QString hash, comics) { - ySession->setComicOnDevice(hash); + auto deviceTypeData = data.at(0).split(":"); + if (deviceTypeData.length() == 2) { + ySession->setDeviceType(deviceTypeData.at(1)); + } + + auto displayTypeData = data.at(1).split(":"); + if (displayTypeData.length() == 2) { + ySession->setDisplayType(displayTypeData.at(1)); + } + + auto comicsData = data.at(2).split(":"); + if (comicsData.length() == 2) { + QList comics = comicsData.at(1).split("\t"); + foreach (QString hash, comics) { + ySession->setComicOnDevice(hash); + } } } else //values by default, only for debug purposes. { From 590513c98e0664f2d99edcabc6de94682463ac29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 22 Apr 2021 07:56:52 +0200 Subject: [PATCH 124/141] Pack Qt5QmlModels.dll in windows installer --- ci/win/build_installer.iss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/win/build_installer.iss b/ci/win/build_installer.iss index 8bad138b7..49916e169 100644 --- a/ci/win/build_installer.iss +++ b/ci/win/build_installer.iss @@ -42,6 +42,7 @@ Source: Qt5Sql.dll; DestDir: {app} Source: Qt5Svg.dll; DestDir: {app} Source: Qt5Widgets.dll; DestDir: {app} Source: Qt5QuickWidgets.dll; DestDir: {app} +Source: Qt5QmlModels.dll; DestDir: {app} ;Qt Angle Source: D3Dcompiler_47.dll; DestDir: {app} @@ -139,7 +140,7 @@ procedure InitializeWizard(); begin URLLabel := TNewStaticText.Create(WizardForm); - URLLabel.Caption:='Make a DONATION/Haz una DONACI�N'; + URLLabel.Caption:='Make a DONATION/Haz una DONACIN'; URLLabel.Cursor:=crHand; URLLabel.OnClick:=@URLLabelOnClick; URLLabel.Parent:=WizardForm; From 020ff5f6b564f5df40a00b7e474ddf5f41653c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 25 Apr 2021 08:59:35 +0200 Subject: [PATCH 125/141] Include missing dependency in windows installer --- ci/win/build_installer.iss | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/win/build_installer.iss b/ci/win/build_installer.iss index 49916e169..02e556ce9 100644 --- a/ci/win/build_installer.iss +++ b/ci/win/build_installer.iss @@ -43,6 +43,7 @@ Source: Qt5Svg.dll; DestDir: {app} Source: Qt5Widgets.dll; DestDir: {app} Source: Qt5QuickWidgets.dll; DestDir: {app} Source: Qt5QmlModels.dll; DestDir: {app} +Source: Qt5QmlWorkerScript.dll; DestDir: {app} ;Qt Angle Source: D3Dcompiler_47.dll; DestDir: {app} From e71e97f2fedffb2029cb9aa24e1faf76e3cd958b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Mon, 26 Apr 2021 22:49:50 +0200 Subject: [PATCH 126/141] Migrate dev builds artifacts from Bintray to Artifactory First attempt --- azure-pipelines.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 35f15369e..4488a91a2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -129,7 +129,7 @@ jobs: - Windows_x64 condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/develop'), true) variables: - - group: bintray + - group: artifactory pool: vmImage: 'ubuntu-16.04' steps: @@ -144,10 +144,9 @@ jobs: files: '$(Build.SourcesDirectory)/dev_bin/**/*.*' authType: 'userAndPass' username: $(username) - password: $(api-key) - options: -H "X-Bintray-Publish:1" + password: $(pass) remotePath: '' - url: https://api.bintray.com/content/luisangelsm/YACReader/DevBuilds/$(Build.BuildNumber)/ + url: https://yacreader.jfrog.io/artifactory/yacreader/$(Build.BuildNumber)/ - ${{ if and(eq(variables['System.TeamFoundationCollectionUri'], 'https://dev.azure.com/luisangelsm/'), or(eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq(variables['Build.SourceBranch'], 'refs/heads/develop'))) }}: - job: Release From 811c3fcfe492066eead83594a78fbdad0e2ba00f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Fri, 30 Apr 2021 09:52:10 +0200 Subject: [PATCH 127/141] Add function to get comics from a folder properly sorted --- YACReaderLibrary/db_helper.cpp | 24 ++++++++++++++++++++++++ YACReaderLibrary/db_helper.h | 1 + 2 files changed, 25 insertions(+) diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index 3a0107560..3b3dd6831 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -33,6 +33,7 @@ YACReaderLibraries DBHelper::getLibraries() libraries.load(); return libraries; } + QList DBHelper::getFolderSubfoldersFromLibrary(qulonglong libraryId, qulonglong folderId) { QString libraryPath = DBHelper::getLibraries().getPath(libraryId); @@ -47,11 +48,34 @@ QList DBHelper::getFolderSubfoldersFromLibrary(qulonglong library QSqlDatabase::removeDatabase(connectionName); return list; } + QList DBHelper::getFolderComicsFromLibrary(qulonglong libraryId, qulonglong folderId) { return DBHelper::getFolderComicsFromLibrary(libraryId, folderId, false); } +QList DBHelper::getFolderComicsFromLibraryForReading(qulonglong libraryId, qulonglong folderId) +{ + auto list = DBHelper::getFolderComicsFromLibrary(libraryId, folderId, false); + + std::sort(list.begin(), list.end(), [](LibraryItem *i1, LibraryItem *i2) { + auto c1 = static_cast(i1); + auto c2 = static_cast(i2); + + if (c1->info.number.isNull() && c2->info.number.isNull()) { + return naturalSortLessThanCI(c1->name, c2->name); + } else { + if (c1->info.number.isNull() == false && c2->info.number.isNull() == false) { + return c1->info.number.toInt() < c2->info.number.toInt(); + } else { + return c2->info.number.isNull(); + } + } + }); + + return list; +} + QList DBHelper::getFolderComicsFromLibrary(qulonglong libraryId, qulonglong folderId, bool sort) { QString libraryPath = DBHelper::getLibraries().getPath(libraryId); diff --git a/YACReaderLibrary/db_helper.h b/YACReaderLibrary/db_helper.h index fa2a8960a..63f3217d9 100644 --- a/YACReaderLibrary/db_helper.h +++ b/YACReaderLibrary/db_helper.h @@ -25,6 +25,7 @@ class DBHelper static QList getFolderSubfoldersFromLibrary(qulonglong libraryId, qulonglong folderId); static QList getFolderComicsFromLibrary(qulonglong libraryId, qulonglong folderId); static QList getFolderComicsFromLibrary(qulonglong libraryId, qulonglong folderId, bool sort); + static QList getFolderComicsFromLibraryForReading(qulonglong libraryId, qulonglong folderId); static quint32 getNumChildrenFromFolder(qulonglong libraryId, qulonglong folderId); static qulonglong getParentFromComicFolderId(qulonglong libraryId, qulonglong id); static ComicDB getComicInfo(qulonglong libraryId, qulonglong id); From b8ad99fcaa7ddc3eba35afbf2f5b3218fb44705e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Fri, 30 Apr 2021 09:52:31 +0200 Subject: [PATCH 128/141] Exract struct to reuse it --- .../server/controllers/v1/foldercontroller.cpp | 7 ------- .../controllers/v2/foldercontentcontroller_v2.cpp | 7 ------- common/qnaturalsorting.h | 11 +++++++++++ 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp b/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp index e31485430..11ae2a839 100644 --- a/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp +++ b/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp @@ -23,13 +23,6 @@ using stefanfrings::HttpResponse; using stefanfrings::HttpSession; using stefanfrings::Template; -struct LibraryItemSorter { - bool operator()(const LibraryItem *a, const LibraryItem *b) const - { - return naturalSortLessThanCI(a->name, b->name); - } -}; - FolderController::FolderController() { } void FolderController::service(HttpRequest &request, HttpResponse &response) diff --git a/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp index dd3d8918c..836fa5eed 100644 --- a/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp @@ -19,13 +19,6 @@ using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; using namespace std; -struct LibraryItemSorter { - bool operator()(const LibraryItem *a, const LibraryItem *b) const - { - return naturalSortLessThanCI(a->name, b->name); - } -}; - FolderContentControllerV2::FolderContentControllerV2() { } void FolderContentControllerV2::service(HttpRequest &request, HttpResponse &response) diff --git a/common/qnaturalsorting.h b/common/qnaturalsorting.h index 95a2275cb..3dfc393bb 100644 --- a/common/qnaturalsorting.h +++ b/common/qnaturalsorting.h @@ -13,4 +13,15 @@ bool naturalSortLessThanCI(const QString &left, const QString &right); bool naturalSortLessThanCIFileInfo(const QFileInfo &left, const QFileInfo &right); bool naturalSortLessThanCILibraryItem(LibraryItem *left, LibraryItem *right); +/* TODO, update to use the issue number once the iOS client supports it + * see DBHelper::getFolderComicsFromLibraryForReading + * NOTE, use this only in the server side for now, this way of sorting just matchs what's used in the iOS client + **/ +struct LibraryItemSorter { + bool operator()(const LibraryItem *a, const LibraryItem *b) const + { + return naturalSortLessThanCI(a->name, b->name); + } +}; + #endif From 5f3824ff3c33017e69eb565fcc064eee7723d185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Fri, 30 Apr 2021 09:53:35 +0200 Subject: [PATCH 129/141] Fix order when getting next/previous remote comics This sorting matches what the remote browser uses. --- .../server/controllers/v2/comiccontroller_v2.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.cpp index 273d275d5..4a32013f6 100644 --- a/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.cpp @@ -10,6 +10,8 @@ #include "comic_db.h" #include "comic.h" +#include "qnaturalsorting.h" + #include "QsLog.h" #include @@ -89,7 +91,10 @@ void ComicControllerV2::service(HttpRequest &request, HttpResponse &response) response.write(QString("libraryId:%1\r\n").arg(libraryId).toUtf8()); if (remoteComic) //send previous and next comics id { - QList siblings = DBHelper::getFolderComicsFromLibrary(libraryId, comic.parentId, true); + QList siblings = DBHelper::getFolderComicsFromLibrary(libraryId, comic.parentId, false); + + std::sort(siblings.begin(), siblings.end(), LibraryItemSorter()); + bool found = false; int i; for (i = 0; i < siblings.length(); i++) { From c3a99b19a5d4fcc12673063b27a79415c4d288cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20A=CC=81ngel=20San=20Marti=CC=81n?= Date: Sat, 8 May 2021 15:21:30 +0200 Subject: [PATCH 130/141] Fix library creation on 9.8.0 by adding missing `manga` field to `folder` --- YACReaderLibrary/db/data_base_management.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/YACReaderLibrary/db/data_base_management.cpp b/YACReaderLibrary/db/data_base_management.cpp index 3e41d77df..93c01af23 100644 --- a/YACReaderLibrary/db/data_base_management.cpp +++ b/YACReaderLibrary/db/data_base_management.cpp @@ -203,6 +203,8 @@ bool DataBaseManagement::createTables(QSqlDatabase &database) "numChildren INTEGER," "firstChildHash TEXT," "customImage TEXT," + //new 9.8 fields + "manga BOOLEAN DEFAULT 0," "FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE)"); success = success && queryFolder.exec(); From dbe1da58dc8054bb690e200d44296dac21dc848d Mon Sep 17 00:00:00 2001 From: Ruoh-Shoei LIN <56530472+LinRs@users.noreply.github.com> Date: Sat, 3 Apr 2021 18:47:54 +0000 Subject: [PATCH 131/141] Update Simplified Chinese GUI translation for YACReader & YACReaderLibrary --- YACReader/yacreader_zh.ts | 994 +++++++----- YACReaderLibrary/yacreaderlibrary_zh.ts | 1861 ++++++++++++++--------- 2 files changed, 1755 insertions(+), 1100 deletions(-) diff --git a/YACReader/yacreader_zh.ts b/YACReader/yacreader_zh.ts index ccc4774a1..48bad086e 100644 --- a/YACReader/yacreader_zh.ts +++ b/YACReader/yacreader_zh.ts @@ -4,689 +4,866 @@ ActionsShortcutsModel + None - 不存在 + BookmarksDialog - Close - 关闭 + + Lastest Page + 尾页 - Loading... - 加载中... + + Close + 关闭 + Click on any image to go to the bookmark - 单击任何图像即可转到书签 + 点击任意图片以跳转至相应书签位置 - Lastest Page - 最后一页 + + + Loading... + 载入中... EditShortcutsDialog - Shortcut in use - 快捷键使用中 + + Restore defaults + 恢复默认 - Restore defaults - 恢复默认设置 + + To change a shortcut, double click in the key combination and type the new keys. + 更改快捷键: 双击按键组合并输入新的映射. + Shortcuts settings 快捷键设置 - The shortcut "%1" is already assigned to other function - 快捷键“%1”已被其他功能占用 + + Shortcut in use + 快捷键被占用 - To change a shortcut, double click in the key combination and type the new keys. - 要更改快捷方式,请双击组合键并键入新键。 + + The shortcut "%1" is already assigned to other function + 快捷键 "%1" 已被映射至其他功能 FileComic - Format not supported - 不支持的文件格式 + + CRC error on page (%1): some of the pages will not be displayed correctly + 第 %1 页 CRC 校验失败: 部分页面将无法正确显示 - 7z not found - 7z 未找到 + + Unknown error opening the file + 打开文件时出现未知错误 - Unknown error opening the file - 打开文件出现未知错误 + + 7z not found + 未找到 7z - CRC error on page (%1): some of the pages will not be displayed correctly - 页面(%1)上CRC错误:某些页面无法正确显示 + + Format not supported + 不支持的文件格式 GoToDialog - Go To - - - - Go to... - 到... + + Page : + 页码 : - Total pages : - 总页码: + + Go To + 跳转 + Cancel 取消 - Page : - 页码: + + + Total pages : + 总页数: + + + + Go to... + 跳转至 ... GoToFlowToolBar + Page : - 页码: + 页码 : HelpAboutDialog - Help - 帮助 - - + About 关于 + + + Help + 帮助 + LogWindow + Log window - + 日志窗口 + &Pause - + 中止(&P) + &Save - + 保存(&S) + C&lear - + 清空(&l) + &Copy - + 复制(&C) + Level: - + 等级: + &Auto scroll - + 自动滚动(&A) MainWindowViewer - Go - 转到 + + &Open + 打开(&O) - Edit - 编辑 + + Open a comic + 打开漫画 - File - 文件 + + Open Folder + 打开文件夹 - Help - 帮助 + + Open image folder + 打开图片文件夹 + Save 保存 - View - 视图 + + + Save current page + 保存当前页面 - &File - &文件 + + Previous Comic + 上一个漫画 - &Next - &下一个 + + + + Open previous comic + 打开上一个漫画 - &Open - &打开 + + Next Comic + 下一个漫画 - Clear - 清除 + + + + Open next comic + 打开下一个漫画 - Close - 关闭 + + &Previous + 上一页(&P) - Open Comic - 打开漫画 + + + + Go to previous page + 转至上一页 - Go To - 转到 + + &Next + 下一页(&N) - Zoom+ - 放大 + + + + Go to next page + 转至下一页 - Zoom- - 缩小 + + Fit Width + 适合宽度 - Open image folder - 打开图片文件夹 + + Fit image to height + 缩放图片以适应高度 - Size down magnifying glass - 放大镜缩小 + + Open latest comic + 打开最近的漫画 - Zoom out magnifying glass - 缩小放大镜 + + Open the latest comic opened in the previous reading session + 打开最近阅读漫画 - Open latest comic - 打开最新的漫画 + + Clear open recent list + 清空最近访问列表 - Autoscroll up - 向上自动滚动 + + Fit Height + 适应高度 - Set bookmark - 设置书签 + + Fit image to width + 缩放图片以适应宽度 - page_%1.jpg - + + Rotate image to the left + 向左旋转图片 - Autoscroll forward, vertical first - 向前自动滚动,垂直优先 + + Rotate image to the right + 向右旋转图片 - Switch to double page mode - 切换到双页模式 + + Double page mode + 双页模式 - Save current page - 保存当前页面 + + Switch to double page mode + 切换至双页模式 - Size up magnifying glass - 放大镜放大 + + Go To + 跳转 - Double page mode - 双页模式 + + Go to page ... + 跳转至页面 ... - Move up - 向上移动 + + Options + 选项 - Switch Magnifying glass - 切换放大镜 + + YACReader options + YACReader 选项 - Open Folder - 打开文件夹 + + + Help + 帮助 - Comics - 漫画 + + Help, About YACReader + 帮助, 关于 YACReader - Fit Height - 适合高度 + + Magnifying glass + 放大镜 - Autoscroll backward, vertical first - 向后自动滚动,垂直优先 + + Switch Magnifying glass + 切换放大镜 - Comic files - 漫画文件 + + Set bookmark + 设置书签 - Not now - 现在不要 + + Set a bookmark on the current page + 在当前页面设置书签 - Go to the first page - 转到第一页 + + Show bookmarks + 显示书签 - Go to previous page - 转到上一页 + + Show the bookmarks of the current comic + 显示当前漫画的书签 - Window - 窗口 + + Show keyboard shortcuts + 显示键盘快捷键 - Open the latest comic opened in the previous reading session - 打开上一个阅读环节中最新的漫画 + + Show Info + 显示信息 - Open a comic - 打开一本漫画 + + Close + 关闭 - Image files (*.jpg) - 图片文件(*.jpg) + + Show Dictionary + 显示字典 - Next Comic - 下一本漫画 + + Always on top + 总在最上 - Fit Width - 适合宽度 + + Show full size + 显示全尺寸 - Options - 选项 + + New instance + 新建实例 - Show Info - 显示信息 + + Clear + 清空 - Open folder - 打开文件夹 + + Fit to page + 适应页面 - Go to page ... - 转到页面... + + Reset zoom + 重置缩放 - Magnifiying glass - 放大镜 + + Show zoom slider + 显示缩放滑块 - Fit image to width - 使图像适合宽度度 + + Zoom+ + 放大 - Toggle fullscreen mode - 切换全屏模式 + + Zoom- + 缩小 - Toggle between fit to width and fit to height - 在适合宽度和适合高度之间切换 + + Double page manga mode + 双页漫画模式 - Move right - 向右移动 + + Reverse reading order in double page mode + 双页模式 (逆序阅读) - Zoom in magnifying glass - 放大放大镜 + + Show go to flow + 显示Go to flow - Open recent - 打开最近 + + Edit shortcuts + 编辑快捷键 - Reading - 阅读 + + &File + 文件(&F) - &Previous - &上一个 + + + Open recent + 最近打开的文件 - Autoscroll forward, horizontal first - 向前自动滚动,水平优先 + + File + 文件 - Go to next page - 转到下一页 + + Edit + 编辑 - Show keyboard shortcuts - 显示键盘快捷键 + + View + 查看 - Double page manga mode - 双页漫画模式 + + Go + 转到 - There is a new version available - 发现新版本 + + Window + 窗口 - Autoscroll down - 向下自动滚动 + + + Open Comic + 打开漫画 - Open next comic - 打开下一本曼胡 + + + Comic files + 漫画文件 - Remind me in 14 days - 在14天内提醒我 + + Open folder + 打开文件夹 - Fit to page - 适合页面 + + Image files (*.jpg) + 图像文件 (*.jpg) - Show bookmarks - 显示书签 + + page_%1.jpg + page_%1.jpg - Open previous comic - 打开上一本漫画 + + Comics + 漫画 - Rotate image to the left - 向左旋转图像 + + Toggle fullscreen mode + 切换全屏模式 - Fit image to height - 使图像适合高度 + + Hide/show toolbar + 隐藏/显示 工具栏 - Reset zoom - 重置缩放 + + General + 常规 - Show the bookmarks of the current comic - 显示当前漫画的书签 + + Size up magnifying glass + 增大放大镜尺寸 - Show Dictionary - 显示字典 + + Size down magnifying glass + 减小放大镜尺寸 - Move down - 向下移动 + + Zoom in magnifying glass + 增大缩放级别 - Move left - 向左移动 + + Zoom out magnifying glass + 减小缩放级别 - Reverse reading order in double page mode - 双页模式下反向阅读 + + Magnifiying glass + 放大镜 - YACReader options - YACReader 选项 + + Toggle between fit to width and fit to height + 切换显示为"适应宽度"或"适应高度" - Clear open recent list - 清除最近的清单 + + Page adjustement + 页面调整 - Help, About YACReader - 帮助,关于YACReader + + Autoscroll down + 向下自动滚动 - Show go to flow - 显示流动展示 + + Autoscroll up + 向上自动滚动 - Previous Comic - 上一本漫画 + + Autoscroll forward, horizontal first + 向前自动滚动,水平优先 - Show full size - 显示完整尺寸 + + Autoscroll backward, horizontal first + 向后自动滚动,水平优先 - Hide/show toolbar - 隐藏/显示工具栏 + + Autoscroll forward, vertical first + 向前自动滚动,垂直优先 - Magnifying glass - 放大镜 + + Autoscroll backward, vertical first + 向后自动滚动,垂直优先 - Edit shortcuts - 编辑快捷键 + + Move down + 向下移动 - General - 常规 + + Move up + 向上移动 - Set a bookmark on the current page - 在当前页面上设置书签 + + Move left + 向左移动 - Page adjustement - 页面调整 + + Move right + 向右移动 - Show zoom slider - 显示缩放滑块 + + Go to the first page + 转到第一页 + Go to the last page 转到最后一页 - Do you want to download the new version? - 你要下载新版本吗? + + Reading + 阅读 - Rotate image to the right - 向右旋转图像 + + There is a new version available + 有新版本可用 - Always on top - 总在最前面 + + Do you want to download the new version? + 你要下载新版本吗? - Autoscroll backward, horizontal first - 向后自动滚动,水平优先 + + Remind me in 14 days + 14天后提醒我 - New instance - + + Not now + 现在不 OptionsDialog - Gamma - 伽玛 - - - Reset - 重置 + + "Go to flow" size + "Go to flow" 尺寸 + My comics path 我的漫画路径 - Image adjustment - 图片调整 - - - "Go to flow" size - “流动展示”尺寸 + + Background color + 背景颜色 + Choose 选择 - Image options - 图片选项 + + Quick Navigation Mode + 快速导航模式 - Contrast - 对比 + + Disable mouse over activation + 禁用鼠标激活 - Options - 选项 + + Restart is needed + 需要重启 - Comics directory - 漫画目录 + + Brightness + 亮度 - Quick Navigation Mode - 快速导航模式 + + Contrast + 对比度 - Background color - 背景颜色 + + Gamma + Gamma值 - Disable mouse over activation - 禁用鼠标活动 + + Reset + 重置 - Page Flow - 页面流 + + Image options + 图片选项 - General - 常规 + + Fit options + 适应项 - Brightness - 亮度 + + Enlarge images to fit width/height + 放大图片以适应宽度/高度 - Restart is needed - 需要重启 + + Double Page options + 双页选项 - Fit options - + + Show covers as single page + 显示封面为单页 - Enlarge images to fit width/height - + + General + 常规 - Double Page options - + + Page Flow + 页面流 - Show covers as single page - + + Image adjustment + 图像调整 + + + + Options + 选项 + + + + Comics directory + 漫画目录 QObject + 7z lib not found - 未找到 7z lib + 未找到 7z 库文件 + unable to load 7z lib from ./utils - 无法从./utils加载7z lib + 无法从 ./utils 载入 7z 库文件 + Trace - + 追踪 + Debug - + 除错 + Info - + 信息 + Warning - + 警告 + Error - + 错误 + Fatal - + 严重错误 QsLogging::LogWindowModel + Time - + 时间 + Level - + 等级 + Message - + 信息 QsLogging::Window + &Pause - + 中止(&P) + &Resume - + 恢复(&R) + Save log - + 保存日志 + Log file (*.log) - + 日志文件 (*.log) ShortcutsDialog - Close - 关闭 - - + YACReader keyboard shortcuts YACReader 键盘快捷键 + + Close + 关闭 + + + Keyboard Shortcuts 键盘快捷键 @@ -694,86 +871,109 @@ Viewer - Page not available! - 页面不可用! + + + Press 'O' to open comic. + 按下 'O' 以打开漫画. - Press 'O' to open comic. - 按下 'O' 键打开漫画。 + + Not found + 未找到 - Error opening comic - 打开漫画出错 + + Comic not found + 未找到漫画 - Cover! - 封面! + + Error opening comic + 打开漫画时发生错误 + CRC Error - CRC 出错 + CRC 校验失败 - Comic not found - 未找到漫画 + + Loading...please wait! + 载入中... 请稍候! - Not found - 未找到 + + Page not available! + 页面不可用! - Last page! - 最后一页! + + Cover! + 封面! - Loading...please wait! - 加载中...请稍后! + + Last page! + 尾页! YACReader::WhatsNewDialog + Close - 关闭 + 关闭 YACReaderFieldEdit - Restore to default - 恢复默认设置 + + + Click to overwrite + 点击以覆盖 - Click to overwrite - 点击覆盖 + + Restore to default + 恢复默认 YACReaderFieldPlainTextEdit - Restore to default - 恢复默认设置 + + + + + Click to overwrite + 点击以覆盖 - Click to overwrite - 点击覆盖 + + Restore to default + 恢复默认 YACReaderFlowConfigWidget - CoverFlow look - 封面流动展示 + + How to show covers: + 封面显示方式: - How to show covers: - 封面显示: + + CoverFlow look + 封面流 + Stripe look 条状 + Overlapped Stripe look 重叠条状 @@ -781,124 +981,153 @@ YACReaderGLFlowConfigWidget - Zoom - 缩放 + + Presets: + 预设: - Light - 亮度 + + Classic look + 经典 - Show advanced settings - 高级设置 + + Stripe look + 条状 + + + + Overlapped Stripe look + 重叠条状 + + + + Modern look + 现代 + Roulette look 轮盘 - Cover Angle - 封面角度 + + Show advanced settings + 显示高级选项 - Stripe look - 条状 + + Custom: + 自定义: - Position - 位置 + + View angle + 视角 - Z offset - Z位移 + + Position + 位置 - Y offset - Y位移 + + Cover gap + 封面间距 + Central gap - 展示区间距 + 中心间距 - Presets: - 预设: + + Zoom + 缩放 - Overlapped Stripe look - 重叠条状 + + Y offset + Y位移 - Modern look - 现代 + + Z offset + Z位移 - View angle - 视角 + + Cover Angle + 封面角度 - Max angle - 最大角度 + + Visibility + 透明度 - Custom: - 自定义: + + Light + 亮度 - Classic look - 经典 + + Max angle + 最大角度 - Cover gap - 封面间距 + + Low Performance + 低性能 + High Performance - - - - Performance: - 性能: + 高性能 + Use VSync (improve the image quality in fullscreen mode, worse performance) - 使用VSync(在全屏模式下提高图像质量,性能更差) - - - Visibility - 透明度 + 使用VSync (在全屏模式下提高图像质量, 性能更差) - Low Performance - + + Performance: + 性能: YACReaderOptionsDialog + Save 保存 - Use hardware acceleration (restart needed) - 使用硬件加速(需要重启) - - + Cancel 取消 + + Edit shortcuts + 编辑快捷键 + + + Shortcuts 快捷键 - Edit shortcuts - 编辑快捷键 + + Use hardware acceleration (restart needed) + 使用硬件加速 (需要重启) YACReaderSlider + Reset 重置 @@ -906,20 +1135,25 @@ YACReaderTranslator - clear - 清除 - - - Service not available - 服务器无响应 + + YACReader translator + YACReader 翻译 + + Translation 翻译 - YACReader translator - YACReader 翻译工具 + + clear + 清空 + + + + Service not available + 服务不可用 diff --git a/YACReaderLibrary/yacreaderlibrary_zh.ts b/YACReaderLibrary/yacreaderlibrary_zh.ts index 4d85a1b4a..aa48874dd 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh.ts @@ -4,212 +4,256 @@ ActionsShortcutsModel + None - 不存在 + AddLabelDialog - red - + + Label name: + 标签名称: - blue - + + Choose a color: + 选择标签颜色: - dark - 深色 + + red + - cyan - + + orange + - pink - + + yellow + + green 绿 - light - 浅色 + + cyan + - white - + + blue + - Choose a color: - 选择标签颜色: + + violet + 紫罗兰 - accept - 接受 + + purple + - cancel - 取消 + + pink + - orange - + + white + - purple - + + light + 浅色 - violet - 紫罗兰 + + dark + 深色 - yellow - + + accept + 接受 - Label name: - 标签名称: + + cancel + 取消 AddLibraryDialog - Add - 添加 + + Comics folder : + 漫画文件夹: - Add an existing library - 添加一个现有库 + + Library name : + Library Name : + 库名: + + Add + 添加 + + + Cancel 取消 - Comics folder : - 漫画文件夹: + + Add an existing library + 添加一个现有库 + + + ApiKeyDialog - Library Name : - 库名: + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要拥有自己的API密匙才能够连接Comic Vine. 你可以通过这个链接获得一个免费的<a href="http://www.comicvine.com/api/">API</a>密匙 - Library name : - + + Paste here your Comic Vine API key + 在此粘贴你的Comic Vine API - - - ApiKeyDialog + Accept 接受 + Cancel 取消 - - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - 你需要拥有自己的API密匙才能够连接Comic Vine. 你可以通过这个链接获得一个免费的<a href="http://www.comicvine.com/api/">API</a>密匙 - - - Paste here your Comic Vine API key - 在此粘贴你的Comic Vine API - ClassicComicsView + Hide comic flow - 隐藏漫画流动预览 + 隐藏漫画流 ComicInfoView + Authors - 作者 + 作者 + writer - + 作者 + penciller - + 线稿 + inker - + 墨稿 + colorist - + 上色 + letterer - + 文本 + cover artist - + 封面设计 + Publisher - + 出版者 + color - + 颜色 + b/w - + 黑白 + Characters - + 角色 ComicModel + + yes + + + + no - yes - + + Title + 标题 - Read - 阅读 + + File Name + 文件名 - Size - 大小 + + Pages + 页数 - Pages - 页码 + + Size + 大小 - Title - 标题 + + Read + 阅读 + Current Page 当前页 - File Name - 文件名 - - + Rating 评分 @@ -217,123 +261,158 @@ ComicVineDialog + + skip + 忽略 + + + back 返回 + next 下一步 - skip - 忽略 + + search + 搜索 + close 关闭 - Retrieving tags for : %1 - 正在检索标签: %1 - - - Looking for comic... - 搜索中... - - - search - 搜索 - - + + + + + Looking for volume... - 搜索中... + 搜索卷... + + comic %1 of %2 - %3 第 %1 本 共 %2 本 - %3 + %1 comics selected 已选择 %1 本漫画 + Error connecting to ComicVine - ComicVine 连接错误 + ComicVine 连接时出错 + + + + + Retrieving tags for : %1 + 正在检索标签: %1 + Retrieving volume info... - 正在检索卷信息... + 正在接收卷信息... + + + + Looking for comic... + 搜索漫画中... CreateLibraryDialog - Create new library - 创建新的文库 + + Comics folder : + 漫画文件夹: - Cancel - 取消 + + Library Name : + 库名: + Create 创建 - Create a library could take several minutes. You can stop the process and update the library later for completing the task. - 创建一个新的文件库可能需要几分钟时间,您可以先停止该进程,稍后可以通过更新文件库选项来更新数据。 - - - The selected path does not exist or is not a valid path. Be sure that you have write access to this folder - 所选路径不存在或不是有效路径. 确保您具有此文件夹的写入权限 + + Cancel + 取消 - Comics folder : - 漫画文件夹: + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + 创建一个新的文件库可能需要几分钟时间,您可以先停止该进程,稍后可以通过更新文件库选项来更新数据。 - Library Name : - 库名: + + Create new library + 创建新的漫画库 + Path not found 未找到路径 + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + 所选路径不存在或不是有效路径. 确保您具有此文件夹的写入权限 + EditShortcutsDialog - Shortcut in use - 快捷键已使用 + + Restore defaults + 恢复默认 - Restore defaults - 恢复默认设置 + + To change a shortcut, double click in the key combination and type the new keys. + 更改快捷键: 双击按键组合并输入新的映射. + Shortcuts settings - 编辑快捷键 + 快捷键设置 - The shortcut "%1" is already assigned to other function - 快捷键 "%1" 已分配给其他功能 + + Shortcut in use + 快捷键被占用 - To change a shortcut, double click in the key combination and type the new keys. - 要更改快捷键,请双击组合键并键入新键。 + + The shortcut "%1" is already assigned to other function + 快捷键 "%1" 已被映射至其他功能 EmptyFolderWidget - Empty folder - 空文件夹 - - + + Subfolders in this folder 建立子文件夹 + + Empty folder + 空文件夹 + + + Drag and drop folders and comics here 拖动文件夹或者漫画到这里 @@ -341,6 +420,7 @@ EmptyLabelWidget + This label doesn't contain comics yet 此标签尚未包含漫画 @@ -348,68 +428,84 @@ EmptyReadingListWidget + This reading list does not contain any comics yet + This reading list doesn't contain any comics yet 此阅读列表尚未包含任何漫画 ExportComicsInfoDialog + Output file : 输出文件: - Destination database name - 目标数据库名称 + + Create + 创建 + Cancel 取消 - Create - 创建 + + Export comics info + 导出漫画信息 - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - 输出文件的选定路径不存在或不是有效路径. 确保您具有此文件夹的写入权限 + + Destination database name + 目标数据库名称 - Export comics info - 导出漫画信息 + + Problem found while writing + 写入时出现问题 - Problem found while writing - 数据库导出失败 + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 选定的输出文件路径不存在或路径无效. 确保您具有此文件夹的写入权限 ExportLibraryDialog - Cancel - 取消 + + Output folder : + 输出文件夹: + Create 创建 - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - 输出文件的选定路径不存在或不是有效路径. 确保您具有此文件夹的写入权限 + + Cancel + 取消 - Output folder : - 输出文件夹: + + Create covers package + 创建封面包 + Problem found while writing - 导出失败 + 写入时出现问题 - Create covers package - 创建封面包 + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 选定的输出文件路径不存在或路径无效. 确保您具有此文件夹的写入权限 + Destination directory 目标目录 @@ -417,25 +513,30 @@ FileComic - Format not supported - 不支持的格式 + + CRC error on page (%1): some of the pages will not be displayed correctly + 第 %1 页 CRC 校验失败: 部分页面将无法正确显示 - 7z not found - 未找到7z文件 + + Unknown error opening the file + 打开文件时出现未知错误 - Unknown error opening the file - 未知错误 + + 7z not found + 未找到 7z - CRC error on page (%1): some of the pages will not be displayed correctly - 页面(%1)CRC错误:某些页面无法正确显示 + + Format not supported + 不支持的文件格式 GridComicsView + Show info 显示信息 @@ -443,33 +544,40 @@ HelpAboutDialog - Help - 帮助 - - + About 关于 + + + Help + 帮助 + ImportComicsInfoDialog - Cancel - 取消 - - - Import - 导入 + + Import comics info + 导入漫画信息 + Info database location : 数据库地址: - Import comics info - 导入漫画信息 + + Import + 导入 + + + + Cancel + 取消 + Comics info file (*.ydb) 漫画信息文件(*.ydb) @@ -477,571 +585,709 @@ ImportLibraryDialog - Destination folder : - 目标文件夹: + + Library Name : + 库名: - Cancel - 取消 - - - Unpack - 解压 + + Package location : + 打包地址: - Compresed library covers (*.clc) - 文件库封面压缩(*.clc) + + Destination folder : + 目标文件夹: - Package location : - 打包地址: + + Unpack + 解压 - Library Name : - 库名: + + Cancel + 取消 + Extract a catalog 提取目录 + + + Compresed library covers (*.clc) + 已压缩的文件库封面 (*.clc) + ImportWidget + stop 停止 + + Some of the comics being added... + 正在添加漫画... + + + Importing comics 正在导入漫画 + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <p>YACReaderLibrary现在正在创建一个新库。</p><p>这可能需要几分钟时间,您可以先停止该进程,稍后可以通过更新文件库选项来更新数据。</p> - Some of the comics being added... - 正在添加漫画... - - + Updating the library 正在更新文库 + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <p>正在更新当前文件库。要获得更快的更新,请经常更新您的文件库。</p><p>您可以停止该进程,稍后继续更新操作。</p> + Upgrading the library - + 正在更新文库 + <p>The current library is being upgraded, please wait.</p> - + <p>正在更新当前漫画库, 请稍候.</p> LibraryWindow - Edit - 编辑 + + YACReader Library + YACReader 库 - The selected folder doesn't contain any library. - 所选文件夹不包含任何库。 + + Library + - This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - 此库是使用旧版本的YACReaderLibrary创建的. 它需要更新. 现在更新? + + Create a new library + 创建一个新的库 - Comic - 漫画 + + Open an existing library + 打开现有的库 - Folder name: - 文件夹名称: + + + Export comics info + 导出漫画信息 - The selected folder and all its contents will be deleted from your disk. Are you sure? - 所选文件夹及其所有内容将从磁盘中删除。 你确定吗? + + + Import comics info + 导入漫画信息 - Update current folder - 更新当前文件夹 + + Pack covers + 打包封面 - Error opening the library - 打开库时出错 + + Pack the covers of the selected library + 打包所选库的封面 - Show/Hide marks - 显示/隐藏标记 + + Unpack covers + 解压封面 - YACReader not found - YACReader 未找到 + + Unpack a catalog + 解压目录 - Show comics server options dialog - 显示漫画服务器选项对话框 + + Update library + 更新库 - There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - 尝试删除所选文件夹时出现问题。 请检查写入权限,并确保没有其他应用程序在使用这些文件夹或文件。 + + Update current library + 更新当前库 - Remove current library from your collection - 从您的集合中移除当前库 + + Rename library + 重命名库 - Set comic as read - 漫画设为已读 + + Rename current library + 重命名当前库 - Rename list name - 重命名列表 + + Remove library + 移除库 - Add selected comics to favorites list - 将所选漫画添加到收藏夹列表 + + Remove current library from your collection + 从您的集合中移除当前库 - Remove and delete metadata - 移除并删除元数据 + + Open current comic + 打开当前漫画 - YACReader not found, YACReader should be installed in the same folder as YACReaderLibrary. - 未找到YACReader,YACReader应安装在与YACReaderLibrary相同的文件夹中。 + + Open current comic on YACReader + 用YACReader打开漫画 - Old library - 旧的库 + + Save selected covers to... + 选中的封面保存到... - Update cover - 更新封面 + + Save covers of the selected comics as JPG files + 保存所选的封面为jpg - Rename any selected labels or lists - 重命名任何选定的标签或列表 + + + Set as read + 设为已读 - Set as completed - 设为已完成 + + Set comic as read + 漫画设为已读 - There was an error accessing the folder's path - 访问文件夹的路径时出错 + + + Set as unread + 设为未读 - Library - + + Set comic as unread + 漫画设为未读 - Add new folder to the current library - 在当前库下添加新的文件夹 + + Show/Hide marks + 显示/隐藏标记 - Comics will only be deleted from the current label/list. Are you sure? - 漫画只会从当前标签/列表中删除。 你确定吗? + + Collapse all nodes + 折叠所有节点 - Rename current library - 重命名当前库 + + Assign current order to comics + 将当前序号分配给漫画 + + + + Library not available + Library ' + 库不可用 + + Fullscreen mode on/off 全屏模式 开/关 - This library was created with a newer version of YACReaderLibrary. Download the new version now? - 此库是使用较新版本的YACReaderLibrary创建的。 立即下载新版本? + + + Set as manga + 设为日漫 - Moving comics... - 移动漫画中... + + Set issue as manga + Set issue as manga - Open current comic on YACReader - 用YACReader打开漫画 + + Set as normal + 设置为正常向 - Update current library - 更新当前库 + + Set issue as normal + 设置发行状态为正常发行 - Copying comics... - 复制漫画中... + + Help, About YACReader + 帮助, 关于 YACReader - Library '%1' is no longer available. Do you want to remove it? - 库 '%1' 不再可用。 你想删除它吗? + + + Delete folder + 删除文件夹 - Update library - 更新库 + + Select root node + 选择根节点 - Open folder... - 打开文件夹... + + Expand all nodes + 展开所有节点 - Do you want remove - 你想要删除 + + Show options dialog + 显示选项对话框 - Set as uncompleted - 设为未完成 + + Show comics server options dialog + 显示漫画服务器选项对话框 - Error in path - 路径错误 + + Open folder... + 打开文件夹... - Reset comic rating - 重置漫画评分 + + Set as uncompleted + 设为未完成 - Error updating the library - 更新库时出错 + + Set as completed + 设为已完成 - Folder - 文件夹 + + Set as comic + 设置为漫画 - The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - 所选项目将被删除,您的漫画或文件夹将不会从您的磁盘中删除。 你确定吗? + + Open containing folder... + 打开包含文件夹... - Expand all nodes - 展开所有节点 + + Reset comic rating + 重置漫画评分 - Delete current folder from disk - 从磁盘上删除当前文件夹 + + Select all comics + 全选漫画 - List name: - 列表名称: + + Edit + 编辑 - Add to... - 添加到... + + Update cover + 更新封面 - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - 库 '%1' 是通过旧版本的YACReaderLibrary创建的。 必须再次创建。 你想现在创建吗? + + Delete selected comics + 删除所选的漫画 - Pack covers - 打包封面 + + Download tags from Comic Vine + 从 Comic Vine 下载标签 - Save covers - 保存封面 + + Edit shortcuts + 编辑快捷键 - Change between comics views - 漫画视图之间的变化 + + Update folder + 更新文件夹 - Remove current reading list from the library - 从当前库移除阅读列表 + + Update current folder + 更新当前文件夹 - Add new reading lists + + Add new reading list 添加新的阅读列表 - You are adding too many libraries. - -You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. - -YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - 您添加的库太多了。 - -一般情况只需要一个顶级的库,您可以使用左侧边栏中的文件夹功能来进行分类管理。 - -YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低的库数量来提升性能。 - - - Set as read - 设为已读 - - - Assign comics numbers - 分配漫画编号 - - - Delete selected comics - 删除所选的漫画 - - - Export comics info - 导出漫画信息 - - - Show options dialog - 显示选项对话框 + + Add a new reading list to the current library + 在当前库添加新的阅读列表 - Please, select a folder first - 请先选择一个文件夹 + + Remove reading list + 移除阅读列表 - Create a new library - 创建一个新的库 + + Remove current reading list from the library + 从当前库移除阅读列表 - Library not available - 库不可用 + + Add new label + 添加新标签 - Import comics info - 导入漫画信息 + + Add a new label to this library + 在当前库添加标签 - The current library can't be udpated. Check for write write permissions on: - 无法更新当前库。 检查读写权限: + + Rename selected list + 重命名列表 - There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - 尝试删除所选漫画时出现问题。 请检查所选文件或包含文件夹中的写入权限。 + + Rename any selected labels or lists + 重命名任何选定的标签或列表 - Add new reading list - 添加新的阅读列表 + + Add to... + 添加到... - Save selected covers to... - 选中的封面保存到... + + Favorites + 收藏夹 - Open current comic - 打开当前漫画 + + Add selected comics to favorites list + 将所选漫画添加到收藏夹列表 - YACReader Library - YACReader库 + + Folder + 文件夹 - Add a new reading list to the current library - 在当前库添加新的阅读列表 + + Comic + 漫画 - Error creating the library - 创建库时出错 + + Upgrade failed + 更新失败 - Update failed - 更新失败 + + There were errors during library upgrade in: + 漫画库更新时出现错误: - You are adding too many libraries. - 您添加的库太多了。 + + Update needed + 需要更新 - Update folder - 更新文件夹 + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + 此库是使用旧版本的YACReaderLibrary创建的. 它需要更新. 现在更新? - Unpack covers - 解压封面 + + Download new version + 下载新版本 - Update needed - 需要更新 + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + 此库是使用较新版本的YACReaderLibrary创建的。 立即下载新版本? - Open an existing library - 打开现有的库 + + Library '%1' is no longer available. Do you want to remove it? + 库 '%1' 不再可用。 你想删除它吗? - Show or hide read marks - 显示或隐藏阅读标记 + + Old library + 旧的库 - Library name already exists - 库名已存在 + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 库 '%1' 是通过旧版本的YACReaderLibrary创建的。 必须再次创建。 你想现在创建吗? - There is another library with the name '%1'. - 已存在另一个名为'%1'的库。 + + + Copying comics... + 复制漫画中... - Remove reading list - 移除阅读列表 + + + Moving comics... + 移动漫画中... - Delete folder - 删除文件夹 + + Folder name: + 文件夹名称: - Assign numbers starting in: - 从以下位置开始分配编号: + + No folder selected + 没有选中的文件夹 - Download new version - 下载新版本 + + Please, select a folder first + 请先选择一个文件夹 - Delete comics - 删除漫画 + + Error in path + 路径错误 - Add new folder - 添加新的文件夹 + + There was an error accessing the folder's path + 访问文件夹的路径时出错 - Select all comics - 全选漫画 + + The selected folder and all its contents will be deleted from your disk. Are you sure? + 所选文件夹及其所有内容将从磁盘中删除。 你确定吗? - Assign current order to comics - 将当前序号分配给漫画 + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + 尝试删除所选文件夹时出现问题。 请检查写入权限,并确保没有其他应用程序在使用这些文件夹或文件。 - Pack the covers of the selected library - 打包所选库的封面 + + Add new reading lists + 添加新的阅读列表 - Help, About YACReader - 帮助, 关于YACReader + + + List name: + 列表名称: - Collapse all nodes - 折叠所有节点 + + Delete list/label + 删除 列表/标签 - Favorites - 收藏夹 + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + 所选项目将被删除,您的漫画或文件夹将不会从您的磁盘中删除。 你确定吗? - Rename selected list + + Rename list name 重命名列表 - Delete list/label - 删除 列表/标签 + + Save covers + 保存封面 - Set comic as unread - 漫画设为未读 + + You are adding too many libraries. + 您添加的库太多了。 - Edit shortcuts - 编辑快捷键 + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + 您添加的库太多了。 + +一般情况只需要一个顶级的库,您可以使用左侧边栏中的文件夹功能来进行分类管理。 + +YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低的库数量来提升性能。 - Select root node - 选择根节点 + + + YACReader not found + YACReader 未找到 - No folder selected - 没有选中的文件夹 + + Library not found + 未找到库 - Unpack a catalog - 解压目录 + + The selected folder doesn't contain any library. + 所选文件夹不包含任何库。 - All the selected comics will be deleted from your disk. Are you sure? - 所有选定的漫画都将从您的磁盘中删除。你确定吗? + + Are you sure? + 你确定吗? - Download tags from Comic Vine - 从 Comic Vine 下载标签 + + Do you want remove + 你想要删除 - Remove comics - 移除漫画 + + library? + 库? - Add a new label to this library - 在当前库添加标签 + + Remove and delete metadata + 移除并删除元数据 - Set as unread - 设为未读 + + Assign comics numbers + 分配漫画编号 - Library not found - 未找到库 + + Assign numbers starting in: + 从以下位置开始分配编号: - Rename library - 重命名库 + + + Unable to delete + 无法删除 - Remove library - 移除库 + + Show or hide read marks + 显示或隐藏阅读标记 - Open containing folder... - 打开包含文件夹... + + + Add new folder + 添加新的文件夹 - Add new label - 添加新标签 + + Add new folder to the current library + 在当前库下添加新的文件夹 - Unable to delete - 无法删除 + + Delete current folder from disk + 从磁盘上删除当前文件夹 - library? - 库? + + + Change between comics views + 漫画视图之间的变化 - Save covers of the selected comics as JPG files - 保存所选的封面为jpg + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + 未找到YACReader. YACReader应安装在与YACReaderLibrary相同的文件夹中. - Are you sure? - 你确定吗? + + YACReader not found. There might be a problem with your YACReader installation. + 未找到YACReader. YACReader的安装可能有问题. - Set as manga - + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + 尝试删除所选漫画时出现问题。 请检查所选文件或包含文件夹中的写入权限。 - Set issue as manga - + + Error creating the library + 创建库时出错 - Set as normal - + + Error updating the library + 更新库时出错 - Set issue as normal - + + Error opening the library + 打开库时出错 - Set as comic - + + Delete comics + 删除漫画 - Upgrade failed - + + All the selected comics will be deleted from your disk. Are you sure? + 所有选定的漫画都将从您的磁盘中删除。你确定吗? - There were errors during library upgrade in: - + + Remove comics + 移除漫画 - YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - + + Comics will only be deleted from the current label/list. Are you sure? + 漫画只会从当前标签/列表中删除。 你确定吗? - YACReader not found. There might be a problem with your YACReader installation. - + + Library name already exists + 库名已存在 + + + + There is another library with the name '%1'. + 已存在另一个名为'%1'的库。 LocalComicListModel + file name 文件名 @@ -1049,411 +1295,508 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 LogWindow + Log window - + 日志窗口 + &Pause - + 中止(&P) + &Save - + 保存(&S) + C&lear - + 清空(&l) + &Copy - + 复制(&C) + Level: - + 等级: + &Auto scroll - + 自动滚动(&A) NoLibrariesWidget - create your first library - 创建一个文库 - - + You don't have any libraries yet 你还没有文件库 + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何文件夹中创建文件库,YACReaderLibrary将导入此文件夹中的所有漫画和文件夹。如果已有文件库,则可以打开它们。</p><p>您可以把YACReader当初独立应用来阅读计算机上的漫画。</p> + + create your first library + 创建一个文库 + + + add an existing one - 现有基础上添加 + 添加一个现有库 OptionsDialog - Restore defautls - 恢复默认值 - - - Background - 背景 + + Tray icon settings (experimental) + 托盘图标设置 (实验特性) - Blur level - 模糊 + + Close to tray + 关闭至托盘 - Enable background image - 启用背景图片 + + Start into the system tray + 启动至系统托盘 - Options - 设置 + + Edit Comic Vine API key + 编辑Comic Vine API 密匙 + Comic Vine API key Comic Vine API 密匙 - Edit Comic Vine API key - 编辑Comic Vine API 密匙 + + Enable background image + 启用背景图片 + Opacity level 透明度 - General - 常规 + + Blur level + 模糊 + Use selected comic cover as background - 使用漫画封面做背景 + 使用选定的漫画封面做背景 - Comic Flow - 漫画流展示 + + Restore defautls + 恢复默认值 - Grid view - 网格视图 + + Background + 背景 - Tray icon settings (experimental) - + + Display continue reading banner + 显示继续阅读横幅 - Close to tray - + + Continue reading + 继续阅读 - Start into the system tray - + + Comic Flow + 漫画流 - Display continue reading banner - + + Grid view + 网格视图 - Continue reading - + + General + 常规 + + + + Options + 选项 PropertiesDialog - Day: - 日: + + General info + 基本信息 - Plot - 情节 + + Authors + 作者 - Size: - 大小: + + Publishing + 出版 - Year: - 年: + + Plot + 情节 - Inker(s): - 墨稿: + + Cover page + 封面 - Publishing - 出版 + + Title: + 标题: - Publisher: - 发行人: + + + of: + of: - General info - 基本信息 + + Issue number: + 发行数量: - Color/BW: - 颜色/BW: + + Volume: + 卷: - Edit selected comics information - 编辑选中的漫画信息 + + Arc number: + 世界线数量: - Penciller(s): - 线稿: + + Story arc: + 故事线: - Colorist(s): - 上色: + + Genre: + Genere: + 类型: - Genre: - 类型: + + Size: + 大小: - Issue number: - 发行数量: + + Writer(s): + 作者: - Month: - 月: + + Penciller(s): + 线稿: - Notes: - 笔记: + + Inker(s): + 墨稿: - Synopsis: - 概要: + + Colorist(s): + 上色: - Title: - 标题: + + Letterer(s): + 文本: - Not found - 未找到 + + Cover Artist(s): + 封面设计: - Characters: - 特点: + + Day: + 日: - Authors - 作者 + + Month: + 月: - Age rating: - 年龄等级: + + Year: + 年: - Story arc: - 故事线: + + Publisher: + 出版者: - Writer(s): - 作者: + + Format: + 格式: - Comic not found. You should update your library. - 未找到漫画,请先更新您的文件库. + + Color/BW: + 彩色/黑白: - Edit comic information - 编辑漫画信息 + + Age rating: + 年龄等级: - Cover page - 封面 + + Manga: + 日漫: - Cover Artist(s): - 封面设计: + + Synopsis: + 概要: - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine 连接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + + Characters: + 角色: - Volume: - 卷: + + Notes: + 笔记: - Format: - 格式: + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 连接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> - Letterer(s): - 文本: + + Not found + 未找到 - of: - + + Comic not found. You should update your library. + 未找到漫画,请先更新您的文件库. - Arc number: - + + Edit selected comics information + 编辑选中的漫画信息 - Manga: - + + Edit comic information + 编辑漫画信息 QObject + 7z lib not found - + 未找到 7z 库文件 + unable to load 7z lib from ./utils - 无法从./utils加载7z lib + 无法从 ./utils 载入 7z 库文件 + Trace - + 追踪 + Debug - + 除错 + Info - + 信息 + Warning - + 警告 + Error - + 错误 + Fatal - + 严重错误 QsLogging::LogWindowModel + Time - + 时间 + Level - + 等级 + Message - + 信息 QsLogging::Window + &Pause - + 中止(&P) + &Resume - + 恢复(&R) + Save log - + 保存日志 + Log file (*.log) - + 日志文件 (*.log) RenameLibraryDialog - Rename current library - 重命名当前库 - - - Cancel - 取消 + + New Library Name : + 新库名: + Rename 重命名 - New Library Name : - 新库名: + + Cancel + 取消 + + + + Rename current library + 重命名当前库 ScraperResultsPaginator - Number of %1 found : %2 - 第 %1 页 共: %2 条 + + Number of volumes found : %1 + 搜索结果: %1 + + page %1 of %2 第 %1 页 共 %2 页 - Number of volumes found : %1 - 搜索结果: %1 + + Number of %1 found : %2 + 第 %1 页 共: %2 条 SearchSingleComic + Please provide some additional information. - 请提供一些其他信息。 + 请提供附加信息. + Series: - 系列: + 系列: SearchVolume + Please provide some additional information. - 请提供一些其他信息。 + 请提供附加信息. + Series: - 系列: + 系列: SelectComic - loading description - 加载描述: + + Please, select the right comic info. + 请正确选择漫画信息. + comics 漫画 + loading cover 加载封面 - Please, select the right comic info. - 请正确选择漫画信息。 + + loading description + 加载描述 + description unavailable 描述不可用 @@ -1461,22 +1804,27 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 SelectVolume - loading description - 加载描述 - - + Please, select the right series for your comic. 请选择正确的漫画系列。 + + volumes + + + + loading cover 加载封面 - volumes - + + loading description + 加载描述 + description unavailable 描述不可用 @@ -1484,93 +1832,103 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 SeriesQuestion - no - + + You are trying to get information for various comics at once, are they part of the same series? + 您正在尝试同时获取各种漫画的信息,它们是同一系列的吗? + yes - You are trying to get information for various comics at once, are they part of the same series? - 您正在尝试同时获取各种漫画的信息,它们是同一系列的吗? + + no + ServerConfigDialog - Port - 端口 - - - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader适用于iOS设备。 <a href='http://ios.yacreader.com'style ='color:rgb(193,148,65)'>下载</a> - - - enable the server - 启用服务器 + + set port + 设置端口 + Server connectivity information 服务器连接信息 - display less information about folders in the browser -to improve the performance - 在浏览器中尽量少显示显示文件夹的有关信息 -这样能提升浏览效果 - - + Scan it! 扫一扫! - QR generator error! - 二维码出错! - - - set port - 设置端口 + + YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> + YACReader适用于iOS设备. <a href='http://ios.yacreader.com'style ='color:rgb(193,148,65)'>下载</a> + Choose an IP address 选择IP地址 + + Port + 端口 + + + + enable the server + 启用服务器 + + + + display less information about folders in the browser +to improve the performance + 在浏览器中尽量少显示文件夹信息 +以提升浏览性能 + + + Could not load libqrencode. - + 无法载入libqrencode. SortVolumeComics - remove selected comics - 移除所选漫画 + + Please, sort the list of comics on the left until it matches the comics' information. + 请在左侧对漫画列表进行排序,直到它与漫画的信息相符。 + sort comics to match comic information 排序漫画以匹配漫画信息 - restore all removed comics - 恢复所有移除的漫画 - - + issues 发行 - Please, sort the list of comics on the left until it matches the comics' information. - 请在左侧对漫画列表进行排序,直到它与漫画的信息相符。 + + remove selected comics + 移除所选漫画 - restore removed comics - 恢复移除的漫画 + + restore all removed comics + 恢复所有移除的漫画 TitleHeader + SEARCH 搜索 @@ -1578,21 +1936,25 @@ to improve the performance UpdateLibraryDialog - Update library - 更新库 + + Updating.... + 更新中... + Cancel 取消 - Updating.... - 更新中... + + Update library + 更新库 VolumeComicsModel + title 标题 @@ -1600,92 +1962,114 @@ to improve the performance VolumesModel + year + issues 发行 + publisher - 发行人 + 出版者 YACReader::TrayIconController + &Restore - + 复位(&R) + &Quit - + 退出(&Q) + Systray - + 系统托盘 + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - + YACReaderLibrary 将继续在系统托盘中运行. 想要终止程序, 请在系统托盘图标的上下文菜单中选择<b>退出</b>. YACReader::WhatsNewDialog + Close - + 关闭 YACReaderDeletingProgress - cancel - 取消 - - + Please wait, deleting in progress... 请稍候,正在删除... + + + cancel + 取消 + YACReaderFieldEdit - Restore to default - 恢复默认值 + + + Click to overwrite + 点击以覆盖 - Click to overwrite - 点击覆盖 + + Restore to default + 恢复默认 YACReaderFieldPlainTextEdit - Restore to default - 恢复默认值 + + + + + Click to overwrite + 点击以覆盖 - Click to overwrite - 点击覆盖 + + Restore to default + 恢复默认 YACReaderFlowConfigWidget - CoverFlow look - 封面流动展示 + + How to show covers: + 封面显示方式: - How to show covers: - 封面显示: + + CoverFlow look + 封面流 + Stripe look 条状 + Overlapped Stripe look 重叠条状 @@ -1693,135 +2077,166 @@ to improve the performance YACReaderGLFlowConfigWidget - Zoom - 缩放 + + Presets: + 预设: - Light - 亮度 + + Classic look + 经典 - Show advanced settings - 高级设置 + + Stripe look + 条状 + + + + Overlapped Stripe look + 重叠条状 + + + + Modern look + 现代 + Roulette look 轮盘 - Cover Angle - 封面角度 + + Show advanced settings + 显示高级选项 - Stripe look - 条状 + + Custom: + 自定义: - Position - 位置 + + View angle + 视角 - Z offset - Z位移 + + Position + 位置 - Y offset - Y位移 + + Cover gap + 封面间距 + Central gap - 展示区间距 + 中心间距 - Presets: - 预设: + + Zoom + 缩放 - Overlapped Stripe look - 重叠条状 + + Y offset + Y位移 - Modern look - 现代 + + Z offset + Z位移 - View angle - 视角 + + Cover Angle + 封面角度 - Max angle - 最大角度 + + Visibility + 透明度 - Custom: - 自定义: + + Light + 亮度 - Classic look - 经典 + + Max angle + 最大角度 - Cover gap - 封面间距 + + Low Performance + 低性能 + High Performance - - - - Performance: - 性能: + 高性能 + Use VSync (improve the image quality in fullscreen mode, worse performance) - 使用VSync(在全屏模式下提高图像质量,性能更差) - - - Visibility - 透明度 + 使用VSync (在全屏模式下提高图像质量, 性能更差) - Low Performance - + + Performance: + 性能: YACReaderNavigationController - You are not reading anything yet, come on!! - 你还没有读任何东西,加油!! - - + No favorites 没有收藏 + + + You are not reading anything yet, come on!! + 你还没有阅读任何东西,加油!! + YACReaderOptionsDialog + Save 保存 - Use hardware acceleration (restart needed) - 使用硬件加速(需要重启) - - + Cancel 取消 + + Edit shortcuts + 编辑快捷键 + + + Shortcuts - 快捷方式 + 快捷键 - Edit shortcuts - 编辑快捷方式 + + Use hardware acceleration (restart needed) + 使用硬件加速 (需要重启) YACReaderSearchLineEdit + type to search 搜索类型 @@ -1829,26 +2244,32 @@ to improve the performance YACReaderSideBar + + Libraries + + + + + Folders + 文件夹 + + + Reading Lists 阅读列表 + LIBRARIES - Libraries - - - + FOLDERS 文件夹 - Folders - 文件夹 - - + READING LISTS 阅读列表 From 5c9a62a2e4019b3837a7ec1ba3156f14e6f81e23 Mon Sep 17 00:00:00 2001 From: Ruoh-Shoei LIN <56530472+LinRs@users.noreply.github.com> Date: Sun, 9 May 2021 09:23:54 +0000 Subject: [PATCH 132/141] Add corresponding QM files --- release/languages/yacreader_zh.qm | Bin 13606 -> 15338 bytes release/languages/yacreaderlibrary_zh.qm | Bin 31685 -> 35310 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/release/languages/yacreader_zh.qm b/release/languages/yacreader_zh.qm index 7100c76b09fdc2cd8d09e98f12fe6daeb69c20ed..973eaf45d0280d2092772ea99c09a210b00a9659 100644 GIT binary patch delta 4552 zcma)83sh9)7Tz^ryJ_67b1GA3-;7Wiw7K8K+ zV7^X4#?xNvkB`hSfNm$q7R^Bo_}=$AK!~50P7MUv;BU?-IVq*~oz z+_3@;%?2Y?EH8ri1?Q1=LwwZ%q=z7$Dq^?6thE6EhEkZf@gQn{2Ij}#4WL>M^Ka-y zb6dPr^{JP}#d)a#-}ml8$7aKV`|m{B2@5t`kyb(WoT&g4+yRi?F$ExU08By8Vzj%w zRC6zwkGzN;cY*mbI+S=C79U2#(Rp4v^&AwJz6B6J9g5eW1G-aS5ibEu-i-7z(nGL} zIymhcSgtHX$2URiS{Z<(8QRmIN5f-4HoOMl4v&W3YCjanf$c>@$S?y=w)dbz6XCN_ zR2*0fKezk{Fx4#y8OR5iI8$Up#fO)se3oJ7;j{2Z$`t0sjPG1 zaWwo2yOKqLpq*YCHOQ`VB4o0_D|7|hv;Ss*(7&<$W0_bRbJ%T9C1HwcST92R*r&7B zVcUMs4nH{n5D>v0`wDA@e^MU4@(DB?C7-+y5xYJ}?w4749f-`=%KY^Y0VMS+7bjzcl3$cXAKU{FmZr1>`(Y94 zl$J9wnDbN0%6mr8@oMGrj}~GZhAUk^eu$2ADP2DWVSpxOcVQdab5BuKM{GxhMJh*8 zCAQZpl~b=l0juiG-Se^U7pZ}BVzCscCA(1oE~|6xuVEzX)JrTV$B(M-|9liv(WLHr z8WqPbQy;cYKs_(1$6m(ykno`T;s7EUT+anQ5sI}{#0m2Z$Tz^HUFgC7=PS6%{-dby z1ZV#`8YAi8YTFyofz4dQfy1bn;hLofFozqtX7^5{N4WhzV}!vRcQEcOIvB)#T)7Kr zFRwg?4ochk($)dY?F)Qa?L?ddoB7Hl>>B?>zHvLIAnFX?oPq5ODg0f_Kga$LJ;$%E z$V3Ms`L(&opu5a>E2pF3=lI@z=!pLse&fe}XtwEcF8*gZIf*Aw*ucqYSmzeW7jiccZ^L}fDWx7}8iR2u&IN}K@!=jXyI%|YnwR*70-ZH5~VaG-ncRW->4Cx&xKE!V8)+N z9ogSiH06O9K&9)yFtdHGP1X{Y)G2qWCRy{#L0n_HAQGeM4jDtEC0kX|N{u&e5XeDQ zf?U<-YLVdcm?}vs){_`@itlKNdX3w^{Y&%Xbsv}?2R+2XY%nMgPhj!K#m;s$Is|8B zgTro@Rx75)rp`dd`y!i%?ROUD-S!|}Ge#N!eO^M5`9`@XE>~1zT*Wz-D z*AmD%Q@q$CkUvg97MpKrx+Z&_thLp{ZXd_aX2#k@OT#tPvny|FdkidTzIfRMVv}f3 zy9TR594UXlbyNN)K3)|>|Ht0Uy`BLvW zbMSrDLt)wlQfXNasSc>t2D%MmhPNTs)3eh7=>fkxE8b6H0@LY7Yhbsxkj4TNr0t_5 zdcsUT&|6Qm^stV^3F-91-zR*h70Qy#PXN|!p3}4rKW&|OJ0G}l{pw*zuF6<}6-&-f zOb-oN^h@rr2N40IH9`_BgL<%mVQ6m9YRP1UI9T>m@z$J9UtpX`Y!+(joQ;;cO7fh4 zxLifiGa1P{lTziZbFffv;t3zTg`|Ya$W6gKc`5j5Y4>qb8I!wNMDhfbeHTmZH z8$v@oV9Wyts%iB6uL3*L=Ao3y*GaURyx|h9m{AnhTT+r%e32AJWN0;uw-&{XJKGkq zhJtPo=JK3PDGoN=YD>uf7N=CJkQJjd%PXzahA9oAXo`#Xm+gQk>m=`6|0()LP79kE z+eovTv_x*_IjW!5McZTMc%qM*#dFjP--#n?BRR`6lQ2;h1WJT*&uF@mI--nD4xfzE z@ES4E896j3nw7}e;vbj4SGI%X>QWiU%eCp`UR_4GfQi7W+T zoEi1pnnqF=BXH=n1#0onk~@nW)-96e4i81fJS&;1p%9ixHd#$+`3w78K7(QT)sAMN z($OR~I0cJSaMsk>(BFErPW)qo$+1{1TSh#!H4+=|W;QPE4fP4jvP7%PMrVXPFUPt} ztZekmPNp}s^V{E;<}@@oJTvMlCWR?x!_li5=UN&qo>_bqBa`!Sh2x4gyl6AG)m1tE zXtMkAI^%C93mPnyo-um0rp~H@`93Cjp{1b?qy2*}qj=VS!t^%Qa}p$j3#+;YE7}P{ z_bUH95sz`Jfp7(s>2VouI%|DuWu8Gxm4@ayagf^3L|U3}xnw(*igqtb^xYZ+%HH%J{$FLjzL^6bK zmaAqX9Sk@dea`#SO;c5a1*bPA*&Q|m4gXKHDd@(e8hz3Vx-12Ih{Kb^KZ=nY?e*mT zxS;_5-(NV$e0|%5KsqPsKou|KA9qF2S|lg*iGD2Jpp*uE&?I_=G9_Xa&_AK`hgLo} zlw=vUbEc91i{gc6%#cb7v>~yfMYA)_qGhSrkd{_hZE1AkpwFtYU{s!Tt30>25t3k> zHSS90GTtcv?Te0_G)7+aRUo?fNI6Rzw{|u$$K%AO&$OAvy*RqlNPqlcnZlG<{@T#8 zgxNTk`cGBF;kE6V#1=W5W1`PPhNS!PLtjVd0px!%xrOJbeE+Go$LOpgH>GsUyfMe^ z(!(OihZRrhr2ga_E9EsVk55pQ4NI0sV$yx)Q0{s`I7iaLrvv*&q!Mqv9=g z(*^Uk^$}Ef6Rd6DaI_#9_sO=Y?P`^cH$P(HJwrWdnv)Di1~KkSoyW<6X&KViR`Sa< G{r>=rI@wMD delta 2971 zcmZWpc~nzp7QabeUfxUIOAv|d5cU8efTB!^#k#akRe~feQWg;iu?W->B8Xx{;aG|l z^&>#hsd`ZB)>Fn*+a5>S)7ojR3sS3PoGyAs+tb?Wv{E;!nfnrL&&(u$-1mKV{oUWa z-w%y@s~ywdsSNn^=62_qh>-Wnb{+p}7JzgVfcgf28wTna1t7l&)VUY{#Zy52n1cHE zyi&Owr1?*S@RRm^1TZPnE0dx@I{Yy}a0}3rN&s{XkRbR=uS4R3F#tLk603$#X2Env z#{__=12DJe1R89Gd5P-)nD1cTG$)4b^GdeVDqS^1` zIU!TDD&__jc1pDBuRaJ&E84$FgTVHS4i_MRi0?(0W~HHhtV8s5X)u64Bf7od3xH5x zapMs+%30#J%3O3b69z=Bsl08K>P!VG3W?DkWRAIhJ{XACfU}t9w72F$&E|r zv9KXZ8F>vL_7^JfE*28FgDQ|(kiu7~n#RolKD(&pq6)nKmg;-JL>^sobRQPBo35RK38U81w!9IP9KDK0`-wk$W%zlz#kLt7K;8FzfOIk4eS8K| z(L(qCIvcqypm!eBW6N7W4fMI|$T_Ex1+UtViGyWfdD!aU zX|lOn(*UCDy)s55EBa_RQuc|g_)9EMHw|S2K;m7QWx(#hmZ!>Ej-i83wQSvB6b@OO ztod`)C+1>_ z&}uC!?oGs*x$2eLpIPOm7qJ5d*1UNefc7xEC>eo>#cbgv$9jN(T6T%Q1gA2HUGh~7 z4vUGcSbq&GY-X2zlLw$rWbOC9Muh8G`+YScS;=-4tignD$d`ui!GJHyUns1=EjTQ< zX_aW-Api8}JY2&S3gB!QcfUe(6z$=GVqwjP2;h|Bxh3ewSrsokzPp7jcPUPmBZt0Y zieKNyJ&irAxI2KYQXk}e_Xpz8oMU$u72nw z#+k`AiiePzhg_rME$nC-cl!8?(oX6d;G`0Ucj||ga7o#9E=m;;N72_k?Z%A(Hax( zrCM2h;s@k*hVq5_XYnC9rR;69U;>?Tw7Uxnyrs%IgA~9=s}nyO$)@sLS$QG< z+GywQ&LKw~@nJIQY=>QIOd`2Vb9mU|>lKYoy(R==AXO7u^2moWePb$?>0-6r> z6Rc7o%L8~=Z4fTGNk1z>O7*7wZZ5}W+(bD4`3j$&&F#aGT$Q;pgH-w({3qoPSoAWR|fF7HExpM=LoRxSiz$#2#Hi(7R&GAn^^J zLtAxKzpcGOii4+%(WyV!z%qiF0F+z}P7V(9IC5W?`JO*b!f> zBI3x*$7kV|WJhigdN>;Sj6!Z6u?<=V>;H@eCPvK(4JptH^ayn1ZWO-yM@#n_=R3zt zvWjxj9rY^J@%Q|PBsF@EH=;KS`B(IGg=&XzBq1^Z*U&bW!KAMonwP`|Kv9YvB zN)_E(_BojnH<_w6nD&w9<1(dG_LH`4WUV$|TtC+}s(n+W_Vca+K2@H@fEsun%E`A0 zi80ZZ%QY8_XOYunutNjh*MLn}+yAl**JY9;6a0xv@8UV{_JAhmzB7=V*RSC{G{2B& zH+XI;laplfM{huPvUZ}M5Y3o`8SvkEr!dEG^FVPF%&g{!w8cU(s$Ec5`KMYadjNmE6Du8A{(G4h#@nn`(@=O*=P-yP00- zXx(xqH`&dS>Wo&Nv+|~0`AaRAbI+7^liL}#&=4qunVv3NUWZ3{ z&oWK(mDHF|EfZ67Dfee?m6`d<-gC*dB-}#;8d%ow49e5zP z!3kYMb{GPW+k8mp4N$NbVEQ%yVK#tkAL@VMm8A_pY&rsv(+b2#1VC&$5dZB15d1EX#BqSaH(fwZ z9*x%U(y8?TfBOhXy8&Rz=Rj612QcOV+2lZjNkFbT08l$0$TvuQp8{md0Dz*OfC?xC zsPPAC!5RSBL7=z~(b^fHHZ=hVvVq!)b_KCOr`^SX>VU3z2^~e>-$XUJ>nzY)N&v!V z1AW{DklGvQwmAUhdm&&`BSsnrF&k?DUP^=5MHoT(j}Xf{^3oPaobf$cc@+|0$Ir+3 z!-%bDQ7eTp!%_jl%3HLV$c7X8}i%$9Y({arU?M?YvI&}P%K$T_;Eg7 zH0lSqKiZD^$?)6sU$IoT1&V0I2J{j5g=_HhErPH_-u`Jp#INH4lr4hP)+|hU)t7>b zRQw{YpJ2_2GZ^tC!Tt?+Ft4}Z@E=_;^0|T&!_e@MQ-bT)G3DuY!EH02@@B#B2M~mV zuL-GL>j7rGA?&2F0d!g}44sq!FnpIVBIO1^|38GIZehgg#lnd@9001%gp+nU0g?lR zx*aYw)a$;my!vNUoFR0|2H=I;gw?SqCtMWHyt@Pu-z;2y5mRf67H)m-8bIG)gf08| zh~F1}Z~!wiaIkRuqGrTIomUn!!Y}gH0_gl7%T2=DL(qW~tME>1F2FE@@YjaJ015vT zflG(AomMK6H=o7YCW_=Mv0bM8A`0|>6`L3$3vf3+4T1D(kw3Gdo$RfoIBi0#&h=C~L zO+__=|>JgPi=2saO&nX}pLs|1fDC zi5cx`AZyr@$On;RP3d$1b1^w{KZ6cjBWH*9!u}7uLN0KI15E8eHnfaIVv&-I#v%Gk z7LhFe3XK5DDWLEgjPnxp^Ed-LenCmh6?~ zr8Gn1WYe1Hu;}yH9Yg85tUg;jw(3&Zm&T2I%Pg-I(f{SLlMTFyiT7 zqI95KMVI~!32X*Um(9b>3C_?{ccQ)~l&*8xdLWa1PtRBxfs`9fH#MQ>#y#|!o)-* zal3eqaXmm}fw*CL2Ed40;@3y$u|0c>4^BS_P<%;z_!xq;Do1=|8)C&0D?V}``GIQm z%Iu-yqe&Ogp+n-IPi{p@f7>hL{t(}LKN+cfltj2P7BMp2<$Z8AN$4mG*7mYQ-W5IT zA1mqd9TG>>c}d)b(KtgsmGn7`-9i0Z(&rk=@|Pupc*7yqfQtXCTB<{!*WUz9{!Nh$4{aPi5ep4aWJH1j*NWSqO zk0ni$DuoFEq0^+DAH4<8*(voezJjG>r11i*J$Xs0Dow@yuSt^*`|38L^qyC;QiD^2 zO)*AV7P25=UdaD5Otll`Y$e zhRqLTn~pC*g8M~w;NuUmk}BEx=(Tv!2eJ!eP=CNf+4YII&vbuNcCQup7W*i9r_Djg zKS4qAz;7`D(OcxqSS)$*%kl^aF-}_s<=%D5OqU=J6%}|h_D3$AxW>zXp zgAg*gO$yT(7h)iOn4)~gT_mJTg=^tg7}58N#*D7G()~xV{CAABbC6<1V}Ha1sd()q zUJzU3m9--k`&B2kciK3`URrl9h)aB_Y$cC{LGtgP^Qb z{!5M#_Ufa&mvF>Ady_@LSJAS)A-iN89{jQc?!S*-$UHt=7>G;g=(KyUR zWKZ;N#zhh4K*)Z}&6LIaDVIrf*UIR+`c<#Zv4M*FNY+;-<=?XvHMcqAl8T zmQgX>GG#CqDfe@~@7Gl*ldf1c|F|{QIkK&}jPUGuy^eN3l+qhYz?}Q}7sWY4GWvuN52Z*&Nt7dxD zu?;|^ORRp8CLg2EFsZkituHjHmbOzBdsIz!#|sRL3j`~5O`kNm-tbwM>#bF+jnUd1 zFFr=(ZmJ#TJ3*Q((_S1TyTBOdQx%(82d3~D?J2&b*Y9a(SyI7T^d__U8GWC6dO^F4 zQ`I&TT7NoLj_5Q^$X2*3J7oz%dq65!p&U%0hspT21z2E~exu*O-q$>A4&p9%9!_>J zbekE@_37J%OZHC^W>s@$e~v(nfo@Tkz9NM(GoE6rx4h)1t1oXwfnZnx*TS}P%V)h;G z-Qd#Ln9{p!%401RFj-${+Vqm)u_No)JnsyJa(cxR(cYhVp=Oof@%+F7PrYjU_-qRNEa*_Z&j%cKhad+tt*T0{Zk9vRz8 zE9B`VC3hNUXEG}c_>m%MqsWgbO32*IU#79Em*9u317)%vE{j^lyWzV~p2a#Ct)0>H zoWs38A~%S=YK?v7>vFBd$c^}0U@tk3A+>6nzGzT(N1vMFu@#HeR<1R3CtnJ5lOv-A z!+Sv%qS}EOGJzfcbMhDmEj}@bd@W+$2wI<&PP`S9-R@+0kN&)}e*k}F*2#u6+x8NH z_iFylcdYYM#~!;-nHcC!Ozkaj|9jLWA|ue7dcF{kF&fl#lLvv%NPISuBc_`Fi?!LT zHalZ*+DsNBV>an*T3Zd{^rW3-Oco^Zj&WVx2gY|5ah)e_;RIV@hv{Sf*5K zGIJHGAVB~pQ2TRVOq?qi&Sj_rU08Ys@?eAqm@H<(fSIvX&C73WIFNO7)+3{Y?;=R> znM}_ck($XOENqO$>R?K(PKzOd@j6{@GL|_Q9cGQGuvv9xww$RpIm(zCtJB6jIcKui z9a^(l>o8db7A|aTprDNR1v?lRZmN0$)9$({PmVpg&iya-eW9zv?4L3>SuSL5LexiM z1kpYp<&h(t4l85V+pK0Y&wP?Jt1-u9F<8A*OrEF69OyZf+U^t?nQE=5d7ipDewxms zp3zR-MMY+4op$zl2hzXJ&-EP0YIlH)%+gjpSKUI^)_T;ZnbfuUItO}otr}fnQeVE4He0}yEU2fGmpAki>*@}FCId<5zHC#qcSDNCHjmyKRNwa&3>wl=fzJhFO z^Bw4rYPC2_7HlXRVh7R8pHX!v9a^LMQ+H}i(P*E3=qQuD!mO=9I(YgVqtjX}tc^eJ zJ}^loAeKp1)o`L5Ly|H(F>}-GJ2TqqFFoaJaFzq-Hg*f|Z5hkhYwQjL=AVv_3FfsY z|6WG(-Hpu8a%f>Jn6FS4#aag1Ob|#9QUcuT-<*Wt49L+l<3ru%8 zqr7v5Gv`c_NsAnRpXVu-iaVB*7$#Q-IMeF)uoW*KhbPsOjj-t%i?dvZVfht?;Of5ZG3S8O_}C2&c^3i#TZo?jZCBBwim~cL{>FE{ZJfBQ~WlA&mkoVBvItR zr;L)w0PJZBmzL6Y{)w!mymMXr+s|NNia5_4tu2Xl5i1PMK|Y9)qgb8O$oBxPN!Lwf z^$zcb+l-9-L}@fn!Otj()e$creOhsh7Gdy=B9VT%#QNA8?z05HOh2o%^wE--Cs!iY z^d6dc+OMY4>APk?e6~lgOKBGQ{I8MNc?!=L2!es!*+|rpHH2loN#l)AC zBPBy!JUo47Ne_|mMuRkVBnl&5p;GzCbE4J2n!QfOelXz>%NYMxrEmaz-wew8&z9nb%^$30yKLp?d-H+Fn( zw<|64f{9tCMI~bgQPR3gLSEHU`nLq>n!^i)SDuUlJe62xxwhIp{ z_##rNa>}$0yPB;YWzu4^aXqXXXlcbxO`G~EmsZh>`>!>y-EU66ib3tZ9sSfd4EJ$G z7)|kG6Ze&$DhB&0`DcC?VRw24X1~hAq*xtayw5GPjS$e(>T^6`xiR+XIF8gF@b0xQ z#4lFO!~cz`;|Rk>T~sPdlr&2&Uq<=_-z1xQD;Gor=yTZa-uY41?f}6iv83w z{fX7Mc4Qo19EIBe{yO5#mfkJAfxp|9RNWTHdZd>uJ!gKyC|N;rjng-9^8UTKoSJl+ o^8Og+w$>zt1oKx+H>>Ywu3Hw$6V*y+oc;3A>_jxuR&zw~e-YmPFaQ7m delta 4762 zcmZ`-2~<;O7QXN0B`+_@OJoxi)PSNavK3nqQB)LH5=mG@_Uu?T!y9QZ{#0M#4dmwo_{Rs(!XQ!yHv z4gA(K0C~8ulaJ$k5DZNR$Xx@1`Yiy=6%cSo(adcS>}vub(m>FL28nQ>7d!(HH3D5Y z9~~0{{V{G6^#lEB7Qm>Ffxc(~h#m#>tCaxS_h9J0Mhs*EOmD-DN$-IrHaZ4iWFO3K z=|PVRVV?FWz?kRgBpNo!AhEp*!1*O4Rbs?~=dgIlY5;W$q>6pf(Pl_Z{{}#Bgv^e` z01202$ve&H00H?;r_jNAFx%`9hhTXl1}1HW3fp^{*HD?&2{6~g0+o;VpyyWD6BZ6I z|0wK9vEs&f_%df6K)`YMcF!n)Nrmu_RT_Y4cj0x}3xNDwg7x2wp-v!tU(5xNoFZbn z)BsD8h{6~&?5`xY^j$&6Gl`x(xG%nnI5+5q0c;}rqKg0`b`lRB{D2Nvw8WEKtl5m! z#BXPe024b%!LeNcg~Leacr(C|?c}J$V1OyZNZ&~h0p1!;&U}m!&8Z~gI*M_B1ew@b zf_{XNnhvz%<3{E!`xzi?6ImjD8xK57E(=7A9YNMUTZiXdCqKA}nbNnBZ3llu{)D)Y z?LD^0_LGOtUN*{ z&40y`XnB%NNJ4c0&%^aY0QqB{=kVj05jWo3hKm5c-n_`ONa}cJUgTeU0a6az(E^Jv z@M0oz@Zh5kOp4;^E78z`N4$IyM!c||S6~{8r5NBX;~oJ_Rq{StiVg;^<#pav0fc(; zE}I(xrjOx0ym1*zca8T#n~w(`r63VYsOqMm8zYVjq@+Im07elde}HzgyQ%QDyU5NU zDHR{!j|Q$fP*Y8%jjsk6ewxaitiS`xsNyJ;)3`NMY32&78Ap|G#ne;dsiqZHG~`dU z&OL#wu5uv%gagG+4s;rDpzBHpdYp6M@IXWhzL>btF`-d7Ft3){{4xPk-c4@uwN0cw}#2!Q)BYF`JESKR18=Ku$~9-&UI+>iTPsISv7Q&ci_HQ-Ck z;9BbHu3muj8tT@f)mV!8)GNza88(JGK4ohN!&3S3=)Fi972oeMk}r7*-+%IO+<1iV z-;H{8;T$-W$B$in3{xA(Px{jm#0`AoO~eF(UoZnRn~y7n7}VLl%d?l@GE=d zX#YCDX4Dvfp^y0WB|ZR|YxtIi_SvZ8k^D7tkfljNe*0ncEMX%5_8qyb<&r#r4n*!QE;1u|y99cNdc=-)poeb~H9L zBQ5&08`WZUpf-?})2A_DOF!-He;rBnf}Z{U1OVMS2kJfPQ~@@Uw<_t>lbFgp5uJ7m z^_{CgEJhqc8>V0*DX`F{I?N1ln_kk1`{ya?6`Opqp@q>+P3UNP5WQveR6LkZZ)s@7 z&iFZf*bg1@?xnjtdQtx=kLWM=;=@cQx=+)CFV@lby?;XaeNMj)$A(1Sre8mwgOOhs zvNDV;d$~{==ZfT9C!DwsYi(F1EIix~ka1nO(zpv?bcJx+bSX!c zazVZDLii2D`NE$swP9yGWJe1GcnJp%O~jVy!jPK+u`|7PU=G93e)(9EM~uWB4-AWC z+`dPd`u@s{zcCACdz%UU5lN~|Vj^q?hi!0R;QLIZ*EF-9~bpSFiCfl8d`cDjDw6z$)yYDj)1)yFVdN>L%IP%ZZc zc72QczNggvYajeNDUWzhoYew60v`8BSsJ_p0pJsjz|(uTWyQn zQ#|d|Dgf8NiIu(Rc~Fa3wP_}nh7xb+L_?Yr;(Zs_;oXodK6BzI&MU+>VsSm(P5dCP z3+1~;JkW*LwBfvj_Hx3^wo9D%4?{VRlUO|NVZ>w4OMJ7DEMuG{k)FNS^QTE-PP?JU zcO;8U50OmYNQ_G2;91r3c)-4x*t(vc9eaE1IA(Pp_ zwcGL1(6NC%Ihd+!c0rs1V9_x)%N;!reZXq|bQv=f$7+MWMEy@;wcS?CB!h@7Pguel zBw7sUGd3pzxv=mKn-hx;1f;Qf9nY{o6R9c<6pDAe^+_N#VZl-*GF^8V}CpnhYoR%42TFS7qoA_?Q4NW~a1@E$vmr5xxP zCw1;m#+pY+y&|WgS`J9%t*92C1JcNaQq(_FCyn()51~{#@9qoi-9ggS-T`z#EKTeA z3H6&S&3c8b_moIA>ROcHeQALi*}UYwbg8X#dhw;@-=RaJUP^247h?c~^pmf4qhnsu zL&q?4;V-0L%tL(ZuJr5S=r9{2J@+OYIS?tmY`Oy$2w5Zjiv%O|R!Rp_`jP!n4qTil zlY1cP=3J7+4d}2mKg$-DU?g+9WyTu3Gv>=>tGP4y%jIvfHQY`*nZa5p{ zG-Ly#`O!pIRJCqhX@*FUb4hF%E3wTau;q_!GuHRn1|ApSCARuHMUhTJS~je@SP)n; zId8gZUu#|CSuWRQ0=L;sLzWTN-`v#12rr0%0?30L&_WV^=Yt;P>+fjyG!JWf#1*PZkb2WONv2gmF6?ajfVr1jFs6+EfFP@A8@rM`}T znG&|vm+Kqj&(-;O$zs=Y@h|oDisz+u8<^D19OpHi%kZtW7K~OAjPSp<&-g!Ex5}i( z08N!D6ehxQn<0)K>+e0jwPcfKP-t^|kiopEAjX!Z!QsX}#TMHdmp<0aNEEC-L`#&` zaks|4O$e>>aXNB@m(559mqu*TsGBVQXe0oFG3B|S9b~L~{cn<1CMb^NT0{H^%Gwjs zMTm!MzCr>j0bsqkz$=ScCuK^HO5Z0M$Gml4$t)?EI#^s zxmPfE?U`y-Tm~0Pg51<)>~DG%|DiFaWuc88LSz&O@UtMnq?c<;%w~Olu{<|NW6n00 z%eC40P{vvWbN{G$J=-=j7_Sg|mlo@2U2jZE^(vS|uY-YeA( zj!yeQn}L?*RsD+FdhvVHDsb`T>}h#Y#ezRu1eS&6NRO{bc6+BX#HjI==C zZ-2g}`-%~oqB3Rn(SE&-5w566ZnBSD4FQaB(Z1!;_R%au5Gzq%YFMBz+<4JGQ)vie zg!+2pc>Cz6AxvNt+8;fQ8H}*PwW-}csy3pTsxN*wbI6z>7TL@wj@ef|OxcVuWn7xW zfohY#Sfrn&XsY_czIxac%m{NY)dCc3rNKJv^7patq>_UCyyfs9a@R?WAM zR^$ZJf{bGOb6d_>Y7l=o&n1DrV{Cj=^dgT#pahDsdE`QoYRCFYn`ltqxj3WY65gH4 z4V6l{wsNsGHm{#>b8Y%X+o#;30L7O0QpHu}cUc9YB-d9ki7P2^$ArC7x!cd;3daB6 zz4QNTpHE>Vi3TzX?~6sY)3q1ZKOP)zowu}yCSbd=Sl9l_lZCl&ECCJZ0nAB$Fa2ZOX=rX-pA|WG zyUN?aPFuUT%Ykp1?3l56ZBMJxa*h_+*3^;K5!KTP9=Z7%r>`mFkxGU2hnm&cAY1G3 zKNYs?rKGlu5pKR#wbw4Dm$h|H6KrC_i$V?McvWZzh1|wE56Pe;Yh3jk!?W~<*vvk! zdqOZ?%B=O*a(5aT?#O$4Sczrm`i-`ZuJ6p0aa$t1xaxW(Bm86LYJE6o$>O_~ Date: Sun, 9 May 2021 14:29:13 +0200 Subject: [PATCH 133/141] Translate spanish parts of the changelog to english (using Deepl) --- CHANGELOG.md | 218 +++++++++++++++++++++++++-------------------------- 1 file changed, 107 insertions(+), 111 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 089d71f8e..3f526b74a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,5 @@ # YACReader Changelog -Please note: this is a work in progress. Keeping a changelog has been neglected -in the past so information is missing and older release information is in -spanish only. Sorry for the mess. - Version counting is based on semantic versioning (Major.Feature.Patch) ## WIP @@ -14,7 +10,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch) * New search engine. * New `manga` field added to comics and folders to tag content as manga, any content added to a manga folder will become manga automatically. * Support for HTML in comic synopsis, this fixes the synopsis when it comes from Comic Vine with HTML tags. -* Improve keyboard navigation in Comic Vine dialog. +* Improve keyboard navigation in Comic Vine dialog. ## 9.7.1 ### YACReader @@ -155,119 +151,119 @@ Version counting is based on semantic versioning (Major.Feature.Patch) * Bug fixes. ## 7.1.0 -* Añadida opción para resetear el rating de un comics -* Corregidos bugs que afectaban a la información de página. -* Corregido error que marcaba un comic terminado como empezado si se volvía a leer. -* Añadidos 2 estados para las carpetas (Completo/Terminado) -* Corregido bug en la comunicación YACReaderLibrary <-> YACReader -* Añadidas las acciones relativas a los comics al menú contextual de la tabla de cómics. -* Corrgido bug que provocaba el crecimiento ilimatado del log del servidor -* Corregidos bugs menores - -## 7.0.2 (Sólo MacOSX) -* Eliminado el uso de Poppler en la versión de MacOSX -* Trabajo en traducciones. -* Corregidos bugs menores +* Added option to reset the rating of a comic book. +* Fixed bugs affecting page information. +* Fixed bug that marked a finished comic as started if it was read again. +* Added 2 statuses for folders (Complete/Completed). +* Fixed bug in YACReaderLibrary <-> YACReader communication. +* Added actions related to comics to the context menu of the comics table. +* Fixed bug that caused unlimited server log growth. +* Fixed minor bugs + +## 7.0.2 (MacOSX only) +* Removed Poppler usage in MacOSX version. +* Work on translations. +* Fixed minor bugs ## 7.0.1 -* Añadido QsLog a YACReader -* Corregido bug en la comunicación YACReaderLibrary <-> YACReader +* Added QsLog to YACReader +* Fixed bug in YACReaderLibrary <-> YACReader communication. ## 7.0 (Final) -* Corregidos eventos de teclado en algunos diálogos -* Corregido soporte para archivos Rar en sistemas Unix -* Corregidos problemas borrando cómics -* Mejorada la gestión de errores -* Corregida la comunicación entre YACReader y YACReaderLibrary -* Corregida la toolBar en MacOSX -* Mejorada la compatabilidad de OpenGL en tarjetas NVIDIA -* Corregidos bugs menores - -## 6.9 (No pública) -* Añadida la apertura automática del siguiente/anterior cómic al llegar al final/portada del cómic actual -* Corregido el comportamiento del diálogo de nueva versión detectada. Ahora avisa una vez al día o si el usuario lo elige cada 14 días. -* Corregido el ajuste a lo ancho del título de la toolbar en YACReaderLibrary. -* Añadido log a YACReaderLibrary (permitirá a los usuarios ofrecer más información sobre sus bugs) -* Corregido bug en el historial de navegación (y al editar comics) después de usar el motor de búsqueda. - -## 6.8 (No pública) -* Corregido bug que causaba un cierre inesperado después de cambiar el modo de sincronización vertical (flow) -* Corregido bug que causaba que la toolbar en el visor no se pudiese ocultar/mostrar sin un cómic abierto -* Mejorada la gestión de errores al abrir cómics -* Corregidos algunos bugs relacionados con la apertura de cómics -* Añadida función de rating -* El visor ahora puede abrir archivos de imagen directamente. Si se abre un archivo de imagen se abre el directorio que lo contiene con todas las imágenes. -* Corregida la ordenación de carpetas y cómics usada en la navegación desde dispositivos iOS - -## 6.7 (No pública) -* Añadidos nuevos campos en la base de datos para almacenar información adicional sobre cómics: rating, página actual, bookmarks y configuración de imagen -* Añadida comunicación entre YACReaderLibrary y YACReader para poder almacenar el progreso de los cómics e información adicional - -## 6.6 (No pública) -* Modificado YACReader para que abra los archivos comprimidos usando 7z.dll (.so, .dylib) -* YACReader abre ahora los cómics por la última página leída. -* Corregido bug que causaba que algunos cómics no se pudiesen abrir desde YACReaderLibrary en YACReader -* Corregido el modo en el que se actualizaba la "information label" +* Fixed keyboard events in some dialogs +* Fixed support for Rar archives on Unix systems +* Fixed problems deleting comics +* Improved error handling +Fixed communication between YACReader and YACReaderLibrary * Fixed communication between YACReader and YACReaderLibrary +* Fixed the toolBar in MacOSX +* Improved OpenGL compatibility on NVIDIA cards +* Fixed minor bugs + +## 6.9 (internal) +* Added automatic opening of the next/previous comic when reaching the end/cover of the current comic +* Fixed behavior of new version detected dialog. Now warns once a day or if user chooses every 14 days. +* Fixed the width adjustment of the toolbar title in YACReaderLibrary. +* Added log to YACReaderLibrary (will allow users to provide more information about their bugs). +* Fixed bug in browsing history (and editing comics) after using search engine. + +## 6.8 (internal) +* Fixed bug that caused unexpected shutdown after changing the vertical sync mode (flow). +* Fixed bug that caused toolbar in viewer could not be hidden/shown without an open comic book +* Improved error handling when opening comics +* Fixed some bugs related to comic opening +* Added rating function +* The viewer can now open image files directly. Opening an image file opens the directory containing the file with all images. +* Fixed sorting of folders and comics used in browsing from iOS devices. + +## 6.7 (internal) +* Added new fields in the database to store additional information about comics: rating, current page, bookmarks and image settings. +* Added communication between YACReaderLibrary and YACReader to be able to store comics progress and additional information + +## 6.6 (internal) +* Modified YACReader to open compressed files using 7z.dll (.so, .dylib) +* YACReader now opens comics by the last page read. +* Fixed bug that caused that some comics could not be opened from YACReaderLibrary in YACReader. +* Fixed the way in which the "information label" was updated. ## 6.5 -* Nueva interfaz principal de YACReaderLibrary y YACReader -* Corregido bug que causaba que el servidor no se activase en el primer arranque en MacOSX -* Corregido bug que causaba un fallo al cerrar YACReaderLibrary cada vez que se usaba el servidor -* Nuevo diseño para el diálogo de propiedades de los cómics. -* Añadida navegación alante y atrás de las carpetas visitadas. -* La edición del nombre de una biblioteca no fuerza ahora que se recargue la biblioteca -* Corregido el color de fondo en la lupa -* Nuevo botón para ajustar a lo alto -* Eliminada la opción always on top -* Mostrar en carpeta contenedora arreglado en Windows y MacOSX - -## 6.4 (No pública) -* Normalizado el renderizado de páginas en modo doble página -* Añadida la función de borrar cómics desde el disco duro -* Nuevos iconos de la barra de herramientas de cómics - -## 6.3 (No pública) -* Mejorada la gestión de errores relacionada con las bibliotecas -* Añadido botón que permite ocultar las portadas en la pantalla de importación -* Añadidos títulos "Bibliotecas" y "Carpetas" a la barra de navegación -* Nuevos iconos para seleccionar la carpeta raíz, expandir y contraer todos. -* Botón para cambiar el puerto del servidor por el usuario. -* Ahora las columnas de la lista de cómics pueden reordenarse -* Ahora YACReaderLibrary sólo permite una instancia ejecutandose. -* Columna leído añadida. -* Cambiado estilo de la lista de cómics -* Corregidos bugs relacionados con realizar operaciones sobre cómics cuando no había ninguno seleccionado en la lista de cómics +* New main interface of YACReaderLibrary and YACReader +* Fixed bug that caused the server not to activate on first boot on MacOSX +* Fixed bug that caused a crash when closing YACReaderLibrary every time the server was used +* New design for the comic properties dialog. +* Added forward and backward navigation of visited folders. +* Editing a library name does not force library reloading now. +* Corrected the background color in the magnifying glass. +* New button to adjust to top +* Removed always on top option +* Show in container folder fixed on Windows and MacOSX + +## 6.4 (internal) +* Normalized rendering of pages in double page mode +* Added delete comics from hard disk function +* New comic toolbar icons + +## 6.3 (internal) +* Improved error handling related to libraries +* Added button to hide cover art in the import screen +* Added "Libraries" and "Folders" headings to the navigation bar +* New icons to select root folder, expand and collapse all. +* Button to change the server port by the user. +* Comic list columns can now be reordered. +* YACReaderLibrary now allows only one instance running. +* Read column added. +* Comic list style changed. +* Fixed bugs related to perform operations on comics when there was none selected in the comics list. ## 6.2 -* Nueva ventana de "bienvenida" -* Nueva ventana de importar/actualizar -* Nuevo control para la búsqueda -* Nueva imagen para las marcas de cómics leídos (sólo en OpenGL) -* Cambiada la distribución de algunos iconos -* Cambiado el modo de eliminar la metainformación (borrar base de datos/portadas de disco) -* Ocultadas las opciones avanzadas de configuración de YACReader Flow, accesibles ahora tras pulsar un botón (diálogos de configuración más simples) - -## 6.0.1 (No pública) -* Corregido bug al usar las teclas Inicio/fin -* Corregido bug que al arrancar YACReaderLibrary por primera vez causaba que no se mostrasen las portadas (sólo bajo ciertas circunstancias) -* Añadidos algunos atajos de teclado a YACReaderLibrary a los ya existentes +* New "welcome" window +* New import/update window +* New control for search +* New image for the marks of read comics (OpenGL only) +* Changed the layout of some icons +* Changed the way to delete meta information (delete database/disk covers) +* Hidden YACReader Flow advanced configuration options, accessible now after pressing a button (simpler configuration dialogs) + +## 6.0.1 (internal) +* Fixed bug when using Home/end keys +* Fixed bug that when starting YACReaderLibrary for the first time caused that the covers were not shown (only under certain circumstances) +* Added some keyboard shortcuts to YACReaderLibrary to the already existing ones ## 6.0 -* Mejorada la velocidad de inicio gracias al uso de /LTCG como opción de compilación -* Corregido bug relacionado con OpenGL que causaba consumo excesivo de CPU en tarjetas NVidia -* Añadidos iconos para cada tipo de archivo soportado en YACReaderLibrary -* Cambiado el icono "folder" en YACReaderLibrary -* Añadida barra para ajustar el ancho de página en la toolbar de YACReader -* Añadido widget para la information label -* Añadido nuevo estilo visual a goToFlow -* Añadidos filtros para controlar el brillo, el contraste y el valor gamma -* Añadidas notificaciones de portada y última página -* InformationLabel se muestra ahora en la esquina superiror derecha. -* InformationLabel se muestra en 3 tamaños diferentes en función de la resolución -* Corregido bug que causaba que las marcas de cómic leído no se dibujasen adecuadamente. -* Se recuerda si se debe mostrar o no la "label" información. -* Corregido bug que provocaba el fallo de YACReader al pasar muy rápido las páginas. -* Añadida columna "Tamaño" a la lista de cómics en YACReaderLibrary -* Añadida la ordinación "natural" de los comics que hay en directorio del cómic actual. -* Corregido bug que causaba que se abriese el cómic erroneo en YACReaderLibrary. -* Cambiado el modo en el que se cargan los lenguages, ahora se pueden añadir traducciones sin necesidad de recompilar. +* Improved startup speed thanks to the use of /LTCG as a compile option +* Fixed OpenGL related bug that caused excessive CPU consumption on NVidia cards +Added icons for each supported file type in YACReaderLibrary * Added icons for each supported file type in YACReaderLibrary +* Changed "folder" icon in YACReaderLibrary +Added page width adjustment bar in YACReader toolbar * Added widget for page width in YACReader toolbar +* Added widget for information label +* Added new visual style to goToFlow +* Added filters to control brightness, contrast and gamma value * Added new filters to control brightness, contrast and gamma value +* Added front page and last page notifications +* InformationLabel is now displayed in the upper right corner. +* InformationLabel is displayed in 3 different sizes depending on resolution. +* Fixed bug that caused read comic marks not to be drawn properly. +* InformationLabel now remembers whether or not to display the information label. +* Fixed bug that caused YACReader to crash when turning pages too fast. +* Added "Size" column to the comics list in YACReaderLibrary. +* Added "natural" sorting of the comics in the current comic directory. +* Fixed bug that caused the wrong comic to open in YACReaderLibrary. +* Changed the way languages are loaded, now you can add translations without recompiling. From 78f7bef9200652f3ff3346d52145be85c7365d4d Mon Sep 17 00:00:00 2001 From: Felix Kauselmann Date: Sun, 9 May 2021 15:44:39 +0200 Subject: [PATCH 134/141] Update build instructions --- INSTALL.md | 80 ++++++++++++++++++----------- compressed_archive/README_7zip.txt | 4 +- compressed_archive/unarr/README.txt | 2 +- 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index eb596da58..0c2c53097 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -3,63 +3,83 @@ YACReader and YACReaderLibrary are build using qmake. To build and install the program, run: -> qmake-qt5 CONFIG+=[Options] -> make -> make install +``` +qmake CONFIG+=[Options] +make +make install +``` -from the source dir. For separate builds of YACReader or YACReaderLibrary, +from the top source dir. For separate builds of YACReader or YACReaderLibrary, enter their respective subfolders and run the commands from there. The headless version of YACReaderLibrary is located in the YACReaderLibraryServer folder. To build it, enter the folder and run the commands described above. +Note: If your system has multiple versions of Qt, you need to make sure you are +using qmake for Qt5 ## Build dependencies: -- Qt >= 5.6 with the following modules: +- Qt >= 5.9 with the following modules: - declarative - quickcontrols - sql - - script - multimedia - imageformats - opengl - sql-sqlite - network -- A pdf rendering backend (optional, see below) -- qrencode (optional) -- 7zip or p7zip (see below) -- (lib)unarr (optional, see below) +- Backends for pdf rendering (optional) and file + decompression (see below) +- qrencode for QR code generation (optional) Not all dependencies are needed at build time. For example the qml components in YACReaderLibrary (GridView, InfoView) will only show a white page if the required qml modules (declarative, quickcontrols) are missing. -This can also happen if these dependencies are too old (i.e Qt < 5.6 is used). ## Backends ### Decompression -Configure the library you want to use throught `qmake` `CONFIG`. `CONFIG += 7zip` or `CONFIG += unarr`, if not specified `7zip` is used in MacOS and Windows and `unarr` in Linux. +YACReader currently supports two decompression backends, 7zip and (lib)unarr. YACReader +defaults to 7zip for Windows and Mac OS and unarr for Linux and other OS, but you can +override this using one of the following config options: + +`CONFIG+=7zip` + +`CONFIG+=unarr` #### 7zip -YACReader uses by default [7zip](https://www.7-zip.org/) for comic book archive -decompression. In MacOS and Linux, it uses [p7zip](http://p7zip.sourceforge.net/). Please read `compressed_archive/README_7zip.txt` for more details. This is the recomended library since supports a wider variety of formats, including RAR5 and 7z. +[7zip](https://www.7-zip.org/) and [p7zip](http://p7zip.sourceforge.net/) +are the default decompression backend for Windows and Mac OS builds. + +They are recommended for these systems, as they currently have better support for 7z +files and support the RAR5 format. + +As this backend requires specific versions of 7zip for Windows and p7zip for *NIX and +is not 100% GPL compatible (unrar License restriction), it is not recommended for +installations where you can't guarantee the installed version of (p7zip) or the license is an issue. + +To build using this backend, you need to install additional sources to the build environment. +For more information, please refer to [README_7zip](compressed_archive/README_7zip.txt). #### unarr -YACReader can use [(lib)unarr](https://github.com/selmf/unarr) for comic book archive -decompression. Most Linux distributions don't ship this library yet, so you will -probably have to build it yourself. +[(lib)unarr](https://github.com/selmf/unarr) is the default backend for Linux builds. + +As of version 1.0.1, it supports less formats than 7zip, notably missing RAR5 support and only having +limited support for 7z on git versions. However, this is rarely an issue in practice as the vast majority +of comic books use either zip or RAR4 compression, which is handled nicely by this backend. -We recommend using (lib)unarr as a shared library, but we also support static -and embedded builds. Please consult the [README](compressed_archive/unarr/README.txt) -for more information on this topic. +The unarr backend is recommended for packaging, lightweight installations and generally for all users requiring +more stability than the 7zip backend can offer. +The recommended way to use this on Linux or other *NIX is to install it as a package, but you can also do an embedded build. +For more information, please consult the [README](compressed_archive/unarr/README.txt) ### PDF -Starting with version 9.0.0 YACReader supports the following pdf render engines: +Starting with version 9.0.0 YACReader supports the following pdf rendering engines: - poppler (Linux/Unix default) - pdfium (default for Windows and MacOS) @@ -70,7 +90,7 @@ To override the default for a given platform add CONFIG+=[pdfbackend] as an opti when running qmake. While the Poppler backend is well tested and has been the standard for YACReader -for a long time, it's performance is a bit lacking. The pdfium engine offers +for a long time, its performance is a bit lacking. The pdfium engine offers much better performance (about 10x faster on some pdf files we tested). However, at the time of this writing, it is not a library that is available prepackaged for Linux. @@ -80,23 +100,25 @@ prepackaged for Linux. You can adjust the installation prefix as well als the path "make install" uses to install the files. ->qmake PREFIX=DIR +`qmake PREFIX=DIR` sets the default prefix (for example "/", "/usr", "/usr/local"). ->make install INSTALL_ROOT=DIR +`make install INSTALL_ROOT=DIR` can be used to install to a different location, which is usefull for packaging. Default values: ->PREFIX=/usr ->INSTALL_ROOT="" +``` +PREFIX=/usr +INSTALL_ROOT="" +``` On embedded devices that don't support desktop OpenGL, it is recommended to use the no_opengl config option: -qmake-qt5 CONFIG+=no_opengl +`qmake CONFIG+=no_opengl` This will remove any dependency on desktop OpenGL and hardlock YACReader's coverflow to software rendering. Please note that it does not actually remove @@ -107,10 +129,10 @@ OpenGL from the build, the Qt toolkit will still make use of it. If you're compiling YACReader because there is no package available for your Linux distribution please consider creating and submitting a package or filing a -package request. +package request for your distribution. While we do provide packages for .deb and .rpm based distributions as well as an -AUR package for Archlinux and it's derivates, we are in need of downstream packagers +AUR package for Archlinux and its derivates, we are in need of downstream packagers that are willing to make YACReader available as a standard package for their distro. If you are interested, please contact @selmf on the YACReader forums or write diff --git a/compressed_archive/README_7zip.txt b/compressed_archive/README_7zip.txt index 4ab47185c..5211df33e 100644 --- a/compressed_archive/README_7zip.txt +++ b/compressed_archive/README_7zip.txt @@ -1,9 +1,7 @@ If you are trying to compile YACReader with a 7zip decompression backend, -you need to download de source code of 7zip (Windows) or p7zip (Linux/MacOSX). +you need to download the source code of 7zip 18.05 (Windows) or p7zip 16.02 (Linux/MacOSX). Please extract it and rename the folder to lib7zip (Windows) or libp7zip (Linux/MacOSX), then copy it to $YACREADER_SRC/compressed_archive/ (this folder). -YACReader is compiled using 7zip 18.05 and p7zip 16.02. - 7zip is the recommended library to use is you want support for 7zip files and rar5. diff --git a/compressed_archive/unarr/README.txt b/compressed_archive/unarr/README.txt index 7c2ff285c..f78187196 100644 --- a/compressed_archive/unarr/README.txt +++ b/compressed_archive/unarr/README.txt @@ -1,4 +1,4 @@ -Starting with YACReader 9.0.0 all versions of YACReader use (lib)unarr >= 1.0.1 +Starting with YACReader 9.0.0 all versions of YACReader can use (lib)unarr >= 1.0.1 as decompression backend. For Windows and MacOSX precompiled libraries are available in the dependencies folder (not included in the source tarballs!). From 5f5ef6833d435d1482ac4dc507e14428733403ef Mon Sep 17 00:00:00 2001 From: F_TD5X Date: Tue, 11 May 2021 00:25:33 +0800 Subject: [PATCH 135/141] p7zip patches (#249) * p7zip patches add patches till CVE-2021-3465 add patch for build on linux --- compressed_archive/libp7zip.patch | 308 +++++++++++++++++++++++++++++- 1 file changed, 301 insertions(+), 7 deletions(-) diff --git a/compressed_archive/libp7zip.patch b/compressed_archive/libp7zip.patch index 7e226f4f8..872b8d76c 100644 --- a/compressed_archive/libp7zip.patch +++ b/compressed_archive/libp7zip.patch @@ -1,11 +1,305 @@ ---- libp7zip/CPP/include_windows/windows.h 2018-09-18 17:17:26.000000000 +0200 ---- libp7zip/CPP/include_windows/windows.h 2018-09-18 17:17:24.000000000 +0200 +previous patch +--- libp7zip/CPP/include_windows/windows.h ++++ libp7zip/CPP/include_windows/windows.h @@ -36,7 +36,7 @@ - #define WINAPI - + #define WINAPI + #undef BOOL -typedef int BOOL; +typedef signed char BOOL; - - - #define CREATE_NEW 1 + + + #define CREATE_NEW 1 + +fix linux build +--- libp7zip/CPP/myWindows/StdAfx.h ++++ libp7zip/CPP/myWindows/StdAfx.h +@@ -206,8 +206,6 @@ + + #if defined( __x86_64__ ) + +-#define _WIN64 1 +- + #endif + + #endif + +CVE-2016-9296 +--- libp7zip/CPP/7zip/Archive/7z/7zIn.cpp ++++ libp7zip/CPP/7zip/Archive/7z/7zIn.cpp +@@ -1097,7 +1097,8 @@ + if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i]) + ThrowIncorrect(); + } +- HeadersSize += folders.PackPositions[folders.NumPackStreams]; ++ if (folders.PackPositions) ++ HeadersSize += folders.PackPositions[folders.NumPackStreams]; + return S_OK; + } + +CVE-2017-17969 +--- libp7zip/CPP/7zip/Compress/ShrinkDecoder.cpp ++++ libp7zip/CPP/7zip/Compress/ShrinkDecoder.cpp +@@ -121,8 +121,13 @@ + { + _stack[i++] = _suffixes[cur]; + cur = _parents[cur]; ++ if (cur >= kNumItems || i >= kNumItems) ++ break; + } +- ++ ++ if (cur >= kNumItems || i >= kNumItems) ++ break; ++ + _stack[i++] = (Byte)cur; + lastChar2 = (Byte)cur; + + + + +CVE-2018-5996 +--- libp7zip/CPP/7zip/Compress/Rar1Decoder.cpp ++++ libp7zip/CPP/7zip/Compress/Rar1Decoder.cpp +@@ -29,7 +29,7 @@ public: + }; + */ + +-CDecoder::CDecoder(): m_IsSolid(false) { } ++CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { } + + void CDecoder::InitStructures() + { +@@ -406,9 +406,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * + InitData(); + if (!m_IsSolid) + { ++ _errorMode = false; + InitStructures(); + InitHuff(); + } ++ ++ if (_errorMode) ++ return S_FALSE; ++ + if (m_UnpackSize > 0) + { + GetFlagsBuf(); +@@ -477,9 +482,9 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) + { + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } +- catch(const CInBufferException &e) { return e.ErrorCode; } +- catch(const CLzOutWindowException &e) { return e.ErrorCode; } +- catch(...) { return S_FALSE; } ++ catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; } ++ catch(const CLzOutWindowException &e) { _errorMode = true; return e.ErrorCode; } ++ catch(...) { _errorMode = true; return S_FALSE; } + } + + STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) + +CVE-2018-5996 +--- libp7zip/CPP/7zip/Compress/Rar1Decoder.h ++++ libp7zip/CPP/7zip/Compress/Rar1Decoder.h +@@ -39,6 +39,7 @@ public: + + Int64 m_UnpackSize; + bool m_IsSolid; ++ bool _errorMode; + + UInt32 ReadBits(int numBits); + HRESULT CopyBlock(UInt32 distance, UInt32 len); + +CVE-2018-5996 +--- libp7zip/CPP/7zip/Compress/Rar2Decoder.cpp ++++ blibp7zip/CPP/7zip/Compress/Rar2Decoder.cpp +@@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20; + static const UInt32 kWindowReservSize = (1 << 22) + 256; + + CDecoder::CDecoder(): +- m_IsSolid(false) ++ m_IsSolid(false), ++ m_TablesOK(false) + { + } + +@@ -100,6 +101,8 @@ UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numB + + bool CDecoder::ReadTables(void) + { ++ m_TablesOK = false; ++ + Byte levelLevels[kLevelTableSize]; + Byte newLevels[kMaxTableSize]; + m_AudioMode = (ReadBits(1) == 1); +@@ -170,6 +173,8 @@ bool CDecoder::ReadTables(void) + } + + memcpy(m_LastLevels, newLevels, kMaxTableSize); ++ m_TablesOK = true; ++ + return true; + } + +@@ -344,6 +349,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * + return S_FALSE; + } + ++ if (!m_TablesOK) ++ return S_FALSE; ++ + UInt64 startPos = m_OutWindowStream.GetProcessedSize(); + while (pos < unPackSize) + { + +CVE-2018-5996 +--- libp7zip/CPP/7zip/Compress/Rar2Decoder.h ++++ libp7zip/CPP/7zip/Compress/Rar2Decoder.h +@@ -139,6 +139,7 @@ class CDecoder : + + UInt64 m_PackSize; + bool m_IsSolid; ++ bool m_TablesOK; + + void InitStructures(); + UInt32 ReadBits(unsigned numBits); + +CVE-2018-5996 +--- libp7zip/CPP/7zip/Compress/Rar3Decoder.cpp ++++ libp7zip/CPP/7zip/Compress/Rar3Decoder.cpp +@@ -92,7 +92,8 @@ CDecoder::CDecoder(): + _writtenFileSize(0), + _vmData(0), + _vmCode(0), +- m_IsSolid(false) ++ m_IsSolid(false), ++ _errorMode(false) + { + Ppmd7_Construct(&_ppmd); + } +@@ -545,6 +546,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) + return InitPPM(); + } + ++ TablesRead = false; ++ TablesOK = false; ++ + _lzMode = true; + PrevAlignBits = 0; + PrevAlignCount = 0; +@@ -606,6 +610,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) + } + } + } ++ if (InputEofError()) ++ return S_FALSE; ++ + TablesRead = true; + + // original code has check here: +@@ -623,6 +630,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) + RIF(m_LenDecoder.Build(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize])); + + memcpy(m_LastLevels, newLevels, kTablesSizesSum); ++ ++ TablesOK = true; ++ + return S_OK; + } + +@@ -824,7 +834,12 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) + PpmEscChar = 2; + PpmError = true; + InitFilters(); ++ _errorMode = false; + } ++ ++ if (_errorMode) ++ return S_FALSE; ++ + if (!m_IsSolid || !TablesRead) + { + bool keepDecompressing; +@@ -838,6 +853,8 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) + bool keepDecompressing; + if (_lzMode) + { ++ if (!TablesOK) ++ return S_FALSE; + RINOK(DecodeLZ(keepDecompressing)) + } + else + + +@@ -901,8 +918,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream + _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1; + return CodeReal(progress); + } +- catch(const CInBufferException &e) { return e.ErrorCode; } +- catch(...) { return S_FALSE; } ++ catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; } ++ catch(...) { _errorMode = true; return S_FALSE; } + // CNewException is possible here. But probably CNewException is caused + // by error in data stream. + } + +CVE-2018-5996 +--- libp7zip/CPP/7zip/Compress/Rar3Decoder.h ++++ libp7zip/CPP/7zip/Compress/Rar3Decoder.h +@@ -192,6 +192,7 @@ class CDecoder: + UInt32 _lastFilter; + + bool m_IsSolid; ++ bool _errorMode; + + bool _lzMode; + bool _unsupportedFilter; +@@ -200,6 +201,7 @@ class CDecoder: + UInt32 PrevAlignCount; + + bool TablesRead; ++ bool TablesOK; + + CPpmd7 _ppmd; + int PpmEscChar; + +CVE-2021-3465 +--- libp7zip/CPP/7zip/Common/StreamObjects.cpp ++++ libp7zip/CPP/7zip/Common/StreamObjects.cpp +@@ -157,6 +157,8 @@ STDMETHODIMP CDynBufSeqOutStream::Write( + + STDMETHODIMP CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) + { ++ if(_buffer == nullptr || _size == _pos) ++ return E_FAIL; + size_t rem = _size - _pos; + if (rem > size) + rem = (size_t)size; + +GCC10 warning fix +--- libp7zip/CPP/Windows/ErrorMsg.cpp 2015-01-18 11:20:28.000000000 -0700 ++++ libp7zip/CPP/Windows/ErrorMsg.cpp 2019-09-24 13:01:18.887289152 -0600 +@@ -14,14 +14,14 @@ UString MyFormatMessage(DWORD errorCode) + AString msg; + + switch(errorCode) { +- case ERROR_NO_MORE_FILES : txt = "No more files"; break ; +- case E_NOTIMPL : txt = "E_NOTIMPL"; break ; +- case E_NOINTERFACE : txt = "E_NOINTERFACE"; break ; +- case E_ABORT : txt = "E_ABORT"; break ; +- case E_FAIL : txt = "E_FAIL"; break ; +- case STG_E_INVALIDFUNCTION : txt = "STG_E_INVALIDFUNCTION"; break ; +- case E_OUTOFMEMORY : txt = "E_OUTOFMEMORY"; break ; +- case E_INVALIDARG : txt = "E_INVALIDARG"; break ; ++ case unsigned (ERROR_NO_MORE_FILES) : txt = "No more files"; break ; ++ case unsigned (E_NOTIMPL) : txt = "E_NOTIMPL"; break ; ++ case unsigned (E_NOINTERFACE) : txt = "E_NOINTERFACE"; break ; ++ case unsigned (E_ABORT) : txt = "E_ABORT"; break ; ++ case unsigned (E_FAIL) : txt = "E_FAIL"; break ; ++ case unsigned (STG_E_INVALIDFUNCTION) : txt = "STG_E_INVALIDFUNCTION"; break ; ++ case unsigned (E_OUTOFMEMORY) : txt = "E_OUTOFMEMORY"; break ; ++ case unsigned (E_INVALIDARG) : txt = "E_INVALIDARG"; break ; + case ERROR_DIRECTORY : txt = "Error Directory"; break ; + default: + txt = strerror(errorCode); From e799513fb46562245fe3799973442cc0fa5d981c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 16 May 2021 08:57:18 +0200 Subject: [PATCH 136/141] Reset the grid current index when the grid content changes `model` object doesn't really change so we can't use `onModelChanged` in QML to reset the index. --- YACReaderLibrary/grid_comics_view.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index f442becee..b844bfa6a 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -259,6 +259,12 @@ void GridComicsView::setModel(ComicModel *model) ctxt->setContextProperty("dropManager", this); ctxt->setContextProperty("comicInfoHelper", comicInfoHelper); + auto grid = view->rootObject()->findChild(QStringLiteral("grid")); + + if (grid != nullptr) { + grid->setProperty("currentIndex", 0); + } + updateBackgroundConfig(); selectionHelper->clear(); From 13a29e2657f2a13505c8aa71730111c09aa7992f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 16 May 2021 09:01:35 +0200 Subject: [PATCH 137/141] Make "delete" icon work properly in the "Reading" list Only the "Favorites" special list was handled. --- YACReaderLibrary/db/comic_model.cpp | 31 +++++++++++++++++++++++ YACReaderLibrary/db/comic_model.h | 2 ++ YACReaderLibrary/db/reading_list_item.cpp | 9 +++++++ YACReaderLibrary/db/reading_list_item.h | 1 + YACReaderLibrary/db_helper.cpp | 16 ++++++++++++ YACReaderLibrary/db_helper.h | 1 + YACReaderLibrary/library_window.cpp | 3 +-- 7 files changed, 61 insertions(+), 2 deletions(-) diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index da6c8a46a..842922bea 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -10,6 +10,7 @@ #include "comic_db.h" #include "db_helper.h" #include "query_parser.h" +#include "reading_list_model.h" //ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read #include "QsLog.h" @@ -986,6 +987,36 @@ void ComicModel::deleteComicsFromFavorites(const QList &comicsList) deleteComicsFromModel(comicsList); } +void ComicModel::deleteComicsFromReading(const QList &comicsList) +{ + QList comics = getComics(comicsList); + QString connectionName = ""; + { + QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); + + DBHelper::deleteComicsFromReading(comics, db); + connectionName = db.connectionName(); + } + QSqlDatabase::removeDatabase(connectionName); + + if (mode == Reading) + deleteComicsFromModel(comicsList); +} + +void ComicModel::deleteComicsFromSpecialList(const QList &comicsList, qulonglong specialListId) +{ + auto type = (ReadingListModel::TypeSpecialList)specialListId; + + switch (type) { + case ReadingListModel::TypeSpecialList::Reading: + deleteComicsFromReading(comicsList); + break; + case ReadingListModel::TypeSpecialList::Favorites: + deleteComicsFromFavorites(comicsList); + break; + } +} + void ComicModel::deleteComicsFromLabel(const QList &comicsList, qulonglong labelId) { QList comics = getComics(comicsList); diff --git a/YACReaderLibrary/db/comic_model.h b/YACReaderLibrary/db/comic_model.h index 4d9c05948..cbe49d450 100644 --- a/YACReaderLibrary/db/comic_model.h +++ b/YACReaderLibrary/db/comic_model.h @@ -119,6 +119,8 @@ class ComicModel : public QAbstractItemModel void addComicsToReadingList(const QList &comicsList, qulonglong readingListId); void deleteComicsFromFavorites(const QList &comicsList); + void deleteComicsFromReading(const QList &comicsList); + void deleteComicsFromSpecialList(const QList &comicsList, qulonglong specialListId); void deleteComicsFromLabel(const QList &comicsList, qulonglong labelId); void deleteComicsFromReadingList(const QList &comicsList, qulonglong readingListId); diff --git a/YACReaderLibrary/db/reading_list_item.cpp b/YACReaderLibrary/db/reading_list_item.cpp index f80e34b3b..53bf7199a 100644 --- a/YACReaderLibrary/db/reading_list_item.cpp +++ b/YACReaderLibrary/db/reading_list_item.cpp @@ -44,6 +44,15 @@ QIcon SpecialListItem::getIcon() const return QIcon(); } +qulonglong SpecialListItem::getId() const +{ + if (itemData.count() > Id) { + return itemData.at(Id).toInt(); + } + + return 0; +} + ReadingListModel::TypeSpecialList SpecialListItem::getType() const { if (itemData.count() > Id) { diff --git a/YACReaderLibrary/db/reading_list_item.h b/YACReaderLibrary/db/reading_list_item.h index a6849afd6..612bc6cf1 100644 --- a/YACReaderLibrary/db/reading_list_item.h +++ b/YACReaderLibrary/db/reading_list_item.h @@ -27,6 +27,7 @@ class SpecialListItem : public ListItem public: SpecialListItem(const QList &data); QIcon getIcon() const override; + qulonglong getId() const override; ReadingListModel::TypeSpecialList getType() const; private: diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index 3b3dd6831..de3a4d56d 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -471,6 +471,22 @@ void DBHelper::deleteComicsFromFavorites(const QList &comicsList, QSqlD db.commit(); } +//a.k.a set comics as unread by reverting the conditions used to load the comics -> void ComicModel::setupReadingModelData(const QString &databasePath) +void DBHelper::deleteComicsFromReading(const QList &comicsList, QSqlDatabase &db) +{ + db.transaction(); + + QLOG_DEBUG() << "deleteComicsFromReading----------------------------------"; + + for (auto comic : comicsList) { + comic.info.hasBeenOpened = false; + comic.info.currentPage = 0; //update sets hasBeenOpened to true if currentPage > 0; + DBHelper::update(&comic.info, db); + } + + db.commit(); +} + void DBHelper::deleteComicsFromLabel(const QList &comicsList, qulonglong labelId, QSqlDatabase &db) { db.transaction(); diff --git a/YACReaderLibrary/db_helper.h b/YACReaderLibrary/db_helper.h index 63f3217d9..93bedfffa 100644 --- a/YACReaderLibrary/db_helper.h +++ b/YACReaderLibrary/db_helper.h @@ -48,6 +48,7 @@ class DBHelper static void removeListFromDB(qulonglong id, QSqlDatabase &db); //logic deletes static void deleteComicsFromFavorites(const QList &comicsList, QSqlDatabase &db); + static void deleteComicsFromReading(const QList &comicsList, QSqlDatabase &db); static void deleteComicsFromLabel(const QList &comicsList, qulonglong labelId, QSqlDatabase &db); static void deleteComicsFromReadingList(const QList &comicsList, qulonglong readingListId, QSqlDatabase &db); //inserts diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 1f68a6d68..b8a0b3396 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -2591,8 +2591,7 @@ void LibraryWindow::deleteComicsFromList() qulonglong id = mi.data(ReadingListModel::IDRole).toULongLong(); switch (typeList) { case ReadingListModel::SpecialList: - //by now only 'favorites' - comicsModel->deleteComicsFromFavorites(indexList); + comicsModel->deleteComicsFromSpecialList(indexList, id); break; case ReadingListModel::Label: comicsModel->deleteComicsFromLabel(indexList, id); From b1713fc184e656bf471507c23eeb1e6e3c4fa1c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 16 May 2021 09:11:00 +0200 Subject: [PATCH 138/141] Fix crash on null pointer --- YACReaderLibrary/classic_comics_view.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/YACReaderLibrary/classic_comics_view.cpp b/YACReaderLibrary/classic_comics_view.cpp index 113a63819..f7b7b552e 100644 --- a/YACReaderLibrary/classic_comics_view.cpp +++ b/YACReaderLibrary/classic_comics_view.cpp @@ -300,6 +300,10 @@ void ClassicComicsView::centerComicFlow(const QModelIndex &mi) void ClassicComicsView::updateTableView(int i) { + if (model == nullptr) { + return; + } + QModelIndex mi = model->index(i, 2); tableView->setCurrentIndex(mi); tableView->scrollTo(mi, QAbstractItemView::EnsureVisible); From 13d0f5fc75d1e3fcd175804fa49bf83191bdd5fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 16 May 2021 09:21:42 +0200 Subject: [PATCH 139/141] Do not show the what's new dialog when there are no libraries No libraries probably means fresh installation. --- YACReaderLibrary/library_window.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index b8a0b3396..2267ab7f7 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -113,9 +113,10 @@ LibraryWindow::LibraryWindow() void LibraryWindow::afterLaunchTasks() { - WhatsNewController whatsNewController; - - whatsNewController.showWhatsNewIfNeeded(this); + if (!libraries.isEmpty()) { + WhatsNewController whatsNewController; + whatsNewController.showWhatsNewIfNeeded(this); + } } void LibraryWindow::setupUI() From e2483217d976610b0714b2f5d6822a79596ba895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 16 May 2021 09:37:05 +0200 Subject: [PATCH 140/141] Configure OpenGL settings earlier to avoid wrong state in the options dialog --- YACReaderLibrary/library_window.cpp | 43 ++++++++++++++++++----------- YACReaderLibrary/library_window.h | 2 ++ 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 2267ab7f7..1b7824d12 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -97,6 +97,8 @@ using namespace YACReader; LibraryWindow::LibraryWindow() : QMainWindow(), fullscreen(false), previousFilter(""), fetching(false), status(LibraryWindow::Normal), removeError(false) { + createSettings(); + setupUI(); loadLibraries(); @@ -119,16 +121,37 @@ void LibraryWindow::afterLaunchTasks() } } +void LibraryWindow::createSettings() +{ + settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); //TODO unificar la creación del fichero de config con el servidor + settings->beginGroup("libraryConfig"); +} + +void LibraryWindow::setupOpenglSetting() +{ +#ifndef NO_OPENGL + //FLOW----------------------------------------------------------------------- + //--------------------------------------------------------------------------- + + OpenGLChecker openGLChecker; + bool openGLAvailable = openGLChecker.hasCompatibleOpenGLVersion(); + + if (openGLAvailable && !settings->contains(USE_OPEN_GL)) + settings->setValue(USE_OPEN_GL, 2); + else if (!openGLAvailable) + settings->setValue(USE_OPEN_GL, 0); +#endif +} + void LibraryWindow::setupUI() { + setupOpenglSetting(); + setUnifiedTitleAndToolBarOnMac(true); libraryCreator = new LibraryCreator(); packageManager = new PackageManager(); - settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); //TODO unificar la creación del fichero de config con el servidor - settings->beginGroup("libraryConfig"); - historyController = new YACReaderHistoryController(this); createActions(); @@ -196,20 +219,8 @@ void LibraryWindow::doLayout() libraryToolBar = new YACReaderMainToolBar(this); #endif -#ifndef NO_OPENGL - //FLOW----------------------------------------------------------------------- + //FOLDERS FILTER------------------------------------------------------------- //--------------------------------------------------------------------------- - - OpenGLChecker openGLChecker; - bool openGLAvailable = openGLChecker.hasCompatibleOpenGLVersion(); - - if (openGLAvailable && !settings->contains(USE_OPEN_GL)) - settings->setValue(USE_OPEN_GL, 2); - else if (!openGLAvailable) - settings->setValue(USE_OPEN_GL, 0); -#endif - //FOLDERS FILTER------------------------------------------------------------- - //--------------------------------------------------------------------------- #ifndef Q_OS_MAC //in MacOSX the searchEdit is created using the toolbar wrapper searchEdit = new YACReaderSearchLineEdit(); diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index 97f517820..8dad315ff 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -261,6 +261,8 @@ class LibraryWindow : public QMainWindow NavigationStatus status; + void createSettings(); + void setupOpenglSetting(); void setupUI(); void createActions(); void createToolBars(); From e7be383bb91127dada0f188839e7439de12d826a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 16 May 2021 16:39:56 +0200 Subject: [PATCH 141/141] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f526b74a..7f5cea12d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ Version counting is based on semantic versioning (Major.Feature.Patch) ## WIP + +## 9.8.0 ### YACReader * Add support for full manga mode. * Fix UP,DOWN,LEFT,RIGHT shortcuts for moving a zoomed in page around. @@ -11,6 +13,8 @@ Version counting is based on semantic versioning (Major.Feature.Patch) * New `manga` field added to comics and folders to tag content as manga, any content added to a manga folder will become manga automatically. * Support for HTML in comic synopsis, this fixes the synopsis when it comes from Comic Vine with HTML tags. * Improve keyboard navigation in Comic Vine dialog. +### Server +* New `manga` field is sent to YACReader for iOS, so comics tagged as manga will be recognized as such when reading remotely or importing comics. ## 9.7.1 ### YACReader