Advertisement
Beatgodes

Untitled

May 9th, 2013
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.70 KB | None | 0 0
  1. #define NULL ((void *)0)
  2.  
  3. #define __SIZE_TYPE__ long unsigned int
  4. typedef __SIZE_TYPE__ size_t;
  5. #define EOF (-1)
  6.  
  7. struct _IO_file {
  8. int _IO_fileno; /* Underlying file descriptor */
  9. _Bool _IO_eof; /* End of file flag */
  10. _Bool _IO_error; /* Error flag */
  11. };
  12. typedef struct _IO_file FILE;
  13.  
  14. /*@
  15. predicate valid_FILE(FILE *f) =
  16. \valid(f) && f->_IO_fileno >= 0;
  17. @*/
  18.  
  19.  
  20.  
  21. /* Actual FILE structure */
  22. struct _IO_file_pvt {
  23. struct _IO_file pub; /* Data exported to inlines */
  24. struct _IO_file_pvt *prev, *next;
  25. char *buf; /* Buffer */
  26. char *data; /* Location of input data in buffer */
  27. unsigned int ibytes; /* Input data bytes in buffer */
  28. unsigned int obytes; /* Output data bytes in buffer */
  29. unsigned int bufsiz; /* Total size of buffer */
  30. enum _IO_bufmode bufmode; /* Type of buffering */
  31. };
  32.  
  33. /*@
  34.  
  35. predicate valid_IO_file_pvt(struct _IO_file_pvt *f) =
  36. \valid(f)
  37. && f->bufsiz == 16384 // _KLIBC_BUFSIZ == _KLIBC_MALLOC_CHUNK_SIZE/4 == 65536/4
  38. && 0 <= f->ibytes < f->bufsiz
  39. && 0 <= f->obytes < f->bufsiz
  40. && valid_FILE(&(f->pub)) // call to valid FILE struct
  41. && \separated(f, f->next, f->prev, f->buf+(0..(f->bufsiz+32-1)))
  42. && (f->next == NULL || valid_IO_file_pvt(f->next))
  43. && (f->prev == NULL || valid_IO_file_pvt(f->prev))
  44. && \valid(f->buf+(0..(f->bufsiz+32-1))) // buffer is valid in defined size + unget_slop
  45. ;
  46. @*/
  47.  
  48.  
  49. #define offsetof(t,m) ((size_t)&((t *)0)->m)
  50. #define container_of(p, c, m) ((c *)((char *)(p) - offsetof(c,m)))
  51. #define stdio_pvt(x) container_of(x, struct _IO_file_pvt, pub)
  52.  
  53.  
  54.  
  55. /*@
  56. requires file != \null;
  57. requires \valid(file);
  58. requires file == &(stdio_pvt(file)->pub);
  59. requires valid_IO_file_pvt(stdio_pvt(file));
  60. requires -128 <= c <= 127;
  61.  
  62. behavior fail:
  63. assumes stdio_pvt(file)->obytes != 0 || stdio_pvt(file)->data <= stdio_pvt(file)->buf;
  64. assigns \nothing;
  65. ensures \result == EOF;
  66.  
  67. behavior success:
  68. assumes stdio_pvt(file)->obytes == 0 && stdio_pvt(file)->data > stdio_pvt(file)->buf;
  69. assigns stdio_pvt(file)->ibytes, stdio_pvt(file)->data, *(\at(stdio_pvt(file)->data, Pre)-1);
  70. ensures \at(stdio_pvt(file)->ibytes, Here) == \at(stdio_pvt(file)->ibytes, Pre) + 1;
  71. ensures \at(stdio_pvt(file)->data, Here) == \at(stdio_pvt(file)->data, Pre) -1;
  72. ensures *(stdio_pvt(file)->data) == c;
  73. ensures \result == c;
  74.  
  75. complete behaviors;
  76. disjoint behaviors;
  77. @*/
  78. int ungetc(int c, FILE *file)
  79. {
  80. struct _IO_file_pvt *f = stdio_pvt(file);
  81.  
  82. if (f->obytes || f->data <= f->buf)
  83. return EOF;
  84.  
  85. //@ assert f->data > f->buf;
  86. *(--f->data) = c;
  87. f->ibytes++;
  88. return c;
  89. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement