/branches/supermon/Supermon/src/common/sexpr_0.2.2/io.c

# · C · 190 lines · 110 code · 29 blank · 51 comment · 44 complexity · 0224f1b49946161bbf24409dafbae555 MD5 · raw file

  1. /**
  2. This software and ancillary information (herein called "SOFTWARE")
  3. called Supermon is made available under the terms described
  4. here. The SOFTWARE has been approved for release with associated
  5. LA-CC Number LA-CC 99-51.
  6. Unless otherwise indicated, this SOFTWARE has been authored by an
  7. employee or employees of the University of California, operator of the
  8. Los Alamos National Laboratory under Contract No. W-7405-ENG-36 with
  9. the U.S. Department of Energy. The U.S. Government has rights to use,
  10. reproduce, and distribute this SOFTWARE, and to allow others to do so.
  11. The public may copy, distribute, prepare derivative works and publicly
  12. display this SOFTWARE without charge, provided that this Notice and
  13. any statement of authorship are reproduced on all copies. Neither the
  14. Government nor the University makes any warranty, express or implied,
  15. or assumes any liability or responsibility for the use of this
  16. SOFTWARE.
  17. If SOFTWARE is modified to produce derivative works, such modified
  18. SOFTWARE should be clearly marked, so as not to confuse it with the
  19. version available from LANL.
  20. **/
  21. /** NOTE: This library is part of the supermon project, hence the name
  22. supermon above. **/
  23. /***
  24. * Matt's smaller s-expression parsing library
  25. *
  26. * Written by Matt Sottile (matt@lanl.gov), January 2002.
  27. ***/
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include "sexpr.h"
  32. #include <assert.h>
  33. /*
  34. * read_sexp :: same as fread_sexp, except with read vs fgetch.
  35. */
  36. int
  37. read_sexp (char *buf, int size, int f)
  38. {
  39. signed char ch = 0;
  40. char *sexp;
  41. int i = 0, depth = 0;
  42. int numread;
  43. sexp = (char *) malloc (sizeof (char) * size);
  44. assert(sexp != NULL);
  45. /* read until a '(' */
  46. do
  47. {
  48. numread = read (f, &ch, 1);
  49. }
  50. while (ch != '(' && numread == 1);
  51. if (numread < 1)
  52. return 0; /* bail! - no sexp here. */
  53. sexp[i] = ch;
  54. i++;
  55. depth++; /* inc depth since we know we have a '(' */
  56. while (depth > 0)
  57. {
  58. numread = read (f, &ch, 1);
  59. if (ch == ')')
  60. depth--;
  61. else if (ch == '(')
  62. depth++;
  63. else if (numread < 1) {
  64. free(sexp); /* fix leak - thanks smj */
  65. return 0; /* bail! */
  66. }
  67. /* strip out CR and LF -- I hate them. */
  68. if (ch != '\n' && ch != '\r')
  69. {
  70. sexp[i] = ch;
  71. i++;
  72. }
  73. if (i == size) {
  74. fprintf(stderr,"read_sexp overran buffer. %d bytes is too small.\n",
  75. size);
  76. free(sexp);
  77. return -1;
  78. }
  79. }
  80. /* null terminate the string */
  81. sexp[i] = '\0';
  82. if (i > size)
  83. {
  84. strncpy (buf, sexp, size);
  85. fprintf (stderr, "Warning: read_sexp over buffer size - truncating.\n");
  86. }
  87. else
  88. strncpy (buf, sexp, i + 1);
  89. free (sexp);
  90. return 1;
  91. }
  92. /*
  93. * fread_sexp :: given a FD, read until ( and return the string including the
  94. * ( to the corresponding ). return 1 if OK, 0 otherwise. this is useful,
  95. * since now we work by sexps, not lines. So if someone asks for a variable
  96. * the expression might span multiple lines. Not hard to deal with.
  97. * Use this if you're reading from a file or socket and know that the
  98. * matchine parens for the s-expr might not be on the same line.
  99. *
  100. * Return value of 0 = fail, 1 = succeed.
  101. */
  102. int
  103. fread_sexp (char *buf, int size, FILE * fd)
  104. {
  105. signed char ch = 0;
  106. char *sexp;
  107. int i = 0, depth = 0;
  108. sexp = (char *) malloc (sizeof (char) * size);
  109. assert(sexp != NULL);
  110. /* read until a '(' */
  111. do
  112. {
  113. ch = fgetc (fd);
  114. }
  115. while (ch != '(' && ch != EOF);
  116. if (ch == EOF)
  117. return 0; /* bail! - no sexp here. */
  118. sexp[i] = ch;
  119. i++;
  120. depth++; /* inc depth since we know we have a '(' */
  121. while (depth > 0)
  122. {
  123. ch = fgetc (fd);
  124. if (ch == ')')
  125. depth--;
  126. else if (ch == '(')
  127. depth++;
  128. else if (ch == EOF) {
  129. free(sexp); /* fix leak - thanks smj */
  130. return 0; /* bail! */
  131. }
  132. /* strip out CR and LF -- I hate them. */
  133. if (ch != '\n' && ch != '\r')
  134. {
  135. sexp[i] = ch;
  136. i++;
  137. }
  138. if (i == size) {
  139. fprintf(stderr,"fread_sexp overran buffer. %d bytes is too small.\n",
  140. size);
  141. free(sexp); /* fix leak - thanks smj */
  142. return -1;
  143. }
  144. }
  145. /* null terminate the string */
  146. sexp[i] = '\0';
  147. if (i > size)
  148. {
  149. strncpy (buf, sexp, size);
  150. fprintf (stderr, "Warning: read_sexp over buffer size - truncating.\n");
  151. }
  152. else
  153. strncpy (buf, sexp, i + 1);
  154. free (sexp);
  155. return 1;
  156. }
  157. /**
  158. * Function that can parse directly from a file descriptor
  159. */