2013-10-30

How to query the X11 screen saver state

This blog post explains how to query the X11 screen saver state and other information such as idle time. This is useful on Unix systems if your program wants to know e.g how long the user has been idle.

If you need only the idle time, and you have TCL/Tk version 8.5 or later installed, run the following command (without the leading $). It prints the number of seconds the user has been idle.

$ echo 'puts [tk inactive]; exit' | wish

If you need more information about the screen saver state or you need better accuracy (milliseconds), then compile and run the following C program:

#define DUMMY \
    set -ex; \
    gcc -s -O2 -W -Wall -o \
        get_x11_screen_saver_info get_x11_screen_saver_info.c \
        -L/usr/X11R6/lib -lX11 -lXext -lXss; \
    exit 2

/*
 * get_x11_screen_saver_info: Get and print X11 screen saver state and info
 * by pts@fazekas.hu at Wed Oct 30 08:28:35 CET 2013
 */

#include <stdio.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/scrnsaver.h>

int main(int argc, char **argv) {
  static XScreenSaverInfo *info;
  Display *display;
  int screen; 
  (void)argc; (void)argv;
  info = XScreenSaverAllocInfo();
  if ((display=XOpenDisplay(NULL)) == NULL) {
    fprintf(stderr, "error: can't open display\n");
    return 2;
  }
  screen = DefaultScreen(display);
  if (!XScreenSaverQueryInfo(display, RootWindow(display, screen), info)) {
    fprintf(stderr, "error: cannot query screen saver info\n");
    return 3;
  }
  printf("idle for %lu ms\n", (unsigned long)info->idle);
  if (info->state == ScreenSaverDisabled) {
    printf("state disabled\n");
  } else if (info->state == ScreenSaverOn) {
    printf("state on for %lu ms\n", (unsigned long)info->til_or_since);
  } else if (info->state == ScreenSaverOff) {
    printf("state off until %lu ms\n", (unsigned long)info->til_or_since);
  } else {
    printf("state unknown\n");
  }
  if (info->kind == ScreenSaverBlanked) {
    printf("kind blanked\n");
  } else if (info->kind == ScreenSaverInternal) {
    printf("kind internal\n");
  } else if (info->kind == ScreenSaverExternal) {
    printf("kind external\n");
  } else {
    printf("kind unknown\n");
  }
  XFree(info);
  XCloseDisplay(display); 
  return 0;
}

Please note that it's possible to affect the screen saver with the xset s ... command, and it's possible to affect the monitor power saving (sleep) with the xset dpms ... command. There are no such widely available commands for querying the screen saver state. The xset ... commands work differently for different display drivers. You may want to do a sleep .1 && xset ... to put your monitor to sleep right away.

2013-10-23

How to fix ugly text when printing a Google document

This blog post explains how to fix the ugliness of letter spacing in text printed from a Google document (text document, presentation etc.). An example ugly output (some letters are too close to each other):

To fix it, export the document to PDF (in the File / Download as / PDF menu item), and print the PDF. Don't choose File / Print / Save as PDF, that produces the ugly output above.

2013-10-21

How to start a Unix process in the foreground instead

This blog post explains how to run a Unix process in the foreground if it automatically puts itself into the background. TL;DR Run it like this:

$ prog 3>&1 | cat

Let's suppose you have two shell scripts:

$ cat >fore.sh <<'END'
#! /bin/sh
echo foo; sleep 1; echo bar
END
$ chmod +x fore.sh
$ cat >back.sh <<'END'
#! /bin/sh
(echo foo; sleep 1; echo bar) &
END
$ _

When running ./fore.sh you have to wait a second for it to finish, because it runs in the foreground. If you want to run it in the background, run it as: ./fore.sh & . You'll get back your prompt instantly, and you'll get the bar message one second later. The & is a standard Bourne shell feature to start processes in the background.

Doing the other way round is a bit trickier. When running ./back.sh, you get your prompt back almost instantly, because the sleeping happens in the background. There is also a race condition: sometimes you get foo first, and then the prompt, sometimes the other way round, depending on whether the kernel schedules the interactive shells or the back.sh script first. If you want to run a command in the foreground, but you don't want to change it in the implementation, a simple solution is this:

$ ./back.sh | cat
foo
bar
$ ./fore.sh | cat
foo
bar
$ _

So appending | cat works no matter the program wants to run in the foreground or in the background. The reason why it works is that you don't get your prompt back until cat has finished, and | cat waits for an EOF on the program's stdout, and there is no EOF on a pipe until all processes writing to that pipe have closed it, i.e. (most of the time) until the entire program terminates.

The | cat solution above breaks if the program is smart and closes its stdout early. In this case you get the prompt back immediately. For example, below bar is displayed only about a second after the $ in front of it was displayed.

$ cat >smart.sh <<'END'
#! /bin/sh
(exec >/dev/null; echo foo >&2; exec sh -c 'sleep 1; echo bar >&2') &
END
$ ./smart.sh | cat
foo
$ bar
_

To make it work for even such a program (in addition to back.sh and fore.sh), run it like this:

$ ./smart.sh 3>&1 | cat

The reason why this works is that 3>&1 instructs the shell to make a copy of the file descriptor 1 (stdout) as file descriptor 3. (Any number between 3 and 9 would do. For smarter shells numbers larger than 9 also work.) So even when the program explicitly closes (or redirects) its own stdout, it will still have file descriptor 3 open until it exits, thus preventing the EOF cat is waiting for, thus making the shell continue waiting for cat, thus not giving back the prompt. Most programs tend not to bother explicitly closing file descriptors larger than 2. The kernel closes file descriptors with the close-on-exec bit automatically closed upon an exec* call. Fortunately that doesn't apply to our file descriptor 3, because the shell has created it using the dup2 system call, which creates file descriptor 3 with the close-on-exec flag off.

2013-08-18

Non-recursive, fast, compact stable sort implementation in C++

This blog post discusses stable sort implementations in various languages, and it also presents a non-recursive, fast and compact mergesort implementation in C++. The implementation runs the original mergesort algorithm in an iterative way with some optimizations, so it is stable.

Please note that C++ STL has a stable sort built in: std::stable_sort in #include <algorithm>. If it's OK to use STL in your C++ code, use that, and you won't need any custom code from this blog post.

About compactness: when compiled statically with GCC 4.1.2 (g++ -fno-rtti -fno-exceptions -s -O2 -static) for i386, the mergesort in this blog post produces an executable 4084 bytes smaller than with std::stable_sort.

About speed: between 10% and 16% faster than std::stable_sort, see speed measurements below.

The fast, non-recursive, stable sort implementation in C++

It's a non-recursive, stable mergesort implementation, with O(n*log(n)) worst-case speed.

#include <sys/types.h>
// Stable, non-recursive mergesort algorithm. Sort a[:n], using temporary
// space of size n starting at tmp. (Please note that mergesort Algorithm
// 5.2.4N and Algorithm 5.2.4S from Knuth's TAOCP are not stable. Please 
// note that most implementations of mergesort found online are recursive,
// thus slower.)
//
// by pts@fazekas.hu at Sun Aug 18 19:23:36 CEST 2013
template <typename T, typename IsLess>
void mergesort(T *a, size_t n, T *tmp, IsLess is_less) {
  for (size_t f = 1; f < n; f += 2) {  // Unfold the first pass for speedup.
    if (is_less(a[f], a[f - 1])) {
      T t = a[f];
      a[f] = a[f - 1];
      a[f - 1] = t;   
    }
  }  
  bool s = false;
  for (size_t p = 2; p != 0 && p < n; p <<= 1, s = !s) {
    // Now all sublists of p are already sorted.
    T *z = tmp;
    for (size_t i = 0; i < n; i += p << 1) {
      T *x = a + i;
      T *y = x + p;
      size_t xn = p < n - i ? p : n - i;
      size_t yn = (p << 1) < n - i ? p : p < n - i ? n - p - i : 0;
      if (xn > 0 && yn > 0 &&
          is_less(*y, x[xn - 1])) {  // Optimization (S), Java 1.6 also has it.
        for (;;) {
          if (is_less(*y, *x)) {
            *z++ = *y++;
            if (--yn == 0) break;
          } else {
            *z++ = *x++;
            if (--xn == 0) break;
          }
        }  
      }    
      while (xn > 0) {  // Copy from *x first because of (S).
        *z++ = *x++;
        --xn;
      }
      while (yn > 0) {
        *z++ = *y++;  
        --yn;
      }
    }  
    z = a; a = tmp; tmp = z;
  }
  if (s) {  // Copy from tmp to result.
    for (T *x = tmp, *y = a, * const x_end = tmp + n; x != x_end; ++x, ++y) {
      *x = *y;
    }
  }  
}

Some convenience functions to call it:

// Stable, non-recursive mergesort.
// To sort vector `a', call mergesort(a.data(), a.data() + a.size(), is_less)'
// or use the convenience function below.
template <typename T, typename IsLess>   
void mergesort(T *a, T *a_end, IsLess is_less) {
  const size_t n = a_end - a;
  if (n < 2) return;
  // Creating ptr_deleter so tmp will be deleted even if is_less or
  // mergesort throws an exception.
  struct ptr_deleter {
    ptr_deleter(T *p): p_(p) {}
    ~ptr_deleter() { delete p_; }
    T *p_;
  } tmp(new T[n]);
  mergesort(a, n, tmp.p_, is_less);
}
 
// Convenience function to sort a range in a vector.
template <typename T, typename IsLess>
// Doesn't match:
//static void mergesort(const typename std::vector<T>::iterator &begin,
//                      const typename std::vector<T>::iterator &end,  
//static void mergesort(const typename T::iterator &begin,
//                      const typename T::iterator &end,  
void mergesort(const T &begin, const T &end, IsLess is_less) {
  mergesort(&*begin, &*end, is_less);
}
 
// Stable, non-recursive mergesort.
// Resizes v to double size temporarily, and then changes it back. Memory may
// be wasted in b after the call because of that.
template <typename T, typename IsLess>
void mergesort_consecutive(std::vector<T> *v, IsLess is_less) {
  const size_t n = v->size();
  if (n < 2) return;
  v->resize(n << 1);  // Allocate temporary space.
  mergesort(v->data(), n, v->data() + n, is_less);
  v->resize(n);
}

Example invocation:

inline bool int_mask_less(int a, int b) {
  return (a & 15) < (b & 15);
}
... 
  std::vector<int> a;
  ...
  mergesort(a.begin(), a.end(), int_mask_less);

A slow, non-recursive stable sort implementation in C++

If you don't care about speed, an insertion sort would do: it's simple (short), stable and non-recursive. Unfortunately it's slow: O(n2) in worst case and average.

// Insertion sort: stable but slow (O(n^2)). Use mergesort instead if you need
// a stable sort.  
template <typename T, typename IsLess>  
static void insertion_sort(T *a, T *a_end, IsLess is_less) {
  const size_t n = a_end - a;
  for (size_t i = 1; i < n; ++i) {
    if (is_less(a[i], a[i - 1])) {
      T t = a[i];
      size_t j = i - 1;  // TODO: Use pointers instead of indexes.
      while (j > 0 && is_less(t, a[j - 1])) {
        --j;
      }
      for (size_t k = i; k > j; --k) {
        a[k] = a[k - 1];
      }  
      a[j] = t; 
    }
  }
}

// Convenience function to sort a range in a vector.
template <typename T, typename IsLess>
static void insertion_sort(const T &begin, const T &end, IsLess is_less) {
  insertion_sort(&*begin, &*end, is_less);
}

C++ stable sort speed measurements

10000 random int vectors (of random size smaller than 16384) were sorted in place in a C++ program running on Linux 2.6.35 running on an Intel Core 2 Duo CPU T6600 @ 2.20GHz. The total user time was measured, including the sort, the running of std::stable_sort, and the verification of the sort output (i.e. comparing it to the output of std::stable_sort. The insmax parameter below indicates the size of the sublists with were sorted using insertion sort before running the mergesort (the implementation above uses insmax=2, which is implemented in the Unfold... loop).

The raw time measurement results:

mask= 15  insmax= 1          18.805s
mask= 15  insmax= 2          17.337s
mask= 15  insmax= 4          17.109s
mask= 15  insmax= 8          17.133s
mask= 15  insmax=16          17.153s
mask= 15  insmax=32          17.325s
mask= 15  insmax=64          18.221s
mask= 15  std::stable_sort   19.401s
mask= 15  insertion_sort    500.83s

mask=255  insmax= 1          19.349s
mask=255  insmax= 2          18.357s
mask=255  insmax= 4          18.493s
mask=255  insmax= 8          18.585s
mask=255  insmax=16          18.741s
mask=255  insmax=32          19.081s
mask=255  insmax=64          20.061s
mask=255  std::stable_sort   21.965s
mask=255  insertion_sort    530.27s

It looks like that the mergesort algorithm proposed in this blog post (insmax=2 in the measurements above) is between 10% and 16% faster than std::stable_sort. It looks like that increasing insmax from 2 to 8 could yield an additional 1.18% speed increase.

Stable sort in other programming languages

  • Java java.util.Collections.sort and java.util.Arrays.sort are stable. In OpenJDK 1.6, for primitive types, it uses an optimized (tuned) quicksort, and for objects (with a comparator) it uses a recursive, stable mergesort. Even though quicksort is not stable, this doesn't matter for primitive types, because there is no comparator (so it's always in ascending order), and it's impossible to distinguish different instances of the same primitive type value.
  • C qsort function is not stable, because it uses quicksort. FreeBSD, Mac OS X and other BSD systems have the mergesort function in their standard library (in libc, stdlib/merge.c), Linux glibc doesn't have it. As an alternative, it's straightforward to convert the mergesort implementation in this blog post from C++ to C.
  • CPython's sorted and list.sort functions are implemented with a stable, recursive mergesort (and binary insertion sort for short inputs) with a sophisticated (complicated, long) code containing lots of optimizations: see the files Objects/listsort.txt and Objects/listobject.c in the Python source code for documentation and implementation. It looks like it's not recursive.
  • Perl sort uses mergesort by default, so it's stable, but the default can change in future versions. Add use sort 'stable'; to the beginning of your code to get a guaranteed stable sort. See the sort pragma page for details.
  • Ruby 2.0 Array#sort doesn't say if it's stable or not, but a quick search for the string qsort in array.c reveals that it uses quicksort, so it's not stable. (a bit slow) stable sorting can be added easily:
    class Array
      def stable_sort
        n = 0
        sort_by {|x| n+= 1; [x, n]}
      end
    end
    ... as explained here. The fundamental idea in this trick is to compare the indexes if the values are equal. This fundamental idea can be implemented in any programming language, although it may have considerable memory and/or time overhead.
  • JavaScript's Array.prototype.sort tends to be stable in modern browsers (see the details), but unstable on old browsers.
  • C# Array.Sort is not stable (because it uses quicksort), but Enumerable.OrderBy and Enumberable.ThenBy are stable (because they use mergesort. See more info here.

Other stable sorting algorithms

Heapsort and quicksort are not stable. Some variations of mergesort (such as Algorithm 5.2.4N and Algorithm 5.2.4S in The Art of Computer programming, Volume 3 by Knuth) are not stable.

This page lists stable sorting algorithms known to mankind. Be careful with the implementations though: even if the algorithm itself is stable, some optimized, otherwise modified or buggy implementations might not be. The algorithms are:

  • O(n*log(n)), stable, comparison-based: mergesort, cascade merge sort, oscillating merge sort.
  • O(n2), stable, comparison-based: bubble sort, cocktail sort, insertion sort, binary insertion sort (where the insertion index is found using binary search), gnome sort, library sort, odd-even sort.
  • O(n2), stable, not comparison-based: bucket sort, proxmap sort.
  • faster than O(n2), stable, not comparison-based: counting sort, pigeonhole sort, radix sort.

So it looks like that we don't know of an alternative of mergesort for comparison-based sorting in O(n*log(n)) time, the others above are slower. Maybe Edsger Dijkstra[citation needed] can come up with an alternative.

2013-08-13

How to send Unix file descriptors between processes?

This blog post explains how to send Unix file descriptors between processes. The example shown below sends from parent to child, but the general idea works the other way round as well, and it works even between unrelated processes.

As a dependency, the processes need to have the opposite ends of a Unix domain socket already. Once they have it, they can use sendfd to send any file descriptor over the existing Unix domain socket. Do it like this in Python:

#! /usr/bin/python

"""sendfd_demo.py: How to send Unix file descriptors between processes

for Python 2.x at Tue Aug 13 16:07:29 CEST 2013
"""

import _multiprocessing
import os
import socket
import sys
import traceback

def run_in_child(f, *args):
  pid = os.fork()
  if not pid:  # Child.
    try:
      child(*args)
    except:
      traceback.print_exc()
      os._exit(1)
    finally:
      os._exit(0)
  return pid  


def child(sb):
  assert sb.recv(1) == 'X'
  # Be careful: there is no EOF handling in
  # _multiprocessing.recvfd (because it's buggy). On EOF, it
  # returns an arbitrary file descriptor number. We work it around by doing
  # a regular sendall--recv pair first, so if there is an obvious reason for
  # failure, they will fail properly.
  f = os.fdopen(_multiprocessing.recvfd(sb.fileno()))
  print repr(f.read())
  print f.tell()  # The file size.


def main(argv):
  sa, sb = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
  pid = run_in_child(child, sb)
  # We open f after creating the child process, so it could not inherit f.
  f = open('/etc/hosts')
  sa.sendall('X')
  _multiprocessing.sendfd(sa.fileno(), f.fileno())  # Send f to child.
  assert (pid, 0) == os.waitpid(pid, 0)
  # The file descriptor is shared between us and the child, so we get the file
  # position where the child has left off (i.e. at the end).
  print f.tell()
  print 'Parent done.'


if __name__ == '__main__':
  sys.exit(main(sys.argv))

It works even for unrelated processes. To try it, run the following program with a command-line argument in a terminal window (it will start the server), and in another terminal window run it several times without arguments (it will run the client). Each time the client is run, it connects to the server, and sends a file descriptor to it, which the server reads. The program:

#! /usr/bin/python2.7

"""sendfd_unrelated.py: Send Unix file descriptors between unrelated processes.

for Python 2.x at Tue Aug 13 16:26:27 CEST 2013
"""

import _multiprocessing
import errno
import os
import socket
import stat
import sys
import time

SOCKET_NAME = '/tmp/sendfd_socket'

def server():
  print 'Server.'
  ssock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  while 1:
    try:
      ssock.bind(SOCKET_NAME)
      break
    except socket.error, e:
      if e[0] != errno.EADDRINUSE:
        raise
      # TODO: Fail if the old server is still running.
      print 'Removing old socket.'
      os.unlink(SOCKET_NAME)
    
  ssock.listen(16)
  while 1:
    print 'Accepting.'
    sock, addr = ssock.accept()
    print 'Accepted.'
    assert sock.recv(1) == 'X'
    f = os.fdopen(_multiprocessing.recvfd(sock.fileno()))
    print repr(f.read())
    print f.tell()  # The file size.
    del sock, f


def client():
  print 'Client.'
  sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  while 1:
    try:
      sock.connect(SOCKET_NAME)
      break
    except socket.error, e:
      if e[0] not in (errno.ENOENT, errno.ECONNREFUSED):
        raise
      print 'Server not listening, trying again.'
      time.sleep(1)
  print 'Connected.'
  f = open('/etc/hosts')
  sock.sendall('X')
  _multiprocessing.sendfd(sock.fileno(), f.fileno())  # Send f to server.
  assert '' == sock.recv(1)  # Wait for the server to close the connection.
  del sock
  print f.tell()


def main(argv):
  if len(argv) > 1:
    server()
  else:
    client()
  print 'Done.'


if __name__ == '__main__':
  sys.exit(main(sys.argv))

There is no system call named sendfd or recvfd. They are implemented in terms of the sendmsg and recvmsg system calls. Passing the correct arguments is tricky and a bit awkward. Here is how to do it in C or C++:

#include <string.h>
#include <sys/socket.h>

int sendfd(int unix_domain_socket_fd, int fd) {
  char dummy_char = 0;
  char buf[CMSG_SPACE(sizeof(int))];
  struct msghdr msg;
  struct iovec dummy_iov;
  struct cmsghdr *cmsg;
  memset(&msg, 0, sizeof msg);
  dummy_iov.iov_base = &dummy_char;
  dummy_iov.iov_len = 1;
  msg.msg_control = buf;
  msg.msg_controllen = sizeof(buf);
  msg.msg_iov = &dummy_iov;
  msg.msg_iovlen = 1;
  cmsg = CMSG_FIRSTHDR(&msg);
  cmsg->cmsg_level = SOL_SOCKET;
  cmsg->cmsg_type = SCM_RIGHTS;
  cmsg->cmsg_len = CMSG_LEN(sizeof(int));
  msg.msg_controllen = cmsg->cmsg_len;
  memcpy(CMSG_DATA(cmsg), &fd, sizeof fd);  /* int. */
  return sendmsg(unix_domain_socket_fd, &msg, 0);  /* I/O error unless 1. */
}

int recvfd(int unix_domain_socket_fd) {
  int res;
  char dummy_char;
  char buf[CMSG_SPACE(sizeof(int))];
  struct msghdr msg;
  struct iovec dummy_iov;
  struct cmsghdr *cmsg;
  memset(&msg, 0, sizeof msg);
  dummy_iov.iov_base = &dummy_char;
  dummy_iov.iov_len = 1;
  msg.msg_control = buf;
  msg.msg_controllen = sizeof(buf);
  msg.msg_iov = &dummy_iov;
  msg.msg_iovlen = 1;
  cmsg = CMSG_FIRSTHDR(&msg);
  cmsg->cmsg_level = SOL_SOCKET;
  cmsg->cmsg_type = SCM_RIGHTS;
  cmsg->cmsg_len = CMSG_LEN(sizeof(int));
  msg.msg_controllen = cmsg->cmsg_len;
  res = recvmsg(unix_domain_socket_fd, &msg, 0);
  if (res == 0) return -2;  /* EOF. */
  if (res < 0) return -1;  /* I/O error. */
  memcpy(&res, CMSG_DATA(cmsg), sizeof res);  /* int. */
  return res;  /* OK, new file descriptor is returned. */
}

See also http://www.mca-ltd.com/resources/fdcred_1.README (download C source of Python extension here) for more information. Perl programmers can use Socket::MsgHdr.

2013-08-08

webfind: How many programming languages can you speak ... at the same time?

When I wrote the following code which compiles and/or executes in 10 different programming languages (C, C++, Perl, TeX, LaTeX, PostScript, sh, bash, zsh and Prolog) and prints a different message in each of them, I think it was cool.

%:/*:if 0;"true" +s ||true<</;#|+q|*/include<stdio.h>/*\_/
{\if(%)}newpath/Times-Roman findfont 20 scalefont setfont(
%%)pop 72 72 moveto(Just another PostScript hacker,)show((
t)}. t:-write('Just another Prolog hacker,'),nl,halt. :-t.
:-initialization(t). end_of_file. %)pop pop showpage(-: */
int main(){return 0&printf("Just another C%s hacker,\n",1%
sizeof'2'*2+"++");}/*\fi}\csname @gobble\endcsname{\egroup
\let\LaTeX\TeX\ifx}\if00\documentclass{article}\begin{doc%
ument}\fi Just another \LaTeX\ hacker,\end{document}|if 0;
/(J.*)\$sh(.*)"/,print"$1Perl$2$/"if$_.=q # hack the lang!
/
sh=sh;test $BASH_VERSION &&sh=bash;test $POSIXLY_CORRECT&&
sh=sh;test  $ZSH_VERSION && sh=zsh;awk 'BEGIN{x="%c[A%c[K"
printf(x,27,27)}';echo "Just another $sh hacker," #)pop%*/

But now I know that the source of this is the the coolest ever (poly.html). I could make it work in 22 languages without changing the original file. Now, that's a feat, congratulations to the author! Good luck for the autodetect feature of your smart text editor to figure out the highlighting. The name of some languages is not explicitly mentioned in the file. Can you find them?

There is another impressive one polyglot with 8 languages: COBOL, Pascal, Fortran, C, PostScript, sh, DOS .com file, Perl.

There is another multilingual program I wrote earlier with 3 languages of: Haskell, Prolog, Perl and Python.

webfind: Bootstrapping a simple compiler from nothing

This document is a case study of writing and bootstrapping a compiler for a simple (but structured) language from scratch. It targets i386 Linux. It starts from a single hex-to-binary converter, and repeats this many times: write a little compiler for a little bit smarter language in the old language, compile it, then rewrite it to the new language. After about a dozen iterations a compiler for a structured language is created. See also the source code. Done in 2001.

webfind: The smallest compiler (it compiles Brainfuck)

I've found the smallest compiler so far. It's a Brainfuck compiler written in x86 assembly, and it compiles to an i386 Linux binary. Downloaded it from here and play with it on Linux (i386 or amd64):

$ sudo apt-get install nasm
$ wget -O bf.asm http://www.muppetlabs.com/~breadbox/software/tiny/bf.asm.txt
$ nasm -f bin -o bf bf.asm && chmod +x bf
$ cat >hello_world.bf <<'END'
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]
>++++++++[<++++>-] <.>+++++++++++[<++++++++>-]<-.--------.+++
.------.--------.[-]>++++++++[<++++>- ]<+.[-]++++++++++.
END
$ ./bf hello_world && chmod +x hello_world
$ ./hello_world
Hello world!

A 16-bit DOS version, which is even shorter (135 bytes) can be found here. There is a challange here for implementing Brainfuck interpreters, and the best so far is 106 bytes in Perl, but unfortunately the source code is not available. There is also a 98-byte interpreter for 16-bit DOS here.

See a 160-byte (source code) interpreter in C here.

Here is a similar page listing short interpreters for a small, Turing-complete language.

2013-05-22

How to create a PDF file with a single hyperlink in it

This blog post explains how to create a PDF file with a single hyperlink in it. Such PDF files are useful as hyperlinks uploaded to prezi.com presentations, because as of 2014-05-22 prezi.com doesn't support hyperlinks with text different from the link target URL: it only supports hyperlinks whose URL appear visually in the presentation. By uploading a PDF with a hyperlink this limitation can be circumvented.

Use this Python script to generate the PDF with a hyperlink. It will create a single page PDF containing green triangle with a hyperlink pointing to the URL specified in the command-line. Example usage on Linux:

$ wget -O linkpdfgen.py \
    https://pts-mini-gpl.googlecode.com/svn/trunk/linkpdfgen/linkpdfgen.py
$ chmod +x linkpdfgen.py
$ ./linkpdfgen.py http://example.org/ output.pdf

To insert the generated PDF file to prezi.com, choose Insert / From file when editing the presentation.

Please note the generated PDF file is very small (about 700 bytes). This is not a coincidence, the file contains only the minimum amount of information necessary.

Non-alternatives on Linux:

  • Adobe Acrobat: This software is not available on Linux.
  • Inkscape: Inkscape 0.48 can't export a PDF containing hyperlinks. (All hyperlinks are removed when the PDF file is saved.)
  • OpenOffice or LibreOffice: They can't add hyperlinks to geometrical shapes, so the generated PDF will have to contain text, thus it has to contain fonts, thus it will be larger than necessary.

2013-04-21

How to send ZIP-compressed, streaming AJAX response

This blog post explains how to send a ZIP-compressed HTTP response to an AJAX (XMLHttpRequest) request in a streaming way. By streaming we mean sending a prefix of the HTTP response in a way that the JavaScript running in the web browser gets notified soon that a partial HTTP response has arrived, and it can react to the bytes it has already received. With streaming all output buffering must be disabled (or output buffers must be flushed explicitly) so even a single extra HTTP response byte can make it to the JavaScript, without having to wait for other bytes to arrive first.

First make sure that streaming works without compression. For that, call all the relevant flush methods on the server. For Chrome (tested on Chrome 22), you also have to send the HTTP response header X-Content-Type-Options: nosniff, otherwise Chrome would buffer the first 1024 bytes of the HTTP response body before notifying the JavaScript. Firefox (tested on Firefox 14) doesn't buffer anything even without this header. I haven't tried Internet Explorer, Safari or other browsers. In your JavaScript onreadystatechange event handler, make sure that you process the .response even if .readyState is not 4. (In fact, partial streaming responses arrive with .readyState 3, and the final response data arrives with .readyState 4.)

Once streaming works without compression, enable compression by specifying Content-Encoding: deflate, and compress the HTTP response body in the ZLIB format (RFC 1950, also called as /FlateEncode). Please note that there is a similar format named GZIP (which is emitted by e.g. Java's GZIPOutputStream), but don't use that, because that produces an output which is about 10 bytes larger than for ZLIB. In Python, zlib.compress(body) can be used. In Java, use the DeflaterOutputStream or the Deflater class. You have to make more changes to make the compressor flush its output. In Python, you have to use the flush method on zlib.compressobj(). Call the .flush(1) method, where 1 corresponds to Z_PARTIAL_FLUSH (see more here). Z_SYNC_FLUSH also works, but it makes the output size larger than with Z_PARTIAL_FLUSH. (Even Z_PARTIAL_FLUSH makes the output larger than without flushing, because it forcibly closes the Huffman block, and starting a new Huffman block requires some extra bytes which describe the Huffman table of the new block.) In Java, you need at least Java 1.7 (because Java 1.6 and earlier doesn't have flushing capabilities in Deflater). If you use DeflaterOutputStream, specify the flushing mode (true for Z_SYNC_FLUSH, false is useless) as the 2nd argument of the constructor, and then call its .flush() method when you want to propagate the HTTP response accumulated so far to the web browser.

Don't send a compressed HTTP response body if the HTTP request headers don't contain Accept-Encoding with an item deflate.

Firefox 14 and Chrome 22 don't need any additional client-side (JavaScript) changes for receiving ZIP-compressed streaming HTTP response parts. These browsers recognize Content-Encoding HTTP response header, and decompress the HTTP response body on the fly, in a streaming way, without extra buffering if Z_PARTIAL_FLUSH or Z_SYNC_FLUSH was used by the HTTP server. I haven't tried other browsers, but most probably they also work except for some possible increased latency because of flushing issues.

How to list Android apps in the order they were installed

This blog post explains how to list applications on an Android device (phone, tablet etc.) in the order they were installed. This list can be used to copy the most recently installed application from the device to the computer.

Enable USB debugging on the phone, and connect the phone. (If you don't know how, follow these steps up to the point of running adb shell.) Make sure adb shell id works. Then run the following command on your computer (without the leading $):

adb shell 'pm list packages -f | while read X; do
    X="${X#package:}"; X="${X%=*}"; L="$(ls -l "$X")";
    echo "${L% *} $X"; done' | sort -k 5

This will list the applications in installation order, i.e. the most recently installed one will be listed last. The full name of the applications are not displayed, but the filename and directory name of the .apk files is.

If /data/app/X.Y.apk is listed, then copy it to the computer like this:

$ adb pull /data/app/X.Y.apk

2013-03-31

How to download all .apk files from an Android device to the computer

This blog post explains how to download all .apk files (application software package installers) from an Android device (phone, tablet, etc.) to your computer. The steps described here work even if the device is not rooted.

Prerequisites:

  • You have a computer running Mac OS X or Linux. It's possible to do it on Windows as well, but this blog post doesn't explain how.
  • You have a USB cable with which you can connect the device to the computer.
  • USB debugging has been enabled on the device. You can enable it in the Settings / Development menu. If you can't see that menu, then go to Settings / About... / Build number, and tap on it quickly 10 times in a row.
  1. Install the adb command-line tool. It's part of the Platform SDK Tools SDK package. First download the Android SDK, then run the tools/android GUI tool, select Platform SDK Tools and install. The adb binary will be downloaded to platform-tools/adb .
  2. If you have a new Android (4.2.2 or later) and an old adb binary (earlier than 1.0.31), then it won't work until you install a newer adb binary.
  3. On Linux, follow these steps to make sure that your user has the permission to access the device.
  4. Don't connect your device yet to the computer via USB.
  5. Run adb devices and verify that it doesn't see the device.
  6. If not enabled yet, enable USB debugging on the device (see in the prerequisites section).
  7. Connect the device to your computer using an USB cable.
  8. Run adb devices and verify that it sees your device.
  9. On the computer, open a terminal window, and cd to the target directory.
  10. Run this command in the terminal window: adb shell pm list packages -f >apks.lst
  11. Run this command in the terminal window: <apks.lst perl -ne 'if (m@^package:(/[^=]+[.]apk)=@) { my $A=$1; $_=$1; s@/base[.]apk$@.apk@; s@^.*/@@; print "$A $_\n" }' | while read F G; do echo "$G"; adb pull "$F" "$G"; done
  12. Wait for a few minutes until the command above finishes copying all the .apk files.

2013-02-11

Calling JavaScript method references

This blog post is a documentation of a quirk in the JavaScript language: method calls and method reference calls don't operate on the same receiver (thisArg), i.e. cat.foo() and (cat.foo)() are not equivalent.

Example:

<script>
function Cat() {}
Cat.prototype.toString = function() { return 'CatObj'; };
Cat.prototype.foo = function() {
  document.write('<p>CATFOO ' + this);
};
function Dog() {}
Dog.prototype.toString = function() { return 'DogObj'; };
Dog.prototype.bar = function() {
  var cat = new Cat();
  cat.foo();          //: CATFOO CatObj
  (cat.foo)();        //: CATFOO [object Window]
  var catFoo = cat.foo;
  catFoo();           //: CATFOO [object Window]
  catFoo.call(cat);   //: CATFOO CatObj
  catFoo.call(this);  //: CATFOO DogObj
};
(new Dog()).bar();
</script>

The solution is to using built-in methods call or apply, and passing the receiver object (thisArg) as the first argument.

2012-12-30

Hungarian spell checking, hyphenation and synonyms in LibreOffice 3 and OpenOffice 3

This blog post explains how to install the Hungarian spell checking, hyphenation and synonyms extensions to OpenOffice 3.x and LibreOffice 3.x.

The most important contribution of this blog post is the http://code.google.com/p/openscope/wiki/DictHuOxt link above, which is very hard to find with web search engines.

2012-12-03

Announcing intalg: integer and number theory algorithms in pure Python 2.x

This is the initial release announcement for pybasealgo (fast implementation of basic algorithms in pure Python 2.x, minimum version:) and the first set of algorithms, intalg (integer and number theory algorithms). The algorithm implementations can be used in Project Euler and programming contest problem solving. These are free software under the GPL. Click on the links above to download the source.

intalg contains the following algorithms:

  • integer bit count (bit_count)
  • square root rounding down (sqrt_floor)
  • kth root rounding down (root_floor)
  • bounded prime list builder using the sieve of Eratosthenes (primes_upto, first_primes_moremem, first_primes)
  • bounded prime generator using the sieve of Eratosthenes (yield_primes_upto, yield_first_primes)
  • unbounded prime generator using the sieve of Eratosthenes (yield_primes, yield_composites)
  • high precision upper bound for natural and base 2 logarithms (log2_256_more, log_more)
  • greatest common divisor using Euclidean algorithm (gcd)
  • primality test using the Rabin-Miller test with fast parameters (is_prime)
  • finding the next prime (next_prime)
  • computation of binary coefficients (choose)
  • integer factorization to prime divisors (factorize, yield_slow_factorize, finder_slow_factorize)
  • computation of the number of divisors (divisor_count)
  • computation of the sum of divisors (divisor_sum)
  • random number generation using the Mersenne twister MT19937, without using floating point numbers (MiniIntRandom)
  • Pollard's Rho algorithm aiding integer factorization (pollard)
  • Brent's algorithm aiding integer factorization (pollard)
  • simplification of fractions (simplify_nonneg)
  • RLE: run-length encoding (rle)
  • conversion of fraction of very large integers to float (fraction_to_float)

Design principles:

  • Pure Python: Provides full functionality using only built-in Python modules.
  • Fast: Fast implementations of fast algorithms, e.g. Newton iteration for square root and kth root, sieve of Eratosthenes for prime number generation, Brent's algorithm for integer factorization. Typically faster than most of the sample code and other libraries found online. (If you find something faster, please let me know by posting a comment.) Not as fast as C code (e.g. pygmp).
  • Correct: Many Python code examples (e.g. Brent's algorithm) found on the net are buggy (especially in corner cases) or are too slow. pybasealgo strives to be correct. Production use (i.e. I use this library for solving Project Euler problems) and unit tests help this.
  • Simple: Maintains a balance between speed and implementation simplicity. It implements sophisticated and fast algorithms in a simple way, but it doesn't contain the fastest possible algorithm if it's very complex (e.g. for integer factorization, pyecm is 1472 lines long, our intalg contains Brent's algorithm, which is slower but much simpler).
  • No-float: Doesn't use floating point numbers, not even for temporary computations (e.g. math.log(...)). This is to avoid rounding errors, which make the correctness of an algorithm hard to prove and they make some computations nondeterministic on some architectures and systems. And also to support arbitrarily large numbers: floats have a maximum (e.g. all IEEE 754 64-bit are less than 2e308), so they cannot be used in calculations with very large numbers. Python uses temporary floating point numbers for random integer generation, so pybasealgo provides an integer-only replacement.
  • Arbitrarily large integers: All algorithms work with small integers (of type int) and arbitrarily large integers (of type long). There is no automatic truncation of the results.
  • Deterministic: Every function returns the same value for the same input, and it runs at the same speed. (Except if some return values are cached in memory, then subsequent calls in the same process will be faster.) This makes debugging and benchmarking a lot easier. Determinism is very important in a programming contest situation: if your program succeeds for you, you don't want it to fail or time out when the judges rerun it. Even those algorithms which use random numbers (e.g. Pollard's Rho algorithm and Brent's algorithm for integer factorization) are deterministic by default, because they use pseudorandom numbers with a seed which depends only on the input.

Have fun programming and Python and I wish you great success in Project Euler and in programming contests.

2012-11-15

How to start and kill a Unix process tree

This blog post explains how to start a (sub)process on Unix, and later kill it so that all its children and other descendants are also killed. The sample implementation is written in Python 2.x (≥ 2.4), but it works equally well in other programming languages. It has been tested on Linux, but it should also work on other Unix systems such as *BSD and the Mac OS X.

For example, the following doesn't work as expected:

import os, signal, subprocess, time
p = subprocess.Popen('cat /dev/zero | wc', shell=True)
time.sleep(.3)
os.kill(p.pid, signal.SIGTERM)

The intention here is to kill the long-running command after 0.3 second, but this will kill the shell only, and both cat /dev/zero (the long-running pipe source) and wc will continue running, both of them consuming 100% CPU until killed manually. The trick for killing the shell and all descendant processes is to put them into a process group first, and to kill all processes in the process group in a single step. Doing so is very easy:

import os, signal, subprocess, time
p = subprocess.Popen('sleep  53 & sleep  54 | sleep  56',
                     shell=True, preexec_fn=os.setpgrp)
time.sleep(.3)
print 'killing'
os.kill(-p.pid, signal.SIGTERM)
p.wait()

By specifying preexec_fn=os.setpgrp we ask the child to call the setpgrp() system call (after fork() but before exec...(...)ing the shell), which will create a new process group and put the child inside it. The ID of the process group (PGID) is the same as the process ID (PID) of the child. All descendant processes of the child will be added to this process group. By specifying a negative PID to os.kill (i.e. the kill(...) system call), we ask for all process group members to be killed in a single step. This will effectively kill all 3 sleep processes.

Of course if some of the descendant processes ignore or handle the TERM signal, they won't get killed. We could have sent the KILL signal to forcibly kill all process group members. Sending the INT signal is similar to the TERM signal, except that Bash explicitly sets up ignoring the INT signal for processes started in the background (sleep 53 in the example above), so those processes won't get killed unless they restore the signal handler to the default (by calling the system call signal(SIGINT, SIG_DFL)). sleep doesn't do that, so sleep 53 wouldn't get killed if the INT signal was sent.

Using shell=True above is not essential: the idea of setting up a process group and killing all process group members in a single step works with shell=False as well.

See The Linux kernel: Processes for a ground-up lesson about processes, process groups, sessions and controlling terminals on Linux. This is a must-read to gain basic understanding, because the relevant system call man pages (e.g. man 2 setpgrp) don't define or describe these basic concepts.

The same idea works through SSH, with a few modifications. There is no need for preexec_fn=os.setpgrp, because sshd sets up a new process group for each new connection. We need to do extra work though to get the remote PID, because p.pid would just return the local PID of the short-living first ssh process. Here is a working example:

import subprocess, time
ssh_target = '127.0.0.1'
command = 'sleep  53 & sleep  54 | sleep  56'
p = subprocess.Popen(('ssh', '-T', '--', ssh_target,
                      'echo $$; exec >/dev/null; (%s\n)&' % command),
                     stdout=subprocess.PIPE)
pid = p.communicate()[0]  # Read stdin (containing the remote PID).
assert not p.wait()
pid = int(pid)
time.sleep(.3)
print 'killing'
assert not subprocess.call(('ssh', '-T', '--', ssh_target,
                            'kill -TERM %d' % -pid))

In the SSH example above, kill is usually the built-in kill command of Bash, but it works equally well if it's the /bin/kill external program. The remote PID (same as the remote PGID) is written by echo $$.

The exec >/dev/null command is needed to redirect stdout. Without it the ssh client would wait for an EOF on stdout before closing the connection. This can be useful in some cases, but in our design p.wait() is called early, and the first SSH connection is expected to close early, not waiting for the command to finish.