Skip to content

Instantly share code, notes, and snippets.

@RobCranfill
Created December 3, 2022 22:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RobCranfill/1eb802d1359550b5d71d8a60e1df9da2 to your computer and use it in GitHub Desktop.
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)
// 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