The Boston Diaries' Journal
 
[Most Recent Entries] [Calendar View] [Friends]

Below are the 5 most recent journal entries recorded in The Boston Diaries' InsaneJournal:

    Tuesday, October 10th, 2023
    1:54 pm
    Mowing Da Lawn

    I've taken over mowing the lawn over the past few months, and I've learned a thing or two:

    1. The electric mower is much nicer than the gas mower. Both are self-propelled, but the speed control is nicer on the electric than the gas. Also, the electric mower is easier to start.
    2. One bad thing about the electric mowerthe grass accumulates inside, and when it gets too thick, the mower stops. I then have to tip it over and scoop out the cut grass. The gas mower does a much better job of mulching the grass.
    3. Also, the electric mower has a safety mechanism where two latches that lock down the handle length (it can slide in and out, shortening or lengthening the handle) must be in the locked position, or the cutting blade won't start (just learned this today). Interesting.
    4. Over the past few months, I've learned that I can finish the entire yard (front, sides and back) with the two batteries we have, but only if the lawn isn't terribly overgrown. And by overgrown I mean longer than two weeks (we've been having a lot of rain lately).
    5. Moving the cars out of the driveway makes mowing the front lawn easier, as I can just simple go back and forth, crossing the driveway. I wish I could do that for the entire lawn, but alas, there are some trees, a fence, and oh yes, the house, in the way.
    6. Chez Boca is on a & I don't want to say a hill, because get real, we're in Florida where we give Kansas a run for its money for Flattest State in America. But there is an incline you can feel when walking towards the house. I suspect that when it rains, the water seeps into the ground, and because the ground here is nothing but sand, the water slowly seeps down the incline towards the street. I say this, because there's a two-foot strip of grass along the road that is gorgeous, but three weeks makes it a bit too long to cut with the electric mower without having to stop several times to clean it out.
    7. The north side of Chez Boca is the most annoying section to mow. It's too narrowthere's a fence on one side, the house on the other. There's also a large tree on the east end, and a shed on the west end, so there's no long stretches to mow. I now do that section after the front yard.
    8. The north-west side of Chez Boca is the second most annoying section to mow. It's next to the house, There are two small trees in the way (I mean, I like trees, but mowing around them, especially given they're very low to the ground, is annoying) and I've smashed several sprinkler heads a few times. I do that after doing the north side, as I'm not completely wrecked yet.
    9. I do the back yard last, when I'm completely wrecked from doing the north and north-west portionslike the front yard, I can do long stretches of back-and-forth mowing which helps when I'm exhausted from mowing (when I first took over mowing, I would end up with doing the north-west then north sections last, and that nearly killed me each time).
    10. After mowing the front yard, I move the cars back into the driveway, instead of after mowing the entire lawn. It's easier to do it then than when I'm about to pass out.

    I'm having a hard time seeing why Bunny would give up mowing the lawn. It's so much fun!

    1:54 pm
    YAML config file? Pain? Try Lua

    Several articles about using YAML for configuration have been making the rounds, yet rarely do I see Lua being mentioned as an alternative for configuration files.

    Yes, it's a language, but it started out life as a configuration format. It's also small for a language, easy to embed, and easy to sandbox for the paranoid. Here's an example:

    lua_State *gL;
    
    bool config_read(char const *conf)
    {
      int rc;
      
      assert(conf != NULL);
      
      /*---------------------------------------------------
      ; Create the Lua state, which includes NO predefined
      ; functions or values.  This is literally an empty
      ; slate.  
      ;----------------------------------------------------*/
      
      gL = luaL_newstate();
      if (gL == NULL)
      {
        fprintf(stderr,"cannot create Lua state");
        return false;
      }
      
      /*-----------------------------------------------------
      ; For the truly paranoid about sandboxing, enable the
      ; following code, which removes the string library,
      ; which some people find problematic to leave un-sand-
      ; boxed. But in my opinion, if you are worried about
      ; such attacks in a configuration file, you have bigger
      ; security issues to worry about than this.
      ;------------------------------------------------------*/
      
    #ifdef PARANOID
      lua_pushliteral(gL,"x");
      lua_pushnil(gL);
      lua_setmetatable(gL,-2);
      lua_pop(gL,1);
    #endif
      
      /*-----------------------------------------------------
      ; Lua 5.2+ can restrict scripts to being text only,
      ; to avoid a potential problem with loading pre-compiled
      ; Lua scripts that may have malformed Lua VM code that
      ; could possibly lead to an exploit, but again, if you
      ; have to worry about that, you have bigger security
      ; issues to worry about.  But in any case, here I'm
      ; restricting the file to "text" only.
      ;------------------------------------------------------*/
      
      rc = luaL_loadfilex(gL,conf,"t");
      if (rc != LUA_OK)
      {
        fprintf(stderr,"Lua error: (%d) %s",rc,lua_tostring(gL,-1));
        return false;
      }
      
      rc = lua_pcall(gL,0,0,0);
      if (rc != LUA_OK)
      {
        fprintf(stderr,"Lua error: (%d) %s",rc,lua_tostring(gL,-1));
        return false;
      }
      
      /*--------------------------------------------
      ; the Lua state gL contains our configuration,
      ; we can now query it for values
      ;---------------------------------------------*/
      
      /* ... */
      return true;
    }
    

    Yes, it's all too possible for someone to write:

    (function() while true do end end)()
    

    in the configuration and block the process with 100% CPU utilization, but as I stated in the code example, if that's a worry, you have bigger security issues to worry about.

    Another nice benefit of using Lua is string management. If you are only using Lua for the configuration file, and once read, don't execute any more Lua code, then there's no need to duplicate the strings for your codebasejust keep using the strings directly from Lua. As long as you close the Lua state at the end of the program, they'll be cleaned up for you. And speaking of strings, you'll also have Lua's long strings:

    long_string = [[
    This is a long Lua string that can
    span several lines.  Escapes like '\n' don't work in this,
    but then again,
    you don't really need the '\n' here because they're part of the 
    string.
    ]]
    
    long_string_2 = [=[
    And if you want to embed a literal ']]' in a long string,
    you can, no problems here.
    ]=]
    

    I use Lua for the configuration file for my blogging engine (to see how I pull the configuration from Lua) which looks like:

    name        = "A Blog Grows in Cyberspace"
    description = "A place where I talk about stuff in cyperspace."
    class       = "blog, rants, random stuff, programming"
    basedir     = "."
    webdir      = "htdocs"
    lockfile    = ".modblog.lock"
    url         = "http://www.example.com/blog/"
    adtag       = "programming"
    conversion  = "html"
    prehook     = "./prehook_script"
    posthook    = "./posthook_script"
    
    author =
    {
      name   = "Joe Blog" ,
      email  = "joe@example.com",
    }
    
    templates =
    {
      {
        template = "html",
        output   = webdir .. "/index.html",
        items    = "7d",
        reverse  = true,
        posthook = "posthook_template_script"
      },
      {
        template = "atom",
        output   = webdir .. "/index.atom",
        items    = 15,
        reverse  = true,
      },
    }
    

    But if you think it'll be too complicated to instruct devops as to when to use a comma and not, you can always include semicolons at the end of each line:

    name        = "A Blog Grows in Cyberspace";
    description = "A place where I talk about stuff in cyperspace.";
    class       = "blog, rants, random stuff, programming";
    basedir     = ".";
    webdir      = "htdocs";
    lockfile    = ".modblog.lock";
    url         = "http://www.example.com/blog/";
    adtag       = "programming";
    conversion  = "html";
    prehook     = "./prehook_script";
    posthook    = "./posthook_script";
    
    author =
    {
      name   = "Joe Blog";
      email  = "joe@example.com";
    };
    
    templates =
    {
      {
        template = "html";
        output   = webdir .. "/index.html";
        items    = "7d";
        reverse  = true;
        posthook = "posthook_template_script";
      };
      {
        template = "atom";
        output   = webdir .. "/index.atom";
        items    = 15;
        reverse  = true;
      };
    };
    

    to simplify the configuration instructions (just add a semicolon to the end of each line & ). One other benefitcomments. That's one of the biggest complaints about using JSON as a configuration file formata lack of comments.

    Also, you don't even have to mention you are using Lua as a configuration filemost likely, no one will really notice anyway. I used Lua to configure “Project: Sippy-Cup” and “Project: Cleese” at The Enterprise and no one said anything about the format. It was also used for “Project: Bradenburg” (written by another team member) and there were no issues with that either.

    Thursday, September 28th, 2023
    5:51 am
    A classic blunder, like getting involved in a land war in Asia

    The first time I included some BASIC code, I typed in the sample directly from a magazine (like we used to do back in the 1980s). The second (and most recent) time I included BASIC code, it was extracted from a disk image downloaded from the Intarwebs (using code I wrote) and then decoded into ASCII, using code I wrote, based off a text file I also found on the Intarwebs. I didn't notice when I posted the code because it was a wall of text 32 characters wide (the width of the text screen on a Color Computer). It was only months later when I finally noticed all the THENNOTs littering the code.

    There was nothing wrong with the actual file, but I did locate the bug in my code:

    char const *const c_tokens[] =
    {
      "FOR",
      "GO",
      /* ... */
      "SUB",
      "THEN"
      "NOT",
      "STEP",
      "OFF",
      /* ... */
      "DSKO$",
      "DOS"
    };
    

    If you look close, you'll see there's a missing comma after the THEN token, and in C, two literal strings separated by whitespace are concatenated into a single string. Thus, all the THENNOTs I was seeing. And a bunch of incorrect code because most of the BASIC keywords were then off-by-one (a classic mistake of C programming).

    Wednesday, September 27th, 2023
    1:15 am
    To err is humanto really mess up takes a computer

    I ran the code to fix the BLOCKQUOTE issue and as it turns out, there were 54 entries that needed further fixing due to the fix I just applied. I wanted the HTML files to still be editable, and as such, I wrapped the contents of the block-level elements to fit within 80 columns, and the function I used did not take into account where it was safe to break on an HTML tag. So for future reference, I'll have to write a customize word-wrapping function to take into account HTML. As it was, I fixed all 54 entries by hand; some were trivial, some required going into the backups.

    Ah, the wonders of automation. A human can mess up, a computer can mess up a lot. Quickly.

    The other thing I learned is that the entity ' is not defined for HTML 4 (it is for HTML 5, and XML). This is important because I'm still using HTML 4 for my blog. Why not HTML 5? Because I'm not fond of the living standard (read: changes whenever, meaning an ever-constant churn of updating HTML to maintain the standard du jour) and the step-by-step parsing rules instead of a concise syntax. It also doesn't help that whenever I see WHATWG, I read it as What working group?

    Tuesday, September 26th, 2023
    4:19 pm
    Changing the historical record of my blog

    Twenty-one years ago I was worried about loosing the historical presentation of my blog both because it was template driven, and through the use of CSS. Changes that effect everything at once certainly appeared quite Orwellian to me, although I might be in a very small minority in worring about this.

    And yet, since then, I've tweaked the CSS quite a bit since I wrote that. I figure I'm not changing the content, so it's okay. right?

    It was over a year ago when I noticed that a lot of my earlier entries had the initial paragraph shifted over to the left, due to a change in the template file I made around 2003. The old template had an initial <P> tag so I didn't have to type it, and the new one removed said tag. That left maybe a thousand posts (give or take) that needed fixing. I started doing the job manually at first, then gave up at the sheer number of posts to fix. Again, it was not changing the content but fixing the presentation. And it bothered me that there were posts that weren't formatted correctly.

    About a week or two ago, I realized that the markup I used for foreign words:

    <span lang="de" title="My hovercraft is full of eels">Mein Luftkissenfahrzeug ist voller Aale</span>
    

    is probably not sematically sound HTML. I even wrote about that issue twenty years ago, and now realize it should be:

    <i lang="de" title="My hovercraft is full of eels">Mein Luftkissenfahrzeug ist voller Aale</i>
    

    Around the same time, I read up on the proper use of <BLOCKQUOTE> and that the attribution should appear outside the blockquote, not inside as I've been doing for years, even though I was doing The Right Thing" when I first started blogging, but changed for some reason I long forgot.

    And then several days ago, I noticed the sample BASIC code was incorrect and it was bugging methe keyword THEN would always show up as THENNOT. How that happened is a topic for another post, but in the meantime, I decided to fix the issue without mentioning it. The change didn't change the intended meaning of the post, it was fixing incorrect output, not saying we were always at war with Eastasia.

    After that, I decided to go back and fix the formatting issues in the blog. I have code that will read entries and parse the HTML I use into into an AST (or should it be a DOM, even though I'm using Lua, not Javascript?) which I use to generate the Gopher and Gemini versions. To fix the initial paragraph issue, all I needed to do was identify the entries that didn't start with a <P> tag and just prefix the raw text with said tag.

    To update the HTML for foreign words, it was enough to identify entries with <SPAN LANG="language"> and with some sed magic, switch it to read <I LANG="language"> (and fix the corresponding closing tags). It's just fixing the semantics of the HTML, not changing the past, right?

    The fix for the <BLOCKQUOTE> issue wasn't quite so easyI still had over 700 entries that needed to be fixed, so I ended up writing code that would spit out the parsed HTML back into HTML. It would have been easy to output it as:

    
    <p>I've been following the various Linux <abbr title="Initial Public Offerin
    g">IPO</abbr>s and today I see that <a class="external" href="http://www.val
    inux.com/">VA Linux Systems</a> had their <a class="external" href="http://d
    ailynews.yahoo.com/h/nm/19991209/bs/markets_valinux_1.html">IPO today.</a>. 
     Briefly, it IPOed (can you verb a TLA?  Can you verb the word verb? Whate
    ver & ) at US$30 and opened at US$299.  Inbloodysane.</p><p><a class="extern
    al" href="http://www.andover.net/">Andover.Net</a> wasn't nearly as inbloody
    sane.</p>
    
    

    one long linethe browsers don't care, but I do if I ever have to go back and edit this. Instead, I want the output to still be editable:

    <p>I've been following the various Linux <abbr title="Initial Public
    Offering">IPO</abbr>s and today I see that <a class="external"
    href="http://www.valinux.com/">VA Linux Systems</a> had their <a
    class="external"
    href="http://dailynews.yahoo.com/h/nm/19991209/bs/markets_valinux_1.html">IPO
    today.</a>. Briefly, it IPOed (can you verb a TLA? Can you verb the word
    verb? Whatever & ) at US$30 and opened at US$299. Inbloodysane.</p>
    
    <p><a class="external" href="http://www.andover.net/">Andover.Net</a> wasn't
    nearly as inbloodysane.</p>
    

    That meant handling not only <P> but all the block level tags in HTML, <BLOCKQUOTE>, <TABLE>, <DL> (which I use for emails and screenplay dialog), <UL>, <OL>, and <PRE>. Now that I have that working, I can identify the citation paragraphs for blockquotes, and move them to the appropriate location.

    I'm about to do that, yet I'm still a bit hesitent. Yes, it's just fixing the semantic presentation, but now that I have the code to read and write HTML, future mass changes are easy to do.

    I'm probably thinking too much on this.

    I think.

The Boston Diaries   About InsaneJournal