Merge "read partition length from recovery.fstab"
diff --git a/core/Makefile b/core/Makefile
index 35773bf..c17b4eb 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -589,7 +589,7 @@
 # $(5): size of the partition
 define build-userimage-ext-target
   @mkdir -p $(dir $(2))
-  $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$(PATH) \
+  $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
 	  $(MKEXTUSERIMG) $(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG) $(1) $(2) $(4) $(3) $(5)
 endef
 else
@@ -1152,8 +1152,8 @@
 
 .PHONY: installed-file-list
 installed-file-list: $(INSTALLED_FILES_FILE)
-ifneq ($(filter sdk,$(MAKECMDGOALS)),)
-$(call dist-for-goals, sdk, $(INSTALLED_FILES_FILE))
+ifneq ($(filter sdk win_sdk,$(MAKECMDGOALS)),)
+$(call dist-for-goals, sdk win_sdk, $(INSTALLED_FILES_FILE))
 endif
 ifneq ($(filter sdk_addon,$(MAKECMDGOALS)),)
 $(call dist-for-goals, sdk_addon, $(INSTALLED_FILES_FILE))
@@ -1412,9 +1412,10 @@
 
 # Is a Windows SDK requested? If so, we need some definitions from here
 # in order to find the Linux SDK used to create the Windows one.
+MAIN_SDK_NAME := $(sdk_name)
+MAIN_SDK_DIR  := $(sdk_dir)
+MAIN_SDK_ZIP  := $(INTERNAL_SDK_TARGET)
 ifneq ($(filter win_sdk,$(MAKECMDGOALS)),)
-LINUX_SDK_NAME := $(sdk_name)
-LINUX_SDK_DIR  := $(sdk_dir)
 include $(TOPDIR)development/build/tools/windows_sdk.mk
 endif
 
@@ -1440,3 +1441,10 @@
 # These are some additional build tasks that need to be run.
 include $(sort $(wildcard $(BUILD_SYSTEM)/tasks/*.mk))
 -include $(sort $(wildcard vendor/*/build/tasks/*.mk))
+
+# -----------------------------------------------------------------
+# Create SDK repository packages. Must be done after tasks/* since
+# we need the addon rules defined.
+ifneq ($(sdk_repo_goal),)
+include $(TOPDIR)development/build/tools/sdk_repo.mk
+endif
diff --git a/core/config.mk b/core/config.mk
index 6cf8f1f..c6f6288 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -70,7 +70,6 @@
 BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk
 BUILD_DROIDDOC:= $(BUILD_SYSTEM)/droiddoc.mk
 BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk
-BUILD_KEY_CHAR_MAP := $(BUILD_SYSTEM)/key_char_map.mk
 BUILD_NATIVE_TEST := $(BUILD_SYSTEM)/native_test.mk
 BUILD_HOST_NATIVE_TEST := $(BUILD_SYSTEM)/host_native_test.mk
 
@@ -232,7 +231,6 @@
 
 # dx is java behind a shell script; no .exe necessary.
 DX := $(HOST_OUT_EXECUTABLES)/dx
-KCM := $(HOST_OUT_EXECUTABLES)/kcm$(HOST_EXECUTABLE_SUFFIX)
 ZIPALIGN := $(HOST_OUT_EXECUTABLES)/zipalign$(HOST_EXECUTABLE_SUFFIX)
 FINDBUGS := prebuilt/common/findbugs/bin/findbugs
 LOCALIZE := $(HOST_OUT_EXECUTABLES)/localize$(HOST_EXECUTABLE_SUFFIX)
diff --git a/core/key_char_map.mk b/core/key_char_map.mk
deleted file mode 100644
index 4693743..0000000
--- a/core/key_char_map.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-###########################################################
-## Standard rules for building an executable file.
-##
-## Additional inputs from base_rules.make:
-## None.
-###########################################################
-
-ifeq ($(strip $(LOCAL_MODULE_CLASS)),)
-LOCAL_MODULE_CLASS := KEYCHARS
-endif
-ifeq ($(strip $(LOCAL_MODULE_SUFFIX)),)
-LOCAL_MODULE_SUFFIX := .bin
-endif
-
-LOCAL_MODULE := $(LOCAL_SRC_FILES)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-full_src_files := $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES))
-
-$(LOCAL_BUILT_MODULE) : PRIVATE_SRC_FILES := $(full_src_files)
-
-ifeq ($(BUILD_TINY_ANDROID),true)
-$(LOCAL_BUILT_MODULE) : $(full_src_files)
-	@echo KeyCharMap: $@
-	@mkdir -p $(dir $@)
-	$(hide) touch $@
-else
-$(LOCAL_BUILT_MODULE) : $(full_src_files) $(KCM)
-	@echo KeyCharMap: $@
-	@mkdir -p $(dir $@)
-	$(hide) $(KCM) $(PRIVATE_SRC_FILES) $@
-endif
\ No newline at end of file
diff --git a/core/main.mk b/core/main.mk
index 1df9a90..e5824db 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -209,13 +209,8 @@
 ###
 
 is_sdk_build :=
-ifneq ($(filter sdk,$(MAKECMDGOALS)),)
-is_sdk_build := true
-endif
-ifneq ($(filter win_sdk,$(MAKECMDGOALS)),)
-is_sdk_build := true
-endif
-ifneq ($(filter sdk_addon,$(MAKECMDGOALS)),)
+
+ifneq ($(filter sdk win_sdk sdk_addon,$(MAKECMDGOALS)),)
 is_sdk_build := true
 endif
 
@@ -290,6 +285,11 @@
 ## sdk ##
 
 ifdef is_sdk_build
+
+# Detect if we want to build a repository for the SDK
+sdk_repo_goal := $(strip $(filter sdk_repo,$(MAKECMDGOALS)))
+MAKECMDGOALS := $(strip $(filter-out sdk_repo,$(MAKECMDGOALS)))
+
 ifneq ($(words $(filter-out $(INTERNAL_MODIFIER_TARGETS),$(MAKECMDGOALS))),1)
 $(error The 'sdk' target may not be specified with any other targets)
 endif
@@ -828,8 +828,8 @@
 .PHONY: sdk
 ALL_SDK_TARGETS := $(INTERNAL_SDK_TARGET)
 sdk: $(ALL_SDK_TARGETS)
-ifneq ($(filter sdk,$(MAKECMDGOALS)),)
-$(call dist-for-goals,sdk, \
+ifneq ($(filter sdk win_sdk,$(MAKECMDGOALS)),)
+$(call dist-for-goals,sdk win_sdk, \
 	$(ALL_SDK_TARGETS) \
 	$(SYMBOLS_ZIP) \
  )
diff --git a/core/package.mk b/core/package.mk
index 57d6f4b..8ca9033 100644
--- a/core/package.mk
+++ b/core/package.mk
@@ -157,15 +157,9 @@
 endif
 endif
 
-# The dex files go in the package, so we don't
-# want to install them separately for this module.
-old_DONT_INSTALL_DEX_FILES := $(DONT_INSTALL_DEX_FILES)
-DONT_INSTALL_DEX_FILES := true
 #################################
 include $(BUILD_SYSTEM)/java.mk
 #################################
-DONT_INSTALL_DEX_FILES := $(old_DONT_INSTALL_DEX_FILES)
-old_DONT_INSTALL_DEX_FILES =
 
 full_android_manifest := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE)
 $(LOCAL_INTERMEDIATE_TARGETS): \
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index b1b2fc1..8d7667b 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -31,6 +31,7 @@
 TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
 CTS_TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/cts-tradefed.jar
 CTS_TF_EXEC_PATH := $(HOST_OUT_EXECUTABLES)/cts-tradefed
+CTS_TF_README_PATH := $(cts_tools_src_dir)/tradefed-host/README
 
 CTS_CORE_CASE_LIST := \
 	android.core.tests.dom \
@@ -49,7 +50,7 @@
 $(cts_dir)/all_cts_files_stamp: PRIVATE_JUNIT_HOST_JAR := $(junit_host_jar)
 
 -include cts/CtsHostLibraryList.mk
-$(cts_dir)/all_cts_files_stamp: $(CTS_CASE_LIST) $(junit_host_jar) $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(ACP)
+$(cts_dir)/all_cts_files_stamp: $(CTS_CASE_LIST) $(junit_host_jar) $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(CTS_TF_README_PATH) $(ACP)
 # Make necessary directory for CTS
 	$(hide) rm -rf $(PRIVATE_CTS_DIR)
 	$(hide) mkdir -p $(TMP_DIR)
@@ -58,7 +59,7 @@
 	$(hide) mkdir -p $(PRIVATE_DIR)/repository/testcases
 	$(hide) mkdir -p $(PRIVATE_DIR)/repository/plans
 # Copy executable and JARs to CTS directory
-	$(hide) $(ACP) -fp $(CTS_HOST_JAR) $(CTS_EXECUTABLE_PATH) $(DDMLIB_JAR) $(PRIVATE_JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(PRIVATE_DIR)/tools
+	$(hide) $(ACP) -fp $(CTS_HOST_JAR) $(CTS_EXECUTABLE_PATH) $(DDMLIB_JAR) $(PRIVATE_JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(CTS_TF_README_PATH) $(PRIVATE_DIR)/tools
 # Change mode of the executables
 	$(hide) chmod ug+rwX $(PRIVATE_DIR)/tools/$(notdir $(CTS_EXECUTABLE_PATH))
 	$(foreach apk,$(CTS_CASE_LIST), \
diff --git a/core/tasks/sdk-addon.mk b/core/tasks/sdk-addon.mk
index 9133312..e21fedc 100644
--- a/core/tasks/sdk-addon.mk
+++ b/core/tasks/sdk-addon.mk
@@ -94,6 +94,10 @@
 .PHONY: sdk_addon
 sdk_addon: $(full_target)
 
+# Keep the name of the addon final zip around for sdk_repo.
+# This is used by development/build/tools/sdk_repo.mk.
+ADDON_SDK_ZIP := $(full_target)
+
 $(call dist-for-goals, sdk_addon, $(full_target))
 
 else # addon_name
diff --git a/core/user_tags.mk b/core/user_tags.mk
index 1b4ef65..090b7fa 100644
--- a/core/user_tags.mk
+++ b/core/user_tags.mk
@@ -169,7 +169,6 @@
 	jsr305lib \
 	junit \
 	jython \
-	kcm \
 	keystore \
 	kxml2-2.3.0 \
 	launch-wrapper \
@@ -395,7 +394,6 @@
 	logcat \
 	logwrapper \
 	lsd \
-	mahimahi-keypad.kcm \
 	make_cfst \
 	makedict \
 	make_ext4fs \
@@ -446,8 +444,6 @@
 	q2dm \
 	q2g \
 	qemu-android \
-	qwerty2.kcm \
-	qwerty.kcm \
 	racoon \
 	read_addr \
 	read_method \
@@ -489,7 +485,6 @@
 	spec-progress \
 	sqlite3 \
 	stack_dump \
-	stingray-keypad.kcm \
 	stringtemplate \
 	surfaceflinger \
 	svc \
diff --git a/tools/droiddoc/templates-sdk/assets/android-developer-docs.css b/tools/droiddoc/templates-sdk/assets/android-developer-docs.css
index 5e12f45..c8699c5 100644
--- a/tools/droiddoc/templates-sdk/assets/android-developer-docs.css
+++ b/tools/droiddoc/templates-sdk/assets/android-developer-docs.css
@@ -791,7 +791,8 @@
   padding-left:1em;
 }
 
-.new {
+.new,
+.new-child {
   font-size: .78em;
   font-weight: bold;
   color: #ff3d3d;
@@ -800,6 +801,10 @@
   line-height:.9em;
 }
 
+.toggle-list.open .new-child {
+  display:none;
+}
+
 pre.classic {
   background-color:transparent;
   border:none;
diff --git a/tools/kcm/Android.mk b/tools/kcm/Android.mk
deleted file mode 100644
index 130a13a..0000000
--- a/tools/kcm/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-# Copies files into the directory structure described by a manifest
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	kcm.cpp
-
-LOCAL_MODULE := kcm
-
-include $(BUILD_HOST_EXECUTABLE)
-
-
diff --git a/tools/kcm/kcm.cpp b/tools/kcm/kcm.cpp
deleted file mode 100644
index 23ac377..0000000
--- a/tools/kcm/kcm.cpp
+++ /dev/null
@@ -1,421 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <ui/KeycodeLabels.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <map>
-#include <string>
-#include <utils/ByteOrder.h>
-
-using namespace std;
-
-enum {
-    LENDIAN,
-    BENDIAN
-};
-
-/*
- * 1: KeyEvent name
- * 2: display_label
- * 3: number
- * 4..7: base, shift, alt, shift-alt
- */
-#define COLUMNS (3+4)
-
-struct KeyRecord
-{
-    int lineno;
-    int values[COLUMNS];
-};
-
-struct PropValue
-{
-    PropValue() { lineno = -1; }
-    PropValue(const PropValue& that) { lineno=that.lineno; value=that.value; }
-    PropValue(int l, const string& v) { lineno = l; value = v; }
-
-    int lineno;
-    string value;
-};
-
-static int usage();
-
-//  0 -- ok
-// >0 -- error
-static int parse_key_line(const char* filename, int lineno, char* line,
-        KeyRecord* out);
-static int write_kr(int fd, const KeyRecord& kr);
-
-int g_endian;
-
-int
-main(int argc, char** argv)
-{
-    int err;
-    if (argc != 3) {
-        return usage();
-    }
-
-    const char* filename = argv[1];
-    const char* outfilename = argv[2];
-
-    int in = open(filename, O_RDONLY);
-    if (in == -1) {
-        fprintf(stderr, "kcm: error opening file for read: %s\n", filename);
-        return 1;
-    }
-
-    off_t size = lseek(in, 0, SEEK_END);
-    lseek(in, 0, SEEK_SET);
-
-    char* input = (char*)malloc(size+1);
-    read(in, input, size);
-    input[size] = '\0';
-
-    close(in);
-    in = -1;
-
-    map<string,PropValue> properties;
-    map<int,KeyRecord> keys;
-    int errorcount = 0;
-    int lineno = 1;
-    char *thisline = input;
-    while (*thisline) {
-        KeyRecord kr;
-        char *nextline = thisline;
-        
-        while (*nextline != '\0' && *nextline != '\n' && *nextline != '\r') {
-            nextline++;
-        }
-
-        // eat whitespace, but not newlines
-        while (*thisline != '\0' && (*thisline == ' ' || *thisline == '\t')) {
-            thisline++;
-        }
-
-        // find the end of the line
-        char lineend = *nextline;
-        *nextline = '\0';
-        if (lineend == '\r' && nextline[1] == '\n') {
-            nextline++;
-        }
-
-        if (*thisline == '\0' || *thisline == '\r' || *thisline == '\n'
-                 || *thisline == '#') {
-            // comment or blank line
-        }
-        else if (*thisline == '[') {
-            // property - syntax [name=value]
-            // look for =
-            char* prop = thisline+1;
-            char* end = prop;
-            while (*end != '\0' && *end != '=') {
-                end++;
-            }
-            if (*end != '=') {
-                fprintf(stderr, "%s:%d: invalid property line: %s\n",
-                        filename, lineno, thisline);
-                errorcount++;
-            } else {
-                *end = '\0';
-                char* value = end+1;
-                end = nextline;
-                while (end > prop && *end != ']') {
-                    end--;
-                }
-                if (*end != ']') {
-                    fprintf(stderr, "%s:%d: property missing closing ]: %s\n",
-                            filename, lineno, thisline);
-                    errorcount++;
-                } else {
-                    *end = '\0';
-                    properties[prop] = PropValue(lineno, value);
-                }
-            }
-        }
-        else {
-            // key
-            err = parse_key_line(filename, lineno, thisline, &kr);
-            if (err == 0) {
-                kr.lineno = lineno;
-
-                map<int,KeyRecord>::iterator old = keys.find(kr.values[0]);
-                if (old != keys.end()) {
-                    fprintf(stderr, "%s:%d: keycode %d already defined\n",
-                            filename, lineno, kr.values[0]);
-                    fprintf(stderr, "%s:%d: previously defined here\n",
-                            filename, old->second.lineno);
-                    errorcount++;
-                }
-
-                keys[kr.values[0]] = kr;
-            }
-            else if (err > 0) {
-                errorcount += err;
-            }
-        }
-        lineno++;
-
-        nextline++;
-        thisline = nextline;
-
-        if (errorcount > 20) {
-            fprintf(stderr, "%s:%d: too many errors.  stopping.\n", filename,
-                    lineno);
-            return 1;
-        }
-    }
-
-    free(input);
-
-    map<string,PropValue>::iterator sit = properties.find("type");
-    if (sit == properties.end()) {
-        fprintf(stderr, "%s: key character map must contain type property.\n",
-		argv[0]);
-        errorcount++;
-    }
-    PropValue pv = sit->second;
-    unsigned char kbdtype = 0;
-    if (pv.value == "NUMERIC") {
-        kbdtype = 1;
-    }
-    else if (pv.value == "Q14") {
-        kbdtype = 2;
-    }
-    else if (pv.value == "QWERTY") {
-        kbdtype = 3;
-    }
-    else {
-        fprintf(stderr, "%s:%d: keyboard type must be one of NUMERIC, Q14 "
-                " or QWERTY, not %s\n", filename, pv.lineno, pv.value.c_str());
-    }
-
-    if (errorcount != 0) {
-        return 1;
-    }
-
-    int out = open(outfilename, O_RDWR|O_CREAT|O_TRUNC, 0664);
-    if (out == -1) {
-        fprintf(stderr, "kcm: error opening file for write: %s\n", outfilename);
-        return 1;
-    }
-
-    int count = keys.size();
-    
-    map<int,KeyRecord>::iterator it;
-    int n;
-
-    /**
-     * File Format:
-     *    Offset    Description     Value
-     *    0         magic string    "keychar"
-     *    8         endian marker   0x12345678
-     *    12        version         0x00000002
-     *    16        key count       number of key entries
-     *    20        keyboard type   NUMERIC, Q14, QWERTY, etc.
-     *    21        padding         0
-     *    32        the keys
-     */
-    err = write(out, "keychar", 8);
-    if (err == -1) goto bad_write;
-
-    n = htodl(0x12345678);
-    err = write(out, &n, 4);
-    if (err == -1) goto bad_write;
-
-    n = htodl(0x00000002);
-    err = write(out, &n, 4);
-    if (err == -1) goto bad_write;
-
-    n = htodl(count);
-    err = write(out, &n, 4);
-    if (err == -1) goto bad_write;
-
-    err = write(out, &kbdtype, 1);
-    if (err == -1) goto bad_write;
-
-    char zero[11];
-    memset(zero, 0, 11);
-    err = write(out, zero, 11);
-    if (err == -1) goto bad_write;
-
-    for (it = keys.begin(); it != keys.end(); it++) {
-        const KeyRecord& kr = it->second;
-        /*
-        printf("%2d/ [%d] [%d] [%d] [%d] [%d] [%d] [%d]\n", kr.lineno,
-                kr.values[0], kr.values[1], kr.values[2], kr.values[3],
-                kr.values[4], kr.values[5], kr.values[6]);
-        */
-        err = write_kr(out, kr);
-        if (err == -1) goto bad_write;
-    }
-
-    close(out);
-    return 0;
-
-bad_write:
-    fprintf(stderr, "kcm: fatal error writing to file: %s\n", outfilename);
-    close(out);
-    unlink(outfilename);
-    return 1;
-}
-
-static int usage()
-{
-    fprintf(stderr,
-            "usage: kcm INPUT OUTPUT\n"
-            "\n"
-            "INPUT   keycharmap file\n"
-            "OUTPUT  compiled keycharmap file\n"
-        );
-    return 1;
-}
-
-static int
-is_whitespace(const char* p)
-{
-    while (*p) {
-        if (!isspace(*p)) {
-            return 0;
-        }
-        p++;
-    }
-    return 1;
-}
-
-
-static int
-parse_keycode(const char* filename, int lineno, char* str, int* value)
-{
-    const KeycodeLabel *list = KEYCODES;
-    while (list->literal) {
-        if (0 == strcmp(str, list->literal)) {
-            *value = list->value;
-            return 0;
-        }
-        list++;
-    }
-
-    char* endptr;
-    *value = strtol(str, &endptr, 0);
-    if (*endptr != '\0') {
-        fprintf(stderr, "%s:%d: expected keycode label or number near: "
-                "%s\n", filename, lineno, str);
-        return 1;
-    }
-
-    if (*value == 0) {
-        fprintf(stderr, "%s:%d: 0 is not a valid keycode.\n",
-                filename, lineno);
-        return 1;
-    }
-
-    return 0;
-}
-
-static int
-parse_number(const char* filename, int lineno, char* str, int* value)
-{
-    int len = strlen(str);
-
-    if (len == 3 && str[0] == '\'' && str[2] == '\'') {
-        if (str[1] > 0 && str[1] < 127) {
-            *value = (int)str[1];
-            return 0;
-        } else {
-            fprintf(stderr, "%s:%d: only low ascii characters are allowed in"
-                    " quotes near: %s\n", filename, lineno, str);
-            return 1;
-        }
-    }
-
-    char* endptr;
-    *value = strtol(str, &endptr, 0);
-    if (*endptr != '\0') {
-        fprintf(stderr, "%s:%d: expected number or quoted ascii but got: %s\n",
-                filename, lineno, str);
-        return 1;
-    }
-
-    if (*value >= 0xfffe || *value < 0) {
-        fprintf(stderr, "%s:%d: unicode char out of range (no negatives, "
-                "nothing larger than 0xfffe): %s\n", filename, lineno, str);
-        return 1;
-    }
-
-    return 0;
-}
-
-static int
-parse_key_line(const char* filename, int lineno, char* line, KeyRecord* out)
-{
-    char* p = line;
-
-    int len = strlen(line);
-    char* s[COLUMNS];
-    for (int i=0; i<COLUMNS; i++) {
-        s[i] = (char*)malloc(len+1);
-    }
-
-    for (int i = 0; i < COLUMNS; i++) {
-        while (*p != '\0' && isspace(*p)) {
-            p++;
-        }
-
-        if (*p == '\0') {
-            fprintf(stderr, "%s:%d: not enough on this line: %s\n", filename,
-                    lineno, line);
-            return 1;
-        }
-
-        char *p1 = p;
-        while (*p != '\0' && !isspace(*p)) {
-            p++;
-        }
-
-        memcpy(s[i], p1, p - p1);
-        s[i][p - p1] = '\0';
-    }
-
-    while (*p != '\0' && isspace(*p)) {
-        *p++;
-    }
-    if (*p != '\0') {
-        fprintf(stderr, "%s:%d: too much on one line near: %s\n", filename,
-                lineno, p);
-        fprintf(stderr, "%s:%d: -->%s<--\n", filename, lineno, line);
-        return 1;
-    }
-
-    int errorcount = parse_keycode(filename, lineno, s[0], &out->values[0]);
-    for (int i=1; i<COLUMNS && errorcount == 0; i++) {
-        errorcount += parse_number(filename, lineno, s[i], &out->values[i]);
-    }
-
-    return errorcount;
-}
-
-struct WrittenRecord
-{
-    unsigned int keycode;       // 4 bytes
-    unsigned short values[COLUMNS - 1];   // 6*2 bytes = 12
-                                // 16 bytes total 
-};
-
-static int
-write_kr(int fd, const KeyRecord& kr)
-{
-    WrittenRecord wr;
-
-    wr.keycode = htodl(kr.values[0]);
-    for (int i=0; i<COLUMNS - 1; i++) {
-        wr.values[i] = htods(kr.values[i+1]);
-    }
-
-    return write(fd, &wr, sizeof(WrittenRecord));
-}
-