[MORE][CONUTILS] Implement missing features of the MORE command (#3658)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Wed, 9 Jun 2021 14:30:30 +0000 (23:30 +0900)
committerGitHub <noreply@github.com>
Wed, 9 Jun 2021 14:30:30 +0000 (23:30 +0900)
Implement missing features of the MORE command. Special thanks to @HBelusca. CORE-4019

26 files changed:
base/applications/cmdutils/more/lang/bg-BG.rc
base/applications/cmdutils/more/lang/ca-ES.rc
base/applications/cmdutils/more/lang/cs-CZ.rc
base/applications/cmdutils/more/lang/de-DE.rc
base/applications/cmdutils/more/lang/el-GR.rc
base/applications/cmdutils/more/lang/en-US.rc
base/applications/cmdutils/more/lang/es-ES.rc
base/applications/cmdutils/more/lang/et-EE.rc
base/applications/cmdutils/more/lang/fr-FR.rc
base/applications/cmdutils/more/lang/it-IT.rc
base/applications/cmdutils/more/lang/lt-LT.rc
base/applications/cmdutils/more/lang/no-NO.rc
base/applications/cmdutils/more/lang/pl-PL.rc
base/applications/cmdutils/more/lang/ro-RO.rc
base/applications/cmdutils/more/lang/ru-RU.rc
base/applications/cmdutils/more/lang/sk-SK.rc
base/applications/cmdutils/more/lang/sq-AL.rc
base/applications/cmdutils/more/lang/sv-SE.rc
base/applications/cmdutils/more/lang/tr-TR.rc
base/applications/cmdutils/more/lang/uk-UA.rc
base/applications/cmdutils/more/lang/zh-CN.rc
base/applications/cmdutils/more/lang/zh-TW.rc
base/applications/cmdutils/more/more.c
base/applications/cmdutils/more/resource.h
sdk/lib/conutils/pager.c
sdk/lib/conutils/pager.h

index 8b05eba..28a9423 100644 (file)
@@ -3,13 +3,34 @@ LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
 STRINGTABLE
 BEGIN
     IDS_USAGE "Показва данните на екрана, разделени на страници.\n\n\
-  MORE < [Устройство:][Път]Файлово име\n\
-  Команда | MORE\n\
-  MORE [Устройство:][Път]Файлово име\n\n\
-  [Устройство:][Път]Файлово име    Файл, чието съдържание да бъде показано.\n\
-  Команда\t\t     Команда, чийто изход да бъде показан.\n\n\
-  При въпроса ""-- Продължаване --"" натиснете произволен клавиш, за показаване на следващата страница.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Продължаване --"
     IDS_CONTINUE_PROGRESS "-- Продължаване (%d%%) --"
     IDS_FILE_ACCESS "Няма достъп до файл %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 9c10620..8762861 100644 (file)
@@ -3,13 +3,34 @@ LANGUAGE LANG_CATALAN, SUBLANG_DEFAULT
 STRINGTABLE
 BEGIN
     IDS_USAGE "Mostra en pantalla el contingut pàgina per pàgina.\n\n\
-  MORE < [Unitat:][Ruta]Nom del fitxer\n\
-  Instrucció | MORE\n\
-  MORE [Unitat:][Ruta]Nom del fitxer\n\n\
-  [Unitat:][Ruta]Nom del fitxer    Un fitxer, el contingut del qual serà mostrat.\n\
-  Instrucció\t\t     Una instrucció, el resultat de la qual serà mostrada.\n\n\
-  Al visualitzar ""-- Continua --"" heu de premer qualsevol tecla per visualitzar la següent pàgina.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Continua --"
     IDS_CONTINUE_PROGRESS "-- Continua (%d%%) --"
     IDS_FILE_ACCESS "No puc accedir al fitxer %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 3497c3e..3b2780e 100644 (file)
@@ -9,14 +9,34 @@ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
 STRINGTABLE
 BEGIN
     IDS_USAGE "Zobrazí výstup po jednotlivých stránkách na obrazovku.\n\n\
-  MORE < [Jednotka:][Cesta]Název souboru\n\
-  Příkaz | MORE\n\
-  MORE [Jednotka:][Cesta]Název souboru\n\n\
-  [Jednotka:][Cesta]Název souboru    Soubor, jehož obsah bude zobrazen.\n\
-  Příkaz\t\t     Příkaz, jehož výstup bude zobrazen.\n\n\
-  Při výzvě ""-- Pokračovat --"" lze stisknout libovolnou klávesu\n\
-  pro zobrazení další stránky.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Pokračovat --"
     IDS_CONTINUE_PROGRESS "-- Pokračovat (%d%%) --"
     IDS_FILE_ACCESS "Nelze získat přístup k souboru %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index a73ce1c..db101d9 100644 (file)
@@ -3,14 +3,34 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
 STRINGTABLE
 BEGIN
     IDS_USAGE "Zeigt Daten seitenweise auf dem Bildschirm an.\n\n\
-  MORE < [Laufwerk:][Pfad]Dateiname\n\
-  Befehl | MORE\n\
-  MORE [Laufwerk:][Pfad]Dateiname\n\n\
-  [Laufwerk:][Pfad]Dateiname Eine Datei, deren Inhalt angezeigt werden soll.\n\
-  Befehl\t\t     Ein Befehl, dessen Ausgabe angezeigt werden soll.\n\n\
-  An der Eingabeaufforderung ""-- Fortsetzung --"" kann eine beliebige\n\
-  Taste gedrückt werden, um die nächste Seite anzuzeigen.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Fortsetzung --"
     IDS_CONTINUE_PROGRESS "-- Fortsetzung (%d%%) --"
     IDS_FILE_ACCESS "Auf die Datei %s kann nicht zugegriffen werden.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 6997579..589fe0c 100644 (file)
@@ -3,13 +3,34 @@ LANGUAGE LANG_GREEK, SUBLANG_DEFAULT
 STRINGTABLE
 BEGIN
     IDS_USAGE "Εμφανίζει τα δεδομένα σελίδα-παρά-σελίδα στην οθόνη.\n\n\
-  MORE < [Δίσκος:][Μονοπάτι]Όνομα αρχείου\n\
-  Εντολή | MORE\n\
-  MORE [Δίσκος:][Μονοπάτι]Όνομα αρχείου\n\n\
-  [Δίσκος:][Μονοπάτι]Όνομα αρχείου    Το αρχείο, τα δεδομένα του οποίου θα εμφανιστούν.\n\
-  Εντολή\t\t     Η εντολή, της οποίας η έξοδος θα εμφανιστεί.\n\n\
-  Στη γραμμή εντολών ""-- Συνέχεια --"" μπορείτε να πατήσετε οποιοδήποτε κουμπί για να δείτε την επόμενη σελίδα.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Συνέχεια --"
     IDS_CONTINUE_PROGRESS "-- Συνέχεια (%d%%) --"
     IDS_FILE_ACCESS "Δεν ήταν δυνατή η προσπέλαση του αρχείου %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 620a67f..d6498d4 100644 (file)
@@ -3,13 +3,34 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 STRINGTABLE
 BEGIN
     IDS_USAGE "Displays data page-by-page on the screen.\n\n\
-  MORE < [Drive:][Path]File name\n\
-  Command | MORE\n\
-  MORE [Drive:][Path]File name\n\n\
-  [Drive:][Path]File name    A file, whose content shall be displayed.\n\
-  Command\t\t     A command, whose output shall be displayed.\n\n\
-  At the prompt ""-- Continue --"" you can press any key to show the next page.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Continue --"
     IDS_CONTINUE_PROGRESS "-- Continue (%d%%) --"
     IDS_FILE_ACCESS "Cannot access the file %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index f622406..94e8436 100644 (file)
@@ -3,13 +3,34 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
 STRINGTABLE
 BEGIN
     IDS_USAGE "Muestra datos página por página en la pantalla.\n\n\
-  MORE < [Unidad:][Ruta]Nombre del archivo\n\
-  Comando | MORE\n\
-  MORE [Unidad:][Ruta]Nombre del archivo\n\n\
-  [Unidad:][Ruta]Nombre del archivo    Un archivo, cuyo contenido pueda ser mostrado.\n\
-  Comando\t\t     Un comando, cuya salida pueda ser mostrada.\n\n\
-  Al visualizar ""-- Continuar --"" presione cualquier tecla para mostrar la siguiente página.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Continuar --"
     IDS_CONTINUE_PROGRESS "-- Continuar (%d%%) --"
     IDS_FILE_ACCESS "No se puede acceder al fichero %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 11a92d0..123eaae 100644 (file)
@@ -3,13 +3,34 @@ LANGUAGE LANG_ESTONIAN, SUBLANG_DEFAULT
 STRINGTABLE
 BEGIN
     IDS_USAGE "Kuvab andmeid lehekülje kaupa ekraanil.\n\n\
-  MORE < [Draiv:][Tee]Faili nimi\n\
-  Käsk | MORE\n\
-  MORE [Draiv:][Tee]Faili nimi\n\n\
-  [Draiv:][Tee]Faili nimi    Fail mille sisu kuvatakse.\n\
-  Käsk\t\t\t     Käsk mille sisu kuvatakse.\n\n\
-  Küsimusel ""-- Jätka --"" võib vajutada mis tahes klahvi järgmise lehe näitamiseks.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Jätka --"
     IDS_CONTINUE_PROGRESS "-- Jätka (%d%%) --"
     IDS_FILE_ACCESS "Ei saa ligi failile %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 43dccce..28899ea 100644 (file)
@@ -3,13 +3,34 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
 STRINGTABLE
 BEGIN
     IDS_USAGE "Affiche les données page par page à l'écran.\n\n\
-  MORE < [Lecteur:][Chemin]Nom du fichier\n\
-  Commande | MORE\n\
-  MORE [Lecteur:][Chemin]Nom du fichier\n\n\
-  [Lecteur:][Chemin]Nom du fichier    Un fichier, dont le contenu sera affiché.\n\
-  Commande\t\t     Une commande, dont la sortie sera affichée.\n\n\
-  À l'invite ""-- Continuer --"" Vous pouvez appuyer sur n'importe quelle touche pour afficher la page suivante.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Continuer --"
     IDS_CONTINUE_PROGRESS "-- Continuer (%d %%) --"
     IDS_FILE_ACCESS "Impossible d'accéder au fichier %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index c08f568..05f6e15 100644 (file)
@@ -3,13 +3,34 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
 STRINGTABLE
 BEGIN
     IDS_USAGE "Visualizza dati una schermata per volta.\n\n\
-  MORE < [Drive:][Path]File\n\
-  Comando | MORE\n\
-  MORE [Drive:][Path]File\n\n\
-  [Drive:][Path]File    Il file da visualizzare.\n\
-  Comando\t\t     Il comando di cui l'output dev'essere visualizzato.\n\n\
-  Alla richiesta ""-- Continua --"" premere un tasto qualsiasi per visualizzare la pagina successiva.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Continua --"
     IDS_CONTINUE_PROGRESS "-- Continua (%d%%) --"
     IDS_FILE_ACCESS "Impossibile accedere al file %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 1073aa7..76ff2a4 100644 (file)
@@ -12,16 +12,34 @@ LANGUAGE LANG_LITHUANIAN, SUBLANG_DEFAULT
 STRINGTABLE
 BEGIN
     IDS_USAGE "Atvaizduoja duomenis puslapiais.\n\n\
-  MORE < [Diskas:][Kelias iki bylos]Bylos vardas\n\
-  Komanda | MORE\n\
-  MORE [Diskas:][Kelias iki bylos]Bylos vardas\n\n\
-  [Diskas:][Kelias iki bylos]Bylos vardas    Byla, kurios turinys turi būti\n\
-                                             atvaizduotas.\n\
-  Komanda                                    Komanda, kurios rezultatas turi\n\
-                                             būti atvaizduotas.\n\n\
-  Pasirodžius raginimui ""-- Toliau --"" spauskite bet kurį klavišą, kad\n\
-  pamatytumėte sekantį puslapį.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Toliau --"
     IDS_CONTINUE_PROGRESS "-- Toliau (%d%%) --"
     IDS_FILE_ACCESS "Nepavyko atverti bylos %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index b300487..7260d25 100644 (file)
@@ -3,13 +3,34 @@ LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL
 STRINGTABLE
 BEGIN
     IDS_USAGE "Vis data side-etter-side på skjermen.\n\n\
-  MORE < [Stasjon:][Mappe]Filnavn\n\
-  command | MORE\n\
-  MORE [Stasjon:][Mappe]Filenavn\n\n\
-  [Stasjon:][Mappe]Filnavn    En fil, Velg innhold som skal vises.\n\
-  Command\t\t     En kommando, Velg output som skal vises.\n\n\
-  At the prompt ""-- Fortsett --"" du kan trykke en tast for å vise neste side.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Fortsett --"
     IDS_CONTINUE_PROGRESS "-- Fortsett (%d%%) --"
     IDS_FILE_ACCESS "Får ikke tilgang til filen %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index e18872b..b8ba373 100644 (file)
@@ -11,13 +11,34 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
 STRINGTABLE
 BEGIN
     IDS_USAGE "Wyświetla dane, podzielone na odcinki o długości ekranu.\n\n\
-  MORE < [Napęd:][Ścieżka]Nazwa pliku\n\
-  Polecenie | MORE\n\
-  MORE [Napęd:][Ścieżka]Nazwa pliku\n\n\
-  [Napęd:][Ścieżka]Nazwa pliku    Plik, którego zawartość ma być wyświetlona.\n\
-  Polecenie\t\t     Polecenie, którego wynik ma być wyświetlony.\n\n\
-  Po wyświetleniu ""-- Kontynuuj --"" możesz nacisnąć dowolny klawisz, aby przejść do następnej strony.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Kontynuuj --"
     IDS_CONTINUE_PROGRESS "-- Kontynuuj (%d%%) --"
     IDS_FILE_ACCESS "Brak dostępu do pliku: %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 45bc899..8d5c990 100644 (file)
@@ -11,14 +11,34 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
 STRINGTABLE
 BEGIN
     IDS_USAGE "Afișează date pe ecran, pagină-cu-pagină.\n\n\
-  MORE < [Unitate:][Cale]Nume fișier\n\
-  Comandă | MORE\n\
-  MORE [Unitate:][Cale]Nume fișier\n\n\
-  [Unitate:][Cale]Nume fișier    Fișierul al cărui conținut va fi afișat.\n\
-  Comandă                        Comanda a cărei ieșire va fi afișată.\n\n\
-  La vederea sugestiei ""-- Continuă --"" veți apăsa o tastă pentru afișarea\n\
-  următoarei pagini.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Continuă --"
     IDS_CONTINUE_PROGRESS "-- Continuă (%d%%) --"
     IDS_FILE_ACCESS "Fișierul «%s» nu poate fi accesat!\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 49a4c45..d251bb0 100644 (file)
@@ -11,13 +11,34 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
 STRINGTABLE
 BEGIN
     IDS_USAGE "Показывать данные постранично заполняя экран.\n\n\
-  MORE < [диск:][путь]имя_файла\n\
-  имя_команды | MORE\n\
-  MORE [диск:][путь]имя_файла\n\n\
-  [диск:][путь]имя_файла    Файл, отображаемый по фрагментам.\n\
-  имя_команды             Команда, вывод которой отображается на экране.\n\n\
-  При запросе  ""-- Продолжить --"" вы можете нажать любую клавишу для отображения следующего экрана.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Продолжить --"
     IDS_CONTINUE_PROGRESS "-- Продолжить (%d%%) --"
     IDS_FILE_ACCESS "Нет доступа к файлу %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 7e4a9de..db3f798 100644 (file)
@@ -7,14 +7,34 @@ LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT
 STRINGTABLE
 BEGIN
     IDS_USAGE "Zobrazuje údaje, stránku za stránkou, na obrazovke.\n\n\
-  MORE < [Jednotka:][Cesta]Názov súboru\n\
-  Príkaz | MORE\n\
-  MORE [Jednotka:][Cesta]Názov súboru\n\n\
-  [Jednotka:][Cesta]Názov súboru    Súbor, ktorého obsah má byť zobrazený.\n\
-  Príkaz\t\t     Príkaz, ktorého výstup má byť zobrazený.\n\n\
-  Pri výzve ""-- Pokračujte --"" môžete stlačiť ľubovoľný kláves\n\
-  k zobrazeniu nasledujúcej stránky.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Pokračujte --"
     IDS_CONTINUE_PROGRESS "-- Pokračujte (%d%%) --"
     IDS_FILE_ACCESS "Neviem získať prístup k súboru %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 8ed10dd..6cf4a8b 100644 (file)
@@ -7,13 +7,34 @@ LANGUAGE LANG_ALBANIAN, SUBLANG_NEUTRAL
 STRINGTABLE
 BEGIN
     IDS_USAGE "Shfaq të dhëna faqe-per-faqe ne ekran.\n\n\
-  MORE < [Drive:][Path]File name\n\
-  Komandë | MORE\n\
-  MORE [Drive:][Path]File name\n\n\
-  [Drive:][Path]File name    Nje dokument, përmbajtja e të cilit do të shfaqet.\n\
-  Komandë\t\t     Nje komande, nxjerrja e te cilit do të shfaqet.\n\n\
-  At the prompt ""-- Vazhdo --"" ju mund të shtypni çfarëdo butoni për të vazhduar në faqen tjetër.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Vazhdo --"
     IDS_CONTINUE_PROGRESS "-- Vazhdo (%d%%) --"
     IDS_FILE_ACCESS "Nuk mund të aksesoj dokumentin %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 4d2a7fa..ea513e2 100644 (file)
@@ -10,13 +10,34 @@ LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
 STRINGTABLE
 BEGIN
     IDS_USAGE "Visa data sida-efter-sida på skärmen.\n\n\
-  MORE < [Enhet:][Mapp]Filnamn\n\
-  Kommando | MORE\n\
-  MORE [Enhet:][Mapp]Filnamn\n\n\
-  [Enhet:][Mapp]Filnamn    En fil, Välj innehåll som skall visas.\n\
-  Kommando\t\t     Ett kommando, Välj vad som skall visas.\n\n\
-  vid prompten ""-- Fortsätt --"" du kan trycka valfri knapp för att visa nästa sida.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Fortsätt --"
     IDS_CONTINUE_PROGRESS "-- Fortsätt (%d%%) --"
     IDS_FILE_ACCESS "Får inte tillgång till filen %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 155a71a..a8cb35e 100644 (file)
@@ -5,13 +5,34 @@ LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
 STRINGTABLE
 BEGIN
     IDS_USAGE "Görüntülükte veriyi sayfa sayfa görüntüler.\n\n\
-  MORE < [Sürücü:][Yol]Kütük adı\n\
-  Komut | MORE\n\
-  MORE [Sürücü:][Yol]Kütük adı\n\n\
-  [Sürücü:][Yol]Kütük adı    İçeriği görüntülenecek bir kütük.\n\
-  Komut\t\t     Çıkışı görüntülenecek bir komut.\n\n\
-  İstemde ""-- Sürdür --"" ile bir sonraki sayfayı göstermek için rastgele bir düğmeye basabilirsiniz.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Sürdür --"
     IDS_CONTINUE_PROGRESS "-- Sürdür (%%%d) --"
     IDS_FILE_ACCESS "%s kütüğüne erişilemiyor.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index 7b637f8..cdb5904 100644 (file)
@@ -10,14 +10,34 @@ LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
 STRINGTABLE
 BEGIN
     IDS_USAGE "Виводить iнфрмацію поекранно. Використання:\n\n\
-  MORE < [Диск:][Шлях]Iм'я_файлу\n\
-  Command | MORE\n\
-  MORE [Диск:][Шлях]Iм'я_файлу\n\n\
-  Де:\n\
-  [Диск:][Шлях]Ім'я_файлу    Файл, вмiст якого треба вивести на екран.\n\
-  Command\t\t     Команда, результат роботи якої треба вивести на екран.\n\n\
-  На запрошення ""-- Далi --"" Ви можете натиснути будь-яку клавiшу щоб побачити наступну сторiнку.\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- Далi --"
     IDS_CONTINUE_PROGRESS "-- Далi (%d%%) --"
     IDS_FILE_ACCESS "Не можу отримати доступ до файла %s.\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index c0b0b0e..da92aa5 100644 (file)
@@ -5,13 +5,34 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
 STRINGTABLE
 BEGIN
     IDS_USAGE "在屏幕上一页一页地显示内容。\n\n\
-  MORE < [驱动器:][路径]文件名\n\
-  命令 | MORE\n\
-  MORE [驱动器:][路径]文件名\n\n\
-  [驱动器:][路径]文件名    一个将要被如此显示内容的文件。\n\
-  命令\t\t     一个输出将要被如此显示的命令。\n\n\
-  在 ""-- 继续 --"" 的提示出现时你可以按任意键来显示下一页。\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- 继续 --"
     IDS_CONTINUE_PROGRESS "-- 继续 (%d%%) --"
     IDS_FILE_ACCESS "无法访问文件 %s。\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index c699579..9e26993 100644 (file)
@@ -5,13 +5,34 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
 STRINGTABLE
 BEGIN
     IDS_USAGE "在螢幕上一頁一頁地顯示內容。\n\n\
-  MORE < [磁碟機:][路徑]檔案名\n\
-  命令 | MORE\n\
-  MORE [磁碟機:][路徑]檔案名\n\n\
-  [磁碟機:][路徑]檔案名    一個將要被如此顯示內容的檔案。\n\
-  命令\t\t     一個輸出將要被如此顯示的命令。\n\n\
-  在 ""-- 繼續 --"" 的提示出現時你可以按任意鍵來顯示下一頁。\n"
+  MORE [options] < [Drive:][Path]Filename\n\
+  Command | MORE [options]\n\
+  MORE [options] [Drive:][Path]Filename\n\n\
+Options:\n\
+  /E        Enable extended features.\n\
+  /C        Clear screen before displaying page.\n\
+  /P        Expand form-feed characters.\n\
+  /S        Shrink multiple blank lines to a single line.\n\
+  /Tn       Expand tabs to n spaces (default: 8).\n\
+  +n        Start displaying the first file at line n.\n\n\
+  [Drive:][Path]Filename     A file, whose content shall be displayed.\n\
+  Command                    A command, whose output shall be displayed.\n\n\
+If extended features are enabled, the following commands are available\n\
+at ""-- Continue --"" prompt:\n\
+   P n      Display n lines.\n\
+   S n      Skip n lines.\n\
+   F        Display next file.\n\
+   Q        Quit.\n\
+   ?        Show help line.\n\
+   =        Show line number.\n\
+   <Space>  Display next page.\n\
+   <Enter>  Display next line.\n"
+
     IDS_CONTINUE "-- 繼續 --"
     IDS_CONTINUE_PROGRESS "-- 繼續 (%d%%) --"
     IDS_FILE_ACCESS "無法訪問檔案 %s。\n"
+    IDS_BAD_FLAG "Invalid argument - '%ls'\n"
+    IDS_CONTINUE_OPTIONS "-- Continue (%d%%) [Options: psfq=<Space><Enter>] --"
+    IDS_CONTINUE_LINES "-- Continue (%d%%) -- Lines: "
+    IDS_CONTINUE_LINE_AT "-- Continue (%d%%) [Line:%d] --"
 END
index b45ce96..5190bc6 100644 (file)
@@ -1,14 +1,13 @@
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS More Command
- * FILE:            base/applications/cmdutils/more/more.c
- * PURPOSE:         Displays text stream from STDIN or from an arbitrary number
- *                  of files to STDOUT, with screen capabilities (more than CAT,
- *                  but less than LESS ^^).
- * PROGRAMMERS:     Paolo Pantaleo
- *                  Timothy Schepens
- *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
- *                  Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
+ * PROJECT:     ReactOS More Command
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Displays text stream from STDIN or from an arbitrary number
+ *              of files to STDOUT, with screen capabilities (more than CAT,
+ *              but less than LESS ^^).
+ * COPYRIGHT:   Copyright 1999 Paolo Pantaleo
+ *              Copyright 2003 Timothy Schepens
+ *              Copyright 2016-2021 Hermes Belusca-Maito
+ *              Copyright 2021 Katayama Hirofumi MZ
  */
 /*
  * MORE.C - external command.
@@ -27,6 +26,7 @@
 
 #include <windef.h>
 #include <winbase.h>
+#include <winnt.h>
 #include <winnls.h>
 #include <winreg.h>
 #include <winuser.h>
@@ -51,14 +51,100 @@ HANDLE hKeyboard;
 /* Enable/Disable extensions */
 BOOL bEnableExtensions = TRUE; // FIXME: By default, it should be FALSE.
 
+#define FLAG_HELP (1 << 0)
+#define FLAG_E (1 << 1)
+#define FLAG_C (1 << 2)
+#define FLAG_P (1 << 3)
+#define FLAG_S (1 << 4)
+#define FLAG_Tn (1 << 5)
+#define FLAG_PLUSn (1 << 6)
+
+static DWORD s_dwFlags = 0;
+static LONG s_nTabWidth = 8;
+static DWORD s_nNextLineNo = 0;
+static BOOL s_bPrevLineIsBlank = FALSE;
+static UINT s_nPromptID = IDS_CONTINUE_PROGRESS;
+static BOOL s_bDoNextFile = FALSE;
+
+static BOOL IsBlankLine(IN PCWCH line, IN DWORD cch)
+{
+    DWORD ich;
+    WORD wType;
+    for (ich = 0; ich < cch; ++ich)
+    {
+        wType = 0;
+        GetStringTypeW(CT_CTYPE1, &line[ich], 1, &wType);
+        if (!(wType & (C1_BLANK | C1_SPACE)))
+            return FALSE;
+    }
+    return TRUE;
+}
+
+static BOOL __stdcall
+MorePagerLine(
+    IN OUT PCON_PAGER Pager,
+    IN PCWCH line,
+    IN DWORD cch)
+{
+    DWORD ich;
+
+    if (s_dwFlags & FLAG_PLUSn) /* Skip lines */
+    {
+        if (Pager->lineno < s_nNextLineNo)
+        {
+            Pager->dwFlags |= CON_PAGER_FLAG_DONT_OUTPUT;
+            s_bPrevLineIsBlank = FALSE;
+            return TRUE; /* Don't output */
+        }
+        s_dwFlags &= ~FLAG_PLUSn;
+    }
+
+    if (s_dwFlags & FLAG_S) /* Shrink blank lines */
+    {
+        if (IsBlankLine(line, cch))
+        {
+            if (s_bPrevLineIsBlank)
+            {
+                Pager->dwFlags |= CON_PAGER_FLAG_DONT_OUTPUT;
+                return TRUE; /* Don't output */
+            }
+
+            for (ich = 0; ich < cch; ++ich)
+            {
+                if (line[ich] == L'\n')
+                {
+                    s_bPrevLineIsBlank = TRUE;
+                    break;
+                }
+            }
+        }
+        else
+        {
+            s_bPrevLineIsBlank = FALSE;
+        }
+    }
+
+    s_nNextLineNo = 0;
+    return FALSE; /* Do output */
+}
 
 static BOOL
 __stdcall
 PagePrompt(PCON_PAGER Pager, DWORD Done, DWORD Total)
 {
     HANDLE hInput = ConStreamGetOSHandle(StdIn);
+    HANDLE hOutput = ConStreamGetOSHandle(Pager->Screen->Stream);
+    CONSOLE_SCREEN_BUFFER_INFO csbi;
+    COORD orgCursorPosition;
     DWORD dwMode;
+
     KEY_EVENT_RECORD KeyEvent;
+    BOOL fCtrl;
+    DWORD nLines;
+    WCHAR chSubCommand = 0;
+
+Restart:
+    nLines = 0;
 
     /*
      * Just use the simple prompt if the file being displayed is the STDIN,
@@ -88,16 +174,18 @@ PagePrompt(PCON_PAGER Pager, DWORD Done, DWORD Total)
     }
     else
     {
-        ConResPrintf(Pager->Screen->Stream, IDS_CONTINUE_PROGRESS,
-                     // (dwSumReadChars - Total + Done) * 100 / dwFileSize
-                     (dwSumReadBytes - (Total - Done) *
-                        (dwSumReadBytes / dwSumReadChars)) * 100 / dwFileSize
-                     );
+        DWORD dwPercent = (dwSumReadBytes - (Total - Done) *
+                           (dwSumReadBytes / dwSumReadChars)) * 100 / dwFileSize;
+        if (s_nPromptID == IDS_CONTINUE_LINE_AT)
+        {
+            ConResPrintf(Pager->Screen->Stream, s_nPromptID, dwPercent, Pager->lineno);
+        }
+        else
+        {
+            ConResPrintf(Pager->Screen->Stream, s_nPromptID, dwPercent);
+        }
     }
-
-    // TODO: Implement prompt read line!
-
-    // FIXME: Does not support TTY yet!
+    s_nPromptID = IDS_CONTINUE_PROGRESS;
 
     /* RemoveBreakHandler */
     SetConsoleCtrlHandler(NULL, TRUE);
@@ -106,25 +194,98 @@ PagePrompt(PCON_PAGER Pager, DWORD Done, DWORD Total)
     dwMode &= ~ENABLE_PROCESSED_INPUT;
     SetConsoleMode(hInput, dwMode);
 
-    do
+    // FIXME: Does not support TTY yet!
+    ConGetScreenInfo(Pager->Screen, &csbi);
+    orgCursorPosition = csbi.dwCursorPosition;
+    for (;;)
     {
-        // FIXME: Does not support TTY yet!
-
-        // ConInKey(&KeyEvent);
-        INPUT_RECORD ir;
+        INPUT_RECORD ir = {0};
         DWORD dwRead;
+        WCHAR ch;
+
         do
         {
             ReadConsoleInput(hInput, &ir, 1, &dwRead);
         }
         while ((ir.EventType != KEY_EVENT) || (!ir.Event.KeyEvent.bKeyDown));
 
-        /* Got our key, return to caller */
+        /* Got our key */
         KeyEvent = ir.Event.KeyEvent;
+
+        /* Ignore any unsupported keyboard press */
+        if ((KeyEvent.wVirtualKeyCode == VK_SHIFT) ||
+            (KeyEvent.wVirtualKeyCode == VK_MENU)  ||
+            (KeyEvent.wVirtualKeyCode == VK_CONTROL))
+        {
+            continue;
+        }
+
+        /* Ctrl key is pressed? */
+        fCtrl = !!(KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED));
+
+        /* Ctrl+C or Ctrl+Esc? */
+        if (fCtrl && ((KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
+                      (KeyEvent.wVirtualKeyCode == L'C')))
+        {
+            chSubCommand = 0;
+            break;
+        }
+
+        /* If extended features are unavailable, or no
+         * pending commands, don't do more processing. */
+        if (!(s_dwFlags & FLAG_E) || (chSubCommand == 0))
+            break;
+
+        ch = KeyEvent.uChar.UnicodeChar;
+        if (L'0' <= ch && ch <= L'9')
+        {
+            nLines *= 10;
+            nLines += ch - L'0';
+            ConStreamWrite(Pager->Screen->Stream, &ch, 1);
+            continue;
+        }
+        else if (KeyEvent.wVirtualKeyCode == VK_RETURN)
+        {
+            /* Validate the line number */
+            break;
+        }
+        else if (KeyEvent.wVirtualKeyCode == VK_ESCAPE)
+        {
+            /* Cancel the current command */
+            chSubCommand = 0;
+            break;
+        }
+        else if (KeyEvent.wVirtualKeyCode == VK_BACK)
+        {
+            if (nLines != 0)
+                nLines /= 10;
+
+            /* Erase the current character */
+            ConGetScreenInfo(Pager->Screen, &csbi);
+            if ( (csbi.dwCursorPosition.Y  > orgCursorPosition.Y) ||
+                ((csbi.dwCursorPosition.Y == orgCursorPosition.Y) &&
+                 (csbi.dwCursorPosition.X  > orgCursorPosition.X)) )
+            {
+                if (csbi.dwCursorPosition.X > 0)
+                {
+                    csbi.dwCursorPosition.X = csbi.dwCursorPosition.X - 1;
+                }
+                else if (csbi.dwCursorPosition.Y > 0)
+                {
+                    csbi.dwCursorPosition.Y = csbi.dwCursorPosition.Y - 1;
+                    csbi.dwCursorPosition.X = (csbi.dwSize.X ? csbi.dwSize.X - 1 : 0);
+                }
+
+                SetConsoleCursorPosition(hOutput, csbi.dwCursorPosition);
+
+                ch = L' ';
+                ConStreamWrite(Pager->Screen->Stream, &ch, 1);
+                SetConsoleCursorPosition(hOutput, csbi.dwCursorPosition);
+            }
+
+            continue;
+        }
     }
-    while ((KeyEvent.wVirtualKeyCode == VK_SHIFT) ||
-           (KeyEvent.wVirtualKeyCode == VK_MENU) ||
-           (KeyEvent.wVirtualKeyCode == VK_CONTROL));
 
     /* AddBreakHandler */
     SetConsoleCtrlHandler(NULL, FALSE);
@@ -140,9 +301,8 @@ PagePrompt(PCON_PAGER Pager, DWORD Done, DWORD Total)
     ConClearLine(Pager->Screen->Stream);
 
     /* Ctrl+C or Ctrl+Esc: Control Break */
-    if ((KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
-        ((KeyEvent.wVirtualKeyCode == L'C') &&
-         (KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))))
+    if (fCtrl && ((KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
+                  (KeyEvent.wVirtualKeyCode == L'C')))
     {
         /* We break, output a newline */
         WCHAR ch = L'\n';
@@ -150,18 +310,114 @@ PagePrompt(PCON_PAGER Pager, DWORD Done, DWORD Total)
         return FALSE;
     }
 
-    /* 'Q': Quit */
-    // FIXME: Available only when command extensions are enabled.
-    if ((KeyEvent.wVirtualKeyCode == L'Q') &&
-        !(KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))
+    switch (chSubCommand)
     {
-        /* We break, output a newline */
-        WCHAR ch = L'\n';
-        ConStreamWrite(Pager->Screen->Stream, &ch, 1);
-        return FALSE;
+        case L'P':
+        {
+            /* If we don't display other lines, just restart the prompt */
+            if (nLines == 0)
+            {
+                chSubCommand = 0;
+                goto Restart;
+            }
+            /* Otherwise tell the pager to display them */
+            Pager->ScrollRows = nLines;
+            return TRUE;
+        }
+        case L'S':
+        {
+            s_dwFlags |= FLAG_PLUSn;
+            s_nNextLineNo = Pager->lineno + nLines;
+            return TRUE;
+        }
+        default:
+            chSubCommand = 0;
+            break;
     }
 
-    return TRUE;
+    /* If extended features are available */
+    if (s_dwFlags & FLAG_E)
+    {
+        /* Ignore any key presses if Ctrl is pressed */
+        if (fCtrl)
+        {
+            chSubCommand = 0;
+            goto Restart;
+        }
+
+        /* 'Q': Quit */
+        if (KeyEvent.wVirtualKeyCode == L'Q')
+        {
+            /* We break, output a newline */
+            WCHAR ch = L'\n';
+            ConStreamWrite(Pager->Screen->Stream, &ch, 1);
+            return FALSE;
+        }
+
+        /* 'F': Next file */
+        if (KeyEvent.wVirtualKeyCode == L'F')
+        {
+            s_bDoNextFile = TRUE;
+            return FALSE;
+        }
+
+        /* '?': Show Options */
+        if (KeyEvent.uChar.UnicodeChar == L'?')
+        {
+            s_nPromptID = IDS_CONTINUE_OPTIONS;
+            goto Restart;
+        }
+
+        /* [Enter] key: Display one line */
+        if (KeyEvent.wVirtualKeyCode == VK_RETURN)
+        {
+            Pager->ScrollRows = 1;
+            return TRUE;
+        }
+
+        /* [Space] key: Display one page */
+        if (KeyEvent.wVirtualKeyCode == VK_SPACE)
+        {
+            if (s_dwFlags & FLAG_C)
+            {
+                /* Clear the screen */
+                ConClearScreen(Pager->Screen);
+            }
+            return TRUE;
+        }
+
+        /* 'P': Display n lines */
+        if (KeyEvent.wVirtualKeyCode == L'P')
+        {
+            s_nPromptID = IDS_CONTINUE_LINES;
+            chSubCommand = L'P';
+            goto Restart;
+        }
+
+        /* 'S': Skip n lines */
+        if (KeyEvent.wVirtualKeyCode == L'S')
+        {
+            s_nPromptID = IDS_CONTINUE_LINES;
+            chSubCommand = L'S';
+            goto Restart;
+        }
+
+        /* '=': Show current line number */
+        if (KeyEvent.uChar.UnicodeChar == L'=')
+        {
+            s_nPromptID = IDS_CONTINUE_LINE_AT;
+            goto Restart;
+        }
+
+        s_nPromptID = IDS_CONTINUE_PROGRESS;
+        chSubCommand = 0;
+        goto Restart;
+    }
+    else
+    {
+        /* Extended features are unavailable: display one page */
+        return TRUE;
+    }
 }
 
 /*
@@ -445,7 +701,6 @@ FileGetString(
     return TRUE;
 }
 
-
 static VOID
 LoadRegistrySettings(HKEY hKeyRoot)
 {
@@ -456,7 +711,8 @@ LoadRegistrySettings(HKEY hKeyRoot)
      * Buffer big enough to hold the string L"4294967295",
      * corresponding to the literal 0xFFFFFFFF (MAXULONG) in decimal.
      */
-    DWORD Buffer[6];
+    WCHAR Buffer[sizeof("4294967295")];
+    C_ASSERT(sizeof(Buffer) >= sizeof(DWORD));
 
     lRet = RegOpenKeyExW(hKeyRoot,
                          L"Software\\Microsoft\\Command Processor",
@@ -471,7 +727,7 @@ LoadRegistrySettings(HKEY hKeyRoot)
                             L"EnableExtensions",
                             NULL,
                             &dwType,
-                            (LPBYTE)&Buffer,
+                            (PBYTE)&Buffer,
                             &len);
     if (lRet == ERROR_SUCCESS)
     {
@@ -486,6 +742,138 @@ LoadRegistrySettings(HKEY hKeyRoot)
     RegCloseKey(hKey);
 }
 
+static BOOL IsFlag(PCWSTR param)
+{
+    PCWSTR pch;
+    PWCHAR endptr;
+
+    if (param[0] == L'/')
+        return TRUE;
+
+    if (param[0] == L'+')
+    {
+        pch = param + 1;
+        if (*pch)
+        {
+            (void)wcstol(pch, &endptr, 10);
+            return (*endptr == 0);
+        }
+    }
+    return FALSE;
+}
+
+static BOOL ParseArgument(PCWSTR arg, BOOL* pbHasFiles)
+{
+    PWCHAR endptr;
+
+    if (arg[0] == L'/')
+    {
+        switch (towupper(arg[1]))
+        {
+            case L'?':
+                if (arg[2] == 0)
+                {
+                    s_dwFlags |= FLAG_HELP;
+                    return TRUE;
+                }
+                break;
+            case L'E':
+                if (arg[2] == 0)
+                {
+                    s_dwFlags |= FLAG_E;
+                    return TRUE;
+                }
+                break;
+            case L'C':
+                if (arg[2] == 0)
+                {
+                    s_dwFlags |= FLAG_C;
+                    return TRUE;
+                }
+                break;
+            case L'P':
+                if (arg[2] == 0)
+                {
+                    s_dwFlags |= FLAG_P;
+                    return TRUE;
+                }
+                break;
+            case L'S':
+                if (arg[2] == 0)
+                {
+                    s_dwFlags |= FLAG_S;
+                    return TRUE;
+                }
+                break;
+            case L'T':
+                if (arg[2] != 0)
+                {
+                    s_dwFlags |= FLAG_Tn;
+                    s_nTabWidth = wcstol(&arg[2], &endptr, 10);
+                    if (*endptr == 0)
+                        return TRUE;
+                }
+                break;
+            default:
+                break;
+        }
+    }
+    else if (arg[0] == L'+')
+    {
+        if (arg[1] != 0)
+        {
+            s_dwFlags |= FLAG_PLUSn;
+            s_nNextLineNo = wcstol(&arg[1], &endptr, 10) + 1;
+            if (*endptr == 0)
+                return TRUE;
+        }
+    }
+
+    if (IsFlag(arg))
+    {
+        ConResPrintf(StdErr, IDS_BAD_FLAG, arg);
+        return FALSE;
+    }
+    else
+    {
+        *pbHasFiles = TRUE;
+    }
+
+    return TRUE;
+}
+
+static BOOL ParseMoreVariable(BOOL* pbHasFiles)
+{
+    BOOL ret = TRUE;
+    PWSTR psz;
+    PWCHAR pch;
+    DWORD cch;
+
+    cch = GetEnvironmentVariableW(L"MORE", NULL, 0);
+    if (cch == 0)
+        return TRUE;
+
+    psz = (PWSTR)malloc((cch + 1) * sizeof(WCHAR));
+    if (!psz)
+        return TRUE;
+
+    if (!GetEnvironmentVariableW(L"MORE", psz, cch + 1))
+    {
+        free(psz);
+        return TRUE;
+    }
+
+    for (pch = wcstok(psz, L" "); pch; pch = wcstok(NULL, L" "))
+    {
+        ret = ParseArgument(pch, pbHasFiles);
+        if (!ret)
+            break;
+    }
+
+    free(psz);
+    return ret;
+}
+
 // INT CommandMore(LPTSTR cmd, LPTSTR param)
 int wmain(int argc, WCHAR* argv[])
 {
@@ -499,12 +887,13 @@ int wmain(int argc, WCHAR* argv[])
 
     ENCODING Encoding;
     DWORD SkipBytes = 0;
+    BOOL HasFiles;
 
 #define FileCacheBufferSize 4096
     PVOID FileCacheBuffer = NULL;
     PWCHAR StringBuffer = NULL;
     DWORD StringBufferLength = 0;
-    DWORD dwReadBytes, dwReadChars;
+    DWORD dwReadBytes = 0, dwReadChars = 0;
 
     TCHAR szFullPath[MAX_PATH];
 
@@ -529,13 +918,8 @@ int wmain(int argc, WCHAR* argv[])
     /* Load the registry settings */
     LoadRegistrySettings(HKEY_LOCAL_MACHINE);
     LoadRegistrySettings(HKEY_CURRENT_USER);
-
-    // TODO: First, load the "MORE" environment variable and parse it,
-    // then parse the command-line parameters.
-
-    // FIXME: Parse all the remaining parameters.
-    // Then the file list can be found at the very end.
-    // FIXME2: Use the PARSER api that can be found in EVENTCREATE.
+    if (bEnableExtensions)
+        s_dwFlags |= FLAG_E;
 
     // NOTE: We might try to duplicate the ConOut for read access... ?
     hKeyboard = CreateFileW(L"CONIN$", GENERIC_READ|GENERIC_WRITE,
@@ -544,7 +928,6 @@ int wmain(int argc, WCHAR* argv[])
     FlushConsoleInputBuffer(hKeyboard);
     ConStreamSetOSHandle(StdIn, hKeyboard);
 
-
     FileCacheBuffer = HeapAlloc(GetProcessHeap(), 0, FileCacheBufferSize);
     if (!FileCacheBuffer)
     {
@@ -553,8 +936,31 @@ int wmain(int argc, WCHAR* argv[])
         return 1;
     }
 
+    /* First, load the "MORE" environment variable and parse it,
+     * then parse the command-line parameters. */
+    HasFiles = FALSE;
+    if (!ParseMoreVariable(&HasFiles))
+        return 1;
+    for (i = 1; i < argc; i++)
+    {
+        if (!ParseArgument(argv[i], &HasFiles))
+            return 1;
+    }
+
+    if (s_dwFlags & FLAG_HELP)
+    {
+        ConResPuts(StdOut, IDS_USAGE);
+        return 0;
+    }
+
+    Pager.PagerLine = MorePagerLine;
+    Pager.dwFlags |= CON_PAGER_FLAG_EXPAND_TABS;
+    if (s_dwFlags & FLAG_P)
+        Pager.dwFlags |= CON_PAGER_FLAG_EXPAND_FF;
+    Pager.nTabWidth = s_nTabWidth;
+
     /* Special case where we run 'MORE' without any argument: we use STDIN */
-    if (argc <= 1)
+    if (!HasFiles)
     {
         /*
          * Assign STDIN handle to hFile so that the page prompt function will
@@ -572,6 +978,7 @@ int wmain(int argc, WCHAR* argv[])
         // SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
         Encoding = ENCODING_ANSI; // ENCODING_UTF8;
 
+        /* Start paging */
         bContinue = ConPutsPaging(&Pager, PagePrompt, TRUE, L"");
         if (!bContinue)
             goto Quit;
@@ -596,7 +1003,7 @@ int wmain(int argc, WCHAR* argv[])
                                        StringBuffer, dwReadChars);
             /* If we Ctrl-C/Ctrl-Break, stop everything */
             if (!bContinue)
-                goto Quit;
+                break;
         }
         while (bRet && dwReadBytes > 0);
         goto Quit;
@@ -605,6 +1012,9 @@ int wmain(int argc, WCHAR* argv[])
     /* We have files: read them and output them to STDOUT */
     for (i = 1; i < argc; i++)
     {
+        if (IsFlag(argv[i]))
+            continue;
+
         GetFullPathNameW(argv[i], ARRAYSIZE(szFullPath), szFullPath, NULL);
         hFile = CreateFileW(szFullPath, 
                             GENERIC_READ,
@@ -616,7 +1026,7 @@ int wmain(int argc, WCHAR* argv[])
         if (hFile == INVALID_HANDLE_VALUE)
         {
             ConResPrintf(StdErr, IDS_FILE_ACCESS, szFullPath);
-            continue;
+            goto Quit;
         }
 
         /* We currently do not support files too big */
@@ -636,13 +1046,27 @@ int wmain(int argc, WCHAR* argv[])
         IsDataUnicode(FileCacheBuffer, dwReadBytes, &Encoding, &SkipBytes);
         SetFilePointer(hFile, SkipBytes, NULL, FILE_BEGIN);
 
+        /* Reset state for paging */
+        s_bPrevLineIsBlank = FALSE;
+        s_nPromptID = IDS_CONTINUE_PROGRESS;
+        s_bDoNextFile = FALSE;
+
         /* Update the statistics for PagePrompt */
         dwSumReadBytes = dwSumReadChars = 0;
 
+        /* Start paging */
         bContinue = ConPutsPaging(&Pager, PagePrompt, TRUE, L"");
         if (!bContinue)
         {
+            /* We stop displaying this file */
             CloseHandle(hFile);
+            if (s_bDoNextFile)
+            {
+                /* Bail out and continue with the other files */
+                continue;
+            }
+
+            /* We Ctrl-C/Ctrl-Break, stop everything */
             goto Quit;
         }
 
@@ -655,8 +1079,8 @@ int wmain(int argc, WCHAR* argv[])
             if (!bRet || dwReadBytes == 0 || dwReadChars == 0)
             {
                 /*
-                 * We failed at reading the file, bail out and
-                 * continue with the other files.
+                 * We failed at reading the file, bail out
+                 * and continue with the other files.
                  */
                 break;
             }
@@ -675,16 +1099,28 @@ int wmain(int argc, WCHAR* argv[])
                 bContinue = ConWritePaging(&Pager, PagePrompt, FALSE,
                                            StringBuffer, dwReadChars);
             }
-            /* If we Ctrl-C/Ctrl-Break, stop everything */
             if (!bContinue)
             {
-                CloseHandle(hFile);
-                goto Quit;
+                /* We stop displaying this file */
+                break;
             }
         }
         while (bRet && dwReadBytes > 0);
 
         CloseHandle(hFile);
+
+        /* Check whether we should stop displaying this file */
+        if (!bContinue)
+        {
+            if (s_bDoNextFile)
+            {
+                /* Bail out and continue with the other files */
+                continue;
+            }
+
+            /* We Ctrl-C/Ctrl-Break, stop everything */
+            goto Quit;
+        }
     }
 
 Quit:
index dc077bb..b477bcc 100644 (file)
@@ -4,3 +4,7 @@
 #define IDS_CONTINUE    101
 #define IDS_CONTINUE_PROGRESS   102
 #define IDS_FILE_ACCESS 103
+#define IDS_BAD_FLAG 104
+#define IDS_CONTINUE_OPTIONS 105
+#define IDS_CONTINUE_LINES 106
+#define IDS_CONTINUE_LINE_AT 107
index 8345906..24d0849 100644 (file)
@@ -2,8 +2,8 @@
  * PROJECT:     ReactOS Console Utilities Library
  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
  * PURPOSE:     Console/terminal paging functionality.
- * COPYRIGHT:   Copyright 2017-2018 ReactOS Team
- *              Copyright 2017-2018 Hermes Belusca-Maito
+ * COPYRIGHT:   Copyright 2017-2021 Hermes Belusca-Maito
+ *              Copyright 2021 Katayama Hirofumi MZ
  */
 
 /**
@@ -21,6 +21,7 @@
 #include <winbase.h>
 // #include <winnls.h>
 #include <wincon.h>  // Console APIs (only if kernel32 support included)
+#include <winnls.h> // for WideCharToMultiByte
 #include <strsafe.h>
 
 #include "conutils.h"
 // Temporary HACK
 #define CON_STREAM_WRITE    ConStreamWrite
 
+#define CP_SHIFTJIS 932  // Japanese Shift-JIS
+#define CP_HANGUL   949  // Korean Hangul/Wansung
+#define CP_JOHAB    1361 // Korean Johab
+#define CP_GB2312   936  // Chinese Simplified (GB2312)
+#define CP_BIG5     950  // Chinese Traditional (Big5)
 
+/* IsFarEastCP(CodePage) */
+#define IsCJKCodePage(CodePage) \
+    ((CodePage) == CP_SHIFTJIS || (CodePage) == CP_HANGUL || \
+  /* (CodePage) == CP_JOHAB || */ \
+     (CodePage) == CP_BIG5     || (CodePage) == CP_GB2312)
+
+static inline INT
+GetWidthOfCharCJK(
+    IN UINT nCodePage,
+    IN WCHAR ch)
+{
+    INT ret = WideCharToMultiByte(nCodePage, 0, &ch, 1, NULL, 0, NULL, NULL);
+    if (ret == 0)
+        ret = 1;
+    else if (ret > 2)
+        ret = 2;
+    return ret;
+}
+
+static VOID
+ConCallPagerLine(
+    IN OUT PCON_PAGER Pager,
+    IN PCTCH line,
+    IN DWORD cch)
+{
+    Pager->dwFlags &= ~CON_PAGER_FLAG_DONT_OUTPUT; /* Clear the flag */
+
+    if (!Pager->PagerLine || !Pager->PagerLine(Pager, line, cch))
+        CON_STREAM_WRITE(Pager->Screen->Stream, line, cch);
+}
+
+static BOOL
+ConPagerWorker(IN PCON_PAGER Pager)
+{
+    const DWORD ScreenColumns = Pager->ScreenColumns;
+    const DWORD ScrollRows = Pager->ScrollRows;
+    const PCTCH TextBuff = Pager->TextBuff;
+    const DWORD cch = Pager->cch;
+
+    BOOL bFinitePaging = ((ScreenColumns > 0) && (Pager->ScreenRows > 0));
+    LONG nTabWidth = Pager->nTabWidth;
+
+    DWORD ich = Pager->ich;
+    DWORD iColumn = Pager->iColumn;
+    DWORD iLine = Pager->iLine;
+    DWORD lineno = Pager->lineno;
+
+    DWORD ichStart = ich;
+    UINT nCodePage;
+    BOOL IsCJK;
+    UINT nWidthOfChar = 1;
+    BOOL IsDoubleWidthCharTrailing = FALSE;
+
+    if (ich >= cch)
+        return FALSE;
+
+    nCodePage = GetConsoleOutputCP();
+    IsCJK = IsCJKCodePage(nCodePage);
+
+    /* Normalize the tab width: if negative or too large,
+     * cap it to the number of columns. */
+    if (ScreenColumns > 0) // if (bFinitePaging)
+    {
+        if (nTabWidth < 0)
+            nTabWidth = ScreenColumns - 1;
+        else
+            nTabWidth = min(nTabWidth, ScreenColumns - 1);
+    }
+    else
+    {
+        /* If no column width is known, default to 8 spaces if the
+         * original value is negative; otherwise keep the current one. */
+        if (nTabWidth < 0)
+            nTabWidth = 8;
+    }
+
+    if (Pager->dwFlags & CON_PAGER_FLAG_EXPAND_TABS)
+    {
+ExpandTab:
+        while (Pager->nSpacePending > 0)
+        {
+            /* Stop now if we have displayed more screen lines than requested */
+            if (bFinitePaging && (iLine >= ScrollRows))
+                break;
+
+            ConCallPagerLine(Pager, L" ", 1);
+            --(Pager->nSpacePending);
+            ++iColumn;
+            if ((ScreenColumns > 0) && (iColumn % ScreenColumns == 0))
+            {
+                if (!(Pager->dwFlags & CON_PAGER_FLAG_DONT_OUTPUT))
+                    ++iLine;
+            }
+        }
+    }
+
+    /* Loop over each character in the buffer */
+    for (; ich < cch; ++ich)
+    {
+        /* Stop now if we have displayed more screen lines than requested */
+        if (bFinitePaging && (iLine >= ScrollRows))
+            break;
+
+        Pager->lineno = lineno;
+
+        /* NEWLINE character */
+        if (TextBuff[ich] == TEXT('\n'))
+        {
+            /* Output the pending text, including the newline */
+            ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart + 1);
+            ichStart = ich + 1;
+            if (!(Pager->dwFlags & CON_PAGER_FLAG_DONT_OUTPUT))
+                ++iLine;
+            iColumn = 0;
+
+            /* Done with this line; start a new one */
+            ++lineno;
+            continue;
+        }
+
+        /* TAB character */
+        if (TextBuff[ich] == TEXT('\t') &&
+            (Pager->dwFlags & CON_PAGER_FLAG_EXPAND_TABS))
+        {
+            /* Output the pending text */
+            ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart);
+
+            /* Perform tab expansion, unless the tab width is zero */
+            if (nTabWidth == 0)
+            {
+                ichStart = ich + 1;
+                continue;
+            }
+            ichStart = ++ich;
+            Pager->nSpacePending += nTabWidth - (iColumn % nTabWidth);
+            goto ExpandTab;
+        }
+
+        /* FORM-FEED character */
+        if (TextBuff[ich] == TEXT('\f') &&
+            (Pager->dwFlags & CON_PAGER_FLAG_EXPAND_FF))
+        {
+            /* Output the pending text, skipping the form-feed */
+            ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart);
+            ichStart = ich + 1;
+            // FIXME: Should we handle CON_PAGER_FLAG_DONT_OUTPUT ?
+
+            if (bFinitePaging)
+            {
+                /* Clear until the end of the screen */
+                while (iLine < ScrollRows)
+                {
+                    ConCallPagerLine(Pager, L"\n", 1);
+                    // CON_STREAM_WRITE(Pager->Screen->Stream, TEXT("\n"), 1);
+                    // if (!(Pager->dwFlags & CON_PAGER_FLAG_DONT_OUTPUT))
+                    ++iLine;
+                }
+            }
+            else
+            {
+                /* Just output a FORM-FEED character */
+                ConCallPagerLine(Pager, L"\f", 1);
+                // CON_STREAM_WRITE(Pager->Screen->Stream, L"\f", 1);
+            }
+
+            iColumn = 0;
+            continue;
+        }
+
+        /* Other character - Handle double-width for CJK */
+
+        if (IsCJK)
+        {
+            nWidthOfChar = GetWidthOfCharCJK(nCodePage, TextBuff[ich]);
+            if (ScreenColumns > 0)
+            {
+                IsDoubleWidthCharTrailing = (nWidthOfChar == 2) &&
+                                            ((iColumn + 1) % ScreenColumns == 0);
+            }
+        }
+
+        /* Care about CJK character presentation only when outputting
+         * to a device where the number of columns is known. */
+        if (ScreenColumns > 0)
+        {
+            if ((iColumn + nWidthOfChar) % ScreenColumns == 0)
+            {
+                /* Output the pending text, including the last double-width character */
+                ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart + 1);
+                ichStart = ich + 1;
+                if (!(Pager->dwFlags & CON_PAGER_FLAG_DONT_OUTPUT))
+                    ++iLine;
+                iColumn += nWidthOfChar;
+                continue;
+            }
+
+            if (IsDoubleWidthCharTrailing)
+            {
+                /* Output the pending text, excluding the last double-width character */
+                ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart);
+                ichStart = ich;
+                if (!(Pager->dwFlags & CON_PAGER_FLAG_DONT_OUTPUT))
+                    CON_STREAM_WRITE(Pager->Screen->Stream, TEXT(" "), 1);
+                --ich;
+                if (!(Pager->dwFlags & CON_PAGER_FLAG_DONT_OUTPUT))
+                    ++iLine;
+                ++iColumn;
+                continue;
+            }
+        }
+
+        iColumn += nWidthOfChar;
+    }
+
+    /* Output the remaining text */
+    if (ich - ichStart > 0)
+        ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart);
+
+    if (iLine >= ScrollRows)
+        iLine = 0; /* Reset the count of lines being printed */
+
+    Pager->ich = ich;
+    Pager->iColumn = iColumn;
+    Pager->iLine = iLine;
+    Pager->lineno = lineno;
+
+    return (ich < cch);
+}
 
 /* Returns TRUE when all the text is displayed, and FALSE if display is stopped */
 BOOL
@@ -43,75 +277,80 @@ ConWritePaging(
     IN DWORD len)
 {
     CONSOLE_SCREEN_BUFFER_INFO csbi;
-
-    /* Used to see how big the screen is */
-    DWORD ScreenLines = 0;
-
-    /* Chars since start of line */
-    DWORD CharSL;
-
-    DWORD from = 0, i = 0;
+    BOOL bIsConsole;
 
     /* Parameters validation */
     if (!Pager)
         return FALSE;
 
-    /* Reset LineCount and return if no string has been given */
-    if (StartPaging == TRUE)
-        Pager->LineCount = 0;
-    if (szStr == NULL)
-        return TRUE;
-
     /* Get the size of the visual screen that can be printed to */
-    if (!ConGetScreenInfo(Pager->Screen, &csbi))
+    bIsConsole = ConGetScreenInfo(Pager->Screen, &csbi);
+    if (bIsConsole)
+    {
+        /* Calculate the console screen extent */
+        Pager->ScreenColumns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
+        Pager->ScreenRows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+    }
+    else
     {
         /* We assume it's a file handle */
-        CON_STREAM_WRITE(Pager->Screen->Stream, szStr, len);
-        return TRUE;
+        Pager->ScreenColumns = 0;
+        Pager->ScreenRows = 0;
     }
 
-    /*
-     * Get the number of lines currently displayed on screen, minus 1
-     * to account for the "press any key..." prompt from PagePrompt().
-     */
-    ScreenLines = (csbi.srWindow.Bottom - csbi.srWindow.Top);
-    CharSL = csbi.dwCursorPosition.X;
-
-    /* Make sure the user doesn't have the screen too small */
-    if (ScreenLines < 4)
+    if (StartPaging)
     {
-        CON_STREAM_WRITE(Pager->Screen->Stream, szStr, len);
-        return TRUE;
+        if (bIsConsole)
+        {
+            /* Reset to display one page by default */
+            Pager->ScrollRows = Pager->ScreenRows - 1;
+        }
+        else
+        {
+            /* File output: all lines are displayed at once; reset to a default value */
+            Pager->ScrollRows = 0;
+        }
     }
 
-    while (i < len)
+    if (StartPaging)
     {
-        /* Search until the end of a line is reached */
-        if (szStr[i++] != TEXT('\n') && ++CharSL < csbi.dwSize.X)
-            continue;
+        /* Reset the output line count, the column index and the line number */
+        Pager->iLine = 0;
+        Pager->iColumn = 0;
+        Pager->lineno = 1;
+        Pager->nSpacePending = 0;
+    }
+
+    Pager->TextBuff = szStr;
+    Pager->cch = len;
+    Pager->ich = 0;
 
-        Pager->LineCount++;
-        CharSL = 0;
+    if (len == 0 || szStr == NULL)
+        return TRUE;
 
-        if (Pager->LineCount >= ScreenLines)
+    while (ConPagerWorker(Pager))
+    {
+        /* Prompt the user only when we display to a console and the screen
+         * is not too small: at least one line for the actual paged text and
+         * one line for the prompt. */
+        if (bIsConsole && (Pager->ScreenRows >= 2))
         {
-            CON_STREAM_WRITE(Pager->Screen->Stream, &szStr[from], i-from);
-            from = i;
+            /* Reset to display one page by default */
+            Pager->ScrollRows = Pager->ScreenRows - 1;
 
             /* Prompt the user; give him some values for statistics */
-            // FIXME TODO: The prompt proc can also take ScreenLines ??
-            if (!PagePrompt(Pager, from, len))
+            if (!PagePrompt(Pager, Pager->ich, Pager->cch))
                 return FALSE;
+        }
 
-            // TODO: Recalculate 'ScreenLines' in case the user redimensions
-            // the window during the prompt.
-
-            /* Reset the number of lines being printed */
-            Pager->LineCount = 0;
+        /* If we display to a console, recalculate its screen extent
+         * in case the user has redimensioned it during the prompt. */
+        if (bIsConsole && ConGetScreenInfo(Pager->Screen, &csbi))
+        {
+            Pager->ScreenColumns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
+            Pager->ScreenRows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
         }
     }
-    if (i > from)
-        CON_STREAM_WRITE(Pager->Screen->Stream, &szStr[from], i-from);
 
     return TRUE;
 }
index 31a3ba8..61bbad6 100644 (file)
@@ -2,8 +2,8 @@
  * PROJECT:     ReactOS Console Utilities Library
  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
  * PURPOSE:     Console/terminal paging functionality.
- * COPYRIGHT:   Copyright 2017-2018 ReactOS Team
- *              Copyright 2017-2018 Hermes Belusca-Maito
+ * COPYRIGHT:   Copyright 2017-2021 Hermes Belusca-Maito
+ *              Copyright 2021 Katayama Hirofumi MZ
  */
 
 /**
 extern "C" {
 #endif
 
-
 // #include <wincon.h>
 
+struct _CON_PAGER;
+typedef BOOL (__stdcall *CON_PAGER_LINE_FN)(
+    IN OUT struct _CON_PAGER *Pager,
+    IN PCTCH line,
+    IN DWORD cch);
+
+/* Flags for CON_PAGER */
+#define CON_PAGER_FLAG_DONT_OUTPUT (1 << 0)
+#define CON_PAGER_FLAG_EXPAND_TABS (1 << 1)
+#define CON_PAGER_FLAG_EXPAND_FF   (1 << 2)
 
 typedef struct _CON_PAGER
 {
+    /* Console screen properties */
     PCON_SCREEN Screen;
-
-    // TODO: Add more properties. Maybe those extra parameters
-    // of PAGE_PROMPT could go there?
-
-    /* Used to count number of lines since last pause */
-    DWORD LineCount;
+    DWORD ScreenColumns;
+    DWORD ScreenRows;
+
+    /* Paging parameters */
+    CON_PAGER_LINE_FN PagerLine; /* The line function */
+    LONG  nTabWidth;
+    DWORD ScrollRows;
+
+    /* Data buffer */
+    PCTCH TextBuff; /* The text buffer */
+    DWORD cch;      /* The total number of characters */
+
+    /* Paging state */
+    DWORD ich;      /* The current index of character */
+    DWORD iColumn;  /* The current index of column */
+    DWORD iLine;    /* The physical output line count of screen */
+    DWORD lineno;   /* The logical line number */
+    DWORD dwFlags;  /* The CON_PAGER_FLAG_... flags */
+    DWORD nSpacePending;
 } CON_PAGER, *PCON_PAGER;
 
 #define INIT_CON_PAGER(pScreen)     {(pScreen), 0}
 
-#define InitializeConPager(pPager, pScreen) \
+#define InitializeConPager(pPager, pScreen)  \
 do { \
-    (pPager)->Screen = (pScreen);   \
-    (pPager)->LineCount = 0;        \
+    ZeroMemory((pPager), sizeof(*(pPager))); \
+    (pPager)->Screen = (pScreen);            \
 } while (0)