mmio.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*************************************************************************
  2. * Copyright (c) 2011 AT&T Intellectual Property
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors: Details at https://graphviz.org
  9. *************************************************************************/
  10. /*
  11. * Matrix Market I/O library for ANSI C
  12. *
  13. * See http://math.nist.gov/MatrixMarket for details.
  14. *
  15. *
  16. */
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <ctype.h>
  21. #include <sparse/SparseMatrix.h>
  22. #include <util/startswith.h>
  23. #include <util/strcasecmp.h>
  24. #include "mmio.h"
  25. int mm_read_banner(FILE * f, MM_typecode * matcode)
  26. {
  27. char line[MM_MAX_LINE_LENGTH];
  28. char banner[MM_MAX_TOKEN_LENGTH] = {0};
  29. char mtx[MM_MAX_TOKEN_LENGTH] = {0};
  30. char crd[MM_MAX_TOKEN_LENGTH] = {0};
  31. char data_type[MM_MAX_TOKEN_LENGTH] = {0};
  32. char storage_scheme[MM_MAX_TOKEN_LENGTH] = {0};
  33. *matcode = (MM_typecode){0};
  34. if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL)
  35. return MM_PREMATURE_EOF;
  36. // note: 63 == MM_MAX_TOKEN_LENGTH - 1
  37. if (sscanf(line, "%63s %63s %63s %63s %63s", banner, mtx, crd, data_type,
  38. storage_scheme) != 5)
  39. return MM_PREMATURE_EOF;
  40. /* check for banner */
  41. if (!startswith(banner, MatrixMarketBanner))
  42. return MM_NO_HEADER;
  43. /* first field should be "mtx" */
  44. if (strcasecmp(mtx, MM_MTX_STR) != 0)
  45. return MM_UNSUPPORTED_TYPE;
  46. // second field describes whether this is a sparse matrix (in coordinate
  47. // storage) or a dense array
  48. if (strcasecmp(crd, MM_SPARSE_STR) != 0)
  49. return MM_UNSUPPORTED_TYPE;
  50. /* third field */
  51. if (strcasecmp(data_type, MM_REAL_STR) == 0)
  52. matcode->type = MATRIX_TYPE_REAL;
  53. else if (strcasecmp(data_type, MM_COMPLEX_STR) == 0)
  54. matcode->type = MATRIX_TYPE_COMPLEX;
  55. else if (strcasecmp(data_type, MM_PATTERN_STR) == 0)
  56. matcode->type = MATRIX_TYPE_PATTERN;
  57. else if (strcasecmp(data_type, MM_INT_STR) == 0)
  58. matcode->type = MATRIX_TYPE_INTEGER;
  59. else
  60. return MM_UNSUPPORTED_TYPE;
  61. /* fourth field */
  62. if (strcasecmp(storage_scheme, MM_GENERAL_STR) == 0)
  63. matcode->shape = MS_GENERAL;
  64. else if (strcasecmp(storage_scheme, MM_SYMM_STR) == 0)
  65. matcode->shape = MS_SYMMETRIC;
  66. else if (strcasecmp(storage_scheme, MM_HERM_STR) == 0)
  67. matcode->shape = MS_HERMITIAN;
  68. else if (strcasecmp(storage_scheme, MM_SKEW_STR) == 0)
  69. matcode->shape = MS_SKEW;
  70. else
  71. return MM_UNSUPPORTED_TYPE;
  72. return 0;
  73. }
  74. int mm_read_mtx_crd_size(FILE * f, int *M, int *N, int *nz)
  75. {
  76. char line[MM_MAX_LINE_LENGTH];
  77. int num_items_read;
  78. /* set return null parameter values, in case we exit with errors */
  79. *M = *N = *nz = 0;
  80. /* now continue scanning until you reach the end-of-comments */
  81. do {
  82. if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL)
  83. return MM_PREMATURE_EOF;
  84. } while (line[0] == '%');
  85. /* line[] is either blank or has M,N, nz */
  86. if (sscanf(line, "%d %d %d", M, N, nz) == 3)
  87. return 0;
  88. else
  89. do {
  90. num_items_read = fscanf(f, "%d %d %d", M, N, nz);
  91. if (num_items_read == EOF)
  92. return MM_PREMATURE_EOF;
  93. }
  94. while (num_items_read != 3);
  95. return 0;
  96. }