private void processBuffHist()

in HSQL/src/org/hsqldb1/util/SqlFile.java [952:1185]


    private void processBuffHist(String inString)
    throws BadSpecial, SQLException, SqlToolError {
        if (inString.length() < 1) {
            throw new BadSpecial(rb.getString(SqltoolRB.BUFHIST_UNSPECIFIED));
        }

        // First handle the simple cases where user may not specify a
        // command number.
        char commandChar = inString.charAt(0);
        String other       = inString.substring(1);
        if (other.trim().length() == 0) {
            other = null;
        }
        switch (commandChar) {
            case 'l' :
            case 'b' :
                enforce1charBH(other, 'l');
                if (buffer == null) {
                    stdprintln(nobufferYetString);
                } else {
                    stdprintln(rb.getString(SqltoolRB.EDITBUFFER_CONTENTS,
                            buffer));
                }

                return;

            case 'h' :
                enforce1charBH(other, 'h');
                showHistory();

                return;

            case '?' :
                stdprintln(rb.getString(SqltoolRB.BUFFER_HELP));

                return;
        }

        Integer histNum = null;
        Matcher hm = slashHistoryPattern.matcher(inString);
        if (hm.matches()) {
            histNum = historySearch(hm.group(1));
            if (histNum == null) {
                stdprintln(rb.getString(SqltoolRB.SUBSTITUTION_NOMATCH));
                return;
            }
        } else {
            hm = historyPattern.matcher(inString);
            if (!hm.matches()) {
                throw new BadSpecial(rb.getString(SqltoolRB.EDIT_MALFORMAT));
                // Empirically, I find that his pattern always captures two
                // groups.  Unfortunately, there's no way to guarantee that :( .
            }
            histNum = ((hm.group(1) == null || hm.group(1).length() < 1)
                    ? null : new Integer(hm.group(1)));
        }
        if (hm.groupCount() != 2) {
            throw new BadSpecial(rb.getString(SqltoolRB.EDIT_MALFORMAT));
            // Empirically, I find that his pattern always captures two
            // groups.  Unfortunately, there's no way to guarantee that :( .
        }
        commandChar = ((hm.group(2) == null || hm.group(2).length() < 1)
                ? '\0' : hm.group(2).charAt(0));
        other = ((commandChar == '\0') ? null : hm.group(2).substring(1));
        if (other != null && other.length() < 1) other = null;
        String targetCommand = ((histNum == null)
                ? null : commandFromHistory(histNum.intValue()));
        // Every command below depends upon buffer content.

        switch (commandChar) {
            case '\0' :  // Special token set above.  Just history recall.
                setBuf(targetCommand);
                stdprintln(rb.getString(SqltoolRB.BUFFER_RESTORED, buffer));
                return;

            case ';' :
                enforce1charBH(other, ';');

                if (targetCommand != null) setBuf(targetCommand);
                if (buffer == null) throw new BadSpecial(
                        rb.getString(SqltoolRB.NOBUFFER_YET));
                stdprintln(rb.getString(SqltoolRB.BUFFER_EXECUTING, buffer));
                processFromBuffer();

                return;

            case 'a' :
                if (targetCommand == null) targetCommand = buffer;
                if (targetCommand == null) throw new BadSpecial(
                        rb.getString(SqltoolRB.NOBUFFER_YET));
                immCmdSB.append(targetCommand);

                if (other != null) {
                    String deTerminated = SqlFile.deTerminated(other);

                    if (!other.equals(";")) {
                        immCmdSB.append(((deTerminated == null)
                                ? other : deTerminated));
                    }

                    if (deTerminated != null) {
                        // If we reach here, then immCmdSB contains a
                        // complete command.

                        setBuf(immCmdSB.toString());
                        immCmdSB.setLength(0);
                        stdprintln(rb.getString(SqltoolRB.BUFFER_EXECUTING,
                                buffer));
                        processFromBuffer();

                        return;
                    }
                }

                magicPrefix = immCmdSB.toString();
                immCmdSB.setLength(0);
                if (interactive) stdprint(magicPrefix);

                return;

            case 'w' :
                if (targetCommand == null) targetCommand = buffer;
                if (targetCommand == null) throw new BadSpecial(
                        rb.getString(SqltoolRB.NOBUFFER_YET));
                if (other == null) {
                    throw new BadSpecial(rb.getString(
                            SqltoolRB.DESTFILE_DEMAND));
                }
                String targetFile = dereference(other.trim(), false);
                // Dereference and trim the target file name
                // This is the only case where we dereference a : command.

                PrintWriter pw = null;
                try {
                    pw = new PrintWriter((charset == null)
                            ?  (new OutputStreamWriter(
                                    new FileOutputStream(targetFile, true)))
                            :  (new OutputStreamWriter(
                                    new FileOutputStream(targetFile, true),
                                            charset))
                            // Appendmode so can append to an SQL script.
                    );
                    // Replace with just "(new FileOutputStream(file), charset)"
                    // once use defaultCharset from Java 1.5 in charset init.
                    // above.

                    pw.print(targetCommand);
                    if (!targetCommand.matches("\\s*[*:\\\\].*")) pw.print(';');
                    pw.println();
                    pw.flush();
                } catch (Exception e) {
                    throw new BadSpecial(rb.getString(SqltoolRB.FILE_APPENDFAIL,
                            targetFile), e);
                } finally {
                    if (pw != null) pw.close();
                }

                return;

            case 's' :
                boolean modeExecute = false;
                boolean modeGlobal = false;
                if (targetCommand == null) targetCommand = buffer;
                if (targetCommand == null) throw new BadSpecial(
                        rb.getString(SqltoolRB.NOBUFFER_YET));

                try {
                    if (other == null || other.length() < 3) {
                        throw new BadSubst(rb.getString(
                                SqltoolRB.SUBSTITUTION_MALFORMAT));
                    }
                    Matcher m = substitutionPattern.matcher(other);
                    if (!m.matches()) {
                        throw new BadSubst(rb.getString(
                                SqltoolRB.SUBSTITUTION_MALFORMAT));
                    }

                    // Note that this pattern does not include the leading :.
                    if (m.groupCount() < 3 || m.groupCount() > 4) {
                        // Assertion failed
                        throw new RuntimeException(
                                "Matched substitution pattern, but "
                                + "captured " + m.groupCount() + " groups");
                    }
                    String optionGroup = (
                            (m.groupCount() > 3 && m.group(4) != null)
                            ? (new String(m.group(4))) : null);

                    if (optionGroup != null) {
                        if (optionGroup.indexOf(';') > -1) {
                            modeExecute = true;
                            optionGroup = optionGroup.replaceFirst(";", "");
                        }
                        if (optionGroup.indexOf('g') > -1) {
                            modeGlobal = true;
                            optionGroup = optionGroup.replaceFirst("g", "");
                        }
                    }

                    Matcher bufferMatcher = Pattern.compile("(?s"
                            + ((optionGroup == null) ? "" : optionGroup)
                            + ')' + m.group(2)).matcher(targetCommand);
                    String newBuffer = (modeGlobal
                            ? bufferMatcher.replaceAll(m.group(3))
                            : bufferMatcher.replaceFirst(m.group(3)));
                    if (newBuffer.equals(targetCommand)) {
                        stdprintln(rb.getString(
                                SqltoolRB.SUBSTITUTION_NOMATCH));
                        return;
                    }

                    setBuf(newBuffer);
                    stdprintln(rb.getString((modeExecute
                            ? SqltoolRB.BUFFER_EXECUTING
                            : SqltoolRB.EDITBUFFER_CONTENTS), buffer));
                } catch (PatternSyntaxException pse) {
                    throw new BadSpecial(
                            rb.getString(SqltoolRB.SUBSTITUTION_SYNTAX), pse);
                } catch (BadSubst badswitch) {
                    throw new BadSpecial(
                            rb.getString(SqltoolRB.SUBSTITUTION_SYNTAX));
                }

                if (modeExecute) {
                    immCmdSB.setLength(0);
                    processFromBuffer();
                }

                return;
        }

        throw new BadSpecial(rb.getString(SqltoolRB.BUFFER_UNKNOWN,
                Character.toString(commandChar)));
    }