/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille, Andrea Enrici * * ludovic.apvrille AT telecom-paristech.fr * andrea.enrici AT telecom-paristech.f * * This software is a computer program whose purpose is to allow the * edition of TURTLE analysis, design and deployment diagrams, to * allow the generation of RT-LOTOS or Java code from this diagram, * and at last to allow the analysis of formal validation traces * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP * from INRIA Rhone-Alpes. * * This software is governed by the CeCILL license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL license and that you accept its terms. */ package ui.window; import launcher.LauncherException; import launcher.RshClient; import myutil.*; import ui.util.IconManager; import ui.*; import tmltranslator.*; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; /** * Class JDialogCCodeGeneration * Dialog for managing the generation and compilation of SystemC code * Creation: 27/04/2005 * @version 1.2 27/04/2015 * @author Andrea ENRICI, Ludovic APVRILLE */ public class JDialogCCodeGeneration extends JDialog implements ActionListener, Runnable { protected MainGUI mgui; private static String textSysC1 = "Generate C code in"; private static String textSysC2 = "Compile C code in"; private static String textSysC3 = "Model compilation options"; //private static String textSysC4 = "Run simulation to completion:"; //private static String textSysC5 = "Run interactive simulation:"; //private static String textSysC6 = "Run formal verification:"; //private static String unitCycle = "1"; //private static String[] simus = { "SystemC Simulator - LabSoC version", //"C++ Simulator - LabSoc version" }; private static String DEFAULT_GENERATOR = "TTool integrated C generator"; // private static int selectedItem = 1; protected static String pathCode; protected static String pathCompiler; protected static String compilerOptions; //protected static String pathExecute; //protected static String pathInteractiveExecute; // protected static String pathFormalExecute; protected static boolean interactiveSimulationSelected = true; //protected static boolean optimizeModeSelected = true; protected final static int NOT_STARTED = 1; protected final static int STARTED = 2; protected final static int STOPPED = 3; int mode; //components protected JTextArea jta; protected JButton start; protected JButton stop; protected JButton close; protected JLabel gen, comp, opt; protected JTextField code1, code2, compiler1, codeOpt; //exe1, exe2, exe3, exe2int, exe2formal; protected JTabbedPane jp1; protected JScrollPane jsp; protected JCheckBox removeCppFiles, removeXFiles;//, debugmode, optimizemode; protected JComboBox<String> versionSimulator; protected Vector<String> generators; protected JComboBox<String> generatorsBox; private Thread t; private boolean go = false; private boolean hasError = false; protected boolean startProcess = false; private String hostSystemC; protected RshClient rshc; private int automatic; //private boolean wasClosed = false; private GTURTLEModeling gtm; /** Creates new form */ public JDialogCCodeGeneration(Frame f, MainGUI _mgui, String title, String _pathCode, String _pathCompiler, GTURTLEModeling _gtm ) { super(f, title, true); mgui = _mgui; gtm = _gtm; pathCode = _pathCode; pathCompiler = _pathCompiler; initComponents(); myInitComponents(); pack(); getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); if (automatic > 0) { startProcess(); } } protected void myInitComponents() { mode = NOT_STARTED; setButtons(); } protected void initComponents() { Container c = getContentPane(); setFont(new Font("Helvetica", Font.PLAIN, 14)); c.setLayout(new BorderLayout()); // Issue #41 Ordering of tabbed panes jp1 = GraphicLib.createTabbedPane();//new JTabbedPane(); JPanel jp01 = new JPanel(); GridBagLayout gridbag01 = new GridBagLayout(); GridBagConstraints c01 = new GridBagConstraints(); jp01.setLayout(gridbag01); jp01.setBorder(new javax.swing.border.TitledBorder("Code generation")); JPanel jp02 = new JPanel(); GridBagLayout gridbag02 = new GridBagLayout(); GridBagConstraints c02 = new GridBagConstraints(); jp02.setLayout(gridbag02); jp02.setBorder(new javax.swing.border.TitledBorder("Compilation")); JPanel jp03 = new JPanel(); GridBagLayout gridbag03 = new GridBagLayout(); //GridBagConstraints c03 = new GridBagConstraints(); jp03.setLayout(gridbag03); jp03.setBorder(new javax.swing.border.TitledBorder("Execution")); c01.gridheight = 1; c01.weighty = 1.0; c01.weightx = 1.0; c01.gridwidth = GridBagConstraints.REMAINDER; //end row c01.fill = GridBagConstraints.BOTH; c01.gridheight = 1; jp01.add(new JLabel(" "), c01); c01.gridwidth = GridBagConstraints.REMAINDER; //end row gen = new JLabel(textSysC1); jp01.add(gen, c01); code1 = new JTextField(pathCode, 100); // Issue #57: code generation directory field is not editable //code1.setEnabled(false); jp01.add(code1, c01); // JLabel for compilation options jp01.add(new JLabel(" "), c01); c01.gridwidth = GridBagConstraints.REMAINDER; //end row opt = new JLabel(textSysC3); jp01.add(opt, c01); codeOpt = new JTextField(compilerOptions, 100); jp01.add(codeOpt, c01); jp01.add(new JLabel(" "), c01); c01.gridwidth = GridBagConstraints.REMAINDER; //end row generators = new Vector<String>(); generators.add(DEFAULT_GENERATOR); fillGeneratorsWithPlugins(generators); generatorsBox = new JComboBox<>(generators); if (generators.size() > 1) { generatorsBox.setSelectedIndex(1); } jp01.add(generatorsBox, c01); c01.gridwidth = GridBagConstraints.REMAINDER; //end row jp01.add(new JLabel(" "), c01); c01.gridwidth = GridBagConstraints.REMAINDER; //end row removeCppFiles = new JCheckBox("Remove old .h, .c, .o files"); removeCppFiles.setSelected(true); jp01.add(removeCppFiles, c01); removeXFiles = new JCheckBox("Remove old .x files"); removeXFiles.setSelected(true); jp01.add(removeXFiles, c01); /*debugmode = new JCheckBox("Put debug information in code"); debugmode.setSelected(false); jp01.add(debugmode, c01);*/ /*optimizemode = new JCheckBox("Optimize code"); optimizemode.setSelected(optimizeModeSelected); jp01.add(optimizemode, c01);*/ jp01.add(new JLabel(" "), c01); jp1.add("Synthesize code", jp01); // Panel 02 c02.gridheight = 1; c02.weighty = 1.0; c02.weightx = 1.0; c02.gridwidth = GridBagConstraints.REMAINDER; //end row c02.fill = GridBagConstraints.BOTH; c02.gridheight = 1; comp = new JLabel(textSysC2); jp02.add(comp, c02); code2 = new JTextField(pathCode, 100); // Issue #57 // code2.setEnabled(false); jp02.add(code2, c02); jp02.add(new JLabel("with"), c02); compiler1 = new JTextField(pathCompiler, 100); // Issue #57 //compiler1.setEnabled(false); jp02.add(compiler1, c02); jp02.add(new JLabel(" "), c02); jp1.add("Compile", jp02); c.add(jp1, BorderLayout.NORTH); if (automatic > 0) { GraphicLib.enableComponents(jp1, false); } jta = new ScrolledJTextArea(); jta.setEditable(false); jta.setMargin(new Insets(10, 10, 10, 10)); jta.setTabSize(3); if (automatic == 0) { jta.append("Select options and then,\n click on 'start' to launch C code generation and compilation\n\n"); } Font f = new Font("Courrier", Font.BOLD, 12); jta.setFont(f); jsp = new JScrollPane(jta, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); c.add(jsp, BorderLayout.CENTER); start = new JButton("Start", IconManager.imgic53); stop = new JButton("Stop", IconManager.imgic55); start.setPreferredSize(new Dimension(100, 30)); stop.setPreferredSize(new Dimension(100, 30)); start.addActionListener(this); stop.addActionListener(this); close = new JButton("Close", IconManager.imgic27); close.setPreferredSize(new Dimension(100, 30)); close.addActionListener(this); JPanel jp2 = new JPanel(); if (automatic == 0) { jp2.add(start); jp2.add(stop); } jp2.add(close); c.add(jp2, BorderLayout.SOUTH); } @Override public void actionPerformed(ActionEvent evt) { String command = evt.getActionCommand(); // Compare the action command to the known actions. if (command.equals("Start")) { startProcess(); } else if (command.equals("Stop")) { stopProcess(); } else if (command.equals("Close")) { closeDialog(); } } public void closeDialog() { if (mode == STARTED) { stopProcess(); } //optimizeModeSelected = optimizemode.isSelected(); //wasClosed = true; dispose(); } // // public boolean wasClosed() { // return wasClosed; // } public void stopProcess() { try { if (rshc != null) { rshc.stopCommand(); } } catch (LauncherException le) { } rshc = null; mode = STOPPED; setButtons(); go = false; } public void startProcess() { if (automatic > 0) { startProcess = false; t = new Thread(this); mode = STARTED; go = true; t.start(); } else { startProcess = false; t = new Thread(this); mode = STARTED; setButtons(); go = true; t.start(); } } private void testGo() throws InterruptedException { if (go == false) { throw new InterruptedException("Stopped by user"); } } @Override public void run() { // String cmd; // String data; hasError = false; try { if (automatic > 0) { hasError = generateCode(); testGo(); compileCode(); testGo(); } else { if( jp1.getSelectedIndex() == 0 ) { //Code generation hasError = generateCode(); } testGo(); // Compilation if( jp1.getSelectedIndex() == 1 ) { compileCode(); } if( ( hasError == false ) && ( jp1.getSelectedIndex() < 1 ) ) { jp1.setSelectedIndex( jp1.getSelectedIndex() + 1 ); } } } catch( InterruptedException ie ) { jta.append("Process interrupted!\n"); } jta.append("\n\nReady to process next command...\n"); checkMode(); setButtons(); } private boolean generateCode() throws InterruptedException { String list; // int cycle = 0; boolean error = false; jta.append( "Generating C code...\n\n" ); if( removeCppFiles.isSelected() ) { jta.append( "Removing all .h files...\n" ); list = FileUtils.deleteFiles( code1.getText(), ".h" ); if( list.length() == 0 ) { jta.append("No files were deleted\n"); } else { jta.append("Files deleted:\n" + list + "\n"); } jta.append("\nRemoving all .c files...\n"); list = FileUtils.deleteFiles( code1.getText(), ".c" ); if( list.length() == 0 ) { jta.append( "No files were deleted\n" ); } else { jta.append("Files deleted:\n" + list + "\n"); } jta.append("\nRemoving all .o files...\n"); list = FileUtils.deleteFiles( code1.getText(), ".o" ); if( list.length() == 0 ) { jta.append( "No files were deleted\n" ); } else { jta.append( "Files deleted:\n" + list + "\n" ); } } if (removeXFiles.isSelected()) { jta.append( "\nRemoving all .x files...\n" ); list = FileUtils.deleteFiles( code1.getText(), ".x" ); if( list.length() == 0 ) { jta.append("No files were deleted\n"); } else { jta.append("Files deleted:\n" + list + "\n"); } } testGo(); if (generatorsBox.getSelectedIndex() == 0) { error = gtm.generateCCode( code1.getText(), codeOpt.getText() ); if( !error ) { File dir = new File( code1.getText() ); StringBuffer s = new StringBuffer(); jta.append( "\nSource files successfully generated:\n" ); for( File f: dir.listFiles() ) { try { if( f.getCanonicalPath().contains(".c") || f.getCanonicalPath().contains(".h") ) { s.append( f.getCanonicalPath() + "\n" ); } } catch( IOException ioe ) { jta.append("Error: " + ioe.getMessage() + "\n"); mode = STOPPED; setButtons(); return true; } } jta.append( s.toString() ); } } else { // code generation by plugin! int index = generatorsBox.getSelectedIndex() - 1; int cpt = 0; Plugin foundPlugin = null; LinkedList<Plugin> listP = PluginManager.pluginManager.getPluginDiplodocusCodeGenerator(); for(Plugin p: listP) { String desc = p.getDiplodocusCodeGeneratorIdentifier(); if (desc != null) { if (index == cpt) { foundPlugin = p; break; } } } if (foundPlugin == null) { jta.append("Invalid plugin\n"); } else { // We have a valid plugin // We first need to get an XML representation of the current mapping TMLMapping<?> tmap = gtm.getTMLMapping(); if (tmap == null) { jta.append("Invalid mapping\n"); } else { String XML = tmap.toXML(); try { Object instance = foundPlugin.getClassDiplodocusCodeGenerator().newInstance(); if (instance == null) { jta.append("Invalid plugin: could not create an instance\n"); } else { boolean ret = Plugin.executeBoolStringMethod(instance, XML, "generateCode", codeOpt.getText()); } } catch (Exception e) { jta.append("Exception when calling plugin:" + e.getMessage()); } } } } return error; } //End of method generateCode() public void compileCode() throws InterruptedException { String cmd = compiler1.getText(); jta.append("Compiling C code with command: \n" + cmd + "\n****\n"); rshc = new RshClient(hostSystemC); // Assuma data are on the remote host // Command try { processCmd(cmd, jta); } catch( Exception e ) { jta.append("**** ERROR ****\n" + e.getMessage() + "\n"); mode = STOPPED; setButtons(); return; } } protected void processCmd( String cmd, JTextArea _jta ) throws Exception { String s; Process p; p = Runtime.getRuntime().exec( cmd ); BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) ); while( ( s = br.readLine() ) != null ) { _jta.append( s + "\n" ); } p.waitFor(); p.destroy(); if( p.exitValue() != 0 ) { throw new Exception( "Make exit status: " + p.exitValue() ); } } protected void checkMode() { mode = NOT_STARTED; } protected void setButtons() { if (automatic == 0) { switch(mode) { case NOT_STARTED: start.setEnabled(true); stop.setEnabled(false); close.setEnabled(true); getGlassPane().setVisible(false); break; case STARTED: start.setEnabled(false); stop.setEnabled(true); close.setEnabled(false); getGlassPane().setVisible(true); break; case STOPPED: default: start.setEnabled(false); stop.setEnabled(false); close.setEnabled(true); getGlassPane().setVisible(false); break; } } else { close.setEnabled(true); } } public void fillGeneratorsWithPlugins(Vector<String> v) { LinkedList<Plugin> list = PluginManager.pluginManager.getPluginDiplodocusCodeGenerator(); for(Plugin p: list) { String desc = p.getDiplodocusCodeGeneratorIdentifier(); if (desc != null) { v.add(desc); } } } } //End of class