зеркало из https://github.com/mozilla/pjs.git
--NOT PART OF DEFAULT BUILD--
XMLterm changes only. Major restructuring of the xmlterm build process. Split lineterm from xmlterm. IDLified all interfaces (bug 69002). Eliminated printing to console in opt builds (bug 78641)
This commit is contained in:
Родитель
079831fe2d
Коммит
66c1b78691
|
@ -64,13 +64,13 @@ DEBUG = 1
|
|||
|
||||
ifdef STAND_ALONE
|
||||
|
||||
DIRS = base tests linetest
|
||||
DIRS = lineterm tests linetest
|
||||
|
||||
else # not STAND_ALONE
|
||||
|
||||
# XMLterm currently works on Linux and SunOS only (testing on BSD family)
|
||||
ifneq (,$(filter Linux SunOS FreeBSD HP-UX,$(OS_ARCH)))
|
||||
DIRS = base ui scripts doc tests
|
||||
DIRS = lineterm base ui build scripts doc tests
|
||||
else # XMLterm not yet been ported to this platform; do nothing
|
||||
DIRS =
|
||||
endif
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
UUID.txt: UUIDs used by XMLTerm
|
||||
-------------------------------
|
||||
|
||||
7 July 2000
|
||||
|
||||
A block of 256 UUIDs was generated by running uuidgen,
|
||||
ranging from
|
||||
/* 0eb82b00-43a2-11d3-8e76-006008948af5 */
|
||||
to
|
||||
/* 0eb82bff-43a2-11d3-8e76-006008948af5 */
|
||||
with the 7th and 8th hex digits varying from 00 to ff.
|
||||
|
||||
Of these, the following UUIDs are being used as IIDs and CIDs:
|
||||
|
||||
mozILineTerm IID "0eb82b00-43a2-11d3-8e76-006008948af5"
|
||||
mozLineTerm CID "0eb82b01-43a2-11d3-8e76-006008948af5"
|
||||
mozILineTermAux IID "0eb82b10-43a2-11d3-8e76-006008948af5"
|
||||
mozIXMLTerminal IID "0eb82b20-43a2-11d3-8e76-006008948af5"
|
||||
mozXMLTerminal CID "0eb82b21-43a2-11d3-8e76-006008948af5"
|
||||
mozIXMLTermShell IID "0eb82b30-43a2-11d3-8e76-006008948af5"
|
||||
mozXMLTermShell CID "0eb82b31-43a2-11d3-8e76-006008948af5"
|
||||
mozIXMLTermStream IID "0eb82b40-43a2-11d3-8e76-006008948af5"
|
||||
mozXMLTermStream CID "0eb82b41-43a2-11d3-8e76-006008948af5"
|
||||
mozIXMLTermSuspend IID "0eb82b50-43a2-11d3-8e76-006008948af5"
|
||||
|
||||
CLINE_SERVICE CID "0eb82bE0-43a2-11d3-8e76-006008948af5"
|
||||
TELNETCNT_HANDLER CID "0eb82bE1-43a2-11d3-8e76-006008948af5"
|
||||
TELNETPROT_HANDLER CID "0eb82bE2-43a2-11d3-8e76-006008948af5"
|
||||
|
||||
mozISimpleContainer IID "0eb82bF0-43a2-11d3-8e76-006008948af5"
|
||||
mozSimpleContainer CID "0eb82bF1-43a2-11d3-8e76-006008948af5"
|
||||
|
||||
--
|
|
@ -33,51 +33,25 @@
|
|||
|
||||
# makefile for xmlterm/base directory
|
||||
|
||||
ifdef STAND_ALONE
|
||||
DEPTH = ..
|
||||
topsrcdir = ..
|
||||
srcdir = .
|
||||
include $(topsrcdir)/config/autoconf.mk
|
||||
else
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
endif
|
||||
|
||||
|
||||
ifdef DEBUG
|
||||
# Debug option
|
||||
DEBUG = 1
|
||||
|
||||
# Library name
|
||||
LIBRARY_NAME = xmlterm
|
||||
|
||||
# C Sources
|
||||
ifdef NO_PTY
|
||||
CSRCS = ltermManager.c ltermIO.c ltermInput.c ltermOutput.c ltermEscape.c \
|
||||
tracelog.c unistring.c
|
||||
else
|
||||
CSRCS = ltermManager.c ltermIO.c ltermInput.c ltermOutput.c ltermEscape.c \
|
||||
tracelog.c unistring.c ptystream.c
|
||||
DEBUG_LTERM = 1
|
||||
endif
|
||||
|
||||
ifdef STAND_ALONE
|
||||
# Defines
|
||||
DEFINES +=
|
||||
|
||||
# Exported header files
|
||||
EXPORTS = lineterm.h tracelog.h unistring.h ptystream.h
|
||||
|
||||
# C++ Sources
|
||||
CPPSRCS =
|
||||
|
||||
else # not STAND_ALONE
|
||||
# Defines
|
||||
DEFINES += $(TK_CFLAGS)
|
||||
ifdef DEBUG_LTERM
|
||||
DEFINES += -DDEBUG_LTERM
|
||||
endif
|
||||
|
||||
# Exported header files (excluding XPCONNECT interfaces)
|
||||
EXPORTS = lineterm.h tracelog.h unistring.h ptystream.h mozXMLT.h mozXMLTermUtils.h mozIXMLTerminal.h mozIXMLTermStream.h
|
||||
EXPORTS = mozXMLT.h mozXMLTermUtils.h
|
||||
|
||||
# C++ Sources
|
||||
CPPSRCS = \
|
||||
|
@ -88,29 +62,25 @@ CPPSRCS = \
|
|||
mozXMLTermListeners.cpp \
|
||||
mozXMLTermShell.cpp \
|
||||
mozXMLTermStream.cpp \
|
||||
mozXMLTermFactory.cpp \
|
||||
$(NULL)
|
||||
|
||||
MODULE = xmlterm
|
||||
IS_COMPONENT = 1
|
||||
EXPORT_LIBRARY = 1
|
||||
REQUIRES = xpcom string pref dom docshell view locale caps layout uriloader necko widget webshell appshell
|
||||
LIBRARY_NAME = xmlterm_s
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
-L$(DIST)/bin \
|
||||
-L$(DIST)/lib \
|
||||
-lgkgfx \
|
||||
$(TK_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
REQUIRES = xpcom string
|
||||
|
||||
XPIDLSRCS = \
|
||||
mozILineTerm.idl \
|
||||
mozIXMLTermShell.idl \
|
||||
mozILineTerm.idl \
|
||||
mozIXMLTermShell.idl \
|
||||
mozIXMLTerminal.idl \
|
||||
mozIXMLTermStream.idl \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../lineterm \
|
||||
$(NULL)
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
include $(srcdir)/../config/xmlterm_config.mk
|
||||
|
||||
|
|
|
@ -22,10 +22,20 @@
|
|||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIObserver.idl"
|
||||
#include "domstubs.idl"
|
||||
|
||||
%{C++
|
||||
#include "nsString.h"
|
||||
class nsIDOMDocument;
|
||||
|
||||
#define MOZLINETERM_CLASSNAME "LineTerm Component"
|
||||
#define MOZLINETERM_CONTRACTID "@mozilla.org/xmlterm/lineterm;1"
|
||||
|
||||
#define MOZLINETERM_CID \
|
||||
{ /* 0eb82b01-43a2-11d3-8e76-006008948af5 */ \
|
||||
0x0eb82b01, 0x43a2, 0x11d3, \
|
||||
{0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5} }
|
||||
%}
|
||||
|
||||
[scriptable, uuid(0eb82b00-43a2-11d3-8e76-006008948af5)]
|
||||
|
@ -75,13 +85,80 @@ interface mozILineTerm : nsISupports
|
|||
out PRInt32 buf_row, out PRInt32 buf_col, in wstring aCookie);
|
||||
};
|
||||
|
||||
[ref] native nsNativeStringRef(nsString);
|
||||
|
||||
%{ C++
|
||||
#define MOZLINETERM_CID \
|
||||
{ /* 0eb82b01-43a2-11d3-8e76-006008948af5 */ \
|
||||
0x0eb82b01, 0x43a2, 0x11d3, \
|
||||
{0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5} }
|
||||
/* NOT SCRIPTABLE */
|
||||
[uuid(0eb82b10-43a2-11d3-8e76-006008948af5)]
|
||||
|
||||
interface mozILineTermAux : mozILineTerm
|
||||
{
|
||||
|
||||
/** Opens LineTerm, a line-oriented terminal interface (without graphics)
|
||||
* @param command name of command to be executed; usually a shell,
|
||||
* e.g., "/bin/sh"; if set to null string, the command name is
|
||||
* determined from the environment variable SHELL
|
||||
* @param promptRegexp command prompt regular expression (for future use);
|
||||
* at the moment, any string terminated by one of the characters
|
||||
* "#$%>?", followed by a space, is assumed to be a prompt
|
||||
* @param options LineTerm option bits (usually 0; see lineterm.h)
|
||||
* @param processType command shell type; if set to -1, type is determined
|
||||
* from the command name
|
||||
* @param nRows no. of screen rows
|
||||
* @param nCols no. of screen columns
|
||||
* @param xPixels screen width in pixels (or 0 if unknown)
|
||||
* @param yPixels screen height in pixels (or 0 if unknown)
|
||||
* @param domDoc DOM document object associated with the LineTerm
|
||||
* (document.cookie will be defined for this document on return)
|
||||
* @param aCookie (output) cookie associated with LineTerm
|
||||
*/
|
||||
|
||||
void openAux(in wstring command,
|
||||
in wstring initInput,
|
||||
in wstring promptRegexp,
|
||||
in PRInt32 options, in PRInt32 processType,
|
||||
in PRInt32 nRows, in PRInt32 nCols,
|
||||
in PRInt32 xPixels, in PRInt32 yPixels,
|
||||
in nsIDOMDocument domDoc,
|
||||
in nsIObserver anObserver,
|
||||
in nsNativeStringRef aCookie);
|
||||
|
||||
/** Suspend/restores LineTerm operation
|
||||
* @param aSuspend suspension state flag
|
||||
*/
|
||||
void suspendAux(in boolean suspend);
|
||||
|
||||
/** Closes LineTerm
|
||||
*/
|
||||
void closeAux();
|
||||
|
||||
/** Close all LineTerms, not just this one
|
||||
*/
|
||||
void closeAllAux();
|
||||
|
||||
/** Resizes XMLterm to match a resized window.
|
||||
* @param nRows number of rows
|
||||
* @param nCols number of columns
|
||||
*/
|
||||
void resizeAux(in long nRows, in long nCols);
|
||||
|
||||
/** Read output data and style strings and parameters from LineTerm
|
||||
* @param opcodes (output) output data descriptor bits (see lineterm.h)
|
||||
* @param opvals (output) output data value(s)
|
||||
* @param buf_row (output) row number (>=-1)
|
||||
* (-1 denotes line mode and 0 represents bottom row)
|
||||
* @param buf_col (output) column number (>=0)
|
||||
* @param _retval (output) success code
|
||||
* @param retstyle (output) output style string
|
||||
* @return output data string from LineTerm
|
||||
*/
|
||||
void readAux(out long opcodes, out long opvals,
|
||||
out long buf_row, out long buf_col,
|
||||
out wstring retval, out wstring retstyle);
|
||||
|
||||
void getCookie(in nsNativeStringRef aCookie);
|
||||
|
||||
attribute long cursorRow;
|
||||
attribute long cursorColumn;
|
||||
attribute boolean echoFlag;
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewLineTerm(mozILineTerm** aLineTerm);
|
||||
%}
|
||||
|
|
|
@ -27,6 +27,17 @@
|
|||
interface nsIDOMWindowInternal;
|
||||
|
||||
|
||||
|
||||
%{C++
|
||||
#define MOZXMLTERMSHELL_CLASSNAME "XMLTerm Shell Component"
|
||||
#define MOZXMLTERMSHELL_CONTRACTID "@mozilla.org/xmlterm/xmltermshell;1"
|
||||
|
||||
#define MOZXMLTERMSHELL_CID \
|
||||
{ /* 0eb82b31-43a2-11d3-8e76-006008948af5 */ \
|
||||
0x0eb82b31, 0x43a2, 0x11d3, \
|
||||
{0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5} }
|
||||
%}
|
||||
|
||||
[scriptable, uuid(0eb82b30-43a2-11d3-8e76-006008948af5)]
|
||||
|
||||
interface mozIXMLTermShell : nsISupports
|
||||
|
@ -85,15 +96,3 @@ interface mozIXMLTermShell : nsISupports
|
|||
void Exit();
|
||||
};
|
||||
|
||||
|
||||
%{C++
|
||||
|
||||
#define MOZXMLTERMSHELL_CID \
|
||||
{ /* 0eb82b31-43a2-11d3-8e76-006008948af5 */ \
|
||||
0x0eb82b31, 0x43a2, 0x11d3, \
|
||||
{0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5} }
|
||||
|
||||
extern nsresult
|
||||
NS_NewXMLTermShell(mozIXMLTermShell** aXMLTermShell);
|
||||
%}
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is XMLterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* mozIXMLTermStream: interface to display HTML/XML streams as documents (unscriptable)
|
||||
*/
|
||||
|
||||
#include "nsIInputStream.idl"
|
||||
|
||||
interface nsIDOMWindowInternal;
|
||||
|
||||
%{C++
|
||||
#define MOZXMLTERMSTREAM_CLASSNAME "XMLTermStream Component"
|
||||
#define MOZXMLTERMSTREAM_CONTRACTID "@mozilla.org/xmlterm/xmlterm-stream;1"
|
||||
|
||||
#define MOZXMLTERMSTREAM_CID \
|
||||
{ /* 0eb82b41-43a2-11d3-8e76-006008948af5 */ \
|
||||
0x0eb82b41, 0x43a2, 0x11d3, \
|
||||
{0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5} }
|
||||
%}
|
||||
|
||||
/* NOT SCRIPTABLE */
|
||||
[uuid(0eb82b40-43a2-11d3-8e76-006008948af5)]
|
||||
|
||||
interface mozIXMLTermStream : nsIInputStream
|
||||
{
|
||||
/** Open stream in specified frame, or in current frame if frameName is null
|
||||
* @param aDOMWindow parent window
|
||||
* @param frameName name of child frame in which to display stream, or null
|
||||
* to display in parent window
|
||||
* @param contentURL URL of stream content
|
||||
* @param contentType MIME type of stream content
|
||||
* @param maxResizeHeight maximum resize height (0=> do not resize)
|
||||
*/
|
||||
void open(in nsIDOMWindowInternal aDOMWindow,
|
||||
in string frameName,
|
||||
in string contentURL,
|
||||
in string contentType,
|
||||
in long maxResizeHeight);
|
||||
|
||||
/** Write Unicode string to stream (blocks until write is completed)
|
||||
* @param buf string to write
|
||||
*/
|
||||
void write(in wstring buf);
|
||||
};
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is XMLterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* mozIXMLTerminal.idl: primary interface for XMLterm operations (unscriptable)
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "mozILineTerm.idl"
|
||||
#include "mozIXMLTermShell.idl"
|
||||
|
||||
interface nsISelectionController;
|
||||
interface nsIDocShell;
|
||||
interface nsIPresShell;
|
||||
|
||||
%{C++
|
||||
#define MOZXMLTERMINAL_CLASSNAME "XMLTerminal Component"
|
||||
#define MOZXMLTERMINAL_CONTRACTID "@mozilla.org/xmlterm/xmlterminal;1"
|
||||
|
||||
#define MOZXMLTERMINAL_CID \
|
||||
{ /* 0eb82b21-43a2-11d3-8e76-006008948af5 */ \
|
||||
0x0eb82b21, 0x43a2, 0x11d3, \
|
||||
{0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5} }
|
||||
%}
|
||||
|
||||
/* NOT SCRIPTABLE */
|
||||
[uuid(0eb82b20-43a2-11d3-8e76-006008948af5)]
|
||||
|
||||
interface mozIXMLTerminal : nsISupports
|
||||
{
|
||||
/** Initializes XMLterm in specified web shell
|
||||
* @param aDocShell web shell in which to embed XMLterm
|
||||
* @param aXMLTermShell scriptable wrapper shell for XMLterm
|
||||
* @param URL URL of document to be loaded in the window
|
||||
* (set to null string if document is already loaded in window)
|
||||
* @param args argument string to be passed to XMLterm
|
||||
* (at the moment this just contains any initial input data)
|
||||
*/
|
||||
void init(in nsIDocShell aDocShell,
|
||||
in mozIXMLTermShell aXMLTermShell,
|
||||
in wstring aURL,
|
||||
in wstring args);
|
||||
|
||||
/** Finalizes (closes) XMLterm
|
||||
*/
|
||||
void finalize();
|
||||
|
||||
/** Polls for readable data from XMLterm
|
||||
*/
|
||||
void poll();
|
||||
|
||||
/** Current entry (command) number
|
||||
*/
|
||||
readonly attribute long currentEntryNumber;
|
||||
|
||||
/** History buffer count
|
||||
*/
|
||||
attribute long history;
|
||||
|
||||
/** Prompt string
|
||||
*/
|
||||
attribute wstring prompt;
|
||||
|
||||
/** Ignore key press flag
|
||||
*/
|
||||
attribute boolean keyIgnore;
|
||||
|
||||
/** Writes string to terminal as if the user had typed it (without authenitcation)
|
||||
* @param aString string to be transmitted to terminal
|
||||
*/
|
||||
void sendTextAux(in wstring aString);
|
||||
|
||||
/** Writes string to terminal as if the user had typed it (command input)
|
||||
* @param aString string to be transmitted to terminal
|
||||
* @param aCookie document.cookie string for authentication
|
||||
*/
|
||||
void sendText(in wstring aString, in wstring aCookie);
|
||||
|
||||
/** Paste data from clipboard into XMLterm at current input line cursor location
|
||||
*/
|
||||
void paste();
|
||||
|
||||
/** Document associated with XMLterm
|
||||
*/
|
||||
readonly attribute nsIDOMDocument document;
|
||||
|
||||
/** Web shell associated with XMLterm
|
||||
*/
|
||||
readonly attribute nsIDocShell docShell;
|
||||
|
||||
/** Presentation shell associated with XMLterm
|
||||
*/
|
||||
readonly attribute nsIPresShell presShell;
|
||||
|
||||
/** DOM document associated with XMLterm
|
||||
*/
|
||||
readonly attribute nsIDOMDocument DOMDocument;
|
||||
|
||||
/** Selection controller associated with XMLterm
|
||||
*/
|
||||
readonly attribute nsISelectionController selectionController;
|
||||
|
||||
/** Flag denoting whether terminal is in full screen mode
|
||||
* @param aFlag (output) screen mode flag
|
||||
*/
|
||||
readonly attribute boolean screenMode;
|
||||
|
||||
/** Checks if supplied cookie is valid for XMLTerm
|
||||
* @param aCookie supplied cookie string
|
||||
* @return PR_TRUE if supplied cookie matches XMLTerm cookie
|
||||
*/
|
||||
boolean matchesCookie(in wstring aCookie);
|
||||
|
||||
/** Resizes XMLterm to match a resized window.
|
||||
*/
|
||||
void resize();
|
||||
|
||||
/** Shows the caret and make it editable.
|
||||
*/
|
||||
void showCaret();
|
||||
|
||||
/** Returns current screen size in rows/cols and in pixels
|
||||
* @param (output) rows
|
||||
* @param (output) cols
|
||||
* @param (output) xPixels
|
||||
* @param (output) yPixels
|
||||
*/
|
||||
void screenSize(out long rows, out long cols,
|
||||
out long xPixels, out long yPixels);
|
||||
};
|
||||
|
||||
/* mozIXMLTermSuspend: interface to suspend/resume select XMLterm operations
|
||||
*/
|
||||
|
||||
/* NOT SCRIPTABLE */
|
||||
[uuid(0eb82b50-43a2-11d3-8e76-006008948af5)]
|
||||
|
||||
interface mozIXMLTermSuspend : nsISupports
|
||||
{
|
||||
attribute boolean suspend;
|
||||
};
|
|
@ -41,7 +41,6 @@
|
|||
#include "mozXMLT.h"
|
||||
#include "mozXMLTermUtils.h"
|
||||
#include "mozLineTerm.h"
|
||||
#include "lineterm.h"
|
||||
|
||||
#define MAXCOL 4096 // Maximum columns in line buffer
|
||||
|
||||
|
@ -53,45 +52,57 @@ static NS_DEFINE_IID(kILineTermAuxIID, MOZILINETERMAUX_IID);
|
|||
|
||||
static NS_DEFINE_IID(kLineTermCID, MOZLINETERM_CID);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// mozLineTerm, mozLineTermAux factories
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewLineTerm(mozILineTerm** aLineTerm)
|
||||
{
|
||||
NS_PRECONDITION(aLineTerm != nsnull, "null ptr");
|
||||
if (! aLineTerm)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aLineTerm = new mozLineTerm();
|
||||
if (! *aLineTerm)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aLineTerm);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewLineTermAux(mozILineTermAux** aLineTermAux)
|
||||
{
|
||||
NS_PRECONDITION(aLineTermAux != nsnull, "null ptr");
|
||||
if (! aLineTermAux)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aLineTermAux = new mozLineTerm();
|
||||
if (! *aLineTermAux)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aLineTermAux);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// mozLineTerm implementaion
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(mozLineTerm)
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(mozLineTerm,
|
||||
mozILineTerm,
|
||||
mozILineTermAux);
|
||||
|
||||
|
||||
PRBool mozLineTerm::mLoggingEnabled = PR_FALSE;
|
||||
|
||||
PRBool mozLineTerm::mLoggingInitialized = PR_FALSE;
|
||||
|
||||
NS_METHOD
|
||||
mozLineTerm::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (!mLoggingInitialized) {
|
||||
// Initialize all LINETERM operations
|
||||
// (This initialization needs to be done at factory creation time;
|
||||
// trying to do it earlier, i.e., at registration time,
|
||||
// does not work ... something to do with loading of static global
|
||||
// variables.)
|
||||
|
||||
int messageLevel = 0;
|
||||
char* debugStr = (char*) PR_GetEnv("LTERM_DEBUG");
|
||||
|
||||
if (debugStr && (strlen(debugStr) == 1)) {
|
||||
messageLevel = 98;
|
||||
debugStr = nsnull;
|
||||
}
|
||||
|
||||
int result = lterm_init(0);
|
||||
if (result == 0) {
|
||||
tlog_set_level(LTERM_TLOG_MODULE, messageLevel, debugStr);
|
||||
}
|
||||
mLoggingInitialized = PR_TRUE;
|
||||
|
||||
char* logStr = (char*) PR_GetEnv("LTERM_LOG");
|
||||
if (logStr && (strlen(logStr) > 0)) {
|
||||
// Enable LineTerm logging
|
||||
mozLineTerm::mLoggingEnabled = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return mozLineTermConstructor( aOuter,
|
||||
aIID,
|
||||
aResult );
|
||||
}
|
||||
|
||||
mozLineTerm::mozLineTerm() :
|
||||
mCursorRow(0),
|
||||
mCursorColumn(0),
|
||||
|
@ -113,44 +124,6 @@ mozLineTerm::~mozLineTerm()
|
|||
}
|
||||
|
||||
|
||||
// Implement AddRef and Release
|
||||
NS_IMPL_ADDREF(mozLineTerm)
|
||||
NS_IMPL_RELEASE(mozLineTerm)
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozLineTerm::QueryInterface(REFNSIID aIID,void** aInstancePtr)
|
||||
{
|
||||
if (aInstancePtr == NULL) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
// Always NULL result, in case of failure
|
||||
*aInstancePtr = NULL;
|
||||
|
||||
//XMLT_LOG(mozLineTerm::QueryInterface,30,("0x%x\n",aIID));
|
||||
|
||||
if ( aIID.Equals(kISupportsIID)) {
|
||||
*aInstancePtr = NS_STATIC_CAST(nsISupports*,
|
||||
NS_STATIC_CAST(mozILineTermAux*,this));
|
||||
|
||||
} else if ( aIID.Equals(NS_GET_IID(mozILineTerm)) ) {
|
||||
*aInstancePtr = NS_STATIC_CAST(mozILineTerm*,
|
||||
NS_STATIC_CAST(mozILineTermAux*,this));
|
||||
|
||||
} else if ( aIID.Equals(NS_GET_IID(mozILineTermAux)) ) {
|
||||
*aInstancePtr = NS_STATIC_CAST(mozILineTermAux*,this);
|
||||
|
||||
} else {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
NS_ADDREF_THIS();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/** Checks if preference settings are secure for LineTerm creation and use
|
||||
*/
|
||||
NS_IMETHODIMP mozLineTerm::ArePrefsSecure(PRBool *_retval)
|
||||
|
@ -412,7 +385,7 @@ NS_IMETHODIMP mozLineTerm::OpenAux(const PRUnichar *command,
|
|||
result = mozXMLTermUtils::TimeStamp(0, mLastTime, timeStamp);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
char* temStr = timeStamp.ToNewCString();
|
||||
fprintf(stderr, "<TS %s> LineTerm %d opened by principal %s\n",
|
||||
PR_LogPrint("<TS %s> LineTerm %d opened by principal %s\n",
|
||||
temStr, mLTerm, securePrincipal);
|
||||
nsMemory::Free(temStr);
|
||||
}
|
||||
|
@ -576,11 +549,11 @@ NS_IMETHODIMP mozLineTerm::Write(const PRUnichar *buf,
|
|||
|
||||
if (NS_SUCCEEDED(result) && (timeStamp.Length() > 0)) {
|
||||
char* temStr = timeStamp.ToNewCString();
|
||||
fprintf(stderr, "<TS %s>\n", temStr);
|
||||
PR_LogPrint("<TS %s>\n", temStr);
|
||||
nsMemory::Free(temStr);
|
||||
|
||||
} else if (newline) {
|
||||
fprintf(stderr, "\n");
|
||||
PR_LogPrint("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,13 +25,15 @@
|
|||
#include "nspr.h"
|
||||
#include "nscore.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
|
||||
#include "mozILineTermAux.h"
|
||||
#include "mozILineTerm.h"
|
||||
#include "lineterm.h"
|
||||
|
||||
#define MAXCOL 4096 // Maximum columns in line buffer
|
||||
|
||||
|
@ -43,58 +45,12 @@ public:
|
|||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_MOZILINETERM
|
||||
NS_DECL_MOZILINETERMAUX
|
||||
|
||||
// mozILineTerm interface
|
||||
NS_IMETHOD Open(const PRUnichar *command,
|
||||
const PRUnichar *initInput,
|
||||
const PRUnichar *promptRegexp,
|
||||
PRInt32 options, PRInt32 processType,
|
||||
nsIDOMDocument *domDoc);
|
||||
|
||||
NS_IMETHOD Close(const PRUnichar* aCookie);
|
||||
|
||||
NS_IMETHOD Write(const PRUnichar *buf, const PRUnichar* aCookie);
|
||||
|
||||
NS_IMETHOD Read(PRInt32 *opcodes, PRInt32 *opvals,
|
||||
PRInt32 *buf_row, PRInt32 *buf_col,
|
||||
const PRUnichar* aCookie,
|
||||
PRUnichar **_retval);
|
||||
|
||||
// mozILineTermAux interface add ons
|
||||
// (not scriptable, no authentication cookie required)
|
||||
|
||||
NS_IMETHOD OpenAux(const PRUnichar *command,
|
||||
const PRUnichar *initInput,
|
||||
const PRUnichar *promptRegexp,
|
||||
PRInt32 options, PRInt32 processType,
|
||||
PRInt32 nRows, PRInt32 nCols,
|
||||
PRInt32 xPixels, PRInt32 yPixels,
|
||||
nsIDOMDocument *domDoc,
|
||||
nsIObserver* anObserver,
|
||||
nsString& aCookie);
|
||||
|
||||
NS_IMETHOD SuspendAux(PRBool aSuspend);
|
||||
|
||||
NS_IMETHOD CloseAux(void);
|
||||
|
||||
NS_IMETHOD CloseAllAux(void);
|
||||
|
||||
NS_IMETHOD ResizeAux(PRInt32 nRows, PRInt32 nCols);
|
||||
|
||||
NS_IMETHOD ReadAux(PRInt32 *opcodes, PRInt32 *opvals,
|
||||
PRInt32 *buf_row, PRInt32 *buf_col,
|
||||
PRUnichar **_retval, PRUnichar **retstyle);
|
||||
|
||||
NS_IMETHOD GetCookie(nsString& aCookie);
|
||||
|
||||
NS_IMETHOD GetCursorRow(PRInt32 *aCursorRow);
|
||||
NS_IMETHOD SetCursorRow(PRInt32 aCursorRow);
|
||||
|
||||
NS_IMETHOD GetCursorColumn(PRInt32 *aCursorColumn);
|
||||
NS_IMETHOD SetCursorColumn(PRInt32 aCursorColumn);
|
||||
|
||||
NS_IMETHOD GetEchoFlag(PRBool *aEchoFlag);
|
||||
NS_IMETHOD SetEchoFlag(PRBool aEchoFlag);
|
||||
// Define a Create method to be used with a factory:
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
// others
|
||||
|
||||
|
@ -104,9 +60,6 @@ public:
|
|||
gint source,
|
||||
GdkInputCondition condition);
|
||||
|
||||
/** Flag controlling logging of user input to STDERR */
|
||||
static PRBool mLoggingEnabled;
|
||||
|
||||
protected:
|
||||
/** Checks if Mozilla preference settings are secure
|
||||
* @param _retval (output) PR_TRUE if settings are secure
|
||||
|
@ -146,4 +99,9 @@ protected:
|
|||
/** record of last time when timestamp was displayed in user input log */
|
||||
PRTime mLastTime;
|
||||
|
||||
/** Flag controlling logging of user input to STDERR */
|
||||
static PRBool mLoggingEnabled;
|
||||
|
||||
static PRBool mLoggingInitialized;
|
||||
|
||||
};
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsIDOMNSUIEvent.h"
|
||||
#include "nsIPrivateTextEvent.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsISelectionController.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
@ -419,7 +420,7 @@ mozXMLTermKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
|
|||
|
||||
keyString.Append((PRUnichar) keyChar);
|
||||
|
||||
result = mXMLTerminal->SendTextAux(keyString);
|
||||
result = mXMLTerminal->SendTextAux(keyString.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -500,7 +501,7 @@ mozXMLTermTextListener::HandleText(nsIDOMEvent* aTextEvent)
|
|||
textEvent->GetText(textStr);
|
||||
|
||||
// Transmit text to terminal
|
||||
mXMLTerminal->SendTextAux(textStr);
|
||||
mXMLTerminal->SendTextAux(textStr.get());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "mozIXMLTerminal.h"
|
||||
#include "mozIXMLTermSuspend.h"
|
||||
|
||||
/* XMLTerm Key Listener */
|
||||
class mozXMLTermKeyListener : public nsIDOMKeyListener,
|
||||
|
|
|
@ -23,8 +23,10 @@
|
|||
#include "nscore.h"
|
||||
#include "prlog.h"
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
#include "nsMemory.h"
|
||||
|
||||
|
@ -51,8 +53,8 @@
|
|||
#include "nsIHTMLContent.h"
|
||||
|
||||
#include "mozXMLT.h"
|
||||
#include "mozILineTermAux.h"
|
||||
#include "mozIXMLTerminal.h"
|
||||
#include "mozIXMLTermStream.h"
|
||||
#include "mozXMLTermUtils.h"
|
||||
#include "mozXMLTermSession.h"
|
||||
#include "nsISelectionController.h"
|
||||
|
@ -303,7 +305,7 @@ NS_IMETHODIMP mozXMLTermSession::Resize(mozILineTermAux* lineTermAux)
|
|||
|
||||
// Determine current screen dimensions
|
||||
PRInt32 nRows, nCols, xPixels, yPixels;
|
||||
result = mXMLTerminal->ScreenSize(nRows, nCols, xPixels, yPixels);
|
||||
result = mXMLTerminal->ScreenSize(&nRows, &nCols, &xPixels, &yPixels);
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
|
@ -898,8 +900,8 @@ NS_IMETHODIMP mozXMLTermSession::ReadAll(mozILineTermAux* lineTermAux,
|
|||
CopyUCS2toASCII(metaCommandOutput, cstrout);
|
||||
else
|
||||
cstrout = "Error in displaying URL\n";
|
||||
printf("mozXMLTermSession::ReadAll, DEFAULT_META output=%s\n",
|
||||
cstrout.get());
|
||||
XMLT_LOG(mozXMLTermSession::ReadAll,63,
|
||||
("DEFAULT_META output=%s\n", cstrout.get()));
|
||||
|
||||
}
|
||||
break;
|
||||
|
@ -933,8 +935,8 @@ NS_IMETHODIMP mozXMLTermSession::ReadAll(mozILineTermAux* lineTermAux,
|
|||
CopyUCS2toASCII(metaCommandOutput, cstrout);
|
||||
else
|
||||
cstrout = "Error in executing JavaScript command\n";
|
||||
printf("mozXMLTermSession::ReadAll, JS output=%s\n",
|
||||
cstrout.get());
|
||||
XMLT_LOG(mozXMLTermSession::ReadAll,63,
|
||||
("JS output=%s\n", cstrout.get()));
|
||||
|
||||
}
|
||||
break;
|
||||
|
@ -1369,7 +1371,8 @@ NS_IMETHODIMP mozXMLTermSession::InitStream(const nsString& streamURL,
|
|||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
result = NS_NewXMLTermStream(getter_AddRefs(mXMLTermStream));
|
||||
mXMLTermStream = do_CreateInstance( MOZXMLTERMSTREAM_CONTRACTID,
|
||||
&result);
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
|
@ -1384,8 +1387,7 @@ NS_IMETHODIMP mozXMLTermSession::InitStream(const nsString& streamURL,
|
|||
getter_AddRefs(outerDOMWindow));
|
||||
|
||||
if (NS_FAILED(result) || !outerDOMWindow) {
|
||||
fprintf(stderr,
|
||||
"mozXMLTermSession::InitStream: Failed to convert webshell\n");
|
||||
XMLT_ERROR("mozXMLTermSession::InitStream: Failed to convert webshell\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -1418,8 +1420,7 @@ NS_IMETHODIMP mozXMLTermSession::InitStream(const nsString& streamURL,
|
|||
url.get(),
|
||||
contentType.get(), 800);
|
||||
if (NS_FAILED(result)) {
|
||||
fprintf(stderr,
|
||||
"mozXMLTermSession::InitStream: Failed to open stream\n");
|
||||
XMLT_ERROR("mozXMLTermSession::InitStream: Failed to open stream\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1532,7 +1533,7 @@ NS_IMETHODIMP mozXMLTermSession::BreakOutput(PRBool positionCursorBelow)
|
|||
// Close HTML/XML document
|
||||
result = mXMLTermStream->Close();
|
||||
if (NS_FAILED(result)) {
|
||||
fprintf(stderr, "mozXMLTermSession::BreakOutput: Failed to close stream\n");
|
||||
XMLT_ERROR("mozXMLTermSession::BreakOutput: Failed to close stream\n");
|
||||
return result;
|
||||
}
|
||||
mXMLTermStream = nsnull;
|
||||
|
@ -1635,7 +1636,7 @@ NS_IMETHODIMP mozXMLTermSession::ProcessOutput(const nsString& aString,
|
|||
|
||||
result = mXMLTermStream->Write(str.get());
|
||||
if (NS_FAILED(result)) {
|
||||
fprintf(stderr, "mozXMLTermSession::ProcessOutput: Failed to write to stream\n");
|
||||
XMLT_ERROR("mozXMLTermSession::ProcessOutput: Failed to write to stream\n");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
|
@ -36,7 +37,7 @@
|
|||
#include "nsIContent.h"
|
||||
|
||||
#include "mozXMLT.h"
|
||||
#include "mozILineTermAux.h"
|
||||
#include "mozILineTerm.h"
|
||||
#include "mozIXMLTerminal.h"
|
||||
#include "mozIXMLTermStream.h"
|
||||
|
||||
|
|
|
@ -49,39 +49,71 @@
|
|||
#include "nsIDOMWindowInternal.h"
|
||||
|
||||
#include "mozXMLT.h"
|
||||
#include "mozLineTerm.h"
|
||||
#include "mozXMLTermUtils.h"
|
||||
#include "mozXMLTermShell.h"
|
||||
|
||||
// Define Interface IDs
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
// Define Class IDs
|
||||
static NS_DEFINE_IID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// mozXMLTermShell factory
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewXMLTermShell(mozIXMLTermShell** aXMLTermShell)
|
||||
{
|
||||
NS_PRECONDITION(aXMLTermShell != nsnull, "null ptr");
|
||||
if (! aXMLTermShell)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aXMLTermShell = new mozXMLTermShell();
|
||||
if (! *aXMLTermShell)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aXMLTermShell);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// mozXMLTermShell implementation
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(mozXMLTermShell)
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(mozXMLTermShell,
|
||||
mozIXMLTermShell);
|
||||
|
||||
PRBool mozXMLTermShell::mLoggingInitialized = PR_FALSE;
|
||||
|
||||
NS_METHOD
|
||||
mozXMLTermShell::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
|
||||
if (!mLoggingInitialized) {
|
||||
// Set initial debugging message level for XMLterm
|
||||
int messageLevel = 0;
|
||||
char* debugStr = (char*) PR_GetEnv("XMLT_DEBUG");
|
||||
|
||||
if (debugStr && (strlen(debugStr) == 1)) {
|
||||
messageLevel = 98;
|
||||
debugStr = nsnull;
|
||||
}
|
||||
|
||||
tlog_set_level(XMLT_TLOG_MODULE, messageLevel, debugStr);
|
||||
mLoggingInitialized = PR_TRUE;
|
||||
}
|
||||
|
||||
return mozXMLTermShellConstructor( aOuter,
|
||||
aIID,
|
||||
aResult );
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
mozXMLTermShell::RegisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const char *componentType,
|
||||
const nsModuleComponentInfo *info)
|
||||
{
|
||||
// Component specific actions at registration time
|
||||
PR_LogPrint("mozXMLTermShell::RegisterProc: registered mozXMLTermShell\n");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
mozXMLTermShell::UnregisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const nsModuleComponentInfo *info)
|
||||
{
|
||||
// Component specific actions at unregistration time
|
||||
return NS_OK; // Return value is not used
|
||||
}
|
||||
|
||||
|
||||
mozXMLTermShell::mozXMLTermShell() :
|
||||
mInitialized(PR_FALSE),
|
||||
mContentWindow(nsnull),
|
||||
|
@ -97,37 +129,6 @@ mozXMLTermShell::~mozXMLTermShell()
|
|||
}
|
||||
|
||||
|
||||
// Implement AddRef and Release
|
||||
NS_IMPL_ADDREF(mozXMLTermShell)
|
||||
NS_IMPL_RELEASE(mozXMLTermShell)
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozXMLTermShell::QueryInterface(REFNSIID aIID,void** aInstancePtr)
|
||||
{
|
||||
if (aInstancePtr == NULL) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
// Always NULL result, in case of failure
|
||||
*aInstancePtr = NULL;
|
||||
|
||||
if ( aIID.Equals(kISupportsIID)) {
|
||||
*aInstancePtr = NS_STATIC_CAST(nsISupports*,
|
||||
NS_STATIC_CAST(mozIXMLTermShell*,this));
|
||||
|
||||
} else if ( aIID.Equals(NS_GET_IID(mozIXMLTermShell)) ) {
|
||||
*aInstancePtr = NS_STATIC_CAST(mozIXMLTermShell*,this);
|
||||
|
||||
} else {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
NS_ADDREF_THIS();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP mozXMLTermShell::GetCurrentEntryNumber(PRInt32 *aNumber)
|
||||
{
|
||||
|
@ -239,22 +240,20 @@ mozXMLTermShell::Init(nsIDOMWindowInternal* aContentWin,
|
|||
mContentAreaDocShell = docShell; // SVN: does this assignment addref?
|
||||
|
||||
// Create XMLTerminal
|
||||
nsCOMPtr<mozIXMLTerminal> newXMLTerminal;
|
||||
result = NS_NewXMLTerminal(getter_AddRefs(newXMLTerminal));
|
||||
nsCOMPtr<mozIXMLTerminal> newXMLTerminal = do_CreateInstance(
|
||||
MOZXMLTERMINAL_CONTRACTID,
|
||||
&result);
|
||||
if(NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
if(!newXMLTerminal)
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
// Initialize XMLTerminal with non-owning reference to us
|
||||
result = newXMLTerminal->Init(mContentAreaDocShell, this, URL, args);
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// Initialize XMLTerminal with non-owning reference to us
|
||||
result = newXMLTerminal->Init(mContentAreaDocShell, this, URL, args);
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
mXMLTerminal = newXMLTerminal;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
mXMLTerminal = newXMLTerminal;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -334,11 +333,9 @@ NS_IMETHODIMP mozXMLTermShell::SendText(const PRUnichar* aString,
|
|||
if (!mXMLTerminal)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsAutoString sendStr (aString);
|
||||
XMLT_LOG(mozXMLTermShell::SendText,10,("\n"));
|
||||
|
||||
XMLT_LOG(mozXMLTermShell::SendText,10,("length=%d\n", sendStr.Length()));
|
||||
|
||||
return mXMLTerminal->SendText(sendStr, aCookie);
|
||||
return mXMLTerminal->SendText(aString, aCookie);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "nspr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
|
||||
#include "mozXMLT.h"
|
||||
#include "mozIXMLTerminal.h"
|
||||
|
@ -43,31 +44,24 @@ class mozXMLTermShell : public mozIXMLTermShell
|
|||
virtual ~mozXMLTermShell();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_MOZIXMLTERMSHELL
|
||||
|
||||
// mozIXMLTermShell interface
|
||||
|
||||
NS_IMETHOD GetCurrentEntryNumber(PRInt32 *aNumber);
|
||||
// Define a Create method to be used with a factory:
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
NS_IMETHOD SetHistory(PRInt32 aHistory, const PRUnichar* aCookie);
|
||||
static NS_METHOD
|
||||
RegisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const char *componentType,
|
||||
const nsModuleComponentInfo *info);
|
||||
|
||||
NS_IMETHOD SetPrompt(const PRUnichar* aPrompt, const PRUnichar* aCookie);
|
||||
|
||||
NS_IMETHOD IgnoreKeyPress(PRBool aIgnore,
|
||||
const PRUnichar* aCookie);
|
||||
|
||||
NS_IMETHOD Init(nsIDOMWindowInternal* aContentWin,
|
||||
const PRUnichar* URL,
|
||||
const PRUnichar* args);
|
||||
|
||||
NS_IMETHOD Close(const PRUnichar* aCookie);
|
||||
|
||||
NS_IMETHOD Poll(void);
|
||||
|
||||
NS_IMETHOD Resize(void);
|
||||
|
||||
NS_IMETHOD SendText(const PRUnichar* aString, const PRUnichar* aCookie);
|
||||
|
||||
NS_IMETHOD Exit(void);
|
||||
static NS_METHOD
|
||||
UnregisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const nsModuleComponentInfo *info);
|
||||
|
||||
NS_IMETHOD Finalize(void);
|
||||
|
||||
|
@ -84,4 +78,6 @@ protected:
|
|||
|
||||
/** owning reference to XMLTerminal object created by us */
|
||||
nsCOMPtr<mozIXMLTerminal> mXMLTerminal;
|
||||
|
||||
static PRBool mLoggingInitialized;
|
||||
};
|
||||
|
|
|
@ -30,13 +30,10 @@
|
|||
#include "nsMemory.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIDocumentLoader.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIDocumentViewer.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIDocumentLoaderFactory.h"
|
||||
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIScrollableView.h"
|
||||
|
@ -46,49 +43,20 @@
|
|||
#include "nsIScriptContextOwner.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIDOMWindowCollection.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "mozXMLT.h"
|
||||
#include "mozXMLTermUtils.h"
|
||||
#include "mozXMLTermStream.h"
|
||||
|
||||
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// mozXMLTermStream factory
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewXMLTermStream(mozIXMLTermStream** aXMLTermStream)
|
||||
{
|
||||
NS_PRECONDITION(aXMLTermStream != nsnull, "null ptr");
|
||||
if (!aXMLTermStream)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aXMLTermStream = new mozXMLTermStream();
|
||||
if (! *aXMLTermStream)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aXMLTermStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// mozXMLTermStream implementation
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(mozXMLTermStream,
|
||||
mozIXMLTermStream,
|
||||
nsIInputStream);
|
||||
|
||||
mozXMLTermStream::mozXMLTermStream() :
|
||||
mUTF8Buffer(""),
|
||||
|
@ -113,42 +81,6 @@ mozXMLTermStream::~mozXMLTermStream()
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
// Implement AddRef and Release
|
||||
NS_IMPL_ADDREF(mozXMLTermStream)
|
||||
NS_IMPL_RELEASE(mozXMLTermStream)
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozXMLTermStream::QueryInterface(REFNSIID aIID,void** aInstancePtr)
|
||||
{
|
||||
if (aInstancePtr == NULL) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
// Always NULL result, in case of failure
|
||||
*aInstancePtr = NULL;
|
||||
|
||||
if ( aIID.Equals(NS_GET_IID(nsISupports))) {
|
||||
*aInstancePtr = NS_STATIC_CAST(nsISupports*,
|
||||
NS_STATIC_CAST(mozIXMLTermStream*,this));
|
||||
} else if(aIID.Equals(NS_GET_IID(nsIInputStream))) {
|
||||
*aInstancePtr = NS_STATIC_CAST(nsIInputStream*,this);
|
||||
|
||||
} else if(aIID.Equals(NS_GET_IID(mozIXMLTermStream))) {
|
||||
*aInstancePtr = NS_STATIC_CAST(mozIXMLTermStream*,this);
|
||||
|
||||
} else {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
NS_ADDREF_THIS();
|
||||
|
||||
XMLT_LOG(mozXMLTermStream::QueryInterface,20,("mRefCnt = %d\n", mRefCnt));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// mozIXMLTermStream interface
|
||||
|
||||
/** Open stream in specified frame, or in current frame if frameName is null
|
||||
|
@ -251,7 +183,7 @@ NS_IMETHODIMP mozXMLTermStream::Open(nsIDOMWindowInternal* aDOMWindow,
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
#ifdef NO_WORKAROUND
|
||||
printf("mozXMLTermStream::Open, NO_WORKAROUND, url=%s\n", contentURL);
|
||||
XMLT_WARNING("mozXMLTermStream::Open, NO_WORKAROUND, url=%s\n", contentURL);
|
||||
|
||||
nsCOMPtr<nsIInputStream> inputStream = this;
|
||||
|
||||
|
@ -326,22 +258,22 @@ NS_IMETHODIMP mozXMLTermStream::Open(nsIDOMWindowInternal* aDOMWindow,
|
|||
return result;
|
||||
|
||||
#else // !NO_WORKAROUND
|
||||
printf("mozXMLTermStream::Open, WORKAROUND\n");
|
||||
XMLT_WARNING("mozXMLTermStream::Open, WORKAROUND\n");
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> innerDOMDoc;
|
||||
result = mDOMWindow->GetDocument(getter_AddRefs(innerDOMDoc));
|
||||
printf("mozXMLTermStream::Open,check1, 0x%x, 0x%x\n",
|
||||
XMLT_WARNING("mozXMLTermStream::Open,check1, 0x%x, 0x%x\n",
|
||||
result, (int) innerDOMDoc.get());
|
||||
if (NS_FAILED(result) || !innerDOMDoc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mDOMHTMLDocument = do_QueryInterface(innerDOMDoc);
|
||||
printf("mozXMLTermStream::Open,check2, 0x%x\n", result);
|
||||
XMLT_WARNING("mozXMLTermStream::Open,check2, 0x%x\n", result);
|
||||
if (!mDOMHTMLDocument)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
result = mDOMHTMLDocument->Open();
|
||||
printf("mozXMLTermStream::Open,check3, 0x%x\n", result);
|
||||
XMLT_WARNING("mozXMLTermStream::Open,check3, 0x%x\n", result);
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
#endif // !NO_WORKAROUND
|
||||
|
@ -463,13 +395,13 @@ NS_IMETHODIMP mozXMLTermStream::SizeToContentHeight(PRInt32 maxHeight)
|
|||
pageWidth = PRInt32((float)contX*pixelScale);
|
||||
pageHeight = PRInt32((float)contY*pixelScale);
|
||||
|
||||
printf("mozXMLTermStream::SizeToContentHeight: scrollbar %d, %d\n",
|
||||
XMLT_WARNING("mozXMLTermStream::SizeToContentHeight: scrollbar %d, %d\n",
|
||||
scrollBarWidth, scrollBarHeight);
|
||||
|
||||
printf("mozXMLTermStream::SizeToContentHeight: presShell %d, %d\n",
|
||||
XMLT_WARNING("mozXMLTermStream::SizeToContentHeight: presShell %d, %d\n",
|
||||
shellWidth, shellHeight);
|
||||
|
||||
printf("mozXMLTermStream::SizeToContentHeight: page %d, %d, %e\n",
|
||||
XMLT_WARNING("mozXMLTermStream::SizeToContentHeight: page %d, %d, %e\n",
|
||||
pageWidth, pageHeight, pixelScale);
|
||||
|
||||
if ((pageHeight > shellHeight) || (pageWidth > shellWidth)) {
|
||||
|
@ -481,7 +413,7 @@ NS_IMETHODIMP mozXMLTermStream::SizeToContentHeight(PRInt32 maxHeight)
|
|||
PRInt32 newPageHeight = pageHeight;
|
||||
PRInt32 excessWidth = (pageWidth+scrollBarWidth - shellWidth);
|
||||
|
||||
printf("mozXMLTermStream::SizeToContentHeight: excessWidth %d\n",
|
||||
XMLT_WARNING("mozXMLTermStream::SizeToContentHeight: excessWidth %d\n",
|
||||
excessWidth);
|
||||
|
||||
if (excessWidth > 0) {
|
||||
|
@ -499,7 +431,7 @@ NS_IMETHODIMP mozXMLTermStream::SizeToContentHeight(PRInt32 maxHeight)
|
|||
if (excessWidth > scrollBarWidth)
|
||||
newPageHeight += scrollBarHeight;
|
||||
|
||||
printf("mozXMLTermStream::SizeToContentHeight: page2 %d, %d, %d\n",
|
||||
XMLT_WARNING("mozXMLTermStream::SizeToContentHeight: page2 %d, %d, %d\n",
|
||||
pageWidth, pageHeight, newPageHeight);
|
||||
|
||||
// Reset IFRAME width
|
||||
|
@ -610,7 +542,7 @@ NS_IMETHODIMP mozXMLTermStream::Write(const PRUnichar* buf)
|
|||
return result;
|
||||
#endif // !NO_WORKAROUND
|
||||
|
||||
printf("mozXMLTermStream::Write: str=%s\n", mUTF8Buffer.get());
|
||||
XMLT_WARNING("mozXMLTermStream::Write: str=%s\n", mUTF8Buffer.get());
|
||||
|
||||
XMLT_LOG(mozXMLTermStream::Write,51,("returning mUTF8Offset=%d\n",
|
||||
mUTF8Offset));
|
||||
|
|
|
@ -26,6 +26,27 @@
|
|||
#include "nspr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIDOMWindowCollection.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
#include "nsIDocumentLoader.h"
|
||||
#include "nsIDocumentLoaderFactory.h"
|
||||
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIIOService.h"
|
||||
|
||||
#include "nsIWebShell.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIScriptContext.h"
|
||||
|
||||
#include "mozXMLT.h"
|
||||
#include "mozIXMLTermStream.h"
|
||||
|
@ -39,23 +60,9 @@ class mozXMLTermStream : public mozIXMLTermStream
|
|||
mozXMLTermStream();
|
||||
virtual ~mozXMLTermStream();
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIInputStream interface
|
||||
NS_DECL_NSIINPUTSTREAM
|
||||
|
||||
// mozIXMLTermStream interface
|
||||
|
||||
// Open stream in specified frame, or in current frame if frameName is null
|
||||
NS_IMETHOD Open(nsIDOMWindowInternal* aDOMWindow,
|
||||
const char* frameName,
|
||||
const char* contentURL,
|
||||
const char* contentType,
|
||||
PRInt32 maxResizeHeight);
|
||||
|
||||
// Write Unicode string to stream
|
||||
NS_IMETHOD Write(const PRUnichar* buf);
|
||||
NS_DECL_MOZIXMLTERMSTREAM
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
#include "mozXMLT.h"
|
||||
#include "mozXMLTermUtils.h"
|
||||
#include "mozXMLTerminal.h"
|
||||
#include "mozIXMLTermSuspend.h"
|
||||
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
|
@ -68,38 +67,20 @@
|
|||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
static NS_DEFINE_IID(kIXMLTerminalIID, MOZIXMLTERMINAL_IID);
|
||||
static NS_DEFINE_IID(kXMLTerminalCID, MOZXMLTERMINAL_CID);
|
||||
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
||||
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// mozXMLTerminal factory
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewXMLTerminal(mozIXMLTerminal** aXMLTerminal)
|
||||
{
|
||||
NS_PRECONDITION(aXMLTerminal != nsnull, "null ptr");
|
||||
if (!aXMLTerminal)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aXMLTerminal = new mozXMLTerminal();
|
||||
if (! *aXMLTerminal)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aXMLTerminal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// mozXMLTerminal implementation
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS4(mozXMLTerminal,
|
||||
mozIXMLTerminal,
|
||||
nsIWebProgressListener,
|
||||
nsIObserver,
|
||||
nsISupportsWeakReference);
|
||||
|
||||
mozXMLTerminal::mozXMLTerminal() :
|
||||
mInitialized(PR_FALSE),
|
||||
|
||||
|
@ -135,25 +116,6 @@ mozXMLTerminal::~mozXMLTerminal()
|
|||
}
|
||||
|
||||
|
||||
// Implement AddRef and Release
|
||||
NS_IMPL_ADDREF(mozXMLTerminal)
|
||||
NS_IMPL_RELEASE(mozXMLTerminal)
|
||||
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(mozXMLTerminal)
|
||||
/*
|
||||
I maintained the order from the original, however,
|
||||
the original called |XMLT_LOG| and in the interface-map form
|
||||
it no longer does. Is this an issue?
|
||||
*/
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozIXMLTerminal)
|
||||
NS_INTERFACE_MAP_ENTRY(mozIXMLTerminal)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
NS_IMETHODIMP mozXMLTerminal::GetCurrentEntryNumber(PRInt32 *aNumber)
|
||||
{
|
||||
if (!mXMLTermSession)
|
||||
|
@ -384,7 +346,7 @@ NS_IMETHODIMP mozXMLTerminal::Activate(void)
|
|||
nsCOMPtr<mozIXMLTermStream> stream;
|
||||
result = NS_NewXMLTermStream(getter_AddRefs(stream));
|
||||
if (NS_FAILED(result)) {
|
||||
fprintf(stderr, "mozXMLTerminal::Activate: Failed to create stream\n");
|
||||
XMLT_ERROR("mozXMLTerminal::Activate: Failed to create stream\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -397,26 +359,26 @@ NS_IMETHODIMP mozXMLTerminal::Activate(void)
|
|||
getter_AddRefs(outerDOMWindow));
|
||||
|
||||
if (NS_FAILED(result) || !outerDOMWindow) {
|
||||
fprintf(stderr, "mozXMLTerminal::Activate: Failed to convert docshell\n");
|
||||
XMLT_ERROR("mozXMLTerminal::Activate: Failed to convert docshell\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
result = stream->Open(outerDOMWindow, "iframet", "chrome://dummy",
|
||||
"text/html", 800);
|
||||
if (NS_FAILED(result)) {
|
||||
fprintf(stderr, "mozXMLTerminal::Activate: Failed to open stream\n");
|
||||
XMLT_ERROR("mozXMLTerminal::Activate: Failed to open stream\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
result = stream->Write(streamData.get());
|
||||
if (NS_FAILED(result)) {
|
||||
fprintf(stderr, "mozXMLTerminal::Activate: Failed to write to stream\n");
|
||||
XMLT_ERROR("mozXMLTerminal::Activate: Failed to write to stream\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
result = stream->Close();
|
||||
if (NS_FAILED(result)) {
|
||||
fprintf(stderr, "mozXMLTerminal::Activate: Failed to close stream\n");
|
||||
XMLT_ERROR("mozXMLTerminal::Activate: Failed to close stream\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -467,7 +429,7 @@ NS_IMETHODIMP mozXMLTerminal::Activate(void)
|
|||
|
||||
// Determine current screen dimensions
|
||||
PRInt32 nRows, nCols, xPixels, yPixels;
|
||||
result = ScreenSize(nRows, nCols, xPixels, yPixels);
|
||||
result = ScreenSize(&nRows, &nCols, &xPixels, &yPixels);
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
|
@ -495,7 +457,7 @@ NS_IMETHODIMP mozXMLTerminal::Activate(void)
|
|||
// Instantiate LineTerm
|
||||
XMLT_LOG(mozXMLTerminal::Activate,22,
|
||||
("instantiating lineterm, nRows=%d, nCols=%d\n", nRows, nCols));
|
||||
result = NS_NewLineTermAux(getter_AddRefs(mLineTermAux));
|
||||
mLineTermAux = do_CreateInstance(MOZLINETERM_CONTRACTID, &result);
|
||||
if (NS_FAILED(result)) {
|
||||
XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to instantiate LineTermAux\n");
|
||||
return result;
|
||||
|
@ -607,8 +569,8 @@ NS_IMETHODIMP mozXMLTerminal::Activate(void)
|
|||
* @param (output) xPixels
|
||||
* @param (output) yPixels
|
||||
*/
|
||||
NS_IMETHODIMP mozXMLTerminal::ScreenSize(PRInt32& rows, PRInt32& cols,
|
||||
PRInt32& xPixels, PRInt32& yPixels)
|
||||
NS_IMETHODIMP mozXMLTerminal::ScreenSize(PRInt32* rows, PRInt32* cols,
|
||||
PRInt32* xPixels, PRInt32* yPixels)
|
||||
{
|
||||
nsresult result;
|
||||
|
||||
|
@ -661,33 +623,33 @@ NS_IMETHODIMP mozXMLTerminal::ScreenSize(PRInt32& rows, PRInt32& cols,
|
|||
xdel = pixelScale * fontWidth;
|
||||
ydel = pixelScale * fontHeight + 2;
|
||||
|
||||
xPixels = (int) (pixelScale * shellArea.width);
|
||||
yPixels = (int) (pixelScale * shellArea.height);
|
||||
*xPixels = (int) (pixelScale * shellArea.width);
|
||||
*yPixels = (int) (pixelScale * shellArea.height);
|
||||
|
||||
// Determine number of rows/columns
|
||||
rows = (int) ((yPixels-16) / ydel);
|
||||
cols = (int) ((xPixels-20) / xdel);
|
||||
*rows = (int) ((*yPixels-16) / ydel);
|
||||
*cols = (int) ((*xPixels-20) / xdel);
|
||||
|
||||
if (rows < 1) rows = 1;
|
||||
if (cols < 1) cols = 1;
|
||||
if (*rows < 1) *rows = 1;
|
||||
if (*cols < 1) *cols = 1;
|
||||
|
||||
XMLT_LOG(mozXMLTerminal::ScreenSize,72,
|
||||
("rows=%d, cols=%d, xPixels=%d, yPixels=%d\n",
|
||||
rows, cols, xPixels, yPixels));
|
||||
*rows, *cols, *xPixels, *yPixels));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Transmit string to LineTerm (use saved cookie)
|
||||
NS_IMETHODIMP mozXMLTerminal::SendTextAux(const nsString& aString)
|
||||
NS_IMETHODIMP mozXMLTerminal::SendTextAux(const PRUnichar* aString)
|
||||
{
|
||||
return SendText(aString, mCookie.get());
|
||||
}
|
||||
|
||||
|
||||
// Transmit string to LineTerm
|
||||
NS_IMETHODIMP mozXMLTerminal::SendText(const nsString& aString,
|
||||
NS_IMETHODIMP mozXMLTerminal::SendText(const PRUnichar* aString,
|
||||
const PRUnichar* aCookie)
|
||||
{
|
||||
nsresult result;
|
||||
|
@ -835,7 +797,7 @@ NS_IMETHODIMP mozXMLTerminal::Paste()
|
|||
PRUnichar* text = nsnull;
|
||||
textDataObj->ToString ( &text );
|
||||
pasteString.Assign( text, objLen / 2 );
|
||||
result = SendTextAux(pasteString);
|
||||
result = SendTextAux(pasteString.get());
|
||||
}
|
||||
}
|
||||
nsMemory::Free(bestFlavor);
|
||||
|
|
|
@ -28,11 +28,12 @@
|
|||
#include "nsWeakReference.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
|
||||
#include "mozXMLT.h"
|
||||
|
||||
#include "mozILineTermAux.h"
|
||||
#include "mozILineTerm.h"
|
||||
#include "mozIXMLTerminal.h"
|
||||
#include "mozXMLTermSession.h"
|
||||
#include "mozXMLTermListeners.h"
|
||||
|
@ -56,49 +57,7 @@ class mozXMLTerminal : public mozIXMLTerminal,
|
|||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
// mozIXMLTerminal interface
|
||||
|
||||
NS_IMETHOD Init(nsIDocShell* aDocShell,
|
||||
mozIXMLTermShell* aXMLTermShell,
|
||||
const PRUnichar* aURL,
|
||||
const PRUnichar* args);
|
||||
|
||||
NS_IMETHOD Finalize(void);
|
||||
NS_IMETHOD Poll(void);
|
||||
|
||||
NS_IMETHOD GetCurrentEntryNumber(PRInt32 *aNumber);
|
||||
NS_IMETHOD GetHistory(PRInt32 *aHistory);
|
||||
NS_IMETHOD SetHistory(PRInt32 aHistory);
|
||||
NS_IMETHOD GetPrompt(PRUnichar **aPrompt);
|
||||
NS_IMETHOD SetPrompt(const PRUnichar* aPrompt);
|
||||
NS_IMETHOD GetKeyIgnore(PRBool* aIgnore);
|
||||
NS_IMETHOD SetKeyIgnore(const PRBool aIgnore);
|
||||
|
||||
NS_IMETHOD SendTextAux(const nsString& aString);
|
||||
NS_IMETHOD SendText(const nsString& aString, const PRUnichar* aCookie);
|
||||
|
||||
NS_IMETHOD Paste();
|
||||
|
||||
NS_IMETHOD GetDocument(nsIDOMDocument** aDoc);
|
||||
|
||||
NS_IMETHOD GetDocShell(nsIDocShell** aDocShell);
|
||||
|
||||
NS_IMETHOD GetPresShell(nsIPresShell** aPresShell);
|
||||
|
||||
NS_IMETHOD GetDOMDocument(nsIDOMDocument** aDOMDocument);
|
||||
|
||||
NS_IMETHOD GetSelectionController(nsISelectionController** aSelectionController);
|
||||
|
||||
NS_IMETHOD GetScreenMode(PRBool* aFlag);
|
||||
|
||||
NS_IMETHOD MatchesCookie(const PRUnichar* aCookie, PRBool *_retval);
|
||||
|
||||
NS_IMETHOD Resize(void);
|
||||
|
||||
NS_IMETHOD ShowCaret(void);
|
||||
|
||||
NS_IMETHOD ScreenSize(PRInt32& rows, PRInt32& cols,
|
||||
PRInt32& xPixels, PRInt32& yPixels);
|
||||
|
||||
NS_DECL_MOZIXMLTERMINAL
|
||||
|
||||
// nsIObserver interface
|
||||
NS_IMETHOD Observe(nsISupports *aSubject, const PRUnichar *aTopic,
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "MPL"); you may not use this file
|
||||
# except in compliance with the MPL. You may obtain a copy of
|
||||
# the MPL at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the MPL is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the MPL for the specific language governing
|
||||
# rights and limitations under the MPL.
|
||||
#
|
||||
# The Original Code is XMLterm.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
# Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
# Copyright (C) 1999,2001 Ramalingam Saravanan. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License (the "GPL"), in which case
|
||||
# the provisions of the GPL are applicable instead of
|
||||
# those above. If you wish to allow use of your version of this
|
||||
# file only under the terms of the GPL and not to allow
|
||||
# others to use your version of this file under the MPL, indicate
|
||||
# your decision by deleting the provisions above and replace them
|
||||
# with the notice and other provisions required by the GPL.
|
||||
# If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
# Makefile for xmlterm/build directory
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
# Debug option
|
||||
DEBUG = 1
|
||||
|
||||
XPI_MODULE = xmlterm
|
||||
XPI_MODULE_VERS = 0.53
|
||||
|
||||
MODULE = xmlterm
|
||||
LIBRARY_NAME = xmlterm
|
||||
EXPORT_LIBRARY = 1
|
||||
SHORT_LIBNAME = xmlterm
|
||||
IS_COMPONENT = 1
|
||||
|
||||
REQUIRES = xpcom string
|
||||
|
||||
MODULE_NAME = XMLTermModule
|
||||
|
||||
DEFINES += $(TK_CFLAGS)
|
||||
|
||||
CPPSRCS = mozXMLTermModule.cpp
|
||||
|
||||
SHARED_LIBRARY_LIBS = \
|
||||
$(DIST)/lib/liblineterm_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/libxmlterm_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../base \
|
||||
-I$(srcdir)/../lineterm \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
-lgkgfx \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(srcdir)/../config/xmlterm_config.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
PLATFORM_STR = unknown
|
||||
|
||||
# Edit the lines below as needed, depending upon your platform(s)
|
||||
ifeq ($(OS_ARCH),Linux)
|
||||
PLATFORM_STR = linux2-ix86
|
||||
endif
|
||||
|
||||
ifeq ($(OS_CONFIG),SunOS5)
|
||||
PLATFORM_STR = sunos5-sparc
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),FreeBSD)
|
||||
PLATFORM_STR = freebsd-ix86
|
||||
endif
|
||||
|
||||
XPIFILE = $(XPI_MODULE)-$(XPI_MODULE_VERS)-$(PLATFORM_STR).xpi
|
||||
|
||||
xpi::
|
||||
zip -r $(DIST)/bin/$(XPIFILE) install.js
|
||||
cd $(DIST)/bin; zip -g $(XPIFILE) \
|
||||
components/$(XPI_MODULE).xpt \
|
||||
components/lib$(XPI_MODULE).so
|
||||
echo Created $(DIST)/bin/$(XPIFILE)
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is XMLterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 2000 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License (the "GPL"), in which case
|
||||
* the provisions of the GPL are applicable instead of
|
||||
* those above. If you wish to allow use of your version of this
|
||||
* file only under the terms of the GPL and not to allow
|
||||
* others to use your version of this file under the MPL, indicate
|
||||
* your decision by deleting the provisions above and replace them
|
||||
* with the notice and other provisions required by the GPL.
|
||||
* If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "mozLineTerm.h"
|
||||
#include "mozXMLTermShell.h"
|
||||
#include "mozXMLTerminal.h"
|
||||
#include "mozXMLTermStream.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(mozXMLTerminal)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(mozXMLTermStream)
|
||||
|
||||
// CIDs implemented by module
|
||||
static nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ MOZLINETERM_CLASSNAME,
|
||||
MOZLINETERM_CID,
|
||||
MOZLINETERM_CONTRACTID,
|
||||
mozLineTerm::Create,
|
||||
},
|
||||
|
||||
{ MOZXMLTERMSHELL_CLASSNAME,
|
||||
MOZXMLTERMSHELL_CID,
|
||||
MOZXMLTERMSHELL_CONTRACTID,
|
||||
mozXMLTermShell::Create,
|
||||
mozXMLTermShell::RegisterProc,
|
||||
mozXMLTermShell::UnregisterProc
|
||||
},
|
||||
|
||||
{ MOZXMLTERMINAL_CLASSNAME,
|
||||
MOZXMLTERMINAL_CID,
|
||||
MOZXMLTERMINAL_CONTRACTID,
|
||||
mozXMLTerminalConstructor,
|
||||
},
|
||||
|
||||
{ MOZXMLTERMSTREAM_CLASSNAME,
|
||||
MOZXMLTERMSTREAM_CID,
|
||||
MOZXMLTERMSTREAM_CONTRACTID,
|
||||
mozXMLTermStreamConstructor,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
// Module entry point
|
||||
NS_IMPL_NSGETMODULE("mozXMLTermModule", components)
|
|
@ -82,7 +82,7 @@ PROGOBJS = $(OBJS)
|
|||
endif
|
||||
|
||||
# Targets
|
||||
all: export libs progs
|
||||
all: export install progs
|
||||
|
||||
export: $(EXPORTS)
|
||||
ifneq (,$(EXPORTS))
|
||||
|
@ -95,7 +95,7 @@ ifneq (,$(EXPORTS))
|
|||
endif
|
||||
+$(LOOP_OVER_DIRS)
|
||||
|
||||
libs: $(LIBRARY)
|
||||
install: $(LIBRARY)
|
||||
mkdir -p $(topsrcdir)/distrib/lib $(topsrcdir)/base/lib
|
||||
+$(LOOP_OVER_DIRS)
|
||||
|
||||
|
@ -152,7 +152,7 @@ $(OBJDIR)/%.o: %.cpp $(wildcard *.h) $(wildcard $(topsrcdir)/distrib/include/*.h
|
|||
.SUFFIXES: .a .o .c .cpp .h .pl .class .java .html .mk .in
|
||||
|
||||
# Always recognized targets
|
||||
.PHONY: all clean clobber clobber_all export install libs
|
||||
.PHONY: all clean clobber clobber_all export install
|
||||
|
||||
# OS configuration
|
||||
os_config:
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "MPL"); you may not use this file
|
||||
# except in compliance with the MPL. You may obtain a copy of
|
||||
# the MPL at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the MPL is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the MPL for the specific language governing
|
||||
# rights and limitations under the MPL.
|
||||
#
|
||||
# The Original Code is lineterm.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
# Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License (the "GPL"), in which case
|
||||
# the provisions of the GPL are applicable instead of
|
||||
# those above. If you wish to allow use of your version of this
|
||||
# file only under the terms of the GPL and not to allow
|
||||
# others to use your version of this file under the MPL, indicate
|
||||
# your decision by deleting the provisions above and replace them
|
||||
# with the notice and other provisions required by the GPL.
|
||||
# If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
# makefile for xmlterm/base directory
|
||||
|
||||
ifdef STAND_ALONE
|
||||
DEPTH = ..
|
||||
topsrcdir = ..
|
||||
srcdir = .
|
||||
include $(topsrcdir)/config/autoconf.mk
|
||||
else
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
endif
|
||||
|
||||
ifdef DEBUG
|
||||
# Debug option
|
||||
DEBUG_LTERM = 1
|
||||
endif
|
||||
|
||||
# C Sources
|
||||
ifdef NO_PTY
|
||||
CSRCS = ltermManager.c ltermIO.c ltermInput.c ltermOutput.c ltermEscape.c \
|
||||
tracelog.c unistring.c
|
||||
else
|
||||
CSRCS = ltermManager.c ltermIO.c ltermInput.c ltermOutput.c ltermEscape.c \
|
||||
tracelog.c unistring.c ptystream.c
|
||||
endif
|
||||
|
||||
# Defines
|
||||
ifdef STAND_ALONE
|
||||
else
|
||||
DEFINES += $(TK_CFLAGS)
|
||||
endif
|
||||
|
||||
ifdef DEBUG_LTERM
|
||||
DEFINES += -DDEBUG_LTERM
|
||||
endif
|
||||
|
||||
# Exported header files
|
||||
EXPORTS = lineterm.h tracelog.h unistring.h ptystream.h
|
||||
|
||||
MODULE = xmlterm
|
||||
LIBRARY_NAME = lineterm_s
|
||||
|
||||
REQUIRES =
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
ifdef STAND_ALONE
|
||||
include $(topsrcdir)/config/config.mk
|
||||
endif
|
||||
|
||||
include $(srcdir)/../config/xmlterm_config.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifndef STAND_ALONE
|
||||
ifeq ($(OS_ARCH),Linux)
|
||||
OS_CFLAGS += -ansi
|
||||
endif
|
||||
endif
|
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is lineterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License (the "GPL"), in which case
|
||||
* the provisions of the GPL are applicable instead of
|
||||
* those above. If you wish to allow use of your version of this
|
||||
* file only under the terms of the GPL and not to allow
|
||||
* others to use your version of this file under the MPL, indicate
|
||||
* your decision by deleting the provisions above and replace them
|
||||
* with the notice and other provisions required by the GPL.
|
||||
* If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/* lineterm.h: Line terminal (LTERM) public interface header file
|
||||
* LINETERM provides a "stream" interface to an XTERM-like terminal,
|
||||
* using line-oriented input/output.
|
||||
*/
|
||||
|
||||
#ifndef _LINETERM_H
|
||||
|
||||
#define _LINETERM_H 1
|
||||
|
||||
#include "unistring.h"
|
||||
|
||||
/* Define LTERM read callback function type */
|
||||
#ifdef USE_GTK_WIDGETS
|
||||
#include <gtk/gtk.h>
|
||||
typedef void (*lterm_callback_func_t)(gpointer, gint, GdkInputCondition);
|
||||
#else
|
||||
typedef void* lterm_callback_func_t;
|
||||
#endif
|
||||
|
||||
/* Unicode character style information (same type as UNICHAR) */
|
||||
typedef UNICHAR UNISTYLE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* lineterm functions */
|
||||
|
||||
/* LTERM module number (used for trace/log operations) */
|
||||
#define LTERM_TLOG_MODULE 1
|
||||
|
||||
/** Initializes all LTERM operations;
|
||||
* needs to be called before any calls to lterm_new.
|
||||
* @return 0 on success, or -1 on error.
|
||||
*
|
||||
* MESSAGELEVEL specifies the diagnostic message display level:
|
||||
* 0 => (normal) only fatal errors cause diagnostic messages to be printed.
|
||||
* -1 => (silent) no diagnostic messages are printed, even for fatal errors.
|
||||
* 1 => (warning) print non-fatal warning messages as well as error messages.
|
||||
* >9 and <= 99 (debugging)
|
||||
* print debugging messages at selected procedure levels/sublevels
|
||||
* (See tracelog.h for more information on messageLevel)
|
||||
*
|
||||
* Returns 0 on successful initialization, -1 otherwise.
|
||||
*/
|
||||
|
||||
int lterm_init(int messageLevel);
|
||||
|
||||
|
||||
/** Creates a new LTERM object and returns its descriptor index but
|
||||
* does not open it for I/O
|
||||
* (documented in the LTERM interface)
|
||||
* @return lterm descriptor index (>= 0) on success, or
|
||||
* -1 on error
|
||||
*/
|
||||
|
||||
int lterm_new();
|
||||
|
||||
/** Opens line terminal indexed by LTERM for input/output and creates
|
||||
* a process attached to it to execute the command line contained in string
|
||||
* array ARGV.
|
||||
* Called from the adminstrative/output thread of LTERM.
|
||||
* @return 0 on success, or -1 on error.
|
||||
*
|
||||
* COOKIE contains a cookie string used for stream security. If it is null,
|
||||
* or a null string, all streams are considered insecure.
|
||||
* (only MAXCOOKIESTR-1 characters of the cookie string are used for checking)
|
||||
*
|
||||
* INIT_COMMAND contains an initialization command string, if any (not echoed)
|
||||
*
|
||||
* PROMPT_REGEXP contains a REGEXP string describing the command prompt.
|
||||
* (**NOTE** For the moment, only a list of prompt delimiters is accepted;
|
||||
* a typical list of prompt delimiters would be "#$%>?")
|
||||
*
|
||||
* OPTIONS is a bitmask controlling the following options:
|
||||
* LTERM_NOCANONICAL_FLAG disable TTY canonical mode
|
||||
* LTERM_NOEDIT_FLAG disable input line editing
|
||||
* LTERM_NOCOMPLETION_FLAG disable command line completion
|
||||
* LTERM_NOMETA_FLAG disable meta input
|
||||
* LTERM_NOMARKUP_FLAG disable HTML/XML element processing in command line
|
||||
* LTERM_NOECHO_FLAG disable TTY echo
|
||||
* LTERM_NOPTY_FLAG do not use pseudo-TTY
|
||||
* LTERM_NONUL_FLAG do not process any NUL characters (discard them)
|
||||
* LTERM_NOLINEWRAP_FLAG disable line wrapping
|
||||
* LTERM_NOEXPORT_FLAG disable export of current environment to new process
|
||||
* LTERM_STDERR_FLAG enable use of separate STDERR
|
||||
* LTERM_PARTLINE_FLAG enable returning of partial line output
|
||||
*
|
||||
* Notes:
|
||||
* -LTERM_STDERR_FLAG, although implemented, does not work properly at all
|
||||
* -LTERM_PARTLINE_FLAG is not yet implemented
|
||||
*
|
||||
* PROCESS_TYPE specifies the subordinate process type, if set to one
|
||||
* of the following:
|
||||
* LTERM_DETERMINE_PROCESS
|
||||
* LTERM_UNKNOWN_PROCESS
|
||||
* LTERM_SH_PROCESS
|
||||
* LTERM_KSH_PROCESS
|
||||
* LTERM_BASH_PROCESS
|
||||
* LTERM_CSH_PROCESS
|
||||
* LTERM_TCSH_PROCESS
|
||||
* If it is set to LTERM_DETERMINE_PROCESS, the process type is determined
|
||||
* from the path name.
|
||||
*
|
||||
* ROWS, COLS contain the initial no. of rows/columns.
|
||||
* X_PIXELS, Y_PIXELS contain the initial screen size in pixels
|
||||
* (may be set to zero if screen size is unknown).
|
||||
*
|
||||
* CALLBACK_FUNC is a pointer to a GTK-style callback function,
|
||||
* or NULL for no callback.
|
||||
* The function is called whenever there is data available for
|
||||
* LTERM_READ to process, with CALLBACK_DATA as the data argument.
|
||||
* The callback function should call LTERM_READ immediately;
|
||||
* otherwise the callback function will be called repeatedly.
|
||||
* (The type LTERM_CALLBACK_FUNC_T is defined at the top of this include file)
|
||||
*
|
||||
* In canonical mode, no input line editing is permitted.
|
||||
* In editing mode, EMACS-style keyboard line editing commands are allowed.
|
||||
* In completion mode, incomplete command/file names are transmitted to
|
||||
* the subordinate process for complettion, as in TCSH.
|
||||
* Meta input refers to input lines that begin with a colon,
|
||||
* or with a "protocol" name followed by a colon, such as
|
||||
* "http: ...".
|
||||
* Meta input lines are not sent to the subordinate process, but simply
|
||||
* echoed as LTERM output through LTERM_READ for further processing.
|
||||
* If command line completion is not disabled, incomplete meta input may
|
||||
* also be echoed for completion. In this case, the completed meta input
|
||||
* should be supplied to the LTERM through a call to LTERM_WRITE as if the
|
||||
* user had entered it.
|
||||
*/
|
||||
|
||||
int lterm_open(int lterm, char *const argv[],
|
||||
const char* cookie, const char* init_command,
|
||||
const UNICHAR* prompt_regexp, int options, int process_type,
|
||||
int rows, int cols, int x_pixels, int y_pixels,
|
||||
lterm_callback_func_t callback_func, void *callback_data);
|
||||
|
||||
|
||||
/** Closes line terminal indexed by LTERM.
|
||||
* The default action is to block until active calls to lterm_write
|
||||
* and lterm_read to complete.
|
||||
* Called from the administrative/output thread of LTERM.
|
||||
* @return 0 on success, or -1 on error.
|
||||
*/
|
||||
int lterm_close(int lterm);
|
||||
|
||||
|
||||
/** Deletes an LTERM object, closing it if necessary.
|
||||
* @return 0 on success, or -1 on error.
|
||||
*/
|
||||
|
||||
int lterm_delete(int lterm);
|
||||
|
||||
|
||||
/** Closes all LTERMs, but does not delete them.
|
||||
* This may be used to free any resources associated with LTERMs for clean up.
|
||||
* The closed LTERMs should still be deleted, if possible.
|
||||
*/
|
||||
void lterm_close_all(void);
|
||||
|
||||
|
||||
/** Set input echo flag for line terminal indexed by LTERM.
|
||||
* Called from the output thread of LTERM.
|
||||
* @return 0 on success, or -1 on error.
|
||||
*/
|
||||
|
||||
int lterm_setecho(int lterm, int echo_flag);
|
||||
|
||||
|
||||
/** Resizes the line terminal indexed by LTERM to new row/column count.
|
||||
* Called from the output thread of LTERM.
|
||||
* @return 0 on success, or -1 on error.
|
||||
*/
|
||||
|
||||
int lterm_resize(int lterm, int rows, int cols);
|
||||
|
||||
|
||||
/** Sets cursor position in line terminal indexed by LTERM.
|
||||
* NOT YET IMPLEMENTED
|
||||
* Row numbers increase upward, starting from 0.
|
||||
* Column numbers increase rightward, starting from 0.
|
||||
* Called from the output thread of LTERM.
|
||||
* @return 0 on success, or -1 on error.
|
||||
*/
|
||||
|
||||
int lterm_setcursor(int lterm, int row, int col);
|
||||
|
||||
|
||||
/** Writes supplied to Unicode string in BUF of length COUNT to
|
||||
* line terminal indexed by LTERM.
|
||||
* (May be called from any thread, since it uses a pipe to communicate
|
||||
* with the output thread.)
|
||||
* DATATYPE may be set to one of the following values:
|
||||
* LTERM_WRITE_PLAIN_INPUT Plain text user input
|
||||
* LTERM_WRITE_XML_INPUT XML element user input
|
||||
* LTERM_WRITE_PLAIN_OUTPUT Plain text server output
|
||||
* LTERM_WRITE_CLOSE_MESSAGE End of file message
|
||||
* NOTE: This is a non-blocking call
|
||||
* Returns the number of characters written.
|
||||
* Returns -1 on error, and
|
||||
* -2 if pseudo-TTY has been closed.
|
||||
* If the return value is less than COUNT, it usually indicates an error.
|
||||
* If the return value is -1, any further operations on the LTERM,
|
||||
* other than LTERM_CLOSE, will always fail with an error return value.
|
||||
*/
|
||||
|
||||
int lterm_write(int lterm, const UNICHAR *buf, int count, int dataType);
|
||||
|
||||
|
||||
/** Completes meta input in line terminal indexed by LTERM with the
|
||||
* supplied to Unicode string in BUF of length COUNT.
|
||||
* Called from the output thread of the LTERM.
|
||||
* @return 0 on success, or -1 on error.
|
||||
*/
|
||||
|
||||
int lterm_metacomplete(int lterm, const UNICHAR *buf, int count);
|
||||
|
||||
|
||||
/** reads upto COUNT Unicode characters from a single line of output
|
||||
* from line terminal indexed by LTERM into BUF.
|
||||
* Called from the output thread of the LTERM.
|
||||
* Returns the number of characters read (>=0) on a successful read.
|
||||
* Returns -1 if an error occurred while reading,
|
||||
* -2 if pseudo-TTY has been closed,
|
||||
* -3 if more than COUNT characters are present in the line
|
||||
* (in this case the first COUNT characters are returned in BUF,
|
||||
* and the rest are discarded).
|
||||
* If the return value is -1, any further operations on the LTERM,
|
||||
* other than LTERM_CLOSE, will always fail with an error return value.
|
||||
* (If return value is -2, it means that the subordinate process has closed
|
||||
* the pseudo-TTY. In this case, the LTERM still needs to be explicitly
|
||||
* closed by calling LTERM_CLOSE for proper clean-up.)
|
||||
*
|
||||
* TIMEOUT is the number of platform-dependent time units
|
||||
* (usually milliseconds on Unix) to wait to read data.
|
||||
* A zero value implies no waiting.
|
||||
* A negative TIMEOUT value implies infinite timeout, i.e., a blocking read.
|
||||
* Non-zero values of TIMEOUT should be used only when the output thread
|
||||
* is allowed to block.
|
||||
*
|
||||
* STYLE should be an array of same length as BUF, and contains
|
||||
* the style bits associated with each character on return (see below).
|
||||
*
|
||||
* OPCODES contains a bit mask describing the type of output (see below).
|
||||
* Using Extended Backus-Naur Form notation:
|
||||
*
|
||||
* OPCODES ::= STREAMDATA NEWLINE? ERROR?
|
||||
* COOKIESTR? DOCSTREAM? XMLSTREAM? JSSTREAM? WINSTREAM?
|
||||
* if StreamMode data is being returned.
|
||||
* (NEWLINE, if set, denotes that the stream has terminated;
|
||||
* if ERROR is also set, it means that the stream has terminated abnormally.)
|
||||
*
|
||||
* OPCODES ::= SCREENDATA BELL? ( OUTPUT | CLEAR | INSERT | DELETE | SCROLL )?
|
||||
* if ScreenMode data is being returned.
|
||||
* If none of the flags OUTPUT ... SCROLL are set in screen mode,
|
||||
* do nothing but position the cursor (and ring the bell, if need be).
|
||||
*
|
||||
* OPCODES ::= LINEDATA BELL? ( CLEAR
|
||||
* | ( PROMPT | OUTPUT)? INPUT ( NEWLINE HIDE? )?
|
||||
* | PROMPT? INPUT META ( COMPLETION | NEWLINE HIDE? )
|
||||
* | PROMPT? OUTPUT NEWLINE? )
|
||||
* if LineMode data is being returned.
|
||||
*
|
||||
* If OPCODES == 0, then it means that no data has been read.
|
||||
*
|
||||
* If the returned OPCODES has META and COMPLETION bits set, then the completed
|
||||
* version of the meta input should be supplied through a call to
|
||||
* LTERM_WRITE, with an input data type, as if the user had typed it.
|
||||
*
|
||||
* BUF_ROW and BUF_COL denote the row and starting column at which to
|
||||
* display the data in BUF.
|
||||
* (BUF_ROW and BUF_COL are not used for CLEAR option in screen/line mode)
|
||||
* In ScreenMode or LineMode, CURSOR_ROW and CURSOR_COL denote the final
|
||||
* cursor position after any data in BUF is displayed.
|
||||
*
|
||||
* The bottom left corner of the screen corresponds to row 0, column 0.
|
||||
* BUF_COL, CURSOR_COL are always >= 0, with 0 denoting the leftmost column.
|
||||
* (BUF_COL is always zero if NOPARTLINE flag is set for LTERM.)
|
||||
* (CURRENT IMPLEMENTATION: BUF_COL is always zero.)
|
||||
* BUF_ROW, CURSOR_ROW are always set to -1 when LTERM is in line mode,
|
||||
* BUF_ROW, CURSOR_ROW are always >=0 when LTERM is in screen mode,
|
||||
* with 0 denoting the bottom row.
|
||||
*
|
||||
* In ScreenMode:
|
||||
* - OUTPUT denotes that a modifed row of data is being returned.
|
||||
* - OPVALS contains the no. of lines to be inserted/deleted,
|
||||
* for INSERT/DELETE/SCROLL operations
|
||||
*
|
||||
*/
|
||||
|
||||
int lterm_read(int lterm, int timeout, UNICHAR *buf, int count,
|
||||
UNISTYLE *style, int *opcodes, int *opvals,
|
||||
int *buf_row, int *buf_col, int *cursor_row, int *cursor_col);
|
||||
|
||||
/* opcodes describing terminal operations:
|
||||
*/
|
||||
#define LTERM_STREAMDATA_CODE 0x0001U /* Stream mode */
|
||||
#define LTERM_SCREENDATA_CODE 0x0002U /* Screen mode */
|
||||
#define LTERM_LINEDATA_CODE 0x0004U /* Line mode */
|
||||
#define LTERM_BELL_CODE 0x0008U /* Ring bell */
|
||||
#define LTERM_CLEAR_CODE 0x0010U /* Clear screen */
|
||||
#define LTERM_INSERT_CODE 0x0020U /* Insert lines above current line */
|
||||
#define LTERM_DELETE_CODE 0x0040U /* Delete lines below current line */
|
||||
#define LTERM_SCROLL_CODE 0x0080U /* Define scrolling region */
|
||||
#define LTERM_INPUT_CODE 0x0100U /* Contains STDIN at end of line */
|
||||
#define LTERM_PROMPT_CODE 0x0200U /* Contains prompt at beginning */
|
||||
#define LTERM_OUTPUT_CODE 0x0400U /* Contains STDOUT/STDERR/ALTOUT */
|
||||
#define LTERM_META_CODE 0x0800U /* Meta input */
|
||||
#define LTERM_COMPLETION_CODE 0x1000U /* Completion requested */
|
||||
#define LTERM_NEWLINE_CODE 0x2000U /* Complete (new) line */
|
||||
#define LTERM_HIDE_CODE 0x4000U /* Hide output */
|
||||
#define LTERM_ERROR_CODE 0x8000U /* Error in output */
|
||||
|
||||
#define LTERM_COOKIESTR_CODE 0x10000U /* Stream prefixed with cookie */
|
||||
#define LTERM_DOCSTREAM_CODE 0x20000U /* Stream contains complete document */
|
||||
#define LTERM_XMLSTREAM_CODE 0x40000U /* Stream contains XML, not HTML */
|
||||
#define LTERM_JSSTREAM_CODE 0x80000U /* Stream contains Javascript */
|
||||
#define LTERM_WINSTREAM_CODE 0x100000U /* Display stream in entire window */
|
||||
|
||||
|
||||
/* LTERM/XTERM 16-bit style mask:
|
||||
* PROMPT, STDIN, STDOUT, STDERR, ALTOUT are mutually exclusive.
|
||||
* The markup styles apply to STDIN/STDOUT/ALTOUT data.
|
||||
* The highlighting styles only apply to STDOUT data.
|
||||
* The VT100 foreground and background styles are not implemented.
|
||||
*/
|
||||
|
||||
#define LTERM_PROMPT_STYLE 0x0001UL /* prompt string */
|
||||
#define LTERM_STDIN_STYLE 0x0002UL /* standard input */
|
||||
#define LTERM_STDOUT_STYLE 0x0004UL /* standard output */
|
||||
#define LTERM_STDERR_STYLE 0x0008UL /* standard error */
|
||||
#define LTERM_ALTOUT_STYLE 0x0010UL /* alternate output */
|
||||
|
||||
#define LTERM_URI_STYLE 0x0020UL /* URI markup */
|
||||
#define LTERM_HTML_STYLE 0x0040UL /* HTML markup */
|
||||
#define LTERM_XML_STYLE 0x0080UL /* XML markup */
|
||||
|
||||
#define LTERM_BOLD_STYLE 0x0100UL /* boldface */
|
||||
#define LTERM_ULINE_STYLE 0x0200UL /* underline */
|
||||
#define LTERM_BLINK_STYLE 0x0400UL /* blink */
|
||||
#define LTERM_INVERSE_STYLE 0x0800UL /* inverse video */
|
||||
|
||||
/* LTERM option flags */
|
||||
#define LTERM_NOCANONICAL_FLAG 0x0001U
|
||||
#define LTERM_NOEDIT_FLAG 0x0002U
|
||||
#define LTERM_NOCOMPLETION_FLAG 0x0004U
|
||||
#define LTERM_NOMETA_FLAG 0x0008U
|
||||
#define LTERM_NOECHO_FLAG 0x0010U
|
||||
#define LTERM_NOMARKUP_FLAG 0x0020U
|
||||
#define LTERM_NOPTY_FLAG 0x0040U
|
||||
#define LTERM_NONUL_FLAG 0x0080U
|
||||
#define LTERM_NOLINEWRAP_FLAG 0x0100U
|
||||
#define LTERM_NOEXPORT_FLAG 0x0200U
|
||||
#define LTERM_STDERR_FLAG 0x0400U
|
||||
#define LTERM_PARTLINE_FLAG 0x0800U
|
||||
|
||||
/* Process type codes */
|
||||
#define LTERM_DETERMINE_PROCESS -1 /* Determine process type from name */
|
||||
#define LTERM_UNKNOWN_PROCESS 0 /* Unknown process type */
|
||||
#define LTERM_SH_PROCESS 1 /* Bourne shell */
|
||||
#define LTERM_KSH_PROCESS 2 /* Korn shell */
|
||||
#define LTERM_BASH_PROCESS 3 /* Bourne Again shell */
|
||||
#define LTERM_CSH_PROCESS 4 /* C shell */
|
||||
#define LTERM_TCSH_PROCESS 5 /* TC shell */
|
||||
|
||||
/* lterm_write data type codes (XML server output not permitted) */
|
||||
#define LTERM_WRITE_PLAIN_INPUT 0 /* Plain text user input */
|
||||
#define LTERM_WRITE_XML_INPUT 1 /* XML element user input */
|
||||
#define LTERM_WRITE_PLAIN_OUTPUT 2 /* Plain text server output */
|
||||
#define LTERM_WRITE_CLOSE_MESSAGE 3 /* End of file message */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LINETERM_H */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,878 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is lineterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License (the "GPL"), in which case
|
||||
* the provisions of the GPL are applicable instead of
|
||||
* those above. If you wish to allow use of your version of this
|
||||
* file only under the terms of the GPL and not to allow
|
||||
* others to use your version of this file under the MPL, indicate
|
||||
* your decision by deleting the provisions above and replace them
|
||||
* with the notice and other provisions required by the GPL.
|
||||
* If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/* ltermInput.c: LTERM PTY input data processing
|
||||
*/
|
||||
|
||||
/* public declarations */
|
||||
#include "lineterm.h"
|
||||
|
||||
/* private declarations */
|
||||
#include "ltermPrivate.h"
|
||||
|
||||
|
||||
static int ltermLineInput(struct lterms *lts, const UNICHAR *buf, int count,
|
||||
int *opcodes);
|
||||
static int ltermMetaInput(struct lterms *lts);
|
||||
static int ltermRequestCompletion(struct lterms *lts, UNICHAR uch);
|
||||
|
||||
|
||||
/** Processes plain text input data and returns
|
||||
* OPCODES ::= LINEDATA ( INPUT ( NEWLINE HIDE? )?
|
||||
* | INPUT META ( COMPLETION | NEWLINE HIDE? ) )
|
||||
* if echoable input data was processed.
|
||||
* (OPCODES is set to zero if raw input data was processed)
|
||||
* Called from ltermWrite
|
||||
* @return 0 on success,
|
||||
* -1 on error, and
|
||||
* -2 if pseudo-TTY has been closed.
|
||||
*/
|
||||
int ltermPlainTextInput(struct lterms *lts,
|
||||
const UNICHAR *buf, int count, int *opcodes)
|
||||
{
|
||||
struct LtermInput *lti = &(lts->ltermInput);
|
||||
int returnCode;
|
||||
|
||||
LTERM_LOG(ltermPlainTextInput,20,
|
||||
("count=%d, lti->inputMode=%d\n", count, lti->inputMode));
|
||||
|
||||
if (lti->inputMode == LTERM0_RAW_MODE) {
|
||||
/* Transmit characters immediately to child process; no buffering */
|
||||
|
||||
LTERM_LOG(ltermPlainTextInput,29,
|
||||
("Raw mode, transmitting %d characters\n",
|
||||
count));
|
||||
|
||||
if (ltermSendData(lts, buf, count) != 0)
|
||||
return -1;
|
||||
|
||||
*opcodes = 0;
|
||||
|
||||
} else {
|
||||
/* Not raw input mode; process line mode input */
|
||||
int processTrailingTab = 0;
|
||||
|
||||
LTERM_LOG(ltermPlainTextInput,21,
|
||||
("Line mode, lts->commandNumber=%d, inputMode=%d\n",
|
||||
lts->commandNumber, lti->inputMode));
|
||||
|
||||
if ((lti->inputMode >= LTERM3_COMPLETION_MODE) &&
|
||||
(lts->commandNumber == 0)) {
|
||||
/* Downgrade input mode */
|
||||
lti->inputMode = LTERM2_EDIT_MODE;
|
||||
|
||||
LTERM_LOG(ltermPlainTextInput,21,
|
||||
("------------ Downgraded input mode=%d\n\n",
|
||||
lti->inputMode));
|
||||
|
||||
} else if ((lti->inputMode < lts->maxInputMode) &&
|
||||
(lts->commandNumber != 0)) {
|
||||
/* Upgrade input mode */
|
||||
int priorInputMode = lti->inputMode;
|
||||
|
||||
/* Set input mode (possibly allowing completion) */
|
||||
lti->inputMode = lts->maxInputMode;
|
||||
|
||||
/* Do not allow command completion without TTY echo */
|
||||
if ( (lts->disabledInputEcho || lts->noTTYEcho) &&
|
||||
(lti->inputMode > LTERM2_EDIT_MODE) )
|
||||
lti->inputMode = LTERM2_EDIT_MODE;
|
||||
|
||||
if ((lti->inputChars > 0) &&
|
||||
(priorInputMode < LTERM3_COMPLETION_MODE) &&
|
||||
(lti->inputMode >= LTERM3_COMPLETION_MODE)) {
|
||||
/* Process prior input TABs before switching to completion mode */
|
||||
int j;
|
||||
|
||||
if ((count == 0) &&
|
||||
(lti->inputCursorGlyph == lti->inputGlyphs) &&
|
||||
(lti->inputGlyphColIndex[lti->inputGlyphs] == lti->inputCols) &&
|
||||
(lti->inputColCharIndex[lti->inputCols] == lti->inputChars) &&
|
||||
(lti->inputLine[lti->inputChars] == U_TAB)) {
|
||||
/* Trailing TAB in prior input; delete it, and process it later */
|
||||
if (ltermDeleteGlyphs(lti, 1) != 0)
|
||||
return -1;
|
||||
processTrailingTab = 1;
|
||||
}
|
||||
|
||||
/* Replace all input TABs with spaces */
|
||||
for (j=0; j < lti->inputChars; j++) {
|
||||
if (lti->inputLine[j] == U_TAB)
|
||||
lti->inputLine[j] = U_SPACE;
|
||||
}
|
||||
}
|
||||
|
||||
LTERM_LOG(ltermPlainTextInput,21,
|
||||
("------------ Upgraded input mode=%d, trailingTab=%d\n\n",
|
||||
lti->inputMode, processTrailingTab));
|
||||
|
||||
}
|
||||
|
||||
if (processTrailingTab) {
|
||||
/* Re-process trailing TAB */
|
||||
UNICHAR uch = U_TAB;
|
||||
|
||||
assert(count == 0);
|
||||
|
||||
LTERM_LOG(ltermPlainTextInput,21,("Reprocessing trailing TAB\n"));
|
||||
|
||||
returnCode= ltermLineInput(lts, &uch, 1, opcodes);
|
||||
if (returnCode < 0)
|
||||
return returnCode;
|
||||
|
||||
} else {
|
||||
/* Process new input characters */
|
||||
returnCode = ltermLineInput(lts, buf, count, opcodes) != 0;
|
||||
if (returnCode < 0)
|
||||
return returnCode;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Cancels a prior command line completion request
|
||||
* @return 0 on success,
|
||||
* -1 on error
|
||||
*/
|
||||
int ltermCancelCompletion(struct lterms *lts)
|
||||
{
|
||||
|
||||
LTERM_LOG(ltermCancelCompletion,40,
|
||||
("++++++++++++ CANCELED COMPLETION REQUEST\n\n"));
|
||||
|
||||
if (lts->completionRequest != LTERM_NO_COMPLETION) {
|
||||
|
||||
/* Kill input line transmitted to process */
|
||||
if (ltermSendData(lts, lts->control+TTYKILL, 1) != 0)
|
||||
return -1;
|
||||
|
||||
lts->completionRequest = LTERM_NO_COMPLETION;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Inserts plain text character UCH as a single-column glyph at the
|
||||
* current input cursor location, translating to escape sequence if needed.
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int ltermInsertChar(struct LtermInput *lti, UNICHAR uch)
|
||||
{
|
||||
UNICHAR* escapeSequence;
|
||||
int insChars, insertColIndex, insertCharIndex, j;
|
||||
|
||||
LTERM_LOG(ltermInsertChar,40,("inserting character 0x%x at glyph %d\n",
|
||||
uch, lti->inputCursorGlyph));
|
||||
|
||||
/* Ignore null character */
|
||||
if (uch == 0)
|
||||
return 0;
|
||||
|
||||
escapeSequence = NULL;
|
||||
insChars = 1;
|
||||
|
||||
#if 0
|
||||
/* COMMENTED OUT: Plain text not escaped; use code later in HTML insert */
|
||||
/* Check if plain text character needs to be escaped for XML/HTML */
|
||||
for (j=0; j<LTERM_PLAIN_ESCAPES; j++) {
|
||||
|
||||
if (uch == ltermGlobal.escapeChars[j]) {
|
||||
/* Insert escape sequence rather than character */
|
||||
escapeSequence = ltermGlobal.escapeSeq[j];
|
||||
insChars = ltermGlobal.escapeLen[j];
|
||||
LTERM_LOG(ltermInsertChar,42,("escape index=%d\n", j));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
if (lti->inputChars+insChars > MAXCOLM1) {
|
||||
/* Input buffer overflow; ignore insert character */
|
||||
LTERM_WARNING("ltermInsertChar: Warning - input line buffer overflow\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(lti->inputChars >= 0);
|
||||
assert(lti->inputCols >= 0);
|
||||
assert(lti->inputGlyphs >= 0);
|
||||
assert(lti->inputCursorGlyph >= 0);
|
||||
|
||||
assert(lti->inputCols <= lti->inputChars);
|
||||
assert(lti->inputGlyphs <= lti->inputCols);
|
||||
|
||||
insertColIndex = lti->inputGlyphColIndex[lti->inputCursorGlyph];
|
||||
insertCharIndex = lti->inputColCharIndex[insertColIndex];
|
||||
|
||||
LTERM_LOG(ltermInsertChar,41,("insertColIndex=%d, insertCharIndex=%d, insChars=%d\n",
|
||||
insertColIndex, insertCharIndex, insChars));
|
||||
|
||||
/* Shift portion of input line to the right;
|
||||
remember that the column/glyph index arrays have an extra element */
|
||||
for (j=lti->inputChars - 1; j >= insertCharIndex; j--)
|
||||
lti->inputLine[j+insChars] = lti->inputLine[j];
|
||||
|
||||
for (j=lti->inputCols; j >= insertColIndex; j--)
|
||||
lti->inputColCharIndex[j+1] = lti->inputColCharIndex[j]+insChars;
|
||||
|
||||
for (j=lti->inputGlyphs; j >= lti->inputCursorGlyph; j--) {
|
||||
lti->inputGlyphCharIndex[j+1] = lti->inputGlyphCharIndex[j]+insChars;
|
||||
lti->inputGlyphColIndex[j+1] = lti->inputGlyphColIndex[j]+1;
|
||||
}
|
||||
|
||||
/* Insert character(s) in input line */
|
||||
if (escapeSequence == NULL) {
|
||||
lti->inputLine[insertCharIndex] = uch;
|
||||
} else {
|
||||
for (j=0; j < insChars; j++)
|
||||
lti->inputLine[j+insertCharIndex] = escapeSequence[j];
|
||||
}
|
||||
|
||||
/* Insert column/glyph */
|
||||
lti->inputColCharIndex[insertColIndex] = insertCharIndex;
|
||||
|
||||
lti->inputGlyphCharIndex[lti->inputCursorGlyph] = insertCharIndex;
|
||||
lti->inputGlyphColIndex[lti->inputCursorGlyph] = insertColIndex;
|
||||
|
||||
lti->inputChars += insChars; /* Increment character count */
|
||||
|
||||
lti->inputCols++; /* Increment column count */
|
||||
|
||||
lti->inputGlyphs++; /* Increment glyph count */
|
||||
|
||||
lti->inputCursorGlyph++; /* Reposition cursor */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** switches to raw input mode */
|
||||
void ltermSwitchToRawMode(struct lterms *lts)
|
||||
{
|
||||
struct LtermInput *lti = &(lts->ltermInput);
|
||||
|
||||
LTERM_LOG(ltermSwitchToRawMode,40,("\n"));
|
||||
|
||||
if (lti->inputMode != LTERM0_RAW_MODE) {
|
||||
/* Do other things ... */
|
||||
lti->inputMode = LTERM0_RAW_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** clears input line buffer and switches to regular input mode */
|
||||
void ltermClearInputLine(struct lterms *lts)
|
||||
{
|
||||
struct LtermInput *lti = &(lts->ltermInput);
|
||||
|
||||
LTERM_LOG(ltermClearInputLine,40,("\n"));
|
||||
|
||||
lti->inputChars = 0;
|
||||
|
||||
lti->inputCols = 0;
|
||||
lti->inputColCharIndex[0] = 0;
|
||||
|
||||
lti->inputGlyphs = 0;
|
||||
lti->inputGlyphCharIndex[0] = 0;
|
||||
lti->inputGlyphColIndex[0] = 0;
|
||||
|
||||
lti->inputCursorGlyph = 0;
|
||||
|
||||
if (lts->maxInputMode >= LTERM2_EDIT_MODE)
|
||||
lti->inputMode = LTERM2_EDIT_MODE;
|
||||
else
|
||||
lti->inputMode = lts->maxInputMode;
|
||||
|
||||
lti->escapeFlag = 0;
|
||||
lti->escapeCSIFlag = 0;
|
||||
lti->escapeCSIArg = 0;
|
||||
}
|
||||
|
||||
|
||||
/** Processes an input string in canonical or higher mode and returns
|
||||
* OPCODES ::= LINEDATA ( INPUT (NEWLINE HIDE?)?
|
||||
* | INPUT META (COMPLETION|NEWLINE HIDE?) )
|
||||
* if echoable input data was processed.
|
||||
* (OPCODES is set to zero if raw input data was processed)
|
||||
* Called from ltermPlainTextInput
|
||||
* @return 0 on success,
|
||||
* -1 on error, and
|
||||
* -2 if pseudo-TTY has been closed.
|
||||
*/
|
||||
static int ltermLineInput(struct lterms *lts,
|
||||
const UNICHAR *buf, int count, int *opcodes)
|
||||
{
|
||||
struct LtermInput *lti = &(lts->ltermInput);
|
||||
UNICHAR uch;
|
||||
int charIndex, metaInput;
|
||||
|
||||
/* Default returned opcodes (maybe overridden) */
|
||||
*opcodes = LTERM_LINEDATA_CODE | LTERM_INPUT_CODE;
|
||||
|
||||
charIndex = 0;
|
||||
|
||||
LTERM_LOG(ltermLineInput,30,
|
||||
("count=%d, lti->inputMode=%d, inputCursorGlyph=%d\n",
|
||||
count, lti->inputMode, lti->inputCursorGlyph));
|
||||
LTERM_LOGUNICODE(ltermLineInput,31,(buf, count));
|
||||
LTERM_LOG(ltermLineInput,31,("Glyphs=%d,Cols=%d,Chars=%d\n",
|
||||
lti->inputGlyphs, lti->inputCols, lti->inputChars));
|
||||
|
||||
while (charIndex < count) {
|
||||
uch = buf[charIndex];
|
||||
|
||||
if (uch == U_ESCAPE) {
|
||||
/* Escape */
|
||||
lti->escapeFlag = 1;
|
||||
uch = U_NUL;
|
||||
|
||||
} else if (lti->escapeFlag) {
|
||||
/* Escaped character */
|
||||
lti->escapeFlag = 0;
|
||||
|
||||
switch (uch) {
|
||||
|
||||
case U_LBRACKET:
|
||||
/* Start of escape code sequence */
|
||||
lti->escapeCSIFlag = 1;
|
||||
lti->escapeCSIArg = 0;
|
||||
uch = U_NUL;
|
||||
break;
|
||||
|
||||
default:
|
||||
uch = U_NUL;
|
||||
}
|
||||
|
||||
} else if (lti->escapeCSIFlag) {
|
||||
/* Character part of escape code sequence */
|
||||
|
||||
LTERM_LOG(ltermLineInput,38,("Escape code sequence - 0x%x\n", uch));
|
||||
|
||||
if ((uch >= (UNICHAR)U_ZERO && uch <= (UNICHAR)U_NINE)) {
|
||||
/* Process numerical argument to escape code sequence */
|
||||
lti->escapeCSIArg = lti->escapeCSIArg*10 + (uch - U_ZERO);
|
||||
uch = U_NUL;
|
||||
|
||||
} else {
|
||||
/* End of escape code sequence */
|
||||
lti->escapeCSIFlag = 0;
|
||||
|
||||
/* NOTE: Input CSI escape sequence; may not be portable */
|
||||
|
||||
/* SUN arrow key bindings */
|
||||
switch (uch) {
|
||||
case U_A_CHAR:
|
||||
uch = U_CTL_P;
|
||||
break;
|
||||
case U_B_CHAR:
|
||||
uch = U_CTL_N;
|
||||
break;
|
||||
case U_C_CHAR:
|
||||
uch = U_CTL_F;
|
||||
break;
|
||||
case U_D_CHAR:
|
||||
uch = U_CTL_B;
|
||||
break;
|
||||
default:
|
||||
uch = U_NUL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ((uch >= (UNICHAR)U_SPACE) && (uch != (UNICHAR)U_DEL)) ||
|
||||
((uch == (UNICHAR)U_TAB) && (lti->inputMode <= LTERM2_EDIT_MODE)) ) {
|
||||
/* printable character or non-completion mode TAB; insert in buffer */
|
||||
/* (NEED TO UPDATE THIS CHECK FOR UNICODE PRINTABILITY) */
|
||||
|
||||
LTERM_LOG(ltermLineInput,39,("inserting printable character - %c\n",
|
||||
(char) uch));
|
||||
|
||||
/* Insert character */
|
||||
if (ltermInsertChar(lti, uch) != 0)
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
/* Control character */
|
||||
|
||||
/* Translate carriage returns to linefeeds in line mode
|
||||
(***NOTE*** may not be portable out of *nix) */
|
||||
if (uch == U_CRETURN)
|
||||
uch = U_LINEFEED;
|
||||
|
||||
/* Line break control characters */
|
||||
if ( (uch == U_LINEFEED) ||
|
||||
(uch == lts->control[TTYDISCARD]) ||
|
||||
(uch == lts->control[TTYSUSPEND]) ||
|
||||
(uch == lts->control[TTYINTERRUPT])) {
|
||||
/* Newline/TTYdiscard/TTYsuspend/TTYinterrupt character */
|
||||
|
||||
/* Assert that linebreak character occurs at end of buffer;
|
||||
* enforced by lterm_write.
|
||||
*/
|
||||
assert(charIndex == count-1);
|
||||
|
||||
/* Check if meta input line */
|
||||
metaInput = ltermMetaInput(lts);
|
||||
|
||||
if ((uch == lts->control[TTYDISCARD]) && !metaInput
|
||||
&& (lts->commandNumber == 0)) {
|
||||
/* Not meta/command line; simply transmit discard character */
|
||||
if (ltermSendData(lts, lts->control+TTYDISCARD, 1) != 0)
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
/* Newline behaviour, with hide option */
|
||||
LTERM_LOG(ltermLineInput,31,("------------ NEWLINE (0x%x)\n\n",
|
||||
uch));
|
||||
LTERM_LOGUNICODE(ltermLineInput,31,( lti->inputLine,
|
||||
lti->inputChars));
|
||||
|
||||
/* The NEWLINE code tells ltermReturnInputLine to clear
|
||||
* the input line buffer after copying it
|
||||
*/
|
||||
*opcodes = LTERM_LINEDATA_CODE | LTERM_INPUT_CODE
|
||||
| LTERM_NEWLINE_CODE;
|
||||
|
||||
if (uch == lts->control[TTYDISCARD]) {
|
||||
*opcodes |= LTERM_HIDE_CODE;
|
||||
uch = U_LINEFEED; /* essentially newline behaviour otherwise */
|
||||
}
|
||||
|
||||
if (uch == lts->control[TTYINTERRUPT]) {
|
||||
/* Interrupt output operations, if necessary */
|
||||
if (ltermInterruptOutput(lts) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (metaInput) {
|
||||
/* meta input; do not send line */
|
||||
*opcodes |= LTERM_META_CODE;
|
||||
} else {
|
||||
/* Send line and copy to echo buffer */
|
||||
if (ltermSendLine(lts, uch, (uch != U_LINEFEED),
|
||||
LTERM_NO_COMPLETION) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if (uch == lts->control[TTYKILL]) {
|
||||
/* kill line */
|
||||
ltermClearInputLine(lts);
|
||||
|
||||
LTERM_LOG(ltermLineInput,31,("TTYKILL\n"));
|
||||
|
||||
} else if ((uch == U_BACKSPACE) || (uch == U_DEL) ||
|
||||
(uch == lts->control[TTYERASE])) {
|
||||
/* erase glyph */
|
||||
if (ltermDeleteGlyphs(lti, 1) != 0)
|
||||
return -1;
|
||||
|
||||
LTERM_LOG(ltermLineInput,39,("TTYERASE=0x%x/0x%x\n",
|
||||
lts->control[TTYERASE], uch ));
|
||||
|
||||
} else {
|
||||
/* other control characters */
|
||||
|
||||
LTERM_LOG(ltermLineInput,32,("^%c\n", uch+U_ATSIGN));
|
||||
|
||||
if (lti->inputMode < LTERM2_EDIT_MODE) {
|
||||
/* Non-edit mode; simply transmit control character */
|
||||
if (ltermSendData(lts, &uch, 1) != 0)
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
/* Edit input mode */
|
||||
|
||||
if (uch == U_CTL_D) {
|
||||
/* Special handling for ^D */
|
||||
|
||||
if (lti->inputChars == 0) {
|
||||
/* Lone ^D in input line, simply transmit it */
|
||||
if (ltermSendData(lts, &uch, 1) != 0)
|
||||
return -1;
|
||||
uch = U_NUL;
|
||||
|
||||
} else if (lti->inputCursorGlyph < lti->inputGlyphs) {
|
||||
/* Cursor not at end of line; delete to right */
|
||||
if (ltermDeleteGlyphs(lti, -1) != 0)
|
||||
return -1;
|
||||
uch = U_NUL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (uch) {
|
||||
|
||||
case U_NUL: /* Null character; ignore */
|
||||
break;
|
||||
|
||||
case U_CTL_B: /* move cursor backward */
|
||||
if (lti->inputCursorGlyph > 0) {
|
||||
lti->inputCursorGlyph--;
|
||||
}
|
||||
break;
|
||||
|
||||
case U_CTL_F: /* move cursor forward */
|
||||
if (lti->inputCursorGlyph < lti->inputGlyphs) {
|
||||
lti->inputCursorGlyph++;
|
||||
}
|
||||
break;
|
||||
|
||||
case U_CTL_A: /* position cursor at beginning of line */
|
||||
lti->inputCursorGlyph = 0;
|
||||
break;
|
||||
|
||||
case U_CTL_E: /* position cursor at end of line */
|
||||
lti->inputCursorGlyph = lti->inputGlyphs;
|
||||
break;
|
||||
|
||||
case U_CTL_K: /* delete to end of line */
|
||||
if (ltermDeleteGlyphs(lti,-(lti->inputGlyphs-lti->inputCursorGlyph))
|
||||
!= 0)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case U_CTL_L: /* form feed */
|
||||
case U_CTL_R: /* redisplay */
|
||||
break;
|
||||
|
||||
case U_CTL_D: /* ^D at end of non-null input line */
|
||||
case U_CTL_N: /* dowN history */
|
||||
case U_CTL_P: /* uP history */
|
||||
case U_CTL_Y: /* yank */
|
||||
case U_TAB: /* command completion */
|
||||
|
||||
/* Assert that completion character occurs at end of buffer;
|
||||
* enforced by lterm_write.
|
||||
*/
|
||||
assert(charIndex == count-1);
|
||||
|
||||
metaInput = ltermMetaInput(lts);
|
||||
|
||||
if (metaInput) {
|
||||
/* Meta input command completion */
|
||||
LTERM_LOG(ltermLineInput,40,
|
||||
("++++++++++++ meta COMPLETION uch=0x%X\n\n", uch));
|
||||
if (uch == U_TAB) {
|
||||
*opcodes = LTERM_LINEDATA_CODE | LTERM_INPUT_CODE
|
||||
| LTERM_META_CODE
|
||||
| LTERM_COMPLETION_CODE;
|
||||
} else {
|
||||
LTERM_WARNING("ltermLineInput: Warning - meta command completion not yet implemented for uch=0x%x\n", uch);
|
||||
}
|
||||
|
||||
} else if (lti->inputMode >= LTERM3_COMPLETION_MODE) {
|
||||
/* Completion mode; non-completion TABs already processed */
|
||||
|
||||
if (ltermRequestCompletion(lts, uch) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default: /* Transmit any other control character */
|
||||
if (ltermSendData(lts, &uch, 1) != 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Increment character index */
|
||||
charIndex++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Check if input line contains a meta delimiter;
|
||||
* @return 1 if it does, 0 otherwise.
|
||||
*/
|
||||
static int ltermMetaInput(struct lterms *lts)
|
||||
{
|
||||
struct LtermInput *lti = &(lts->ltermInput);
|
||||
UNICHAR *delimLoc, *ustr, *ustr2;
|
||||
|
||||
LTERM_LOG(ltermMetaInput,40,("\n"));
|
||||
|
||||
if (lts->options & LTERM_NOMETA_FLAG)
|
||||
return 0;
|
||||
|
||||
/* Assert that there is at least one free character position in the buffer */
|
||||
assert(lti->inputChars < MAXCOL);
|
||||
|
||||
/* Insert null character at the end of the input buffer */
|
||||
lti->inputLine[lti->inputChars] = U_NUL;
|
||||
|
||||
/* Locate first occurrence of meta delimiter in input line */
|
||||
delimLoc = ucschr(lti->inputLine, ltermGlobal.metaDelimiter);
|
||||
|
||||
if (delimLoc == NULL)
|
||||
return 0;
|
||||
|
||||
for (ustr=lti->inputLine; ustr<delimLoc; ustr++) /* skip spaces/TABs */
|
||||
if ((*ustr != U_SPACE) && (*ustr != U_TAB)) break;
|
||||
|
||||
if (ustr == delimLoc) {
|
||||
/* Nameless meta command */
|
||||
LTERM_LOG(ltermMetaInput,41,("Nameless meta command\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!IS_ASCII_LETTER(*ustr)) /* meta command must start with a letter */
|
||||
return 0;
|
||||
|
||||
for (ustr2=ustr+1; ustr2<delimLoc; ustr2++)
|
||||
if (!IS_ASCII_LETTER(*ustr2) && !IS_ASCII_DIGIT(*ustr2))
|
||||
return 0;
|
||||
|
||||
LTERM_LOG(ltermMetaInput,41,("Named meta command\n"));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/** Requests command line completion from process corresponding to
|
||||
* control character UCH.
|
||||
* @return 0 on success,
|
||||
* -1 on error
|
||||
*/
|
||||
static int ltermRequestCompletion(struct lterms *lts, UNICHAR uch)
|
||||
{
|
||||
LTERM_LOG(ltermRequestCompletion,40,
|
||||
("++++++++++++ COMPLETION REQUEST uch=0x%X\n\n", uch));
|
||||
|
||||
switch (uch) {
|
||||
case U_TAB:
|
||||
/* Send line and copy to echo buffer */
|
||||
if (ltermSendLine(lts, uch, 0, LTERM_TAB_COMPLETION) != 0)
|
||||
return -1;
|
||||
break;
|
||||
case U_CTL_P:
|
||||
case U_CTL_N:
|
||||
/* Send line and copy to echo buffer */
|
||||
if (ltermSendLine(lts, uch, 0, LTERM_HISTORY_COMPLETION) != 0)
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
LTERM_WARNING("ltermCompletionRequest: Warning - command completion not yet implemented for uch=0x%x\n", uch);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Deletes glyphs from the input line.
|
||||
* If COUNT > 0, glyphs are deleted to the left of the cursor.
|
||||
* If COUNT < 0, glyphs are deleted to the right of the cursor.
|
||||
* Called from ltermLineInput.
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int ltermDeleteGlyphs(struct LtermInput *lti, int count)
|
||||
{
|
||||
int leftGlyph, leftColIndex, leftCharIndex;
|
||||
int rightGlyph, rightColIndex, rightCharIndex;
|
||||
int deleteGlyphs, deleteCols, deleteChars, j;
|
||||
|
||||
LTERM_LOG(ltermDeleteGlyphs,40,("deleting %d glyphs from glyph %d\n",
|
||||
count, lti->inputCursorGlyph));
|
||||
|
||||
if (count >= 0) {
|
||||
/* Delete to the left */
|
||||
deleteGlyphs = count;
|
||||
|
||||
/* Limit the number of glyphs deleted to that present to the left */
|
||||
if (deleteGlyphs > lti->inputCursorGlyph)
|
||||
deleteGlyphs = lti->inputCursorGlyph;
|
||||
|
||||
rightGlyph = lti->inputCursorGlyph;
|
||||
leftGlyph = rightGlyph - deleteGlyphs;
|
||||
|
||||
} else {
|
||||
/* Delete to the right */
|
||||
deleteGlyphs = -count;
|
||||
|
||||
/* Limit the number of glyphs deleted to that present to the right */
|
||||
if (deleteGlyphs > (lti->inputGlyphs - lti->inputCursorGlyph))
|
||||
deleteGlyphs = lti->inputGlyphs - lti->inputCursorGlyph;
|
||||
|
||||
leftGlyph = lti->inputCursorGlyph;
|
||||
rightGlyph = leftGlyph + deleteGlyphs;
|
||||
}
|
||||
|
||||
leftColIndex = lti->inputGlyphColIndex[leftGlyph];
|
||||
leftCharIndex = lti->inputGlyphCharIndex[leftGlyph];
|
||||
|
||||
rightColIndex = lti->inputGlyphColIndex[rightGlyph];
|
||||
rightCharIndex = lti->inputGlyphCharIndex[rightGlyph];
|
||||
|
||||
deleteCols = rightColIndex - leftColIndex;
|
||||
deleteChars = rightCharIndex - leftCharIndex;
|
||||
|
||||
LTERM_LOG(ltermDeleteGlyphs,41,("deleteCols=%d, deleteChars=%d\n",
|
||||
deleteCols, deleteChars));
|
||||
|
||||
LTERM_LOG(ltermDeleteGlyphs,42,("leftGlyph=%d, leftCol=%d, leftChar=%d\n",
|
||||
leftGlyph, leftColIndex, leftCharIndex));
|
||||
|
||||
LTERM_LOG(ltermDeleteGlyphs,42,("rightGlyph=%d, rightCol=%d, rightChar=%d\n",
|
||||
rightGlyph, rightColIndex, rightCharIndex));
|
||||
|
||||
/* Shift portion of input line to the left;
|
||||
remember that the column/glyph index arrays have an extra element */
|
||||
for (j = leftCharIndex; j < lti->inputChars-deleteChars; j++)
|
||||
lti->inputLine[j] = lti->inputLine[j+deleteChars];
|
||||
|
||||
for (j = leftColIndex; j <= lti->inputCols-deleteCols; j++)
|
||||
lti->inputColCharIndex[j] = lti->inputColCharIndex[j+deleteCols]
|
||||
- deleteChars;
|
||||
|
||||
for (j = leftGlyph; j <= lti->inputGlyphs-deleteGlyphs; j++)
|
||||
lti->inputGlyphColIndex[j] = lti->inputGlyphColIndex[j+deleteGlyphs]
|
||||
- deleteCols;
|
||||
|
||||
lti->inputChars -= deleteChars; /* Decrement character count */
|
||||
|
||||
lti->inputCols -= deleteCols; /* Decrement column count */
|
||||
|
||||
lti->inputGlyphs -= deleteGlyphs; /* Decrement glyph count */
|
||||
|
||||
if (count > 0)
|
||||
lti->inputCursorGlyph -= deleteGlyphs; /* Reposition glyph cursor */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Transmits COUNT Unicode characters from BUF to child process
|
||||
* after translating Unicode to UTF8 or Latin1, as appropriate.
|
||||
* The data is transmitted in smallish chunks so as not to overflow the
|
||||
* PTY input buffer.
|
||||
* @return 0 on successful write, -1 on error.
|
||||
*/
|
||||
int ltermSendData(struct lterms *lts, const UNICHAR *buf, int count)
|
||||
{
|
||||
char ch, ptyBuf[MAXPTYIN];
|
||||
int remainingChars, chunkSize, success;
|
||||
|
||||
assert(lts != NULL);
|
||||
assert(count >= 0);
|
||||
|
||||
LTERM_LOG(ltermSendData,40,("count=%d\n", count));
|
||||
LTERM_LOGUNICODE(ltermSendData,41,(buf, count));
|
||||
|
||||
if ((count == 1) && (*buf < 0x80)) {
|
||||
/* Optimized code to transmit single ASCII character */
|
||||
ch = (char) *buf;
|
||||
|
||||
if (lts->ptyMode)
|
||||
#ifndef USE_NSPR_IO
|
||||
success = (write(lts->pty.ptyFD, &ch, 1) == 1);
|
||||
#else
|
||||
assert(0);
|
||||
#endif
|
||||
else
|
||||
success = (WRITE(lts->ltermProcess.processIN, &ch, 1) == 1);
|
||||
|
||||
if (!success) {
|
||||
#if defined(DEBUG_LTERM) && !defined(USE_NSPR_IO)
|
||||
int errcode = errno;
|
||||
perror("ltermSendData");
|
||||
#else
|
||||
int errcode = 0;
|
||||
#endif
|
||||
LTERM_ERROR("ltermSendData: Error %d in writing to child STDIN\n",
|
||||
errcode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
remainingChars = count;
|
||||
while (remainingChars > 0) {
|
||||
/* Convert Unicode to UTF8 */
|
||||
ucstoutf8(&buf[count-remainingChars], remainingChars,
|
||||
ptyBuf, MAXPTYIN,
|
||||
&remainingChars, &chunkSize);
|
||||
|
||||
assert(chunkSize > 0);
|
||||
|
||||
LTERM_LOG(ltermSendData,42,("remainingChars=%d, chunkSize=%d\n",
|
||||
remainingChars, chunkSize));
|
||||
|
||||
/* Send UTF8 to process */
|
||||
if (ltermSendChar(lts, ptyBuf, chunkSize) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Transmits COUNT characters from BUF to child process.
|
||||
* @return 0 on successful write, -1 on error.
|
||||
*/
|
||||
int ltermSendChar(struct lterms *lts, const char *buf, int count)
|
||||
{
|
||||
int success;
|
||||
|
||||
LTERM_LOG(ltermSendChar,50,("count=%d\n", count));
|
||||
|
||||
if (lts->ptyMode)
|
||||
#ifndef USE_NSPR_IO
|
||||
success = (write(lts->pty.ptyFD, buf,
|
||||
(SIZE_T) count) == count);
|
||||
#else
|
||||
assert(0);
|
||||
#endif
|
||||
else
|
||||
success = (WRITE(lts->ltermProcess.processIN, buf,
|
||||
(SIZE_T) count) == count);
|
||||
|
||||
if (!success) {
|
||||
#if defined(DEBUG_LTERM) && !defined(USE_NSPR_IO)
|
||||
int errcode = errno;
|
||||
perror("ltermSendChar");
|
||||
#else
|
||||
int errcode = 0;
|
||||
#endif
|
||||
LTERM_ERROR("ltermSendChar: Error %d in writing to child STDIN\n",
|
||||
errcode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,971 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is lineterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License (the "GPL"), in which case
|
||||
* the provisions of the GPL are applicable instead of
|
||||
* those above. If you wish to allow use of your version of this
|
||||
* file only under the terms of the GPL and not to allow
|
||||
* others to use your version of this file under the MPL, indicate
|
||||
* your decision by deleting the provisions above and replace them
|
||||
* with the notice and other provisions required by the GPL.
|
||||
* If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/* ltermOutput.c: LTERM PTY output processing
|
||||
*/
|
||||
|
||||
/* public declarations */
|
||||
#include "lineterm.h"
|
||||
|
||||
/* private declarations */
|
||||
#include "ltermPrivate.h"
|
||||
|
||||
|
||||
static int ltermAppendOutput(struct lterms *lts, const char *cbuf, int count,
|
||||
UNISTYLE style, int interleaveCheck,
|
||||
int *interleavedBytes, int rawIncompleteMax,
|
||||
int *rawIncompleteBytes, char *rawIncompleteBuf);
|
||||
static int ltermDecode(const char *rawBuf, int n_total,
|
||||
UNICHAR* decodedBuf, int decodeMax,
|
||||
int decodeNUL,
|
||||
int *rawIncompleteBytes);
|
||||
static int ltermPromptLocate(struct lterms *lts);
|
||||
|
||||
|
||||
/** Processes output from decoded output buffer and returns *opcodes:
|
||||
* OPCODES ::= SCREENDATA BELL? ( CLEAR | INSERT | DELETE | SCROLL )?
|
||||
* if ScreenMode data is being returned.
|
||||
* OPCODES ::= LINEDATA BELL? ( CLEAR
|
||||
* | OUTPUT NEWLINE?)
|
||||
* if LineMode data is being returned.
|
||||
* OPVALS contains return value(s) for specific screen operations
|
||||
* such as INSERT, DELETE, and SCROLL.
|
||||
* OPROW contains the row value for specific screen operations such as
|
||||
* INSERT, DELETE, and SCROLL (or -1, cursor row is to be used).
|
||||
* @return 0 on success and -1 on error.
|
||||
*/
|
||||
int ltermProcessOutput(struct lterms *lts, int *opcodes, int *opvals,
|
||||
int *oprow)
|
||||
{
|
||||
struct LtermOutput *lto = &(lts->ltermOutput);
|
||||
UNICHAR uch;
|
||||
UNISTYLE ustyle;
|
||||
int charIndex, returnCode, consumedChars, remainingChars, j;
|
||||
int bellFlag;
|
||||
|
||||
LTERM_LOG(ltermProcessOutput,30,("lto->outputMode=%d, cursorChar=%d, Chars=%d\n",
|
||||
lto->outputMode, lto->outputCursorChar, lto->outputChars));
|
||||
|
||||
LTERM_LOG(ltermProcessOutput,32, ("lts->commandNumber=%d\n",
|
||||
lts->commandNumber));
|
||||
|
||||
/* Set default returned opcodes, opvals, oprow */
|
||||
*opcodes = 0;
|
||||
*opvals = 0;
|
||||
*oprow = -1;
|
||||
|
||||
charIndex = 0;
|
||||
bellFlag = 0;
|
||||
|
||||
while ((*opcodes == 0) && (charIndex < lto->decodedChars)) {
|
||||
uch = lto->decodedOutput[charIndex];
|
||||
ustyle = lto->decodedStyle[charIndex] | lto->styleMask;
|
||||
|
||||
consumedChars = 1;
|
||||
|
||||
if (uch == U_ESCAPE) {
|
||||
/* Process escape sequence */
|
||||
int savedOutputMode = lto->outputMode;
|
||||
|
||||
LTERM_LOG(ltermProcessOutput,31,("ESCAPE sequence\n"));
|
||||
|
||||
returnCode = ltermProcessEscape(lts, lto->decodedOutput+charIndex,
|
||||
lto->decodedChars-charIndex,
|
||||
lto->decodedStyle+charIndex,
|
||||
&consumedChars, opcodes, opvals, oprow);
|
||||
if (returnCode < 0)
|
||||
return -1;
|
||||
|
||||
if (returnCode == 1) {
|
||||
/* Incomplete escape sequence */
|
||||
lto->incompleteEscapeSequence = 1;
|
||||
if (lto->outputMode == LTERM1_SCREEN_MODE)
|
||||
*opcodes = LTERM_SCREENDATA_CODE;
|
||||
else
|
||||
*opcodes = LTERM_LINEDATA_CODE | LTERM_OUTPUT_CODE;
|
||||
}
|
||||
|
||||
/* Assert that change in output mode is a loop terminating condition */
|
||||
if (lto->outputMode != savedOutputMode)
|
||||
assert(*opcodes != 0);
|
||||
|
||||
} else if (lto->outputMode == LTERM1_SCREEN_MODE) {
|
||||
/* Screen mode processing */
|
||||
|
||||
if ((uch >= (UNICHAR)U_SPACE) && (uch != (UNICHAR)U_DEL)) {
|
||||
/* Printable non-TAB character */
|
||||
|
||||
LTERM_LOG(ltermProcessOutput,39,("Screen mode, printable char - %c\n",
|
||||
(char) uch));
|
||||
|
||||
if (lto->insertMode) {
|
||||
/* Insert blank character at cursor position */
|
||||
if (ltermInsDelEraseChar(lts, 1, LTERM_INSERT_ACTION) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Mark column as being modified */
|
||||
if ((lto->modifiedCol[lto->cursorRow] == -1) ||
|
||||
(lto->modifiedCol[lto->cursorRow] > lto->cursorCol))
|
||||
lto->modifiedCol[lto->cursorRow] = lto->cursorCol;
|
||||
|
||||
/* Replace character and style info at current cursor location */
|
||||
j = lto->cursorRow*lts->nCols + lto->cursorCol;
|
||||
|
||||
assert(j < (lts->nRows * lts->nCols));
|
||||
|
||||
lto->screenChar[j] = uch;
|
||||
lto->screenStyle[j] = ustyle;
|
||||
|
||||
if (lto->cursorCol < lts->nCols-1) {
|
||||
/* Move cursor right */
|
||||
lto->cursorCol++;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Control character */
|
||||
|
||||
switch (uch) {
|
||||
case U_BACKSPACE: /* Backspace */
|
||||
LTERM_LOG(ltermProcessOutput,32,("Screen mode, BACKSPACE\n"));
|
||||
if (lto->cursorCol > 0)
|
||||
lto->cursorCol--;
|
||||
break;
|
||||
|
||||
case U_TAB: /* Tab */
|
||||
LTERM_LOG(ltermProcessOutput,32,("Screen mode, TAB\n"));
|
||||
lto->cursorCol = ((lto->cursorCol/8)+1)*8;
|
||||
if (lto->cursorCol > lts->nCols-1)
|
||||
lto->cursorCol = lts->nCols-1;
|
||||
break;
|
||||
|
||||
case U_BEL: /* Bell */
|
||||
LTERM_LOG(ltermProcessOutput,32,("************ Screen mode, BELL\n"));
|
||||
bellFlag = 1;
|
||||
break;
|
||||
|
||||
case U_CRETURN: /* Carriage return */
|
||||
lto->cursorCol = 0;
|
||||
break;
|
||||
|
||||
case U_LINEFEED: /* Newline */
|
||||
LTERM_LOG(ltermProcessOutput,32,("************ Screen mode, NEWLINE\n\n"));
|
||||
|
||||
*opcodes = LTERM_SCREENDATA_CODE;
|
||||
|
||||
if (lto->cursorRow > lto->botScrollRow) {
|
||||
/* Not bottom scrolling line; simply move cursor down one row */
|
||||
lto->cursorRow--;
|
||||
|
||||
} else {
|
||||
/* Delete top scrollable line, scrolling up */
|
||||
if (ltermInsDelEraseLine(lts, 1, lto->topScrollRow, LTERM_DELETE_ACTION) != 0)
|
||||
return -1;
|
||||
*opcodes |= LTERM_DELETE_CODE;
|
||||
*opvals = 1;
|
||||
*oprow = lto->topScrollRow;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Ignore other control characters (including NULs) */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Line mode processing */
|
||||
|
||||
if ( ((uch >= (UNICHAR)U_SPACE) && (uch != (UNICHAR)U_DEL)) ||
|
||||
(uch == (UNICHAR)U_TAB)) {
|
||||
/* Printable/TAB character; replace/insert at current cursor location
|
||||
or append to end of line */
|
||||
|
||||
LTERM_LOG(ltermProcessOutput,39,("Line mode, printable char - %c\n",
|
||||
(char) uch));
|
||||
|
||||
if (lto->outputCursorChar == lto->outputChars) {
|
||||
/* Append single character to end of line */
|
||||
|
||||
if (lto->outputChars+1 > MAXCOLM1) {
|
||||
/* Output buffer overflow; ignore character */
|
||||
LTERM_WARNING("ltermProcessOutput: Warning - output line buffer overflow\n");
|
||||
}
|
||||
|
||||
lto->outputLine[lto->outputChars] = uch;
|
||||
lto->outputStyle[lto->outputChars] = ustyle;
|
||||
lto->outputChars++; /* Insert character in output line */
|
||||
|
||||
lto->outputCursorChar++; /* Reposition cursor */
|
||||
|
||||
} else {
|
||||
/* Replace/insert single character in the middle of line */
|
||||
|
||||
if (lto->insertMode) {
|
||||
/* Insert blank character at cursor position */
|
||||
if (ltermInsDelEraseChar(lts, 1, LTERM_INSERT_ACTION) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Overwrite single character in the middle of line */
|
||||
lto->outputLine[lto->outputCursorChar] = uch;
|
||||
lto->outputStyle[lto->outputCursorChar] = ustyle;
|
||||
|
||||
/* Note modifications */
|
||||
if (lto->outputCursorChar < lto->outputModifiedChar)
|
||||
lto->outputModifiedChar = lto->outputCursorChar;
|
||||
|
||||
lto->outputCursorChar++; /* Reposition cursor */
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Control character */
|
||||
|
||||
switch (uch) {
|
||||
case U_BACKSPACE: /* Backspace */
|
||||
LTERM_LOG(ltermProcessOutput,32,("Line mode, BACKSPACE\n"));
|
||||
if (lto->outputCursorChar > 0)
|
||||
lto->outputCursorChar--;
|
||||
break;
|
||||
|
||||
case U_CRETURN: /* Carriage return */
|
||||
LTERM_LOG(ltermProcessOutput,32,("Line mode, CRETURN\n"));
|
||||
lto->outputCursorChar = 0;
|
||||
break;
|
||||
|
||||
case U_BEL: /* Bell */
|
||||
LTERM_LOG(ltermProcessOutput,32,("************ Line mode, BELL\n"));
|
||||
bellFlag = 1;
|
||||
break;
|
||||
|
||||
case U_CTL_L: /* Formfeed; clear line and return */
|
||||
LTERM_LOG(ltermProcessOutput,32,("************ Line mode, FORMFEED\n\n"));
|
||||
|
||||
ltermClearOutputLine(lts);
|
||||
*opcodes = LTERM_LINEDATA_CODE | LTERM_CLEAR_CODE;
|
||||
break;
|
||||
|
||||
case U_LINEFEED: /* Newline; return complete line */
|
||||
LTERM_LOG(ltermProcessOutput,32,("************ Line mode, NEWLINE\n\n"));
|
||||
|
||||
*opcodes = LTERM_LINEDATA_CODE
|
||||
| LTERM_OUTPUT_CODE
|
||||
| LTERM_NEWLINE_CODE;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Ignore other control characters (including NULs) */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Increment character index */
|
||||
charIndex += consumedChars;
|
||||
}
|
||||
|
||||
/* Determine count of unprocessed characters */
|
||||
remainingChars = lto->decodedChars - charIndex;
|
||||
|
||||
if (remainingChars > 0) {
|
||||
/* Move unprocessed output to beginning of decode buffer */
|
||||
|
||||
LTERM_LOG(ltermProcessOutput,32,("Moved %d chars to beginning of decodedOutput\n", remainingChars));
|
||||
for (j=0; j<remainingChars; j++) {
|
||||
lto->decodedOutput[j] = lto->decodedOutput[j+charIndex];
|
||||
lto->decodedStyle[j] = lto->decodedStyle[j+charIndex];
|
||||
}
|
||||
}
|
||||
|
||||
/* Update remaining decoded character count */
|
||||
lto->decodedChars = remainingChars;
|
||||
|
||||
if (*opcodes == 0) {
|
||||
/* All output processed; without any special terminating condition */
|
||||
if (lto->outputMode == LTERM1_SCREEN_MODE) {
|
||||
/* Full screen mode */
|
||||
*opcodes = LTERM_SCREENDATA_CODE;
|
||||
|
||||
} else {
|
||||
/* Line mode */
|
||||
*opcodes = LTERM_LINEDATA_CODE | LTERM_OUTPUT_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set bell code */
|
||||
if (bellFlag)
|
||||
*opcodes |= LTERM_BELL_CODE;
|
||||
|
||||
if (*opcodes & LTERM_LINEDATA_CODE) {
|
||||
/* Returning line mode data; check for prompt */
|
||||
|
||||
if ((lts->commandNumber == 0) ||
|
||||
(lto->outputModifiedChar < lto->promptChars)) {
|
||||
/* If not command line or if "prompt string" may have been modified,
|
||||
* search for prompt
|
||||
*/
|
||||
int promptLen;
|
||||
|
||||
LTERM_LOG(ltermProcessOutput,39,("Prompt? modifiedChar=%d, promptChars=%d\n",
|
||||
lto->outputModifiedChar, lto->promptChars));
|
||||
|
||||
/* Reset modification marker */
|
||||
lto->outputModifiedChar = lto->outputChars;
|
||||
|
||||
/* Check if prompt string is present in output */
|
||||
promptLen = ltermPromptLocate(lts);
|
||||
|
||||
if (promptLen > 0) {
|
||||
/* Prompt string found */
|
||||
lto->promptChars = promptLen;
|
||||
|
||||
if (lts->commandNumber == 0) {
|
||||
/* Set command number */
|
||||
|
||||
/* New command number */
|
||||
if (lts->lastCommandNum == 0xFFFF)
|
||||
lts->lastCommandNum = 0;
|
||||
lts->lastCommandNum++;
|
||||
|
||||
lts->commandNumber = lts->lastCommandNum;
|
||||
|
||||
LTERM_LOG(ltermProcessOutput,32,
|
||||
("************ Prompt found; commandNumber=%d\n\n",
|
||||
lts->commandNumber));
|
||||
}
|
||||
|
||||
} else {
|
||||
/* No prompt string */
|
||||
if (lts->commandNumber != 0) {
|
||||
/* Unset command number and prompt columns */
|
||||
UNICHAR temLine[2] = {0, LTERM_WRITE_PLAIN_INPUT};
|
||||
|
||||
lts->commandNumber = 0;
|
||||
lto->promptChars = 0;
|
||||
|
||||
/* Notify "input thread" by writing null input record */
|
||||
WRITE(lts->writeBUFFER, temLine, 2*sizeof(UNICHAR));
|
||||
|
||||
LTERM_LOG(ltermProcessOutput,32,
|
||||
("************ No prompt found; not command line\n\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lto->outputMode == LTERM1_SCREEN_MODE) {
|
||||
char modifiedRows[81];
|
||||
int showRows = (lts->nRows < 80) ? lts->nRows : 80;
|
||||
for (j=0; j<showRows; j++) {
|
||||
if (lto->modifiedCol[j] > -1)
|
||||
modifiedRows[j] = 'M';
|
||||
else
|
||||
modifiedRows[j] = '.';
|
||||
}
|
||||
modifiedRows[showRows] = '\0';
|
||||
LTERM_LOG(ltermProcessOutput,38,("modifiedRows=%s\n", modifiedRows));
|
||||
}
|
||||
|
||||
LTERM_LOG(ltermProcessOutput,31,("returned opcodes=0x%X\n", *opcodes));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Clears output line buffer */
|
||||
void ltermClearOutputLine(struct lterms *lts)
|
||||
{
|
||||
struct LtermOutput *lto = &(lts->ltermOutput);
|
||||
|
||||
LTERM_LOG(ltermClearOutputLine,40,("\n"));
|
||||
|
||||
lto->outputChars = 0;
|
||||
lto->outputCursorChar = 0;
|
||||
lto->outputModifiedChar = 0;
|
||||
lto->promptChars = 0;
|
||||
|
||||
lts->commandNumber = 0;
|
||||
}
|
||||
|
||||
|
||||
/** Clears output screen buffer (allocating memory, if first time/resized) */
|
||||
int ltermClearOutputScreen(struct lterms *lts)
|
||||
{
|
||||
struct LtermOutput *lto = &(lts->ltermOutput);
|
||||
int j;
|
||||
|
||||
LTERM_LOG(ltermClearOutputScreen,40,("\n"));
|
||||
|
||||
if (lto->screenChar == NULL) {
|
||||
/* Allocate memory for full screen */
|
||||
int screenSize = lts->nRows * lts->nCols;
|
||||
|
||||
lto->screenChar = (UNICHAR *) MALLOC(screenSize * sizeof(UNICHAR));
|
||||
|
||||
if (lto->screenChar == NULL) {
|
||||
LTERM_ERROR("ltermClearOutputScreen: Error - failed to allocate memory for chars\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(lto->screenStyle == NULL);
|
||||
lto->screenStyle = (UNISTYLE *) MALLOC(screenSize * sizeof(UNISTYLE));
|
||||
|
||||
if (lto->screenStyle == NULL) {
|
||||
LTERM_ERROR("ltermClearOutputScreen: Error - failed to allocate memory for style\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Position cursor at home */
|
||||
lto->cursorRow = lts->nRows - 1;
|
||||
lto->cursorCol = 0;
|
||||
|
||||
/* Blank out entire screen */
|
||||
if (ltermInsDelEraseLine(lts, lts->nRows, lts->nRows-1, LTERM_ERASE_ACTION) != 0)
|
||||
return -1;
|
||||
|
||||
/* No rows modified yet */
|
||||
for (j=0; j<lts->nRows; j++) {
|
||||
lto->modifiedCol[j] = -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Saves current output mode value and switches to stream output mode,
|
||||
* with specified opcodes and terminator string.
|
||||
* @return 0 on success and -1 on error.
|
||||
*/
|
||||
int ltermSwitchToStreamMode(struct lterms *lts, int streamOpcodes,
|
||||
const UNICHAR *streamTerminator)
|
||||
{
|
||||
struct LtermOutput *lto = &(lts->ltermOutput);
|
||||
int strLength;
|
||||
|
||||
LTERM_LOG(ltermSwitchToStreamMode,40,("streamOpcodes=0x%x\n",streamOpcodes));
|
||||
|
||||
if (streamTerminator != NULL) {
|
||||
/* Save terminator string (may be null) */
|
||||
strLength = ucslen(streamTerminator);
|
||||
ucsncpy( lto->streamTerminator, streamTerminator, MAXSTREAMTERM);
|
||||
|
||||
LTERM_LOGUNICODE(ltermSwitchToStreamMode,41,(streamTerminator,
|
||||
(int) strLength));
|
||||
} else {
|
||||
/* Null terminator */
|
||||
strLength = 0;
|
||||
lto->streamTerminator[0] = U_NUL;
|
||||
}
|
||||
|
||||
if (strLength > MAXSTREAMTERM-1) {
|
||||
LTERM_ERROR("ltermSwitchToStreamMode: Error - terminator string too long\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lts->options & LTERM_NONUL_FLAG) {
|
||||
/* No decoding of NUL characters */
|
||||
if (strLength == 0) {
|
||||
LTERM_ERROR("ltermSwitchToStreamMode: Error - null terminator string not allowed\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* Decoding NUL characters */
|
||||
if (strLength > 0) {
|
||||
LTERM_ERROR("ltermSwitchToStreamMode: Error - terminator string must be NUL\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
lto->savedOutputMode = lto->outputMode;
|
||||
lto->outputMode = LTERM0_STREAM_MODE;
|
||||
lto->streamOpcodes = streamOpcodes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Switches to screen output mode.
|
||||
* @return 0 on success and -1 on error.
|
||||
*/
|
||||
int ltermSwitchToScreenMode(struct lterms *lts)
|
||||
{
|
||||
struct LtermOutput *lto = &(lts->ltermOutput);
|
||||
|
||||
LTERM_LOG(ltermSwitchToScreenMode,40,("\n"));
|
||||
|
||||
if (lto->outputMode == LTERM2_LINE_MODE) {
|
||||
/* Switching from line mode to screen mode */
|
||||
|
||||
/* Clear styleMask */
|
||||
lto->styleMask = 0;
|
||||
|
||||
/* Clear screen */
|
||||
if (ltermClearOutputScreen(lts) != 0)
|
||||
return -1;
|
||||
|
||||
/* Reset returned cursor location */
|
||||
lto->returnedCursorRow = -1;
|
||||
lto->returnedCursorCol = -1;
|
||||
|
||||
/* Scrolling region */
|
||||
lto->topScrollRow = lts->nRows-1;
|
||||
lto->botScrollRow = 0;
|
||||
|
||||
/* Disable input echo */
|
||||
lts->restoreInputEcho = !lts->disabledInputEcho;
|
||||
lts->disabledInputEcho = 1;
|
||||
|
||||
/* Switch to raw input mode */
|
||||
ltermSwitchToRawMode(lts);
|
||||
|
||||
}
|
||||
|
||||
lto->outputMode = LTERM1_SCREEN_MODE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Switches to line output mode.
|
||||
* @return 0 on success and -1 on error.
|
||||
*/
|
||||
int ltermSwitchToLineMode(struct lterms *lts)
|
||||
{
|
||||
struct LtermOutput *lto = &(lts->ltermOutput);
|
||||
int j;
|
||||
|
||||
LTERM_LOG(ltermSwitchToLineMode,40,("\n"));
|
||||
|
||||
if (lto->outputMode == LTERM1_SCREEN_MODE) {
|
||||
/* Switching from screen mode to line mode */
|
||||
|
||||
/* Switch to line input mode */
|
||||
ltermClearInputLine(lts);
|
||||
|
||||
if (lts->restoreInputEcho) {
|
||||
/* Re-enable input echo */
|
||||
lts->disabledInputEcho = 0;
|
||||
lts->restoreInputEcho = 0;
|
||||
}
|
||||
|
||||
/* Clear styleMask */
|
||||
lto->styleMask = 0;
|
||||
|
||||
/* Clear output line */
|
||||
ltermClearOutputLine(lts);
|
||||
|
||||
/* Copy bottom line to line output buffer ??? */
|
||||
lto->outputChars = lts->nCols;
|
||||
|
||||
assert(lts->nCols < MAXCOL);
|
||||
|
||||
for (j=0; j<lts->nCols; j++) {
|
||||
lto->outputLine[j] = lto->screenChar[j];
|
||||
lto->outputStyle[j] = lto->screenStyle[j];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lto->outputMode = LTERM2_LINE_MODE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Reads data from process STDOUT and/or STDERR using file descriptors
|
||||
* from the LTERM POLL structure, and converts to Unicode, saving
|
||||
* incomplete character encodings in corresponding incomplete raw buffers.
|
||||
* Decoded characters are appended to the decodedOutput buffer,
|
||||
* with appropriate style settings.
|
||||
* If READERR is false, STDERR is never read.
|
||||
* @return the number of decoded characters appended (>=0) if successful,
|
||||
* -1 if an error occurred during processing, or
|
||||
* -2 if pseudo-TTY has been closed.
|
||||
*/
|
||||
int ltermReceiveData(struct lterms *lts, int readERR)
|
||||
{
|
||||
struct LtermOutput *lto = &(lts->ltermOutput);
|
||||
char temERRBuf[MAXCOL], temOUTBuf[MAXCOL];
|
||||
int readERRMax, readOUTMax;
|
||||
int nReadERR, nTotalERR, nReadOUT, nTotalOUT;
|
||||
int interleavedBytes, n_decoded, n_decoded_tot, j;
|
||||
|
||||
LTERM_LOG(ltermReceiveData,30,("\n"));
|
||||
|
||||
nTotalERR = 0;
|
||||
if (readERR && (lto->pollFD[POLL_STDERR].POLL_REVENTS != 0)) {
|
||||
/* Read data from STDERR */
|
||||
|
||||
/* Read maximum number of bytes that will all fit into decodedOutput
|
||||
when decoded, assuming number of decoded characters will not exceed
|
||||
the number of encoded bytes */
|
||||
|
||||
readERRMax = MAXCOLM1 - lto->decodedChars - lto->rawERRBytes;
|
||||
|
||||
/* Reduce by half to leave some space for STDOUT data */
|
||||
readERRMax = readERRMax / 2;
|
||||
|
||||
if (readERRMax <= 0) {
|
||||
/* Decoded buffer overflow */
|
||||
LTERM_WARNING("ltermReceiveData: Warning - decoded buffer overflow\n");
|
||||
|
||||
/* Non-fatal error recovery; return without reading */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy any incomplete raw output to beginning of buffer */
|
||||
for (j=0; j<lto->rawERRBytes; j++)
|
||||
temERRBuf[j] = lto->rawERRBuf[j];
|
||||
|
||||
/* Read STDERRdata (blocking mode) */
|
||||
nReadERR = READ(lto->pollFD[POLL_STDERR].fd,
|
||||
temERRBuf + lto->rawERRBytes, (SIZE_T) readERRMax);
|
||||
|
||||
if (nReadERR < 0) {
|
||||
#if defined(DEBUG_LTERM) && !defined(USE_NSPR_IO)
|
||||
int errcode = errno;
|
||||
/* perror("ltermReceiveData"); */
|
||||
#else
|
||||
int errcode = 0;
|
||||
#endif
|
||||
LTERM_ERROR( "ltermReceiveData: Error %d in reading from process STDERR\n",
|
||||
errcode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nReadERR == 0) {
|
||||
/* End of file => pseudo-TTY has been closed */
|
||||
LTERM_LOG(ltermReceiveData,31,("pseudo-TTY has been closed\n"));
|
||||
|
||||
/* Suspend LTERM */
|
||||
lts->suspended = 1;
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
LTERM_LOG(ltermReceiveData,32,("Read %d raw bytes from STDERR\n", nReadERR));
|
||||
nTotalERR = nReadERR + lto->rawERRBytes;
|
||||
}
|
||||
|
||||
nTotalOUT = 0;
|
||||
if (lto->pollFD[POLL_STDOUT].POLL_REVENTS != 0) {
|
||||
/* Read data from STDOUT */
|
||||
|
||||
/* Read maximum number of bytes that will all fit into decodedOutput
|
||||
when decoded, assuming number of decoded characters will not exceed
|
||||
the number of encoded bytes */
|
||||
readOUTMax = MAXCOLM1 - lto->decodedChars - lto->rawOUTBytes - nTotalERR;
|
||||
|
||||
if (readOUTMax <= 0) {
|
||||
/* Decoded buffer overflow */
|
||||
LTERM_WARNING("ltermReceiveData: Warning - decoded buffer overflow\n");
|
||||
|
||||
/* Non-fatal error recovery; return without reading */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy any incomplete raw output to beginning of buffer */
|
||||
for (j=0; j<lto->rawOUTBytes; j++)
|
||||
temOUTBuf[j] = lto->rawOUTBuf[j];
|
||||
|
||||
/* Read STDOUTdata (blocking mode) */
|
||||
nReadOUT = READ(lto->pollFD[POLL_STDOUT].fd,
|
||||
temOUTBuf + lto->rawOUTBytes, (SIZE_T) readOUTMax);
|
||||
|
||||
if (nReadOUT < 0) {
|
||||
#if defined(DEBUG_LTERM) && !defined(USE_NSPR_IO)
|
||||
int errcode = errno;
|
||||
/* perror("ltermReceiveData"); */
|
||||
#else
|
||||
int errcode = 0;
|
||||
#endif
|
||||
LTERM_ERROR( "ltermReceiveData: Error %d in reading from process STDOUT\n",
|
||||
errcode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nReadOUT == 0) {
|
||||
/* End of file => pseudo-TTY has been closed */
|
||||
LTERM_LOG(ltermReceiveData,31,("pseudo-TTY has been closed\n"));
|
||||
|
||||
/* Suspend LTERM */
|
||||
lts->suspended = 1;
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
LTERM_LOG(ltermReceiveData,32,("Read %d raw bytes from STDOUT\n", nReadOUT));
|
||||
|
||||
nTotalOUT = nReadOUT + lto->rawOUTBytes;
|
||||
}
|
||||
|
||||
n_decoded_tot = 0;
|
||||
|
||||
if (lts->readERRfirst) {
|
||||
/* Decode STDERR data first */
|
||||
interleavedBytes = 0;
|
||||
n_decoded = ltermAppendOutput(lts, temERRBuf, nTotalERR,
|
||||
LTERM_STDERR_STYLE,
|
||||
lts->interleave, &interleavedBytes,
|
||||
MAXRAWINCOMPLETE,
|
||||
&(lto->rawERRBytes), lto->rawERRBuf);
|
||||
if (n_decoded < 0)
|
||||
return -1;
|
||||
n_decoded_tot += n_decoded;
|
||||
|
||||
/* Decode STDOUT data next */
|
||||
n_decoded = ltermAppendOutput(lts, temOUTBuf, nTotalOUT,
|
||||
LTERM_STDOUT_STYLE,
|
||||
0, NULL,
|
||||
MAXRAWINCOMPLETE,
|
||||
&(lto->rawOUTBytes), lto->rawOUTBuf);
|
||||
if (n_decoded < 0)
|
||||
return -1;
|
||||
n_decoded_tot += n_decoded;
|
||||
|
||||
if (interleavedBytes > 0) {
|
||||
/* Decode remaining STDERR data */
|
||||
n_decoded = ltermAppendOutput(lts, temERRBuf+interleavedBytes,
|
||||
nTotalERR-interleavedBytes,
|
||||
LTERM_STDERR_STYLE,
|
||||
0, NULL,
|
||||
MAXRAWINCOMPLETE,
|
||||
&(lto->rawERRBytes), lto->rawERRBuf);
|
||||
if (n_decoded < 0)
|
||||
return -1;
|
||||
n_decoded_tot += n_decoded;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Decode STDOUT data first */
|
||||
interleavedBytes = 0;
|
||||
n_decoded = ltermAppendOutput(lts, temOUTBuf, nTotalOUT,
|
||||
LTERM_STDOUT_STYLE,
|
||||
lts->interleave, &interleavedBytes,
|
||||
MAXRAWINCOMPLETE,
|
||||
&(lto->rawOUTBytes), lto->rawOUTBuf);
|
||||
if (n_decoded < 0)
|
||||
return -1;
|
||||
n_decoded_tot += n_decoded;
|
||||
|
||||
/* Decode STDERR data next */
|
||||
n_decoded = ltermAppendOutput(lts, temERRBuf, nTotalERR,
|
||||
LTERM_STDERR_STYLE,
|
||||
0, NULL,
|
||||
MAXRAWINCOMPLETE,
|
||||
&(lto->rawERRBytes), lto->rawERRBuf);
|
||||
if (n_decoded < 0)
|
||||
return -1;
|
||||
n_decoded_tot += n_decoded;
|
||||
|
||||
if (interleavedBytes > 0) {
|
||||
/* Decode remaining STDOUT data */
|
||||
n_decoded = ltermAppendOutput(lts, temOUTBuf+interleavedBytes,
|
||||
nTotalOUT-interleavedBytes,
|
||||
LTERM_STDOUT_STYLE,
|
||||
0, NULL,
|
||||
MAXRAWINCOMPLETE,
|
||||
&(lto->rawOUTBytes), lto->rawOUTBuf);
|
||||
if (n_decoded < 0)
|
||||
return -1;
|
||||
n_decoded_tot += n_decoded;
|
||||
}
|
||||
}
|
||||
|
||||
if (n_decoded_tot > 0) {
|
||||
/* New characters have been decoded; no longer incomplete escape seq. */
|
||||
lto->incompleteEscapeSequence = 0;
|
||||
}
|
||||
|
||||
return n_decoded_tot;
|
||||
}
|
||||
|
||||
|
||||
/** Process COUNT bytes raw data from CBUF, converting complete
|
||||
* character encodings to Unicode, saving RAWINCOMPLETEBYTES in
|
||||
* RAWINCOMPLETEBUF, whose maximum size is specified by RAWINCOMPLETEMAX.
|
||||
* If INTERLEAVECHECK, check for starting NEWLINE and other interleavable
|
||||
* characters, and if found "decode" just those characters and set
|
||||
* INTERLEAVEDBYTES to the number of bytes consumed on return;
|
||||
* otherwise INTERLEAVEDBYTES is set to 0.
|
||||
* The decoded characters are appended to the decodedOutput buffer,
|
||||
* with style STYLE.
|
||||
* @return the number of characters appended (>=0) if successful,
|
||||
* -1 if an error occurred during processing, or
|
||||
* -2 if pseudo-TTY has been closed.
|
||||
*/
|
||||
static int ltermAppendOutput(struct lterms *lts, const char *cbuf, int count,
|
||||
UNISTYLE style, int interleaveCheck,
|
||||
int *interleavedBytes, int rawIncompleteMax,
|
||||
int *rawIncompleteBytes, char *rawIncompleteBuf)
|
||||
{
|
||||
struct LtermOutput *lto = &(lts->ltermOutput);
|
||||
int decodeMax, n_decoded, decodeNUL, j;
|
||||
|
||||
LTERM_LOG(ltermAppendOutput,30,("count=%d, style=0x%X, iCheck=%d, rawIncMax=%d\n",
|
||||
count, style, interleaveCheck, rawIncompleteMax));
|
||||
|
||||
if (interleaveCheck && (count > 0) && (cbuf[0] == '\n')) {
|
||||
/* Raw buffer starts with NEWLINE character; interleave */
|
||||
|
||||
assert(lto->decodedChars < MAXCOLM1);
|
||||
|
||||
/* "Decode" just the NEWLINE character */
|
||||
lto->decodedOutput[lto->decodedChars] = U_LINEFEED;
|
||||
lto->decodedStyle[lto->decodedChars] = LTERM_STDOUT_STYLE;
|
||||
|
||||
lto->decodedChars++;
|
||||
|
||||
*interleavedBytes = 1;
|
||||
|
||||
LTERM_LOG(ltermAppendOutput,32,("INTERLEAVED %d bytes\n",
|
||||
*interleavedBytes));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (interleavedBytes != NULL)
|
||||
*interleavedBytes = 0;
|
||||
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
/* Decode all complete encoded character sequences */
|
||||
decodeMax = MAXCOLM1 - lto->decodedChars;
|
||||
decodeNUL = (lts->options & LTERM_NONUL_FLAG) == 0;
|
||||
n_decoded = ltermDecode(cbuf, count,
|
||||
lto->decodedOutput+lto->decodedChars,
|
||||
decodeMax, decodeNUL,
|
||||
rawIncompleteBytes);
|
||||
|
||||
if (n_decoded < 0)
|
||||
return -1;
|
||||
|
||||
/* Save any incomplete raw byte encodings */
|
||||
if (*rawIncompleteBytes > rawIncompleteMax) {
|
||||
LTERM_ERROR("ltermAppendOutput: Error - too many incomplete raw characters\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (j=0; j<*rawIncompleteBytes; j++)
|
||||
rawIncompleteBuf[j] = cbuf[j+count-*rawIncompleteBytes];
|
||||
|
||||
/* Set decoded character styles */
|
||||
for (j=lto->decodedChars; j<lto->decodedChars+n_decoded; j++)
|
||||
lto->decodedStyle[j] = style;
|
||||
|
||||
/* Increment decoded character count */
|
||||
lto->decodedChars += n_decoded;
|
||||
|
||||
LTERM_LOG(ltermAppendOutput,32,("Appended %d bytes\n", n_decoded));
|
||||
|
||||
return n_decoded;
|
||||
}
|
||||
|
||||
|
||||
/** Decodes N_TOTAL bytes in RAWBUF, returning upto DECODEMAX Unicode
|
||||
* characters in DECODEDBUF, leaving *RAWINCOMPLETEBYTES at the end of
|
||||
* RAWBUF undecoded.
|
||||
* Any NUL (zero) characters in RAWBUF are skipped, unless
|
||||
* decodeNUL is true.
|
||||
* If there is not enough space in DECODEDBUF for all characters to be
|
||||
* decoded, an error is returned.
|
||||
* @return the number of Unicoded characters decoded (>=0) or -1 on error.
|
||||
*/
|
||||
static int ltermDecode(const char *rawBuf, int n_total,
|
||||
UNICHAR* decodedBuf, int decodeMax,
|
||||
int decodeNUL,
|
||||
int *rawIncompleteBytes)
|
||||
{
|
||||
int n_decoded, result;
|
||||
|
||||
LTERM_LOG(ltermDecode,40,("\n"));
|
||||
|
||||
if (decodeMax < n_total) {
|
||||
LTERM_ERROR("ltermDecode: Error - decode buffer overflow\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = utf8toucs(rawBuf, n_total, decodedBuf, decodeMax,
|
||||
!decodeNUL, rawIncompleteBytes, &n_decoded);
|
||||
|
||||
if (result != 0) {
|
||||
LTERM_WARNING("ltermDecode: Warning - Invalid UTF8 data encountered\n");
|
||||
}
|
||||
|
||||
LTERM_LOG(ltermDecode,41,("result=%d, incomplete=%d, n_decoded=%d\n",
|
||||
result, *rawIncompleteBytes, n_decoded));
|
||||
LTERM_LOGUNICODE(ltermDecode,42,(decodedBuf, n_decoded));
|
||||
|
||||
return n_decoded;
|
||||
}
|
||||
|
||||
|
||||
/** Search for prompt string in the output line buffer.
|
||||
* TEMPORARY implementation: assume promptRegexp is just a list of delimiters
|
||||
* @return the length of the matching prompt string, or
|
||||
* 0 if there is no match.
|
||||
*/
|
||||
static int ltermPromptLocate(struct lterms *lts)
|
||||
{
|
||||
struct LtermOutput *lto = &(lts->ltermOutput);
|
||||
int prefixCount, promptLen;
|
||||
|
||||
LTERM_LOG(ltermPromptLocate,49,("lto->outputChars=%d\n",
|
||||
lto->outputChars));
|
||||
|
||||
/* Assert that there is at least one free character in the buffer */
|
||||
assert(lto->outputChars < MAXCOL);
|
||||
|
||||
if (lto->outputChars == 0)
|
||||
return 0;
|
||||
|
||||
/* Insert null character at the end of the output buffer */
|
||||
lto->outputLine[lto->outputChars] = U_NUL;
|
||||
|
||||
/* Determine length of initial non-delimiter prefix */
|
||||
prefixCount = ucscspn(lto->outputLine, lts->promptRegexp);
|
||||
|
||||
if (prefixCount+1 >= lto->outputChars) {
|
||||
promptLen = 0;
|
||||
|
||||
} else {
|
||||
/* Skip any whitespace following the delimiter */
|
||||
const UNICHAR spaceStr[3] = {U_SPACE, U_TAB, U_NUL};
|
||||
int spaceCount = ucsspn(lto->outputLine+prefixCount+1, spaceStr);
|
||||
|
||||
promptLen = prefixCount + 1 + spaceCount;
|
||||
|
||||
LTERM_LOGUNICODE(ltermPromptLocate,41,(lto->outputLine, promptLen));
|
||||
}
|
||||
|
||||
return promptLen;
|
||||
}
|
|
@ -0,0 +1,572 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is lineterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License (the "GPL"), in which case
|
||||
* the provisions of the GPL are applicable instead of
|
||||
* those above. If you wish to allow use of your version of this
|
||||
* file only under the terms of the GPL and not to allow
|
||||
* others to use your version of this file under the MPL, indicate
|
||||
* your decision by deleting the provisions above and replace them
|
||||
* with the notice and other provisions required by the GPL.
|
||||
* If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/* ltermPrivate.h: Line terminal (LTERM) private header file
|
||||
* LTERM provides a "stream" interface to an XTERM-like terminal,
|
||||
* using line input/output.
|
||||
* CPP options:
|
||||
* LINUX: for Linux2.0/glibc
|
||||
* SOLARIS: for Solaris2.6
|
||||
* BSDFAMILY: for FreeBSD, ...
|
||||
* DEBUG_LTERM: to enable some debugging output
|
||||
* NO_PTY: force use of pipes rather than PTY for process
|
||||
* communication
|
||||
* MOZILLA_CLIENT: set if embedded in Mozilla
|
||||
* USE_NSPR_BASE: use basic NSPR API (excluding I/O and process creation)
|
||||
* USE_NSPR_LOCK: use NSPR lock API instead of Unix mutex API
|
||||
* USE_NSPR_IO: use NSPR I/O and process API instead of Unix API
|
||||
* (current implementation of pseudo-TTY is incompatible with
|
||||
* the NSPR I/O API; set the USE_NSPR_IO option only on platforms
|
||||
* where PTYSTREAM is not implemented)
|
||||
*/
|
||||
|
||||
#ifndef _LTERMPRIVATE_H
|
||||
|
||||
#define _LTERMPRIVATE_H 1
|
||||
|
||||
/* Standard C header files */
|
||||
#include <string.h>
|
||||
|
||||
/* public declarations */
|
||||
#include "lineterm.h"
|
||||
#include "tracelog.h"
|
||||
|
||||
/* private declarations */
|
||||
|
||||
/* Force use of basic NSPR API if MOZILLA_CLIENT or USE_NSPR_IO are defined */
|
||||
#if defined(MOZILLA_CLIENT) || defined(USE_NSPR_IO)
|
||||
#define USE_NSPR_BASE 1
|
||||
#endif
|
||||
|
||||
/* pseudo-TTY stream interface */
|
||||
#include "ptystream.h"
|
||||
|
||||
#define LTERM_ERROR TLOG_ERROR
|
||||
#define LTERM_WARNING TLOG_WARNING
|
||||
#define LTERM_LOG(procname,level,args) TLOG_PRINT(LTERM_TLOG_MODULE,procname,level,args)
|
||||
#define LTERM_LOGUNICODE(procname,level,args) TLOG_UNICHAR(LTERM_TLOG_MODULE,procname,level,args)
|
||||
|
||||
#ifdef USE_NSPR_BASE /* Use basic NSPR API (excluding I/O) */
|
||||
|
||||
#include "nspr.h"
|
||||
|
||||
#define assert PR_ASSERT
|
||||
|
||||
#define int32 PRInt32
|
||||
|
||||
#define getenv PR_GetEnv
|
||||
|
||||
#define MALLOC(x) PR_Malloc(x)
|
||||
#define REALLOC(x,y) PR_Realloc((x),(y))
|
||||
#define CALLOC(x,y) PR_Calloc((x),(y))
|
||||
#define FREE(x) PR_Free(x)
|
||||
|
||||
#else /* not USE_NSPR_BASE */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define int32 long
|
||||
|
||||
#define MALLOC(x) malloc(x)
|
||||
#define REALLOC(x,y) realloc((x),(y))
|
||||
#define CALLOC(x,y) calloc((x),(y))
|
||||
#define FREE(x) free(x)
|
||||
|
||||
#endif /* not USE_NSPR_BASE */
|
||||
|
||||
|
||||
#ifdef USE_NSPR_IO /* Use NSPR I/O API (no PTY implementation) */
|
||||
|
||||
typedef PRFileDesc *FILEDESC;
|
||||
#define NULL_FILEDESC 0
|
||||
#define VALID_FILEDESC(x) (x != 0)
|
||||
|
||||
typedef PRFileDesc FILESTREAM;
|
||||
|
||||
#define SIZE_T PRInt32
|
||||
#define WRITE PR_Write
|
||||
#define READ PR_Read
|
||||
#define CLOSE(x) (PR_Close(x) != PR_SUCCESS)
|
||||
#define PIPE(x) (PR_CreatePipe((x),(x)+1) != PR_SUCCESS)
|
||||
|
||||
#define POLL(x,y,z) PR_Poll((x),(y),(z))
|
||||
#define POLLFD PRPollDesc
|
||||
#define POLL_EVENTS in_flags
|
||||
#define POLL_REVENTS out_flags
|
||||
#define POLL_READ PR_POLL_READ
|
||||
|
||||
#define PROCESS PRProcess *
|
||||
#define NULL_PROCESS 0
|
||||
#define VALID_PROCESS(x) (x != 0)
|
||||
|
||||
#else /* not USE_NSPR_IO */
|
||||
|
||||
/* system header files */
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
/* Diagnostic/debugging files */
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined(SOLARIS)
|
||||
#include <poll.h>
|
||||
#else
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
|
||||
typedef int FILEDESC;
|
||||
#define NULL_FILEDESC -1
|
||||
#define VALID_FILEDESC(x) (x >= 0)
|
||||
|
||||
typedef FILE FILESTREAM;
|
||||
|
||||
#define SIZE_T size_t
|
||||
#define WRITE write
|
||||
#define READ read
|
||||
#define CLOSE(x) close(x)
|
||||
#define PIPE(x) pipe(x)
|
||||
|
||||
#define POLL(x,y,z) poll((x),(y),(z))
|
||||
#define POLLFD pollfd
|
||||
#define POLL_EVENTS events
|
||||
#define POLL_REVENTS revents
|
||||
#define POLL_READ POLLIN
|
||||
|
||||
#define PROCESS long
|
||||
#define NULL_PROCESS 0
|
||||
#define VALID_PROCESS(x) (x > 0)
|
||||
|
||||
#endif /* not USE_NSPR_IO */
|
||||
|
||||
|
||||
#ifdef USE_NSPR_LOCK /* Use NSPR lock API */
|
||||
|
||||
#define MUTEX_DECLARE(x) PRLock *x
|
||||
#define MUTEX_INITIALIZE(x) ((x=PR_NewLock()) == NULL)
|
||||
#define MUTEX_LOCK(x) PR_Lock(x)
|
||||
#define MUTEX_UNLOCK(x) PR_Unlock(x)
|
||||
#define MUTEX_DESTROY(x) PR_DestroyLock(x)
|
||||
|
||||
#define THREAD_DECLARE(x) PRThread *x
|
||||
#define THREAD_CREATE ((x=PR_CreateThread(PR_USER_THREAD, (y), (z), \
|
||||
PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, \
|
||||
PR_JOINABLE_THREAD, 0)) == NULL)
|
||||
#define THREAD_SELF PR_GetCurrentThread
|
||||
#define THREAD_EQUAL(x,y) ((x) == (y))
|
||||
#define THREAD_JOIN(x) (PR_JoinThread(x) != PR_SUCCESS)
|
||||
|
||||
#else /* not USE_NSPR_LOCK */
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#define MUTEX_DECLARE(x) pthread_mutex_t x
|
||||
#define MUTEX_INITIALIZE(x) pthread_mutex_init(&(x), NULL)
|
||||
#define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
|
||||
#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
|
||||
#define MUTEX_DESTROY(x) pthread_mutex_destroy(&(x))
|
||||
|
||||
#define THREAD_DECLARE(x) pthread_t x
|
||||
#define THREAD_CREATE(x,y,z) pthread_create(&(x),NULL,(y),(z))
|
||||
#define THREAD_SELF pthread_self
|
||||
#define THREAD_EQUAL(x,y) pthread_equal(x,y)
|
||||
#define THREAD_JOIN(x) pthread_join((x),NULL)
|
||||
|
||||
#endif /* not USE_NSPR_LOCK */
|
||||
|
||||
|
||||
#define MAXTERM 256 /* Maximum number of LTERMs;
|
||||
* affects static memory "footprint"
|
||||
*/
|
||||
|
||||
#define MAXCOL 4096 /* Maximum columns in line buffer;
|
||||
* affects static memory "footprint";
|
||||
* the only limitation on this value is that
|
||||
* it must fit into a UNICHAR, because of the
|
||||
* way lterm_write and ltermWrite implement
|
||||
* the input buffer pipe.
|
||||
*/
|
||||
|
||||
#define MAXROW 1024 /* Maximum rows in screen;
|
||||
* primarily affects dynamically allocated
|
||||
* memory
|
||||
*/
|
||||
|
||||
/* The only obvious limitation on the following is that they should be
|
||||
* significantly less than MAXCOL
|
||||
*/
|
||||
#define MAXPROMPT 256 /* Maximum length of prompt regexp+1 */
|
||||
#define MAXRAWINCOMPLETE 5 /* Maximum incomplete raw buffer size */
|
||||
#define MAXSTREAMTERM 11 /* Maximum stream terminator buffer size */
|
||||
#define MAXCOOKIESTR 64 /* Maximum length of cookie string+1 */
|
||||
#define MAXESCAPEPARAMS 16 /* Maximum no. of numeric ESCAPE parameters */
|
||||
#define MAXSTRINGPARAM 512 /* Maximum length of string ESCAPE parameters */
|
||||
#define MAXSHELLINITCMD 2 /* Maximum no. of shell init commands */
|
||||
#define MAXSHELLINITSTR 256 /* Maximum length of shell init string+1 */
|
||||
|
||||
#define MAXPTYIN 128 /* 1/2 POSIX minimum MAX_INPUT for PTY */
|
||||
|
||||
#define MAXCOLM1 (MAXCOL-1) /* Maximum columns in line buffer - 1 */
|
||||
|
||||
#define MAXTTYCONTROL 8 /* Maximum TTY control character list */
|
||||
#define TTYINTERRUPT 0
|
||||
#define TTYERASE 1
|
||||
#define TTYKILL 2
|
||||
#define TTYEOF 3
|
||||
#define TTYSUSPEND 4
|
||||
#define TTYREPRINT 5
|
||||
#define TTYDISCARD 6
|
||||
#define TTYWERASE 7
|
||||
|
||||
/* input modes */
|
||||
#define LTERM0_RAW_MODE 0
|
||||
#define LTERM1_CANONICAL_MODE 1
|
||||
#define LTERM2_EDIT_MODE 2
|
||||
#define LTERM3_COMPLETION_MODE 3
|
||||
|
||||
/* completion request codes */
|
||||
#define LTERM_NO_COMPLETION 0
|
||||
#define LTERM_TAB_COMPLETION 1
|
||||
#define LTERM_HISTORY_COMPLETION 2
|
||||
|
||||
/* output modes */
|
||||
#define LTERM0_STREAM_MODE 0
|
||||
#define LTERM1_SCREEN_MODE 1
|
||||
#define LTERM2_LINE_MODE 2
|
||||
|
||||
/* character/line action codes */
|
||||
#define LTERM_INSERT_ACTION 0
|
||||
#define LTERM_DELETE_ACTION 1
|
||||
#define LTERM_ERASE_ACTION 2
|
||||
|
||||
/* List of characters escaped in XML */
|
||||
#define LTERM_AMP_ESCAPE 0
|
||||
#define LTERM_LT_ESCAPE 1
|
||||
#define LTERM_GT_ESCAPE 2
|
||||
#define LTERM_QUOT_ESCAPE 3
|
||||
#define LTERM_APOS_ESCAPE 4
|
||||
|
||||
#define LTERM_XML_ESCAPES 5
|
||||
#define LTERM_PLAIN_ESCAPES 3
|
||||
|
||||
/* Maximum no. of characters in an XML escape sequence (excluding NUL) */
|
||||
#define LTERM_MAXCHAR_ESCAPE 6
|
||||
|
||||
/* input buffer pipe header "character" count */
|
||||
#define PIPEHEADER 2
|
||||
|
||||
/* input buffer pipe header components */
|
||||
#define PHDR_CHARS 0
|
||||
#define PHDR_TYPE 1
|
||||
|
||||
/* LTERM read in/out parameter structure */
|
||||
struct LtermRead {
|
||||
UNICHAR *buf; /* Pointer to Unicode character buffer (IN param) */
|
||||
UNISTYLE *style; /* Pointer to character style buffer (IN param) */
|
||||
int max_count; /* max. number of characters in buffers (IN param) */
|
||||
int read_count; /* actual number of characters in buffers */
|
||||
int opcodes; /* Returned opcodes */
|
||||
int opvals; /* Returned opvalues */
|
||||
int buf_row; /* row at which to display buffer data */
|
||||
int buf_col; /* starting column at which to display buffer data */
|
||||
int cursor_row; /* final cursor row position */
|
||||
int cursor_col; /* final cursor column position */
|
||||
};
|
||||
|
||||
/* LTERM input structure: managed by lterm_write */
|
||||
struct LtermInput {
|
||||
|
||||
UNICHAR inputBuf[PIPEHEADER+MAXCOL]; /* holds data read from input buffer
|
||||
* pipe
|
||||
*/
|
||||
int inputBufBytes; /* Count of bytes already read in */
|
||||
|
||||
int inputMode; /* input mode:
|
||||
* 0 = raw mode
|
||||
* 1 = canonical mode
|
||||
* 2 = edit + canonical mode
|
||||
* 3 = completion + edit + canonical mode
|
||||
*/
|
||||
|
||||
int escapeFlag; /* processing ESCAPE in line mode */
|
||||
int escapeCSIFlag; /* processing ESCAPE Code Sequence Introducer */
|
||||
int escapeCSIArg; /* ESCAPE Code Sequence Argument value */
|
||||
|
||||
int inputOpcodes; /* input opcodes */
|
||||
|
||||
int clearInputLine; /* true if input line buffer needs to be
|
||||
* cleared (after echoing) */
|
||||
|
||||
UNICHAR inputLine[MAXCOL]; /* input line buffer:
|
||||
only MAXCOL-1 characters should actually
|
||||
be inserted in the buffer, to allow
|
||||
one character padding if necessary */
|
||||
|
||||
int inputChars; /* length of input line (characters);
|
||||
* should never exceed MAXCOL-1,
|
||||
* to allow for null termination
|
||||
*/
|
||||
int inputCols; /* number of displayed columns in input line;
|
||||
* a column corresponds to a single
|
||||
* plain text character transmitted to the
|
||||
* subordinate process, although it may occupy
|
||||
* multiple character positions, e.g.,
|
||||
* e.g., < represents "<"
|
||||
*/
|
||||
int inputGlyphs; /* number of displayed glyphs in input line;
|
||||
* a glyph corresponds to a logical column
|
||||
* on the layout, i.e., a single Unicode
|
||||
* character or an XML element, such as an
|
||||
* iconic representiion of an URI.
|
||||
*/
|
||||
|
||||
unsigned short inputColCharIndex[MAXCOL]; /* starting character index of
|
||||
* each column, including the
|
||||
* cursor column at end of line.
|
||||
* (inputCols+1 values should be
|
||||
* defined)
|
||||
*/
|
||||
|
||||
unsigned short inputGlyphCharIndex[MAXCOL]; /* starting character index
|
||||
* of each glyph, including
|
||||
* empty glyph at the end of
|
||||
* the line.
|
||||
* (inputGlyphs+1 values
|
||||
* should be defined)
|
||||
*/
|
||||
unsigned short inputGlyphColIndex[MAXCOL]; /* starting column index of
|
||||
* each glyph
|
||||
* (inputGlyphs+1 values)
|
||||
*/
|
||||
|
||||
int inputCursorGlyph; /* current input cursor glyph number (>=0) */
|
||||
};
|
||||
|
||||
/* LtermOutput poll structure index count and values */
|
||||
#define POLL_COUNT 3
|
||||
#define POLL_INPUTBUF 0
|
||||
#define POLL_STDOUT 1
|
||||
#define POLL_STDERR 2
|
||||
|
||||
/* LTERM output structure: managed by lterm_read */
|
||||
struct LtermOutput {
|
||||
struct POLLFD pollFD[POLL_COUNT]; /* output polling structure */
|
||||
long callbackTag[POLL_COUNT]; /* GTK callback tag for each FD (0 if none) */
|
||||
int nfds; /* count of "files" to be polled */
|
||||
int outputMode; /* output mode:
|
||||
* 0 = full screen mode
|
||||
* 1 = line mode
|
||||
* 2 = command line mode
|
||||
*/
|
||||
|
||||
UNICHAR streamTerminator[MAXSTREAMTERM]; /* stream terminator buffer */
|
||||
int streamOpcodes; /* Stream opcodes */
|
||||
int savedOutputMode; /* saved output mode (prior to stream mode) */
|
||||
|
||||
int insertMode; /* character insert mode */
|
||||
int automaticNewline; /* automatic newline mode */
|
||||
|
||||
UNISTYLE styleMask; /* current output style mask */
|
||||
|
||||
char rawOUTBuf[MAXRAWINCOMPLETE]; /* incomplete raw STDOUT buffer */
|
||||
int rawOUTBytes; /* incomplete raw STDOUT byte count */
|
||||
|
||||
char rawERRBuf[MAXRAWINCOMPLETE]; /* incomplete raw STDERR buffer */
|
||||
int rawERRBytes; /* incomplete raw STDERR byte count */
|
||||
|
||||
UNICHAR decodedOutput[MAXCOL]; /* decoded output buffer:
|
||||
only MAXCOL-1 characters should actually
|
||||
be inserted in the buffer, to allow
|
||||
one character padding if necessary */
|
||||
UNISTYLE decodedStyle[MAXCOL]; /* decoded output style buffer */
|
||||
int decodedChars; /* decoded character count;
|
||||
should never exceed MAXCOL-1 */
|
||||
int incompleteEscapeSequence; /* Incomplete ESCAPE sequence flag */
|
||||
|
||||
UNICHAR outputLine[MAXCOL]; /* output line buffer (processed);
|
||||
only MAXCOL-1 characters should actually
|
||||
be inserted in the buffer, to allow
|
||||
one character padding if necessary */
|
||||
UNISTYLE outputStyle[MAXCOL]; /* output style buffer for each character */
|
||||
|
||||
int outputChars; /* length of output line (characters)
|
||||
should never exceed MAXCOL-1 */
|
||||
int outputCursorChar; /* output cursor character position (>=0) */
|
||||
int promptChars; /* prompt character count */
|
||||
int outputModifiedChar; /* leftmost modified character in output line */
|
||||
|
||||
int cursorRow, cursorCol; /* screen cursor row and column */
|
||||
int returnedCursorRow, returnedCursorCol;
|
||||
/* returned screen cursor row and column */
|
||||
|
||||
int topScrollRow, botScrollRow; /* top and bottom scrolling rows */
|
||||
|
||||
int modifiedCol[MAXROW]; /* first modified column in each row;
|
||||
-1 if no column has been modified */
|
||||
|
||||
UNICHAR *screenChar; /* Screen character array (nRows*nCols long) */
|
||||
UNISTYLE *screenStyle; /* Screen style array (nRows*nCols long) */
|
||||
};
|
||||
|
||||
/* LTERM process structure: managed by lterm_create, lterm_close */
|
||||
struct LtermProcess {
|
||||
PROCESS processID; /* process ID */
|
||||
FILEDESC processIN; /* process input pipe */
|
||||
FILEDESC processOUT; /* process output pipe */
|
||||
FILEDESC processERR; /* process error pipe */
|
||||
};
|
||||
|
||||
/* line terminal (LTERM) structure: managed by lterm_open, lterm_close */
|
||||
struct lterms {
|
||||
int opened; /* LTERM opened status flag */
|
||||
int suspended; /* LTERM suspended flag:
|
||||
* an LTERM is suspended when an error
|
||||
* occurs, to prevent further I/O operations
|
||||
* which have unpredictable results.
|
||||
* The LTERM still needs to be closed to
|
||||
* release any resources used by it.
|
||||
* (a suspended LTERM is still open)
|
||||
*/
|
||||
|
||||
MUTEX_DECLARE(adminMutex); /* LTERM administrative mutex */
|
||||
MUTEX_DECLARE(outputMutex); /* LTERM output thread mutex */
|
||||
|
||||
int adminMutexLocked; /* administrative mutex lock status */
|
||||
int outputMutexLocked; /* output mutex lock status */
|
||||
|
||||
FILEDESC writeBUFFER, readBUFFER; /* input character BUFFER pipe */
|
||||
|
||||
int options; /* TTY options */
|
||||
int ptyMode; /* pseudo-TTY mode flag */
|
||||
int noTTYEcho; /* no TTY echo flag */
|
||||
int disabledInputEcho; /* disabled input echo flag */
|
||||
int restoreInputEcho; /* restore input echo flag */
|
||||
|
||||
int processType; /* Process type code */
|
||||
int maxInputMode; /* maximum allowed input mode value */
|
||||
int readERRfirst; /* Read STDERR before STDOUT */
|
||||
int interleave; /* interleave STDERR/STDOUT flag */
|
||||
UNICHAR control[MAXTTYCONTROL]; /* TTY control characters */
|
||||
|
||||
|
||||
int commandNumber; /* output command number
|
||||
* (0 if not command line)
|
||||
*/
|
||||
unsigned short lastCommandNum; /* last command number */
|
||||
int completionRequest; /* command completion request code:
|
||||
* LTERM_NO_COMPLETION, or
|
||||
* LTERM_TAB_COMPLETION, or
|
||||
* LTERM_HISTORY_COMPLETION
|
||||
*/
|
||||
int completionChars; /* command completion insert count */
|
||||
|
||||
int inputBufRecord; /* True if input buffer contains record */
|
||||
|
||||
int inputLineBreak; /* True if input line was transmitted
|
||||
* and plain text copy saved in echo buffer
|
||||
*/
|
||||
UNICHAR echoLine[MAXCOL]; /* Plain text of echo line */
|
||||
int echoChars; /* Count of echo characters */
|
||||
|
||||
int nRows; /* Number of rows */
|
||||
int nCols; /* Number of columns */
|
||||
int xPixels; /* Number of X pixels in screen */
|
||||
int yPixels; /* Number of Y pixels in screen */
|
||||
|
||||
UNICHAR promptRegexp[MAXPROMPT]; /* prompt regular expression
|
||||
JUST A LIST OF DELIMITERS AT PRESENT */
|
||||
|
||||
char cookie[MAXCOOKIESTR]; /* cookie string */
|
||||
char shellInitStr[MAXSHELLINITCMD][MAXSHELLINITSTR];
|
||||
/* shell initialization strings */
|
||||
int shellInitCommands; /* shell init command count */
|
||||
|
||||
struct ptys pty; /* pseudo-tty (PTY) stream info for LTERM */
|
||||
struct LtermProcess ltermProcess; /* LTERM process structure */
|
||||
struct LtermInput ltermInput; /* LTERM input structure */
|
||||
struct LtermOutput ltermOutput; /* LTERM output structure */
|
||||
};
|
||||
|
||||
/* LTERM global variables */
|
||||
typedef struct {
|
||||
int initialized; /* Initialization flag */
|
||||
struct lterms *termList[MAXTERM]; /* List of LTERMS */
|
||||
MUTEX_DECLARE(listMutex); /* Thread lock to access to LTERM list */
|
||||
UNICHAR metaDelimiter; /* Meta command delimiter (usually :) */
|
||||
char escapeChars[LTERM_XML_ESCAPES+1]; /* String of chars escaped in XML */
|
||||
UNICHAR escapeSeq[LTERM_XML_ESCAPES][LTERM_MAXCHAR_ESCAPE+1];
|
||||
/* XML character escape sequences */
|
||||
int escapeLen[LTERM_XML_ESCAPES]; /* XML char. escape sequence lengths */
|
||||
} LtermGlobal;
|
||||
|
||||
extern LtermGlobal ltermGlobal;
|
||||
|
||||
|
||||
/* Visible prototypes */
|
||||
|
||||
/* ltermIO.c */
|
||||
int ltermInterruptOutput(struct lterms *lts);
|
||||
int ltermSendLine(struct lterms *lts, UNICHAR uch,
|
||||
int echoControl, int completionCode);
|
||||
int ltermRead(struct lterms *lts, struct LtermRead *ltr, int timeout);
|
||||
|
||||
/* ltermInput.c */
|
||||
int ltermPlainTextInput(struct lterms *lts,
|
||||
const UNICHAR *buf, int count, int *opcodes);
|
||||
int ltermCancelCompletion(struct lterms *lts);
|
||||
int ltermInsertChar(struct LtermInput *lti, UNICHAR uch);
|
||||
void ltermSwitchToRawMode(struct lterms *lts);
|
||||
void ltermClearInputLine(struct lterms *lts);
|
||||
int ltermDeleteGlyphs(struct LtermInput *lti, int count);
|
||||
int ltermSendData(struct lterms *lts, const UNICHAR *buf, int count);
|
||||
int ltermSendChar(struct lterms *lts, const char *buf, int count);
|
||||
|
||||
/* ltermOutput.c */
|
||||
int ltermProcessOutput(struct lterms *lts, int *opcodes, int *opvals,
|
||||
int *oprow);
|
||||
int ltermReceiveData(struct lterms *lts, int readERR);
|
||||
void ltermClearOutputLine(struct lterms *lts);
|
||||
int ltermClearOutputScreen(struct lterms *lts);
|
||||
int ltermSwitchToStreamMode(struct lterms *lts, int streamOpcodes,
|
||||
const UNICHAR *streamTerminator);
|
||||
int ltermSwitchToScreenMode(struct lterms *lts);
|
||||
int ltermSwitchToLineMode(struct lterms *lts);
|
||||
|
||||
/* ltermEscape.c */
|
||||
int ltermProcessEscape(struct lterms *lts, const UNICHAR *buf,
|
||||
int count, const UNISTYLE *style, int *consumed,
|
||||
int *opcodes, int *opvals, int *oprow);
|
||||
int ltermInsDelEraseChar(struct lterms *lts, int count, int action);
|
||||
int ltermInsDelEraseLine(struct lterms *lts, int count, int row, int action);
|
||||
|
||||
#endif /* _LTERMPRIVATE_H */
|
|
@ -0,0 +1,549 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is lineterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License (the "GPL"), in which case
|
||||
* the provisions of the GPL are applicable instead of
|
||||
* those above. If you wish to allow use of your version of this
|
||||
* file only under the terms of the GPL and not to allow
|
||||
* others to use your version of this file under the MPL, indicate
|
||||
* your decision by deleting the provisions above and replace them
|
||||
* with the notice and other provisions required by the GPL.
|
||||
* If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/* ptystream.c: pseudo-TTY stream implementation
|
||||
* CPP options:
|
||||
* LINUX: for Linux2.0/glibc
|
||||
* SOLARIS: for Solaris2.6
|
||||
* BSDFAMILY: for FreeBSD, ...
|
||||
* NOERRMSG: for suppressing all error messages
|
||||
* USE_NSPR_BASE: use NSPR to log error messages (defines NOERRMSG as well)
|
||||
* DEBUG_LTERM: for printing some debugging output to STDERR
|
||||
*/
|
||||
|
||||
/* system header files */
|
||||
|
||||
|
||||
#ifdef LINUX
|
||||
#define _BSD_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
#if defined(LINUX) || defined(BSDFAMILY) || defined(HPUX11)
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef USE_NSPR_BASE
|
||||
#include "prlog.h"
|
||||
#define NOERRMSG 1
|
||||
#endif
|
||||
|
||||
/* public declarations */
|
||||
#include "ptystream.h"
|
||||
|
||||
/* private declarations */
|
||||
static int openPTY(struct ptys *ptyp, int noblock);
|
||||
static int attachToTTY(struct ptys *ptyp, int errfd, int noecho);
|
||||
static int setTTYAttr(int ttyFD, int noecho);
|
||||
static void pty_error(const char *errmsg, const char *errmsg2);
|
||||
|
||||
/* parameters */
|
||||
#define C_CTL_C '\003' /* ^C */
|
||||
#define C_CTL_D '\004' /* ^D */
|
||||
#define C_CTL_H '\010' /* ^H */
|
||||
#define C_CTL_O '\017' /* ^O */
|
||||
#define C_CTL_Q '\021' /* ^Q */
|
||||
#define C_CTL_R '\022' /* ^R */
|
||||
#define C_CTL_S '\023' /* ^S */
|
||||
#define C_CTL_U '\025' /* ^U */
|
||||
#define C_CTL_V '\026' /* ^V */
|
||||
#define C_CTL_W '\027' /* ^W */
|
||||
#define C_CTL_Y '\031' /* ^Y */
|
||||
#define C_CTL_Z '\032' /* ^Z */
|
||||
#define C_CTL_BSL '\034' /* ^\ */
|
||||
|
||||
/* Disable special character functions */
|
||||
#ifdef _POSIX_VDISABLE
|
||||
#define VDISABLE _POSIX_VDISABLE
|
||||
#else
|
||||
#define VDISABLE 255
|
||||
#endif
|
||||
|
||||
#define PTYCHAR1 "pqrstuvwxyzPQRSTUVWXYZ"
|
||||
#define PTYCHAR2 "0123456789abcdef"
|
||||
|
||||
|
||||
/* creates a new pseudo-TTY */
|
||||
int pty_create(struct ptys *ptyp, char *const argv[],
|
||||
int rows, int cols, int x_pixels, int y_pixels,
|
||||
int errfd, int noblock, int noecho, int noexport, int debug)
|
||||
{
|
||||
pid_t child_pid;
|
||||
int errfd2;
|
||||
|
||||
if (!ptyp) {
|
||||
pty_error("pty_create: NULL value for PTY structure", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set debug flag */
|
||||
ptyp->debug = debug;
|
||||
|
||||
#ifdef DEBUG_LTERM
|
||||
if (ptyp->debug)
|
||||
fprintf(stderr, "00-pty_create: errfd=%d, noblock=%d, noecho=%d, noexport=%d\n",
|
||||
errfd, noblock, noecho, noexport);
|
||||
#endif
|
||||
|
||||
/* Open PTY */
|
||||
if (openPTY(ptyp, noblock) == -1) return -1;
|
||||
|
||||
#ifndef BSDFAMILY
|
||||
/* Set default TTY size */
|
||||
if (pty_resize(ptyp, rows, cols, x_pixels, y_pixels) != 0)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
if (errfd >= -1) {
|
||||
/* No STDERR pipe */
|
||||
ptyp->errpipeFD = -1;
|
||||
errfd2 = errfd;
|
||||
|
||||
} else {
|
||||
/* Create pipe to handle STDERR output */
|
||||
int pipeFD[2];
|
||||
|
||||
if (pipe(pipeFD) == -1) {
|
||||
pty_error("pty_create: STDERR pipe creation failed", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy pipe file descriptors */
|
||||
ptyp->errpipeFD = pipeFD[0];
|
||||
errfd2 = pipeFD[1];
|
||||
}
|
||||
|
||||
/* Fork a child process (VFORK) */
|
||||
child_pid = vfork();
|
||||
if (child_pid < 0) {
|
||||
pty_error("pty_create: vfork failed", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptyp->pid = child_pid;
|
||||
|
||||
#ifdef DEBUG_LTERM
|
||||
if (ptyp->debug)
|
||||
fprintf(stderr, "00-pty_create: Fork child pid = %d, initially attached to %s\n",
|
||||
child_pid, ttyname(0));
|
||||
#endif
|
||||
|
||||
if (child_pid == 0) {
|
||||
/* Child process */
|
||||
|
||||
/* Attach child to slave TTY */
|
||||
if (attachToTTY(ptyp, errfd2, noecho) == -1) return -1;
|
||||
|
||||
#ifdef BSDFAMILY
|
||||
/* Set default TTY size */
|
||||
if (pty_resize(NULL, rows, cols, x_pixels, y_pixels) != 0)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
/* Set default signal handling */
|
||||
signal(SIGINT, SIG_DFL);
|
||||
signal(SIGQUIT, SIG_DFL);
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
|
||||
/* Set ignore signal handling */
|
||||
signal(SIGTSTP, SIG_IGN);
|
||||
signal(SIGTTIN, SIG_IGN);
|
||||
signal(SIGTTOU, SIG_IGN);
|
||||
|
||||
if (argv != NULL) {
|
||||
/* Execute specified command with arguments */
|
||||
if (noexport)
|
||||
execve(argv[0], argv, NULL);
|
||||
else
|
||||
execvp(argv[0], argv);
|
||||
|
||||
pty_error("Error in executing command ", argv[0]);
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
/* Execute $SHELL or /bin/sh by default */
|
||||
char *shell = (char *) getenv("SHELL");
|
||||
|
||||
if ((shell == NULL) || (*shell == '\0'))
|
||||
shell = "/bin/sh";
|
||||
|
||||
if (noexport)
|
||||
execle(shell, shell, NULL, NULL);
|
||||
else
|
||||
execlp(shell, shell, NULL);
|
||||
|
||||
pty_error("pty_create: Error in executing command ", shell);
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (errfd < -1) {
|
||||
/* Close write end of STDERR pipe in parent process */
|
||||
close(errfd2);
|
||||
}
|
||||
|
||||
/* Return from parent */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* closes a pseudo-TTY */
|
||||
int pty_close(struct ptys *ptyp)
|
||||
{
|
||||
if (!ptyp) {
|
||||
pty_error("pty_close: NULL value for PTY structure", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
kill(ptyp->pid, SIGKILL);
|
||||
ptyp->pid = 0;
|
||||
|
||||
close(ptyp->ptyFD);
|
||||
ptyp->ptyFD = -1;
|
||||
|
||||
if (ptyp->errpipeFD >= 0) {
|
||||
close(ptyp->errpipeFD);
|
||||
ptyp->errpipeFD = -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* resizes a PTY; if ptyp is null, resizes file desciptor 0,
|
||||
* returning 0 on success and -1 on error.
|
||||
*/
|
||||
int pty_resize(struct ptys *ptyp, int rows, int cols,
|
||||
int xpix, int ypix)
|
||||
{
|
||||
struct winsize wsize;
|
||||
int fd = ptyp ? ptyp->ptyFD : 0;
|
||||
|
||||
/* Set TTY window size */
|
||||
wsize.ws_row = (unsigned short) rows;
|
||||
wsize.ws_col = (unsigned short) cols;
|
||||
wsize.ws_xpixel = (unsigned short) xpix;
|
||||
wsize.ws_ypixel = (unsigned short) ypix;
|
||||
|
||||
if (ioctl(fd, TIOCSWINSZ, &wsize ) == -1) {
|
||||
pty_error("pty_resize: Failed to set TTY window size", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int openPTY(struct ptys *ptyp, int noblock)
|
||||
{
|
||||
char ptyName[PTYNAMELEN+1], ttyName[PTYNAMELEN+1];
|
||||
|
||||
int plen, tlen, ptyFD, letIndex, devIndex;
|
||||
|
||||
(void) strncpy(ptyName, "/dev/pty??", PTYNAMELEN+1);
|
||||
(void) strncpy(ttyName, "/dev/tty??", PTYNAMELEN+1);
|
||||
|
||||
plen = strlen(ptyName);
|
||||
tlen = strlen(ttyName);
|
||||
|
||||
assert(ptyp != NULL);
|
||||
assert(plen <= PTYNAMELEN);
|
||||
assert(tlen <= PTYNAMELEN);
|
||||
|
||||
ptyFD = -1;
|
||||
letIndex = 0;
|
||||
while (PTYCHAR1[letIndex] && (ptyFD == -1)) {
|
||||
ttyName[tlen - 2] =
|
||||
ptyName[plen - 2] = PTYCHAR1 [letIndex];
|
||||
|
||||
devIndex = 0;
|
||||
while (PTYCHAR2[devIndex] && (ptyFD == -1)) {
|
||||
ttyName [tlen - 1] =
|
||||
ptyName [plen - 1] = PTYCHAR2 [devIndex];
|
||||
|
||||
if ((ptyFD = open(ptyName, O_RDWR)) >= 0) {
|
||||
if (access(ttyName, R_OK | W_OK) != 0) {
|
||||
close(ptyFD);
|
||||
ptyFD = -1;
|
||||
}
|
||||
}
|
||||
devIndex++;
|
||||
}
|
||||
|
||||
letIndex++;
|
||||
}
|
||||
|
||||
if (ptyFD == -1) {
|
||||
pty_error("openPTY: Unable to open pseudo-tty", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (noblock) {
|
||||
/* Set non-blocking mode */
|
||||
fcntl(ptyFD, F_SETFL, O_NDELAY);
|
||||
}
|
||||
|
||||
strncpy(ptyp->ptydev, ptyName, PTYNAMELEN+1);
|
||||
strncpy(ptyp->ttydev, ttyName, PTYNAMELEN+1);
|
||||
|
||||
ptyp->ptyFD = ptyFD;
|
||||
|
||||
#ifdef DEBUG_LTERM
|
||||
if (ptyp->debug)
|
||||
fprintf(stderr, "00-openPTY: Opened pty %s on fd %d\n", ptyName, ptyFD);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* attaches new process to slave TTY */
|
||||
static int attachToTTY(struct ptys *ptyp, int errfd, int noecho)
|
||||
{
|
||||
int ttyFD, fd, fdMax;
|
||||
pid_t sid;
|
||||
gid_t gid;
|
||||
unsigned int ttyMode = 0622;
|
||||
|
||||
assert(ptyp != NULL);
|
||||
|
||||
/* Create new session */
|
||||
sid = setsid();
|
||||
|
||||
#ifdef DEBUG_LTERM
|
||||
if (ptyp->debug)
|
||||
fprintf(stderr, "00-attachToTTY: Returned %d from setsid\n", sid);
|
||||
#endif
|
||||
|
||||
if (sid < 0) {
|
||||
#ifndef NOERRMSG
|
||||
perror("attachToTTY");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((ttyFD = open(ptyp->ttydev, O_RDWR)) < 0) {
|
||||
pty_error("attachToTTY: Unable to open slave tty ", ptyp->ttydev );
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LTERM
|
||||
if (ptyp->debug)
|
||||
fprintf(stderr,"00-attachToTTY: Attaching process %d to TTY %s on fd %d\n",
|
||||
getpid(), ptyp->ttydev, ttyFD);
|
||||
#endif
|
||||
|
||||
/* Change TTY ownership and permissions*/
|
||||
gid = getgid();
|
||||
|
||||
fchown(ttyFD, getuid(), gid);
|
||||
fchmod(ttyFD, ttyMode);
|
||||
|
||||
/* Set TTY attributes (this actually seems to be harmful; so commented out!)
|
||||
*/
|
||||
/* if (setTTYAttr(ttyFD, noecho) == -1) return -1; */
|
||||
|
||||
/* Redirect to specified descriptor or to PTY */
|
||||
if (errfd >= 0) {
|
||||
/* Redirect STDERR to specified file descriptor */
|
||||
if (dup2(errfd, 2) == -1) {
|
||||
pty_error("attachToTTY: Failed dup2 for specified stderr", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Redirect STDERR to PTY */
|
||||
if (dup2(ttyFD, 2) == -1) {
|
||||
pty_error("attachToTTY: Failed dup2 for default stderr", NULL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Redirect STDIN and STDOUT to PTY */
|
||||
if (dup2(ttyFD, 0) == -1) {
|
||||
pty_error("attachToTTY: Failed dup2 for stdin", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dup2(ttyFD, 1) == -1) {
|
||||
pty_error("attachToTTY: Failed dup2 for stdout", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Close all other file descriptors in child process */
|
||||
fdMax = sysconf(_SC_OPEN_MAX);
|
||||
for (fd = 3; fd < fdMax; fd++)
|
||||
close(fd);
|
||||
|
||||
#ifdef BSDFAMILY
|
||||
ioctl(0, TIOCSCTTY, 0);
|
||||
#endif
|
||||
|
||||
/* Set process group */
|
||||
tcsetpgrp(0, sid);
|
||||
|
||||
/* close(open(ptyp->ttydev, O_RDWR, 0)); */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* sets slave TTY attributes (NOT USED) */
|
||||
static int setTTYAttr(int ttyFD, int noecho)
|
||||
{
|
||||
struct termios tios;
|
||||
|
||||
/* Get TTY attributes */
|
||||
if (tcgetattr(ttyFD, &tios ) == -1) {
|
||||
#ifndef NOERRMSG
|
||||
perror("setTTYAttr");
|
||||
#endif
|
||||
pty_error("setTTYattr: Failed to get TTY attributes", NULL);
|
||||
return -1;
|
||||
}
|
||||
memset(&tios, 0, sizeof(struct termios));
|
||||
|
||||
/* TERMIOS settings for TTY */
|
||||
tios.c_cc[VINTR] = C_CTL_C;
|
||||
tios.c_cc[VQUIT] = C_CTL_BSL;
|
||||
tios.c_cc[VERASE] = C_CTL_H;
|
||||
tios.c_cc[VKILL] = C_CTL_U;
|
||||
tios.c_cc[VEOF] = C_CTL_D;
|
||||
tios.c_cc[VEOL] = VDISABLE;
|
||||
tios.c_cc[VEOL2] = VDISABLE;
|
||||
#ifdef SOLARIS
|
||||
tios.c_cc[VSWTCH] = VDISABLE;
|
||||
#endif
|
||||
tios.c_cc[VSTART] = C_CTL_Q;
|
||||
tios.c_cc[VSTOP] = C_CTL_S;
|
||||
tios.c_cc[VSUSP] = C_CTL_Z;
|
||||
#ifndef HPUX11
|
||||
tios.c_cc[VREPRINT] = C_CTL_R;
|
||||
tios.c_cc[VDISCARD] = C_CTL_O;
|
||||
#endif /* !HPUX11 */
|
||||
tios.c_cc[VWERASE] = C_CTL_W;
|
||||
tios.c_cc[VLNEXT] = C_CTL_V;
|
||||
|
||||
tios.c_cc[VMIN] = 1; /* Wait for at least 1 char of input */
|
||||
tios.c_cc[VTIME] = 0; /* Wait indefinitely (block) */
|
||||
|
||||
#ifdef BSDFAMILY
|
||||
tios.c_iflag = (BRKINT | IGNPAR | ICRNL | IXON
|
||||
| IMAXBEL);
|
||||
tios.c_oflag = (OPOST | ONLCR);
|
||||
|
||||
#else /* !BSDFAMILY */
|
||||
/* Input modes */
|
||||
tios.c_iflag &= ~IUCLC; /* Disable map of upper case input to lower*/
|
||||
tios.c_iflag &= ~IGNBRK; /* Do not ignore break */
|
||||
tios.c_iflag &= ~BRKINT; /* Do not signal interrupt on break either */
|
||||
|
||||
/* Output modes */
|
||||
tios.c_oflag &= ~OPOST; /* Disable output postprocessing */
|
||||
tios.c_oflag &= ~ONLCR; /* Disable mapping of NL to CR-NL on output */
|
||||
tios.c_oflag &= ~OLCUC; /* Disable map of lower case output to upper */
|
||||
/* No output delays */
|
||||
tios.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
|
||||
|
||||
#endif /* !BSDFAMILY */
|
||||
|
||||
/* control modes */
|
||||
tios.c_cflag |= (CS8 | CREAD);
|
||||
|
||||
/* line discipline modes */
|
||||
if (noecho)
|
||||
tios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHOKE | ECHONL | ECHOPRT |
|
||||
ECHOCTL); /* Disable echo */
|
||||
else
|
||||
tios.c_lflag |= (ECHO | ECHOE | ECHOK | ECHOKE | ECHONL | ECHOPRT |
|
||||
ECHOCTL); /* Enable echo */
|
||||
|
||||
tios.c_lflag |= ISIG; /* Enable signals */
|
||||
tios.c_lflag |= ICANON; /* Enable erase/kill and eof processing */
|
||||
|
||||
/* NOTE: tcsh does not echo to be turned off if TERM=xterm;
|
||||
setting TERM=dumb allows echo to be turned off,
|
||||
but command completion is turned off as well */
|
||||
|
||||
/* Set TTY attributes */
|
||||
cfsetospeed (&tios, B38400);
|
||||
cfsetispeed (&tios, B38400);
|
||||
|
||||
if (tcsetattr(ttyFD, TCSADRAIN, &tios ) == -1) {
|
||||
#ifndef NOERRMSG
|
||||
perror("setTTYAttr");
|
||||
#endif
|
||||
pty_error("setTTYattr: Failed to set TTY attributes", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* displays an error message, optionally concatenated with another */
|
||||
static void pty_error(const char *errmsg, const char *errmsg2) {
|
||||
|
||||
#ifndef NOERRMSG
|
||||
if (errmsg != NULL) {
|
||||
if (errmsg2 != NULL) {
|
||||
fprintf(stderr, "%s%s\n", errmsg, errmsg2);
|
||||
} else {
|
||||
fprintf(stderr, "%s\n", errmsg);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifdef USE_NSPR_BASE
|
||||
if (errmsg != NULL) {
|
||||
if (errmsg2 != NULL) {
|
||||
PR_LogPrint("%s%s\n", errmsg, errmsg2);
|
||||
} else {
|
||||
PR_LogPrint("%s\n", errmsg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is lineterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License (the "GPL"), in which case
|
||||
* the provisions of the GPL are applicable instead of
|
||||
* those above. If you wish to allow use of your version of this
|
||||
* file only under the terms of the GPL and not to allow
|
||||
* others to use your version of this file under the MPL, indicate
|
||||
* your decision by deleting the provisions above and replace them
|
||||
* with the notice and other provisions required by the GPL.
|
||||
* If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/* ptystream.h: pseudo-TTY stream header
|
||||
* (used by ltermPrivate.h)
|
||||
*/
|
||||
|
||||
#ifndef _PTYSTREAM_H
|
||||
|
||||
#define _PTYSTREAM_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PTYNAMELEN 10 /* Length of PTY/TTY device name: /dev/pty?? */
|
||||
|
||||
struct ptys { /* PTY structure */
|
||||
|
||||
int ptyFD; /* PTY file descriptor (bi-directional) */
|
||||
int errpipeFD; /* stderr pipe file descriptor (-1, if none) */
|
||||
|
||||
long pid; /* PTY child PID */
|
||||
|
||||
int debug; /* Debugging flag */
|
||||
|
||||
char ptydev[PTYNAMELEN+1]; /* PTY (master) name */
|
||||
char ttydev[PTYNAMELEN+1]; /* TTY (slave) name */
|
||||
};
|
||||
|
||||
/* creates a new pseudo-TTY (PTY) and also a new process attached to
|
||||
* it to execute the command line contained in array ARGV.
|
||||
* The PTY details are stored in the PTY structure PTYP.
|
||||
* ROWS, COLS contain the initial no. of rows/columns.
|
||||
* X_PIXELS, Y_PIXELS contain the initial screen size in pixels
|
||||
* (may be set to zero if screen size is unknown).
|
||||
* ERRFD is the file descriptor to which the STDERR output of the
|
||||
* child process is directed.
|
||||
* If ERRFD == -1, then the STDERR output is redirected to STDOUT.
|
||||
* If ERRFD == -2, then a new pipe is created and STDERR is redirected
|
||||
* through it.
|
||||
* If NOBLOCK is true, enable non-blocking I/O on PTY.
|
||||
* If NOECHO is true, tty echoing is turned off.
|
||||
* If NOEXPORT is true, then the current environment is not exported
|
||||
* to the new process.
|
||||
* If DEBUG_LTERM is true, debugging messages are printed to STDERR.
|
||||
* Returns 0 on success and -1 on error.
|
||||
*/
|
||||
int pty_create(struct ptys *ptyp, char *const argv[],
|
||||
int rows, int cols, int x_pixels, int y_pixels,
|
||||
int errfd, int noblock, int noecho, int noexport, int debug);
|
||||
|
||||
/* resizes a PTY; if ptyp is null, resizes file desciptor 0,
|
||||
* returning 0 on success and -1 on error.
|
||||
*/
|
||||
int pty_resize(struct ptys *ptyp, int rows, int cols,
|
||||
int xpix, int ypix);
|
||||
|
||||
/* closes the PTY and kills the associated child process, if still alive.
|
||||
* Also close STDERR pipe, if open.
|
||||
* Returns 0 on success and -1 on error.
|
||||
*/
|
||||
int pty_close(struct ptys *ptyp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PTYSTREAM_H */
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is lineterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License (the "GPL"), in which case
|
||||
* the provisions of the GPL are applicable instead of
|
||||
* those above. If you wish to allow use of your version of this
|
||||
* file only under the terms of the GPL and not to allow
|
||||
* others to use your version of this file under the MPL, indicate
|
||||
* your decision by deleting the provisions above and replace them
|
||||
* with the notice and other provisions required by the GPL.
|
||||
* If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/* tracelog.c: Tracing/logging module implementation
|
||||
*/
|
||||
|
||||
/* public declarations */
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "unistring.h"
|
||||
#include "tracelog.h"
|
||||
|
||||
#ifdef USE_NSPR_BASE
|
||||
#include "prlog.h"
|
||||
#endif
|
||||
|
||||
/* private declarations */
|
||||
|
||||
/* TRACELOG global variable structure */
|
||||
TlogGlobal tlogGlobal;
|
||||
|
||||
/** Initializes all TRACELOG operations and sets filestream for trace/log
|
||||
* output. Setting filestream to NULL suppresses all output.
|
||||
* (documented in tracelog.h)
|
||||
*/
|
||||
void tlog_init(FILE* fileStream)
|
||||
{
|
||||
int imodule;
|
||||
|
||||
#ifdef DEBUG_LTERM
|
||||
fprintf(stderr, "tlog_init:\n");
|
||||
#endif
|
||||
|
||||
/* Error output stream */
|
||||
tlogGlobal.errorStream = fileStream;
|
||||
|
||||
/* Debugging is disabled initially */
|
||||
tlogGlobal.debugOn = 0;
|
||||
|
||||
for (imodule=0; imodule<TLOG_MAXMODULES; imodule++) {
|
||||
tlogGlobal.messageLevel[imodule] = 0;
|
||||
tlogGlobal.functionList[imodule] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Sets TRACELOG display levels for module IMODULE
|
||||
* (documented in tracelog.h)
|
||||
* @return 0 on success, or -1 on error.
|
||||
*/
|
||||
int tlog_set_level(int imodule, int messageLevel, const char *functionList)
|
||||
{
|
||||
int j;
|
||||
|
||||
#ifdef DEBUG_LTERM
|
||||
fprintf(stderr, "tlog_set_level:%d, %d\n", imodule, messageLevel);
|
||||
#endif
|
||||
|
||||
if ((imodule < 0) || (imodule >= TLOG_MAXMODULES))
|
||||
return -1;
|
||||
|
||||
/* Message level */
|
||||
tlogGlobal.messageLevel[imodule] = messageLevel;
|
||||
|
||||
if (messageLevel > 0) {
|
||||
tlog_warning("tlog_set_level: module %d, messageLevel=%d\n",
|
||||
imodule, messageLevel);
|
||||
}
|
||||
|
||||
/* Free function list string */
|
||||
free(tlogGlobal.functionList[imodule]);
|
||||
|
||||
if (functionList == NULL) {
|
||||
tlogGlobal.functionList[imodule] = NULL;
|
||||
|
||||
} else {
|
||||
/* Duplicate function list string */
|
||||
int slen = strlen(functionList);
|
||||
char *stem;
|
||||
|
||||
if (slen > 1000) slen = 1000;
|
||||
|
||||
stem = malloc((unsigned int) slen+3);
|
||||
strncpy(&stem[1], functionList, (unsigned int) slen);
|
||||
stem[0] = ':';
|
||||
stem[slen+1] = ':';
|
||||
stem[slen+2] = '\0';
|
||||
|
||||
tlogGlobal.functionList[imodule] = stem;
|
||||
|
||||
if (messageLevel > 0) {
|
||||
tlog_warning("tlog_set_level: module %d, functionList=\"%s\"\n",
|
||||
imodule, tlogGlobal.functionList[imodule]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Turn on debugging only if needed */
|
||||
tlogGlobal.debugOn = 0;
|
||||
|
||||
if (tlogGlobal.errorStream != NULL) {
|
||||
for (j=0; j<TLOG_MAXMODULES; j++) {
|
||||
if ((tlogGlobal.messageLevel[j] > 0) ||
|
||||
(tlogGlobal.functionList != NULL))
|
||||
tlogGlobal.debugOn = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Determines whether trace/log message is to be displayed for specified
|
||||
* module at specified message level.
|
||||
* @return 1 (true) if message should be displayed, 0 otherwise
|
||||
*/
|
||||
int tlog_test(int imodule, char *procstr, int level)
|
||||
{
|
||||
if (tlogGlobal.errorStream == NULL)
|
||||
return 0;
|
||||
|
||||
if ((imodule < 0) || (imodule >= TLOG_MAXMODULES))
|
||||
return 0;
|
||||
|
||||
if ( (level%10 <= tlogGlobal.messageLevel[imodule]%10) &&
|
||||
( (level <= tlogGlobal.messageLevel[imodule]) ||
|
||||
((tlogGlobal.functionList[imodule] != NULL) &&
|
||||
( (strstr(tlogGlobal.functionList[imodule],procstr) != NULL) ||
|
||||
(strstr(procstr,tlogGlobal.functionList[imodule]) != NULL)) ) )) {
|
||||
/* Display message */
|
||||
#if defined(USE_NSPR_BASE) && !defined(DEBUG_LTERM)
|
||||
PR_LogPrint("%s%2d: ", procstr, level);
|
||||
#else
|
||||
fprintf(tlogGlobal.errorStream, "%s%2d: ", procstr, level);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Displays an error message on the TRACELOG filestream */
|
||||
void tlog_message(const char *format, ...)
|
||||
{
|
||||
va_list ap; /* pointer to variable length argument list */
|
||||
|
||||
if (tlogGlobal.errorStream == NULL)
|
||||
return;
|
||||
|
||||
va_start(ap, format); /* make ap point to first unnamed arg */
|
||||
vfprintf(tlogGlobal.errorStream, format, ap);
|
||||
va_end(ap); /* clean up */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/** Displays a warning message on the TRACELOG filestream */
|
||||
void tlog_warning(const char *format, ...)
|
||||
{
|
||||
va_list ap; /* pointer to variable length argument list */
|
||||
|
||||
if ((tlogGlobal.errorStream == NULL) || !tlogGlobal.debugOn)
|
||||
return;
|
||||
|
||||
va_start(ap, format); /* make ap point to first unnamed arg */
|
||||
vfprintf(tlogGlobal.errorStream, format, ap);
|
||||
va_end(ap); /* clean up */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _UNISTRING_H
|
||||
#define MAXCOL 1024 /* Maximum columns in line buffer */
|
||||
|
||||
/** Displays an Unicode message on the TRACELOG filestream */
|
||||
void tlog_unichar(const UNICHAR *buf, int count)
|
||||
{
|
||||
if (tlogGlobal.errorStream == NULL)
|
||||
return;
|
||||
|
||||
#if defined(USE_NSPR_BASE) && !defined(DEBUG_LTERM)
|
||||
PR_LogPrint("U(%d):\n", count);
|
||||
#else
|
||||
fprintf(tlogGlobal.errorStream, "U(%d): ", count);
|
||||
ucsprint(tlogGlobal.errorStream, buf, count);
|
||||
fprintf(tlogGlobal.errorStream, "\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is lineterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License (the "GPL"), in which case
|
||||
* the provisions of the GPL are applicable instead of
|
||||
* those above. If you wish to allow use of your version of this
|
||||
* file only under the terms of the GPL and not to allow
|
||||
* others to use your version of this file under the MPL, indicate
|
||||
* your decision by deleting the provisions above and replace them
|
||||
* with the notice and other provisions required by the GPL.
|
||||
* If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/* tracelog.h: Tracing/logging module header
|
||||
* CPP options:
|
||||
* DEBUG_LTERM: to enable debugging output
|
||||
* _UNISTRING_H: for unicode messages compatible with "unistring.h"
|
||||
*/
|
||||
|
||||
#ifndef _TRACELOG_H
|
||||
|
||||
#define _TRACELOG_H 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Trace/log macros (to be used after call to tlog_init to initialize):
|
||||
* TLOG_ERROR: error message macro, e.g.,
|
||||
* TLOG_ERROR(format, val1, val2);
|
||||
* TOG_WARNING: warning message macro, e.g.,
|
||||
* TLOG_WARNING(format, val1, val2);
|
||||
* TLOG_PRINT: message logging macro, e.g., (no terminating semicolon)
|
||||
* TLOG_PRINT(10,(format, val1, val2));
|
||||
* (if UNISTRING module is being used)
|
||||
* TLOG_UNICHAR: Unicode string logging macro, e.g., (no terminating semicolon)
|
||||
* TLOG_UNICHAR(10,(label,str,count));
|
||||
*/
|
||||
|
||||
/* Max. number of modules recognized by TRACELOG */
|
||||
# define TLOG_MAXMODULES 50
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializes all TRACELOG operations;
|
||||
* needs to be called before any other trace/log calls.
|
||||
*
|
||||
* FILESTREAM is the file stream to be used to print messages.
|
||||
*
|
||||
* Normally, only error messages are sent to FILESTREAM.
|
||||
* If FILESTREAM is null, all output, including error output, is suppressed.
|
||||
*/
|
||||
|
||||
void tlog_init(FILE* fileStream);
|
||||
|
||||
/** Set diagnostic message display level for module no. IMODULE.
|
||||
* (0 <= IMODULE < TLOG_MAXMODULES)
|
||||
*
|
||||
* MESSAGELEVEL (>=0) specifies the diagnostic message display level:
|
||||
* only diagnostic messages with level values >= MESSAGELEVEL are printed
|
||||
* (For example, level 10, 11, ...: outermost level;
|
||||
* level 20, 21, ...: next inner level;
|
||||
* ...
|
||||
* level 50, 51, ...: innermost level)
|
||||
*
|
||||
* The message SUBLEVEL threshold is defined as MESSAGELEVEL%10
|
||||
* (ranging from 0 to 9).
|
||||
* Only those diagnostic messages with sublevel values >= SUBLEVEL threshold
|
||||
* are displayed
|
||||
* Usually, the SUBLEVEL threshold values are interpreted as
|
||||
* 0 => print single message per selected procedure.
|
||||
* 1...9 => print only messages upto selected sublevel.
|
||||
*
|
||||
* Setting MESSAGELEVEL to zero and FUNCTIONLIST to null for all modules
|
||||
* disables debugging and printing of warning messages.
|
||||
* (This is the initial configuration following the call to lterm_init.)
|
||||
* Setting MESSAGELEVEL to 1 for atleast one module enables debugging and
|
||||
* causes warning messages for all modules to be printed.
|
||||
*
|
||||
* FUNCTIONLIST is a colon-separated string of function names, e.g.,
|
||||
* "func_a:func_b".
|
||||
* Trace/log messages for functions in this list are always output
|
||||
* if debugging is enabled provided the sublevel values exceed the threshold,
|
||||
* regardless of full message level values.
|
||||
* If FUNCTIONLIST contains a single method name without a class name, or a
|
||||
* class name without a method name, then the missing portion is assumed
|
||||
* to be wild-carded.
|
||||
*
|
||||
* Returns 0 on success, -1 otherwise (i.e., for invalid module numbers)
|
||||
*/
|
||||
|
||||
int tlog_set_level(int imodule, int messageLevel, const char *functionList);
|
||||
|
||||
int tlog_test(int imodule, char *procname, int level);
|
||||
void tlog_message(const char *format, ...);
|
||||
void tlog_warning(const char *format, ...);
|
||||
|
||||
/* TRACELOG global variables */
|
||||
typedef struct {
|
||||
FILE *errorStream; /* file stream for logging */
|
||||
int debugOn;
|
||||
int messageLevel[TLOG_MAXMODULES];
|
||||
char *functionList[TLOG_MAXMODULES]; /* list of functions to be debugged */
|
||||
} TlogGlobal;
|
||||
|
||||
extern TlogGlobal tlogGlobal;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_NSPR_BASE) && !defined(DEBUG_LTERM)
|
||||
#include "prlog.h"
|
||||
#define TLOG_MESSAGE PR_LogPrint
|
||||
#else
|
||||
#define TLOG_MESSAGE tlog_message
|
||||
#endif
|
||||
|
||||
#define TLOG_ERROR TLOG_MESSAGE
|
||||
|
||||
#define TLOG_WARNING if (tlogGlobal.debugOn) TLOG_MESSAGE
|
||||
|
||||
#define TLOG_PRINT(imodule,procname,level,args) \
|
||||
do { \
|
||||
if (tlogGlobal.debugOn && tlog_test(imodule,":" #procname ":",level)) { \
|
||||
TLOG_MESSAGE args; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#ifdef _UNISTRING_H
|
||||
void tlog_unichar(const UNICHAR *buf, int count);
|
||||
|
||||
#define TLOG_UNICHAR(imodule,procname,level,args) \
|
||||
do { \
|
||||
if (tlogGlobal.debugOn && tlog_test(imodule,":" #procname ":",level)) { \
|
||||
tlog_unichar args; \
|
||||
} \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#endif /* _TRACELOG_H */
|
|
@ -0,0 +1,409 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is lineterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License (the "GPL"), in which case
|
||||
* the provisions of the GPL are applicable instead of
|
||||
* those above. If you wish to allow use of your version of this
|
||||
* file only under the terms of the GPL and not to allow
|
||||
* others to use your version of this file under the MPL, indicate
|
||||
* your decision by deleting the provisions above and replace them
|
||||
* with the notice and other provisions required by the GPL.
|
||||
* If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/* unistring.c: Unicode string operations implementation */
|
||||
|
||||
/* public declarations */
|
||||
#include "unistring.h"
|
||||
|
||||
/* private declarations */
|
||||
|
||||
/** Encodes Unicode string US with NUS characters into UTF8 string S with
|
||||
* upto NS characters, returning the number of REMAINING Unicode characters
|
||||
* and the number of ENCODED Utf8 characters
|
||||
*/
|
||||
void ucstoutf8(const UNICHAR* us, int nus, char* s, int ns,
|
||||
int* remaining, int* encoded)
|
||||
{
|
||||
int j, k;
|
||||
|
||||
j = 0;
|
||||
k = 0;
|
||||
while ((j < ns) && (k < nus)) {
|
||||
UNICHAR uch = us[k++];
|
||||
|
||||
if (uch < 0x0080) {
|
||||
s[j++] = uch;
|
||||
|
||||
} else if (uch < 0x0800) {
|
||||
if (j >= ns-1) break;
|
||||
s[j++] = ((uch & 0x07C0) >> 6) | 0xC0;
|
||||
s[j++] = (uch & 0x003F) | 0x80;
|
||||
|
||||
} else {
|
||||
if (j >= ns-2) break;
|
||||
s[j++] = ((uch & 0xF000) >> 12) | 0xE0;
|
||||
s[j++] = ((uch & 0x0FC0) >> 6) | 0x80;
|
||||
s[j++] = (uch & 0x003F) | 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
if (remaining)
|
||||
*remaining = nus - k;
|
||||
|
||||
if (encoded)
|
||||
*encoded = j;
|
||||
}
|
||||
|
||||
|
||||
/** Decodes UTF8 string S with NS characters to Unicode string US with
|
||||
* upto NUS characters, returning the number of REMAINING Utf8 characters
|
||||
* and the number of DECODED Unicode characters.
|
||||
* If skipNUL is non-zero, NUL input characters are skipped.
|
||||
* returns 0 if successful,
|
||||
* -1 if an error occurred during decoding
|
||||
*/
|
||||
int utf8toucs(const char* s, int ns, UNICHAR* us, int nus,
|
||||
int skipNUL, int* remaining, int* decoded)
|
||||
{
|
||||
int j, k;
|
||||
int retcode = 0;
|
||||
|
||||
j = 0;
|
||||
k = 0;
|
||||
while ((j < ns) && (k < nus)) {
|
||||
char ch = s[j];
|
||||
|
||||
if (0x80 & ch) {
|
||||
if (0x40 & ch) {
|
||||
if (0x20 & ch) {
|
||||
/* consume 3 */
|
||||
if (j >= ns-2) break;
|
||||
|
||||
if ( (s[j+1] & 0x40) || !(s[j+1] & 0x80) ||
|
||||
(s[j+2] & 0x40) || !(s[j+2] & 0x80) ) {
|
||||
retcode = -1;
|
||||
}
|
||||
|
||||
us[k++] = ((ch & 0x0F) << 12)
|
||||
| ((s[j+1] & 0x3F) << 6)
|
||||
| ( s[j+2] & 0x3F);
|
||||
|
||||
j += 3;
|
||||
|
||||
} else {
|
||||
/* consume 2 */
|
||||
if (j >= ns-1) break;
|
||||
|
||||
if ( (s[j+1] & 0x40) || !(s[j+1] & 0x80) ) {
|
||||
retcode = -1;
|
||||
}
|
||||
|
||||
us[k++] = ((ch & 0x1F) << 6)
|
||||
| ( s[j+1] & 0x3F);
|
||||
j += 2;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* consume 1 (error) */
|
||||
retcode = -1;
|
||||
j++;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* consume 1 */
|
||||
if (ch || !skipNUL) {
|
||||
us[k++] = ch;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if (remaining)
|
||||
*remaining = ns - j;
|
||||
|
||||
if (decoded)
|
||||
*decoded = k;
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
/** Prints Unicode string US with NUS characters to file stream STREAM,
|
||||
* escaping non-printable ASCII characters and all non-ASCII characters
|
||||
*/
|
||||
void ucsprint(FILE* stream, const UNICHAR* us, int nus)
|
||||
{
|
||||
static const char hexDigits[17] = "0123456789abcdef";
|
||||
UNICHAR uch;
|
||||
int k;
|
||||
|
||||
for (k=0; k<nus; k++) {
|
||||
uch = us[k];
|
||||
|
||||
if (uch < (UNICHAR)U_SPACE) {
|
||||
/* ASCII control character */
|
||||
fprintf(stream, "^%c", (char) uch+U_ATSIGN);
|
||||
|
||||
} else if (uch == (UNICHAR)U_CARET) {
|
||||
/* Caret */
|
||||
fprintf(stream, "^^");
|
||||
|
||||
} else if (uch < (UNICHAR)U_DEL) {
|
||||
/* Printable ASCII character */
|
||||
fprintf(stream, "%c", (char) uch);
|
||||
|
||||
} else {
|
||||
/* DEL or non-ASCII character */
|
||||
char esc_str[8]="�";
|
||||
int j;
|
||||
for (j=5; j>1; j--) {
|
||||
esc_str[j] = hexDigits[uch%16];
|
||||
uch = uch / 16;
|
||||
}
|
||||
fprintf(stream, "%s", esc_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Copy exactly n characters from plain character source string to UNICHAR
|
||||
* destination string, ignoring source characters past a null character and
|
||||
* padding the destination with null characters if necessary.
|
||||
*/
|
||||
UNICHAR* ucscopy(register UNICHAR* dest, register const char* srcplain,
|
||||
size_t n)
|
||||
{
|
||||
register UNICHAR ch;
|
||||
register const UNICHAR* destmx = dest + n;
|
||||
|
||||
/* Copy characters from source to destination, stopping at NUL */
|
||||
while (dest < destmx) {
|
||||
*dest++ = (ch = *srcplain++);
|
||||
if (ch == U_NUL)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Pad with NULs, if necessary */
|
||||
while (dest < destmx)
|
||||
*dest++ = U_NUL;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
#ifndef USE_WCHAR
|
||||
/** Locates first occurrence of character within string and returns pointer
|
||||
* to it if found, else returning null pointer. (character may be NUL)
|
||||
*/
|
||||
UNICHAR* ucschr(register const UNICHAR* str, register const UNICHAR chr)
|
||||
{
|
||||
do {
|
||||
if (*str == chr)
|
||||
return (UNICHAR*) str;
|
||||
} while (*str++ != U_NUL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/** Locates last occurrence of character within string and returns pointer
|
||||
* to it if found, else returning null pointer. (character may be NUL)
|
||||
*/
|
||||
UNICHAR* ucsrchr(register const UNICHAR* str, register const UNICHAR chr)
|
||||
{
|
||||
const UNICHAR* retstr = NULL;
|
||||
do {
|
||||
if (*str == chr)
|
||||
retstr = str;
|
||||
} while (*str++ != U_NUL);
|
||||
|
||||
return (UNICHAR*) retstr;
|
||||
}
|
||||
|
||||
|
||||
/** Compare all characters between string1 and string2, returning
|
||||
* a zero value if all characters are equal, or returning
|
||||
* character1 - character2 for the first character that is different
|
||||
* between the two strings.
|
||||
* (Characters following a null character are not compared.)
|
||||
*/
|
||||
int ucscmp(register const UNICHAR* str1, register const UNICHAR* str2)
|
||||
{
|
||||
register UNICHAR ch1, ch2;
|
||||
|
||||
do {
|
||||
if ((ch1 = *str1++) != (ch2 = *str2++))
|
||||
return ch1 - ch2;
|
||||
|
||||
} while (ch1 != U_NUL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Compare upto n characters between string1 and string2, returning
|
||||
* a zero value if all compared characters are equal, or returning
|
||||
* character1 - character2 for the first character that is different
|
||||
* between the two strings.
|
||||
* (Characters following a null character are not compared.)
|
||||
*/
|
||||
int ucsncmp(register const UNICHAR* str1, register const UNICHAR* str2,
|
||||
size_t n)
|
||||
{
|
||||
register UNICHAR ch1, ch2;
|
||||
register const UNICHAR* str1mx = str1 + n;
|
||||
|
||||
while (str1 < str1mx) {
|
||||
if ((ch1 = *str1++) != (ch2 = *str2++))
|
||||
return ch1 - ch2;
|
||||
|
||||
if (ch1 == U_NUL)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Copy exactly n characters from source to destination, ignoring source
|
||||
* characters past a null character and padding the destination with null
|
||||
* characters if necessary.
|
||||
*/
|
||||
UNICHAR* ucsncpy(register UNICHAR* dest, register const UNICHAR* src,
|
||||
size_t n)
|
||||
{
|
||||
register UNICHAR ch;
|
||||
register const UNICHAR* destmx = dest + n;
|
||||
|
||||
/* Copy characters from source to destination, stopping at NUL */
|
||||
while (dest < destmx) {
|
||||
*dest++ = (ch = *src++);
|
||||
if (ch == U_NUL)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Pad with NULs, if necessary */
|
||||
while (dest < destmx)
|
||||
*dest++ = U_NUL;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
/** Returns string length
|
||||
*/
|
||||
size_t ucslen(const UNICHAR* str)
|
||||
{
|
||||
register const UNICHAR* strcp = str;
|
||||
|
||||
while (*strcp++ != U_NUL);
|
||||
|
||||
return strcp - str - 1;
|
||||
}
|
||||
|
||||
|
||||
/** Locates substring within string and returns pointer to it if found,
|
||||
* else returning null pointer. If substring has zero length, then full
|
||||
* string is returned.
|
||||
*/
|
||||
UNICHAR* ucsstr(register const UNICHAR* str, const UNICHAR* substr)
|
||||
{
|
||||
register UNICHAR subch1, ch;
|
||||
|
||||
/* If null substring, return string */
|
||||
if (*substr == U_NUL)
|
||||
return (UNICHAR*) str;
|
||||
|
||||
/* First character of non-null substring */
|
||||
subch1 = *substr;
|
||||
|
||||
if ((ch = *str) == U_NUL)
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
|
||||
if (ch == subch1) {
|
||||
/* First character matches; check if rest of substring matches */
|
||||
register const UNICHAR* strcp = str;
|
||||
register const UNICHAR* substrcp = substr;
|
||||
do {
|
||||
substrcp++;
|
||||
strcp++;
|
||||
if (*substrcp == U_NUL)
|
||||
return (UNICHAR*) str;
|
||||
} while (*substrcp == *strcp);
|
||||
}
|
||||
|
||||
} while ((ch = *(++str)) != U_NUL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/** Returns length of longest initial segment of string that contains
|
||||
* only the specified characters.
|
||||
*/
|
||||
size_t ucsspn(const UNICHAR* str, const UNICHAR* chars)
|
||||
{
|
||||
register UNICHAR strch, ch;
|
||||
register const UNICHAR* charscp;
|
||||
register const UNICHAR* strcp = str;
|
||||
|
||||
while ((strch = *strcp++) != U_NUL) {
|
||||
charscp = chars;
|
||||
|
||||
/* Check that it is one of the specified characters */
|
||||
while ((ch = *charscp++) != U_NUL) {
|
||||
if (strch == ch)
|
||||
break;
|
||||
}
|
||||
if (ch == U_NUL)
|
||||
return (size_t) (strcp - str - 1);
|
||||
}
|
||||
|
||||
return (size_t) (strcp - str - 1);
|
||||
}
|
||||
|
||||
|
||||
/** Returns length of longest initial segment of string that does not
|
||||
* contain any of the specified characters.
|
||||
*/
|
||||
size_t ucscspn(const UNICHAR* str, const UNICHAR* chars)
|
||||
{
|
||||
register UNICHAR strch, ch;
|
||||
register const UNICHAR* charscp;
|
||||
register const UNICHAR* strcp = str;
|
||||
|
||||
while ((strch = *strcp++) != U_NUL) {
|
||||
charscp = chars;
|
||||
|
||||
/* Check that it is not one of the specified characters */
|
||||
while ((ch = *charscp++) != U_NUL) {
|
||||
if (strch == ch)
|
||||
return (size_t) (strcp - str - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return (size_t) (strcp - str - 1);
|
||||
}
|
||||
#endif /* !USE_WCHAR */
|
|
@ -0,0 +1,342 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "MPL"); you may not use this file
|
||||
* except in compliance with the MPL. You may obtain a copy of
|
||||
* the MPL at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the MPL is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the MPL for the specific language governing
|
||||
* rights and limitations under the MPL.
|
||||
*
|
||||
* The Original Code is lineterm.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
||||
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
||||
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License (the "GPL"), in which case
|
||||
* the provisions of the GPL are applicable instead of
|
||||
* those above. If you wish to allow use of your version of this
|
||||
* file only under the terms of the GPL and not to allow
|
||||
* others to use your version of this file under the MPL, indicate
|
||||
* your decision by deleting the provisions above and replace them
|
||||
* with the notice and other provisions required by the GPL.
|
||||
* If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/* unistring.h: Unicode string operations header
|
||||
* (used by lineterm.h)
|
||||
* CPP options:
|
||||
* USE_WCHAR: use system wchar implementation, rather than unsigned short
|
||||
* HAVE_WCSSTR: use wcsstr rather than wcswcs (used for wchar only)
|
||||
*/
|
||||
|
||||
#ifndef _UNISTRING_H
|
||||
|
||||
#define _UNISTRING_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Standard C header files */
|
||||
#include <stdio.h>
|
||||
|
||||
/* Unicode character type:
|
||||
* Use either the wchar_t implementation or unsigned short
|
||||
*/
|
||||
|
||||
#ifdef USE_WCHAR
|
||||
#include <wchar.h>
|
||||
typedef wchar_t UNICHAR;
|
||||
#else /* !USE_WCHAR */
|
||||
typedef unsigned short UNICHAR;
|
||||
#endif
|
||||
|
||||
/* Unicode string functions:
|
||||
* use the wchar_t implementation for moment
|
||||
*/
|
||||
|
||||
/** Encodes Unicode string US with NUS characters into UTF8 string S with
|
||||
* upto NS characters, returning the number of REMAINING Unicode characters
|
||||
* and the number of ENCODED Utf8 characters
|
||||
*/
|
||||
void ucstoutf8(const UNICHAR* us, int nus, char* s, int ns,
|
||||
int* remaining, int* encoded);
|
||||
|
||||
/** Decodes UTF8 string S with NS characters to Unicode string US with
|
||||
* upto NUS characters, returning the number of REMAINING Utf8 characters
|
||||
* and the number of DECODED Unicode characters.
|
||||
* If skipNUL is non-zero, NUL input characters are skipped.
|
||||
* returns 0 if successful,
|
||||
* -1 if an error occurred during decoding
|
||||
*/
|
||||
int utf8toucs(const char* s, int ns, UNICHAR* us, int nus,
|
||||
int skipNUL, int* remaining, int* decoded);
|
||||
|
||||
/** Prints Unicode string US with NUS characters to file stream STREAM,
|
||||
* escaping non-printable ASCII characters and all non-ASCII characters
|
||||
*/
|
||||
void ucsprint(FILE* stream, const UNICHAR* us, int nus);
|
||||
|
||||
/** Copy exactly n characters from plain character source string to UNICHAR
|
||||
* destination string, ignoring source characters past a null character and
|
||||
* padding the destination with null characters if necessary.
|
||||
*/
|
||||
UNICHAR* ucscopy(UNICHAR* dest, const char* srcplain, size_t n);
|
||||
|
||||
#ifdef USE_WCHAR
|
||||
|
||||
#define ucscpy wcscpy
|
||||
#define ucsncpy wcsncpy
|
||||
|
||||
#define ucscat wcscat
|
||||
#define ucsncat wcsncat
|
||||
|
||||
#define ucscmp wcscmp
|
||||
#define ucsncmp wcsncmp
|
||||
|
||||
#define ucschr wcschr
|
||||
#define ucsrchr wcsrchr
|
||||
|
||||
#define ucsspn wcsspn
|
||||
#define ucscspn wcscspn
|
||||
|
||||
#define ucspbrk wcspbrk
|
||||
|
||||
#ifdef HAVE_WCSSTR
|
||||
#define ucsstr wcsstr
|
||||
#else
|
||||
#define ucsstr wcswcs
|
||||
#endif
|
||||
|
||||
#define ucslen wcslen
|
||||
|
||||
#define ucstok wcstok
|
||||
|
||||
#else /* !USE_WCHAR */
|
||||
/** Locates first occurrence of character within string and returns pointer
|
||||
* to it if found, else returning null pointer. (character may be NUL)
|
||||
*/
|
||||
UNICHAR* ucschr(const UNICHAR* str, const UNICHAR chr);
|
||||
|
||||
/** Locates last occurrence of character within string and returns pointer
|
||||
* to it if found, else returning null pointer. (character may be NUL)
|
||||
*/
|
||||
UNICHAR* ucsrchr(const UNICHAR* str, const UNICHAR chr);
|
||||
|
||||
/** Compare all characters between string1 and string2, returning
|
||||
* a zero value if all characters are equal, or returning
|
||||
* character1 - character2 for the first character that is different
|
||||
* between the two strings.
|
||||
* (Characters following a null character are not compared.)
|
||||
*/
|
||||
int ucscmp(register const UNICHAR* str1, register const UNICHAR* str2);
|
||||
|
||||
/** Compare upto n characters between string1 and string2, returning
|
||||
* a zero value if all compared characters are equal, or returning
|
||||
* character1 - character2 for the first character that is different
|
||||
* between the two strings.
|
||||
* (Characters following a null character are not compared.)
|
||||
*/
|
||||
int ucsncmp(const UNICHAR* str1, const UNICHAR* str2,
|
||||
size_t n);
|
||||
|
||||
/** Copy exactly n characters from source to destination, ignoring source
|
||||
* characters past a null character and padding the destination with null
|
||||
* characters if necessary.
|
||||
*/
|
||||
UNICHAR* ucsncpy(UNICHAR* dest, const UNICHAR* src,
|
||||
size_t n);
|
||||
|
||||
/** Returns string length
|
||||
*/
|
||||
size_t ucslen(const UNICHAR* str);
|
||||
|
||||
/** Locates substring within string and returns pointer to it if found,
|
||||
* else returning null pointer. If substring has zero length, then full
|
||||
* string is returned.
|
||||
*/
|
||||
UNICHAR* ucsstr(const UNICHAR* str, const UNICHAR* substr);
|
||||
|
||||
/** Returns length of longest initial segment of string that contains
|
||||
* only the specified characters.
|
||||
*/
|
||||
size_t ucsspn(const UNICHAR* str, const UNICHAR* chars);
|
||||
|
||||
/** Returns length of longest initial segment of string that does not
|
||||
* contain any of the specified characters.
|
||||
*/
|
||||
size_t ucscspn(const UNICHAR* str, const UNICHAR* chars);
|
||||
|
||||
#endif /* !USE_WCHAR */
|
||||
|
||||
/* unsigned short constants */
|
||||
#define U_NUL 0x00U
|
||||
|
||||
#define U_CTL_A 0x01U
|
||||
#define U_CTL_B 0x02U
|
||||
#define U_CTL_C 0x03U
|
||||
#define U_CTL_D 0x04U
|
||||
#define U_CTL_E 0x05U
|
||||
#define U_CTL_F 0x06U
|
||||
|
||||
#define U_BEL 0x07U /* ^G */
|
||||
#define U_BACKSPACE 0x08U /* ^H */
|
||||
#define U_TAB 0x09U /* ^I */
|
||||
#define U_LINEFEED 0x0AU /* ^J */
|
||||
|
||||
#define U_CTL_K 0x0BU
|
||||
#define U_CTL_L 0x0CU
|
||||
|
||||
#define U_CRETURN 0x0DU /* ^M */
|
||||
|
||||
#define U_CTL_N 0x0EU
|
||||
#define U_CTL_O 0x0FU
|
||||
#define U_CTL_P 0x10U
|
||||
#define U_CTL_Q 0x11U
|
||||
#define U_CTL_R 0x12U
|
||||
#define U_CTL_S 0x13U
|
||||
#define U_CTL_T 0x14U
|
||||
#define U_CTL_U 0x15U
|
||||
#define U_CTL_V 0x16U
|
||||
#define U_CTL_W 0x17U
|
||||
#define U_CTL_X 0x18U
|
||||
#define U_CTL_Y 0x19U
|
||||
#define U_CTL_Z 0x1AU
|
||||
|
||||
#define U_ESCAPE 0x1BU /* escape */
|
||||
|
||||
#define U_SPACE 0x20U /* space */
|
||||
#define U_EXCLAMATION 0x21U /* ! */
|
||||
#define U_DBLQUOTE 0x22U /* " */
|
||||
#define U_NUMBER 0x23U /* # */
|
||||
#define U_DOLLAR 0x24U /* $ */
|
||||
#define U_PERCENT 0x25U /* % */
|
||||
#define U_AMPERSAND 0x26U /* & */
|
||||
#define U_SNGLQUOTE 0x27U /* ' */
|
||||
#define U_LPAREN 0x28U /* ( */
|
||||
#define U_RPAREN 0x29U /* ) */
|
||||
|
||||
#define U_STAR 0x2AU /* * */
|
||||
#define U_PLUS 0x2BU /* + */
|
||||
#define U_COMMA 0x2CU /* , */
|
||||
#define U_DASH 0x2DU /* - */
|
||||
#define U_PERIOD 0x2EU /* . */
|
||||
#define U_SLASH 0x2FU /* / */
|
||||
|
||||
#define U_ZERO 0x30U /* 0 */
|
||||
#define U_ONE 0x31U /* 1 */
|
||||
#define U_TWO 0x32U /* 2 */
|
||||
#define U_THREE 0x33U /* 3 */
|
||||
#define U_FOUR 0x34U /* 4 */
|
||||
#define U_FIVE 0x35U /* 5 */
|
||||
#define U_SIX 0x36U /* 6 */
|
||||
#define U_SEVEN 0x37U /* 7 */
|
||||
#define U_EIGHT 0x38U /* 8 */
|
||||
#define U_NINE 0x39U /* 9 */
|
||||
|
||||
#define U_COLON 0x3AU /* : */
|
||||
#define U_SEMICOLON 0x3BU /* ; */
|
||||
#define U_LESSTHAN 0x3CU /* < */
|
||||
#define U_EQUALS 0x3DU /* = */
|
||||
#define U_GREATERTHAN 0x3EU /* > */
|
||||
#define U_QUERYMARK 0x3FU /* ? */
|
||||
|
||||
#define U_ATSIGN 0x40U /* @ */
|
||||
|
||||
#define U_A_CHAR 0x41U /* A */
|
||||
#define U_B_CHAR 0x42U /* B */
|
||||
#define U_C_CHAR 0x43U /* C */
|
||||
#define U_D_CHAR 0x44U /* D */
|
||||
#define U_E_CHAR 0x45U /* E */
|
||||
#define U_F_CHAR 0x46U /* F */
|
||||
#define U_G_CHAR 0x47U /* G */
|
||||
#define U_H_CHAR 0x48U /* H */
|
||||
#define U_I_CHAR 0x49U /* I */
|
||||
#define U_J_CHAR 0x4AU /* J */
|
||||
#define U_K_CHAR 0x4BU /* K */
|
||||
#define U_L_CHAR 0x4CU /* L */
|
||||
#define U_M_CHAR 0x4DU /* M */
|
||||
#define U_N_CHAR 0x4EU /* N */
|
||||
#define U_O_CHAR 0x4FU /* O */
|
||||
#define U_P_CHAR 0x50U /* P */
|
||||
#define U_Q_CHAR 0x51U /* Q */
|
||||
#define U_R_CHAR 0x52U /* R */
|
||||
#define U_S_CHAR 0x53U /* S */
|
||||
#define U_T_CHAR 0x54U /* T */
|
||||
#define U_U_CHAR 0x55U /* U */
|
||||
#define U_V_CHAR 0x56U /* V */
|
||||
#define U_W_CHAR 0x57U /* W */
|
||||
#define U_X_CHAR 0x58U /* X */
|
||||
#define U_Y_CHAR 0x59U /* Y */
|
||||
#define U_Z_CHAR 0x5AU /* Z */
|
||||
|
||||
#define U_LBRACKET 0x5BU /* [ */
|
||||
#define U_BACKSLASH 0x5CU /* \ */
|
||||
#define U_RBRACKET 0x5DU /* ] */
|
||||
|
||||
#define U_CARET 0x5EU /* ^ */
|
||||
#define U_UNDERSCORE 0x5FU /* _ */
|
||||
#define U_BACKQUOTE 0x60U /* ` */
|
||||
|
||||
#define U_a_CHAR 0x61U /* a */
|
||||
#define U_b_CHAR 0x62U /* b */
|
||||
#define U_c_CHAR 0x63U /* c */
|
||||
#define U_d_CHAR 0x64U /* d */
|
||||
#define U_e_CHAR 0x65U /* e */
|
||||
#define U_f_CHAR 0x66U /* f */
|
||||
#define U_g_CHAR 0x67U /* g */
|
||||
#define U_h_CHAR 0x68U /* h */
|
||||
#define U_i_CHAR 0x69U /* i */
|
||||
#define U_j_CHAR 0x6AU /* j */
|
||||
#define U_k_CHAR 0x6BU /* k */
|
||||
#define U_l_CHAR 0x6CU /* l */
|
||||
#define U_m_CHAR 0x6DU /* m */
|
||||
#define U_n_CHAR 0x6EU /* n */
|
||||
#define U_o_CHAR 0x6FU /* o */
|
||||
#define U_p_CHAR 0x70U /* p */
|
||||
#define U_q_CHAR 0x71U /* q */
|
||||
#define U_r_CHAR 0x72U /* r */
|
||||
#define U_s_CHAR 0x73U /* s */
|
||||
#define U_t_CHAR 0x74U /* t */
|
||||
#define U_u_CHAR 0x75U /* u */
|
||||
#define U_v_CHAR 0x76U /* v */
|
||||
#define U_w_CHAR 0x77U /* w */
|
||||
#define U_x_CHAR 0x78U /* x */
|
||||
#define U_y_CHAR 0x79U /* y */
|
||||
#define U_z_CHAR 0x7AU /* z */
|
||||
|
||||
#define U_LCURLY 0x7BU /* { */
|
||||
#define U_VERTBAR 0x7CU /* | */
|
||||
#define U_RCURLY 0x7DU /* } */
|
||||
|
||||
#define U_TILDE 0x7EU /* ~ */
|
||||
#define U_DEL 0x7FU /* delete */
|
||||
|
||||
#define U_LATIN1LO 0xA0U /* lowest Latin1 extension character */
|
||||
#define U_NOBRKSPACE 0xA0U /* no-break space */
|
||||
#define U_LATIN1HI 0xFFU /* highest Latin1 extension character */
|
||||
|
||||
#define U_PRIVATE0 0xE000U /* first private use Unicode character */
|
||||
|
||||
#define IS_ASCII_LETTER(x) ( (((x) >= (UNICHAR)U_A_CHAR) && \
|
||||
((x) <= (UNICHAR)U_Z_CHAR)) || \
|
||||
(((x) >= (UNICHAR)U_a_CHAR) && \
|
||||
((x) <= (UNICHAR)U_z_CHAR)) )
|
||||
|
||||
#define IS_ASCII_DIGIT(x) ( ((x) >= (UNICHAR)U_ZERO) && \
|
||||
((x) <= (UNICHAR)U_NINE) )
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _UNISTRING_H */
|
|
@ -63,9 +63,9 @@ PTHREADLIBOPT = -lpthread
|
|||
endif
|
||||
|
||||
ifdef USE_NCURSES
|
||||
LIBS = -lncurses -lxmlterm $(PTHREADLIBOPT)
|
||||
LIBS = -lncurses -llineterm_s $(PTHREADLIBOPT)
|
||||
else
|
||||
LIBS = -lxmlterm $(PTHREADLIBOPT)
|
||||
LIBS = -llineterm_s $(PTHREADLIBOPT)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
|
|
@ -66,7 +66,6 @@
|
|||
#ifdef LINUX
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
typedef unsigned int nfds_t;
|
||||
#endif
|
||||
|
||||
#include "lineterm.h"
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#if defined(LINUX) || defined(BSDFAMILY)
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
typedef unsigned int nfds_t;
|
||||
#endif
|
||||
|
||||
#include "ptystream.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче