|
From: <cr...@us...> - 2009-06-13 05:09:45
|
Revision: 5570
http://jnode.svn.sourceforge.net/jnode/?rev=5570&view=rev
Author: crawley
Date: 2009-06-13 05:09:38 +0000 (Sat, 13 Jun 2009)
Log Message:
-----------
Implemented the 'readonly' builtin command
Modified Paths:
--------------
trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java
trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneInterpreter.java
trunk/shell/src/shell/org/jnode/shell/bjorne/ExportBuiltin.java
trunk/shell/src/shell/org/jnode/shell/bjorne/VariableSlot.java
trunk/shell/src/test/org/jnode/test/shell/bjorne/BjorneContextTest.java
trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-builtin-tests.xml
Added Paths:
-----------
trunk/shell/src/shell/org/jnode/shell/bjorne/ReadonlyBuiltin.java
Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java 2009-06-12 16:56:18 UTC (rev 5569)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java 2009-06-13 05:09:38 UTC (rev 5570)
@@ -264,13 +264,13 @@
* @param name the name of the variable to be set
* @param value a non-null value for the variable
*/
- public void setVariable(String name, String value) {
+ protected void setVariable(String name, String value) {
value.length(); // Check that the value is non-null.
VariableSlot var = variables.get(name);
if (var == null) {
variables.put(name, new VariableSlot(name, value, false));
- } else {
- var.value = value;
+ } else if (!var.isReadOnly()) {
+ var.setValue(value);
}
}
@@ -289,23 +289,39 @@
*
* @param name the name of the variable to be unset
*/
- void unsetVariableValue(String name) {
- variables.remove(name);
+ void unsetVariable(String name) {
+ if (!variables.get(name).isReadOnly()) {
+ variables.remove(name);
+ }
}
/**
+ * This method implements 'readonly NAME'
+ *
+ * @param name the name of the variable to be marked as readonly
+ */
+ void setVariableReadonly(String name, boolean readonly) {
+ VariableSlot var = variables.get(name);
+ if (var == null) {
+ var = new VariableSlot(name, "", false);
+ variables.put(name, var);
+ }
+ var.setReadOnly(readonly);
+ }
+
+ /**
* This method implements 'export NAME' or 'unexport NAME'.
*
* @param name the name of the variable to be exported / unexported
*/
- void setExported(String name, boolean exported) {
+ void setVariableExported(String name, boolean exported) {
VariableSlot var = variables.get(name);
if (var == null) {
if (exported) {
variables.put(name, new VariableSlot(name, "", exported));
}
} else {
- var.exported = exported;
+ var.setExported(exported);
}
}
@@ -921,7 +937,7 @@
private String variable(String parameter) throws ShellSyntaxException {
if (BjorneToken.isName(parameter)) {
VariableSlot var = variables.get(parameter);
- return (var != null) ? var.value : null;
+ return (var != null) ? var.getValue() : null;
} else {
try {
int argNo = Integer.parseInt(parameter);
@@ -1003,8 +1019,8 @@
private Map<String, String> buildEnvFromExports() {
HashMap<String, String> map = new HashMap<String, String>(variables.size());
for (VariableSlot var : variables.values()) {
- if (var.exported) {
- map.put(var.name, var.value);
+ if (var.isExported()) {
+ map.put(var.getName(), var.getValue());
}
}
return Collections.unmodifiableMap(map);
Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneInterpreter.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneInterpreter.java 2009-06-12 16:56:18 UTC (rev 5569)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneInterpreter.java 2009-06-13 05:09:38 UTC (rev 5570)
@@ -143,6 +143,7 @@
BUILTINS.put("continue", ContinueBuiltin.FACTORY);
BUILTINS.put("exit", ExitBuiltin.FACTORY);
BUILTINS.put("export", ExportBuiltin.FACTORY);
+ BUILTINS.put("readonly", ReadonlyBuiltin.FACTORY);
BUILTINS.put("return", ReturnBuiltin.FACTORY);
BUILTINS.put("set", SetBuiltin.FACTORY);
BUILTINS.put("shift", ShiftBuiltin.FACTORY);
Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/ExportBuiltin.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/ExportBuiltin.java 2009-06-12 16:56:18 UTC (rev 5569)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/ExportBuiltin.java 2009-06-13 05:09:38 UTC (rev 5570)
@@ -42,39 +42,39 @@
}
};
- private final AssignmentArgument argExport;
+ private final AssignmentArgument argVariables;
ExportBuiltin(BjorneContext context) {
super("Export shell variables to the environment");
- argExport = new AssignmentArgument(
+ argVariables = new AssignmentArgument(
"export", context, Argument.MANDATORY, "variables to be exported");
- registerArguments(argExport);
+ registerArguments(argVariables);
}
public void execute() throws Exception {
int errorCount = 0;
- if (!argExport.isSet()) {
+ if (!argVariables.isSet()) {
// FIXME - implement this?
} else {
BjorneContext pc = getParentContext();
PrintWriter err = getError().getPrintWriter();
- for (String arg : argExport.getValues()) {
- int pos = arg.indexOf('=');
+ for (String var : argVariables.getValues()) {
+ int pos = var.indexOf('=');
if (pos == -1) {
- pc.setExported(arg, true);
+ pc.setVariableExported(var, true);
} else if (pos == 0) {
- err.println("export: " + arg + ": not a valid identifier");
+ err.println("export: " + var + ": not a valid identifier");
errorCount++;
} else {
- String name = arg.substring(0, pos);
- String value = arg.substring(pos + 1);
+ String name = var.substring(0, pos);
+ String value = var.substring(pos + 1);
if (!BjorneToken.isName(name)) {
err.println("export: " + name + ": not a valid identifier");
errorCount++;
}
pc.setVariable(name, value);
- pc.setExported(name, true);
+ pc.setVariableExported(name, true);
}
}
}
Added: trunk/shell/src/shell/org/jnode/shell/bjorne/ReadonlyBuiltin.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/ReadonlyBuiltin.java (rev 0)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/ReadonlyBuiltin.java 2009-06-13 05:09:38 UTC (rev 5570)
@@ -0,0 +1,85 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2003-2009 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package org.jnode.shell.bjorne;
+
+import java.io.PrintWriter;
+
+import org.jnode.shell.syntax.Argument;
+import org.jnode.shell.syntax.ArgumentSyntax;
+import org.jnode.shell.syntax.RepeatSyntax;
+import org.jnode.shell.syntax.SyntaxBundle;
+
+/**
+ * This class implements the 'readonly' built-in.
+ *
+ * @author cr...@jn...
+ */
+final class ReadonlyBuiltin extends BjorneBuiltin {
+ private static final SyntaxBundle SYNTAX =
+ new SyntaxBundle("readonly", new RepeatSyntax(new ArgumentSyntax("readonly")));
+
+ static final Factory FACTORY = new Factory() {
+ public BjorneBuiltinCommandInfo buildCommandInfo(BjorneContext context) {
+ return new BjorneBuiltinCommandInfo("readonly", SYNTAX, new ReadonlyBuiltin(context), context);
+ }
+ };
+
+ private final AssignmentArgument argVariables;
+
+
+ ReadonlyBuiltin(BjorneContext context) {
+ super("Mark shell variables as readonly");
+ argVariables = new AssignmentArgument(
+ "readonly", context, Argument.MANDATORY, "variables to be marked as readonly");
+ registerArguments(argVariables);
+ }
+
+ public void execute() throws Exception {
+ int errorCount = 0;
+ if (!argVariables.isSet()) {
+ // FIXME - implement this?
+ } else {
+ BjorneContext pc = getParentContext();
+ PrintWriter err = getError().getPrintWriter();
+ for (String var : argVariables.getValues()) {
+ int pos = var.indexOf('=');
+ if (pos == -1) {
+ pc.setVariableReadonly(var, true);
+ } else if (pos == 0) {
+ err.println("readonly: " + var + ": not a valid identifier");
+ errorCount++;
+ } else {
+ String name = var.substring(0, pos);
+ String value = var.substring(pos + 1);
+ if (!BjorneToken.isName(name)) {
+ err.println("readonly: " + name + ": not a valid identifier");
+ errorCount++;
+ }
+ pc.setVariable(name, value);
+ pc.setVariableReadonly(name, true);
+ }
+ }
+ }
+ if (errorCount > 0) {
+ exit(1);
+ }
+ }
+}
Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/VariableSlot.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/VariableSlot.java 2009-06-12 16:56:18 UTC (rev 5569)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/VariableSlot.java 2009-06-13 05:09:38 UTC (rev 5570)
@@ -22,11 +22,12 @@
import org.jnode.shell.ShellFailureException;
class VariableSlot {
- public String value;
- public final String name;
- public boolean exported;
+ private String value;
+ private final String name;
+ private boolean exported;
+ private boolean readOnly;
- public VariableSlot(String name, String value, boolean exported) {
+ VariableSlot(String name, String value, boolean exported) {
if (name == null) {
throw new ShellFailureException("null name");
}
@@ -38,9 +39,38 @@
this.name = name;
}
- public VariableSlot(VariableSlot other) {
+ VariableSlot(VariableSlot other) {
this.value = other.value;
this.exported = other.exported;
this.name = other.name;
}
+
+ String getValue() {
+ return value;
+ }
+
+ void setValue(String value) {
+ this.value = value;
+ }
+
+ boolean isExported() {
+ return exported;
+ }
+
+ void setExported(boolean exported) {
+ this.exported = exported;
+ }
+
+ boolean isReadOnly() {
+ return readOnly;
+ }
+
+ void setReadOnly(boolean readOnly) {
+ this.readOnly = readOnly;
+ }
+
+ String getName() {
+ return name;
+ }
+
}
Modified: trunk/shell/src/test/org/jnode/test/shell/bjorne/BjorneContextTest.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/bjorne/BjorneContextTest.java 2009-06-12 16:56:18 UTC (rev 5569)
+++ trunk/shell/src/test/org/jnode/test/shell/bjorne/BjorneContextTest.java 2009-06-13 05:09:38 UTC (rev 5570)
@@ -31,10 +31,29 @@
import org.jnode.shell.PathnamePattern;
import org.jnode.shell.ShellException;
import org.jnode.shell.bjorne.BjorneContext;
+import org.jnode.shell.bjorne.BjorneInterpreter;
import org.jnode.shell.bjorne.BjorneToken;
import org.jnode.shell.io.CommandIOHolder;
+/**
+ * Some unit tests for the BjorneContext class, focusing on the expansion and word-splitting
+ * methods.
+ *
+ * @author cr...@jn...
+ */
public class BjorneContextTest extends TestCase {
+
+ // This class simply allows us to call the setVariable method directly
+ private static class TestBjorneContext extends BjorneContext {
+ TestBjorneContext(BjorneInterpreter interpreter, CommandIOHolder[] holders) {
+ super(interpreter, holders);
+ }
+
+ @Override
+ protected void setVariable(String name, String value) {
+ super.setVariable(name, value);
+ }
+ }
public void testContext() {
new BjorneContext(null, null);
@@ -96,7 +115,7 @@
}
public void testExpand10() throws ShellException {
- BjorneContext context = new BjorneContext(null, null);
+ TestBjorneContext context = new TestBjorneContext(null, null);
context.setVariable("A", "A");
List<BjorneToken> expansion = context.expandAndSplit(
new BjorneToken("$A"));
@@ -104,7 +123,7 @@
}
public void testExpand11() throws ShellException {
- BjorneContext context = new BjorneContext(null, null);
+ TestBjorneContext context = new TestBjorneContext(null, null);
context.setVariable("A", "A");
List<BjorneToken> expansion = context.expandAndSplit(
new BjorneToken("\\$A"));
@@ -112,7 +131,7 @@
}
public void testExpand12() throws ShellException {
- BjorneContext context = new BjorneContext(null, null);
+ TestBjorneContext context = new TestBjorneContext(null, null);
context.setVariable("A", "A");
List<BjorneToken> expansion = context.expandAndSplit(
new BjorneToken("\"$A\""));
@@ -120,7 +139,7 @@
}
public void testExpand13() throws ShellException {
- BjorneContext context = new BjorneContext(null, null);
+ TestBjorneContext context = new TestBjorneContext(null, null);
context.setVariable("A", "A");
List<BjorneToken> expansion = context.expandAndSplit(
new BjorneToken("'$A'"));
@@ -128,7 +147,7 @@
}
public void testExpand14() throws ShellException {
- BjorneContext parentContext = new BjorneContext(null, new CommandIOHolder[0]);
+ TestBjorneContext parentContext = new TestBjorneContext(null, new CommandIOHolder[0]);
parentContext.setVariable("A", "A");
BjorneContext context = new BjorneContext(parentContext);
List<BjorneToken> expansion = context.expandAndSplit(
Modified: trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-builtin-tests.xml
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-builtin-tests.xml 2009-06-12 16:56:18 UTC (rev 5569)
+++ trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-builtin-tests.xml 2009-06-13 05:09:38 UTC (rev 5570)
@@ -94,4 +94,28 @@
<error>Cannot find an alias or load a command class for 'unalias'
</error>
</testSpec>
+ <testSpec title="readonly" runMode="AS_SCRIPT" rc="0">
+ <script>#!bjorne
+ readonly A
+ echo A -${A}-
+ A=1
+ echo A -${A}-
+ readonly B=1
+ echo B -${B}-
+ B=2
+ echo B -${B}-
+ readonly B=2
+ echo B -${B}-
+ export B=2
+ echo B -${B}-
+ </script>
+ <output>A --
+A --
+B -1-
+B -1-
+B -1-
+B -1-
+B -1-
+</output>
+ </testSpec>
</testSet>
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|