Send commitlog mailing list submissions to
        commitlog@lists.openmoko.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://lists.openmoko.org/mailman/listinfo/commitlog
or, via email, send a message with subject or body 'help' to
        commitlog-requ...@lists.openmoko.org

You can reach the person managing the list at
        commitlog-ow...@lists.openmoko.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of commitlog digest..."
Today's Topics:

   1. r5416 - trunk/eda/fped (wer...@docs.openmoko.org)
--- Begin Message ---
Author: werner
Date: 2009-08-10 23:02:26 +0200 (Mon, 10 Aug 2009)
New Revision: 5416

Added:
   trunk/eda/fped/dump.c
   trunk/eda/fped/kicad.c
   trunk/eda/fped/kicad.h
Removed:
   trunk/eda/fped/dump.c
Modified:
   trunk/eda/fped/Makefile
   trunk/eda/fped/TODO
   trunk/eda/fped/coord.h
   trunk/eda/fped/gui.c
   trunk/eda/fped/inst.c
   trunk/eda/fped/inst.h
Log:
- added KiCad output
- when saving a file, we now make a backup of any existing file with the same
  name



Modified: trunk/eda/fped/Makefile
===================================================================
--- trunk/eda/fped/Makefile     2009-08-10 15:13:07 UTC (rev 5415)
+++ trunk/eda/fped/Makefile     2009-08-10 21:02:26 UTC (rev 5416)
@@ -11,7 +11,7 @@
 #
 
 OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \
-       unparse.o dump.o meas.o \
+       unparse.o dump.o kicad.o meas.o \
        cpp.o lex.yy.o y.tab.o \
        gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \
        gui_tool.o gui_over.o gui_meas.o gui_frame.o

Modified: trunk/eda/fped/TODO
===================================================================
--- trunk/eda/fped/TODO 2009-08-10 15:13:07 UTC (rev 5415)
+++ trunk/eda/fped/TODO 2009-08-10 21:02:26 UTC (rev 5416)
@@ -2,7 +2,6 @@
 - populate input area (still needed: mm/mil, rezoom)
 - add default unit (combine with grid unit selection ?)
 - consider adding auto/mm/mil selection for each dimension
-- add KiCad output
 - add postscript output
 - add option to include/omit helper vecs and frames (done for display, still
   need postscript)

Modified: trunk/eda/fped/coord.h
===================================================================
--- trunk/eda/fped/coord.h      2009-08-10 15:13:07 UTC (rev 5415)
+++ trunk/eda/fped/coord.h      2009-08-10 21:02:26 UTC (rev 5416)
@@ -20,7 +20,7 @@
 #define MICRON_UNITS   10
 #define        MIL_UNITS       (25.4*MICRON_UNITS)
 #define        MM_UNITS        (1000.0*MICRON_UNITS)
-#define        KICAD_UNIT      (10.0*MIL_UNITS)
+#define        KICAD_UNIT      (MIL_UNITS/10.0)
 
 #define        MIL_IN_MM       0.0254
 
@@ -54,7 +54,7 @@
 }
 
 
-static inline double units_to_kicad(unit_type u)
+static inline int units_to_kicad(unit_type u)
 {
        return (double) u/KICAD_UNIT;
 }

Deleted: trunk/eda/fped/dump.c
===================================================================
--- trunk/eda/fped/dump.c       2009-08-10 15:13:07 UTC (rev 5415)
+++ trunk/eda/fped/dump.c       2009-08-10 21:02:26 UTC (rev 5416)
@@ -1,396 +0,0 @@
-/*
- * dump.c - Dump objects in the native FPD format
- *
- * Written 2009 by Werner Almesberger
- * Copyright 2009 by Werner Almesberger
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "util.h"
-#include "unparse.h"
-#include "obj.h"
-#include "dump.h"
-
-
-/* ----- variables --------------------------------------------------------- */
-
-
-static void dump_var(FILE *file, const struct table *table,
-    const char *indent)
-{
-       char *s;
-
-       s = unparse(table->rows->values->expr);
-       fprintf(file, "%sset %s = %s\n\n", indent, table->vars->name, s);
-       free(s);
-}
-
-
-static void dump_table(FILE *file, const struct table *table,
-    const char *indent)
-{
-       const struct var *var;
-       const struct row *row;
-       const struct value *value;
-       char *s;
-
-       if (table->vars && !table->vars->next &&
-           table->rows && !table->rows->next) {
-               dump_var(file, table, indent);
-               return;
-       }
-       fprintf(file, "%stable\n%s    {", indent, indent);
-       for (var = table->vars; var; var = var->next)
-               fprintf(file, "%s %s", var == table->vars ? "" : ",",
-                   var->name);
-       fprintf(file, " }\n");
-       for (row = table->rows; row; row = row->next) {
-               fprintf(file, "%s    {", indent);
-               for (value = row->values; value; value = value->next) {
-                       s = unparse(value->expr);
-                       fprintf(file, "%s %s",
-                           value == row->values? "" : ",", s);
-                       free(s);
-               }
-               fprintf(file, " }\n");
-       }
-       fprintf(file, "\n");
-}
-
-
-static void dump_loop(FILE *file, const struct loop *loop, const char *indent)
-{
-       char *from, *to;
-
-       from = unparse(loop->from.expr);
-       to = unparse(loop->to.expr);
-       fprintf(file, "%sloop %s = %s, %s\n\n",
-           indent, loop->var.name, from, to);
-       free(from);
-       free(to);
-}
-
-
-/* ----- vectors and objects ----------------------------------------------- */
-
-
-static char *generate_name(const struct vec *base)
-{
-       const struct vec *walk;
-       int n;
-
-       n = 0;
-       for (walk = base->frame->vecs; walk != base; walk = walk->next)
-               n++;
-       return stralloc_printf("_%s_%d",
-           base->frame->name ? base->frame->name : "", n);
-}
-
-
-static char *base_name(const struct vec *base, const struct vec *next)
-{
-       if (!base)
-               return stralloc("@");
-       if (next && base->next == next)
-               return stralloc(".");
-       if (base->name)
-               return stralloc(base->name);
-       return generate_name(base);
-}
-
-
-static char *obj_base_name(const struct vec *base, const struct vec *prev)
-{
-       if (base && base == prev)
-               return stralloc(".");
-       return base_name(base, NULL);
-}
-
-
-static int n_vec_refs(const struct vec *vec)
-{
-       const struct vec *walk;
-       int n;
-
-       n = 0;
-       for (walk = vec->frame->vecs; walk; walk = walk->next)
-               if (walk->base == vec)
-                       n++;
-       return n;
-}
-
-
-/*
- * "need" operates in two modes:
- *
- * - if "prev" is non-NULL, we're looking for objects that need to be put after
- *   the current vector (in "prev"). Only those objects need to be put there
- *   that have at least one base that isn't the frame's origin or already has a
- *   name.
- *
- * - if "prev" is NULL, we're at the end of the frame. We have already used all
- *   the . references we could, so now we have to find out which objects
- *   haven't been dumped yet. "need" still returns the ones that had a need to
- *   be dumped. Again, that's those that have at least one possible "." base.
- *   Since this "." base will have been used by now, the object must have been
- *   dumped.
- */
-
-static int need(const struct vec *base, const struct vec *prev)
-{
-       if (!base)
-               return 0;
-       if (base->name)
-               return 0;
-       if (prev)
-               return base == prev;
-       return 1;
-}
-
-
-/*
- * If we need a vector that's defined later, we have to defer dumping the
- * object.
- */
-
-static int later(const struct vec *base, const struct vec *prev)
-{
-       while (prev) {
-               if (base == prev)
-                       return 1;
-               prev = prev->next;
-       }
-       return 0;
-}
-
-
-static int may_dump_obj_now(const struct obj *obj, const struct vec *prev)
-{
-       int n, l;
-
-       n = need(obj->base, prev);
-       l = later(obj->base, prev);
-
-       switch (obj->type) {
-       case ot_frame:
-               break;
-       case ot_line:
-               n |= need(obj->u.line.other, prev);
-               l |= later(obj->u.line.other, prev);
-               break;
-       case ot_rect:
-               n |= need(obj->u.rect.other, prev);
-               l |= later(obj->u.rect.other, prev);
-               break;
-       case ot_pad:
-               n |= need(obj->u.pad.other, prev);
-               l |= later(obj->u.pad.other, prev);
-               break;
-       case ot_arc:
-               n |= need(obj->u.arc.start, prev);
-               n |= need(obj->u.arc.end, prev);
-               l |= later(obj->u.arc.start, prev);
-               l |= later(obj->u.arc.end, prev);
-               break;
-       case ot_meas:
-               return 0;
-       default:
-               abort();
-       }
-
-       return n && !l;
-}
-
-
-static const char *meas_type_name[mt_n] = {
-       "meas", "measx", "measy",
-       "meas", "measx", "measy",
-};
-
-
-
-static void print_meas_base(FILE *file, struct vec *base)
-{
-       if (base->frame != root_frame)
-               fprintf(file, "%s.", base->frame->name);
-       fprintf(file, "%s", base->name);
-}
-
-
-static void dump_obj(FILE *file, struct obj *obj, const char *indent,
-    const struct vec *prev)
-{
-       char *base, *s1, *s2, *s3;
-
-       if (obj->dumped)
-               return;
-       obj->dumped = 1;
-       base = obj_base_name(obj->base, prev);
-       switch (obj->type) {
-       case ot_frame:
-               fprintf(file, "%sframe %s %s\n",
-                   indent, obj->u.frame.ref->name, base);
-               break;
-       case ot_line:
-               s1 = obj_base_name(obj->u.line.other, prev);
-               s2 = unparse(obj->u.line.width);
-               fprintf(file, "%sline %s %s %s\n", indent, base, s1, s2);
-               free(s1);
-               free(s2);
-               break;
-       case ot_rect:
-               s1 = obj_base_name(obj->u.rect.other, prev);
-               s2 = unparse(obj->u.rect.width);
-               fprintf(file, "%srect %s %s %s\n", indent, base, s1, s2);
-               free(s1);
-               free(s2);
-               break;
-       case ot_pad:
-               s1 = obj_base_name(obj->u.pad.other, prev);
-               fprintf(file, "%spad \"%s\" %s %s\n", indent,
-                   obj->u.pad.name, base, s1);
-               free(s1);
-               break;
-       case ot_arc:
-               s1 = obj_base_name(obj->u.arc.start, prev);
-               s3 = unparse(obj->u.arc.width);
-               if (obj->u.arc.start == obj->u.arc.end) {
-                       fprintf(file, "%scirc %s %s %s\n",
-                           indent, base, s1, s3);
-               } else {
-                       s2 = obj_base_name(obj->u.arc.end, prev);
-                       fprintf(file, "%sarc %s %s %s %s\n", indent,
-                           base, s1, s2, s3);
-                       free(s2);
-               }
-               free(s1);
-               free(s3);
-               break;
-       case ot_meas:
-               fprintf(file, "%s%s ", indent,
-                   meas_type_name[obj->u.meas.type]);
-               if (obj->u.meas.label)
-                       fprintf(file, "\"%s\" ", obj->u.meas.label);
-               print_meas_base(file, obj->base);
-               fprintf(file, " %s ",
-                   obj->u.meas.type < 3 ? obj->u.meas.inverted ? "<-" : "->" :
-                   obj->u.meas.inverted ? "<<" : ">>");
-               print_meas_base(file, obj->u.meas.high);
-               if (!obj->u.meas.offset)
-                       fprintf(file, "\n");
-               else {
-                       s1 = unparse(obj->u.meas.offset);
-                       fprintf(file, " %s\n", s1);
-                       free(s1);
-               }
-               break;
-       default:
-               abort();
-       }
-       free(base);
-}
-
-
-/*
- * Tricky logic ahead: when dumping a vector, we search for a vectors that
- * depends on that vector for ".". If we find one, we dump it immediately after
- * this vector.
- */
-
-static void recurse_vec(FILE *file, const struct vec *vec, const char *indent)
-{
-       const struct vec *next;
-       struct obj *obj;
-       char *base, *x, *y, *s;
-
-       base = base_name(vec->base, vec);
-       x = unparse(vec->x);
-       y = unparse(vec->y);
-       if (vec->name)
-               fprintf(file, "%s%s: vec %s(%s, %s)\n",
-                   indent, vec->name, base, x, y);
-       else {
-               s = generate_name(vec);
-               fprintf(file, "%s%s: vec %s(%s, %s)\n", indent, s, base, x, y);
-               free(s);
-       }
-       free(base);
-       free(x);
-       free(y);
-
-       for (obj = vec->frame->objs; obj; obj = obj->next)
-               if (may_dump_obj_now(obj, vec))
-                       dump_obj(file, obj, indent, vec);
-       if (n_vec_refs(vec) == 1) {
-               for (next = vec->next; next->base != vec; next = next->next);
-               recurse_vec(file, next, indent);
-       }
-}
-
-
-static void dump_vecs(FILE *file, const struct vec *vecs, const char *indent)
-{
-       const struct vec *vec;
-
-       for (vec = vecs; vec; vec = vec->next)
-               if (!vec->base || n_vec_refs(vec->base) != 1)
-                       recurse_vec(file, vec, indent);
-}
-
-
-/* ----- frames ------------------------------------------------------------ */
-
-
-static void dump_frame(FILE *file, const struct frame *frame,
-    const char *indent)
-{
-       const struct table *table;
-       const struct loop *loop;
-       struct obj *obj;
-
-       for (table = frame->tables; table; table = table->next)
-               dump_table(file, table, indent);
-       for (loop = frame->loops; loop; loop = loop->next)
-               dump_loop(file, loop, indent);
-       for (obj = frame->objs; obj; obj = obj->next)
-               obj->dumped = 0;
-       dump_vecs(file, frame->vecs, indent);
-
-       /* frames based on @ (anything else ?) */
-       for (obj = frame->objs; obj; obj = obj->next)
-               if (obj->type != ot_meas)
-                       dump_obj(file, obj, indent, NULL);
-       for (obj = frame->objs; obj; obj = obj->next)
-               dump_obj(file, obj, indent, NULL);
-}
-
-
-/* ----- file -------------------------------------------------------------- */
-
-
-int dump(FILE *file)
-{
-       const struct frame *frame;
-
-       fprintf(file, "/* MACHINE-GENERATED ! */\n\n");
-       for (frame = frames; frame; frame = frame->next) {
-               if (!frame->name) {
-                       fprintf(file, "part \"%s\"\n", part_name);
-                       dump_frame(file, frame, "");
-               } else {
-                       fprintf(file, "frame %s {\n", frame->name);
-                       dump_frame(file, frame, "\t");
-                       fprintf(file, "}\n\n");
-               }
-       }
-       fflush(file);
-       return !ferror(file);
-}

Added: trunk/eda/fped/dump.c
===================================================================
--- trunk/eda/fped/dump.c                               (rev 0)
+++ trunk/eda/fped/dump.c       2009-08-10 21:02:26 UTC (rev 5416)
@@ -0,0 +1,396 @@
+/*
+ * dump.c - Dump objects in the native FPD format
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "util.h"
+#include "unparse.h"
+#include "obj.h"
+#include "dump.h"
+
+
+/* ----- variables --------------------------------------------------------- */
+
+
+static void dump_var(FILE *file, const struct table *table,
+    const char *indent)
+{
+       char *s;
+
+       s = unparse(table->rows->values->expr);
+       fprintf(file, "%sset %s = %s\n\n", indent, table->vars->name, s);
+       free(s);
+}
+
+
+static void dump_table(FILE *file, const struct table *table,
+    const char *indent)
+{
+       const struct var *var;
+       const struct row *row;
+       const struct value *value;
+       char *s;
+
+       if (table->vars && !table->vars->next &&
+           table->rows && !table->rows->next) {
+               dump_var(file, table, indent);
+               return;
+       }
+       fprintf(file, "%stable\n%s    {", indent, indent);
+       for (var = table->vars; var; var = var->next)
+               fprintf(file, "%s %s", var == table->vars ? "" : ",",
+                   var->name);
+       fprintf(file, " }\n");
+       for (row = table->rows; row; row = row->next) {
+               fprintf(file, "%s    {", indent);
+               for (value = row->values; value; value = value->next) {
+                       s = unparse(value->expr);
+                       fprintf(file, "%s %s",
+                           value == row->values? "" : ",", s);
+                       free(s);
+               }
+               fprintf(file, " }\n");
+       }
+       fprintf(file, "\n");
+}
+
+
+static void dump_loop(FILE *file, const struct loop *loop, const char *indent)
+{
+       char *from, *to;
+
+       from = unparse(loop->from.expr);
+       to = unparse(loop->to.expr);
+       fprintf(file, "%sloop %s = %s, %s\n\n",
+           indent, loop->var.name, from, to);
+       free(from);
+       free(to);
+}
+
+
+/* ----- vectors and objects ----------------------------------------------- */
+
+
+static char *generate_name(const struct vec *base)
+{
+       const struct vec *walk;
+       int n;
+
+       n = 0;
+       for (walk = base->frame->vecs; walk != base; walk = walk->next)
+               n++;
+       return stralloc_printf("_%s_%d",
+           base->frame->name ? base->frame->name : "", n);
+}
+
+
+static char *base_name(const struct vec *base, const struct vec *next)
+{
+       if (!base)
+               return stralloc("@");
+       if (next && base->next == next)
+               return stralloc(".");
+       if (base->name)
+               return stralloc(base->name);
+       return generate_name(base);
+}
+
+
+static char *obj_base_name(const struct vec *base, const struct vec *prev)
+{
+       if (base && base == prev)
+               return stralloc(".");
+       return base_name(base, NULL);
+}
+
+
+static int n_vec_refs(const struct vec *vec)
+{
+       const struct vec *walk;
+       int n;
+
+       n = 0;
+       for (walk = vec->frame->vecs; walk; walk = walk->next)
+               if (walk->base == vec)
+                       n++;
+       return n;
+}
+
+
+/*
+ * "need" operates in two modes:
+ *
+ * - if "prev" is non-NULL, we're looking for objects that need to be put after
+ *   the current vector (in "prev"). Only those objects need to be put there
+ *   that have at least one base that isn't the frame's origin or already has a
+ *   name.
+ *
+ * - if "prev" is NULL, we're at the end of the frame. We have already used all
+ *   the . references we could, so now we have to find out which objects
+ *   haven't been dumped yet. "need" still returns the ones that had a need to
+ *   be dumped. Again, that's those that have at least one possible "." base.
+ *   Since this "." base will have been used by now, the object must have been
+ *   dumped.
+ */
+
+static int need(const struct vec *base, const struct vec *prev)
+{
+       if (!base)
+               return 0;
+       if (base->name)
+               return 0;
+       if (prev)
+               return base == prev;
+       return 1;
+}
+
+
+/*
+ * If we need a vector that's defined later, we have to defer dumping the
+ * object.
+ */
+
+static int later(const struct vec *base, const struct vec *prev)
+{
+       while (prev) {
+               if (base == prev)
+                       return 1;
+               prev = prev->next;
+       }
+       return 0;
+}
+
+
+static int may_dump_obj_now(const struct obj *obj, const struct vec *prev)
+{
+       int n, l;
+
+       n = need(obj->base, prev);
+       l = later(obj->base, prev);
+
+       switch (obj->type) {
+       case ot_frame:
+               break;
+       case ot_line:
+               n |= need(obj->u.line.other, prev);
+               l |= later(obj->u.line.other, prev);
+               break;
+       case ot_rect:
+               n |= need(obj->u.rect.other, prev);
+               l |= later(obj->u.rect.other, prev);
+               break;
+       case ot_pad:
+               n |= need(obj->u.pad.other, prev);
+               l |= later(obj->u.pad.other, prev);
+               break;
+       case ot_arc:
+               n |= need(obj->u.arc.start, prev);
+               n |= need(obj->u.arc.end, prev);
+               l |= later(obj->u.arc.start, prev);
+               l |= later(obj->u.arc.end, prev);
+               break;
+       case ot_meas:
+               return 0;
+       default:
+               abort();
+       }
+
+       return n && !l;
+}
+
+
+static const char *meas_type_name[mt_n] = {
+       "meas", "measx", "measy",
+       "meas", "measx", "measy",
+};
+
+
+
+static void print_meas_base(FILE *file, struct vec *base)
+{
+       if (base->frame != root_frame)
+               fprintf(file, "%s.", base->frame->name);
+       fprintf(file, "%s", base->name);
+}
+
+
+static void dump_obj(FILE *file, struct obj *obj, const char *indent,
+    const struct vec *prev)
+{
+       char *base, *s1, *s2, *s3;
+
+       if (obj->dumped)
+               return;
+       obj->dumped = 1;
+       base = obj_base_name(obj->base, prev);
+       switch (obj->type) {
+       case ot_frame:
+               fprintf(file, "%sframe %s %s\n",
+                   indent, obj->u.frame.ref->name, base);
+               break;
+       case ot_line:
+               s1 = obj_base_name(obj->u.line.other, prev);
+               s2 = unparse(obj->u.line.width);
+               fprintf(file, "%sline %s %s %s\n", indent, base, s1, s2);
+               free(s1);
+               free(s2);
+               break;
+       case ot_rect:
+               s1 = obj_base_name(obj->u.rect.other, prev);
+               s2 = unparse(obj->u.rect.width);
+               fprintf(file, "%srect %s %s %s\n", indent, base, s1, s2);
+               free(s1);
+               free(s2);
+               break;
+       case ot_pad:
+               s1 = obj_base_name(obj->u.pad.other, prev);
+               fprintf(file, "%spad \"%s\" %s %s\n", indent,
+                   obj->u.pad.name, base, s1);
+               free(s1);
+               break;
+       case ot_arc:
+               s1 = obj_base_name(obj->u.arc.start, prev);
+               s3 = unparse(obj->u.arc.width);
+               if (obj->u.arc.start == obj->u.arc.end) {
+                       fprintf(file, "%scirc %s %s %s\n",
+                           indent, base, s1, s3);
+               } else {
+                       s2 = obj_base_name(obj->u.arc.end, prev);
+                       fprintf(file, "%sarc %s %s %s %s\n", indent,
+                           base, s1, s2, s3);
+                       free(s2);
+               }
+               free(s1);
+               free(s3);
+               break;
+       case ot_meas:
+               fprintf(file, "%s%s ", indent,
+                   meas_type_name[obj->u.meas.type]);
+               if (obj->u.meas.label)
+                       fprintf(file, "\"%s\" ", obj->u.meas.label);
+               print_meas_base(file, obj->base);
+               fprintf(file, " %s ",
+                   obj->u.meas.type < 3 ? obj->u.meas.inverted ? "<-" : "->" :
+                   obj->u.meas.inverted ? "<<" : ">>");
+               print_meas_base(file, obj->u.meas.high);
+               if (!obj->u.meas.offset)
+                       fprintf(file, "\n");
+               else {
+                       s1 = unparse(obj->u.meas.offset);
+                       fprintf(file, " %s\n", s1);
+                       free(s1);
+               }
+               break;
+       default:
+               abort();
+       }
+       free(base);
+}
+
+
+/*
+ * Tricky logic ahead: when dumping a vector, we search for a vectors that
+ * depends on that vector for ".". If we find one, we dump it immediately after
+ * this vector.
+ */
+
+static void recurse_vec(FILE *file, const struct vec *vec, const char *indent)
+{
+       const struct vec *next;
+       struct obj *obj;
+       char *base, *x, *y, *s;
+
+       base = base_name(vec->base, vec);
+       x = unparse(vec->x);
+       y = unparse(vec->y);
+       if (vec->name)
+               fprintf(file, "%s%s: vec %s(%s, %s)\n",
+                   indent, vec->name, base, x, y);
+       else {
+               s = generate_name(vec);
+               fprintf(file, "%s%s: vec %s(%s, %s)\n", indent, s, base, x, y);
+               free(s);
+       }
+       free(base);
+       free(x);
+       free(y);
+
+       for (obj = vec->frame->objs; obj; obj = obj->next)
+               if (may_dump_obj_now(obj, vec))
+                       dump_obj(file, obj, indent, vec);
+       if (n_vec_refs(vec) == 1) {
+               for (next = vec->next; next->base != vec; next = next->next);
+               recurse_vec(file, next, indent);
+       }
+}
+
+
+static void dump_vecs(FILE *file, const struct vec *vecs, const char *indent)
+{
+       const struct vec *vec;
+
+       for (vec = vecs; vec; vec = vec->next)
+               if (!vec->base || n_vec_refs(vec->base) != 1)
+                       recurse_vec(file, vec, indent);
+}
+
+
+/* ----- frames ------------------------------------------------------------ */
+
+
+static void dump_frame(FILE *file, const struct frame *frame,
+    const char *indent)
+{
+       const struct table *table;
+       const struct loop *loop;
+       struct obj *obj;
+
+       for (table = frame->tables; table; table = table->next)
+               dump_table(file, table, indent);
+       for (loop = frame->loops; loop; loop = loop->next)
+               dump_loop(file, loop, indent);
+       for (obj = frame->objs; obj; obj = obj->next)
+               obj->dumped = 0;
+       dump_vecs(file, frame->vecs, indent);
+
+       /* frames based on @ (anything else ?) */
+       for (obj = frame->objs; obj; obj = obj->next)
+               if (obj->type != ot_meas)
+                       dump_obj(file, obj, indent, NULL);
+       for (obj = frame->objs; obj; obj = obj->next)
+               dump_obj(file, obj, indent, NULL);
+}
+
+
+/* ----- file -------------------------------------------------------------- */
+
+
+int dump(FILE *file)
+{
+       const struct frame *frame;
+
+       fprintf(file, "/* MACHINE-GENERATED ! */\n\n");
+       for (frame = frames; frame; frame = frame->next) {
+               if (!frame->name) {
+                       fprintf(file, "part \"%s\"\n", part_name);
+                       dump_frame(file, frame, "");
+               } else {
+                       fprintf(file, "frame %s {\n", frame->name);
+                       dump_frame(file, frame, "\t");
+                       fprintf(file, "}\n\n");
+               }
+       }
+       fflush(file);
+       return !ferror(file);
+}

Modified: trunk/eda/fped/gui.c
===================================================================
--- trunk/eda/fped/gui.c        2009-08-10 15:13:07 UTC (rev 5415)
+++ trunk/eda/fped/gui.c        2009-08-10 21:02:26 UTC (rev 5416)
@@ -12,11 +12,16 @@
 
 
 #include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
 #include <gtk/gtk.h>
 
+#include "util.h"
 #include "inst.h"
 #include "obj.h"
 #include "dump.h"
+#include "kicad.h"
 #include "gui_util.h"
 #include "gui_style.h"
 #include "gui_status.h"
@@ -46,27 +51,98 @@
 /* ----- menu bar ---------------------------------------------------------- */
 
 
-static void menu_save(GtkWidget *widget, gpointer user)
+static char *set_extension(const char *name, const char *ext)
 {
+       char *s = stralloc(name);
+       char *slash, *dot;
+       char *res;
+
+       slash = strrchr(s, '/');
+       dot = strrchr(slash ? slash : s, '.');
+       if (dot)
+               *dot = 0;
+       res = stralloc_printf("%s.%s", s, ext);
+       free(s);
+       return res;
+}
+
+
+static void save_with_backup(const char *name, int (*fn)(FILE *file))
+{
        FILE *file;
+       char *s = stralloc(name);
+       char *slash, *dot, *tmp;
+       int n;
+       struct stat st;
 
-       if (!save_file) {
-               if (!dump(stdout))
-                       perror("stdout");
-               return;
+       slash = strrchr(s, '/');
+       dot = strrchr(slash ? slash : s, '.');
+       if (dot)
+               *dot = 0;
+       n = 0;
+       while (1) {
+               tmp = stralloc_printf("%s~%d%s%s",
+                   s, n, dot ? "." : "", dot ? dot+1 : "");
+               if (stat(tmp, &st) < 0) {
+                       if (errno == ENOENT)
+                               break;
+                       perror(tmp);
+                       free(tmp);
+                       return;
+               }
+               free(tmp);
+               n++;
        }
-       file = fopen(save_file, "w");
+       if (rename(name, tmp) < 0) {
+               if (errno != ENOENT) {
+                       perror(name);
+                       free(tmp);
+                       return;
+               }
+       } else {
+               fprintf(stderr, "renamed %s to %s\n", name, tmp);
+       }
+       free(tmp);
+
+       file = fopen(name, "w");
        if (!file) {
-               perror(save_file);
+               perror(name);
                return;
        }
-       if (!dump(file))
-               perror(save_file);
+       if (!fn(file))
+               perror(name);
        if (fclose(file) == EOF)
-               perror(save_file);
+               perror(name);
+       fprintf(stderr, "saved to %s\n", name);
 }
 
 
+static void menu_save(GtkWidget *widget, gpointer user)
+{
+       if (save_file)
+               save_with_backup(save_file, dump);
+       else {
+               if (!dump(stdout))
+                       perror("stdout");
+       }
+}
+
+
+static void menu_save_kicad(GtkWidget *widget, gpointer user)
+{
+       char *name;
+
+       if (save_file) {
+               name = set_extension(save_file, "mod");
+               save_with_backup(name, kicad);
+               free(name);
+       } else {
+               if (!kicad(stdout))
+                       perror("stdout");
+       }
+}
+
+
 static void make_menu_bar(GtkWidget *hbox)
 {
        GtkWidget *bar;
@@ -86,6 +162,11 @@
        g_signal_connect(G_OBJECT(save), "activate",
            G_CALLBACK(menu_save), NULL);
 
+       save = gtk_menu_item_new_with_label("Save as KiCad");
+       gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), save);
+       g_signal_connect(G_OBJECT(save), "activate",
+           G_CALLBACK(menu_save_kicad), NULL);
+
        quit = gtk_menu_item_new_with_label("Quit");
        gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), quit);
        g_signal_connect(G_OBJECT(quit), "activate",

Modified: trunk/eda/fped/inst.c
===================================================================
--- trunk/eda/fped/inst.c       2009-08-10 15:13:07 UTC (rev 5415)
+++ trunk/eda/fped/inst.c       2009-08-10 21:02:26 UTC (rev 5416)
@@ -29,39 +29,12 @@
 #include "inst.h"
 
 
-enum inst_prio {
-       ip_frame,       /* frames have their own selection */
-       ip_pad,         /* pads also accept clicks inside */
-       ip_circ,        /* circles don't overlap easily */
-       ip_arc,         /* arc are like circles, just shorter */
-       ip_rect,        /* rectangles have plenty of sides */
-       ip_meas,        /* mesurements are like lines but set a bit apart */
-       ip_line,        /* lines are easly overlapped by other things */
-       ip_vec,         /* vectors only have the end point */
-       ip_n,           /* number of priorities */
-};
-
-
-#define FOR_INST_PRIOS_UP(prio)                                        \
-       for (prio = 0; prio != ip_n; prio++)
-
-#define FOR_INST_PRIOS_DOWN(prio)                              \
-       for (prio = ip_n-1; prio != (enum inst_prio) -1; prio--)
-
-#define        FOR_INSTS_UP(prio, inst)                                \
-       FOR_INST_PRIOS_UP(prio)                                 \
-               for (inst = insts[prio]; inst; inst = inst->next)
-
-#define        FOR_INSTS_DOWN(prio, inst)                              \
-       FOR_INST_PRIOS_DOWN(prio)                               \
-               for (inst = insts[prio]; inst; inst = inst->next)
-
-
 struct inst *selected_inst = NULL;
+struct inst *insts[ip_n];
 struct bbox active_frame_bbox;
 
 static struct inst *curr_frame = NULL;
-static struct inst *insts[ip_n], **next_inst[ip_n];
+static struct inst **next_inst[ip_n];
 static struct inst *prev_insts[ip_n];
 
 static unsigned long active_set = 0;

Modified: trunk/eda/fped/inst.h
===================================================================
--- trunk/eda/fped/inst.h       2009-08-10 15:13:07 UTC (rev 5415)
+++ trunk/eda/fped/inst.h       2009-08-10 21:02:26 UTC (rev 5416)
@@ -36,8 +36,23 @@
        struct coord max;
 };
 
+
+enum inst_prio {
+       ip_frame,       /* frames have their own selection */
+       ip_pad,         /* pads also accept clicks inside */
+       ip_circ,        /* circles don't overlap easily */
+       ip_arc,         /* arc are like circles, just shorter */
+       ip_rect,        /* rectangles have plenty of sides */
+       ip_meas,        /* mesurements are like lines but set a bit apart */
+       ip_line,        /* lines are easly overlapped by other things */
+       ip_vec,         /* vectors only have the end point */
+       ip_n,           /* number of priorities */
+};
+
+
 struct inst;
 
+
 struct inst_ops {
        void (*debug)(struct inst *self);
        void (*save)(FILE *file, struct inst *self);
@@ -95,9 +110,25 @@
 
 
 extern struct inst *selected_inst;
+extern struct inst *insts[ip_n];
 extern struct bbox active_frame_bbox;
 
 
+#define FOR_INST_PRIOS_UP(prio)                                        \
+       for (prio = 0; prio != ip_n; prio++)
+
+#define FOR_INST_PRIOS_DOWN(prio)                              \
+       for (prio = ip_n-1; prio != (enum inst_prio) -1; prio--)
+
+#define        FOR_INSTS_UP(prio, inst)                                \
+       FOR_INST_PRIOS_UP(prio)                                 \
+               for (inst = insts[prio]; inst; inst = inst->next)
+
+#define        FOR_INSTS_DOWN(prio, inst)                              \
+       FOR_INST_PRIOS_DOWN(prio)                               \
+               for (inst = insts[prio]; inst; inst = inst->next)
+
+
 void inst_select_outside(void *item, void (*deselect)(void *item));
 int inst_select(struct coord pos);
 void inst_deselect(void);

Added: trunk/eda/fped/kicad.c
===================================================================
--- trunk/eda/fped/kicad.c                              (rev 0)
+++ trunk/eda/fped/kicad.c      2009-08-10 21:02:26 UTC (rev 5416)
@@ -0,0 +1,260 @@
+/*
+ * kicad.c - Dump objects in the KiCad board/module format
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#include <stdio.h>
+#include <time.h>
+
+#include "coord.h"
+#include "inst.h"
+#include "kicad.h"
+
+
+enum kicad_layer {
+       layer_bottom,           /* "copper" */
+       layer_l15,
+       layer_l14,
+       layer_l13,
+       layer_l12,
+       layer_l11,
+       layer_l10,
+       layer_l9,
+       layer_l8,
+       layer_l7,
+       layer_l6,
+       layer_l5,
+       layer_l4,
+       layer_l3,
+       layer_l2,
+       layer_top,              /* "component" */
+       layer_glue_bottom,      /* adhesive, copper side */
+       layer_glue_top,         /* adhesive, component side */
+       layer_paste_bottom,     /* solder paste */
+       layer_paste_top,
+       layer_silk_bottom,      /* silk screen */
+       layer_silk_top,
+       layer_mask_bottom,      /* solder mask */
+       layer_mask_top,
+       layer_draw,             /* general drawing */
+       layer_comment,
+       layer_eco1,
+       layer_eco2,
+       layer_edge,             /* edge */
+};
+
+
+static void kicad_pad(FILE *file, const struct inst *inst)
+{
+       struct coord min, max;
+       unit_type tmp;
+
+       min.x = units_to_kicad(inst->base.x);
+       min.y = units_to_kicad(inst->base.y);
+       max.x = units_to_kicad(inst->u.pad.other.x);
+       max.y = units_to_kicad(inst->u.pad.other.y);
+
+       if (min.x > max.x) {
+               tmp = min.x;
+               min.x = max.x;
+               max.x = tmp;
+       }
+       if (min.y > max.y) {
+               tmp = min.y;
+               min.y = max.y;
+               max.y = tmp;
+       }
+
+       fprintf(file, "$PAD\n");
+
+       /*
+        * name, shape (rectangle), Xsize, Ysize, Xdelta, Ydelta, Orientation
+        */
+       fprintf(file, "Sh \"%s\" R %d %d 0 0 0\n",
+           inst->u.pad.name, max.x-min.x, max.y-min.y);
+
+       /*
+        * Attributes: pad type, N, layer mask
+        */
+       fprintf(file, "At SMD N %8.8X\n",
+           (1 << layer_top) |
+           (1 << layer_paste_top) |
+           (1 << layer_mask_top));
+
+       /*
+        * Position: Xpos, Ypos
+        */
+       fprintf(file, "Po %d %d\n", (min.x+max.x)/2, -(min.y+max.y)/2);
+
+       fprintf(file, "$EndPAD\n");
+}
+
+
+static void kicad_line(FILE *file, const struct inst *inst)
+{
+       /*
+        * Xstart, Ystart, Xend, Yend, Width, Layer
+        */
+       fprintf(file, "DS %d %d %d %d %d %d\n",
+           units_to_kicad(inst->base.x),
+           -units_to_kicad(inst->base.y),
+           units_to_kicad(inst->u.rect.end.x),
+           -units_to_kicad(inst->u.rect.end.y),
+           units_to_kicad(inst->u.rect.width),
+           layer_silk_top);
+}
+
+
+static void kicad_rect(FILE *file, const struct inst *inst)
+{
+       unit_type xa, ya, xb, yb;
+       unit_type width;
+
+       xa = units_to_kicad(inst->base.x);
+       ya = units_to_kicad(inst->base.y);
+       xb = units_to_kicad(inst->u.rect.end.x);
+       yb = units_to_kicad(inst->u.rect.end.y);
+       width = units_to_kicad(inst->u.rect.width);
+
+       fprintf(file, "DS %d %d %d %d %d %d\n",
+           xa, -ya, xa, -yb, width, layer_silk_top);
+       fprintf(file, "DS %d %d %d %d %d %d\n",
+           xa, -yb, xb, -yb, width, layer_silk_top);
+       fprintf(file, "DS %d %d %d %d %d %d\n",
+           xb, -yb, xb, -ya, width, layer_silk_top);
+       fprintf(file, "DS %d %d %d %d %d %d\n",
+           xb, -ya, xa, -ya, width, layer_silk_top);
+}
+
+
+static void kicad_circ(FILE *file, const struct inst *inst)
+{
+       /*
+        * Xcenter, Ycenter, Xpoint, Ypoint, Width, Layer
+        */
+       fprintf(file, "DC %d %d %d %d %d %d\n",
+           units_to_kicad(inst->base.x),
+           -units_to_kicad(inst->base.y),
+           units_to_kicad(inst->base.x),
+           units_to_kicad(inst->base.y+inst->u.arc.r),
+           units_to_kicad(inst->u.arc.width),
+           layer_silk_top);
+}
+
+
+static void kicad_arc(FILE *file, const struct inst *inst)
+{
+       fprintf(stderr, "NOT YET IMPLEMENTED\n");
+}
+
+
+static void kicad_inst(FILE *file, enum inst_prio prio, const struct inst 
*inst)
+{
+       switch (prio) {
+       case ip_pad:
+               kicad_pad(file, inst);
+               break;
+       case ip_line:
+               kicad_line(file, inst);
+               break;
+       case ip_rect:
+               kicad_rect(file, inst);
+               break;
+       case ip_circ:
+               kicad_circ(file, inst);
+               break;
+       case ip_arc:
+               kicad_arc(file, inst);
+               break;
+       default:
+               break;
+       }
+}
+
+
+static void kicad_module(FILE *file, const char *name, time_t now)
+{
+       enum inst_prio prio;
+       const struct inst *inst;
+
+       /*
+        * Module library name
+        */
+       fprintf(file, "$MODULE %s\n", name);
+
+       /*
+        * Xpos = 0, Ypos = 0, 15 layers, last modification, timestamp,
+        * moveable, not autoplaced.
+        */
+       fprintf(file, "Po 0 0 0 15 %8.8lX 00000000 ~~\n", (long) now);
+
+       /*
+        * Module library name again
+        */
+       fprintf(file, "Li %s\n", name);
+
+#if 0 /* optional */
+       /*
+        * Description
+        */
+       fprintf(file, "Cd %s\n", name);
+#endif
+
+       /*
+        *
+        */
+       fprintf(file, "Sc %8.8lX\n", (long) now);
+
+       /*
+        * Attributes: SMD = listed in the automatic insertion list
+        */
+       fprintf(file, "At SMD\n");
+
+       /*
+        * Rotation cost: 0 for 90 deg, 0 for 180 deg, 0 = disable rotation
+        */
+       fprintf(file, "Op 0 0 0\n");
+
+       /*
+        * Text fields: Tn = field number, Xpos, Ypos, Xsize ("emspace"),
+        * Ysize ("emspace"), rotation, pen width, N (none), V = visible,
+        * comment layer. All dimensions are 1/10 mil.
+        */
+
+       fprintf(file, "T0 0 -150 200 200 0 40 N V %d \"%s\"\n",
+           layer_comment, name);
+       fprintf(file, "T1 0 150 200 200 0 40 N I %d \"Val*\"\n",
+           layer_comment);
+
+       FOR_INSTS_UP(prio, inst)
+               kicad_inst(file, prio, inst);
+
+       fprintf(file, "$EndMODULE %s\n", name);
+}
+
+
+int kicad(FILE *file)
+{
+       time_t now = time(NULL);
+
+       fprintf(file, "PCBNEW-LibModule-V1 %s\n", ctime(&now));
+
+       fprintf(file, "$INDEX\n");
+       fprintf(file, "%s\n", part_name);
+       fprintf(file, "$EndINDEX\n");
+
+       kicad_module(file, part_name, now);
+
+       fprintf(file, "$EndLIBRARY\n");
+
+       fflush(file);
+       return !ferror(file);
+}

Added: trunk/eda/fped/kicad.h
===================================================================
--- trunk/eda/fped/kicad.h                              (rev 0)
+++ trunk/eda/fped/kicad.h      2009-08-10 21:02:26 UTC (rev 5416)
@@ -0,0 +1,22 @@
+/*
+ * kicad.h - Dump objects in the KiCad board/module format
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#ifndef KICAD_H
+#define KICAD_H
+
+#include <stdio.h>
+
+
+int kicad(FILE *file);
+
+#endif /* !KICAD_H */




--- End Message ---
_______________________________________________
commitlog mailing list
commitlog@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/commitlog

Reply via email to