commit b68ca27ff61cc5435fcee75786464e5a6d2242f7
parent 28c6b9090727cc7e9eda7c6a7d8cefdfc02ef6ce
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Sun, 12 Jun 2022 18:57:21 +0200
Added blog post
Diffstat:
3 files changed, 133 insertions(+), 0 deletions(-)
diff --git a/src/blog/2022-06-12-shell-ide-sed/shell-ide-sed.md b/src/blog/2022-06-12-shell-ide-sed/shell-ide-sed.md
@@ -0,0 +1,125 @@
+# The UNIX shell as an IDE: lookup stuff sed
+
+Recently I have been working on [nissy](https://nissy.tronto.net), my
+Rubik's cube solver written in C. It is a faily large project for me,
+consisting of multiple files for a total of ~8k lines.
+
+Something that I need to do quite often is quickly checking a structure's
+or a function's definition. Using a simple text editor without
+any plugin, my workflow for this at the moment is the following:
+
+* Open a new terminal in the project's directory (one key-binding in
+ my terminal's configuration)
+* Open the correct file with `vi src/file.c` (this can be tricky,
+ because I don't always remember in which file the object I am looking
+ for is defined)
+* Search with `/`
+
+This is not too bad, but I can do better using a short sed script!
+
+## Coding style
+
+I write my functions like this:
+
+```
+static int
+do_thing(int var)
+{
+ function body...
+}
+```
+
+The important part is that the function's name is at the start of the line.
+In this way when I search for the function's definition I can type
+`/^do_thing`. Here `^` stands for the beginning of the line, and it
+is fairly standard across UNIX tools (sed, grep, ed...), so all other
+uses of the funciton in the same file are ignored.
+The other important thing is that the closing `}` is also at the beginning
+of the line, but everyone in their right mind does that (I hope).
+
+## The sed command
+
+If you are like me, 99% of the time you use sed it is to replace some text
+with something like `sed 's/old text/new text/g`.
+But this classic program can actually do more: it parses the input line by
+line, applies a series of commands to each line that matches the given
+address, and then prints the result. For example
+
+```
+$ sed '5,10 p' file.c
+```
+
+prints (`p`) the lines from 5 to 10 of `file.c`. Well, kind of: it prints
+the whole file, but the lines from 5 to 10 are duplicated. This is because the
+default behavior, applied to every line, is to do nothing and print the
+(unmodified) input. We can change this behavior with the `-n` option:
+
+```
+$ sed -n '5,10 p' file.c
+```
+
+To print our `do_thing` function, we can find its address in the file using
+the `/` search. The following command:
+
+```
+$ sed -n '/^do_/,/^}/ p' file.c
+```
+
+prints all the lines between one that starts with `/^do_/` and the first
+one after that that starts with `}`. If you have another function called
+`do_other_thing`, it will print that one too.
+
+## Turning it into a script
+
+Of course typing all of this every time we want to check out a function from
+our file is too complicated. So we want to turn this into a script that we
+can easily call.
+We will call it `cth`, for "see thing', where the `c` also reminds us
+that it is based on C's syntax.
+
+We may start with something like this:
+
+```
+#!/bin/sh
+
+sed -n "/^$1/,/^}/ p"
+```
+
+Using double quotes instead of single quotes is necessary to have the `$1`
+expand to the first argument. After saving our script to `cth` and making
+it executable with `chmod +x cth`, we can call it with
+
+```
+$ ./cth do_ < file.c
+```
+
+We have to use `<` to redirect the standard input, because our script does
+not read any other argument that could be interpreted as a file name.
+To do this, we can do:
+
+
+```
+#!/bin/sh
+
+name=$1
+shift
+sed -n "/^$name/,/^}/ p" $@
+```
+
+This will save the first argument to a variable called `name`, "shift" the
+list of arguments and pass every remaining argument to sed with `$@`. In this
+way we can pass any number of file names. For example if we know our file
+is in the `src` directory, but we do not remember what its name is, we can
+[glob](https://en.wikipedia.org/wiki/Glob_(programming)) it with:
+
+```
+$ cth do_ src/*
+```
+
+And it works! You can now find
+[this script](https://git.tronto.net/scripts/file/cth%2Ehtml)
+among my other [scripts](https://git.tronto.net/scripts).
+
+*Remark: in bash one can simply do `sed -n "/^$1/,/^}/ p" ${@:2}` to match
+every argument from the second to the last, but this does not work in other
+shells such as ksh.*
diff --git a/src/blog/blog.md b/src/blog/blog.md
@@ -2,6 +2,7 @@
[RSS Feed](feed.xml)
+* 2022-06-12 [The UNIX shell as an IDE: lookup stuff sed](2022-06-12-shell-ide-sed)
* 2022-06-08 [The man page reading club: more(1)](2022-06-08-more)
* 2022-06-04 [The gemini protocol](2022-06-04-gemini)
* 2022-05-29 [The man page reading club: man(1)](2022-05-29-man)
diff --git a/src/blog/feed.xml b/src/blog/feed.xml
@@ -9,6 +9,13 @@ Thoughts about software, computers and whatever I feel like sharing
</description>
<item>
+<title>The UNIX shell as an IDE: lookup stuff sed</title>
+<link>https://sebastiano.tronto.net/blog/2022-06-12-shell-ide-sed</link>
+<description>The UNIX shell as an IDE: lookup stuff sed</description>
+<pubDate>2022-06-12</pubDate>
+</item>
+
+<item>
<title>The man page reading club: more(1)</title>
<link>https://sebastiano.tronto.net/blog/2022-06-08-more</link>
<description>The man page reading club: more(1)</description>