/* ZZPath.java * * Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka * * You may use and distribute under the terms of either the GNU Lesser * General Public License, either version 2 of the license or, * at your choice, any later version. Alternatively, you may use and * distribute under the terms of the XPL. * * See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of * the licenses. * * This software 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 README * file for more details. * */ /* * Written by Tuomas Lukka */ package org.gzigzag; import java.util.*; /* Possibly publish this API later on? */ interface PathOp { /** Apply the pathop to the from cell, attaching the observer o * to observe the relevant information about all the cells on the way. * These objects do not need to attach observers to the from * cell but all the others, including the last cell. * @return null if the requested cell does not exist. */ ZZCell apply(ZZCell from, ZZObs o); } /** A class to represent paths in the structure. * It used to also be a notifier but that was changed: now it's just * an abstract "path". */ public class ZZPath { public static final String rcsid = "$Id: ZZPath.java,v 1.26 2000/10/18 14:35:31 tjl Exp $"; static public boolean dbg = false; static final void p(String s) { if(dbg) System.out.println(s); } PathOp[] arr = new PathOp[0]; public ZZPath() { } static final String drdim(ZZCell c) { return ZZDefaultSpace.getPossDerefCell(c).getText(); } static final int drdir(ZZCell c) { String s = ZZDefaultSpace.getPossDerefCell(c).getText(); if(s.equals("-")) return -1; if(s.equals("+")) return +1; return Integer.parseInt(s); } static final String drtext(ZZCell c) { return drdim(c); } /** Creates a ZZPath from cells. * The cells give the path through a simple format in d.1 and d.2: * The first cell is the operation name, and then follow the * parameters, just like in the other calls for this class. *
	 * 	STEP  dim  n
	 *	HEAD dim dir
	 *	END dim dir
	 *	FIND dim dir str
	 * 
* Note that this is not automatically updated each time the path * or the cursors in the path change - to be up to date, you need * to create a new path each time. However, this is not such a * time-consuming operation. *

* "HEAD" is now deprecated in favor of "END". */ static public ZZPath createFromStructure1(ZZCell c) { ZZPath p = new ZZPath(); while(c!=null) { ZZCell[] args = c.readRank("d.1", 1, false); String s = c.getText(); if(s.equals("STEP")) { if(args.length < 2) throw new ZZError("Not enough args for '"+s+"'"); p = p.step(drdim(args[0]), drdir(args[1])); } else if(s.equals("HEAD") || s.equals("END")) { if(args.length < 2) throw new ZZError("Not enough args for '"+s+"'"); p = p.headcell(drdim(args[0]), drdir(args[1])); } else if(s.equals("FIND")) { if(args.length < 3) throw new ZZError("Not enough args for '"+s+"'"); p = p.untilstring(drdim(args[0]), drdir(args[1]), drtext(args[2])); } else { throw new ZZError("ZZPath syntax: '"+s+"'"); } c = c.s("d.2", 1); } return p; } /** Reads the structure through this path to obtain a cell. * @param from The cell to start from * @param error Whether not finding a cell is an error. * This is for coder convenience: the message * in the exception thrown is descriptive of * where the not-found leg of the path was. * @param o The observer to attach. */ public ZZCell readFrom(ZZCell from, boolean error, ZZObs o) { if(from == null) throw new ZZError("Can't read path from null!"); ZZCell n = from; for(int i=0; i