Added file browser and source code editor

master
Marco Maccaferri 2018-12-18 04:33:07 +01:00
rodzic 441a344dcf
commit 4404375e85
15 zmienionych plików z 2804 dodań i 35 usunięć

Wyświetl plik

@ -34,7 +34,7 @@
<mkdir dir="${work}/bin" />
<javac target="1.8" source="1.8" destdir="${work}/bin" srcdir="src" debug="true" includeantruntime="false">
<classpath refid="lib.path.ref"/>
<classpath refid="lib.path.ref"/>
<classpath>
<pathelement location="lib/org.eclipse.swt.gtk.linux.x86_64_3.104.2.v20160212-1350.jar"/>
</classpath>
@ -184,7 +184,7 @@
</target>
<path id="lib.path.ref">
<path id="lib.path.ref">
<pathelement location="lib/org.eclipse.core.commands_3.7.0.v20150422-0725.jar"/>
<pathelement location="lib/org.eclipse.core.databinding_1.5.0.v20150422-0725.jar"/>
<pathelement location="lib/org.eclipse.core.databinding.beans_1.3.0.v20150422-0725.jar"/>
@ -194,7 +194,10 @@
<pathelement location="lib/org.eclipse.jface_3.11.1.v20160128-1644.jar"/>
<pathelement location="lib/org.eclipse.jface.databinding_1.7.0.v20150406-2148.jar"/>
<pathelement location="lib/org.eclipse.jface.text_3.10.0.v20150603-1752.jar"/>
</path>
<pathelement location="lib/jackson-annotations-2.7.0.jar"/>
<pathelement location="lib/jackson-core-2.7.0.jar"/>
<pathelement location="lib/jackson-databind-2.7.0.jar"/>
</path>
<target name="copy-common-files">
<jar destfile="${work}/${folder}/lib/${package}.jar">
@ -214,6 +217,9 @@
<fileset dir="lib" includes="org.eclipse.jface_3.11.1.v20160128-1644.jar"/>
<fileset dir="lib" includes="org.eclipse.jface.databinding_1.7.0.v20150406-2148.jar"/>
<fileset dir="lib" includes="org.eclipse.jface.text_3.10.0.v20150603-1752.jar"/>
<fileset dir="lib" includes="jackson-annotations-2.7.0.jar"/>
<fileset dir="lib" includes="jackson-core-2.7.0.jar"/>
<fileset dir="lib" includes="jackson-databind-2.7.0.jar"/>
</copy>
<copy todir="${work}/${folder}">

Wyświetl plik

@ -10,14 +10,32 @@
package com.maccasoft.tools;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.jface.databinding.swt.DisplayRealm;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabFolder2Adapter;
import org.eclipse.swt.custom.CTabFolderEvent;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MenuEvent;
@ -29,9 +47,11 @@ import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
@ -47,10 +67,14 @@ public class Application {
Display display;
Shell shell;
SashForm sashForm;
FileBrowser browser;
CTabFolder tabFolder;
public Application() {
Preferences preferences;
public Application() {
preferences = Preferences.getInstance();
}
public void open() {
@ -96,10 +120,22 @@ public class Application {
shell.open();
shell.addListener(SWT.Close, new Listener() {
@Override
public void handleEvent(Event event) {
event.doit = handleUnsavedContent();
}
});
shell.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
try {
preferences.save();
} catch (IOException e1) {
e1.printStackTrace();
}
ImageRegistry.dispose();
}
});
@ -107,46 +143,93 @@ public class Application {
void createFileMenu(Menu parent) {
final Menu menu = new Menu(parent.getParent(), SWT.DROP_DOWN);
menu.addMenuListener(new MenuListener() {
@Override
public void menuShown(MenuEvent e) {
MenuItem[] item = menu.getItems();
for (int i = 0; i < item.length; i++) {
item[i].dispose();
}
populateFileMenu(menu);
}
@Override
public void menuHidden(MenuEvent e) {
}
});
populateFileMenu(menu);
MenuItem item = new MenuItem(parent, SWT.CASCADE);
item.setText("&File");
item.setMenu(menu);
}
void populateFileMenu(Menu menu) {
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText("New");
item = new MenuItem(menu, SWT.CASCADE);
item.setText("New\tCtrl+N");
item.setAccelerator(SWT.MOD1 + 'N');
item.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event e) {
SourceEditorTab tab = new SourceEditorTab(tabFolder, "");
tab.setText(getDefaultName());
tab.setFocus();
}
String getDefaultName() {
Date date = new Date();
SimpleDateFormat df = new SimpleDateFormat("MMMdd");
for (char c = 'a'; c <= 'z'; c++) {
String result = String.format("%s%c.asm", df.format(date), c);
File file = new File(result);
if (!file.exists() && !nameExists(result)) {
return result;
}
}
return null;
}
boolean nameExists(String name) {
CTabItem[] tabItem = tabFolder.getItems();
for (int n = 0; n < tabItem.length; n++) {
if (name.equals(tabItem[n].getText())) {
return true;
}
}
return false;
}
});
item = new MenuItem(menu, SWT.PUSH);
item.setText("Open...");
item.setText("Open...\tCtrl+O");
item.setAccelerator(SWT.MOD1 + 'O');
item.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event e) {
try {
handleFileOpen();
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
new MenuItem(menu, SWT.SEPARATOR);
item = new MenuItem(menu, SWT.PUSH);
item.setText("Close");
item.setAccelerator(SWT.MOD1 + 'O');
item.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event e) {
try {
handleFileClose();
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
item = new MenuItem(menu, SWT.PUSH);
item.setText("Close All");
item.setAccelerator(SWT.MOD1 + 'O');
item.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event e) {
try {
handleFileCloseAll();
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
@ -159,7 +242,11 @@ public class Application {
@Override
public void handleEvent(Event e) {
try {
handleFileSave();
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
@ -169,7 +256,11 @@ public class Application {
@Override
public void handleEvent(Event e) {
try {
handleFileSaveAs();
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
@ -180,7 +271,11 @@ public class Application {
@Override
public void handleEvent(Event e) {
try {
handleFileSaveAll();
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
@ -198,7 +293,26 @@ public class Application {
new MenuItem(menu, SWT.SEPARATOR);
populateLruFiles(menu);
final int lruItemIndex = menu.getItemCount();
menu.addMenuListener(new MenuListener() {
MenuItem[] lruItems;
@Override
public void menuShown(MenuEvent e) {
if (lruItems != null) {
for (int i = 0; i < lruItems.length; i++) {
lruItems[i].dispose();
}
}
lruItems = populateLruFiles(menu, lruItemIndex);
}
@Override
public void menuHidden(MenuEvent e) {
}
});
item = new MenuItem(menu, SWT.PUSH);
item.setText("Exit");
@ -211,27 +325,42 @@ public class Application {
});
}
void populateLruFiles(Menu menu) {
MenuItem[] populateLruFiles(Menu menu, int itemIndex) {
int index = 0;
List<MenuItem> list = new ArrayList<MenuItem>();
Iterator<String> iter = new ArrayList<String>().iterator();
Iterator<String> iter = preferences.getLru().iterator();
while (iter.hasNext() && index < 4) {
final File fileToOpen = new File(iter.next());
MenuItem item = new MenuItem(menu, SWT.PUSH);
MenuItem item = new MenuItem(menu, SWT.PUSH, itemIndex++);
item.setText(String.format("%d %s", index + 1, fileToOpen.getName()));
item.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event e) {
try {
if (!fileToOpen.exists()) {
preferences.removeLru(fileToOpen);
return;
}
SourceEditorTab tab = openSourceTab(fileToOpen);
tabFolder.setSelection(tab.getTabItem());
tab.setFocus();
preferences.addLru(fileToOpen);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
list.add(item);
index++;
}
if (index > 0) {
new MenuItem(menu, SWT.SEPARATOR);
list.add(new MenuItem(menu, SWT.SEPARATOR, itemIndex));
}
return list.toArray(new MenuItem[list.size()]);
}
void createEditMenu(Menu parent) {
@ -378,7 +507,15 @@ public class Application {
FontMetrics fontMetrics = gc.getFontMetrics();
gc.dispose();
tabFolder = new CTabFolder(parent, SWT.BORDER);
sashForm = new SashForm(parent, SWT.HORIZONTAL);
sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
browser = new FileBrowser(sashForm);
browser.setRoots(new File[] {
new File(System.getProperty("user.home"))
});
tabFolder = new CTabFolder(sashForm, SWT.BORDER);
tabFolder.setTabHeight((int) (fontMetrics.getHeight() * 1.5));
tabFolder.addSelectionListener(new SelectionAdapter() {
@ -387,6 +524,265 @@ public class Application {
}
});
tabFolder.addCTabFolder2Listener(new CTabFolder2Adapter() {
@Override
public void close(CTabFolderEvent event) {
SourceEditorTab tab = (SourceEditorTab) event.item.getData();
event.doit = canCloseSourceTab(tab);
}
});
sashForm.setWeights(new int[] {
20, 80
});
String lastPath = preferences.getLastPath();
if (lastPath == null) {
lastPath = new File("").getAbsolutePath();
}
File file = new File(lastPath).getAbsoluteFile();
if (!file.isDirectory()) {
file = file.getParentFile();
}
browser.setSelection(file);
browser.addOpenListener(new IOpenListener() {
@Override
public void open(OpenEvent event) {
try {
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
if (selection.getFirstElement() instanceof File) {
File file = (File) selection.getFirstElement();
if (file.isDirectory()) {
return;
}
SourceEditorTab tab = openSourceTab(file);
tabFolder.setSelection(tab.getTabItem());
tab.setFocus();
preferences.addLru(file);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void handleFileOpen() {
FileDialog dlg = new FileDialog(shell, SWT.OPEN);
String[] filterNames = new String[] {
"Assembler Files"
};
String[] filterExtensions = new String[] {
"*.ASM;*.asm"
};
dlg.setFilterNames(filterNames);
dlg.setFilterExtensions(filterExtensions);
if (preferences.getLastPath() != null) {
dlg.setFilterPath(preferences.getLastPath());
}
dlg.setText("Open File");
final String fileName = dlg.open();
if (fileName != null) {
File file = new File(fileName);
try {
SourceEditorTab tab = openSourceTab(file);
tabFolder.setSelection(tab.getTabItem());
tab.setFocus();
} catch (IOException e) {
e.printStackTrace();
}
preferences.addLru(file);
preferences.setLastPath(file.getParent());
}
}
SourceEditorTab openSourceTab(File file) throws IOException {
String line;
StringBuilder sb = new StringBuilder();
if (file.exists()) {
BufferedReader reader = new BufferedReader(new FileReader(file));
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
reader.close();
}
SourceEditorTab tab = new SourceEditorTab(tabFolder, sb.toString());
tab.setText(file.getName());
tab.setToolTipText(file.getAbsolutePath());
tab.setFile(file);
return tab;
}
private void handleFileSave() throws IOException {
CTabItem tabItem = tabFolder.getSelection();
if (tabItem == null) {
return;
}
saveSourceTab((SourceEditorTab) tabItem.getData(), false);
}
private void handleFileSaveAs() throws IOException {
CTabItem tabItem = tabFolder.getSelection();
if (tabItem == null) {
return;
}
saveSourceTab((SourceEditorTab) tabItem.getData(), true);
}
private void handleFileSaveAll() {
CTabItem[] tabItem = tabFolder.getItems();
for (int i = 0; i < tabItem.length; i++) {
SourceEditorTab tab = (SourceEditorTab) tabItem[i].getData();
if (tab.isDirty()) {
try {
if (saveSourceTab(tab, false) == null) {
break;
}
tab.clearDirty();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
private boolean handleUnsavedContent() {
boolean dirty = false;
CTabItem[] tabItem = tabFolder.getItems();
for (int i = 0; i < tabItem.length; i++) {
SourceEditorTab tab = (SourceEditorTab) tabItem[i].getData();
if (tab.isDirty()) {
dirty = true;
break;
}
}
if (dirty) {
String msg = "Editor contains unsaved changes. Save before exit?";
String[] buttons = new String[] {
IDialogConstants.YES_LABEL,
IDialogConstants.NO_LABEL,
IDialogConstants.CANCEL_LABEL
};
MessageDialog dlg = new MessageDialog(shell, APP_TITLE, null, msg, MessageDialog.QUESTION, buttons, 0);
switch (dlg.open()) {
case 0: // YES
try {
for (int i = 0; i < tabItem.length; i++) {
SourceEditorTab tab = (SourceEditorTab) tabItem[i].getData();
if (tab.isDirty()) {
if (saveSourceTab(tab, false) == null) {
return false;
}
}
}
dirty = false;
} catch (IOException e) {
e.printStackTrace();
}
break;
case 1: // NO
return true;
case 2: // CANCEL
return false;
}
}
return !dirty;
}
File saveSourceTab(SourceEditorTab tab, boolean saveAs) throws IOException {
File file = tab.getFile();
if (saveAs || file == null) {
FileDialog dlg = new FileDialog(shell, SWT.SAVE);
if (preferences.getLastPath() != null) {
dlg.setFilterPath(preferences.getLastPath());
}
dlg.setFileName(tab.getText());
dlg.setText("Save File");
String fileName = dlg.open();
if (fileName == null) {
return null;
}
file = new File(fileName);
}
Writer os = new OutputStreamWriter(new FileOutputStream(file));
os.write(tab.getEditor().getText());
os.close();
if (saveAs || tab.getFile() == null) {
tab.setFile(file);
tab.setText(file.getName());
tab.setToolTipText(file.getAbsolutePath());
preferences.setLastPath(file.getParent());
}
tab.clearDirty();
return file;
}
private void handleFileClose() {
CTabItem tabItem = tabFolder.getSelection();
if (tabItem == null) {
return;
}
SourceEditorTab tab = (SourceEditorTab) tabItem.getData();
if (canCloseSourceTab(tab)) {
tabItem.dispose();
}
}
private void handleFileCloseAll() {
CTabItem[] tabItem = tabFolder.getItems();
for (int i = 0; i < tabItem.length; i++) {
SourceEditorTab tab = (SourceEditorTab) tabItem[i].getData();
if (!canCloseSourceTab(tab)) {
return;
}
}
for (int i = 0; i < tabItem.length; i++) {
tabItem[i].dispose();
}
}
boolean canCloseSourceTab(SourceEditorTab tab) {
if (tab.isDirty()) {
String msg = "Save changes in '" + tab.getText() + "'?";
String[] buttons = new String[] {
IDialogConstants.YES_LABEL,
IDialogConstants.NO_LABEL,
IDialogConstants.CANCEL_LABEL
};
MessageDialog dlg = new MessageDialog(shell, APP_TITLE, null, msg, MessageDialog.QUESTION, buttons, 0);
switch (dlg.open()) {
case 0:
try {
if (saveSourceTab(tab, false) == null) {
return false;
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
break;
case 2:
return false;
}
tab.clearDirty();
}
return true;
}
static {

Wyświetl plik

@ -0,0 +1,174 @@
/*
* Copyright (c) 2018 Marco Maccaferri and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.maccasoft.tools;
import java.io.File;
import java.io.FileFilter;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import com.maccasoft.tools.internal.ImageRegistry;
public class FileBrowser {
TreeViewer viewer;
File[] roots;
Set<String> visibleExtensions;
class FileLabelProvider extends LabelProvider {
@Override
public String getText(Object element) {
return ((File) element).getName();
}
@Override
public Image getImage(Object element) {
if (((File) element).isDirectory()) {
return ImageRegistry.getImageFromResources("folder.png");
}
return ImageRegistry.getImageFromResources("document-code.png");
}
}
class FileTreeContentProvider implements ITreeContentProvider {
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
@Override
public Object[] getElements(Object inputElement) {
if (inputElement instanceof File[]) {
return (File[]) inputElement;
}
return new File[0];
}
@Override
public Object[] getChildren(Object parentElement) {
File[] childs = ((File) parentElement).listFiles(visibleExtensionsFilter);
return childs;
}
@Override
public Object getParent(Object element) {
return ((File) element).getParentFile();
}
@Override
public boolean hasChildren(Object element) {
return ((File) element).isDirectory();
}
}
class FileSorter extends ViewerSorter {
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
if (((File) e1).isDirectory() && !((File) e2).isDirectory()) {
return -1;
}
if (!((File) e1).isDirectory() && ((File) e2).isDirectory()) {
return 1;
}
return super.compare(viewer, e1, e2);
}
}
final FileFilter visibleExtensionsFilter = new FileFilter() {
@Override
public boolean accept(File pathname) {
String name = pathname.getName();
if (pathname.isDirectory()) {
if (name.equals(".") || name.equals("..")) {
return false;
}
return true;
}
if (name.startsWith(".")) {
return false;
}
return accept(name);
}
boolean accept(String name) {
int i = name.lastIndexOf('.');
if (i != -1) {
return visibleExtensions.contains(name.substring(i).toLowerCase());
}
return false;
}
};
public FileBrowser(Composite parent) {
viewer = new TreeViewer(parent);
viewer.setLabelProvider(new FileLabelProvider());
viewer.setSorter(new FileSorter());
viewer.setContentProvider(new FileTreeContentProvider());
viewer.setUseHashlookup(true);
visibleExtensions = new HashSet<String>();
visibleExtensions.add(".asm");
}
public File[] getRoots() {
return roots;
}
public void setRoots(File[] roots) {
this.roots = roots;
viewer.setInput(roots);
}
public void setSelection(File file) {
viewer.setSelection(new StructuredSelection(file), true);
viewer.setExpandedState(file, true);
}
public void addSelectionChangedListener(ISelectionChangedListener l) {
viewer.addSelectionChangedListener(l);
}
public void removeSelectionChangedListener(ISelectionChangedListener l) {
viewer.removeSelectionChangedListener(l);
}
public void addOpenListener(IOpenListener l) {
viewer.addOpenListener(l);
}
public void removeOpenListener(IOpenListener l) {
viewer.removeOpenListener(l);
}
}

Wyświetl plik

@ -0,0 +1,120 @@
/*
* Copyright (c) 2018 Marco Maccaferri and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.maccasoft.tools;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
public class Preferences {
public static final String PROP_LRU = "lru";
public static final String PROP_LASTPATH = "lastPath";
public static final String PREFERENCES_NAME = ".z80-tools";
private static Preferences instance;
public static Preferences getInstance() {
if (instance != null) {
return instance;
}
File file = new File(System.getProperty("user.home"), PREFERENCES_NAME);
if (file.exists()) {
try {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
instance = mapper.readValue(file, Preferences.class);
} catch (Exception e) {
e.printStackTrace();
instance = new Preferences();
}
}
else {
instance = new Preferences();
}
return instance;
}
String lastPath;
List<String> lru;
final PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
Preferences() {
lru = new ArrayList<String>();
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
changeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
changeSupport.removePropertyChangeListener(listener);
}
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
changeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
changeSupport.removePropertyChangeListener(propertyName, listener);
}
public String getLastPath() {
return lastPath;
}
public void setLastPath(String lastPath) {
this.lastPath = lastPath;
}
public List<String> getLru() {
return lru;
}
public void addLru(File file) {
lru.remove(file.getAbsolutePath());
lru.add(0, file.getAbsolutePath());
while (lru.size() > 10) {
lru.remove(lru.size() - 1);
}
changeSupport.firePropertyChange(PROP_LRU, null, this.lru);
}
public void removeLru(File file) {
lru.remove(file.getAbsolutePath());
changeSupport.firePropertyChange(PROP_LRU, null, this.lru);
}
public void save() throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
mapper.setSerializationInclusion(Include.NON_EMPTY);
mapper.writeValue(new File(System.getProperty("user.home"), PREFERENCES_NAME), this);
}
public void dispose() {
instance = null;
for (PropertyChangeListener l : changeSupport.getPropertyChangeListeners()) {
changeSupport.removePropertyChangeListener(l);
}
}
}

Wyświetl plik

@ -0,0 +1,145 @@
/*
* Copyright (c) 2018 Marco Maccaferri and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.maccasoft.tools;
import java.io.File;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import com.maccasoft.tools.editor.SourceEditor;
import com.maccasoft.tools.editor.Z80TokenMarker;
public class SourceEditorTab {
String text;
SourceEditor editor;
CTabItem tabItem;
File file;
boolean dirty;
final ModifyListener modifyListener = new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
if (!dirty) {
dirty = true;
updateTabItemText();
}
}
};
public SourceEditorTab(CTabFolder parent, String text) {
editor = new SourceEditor(parent, new Z80TokenMarker());
editor.setText(text);
tabItem = new CTabItem(parent, SWT.NONE);
tabItem.setShowClose(true);
tabItem.setControl(editor.getControl());
tabItem.setData(this);
editor.addModifyListener(modifyListener);
tabItem.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
}
});
}
public void setFocus() {
tabItem.getParent().setSelection(tabItem);
editor.getControl().setFocus();
}
public void setText(String text) {
if (this.text != null && !text.equals(this.text)) {
dirty = true;
}
this.text = text;
updateTabItemText();
}
public String getText() {
return text;
}
public void setToolTipText(String text) {
tabItem.setToolTipText(text);
}
public String getToolTipText() {
return tabItem.getToolTipText();
}
public void addModifyListener(ModifyListener listener) {
editor.addModifyListener(listener);
}
public void removeModifyListener(ModifyListener listener) {
editor.removeModifyListener(listener);
}
public void addDisposeListener(DisposeListener listener) {
tabItem.addDisposeListener(listener);
}
public void removeDisposeListener(DisposeListener listener) {
tabItem.removeDisposeListener(listener);
}
public void dispose() {
editor.removeModifyListener(modifyListener);
editor.getControl().dispose();
tabItem.dispose();
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public boolean isDirty() {
return dirty;
}
public void clearDirty() {
if (dirty) {
dirty = false;
}
updateTabItemText();
}
void updateTabItemText() {
String dirtyFlag = dirty ? "*" : "";
tabItem.setText(dirtyFlag + text);
}
public SourceEditor getEditor() {
return editor;
}
public CTabItem getTabItem() {
return tabItem;
}
}

Wyświetl plik

@ -0,0 +1,48 @@
/*
* Copyright (c) 2018 Marco Maccaferri and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.maccasoft.tools.editor;
public class EditorUtil {
public static boolean isWhitespace(char c) {
return c == ' ' || c == '\t';
}
public static boolean isSeparator(char c) {
if (Character.isWhitespace(c)) {
return false;
}
return !Character.isLetterOrDigit(c);
}
public static String replaceTabs(String text, int tabs) {
final StringBuilder spaces = new StringBuilder(tabs);
for (int i = 0; i < tabs; i++) {
spaces.append(' ');
}
int i = 0;
while ((i = text.indexOf('\t', i)) != -1) {
int s = i;
while (s > 0) {
s--;
if (text.charAt(s) == '\r' || text.charAt(s) == '\n') {
s++;
break;
}
}
int n = ((i - s) % tabs);
text = text.substring(0, i) + spaces.substring(0, tabs - n) + text.substring(i + 1);
}
return text;
}
}

Wyświetl plik

@ -0,0 +1,127 @@
/*
* Copyright (c) 2018 Marco Maccaferri and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.maccasoft.tools.editor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ScrollBar;
public class LineNumbersRuler {
Canvas canvas;
GridData layoutData;
FontMetrics fontMetrics;
StyledText text;
int leftMargin;
int rightMargin;
private int scrollBarSelection;
private int lineCount;
final PaintListener paintListener = new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
if (text != null) {
onPaintControl(e.gc);
}
}
};
final PaintListener textPaintListener = new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
ScrollBar scrollBar = text.getVerticalBar();
if (scrollBarSelection != scrollBar.getSelection() || lineCount != text.getLineCount()) {
canvas.redraw();
scrollBarSelection = scrollBar.getSelection();
lineCount = text.getLineCount();
}
}
};
public LineNumbersRuler(Composite parent) {
canvas = new Canvas(parent, SWT.NO_FOCUS);
canvas.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
canvas.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND));
canvas.setLayoutData(layoutData = new GridData(SWT.FILL, SWT.FILL, false, true));
canvas.addPaintListener(paintListener);
GC gc = new GC(canvas);
fontMetrics = gc.getFontMetrics();
gc.dispose();
leftMargin = rightMargin = 5;
layoutData.widthHint = leftMargin + fontMetrics.getAverageCharWidth() * 4 + rightMargin;
scrollBarSelection = lineCount = -1;
}
public void setText(StyledText text) {
this.text = text;
this.text.addPaintListener(textPaintListener);
}
void onPaintControl(GC gc) {
Rectangle rect = canvas.getClientArea();
gc.setClipping(0, text.getTopMargin(), rect.width, rect.height - text.getTopMargin() - text.getBottomMargin());
int lineNumber = text.getTopIndex() - 1;
if (lineNumber < 0) {
lineNumber = 0;
}
while (lineNumber < text.getLineCount()) {
int y = text.getLinePixel(lineNumber);
if (y >= rect.height) {
break;
}
String s = Integer.toString(lineNumber + 1);
gc.drawString(s, rect.width - gc.stringExtent(s).x - rightMargin, y);
lineNumber++;
}
}
public void setFont(Font font) {
canvas.setFont(font);
GC gc = new GC(canvas);
fontMetrics = gc.getFontMetrics();
gc.dispose();
layoutData.widthHint = leftMargin + fontMetrics.getAverageCharWidth() * 4 + rightMargin;
canvas.redraw();
}
public void setVisible(boolean visible) {
canvas.setVisible(visible);
layoutData.exclude = !visible;
}
public void redraw() {
canvas.redraw();
}
}

Wyświetl plik

@ -0,0 +1,204 @@
/*
* Copyright (c) 2018 Marco Maccaferri and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.maccasoft.tools.editor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class SearchBox {
Shell parentShell;
StyledText control;
Shell shell;
Label label;
Text text;
static String lastSearch;
int lastIndex;
final TraverseListener traverseListener = new TraverseListener() {
@Override
public void keyTraversed(TraverseEvent e) {
}
};
final ModifyListener modifyListener = new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
if (text.getText().length() == 0) {
return;
}
text.getDisplay().timerExec(250, searchRunnable);
}
};
final Runnable searchRunnable = new Runnable() {
@Override
public void run() {
if (text.isDisposed()) {
return;
}
searchNext(text.getText());
}
};
final KeyListener keyListener = new KeyListener() {
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.stateMask != 0) {
return;
}
if (e.character == 0x1B) {
shell.setVisible(false);
shell.dispose();
e.doit = false;
return;
}
if (e.character == 0x0D) {
lastSearch = text.getText();
searchNext();
e.doit = false;
return;
}
}
};
final FocusListener focusListener = new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
shell.setVisible(false);
shell.dispose();
}
@Override
public void focusGained(FocusEvent e) {
}
};
public SearchBox(StyledText control) {
this.control = control;
this.parentShell = control.getShell();
}
public void setLabelText(String text) {
label.setText(text);
}
public void setText(String text) {
this.text.setText(text);
}
public void open() {
shell = new Shell(parentShell, SWT.ON_TOP | SWT.TOOL);
GridLayout rowLayout = new GridLayout(1, false);
rowLayout.marginWidth = 5;
rowLayout.marginHeight = 5;
rowLayout.verticalSpacing = 2;
shell.setLayout(rowLayout);
shell.addTraverseListener(traverseListener);
label = new Label(shell, SWT.NONE);
label.setText("Search:");
label.setLayoutData(new GridData(SWT.BEGINNING, SWT.TOP, false, false));
text = new Text(shell, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
if (lastSearch != null) {
text.setText(lastSearch);
text.setSelection(0, lastSearch.length());
}
text.addKeyListener(keyListener);
text.addFocusListener(focusListener);
text.addModifyListener(modifyListener);
Point size = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
if (size.x < 200) {
size.x = 200;
}
Point location = control.toDisplay(control.getLocation());
Point parentSize = control.getSize();
shell.setBounds(location.x + parentSize.x - size.x - 10, location.y + parentSize.y - size.y - 10, size.x, size.y);
shell.open();
text.setFocus();
}
public void dispose() {
if (shell != null && !shell.isDisposed()) {
shell.dispose();
}
}
void searchNext(String string) {
lastSearch = string;
searchNext(control.getCaretOffset());
}
public void searchNext() {
searchNext(control.getCaretOffset() + 1);
}
public void searchNext(int fromIndex) {
if (lastSearch == null) {
return;
}
String search = lastSearch.toLowerCase();
String controlText = control.getText().toLowerCase();
int index = controlText.indexOf(search, fromIndex);
if (index == -1) {
index = controlText.indexOf(search);
}
if (index != -1) {
control.setCaretOffset(index);
control.setSelection(index + lastSearch.length(), index);
int line = control.getLineAtOffset(index);
control.setTopIndex(line > 10 ? line - 10 : 0);
}
}
public void addDisposeListenr(DisposeListener l) {
text.addDisposeListener(l);
}
public void removeDisposeListenr(DisposeListener l) {
text.removeDisposeListener(l);
}
public void setLastSearch(String string) {
lastSearch = string;
}
}

Wyświetl plik

@ -0,0 +1,28 @@
/*
* Copyright (c) 2018 Marco Maccaferri and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.maccasoft.tools.editor;
public class Token {
public TokenId id;
public int length;
public Token next;
public Token(int length, TokenId id) {
this.length = length;
this.id = id;
}
@Override
public String toString() {
return "[id=" + id + ",length=" + length + "]";
}
}

Wyświetl plik

@ -0,0 +1,25 @@
/*
* Copyright (c) 2018 Marco Maccaferri and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.maccasoft.tools.editor;
public enum TokenId {
Null,
Comment,
StringLiteral1,
StringLiteral2,
NumberLiteral,
Instruction,
Register,
Flag,
Directive1,
Directive2,
End
}

Wyświetl plik

@ -0,0 +1,133 @@
/*
* Copyright (c) 2018 Marco Maccaferri and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.maccasoft.tools.editor;
import java.util.HashMap;
import java.util.Map;
public abstract class TokenMarker {
static Map<String, TokenId> keywords = new HashMap<String, TokenId>();
final Map<String, TokenId> additionalKeywords = new HashMap<String, TokenId>();
Token firstToken;
Token lastToken;
int lastKeyword;
int lastOffset;
public TokenMarker() {
}
public boolean refreshMultilineComments(String text) {
return false;
}
public abstract Token markTokens(String text, int offset);
public void clearKeywords() {
additionalKeywords.clear();
}
public void addKeyword(String text, TokenId id) {
if (text == null || "".equals(text)) {
return;
}
additionalKeywords.put(text, id);
}
public void removeKeyword(String text) {
additionalKeywords.remove(text);
}
protected void addToken(int length, TokenId id) {
if (length == 0 && id != TokenId.End) {
return;
}
if (firstToken == null) {
firstToken = new Token(length, id);
lastToken = firstToken;
}
else if (lastToken == null) {
lastToken = firstToken;
firstToken.length = length;
firstToken.id = id;
}
else if (lastToken.next == null) {
lastToken.next = new Token(length, id);
lastToken = lastToken.next;
}
else {
lastToken = lastToken.next;
lastToken.length = length;
lastToken.id = id;
}
}
protected TokenId doKeyword(String line, int i, char c) {
int i1 = i + 1;
int len = i - lastKeyword;
String s = line.substring(lastKeyword, i);
TokenId id = getNumberTokenId(s);
if (id == null) {
id = keywords.get(s.toUpperCase());
}
if (id == null) {
id = additionalKeywords.get(s);
}
if (id != null) {
if (lastKeyword != lastOffset) {
addToken(lastKeyword - lastOffset, TokenId.Null);
}
addToken(len, id);
lastOffset = i;
}
lastKeyword = i1;
return id;
}
TokenId getNumberTokenId(String s) {
if (s.length() > 0 && (Character.isDigit(s.charAt(0)) || s.charAt(0) == '$')) {
int i = 1;
char c0 = s.charAt(0);
while (i < s.length()) {
if (!isHexDigit(s.charAt(i))) {
break;
}
i++;
}
if (i == s.length()) {
return TokenId.NumberLiteral;
}
if (c0 == '$' && !Character.isWhitespace(s.charAt(i))) {
return null;
}
if (s.charAt(i) == 'H' || s.charAt(i) == 'h' || s.charAt(i) == 'B' || s.charAt(i) == 'b') {
return TokenId.NumberLiteral;
}
}
return null;
}
boolean isHexDigit(char c) {
if (c >= '0' && c <= '9') {
return true;
}
if ((c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) {
return true;
}
return false;
}
}

Wyświetl plik

@ -0,0 +1,263 @@
/*
* Copyright (c) 2018 Marco Maccaferri and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.maccasoft.tools.editor;
public class Z80TokenMarker extends TokenMarker {
static {
keywords.put("ADC", TokenId.Instruction);
keywords.put("ADD", TokenId.Instruction);
keywords.put("AND", TokenId.Instruction);
keywords.put("BIT", TokenId.Instruction);
keywords.put("CALL", TokenId.Instruction);
keywords.put("CCF", TokenId.Instruction);
keywords.put("CP", TokenId.Instruction);
keywords.put("CPD", TokenId.Instruction);
keywords.put("CPDR", TokenId.Instruction);
keywords.put("CPI", TokenId.Instruction);
keywords.put("CPIR", TokenId.Instruction);
keywords.put("CPL", TokenId.Instruction);
keywords.put("DAA", TokenId.Instruction);
keywords.put("DEC", TokenId.Instruction);
keywords.put("DI", TokenId.Instruction);
keywords.put("DJNZ", TokenId.Instruction);
keywords.put("EI", TokenId.Instruction);
keywords.put("EX", TokenId.Instruction);
keywords.put("EXX", TokenId.Instruction);
keywords.put("HALT", TokenId.Instruction);
keywords.put("IM", TokenId.Instruction);
keywords.put("INC", TokenId.Instruction);
keywords.put("IN", TokenId.Instruction);
keywords.put("INI", TokenId.Instruction);
keywords.put("IND", TokenId.Instruction);
keywords.put("INIR", TokenId.Instruction);
keywords.put("INDR", TokenId.Instruction);
keywords.put("JR", TokenId.Instruction);
keywords.put("JP", TokenId.Instruction);
keywords.put("LD", TokenId.Instruction);
keywords.put("LDI", TokenId.Instruction);
keywords.put("LDIR", TokenId.Instruction);
keywords.put("LDD", TokenId.Instruction);
keywords.put("LDDR", TokenId.Instruction);
keywords.put("NEG", TokenId.Instruction);
keywords.put("NOP", TokenId.Instruction);
keywords.put("OR", TokenId.Instruction);
keywords.put("OUT", TokenId.Instruction);
keywords.put("OUTI", TokenId.Instruction);
keywords.put("OUTD", TokenId.Instruction);
keywords.put("OTIR", TokenId.Instruction);
keywords.put("OTDR", TokenId.Instruction);
keywords.put("POP", TokenId.Instruction);
keywords.put("PUSH", TokenId.Instruction);
keywords.put("RES", TokenId.Instruction);
keywords.put("RET", TokenId.Instruction);
keywords.put("RETI", TokenId.Instruction);
keywords.put("RETN", TokenId.Instruction);
keywords.put("RL", TokenId.Instruction);
keywords.put("RLA", TokenId.Instruction);
keywords.put("RLC", TokenId.Instruction);
keywords.put("RLCA", TokenId.Instruction);
keywords.put("RLD", TokenId.Instruction);
keywords.put("RR", TokenId.Instruction);
keywords.put("RRA", TokenId.Instruction);
keywords.put("RRC", TokenId.Instruction);
keywords.put("RRCA", TokenId.Instruction);
keywords.put("RRD", TokenId.Instruction);
keywords.put("RST", TokenId.Instruction);
keywords.put("SBC", TokenId.Instruction);
keywords.put("SCF", TokenId.Instruction);
keywords.put("SET", TokenId.Instruction);
keywords.put("SLA", TokenId.Instruction);
keywords.put("SRA", TokenId.Instruction);
keywords.put("SRL", TokenId.Instruction);
keywords.put("SUB", TokenId.Instruction);
keywords.put("XOR", TokenId.Instruction);
keywords.put("DB", TokenId.Directive2);
keywords.put("DD", TokenId.Directive2);
keywords.put("DS", TokenId.Directive2);
keywords.put("DW", TokenId.Directive2);
keywords.put("INCLUDE", TokenId.Directive1);
keywords.put("EQU", TokenId.Directive1);
keywords.put("ORG", TokenId.Directive2);
keywords.put("ENDM", TokenId.Directive1);
keywords.put("ENDP", TokenId.Directive1);
keywords.put("ENDS", TokenId.Directive1);
keywords.put("END", TokenId.Directive1);
keywords.put("ENDIF", TokenId.Directive1);
keywords.put("ELSE", TokenId.Directive1);
keywords.put("ERROR", TokenId.Directive1);
keywords.put("WARNING", TokenId.Directive1);
keywords.put("FILL", TokenId.Directive1);
keywords.put(".DB", TokenId.Directive2);
keywords.put(".DD", TokenId.Directive2);
keywords.put(".DS", TokenId.Directive2);
keywords.put(".DW", TokenId.Directive2);
keywords.put(".INCLUDE", TokenId.Directive1);
keywords.put(".EQU", TokenId.Directive1);
keywords.put(".ORG", TokenId.Directive2);
keywords.put(".ENDM", TokenId.Directive1);
keywords.put(".ENDP", TokenId.Directive1);
keywords.put(".ENDS", TokenId.Directive1);
keywords.put(".END", TokenId.Directive1);
keywords.put(".ENDIF", TokenId.Directive1);
keywords.put(".ELSE", TokenId.Directive1);
keywords.put(".ERROR", TokenId.Directive1);
keywords.put(".WARNING", TokenId.Directive1);
keywords.put(".FILL", TokenId.Directive1);
keywords.put("A", TokenId.Register);
keywords.put("B", TokenId.Register);
keywords.put("C", TokenId.Register);
keywords.put("D", TokenId.Register);
keywords.put("E", TokenId.Register);
keywords.put("F", TokenId.Register);
keywords.put("H", TokenId.Register);
keywords.put("L", TokenId.Register);
keywords.put("AF", TokenId.Register);
keywords.put("BC", TokenId.Register);
keywords.put("DE", TokenId.Register);
keywords.put("HL", TokenId.Register);
keywords.put("SP", TokenId.Register);
keywords.put("IX", TokenId.Register);
keywords.put("IY", TokenId.Register);
keywords.put("I", TokenId.Register);
keywords.put("R", TokenId.Register);
keywords.put("Z", TokenId.Flag);
keywords.put("NZ", TokenId.Flag);
keywords.put("C", TokenId.Flag);
keywords.put("NC", TokenId.Flag);
keywords.put("PO", TokenId.Flag);
keywords.put("PE", TokenId.Flag);
keywords.put("P", TokenId.Flag);
keywords.put("M", TokenId.Flag);
}
public Z80TokenMarker() {
}
@Override
public Token markTokens(String text, int offset) {
boolean backslash = false;
TokenId token = TokenId.Null;
firstToken = lastToken = null;
lastOffset = lastKeyword = 0;
int start = 0;
for (int i = start; i < text.length(); i++) {
int i1 = (i + 1);
char c = text.charAt(i);
if (c == '\\') {
backslash = !backslash;
continue;
}
switch (token) {
case Null:
switch (c) {
case '\'':
case '"':
doKeyword(text, i, c);
if (backslash) {
backslash = false;
}
else {
addToken(i - lastOffset, token);
token = c == '"' ? TokenId.StringLiteral1 : TokenId.StringLiteral2;
lastOffset = lastKeyword = i;
}
break;
case ';': {
backslash = false;
doKeyword(text, i, c);
addToken(i - lastOffset, token);
int mlength = text.indexOf('\n', i);
if (mlength == -1) {
mlength = text.length();
}
addToken(mlength - i, TokenId.Comment);
lastOffset = lastKeyword = i = mlength;
break;
}
case '$':
backslash = false;
doKeyword(text, i, c);
addToken(i - lastOffset, token);
int mlength = i + 1;
while (mlength < text.length() && isHexDigit(text.charAt(mlength))) {
mlength++;
}
if ((mlength - i) > 1) {
addToken(mlength - i, TokenId.NumberLiteral);
lastOffset = lastKeyword = i = mlength;
}
break;
default:
backslash = false;
if (!Character.isLetterOrDigit(c) && c != '_' && c != '.') {
doKeyword(text, i, c);
}
break;
}
break;
case StringLiteral1:
if (backslash) {
backslash = false;
}
else if (c == '"') {
addToken(i1 - lastOffset, token);
token = TokenId.Null;
lastOffset = lastKeyword = i1;
}
break;
case StringLiteral2:
if (backslash) {
backslash = false;
}
else if (c == '\'') {
addToken(i1 - lastOffset, token);
token = TokenId.Null;
lastOffset = lastKeyword = i1;
}
break;
default:
// Do nothing
break;
}
}
if (token == TokenId.Null) {
doKeyword(text, text.length(), '\0');
}
switch (token) {
case StringLiteral1:
case StringLiteral2:
addToken(text.length() - lastOffset, null);
token = null;
break;
default:
addToken(text.length() - lastOffset, token);
break;
}
return firstToken;
}
}

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 590 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 537 B