int _flushbuf(int ch, FILE *stream) { int flag = stream -> _flag; if ((flag & _IOERR+_IOSTRG+_IOWRITE+_IOFP1) != _IOWRITE) { stream->_ocnt = 0; /* 2^31 is big but finite */ seterr(stream); return EOF; } /* the next conditional code is ACN's view of that APPEND means seek to */ /* EOF after EVERY fflush, not just initially. Hmm, ANSI really should */ /* clarify - the problem is perhaps that we wish to seek to EOF after */ /* fflush after read, but not after fflush after write? */ if ((flag & (_IOFP2+_IOSEEK+_IOAPPEND)) == _IOAPPEND) { /* first write to APPEND file after FFLUSH, but not FSEEK nor */ /* fopen (does its own FSEEK) */ fseek(stream, 0L, SEEK_END); flag = stream->_flag; } stream->_flag = (flag |= _IOFP2); /* we are writing */ if ((flag & _IOFBF+_IOSBF+_IONBF+_IOLBF) == 0) { if (_sys_istty_(stream->_file)) /* terminal - unbuffered */ #ifdef LINE_BUFFERED_TTYIO stream->_ptr = stream -> _base = _sys_alloc(LINBUFSIZ), stream->_bufsiz = LINBUFSIZ, stream->_flag |= (flag |= _IOLBF); #else stream->_ptr = stream->_base = stream->_lilbuf, stream->_bufsiz = 1, stream->_flag = (flag |= _IONBF); #endif else /* allocate default system buffer */ stream->_ptr = stream->_base = _sys_alloc(BUFSIZ), stream->_bufsiz = BUFSIZ, stream->_flag |= (flag |= _IOSBF); }
/* @description: Heapify helper for _sort. */ void do_heap(uint8_t *base, size_t i, size_t n, size_t size, _cmp_func_t cmp) { /* Not much can be done when size is unknown */ void *temp = _sys_alloc(size); size_t k; /* Save the node that's being overwritten below */ memcpy(temp, &base[i * size], size); /* Move all subsequent child nodes into place to maintain the heap property */ for (k = i * 2 + 1; k < n; k = i * 2 + 1) { /* Find the next child node */ if (k + 1 < n && cmp(&base[k * size], &base[(k + 1) * size]) < 0) ++k; /* Are we at the saved node's sorted position? */ if (cmp(temp, &base[k * size]) >= 0) break; /* Overwrite the parent with one of its children */ memcpy(&base[i * size], &base[k * size], size); i = k; } /* Copy the saved node into its final resting place */ memcpy(&base[i * size], temp, size); _sys_free(temp); }
/* @description: qsort-friendly implementation of heapsort for guaranteed time complexity. */ void _sort(void *base, size_t n, size_t size, _cmp_func_t cmp) { /* Not much can be done when size is unknown */ void *temp = _sys_alloc(size); uint8_t *p = (uint8_t*)base; int i = n / 2; /* Heapify the array */ while (i-- > 0) do_heap(p, i, n, size, cmp); /* Extrac the heap max and place it in sorted position */ while (--n < (size_t)-1) { /* Swap the heap max with base[n] */ memcpy(temp, p, size); memcpy(p, &p[n * size], size); memcpy(&p[n * size], temp, size); /* Re-heapify after removing the heap max */ do_heap(p, 0, n, size, cmp); } _sys_free(temp); }