Annotation of rpl/lapack/lapack/ilaenv.f, revision 1.1
1.1 ! bertrand 1: INTEGER FUNCTION ILAENV( ISPEC, NAME, OPTS, N1, N2, N3, N4 )
! 2: *
! 3: * -- LAPACK auxiliary routine (version 3.2.1) --
! 4: *
! 5: * -- April 2009 --
! 6: *
! 7: * -- LAPACK is a software package provided by Univ. of Tennessee, --
! 8: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! 9: *
! 10: * .. Scalar Arguments ..
! 11: CHARACTER*( * ) NAME, OPTS
! 12: INTEGER ISPEC, N1, N2, N3, N4
! 13: * ..
! 14: *
! 15: * Purpose
! 16: * =======
! 17: *
! 18: * ILAENV is called from the LAPACK routines to choose problem-dependent
! 19: * parameters for the local environment. See ISPEC for a description of
! 20: * the parameters.
! 21: *
! 22: * ILAENV returns an INTEGER
! 23: * if ILAENV >= 0: ILAENV returns the value of the parameter specified by ISPEC
! 24: * if ILAENV < 0: if ILAENV = -k, the k-th argument had an illegal value.
! 25: *
! 26: * This version provides a set of parameters which should give good,
! 27: * but not optimal, performance on many of the currently available
! 28: * computers. Users are encouraged to modify this subroutine to set
! 29: * the tuning parameters for their particular machine using the option
! 30: * and problem size information in the arguments.
! 31: *
! 32: * This routine will not function correctly if it is converted to all
! 33: * lower case. Converting it to all upper case is allowed.
! 34: *
! 35: * Arguments
! 36: * =========
! 37: *
! 38: * ISPEC (input) INTEGER
! 39: * Specifies the parameter to be returned as the value of
! 40: * ILAENV.
! 41: * = 1: the optimal blocksize; if this value is 1, an unblocked
! 42: * algorithm will give the best performance.
! 43: * = 2: the minimum block size for which the block routine
! 44: * should be used; if the usable block size is less than
! 45: * this value, an unblocked routine should be used.
! 46: * = 3: the crossover point (in a block routine, for N less
! 47: * than this value, an unblocked routine should be used)
! 48: * = 4: the number of shifts, used in the nonsymmetric
! 49: * eigenvalue routines (DEPRECATED)
! 50: * = 5: the minimum column dimension for blocking to be used;
! 51: * rectangular blocks must have dimension at least k by m,
! 52: * where k is given by ILAENV(2,...) and m by ILAENV(5,...)
! 53: * = 6: the crossover point for the SVD (when reducing an m by n
! 54: * matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds
! 55: * this value, a QR factorization is used first to reduce
! 56: * the matrix to a triangular form.)
! 57: * = 7: the number of processors
! 58: * = 8: the crossover point for the multishift QR method
! 59: * for nonsymmetric eigenvalue problems (DEPRECATED)
! 60: * = 9: maximum size of the subproblems at the bottom of the
! 61: * computation tree in the divide-and-conquer algorithm
! 62: * (used by xGELSD and xGESDD)
! 63: * =10: ieee NaN arithmetic can be trusted not to trap
! 64: * =11: infinity arithmetic can be trusted not to trap
! 65: * 12 <= ISPEC <= 16:
! 66: * xHSEQR or one of its subroutines,
! 67: * see IPARMQ for detailed explanation
! 68: *
! 69: * NAME (input) CHARACTER*(*)
! 70: * The name of the calling subroutine, in either upper case or
! 71: * lower case.
! 72: *
! 73: * OPTS (input) CHARACTER*(*)
! 74: * The character options to the subroutine NAME, concatenated
! 75: * into a single character string. For example, UPLO = 'U',
! 76: * TRANS = 'T', and DIAG = 'N' for a triangular routine would
! 77: * be specified as OPTS = 'UTN'.
! 78: *
! 79: * N1 (input) INTEGER
! 80: * N2 (input) INTEGER
! 81: * N3 (input) INTEGER
! 82: * N4 (input) INTEGER
! 83: * Problem dimensions for the subroutine NAME; these may not all
! 84: * be required.
! 85: *
! 86: * Further Details
! 87: * ===============
! 88: *
! 89: * The following conventions have been used when calling ILAENV from the
! 90: * LAPACK routines:
! 91: * 1) OPTS is a concatenation of all of the character options to
! 92: * subroutine NAME, in the same order that they appear in the
! 93: * argument list for NAME, even if they are not used in determining
! 94: * the value of the parameter specified by ISPEC.
! 95: * 2) The problem dimensions N1, N2, N3, N4 are specified in the order
! 96: * that they appear in the argument list for NAME. N1 is used
! 97: * first, N2 second, and so on, and unused problem dimensions are
! 98: * passed a value of -1.
! 99: * 3) The parameter value returned by ILAENV is checked for validity in
! 100: * the calling subroutine. For example, ILAENV is used to retrieve
! 101: * the optimal blocksize for STRTRI as follows:
! 102: *
! 103: * NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 )
! 104: * IF( NB.LE.1 ) NB = MAX( 1, N )
! 105: *
! 106: * =====================================================================
! 107: *
! 108: * .. Local Scalars ..
! 109: INTEGER I, IC, IZ, NB, NBMIN, NX
! 110: LOGICAL CNAME, SNAME
! 111: CHARACTER C1*1, C2*2, C4*2, C3*3, SUBNAM*6
! 112: * ..
! 113: * .. Intrinsic Functions ..
! 114: INTRINSIC CHAR, ICHAR, INT, MIN, REAL
! 115: * ..
! 116: * .. External Functions ..
! 117: INTEGER IEEECK, IPARMQ
! 118: EXTERNAL IEEECK, IPARMQ
! 119: * ..
! 120: * .. Executable Statements ..
! 121: *
! 122: GO TO ( 10, 10, 10, 80, 90, 100, 110, 120,
! 123: $ 130, 140, 150, 160, 160, 160, 160, 160 )ISPEC
! 124: *
! 125: * Invalid value for ISPEC
! 126: *
! 127: ILAENV = -1
! 128: RETURN
! 129: *
! 130: 10 CONTINUE
! 131: *
! 132: * Convert NAME to upper case if the first character is lower case.
! 133: *
! 134: ILAENV = 1
! 135: SUBNAM = NAME
! 136: IC = ICHAR( SUBNAM( 1: 1 ) )
! 137: IZ = ICHAR( 'Z' )
! 138: IF( IZ.EQ.90 .OR. IZ.EQ.122 ) THEN
! 139: *
! 140: * ASCII character set
! 141: *
! 142: IF( IC.GE.97 .AND. IC.LE.122 ) THEN
! 143: SUBNAM( 1: 1 ) = CHAR( IC-32 )
! 144: DO 20 I = 2, 6
! 145: IC = ICHAR( SUBNAM( I: I ) )
! 146: IF( IC.GE.97 .AND. IC.LE.122 )
! 147: $ SUBNAM( I: I ) = CHAR( IC-32 )
! 148: 20 CONTINUE
! 149: END IF
! 150: *
! 151: ELSE IF( IZ.EQ.233 .OR. IZ.EQ.169 ) THEN
! 152: *
! 153: * EBCDIC character set
! 154: *
! 155: IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.
! 156: $ ( IC.GE.145 .AND. IC.LE.153 ) .OR.
! 157: $ ( IC.GE.162 .AND. IC.LE.169 ) ) THEN
! 158: SUBNAM( 1: 1 ) = CHAR( IC+64 )
! 159: DO 30 I = 2, 6
! 160: IC = ICHAR( SUBNAM( I: I ) )
! 161: IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.
! 162: $ ( IC.GE.145 .AND. IC.LE.153 ) .OR.
! 163: $ ( IC.GE.162 .AND. IC.LE.169 ) )SUBNAM( I:
! 164: $ I ) = CHAR( IC+64 )
! 165: 30 CONTINUE
! 166: END IF
! 167: *
! 168: ELSE IF( IZ.EQ.218 .OR. IZ.EQ.250 ) THEN
! 169: *
! 170: * Prime machines: ASCII+128
! 171: *
! 172: IF( IC.GE.225 .AND. IC.LE.250 ) THEN
! 173: SUBNAM( 1: 1 ) = CHAR( IC-32 )
! 174: DO 40 I = 2, 6
! 175: IC = ICHAR( SUBNAM( I: I ) )
! 176: IF( IC.GE.225 .AND. IC.LE.250 )
! 177: $ SUBNAM( I: I ) = CHAR( IC-32 )
! 178: 40 CONTINUE
! 179: END IF
! 180: END IF
! 181: *
! 182: C1 = SUBNAM( 1: 1 )
! 183: SNAME = C1.EQ.'S' .OR. C1.EQ.'D'
! 184: CNAME = C1.EQ.'C' .OR. C1.EQ.'Z'
! 185: IF( .NOT.( CNAME .OR. SNAME ) )
! 186: $ RETURN
! 187: C2 = SUBNAM( 2: 3 )
! 188: C3 = SUBNAM( 4: 6 )
! 189: C4 = C3( 2: 3 )
! 190: *
! 191: GO TO ( 50, 60, 70 )ISPEC
! 192: *
! 193: 50 CONTINUE
! 194: *
! 195: * ISPEC = 1: block size
! 196: *
! 197: * In these examples, separate code is provided for setting NB for
! 198: * real and complex. We assume that NB will take the same value in
! 199: * single or double precision.
! 200: *
! 201: NB = 1
! 202: *
! 203: IF( C2.EQ.'GE' ) THEN
! 204: IF( C3.EQ.'TRF' ) THEN
! 205: IF( SNAME ) THEN
! 206: NB = 64
! 207: ELSE
! 208: NB = 64
! 209: END IF
! 210: ELSE IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR.
! 211: $ C3.EQ.'QLF' ) THEN
! 212: IF( SNAME ) THEN
! 213: NB = 32
! 214: ELSE
! 215: NB = 32
! 216: END IF
! 217: ELSE IF( C3.EQ.'HRD' ) THEN
! 218: IF( SNAME ) THEN
! 219: NB = 32
! 220: ELSE
! 221: NB = 32
! 222: END IF
! 223: ELSE IF( C3.EQ.'BRD' ) THEN
! 224: IF( SNAME ) THEN
! 225: NB = 32
! 226: ELSE
! 227: NB = 32
! 228: END IF
! 229: ELSE IF( C3.EQ.'TRI' ) THEN
! 230: IF( SNAME ) THEN
! 231: NB = 64
! 232: ELSE
! 233: NB = 64
! 234: END IF
! 235: END IF
! 236: ELSE IF( C2.EQ.'PO' ) THEN
! 237: IF( C3.EQ.'TRF' ) THEN
! 238: IF( SNAME ) THEN
! 239: NB = 64
! 240: ELSE
! 241: NB = 64
! 242: END IF
! 243: END IF
! 244: ELSE IF( C2.EQ.'SY' ) THEN
! 245: IF( C3.EQ.'TRF' ) THEN
! 246: IF( SNAME ) THEN
! 247: NB = 64
! 248: ELSE
! 249: NB = 64
! 250: END IF
! 251: ELSE IF( SNAME .AND. C3.EQ.'TRD' ) THEN
! 252: NB = 32
! 253: ELSE IF( SNAME .AND. C3.EQ.'GST' ) THEN
! 254: NB = 64
! 255: END IF
! 256: ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN
! 257: IF( C3.EQ.'TRF' ) THEN
! 258: NB = 64
! 259: ELSE IF( C3.EQ.'TRD' ) THEN
! 260: NB = 32
! 261: ELSE IF( C3.EQ.'GST' ) THEN
! 262: NB = 64
! 263: END IF
! 264: ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN
! 265: IF( C3( 1: 1 ).EQ.'G' ) THEN
! 266: IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
! 267: $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
! 268: $ THEN
! 269: NB = 32
! 270: END IF
! 271: ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN
! 272: IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
! 273: $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
! 274: $ THEN
! 275: NB = 32
! 276: END IF
! 277: END IF
! 278: ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN
! 279: IF( C3( 1: 1 ).EQ.'G' ) THEN
! 280: IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
! 281: $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
! 282: $ THEN
! 283: NB = 32
! 284: END IF
! 285: ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN
! 286: IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
! 287: $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
! 288: $ THEN
! 289: NB = 32
! 290: END IF
! 291: END IF
! 292: ELSE IF( C2.EQ.'GB' ) THEN
! 293: IF( C3.EQ.'TRF' ) THEN
! 294: IF( SNAME ) THEN
! 295: IF( N4.LE.64 ) THEN
! 296: NB = 1
! 297: ELSE
! 298: NB = 32
! 299: END IF
! 300: ELSE
! 301: IF( N4.LE.64 ) THEN
! 302: NB = 1
! 303: ELSE
! 304: NB = 32
! 305: END IF
! 306: END IF
! 307: END IF
! 308: ELSE IF( C2.EQ.'PB' ) THEN
! 309: IF( C3.EQ.'TRF' ) THEN
! 310: IF( SNAME ) THEN
! 311: IF( N2.LE.64 ) THEN
! 312: NB = 1
! 313: ELSE
! 314: NB = 32
! 315: END IF
! 316: ELSE
! 317: IF( N2.LE.64 ) THEN
! 318: NB = 1
! 319: ELSE
! 320: NB = 32
! 321: END IF
! 322: END IF
! 323: END IF
! 324: ELSE IF( C2.EQ.'TR' ) THEN
! 325: IF( C3.EQ.'TRI' ) THEN
! 326: IF( SNAME ) THEN
! 327: NB = 64
! 328: ELSE
! 329: NB = 64
! 330: END IF
! 331: END IF
! 332: ELSE IF( C2.EQ.'LA' ) THEN
! 333: IF( C3.EQ.'UUM' ) THEN
! 334: IF( SNAME ) THEN
! 335: NB = 64
! 336: ELSE
! 337: NB = 64
! 338: END IF
! 339: END IF
! 340: ELSE IF( SNAME .AND. C2.EQ.'ST' ) THEN
! 341: IF( C3.EQ.'EBZ' ) THEN
! 342: NB = 1
! 343: END IF
! 344: END IF
! 345: ILAENV = NB
! 346: RETURN
! 347: *
! 348: 60 CONTINUE
! 349: *
! 350: * ISPEC = 2: minimum block size
! 351: *
! 352: NBMIN = 2
! 353: IF( C2.EQ.'GE' ) THEN
! 354: IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. C3.EQ.
! 355: $ 'QLF' ) THEN
! 356: IF( SNAME ) THEN
! 357: NBMIN = 2
! 358: ELSE
! 359: NBMIN = 2
! 360: END IF
! 361: ELSE IF( C3.EQ.'HRD' ) THEN
! 362: IF( SNAME ) THEN
! 363: NBMIN = 2
! 364: ELSE
! 365: NBMIN = 2
! 366: END IF
! 367: ELSE IF( C3.EQ.'BRD' ) THEN
! 368: IF( SNAME ) THEN
! 369: NBMIN = 2
! 370: ELSE
! 371: NBMIN = 2
! 372: END IF
! 373: ELSE IF( C3.EQ.'TRI' ) THEN
! 374: IF( SNAME ) THEN
! 375: NBMIN = 2
! 376: ELSE
! 377: NBMIN = 2
! 378: END IF
! 379: END IF
! 380: ELSE IF( C2.EQ.'SY' ) THEN
! 381: IF( C3.EQ.'TRF' ) THEN
! 382: IF( SNAME ) THEN
! 383: NBMIN = 8
! 384: ELSE
! 385: NBMIN = 8
! 386: END IF
! 387: ELSE IF( SNAME .AND. C3.EQ.'TRD' ) THEN
! 388: NBMIN = 2
! 389: END IF
! 390: ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN
! 391: IF( C3.EQ.'TRD' ) THEN
! 392: NBMIN = 2
! 393: END IF
! 394: ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN
! 395: IF( C3( 1: 1 ).EQ.'G' ) THEN
! 396: IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
! 397: $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
! 398: $ THEN
! 399: NBMIN = 2
! 400: END IF
! 401: ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN
! 402: IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
! 403: $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
! 404: $ THEN
! 405: NBMIN = 2
! 406: END IF
! 407: END IF
! 408: ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN
! 409: IF( C3( 1: 1 ).EQ.'G' ) THEN
! 410: IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
! 411: $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
! 412: $ THEN
! 413: NBMIN = 2
! 414: END IF
! 415: ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN
! 416: IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
! 417: $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
! 418: $ THEN
! 419: NBMIN = 2
! 420: END IF
! 421: END IF
! 422: END IF
! 423: ILAENV = NBMIN
! 424: RETURN
! 425: *
! 426: 70 CONTINUE
! 427: *
! 428: * ISPEC = 3: crossover point
! 429: *
! 430: NX = 0
! 431: IF( C2.EQ.'GE' ) THEN
! 432: IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. C3.EQ.
! 433: $ 'QLF' ) THEN
! 434: IF( SNAME ) THEN
! 435: NX = 128
! 436: ELSE
! 437: NX = 128
! 438: END IF
! 439: ELSE IF( C3.EQ.'HRD' ) THEN
! 440: IF( SNAME ) THEN
! 441: NX = 128
! 442: ELSE
! 443: NX = 128
! 444: END IF
! 445: ELSE IF( C3.EQ.'BRD' ) THEN
! 446: IF( SNAME ) THEN
! 447: NX = 128
! 448: ELSE
! 449: NX = 128
! 450: END IF
! 451: END IF
! 452: ELSE IF( C2.EQ.'SY' ) THEN
! 453: IF( SNAME .AND. C3.EQ.'TRD' ) THEN
! 454: NX = 32
! 455: END IF
! 456: ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN
! 457: IF( C3.EQ.'TRD' ) THEN
! 458: NX = 32
! 459: END IF
! 460: ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN
! 461: IF( C3( 1: 1 ).EQ.'G' ) THEN
! 462: IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
! 463: $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
! 464: $ THEN
! 465: NX = 128
! 466: END IF
! 467: END IF
! 468: ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN
! 469: IF( C3( 1: 1 ).EQ.'G' ) THEN
! 470: IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
! 471: $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
! 472: $ THEN
! 473: NX = 128
! 474: END IF
! 475: END IF
! 476: END IF
! 477: ILAENV = NX
! 478: RETURN
! 479: *
! 480: 80 CONTINUE
! 481: *
! 482: * ISPEC = 4: number of shifts (used by xHSEQR)
! 483: *
! 484: ILAENV = 6
! 485: RETURN
! 486: *
! 487: 90 CONTINUE
! 488: *
! 489: * ISPEC = 5: minimum column dimension (not used)
! 490: *
! 491: ILAENV = 2
! 492: RETURN
! 493: *
! 494: 100 CONTINUE
! 495: *
! 496: * ISPEC = 6: crossover point for SVD (used by xGELSS and xGESVD)
! 497: *
! 498: ILAENV = INT( REAL( MIN( N1, N2 ) )*1.6E0 )
! 499: RETURN
! 500: *
! 501: 110 CONTINUE
! 502: *
! 503: * ISPEC = 7: number of processors (not used)
! 504: *
! 505: ILAENV = 1
! 506: RETURN
! 507: *
! 508: 120 CONTINUE
! 509: *
! 510: * ISPEC = 8: crossover point for multishift (used by xHSEQR)
! 511: *
! 512: ILAENV = 50
! 513: RETURN
! 514: *
! 515: 130 CONTINUE
! 516: *
! 517: * ISPEC = 9: maximum size of the subproblems at the bottom of the
! 518: * computation tree in the divide-and-conquer algorithm
! 519: * (used by xGELSD and xGESDD)
! 520: *
! 521: ILAENV = 25
! 522: RETURN
! 523: *
! 524: 140 CONTINUE
! 525: *
! 526: * ISPEC = 10: ieee NaN arithmetic can be trusted not to trap
! 527: *
! 528: * ILAENV = 0
! 529: ILAENV = 1
! 530: IF( ILAENV.EQ.1 ) THEN
! 531: ILAENV = IEEECK( 1, 0.0, 1.0 )
! 532: END IF
! 533: RETURN
! 534: *
! 535: 150 CONTINUE
! 536: *
! 537: * ISPEC = 11: infinity arithmetic can be trusted not to trap
! 538: *
! 539: * ILAENV = 0
! 540: ILAENV = 1
! 541: IF( ILAENV.EQ.1 ) THEN
! 542: ILAENV = IEEECK( 0, 0.0, 1.0 )
! 543: END IF
! 544: RETURN
! 545: *
! 546: 160 CONTINUE
! 547: *
! 548: * 12 <= ISPEC <= 16: xHSEQR or one of its subroutines.
! 549: *
! 550: ILAENV = IPARMQ( ISPEC, NAME, OPTS, N1, N2, N3, N4 )
! 551: RETURN
! 552: *
! 553: * End of ILAENV
! 554: *
! 555: END
CVSweb interface <joel.bertrand@systella.fr>