#usage "<b>DumpLib</b>\n"
       "<p>"
       "<p>used in the library-editor, it dumps the whole ULP-library-struct to a textfile"
       "<author>Author: fb@frb-computersysteme.de</author>"

if(!library) {
   dlgMessageBox(usage + "<hr><b>ERROR: No library!</b><p>\nThis ULP-program can only work in the library editor.");
   exit(1);
}

// Object directly depends on UL_WIRE 
// Object indirectly depends on UL_WIRE
int DumpWIRE( UL_WIRE Element, string strIndent )
{
  printf("%slayer	 %d\n", strIndent, Element.layer );
  printf("%sstyle	 %d\n", strIndent, Element.style );
  printf("%swidth	 %d\n", strIndent, Element.width );
  printf("%sx1	 %d\n", strIndent, Element.x1 );
  printf("%sx2	 %d\n", strIndent, Element.x2 );
  printf("%sy1	 %d\n", strIndent, Element.y1 );
  printf("%sy2	 %d\n", strIndent, Element.y2 );
  Element.pieces(E) {
// we do not allow self-recursions
  }
  return 0;
}

// Object directly depends on UL_WIRE 
// Object indirectly depends on UL_WIRE
int DumpTEXT( UL_TEXT Element, string strIndent )
{
  printf("%sangle	 %.3f\n", strIndent, Element.angle );
  printf("%sfont	 %d\n", strIndent, Element.font );
  printf("%slayer	 %d\n", strIndent, Element.layer );
  printf("%smirror	 %d\n", strIndent, Element.mirror );
  printf("%sratio	 %d\n", strIndent, Element.ratio );
  printf("%ssize	 %d\n", strIndent, Element.size );
  printf("%svalue	 \"%s\"\n", strIndent, Element.value );
  printf("%sx	 %d\n", strIndent, Element.x );
  printf("%sy	 %d\n", strIndent, Element.y );
  Element.wires(E) {
    printf("%swires	 {\n", strIndent );
    DumpWIRE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  return 0;
}

// Object directly depends on 
// Object indirectly depends on 
int DumpAREA( UL_AREA Element, string strIndent )
{
  printf("%sx1	 %d\n", strIndent, Element.x1 );
  printf("%sx2	 %d\n", strIndent, Element.x2 );
  printf("%sy1	 %d\n", strIndent, Element.y1 );
  printf("%sy2	 %d\n", strIndent, Element.y2 );
  return 0;
}

// Object directly depends on 
// Object indirectly depends on 
int DumpSMD( UL_SMD Element, string strIndent )
{
  printf("%sdx[0]	 %d\n", strIndent, Element.dx[0] );
  printf("%sdy[0]	 %d\n", strIndent, Element.dy[0] );
  printf("%slayer	 %d\n", strIndent, Element.layer );
  printf("%sname	 \"%s\"\n", strIndent, Element.name );
  printf("%sroundness	 %d\n", strIndent, Element.roundness );
  printf("%ssignal	 \"%s\"\n", strIndent, Element.signal );
  printf("%sx	 %d\n", strIndent, Element.x );
  printf("%sy	 %d\n", strIndent, Element.y );
  return 0;
}

// Object directly depends on 
// Object indirectly depends on 
int DumpRECTANGLE( UL_RECTANGLE Element, string strIndent )
{
  printf("%slayer	 %d\n", strIndent, Element.layer );
  printf("%sx1	 %d\n", strIndent, Element.x1 );
  printf("%sx2	 %d\n", strIndent, Element.x2 );
  printf("%sy1	 %d\n", strIndent, Element.y1 );
  printf("%sy2	 %d\n", strIndent, Element.y2 );
  return 0;
}

// Object directly depends on UL_WIRE UL_WIRE UL_WIRE 
// Object indirectly depends on UL_WIRE
int DumpPOLYGON( UL_POLYGON Element, string strIndent )
{
  printf("%sisolate	 %d\n", strIndent, Element.isolate );
  printf("%slayer	 %d\n", strIndent, Element.layer );
  printf("%sorphans	 %d\n", strIndent, Element.orphans );
  printf("%spour	 %d\n", strIndent, Element.pour );
  printf("%srank	 %d\n", strIndent, Element.rank );
  printf("%sspacing	 %d\n", strIndent, Element.spacing );
  printf("%sthermals	 %d\n", strIndent, Element.thermals );
  printf("%swidth	 %d\n", strIndent, Element.width );
  Element.wires(E) {
    printf("%swires	 {\n", strIndent );
    DumpWIRE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.fillings(E) {
    printf("%sfillings	 {\n", strIndent );
    DumpWIRE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.contours(E) {
    printf("%scontours	 {\n", strIndent );
    DumpWIRE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  return 0;
}

// Object directly depends on 
// Object indirectly depends on 
int DumpCIRCLE( UL_CIRCLE Element, string strIndent )
{
  printf("%slayer	 %d\n", strIndent, Element.layer );
  printf("%sradius	 %d\n", strIndent, Element.radius );
  printf("%swidth	 %d\n", strIndent, Element.width );
  printf("%sx	 %d\n", strIndent, Element.x );
  printf("%sy	 %d\n", strIndent, Element.y );
  return 0;
}

// Object directly depends on 
// Object indirectly depends on 
int DumpPAD( UL_PAD Element, string strIndent )
{
  printf("%sdiameter[0]	 %d\n", strIndent, Element.diameter[0] );
  printf("%sdrill	 %d\n", strIndent, Element.drill );
  printf("%sname	 \"%s\"\n", strIndent, Element.name );
  printf("%sshape[0]	 %d\n", strIndent, Element.shape[0] );
  printf("%ssignal	 \"%s\"\n", strIndent, Element.signal );
  printf("%sx	 %d\n", strIndent, Element.x );
  printf("%sy	 %d\n", strIndent, Element.y );
  return 0;
}

// Object directly depends on 
// Object indirectly depends on 
int DumpARC( UL_ARC Element, string strIndent )
{
  printf("%sangle1	 %.3f\n", strIndent, Element.angle1 );
  printf("%sangle2	 %.3f\n", strIndent, Element.angle2 );
  printf("%slayer	 %d\n", strIndent, Element.layer );
  printf("%sradius	 %d\n", strIndent, Element.radius );
  printf("%swidth	 %d\n", strIndent, Element.width );
  printf("%sx1	 %d\n", strIndent, Element.x1 );
  printf("%sx2	 %d\n", strIndent, Element.x2 );
  printf("%sxc	 %d\n", strIndent, Element.xc );
  printf("%sy1	 %d\n", strIndent, Element.y1 );
  printf("%sy2	 %d\n", strIndent, Element.y2 );
  printf("%syc	 %d\n", strIndent, Element.yc );
  return 0;
}

// Object directly depends on UL_PAD UL_SMD 
// Object indirectly depends on UL_PAD UL_SMD
int DumpCONTACT( UL_CONTACT Element, string strIndent )
{
  printf("%sname	 \"%s\"\n", strIndent, Element.name );
  printf("%spad	 {\n", strIndent );
  DumpPAD( Element.pad, strIndent+"  " );
  printf("%s}\n", strIndent );
  printf("%ssignal	 \"%s\"\n", strIndent, Element.signal );
  printf("%ssmd	 {\n", strIndent );
  DumpSMD( Element.smd, strIndent+"  " );
  printf("%s}\n", strIndent );
  printf("%sx	 %d\n", strIndent, Element.x );
  printf("%sy	 %d\n", strIndent, Element.y );
  return 0;
}

// Object directly depends on 
// Object indirectly depends on 
int DumpLAYER( UL_LAYER Element, string strIndent )
{
  printf("%scolor	 %d\n", strIndent, Element.color );
  printf("%sfill	 %d\n", strIndent, Element.fill );
  printf("%sname	 \"%s\"\n", strIndent, Element.name );
  printf("%snumber	 %d\n", strIndent, Element.number );
  printf("%sused	 %d\n", strIndent, Element.used );
  printf("%svisible	 %d\n", strIndent, Element.visible );
  return 0;
}

// Object directly depends on 
// Object indirectly depends on 
int DumpHOLE( UL_HOLE Element, string strIndent )
{
  printf("%sdrill	 %d\n", strIndent, Element.drill );
  printf("%sx	 %d\n", strIndent, Element.x );
  printf("%sy	 %d\n", strIndent, Element.y );
  return 0;
}

// Object directly depends on 
// Object indirectly depends on 
int DumpGRID( UL_GRID Element, string strIndent )
{
  printf("%sdistance	 %.3f\n", strIndent, Element.distance );
  printf("%sdots	 %d\n", strIndent, Element.dots );
  printf("%smultiple	 %d\n", strIndent, Element.multiple );
  printf("%son	 %d\n", strIndent, Element.on );
  printf("%sunit	 %d\n", strIndent, Element.unit );
  return 0;
}

// Object directly depends on UL_CONTACT UL_CIRCLE UL_WIRE UL_TEXT 
// Object indirectly depends on UL_CIRCLE UL_CONTACT UL_PAD UL_SMD UL_TEXT UL_WIRE
int DumpPIN( UL_PIN Element, string strIndent )
{
  printf("%sangle	 %.3f\n", strIndent, Element.angle );
  printf("%scontact	 {\n", strIndent );
  DumpCONTACT( Element.contact, strIndent+"  " );
  printf("%s}\n", strIndent );
  printf("%sdirection	 %d\n", strIndent, Element.direction );
  printf("%sfunction	 %d\n", strIndent, Element.function );
  printf("%slength	 %d\n", strIndent, Element.length );
  printf("%sname	 \"%s\"\n", strIndent, Element.name );
  printf("%sswaplevel	 %d\n", strIndent, Element.swaplevel );
  printf("%svisible	 %d\n", strIndent, Element.visible );
  printf("%sx	 %d\n", strIndent, Element.x );
  printf("%sy	 %d\n", strIndent, Element.y );
  Element.circles(E) {
    printf("%scircles	 {\n", strIndent );
    DumpCIRCLE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.wires(E) {
    printf("%swires	 {\n", strIndent );
    DumpWIRE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.texts(E) {
    printf("%stexts	 {\n", strIndent );
    DumpTEXT( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  return 0;
}

// Object directly depends on UL_AREA UL_ARC UL_POLYGON UL_CIRCLE UL_WIRE UL_TEXT UL_PIN UL_RECTANGLE 
// Object indirectly depends on UL_ARC UL_AREA UL_CIRCLE UL_CONTACT UL_PAD UL_PIN UL_POLYGON UL_RECTANGLE UL_SMD UL_TEXT UL_WIRE
int DumpSYMBOL( UL_SYMBOL Element, string strIndent )
{
  printf("%sarea	 {\n", strIndent );
  DumpAREA( Element.area, strIndent+"  " );
  printf("%s}\n", strIndent );
  printf("%slibrary	 \"%s\"\n", strIndent, Element.library );
  printf("%sname	 \"%s\"\n", strIndent, Element.name );
  Element.arcs(E) {
    printf("%sarcs	 {\n", strIndent );
    DumpARC( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.polygons(E) {
    printf("%spolygons	 {\n", strIndent );
    DumpPOLYGON( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.circles(E) {
    printf("%scircles	 {\n", strIndent );
    DumpCIRCLE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.wires(E) {
    printf("%swires	 {\n", strIndent );
    DumpWIRE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.texts(E) {
    printf("%stexts	 {\n", strIndent );
    DumpTEXT( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.pins(E) {
    printf("%spins	 {\n", strIndent );
    DumpPIN( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.rectangles(E) {
    printf("%srectangles	 {\n", strIndent );
    DumpRECTANGLE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  return 0;
}

// Object directly depends on UL_AREA UL_ARC UL_POLYGON UL_CIRCLE UL_WIRE UL_CONTACT UL_TEXT UL_HOLE UL_RECTANGLE 
// Object indirectly depends on UL_ARC UL_AREA UL_CIRCLE UL_CONTACT UL_HOLE UL_PAD UL_POLYGON UL_RECTANGLE UL_SMD UL_TEXT UL_WIRE
int DumpPACKAGE( UL_PACKAGE Element, string strIndent )
{
  printf("%sarea	 {\n", strIndent );
  DumpAREA( Element.area, strIndent+"  " );
  printf("%s}\n", strIndent );
  printf("%sdescription	 \"%s\"\n", strIndent, Element.description );
  printf("%sheadline	 \"%s\"\n", strIndent, Element.headline );
  printf("%slibrary	 \"%s\"\n", strIndent, Element.library );
  printf("%sname	 \"%s\"\n", strIndent, Element.name );
  Element.arcs(E) {
    printf("%sarcs	 {\n", strIndent );
    DumpARC( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.polygons(E) {
    printf("%spolygons	 {\n", strIndent );
    DumpPOLYGON( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.circles(E) {
    printf("%scircles	 {\n", strIndent );
    DumpCIRCLE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.wires(E) {
    printf("%swires	 {\n", strIndent );
    DumpWIRE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.contacts(E) {
    printf("%scontacts	 {\n", strIndent );
    DumpCONTACT( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.texts(E) {
    printf("%stexts	 {\n", strIndent );
    DumpTEXT( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.holes(E) {
    printf("%sholes	 {\n", strIndent );
    DumpHOLE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.rectangles(E) {
    printf("%srectangles	 {\n", strIndent );
    DumpRECTANGLE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  return 0;
}

// Object directly depends on UL_SYMBOL 
// Object indirectly depends on UL_ARC UL_AREA UL_CIRCLE UL_CONTACT UL_PAD UL_PIN UL_POLYGON UL_RECTANGLE UL_SMD UL_SYMBOL UL_TEXT UL_WIRE
int DumpGATE( UL_GATE Element, string strIndent )
{
  printf("%saddlevel	 %d\n", strIndent, Element.addlevel );
  printf("%sname	 \"%s\"\n", strIndent, Element.name );
  printf("%sswaplevel	 %d\n", strIndent, Element.swaplevel );
  printf("%ssymbol	 {\n", strIndent );
  DumpSYMBOL( Element.symbol, strIndent+"  " );
  printf("%s}\n", strIndent );
  printf("%sx	 %d\n", strIndent, Element.x );
  printf("%sy	 %d\n", strIndent, Element.y );
  return 0;
}

// Object directly depends on UL_AREA UL_PACKAGE UL_GATE 
// Object indirectly depends on UL_ARC UL_AREA UL_CIRCLE UL_CONTACT UL_GATE UL_HOLE UL_PACKAGE UL_PAD UL_PIN UL_POLYGON UL_RECTANGLE UL_SMD UL_SYMBOL UL_TEXT UL_WIRE
int DumpDEVICE( UL_DEVICE Element, string strIndent )
{
  printf("%sarea	 {\n", strIndent );
  DumpAREA( Element.area, strIndent+"  " );
  printf("%s}\n", strIndent );
  printf("%sdescription	 \"%s\"\n", strIndent, Element.description );
  printf("%sheadline	 \"%s\"\n", strIndent, Element.headline );
  printf("%slibrary	 \"%s\"\n", strIndent, Element.library );
  printf("%sname	 \"%s\"\n", strIndent, Element.name );
  printf("%spackage	 {\n", strIndent );
  DumpPACKAGE( Element.package, strIndent+"  " );
  printf("%s}\n", strIndent );
  printf("%sprefix	 \"%s\"\n", strIndent, Element.prefix );
  printf("%stechnologies	 \"%s\"\n", strIndent, Element.technologies );
  printf("%svalue	 \"%s\"\n", strIndent, Element.value );
  Element.gates(E) {
    printf("%sgates	 {\n", strIndent );
    DumpGATE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  return 0;
}

// Object directly depends on UL_AREA UL_GATE UL_DEVICE 
// Object indirectly depends on UL_ARC UL_AREA UL_CIRCLE UL_CONTACT UL_DEVICE UL_GATE UL_HOLE UL_PACKAGE UL_PAD UL_PIN UL_POLYGON UL_RECTANGLE UL_SMD UL_SYMBOL UL_TEXT UL_WIRE
int DumpDEVICESET( UL_DEVICESET Element, string strIndent )
{
  printf("%sarea	 {\n", strIndent );
  DumpAREA( Element.area, strIndent+"  " );
  printf("%s}\n", strIndent );
  printf("%sdescription	 \"%s\"\n", strIndent, Element.description );
  printf("%sheadline	 \"%s\"\n", strIndent, Element.headline );
  printf("%slibrary	 \"%s\"\n", strIndent, Element.library );
  printf("%sname	 \"%s\"\n", strIndent, Element.name );
  printf("%sprefix	 \"%s\"\n", strIndent, Element.prefix );
  printf("%svalue	 \"%s\"\n", strIndent, Element.value );
  Element.gates(E) {
    printf("%sgates	 {\n", strIndent );
    DumpGATE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.devices(E) {
    printf("%sdevices	 {\n", strIndent );
    DumpDEVICE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  return 0;
}

// Object directly depends on UL_GRID UL_DEVICE UL_LAYER UL_SYMBOL UL_DEVICESET UL_PACKAGE 
// Object indirectly depends on UL_ARC UL_AREA UL_CIRCLE UL_CONTACT UL_DEVICE UL_DEVICESET UL_GATE UL_GRID UL_HOLE UL_LAYER UL_PACKAGE UL_PAD UL_PIN UL_POLYGON UL_RECTANGLE UL_SMD UL_SYMBOL UL_TEXT UL_WIRE
int DumpLIBRARY( UL_LIBRARY Element, string strIndent )
{
  printf("%sdescription	 \"%s\"\n", strIndent, Element.description );
  printf("%sgrid	 {\n", strIndent );
  DumpGRID( Element.grid, strIndent+"  " );
  printf("%s}\n", strIndent );
  printf("%sheadline	 \"%s\"\n", strIndent, Element.headline );
  printf("%sname	 \"%s\"\n", strIndent, Element.name );
  Element.devices(E) {
    printf("%sdevices	 {\n", strIndent );
    DumpDEVICE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.layers(E) {
    printf("%slayers	 {\n", strIndent );
    DumpLAYER( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.symbols(E) {
    printf("%ssymbols	 {\n", strIndent );
    DumpSYMBOL( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.devicesets(E) {
    printf("%sdevicesets	 {\n", strIndent );
    DumpDEVICESET( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  Element.packages(E) {
    printf("%spackages	 {\n", strIndent );
    DumpPACKAGE( E, strIndent+"  " );
    printf("%s}\n", strIndent );
  }
  return 0;
}

string strFilename="/library.txt";
if (library) library(L) {
	int pos = strrchr(L.name, '.');
	if (pos >= 0) strFilename = strsub(L.name, 0, pos + 1)+"txt";
}

strFilename = dlgFileSave("Specify name to save to", strFilename);

if(strFilename=="") {
	exit(-1);
}

output( strFilename )  {
	if (library) library(L) {
		printf("Library-Dump of \"%s\"\n", L.name);
		printf("\n");
		printf("generated by DumpLib.ulp\n");
		printf("\n");
		printf("L {\n");
		DumpLIBRARY( L, "  " );
		printf("}\n");
	}
}



