Created
January 6, 2023 08:22
-
-
Save leok7v/b8ff88dcd5f36a742200568fcf293891 to your computer and use it in GitHub Desktop.
lorem ipsum generator in C
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
#include <assert.h> | |
#include <ctype.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <time.h> | |
typedef struct { | |
char* text; | |
int32_t count; // at least 1KB | |
int32_t min_paragraphs; // at least 1 | |
int32_t max_paragraphs; | |
int32_t min_sentences; // at least 1 | |
int32_t max_sentences; | |
int32_t min_words; // at least 2 | |
int32_t max_words; | |
} lorem_ipsum_generator_params_t; | |
#define countof(array) (sizeof(array) / sizeof(array[0])) | |
static void lorem_ipsum_generator(lorem_ipsum_generator_params_t p) { | |
assert(p.count >= 1024); // at least 1KB expected | |
assert(0 < p.min_paragraphs && p.min_paragraphs <= p.max_paragraphs); | |
assert(0 < p.min_sentences && p.min_sentences <= p.max_sentences); | |
assert(2 < p.min_words && p.min_words <= p.max_words); | |
static const char* words[] = { "lorem", "ipsum", "dolor", "sit", "amet", | |
"consectetur", "adipiscing", "elit", "quisque", "faucibus", "ex", "sapien", | |
"vitae", "pellentesque", "sem", "placerat", "in", "id", "cursus", "mi", | |
"pretium", "tellus", "duis", "convallis", "tempus", "leo", "eu", "aenean", | |
"sed", "diam", "urna", "tempor", "pulvinar", "vivamus", "fringilla", "lacus", | |
"nec", "metus", "bibendum", "egestas", "iaculis", "massa", "nisl", | |
"malesuada", "lacinia", "integer", "nunc", "posuere", "ut", "hendrerit", | |
"semper", "vel", "class", "aptent", "taciti", "sociosqu", "ad", "litora", | |
"torquent", "per", "conubia", "nostra", "inceptos", "himenaeos", "orci", | |
"varius", "natoque", "penatibus", "et", "magnis", "dis", "parturient", | |
"montes", "nascetur", "ridiculus", "mus", "donec", "rhoncus", "eros", | |
"lobortis", "nulla", "molestie", "mattis", "scelerisque", "maximus", "eget", | |
"fermentum", "odio", "phasellus", "non", "purus", "est", "efficitur", | |
"laoreet", "mauris", "pharetra", "vestibulum", "fusce", "dictum", "risus", | |
"blandit", "quis", "suspendisse", "aliquet", "nisi", "sodales", "consequat", | |
"magna", "ante", "condimentum", "neque", "at", "luctus", "nibh", "finibus", | |
"facilisis", "dapibus", "etiam", "interdum", "tortor", "ligula", "congue", | |
"sollicitudin", "erat", "viverra", "ac", "tincidunt", "nam", "porta", | |
"elementum", "a", "enim", "euismod", "quam", "justo", "lectus", "commodo", | |
"augue", "arcu", "dignissim", "velit", "aliquam", "imperdiet", "mollis", | |
"nullam", "volutpat", "porttitor", "ullamcorper", "rutrum", "gravida", | |
"cras", "eleifend", "turpis", "fames", "primis", "vulputate", "ornare", | |
"sagittis", "vehicula", "praesent", "dui", "felis", "venenatis", "ultrices", | |
"proin", "libero", "feugiat", "tristique", "accumsan", "maecenas", "potenti", | |
"ultricies", "habitant", "morbi", "senectus", "netus", "suscipit", "auctor", | |
"curabitur", "facilisi", "cubilia", "curae", "hac", "habitasse", "platea", | |
"dictumst" | |
}; | |
char* s = p.text; | |
char* end = p.text + p.count - 64; | |
uint32_t paragraphs = p.min_paragraphs + | |
(p.min_paragraphs == p.max_paragraphs ? 0 : | |
random() % (p.max_paragraphs - p.min_paragraphs + 1)); | |
while (paragraphs > 0 && s < end) { | |
uint32_t sentences_in_paragraph = p.min_sentences + | |
(p.min_sentences == p.max_sentences ? 0 : | |
random() % (p.max_sentences - p.min_sentences + 1)); | |
while (sentences_in_paragraph > 0 && s < end) { | |
const uint32_t words_in_sentence = p.min_words + | |
(p.min_words == p.max_words ? 0 : | |
random() % (p.max_words - p.min_words + 1)); | |
for (uint32_t i = 0; i < words_in_sentence && s < end; i++) { | |
const char* word = words[random() % countof(words)]; | |
memcpy(s, word, strlen(word)); | |
if (i == 0) { *s = (char)toupper(*s); } | |
s += strlen(word); | |
if (i < words_in_sentence - 1 && s < end) { | |
const char* delimiter = "\x20"; | |
int32_t punctuation = random() % 128; | |
switch (punctuation) { | |
case 0: | |
case 1: | |
case 2: delimiter = ", "; break; | |
case 3: | |
case 4: delimiter = "; "; break; | |
case 6: delimiter = ": "; break; | |
case 7: delimiter = " - "; break; | |
default: break; | |
} | |
memcpy(s, delimiter, strlen(delimiter)); | |
s += strlen(delimiter); | |
} | |
} | |
if (sentences_in_paragraph > 1 && s < end) { | |
memcpy(s, ".\x20", 2); | |
s += 2; | |
} else { | |
*s++ = '.'; | |
} | |
sentences_in_paragraph--; | |
} | |
if (paragraphs > 1 && s < end) { | |
*s++ = '\n'; | |
} | |
paragraphs--; | |
} | |
*s = 0; | |
} | |
int main() { | |
static char text[64 * 1024]; | |
lorem_ipsum_generator_params_t p = { | |
.text = text, | |
.count = countof(text), | |
.min_paragraphs = 4, | |
.max_paragraphs = 15, | |
.min_sentences = 4, | |
.max_sentences = 20, | |
.min_words = 8, | |
.max_words = 16 | |
}; | |
srandom(time(NULL)); | |
lorem_ipsum_generator(p); | |
printf("%s\n", p.text); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment