Filename too long to delete or rename

I couldn’t delete or rename a file because the path was too long. dir /X did not help. Thanks to ask.Metafilter, I got these instructions:

> cd path-to-dir-of-long-filename

> subst Y: .

> Y:

> rename long-filename short

> C:

> subst Y: /d

For the drive letter, make sure it’s an unassigned one.

Make sure you don’t type subst C: /d… I’m not sure if it’s possible, but it may be better to wrap this up in a script to avoid it.

Determine your disk usage with diskuse.exe

Windows Server 2003 Resource Kit has a tool called diskuse.exe; searching StackOverflow should give the right invocation. I call it from a bundled script and voila: users can manage their own disk usage. That’s one less thing for IT to scrummage* in their daily duties. Let the users serve themselves, as it were.

Bundling tclkit as a standalone exe produces a 5 MB beast, which is overkill; AutoIt would create something less than 350 KB and with less configuration. ActiveState should make it friendlier, but they have commercial offerings. It’s possible I have not fully investigated Starkits. Including the entire Img dep tree to put a JPEG on a button is deranged.

Today someone remarked that telephone extensions would be easy to memorize if they were associated with a visual cubicle map. I think I could make something for that. Crowd-sourced maintenance of points of contact. And if that one data point, others: IP address, name, position in the Hierarchy…

* scrummage – to scrounge hastily, to rummage with occupied reluctance

Picking projects

I felt really bad about purchasing domain books like physics and chemistry without showing anything for it. My spirits lifted after I made a distinction between domain books and programming books.

  • Domain books are textbooks in math and science. They are essentially specs, suggestions for models and problems for which your toolbox of programs are meant to compute and solve.
  • Programming books are CS books: books on languages, operating systems, system administration. They are your API and reference.

The basic point is human memory is short-lived and computer memory is long-lived: it seems the only things I commit long-term nowadays is repetitive kinesthetics a la keystrokes. The code acts as a conceptual, executable document.

Like any written work, it can be in various stages of revision (or first draft). Puzzling it out, though, seems much more productive than re-reading the material. Even so, a review of state by discrete variables and the functions manipulating them may be sufficient refresher to enjoy reviewing the author’s work (again).

A couple examples: system config scripts and vimrc. I am using Tcl to puzzle out the basic question of “How do I set up gvim to look sane without configuring (everything) again.”

AutoIt ADODB to Tcl tdbc::odbc

In AutoIt, I single-quote all strings, hashtag all dates and I can specify column names from parameters:

Local $query = "select " & $colName & " from " & $tbl & " " & _
  "where name = '" & $playerName & "' and createDate > #" & _
  $createDate & "#"

$rs.Open($query, $conn)

In Tcl, you don’t have to do the first two things and you can’t – or, I can’t – use column names as parameters in the SQL statement.

Opening connections, closing connections and the connection string are all similar. In AutoIt, the result set can be queried by index; fortunately, tdbc::odbc provides

set colnames [$resultset columns]; # returns a list to iterate over

tdbc::odbc query mysteriously fails

It may be an injection vulnerability to allow column names in queries; that’s why the statement doesn’t work.

proc dao_search {userchoice searchusing} { 
  set statement [db prepare { 
    select * from tbl where $userchoice = $searchusing;
  set resultset [$statement execute]
  $statement close

I had to hardcode the choice; so if $userchoice is “by gender,” I write one SQL query like this:

set statement [db prepare { 
  select * from tbl where gender like $searchusing
]}; #                     ^^^^^^

You can imagine that for each column in the table – gender, ice cream flavor, favorite color – I have multiple, similar queries that differ only in the column name: that has to be hardcoded.

Compared to the risk of injection – and awareness thereof – I think it is overall a good thing. Hope this saves you some hours.

Tcl 8.6: tdbc::odbc standalone exe

You will need three files:

  • sdx-20110317.kit
  • tclkitsh-8.5.9-win32.upx.exe
  • tclkit-gui-8_6_1-x86-max.exe

You also need to make sure tdbc::odbc is installed:

> teapot install tdbc::odbc
> tclsh
% package ifneeded tdbc::odbc

The overview is

  1. Get your files together.
  2. Wrap and then unwrap to create a virtual filesystem (vfs), which is just a folder.
  3. Put your source files and tdbc-related directories inside.
  4. Re-wrap and produce the executable.

The first step assumes you have three source files: a controller.tcl file, a dao.tcl file and a gui.tcl file. So they will look something like this:

# gui.tcl
package provide gui 1.0
package require controller 1.0
package require Tk
package require jnc-combobox; # see Tcl wiki for autofill combobox

# controller.tcl
package provide controller 1.0
package require dao 1.0

# dao.tcl
package provide dao 1.0
package require tdbc::odbc 1.0.0

Now for the build script: (link).

One-step deploy with Tclkit

I scripted a one-step build in Tcl using the instructions here:

Here are some adjustments to the basic instructions (steps 1-6 of Tclkit):

Step 1. The .kit and Tclkit can be found at Google Code:

You will need three files: tclkitsh, tclkit and sdx-xxx.kit. The .exe file with the “sh” in the name lets you run Tclkit via the command-line, which is good for automation.

Windows may interfere with the downloaded files. Right-click on the files and Unblock them.

Step 2. You will use the non-sh .exe file in only one step: the last one, passed as an argument to -runtime. So there is no need to rename any file to “tclkit2.exe.”

Step 3. Use exec to launch the tclkitsh executable. For example,

exec [pwd]\\tclkitsh-8.5.9-win32.upx.exe sdx-20110317.kit \
  qwrap tk-sample.tcl

Step 4. Nothing to note!

Step 5. Skipped.

Step 6. I referenced StackOverflow for this step:

First, do not use “bird.exe”; use “bird” as the argument. And for the -runtime parameter, specify the non-sh tclkit executable name. Finally, rename the file to .exe.

If you use bird.exe before the rename, Tclkit will output itself as a different name. If you double-click it, it will open Tclkit console. That’s how you’ll know to use “bird” instead.

If you specify the sh version of Tclkit to the -runtime param, you will get an Mkt4 error. You will need to pass in the non-sh version.

I’m saving up for ActiveState Pro Studio.

A lesson on frameworks

One good thing I see about frameworks is they encode a domain into a layered hierarchy. A properly refactored framework acts as an anchor and a lifeline; for its creator, a means to navigate a temporally independent context: in the beginning were lines to the console; by the end, a system of message passing for distributed machines.

Encountering code and concepts, I will endeavor to automate it. For CVS, it was creating repositories and creating projects. That’s simple enough after the first couple chapters of the handbook and (repeated) readings throughout. It’s in batch script because I could not get the Tcl script to print the output from CVS.

I had to take a break from game programming, because (1) I did not have any good game ideas, and (2) there were many other books to slog through: “UNIX Network Programming,” “Compiler Design in C,” “Absolute OpenBSD,” “Mathematical Elements for Computer Graphics,” and “Advanced Animation & Rendering Techniques.” (To name a few.)

And all these brought to heel by the gateway book itself, K&R C.

Library calls, all the way down

Even in the 80s books, there are these:

#include <stdio.h>

I can say “fundamentals” thirty times in a row, but that doesn’t stop the truth: if you’re not writing the kernel, there’s going to be an API call. Sockets are implemented in libs. File I/O is implemented in libs. Graphics routines are implemented in libs. You can’t escape some level of abstraction.

That sort of makes me a hypocrite by snubbing the modern techniques, the results-oriented stuff that people employ to ship. Not learning TCP/IP from scratch, or threads from scratch, or graphics from scratch: that’s sort of futile. It’s silly to work on a problem before you encounter it, right? Just for “interest’s sake.”

But no artist says, “Since I didn’t crush the graphite and mix the paint, or fasten the sable and wring out the canvas, this work is not truly mine.”

An audience of one

Many of my projects are named after the person who requested it. It’s easier to remember the patient when he’s talking to you. As a field observer, I get this cognitive defect of not remembering as much. But when you’re engaged with a person, one-on-one, a switch gets flicked and I can rattle off sentence after sentence of little details.

Software is eating the world, but for starters I would suffice with a nibble: one or two people using my work for a purpose, whether to be entertained or to be efficient. As demographics go, one ardent user means a potential ‘nother. Maybe I can motivate myself to create for one outside person. I imagine his life as a constant flurry of social strokes.

Or it could be an exercise in wish fulfillment: if the desire is not accomplished, scrap and start over. Get to the main experience, the core mechanic: polish it down by taking things away; scope them off with layers of painter’s tape. Once I am down to “user clicks left mouse button,” I may have something.

It also helps with managing complexity: subtraction is exclusion. Take off all the fat, trim away the commercial parts, and render aesthetics to a nearby bin.