PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/Release_1_4_beta/Supermon/src/common/sexpr_0.3.0/io.c

#
C | 277 lines | 179 code | 43 blank | 55 comment | 75 complexity | ce50d89a945045a2f3f09d0505d74ffa MD5 | raw file
Possible License(s): GPL-2.0
  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 <unistd.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include "sexp.h"
  33. #include <assert.h>
  34. /**
  35. * read_sexp :: same as fread_sexp, except with read vs fgetch. NOTE:
  36. * assumes that the expression has at least one pair of outer parens.
  37. * So it will not read an atom in properly.
  38. */
  39. int
  40. read_sexp (char *buf, int size, int f)
  41. {
  42. signed char ch = 0;
  43. char *sexp;
  44. int i = 0, depth = 0;
  45. int numread;
  46. int sawQuote = 0;
  47. sexp = (char *) malloc (sizeof (char) * size);
  48. assert(sexp != NULL);
  49. /* read until a '(' */
  50. do
  51. {
  52. numread = read (f, &ch, 1);
  53. }
  54. while (ch != '(' && numread == 1);
  55. if (numread < 1) {
  56. free(sexp);
  57. return 0; /* bail! - no sexp here. */
  58. }
  59. sexp[i] = ch;
  60. i++;
  61. depth++; /* inc depth since we know we have a '(' */
  62. while (depth > 0)
  63. {
  64. numread = read (f, &ch, 1);
  65. /* if we see an escape character, store it and the character it
  66. is escaping, and move on. */
  67. if (ch == '\\') {
  68. sexp[i] = ch;
  69. i++;
  70. if (i == size) {
  71. fprintf(stderr,"read_sexp overran buffer. %d bytes is too small.\n",
  72. size);
  73. free(sexp);
  74. return -1;
  75. }
  76. numread = read(f,&ch,1);
  77. if (numread < 1) {
  78. free(sexp);
  79. return 0;
  80. } else {
  81. sexp[i] = ch;
  82. i++;
  83. if (i == size) {
  84. fprintf(stderr,"read_sexp overran buffer. %d bytes is too small.\n",
  85. size);
  86. free(sexp);
  87. return -1;
  88. }
  89. numread = read(f,&ch,1);
  90. }
  91. }
  92. if (numread < 1) {
  93. free(sexp); /* fix leak - thanks smj */
  94. return 0; /* bail! */
  95. }
  96. if (ch == '\"') {
  97. if (sawQuote == 0)
  98. sawQuote = 1;
  99. else
  100. sawQuote = 0;
  101. }
  102. if (ch == ')' && sawQuote == 0)
  103. depth--;
  104. else if (ch == '(' && sawQuote == 0)
  105. depth++;
  106. /* strip out CR and LF -- I hate them. */
  107. if (ch != '\n' && ch != '\r')
  108. {
  109. sexp[i] = ch;
  110. i++;
  111. }
  112. if (i == size) {
  113. fprintf(stderr,"read_sexp overran buffer. %d bytes is too small.\n",
  114. size);
  115. free(sexp);
  116. return -1;
  117. }
  118. }
  119. /* null terminate the string */
  120. sexp[i] = '\0';
  121. if (i > size)
  122. {
  123. strncpy (buf, sexp, size);
  124. fprintf (stderr, "Warning: read_sexp over buffer size - truncating.\n");
  125. }
  126. else
  127. strncpy (buf, sexp, i + 1);
  128. free (sexp);
  129. return 1;
  130. }
  131. /*
  132. * fread_sexp :: given a FD, read until ( and return the string including the
  133. * ( to the corresponding ). return 1 if OK, 0 otherwise. this is useful,
  134. * since now we work by sexps, not lines. So if someone asks for a variable
  135. * the expression might span multiple lines. Not hard to deal with.
  136. * Use this if you're reading from a file or socket and know that the
  137. * matchine parens for the s-expr might not be on the same line.
  138. *
  139. * Return value of 0 = fail, 1 = succeed.
  140. */
  141. int
  142. fread_sexp (char *buf, int size, FILE * fd)
  143. {
  144. signed char ch = 0;
  145. char *sexp;
  146. int i = 0, depth = 0;
  147. int sawQuote = 0;
  148. sexp = (char *) malloc (sizeof (char) * size);
  149. assert(sexp != NULL);
  150. /* read until a '(' */
  151. do
  152. {
  153. ch = fgetc (fd);
  154. }
  155. while (ch != '(' && ch != EOF);
  156. if (ch == EOF) {
  157. free(sexp);
  158. return 0; /* bail! - no sexp here. */
  159. }
  160. sexp[i] = ch;
  161. i++;
  162. depth++; /* inc depth since we know we have a '(' */
  163. while (depth > 0)
  164. {
  165. ch = fgetc (fd);
  166. if (ch == '\"') {
  167. if (sawQuote == 0)
  168. sawQuote = 1;
  169. else
  170. sawQuote = 0;
  171. }
  172. if (ch == '\\') {
  173. sexp[i] = ch;
  174. i++;
  175. if (i == size) {
  176. fprintf(stderr,"fread_sexp overran buffer. %d bytes is too small.\n",
  177. size);
  178. free(sexp); /* fix leak - thanks smj */
  179. return -1;
  180. }
  181. ch = fgetc(fd);
  182. if (ch == EOF) {
  183. free(sexp);
  184. return 0;
  185. } else {
  186. sexp[i] = ch;
  187. i++;
  188. if (i == size) {
  189. fprintf(stderr,"fread_sexp overran buffer. %d bytes is too small.\n",
  190. size);
  191. free(sexp); /* fix leak - thanks smj */
  192. return -1;
  193. }
  194. ch = fgetc(fd);
  195. }
  196. }
  197. if (ch == EOF) {
  198. free(sexp); /* fix leak - thanks smj */
  199. return 0; /* bail! */
  200. }
  201. if (ch == ')' && sawQuote == 0)
  202. depth--;
  203. else if (ch == '(' && sawQuote == 0)
  204. depth++;
  205. /* strip out CR and LF -- I hate them. */
  206. if (ch != '\n' && ch != '\r')
  207. {
  208. sexp[i] = ch;
  209. i++;
  210. }
  211. if (i == size) {
  212. fprintf(stderr,"fread_sexp overran buffer. %d bytes is too small.\n",
  213. size);
  214. free(sexp); /* fix leak - thanks smj */
  215. return -1;
  216. }
  217. }
  218. /* null terminate the string */
  219. sexp[i] = '\0';
  220. if (i > size)
  221. {
  222. strncpy (buf, sexp, size);
  223. fprintf (stderr, "Warning: read_sexp over buffer size - truncating.\n");
  224. }
  225. else
  226. strncpy (buf, sexp, i + 1);
  227. free (sexp);
  228. return 1;
  229. }
  230. /**
  231. * Function that can parse directly from a file descriptor
  232. */