diff --git a/build/pkgs/meataxe/patches/UseErrorPropagation.patch b/build/pkgs/meataxe/patches/UseErrorPropagation.patch new file mode 100644 index 00000000000..00745e8b967 --- /dev/null +++ b/build/pkgs/meataxe/patches/UseErrorPropagation.patch @@ -0,0 +1,1147 @@ +In functions that appear in matrix arithmetic, use specific return values +on error, and propagate errors. This is *not* done in other parts of +MeatAxe (e.g., not for greased matrices or polynomials) and not for +standalone programs. + +AUTHOR: + +- Simon King, 2015-09-26 + +diff --git a/src/cfinfo.c b/src/cfinfo.c +index 293526b..9c1a004 100644 +--- a/src/cfinfo.c ++++ b/src/cfinfo.c +@@ -215,7 +215,7 @@ int Lat_ReadInfo(Lat_Info *li, const char *basename) + } + for (i = 0; i < li->NCf; ++i) + { +- ReadWord(f,&(li->Cf[i].idword),&(li->Cf[i].idpol),fn); ++ if (!ReadWord(f,&(li->Cf[i].idword),&(li->Cf[i].idpol),fn)) return -1; + if (StfMatch(f,i < li->NCf - 1 ? "," : "];") != 0) + { + MTX_ERROR2("%s: %E",fn,MTX_ERR_FILEFMT); +@@ -232,7 +232,7 @@ int Lat_ReadInfo(Lat_Info *li, const char *basename) + } + for (i = 0; i < li->NCf; ++i) + { +- ReadWord(f,&(li->Cf[i].peakword),&(li->Cf[i].peakpol),fn); ++ if (!ReadWord(f,&(li->Cf[i].peakword),&(li->Cf[i].peakpol),fn)) return -1; + if (StfMatch(f,i < li->NCf - 1 ? "," : "];") != 0) + { + MTX_ERROR2("%s: %E",fn,MTX_ERR_FILEFMT); +diff --git a/src/chbasis.c b/src/chbasis.c +index 34cf886..f1ee2e8 100644 +--- a/src/chbasis.c ++++ b/src/chbasis.c +@@ -61,7 +61,8 @@ int MrChangeBasis(MatRep_t *rep, const Matrix_t *trans) + /** Conjugate a list @em gen of @em ngen square matrices over the same + * field and of the same dimensions by a mattrix @em trans + * and write the result into @em newgen. If @em gen == @em newgen, then +- * the previous content of @em newgen will be overridden. **/ ++ * the previous content of @em newgen will be overridden. ++ * Return -1 on error and 0 on success. **/ + int ChangeBasis(const Matrix_t *trans, int ngen, const Matrix_t *gen[], + Matrix_t *newgen[]) + +@@ -83,18 +84,36 @@ int ChangeBasis(const Matrix_t *trans, int ngen, const Matrix_t *gen[], + } + + Matrix_t *tmp = MatAlloc(trans->Field, trans->Nor, trans->Noc); ++ if (!tmp) return -1; + size_t tmpsize = FfCurrentRowSize*trans->Nor; + for (i = 0; i < ngen; ++i) + { + MTX_VERIFY(gen[i]->Nor==trans->Nor); + MTX_VERIFY(gen[i]->Noc==trans->Noc); + memset(tmp->Data, FF_ZERO, tmpsize); +- MatMulStrassen(tmp, trans, gen[i]); ++ if (!MatMulStrassen(tmp, trans, gen[i])) ++ { ++ MatFree(tmp); ++ return -1; ++ } + if ((const Matrix_t **)newgen == gen) + memset(newgen[i]->Data, FF_ZERO, tmpsize); + else ++ { + newgen[i] = MatAlloc(trans->Field, trans->Nor, trans->Noc); +- MatMulStrassen(newgen[i], tmp, bi); ++ if (!newgen[i]) ++ { ++ MatFree(tmp); ++ MatFree(bi); ++ return -1; ++ } ++ } ++ if (!MatMulStrassen(newgen[i], tmp, bi)) ++ { ++ MatFree(tmp); ++ MatFree(bi); ++ return -1; ++ } + } + MatFree(bi); + MatFree(tmp); +diff --git a/src/ffio.c b/src/ffio.c +index 92f9360..d2e3f1c 100644 +--- a/src/ffio.c ++++ b/src/ffio.c +@@ -71,8 +71,11 @@ int FfReadRows(FILE *f, PTR buf, int n) + if (fread(b,FfTrueRowSize(FfNoc),1,f) != 1) break; + b += FfCurrentRowSize; + } +- if (ferror(f)) +- MTX_ERROR("Read failed: %S"); ++ if (ferror(f)) ++ { ++ MTX_ERROR("Read failed: %S"); ++ return -1; ++ } + return i; + } + +@@ -106,8 +109,11 @@ int FfWriteRows(FILE *f, PTR buf, int n) + if (fwrite(b,FfTrueRowSize(FfNoc),1,f) != 1) break; + b += FfCurrentRowSize; + } +- if (ferror(f)) +- MTX_ERROR("Write failed: %S"); ++ if (ferror(f)) ++ { ++ MTX_ERROR("Write failed: %S"); ++ return -1; ++ } + return i; + } + +diff --git a/src/kernel-0.c b/src/kernel-0.c +index 6ef2f72..431f01a 100644 +--- a/src/kernel-0.c ++++ b/src/kernel-0.c +@@ -304,7 +304,10 @@ static FILE *OpenTableFile(int fl) + /* Create the table file. + ---------------------- */ + if (FfMakeTables(fl) != 0) +- MTX_ERROR("Unable to build arithmetic tables"); ++ { ++ MTX_ERROR("Unable to build arithmetic tables"); ++ return NULL; ++ } + fd = SysFopen(fn,FM_READ|FM_LIB); + return fd; + } +@@ -363,8 +366,7 @@ static int ReadTableFile(FILE *fd, int field) + return -1; + } + FfOrder = field; +- FfSetNoc(FfOrder); +- return 0; ++ return FfSetNoc(FfOrder); + } + + +@@ -471,7 +473,7 @@ size_t FfTrueRowSize(int noc) + ** Embed a subfield. + ** @param a Element of the subfield field. + ** @param subfield Subfield order. Must be a divisor of the current field order. +- ** @return @em a, embedded into the current field. ++ ** @return @em a, embedded into the current field, or 255 on error. + **/ + + FEL FfEmbed(FEL a, int subfield) +@@ -482,7 +484,9 @@ FEL FfEmbed(FEL a, int subfield) + return a; + for (i = 0; mtx_embedord[i] != subfield && i < 4; ++i); + if (i >= 4) +- MTX_ERROR2("Cannot embed GF(%d) into GF(%d)",(int)subfield,(int)FfOrder); ++ { MTX_ERROR2("Cannot embed GF(%d) into GF(%d)",(int)subfield,(int)FfOrder); ++ return (FEL)255; ++ } + return mtx_embed[i][a]; + } + +@@ -498,6 +502,7 @@ FEL FfEmbed(FEL a, int subfield) + ** FfSetField(subfield). + ** @param a Element of the current field. + ** @param subfield Subfield order. Must be a divisor of the current field order. ++ ** Return 255 on error. + **/ + + FEL FfRestrict(FEL a, int subfield) +@@ -511,6 +516,7 @@ FEL FfRestrict(FEL a, int subfield) + { + MTX_ERROR2("Cannot restrict GF(%d) to GF(%d)",(int)FfOrder, + (int)subfield); ++ return (FEL)255; + } + return mtx_restrict[i][a]; + } +diff --git a/src/maddmul.c b/src/maddmul.c +index f5c171d..24ad3a5 100644 +--- a/src/maddmul.c ++++ b/src/maddmul.c +@@ -59,7 +59,7 @@ Matrix_t *MatAddMul(Matrix_t *dest, const Matrix_t *src, FEL coeff) + ------------ */ + PTR dp = dest->Data, sp = src->Data; + int n; +- FfSetField(src->Field); ++ FfSetField(src->Field); /* No error checking */ + FfSetNoc(src->Noc); + for (n = src->Nor; n > 0; --n) + { +diff --git a/src/maketabF.c b/src/maketabF.c +index d7af83e..0fa26fb 100644 +--- a/src/maketabF.c ++++ b/src/maketabF.c +@@ -175,7 +175,7 @@ static void polymod(POLY a, POLY b) + testprim() - Test for primitivity. + ----------------------------------------------------------------- */ + +-static void testprim() ++static int testprim() + { + int i, a[256]; + +@@ -187,7 +187,9 @@ static void testprim() + { + fprintf(stderr,"*** a[%d]=%d.",i,a[i]); + MTX_ERROR("Polynome is not primitive."); ++ return 1; + } ++ return 0; + } + + +@@ -195,7 +197,7 @@ static void testprim() + initarith() - Initialize index and zech logarithm tables. + ----------------------------------------------------------------- */ + +-static void initarith() ++static int initarith() + { int i,elem; + POLY a; + +@@ -214,7 +216,7 @@ static void initarith() + polmultx(a); + polymod(a,irred); + } +- testprim(); ++ if (testprim()) return 1; + + /* Calculate zech logarithms + ------------------------- */ +@@ -222,6 +224,7 @@ static void initarith() + { elem = (int)((i%P)==P-1 ? i+1-P : i+1); /* add 1 */ + zech[indx[i]]=indx[elem]; /* Zech-table=result */ + } ++ return 0; + } + + +@@ -314,7 +317,7 @@ static BYTE pack(BYTE a[8]) + and initialize tables. + ----------------------------------------------------------------- */ + +-static void writeheader() ++static int writeheader() + { + int i, j; + +@@ -324,6 +327,7 @@ static void writeheader() + { + perror(filename); + MTX_ERROR("Cannot open table file"); ++ return 1; + } + for (CPM=1,maxmem=Q; (long)maxmem * Q <= 256L; ++CPM, maxmem *= Q); + for (i = 0; irrednrs[i] != (int) Q && irrednrs[i] != 0; ++i); +@@ -333,7 +337,7 @@ static void writeheader() + for (j = 0; j <= MAXGRAD; j++) + irred[j] = irreducibles[i][MAXGRAD-j]; + G = P; /* Generator is X */ +- initarith(); /* Init index- and Zech-tables */ ++ if (initarith()) return 1; /* Init index- and Zech-tables */ + } + else + { +@@ -357,6 +361,7 @@ static void writeheader() + } + MESSAGE(1,("Generator : %ld\n",info[1])); + MESSAGE(1,("Packing : %ld/byte\n",info[3])); ++ return 0; + } + + +@@ -364,14 +369,14 @@ static void writeheader() + checkq() - Set Q and N. Verify that Q is a prime power. + ----------------------------------------------------------------- */ + +-static void checkq(long l) ++static int checkq(long l) + { + long q, d; + + if (l < 2 || l > 256) + { +- fprintf(stderr,"Field order out of range (2-256)\n"); +- exit(EXIT_ERR); ++ MTX_ERROR1("Field order out of range (2-256): %E", MTX_ERR_RANGE); ++ return 1; + } + + Q = l; +@@ -381,9 +386,10 @@ static void checkq(long l) + q /= d; + if (q != 1) + { +- fprintf(stderr,"Illegal Field order\n"); +- exit(EXIT_ERR); ++ MTX_ERROR("Illegal Field order\n"); ++ return 1; + } ++ return 0; + } + + +@@ -407,7 +413,7 @@ static void inittables() + mkembed() - Calculate embeddings of all subfields. + ----------------------------------------------------------------- */ + +-static void mkembed() ++static int mkembed() + { + int n; /* Degree of subfield over Z_p */ + long q; /* subfield order */ +@@ -456,6 +462,7 @@ static void mkembed() + { + fprintf(stderr,"*** q=%ld, Q=%ld.",q,Q); + MTX_ERROR("Internal error."); ++ return 1; + } + + /* Calculate a generator for the subfield +@@ -502,13 +509,13 @@ static void mkembed() + fflush(stdout); + } + } ++ return 0; + } + + + static int Init(int field) + { +- checkq(field); +- return 0; ++ return checkq(field); + } + + /* ----------------------------------------------------------------- +@@ -526,7 +533,7 @@ int FfMakeTables(int field) + ---------- */ + if (Init(field) != 0) + return 1; +- writeheader(); /* Open file and write header */ ++ if (writeheader()) return 1; /* Open file and write header */ + inittables(); + + /* Make insert table +@@ -618,7 +625,7 @@ int FfMakeTables(int field) + } + } + +- mkembed(); ++ if (mkembed()) return 1; + + MESSAGE(1,("Writing tables to %s\n",filename)); + if ( +@@ -639,6 +646,7 @@ int FfMakeTables(int field) + { + perror(filename); + MTX_ERROR("Error writing table file"); ++ return 1; + } + fclose(fd); + return(0); +diff --git a/src/matadd.c b/src/matadd.c +index 54dbcb1..2d86d86 100644 +--- a/src/matadd.c ++++ b/src/matadd.c +@@ -48,7 +48,7 @@ Matrix_t *MatAdd(Matrix_t *dest, const Matrix_t *src) + ------------------- */ + dp = dest->Data; + sp = src->Data; +- FfSetField(src->Field); ++ FfSetField(src->Field); /* No error checking */ + FfSetNoc(src->Noc); + for (n = src->Nor; n > 0; --n) + { +diff --git a/src/matclean.c b/src/matclean.c +index e7307bf..16f02d6 100644 +--- a/src/matclean.c ++++ b/src/matclean.c +@@ -53,7 +53,7 @@ int MatClean(Matrix_t *mat, const Matrix_t *sub) + + /* Clean + ----- */ +- FfSetNoc(mat->Noc); ++ FfSetNoc(mat->Noc); /* No error checking */ + for (i = 0; i < mat->Nor; ++i) + { + PTR m = MatGetPtr(mat,i); +diff --git a/src/matcmp.c b/src/matcmp.c +index b778ec4..d503285 100644 +--- a/src/matcmp.c ++++ b/src/matcmp.c +@@ -38,7 +38,7 @@ MTX_DEFINE_FILE_INFO + ** not necessarily mean that an error has occured. + ** @param a First matrix. + ** @param b Second matrix. +- ** @return 0 if the matrices are equal, nonzero otherwise (see description). ++ ** @return 0 if the matrices are equal, nonzero otherwise (see description), -2 on error. + **/ + + int MatCompare(const Matrix_t *a, const Matrix_t *b) +@@ -50,7 +50,7 @@ int MatCompare(const Matrix_t *a, const Matrix_t *b) + if (!MatIsValid(a) || !MatIsValid(b)) + { + MTX_ERROR1("%E",MTX_ERR_BADARG); +- return -1; ++ return -2; + } + + /* Compare fields and dimensions +@@ -65,7 +65,7 @@ int MatCompare(const Matrix_t *a, const Matrix_t *b) + /* Compare the entries row by row. We do not use memcmp on the + whole matrix because we must ignore padding bytes. + ----------------------------------------------------------- */ +- FfSetField(a->Field); ++ FfSetField(a->Field); /* No error checking */ + FfSetNoc(a->Noc); + for (i = 0; i < a->Nor; ++i) + { +diff --git a/src/matcopy.c b/src/matcopy.c +index 75852dd..c3e7850 100644 +--- a/src/matcopy.c ++++ b/src/matcopy.c +@@ -105,7 +105,7 @@ int MatCopyRegion(Matrix_t *dest, int destrow, int destcol, + { + #ifdef PARANOID + FEL f; +- FfSetNoc(src->Noc); ++ FfSetNoc(src->Noc); /* No error checking */ + f = FfExtract(s,k); + FfSetNoc(dest->Noc); + FfInsert(d,destcol+k-col1,f); +diff --git a/src/matcore.c b/src/matcore.c +index 1f27dfd..0dc9d92 100644 +--- a/src/matcore.c ++++ b/src/matcore.c +@@ -131,7 +131,7 @@ Matrix_t *MatAlloc(int field, int nor, int noc) + SysFree(m); + return NULL; + } +- FfSetNoc(noc); ++ if (FfSetNoc(noc)) return NULL; + m->Magic = MAT_MAGIC; + m->Field = field; + m->Nor = nor; +diff --git a/src/matcut.c b/src/matcut.c +index fde0662..f274311 100644 +--- a/src/matcut.c ++++ b/src/matcut.c +@@ -79,11 +79,12 @@ Matrix_t *MatCut(const Matrix_t *src, int row1, int col1, int nrows, int ncols) + /* Initialize pointers to the source and destination matrix + -------------------------------------------------------- */ + s = MatGetPtr(src,row1); ++ if (!s) return NULL; + d = result->Data; + + /* Copy the requested data + ----------------------- */ +- FfSetNoc(ncols); ++ if (FfSetNoc(ncols)) return NULL; + for (n = nrows; n > 0; --n) + { + if (col1 == 0) +@@ -95,9 +96,9 @@ Matrix_t *MatCut(const Matrix_t *src, int row1, int col1, int nrows, int ncols) + { + #ifdef PARANOID + FEL f; +- FfSetNoc(src->Noc); ++ FfSetNoc(src->Noc); /* No error checking */ + f = FfExtract(s,col1+k); +- FfSetNoc(ncols); ++ FfSetNoc(ncols); /* error was checked above */ + FfInsert(d,k,f); + #else + FfInsert(d,k,FfExtract(s,col1+k)); +diff --git a/src/matech.c b/src/matech.c +index ed31cf4..ee52ebe 100644 +--- a/src/matech.c ++++ b/src/matech.c +@@ -124,7 +124,7 @@ int MatEchelonize(Matrix_t *mat) + + /* Build the pivot table + --------------------- */ +- FfSetField(mat->Field); ++ FfSetField(mat->Field); /* No error checking */ + FfSetNoc(mat->Noc); + rank = zmkechelon(mat->Data,mat->Nor,mat->Noc,mat->PivotTable,is_pivot); + +@@ -163,13 +163,14 @@ long MatNullity(const Matrix_t *mat) + ** This function calculates the dimension of the null-space of a matrix + ** and deletes the matrix. + ** @param mat Pointer to the matrix. +- ** @return Nullity of @em mat, or -$ on error. ++ ** @return Nullity of @em mat, or $-1$ on error. + **/ + + long MatNullity__(Matrix_t *mat) + { + long nul; +- MatEchelonize(mat); ++ if (!mat) return -1; ++ if (MatEchelonize(mat)==-1) return -1; + nul = mat->Noc - mat->Nor; + MatFree(mat); + return nul; +diff --git a/src/matins.c b/src/matins.c +index 45c31e4..50fe9c1 100644 +--- a/src/matins.c ++++ b/src/matins.c +@@ -54,7 +54,7 @@ Matrix_t *MatInsert_(Matrix_t *mat, const Poly_t *pol) + return NULL; + } + +- FfSetField(mat->Field); ++ FfSetField(mat->Field); /* No error checking */ + FfSetNoc(nor); + + /* Special case: p(x) = 0 +@@ -81,7 +81,10 @@ Matrix_t *MatInsert_(Matrix_t *mat, const Poly_t *pol) + /* Evaluate p(A) + ------------- */ + if (pol->Degree > 1) +- x = MatDup(mat); ++ { ++ x = MatDup(mat); ++ if (!x) return NULL; ++ } + if ((f = pol->Data[pol->Degree]) != FF_ONE) + { + for (l = nor, v = mat->Data; l > 0; --l, FfStepPtr(&v)) +@@ -147,6 +150,7 @@ Matrix_t *MatInsert(const Matrix_t *mat, const Poly_t *pol) + if (pol->Degree == 0) + { + x = MatAlloc(mat->Field,nor,nor); ++ if (!x) return NULL; + for (l = 0, v = x->Data; l < nor; ++l, FfStepPtr(&v)) + FfInsert(v,l,pol->Data[0]); + return x; +@@ -155,6 +159,7 @@ Matrix_t *MatInsert(const Matrix_t *mat, const Poly_t *pol) + /* Evaluate p(A) + ------------- */ + x = MatDup(mat); ++ if (!x) return NULL; + if ((f = pol->Data[pol->Degree]) != FF_ONE) + { + for (l = nor, v = x->Data; l > 0; --l, FfStepPtr(&v)) +diff --git a/src/matinv.c b/src/matinv.c +index 217eb0e..990cbe7 100644 +--- a/src/matinv.c ++++ b/src/matinv.c +@@ -114,6 +114,7 @@ Matrix_t *MatInverse(const Matrix_t *mat) + /* Copy matrix into workspace + -------------------------- */ + tmp = FfAlloc(mat->Nor); ++ if (!tmp) return NULL; + memcpy(tmp,mat->Data,FfCurrentRowSize * mat->Nor); + + /* Inversion +diff --git a/src/matmul.c b/src/matmul.c +index 20f5e88..bed30fc 100644 +--- a/src/matmul.c ++++ b/src/matmul.c +@@ -63,7 +63,7 @@ Matrix_t *MatMul(Matrix_t *dest, const Matrix_t *src) + + /* Matrix multiplication + --------------------- */ +- FfSetField(src->Field); ++ FfSetField(src->Field); /* no error checking, since the matrix *exists* */ + FfSetNoc(src->Noc); + result = tmp = FfAlloc(dest->Nor); + if (result == NULL) +diff --git a/src/matnull.c b/src/matnull.c +index 4f28566..2550b96 100644 +--- a/src/matnull.c ++++ b/src/matnull.c +@@ -27,6 +27,8 @@ MTX_DEFINE_FILE_INFO + - |piv| contains a pivot table for the null space. + If |flags| is nonzero, the null-space is not reduced to echelon form, + and the contents of |piv| are undefined. ++ ++ Return -1 on error, the dimension of the null-space on success. + ** @see + **/ + +@@ -40,7 +42,7 @@ static long znullsp(PTR matrix, long nor, int *piv, PTR nsp, int flags) + + /* Make the identity matrix in . + ---------------------------------- */ +- FfSetNoc(nor); ++ if (FfSetNoc(nor)) return -1; + x = nsp; + for (i = 0; i < nor; ++i) + { +@@ -61,13 +63,12 @@ static long znullsp(PTR matrix, long nor, int *piv, PTR nsp, int flags) + + for (k = 0; k < i; ++k) + { +- FfSetNoc(noc); ++ FfSetNoc(noc); /* No error checking, since noc used to be the previously assigned number of columns */ + if ((p = piv[k]) >= 0 && (f = FfExtract(x,p)) != FF_ZERO) + { + f = FfNeg(FfDiv(f,FfExtract(xx,p))); +- FfSetNoc(noc); + FfAddMulRow(x,xx,f); +- FfSetNoc(nor); ++ FfSetNoc(nor); /* we have asserted above that it doesn't fail */ + FfAddMulRow(y,yy,f); + } + FfSetNoc(noc); +@@ -151,11 +152,21 @@ Matrix_t *MatNullSpace_(Matrix_t *mat, int flags) + if (nsp == NULL) + return NULL; + nsp->PivotTable = NREALLOC(nsp->PivotTable,int,mat->Nor); ++ if (!nsp->PivotTable) ++ { ++ MatFree(nsp); ++ return NULL; ++ } + + /* Calculate the null-space + ------------------------ */ +- FfSetNoc(mat->Noc); ++ FfSetNoc(mat->Noc); /* No error checking */ + dim = znullsp(mat->Data,mat->Nor,nsp->PivotTable,nsp->Data,flags); ++ if (dim==-1) ++ { ++ MatFree(nsp); ++ return NULL; ++ } + if (flags) + { + SysFree(nsp->PivotTable); +diff --git a/src/matorder.c b/src/matorder.c +index 16aec74..24b31a3 100644 +--- a/src/matorder.c ++++ b/src/matorder.c +@@ -32,7 +32,7 @@ MTX_DEFINE_FILE_INFO + ** the order is greater than 1000000, or if the order on any cyclic + ** subspace is greater than 1000. + ** @param mat Pointer to the matrix. +- ** @return The order of @em mat, or 1 on error. ++ ** @return The order of @em mat, or -1 on error. + **/ + + int MatOrder(const Matrix_t *mat) +@@ -59,15 +59,29 @@ int MatOrder(const Matrix_t *mat) + FfSetNoc(mat->Noc); + nor = mat->Nor; + m1 = FfAlloc(nor); ++ if (!m1) return -1; + memcpy(m1,mat->Data,FfCurrentRowSize * nor); + bend = basis = FfAlloc(nor+1); ++ if (!bend) ++ { ++ SysFree(m1); ++ return -1; ++ } + + piv = NALLOC(int,nor+1); + done = NALLOC(char,nor); ++ if (!piv || !done) ++ { SysFree(m1); ++ return -1; ++ } + memset(done,0,(size_t)nor); + v1 = FfAlloc(1); + v2 = FfAlloc(1); + v3 = FfAlloc(1); ++ if (!v1 || !v2 || !v3) ++ { SysFree(m1); ++ return -1; ++ } + tord = ord = 1; + dim = 0; + j1 = 1; +diff --git a/src/matpivot.c b/src/matpivot.c +index abe342a..c843282 100644 +--- a/src/matpivot.c ++++ b/src/matpivot.c +@@ -71,7 +71,6 @@ static int zmkpivot(PTR matrix, int nor, int noc, int *piv, int *ispiv) + + int MatPivotize(Matrix_t *mat) + { +- int rc; + int *newtab; + static int *is_pivot = NULL; + static int maxnoc = -1; +@@ -106,9 +105,7 @@ int MatPivotize(Matrix_t *mat) + --------------------- */ + FfSetField(mat->Field); + FfSetNoc(mat->Noc); +- rc = zmkpivot(mat->Data,mat->Nor,mat->Noc,mat->PivotTable,is_pivot); +- +- return rc; ++ return zmkpivot(mat->Data,mat->Nor,mat->Noc,mat->PivotTable,is_pivot); + } + + /** +diff --git a/src/matpwr.c b/src/matpwr.c +index cd66b5e..b06e5b2 100644 +--- a/src/matpwr.c ++++ b/src/matpwr.c +@@ -119,8 +119,14 @@ Matrix_t *MatPower(const Matrix_t *mat, long n) + FfSetField(mat->Field); + FfSetNoc(mat->Noc); + tmp = FfAlloc(FfNoc); ++ if (!tmp) return NULL; + memcpy(tmp,mat->Data,FfCurrentRowSize * FfNoc); + tmp2 = FfAlloc(FfNoc); ++ if (!tmp2) ++ { ++ SysFree(tmp); ++ return NULL; ++ } + result = MatAlloc(mat->Field,mat->Nor,mat->Noc); + if (result != NULL) + matpwr_(n,tmp,result->Data,tmp2); +diff --git a/src/matread.c b/src/matread.c +index 031d100..06e6e6b 100644 +--- a/src/matread.c ++++ b/src/matread.c +@@ -46,8 +46,9 @@ Matrix_t *MatRead(FILE *f) + return NULL; + if (FfReadRows(f,m->Data,m->Nor) != m->Nor) + { +- MatFree(m); +- return NULL; ++ MTX_ERROR("Number of given rows does not coincide with given row number"); ++ MatFree(m); ++ return NULL; + } + return m; + } +diff --git a/src/mattrace.c b/src/mattrace.c +index f500248..772a6e4 100644 +--- a/src/mattrace.c ++++ b/src/mattrace.c +@@ -21,7 +21,7 @@ + ** This function calculates the sum of all diagonal elements of a matrix. + ** Note that the matrix need not be square. + ** @param mat Pointer to the matrix. +- ** @return Trace of @a mat, @c FF_ZERO on error. ++ ** @return Trace of @a mat, @c 255 on error. + **/ + + FEL MatTrace(const Matrix_t *mat) +@@ -35,7 +35,7 @@ FEL MatTrace(const Matrix_t *mat) + ------------------ */ + #ifdef DEBUG + if (!MatIsValid(mat)) +- return FF_ZERO; ++ return (FEL)255; + #endif + + maxi = mat->Nor > mat->Noc ? mat->Noc : mat->Nor; +diff --git a/src/matwrite.c b/src/matwrite.c +index 1fb6af3..b364e80 100644 +--- a/src/matwrite.c ++++ b/src/matwrite.c +@@ -44,7 +44,10 @@ int MatWrite(const Matrix_t *mat, FILE *f) + FfSetField(mat->Field); + FfSetNoc(mat->Noc); + if (FfWriteRows(f,mat->Data,mat->Nor) != mat->Nor) +- return -1; ++ { ++ MTX_ERROR("Cannot write rows"); ++ return -1; ++ } + return 0; + } + +@@ -75,7 +78,10 @@ int MatSave(const Matrix_t *mat, const char *fn) + i = MatWrite(mat,f); + fclose(f); + if (i != 0) +- MTX_ERROR1("Cannot write matrix to %s",fn); ++ { ++ MTX_ERROR1("Cannot write matrix to %s",fn); ++ return -1; ++ } + return i; + } + +diff --git a/src/meataxe.h b/src/meataxe.h +index 368b37b..0efa7dd 100644 +--- a/src/meataxe.h ++++ b/src/meataxe.h +@@ -135,8 +135,8 @@ PTR FfSubRowPartialReverse(PTR dest, PTR src, int first, int len); + PTR FfAlloc(int nor); + int FfCmpRows(PTR p1, PTR p2); + void FfCleanRow(PTR row, PTR matrix, int nor, const int *piv); +-void FfCleanRow2(PTR row, PTR matrix, int nor, const int *piv, PTR row2); +-void FfCleanRowAndRepeat(PTR row, PTR mat, int nor, const int *piv, ++int FfCleanRow2(PTR row, PTR matrix, int nor, const int *piv, PTR row2); ++int FfCleanRowAndRepeat(PTR row, PTR mat, int nor, const int *piv, + PTR row2, PTR mat2); + void FfCopyRow(PTR dest, PTR src); + FEL FfEmbed(FEL a, int subfield); +diff --git a/src/mmulscal.c b/src/mmulscal.c +index 281be16..9bff3ff 100644 +--- a/src/mmulscal.c ++++ b/src/mmulscal.c +@@ -21,7 +21,7 @@ + ** Multiply a Matrix by a Constant. + ** @param dest Pointer to the matrix. + ** @param coeff Value to multiply with. +- ** @return The function returns @a dest. ++ ** @return The function returns @a dest, or NULL on error in debug mode only. + **/ + + Matrix_t *MatMulScalar(Matrix_t *dest, FEL coeff) +diff --git a/src/mtensor.c b/src/mtensor.c +index b2b9ac7..2fb90ca 100644 +--- a/src/mtensor.c ++++ b/src/mtensor.c +@@ -85,6 +85,11 @@ Matrix_t *MatTensor(const Matrix_t *m1, const Matrix_t *m2) + ---------------------------------------- */ + x1 = m1->Data; + x3 = MatGetPtr(temat,i2); ++ if (!x3) ++ { ++ MatFree(temat); ++ return NULL; ++ } + FfSetNoc(temat->Noc); + + /* Loop through all rows of +diff --git a/src/quotient.c b/src/quotient.c +index f44b556..eea0754 100644 +--- a/src/quotient.c ++++ b/src/quotient.c +@@ -82,16 +82,23 @@ Matrix_t *QProjection(const Matrix_t *subspace, const Matrix_t *vectors) + sdim = subspace->Nor; + qdim = subspace->Noc - sdim; + result = MatAlloc(subspace->Field,vectors->Nor,qdim); ++ if (!result) return NULL; + + /* Calculate the projection + ------------------------ */ + FfSetNoc(subspace->Noc); + tmp = FfAlloc(1); ++ if (!tmp) return NULL; + non_piv = subspace->PivotTable + subspace->Nor; + for (i = 0; i < vectors->Nor; ++i) + { + int k; + PTR q = MatGetPtr(result,i); ++ if (!q) ++ { ++ SysFree(tmp); ++ return NULL; ++ } + FfCopyRow(tmp,MatGetPtr(vectors,i)); + FfCleanRow(tmp,subspace->Data,sdim,subspace->PivotTable); + for (k = 0; k < qdim; ++k) +@@ -158,14 +165,20 @@ Matrix_t *QAction(const Matrix_t *subspace, const Matrix_t *gen) + + /* Calculate the action on the quotient + ------------------------------------ */ +- FfSetNoc(dim); ++ FfSetNoc(dim); /* No error checking, since dim is the ->Noc of an existing matrix */ + tmp = FfAlloc(1); ++ if (!tmp) return NULL; + piv = subspace->PivotTable; + non_piv = piv + subspace->Nor; + for (k = 0; k < qdim; ++k) + { + int l; + PTR qx = MatGetPtr(action,k); ++ if (!qx) ++ { ++ SysFree(tmp); ++ return NULL; ++ } + FfCopyRow(tmp,MatGetPtr(gen,non_piv[k])); + FfCleanRow(tmp,subspace->Data,sdim,piv); + for (l = 0; l < qdim; ++l) +diff --git a/src/saction.c b/src/saction.c +index adae3cf..0aba44d 100644 +--- a/src/saction.c ++++ b/src/saction.c +@@ -68,8 +68,14 @@ Matrix_t *SAction(const Matrix_t *subspace, const Matrix_t *gen) + sdim = subspace->Nor; + FfSetField(subspace->Field); + action = MatAlloc(FfOrder,sdim,sdim); +- FfSetNoc(dim); ++ if (!action) return NULL; ++ FfSetNoc(dim); /* No error checking, since dim is the ->Noc of an existing matrix */ + tmp = FfAlloc(1); ++ if (!tmp) ++ { ++ MatFree(action); ++ return NULL; ++ } + + /* Calaculate the action. + ---------------------- */ +@@ -77,6 +83,12 @@ Matrix_t *SAction(const Matrix_t *subspace, const Matrix_t *gen) + { + PTR xi = MatGetPtr(subspace,i); + PTR yi = MatGetPtr(action,i); ++ if (!xi || !yi) ++ { ++ MatFree(action); ++ SysFree(tmp); ++ return NULL; ++ } + FEL f; + + /* Calculate the image of the -th row of . +@@ -85,10 +97,20 @@ Matrix_t *SAction(const Matrix_t *subspace, const Matrix_t *gen) + + /* Clean the image with the subspace and store coefficients. + --------------------------------------------------------- */ +- FfCleanRow2(tmp,subspace->Data,sdim,subspace->PivotTable,yi); ++ if (FfCleanRow2(tmp,subspace->Data,sdim,subspace->PivotTable,yi)) ++ { ++ MatFree(action); ++ SysFree(tmp); ++ return NULL; ++ } + if (FfFindPivot(tmp,&f) >= 0) +- MTX_ERROR("Split(): Subspace not invariant"); ++ { ++ MatFree(action); ++ SysFree(tmp); ++ MTX_ERROR("Split(): Subspace not invariant"); ++ return NULL; + } ++ } + + /* Clean up and return the result. + ------------------------------- */ +diff --git a/src/stabpwr.c b/src/stabpwr.c +index ff33bc6..01282ab 100644 +--- a/src/stabpwr.c ++++ b/src/stabpwr.c +@@ -68,15 +68,18 @@ int StablePower_(Matrix_t *mat, int *pwr, Matrix_t **ker) + --------------------------- */ + p = 1; + k1 = MatNullSpace(mat); +- MatMul(mat,mat); ++ if (!k1) return -1; ++ if (!MatMul(mat,mat)) return -1; + k2 = MatNullSpace(mat); ++ if (!k2) return -1; + while (k2->Nor > k1->Nor) + { + p *= 2; + MatFree(k1); + k1 = k2; +- MatMul(mat,mat); ++ if (!MatMul(mat,mat)) return -1; + k2 = MatNullSpace(mat); ++ if (!k2) return -1; + } + MatFree(k2); + +diff --git a/src/sumint.c b/src/sumint.c +index 278acd8..905fa79 100644 +--- a/src/sumint.c ++++ b/src/sumint.c +@@ -77,7 +77,7 @@ int FfSumAndIntersection(PTR wrk1, int *nor1, int *nor2, PTR wrk2, int *piv) + { + FEL f; + int p; +- FfCleanRowAndRepeat(x1,wrk1,k,piv,x2,wrk2); ++ if (FfCleanRowAndRepeat(x1,wrk1,k,piv,x2,wrk2)) return -1; + if ((p = FfFindPivot(x1,&f)) < 0) + continue; /* Null row - ignore */ + if (k < i) +diff --git a/src/temap.c b/src/temap.c +index 7ba445a..4c2d493 100644 +--- a/src/temap.c ++++ b/src/temap.c +@@ -74,17 +74,21 @@ Matrix_t *TensorMap(Matrix_t *vec, const Matrix_t *a, const Matrix_t *b) + for (i = 0; i < vec->Nor; ++i) + { + Matrix_t *tmp = MatTransposed(a); ++ if (!tmp) return NULL; + Matrix_t *v = VectorToMatrix(vec,i,b->Nor); + if (v == NULL) + { + MTX_ERROR("Conversion failed"); +- break; ++ return NULL; + } +- MatMul(tmp,v); ++ if (!MatMul(tmp,v)) return NULL; + MatFree(v); +- MatMul(tmp,b); ++ if (!MatMul(tmp,b)) return NULL; + if (MatrixToVector(tmp,result,i)) +- MTX_ERROR("Conversion failed"); ++ { ++ MTX_ERROR("Conversion failed"); ++ return NULL; ++ } + MatFree(tmp); + } + return result; +diff --git a/src/vec2mat.c b/src/vec2mat.c +index 1047805..e76ad88 100644 +--- a/src/vec2mat.c ++++ b/src/vec2mat.c +@@ -63,8 +63,11 @@ Matrix_t *VectorToMatrix(Matrix_t *vecs, int n, int noc) + return NULL; + for (i = 0; i < result->Nor; ++i) + { +- if (MatCopyRegion(result,i,0, vecs,n,i*noc,1,noc) != 0) +- MTX_ERROR("Copy failed"); ++ if (MatCopyRegion(result,i,0, vecs,n,i*noc,1,noc) != 0) ++ { ++ MTX_ERROR("Copy failed"); ++ return NULL; ++ } + } + return result; + } +diff --git a/src/window.c b/src/window.c +index 9c87694..fbeb943 100644 +--- a/src/window.c ++++ b/src/window.c +@@ -69,7 +69,11 @@ MatrixWindow_t *WindowAlloc(int fl, int nor, size_t rowsize) + MTX_ERROR1("%E",MTX_ERR_NOMEM); + return NULL; + } +- FfSetField(fl); ++ if (FfSetField(fl)) ++ { ++ free(out); ++ return NULL; ++ } + out->Matrix = MatAlloc(fl, nor, rowsize*sizeof(long)*MPB); + if (out->Matrix == NULL) + { +@@ -266,7 +270,8 @@ __asm__(" popl %ebx\n" + + /** dest := left+right + left and right must be distinct, but one of them may coincide with dest -- under the assumption +- that, in that case, the ambient matrices coincide as well. **/ ++ that, in that case, the ambient matrices coincide as well. ++ Return dest, or NULL on error (the only error may occur in a compatibility check). **/ + MatrixWindow_t *WindowSum(MatrixWindow_t *dest, MatrixWindow_t *left, MatrixWindow_t *right) + { + PTR x, result, tmp; +@@ -335,6 +340,7 @@ MatrixWindow_t *WindowSum(MatrixWindow_t *dest, MatrixWindow_t *left, MatrixWind + /** dest := left-right + left and right must be distinct, but one of them may coincide with dest -- under the assumption + that, in that case, the ambient matrices coincide as well. ++ Return dest, or NULL on error (the only error may occur in a compatibility check). + **/ + MatrixWindow_t *WindowDif(MatrixWindow_t *dest, MatrixWindow_t *left, MatrixWindow_t *right) + { +@@ -407,7 +413,7 @@ MatrixWindow_t *WindowDif(MatrixWindow_t *dest, MatrixWindow_t *left, MatrixWind + can write the result into it. Moreover, the chunk of memory pointed at by dest MUST be disjoint + from the chunks for left and right! + +- Dimensions are not tested! ++ Dimensions are not tested, always dest will be returned (no error value). + **/ + MatrixWindow_t *WindowAddMul(MatrixWindow_t *dest, MatrixWindow_t *left, MatrixWindow_t *right) + { +@@ -617,7 +623,7 @@ int StrassenStep(MatrixWindow_t *dest_win, MatrixWindow_t *A_win, MatrixWindow_t + S2->RowSize = A_sub_rowsize; + S2->Matrix = X->Matrix; + S2->ULCorner = X->ULCorner; +- WindowDif(S2, A00, A10); ++ WindowDif(S2, A00, A10); /* No error checking, as we know that the windows are compatible */ + /* + printf("1. S2 = A00-A10 in X\n"); + WindowShow(X); +@@ -653,7 +659,7 @@ int StrassenStep(MatrixWindow_t *dest_win, MatrixWindow_t *A_win, MatrixWindow_t + S0->RowSize = A_sub_rowsize; + S0->Matrix = X->Matrix; + S0->ULCorner = X->ULCorner; +- WindowSum(S0, A10, A11); ++ WindowSum(S0, A10, A11); /* no error checking here and below, as we know the dimensions of the windows */ + /* + printf("4. S0 = A10+A11 in X\n"); + WindowShow(X); +diff --git a/src/zcleanrow.c b/src/zcleanrow.c +index b4dcb30..d36a165 100644 +--- a/src/zcleanrow.c ++++ b/src/zcleanrow.c +@@ -63,10 +63,10 @@ void FfCleanRow(PTR row, PTR matrix, int nor, const int *piv) + ** @param nor Number of rows. + ** @param piv Pivot table for @em matrix. + ** @param row2 Pointer to row where the operations are recorded. +- ** @return Always 0. ++ ** @return 0, or 1 on error. + **/ + +-void FfCleanRow2(PTR row, PTR mat, int nor, const int *piv, PTR row2) ++int FfCleanRow2(PTR row, PTR mat, int nor, const int *piv, PTR row2) + { + int i; + PTR x; +@@ -74,7 +74,7 @@ void FfCleanRow2(PTR row, PTR mat, int nor, const int *piv, PTR row2) + if (row2 == NULL || piv == NULL) + { + MTX_ERROR1("%E",MTX_ERR_BADARG); +- return; ++ return 1; + } + for (i = 0, x = mat; i < nor; ++i, FfStepPtr(&x)) + { +@@ -86,6 +86,7 @@ void FfCleanRow2(PTR row, PTR mat, int nor, const int *piv, PTR row2) + FfInsert(row2,i,f); + } + } ++ return 0; + } + + +@@ -100,10 +101,10 @@ void FfCleanRow2(PTR row, PTR mat, int nor, const int *piv, PTR row2) + ** @param piv Pivot table for @em mat. + ** @param row2 Pointer to the second row to be cleaned. + ** @param mat2 Matrix to the second matrix. +- ** @return Always 0. ++ ** @return 0, or 1 on error. + **/ + +-void FfCleanRowAndRepeat(PTR row, PTR mat, int nor, const int *piv, PTR row2, PTR mat2) ++int FfCleanRowAndRepeat(PTR row, PTR mat, int nor, const int *piv, PTR row2, PTR mat2) + { + int i; + PTR x, x2; +@@ -112,7 +113,7 @@ void FfCleanRowAndRepeat(PTR row, PTR mat, int nor, const int *piv, PTR row2, PT + if (row2 == NULL || piv == NULL || row2 == NULL || mat2 == NULL) + { + MTX_ERROR1("%E",MTX_ERR_BADARG); +- return; ++ return 1; + } + #endif + for (i = 0, x = mat, x2 = mat2; i < nor; ++i, FfStepPtr(&x), FfStepPtr(&x2)) +@@ -125,6 +126,7 @@ void FfCleanRowAndRepeat(PTR row, PTR mat, int nor, const int *piv, PTR row2, PT + FfAddMulRow(row2,x2,f); + } + } ++ return 0; + } + + diff --git a/src/sage/libs/meataxe.pxd b/src/sage/libs/meataxe.pxd index fc76bfc781e..68878f3fa19 100644 --- a/src/sage/libs/meataxe.pxd +++ b/src/sage/libs/meataxe.pxd @@ -56,8 +56,8 @@ cdef extern from "meataxe.h": # FEL FfMul(FEL a, FEL b) # FEL FfDiv(FEL a, FEL b) # FEL FfInv(FEL a) - # FEL FfEmbed(FEL a, int subfield) - # FEL FfRestrict(FEL a, int subfield) + # FEL FfEmbed(FEL a, int subfield) except 255 + # FEL FfRestrict(FEL a, int subfield) except 255 FEL FfFromInt(int l) int FfToInt(FEL f) @@ -97,8 +97,8 @@ cdef extern from "meataxe.h": ## Basic memory operations Matrix_t *MatAlloc(int field, int nor, int noc) except NULL int MatFree(Matrix_t *mat) - PTR MatGetPtr(Matrix_t *mat, int row) - int MatCompare(Matrix_t *a, Matrix_t *b) except? -1 + PTR MatGetPtr(Matrix_t *mat, int row) except NULL + int MatCompare(Matrix_t *a, Matrix_t *b) except -2 int MatCopyRegion(Matrix_t *dest, int destrow, int destcol, Matrix_t *src, int row1, int col1, int nrows, int ncols) except -1 Matrix_t *MatCut(Matrix_t *src, int row1, int col1, int nrows, int ncols) except NULL Matrix_t *MatCutRows(Matrix_t *src, int row1, int nrows) except NULL @@ -115,11 +115,15 @@ cdef extern from "meataxe.h": Matrix_t *MatMul(Matrix_t *dest, Matrix_t *src) except NULL Matrix_t *MatMulScalar(Matrix_t *dest, FEL coeff) except NULL Matrix_t *MatPower(Matrix_t *mat, long n) except NULL - FEL MatTrace(Matrix_t *mat) + int StablePower(Matrix_t *mat, int *pwr, Matrix_t **ker) except -1 + FEL MatTrace(Matrix_t *mat) except 255 Matrix_t *MatMulStrassen(Matrix_t *dest, Matrix_t *A, Matrix_t *B) except NULL void StrassenSetCutoff(size_t size) ## "Higher" Arithmetic + Matrix_t *MatTensor(Matrix_t *m1, Matrix_t *m2) except NULL + Matrix_t *TensorMap(Matrix_t *vec, Matrix_t *a, Matrix_t *b) except NULL + int MatClean(Matrix_t *mat, Matrix_t *sub) except -1 int MatEchelonize(Matrix_t *mat) except -1 int MatOrder(Matrix_t *mat) except? -1