Created
December 3, 2022 22:32
-
-
Save RobCranfill/1eb802d1359550b5d71d8a60e1df9da2 to your computer and use it in GitHub Desktop.
getLine for RPi Pico, in C (based on https://github.com/ambotaku/pico-getLine)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Adapted from https://github.com/ambotaku/pico-getLine | |
// Trivial code change to allow compiling with plain C on Pico. | |
// | |
const uint startLineLength = 8; // the linebuffer will automatically grow for longer lines | |
const char eof = 255; // EOF in stdio.h -is -1, but getchar returns int 255 to avoid blocking | |
/* | |
* read a line of any length from stdio (grows) | |
* | |
* @param fullDuplex input will echo on entry (terminal mode) when false | |
* @param linebreak "\r" may be needed for terminals | |
* @return entered line on heap - don't forget calling free() to get memory back | |
*/ | |
// static char * getLine(bool fullDuplex = true, char lineBreak = '\n') { | |
static char * getLine(bool fullDuplex, char lineBreak) { | |
// th line buffer | |
// will allocated by pico_malloc module if <cstdlib> gets included | |
char * pStart = (char*)malloc(startLineLength); | |
char * pPos = pStart; // next character position | |
size_t maxLen = startLineLength; // current max buffer size | |
size_t len = maxLen; // current max length | |
int c; | |
if (!pStart) { | |
return NULL; // out of memory or dysfunctional heap | |
} | |
while (1) { | |
c = getchar(); // expect next character entry | |
if (c == eof || c == lineBreak) { | |
break; // non blocking exit | |
} | |
if (fullDuplex) { | |
putchar(c); // echo for fullDuplex terminals | |
} | |
if (--len == 0) { // allow larger buffer | |
len = maxLen; | |
// double the current line buffer size | |
char *pNew = (char*)realloc(pStart, maxLen *= 2); | |
if (!pNew) { | |
free(pStart); | |
return NULL; // out of memory abort | |
} | |
// fix pointer for new buffer | |
pPos = pNew + (pPos - pStart); | |
pStart = pNew; | |
} | |
// stop reading if lineBreak character entered | |
if ((*pPos++ = c) == lineBreak) { | |
break; | |
} | |
} | |
*pPos = '\0'; // set string end mark | |
return pStart; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment