aboutsummaryrefslogtreecommitdiff
path: root/examples/redis-unstable/src/lolwut.c
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2026-01-21 22:40:55 +0100
committerMitja Felicijan <mitja.felicijan@gmail.com>2026-01-21 22:40:55 +0100
commit5d8dfe892a2ea89f706ee140c3bdcfd89fe03fda (patch)
tree1acdfa5220cd13b7be43a2a01368e80d306473ca /examples/redis-unstable/src/lolwut.c
parentc7ab12bba64d9c20ccd79b132dac475f7bc3923e (diff)
downloadcrep-5d8dfe892a2ea89f706ee140c3bdcfd89fe03fda.tar.gz
Add Redis source code for testing
Diffstat (limited to 'examples/redis-unstable/src/lolwut.c')
-rw-r--r--examples/redis-unstable/src/lolwut.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/examples/redis-unstable/src/lolwut.c b/examples/redis-unstable/src/lolwut.c
new file mode 100644
index 0000000..8467c78
--- /dev/null
+++ b/examples/redis-unstable/src/lolwut.c
@@ -0,0 +1,172 @@
1/*
2 * Copyright (c) 2018-Present, Redis Ltd.
3 * All rights reserved.
4 *
5 * Licensed under your choice of (a) the Redis Source Available License 2.0
6 * (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the
7 * GNU Affero General Public License v3 (AGPLv3).
8 *
9 * ----------------------------------------------------------------------------
10 *
11 * This file implements the LOLWUT command. The command should do something
12 * fun and interesting, and should be replaced by a new implementation at
13 * each new version of Redis.
14 */
15
16#include "server.h"
17#include "lolwut.h"
18#include <math.h>
19
20void lolwut5Command(client *c);
21void lolwut6Command(client *c);
22void lolwut8Command(client *c);
23
24/* The default target for LOLWUT if no matching version was found.
25 * This is what unstable versions of Redis will display. */
26void lolwutUnstableCommand(client *c) {
27 sds rendered = sdsnew("Redis ver. ");
28 rendered = sdscat(rendered,REDIS_VERSION);
29 rendered = sdscatlen(rendered,"\n",1);
30 addReplyVerbatim(c,rendered,sdslen(rendered),"txt");
31 sdsfree(rendered);
32}
33
34/* LOLWUT [VERSION <version>] [... version specific arguments ...] */
35void lolwutCommand(client *c) {
36 char *v = REDIS_VERSION;
37 char verstr[64];
38
39 if (c->argc >= 3 && !strcasecmp(c->argv[1]->ptr,"version")) {
40 long ver;
41 if (getLongFromObjectOrReply(c,c->argv[2],&ver,NULL) != C_OK) return;
42 snprintf(verstr,sizeof(verstr),"%u.0.0",(unsigned int)ver);
43 v = verstr;
44
45 /* Adjust argv/argc to filter the "VERSION ..." option, since the
46 * specific LOLWUT version implementations don't know about it
47 * and expect their arguments. */
48 c->argv += 2;
49 c->argc -= 2;
50 }
51
52 if ((v[0] == '5' && v[1] == '.' && v[2] != '9') ||
53 (v[0] == '4' && v[1] == '.' && v[2] == '9'))
54 lolwut5Command(c);
55 else if ((v[0] == '6' && v[1] == '.' && v[2] != '9') ||
56 (v[0] == '5' && v[1] == '.' && v[2] == '9'))
57 lolwut6Command(c);
58 else if ((v[0] == '8' && v[1] == '.' && v[2] != '9') ||
59 (v[0] == '7' && v[1] == '.' && v[2] == '9'))
60 lolwut8Command(c);
61 else
62 lolwutUnstableCommand(c);
63
64 /* Fix back argc/argv in case of VERSION argument. */
65 if (v == verstr) {
66 c->argv -= 2;
67 c->argc += 2;
68 }
69}
70
71/* ========================== LOLWUT Canvas ===============================
72 * Many LOLWUT versions will likely print some computer art to the screen.
73 * This is the case with LOLWUT 5 and LOLWUT 6, so here there is a generic
74 * canvas implementation that can be reused. */
75
76/* Allocate and return a new canvas of the specified size. */
77lwCanvas *lwCreateCanvas(int width, int height, int bgcolor) {
78 lwCanvas *canvas = zmalloc(sizeof(*canvas));
79 canvas->width = width;
80 canvas->height = height;
81 canvas->pixels = zmalloc((size_t)width*height);
82 memset(canvas->pixels,bgcolor,(size_t)width*height);
83 return canvas;
84}
85
86/* Free the canvas created by lwCreateCanvas(). */
87void lwFreeCanvas(lwCanvas *canvas) {
88 zfree(canvas->pixels);
89 zfree(canvas);
90}
91
92/* Set a pixel to the specified color. Color is 0 or 1, where zero means no
93 * dot will be displayed, and 1 means dot will be displayed.
94 * Coordinates are arranged so that left-top corner is 0,0. You can write
95 * out of the size of the canvas without issues. */
96void lwDrawPixel(lwCanvas *canvas, int x, int y, int color) {
97 if (x < 0 || x >= canvas->width ||
98 y < 0 || y >= canvas->height) return;
99 canvas->pixels[x+y*canvas->width] = color;
100}
101
102/* Return the value of the specified pixel on the canvas. */
103int lwGetPixel(lwCanvas *canvas, int x, int y) {
104 if (x < 0 || x >= canvas->width ||
105 y < 0 || y >= canvas->height) return 0;
106 return canvas->pixels[x+y*canvas->width];
107}
108
109/* Draw a line from x1,y1 to x2,y2 using the Bresenham algorithm. */
110void lwDrawLine(lwCanvas *canvas, int x1, int y1, int x2, int y2, int color) {
111 int dx = abs(x2-x1);
112 int dy = abs(y2-y1);
113 int sx = (x1 < x2) ? 1 : -1;
114 int sy = (y1 < y2) ? 1 : -1;
115 int err = dx-dy, e2;
116
117 while(1) {
118 lwDrawPixel(canvas,x1,y1,color);
119 if (x1 == x2 && y1 == y2) break;
120 e2 = err*2;
121 if (e2 > -dy) {
122 err -= dy;
123 x1 += sx;
124 }
125 if (e2 < dx) {
126 err += dx;
127 y1 += sy;
128 }
129 }
130}
131
132/* Draw a square centered at the specified x,y coordinates, with the specified
133 * rotation angle and size. In order to write a rotated square, we use the
134 * trivial fact that the parametric equation:
135 *
136 * x = sin(k)
137 * y = cos(k)
138 *
139 * Describes a circle for values going from 0 to 2*PI. So basically if we start
140 * at 45 degrees, that is k = PI/4, with the first point, and then we find
141 * the other three points incrementing K by PI/2 (90 degrees), we'll have the
142 * points of the square. In order to rotate the square, we just start with
143 * k = PI/4 + rotation_angle, and we are done.
144 *
145 * Of course the vanilla equations above will describe the square inside a
146 * circle of radius 1, so in order to draw larger squares we'll have to
147 * multiply the obtained coordinates, and then translate them. However this
148 * is much simpler than implementing the abstract concept of 2D shape and then
149 * performing the rotation/translation transformation, so for LOLWUT it's
150 * a good approach. */
151void lwDrawSquare(lwCanvas *canvas, int x, int y, float size, float angle, int color) {
152 int px[4], py[4];
153
154 /* Adjust the desired size according to the fact that the square inscribed
155 * into a circle of radius 1 has the side of length SQRT(2). This way
156 * size becomes a simple multiplication factor we can use with our
157 * coordinates to magnify them. */
158 size /= 1.4142135623;
159 size = round(size);
160
161 /* Compute the four points. */
162 float k = M_PI/4 + angle;
163 for (int j = 0; j < 4; j++) {
164 px[j] = round(sin(k) * size + x);
165 py[j] = round(cos(k) * size + y);
166 k += M_PI/2;
167 }
168
169 /* Draw the square. */
170 for (int j = 0; j < 4; j++)
171 lwDrawLine(canvas,px[j],py[j],px[(j+1)%4],py[(j+1)%4],color);
172}