// ========================================================= //
//                                                           //
//   File      : gets_noOverflow.h                           //
//   Purpose   : drop-in replacement for gets()              //
//                                                           //
//   Coded by Ralf Westram (coder@reallysoft.de) in Aug 23   //
//   http://www.arb-home.de/                                 //
//                                                           //
// ========================================================= //

#ifndef GETS_NOOVERFLOW_H
#define GETS_NOOVERFLOW_H

#ifndef _STDIO_H
#include <stdio.h>
#endif
#ifndef _STRING_H
#include <string.h>
#endif

// inspired by https://codereview.stackexchange.com/questions/163133/c-gets-s-implementation


#ifndef __cplusplus
static
#endif

inline char *gets_noOverflow(char *buffer, int buffersize) {
    // behaves like gets(), but does NOT overflow the given 'buffer'.
    // 'buffersize' includes the terminal zero byte.
    //
    // Note: behavior of code may change, because the result is truncated
    //       in those cases where an overflow did happen with gets()!

    char *result = fgets(buffer, buffersize, stdin);

    if (!result) {
        buffer[0] = 0;
    }
    else {
        char *delim = strchr(buffer, 0);
        if (delim>result) {
            char *last_read = delim-1;
            if (last_read[0] == '\n') {
                last_read[0] = 0; // remove trailing newline (as gets did)
            }
            else {
                int c = fgetc(stdin);
                if (c != EOF && c != '\n') {
                    // original gets() did overflow buffer NOW!
                    // continue reading as far as gets() would have done:
                    do c = fgetc(stdin);
                    while (c != EOF && c != '\n');
                }
            }
        }
    }

    return result;
}

#else
#error gets_noOverflow.h included twice
#endif // GETS_NOOVERFLOW_H
