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. |