001    /**
002     * @author paulk
003     */
004    package toolbus.atom;
005    
006    import java.io.PrintWriter;
007    
008    import toolbus.TBTermFactory;
009    import toolbus.environment.Environment;
010    import toolbus.exceptions.ToolBusException;
011    import toolbus.exceptions.ToolBusExecutionException;
012    import toolbus.parsercup.PositionInformation;
013    import toolbus.process.ProcessExpression;
014    import aterm.ATerm;
015    import aterm.ATermAppl;
016    import aterm.ATermList;
017    
018    public class Print extends Atom{
019            private final Ref arg;
020            
021            public Print(ATerm a, TBTermFactory tbfactory, PositionInformation posInfo){
022                    super(tbfactory, posInfo);
023                    
024                    arg = new Ref(a);
025                    setAtomArgs(new Ref[]{arg});
026            }
027            
028            public ProcessExpression copy(){
029                    Atom a = new Print(arg.value, tbfactory, getPosInfo());
030                    a.copyAtomAttributes(this);
031                    return a;
032            }
033            
034            private String sprintf(ATermList args){
035                    if(args.getLength() == 0) new ToolBusExecutionException("Missing arguments.", getPosInfo());
036                    if(tbfactory.isStr(args.elementAt(0))) new ToolBusExecutionException("First argument should be a string.", getPosInfo());
037                    String fmt = ((ATermAppl) args.elementAt(0)).getName();
038                    String res = new String();
039                    int iarg = 1;
040                    for(int i = 0; i < fmt.length(); i++){
041                            char c = fmt.charAt(i);
042                            if(c != '%'){
043                                    if(c != '\\'){
044                                            res += c;
045                                            continue;
046                                    }
047                                    
048                                    if(i == fmt.length()) new ToolBusExecutionException("Format string too short.", getPosInfo());
049                                    i++;
050                                    char d = fmt.charAt(i);
051                                    if(d == 'n')
052                                            res += "\n";
053                                    else if(d == 't')
054                                            res += "\t";
055                                    else res += d;
056                                    continue;
057                            }
058                            if(i == fmt.length()) new ToolBusExecutionException("Format string too short.", getPosInfo());
059                            i++;
060                            
061                            if(iarg == args.getLength()) new ToolBusExecutionException("Argument list too short.", getPosInfo());
062                            res += args.elementAt(iarg++);
063                    }
064                    if(iarg < args.getLength()) new ToolBusExecutionException("Argument list too long.", getPosInfo());
065                    return res;
066            }
067            
068            public boolean execute() throws ToolBusException{
069                    if(isEnabled()){
070                            Environment e = getEnv();
071                            // System.err.println("Print.execute: " + this + "; env = " + e);
072                            PrintWriter out = getToolBus().getPrintWriter();
073                            ATerm res = tbfactory.fullSubstitute(arg.value, e);
074                            if(res == null) throw new ToolBusExecutionException("Illegal printf pattern: "+arg.value+".", getPosInfo());
075                            // System.err.println("res =" + res);
076                            out.print(sprintf((ATermList) res));
077                            out.flush();
078                            return true;
079                    }
080                    return false;
081            }
082    }