-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
500 lines (370 loc) · 56.9 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[Opening Open Source]]></title>
<link href="http://darthbeep.github.io/atom.xml" rel="self"/>
<link href="http://darthbeep.github.io/"/>
<updated>2019-08-21T21:08:22-04:00</updated>
<id>http://darthbeep.github.io/</id>
<author>
<name><![CDATA[Shaina Peters]]></name>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[solving git lfs issues -- for when your unity assets won't load]]></title>
<link href="http://darthbeep.github.io/blog/2019/08/11/solving-git-lfs-issues-for-when-your-unity-assets-wont-load/"/>
<updated>2019-08-11T21:35:17-04:00</updated>
<id>http://darthbeep.github.io/blog/2019/08/11/solving-git-lfs-issues-for-when-your-unity-assets-wont-load</id>
<content type="html"><![CDATA[<p>Unlike my usual posts on how something works, this post is a solution post. It presents a problem I recently had, and how I solved it. If you’re also interested in solving things, go ahead and read this, and maybe try to find a solution and compare your answers with mine. But the intended audience for this post is people who are trying to solve this problem.</p>
<p>I’ll start by describing the problem. I recently participated in a game jam with some friends. <a href="https://hwkeyser.itch.io/one-engine-left">Here</a> is our game, if you want to try it out. But on two computers, mine (Arch Linux), and a friend’s (oldish Mac), none of the assets would load. We were using Unity, with both our own custom asset files and TextMesh Pro assets, both of which failed to load.</p>
<p>So how did I solve this?</p>
<p>First I checked on the asset files themselves. At first I was worried they weren’t cloned correctly, and when I <code>cat</code>ed them I got this.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>cat Sunny<span class="se">\ </span>Days<span class="se">\ </span>-<span class="se">\ </span>Seamless.jpg
</span><span class='line'>version https://git-lfs.github.com/spec/v1
</span><span class='line'>oid sha256:ab6536daf74188dfc075d65f5d85aca9efeaead7f03b905514e53076d854f365
</span><span class='line'>size 273488
</span></code></pre></td></tr></table></div></figure>
<p>Well, that doesn’t look like what usually happens when you cat a jpg. Was it uploaded wrong? I went to the GitHub page for the file to check. But the image on GitHub looked normal. Well, with one added detail.</p>
<p><img src="images/2019/08/bloglfs.png" alt="Stored with Git LFS" /></p>
<p><code>Stored with Git LFS</code>. Clicking on the question mark took me <a href="https://help.github.com/en/articles/versioning-large-files">here</a>. Essentially, Git LFS, or Git Large File Storage, is GitHub’s way of storing large files. Rather than put the files where they appear in the repository, it stores them elsewhere and puts a pointer file in their place. You can read more about it <a href="https://help.github.com/en/articles/about-git-large-file-storage">here</a>. But what does this have to do with solving the problem? Well now that we know the reason files look strange is because they are being hidden with Git LFS, we can use Git LFS to find them.</p>
<p>Unfortunately, Git LFS isn’t preinstalled, at least on some systems. Fortunately, it is at least on the AUR and homebrew. Weirdly enough, the package has to be downloaded manually on Debian/Ubuntu, but you can find the instructions for that <a href="https://github.com/git-lfs/git-lfs/wiki/Installation#debian-and-ubuntu">here</a>.</p>
<p>Once you’ve downloaded git-lfs, you need to install it. Just do it once with</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>git lfs install
</span></code></pre></td></tr></table></div></figure>
<p>Now Git LFS is installed! Any new repos you clone will clone large files properly automatically. Unfortunately, that doesn’t include current ones. Those require a bit of extra work. If you’re feeling lazy, you can just delete and reclone the repo. Otherwise, just type</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>git lfs fetch
</span><span class='line'><span class="nv">$ </span>git lfs pull
</span></code></pre></td></tr></table></div></figure>
<p>And you’re done! If you cat image files, you will be greeted with binary files and not plaintext. And now if you open up the project in unity, you will be able to use assets. Happy coding!</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Analyzing an Open Source Project: Part III -- If Statements]]></title>
<link href="http://darthbeep.github.io/blog/2019/07/24/analyzing-an-open-source-project-part-iii-if-statements/"/>
<updated>2019-07-24T15:49:35-04:00</updated>
<id>http://darthbeep.github.io/blog/2019/07/24/analyzing-an-open-source-project-part-iii-if-statements</id>
<content type="html"><![CDATA[<p>And here’s Part III of Analyzing an Open Source Project. <a href="http://darthbeep.github.io/blog/2019/07/02/analyzing-an-open-source-project-part-ii-reading-installation-script-arguments/">Last time</a> we started reading the install script of <a href="https://github.com/bulletmark/libinput-gestures">libinput-gestures</a> (<a href="https://github.com/bulletmark/libinput-gestures/blob/master/libinput-gestures-setup#L147">here’s</a> the file we’re looking at, click to read along), and we haven’t sped up since. The goal of this blog is not to read open source projects, but to look at everything. Every. Single. Thing! There are plenty of tangents but you won’t be missing out on a single detail. So without further ado.</p>
<p>Now that we’ve set our cmd variable to the entered command and done our variable parsing, it’s time to use our variables. While the next things to look at are functions that will be run later, we’re going in execution order, so now we’re going to skip to line 147 where the script really starts happening.</p>
<figure class='code'><figcaption><span>libinput-gestures-setup </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="k">if</span> <span class="o">[[</span> <span class="nv">$cmd</span> <span class="o">==</span> install <span class="o">||</span> <span class="nv">$cmd</span> <span class="o">==</span> uninstall <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></code></pre></td></tr></table></div></figure>
<p>Everything until the end is wrapped in this if statement and its corresponding else. This is a typical example of a bash if statement, and contains no surprises. It can be read with knowledge of any other programming language, or even English. Simply put, the if statement checks the truthfulness of what’s in the double brackets. Single brackets could also be used. While double brackets have less surprises and are more smoothed out, single brackets are a <a href="https://pubs.opengroup.org/onlinepubs/9699919799/">POSIX</a> standard and therefore more portable. Because double brackets are a bash extension, they do require the user to learn a little more, but most of that is intuitive or googleable. But if you code, you can generally choose which one you want to use.</p>
<p>The contents of the if statement are exactly what they seem. <code>$cmd == install</code> returns, well, if <code>$cmd</code> is equal to <code>install</code>. The reason <code>==</code> is used instead of <code>-eq</code> is because <code>-eq</code> is for numbers and <code>==</code> is for strings.</p>
<p>At first I wanted to say that <code>||</code> worked differently in bash based on the fact that is often used outside of scripts. It’s common to write <code>function || error</code>, where error will run if function returns an error (manifested by a non-zero value, in contrast to most programming languages, though this makes sense because many bash scripts use their number outputted as the error message). However, instead of working differently in and out of conditionals, <code>||</code> works exactly the same, though it is often used differently. It goes to the first value, sees if it’s true or not, and continues until something is true. It then returns if it is able to find a true statement or not.</p>
<p>Realizing that in bash <code>||</code> is more commonly used outside of conditionals than in them, I wondered if it were true in other languages. In perl, if a function might error, it’s common to write code similar to <code>function() or die</code>, where if the function fails the die command is run with an optional error message. But what about other languages, where <code>||</code> is usually confined to conditionals? Well, I opened up a python shell.</p>
<figure class='code'><figcaption><span>python shell </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="o">>>></span> <span class="mi">1</span> <span class="ow">and</span> <span class="s">"psyduck"</span>
</span><span class='line'><span class="s">'psyduck'</span>
</span><span class='line'><span class="o">>>></span> <span class="mi">0</span> <span class="ow">and</span> <span class="s">"penn"</span>
</span><span class='line'><span class="mi">0</span>
</span><span class='line'><span class="o">>>></span> <span class="mi">1</span> <span class="ow">or</span> <span class="s">"muack"</span>
</span><span class='line'><span class="mi">1</span>
</span><span class='line'><span class="o">>>></span> <span class="mi">0</span> <span class="ow">or</span> <span class="s">"blob"</span>
</span><span class='line'><span class="s">'blob'</span>
</span></code></pre></td></tr></table></div></figure>
<p>And C?</p>
<figure class='code'><figcaption><span>test.c </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="cp">#include <stdio.h></span>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="mi">1</span> <span class="o">&&</span> <span class="n">printf</span><span class="p">(</span><span class="s">"psyduck "</span><span class="p">);</span>
</span><span class='line'> <span class="mi">0</span> <span class="o">&&</span> <span class="n">printf</span><span class="p">(</span><span class="s">"penn "</span><span class="p">);</span>
</span><span class='line'> <span class="mi">1</span> <span class="o">||</span> <span class="n">printf</span><span class="p">(</span><span class="s">"muack "</span><span class="p">);</span>
</span><span class='line'> <span class="mi">0</span> <span class="o">||</span> <span class="n">printf</span><span class="p">(</span><span class="s">"blob</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">//prints "psyduck blob"</span>
</span><span class='line'>
</span><span class='line'> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>Note: Psyduck, Penn, Muack, and Blob are my stuffed platypodes. They are very cute.</p>
<p>It seems that instead of one line if statements, and or or operands with error messages could work as well. In fact, I may start using them to shorten my code. But back on topic. After the brackets are closed again, a semicolon stands in place for a newline, which is followed by a then, which says that everything after should be executed. Then is needed because if statements don’t need to be confined to just one set of brackets (and in fact can have any amount of brackets from 0 to infinity, with any number of things stringing them together). Now that the then is in place, we can finally analyze the if statement. Let’s look at it’s first line.</p>
<figure class='code'><figcaption><span>libinput-gestures-setup </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">DESTDIR</span><span class="o">=</span><span class="s2">"${DESTDIR%%+(/)}"</span>
</span></code></pre></td></tr></table></div></figure>
<p>Last time we determined that DESTDIR is by default <code>""</code> but can be set to any directory with the -d argument. We also covered substitution, which tells us that everything after the <code>%%</code> containing exactly <code>+(/)</code> is removed. Because this substitution is extremely specific and doesn’t contain a common case, I believe it is an artifact from testing.</p>
<p>Next we have another if statement.</p>
<figure class='code'><figcaption><span>libinput-gestures-setup </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="k">if</span> <span class="o">[[</span> -z <span class="nv">$DESTDIR</span> <span class="o">&&</span> <span class="k">$(</span>id -un<span class="k">)</span> !<span class="o">=</span> root <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span><span class='line'> <span class="nb">echo</span> <span class="s2">"Install or uninstall must be run as sudo/root."</span>
</span><span class='line'> <span class="nb">exit </span>1
</span><span class='line'><span class="k">fi</span>
</span></code></pre></td></tr></table></div></figure>
<p>I’m going to avoid repeating myself and not discuss anything previously discussed. For the if statement to trigger, two conditions must be met. First, <code>-z</code> checks if something is <code>null</code>, so <code>$DESTDIR</code> be an empty string. Second the output of <code>id -un</code> must not be equal to <code>root</code>. <code>id</code> is a function that gives information on users, with <code>-u</code> giving only information on the user running the command and <code>-n</code> giving the user’s name. So <code>id -un</code> will only output root if the user is running the script as root. Therefore, the if statement will only trigger if <code>$DESTDIR</code> is an empty string (in this case representing the root directory) and if the user is not <code>root</code>. Essentially checking if the user is trying to build the directory in a place they have access to. If the user doesn’t have access to the directory, the script will exit with an error.</p>
<p>However, this method of checking is not perfect. If the user tries to build in a non <code>root</code> directory they don’t have access to as non <code>root</code> (and this sentence is why you shouldn’t give a person and a place the same name), this error checker wont trigger.</p>
<p>One smarter thing would be to check if the user is not root and not the owner of the file (admittedly this leaves out groups and everyone-can-edit directories, but those are really edge cases). The command <code>stat</code> gives information on the file, and its <code>--format</code> argument allows it to display only certain things. When <code>--format</code> is set to <code>"%U"</code>, it only prints out the user. So put together.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="k">if</span> <span class="o">[[</span> <span class="k">$(</span>id -un<span class="k">)</span> !<span class="o">=</span> <span class="k">$(</span>stat --format<span class="o">=</span><span class="s2">"%U"</span> <span class="s2">"$DESTDIR/"</span><span class="k">)</span> <span class="o">&&</span> <span class="k">$(</span>id -un<span class="k">)</span> !<span class="o">=</span> root <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span><span class='line'> <span class="nb">echo</span> <span class="s2">"Install or uninstall must be run as sudo/root."</span>
</span><span class='line'> <span class="nb">exit </span>1
</span><span class='line'><span class="k">fi</span>
</span></code></pre></td></tr></table></div></figure>
<p>Because apparently six lines merit a whole entry, that’s all for today. But on the bright side, I actually wrote some code. And I got to plug my stuffed platypodes. Keep reading and you might get a picture. But that’s all for today.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Analyzing an Open Source Project: Part II -- Reading Installation Script Arguments]]></title>
<link href="http://darthbeep.github.io/blog/2019/07/02/analyzing-an-open-source-project-part-ii-reading-installation-script-arguments/"/>
<updated>2019-07-02T21:56:58-04:00</updated>
<id>http://darthbeep.github.io/blog/2019/07/02/analyzing-an-open-source-project-part-ii-reading-installation-script-arguments</id>
<content type="html"><![CDATA[<p>Here we begin Part II of Analyzing an Open Source Project. For Part I, which deals with setting up and looking at a makefile, <a href="http://darthbeep.github.io/blog/2019/06/22/how-do-linux-gestures-work-part-i-before-you-install/">click here</a>. The open source project I’m analyzing is <a href="https://github.com/bulletmark/libinput-gestures">libinput-gestures</a>, and this part begins looking at the setup script. <a href="https://github.com/bulletmark/libinput-gestures/blob/master/libinput-gestures-setup">Click here</a> for the code. To keep each article from getting too long, the setup script will require multiple articles. This part will focus on getting the program name and article parsing.</p>
<p>Some things start off with a bang, but libinput-gestures-setup starts off with a shebang. So we know that the script is meant to be run in bash, but what else do we know? Well, just like us, the script starts by trying to learn more about itself.</p>
<figure class='code'><figcaption><span>libinput-gestures-setup </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">PROG</span><span class="o">=</span><span class="s2">"$(basename $0)"</span>
</span><span class='line'><span class="nv">NAME</span><span class="o">=</span><span class="k">${</span><span class="nv">PROG</span><span class="p">%-*</span><span class="k">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>The argument <code>$0</code> is the name of the command or script that is run. For example, the <code>$0</code> for <code>ls -l</code> is <code>ls</code>. The command <code>basename</code> strips away both the path to the file and the file extensions. So if you were to call <code>libinput-gestures/libinput-gestures-setup</code> or even .<code>/libinput-gestures-setup</code>, it would take away the first part, making <code>$PROG</code> result in <code>libinput-gestures-setup</code>.</p>
<p>In bash, a <code>%</code> means to remove what comes after it from the suffix. And since what comes after it is <code>-*</code>, meaning the <code>-</code> and everything after it are removed, making <code>$NAME</code> become <code>libinput-gestures</code>. For some interesting and related facts, while <code>%</code> removes everything after the the last instance it finds, <code>%%</code> removes everything after the first instance. While <code>%</code> and <code>%%</code> deal with suffixes, their prefix equivalents are <code>#</code> and <code>##</code> (however, this time <code>##</code> looks for the last instance). And finally, it is an absolute pain to google the symbol <code>%</code>. Yes, even with quotes.</p>
<p>Great! Now we’ve gotten through two lines of code! Wasn’t that exciting? Well, now we’re going to skip around a bit. Don’t worry, well cover everything we missed. But first, let’s zoom out for a second. The setup script allows for two command line arguments, <code>-d</code> and <code>-r</code>. <code>-d</code> takes and argument, which is used to determine the destination where everything is installed. By default, it’s empty and causes everything to be installed in children of the root folder, but the script does give you the option to specify. You probably shouldn’t need to if you just plan on installing, but it’s good to have options. The <code>-r</code> argument force allows root to perform user commands, and is not recommended. For a more in depth look at these commands, keep reading my blog. Until then, let’s look at how arguments are actually parsed.</p>
<figure class='code'><figcaption><span>libinput-gestures-setup </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">DESTDIR</span><span class="o">=</span><span class="s2">""</span>
</span><span class='line'><span class="nv">FORCEROOT</span><span class="o">=</span>0
</span><span class='line'><span class="k">while</span> <span class="nb">getopts </span>d:r c<span class="p">;</span> <span class="k">do</span>
</span><span class='line'> <span class="k">case</span> <span class="nv">$c</span> in
</span><span class='line'> d<span class="o">)</span> <span class="nv">DESTDIR</span><span class="o">=</span><span class="s2">"$OPTARG"</span><span class="p">;;</span>
</span><span class='line'> r<span class="o">)</span> <span class="nv">FORCEROOT</span><span class="o">=</span>1<span class="p">;;</span>
</span><span class='line'> <span class="se">\?</span><span class="o">)</span> usage<span class="p">;;</span>
</span><span class='line'> <span class="k">esac</span>
</span><span class='line'><span class="k">done</span>
</span><span class='line'>
</span><span class='line'><span class="nb">shift</span> <span class="k">$((</span>OPTIND <span class="o">-</span> <span class="m">1</span><span class="k">))</span>
</span></code></pre></td></tr></table></div></figure>
<p>The first two lines are simple, they’re setting the defaults of variables that may or may not be overridden later. But the third is where things get interesting. Given that many bash functions take in arguments of the form <code>-a test -b</code>, there needs to be a builtin to parse them. And that’s what getopts is. It’s used in a while loop (or for each loop, whichever helps to visualize it better) to make sure that every option is parsed, as the loop will run for every option. Now let’s look at the first argument, <code>d:r</code>. The script’s two arguments, <code>-d</code> and <code>-r</code> are present, with <code>-d</code>, which takes an argument, on the left, and <code>-r</code>, which does not, on the right. The second getopts argument, <code>c</code>, will be filled with the argument the user uses. At the same time, if applicable, the builtin <code>$OPTARG</code> will be filled with the argument’s argument. For example, if the user types in the command <code>./libinput-gestures-setup -d place -r</code>, the first pass of the while loop will fill <code>$c</code> with <code>d</code> and <code>$OPTARG</code> with <code>test</code>, and on the second pass <code>$c</code> will fill with <code>r</code>.</p>
<p>Now that we know <code>$c</code> is being filled in with something, the question is what we can do about that. And the answer is a case statement. Interestingly enough, the case command’s man page calls it obsolete and says it should be replaced by switch statements. Though case statements seem far more popular online. In this particular case, the programmer probably doesn’t need to switch, but it’s something to keep in mind.</p>
<p>Once you get past the confusing getopts syntax, case statements are fairly readable. The syntax checks what <code>$c</code> is against <code>d</code>, and if so sets <code>$DESTDIR</code> to <code>$OPTARG</code>, which holds <code>-d</code>’s argument. All case statements are terminated with two semicolons. Similar is the case for <code>r</code>. If an illegal option is called, the case <code>\?</code> will trigger. This calls the function <code>usage</code>, which outputs the script’s usage as text and then quits with an error. After the case is chosen, the case statement will end with <code>esac</code>.</p>
<p>Why <code>esac</code>? To slightly paraphrase <a href="https://unix.stackexchange.com/a/256175">this answer</a>, the <code>case</code>/<code>esac</code> convention, as well as if statements ending in fi, comes from ALGOL68. Both the original <code>sh</code> shell and ALGOL68 have, the same author, Stephen Borne. One of the influences <code>sh</code> took from ALGOL68 are the <code>case</code>/<code>esac</code> and <code>if</code>/<code>fi</code> openings and closings. ALGOL68 also has <code>do</code>/<code>od</code> as a pair, but <code>od</code> is already a keyword in bash (octal dump), so that was scrapped in favor of <code>done</code>.</p>
<p>This leaves us with one final line of code, <code>shift $((OPTIND - 1))</code>. Of the statement above, this part is the most enigmatic. If you google around to understand getopts, you’ll find that this part is usually ignored. You don’t achieve anything by modifying it, and it’s something you put at the end no matter what. So, what does this command actually do, and how does it work?</p>
<p>Starting from the beginning, the variable <code>$OPTIND</code>, short for option index, is part of the <code>getopts</code> utility. When <code>getopts</code> runs through the command line argument, like a for each loop, it needs something to look at next. At all times, the next argument for <code>getopts</code> is stored in <code>$OPTIND</code>. How does this work so easily? <code>$OPTIND</code> isn’t actually storage, but a number. Remember, <code>$1</code> in bash will get you the first argument, <code>$2</code> the second, and so on. So <code>$OPTIND</code> starts at 1 and is incremented with each pass. If you run the program with 3 arguments, <code>$OPTIND</code> will end as 4.</p>
<p>In bash, double parentheses evaluate an expression, and a $ in front of them returns the result as a statement. So shift is being called on the result of <code>$OPTIND - 1</code>. <code>shift</code> is a command which shifts the position of arguments to the left by the number given to it as argument. That is, if you run <code>shift 2</code>, the variable that used to be referenced with <code>$4</code> can now be referenced with <code>$2.</code> Because <code>$OPTIND</code> is always one more than the number of optional arguments, shifting by <code>$OPTIND - 1</code> will make the main arguments always be in the same place. So for example calling <code>./libinput-gestures-setup -d place install</code> and <code>./libinput-gestures-setup install</code> will both lead to <code>install</code> being <code>$1</code> after the shift happens.</p>
<p>The next function is fairly simple.</p>
<figure class='code'><figcaption><span>libinput-gestures-setup </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="k">if</span> <span class="o">[[</span> <span class="nv">$# </span>-ne <span class="m">1</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span><span class='line'> usage
</span><span class='line'><span class="k">fi</span>
</span></code></pre></td></tr></table></div></figure>
<p>The program wants you to input only one main command, in this case <code>start</code>, <code>stop</code>, <code>restart</code>, <code>autostart</code>, <code>autostop</code>, or <code>status</code>. If you give it a number of commands that is not one, it will display the usage. The program checks if you are giving it only one argument (after the shift), with <code>[[ $# -ne 1 ]]</code>. Double square brackets surround a statement. <code>-ne</code> compares two numbers to see if they are not equal, in this case <code>$#</code> or the number of arguments, and 1. So if the number of arguments is not equal to one, the <code>usage</code> function is triggered. Otherwise, you can proceed on to</p>
<figure class='code'><figcaption><span>libinput-gestures-setup </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">cmd</span><span class="o">=</span><span class="s2">"$1"</span>
</span></code></pre></td></tr></table></div></figure>
<p>Whatever the main command is, it’s stored in the argument <code>$1</code>. So now the script knows what you’re trying to do, and sets it as the <code>$cmd</code> variable.</p>
<p>That’s all for this entry, but keep reading to find out what’s next. Check out this blog <a href="http://darthbeep.github.io/blog/2019/07/24/analyzing-an-open-source-project-part-iii-if-statements/">next time</a> for more exciting code. In either way you interpret that sentence.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[How I Linked My 3DS As My Controller On Linux]]></title>
<link href="http://darthbeep.github.io/blog/2019/06/30/how-i-linked-my-3ds-as-my-controller-on-linux/"/>
<updated>2019-06-30T19:45:46-04:00</updated>
<id>http://darthbeep.github.io/blog/2019/06/30/how-i-linked-my-3ds-as-my-controller-on-linux</id>
<content type="html"><![CDATA[<p>Early one morning my friend Jake texted me about playing Stardew Valley that night. I immidietly agreed, but was soon faced with a problem: my desk was currently full, leaving me unable to use my mouse. I don’t usually work at my desk or use my mouse, as I favor the trackpad, but Stardew Valley is very hard to play without one. So I looked at my options. Finding a place to use a mouse was sub optimal, as was using the trackpad, but there was one thing I could do: using a controller. Which led to one more problem: the only controller I actually had was a 3DS. Well, not to worry, right? I’d used the 3DS as a console to play Smash before, and I’d heard rumors about the 3DS as a controller on Linux. So, I imminently got to work, setting up my 3DS as a controller for my computer.</p>
<p>A few software notes: My <a href="https://3ds.hacks.guide/">3DS is homebrewed</a>. A quick glance at the source code suggested that homebrew isn’t necessary, but I can’t comment if it is. I originally did all of this on my computer, which runs Arch, but when writing this shortly after the fact, I tested it on Debian, both to ensure that I wasn’t forgetting anything and to make sure this guide wasn’t Arch only.</p>
<p>After a bit of googling, I decided on <a href="https://github.com/phijor/ctroller">this repository</a>, called ctroller. There was one other, but this had the prettiest readme. One thing to keep in mind about the repository is that it has two parts. One for the Linux side, which has a server that interprets data sent from the 3DS into a device on the system, and the 3DS side, which builds a 3DS application the 3DS uses to send the data. Well, now that I had a repo, it was time to build all the things.</p>
<p>First, on to the Linux side of things. The repository tells you to install the AUR package <code>ctroller-git</code>, which couldn’t be installed, or <code>ctroller-bin</code>, which could. Then I just typed in <code>make install</code> and it worked perfectly. That was easy. Going off of this it should be smooth sailing for the rest of the setup, right?</p>
<p>The next step is to get the 3DS files on your 3DS. You can either download them or make them yourself. Personally, I only use locally-sourced, grass-fed, vaccine-free binaries. So obviously I was going to build them myself. So I followed the instructions and went into the 3DS folder.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>make release
</span><span class='line'>Makefile:6: *** <span class="s2">"Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM"</span>. Stop.
</span></code></pre></td></tr></table></div></figure>
<p>Alright, let’s go up to the part in the repository where it tells us about DevkitARM. Wait– why doesn’t this link have any file?</p>
<p>So a bit of googling got me <a href="https://devkitpro.org/wiki/devkitPro_pacman">here</a>. And because entering random commands is what I do to keep life exciting, I entered the following into my computer (the page contains information for multiple operating systems, but I followed the instructions for Arch). For a more in depth explanation of what happened, follow the link. The next 3 code blocks are for Arch, but I’ll get to other distributions in a second.</p>
<figure class='code'><figcaption><span>Arch instructions </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ DEVKITPRO</span><span class="o">=</span>/opt/devkitpro
</span><span class='line'><span class="nv">$ DEVKITARM</span><span class="o">=</span>/opt/devkitpro/devkitARM
</span><span class='line'><span class="nv">$ DEVKITPPC</span><span class="o">=</span>/opt/devkitpro/devkitPPC
</span><span class='line'><span class="nv">$ </span>sudo pacman-key --recv F7FD5492264BB9D0
</span><span class='line'><span class="nv">$ </span>sudo pacman-key --lsign F7FD5492264BB9D0sudo pacman -U https://downloads.devkitpro.org/devkitpro-<span class="nv">$ </span>keyring-r1.787e015-2-any.pkg.tar.xz
</span></code></pre></td></tr></table></div></figure>
<p>Then I added these lines to /etc/pacman.conf</p>
<figure class='code'><figcaption><span>/etc/pacman.conf </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="o">[</span>dkp-libs<span class="o">]</span>
</span><span class='line'><span class="nv">Server</span> <span class="o">=</span> https://downloads.devkitpro.org/packages
</span><span class='line'><span class="o">[</span>dkp-linux<span class="o">]</span>
</span><span class='line'><span class="nv">Server</span> <span class="o">=</span> https://downloads.devkitpro.org/packages/linux
</span></code></pre></td></tr></table></div></figure>
<p>Followed by the commands</p>
<figure class='code'><figcaption><span>Arch instructions </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>sudo pacman -Syu
</span><span class='line'><span class="nv">$ </span>sudo pacman -S 3ds-dev
</span></code></pre></td></tr></table></div></figure>
<p>Because this blog was written slightly after the fact, and to ensure accuracy was tested again on a Debian VM. Distributions based on neither Debian nor Arch should probably follow the instructions on linked page, but will look a lot like this. The first part downloads a .deb binary I found <a href="https://github.com/devkitPro/pacman/releases/tag/devkitpro-pacman-1.0.1">here</a>, but you can find instructions for other distributions <a href="https://devkitpro.org/wiki/devkitPro_pacman">on the main page</a>.</p>
<figure class='code'><figcaption><span>Debian instructions </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>wget https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman.deb
</span><span class='line'><span class="nv">$ </span>sudo dpkg -i devkitpro-pacman.deb
</span><span class='line'><span class="nv">$ </span>sudo dkp-pacman -Syu
</span><span class='line'><span class="nv">$ </span>sudo dkp-pacman -S 3ds-dev
</span></code></pre></td></tr></table></div></figure>
<p>No matter which path you choose, you’ll need to enter the following afterwards.</p>
<figure class='code'><figcaption><span>Any distribution </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span><span class="nb">export </span><span class="nv">DEVKITPRO</span><span class="o">=</span>/opt/devkitpro
</span><span class='line'><span class="nv">$ </span><span class="nb">export </span><span class="nv">DEVKITARM</span><span class="o">=</span>/opt/devkitpro/devkitARM
</span></code></pre></td></tr></table></div></figure>
<p>Alright, we got one thing working. Now let’s run make release again. And… seems like we’re missing bannertool. Fortunately, this is one problem the AUR can fix. Less fortunately, it seems like for any other operating system, we’re dealing with <a href="https://github.com/Steveice10/bannertool">a repository</a> with a vague makefile and no readme. Usually a makefile gives some clue as to how to run it, and this makefile certainly gave a clue: it got its pattern from a file in a subfolder.</p>
<p>The only problem? That subfolder was the submodule for <a href="https://github.com/Steveice10/bannertool">a different Github repository</a>. The submodule didn’t copy over when cloning, but fortunately you can able to manually fix it by deleting the buildtools folder and cloning the linked buildtools repo instead. Now I just had to type make, and at least I got an executable out of it, even if it was hidden in the <code>output/linux-x86_64/</code> folder. Here’s the executed code, for reference.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>git clone https://github.com/Steveice10/bannertool
</span><span class='line'><span class="nv">$ </span><span class="nb">cd </span>bannertool/
</span><span class='line'><span class="nv">$ </span>rm -rf buildtools/
</span><span class='line'><span class="nv">$ </span>git clone https://github.com/Steveice10/buildtools
</span><span class='line'><span class="nv">$ </span>make
</span><span class='line'><span class="nv">$ </span>ls -F output/linux-x86_64/ <span class="c"># -F will give executables a *, among other things</span>
</span><span class='line'>bannertool*
</span></code></pre></td></tr></table></div></figure>
<p>So we’ve got an executable. What to do with it? Well, nothing yet. My gift of foresight tells me that the executable will have a twin before we’re done. And where do we find this twin? Well, the original repository says to have both <code>bannertool</code> and <code>makerom</code> in your <code>$PATH</code>. And we already have an executable for bannertool, so now we need one for makerom. Following the link for the repository, we end up <a href="https://github.com/profi200/Project_CTR/tree/master/makerom">here</a>.</p>
<p>Anyone who clicks links before reading ahead will notice two things: first, that we aren’t even in the head of a repository. We’re in a subfolder of a repository with an entirely different goal. And second, the readme only links to a site which definitely does not contain installation information. We’re back to running unidentified makefiles. At least this one gives less of a fight, all you have to do is clone the parent repository, <code>cd</code> into the <code>makerom</code> folder, and type <code>make</code>. And thus an executable is born. Reference code below.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>git clone https://github.com/profi200/Project_CTR
</span><span class='line'><span class="nv">$ </span><span class="nb">cd </span>makerom/
</span><span class='line'><span class="nv">$ </span>make
</span><span class='line'><span class="nv">$ </span>ls -F makerom <span class="c"># -F will give executables a *, among other things</span>
</span><span class='line'>makerom*
</span></code></pre></td></tr></table></div></figure>
<p>So now we have the two executables we need. Now we just need to put them in our $PATH. There are probably a lot of ways to do this, but keep in mind when I had to get this done, I was doing it after a fair amount of figuring things out. I was tired. So this is what I did.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>mkdir path
</span><span class='line'><span class="nv">$ </span>cp bannertool/output/linux-x86_64/bannertool path
</span><span class='line'><span class="nv">$ </span>cp Project_CTR/makerom/makerom path
</span><span class='line'><span class="nv">$ </span><span class="nb">cd </span>path/
</span><span class='line'><span class="nv">$ </span><span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="s2">"$PATH:$(pwd)"</span>
</span></code></pre></td></tr></table></div></figure>
<p>Yeah.</p>
<p>For those of you who can’t or don’t want to read what I just did, I essentially made a new folder, added the two gained executables to it, and then added it to my <code>$PATH</code> variable. This is probably not advised, but in my defense, it worked.</p>
<p>Now, if we run make release again in the 3DS folder, it works. The 3DS files are generated. We can rest. Almost.</p>
<p>Now, all you have to do is plug in your SD card into your computer. There is an upload script mentioned by the repository, but I didn’t test it. Once the SD is in the computer, you need to create a directory called <code>ctroller</code> in your sd card’s root directory, and then you should put <code>ctroller.cfg</code> in it. <code>ctroller.cfg</code> should contain your computer’s IP address instead of the default. You can find your ip address many ways, but it will be listed under <code>$ ip addr</code>. You should also put <code>ctroller.cia</code> on the SD if your 3DS is homebrewed, and <code>ctroller.3dsx</code> if it isn’t (or install the actual program however you usually transfer programs onto your 3DS).</p>
<p>Now, the hard part is over. Before you run the server on Linux, you need to run <code>$ modprobe uinput</code>, and to run it you need to run the actual executable <code>ctroller</code> file, probably with <code>$ ./linux/ctroller</code>. Now that you have the server running on your computer, convert the cia to a program or install it like any other program and run it. Then make sure your computer and 3DS are on the same network. You’re done! You can now use the 3DS as a controller for your computer!</p>
<p>To review the controller, it normally works just fine. However, it does go through periods of lag, where commands pause for a little while and then execute all at once. I would not recommended using the controller for a game with any stakes, but it works fine for Stardew Valley. Except when your internet goes down for a minute (hi Spectrum). But it’s worth it to say you’re gaming with a 3DS as a controller.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Analyzing an Open Source Project: Part I -- Before You Install]]></title>
<link href="http://darthbeep.github.io/blog/2019/06/22/how-do-linux-gestures-work-part-i-before-you-install/"/>
<updated>2019-06-22T23:52:26-04:00</updated>
<id>http://darthbeep.github.io/blog/2019/06/22/how-do-linux-gestures-work-part-i-before-you-install</id>
<content type="html"><![CDATA[<p>I’m probably one of the only Linux users who really likes gestures. Going back a web page and switching desktops with a swipe of my fingers is really easy and convenient. But when I switched to Linux, I found the support ridiculously lacking. It took a week of searching and trial and error to finally figure out how to implement gestures, at which point I stumbled upon <a href="https://github.com/bulletmark/libinput-gestures" title="libinput-gestures">libinput gestures</a>, which finally did solve my problem. Now that I have a solution (and a fair amount of time has passed) I want to work on a project: documenting open source. But not just going over the functions, but going extremely in depth and looking at EVERYTHING that happens.</p>
<p>This guide won’t just show off what happens to make gestures work, but will talk about everything along the way. While the actual code is written in python, this part will only focus on bash and make. Essentially, the things you have to run yourself to get libinput-gestures working. For an in depth analysis of the code, look for later parts. Because this code is based on the libinput-gestures code, you should familiarize yourself with the README and Makefile before or during your reading. Now let’s get started.</p>
<p>No matter where you go to do your gestures, you’ll encounter the same command before you start:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>sudo gpasswd -a <span class="nv">$USER</span> input
</span></code></pre></td></tr></table></div></figure>
<p>To understand this command, first you need to understand groups. Though they are commonly come across, they don’t get much attention. If you <code>chmod</code> a file to 764, you’re saying that the group is given permissions associated with 6 (reading and writing). The middle 3 characters when you use <code>$ ls -l</code> say the permissions the file’s group has when modifying it. Every file has not just a user who can access it, but a group. While said group is often just the user, that’s not always the case. In this case, we’re dealing with a series of files that can only be accessed by the group input.</p>
<p>The command gpasswd is used when administrating groups. The argument <code>-a</code> adds a user to a group. So <code>$ gpasswd -a $USER input</code> adds <code>$USER</code> (which is your username) to the group input. This is important because the group input has access to the files <code>/dev/input/event*</code> (as well as <code>/dev/input/mouse*</code>, though this is less important for gestures). So what is the point of this?</p>
<p>You may have heard the saying “In Linux, everything is a file.” Well, that includes input devices. And if you’re going to treat physical files like devices, you need to include that actual files for the devices. These are said files. These files, whose type is character files, are essentially pipes between physical inputs and what the computer receives. Although they are simply labeled event followed by a number, running the command <code>$ xinput list</code> will tell you exactly which event pipe corresponds with which device. In this particular case, the only file necessary is the one for the trackpad. Exactly how the code interacts with the device will be discussed in a later entry.</p>
<p>Now that you’re allowing the user access to the input devices, you can actually install libinput gestures. Here we shift from looking at bash setup commands to looking at the makefile itself, and what it contains.</p>
<p>Immediately running <code>$ make install</code> is the easiest way to set up gestures, but that is neither the only way to set up functions nor the only way to use the makefile. Starting with the latter, the makefile includes <code>make all</code>, which tells you to run <code>make install</code> or <code>make uninstall</code>, which run the install script that will be covered next entry, and <code>make clean</code>, which cleans. The makefile also includes two more slightly more interesting rules, which I’m going to discuss in detail because their code is interesting. The first, <code>make doc</code>, is as follows (including all of the relevant code but leaving out everything else):</p>
<figure class='code'><figcaption><span>Makefile </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='make'><span class='line'><span class="nv">DOC</span> <span class="o">=</span> README.md
</span><span class='line'><span class="nv">DOCOUT</span> <span class="o">=</span> <span class="k">$(</span>DOC:.md<span class="o">=</span>.html<span class="k">)</span>
</span><span class='line'>
</span><span class='line'><span class="nf">doc</span><span class="o">:</span> <span class="k">$(</span><span class="nv">DOCOUT</span><span class="k">)</span>
</span><span class='line'>
</span><span class='line'><span class="nf">$(DOCOUT)</span><span class="o">:</span> <span class="k">$(</span><span class="nv">DOC</span><span class="k">)</span>
</span><span class='line'> markdown <span class="nv">$<</span> ><span class="nv">$@</span>
</span></code></pre></td></tr></table></div></figure>
<p>The interesting part of this command comes not from the content, but the presentation. But what it actually does is fairly simple. The command markdown converts a text file to html. The make variable <code>$<</code> gives the name of the first prerequisite, in this case <code>$(DOC)</code>, which is defined earlier as <code>README.md</code>. The second variable, <code>>$@</code>, is a little more complex. Any variable prefixed with <code>></code> means that if it involves a file, that file will be overridden, rather than appended to. And <code>$@</code> takes in the target of the rule, in this case <code>$(DOCOUT)</code>. <code>$(DOCOUT)</code> takes in <code>$(DOC)</code> (still <code>README.md</code>) and performs a substitution reference on it, substituting .md for .html. So essentially <code>$(DOCOUT)</code> is equivalent to <code>README.html</code>. Put together, all of this means convert to markdown README.md, outputting with override to the file <code>README.html</code>. Or, in simplest terms, converting the README from markdown to html.</p>
<p>The second rule, <code>make check</code> is less stylish or hard to read, but it’s no less interesting. Instead, its uniqueness comes from its content. The rule is as follows:</p>
<figure class='code'><figcaption><span>Makefile </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='make'><span class='line'><span class="nv">SHELLCHECK_OPTS</span> <span class="o">=</span> -eSC2053,SC2064,SC2086,SC1117,SC2162,SC2181,SC2034,SC1090,SC2115
</span><span class='line'>
</span><span class='line'><span class="nf">check</span><span class="o">:</span>
</span><span class='line'> flake8 libinput-gestures
</span><span class='line'> shellcheck <span class="k">$(</span>SHELLCHECK_OPTS<span class="k">)</span> libinput-gestures-setup list-version-hashes
</span></code></pre></td></tr></table></div></figure>
<p>This is pretty standard make. The interesting part comes with the make code. The first line just does exactly what it says, running the command <code>$ flake8 libinput-gestures</code>. <code>flake8</code> is a command that tests for proper conventions in python code. This check fails, as line 533 is longer than 80 characters. I don’t know why the developers included a check if they don’t intend to use it themselves, but if anyone is looking for an easy pull request, they can have one. The second line is similar in that it checks shell scripts for errors and bad code, though it differs in that the code passes the check. It also includes an argument <code>-e</code> which tells it to exclude the errors corresponding to the codes listed after it. In short, the allowed forms of bad code are redundant logic, double double quotation marks, not double quoting expanding variables, using <code>\n</code> rather than <code>\\n</code>, using read without <code>-r</code>, running then checking exit status in two steps, unused variables, not using a directive to specify the location of a source file with a variable location, and not checking to make sure a path variable isn’t empty. The conclusion that can be drawn from this is shellcheck has a lot of different types of errors. I’m not sure if this is intentional or laziness, though there are a lot of fixable errors if shellcheck is run to allow these errors (though some do seem justified in the code).</p>
<p>So which shellcheck errors are justified? And what happens after you actually type make install? How does libinput gestures actually work? Find out <a href="http://darthbeep.github.io/blog/2019/06/30/how-i-linked-my-3ds-as-my-controller-on-linux/">next time</a> on my blog.</p>
]]></content>
</entry>
</feed>