--- /dev/null	2012-04-03 10:16:45.622661012 +0200
+++ kicad/eeschema/eeschema_cmdline.h	2012-04-08 06:48:35.478088781 +0200
@@ -0,0 +1,14 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        eeschema_cmdline.h
+// Copyright:   Wolfgang Spraul
+// Licence:     GPL v3 or higher
+/////////////////////////////////////////////////////////////////////////////
+
+class EESCHEMA_CMDLINE
+{
+public:
+    EESCHEMA_CMDLINE() { }
+    bool Run();
+};
+
+extern EESCHEMA_CMDLINE g_EESchemaCmdLine;
--- /dev/null	2012-04-03 10:16:45.622661012 +0200
+++ kicad/eeschema/eeschema_cmdline.cpp	2012-04-08 07:11:42.232529821 +0200
@@ -0,0 +1,234 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        eeschema_cmdline.cpp
+// Copyright:   Werner Almesberger, Wolfgang Spraul
+// License:     GPL v2 or higher
+/////////////////////////////////////////////////////////////////////////////
+
+#include <wx/notebook.h>
+#include <fctsys.h>
+#include <appl_wxstruct.h>
+#include <common.h>
+#include <general.h>
+#include <netlist.h>
+#include <netlist_control.h>
+#include <protos.h>
+#include <gr_basic.h>
+#include <wx/cmdline.h>
+#include <dialog_build_BOM.h>
+#include <dialog_SVG_print_base.h>
+#include <dialog_erc.h>
+#include <dialog_color_config.h>
+#include <wxEeschemaStruct.h>
+#include <sch_sheet.h>
+#include <wildcards_and_files_ext.h>
+#include <eeschema_cmdline.h>
+
+EESCHEMA_CMDLINE g_EESchemaCmdLine;
+
+static const wxCmdLineEntryDesc g_cmdLineDesc [] =
+{
+     { wxCMD_LINE_SWITCH, 0, wxT("help"),
+          wxT("command line help\n"),
+          wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
+
+     { wxCMD_LINE_SWITCH, 0, wxT("list-sheets"),
+          wxT("list schematic pages\n") },
+
+     { wxCMD_LINE_OPTION, 0, wxT("plot"),
+          wxT("File -> Plot [ps|svg|dxf]"),
+          wxCMD_LINE_VAL_STRING },
+     { wxCMD_LINE_SWITCH, 0, wxT("plot-bw"),
+          wxT(" Black & white (default: color)") },
+     { wxCMD_LINE_SWITCH, 0, wxT("plot-sheetref"),
+          wxT(" Print page references (default: off)\n") },
+
+     { wxCMD_LINE_SWITCH, 0, wxT("erc"),
+          wxT("Tools -> ERC (.erc)") },
+     { wxCMD_LINE_SWITCH, 0, wxT("netlist"),
+          wxT("Tools -> Generate Netlist (.net)") },
+     { wxCMD_LINE_SWITCH, 0, wxT("bom"),
+          wxT("Tools -> Generate Bill of Materials (.bom)") },
+     { wxCMD_LINE_PARAM, 0, 0, wxT("<path to .sch file>"),
+          wxCMD_LINE_VAL_STRING },
+     { wxCMD_LINE_NONE }
+};
+
+bool CmdLineDrawSVGPage( EDA_DRAW_FRAME* frame,
+                   const wxString& FullFileName, BASE_SCREEN* screen,
+                   bool aPrintBlackAndWhite = false,
+                   bool aPrint_Sheet_Ref = false);
+
+// called from EDA_APP::OnInit()
+bool EESCHEMA_CMDLINE::Run()
+{
+    wxFileName fn;
+    SCH_EDIT_FRAME* frame;
+    wxCommandEvent DummyCmd;
+    wxString str;
+    int i;
+
+    EDA_APP& app = wxGetApp();
+    g_CmdLineMode = true;
+    wxLog::EnableLogging(false); // this should suppress some wx dialogs
+    app.InitEDA_Appl( wxT( "Eeschema" ), APP_EESCHEMA_T );
+
+    wxCmdLineParser parser;
+    parser.SetDesc(g_cmdLineDesc);
+    parser.SetCmdLine(app.argc, app.argv);
+    if (parser.Parse())
+        return false;
+
+    i = parser.Found( _("list-sheets") )
+        + parser.Found( _("plot") )
+        + parser.Found( _("erc") )
+        + parser.Found( _("netlist") )
+        + parser.Found( _("bom") );
+    if ( !i )
+    {
+        wxFprintf( stderr, wxT("One of --list-sheets --plot --erc --netlist"
+            " --bom must be given.\n"));
+        return false;
+    }
+    if ( i > 1 )
+    {
+        wxFprintf( stderr, wxT("Only one of --list-sheets --plot --erc"
+            " --netlist --bom may be given at a time.\n"));
+        return false;
+    }
+
+    // parse plotting parameters
+    enum PlotCommand {
+        PLOT_NONE,
+        PLOT_PS,
+        PLOT_SVG,
+        PLOT_DXF
+    } PlotCmd;
+    bool PlotBW;
+    bool PlotSheetRef;
+
+    PlotCmd = PLOT_NONE;
+    if ( parser.Found( _("plot"), &str ) )
+    {
+        if (!str.CmpNoCase( wxT("ps") ) )
+            PlotCmd = PLOT_PS;
+        else if ( !str.CmpNoCase( wxT("svg") ) )
+            PlotCmd = PLOT_SVG;
+        else if ( !str.CmpNoCase( wxT("dxf") ) )
+            PlotCmd = PLOT_DXF;
+        else
+        {
+            wxFprintf( stderr, wxT("Unexpected plot format '%ls'.\n"), str.c_str());
+            return false;
+        }
+        PlotBW = parser.Found( _("plot-bw") );
+        PlotSheetRef = parser.Found( _("plot-sheetref") );
+    }
+
+    fn = parser.GetParam();
+    if( fn.GetExt() != SchematicFileExtension )
+    {
+        wxLogDebug( wxT( "eeschema file <%s> has the wrong extension."
+            " Changing extension to .sch." ), GetChars( fn.GetFullPath() ) );
+        fn.SetExt( PcbFileExtension );
+    }
+    if( !fn.FileExists())
+    {
+        wxFprintf( stderr, wxT("%ls: file '%ls' does not exist.\n" ),
+            app.argv[0], fn.GetFullPath().c_str() );
+        return false;
+    }
+    wxSetWorkingDirectory( fn.GetPath() );
+
+    SeedLayers();
+    frame = new SCH_EDIT_FRAME( NULL, wxT( "Eeschema" ), wxPoint( 0, 0 ),
+        wxSize( 600, 400 ) );
+    app.SetTopWindow( frame );
+#if 0 // enable this to see more of the GUI
+    frame->Show( true );
+#endif
+    if( !frame->LoadOneEEProject( fn.GetFullPath(), false ) )
+    {
+        wxFprintf( stderr, fn.GetFullPath() + _(": can't load\n") );
+        return false;
+    }
+
+    if ( parser.Found( wxT("list-sheets") ) )
+    {
+        SCH_SHEET_LIST SheetList( 0 /* aSheet */ );
+        SCH_SHEET_PATH* sheetpath;
+        SCH_SHEET_PATH oldsheetpath, list;
+        SCH_SCREEN* schscreen;
+
+        // dialogs/dialog_SVG_print.cpp:DIALOG_SVG_PRINT:PrintSVGDoc()
+        oldsheetpath = frame->GetCurrentSheet();
+        sheetpath = SheetList.GetFirst();
+        while ( sheetpath )
+        {
+            list.Clear();
+            if ( list.BuildSheetPathInfoFromSheetPathValue( sheetpath->Path() ) )
+            {
+                frame->SetCurrentSheet( list );
+                frame->GetCurrentSheet().UpdateAllScreenReferences();
+                frame->SetSheetNumberAndCount();
+                schscreen = frame->GetCurrentSheet().LastScreen();
+
+                wxPrintf( sheetpath->Path() + _(" ")
+                    + sheetpath->PathHumanReadable() + _(" ")
+                    + sheetpath->Last()->GetFileName() + _(" ")
+                    + frame->GetUniqueFilenameForCurrentSheet( ) + wxT( ".sch\n") );
+            }
+            sheetpath = SheetList.GetNext();
+        }
+        frame->SetCurrentSheet( oldsheetpath );
+        frame->GetCurrentSheet().UpdateAllScreenReferences();
+        frame->SetSheetNumberAndCount();
+    }
+    else if ( PlotCmd == PLOT_PS )
+    {
+        // dialogs/dialog_plot_schematic_PS_base.cpp
+        // dialogs/dialog_plot_schematic_PS.cpp
+        frame->CmdLineToPlot_PS( PlotBW, PlotSheetRef );
+    }
+    else if ( PlotCmd == PLOT_SVG )
+    {
+        // dialogs/dialog_SVG_print.cpp:DIALOG_SVG_PRINT::DrawSVGPage()
+        void CmdLinePrintSVGDoc( EDA_DRAW_FRAME* frame, bool aPrintAll,
+            bool aPrint_Sheet_Ref, bool aPrintBlackAndWhite );
+        CmdLinePrintSVGDoc( frame, true /* aPrintAll */, PlotSheetRef, PlotBW );
+    }
+    else if ( PlotCmd == PLOT_DXF )
+    {
+        // dialogs/dialog_plot_schematic_DXF_base.cpp
+        // dialogs/dialog_plot_schematic_DXF.cpp
+        frame->CmdLineToPlot_DXF( PlotBW, PlotSheetRef );
+    }
+    else if ( parser.Found( wxT("erc") ) ) // erc.cpp:DIALOG_ERC::TestErc()
+    {
+        DIALOG_ERC* dlg = new DIALOG_ERC( frame );
+        dlg->m_WriteResultOpt->SetValue( true );
+        dlg->TestErc( 0 /* messageList */ );
+        delete dlg;
+    }
+    else if ( parser.Found( wxT("netlist") ) )
+    {
+        // netlist_control.cpp:WinEDA_SchematicFrame::CreateNetlist()
+        frame->BuildNetListBase();
+        fn.SetExt( wxT( "net" ) );
+        frame->WriteNetListFile( NET_TYPE_PCBNEW /* aFormat */,
+            fn.GetFullPath(), 0 /* aNetlistOptions */ );
+    }
+    else if ( parser.Found( wxT("bom") ) )
+    {
+        // see build_BOM.cpp:DIALOG_BUILD_BOM::GenereListeOfItems()
+        DIALOG_BUILD_BOM* dlg = new DIALOG_BUILD_BOM( frame );
+
+        dlg->m_ListCmpbyRefItems->SetValue( true );
+        dlg->m_AddFootprintField->SetValue( true );
+        dlg->m_AddAllFields->SetValue( true );
+
+        fn.SetExt( wxT( "lst" ) );
+        dlg->GenereListeOfItems( fn.GetFullPath(), false /* aIncludeSubComponents */ );
+        delete dlg;
+    }
+    return true;
+}
--- /dev/null	2012-04-03 10:16:45.622661012 +0200
+++ kicad/pcbnew/pcbnew_cmdline.h	2012-04-08 06:48:35.482088711 +0200
@@ -0,0 +1,7 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        pcbnew_cmdline.h
+// Copyright:   Wolfgang Spraul
+// Licence:     GPL v3 or higher
+/////////////////////////////////////////////////////////////////////////////
+
+bool Pcbnew_CmdLine();
--- /dev/null	2012-04-03 10:16:45.622661012 +0200
+++ kicad/pcbnew/pcbnew_cmdline.cpp	2012-04-08 08:12:17.841567431 +0200
@@ -0,0 +1,538 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        pcbnew_cmdline.cpp
+// Copyright:   Wolfgang Spraul
+// Licence:     GPL v3 or higher
+/////////////////////////////////////////////////////////////////////////////
+
+#include <fctsys.h>
+#include <appl_wxstruct.h>
+#include <confirm.h>
+
+#include <wx/file.h>
+#include <wx/snglinst.h>
+#include <wx/cmdline.h>
+#include <wx/tokenzr.h>
+#include <wx/svg/dcsvg.h>
+
+#include <common.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <plot_common.h>
+#include <gestfich.h>
+#include <pcbplot.h>
+#include <autorout.h>
+#include <cell.h>
+#include <worksheet.h>
+#include <zones.h>
+#include <drag.h>
+#include <eda_dde.h>
+#include <colors_selection.h>
+#include <class_drawpanel.h>
+#include <gr_basic.h>
+#include <id.h>
+#include <build_version.h>
+
+#include <protos.h>
+#include <pcbnew_cmdline.h>
+#include <gendrill.h>
+#include <dialog_gendrill.h>
+#include <dialog_drc.h>
+#include <printout_controler.h>
+#include <dialog_plot_base.h>
+#include <dialog_SVG_print.h>
+#include <wildcards_and_files_ext.h>
+
+extern int g_DrawDefaultLineThickness;
+
+static const wxCmdLineEntryDesc g_cmdLineDesc [] =
+{
+     { wxCMD_LINE_SWITCH, 0, wxT("help"),
+          wxT("command line help\n"),
+          wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
+
+     { wxCMD_LINE_SWITCH, 0, wxT("list-layers"),
+          wxT("list names of enabled layers in .brd file") },
+     { wxCMD_LINE_OPTION, 0, wxT("layers"),
+          wxT("comma separated layers for plot and SVG\n"),
+          wxCMD_LINE_VAL_STRING },
+
+     { wxCMD_LINE_SWITCH, 0, wxT("drill"),
+          wxT("File -> Fabrication -> Drill File (.drl)") },
+     { wxCMD_LINE_SWITCH, 0, wxT("drill-aux-origin"),
+          wxT(" Use aux axis as origin (def: abs)\n") },
+
+     { wxCMD_LINE_OPTION, 0, wxT("plot"),
+          wxT("File -> Plot [gerber|ps|dxf]"),
+          wxCMD_LINE_VAL_STRING },
+     { wxCMD_LINE_SWITCH, 0, wxT("plot-fill-all-zones"),
+          wxT(" Fill zones before plotting (not in the dialog)") },
+     { wxCMD_LINE_OPTION, 0, wxT("plot-drill-marks"),
+          wxT(" Drill marks [none|small|actual] (def: small)"),
+          wxCMD_LINE_VAL_STRING },
+     { wxCMD_LINE_SWITCH, 0, wxT("plot-mirror"),
+          wxT(" Postscript: Mirrored plot") },
+     { wxCMD_LINE_SWITCH, 0, wxT("plot-force-a4"),
+          wxT(" Postscript: Force A4 output") },
+     { wxCMD_LINE_SWITCH, 0, wxT("plot-aux-origin"),
+          wxT(" Gerber & DXF: Aux axis as origin (def: abs)") },
+     { wxCMD_LINE_SWITCH, 0, wxT("plot-exclude-edge"),
+          wxT(" Gerber: Exclude PCB edge\n") },
+
+     { wxCMD_LINE_OPTION, 0, wxT("svg"),
+          wxT("File -> Print SVG [selected|board]"),
+          wxCMD_LINE_VAL_STRING },
+     { wxCMD_LINE_SWITCH, 0, wxT("svg-board-edges"),
+          wxT(" add board edges to SVG plots (def: off)\n") },
+
+     { wxCMD_LINE_SWITCH, 0, wxT("drc"),
+          wxT("Tools -> DRC (.rpt)") },
+     { wxCMD_LINE_SWITCH, 0, wxT("pos"),
+          wxT("File -> Fabrication -> Modules Pos. (.pos)") },
+     { wxCMD_LINE_SWITCH, 0, wxT("bom"),
+          wxT("File -> Fabrication -> BOM File (.csv)") },
+     { wxCMD_LINE_SWITCH, 0, wxT("cmp"),
+          wxT("File -> Fabrication -> Comp. File (.cmp)") },
+     { wxCMD_LINE_SWITCH, 0, wxT("vrml"),
+          wxT("File -> Export -> VRML (.wrl)") },
+     { wxCMD_LINE_PARAM, 0, 0, wxT("<path to .brd file>"),
+          wxCMD_LINE_VAL_STRING },
+     { wxCMD_LINE_NONE }
+};
+
+bool Pcbnew_CmdLine()
+{
+    wxFileName cmdline_fn, fn;
+    wxString str;
+    PCB_EDIT_FRAME* frame = NULL;
+    wxCommandEvent dummy;
+    int i;
+
+    EDA_APP& app = wxGetApp();
+    g_CmdLineMode = true;
+    wxLog::EnableLogging(false); // this should suppress some wx dialogs
+    app.InitEDA_Appl( wxT( "Pcbnew" ), APP_PCBNEW_T );
+
+    wxCmdLineParser parser;
+    parser.SetDesc(g_cmdLineDesc);
+    parser.SetCmdLine(app.argc, app.argv);
+    if (parser.Parse())
+        return false;
+    i = parser.Found( _("list-layers") )
+        + parser.Found( _("drill") )
+        + parser.Found( _("plot") )
+        + parser.Found( _("svg") )
+        + parser.Found( _("drc") )
+        + parser.Found( _("pos") )
+        + parser.Found( _("bom") )
+        + parser.Found( _("cmp") )
+        + parser.Found( _("vrml") );
+    if ( !i )
+    {
+        wxFprintf( stderr, wxT("One of --list-layers --drill --plot --svg --drc --pos --bom --cmp or --vrml must be given.\n"));
+        return false;
+    }
+    if ( i > 1 )
+    {
+        wxFprintf( stderr, wxT("Only one of ---list-layers --drill --plot --svg --drc --pos --bom --cmp or --vrml may be given at a time.\n"));
+        return false;
+    }
+
+    cmdline_fn = parser.GetParam();
+    if( cmdline_fn.GetExt() != PcbFileExtension )
+    {
+        wxLogDebug( wxT( "PcbNew file <%s> has the wrong extension. Changing extension to .brd." ), GetChars( cmdline_fn.GetFullPath() ) );
+        cmdline_fn.SetExt( PcbFileExtension );
+    }
+    if( !cmdline_fn.FileExists())
+    {
+        wxFprintf( stderr, wxT("%ls: file '%ls' does not exist.\n" ), app.argv[0], cmdline_fn.GetFullPath().c_str() );
+        return false;
+    }
+    wxSetWorkingDirectory( cmdline_fn.GetPath() );
+
+    app.GetSettings( false /* reopenLastUsedDirectory */ );
+
+    g_DrawBgColor = BLACK;
+    frame = new PCB_EDIT_FRAME( NULL, wxT( "Pcbnew" ), wxPoint( 0, 0 ),
+        wxSize( 600, 400 ) );
+    app.SetTopWindow( frame );
+
+#if 0 // enable this to see more of the GUI
+    frame->Show( true );
+    frame->Zoom_Automatique( true );
+#endif
+
+    frame->LoadOnePcbFile( cmdline_fn.GetFullPath() );
+    frame->LoadProjectSettings( cmdline_fn.GetFullPath() );
+
+    if ( parser.Found( wxT("list-layers") ) )
+    {
+        for ( i = 0; i < NB_LAYERS; i++ )
+        {
+            if( frame->GetBoard()->IsLayerEnabled( i ) )
+            {
+                str = frame->GetBoard()->GetLayerName( i );
+                // remove leading and trailing spaces if any
+                str.Trim( true ); str.Trim( false );
+                wxPrintf(str + _("\n"));
+            }
+        }
+    }
+
+    if ( parser.Found( wxT("drill") ) )
+    {
+        DIALOG_GENDRILL drill_frame( frame );
+        drill_frame.m_Choice_Drill_Offset->SetSelection(
+            parser.Found( wxT("drill-aux-origin") ) );
+        wxSafeYield();
+        drill_frame.GenDrillAndReportFiles();
+    }
+
+    if ( parser.Found( wxT("plot"), &str ) ) // see pcbplot.cpp
+    {
+        int plot_format;
+        PCB_PLOT_PARAMS plot_params;
+        wxString ext, layers_str;
+
+        plot_params = frame->GetPlotSettings();
+	plot_params.m_PlotLineWidth = g_DrawDefaultLineThickness;
+        if (!str.CmpNoCase( wxT("ps") ) )
+        {
+            plot_format = PLOT_FORMAT_POST;
+            ext = wxT( "ps" );
+        }
+        else if ( !str.CmpNoCase( wxT("gerber") ) )
+        {
+            plot_format = PLOT_FORMAT_GERBER;
+            ext = wxT( "pho" );
+        }
+        else if ( !str.CmpNoCase( wxT("dxf") ) )
+        {
+            plot_format = PLOT_FORMAT_DXF;
+            ext = wxT( "dxf" );
+        }
+        else
+        {
+            wxFprintf( stderr,
+                wxT("Unexpected plot type '%ls'.\n"), str.c_str() );
+            return false;
+        }
+
+        // --plot-fill-all-zones
+        if ( parser.Found( wxT("plot-fill-all-zones") ) )
+            frame->Fill_All_Zones( 0 /* aActiveWindow for progress bar */,
+                false /* verbose */ );
+
+        // --plot-drill-marks
+        if ( plot_format == PLOT_FORMAT_POST
+            && parser.Found( wxT("plot-drill-marks"), &str ) )
+        {
+            if (!str.CmpNoCase( wxT("none") ) )
+                plot_params.m_DrillShapeOpt = PCB_PLOT_PARAMS::NO_DRILL_SHAPE;
+            else if ( !str.CmpNoCase( wxT("small") ) )
+                plot_params.m_DrillShapeOpt = PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE;
+            else if ( !str.CmpNoCase( wxT("actual") ) )
+                plot_params.m_DrillShapeOpt = PCB_PLOT_PARAMS::FULL_DRILL_SHAPE;
+            else
+            {
+                wxFprintf( stderr, wxT("Unexpected Postscript plot drill marks option '%ls'.\n"), str.c_str());
+                return false;
+            }
+        }
+
+        // --plot-mirror
+        plot_params.m_PlotMirror = parser.Found( wxT("plot-mirror") );
+
+        // --plot-exclude-edge
+        plot_params.m_ExcludeEdgeLayer =
+            parser.Found( wxT("plot-exclude-edge") );
+
+        frame->SetPlotSettings(plot_params);
+
+        parser.Found( wxT("layers"), &layers_str );
+        wxStringTokenizer tokenizer( layers_str, _(",") );
+        int layer_i = 0;
+        wxString layername;
+        while ( ( layers_str.IsEmpty() && layer_i < NB_LAYERS ) || tokenizer.HasMoreTokens() )
+        {
+            if ( layers_str.IsEmpty() )
+            {
+                if( !frame->GetBoard()->IsLayerEnabled( layer_i ) )
+                {
+                    layer_i++;
+                    continue;
+                }
+                layername = frame->GetBoard()->GetLayerName( layer_i );
+                // remove leading and trailing spaces if any
+                layername.Trim( true ); layername.Trim( false );
+                layer_i++;
+            }
+            else
+            {
+                layername = tokenizer.GetNextToken();
+                for( layer_i = 0; layer_i < NB_LAYERS; layer_i++ )
+                {
+                    str = frame->GetBoard()->GetLayerName( layer_i );
+                    // remove leading and trailing spaces if any
+                    str.Trim( true ); str.Trim( false );
+                    if ( !str.Cmp( layername ) )
+                        break;
+                }
+                if (layer_i >= NB_LAYERS)
+                {
+                    wxFprintf( stderr, _( "Unknown layer name '%ls'\n" ), layername.c_str() );
+                    continue;
+                }
+            }
+            fn = cmdline_fn;
+            fn.SetName( fn.GetName() + wxT( "-" ) + layername );
+
+            // Use Gerber Extensions based on layer number
+            // (See http://en.wikipedia.org/wiki/Gerber_File)
+            if( (plot_format == PLOT_FORMAT_GERBER) && true /* always use gerber extensions */ )
+            {
+                switch( layer_i )
+                {
+                case LAYER_N_FRONT:
+                    fn.SetExt( wxT( "gtl" ) );
+                    break;
+
+                case LAYER_N_2:
+                case LAYER_N_3:
+                case LAYER_N_4:
+                case LAYER_N_5:
+                case LAYER_N_6:
+                case LAYER_N_7:
+                case LAYER_N_8:
+                case LAYER_N_9:
+                case LAYER_N_10:
+                case LAYER_N_11:
+                case LAYER_N_12:
+                case LAYER_N_13:
+                case LAYER_N_14:
+                case LAYER_N_15:
+
+                    // TODO: see if we use .gbr or a layer identifier (gb1 .. gbnn ?)
+                    // according to the new internal layers designation
+                    // (1 is the first internal layer from the front layer)
+                    fn.SetExt( wxT( "gbr" ) );
+                    break;
+
+                case LAYER_N_BACK:
+                    fn.SetExt( wxT( "gbl" ) );
+                    break;
+
+                case ADHESIVE_N_BACK:
+                    fn.SetExt( wxT( "gba" ) );
+                    break;
+
+                case ADHESIVE_N_FRONT:
+                    fn.SetExt( wxT( "gta" ) );
+                    break;
+
+                case SOLDERPASTE_N_BACK:
+                    fn.SetExt( wxT( "gbp" ) );
+                    break;
+
+                case SOLDERPASTE_N_FRONT:
+                    fn.SetExt( wxT( "gtp" ) );
+                    break;
+
+                case SILKSCREEN_N_BACK:
+                    fn.SetExt( wxT( "gbo" ) );
+                    break;
+
+                case SILKSCREEN_N_FRONT:
+                    fn.SetExt( wxT( "gto" ) );
+                    break;
+
+                case SOLDERMASK_N_BACK:
+                    fn.SetExt( wxT( "gbs" ) );
+                    break;
+
+                case SOLDERMASK_N_FRONT:
+                    fn.SetExt( wxT( "gts" ) );
+                    break;
+
+                case DRAW_N:
+                case COMMENT_N:
+                case ECO1_N:
+                case ECO2_N:
+                case EDGE_N:
+                default:
+                    fn.SetExt( wxT( "gbr" ) );
+                    break;
+                }
+            }
+            else
+            {
+                fn.SetExt( ext );
+            }
+
+            bool success = false;
+
+            switch( plot_format )
+            {
+            case PLOT_FORMAT_POST:
+                success = frame->ExportToPostScriptFile( fn.GetFullPath(),
+                    layer_i,
+                    parser.Found( wxT("plot-force-a4") ),
+                    FILLED /* trace_mode */ );
+                break;
+
+            case PLOT_FORMAT_GERBER:
+                success = frame->ExportToGerberFile( fn.GetFullPath(), layer_i,
+                    parser.Found( wxT("plot-aux-origin") ),
+                    FILLED /* trace_mode */ );
+                break;
+
+            case PLOT_FORMAT_DXF:
+                success = frame->ExportToDxfFile( fn.GetFullPath(), layer_i,
+                    parser.Found( wxT("plot-aux-origin") ),
+                    FILLED /* trace_mode */ );
+                break;
+            }
+
+            // Print diags in messages box:
+            wxString msg;
+            if( !success )
+                wxFprintf( stderr, _( "Unable to create <%s>\n" ),
+                    GetChars( fn.GetFullPath() ) );
+        }
+    }
+    if ( parser.Found( wxT("svg"), &str ) )
+    {
+        wxString layers_str;
+        DIALOG_SVG_PRINT dlg( frame );
+
+        parser.Found( wxT("layers"), &layers_str );
+        if ( !layers_str.IsEmpty() )
+        {
+            int layer;
+            for( layer = 0; layer < NB_LAYERS; ++layer )
+            {
+                if (dlg.m_BoxSelectLayer[layer])
+                    dlg.m_BoxSelectLayer[layer]->SetValue( 0 );
+            }
+
+            wxStringTokenizer tokenizer( layers_str, _(",") );
+            while ( tokenizer.HasMoreTokens() )
+            {
+                wxString layername = tokenizer.GetNextToken();
+                for( layer = 0; layer < NB_LAYERS; layer++ )
+                {
+                    wxString cur = frame->GetBoard()->GetLayerName( layer );
+                    // remove leading and trailing spaces if any
+                    cur.Trim( true ); cur.Trim( false );
+                    if ( !cur.Cmp( layername ) )
+                        break;
+                }
+                if (layer >= NB_LAYERS)
+                {
+                    wxFprintf( stderr, _( "Unknown layer '%ls'\n" ),
+                        layername.c_str() );
+                    continue;
+                }
+                if (!dlg.m_BoxSelectLayer[layer])
+                    wxFprintf( stderr, _( "No layer '%ls'\n" ),
+                        layername.c_str() );
+                else
+                    dlg.m_BoxSelectLayer[layer]->SetValue( 1 );
+            }
+        }
+
+        dlg.m_Print_Frame_Ref_Ctrl->SetValue( 0 );
+        dlg.m_PrintBoardEdgesCtrl->SetValue(
+            parser.Found( wxT("svg-board-edges") ) );
+
+        wxSafeYield();
+        if ( !str.CmpNoCase( wxT("selected") ) )
+            dlg.OnButtonPrintSelectedClick( dummy );
+        else if ( !str.CmpNoCase( wxT("board") ) )
+            dlg.OnButtonPrintBoardClick( dummy );
+        else
+        {
+            wxFprintf( stderr, wxT("Unexpected SVG type '%ls'.\n"),
+                str.c_str());
+            return false;
+        }
+    }
+
+    if ( parser.Found( wxT("drc") ) )
+    {
+        wxTextCtrl msgs;
+
+        fn = cmdline_fn;
+        fn.SetExt( _("rpt") );
+
+        // drc.cpp DRC::ShowDialog()
+        // dialogs/dialog_drc.cpp DIALOG_DRC_CONTROL::OnStartdrcClick()
+        frame->m_drc->updatePointers();
+        frame->m_drc->SetSettings(true, // Pad to pad DRC test enabled
+                          true,         // unconnected pdas DRC test enabled
+                          true,         // DRC test for zones enabled
+                          fn.GetFullPath(), // report file name
+                          true /* aSaveReport */ );
+        frame->m_drc->m_pcb->m_Status_Pcb = 0;      // Force full connectivity and ratsnest recalculations
+        frame->m_drc->RunTests(&msgs); // not everybody checks for 0 pointer
+        FILE* fp = wxFopen( fn.GetFullPath(), wxT( "w" ) );
+        { // strings should match dialogs/dialog_drc.cpp:DIALOG_DRC_CONTROL::writeReport()
+            int count;
+
+            fprintf( fp, "** Drc report for %s **\n", TO_UTF8( cmdline_fn.GetFullPath() ) );
+
+            wxDateTime now = wxDateTime::Now();
+            fprintf( fp, "** Created on %s **\n", TO_UTF8( now.Format( wxT( "%F %T" ) ) ) );
+
+            class DRC_LIST_MARKERS* markers = new DRC_LIST_MARKERS( frame->m_drc->m_pcb );
+            count = markers->GetCount();
+            fprintf( fp, "\n** Found %d DRC errors **\n", count );
+            for ( i = 0; i < count; i++ )
+                fprintf( fp, "%s", TO_UTF8( markers->GetItem( i )->ShowReport()) );
+            delete markers;
+
+            class DRC_LIST_UNCONNECTED* unconnected = new DRC_LIST_UNCONNECTED( &frame->m_drc->m_unconnected );
+            count = unconnected->GetCount();
+            fprintf( fp, "\n** Found %d unconnected pads **\n", count );
+            for ( i = 0; i < count; i++ )
+                fprintf( fp, "%s", TO_UTF8( unconnected->GetItem( i )->ShowReport()) );
+            delete unconnected;
+
+            fprintf( fp, "\n** End of Report **\n" );
+        }
+        fclose( fp );
+    }
+
+    if ( parser.Found( wxT("pos") ) )
+    {
+        // see gen_modules_placefile.cpp:PCB_EDIT_FRAME::GenFootprintsPositionFile()
+        fn = cmdline_fn;
+        fn.SetName( fn.GetName() + wxT( "_all") );
+        fn.SetExt( FootprintPlaceFileExtension );
+        frame->DoGenFootprintsPositionFile( fn.GetFullPath(),
+            true /* aUnitsMM */, true /* aForceSmdItems */,
+            2 /* aSide, 2 = both */ );
+    }
+
+    if ( parser.Found( wxT("bom") ) )
+        // see build_BOM_from_board.cpp:PCB_EDIT_FRAME::RecreateBOMFileFromBoard()
+        frame->RecreateBOMFileFromBoard( dummy );
+
+    if ( parser.Found( wxT("cmp") ) )
+        // see xchgmod.cpp:WinEDA_PcbFrame::RecreateCmpFileFromBoard()
+        frame->RecreateCmpFileFromBoard( dummy );
+
+    if ( parser.Found( wxT("vrml") ) )
+    {
+        // see export_vrml.cpp:WinEDA_PcbFrame::OnExportVRML()
+        wxString subDirFor3Dshapes( _( "shapes3D" ) );
+
+        fn = cmdline_fn;
+        fn.SetExt( _("wrl") );
+        if( ! wxDirExists( subDirFor3Dshapes ) )
+            wxMkdir( subDirFor3Dshapes );
+        frame->ExportVRML_File( fn.GetFullPath(), 1.0 /* aScale */,
+            true /* aExport3DFile */, subDirFor3Dshapes );
+    }
+    return true;
+}