From c423ff0d63cafcb641cbfe19a94f5be6f94d84b6 Mon Sep 17 00:00:00 2001 From: Pramoth Ragavan <107881923+pramothragavan@users.noreply.github.com> Date: Wed, 9 Apr 2025 16:24:11 +0100 Subject: [PATCH 1/8] fix issues for read, add tests --- gap/io.gi | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/gap/io.gi b/gap/io.gi index ed8585a28..55a53ebaa 100644 --- a/gap/io.gi +++ b/gap/io.gi @@ -402,7 +402,7 @@ end); InstallGlobalFunction(ReadDigraphs, function(arg...) - local nr, decoder, name, file, i, next, out; + local nr, decoder, name, file, i, next, out, line; # defaults nr := infinity; @@ -474,8 +474,12 @@ function(arg...) out := []; if NameFunction(decoder) in WholeFileDecoders then - Add(out, decoder(IO_ReadUntilEOF(file))); - next := IO_Nothing; + line := IO_ReadUntilEOF(file); + if IsString(arg[1]) then + IO_Close(file); + fi; + Add(out, decoder(line)); + return out; else next := decoder(file); fi; @@ -606,6 +610,9 @@ function(arg...) fi; file := DigraphFile(name, encoder, mode); if NameFunction(file!.coder) in WholeFileEncoders and file!.mode <> "w" then + if IsString(arg[1]) then + IO_Close(file); + fi; ErrorNoReturn(NameFunction(file!.coder), " is a whole file ", "encoder and so the argument must be \"w\"."); fi; From 011bf746ee052dc184d2bcb4a2503fd0bba0d499 Mon Sep 17 00:00:00 2001 From: Pramoth Ragavan <107881923+pramothragavan@users.noreply.github.com> Date: Wed, 9 Apr 2025 16:49:04 +0100 Subject: [PATCH 2/8] add tests --- tst/standard/io.tst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tst/standard/io.tst b/tst/standard/io.tst index 20342dfdd..6dd3dad41 100644 --- a/tst/standard/io.tst +++ b/tst/standard/io.tst @@ -12,6 +12,7 @@ gap> LoadPackage("digraphs", false);; # gap> DIGRAPHS_StartTest(); +gap> files := ShallowCopy(IO.OpenFiles);; # DigraphFromGraph6String and Graph6String gap> DigraphFromGraph6String("?"); @@ -276,6 +277,9 @@ gap> gr = ReadDigraphs(filename); true gap> gr[3] := Digraph([[1, 2], [1, 2]]); +gap> WriteDigraphs(filename, Digraph([[2], []]), Graph6String); +Error, the argument must be a symmetric digraph with no loops or multiple \ +edges, gap> filename := Concatenation(DIGRAPHS_Dir(), "/tst/out/test.s6.bz2");; gap> WriteDigraphs(filename, gr, "w"); IO_OK @@ -889,6 +893,9 @@ gap> str := DIMACSString(gr); gap> DigraphFromDIMACSString(str) = gr; true gap> filename := Concatenation(DIGRAPHS_Dir(), "/tst/out/more.dimacs");; +gap> WriteDigraphs(filename, gr); +Error, DIMACSString is a whole file encoder and so the argument must be\ + "w". gap> WriteDigraphs(filename, gr, "w");; gap> ReadDigraphs(filename)[1] = gr; true @@ -1045,6 +1052,11 @@ gap> DigraphFromDreadnautString("$=1n3dg\n1 : 2 3.\nf=[1:\n:]"); Error, Invalid range 1 : ':' in partition specification (line 3) gap> DigraphFromDreadnautString("$=1n3dg\n1 : 2 3.\nf=[1\nf=2"); Error, Unexpected character 'f' in partition specification (line 4) +gap> IO_Close(file);; + +# Ensure all files introduced by tests are closed +gap> IO.OpenFiles = files; +true # DIGRAPHS_UnbindVariables gap> Unbind(D); @@ -1066,6 +1078,7 @@ gap> Unbind(rdgr); gap> Unbind(read); gap> Unbind(str); gap> Unbind(x); +gap> Unbind(files); # gap> DIGRAPHS_StopTest(); From 7c23b79d21c6f413f7b8b152593fb7440fe0558e Mon Sep 17 00:00:00 2001 From: Pramoth Ragavan <107881923+pramothragavan@users.noreply.github.com> Date: Wed, 9 Apr 2025 22:50:56 +0100 Subject: [PATCH 3/8] close files with WriteDigraphs --- gap/io.gi | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/gap/io.gi b/gap/io.gi index 55a53ebaa..71896890f 100644 --- a/gap/io.gi +++ b/gap/io.gi @@ -499,7 +499,8 @@ end); InstallGlobalFunction(WriteDigraphs, function(arg...) local name, digraphs, encoder, mode, splitname, compext, g6sum, s6sum, v, e, - dg6sum, ds6sum, file, D, i; + dg6sum, ds6sum, file, D, i, out, oldBoE, oldSNE, CloseAndCleanup, + SafeEncode; # defaults encoder := fail; @@ -626,7 +627,29 @@ function(arg...) fi; fi; + CloseAndCleanup := function() + if IsString(arg[1]) then + IO_Close(file); + fi; + BreakOnError := oldBoE; + SilentNonInteractiveErrors := oldSNE; + end; + + SafeEncode := function(enc, args) + local out; + out := CALL_WITH_CATCH(enc, args); + if out[1] = false then + CloseAndCleanup(); + CallFuncList(enc, args); + fi; + return out[2]; + end; + encoder := file!.coder; + oldBoE := BreakOnError; + BreakOnError := false; + oldSNE := SilentNonInteractiveErrors; + SilentNonInteractiveErrors := true; if NameFunction(encoder) in WholeFileEncoders then if Length(digraphs) > 1 then @@ -634,17 +657,15 @@ function(arg...) " is a whole file encoder, and so only one digraph should be ", "specified. Only the last digraph will be encoded."); fi; - IO_Write(file, encoder(digraphs[Length(digraphs)])); + out := SafeEncode(encoder, [digraphs[Length(digraphs)]]); + IO_Write(file, out); else for i in [1 .. Length(digraphs)] do - encoder(file, digraphs[i]); + SafeEncode(encoder, [file, digraphs[i]]); od; fi; - if IsString(arg[1]) then - IO_Close(file); - fi; - + CloseAndCleanup(); return IO_OK; end); @@ -2027,16 +2048,7 @@ end); # 4. Encoders ################################################################################ InstallMethod(WriteDIMACSDigraph, "for a digraph", [IsString, IsDigraph], -function(name, D) - local file; - file := IO_CompressedFile(UserHomeExpand(name), "w"); - if file = fail then - ErrorNoReturn("cannot open the file given as the 1st argument ,"); - fi; - IO_Write(file, DIMACSString(D)); - IO_Close(file); - return IO_OK; -end); + {name, D} -> WriteDigraphs(name, D, DIMACSString, "w")); InstallMethod(DIMACSString, "for a digraph", [IsDigraph], function(D) From c2b8db92b12016c6e43d9ced953da6ccfcd8153d Mon Sep 17 00:00:00 2001 From: Pramoth Ragavan <107881923+pramothragavan@users.noreply.github.com> Date: Thu, 10 Apr 2025 00:03:51 +0100 Subject: [PATCH 4/8] fix ci --- tst/standard/io.tst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tst/standard/io.tst b/tst/standard/io.tst index 6dd3dad41..cc4e7d144 100644 --- a/tst/standard/io.tst +++ b/tst/standard/io.tst @@ -893,12 +893,12 @@ gap> str := DIMACSString(gr); gap> DigraphFromDIMACSString(str) = gr; true gap> filename := Concatenation(DIGRAPHS_Dir(), "/tst/out/more.dimacs");; -gap> WriteDigraphs(filename, gr); -Error, DIMACSString is a whole file encoder and so the argument must be\ - "w". gap> WriteDigraphs(filename, gr, "w");; gap> ReadDigraphs(filename)[1] = gr; true +gap> WriteDigraphs(filename, gr); +Error, DIMACSString is a whole file encoder and so the argument must be\ + "w". gap> DigraphVertexLabels(gr) = [1 .. 3]; true From 9ff142aa71a14ace1a30edd2983a4a8ac1e4d121 Mon Sep 17 00:00:00 2001 From: Pramoth Ragavan <107881923+pramothragavan@users.noreply.github.com> Date: Thu, 10 Apr 2025 00:41:23 +0100 Subject: [PATCH 5/8] a little tidier --- gap/io.gi | 6 ++---- tst/standard/io.tst | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gap/io.gi b/gap/io.gi index 71896890f..5b0f78f87 100644 --- a/gap/io.gi +++ b/gap/io.gi @@ -499,8 +499,7 @@ end); InstallGlobalFunction(WriteDigraphs, function(arg...) local name, digraphs, encoder, mode, splitname, compext, g6sum, s6sum, v, e, - dg6sum, ds6sum, file, D, i, out, oldBoE, oldSNE, CloseAndCleanup, - SafeEncode; + dg6sum, ds6sum, file, D, i, oldBoE, oldSNE, CloseAndCleanup, SafeEncode; # defaults encoder := fail; @@ -657,8 +656,7 @@ function(arg...) " is a whole file encoder, and so only one digraph should be ", "specified. Only the last digraph will be encoded."); fi; - out := SafeEncode(encoder, [digraphs[Length(digraphs)]]); - IO_Write(file, out); + IO_Write(file, SafeEncode(encoder, [digraphs[Length(digraphs)]])); else for i in [1 .. Length(digraphs)] do SafeEncode(encoder, [file, digraphs[i]]); diff --git a/tst/standard/io.tst b/tst/standard/io.tst index cc4e7d144..af5c8080f 100644 --- a/tst/standard/io.tst +++ b/tst/standard/io.tst @@ -957,6 +957,8 @@ gap> DreadnautString(1); Error, the first argument must be a digraph gap> DreadnautString(D, 1); Error, the second argument must be a list +gap> WriteDigraphs(filename, Digraph([]), "w"); +Error, the argument must be a digraph with at least one vertex gap> WriteDigraphs(filename, D, "w"); IO_OK From 919c7597c8d9778b55c0c5ad399d92cf8803c346 Mon Sep 17 00:00:00 2001 From: Pramoth Ragavan <107881923+pramothragavan@users.noreply.github.com> Date: Fri, 11 Apr 2025 12:17:55 +0100 Subject: [PATCH 6/8] implement max's suggestion --- gap/io.gi | 27 +++++++++------------------ tst/standard/io.tst | 3 +++ 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/gap/io.gi b/gap/io.gi index 5b0f78f87..822e682f7 100644 --- a/gap/io.gi +++ b/gap/io.gi @@ -499,7 +499,7 @@ end); InstallGlobalFunction(WriteDigraphs, function(arg...) local name, digraphs, encoder, mode, splitname, compext, g6sum, s6sum, v, e, - dg6sum, ds6sum, file, D, i, oldBoE, oldSNE, CloseAndCleanup, SafeEncode; + dg6sum, ds6sum, file, i, D, oldOnBreak, CloseAndCleanup, OnBreakWithCleanup; # defaults encoder := fail; @@ -626,40 +626,31 @@ function(arg...) fi; fi; + oldOnBreak := OnBreak; CloseAndCleanup := function() if IsString(arg[1]) then IO_Close(file); fi; - BreakOnError := oldBoE; - SilentNonInteractiveErrors := oldSNE; + OnBreak := oldOnBreak; end; - SafeEncode := function(enc, args) - local out; - out := CALL_WITH_CATCH(enc, args); - if out[1] = false then - CloseAndCleanup(); - CallFuncList(enc, args); - fi; - return out[2]; + OnBreakWithCleanup := function() + CloseAndCleanup(); + OnBreak(); end; + OnBreak := OnBreakWithCleanup; encoder := file!.coder; - oldBoE := BreakOnError; - BreakOnError := false; - oldSNE := SilentNonInteractiveErrors; - SilentNonInteractiveErrors := true; - if NameFunction(encoder) in WholeFileEncoders then if Length(digraphs) > 1 then Info(InfoWarning, 1, "the encoder ", NameFunction(encoder), " is a whole file encoder, and so only one digraph should be ", "specified. Only the last digraph will be encoded."); fi; - IO_Write(file, SafeEncode(encoder, [digraphs[Length(digraphs)]])); + IO_Write(file, encoder(digraphs[Length(digraphs)])); else for i in [1 .. Length(digraphs)] do - SafeEncode(encoder, [file, digraphs[i]]); + encoder(file, digraphs[i]); od; fi; diff --git a/tst/standard/io.tst b/tst/standard/io.tst index af5c8080f..493e61c61 100644 --- a/tst/standard/io.tst +++ b/tst/standard/io.tst @@ -1059,6 +1059,9 @@ gap> IO_Close(file);; # Ensure all files introduced by tests are closed gap> IO.OpenFiles = files; true +gap> OnBreak = Where; # remove this line post debugging +true +gap> OnBreak := Where;; # remove this line post debugging # DIGRAPHS_UnbindVariables gap> Unbind(D); From b8c6eaf3c0bc14079b529ed74de6903d9274e9ff Mon Sep 17 00:00:00 2001 From: Pramoth Ragavan <107881923+pramothragavan@users.noreply.github.com> Date: Fri, 11 Apr 2025 12:25:32 +0100 Subject: [PATCH 7/8] fix tests --- tst/standard/io.tst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tst/standard/io.tst b/tst/standard/io.tst index 493e61c61..6254c0ee7 100644 --- a/tst/standard/io.tst +++ b/tst/standard/io.tst @@ -13,6 +13,7 @@ gap> LoadPackage("digraphs", false);; # gap> DIGRAPHS_StartTest(); gap> files := ShallowCopy(IO.OpenFiles);; +gap> oldOnBreak := OnBreak;; # DigraphFromGraph6String and Graph6String gap> DigraphFromGraph6String("?"); @@ -280,6 +281,8 @@ gap> gr[3] := Digraph([[1, 2], [1, 2]]); gap> WriteDigraphs(filename, Digraph([[2], []]), Graph6String); Error, the argument must be a symmetric digraph with no loops or multiple \ edges, +gap> OnBreak := oldOnBreak;; +gap> IO_Close(IO.OpenFiles[Length(IO.OpenFiles)]);; gap> filename := Concatenation(DIGRAPHS_Dir(), "/tst/out/test.s6.bz2");; gap> WriteDigraphs(filename, gr, "w"); IO_OK @@ -680,6 +683,8 @@ Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for `WriteDIMACSDigraph' on 2 arguments gap> WriteDIMACSDigraph("file", ChainDigraph(2)); Error, the argument must be a symmetric digraph, +gap> OnBreak := oldOnBreak;; +gap> IO_Close(IO.OpenFiles[Length(IO.OpenFiles)]);; gap> WriteDIMACSDigraph(filename, gr); Error, cannot open the file given as the 1st argument , gap> filename := "tmp.gz";; @@ -959,6 +964,8 @@ gap> DreadnautString(D, 1); Error, the second argument must be a list gap> WriteDigraphs(filename, Digraph([]), "w"); Error, the argument must be a digraph with at least one vertex +gap> OnBreak := oldOnBreak;; +gap> IO_Close(IO.OpenFiles[Length(IO.OpenFiles)]);; gap> WriteDigraphs(filename, D, "w"); IO_OK From a12175ae5b4128ea0cffc63cb5890d8e65aff819 Mon Sep 17 00:00:00 2001 From: Pramoth Ragavan <107881923+pramothragavan@users.noreply.github.com> Date: Fri, 11 Apr 2025 12:30:14 +0100 Subject: [PATCH 8/8] rm debugging lines --- tst/standard/io.tst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tst/standard/io.tst b/tst/standard/io.tst index 6254c0ee7..15bf15414 100644 --- a/tst/standard/io.tst +++ b/tst/standard/io.tst @@ -1066,9 +1066,8 @@ gap> IO_Close(file);; # Ensure all files introduced by tests are closed gap> IO.OpenFiles = files; true -gap> OnBreak = Where; # remove this line post debugging +gap> OnBreak = oldOnBreak; true -gap> OnBreak := Where;; # remove this line post debugging # DIGRAPHS_UnbindVariables gap> Unbind(D);