mendex/upmendex と makeindex での空入力に対する挙動の違い

mendex/upmendex と makeindex での空入力に対する挙動の違い

- Lemures Lemniscati の投稿
返信数: 24

makeindex では入力が空でも exit code は 0 なのですが,
$ makeindex < /dev/null ; echo $?
This is makeindex, version 2.17 [TeX Live 2025] (kpathsea + Thai support).
Scanning input file stdin...done (0 entries accepted, 0 rejected).
Nothing written in stdout.
Transcript written in stderr.
0

mendex/upmendex だと exit code が 255 になります.
$ mendex < /dev/null ; echo $?
This is mendex version 3.8 [09-Feb-2025] (utf8.uptex) (TeX Live 2025).
Scanning input file stdin....done (0 entries accepted, 0 rejected).
0 entries accepted, 0 rejected.
Nothing written in output file.
255

$ upmendex < /dev/null ; echo $?
This is upmendex version 1.11 [ICU 76.1] (TeX Live 2025).
Scanning input file stdin....done (0 entries accepted, 0 rejected).
0 entries accepted, 0 rejected.
Nothing written in output file.
255

非常にニッチかつ些末なことで大変恐縮ですが,これはなにか意図があっての違いなのでしょうか.
できれば共通のほうがよいのですが……

※ exit code の違いのほかにも下記のような微妙な違いがありましたが,これはどちらでもよいような気がします.
mendex/upmenex  だと,0 entries accepted, 0 rejected. が(ある意味,二重に)出力されるが,makeindex では(ある意味,一度しか)出力されない.
makeindex だと,Nothing written in stdout. が出力されるが,mendex/upmendex では Nothing written in output file. が出力される.
makeindex だと,Transcript written in stderr. が出力されるが,mendex/upmendex では出力されない.

Lemures Lemniscati への返信

Re: mendex/upmendex と makeindex での空入力に対する挙動の違い

- 和田 勇 の投稿

makeindex と mendex/upmendex ではソースが異なるので統一するのは難しいと思います。

参照したソースは makeindexmendex/upmendex です。

もし makeinndex と mended/upmedex の処理結果からその後の処理をと お考えなら、exit status ではなく 出力ファイルの有無、また存在すれば empty か否かチェック する方法も考えられます。

和田 勇 への返信

Re: mendex/upmendex と makeindex での空入力に対する挙動の違い

- Lemures Lemniscati の投稿

ありがとうございます.

実は,索引語を一つも設定していないテンプレートの動作確認をしようとするときに latexmk 経由で mendex/upmendex を使おうとしてエラーになるのを避けたかったのです(makeindex では問題ありません).この目的のためには,テンプレートのほうにダミーの索引語を入れておくのが簡単なようです.

さて,GItHub にある mendex のソースを拝見しました.GIt にあるもっとも古いコミットでも,索引語が見つからないときは -1 を返すようになっていました.
しかし,その一方で,mendex の文書(2025-05-10版 PDFソースの該当部分)の「1.3 参考:makeindex との比較」では,このようなケースについて makeindex との差異にあげられていませんでした.

もしかすると,これは意図されていなかった非互換性なのかもしれないと愚考している次第です.

Lemures Lemniscati への返信

Re: mendex/upmendex と makeindex での空入力に対する挙動の違い

- t tk の投稿
> GIt にあるもっとも古いコミットでも,索引語が見つからないときは -1 を返すようになっていました

索引語が見つからないときの返り値を -1 から 255 に替えたのはPeterさんで、2012年7月のことのようです。
exit()関数は、ゼロならば正常終了、非ゼロならば異常終了を示しつつatexit()で登録されている事後処理は実行する、と解説書にあります。
-1でも255でも本質的には変わりないので、原作者のASCII社がどう考えていたか、が焦点になると思います。

> 意図されていなかった非互換性なのかもしれない
これは原作者のASCII社の中の人がどう考えていたか、になりますが、当時の事情をご存じの方がいらっしゃるかどうか。

upmendex の開発は、2015年頃のTeX Live版のmendex (mendex version 2.6f [14-Aug-2009] (TeX Live 2015/dev))をベースにしています。
upmendexの開発方針は、mendexのUnicode化、骨格部分はmendexを踏襲する、というものです。
なので、当初の方針からすると、現状の仕様は整合性が取れています。
「索引語が一つもない」状態が「正常ではない」と判断すべきものだ、とmendexが考えているのであれば、upmendexは踏襲したい、と思っています。
しかし、昨今、makeindexとの互換性は高める方向にしたいとも考えており、今後の議論の内容によっては考えを改めるかもしれません。

----
mendexk の ChangeLogより抜粋:

2012-07-26 Peter Breitenlohner
* fwrite.c, main.c: Use binary mode for input and output
(from W32TeX).
* convert.c, fread.c, main.c: Use 8-bit exit() codes.
* main.c: Terminate main() with return instead of exit().
t tk への返信

Re: mendex/upmendex と makeindex での空入力に対する挙動の違い

- Lemures Lemniscati の投稿

※ exit code の挙動を変えてほしい(索引の語が一つもない場合もエラーにしないようにしてほしい/空のテンプレート用意したときのテストで特に複雑なことをせずにパスできるように)という立場で,発言します.

asciidwango のリポジトリにある mendexk のソースファイル [1] で READMEを見比べると,「<特徴>」のところで,

mendexk2.4b ~ mendexk2.4f では,
「・基本的に makeindex 上位互換。」
と,
mendex2.5 ~ mendex2.6f では,
「・基本的にmakeindex互換だが、以下の点で非互換。……(以下略)」
と,書かれています.

これらは,株式会社アスキーの名前を入れて配布された文書ですが,いずれにおいても exit code には言及されていませんでした.
[1]: https://github.com/asciidwango/ptex/tree/master/archives/ascii-ptex/mendex

書かれていないことについてあれこれいうのには飛躍がありますが,exit code のことはあまり気に留めていらっしゃらなかったのではないかと推測します.

また,mendex2.6f で main.c の該当箇所の直前を含めたコードをみると,以下のようになっていて,
`````` mendex2.6f/main.c
       if (ecount!=0) {
                if (verb!=0) {
                        fprintf(stderr,"%d errors, written in %s.\n",ecount,logfile);
                }
                if (efp!=stderr) {
                        fprintf(efp,"%d errors.\n",ecount);
                }
                lines=0;
        }
        if (lines==0) {
                if (verb!=0) {
                        fprintf(stderr,"Nothing written in output file.\n");
                }
                if (efp!=stderr) {
                        fprintf(efp,"Nothing written in output file.\n");
                        fclose(efp);
                }
                exit(-1);
        }
``````
ecount != 0 のときに lines = 0 と設定しておき,lines==0 の条件に引っ掛けて exit (-1) を踏ませるような仕組みになっています.

全く個人的な意見ですが,エラーもなく lines==0 のときは exit(0) でもよいものが,エラーがあって ecount!=0 となる場合に lines=0 として処理を終了させようとした影響で,一緒に exit (-1) を踏まされるようになったとみることもできます.

少し長くなってしまいますが exit code を気にするなら次のように書いてもよかったのではないかと思いました.

``````
       if (ecount!=0) {
                if (verb!=0) {
                        fprintf(stderr,"%d errors, written in %s.\n",ecount,logfile);
                }
                if (efp!=stderr) {
                        fprintf(efp,"%d errors.\n",ecount);
                }
                /* lines=0; 削除 */ 
        }
        if (lines==0 || ecount!=0) {  /* (lines==0) から変更*/
                if (verb!=0) {
                        fprintf(stderr,"Nothing written in output file.\n");
                }
                if (efp!=stderr) {
                        fprintf(efp,"Nothing written in output file.\n");
                        fclose(efp);
                }
                /* exit(-1); 削除して以下を追加 */
                if (ecount!=0) {
                  exit(-1);
                } else {
                  exit(0);
                }
                /* ここまでを追加 */
       }
``````
長々とすみません.

Lemures Lemniscati への返信

Re: mendex/upmendex と makeindex での空入力に対する挙動の違い

- Lemures Lemniscati の投稿
例えば,現行の mendex, upmendex については,添付のようなパッチはいかがでしょうか.

From 9a8b365061b66eda39ca1a7eff4aeb8ff383e75d Mon Sep 17 00:00:00 2001
From: Lemures Lemniscati <lemures.lemniscati@gmail.com>
Date: Mon, 14 Jul 2025 20:10:28 +0900
Subject: [PATCH] mendexk, upmendex: main() return exit code 0 when lines==0
 without error

---
 source/texk/mendexk/main.c  | 6 +++---
 source/texk/upmendex/main.c | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/source/texk/mendexk/main.c b/source/texk/mendexk/main.c
index 88be84da3..871638d08 100644
--- a/source/texk/mendexk/main.c
+++ b/source/texk/mendexk/main.c
@@ -325,12 +325,12 @@ int main(int argc, char **argv)
 
     if (ecount!=0) {
         verb_printf(efp,"%d errors, written in %s.\n",ecount,logfile);
-        lines=0;
     }
-    if (lines==0) {
+    if ((lines==0)||(ecount!=0)) {
         verb_printf(efp,"Nothing written in output file.\n");
         if (efp!=stderr) fclose(efp);
-        exit(255);
+        if (ecount!=0) exit(255);
+        return 0;
     }
 
 /*   sort index   */
diff --git a/source/texk/upmendex/main.c b/source/texk/upmendex/main.c
index bfafbae80..a78bbd164 100644
--- a/source/texk/upmendex/main.c
+++ b/source/texk/upmendex/main.c
@@ -312,12 +312,12 @@ int main(int argc, char **argv)
 
     if (ecount!=0) {
         verb_printf(efp,"%d errors, written in %s.\n",ecount,logfile);
-        lines=0;
     }
-    if (lines==0) {
+    if ((lines==0)||(ecount!=0)) {
         verb_printf(efp,"Nothing written in output file.\n");
         if (efp!=stderr) fclose(efp);
-        exit(255);
+        if (ecount!=0) exit(255);
+        return 0;
     }
 
 /*   sort index   */
-- 
2.45.1

Lemures Lemniscati への返信

Re: mendex/upmendex と makeindex での空入力に対する挙動の違い

- 和田 勇 の投稿

※ exit code の挙動を変えてほしい

この要望は賛同しますが、mendex/upmendex の現状の基本動作は変更してほしくないと言うのが私の意見。

ご提案の改修方法は mendex/upmendex 作成時頃であれば妥当かもしれませんが、「索引の語が一つもない場合もエラーにしないようにしてほしい...(略)」を満足する -ignore-no-index(仮)のような コンパーティブルオプションの追加でも対応可能かと思います。

これは、杞憂かもしれませんが、latexmk ではなく スクリプトファイルで運用されているかもしれないユーザ対策としてです。

和田 勇 への返信

Re: mendex/upmendex と makeindex での空入力に対する挙動の違い

- Lemures Lemniscati の投稿

> 「索引の語が一つもない場合もエラーにしないようにしてほしい...(略)」を満足する -ignore-no-index(仮)のような コンパーティブルオプションの追加でも対応可能かと思います。
> これは、杞憂かもしれませんが、latexmk ではなく スクリプトファイルで運用されているかもしれないユーザ対策としてです。

確かにオプションの追加でも十分ですので,いずれにしても修正が入ると助かります.


些細なことですが,makeindex との互換性をより高める機会を得るか失うか,もし exit code を変更すると困りそうな人がどのくらいいるか,ということでの選択なのだと思います.

Lemures Lemniscati への返信

Re: mendex/upmendex と makeindex での空入力に対する挙動の違い

- 和田 勇 の投稿

たまたま見つけたコードですので読み違いかもしれませんが。

makeindex/src/mkind.c の static void prepare_idx(VOID_ARG) 内の289行目、290行目に以下のような記述があります。

        if (head == (NODE_PTR)NULL)
        FATAL("No valid index entries collected.\n", "");

NULL になるのは malloc で領域取得失敗したときで、その時点で FATAL エラーにはなっています。 ですので上記のコードはフェールセーフなコード故に実際に動くことはありません。

しかし、このコードから、makeindex も当初はエントリー無しはエラーにしたかったのではと思えてきました。

エントリー無しは軽微なエラーだとしてスルーして欲しい気持ちは理解できますが、 その逆も有りだとも考えることができます。

以上から、私見では有りますが、mended/upmendex に makeindex のこの挙動に準拠するようなオプションを追加した方が良いように思っています。

和田 勇 への返信

Re: mendex/upmendex と makeindex での空入力に対する挙動の違い

- Lemures Lemniscati の投稿

GItHub にある TeX Live のミラーで,現行の makeindex のソースをみてみました.
https://github.com/TeX-Live/texlive-source/tree/f767c1003714b2caa71ffc740c57399bf79f0f3d/texk/makeindexk

このソースに基づくと,makeindex において exit code の挙動は以下のように要約できます.

  • FATAL が出たら,exit code は 1 .
  • FATAL が出なかったら(ERROR があっても),exit code は 0 .

個人的にはちょっと衝撃的だったので,どう考えるべきか悩んでいます……

確かに,オプション対応のほうがよさそうな気がしてきました.

Lemures Lemniscati への返信

Re: mendex/upmendex と makeindex での空入力に対する挙動の違い

- t tk の投稿
ご意見、パッチありがとうございます。
makeindexとmendex/upmendexの互換性を高めたい、もしくは、mendex/upmendexの挙動をmakeindexに近づけたい、という考え方はありだと思っています。
特にupmendexは日本語圏の外でも使われだしており、makeindexからupmendexに移行してみたいという方も出てきているので思わぬ差異は出来れば減らしたいと思っています。
ただ、アスキー社さんのmendexはmakeindexの仕様を参考にしつつスクラッチからお書きになったものなので、完璧にmakeindexに揃えるのは無理とも思っています。
また、既存の動作を変えると影響が出て困ってしまう人がいるかもしれず、悩ましいところです。

今回の件に限定しないで、網羅的に比較した場合、アスキー社さんの「以下の点で非互換」と明記した部分以外の互換性・非互換性はどの程度なのでしょうか?
見つかったところを見つかるたびに対症療法的にパッチしていくのではなく、全体方針のようなものをつくれたら好ましい…と思いつつ面倒そうで手付かずです。

↓こちらでもエラー処理について質問を受けていますが、ちゃんと回答できていません。
https://github.com/t-tk/upmendex-package/issues/12
t tk への返信

Re: mendex/upmendex と makeindex での空入力に対する挙動の違い

- Lemures Lemniscati の投稿
> 見つかったところを見つかるたびに対症療法的にパッチしていくのではなく、全体方針のようなものをつくれたら好ましい…と思いつつ面倒そうで手付かずです。
メンテナンスが大変になりそうですが……
変更する挙動に対して, makeindex よりの挙動をさせるためのオプションと,mendex/upmendexの既存の挙動を維持するオプションの両方作成して準備したうえで,
メジャーバージョンアップをする際に,徐々に挙動変更の予告を出すようにしたり,デフォルトの動作を makeindex に寄せていくなどでしょうか.

私自身は,索引について関心を持ち始めたばかりなので細かなことはよくわかっていません.
Lemures Lemniscati への返信

mendex/upmendex と makeindex での挙動の違い

- Lemures Lemniscati の投稿

これは別スレッドか github のほうに書くのがよいのかもしれませんが,当座のメモとして残しておきます.

下記のように,Bash で赤字の部分を実行すると……
makeindex のときは,二番目のエントリがページ番号のエラーで無視され,ますが exit code は 0 で終了します(FATALがないため).
mendex/upmendex のときは,二番目のエントリはエラーなく受け入れられますが,結果を書き出すときに Segmentation fault が起きます……

printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{-1.1.1}' | makeindex -s <( printf '%s\n' 'page_compositor "."' ); printf '%s\n' "${PIPESTATUS[@]}"
Scanning style file /dev/fd/63.done (1 attributes redefined, 0 ignored).
This is makeindex, version 2.17 [TeX Live 2025] (kpathsea + Thai support).
Scanning input file stdin....
!! Input index error (file = stdin, line = 2):
   -- Illegal page number -1.1.1 or page_precedence rnaRA.
done (1 entries accepted, 1 rejected).
Sorting entries...done (0 comparisons).
Generating output file stdout...\begin{theindex}
.
  \item entryA, 0

\end{theindex}
done (5 lines written, 0 warnings).
Output written in stdout.
Transcript written in stderr.
0
0

$ printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{-1.1.1}' | mendex -s <( printf '%s\n' 'page_compositor "."' ); printf '%s\n' "${PIPESTATUS[@]}"
This is mendex version 3.8 [09-Feb-2025] (utf8.uptex) (TeX Live 2025).
Scanning style file /dev/fd/63....done.
Scanning input file stdin....done (2 entries accepted, 0 rejected).
2 entries accepted, 0 rejected.
Sorting index....done(0 comparisons).
Sorting pages....done(2 comparisons).
Making index file.\begin{theindex}

Segmentation fault
0
139

$ printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{-1.1.1}' | upmendex -s <( printf '%s\n' 'page_compositor "."' ); printf '%s\n' "${PIPESTATUS[@]}"
This is upmendex version 1.11 [ICU 76.1] (TeX Live 2025).
Scanning style file /dev/fd/63....done.
Scanning input file stdin....done (2 entries accepted, 0 rejected).
2 entries accepted, 0 rejected.
Sorting index....done(0 comparisons).
Sorting pages....done(2 comparisons).
Making index file.\begin{theindex}

Segmentation fault
0
139

Lemures Lemniscati への返信

Re: mendex/upmendex と makeindex での挙動の違い

- 和田 勇 の投稿

示された bash で試されたものをそのままコピペして macOS 環境で実施しましたが エラーにはなりませんでした。

    This is upmendex version 1.11 [ICU 76.1] (TeX Live 2025).
    Scanning style file /dev/fd/63....done.
    Scanning input file stdin....done (2 entries accepted, 0 rejected).
    2 entries accepted, 0 rejected.
    Sorting index....done(0 comparisons).
    Sorting pages....done(2 comparisons).
    Making index file.\begin{theindex}

    \item entryA, -1.1.1, 0

    \end{theindex}
    ...done.
    0 warnings, written in stderr.
    Output written in stdout.
    0
    0

これから所用で外出するので、詳しくは後ほどテストしますが、 お試しの OS 環境は? linux ? windows? freeBSD? その他? それと bash のバージョンも教えてください。

PS

(なので、これは別スレッドの方がよいかな?)

和田 勇 への返信

Re: mendex/upmendex と makeindex での挙動の違い

- t tk の投稿
こちらは、WindowsのWSLの ubuntu (Ubuntu 22.04.2 LTS) です。
お示しになったスクリプトで Segmentation fault は再現しません。

makeindex, mendex, upmendex のversionは以下。

This is makeindex, version 2.15 [TeX Live 2022/dev] (kpathsea + Thai support).
This is mendex version 3.5 [13-Jun-2021] (utf8.uptex) (TeX Live 2022/dev).
This is upmendex version 0.57 [ICU 70.1] (TeX Live 2022/dev).
This is mendex version 3.8 [09-Feb-2025] (utf8.uptex) (TeX Live 2026/dev).
This is upmendex version 1.20 [ICU 76.1] (TeX Live 2026/dev).
t tk への返信

Re: mendex/upmendex と makeindex での挙動の違い

- はやて (h20y6m) の投稿
Ubuntu 22.04.5 LTS on WSL の TeX Live 2024 ですが、
Valgrind で --malloc-fill=CD とかすると SEGV 再現できますね
(mendex が debug ビルドでないのでどこで落ちてるかわかりませんが……)

$ valgrind --malloc-fill=CD mendex -s test.ist < test.ind
==1044== Memcheck, a memory error detector
==1044== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1044== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==1044== Command: mendex -s test.ist
==1044==
This is mendex version 3.6 [12-Jun-2022] (utf8.uptex) (TeX Live 2024).
Scanning style file ./test.ist.(guessed encoding #3: ASCII = utf8)...done.
Scanning input file stdin....done (2 entries accepted, 0 rejected).
2 entries accepted, 0 rejected.
Sorting index....done(0 comparisons).
Sorting pages....done(2 comparisons).
Making index file.\begin{theindex}

==1044== Use of uninitialised value of size 8
==1044==    at 0x4043C7: ??? (in /usr/local/texlive/2024/bin/x86_64-linux/mendex)
==1044==    by 0x406BBE: ??? (in /usr/local/texlive/2024/bin/x86_64-linux/mendex)
==1044==    by 0x4081F0: ??? (in /usr/local/texlive/2024/bin/x86_64-linux/mendex)
==1044==    by 0x4028F6: ??? (in /usr/local/texlive/2024/bin/x86_64-linux/mendex)
==1044==    by 0x488CD8F: (below main) (libc_start_call_main.h:58)
==1044==
==1044== Invalid read of size 1
==1044==    at 0x4043C7: ??? (in /usr/local/texlive/2024/bin/x86_64-linux/mendex)
==1044==    by 0x406BBE: ??? (in /usr/local/texlive/2024/bin/x86_64-linux/mendex)
==1044==    by 0x4081F0: ??? (in /usr/local/texlive/2024/bin/x86_64-linux/mendex)
==1044==    by 0x4028F6: ??? (in /usr/local/texlive/2024/bin/x86_64-linux/mendex)
==1044==    by 0x488CD8F: (below main) (libc_start_call_main.h:58)
==1044==  Address 0xffffffffce105a4d is not stack'd, malloc'd or (recently) free'd
==1044==
==1044==
==1044== Process terminating with default action of signal 11 (SIGSEGV)
和田 勇 への返信

Re: mendex/upmendex と makeindex での挙動の違い

- 和田 勇 の投稿

Segmentation faultの方に気を取られていました。 これはこれで問題なのですが当方でテストした bash の $BASH_VERSION は OS バンドルのもの 3.2.57(1)-release と homebrew で追加インストールしたもの 5.3.0(1)-release です。

さて、よくよく見るとページ番号 0-1.0.0 でしたね。

なので mendex/upmendex でも以下のようなメッセージが出力されることを期待されてたのかな?

    !! Input index error (file = stdin, line = 2):
       -- Illegal page number -1.1.1 or page_precedence rnaRA.

まだ分析中ですが、makeindex では-1.1.1- で蹴られていますね。 試したのは -1 としたときに警告が出ますので。mendex/upmendex は問題なく処理されるようです。

途中経過ですがレポートしておきます。 `

和田 勇 への返信

Re: mendex/upmendex と makeindex での挙動の違い

- Lemures Lemniscati の投稿
皆様,テストありがとうございます.

私の使用している環境を示し損ねていてすみません.
Cygwin で最新版にアップデートしてから実行してみましたが Segmentation fault でした.

$ uname -svrmopi; bash --version | head -1; printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{-1.1.1}' | mendex -s <( printf '%s\n' 'page_compositor "."' ); printf '%s\n' "${PIPESTATUS[@]}"
CYGWIN_NT-10.0-26100 3.6.4-1.x86_64 2025-07-15 07:55 UTC x86_64 unknown unknown Cygwin
GNU bash, version 5.2.21(1)-release (x86_64-pc-cygwin)
This is mendex version 3.8 [09-Feb-2025] (utf8.uptex) (TeX Live 2025).
Scanning style file /dev/fd/63....done.
Scanning input file stdin....done (2 entries accepted, 0 rejected).
2 entries accepted, 0 rejected.
Sorting index....done(0 comparisons).
Sorting pages....done(2 comparisons).
Making index file.\begin{theindex}

Segmentation fault
0
139

$ uname -svrmopi; bash --version | head -1; printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{-1.1.1}' | upmendex -s <( printf '%s\n' 'page_compositor "."' ); printf '%s\n' "${PIPESTATUS[@]}"
CYGWIN_NT-10.0-26100 3.6.4-1.x86_64 2025-07-15 07:55 UTC x86_64 unknown unknown Cygwin
GNU bash, version 5.2.21(1)-release (x86_64-pc-cygwin)
This is upmendex version 1.11 [ICU 76.1] (TeX Live 2025).
Scanning style file /dev/fd/63....done.
Scanning input file stdin....done (2 entries accepted, 0 rejected).
2 entries accepted, 0 rejected.
Sorting index....done(0 comparisons).
Sorting pages....done(2 comparisons).
Making index file.\begin{theindex}

Segmentation fault
0
139

$


そのほか,makeindex の挙動も不思議でした.通常はありえない入力に対してですが…… 
やはり Segmentation fault や,ページ番号のソート順がおかしかったりします.

$ uname -svrmopi; bash --version | head -1; printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{1234567890123456789}' '\indexentry{entryA}{12345678901234567890}' | makeindex
CYGWIN_NT-10.0-26100 3.6.4-1.x86_64 2025-07-15 07:55 UTC x86_64 unknown unknown Cygwin
GNU bash, version 5.2.21(1)-release (x86_64-pc-cygwin)
This is makeindex, version 2.17 [TeX Live 2025] (kpathsea + Thai support).
Scanning input file stdin....done (3 entries accepted, 0 rejected).
Sorting entries....Segmentation fault

uname -svrmopi; bash --version | head -1; printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{12345678901234567890}' | makeindex
CYGWIN_NT-10.0-26100 3.6.4-1.x86_64 2025-07-15 07:55 UTC x86_64 unknown unknown Cygwin
GNU bash, version 5.2.21(1)-release (x86_64-pc-cygwin)
This is makeindex, version 2.17 [TeX Live 2025] (kpathsea + Thai support).
Scanning input file stdin....done (2 entries accepted, 0 rejected).
Sorting entries....done (2 comparisons).
Generating output file stdout...\begin{theindex}
.
  \item entryA, 12345678901234567890, 0

\end{theindex}
done (5 lines written, 0 warnings).
Output written in stdout.
Transcript written in stderr.

$

Lemures Lemniscati への返信

Re: mendex/upmendex と makeindex での挙動の違い

- Lemures Lemniscati の投稿

こちらは Ubuntu 24.04 でのテストです.
Ubuntu で配布されているパッケージのバイナリを使用しています.
mendex では Segmentation fault,upmendex では問題なしでした.

$ grep PRETTY_NAME /etc/os-release
PRETTY_NAME="Ubuntu 24.04.2 LTS

$ uname -svrmopi; bash --version | head -1; printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{-1.1.1}' | mendex -s <( printf '%s\n' 'page_compositor "."' ); printf '%s\n' "${PIPESTATUS[@]}"
Linux 6.8.0-63-generic #66-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 13 20:25:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)
This is mendex version 3.6 [12-Jun-2022] (utf8.uptex) (TeX Live 2023).
Scanning style file /dev/fd/63....done.
Scanning input file stdin....done (2 entries accepted, 0 rejected).
2 entries accepted, 0 rejected.
Sorting index....done(0 comparisons).
Sorting pages....done(2 comparisons).
Making index file.\begin{theindex}

Segmentation fault (core dumped)
0
139

$ uname -svrmopi; bash --version | head -1; printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{-1.1.1}' | upmendex -s <( printf '%s\n' 'page_compositor "."' ); printf '%s\n' "${PIPESTATUS[@]}"
Linux 6.8.0-63-generic #66-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 13 20:25:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)
This is upmendex version 1.07 [ICU 74.2] (TeX Live 2023).
Scanning style file /dev/fd/63....done.
Scanning input file stdin....done (2 entries accepted, 0 rejected).
2 entries accepted, 0 rejected.
Sorting index....done(0 comparisons).
Sorting pages....done(2 comparisons).
Making index file.\begin{theindex}

  \item entryA, -1.1.1, 0

\end{theindex}
...done.
0 warnings, written in stderr.
Output written in stdout.
0
0

$


makeindex については,同様に Segmentation fault やソート順がおかしかったりします.

$ uname -svrmopi; bash --version | head -1; printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{1234567890123456789}' '\indexentry{entryA}{12345678901234567890}' | makeindex
Linux 6.8.0-63-generic #66-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 13 20:25:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)
This is makeindex, version 2.17 [TeX Live 2023] (kpathsea + Thai support).
Scanning input file stdin....done (3 entries accepted, 0 rejected).
Sorting entries....Segmentation fault (core dumped)

$ uname -svrmopi; bash --version | head -1; printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{12345678901234567890}' | makeindex
Linux 6.8.0-63-generic #66-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 13 20:25:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)
This is makeindex, version 2.17 [TeX Live 2023] (kpathsea + Thai support).
Scanning input file stdin....done (2 entries accepted, 0 rejected).
Sorting entries....done (2 comparisons).
Generating output file stdout...\begin{theindex}
.
  \item entryA, 12345678901234567890, 0

\end{theindex}
done (5 lines written, 0 warnings).
Output written in stdout.
Transcript written in stderr.

$

Lemures Lemniscati への返信

Re: mendex/upmendex と makeindex での挙動の違い

- Lemures Lemniscati の投稿

こちらは Raspberry Pi 5 での Debian 12 です.
Debian で配布されているパッケージのバイナリを使用しています.

mendex/upmendex ともに Segmentation fault はありませんでした.
makeindex については,同様に Segmentation fault やソート順がおかしかったりします.

$ grep PRETTY_NAME /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"

$ uname -svrmopi; bash --version | head -1; printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{-1.1.1}' | mendex -s <( printf '%s\n' 'page_compositor "."' ); printf '%s\n' "${PIPESTATUS[@]}"
Linux 6.12.34+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.12.34-1+rpt1~bookworm (2025-06-26) aarch64 unknown unknown GNU/Linux
GNU bash, version 5.2.15(1)-release (aarch64-unknown-linux-gnu)
This is mendex version 3.6 [19-Sep-2021] (utf8.uptex) (TeX Live 2022).
Scanning style file /dev/fd/63....done.
Scanning input file stdin....done (2 entries accepted, 0 rejected).
2 entries accepted, 0 rejected.
Sorting index....done(0 comparisons).
Sorting pages....done(2 comparisons).
Making index file.\begin{theindex}

  \item entryA, -1.1.1, 0

\end{theindex}
...done.
0 warnings, written in stderr.
Output written in stdout.
0
0

$ uname -svrmopi; bash --version | head -1; printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{-1.1.1}' | upmendex -s <( printf '%s\n' 'page_compositor "."' ); printf '%s\n' "${PIPESTATUS[@]}"
Linux 6.12.34+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.12.34-1+rpt1~bookworm (2025-06-26) aarch64 unknown unknown GNU/Linux
GNU bash, version 5.2.15(1)-release (aarch64-unknown-linux-gnu)
This is upmendex version 1.00 [ICU 72.1] (TeX Live 2022).
Scanning style file /dev/fd/63....done.
Scanning input file stdin....done (2 entries accepted, 0 rejected).
2 entries accepted, 0 rejected.
Sorting index....done(0 comparisons).
Sorting pages....done(2 comparisons).
Making index file.\begin{theindex}

  \item entryA, -1.1.1, 0

\end{theindex}
...done.
0 warnings, written in stderr.
Output written in stdout.
0
0

$

$ uname -svrmopi; bash --version | head -1; printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{1234567890123456789}' '\indexentry{entryA}{12345678901234567890}' | makeindex
Linux 6.12.34+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.12.34-1+rpt1~bookworm (2025-06-26) aarch64 unknown unknown GNU/Linux
GNU bash, version 5.2.15(1)-release (aarch64-unknown-linux-gnu)
This is makeindex, version 2.16 [TeX Live 2022] (kpathsea + Thai support).
Scanning input file stdin....done (3 entries accepted, 0 rejected).
Sorting entries....Segmentation fault

$ uname -svrmopi; bash --version | head -1; printf '%s\n' '\indexentry{entryA}{0}' '\indexentry{entryA}{12345678901234567890}' | makeindex
Linux 6.12.34+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.12.34-1+rpt1~bookworm (2025-06-26) aarch64 unknown unknown GNU/Linux
GNU bash, version 5.2.15(1)-release (aarch64-unknown-linux-gnu)
This is makeindex, version 2.16 [TeX Live 2022] (kpathsea + Thai support).
Scanning input file stdin....done (2 entries accepted, 0 rejected).
Sorting entries....done (2 comparisons).
Generating output file stdout...\begin{theindex}
.
  \item entryA, 12345678901234567890, 0

\end{theindex}
done (5 lines written, 0 warnings).
Output written in stdout.
Transcript written in stderr.

$

Lemures Lemniscati への返信

Re: mendex/upmendex と makeindex での挙動の違い

- 和田 勇 の投稿

Table of Contents

  1. 総評
  2. 検証
    1. \indexentry データ
    2. 環境による状況
      1. 思わしくないもの
      2. 良好なもの

総評

データ収集にミスがあるかもしれませんが、現時点では、makeindex mendex upmendex がどのように作成されたかが不明ですが、ubuntu 系のうち x86 環 境で問題が生じているようです。なので少なくとも x86 系の ubuntu をはじ めとする debian 系で確認が必要かもしれません。

なお t tk さんは TL2022/dev TL2026/dev なので、想像するに、正常に動く メモリ管理ライブラリを参照するようになってる可能性があると考えています。 strace を利用すれば、利用=使用するライブラリのパス情報が得られるかと 思います。

現在、当方の ubuntu / debian 環境は、諸事情でダンボールの箱の中。ですので 同環境を所有している方、追試していただけると助かります。

追試は はやてさんが示されているような make index 用スタイルファイル test.ist やindex用データファイル test.idx を使ったものをベースに環境情 報も取得できる以下を参考にして、ターミナルに表示されたもの全てをコピペ でファイルに書き込んだものをアップしていただけると情報収集が楽になりま す。

  1. test.ist (make index 用スタイルファイル)作成

    page_compositor "."
    
  2. test.idx (index用データファイル)作成

    \indexentry{entryA}{0}
    \indexentry{entryA}{-1.1.1}
    
  3. 検証用コマンドライン(テスト環境調査コマンドも含む)

    uname -a
    which -a makeindex mendex upmendex
    makeindex -s test.ist < test.idx
    mendex    -s test.ist < test.idx
    upmendex  -s test.ist < test.idx
    

検証

\indexentry データ

\indexentry{entryA}{0}
\indexentry{entryA}{-1.1.1}

環境による状況

思わしくないもの
  1. CYGWIN_NT-10.0-26100 / GNU bash, version 5.2.21(1)-release

    makeindex 2.17 エラーにはならないけど以下の警告で「-1.1.1」は無視
      !! Input index error (file = stdin, line = 2):
      – Illegal page number -1.1.1 or page_precedence rnaRA.
    mendex 3.8 「Making index file.」の処理中にSegmentation fault
    upmendex 1.11 「Making index file.」の処理中にSegmentation fault
  2. Ubuntu 24.04 / GNU bash, version 5.2.21(1)-release

    makeindex 2.17 情報なし
    mendex 3.6 「Making index file.」の処理中にSegmentation fault
    upmendex 1.07 OK
  3. Ubuntu 22.04.5 LTS on WSL の TeX Live 2024

    mendex 3.6 (TL2024) 「Making index file.」の処理中にSegmentation fault

良好なもの
  1. Ubuntu 22.04.2 LTS on WSL / bash

    makeindex 2.15 (TL2022/dev) OK
    mendex 3.5 (TL2022/dev) OK
    upmendex 0.57 (TL2022/dev) OK
    mendex 3.8 (TL2026/dev) OK
    upmendex 1.20 (TL2026/dev) OK
  2. Debian 12 on Raspberry Pi 5(aarch64) / bash 5.2.15

    mendex 3.6 (TL2022) OK
    upmendex 1.00 (TL2022) OK
  3. macOS / bash 3.2.57(1)-release / 5.3.0(1)-release

    makeindex 2.17 (TL2025) OK
    mendex 3.8 (TL2025) OK
    upmendex 1.11 (TL2025) OK
和田 勇 への返信

Re: mendex/upmendex と makeindex での挙動の違い

- Lemures Lemniscati の投稿

Cygwin でためしてみましたが,
Segmentation fault は,未初期化領域のデータにアクセスして使用した結果によるものです.

データは

test.idx 

\indexentry{entryA}{0}
\indexentry{entryA}{-1.1.1}

test.ist 

page_compositor "."

添付のファイルで

gdb < test.gdb_mendex.txt
gdb < test.gdb_upmendex.txt

を実行すると,以下のログファイル
test.gdb_mendex.log
test.gdb_upmendex.log
が生成されます.

いずれも pnumconv2() の return pnumconv(p->page+k,p->attr[cc]); における p->attr[cc] で未初期化領域のデータにアクセスしており,
そこで得られた未初期化値が pnumconv()attr に割り当てられ,page_precedence[attr] にて Segmentation fault に至ります.


pnumconv2() では,cc==2 のときに p->attr[cc] で未初期化領域を参照しますが,

これは fread.c にある chkpageattr()"-1.1.1" を扱う際に,最初の文字が '-' であるため,cc==0 のときに,次の if 文の条件がみたされることによります.

                        if (!((*page0>='0' && *page0<='9') || (*page0>='A' && *page0<='Z') || (*page0>='a' && *page0<='z'))) {
                                p->attr[cc]= -1;
                                if (cc<2) p->attr[++cc]= -1;
                                return;
                        }
この場合は,cc==0 なので,p->attr[0]=-1;  p->attr[1]=-1; と初期化されますが,p->attr[2] 以降は初期化せずに return; してしまうわけです.

以上で,今回の Segmentation fault の原因が判明しました.

しかし,ここにでてくる (cc<2) という条件が何なのかは,私には理解できていません.

Lemures Lemniscati への返信

Re: mendex/upmendex と makeindex での挙動の違い

- t tk の投稿
詳細な解析ありがとうございます。
mendex.h に以下のようにあるので、p->attr[cc] のccの添え字は 0~9 の可能性がありそうです。
(cc<2) は不思議な感じがします。

```
#define PAGE_COMPOSIT_DEPTH 10

struct page {
char *page;
char *enc;
int attr[PAGE_COMPOSIT_DEPTH];
};
```
 
添付のパッチでいかがでしょうか。
Lemures Lemniscati への返信

Re: mendex/upmendex と makeindex での挙動の違い

- 和田 勇 の投稿

page カウンターを \setcounter でセットしようとすると 2^31 - 1 である 2147483647 までは OK だけどそれ以上の値は ! Number too big. となり  \setcounter で page 番号をリセットできません。

でも page カウンターを 2147483647 にセットして \newpage を 繰り返すと -2147483648 のようにページ番号がなってしまいますが... こう言うのをチェックしたいのかな?

コマンドラインからですと big number はいくらでも指定できてしまいますが、 今まで示された情報をもとにページ番号が 1.1.1 になるようなテスト方法は思いつかないのですが 以下のような latex 自体の機能を利用したテスト方法でどうでしょうか?

     \documentclass{jlreq}
     \usepackage{makeidx}
     \makeindex
     \setcounter{page}{0}
     \begin{document}
     投票に行こう
     \setcounter{page}{-9        }\index{entryA}\newpage% makeindex だとエラー
     \setcounter{page}{1234567890}\index{entryA}\newpage
     \setcounter{page}{1111111111}\index{entryA}\newpage
     \setcounter{page}{2147483647}\index{entryA}\newpage% 2^31 - 1 までOK
     今度の日曜に用事のある人は期日前投票しよう\newpage
     ヤダァ -2147483648 ページになっちゃう     \newpage
     %\typeout{以下は LaTeX 処理で ! Number too big. エラーになる}
     %\setcounter{page}{2147483648}\index{entryA}\newpage% 2^31 以上は NG
     \printindex
     \end{document}

上記を test.tex とし、また bash であれば以下のようにすれば色々テストできますので参考にしてください。 なお、余分な .latexmkrc ないし latexmkrc を読み込まないために空の同ファイルをカレントに作成しても良いかと思います。

    latexmk -f --gg -lualatex -e '$makeindex="makeindex %O -o %D %S;"' test
和田 勇 への返信

Re: mendex/upmendex と makeindex での挙動の違い

- Lemures Lemniscati の投稿

和田様,ありがとうございます.
これは,便利そうです.

big number については,latexでも \thepage をいじればカウンタとは無関係に生成できるので,latex のカウンタの限界と mendex/upmendex で扱うページ番号の長さの限界(「15」がハードコーディングされています cf. fread.c: chkpageattr())は,分けて考えるほうがよいと思います.

何と言いますが,とりちらかしてしまいましてすみません.

いいわけですが,

1. 最初の要点は mendex/upmendex で索引語が一つも指定されていないときの扱いについてでした.
 いろいろとコメントをいただき,対応するなら挙動は変えずオプション作成対応がよいのではないかということで,納得できたように思います.
2. 上記の経過中,ソースコードやドキュメントを一部拝見しましたが,個人的な技量や理解力の問題で,正直なところソースコードは複雑すぎ,ドキュメントのほうも具体的なところまではよくわからないという感覚でした.
 よくわからないので,いろいろデータを投げ込んで何が起こるのかを試してみようとおもったところ,意外な動作や Segmentation fault などに遭遇した次第です.
3. 索引作成にちょっと興味をもっていたところで,通りがかりのはずだったのですが,なんだかムシャクシャしてしまい,変なところをあげつらってやるぞとなって,長年使われてきたコードでもまだまだバグがあるのではないかと,あれこれと変な状況をテストしてみたくなってしまいました.
4. なんとも衝動的で重ね重ねすみません.