emacs upgrade from its git repo

There is a full Emacs Git repository on the Emacs Savannah site. I had cloned a local copy to work with, but when I read the README and then tried to run configure, there was no configure script to run. I didn’t know why at the time so I deleted the local clone copy and instead downloaded a released source tarball and built from that. Before deleteing the clone copy I found out that that version was 30.0.50.

After building version 28.2 and then building a minimal init.el, I cloned the Git repo again with the intent to do a bit more reading. Sure enough, buried in the top level README text file was a single reference to the script autogen.sh. I ran that script and it in turn produced the necessary configure script.

The version of configure for this version of Emacs wanted makeinfo, which is a part of texinfo. Sure enough Linux Mint 21 needed to have texinfo installed, which in turn fullfilled the makeinfo build requirement and allowed configure to complete. Once completed I installed that emacs locally to my home directory and started to use it. No problems encountered so far, and my very modest init.el works identically in this latest version as it did in Emacs 28.2.

My biggest annoyance so far is cosmetic, and that’s with attempting to duplicate Vim’s PowerLine feature. I found several Emacs Lisp packages that attempt to replicate the look, but they don’t seem to want to work with my Emacs theme, doom-material-dark. So I’ve turned it off/removed it from my init.el file. I’ve started to re-learn Emacs Lisp again, with an eye towards either fixing one of the existing packages, or else trying to write something from scratch.

Otherwise I’m happy with how it works. There’s a slight irony in me selecting Emacs because of its small resource footprint compared to VSCode. I remember distinctly “back in the day” when Emacs was the heavy-duty application that sysadmins frowned upon, especially those with multi-user resource-constrained boxen running Unix or VMS. I knew  a guy by the name of Bob Talley (one of the three Bobs) who, in the mid-to-late 1980s ran a microVAX at his home, upon which he ran Emacs. This was a machine with two whole megabytes of RAM and a ridiculously small DEC hard drive. It was his personal system upon which he hosted Emacs, and according to him he lived inside of Emacs, although I don’t know what that means exactly. Bob took great pride in multi-month uptimes as well as having a local terminal constantly logged in. He could do that because he was the only user on the system. Leap ahead 35 years and I’m running the latest Emacs release on a personal computer running Linux Mint that cost a fraction of what that microVAX cost, with 16 GB of RAM, a 1 TB SSD, a 64-bit processor with four hyper-threading cores, the same shape and size of Apple’s Mac Mini, upon which Emacs is now considered a light-weight tool. So much computational power that was unaffordable back in the mid-1980s, but which is considered more than sufficient today. At least by me.

tinkering with c++ — replacing boost array with standard c++ array

Boost does more than provide a collection of advanced libraries for the C++ language. Many of Boost’s authors are also part of the C++ standards committee. Thus, many new features being considered for the C++ standard are implemented here first. One of those features that has now migrated into the official standard is boost::array, which as of C++11 is now std::array. The page for boost::array has the following line on its documentation front page:

Update: std::array is (as of C++11) part of the C++ standard. The differences between boost::array and std::array are minimal. If you are using C++11, you should consider using std::array instead of boost::array.

The following code shows some of the ways this container is used. If you change the #include <array> to <boost/array>, as well as the corresponding using statement, then it will compile and execute the same.

#include <array>#include <algorithm>#include <iostream>using std::array;using std::cout;using std::sort;using std::string;int main() {array<int, 10> iarray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};cout << "Array of integers:" << "\n";for (const auto value : iarray) {cout << "Integer array value: " << value << "\n";}cout << "\n" << "Array of standard strings:" << "\n";array<string, 10> sarray ={"one","two","three","four","five","six","seven","eight","nine","ten"};for (const auto value : sarray) {cout << "String array value: " << value << "\n";}cout << "\n" << "Array of sorted strings:" << "\n";sort(sarray.begin(), sarray.end());for (const auto value : sarray) {cout << "String array value: " << value << "\n";}return 0;}

Compiling It

Compilation is a simple one liner.

g++ -std=c++20 array-test.cpp -o array-test

Sample Run

Here’s what happens when we run it.

~ ./array-test Array of integers:Integer array value: 1Integer array value: 2Integer array value: 3Integer array value: 4Integer array value: 5Integer array value: 6Integer array value: 7Integer array value: 8Integer array value: 9Integer array value: 10Array of standard strings:String array value: oneString array value: twoString array value: threeString array value: fourString array value: fiveString array value: sixString array value: sevenString array value: eightString array value: nineString array value: tenArray of sorted strings:String array value: eightString array value: fiveString array value: fourString array value: nineString array value: oneString array value: sevenString array value: sixString array value: tenString array value: threeString array value: two

Comments

What makes std::array better than std::vector is that there is no need for extra code to support a dynamic container like vector. The container array is like the simpler C fixed array, in that it’s fixed and static, but has enough container traits that it can be used in a C++ ranged for loop (lines 15,23, and 29), as show in the example above.

Using std::array in an Embedded Application

I have been writing ESP32-S3 and ESP32-C3 C++ code. I’ve published the following code more than once, but this time, I just want to highlight how I replaced the C++ standard library vector and tuple type with array. Here is where std::array helps in dropping the size of the binary. I checked the size of the generated binary (everything else the same) and discovered that I save a bit of 10K of generated binary, meaning that I saved 10K by switching to array. What’s more the ability to access the elements of the inner array in line 44 makes a lot more sense than the older way of declaring the inner colors a tuple and the convoluted way I accessed tuple members the way I did.

#include <stdio.h>#include <array>#include "freertos/FreeRTOS.h"#include "freertos/task.h"#include "driver/gpio.h"#include "esp_log.h"#include "led_strip.h"#include "sdkconfig.h"using std::array;const array<array<int, 3>, 7> colors {{{32,0,0},  // red{0,32,0},  // green{0,0,32},  // blue{0,32,32}, // cyan{32,0,32}, // magenta{32,16,0}, // yellow{0,0,0}// black}};// Task 1.//static void task_blink_neo_pixel(void * pvParameters) {static led_strip_t *pStrip_a;pStrip_a = led_strip_init(CONFIG_BLINK_LED_RMT_CHANNEL, CONFIG_BLINK_GPIO, 1);pStrip_a->clear(pStrip_a, 50);// Stay in an endless loop. Don't return from this task.//while(true) {for(auto color : colors) {pStrip_a->set_pixel(pStrip_a, 0, color[0], color[1], color[2]);pStrip_a->refresh(pStrip_a, 100);vTaskDelay(500 / portTICK_PERIOD_MS);// Set NeoPixel LED dark by clearing all its individual LEDs.pStrip_a->clear(pStrip_a, 50);vTaskDelay(500 / portTICK_PERIOD_MS);}}}// Task 2.//static void task_blink_led(void * pvParameters) {gpio_reset_pin(GPIO_NUM_46);// Set the GPIO as a push/pull output//gpio_set_direction(GPIO_NUM_46, GPIO_MODE_OUTPUT);// Stay in an endless loop. Don't return from this task.//while (true) {gpio_set_level(GPIO_NUM_46, true);   // LED onvTaskDelay(100 / portTICK_PERIOD_MS);gpio_set_level(GPIO_NUM_46, false);  // LED offvTaskDelay(100 / portTICK_PERIOD_MS);gpio_set_level(GPIO_NUM_46, true);   // LED onvTaskDelay(100 / portTICK_PERIOD_MS);gpio_set_level(GPIO_NUM_46, false);  // LED offvTaskDelay(2700 / portTICK_PERIOD_MS);}}extern "C" void app_main(void) {static const char *TAG = "DUAL_BLINK";int core = xPortGetCoreID();ESP_LOGI(TAG, "app_main running on core %i", core);ESP_LOGI(TAG, "CONFIG_BLINK_GPIO %i", CONFIG_BLINK_GPIO);// Create task 1.//TaskHandle_t xHandle1 = NULL;static uint8_t ucParameterToPass1 = 1;xTaskCreate(task_blink_neo_pixel,"BlinkNeoPixel",// human readable task name.2048,   // stack size in bytes.&ucParameterToPass1,tskIDLE_PRIORITY,&xHandle1);configASSERT(xHandle1);// Create task 2.//TaskHandle_t xHandle2 = NULL;static uint8_t ucParameterToPass2 = 1;xTaskCreate(task_blink_led,"BlinkLED", // human-readable task name.2048,   // stack size in bytes.&ucParameterToPass2,tskIDLE_PRIORITY,&xHandle2);configASSERT(xHandle2);// Stay in an endless loop. Don't return from this task.//while (true) {vTaskDelay(1000 / portTICK_PERIOD_MS);}}