xless-1.7.orig/ 40775 0 62 0 6302064337 11615 5ustar rootstaffxless-1.7.orig/CHANGES100444 0 0 13320 5616067724 12562 0ustar rootrootChanges for version 1.7: - pressing [Search Next] button before [Search] button has been pressed caused a core dump (reported by Mark Phillips ) - fixed search code so Case Insensitive mode is possible (reported by Dale W. King ) - non-regexp search code is buggy; use regexp code for all searches (indirectly suggested by Dale W. King ) - fixed popup windows so input line is as long as possible (suggested by Roberto Horowitz ) - a couple of man page bugs were fixed by "Len Makin, CSIRO DIT Melbourne." - added '-version' option (suggested by Marty Leisner ) - stdin now has 'monitorFile' mode off by default (suggested by EVERYONE) - text width is now calculated correctly when text contains TAB chars (fixed by Dimitrios P. Bouras ) - fixed geometry bug reported by Al Womelsdorf - included Xmu/Converters.h in window.c, which may allow OpenWindows users to build (fixed by Huzefa Mustaly ) - added [Background] button (suggested by Marty Leisner ) - fixed Help window geometry problem (pointed out by Gordon Berkley and others) - complain about 'printCmd' usage; honor 'printCommand' (pointed out by Tim Medley ) Changes for version 1.6.1: - pressing [Help] button caused xless to dump core (reported by several people, fixed by Martin Boyer ) - cleaned up "Features" list in help message & README Changes for version 1.6: - fixed copyright notices for R6 contrib tape - cleaned up code, help message & README - added 'defaultSearchType' resource (suggested by Dale W. King ) - added code to let xless continually monitor input file, like 'tail -f' - added 'monitorFile' resource and '-f' option to enable file monitoring code Changes for version 1.5: - changed '-textGeometry' to the standard '-geometry' and handled X and Y positioning correctly (reported by Steven Fought and Volker Zink ) - renamed #define'd to avoid conflicts with POSIX or other system constants (reported by Bob Friesenhahn and others) - fixed font width calculation (reported by Giuseppe Carnevale and Vladimir V. Egorin ) - added 'editor' resource, now check VISUAL envvar before EDITOR (suggested by Joerg Hoehle ) - added case-insensitive searching contributed by Dale W. King - now use nicer fonts - overrode ctrl-S and ctrl-R so second search box doesn't confuse people Changes for version 1.4: - added 'maxWindows' resource to limit damage done by 'xless *' (suggested by Markus Koch ) - cleaned up help window (suggested by Len Makin ) - cleaned up manual page - massive source code reformatting - all buffers should be dynamically allocated now - tried to eliminate as much code duplication as practical - tilde expansion performed on file names (suggested by Michael J. Thibodeau ) - icon & title name are now set to 'xless:filename' - title line is gone because titlebar name should now be correct - '?' is an accelerator for the [Help] button, 'Q' is an accelerator for the [Close window] button and 'Meta-Q' is an accelerator for the [Quit] button (if present) - you are now prompted if you try to [Quit] and there is more than one window - popup boxes are now created when they're needed and (most of them) are only created once - all windows are now created equal; there's no main window anymore - added 'quitButton' resource for those who would like something like the old behavior - [Editor] and [Reload] buttons are now re-sensitized if user starts with a file from STDIN, then changes to another file - Add 'textGeometry' resource (suggested by Tom Bannon ) - Set window manager size hints - Change default textFont to Courier 12; variable-width fonts screw up geometry guess - Add 'namePrefix' resource which adds 'xless:' (or whatever) to the front of all icon names and window titles - Add 'removePath' resource which, if true, truncates the path name to just the last element so names are somewhat more readable - Add 'sizeToFit' resource which, if true, make the window only as large as it needs to be (handy for lists or short files) - The button colors were quieted down a bit Changes for version 1.3: - icon name now changed when file is changed - added code for "help" action from Fred Gilham - merged in interface cleanups from Fred Gilham - added code to filter out ^H_ left by 'man' underlining (from Fred Gilham, but simplified by me, so bugs are probably my fault) Changes for version 1.2: - fixed R4 scrolling problem reported by Karsten Gaier - added resource file files from Rainer Klute - added print button code from Andrew Bacon (but I hacked on it, so any bugs are undoubtedly mine) - ANSIfied some stuff Changes for version 1.1: - fixed things to work under R5 - added 'editorDoesWindows' which can be set if your editor is X-savvy enough to come up in its own window - added a 'quit()' action - created XLess.ad, which incorporates the previous .Xresources with a bunch of keyboard bindings to make xless behave more like less xless-1.7.orig/README100444 0 0 5641 5575236575 12444 0ustar rootrootThis is XLess version 1.7, a file browsing tool for the X Window System CREDITS: By Dave Glowacki - UCB Software Warehouse Originally By Carlo Lisa - MIT Project Athena. Based Upon Xmore for X11R2 by Chris Peterson - MIT Project Athena. The regular expression library in the 'regexp' subdirectory was written by Henry Spencer and is Copyright (c) 1986 by University of Toronto LEGAL STUFF: Copyright (C) 1994 by Dave Glowacki Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation to rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DAVE GLOWACKI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. FEATURES: Display either the file(s) specified on the command line or input from standard input, supplied by a pipe. File/pipe may be optionally monitored so that the display is continuously updated as new text is added. Display new files in the current window or by creating a new window. Reload or print the displayed file. Search the displayed file using either exact, case-insensitive, or regular expression patterns. Edit the displayed file with your favorite editor (as specified in the VISUAL or EDITOR environment variable) AVAILABLE FROM: ftp.cs.berkeley.edu:/ucb/people/dglo/xless/xless-1.7.tar.gz ftp.x.org:/contrib/applications/xless-1.7.tar.gz TESTED ON: SunOS 4.1.3 Ultrix 4.2 HP-UX 9.01 OSF/1 1.3 INSTALLATION: Check the Imakefile to see if you need to add or change any DEFINES, then do the usual 'xmkmf', etc. CAVEAT: The color resources are stored in the global app-defaults directory in a file named 'XLess-color'. If you have a color display and are running at least X11R5, you may want to add a line like this to your personal resources file: #ifdef COLOR *customization: -color #endif Versions of X earlier than X11R5 don't support the `customization' resource. If you're on one of those, you'll have to include the color resources in your personal resources file. COMMENTS? Send bugs, impressions, suggestions to: dglo@cs.berkeley.edu Enjoy! xless-1.7.orig/XLess-co.ad100444 0 0 276 5370317433 13470 0ustar rootroot#include "XLess" XLess*Background: ivory XLess*Command.background: cornsilk XLess*confirm.background: sea green XLess*Cancel.background: orange red XLess*Ok !.background: spring green xless-1.7.orig/XLess.ad100444 0 0 2243 5572755173 13120 0ustar rootroot!$Header: /usr/sww/share/src/X11R6/local/applications/xless-1.5/RCS/XLess.ad,v 1.8 1994/06/01 00:46:29 dglo Exp $ XLess*standardFont: fixed XLess*textFont: -misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-1 XLess*labelFont: -adobe-times-medium-r-normal--12-120-75-75-p-*-iso8859-1 XLess*buttonFont: -adobe-new century schoolbook-medium-r-normal--12-120-75-75-p-*-iso8859-1 XLess*standardCur: left_ptr XLess*dialogCur: center_ptr XLess.Paned.Text.Translations: #override\n\ CtrlS: no-op(RingBell)\n\ CtrlR: no-op(RingBell)\n\ space: next-page()\n\ F: next-page()\n\ CtrlB: previous-page()\n\ B: previous-page()\n\ K: scroll-one-line-down()\n\ Y: scroll-one-line-down()\n\ Return: scroll-one-line-up()\n\ J: scroll-one-line-up()\n\ E: scroll-one-line-up()\n\ q: quit()\n XLess.Paned.Text.baseTranslations: #override\n\ space: next-page()\n\ F: next-page()\n\ CtrlB: previous-page()\n\ K: scroll-one-line-down()\n\ Y: scroll-one-line-down()\n\ Return: scroll-one-line-up()\n\ J: scroll-one-line-up()\n\ E: scroll-one-line-up()\n\ q: quit()\n xless-1.7.orig/XLessTop.icn100444 0 0 2100 5242533400 13735 0ustar rootroot#define XLessTop_width 30 #define XLessTop_height 40 static char XLessTop_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x0e, 0x30, 0x00, 0x00, 0x1c, 0x18, 0x00, 0x00, 0x38, 0x0c, 0x01, 0x00, 0x70, 0x06, 0x01, 0x00, 0x60, 0x03, 0x19, 0x11, 0xb0, 0x03, 0xa5, 0x2a, 0x18, 0x07, 0xa5, 0x08, 0x0c, 0x0e, 0x1d, 0x11, 0x06, 0x1c, 0x05, 0x22, 0x03, 0x38, 0x85, 0x2a, 0x01, 0x70, 0x39, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1c, 0xfe, 0xff, 0x1f, 0xbe, 0x01, 0x00, 0x28, 0x88, 0xf8, 0x7f, 0x0c, 0xc8, 0x00, 0x00, 0x04, 0x60, 0xfe, 0x1f, 0x06, 0x20, 0x00, 0x00, 0x03, 0x30, 0xff, 0x0f, 0x01, 0x18, 0x00, 0x80, 0x08, 0xc8, 0xff, 0x47, 0x08, 0x0c, 0x00, 0x60, 0x3e, 0x04, 0x00, 0x20, 0x1c, 0x0c, 0x00, 0x60, 0x08, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xc3, 0xe1, 0x01, 0xc0, 0x60, 0x63, 0x03, 0xc0, 0x60, 0x63, 0x03, 0xc0, 0x60, 0xe3, 0x01, 0xc0, 0x60, 0x63, 0x00, 0xc0, 0xc0, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; xless-1.7.orig/XLessWin.icn100444 0 0 2164 5242533404 13746 0ustar rootroot#define XLessWin_width 30 #define XLessWin_height 40 #define XLessWin_x_hot -1 #define XLessWin_y_hot -1 static char XLessWin_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x0e, 0x30, 0x00, 0x00, 0x1c, 0x18, 0x00, 0x00, 0x38, 0x0c, 0x01, 0x00, 0x70, 0x06, 0x01, 0x00, 0x60, 0x03, 0x19, 0x11, 0xb0, 0x03, 0xa5, 0x2a, 0x18, 0x07, 0xa5, 0x08, 0x0c, 0x0e, 0x1d, 0x11, 0x06, 0x1c, 0x05, 0x22, 0x03, 0x38, 0x85, 0x2a, 0x01, 0x70, 0x39, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1c, 0xfe, 0xff, 0x1f, 0xbe, 0x01, 0x00, 0x28, 0x88, 0xf8, 0x7f, 0x0c, 0xc8, 0x00, 0x00, 0x04, 0x60, 0xfe, 0x1f, 0x06, 0x20, 0x00, 0x00, 0x03, 0x30, 0xff, 0x0f, 0x01, 0x18, 0x00, 0x80, 0x08, 0xc8, 0xff, 0x47, 0x08, 0x0c, 0x00, 0x60, 0x3e, 0x04, 0x00, 0x20, 0x1c, 0x0c, 0x00, 0x60, 0x08, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xd5, 0x48, 0x04, 0x44, 0x5d, 0x55, 0x04, 0x54, 0x5d, 0x55, 0x05, 0x54, 0x5d, 0x55, 0x05, 0x54, 0x55, 0x55, 0x05, 0x28, 0xd5, 0x88, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; xless-1.7.orig/xless.man100444 0 0 10734 5616033201 13407 0ustar rootroot.TH Xless 1 "6 June 1993" "X Version 11" .SH NAME xless - File browsing program for the X Window System. .SH SYNOPSIS .B xless .I [-f] [-toolkitoption ...] [filename ...] .SH DESCRIPTION Xless pops up a window on the display specified, containing the file specified on the command line or piped in from stdin. This file may easily be viewed using the scrollbar to the left of the window. Xless also takes input from the standard input. Extra function are available on the toolbox to the right of the window: .LP .TP 10 - Pop up a help window. .TP - Search a specified pattern .TP - Search the next occurance of the above specified pattern .LP - Open a session of the editor (specified in the environment variable EDITOR) on the current file .TP - Reload the current file .TP - Change file in the current window .TP - Open a new \fBxless\fP window to display the specified file .TP - Print the current file .TP - Close the current window .LP For further information on using .B xless please read the online help information. The rest of this manual page will discuss customization of .B xless to suit the needs of a particular user. .SH "OPTIONS" .LP Xless is build upon the \fIX Toolkit (Xt)\fP and as such understands all the normal command line options (as described in \fIX(1)\fP. It also supports: .TP .B \-follow Continually check the file for new input (so that \fBxless\fP behaves like \fItail -f\fP). .TP .B -f Alias for \fI-f\fP. .TP .B -help Print a list of valid options. .B -version Print the version number of this \fBxless\fP executable. .SH "WIDGET AND RESOURCE NAMES" .LP In addition to the usual widget resources, Xless has the following application resources: .LP .TP 10 .B standardFont The default font to be used if any of the specified fonts are available. .TP .B textFont The fonts to use for the text. .TP .B labelFont The fonts to use for labels in dialog boxes. .TP .B buttonFont The fonts to use for labels on buttons. .TP .B standardCur The cursors to use in the main button window with the Quit and Help commands. .TP .B dialogCur The cursors to use in the toolbox and dialog box windows. .TP .B helpFile Name of a file to use instead of the system default helpfile. .TP .B editor Name of editor to invoke (if neither \fBVISUAL\fP nor \fBEDITOR\fP environment variable is set) .TP .B editorDoesWindows Set to TRUE if your editor brings up its own window (\fBxedit\fP or GNU \fBemacs\fP, for example.) .TP .B printCommand Command string used to print the current file. The name of the file is simply appended to this string. (\fIenscript -G\fP is nice, if you've got it.) .TP .B maxWindows Maximum number of windows which \fBxless\fB will display at one time. Set this to zero if you don't want a limit. (This is a good thing to set if you tend to run \fIxless *\fP in directories with lots of files.) .TP .B quitButton Set to TRUE if you want a Quit button on every window which, when clicked, will quit \fBevery\fP window started from this copy of \fBxless\fP. The default is FALSE. .TP .B sizeToFit Set to TRUE if you want text windows to be only as big as they need to be, up to the maximum size specified by 'geometry'. .TP .B removePath Set to TRUE if you want the directory portion of the file path removed. For example, a path like \fI/usr/src/X11/xless/main.c\fP would be shortened to \fImain.c\fP. The default is TRUE. .TP .B defaultSearchType Default method used to search the text (invoked from the Search button). Possible values are \fBExactMatch\fP (which is the default), \fBCaseInsensitive\fP and \fBRegularExpression\fP. .TP .B monitorFile Set to TRUE if you want the file to be continually checked for new input (so that \fBxless\fP behaves like \fItail -f\fP). The default is FALSE. .LP .SH "COLOR RESOURCES" .LP If you have a color display and you're running at least X11R5, you may want to add a line like: .LP .RS .ft B .nf #ifdef COLOR *customization: -color #endif .fi .ft R .RE .LP to your personal resources file. This will allow you to get the color-related resources for not only .B xless, but for every program which sets up its own color resources. .LP Versions of X earlier than X11R5 don't support the .B customization resource. If you're on one of those, you'll have to include the color resources in your personal resources file. .SH "SEE ALSO" X(1), X(8C), more(1), less(1) .SH BUGS There probably are some. .LP .SH AUTHOR Dave Glowacki (UC Berkeley Software Warehouse) Originally by Carlo Lisa (MIT Project Athena) from xmore written by Chris Peterson (MIT Project Athena). xless-1.7.orig/regexp/ 40775 0 62 0 6302064337 13107 5ustar rootstaffxless-1.7.orig/regexp/COPYRIGHT100444 0 0 1614 4641477703 14336 0ustar rootrootThis entire subtree is copyright the University of Toronto. The following copyright notice applies to all files found here. None of these files contain AT&T proprietary source code. _____________________________________________________________________________ Copyright (c) 1986 by University of Toronto. Written by Henry Spencer. Not derived from licensed software. Permission is granted to anyone to use this software for any purpose on any computer system, and to redistribute it freely, subject to the following restrictions: 1. The author is not responsible for the consequences of use of this software, no matter how awful, even if they arise from defects in it. 2. The origin of this software must not be misrepresented, either by explicit claim or by omission. 3. Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. xless-1.7.orig/regexp/regerror.c100444 0 0 372 4762035353 15011 0ustar rootroot#include #include void regerror(s) const char *s; { #ifdef ERRAVAIL error("regexp: %s", s); #else /* fprintf(stderr, "regexp(3): %s\n", s); exit(1); */ return; /* let std. egrep handle errors */ #endif /* NOTREACHED */ } xless-1.7.orig/regexp/README100444 0 0 10376 4620150456 13736 0ustar rootrootThis is a nearly-public-domain reimplementation of the V8 regexp(3) package. It gives C programs the ability to use egrep-style regular expressions, and does it in a much cleaner fashion than the analogous routines in SysV. Copyright (c) 1986 by University of Toronto. Written by Henry Spencer. Not derived from licensed software. Permission is granted to anyone to use this software for any purpose on any computer system, and to redistribute it freely, subject to the following restrictions: 1. The author is not responsible for the consequences of use of this software, no matter how awful, even if they arise from defects in it. 2. The origin of this software must not be misrepresented, either by explicit claim or by omission. 3. Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. Barring a couple of small items in the BUGS list, this implementation is believed 100% compatible with V8. It should even be binary-compatible, sort of, since the only fields in a "struct regexp" that other people have any business touching are declared in exactly the same way at the same location in the struct (the beginning). This implementation is *NOT* AT&T/Bell code, and is not derived from licensed software. Even though U of T is a V8 licensee. This software is based on a V8 manual page sent to me by Dennis Ritchie (the manual page enclosed here is a complete rewrite and hence is not covered by AT&T copyright). The software was nearly complete at the time of arrival of our V8 tape. I haven't even looked at V8 yet, although a friend elsewhere at U of T has been kind enough to run a few test programs using the V8 regexp(3) to resolve a few fine points. I admit to some familiarity with regular-expression implementations of the past, but the only one that this code traces any ancestry to is the one published in Kernighan & Plauger (from which this one draws ideas but not code). Simplistically: put this stuff into a source directory, copy regexp.h into /usr/include, inspect Makefile for compilation options that need changing to suit your local environment, and then do "make r". This compiles the regexp(3) functions, compiles a test program, and runs a large set of regression tests. If there are no complaints, then put regexp.o, regsub.o, and regerror.o into your C library, and regexp.3 into your manual-pages directory. Note that if you don't put regexp.h into /usr/include *before* compiling, you'll have to add "-I." to CFLAGS before compiling. The files are: Makefile instructions to make everything regexp.3 manual page regexp.h header file, for /usr/include regexp.c source for regcomp() and regexec() regsub.c source for regsub() regerror.c source for default regerror() regmagic.h internal header file try.c source for test program timer.c source for timing program tests test list for try and timer This implementation uses nondeterministic automata rather than the deterministic ones found in some other implementations, which makes it simpler, smaller, and faster at compiling regular expressions, but slower at executing them. In theory, anyway. This implementation does employ some special-case optimizations to make the simpler cases (which do make up the bulk of regular expressions actually used) run quickly. In general, if you want blazing speed you're in the wrong place. Replacing the insides of egrep with this stuff is probably a mistake; if you want your own egrep you're going to have to do a lot more work. But if you want to use regular expressions a little bit in something else, you're in luck. Note that many existing text editors use nondeterministic regular-expression implementations, so you're in good company. This stuff should be pretty portable, given appropriate option settings. If your chars have less than 8 bits, you're going to have to change the internal representation of the automaton, although knowledge of the details of this is fairly localized. There are no "reserved" char values except for NUL, and no special significance is attached to the top bit of chars. The string(3) functions are used a fair bit, on the grounds that they are probably faster than coding the operations in line. Some attempts at code tuning have been made, but this is invariably a bit machine-specific. xless-1.7.orig/regexp/regexp.c100444 0 0 75014 5011650416 14510 0ustar rootroot/* * regcomp and regexec -- regsub and regerror are elsewhere * * Copyright (c) 1986 by University of Toronto. * Written by Henry Spencer. Not derived from licensed software. * * Permission is granted to anyone to use this software for any * purpose on any computer system, and to redistribute it freely, * subject to the following restrictions: * * 1. The author is not responsible for the consequences of use of * this software, no matter how awful, even if they arise * from defects in it. * * 2. The origin of this software must not be misrepresented, either * by explicit claim or by omission. * * 3. Altered versions must be plainly marked as such, and must not * be misrepresented as being the original software. *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to | *** to assist in implementing egrep. *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching *** as in BSD grep and ex. *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \. *** THIS IS AN ALTERED VERSION. It was altered by James A. Woods, *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy. * * Beware that some of this code is subtly aware of the way operator * precedence is structured in regular expressions. Serious changes in * regular-expression syntax might require a total rethink. */ #include #include #include #include #include #include "regmagic.h" /* * The "internal use only" fields in regexp.h are present to pass info from * compile to execute that permits the execute phase to run lots faster on * simple cases. They are: * * regstart char that must begin a match; '\0' if none obvious * reganch is the match anchored (at beginning-of-line only)? * regmust string (pointer into program) that match must include, or NULL * regmlen length of regmust string * * Regstart and reganch permit very fast decisions on suitable starting points * for a match, cutting down the work a lot. Regmust permits fast rejection * of lines that cannot possibly match. The regmust tests are costly enough * that regcomp() supplies a regmust only if the r.e. contains something * potentially expensive (at present, the only such thing detected is * or + * at the start of the r.e., which can involve a lot of backup). Regmlen is * supplied because the test in regexec() needs it and regcomp() is computing * it anyway. */ /* * Structure for regexp "program". This is essentially a linear encoding * of a nondeterministic finite-state machine (aka syntax charts or * "railroad normal form" in parsing technology). Each node is an opcode * plus a "next" pointer, possibly plus an operand. "Next" pointers of * all nodes except BRANCH implement concatenation; a "next" pointer with * a BRANCH on both ends of it is connecting two alternatives. (Here we * have one of the subtle syntax dependencies: an individual BRANCH (as * opposed to a collection of them) is never concatenated with anything * because of operator precedence.) The operand of some types of node is * a literal string; for others, it is a node leading into a sub-FSM. In * particular, the operand of a BRANCH node is the first node of the branch. * (NB this is *not* a tree structure: the tail of the branch connects * to the thing following the set of BRANCHes.) The opcodes are: */ /* definition number opnd? meaning */ #define END 0 /* no End of program. */ #define BOL 1 /* no Match "" at beginning of line. */ #define EOL 2 /* no Match "" at end of line. */ #define ANY 3 /* no Match any one character. */ #define ANYOF 4 /* str Match any character in this string. */ #define ANYBUT 5 /* str Match any character not in this string. */ #define BRANCH 6 /* node Match this alternative, or the next... */ #define BACK 7 /* no Match "", "next" ptr points backward. */ #define EXACTLY 8 /* str Match this string. */ #define NOTHING 9 /* no Match empty string. */ #define STAR 10 /* node Match this (simple) thing 0 or more times. */ #define PLUS 11 /* node Match this (simple) thing 1 or more times. */ #define WORDA 12 /* no Match "" at wordchar, where prev is nonword */ #define WORDZ 13 /* no Match "" at nonwordchar, where prev is word */ #define OPEN 20 /* no Mark this point in input as start of #n. */ /* OPEN+1 is number 1, etc. */ #define CLOSE 30 /* no Analogous to OPEN. */ /* * Opcode notes: * * BRANCH The set of branches constituting a single choice are hooked * together with their "next" pointers, since precedence prevents * anything being concatenated to any individual branch. The * "next" pointer of the last BRANCH in a choice points to the * thing following the whole choice. This is also where the * final "next" pointer of each individual branch points; each * branch starts with the operand node of a BRANCH node. * * BACK Normal "next" pointers all implicitly point forward; BACK * exists to make loop structures possible. * * STAR,PLUS '?', and complex '*' and '+', are implemented as circular * BRANCH structures using BACK. Simple cases (one character * per match) are implemented with STAR and PLUS for speed * and to minimize recursive plunges. * * OPEN,CLOSE ...are numbered at compile time. */ /* * A node is one char of opcode followed by two chars of "next" pointer. * "Next" pointers are stored as two 8-bit pieces, high order first. The * value is a positive offset from the opcode of the node containing it. * An operand, if any, simply follows the node. (Note that much of the * code generation knows about this implicit relationship.) * * Using two bytes for the "next" pointer is vast overkill for most things, * but allows patterns to get big without disasters. */ #define OP(p) (*(p)) #define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) #define OPERAND(p) ((p) + 3) /* * See regmagic.h for one further detail of program structure. */ /* * Utility definitions. */ #ifndef CHARBITS #define UCHARAT(p) ((int)*(unsigned char *)(p)) #else #define UCHARAT(p) ((int)*(p)&CHARBITS) #endif #define FAIL(m) { regerror(m); return(NULL); } #define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') /* * Flags to be passed up and down. */ #define HASWIDTH 01 /* Known never to match null string. */ #define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ #define SPSTART 04 /* Starts with * or +. */ #define WORST 0 /* Worst case. */ /* * Global work variables for regcomp(). */ static char *regparse; /* Input-scan pointer. */ static int regnpar; /* () count. */ static char regdummy; static char *regcode; /* Code-emit pointer; ®dummy = don't. */ static long regsize; /* Code size. */ /* * Forward declarations for regcomp()'s friends. */ #ifndef STATIC #define STATIC static #endif STATIC char *reg(); STATIC char *regbranch(); STATIC char *regpiece(); STATIC char *regatom(); STATIC char *regnode(); STATIC char *regnext(); STATIC void regc(); STATIC void reginsert(); STATIC void regtail(); STATIC void regoptail(); #ifdef STRCSPN STATIC int strcspn(); #endif /* - regcomp - compile a regular expression into internal code * * We can't allocate space until we know how big the compiled form will be, * but we can't compile it (and thus know how big it is) until we've got a * place to put the code. So we cheat: we compile it twice, once with code * generation turned off and size counting turned on, and once "for real". * This also means that we don't allocate space until we are sure that the * thing really will compile successfully, and we never have to move the * code and thus invalidate pointers into it. (Note that it has to be in * one piece because free() must be able to free it all.) * * Beware that the optimization-preparation code in here knows about some * of the structure of the compiled regexp. */ regexp * regcomp(exp) const char *exp; { register regexp *r; register char *scan; register char *longest; register int len; int flags; if (exp == NULL) FAIL("NULL argument"); /* First pass: determine size, legality. */ #ifdef notdef if (exp[0] == '.' && exp[1] == '*') exp += 2; /* aid grep */ #endif regparse = (char *)exp; regnpar = 1; regsize = 0L; regcode = ®dummy; regc(MAGIC); if (reg(0, &flags) == NULL) return(NULL); /* Small enough for pointer-storage convention? */ if (regsize >= 32767L) /* Probably could be 65535L. */ FAIL("regexp too big"); /* Allocate space. */ r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize); if (r == NULL) FAIL("out of space"); /* Second pass: emit code. */ regparse = (char *)exp; regnpar = 1; regcode = r->program; regc(MAGIC); if (reg(0, &flags) == NULL) return(NULL); /* Dig out information for optimizations. */ r->regstart = '\0'; /* Worst-case defaults. */ r->reganch = 0; r->regmust = NULL; r->regmlen = 0; scan = r->program+1; /* First BRANCH. */ if (OP(regnext(scan)) == END) { /* Only one top-level choice. */ scan = OPERAND(scan); /* Starting-point info. */ if (OP(scan) == EXACTLY) r->regstart = *OPERAND(scan); else if (OP(scan) == BOL) r->reganch++; /* * If there's something expensive in the r.e., find the * longest literal string that must appear and make it the * regmust. Resolve ties in favor of later strings, since * the regstart check works with the beginning of the r.e. * and avoiding duplication strengthens checking. Not a * strong reason, but sufficient in the absence of others. */ if (flags&SPSTART) { longest = NULL; len = 0; for (; scan != NULL; scan = regnext(scan)) if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { longest = OPERAND(scan); len = strlen(OPERAND(scan)); } r->regmust = longest; r->regmlen = len; } } return(r); } /* - reg - regular expression, i.e. main body or parenthesized thing * * Caller must absorb opening parenthesis. * * Combining parenthesis handling with the base level of regular expression * is a trifle forced, but the need to tie the tails of the branches to what * follows makes it hard to avoid. */ static char * reg(paren, flagp) int paren; /* Parenthesized? */ int *flagp; { register char *ret; register char *br; register char *ender; register int parno; int flags; *flagp = HASWIDTH; /* Tentatively. */ /* Make an OPEN node, if parenthesized. */ if (paren) { if (regnpar >= NSUBEXP) FAIL("too many ()"); parno = regnpar; regnpar++; ret = regnode(OPEN+parno); } else ret = NULL; /* Pick up the branches, linking them together. */ br = regbranch(&flags); if (br == NULL) return(NULL); if (ret != NULL) regtail(ret, br); /* OPEN -> first. */ else ret = br; if (!(flags&HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags&SPSTART; while (*regparse == '|' || *regparse == '\n') { regparse++; br = regbranch(&flags); if (br == NULL) return(NULL); regtail(ret, br); /* BRANCH -> BRANCH. */ if (!(flags&HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags&SPSTART; } /* Make a closing node, and hook it on the end. */ ender = regnode((paren) ? CLOSE+parno : END); regtail(ret, ender); /* Hook the tails of the branches to the closing node. */ for (br = ret; br != NULL; br = regnext(br)) regoptail(br, ender); /* Check for proper termination. */ if (paren && *regparse++ != ')') { FAIL("unmatched ()"); } else if (!paren && *regparse != '\0') { if (*regparse == ')') { FAIL("unmatched ()"); } else FAIL("junk on end"); /* "Can't happen". */ /* NOTREACHED */ } return(ret); } /* - regbranch - one alternative of an | operator * * Implements the concatenation operator. */ static char * regbranch(flagp) int *flagp; { register char *ret; register char *chain; register char *latest; int flags; *flagp = WORST; /* Tentatively. */ ret = regnode(BRANCH); chain = NULL; while (*regparse != '\0' && *regparse != ')' && *regparse != '\n' && *regparse != '|') { latest = regpiece(&flags); if (latest == NULL) return(NULL); *flagp |= flags&HASWIDTH; if (chain == NULL) /* First piece. */ *flagp |= flags&SPSTART; else regtail(chain, latest); chain = latest; } if (chain == NULL) /* Loop ran zero times. */ (void) regnode(NOTHING); return(ret); } /* - regpiece - something followed by possible [*+?] * * Note that the branching code sequences used for ? and the general cases * of * and + are somewhat optimized: they use the same NOTHING node as * both the endmarker for their branch list and the body of the last branch. * It might seem that this node could be dispensed with entirely, but the * endmarker role is not redundant. */ static char * regpiece(flagp) int *flagp; { register char *ret; register char op; register char *next; int flags; ret = regatom(&flags); if (ret == NULL) return(NULL); op = *regparse; if (!ISMULT(op)) { *flagp = flags; return(ret); } if (!(flags&HASWIDTH) && op != '?') FAIL("*+ operand could be empty"); *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); if (op == '*' && (flags&SIMPLE)) reginsert(STAR, ret); else if (op == '*') { /* Emit x* as (x&|), where & means "self". */ reginsert(BRANCH, ret); /* Either x */ regoptail(ret, regnode(BACK)); /* and loop */ regoptail(ret, ret); /* back */ regtail(ret, regnode(BRANCH)); /* or */ regtail(ret, regnode(NOTHING)); /* null. */ } else if (op == '+' && (flags&SIMPLE)) reginsert(PLUS, ret); else if (op == '+') { /* Emit x+ as x(&|), where & means "self". */ next = regnode(BRANCH); /* Either */ regtail(ret, next); regtail(regnode(BACK), ret); /* loop back */ regtail(next, regnode(BRANCH)); /* or */ regtail(ret, regnode(NOTHING)); /* null. */ } else if (op == '?') { /* Emit x? as (x|) */ reginsert(BRANCH, ret); /* Either x */ regtail(ret, regnode(BRANCH)); /* or */ next = regnode(NOTHING); /* null. */ regtail(ret, next); regoptail(ret, next); } regparse++; if (ISMULT(*regparse)) FAIL("nested *?+"); return(ret); } /* - regatom - the lowest level * * Optimization: gobbles an entire sequence of ordinary characters so that * it can turn them into a single node, which is smaller to store and * faster to run. Backslashed characters are exceptions, each becoming a * separate node; the code is simpler that way and it's not worth fixing. */ static char * regatom(flagp) int *flagp; { register char *ret; int flags; *flagp = WORST; /* Tentatively. */ switch (*regparse++) { /* FIXME: these chars only have meaning at beg/end of pat? */ case '^': ret = regnode(BOL); break; case '$': ret = regnode(EOL); break; case '.': ret = regnode(ANY); *flagp |= HASWIDTH|SIMPLE; break; case '[': { register int class; register int classend; if (*regparse == '^') { /* Complement of range. */ ret = regnode(ANYBUT); regparse++; } else ret = regnode(ANYOF); if (*regparse == ']' || *regparse == '-') regc(*regparse++); while (*regparse != '\0' && *regparse != ']') { if (*regparse == '-') { regparse++; if (*regparse == ']' || *regparse == '\0') regc('-'); else { class = UCHARAT(regparse-2)+1; classend = UCHARAT(regparse); if (class > classend+1) FAIL("invalid [] range"); for (; class <= classend; class++) regc(class); regparse++; } } else regc(*regparse++); } regc('\0'); if (*regparse != ']') FAIL("unmatched []"); regparse++; *flagp |= HASWIDTH|SIMPLE; } break; case '(': ret = reg(1, &flags); if (ret == NULL) return(NULL); *flagp |= flags&(HASWIDTH|SPSTART); break; case '\0': case '|': case '\n': case ')': FAIL("internal urp"); /* Supposed to be caught earlier. */ break; case '?': case '+': case '*': FAIL("?+* follows nothing"); break; case '\\': switch (*regparse++) { case '\0': FAIL("trailing \\"); break; case '<': ret = regnode(WORDA); break; case '>': ret = regnode(WORDZ); break; /* FIXME: Someday handle \1, \2, ... */ default: /* Handle general quoted chars in exact-match routine */ goto de_fault; } break; de_fault: default: /* * Encode a string of characters to be matched exactly. * * This is a bit tricky due to quoted chars and due to * '*', '+', and '?' taking the SINGLE char previous * as their operand. * * On entry, the char at regparse[-1] is going to go * into the string, no matter what it is. (It could be * following a \ if we are entered from the '\' case.) * * Basic idea is to pick up a good char in ch and * examine the next char. If it's *+? then we twiddle. * If it's \ then we frozzle. If it's other magic char * we push ch and terminate the string. If none of the * above, we push ch on the string and go around again. * * regprev is used to remember where "the current char" * starts in the string, if due to a *+? we need to back * up and put the current char in a separate, 1-char, string. * When regprev is NULL, ch is the only char in the * string; this is used in *+? handling, and in setting * flags |= SIMPLE at the end. */ { char *regprev; register char ch; regparse--; /* Look at cur char */ ret = regnode(EXACTLY); for ( regprev = 0 ; ; ) { ch = *regparse++; /* Get current char */ switch (*regparse) { /* look at next one */ default: regc(ch); /* Add cur to string */ break; case '.': case '[': case '(': case ')': case '|': case '\n': case '$': case '^': case '\0': /* FIXME, $ and ^ should not always be magic */ magic: regc(ch); /* dump cur char */ goto done; /* and we are done */ case '?': case '+': case '*': if (!regprev) /* If just ch in str, */ goto magic; /* use it */ /* End mult-char string one early */ regparse = regprev; /* Back up parse */ goto done; case '\\': regc(ch); /* Cur char OK */ switch (regparse[1]){ /* Look after \ */ case '\0': case '<': case '>': /* FIXME: Someday handle \1, \2, ... */ goto done; /* Not quoted */ default: /* Backup point is \, scan * point is after it. */ regprev = regparse; regparse++; continue; /* NOT break; */ } } regprev = regparse; /* Set backup point */ } done: regc('\0'); *flagp |= HASWIDTH; if (!regprev) /* One char? */ *flagp |= SIMPLE; } break; } return(ret); } /* - regnode - emit a node */ static char * /* Location. */ regnode(op) char op; { register char *ret; register char *ptr; ret = regcode; if (ret == ®dummy) { regsize += 3; return(ret); } ptr = ret; *ptr++ = op; *ptr++ = '\0'; /* Null "next" pointer. */ *ptr++ = '\0'; regcode = ptr; return(ret); } /* - regc - emit (if appropriate) a byte of code */ static void regc(b) char b; { if (regcode != ®dummy) *regcode++ = b; else regsize++; } /* - reginsert - insert an operator in front of already-emitted operand * * Means relocating the operand. */ static void reginsert(op, opnd) char op; char *opnd; { register char *src; register char *dst; register char *place; if (regcode == ®dummy) { regsize += 3; return; } src = regcode; regcode += 3; dst = regcode; while (src > opnd) *--dst = *--src; place = opnd; /* Op node, where operand used to be. */ *place++ = op; *place++ = '\0'; *place++ = '\0'; } /* - regtail - set the next-pointer at the end of a node chain */ static void regtail(p, val) char *p; char *val; { register char *scan; register char *temp; register int offset; if (p == ®dummy) return; /* Find last node. */ scan = p; for (;;) { temp = regnext(scan); if (temp == NULL) break; scan = temp; } if (OP(scan) == BACK) offset = scan - val; else offset = val - scan; *(scan+1) = (offset>>8)&0377; *(scan+2) = offset&0377; } /* - regoptail - regtail on operand of first argument; nop if operandless */ static void regoptail(p, val) char *p; char *val; { /* "Operandless" and "op != BRANCH" are synonymous in practice. */ if (p == NULL || p == ®dummy || OP(p) != BRANCH) return; regtail(OPERAND(p), val); } /* * regexec and friends */ /* * Global work variables for regexec(). */ static char *reginput; /* String-input pointer. */ static char *regbol; /* Beginning of input, for ^ check. */ static char **regstartp; /* Pointer to startp array. */ static char **regendp; /* Ditto for endp. */ /* * Forwards. */ STATIC int regtry(); STATIC int regmatch(); STATIC int regrepeat(); #ifdef DEBUG int regnarrate = 0; void regdump(); STATIC char *regprop(); #endif /* - regexec - match a regexp against a string */ int regexec(prog, string) register const regexp *prog; register const char *string; { register char *s; extern char *strchr(); /* Be paranoid... */ if (prog == NULL || string == NULL) { regerror("NULL parameter"); return(0); } /* Check validity of program. */ if (UCHARAT(prog->program) != MAGIC) { regerror("corrupted program"); return(0); } /* If there is a "must appear" string, look for it. */ if (prog->regmust != NULL) { s = (char *)string; while ((s = strchr(s, prog->regmust[0])) != NULL) { if (strncmp(s, prog->regmust, prog->regmlen) == 0) break; /* Found it. */ s++; } if (s == NULL) /* Not present. */ return(0); } /* Mark beginning of line for ^ . */ regbol = (char *)string; /* Simplest case: anchored match need be tried only once. */ if (prog->reganch) return(regtry(prog, string)); /* Messy cases: unanchored match. */ s = (char *)string; if (prog->regstart != '\0') /* We know what char it must start with. */ while ((s = strchr(s, prog->regstart)) != NULL) { if (regtry(prog, s)) return(1); s++; } else /* We don't -- general case. */ do { if (regtry(prog, s)) return(1); } while (*s++ != '\0'); /* Failure. */ return(0); } /* - regtry - try match at specific point */ static int /* 0 failure, 1 success */ regtry(prog, string) regexp *prog; char *string; { register int i; register char **sp; register char **ep; reginput = string; regstartp = prog->startp; regendp = prog->endp; sp = prog->startp; ep = prog->endp; for (i = NSUBEXP; i > 0; i--) { *sp++ = NULL; *ep++ = NULL; } if (regmatch(prog->program + 1)) { prog->startp[0] = string; prog->endp[0] = reginput; return(1); } else return(0); } /* - regmatch - main matching routine * * Conceptually the strategy is simple: check to see whether the current * node matches, call self recursively to see whether the rest matches, * and then act accordingly. In practice we make some effort to avoid * recursion, in particular by going through "ordinary" nodes (that don't * need to know whether the rest of the match failed) by a loop instead of * by recursion. */ static int /* 0 failure, 1 success */ regmatch(prog) char *prog; { register char *scan; /* Current node. */ char *next; /* Next node. */ extern char *strchr(); scan = prog; #ifdef DEBUG if (scan != NULL && regnarrate) fprintf(stderr, "%s(\n", regprop(scan)); #endif while (scan != NULL) { #ifdef DEBUG if (regnarrate) fprintf(stderr, "%s...\n", regprop(scan)); #endif next = regnext(scan); switch (OP(scan)) { case BOL: if (reginput != regbol) return(0); break; case EOL: if (*reginput != '\0') return(0); break; case WORDA: /* Must be looking at a letter, digit, or _ */ if ((!isalnum(*reginput)) && *reginput != '_') return(0); /* Prev must be BOL or nonword */ if (reginput > regbol && (isalnum(reginput[-1]) || reginput[-1] == '_')) return(0); break; case WORDZ: /* Must be looking at non letter, digit, or _ */ if (isalnum(*reginput) || *reginput == '_') return(0); /* We don't care what the previous char was */ break; case ANY: if (*reginput == '\0') return(0); reginput++; break; case EXACTLY: { register int len; register char *opnd; opnd = OPERAND(scan); /* Inline the first character, for speed. */ if (*opnd != *reginput) return(0); len = strlen(opnd); if (len > 1 && strncmp(opnd, reginput, len) != 0) return(0); reginput += len; } break; case ANYOF: if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) return(0); reginput++; break; case ANYBUT: if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) return(0); reginput++; break; case NOTHING: break; case BACK: break; case OPEN+1: case OPEN+2: case OPEN+3: case OPEN+4: case OPEN+5: case OPEN+6: case OPEN+7: case OPEN+8: case OPEN+9: { register int no; register char *save; no = OP(scan) - OPEN; save = reginput; if (regmatch(next)) { /* * Don't set startp if some later * invocation of the same parentheses * already has. */ if (regstartp[no] == NULL) regstartp[no] = save; return(1); } else return(0); } break; case CLOSE+1: case CLOSE+2: case CLOSE+3: case CLOSE+4: case CLOSE+5: case CLOSE+6: case CLOSE+7: case CLOSE+8: case CLOSE+9: { register int no; register char *save; no = OP(scan) - CLOSE; save = reginput; if (regmatch(next)) { /* * Don't set endp if some later * invocation of the same parentheses * already has. */ if (regendp[no] == NULL) regendp[no] = save; return(1); } else return(0); } break; case BRANCH: { register char *save; if (OP(next) != BRANCH) /* No choice. */ next = OPERAND(scan); /* Avoid recursion. */ else { do { save = reginput; if (regmatch(OPERAND(scan))) return(1); reginput = save; scan = regnext(scan); } while (scan != NULL && OP(scan) == BRANCH); return(0); /* NOTREACHED */ } } break; case STAR: case PLUS: { register char nextch; register int no; register char *save; register int min; /* * Lookahead to avoid useless match attempts * when we know what character comes next. */ nextch = '\0'; if (OP(next) == EXACTLY) nextch = *OPERAND(next); min = (OP(scan) == STAR) ? 0 : 1; save = reginput; no = regrepeat(OPERAND(scan)); while (no >= min) { /* If it could work, try it. */ if (nextch == '\0' || *reginput == nextch) if (regmatch(next)) return(1); /* Couldn't or didn't -- back up. */ no--; reginput = save + no; } return(0); } break; case END: return(1); /* Success! */ break; default: regerror("memory corruption"); return(0); break; } scan = next; } /* * We get here only if there's trouble -- normally "case END" is * the terminating point. */ regerror("corrupted pointers"); return(0); } /* - regrepeat - repeatedly match something simple, report how many */ static int regrepeat(p) char *p; { register int count = 0; register char *scan; register char *opnd; scan = reginput; opnd = OPERAND(p); switch (OP(p)) { case ANY: count = strlen(scan); scan += count; break; case EXACTLY: while (*opnd == *scan) { count++; scan++; } break; case ANYOF: while (*scan != '\0' && strchr(opnd, *scan) != NULL) { count++; scan++; } break; case ANYBUT: while (*scan != '\0' && strchr(opnd, *scan) == NULL) { count++; scan++; } break; default: /* Oh dear. Called inappropriately. */ regerror("internal foulup"); count = 0; /* Best compromise. */ break; } reginput = scan; return(count); } /* - regnext - dig the "next" pointer out of a node */ static char * regnext(p) register char *p; { register int offset; if (p == ®dummy) return(NULL); offset = NEXT(p); if (offset == 0) return(NULL); if (OP(p) == BACK) return(p-offset); else return(p+offset); } #ifdef DEBUG STATIC char *regprop(); /* - regdump - dump a regexp onto stdout in vaguely comprehensible form */ void regdump(r) regexp *r; { register char *s; register char op = EXACTLY; /* Arbitrary non-END op. */ register char *next; extern char *strchr(); s = r->program + 1; while (op != END) { /* While that wasn't END last time... */ op = OP(s); printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */ next = regnext(s); if (next == NULL) /* Next ptr. */ printf("(0)"); else printf("(%d)", (s-r->program)+(next-s)); s += 3; if (op == ANYOF || op == ANYBUT || op == EXACTLY) { /* Literal string, where present. */ while (*s != '\0') { putchar(*s); s++; } s++; } putchar('\n'); } /* Header fields of interest. */ if (r->regstart != '\0') printf("start `%c' ", r->regstart); if (r->reganch) printf("anchored "); if (r->regmust != NULL) printf("must have \"%s\"", r->regmust); printf("\n"); } /* - regprop - printable representation of opcode */ static char * regprop(op) char *op; { register char *p; static char buf[50]; (void) strcpy(buf, ":"); switch (OP(op)) { case BOL: p = "BOL"; break; case EOL: p = "EOL"; break; case ANY: p = "ANY"; break; case ANYOF: p = "ANYOF"; break; case ANYBUT: p = "ANYBUT"; break; case BRANCH: p = "BRANCH"; break; case EXACTLY: p = "EXACTLY"; break; case NOTHING: p = "NOTHING"; break; case BACK: p = "BACK"; break; case END: p = "END"; break; case OPEN+1: case OPEN+2: case OPEN+3: case OPEN+4: case OPEN+5: case OPEN+6: case OPEN+7: case OPEN+8: case OPEN+9: sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN); p = NULL; break; case CLOSE+1: case CLOSE+2: case CLOSE+3: case CLOSE+4: case CLOSE+5: case CLOSE+6: case CLOSE+7: case CLOSE+8: case CLOSE+9: sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE); p = NULL; break; case STAR: p = "STAR"; break; case PLUS: p = "PLUS"; break; case WORDA: p = "WORDA"; break; case WORDZ: p = "WORDZ"; break; default: regerror("corrupted opcode"); break; } if (p != NULL) (void) strcat(buf, p); return(buf); } #endif /* * The following is provided for those people who do not have strcspn() in * their C libraries. They should get off their butts and do something * about it; at least one public-domain implementation of those (highly * useful) string routines has been published on Usenet. */ #ifdef STRCSPN /* * strcspn - find length of initial segment of s1 consisting entirely * of characters not from s2 */ static int strcspn(s1, s2) char *s1; char *s2; { register char *scan1; register char *scan2; register int count; count = 0; for (scan1 = s1; *scan1 != '\0'; scan1++) { for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */ if (*scan1 == *scan2++) return(count); count++; } return(count); } #endif xless-1.7.orig/regexp/regexp.3100444 0 0 21347 5004124440 14423 0ustar rootroot.\" Copyright 1991 The Regents of the University of California. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)regexp.3 5.2 (Berkeley) 4/20/91 .\" .Dd April 20, 1991 .Dt REGEXP 3 .Os .Sh NAME .Nm regcomp , .Nm regexec , .Nm regsub , .Nm regerror .Nd regular expression handlers .Sh SYNOPSIS .Fd #include .Ft regexp * .Fn regcomp "const char *exp" .Ft int .Fn regexec "const regexp *prog" "const char *string" .Ft void .Fn regsub "const regexp *prog" "const char *source" "char *dest" .Sh DESCRIPTION The .Fn regcomp , .Fn regexec , .Fn regsub , and .Fn regerror functions implement .Xr egrep 1 Ns -style regular expressions and supporting facilities. .Pp The .Fn regcomp function compiles a regular expression into a structure of type .Xr regexp , and returns a pointer to it. The space has been allocated using .Xr malloc 3 and may be released by .Xr free . .Pp The .Fn regexec function matches a .Dv NUL Ns -terminated .Fa string against the compiled regular expression in .Fa prog . It returns 1 for success and 0 for failure, and adjusts the contents of .Fa prog Ns 's .Em startp and .Em endp (see below) accordingly. .Pp The members of a .Xr regexp structure include at least the following (not necessarily in order): .Bd -literal -offset indent char *startp[NSUBEXP]; char *endp[NSUBEXP]; .Ed .Pp where .Dv NSUBEXP is defined (as 10) in the header file. Once a successful .Fn regexec has been done using the .Fn regexp , each .Em startp Ns - Em endp pair describes one substring within the .Fa string , with the .Em startp pointing to the first character of the substring and the .Em endp pointing to the first character following the substring. The 0th substring is the substring of .Fa string that matched the whole regular expression. The others are those substrings that matched parenthesized expressions within the regular expression, with parenthesized expressions numbered in left-to-right order of their opening parentheses. .Pp The .Fn regsub function copies .Fa source to .Fa dest , making substitutions according to the most recent .Fn regexec performed using .Fa prog . Each instance of `&' in .Fa source is replaced by the substring indicated by .Em startp Ns Bq and .Em endp Ns Bq . Each instance of .Sq \e Ns Em n , where .Em n is a digit, is replaced by the substring indicated by .Em startp Ns Bq Em n and .Em endp Ns Bq Em n . To get a literal `&' or .Sq \e Ns Em n into .Fa dest , prefix it with `\e'; to get a literal `\e' preceding `&' or .Sq \e Ns Em n , prefix it with another `\e'. .Pp The .Fn regerror function is called whenever an error is detected in .Fn regcomp , .Fn regexec , or .Fn regsub . The default .Fn regerror writes the string .Fa msg , with a suitable indicator of origin, on the standard error output and invokes .Xr exit 2 . The .Fn regerror function can be replaced by the user if other actions are desirable. .Sh REGULAR EXPRESSION SYNTAX A regular expression is zero or more .Em branches , separated by `|'. It matches anything that matches one of the branches. .Pp A branch is zero or more .Em pieces , concatenated. It matches a match for the first, followed by a match for the second, etc. .Pp A piece is an .Em atom possibly followed by `*', `+', or `?'. An atom followed by `*' matches a sequence of 0 or more matches of the atom. An atom followed by `+' matches a sequence of 1 or more matches of the atom. An atom followed by `?' matches a match of the atom, or the null string. .Pp An atom is a regular expression in parentheses (matching a match for the regular expression), a .Em range (see below), `.' (matching any single character), `^' (matching the null string at the beginning of the input string), `$' (matching the null string at the end of the input string), a `\e' followed by a single character (matching that character), or a single character with no other significance (matching that character). .Pp A .Em range is a sequence of characters enclosed in `[]'. It normally matches any single character from the sequence. If the sequence begins with `^', it matches any single character .Em not from the rest of the sequence. If two characters in the sequence are separated by `\-', this is shorthand for the full list of .Tn ASCII characters between them (e.g. `[0-9]' matches any decimal digit). To include a literal `]' in the sequence, make it the first character (following a possible `^'). To include a literal `\-', make it the first or last character. .Sh AMBIGUITY If a regular expression could match two different parts of the input string, it will match the one which begins earliest. If both begin in the same place but match different lengths, or match the same length in different ways, life gets messier, as follows. .Pp In general, the possibilities in a list of branches are considered in left-to-right order, the possibilities for `*', `+', and `?' are considered longest-first, nested constructs are considered from the outermost in, and concatenated constructs are considered leftmost-first. The match that will be chosen is the one that uses the earliest possibility in the first choice that has to be made. If there is more than one choice, the next will be made in the same manner (earliest possibility) subject to the decision on the first choice. And so forth. .Pp For example, .Sq Li (ab|a)b*c could match `abc' in one of two ways. The first choice is between `ab' and `a'; since `ab' is earlier, and does lead to a successful overall match, it is chosen. Since the `b' is already spoken for, the `b*' must match its last possibility\(emthe empty string\(emsince it must respect the earlier choice. .Pp In the particular case where no `|'s are present and there is only one `*', `+', or `?', the net effect is that the longest possible match will be chosen. So .Sq Li ab* , presented with `xabbbby', will match `abbbb'. Note that if .Sq Li ab* , is tried against `xabyabbbz', it will match `ab' just after `x', due to the begins-earliest rule. (In effect, the decision on where to start the match is the first choice to be made, hence subsequent choices must respect it even if this leads them to less-preferred alternatives.) .Sh RETURN VALUES The .Fn regcomp function returns .Dv NULL for a failure .Pf ( Fn regerror permitting), where failures are syntax errors, exceeding implementation limits, or applying `+' or `*' to a possibly-null operand. .Sh SEE ALSO .Xr ed 1 , .Xr ex 1 , .Xr expr 1 , .Xr egrep 1 , .Xr fgrep 1 , .Xr grep 1 , .Xr regex 3 .Sh HISTORY Both code and manual page for .Fn regcomp , .Fn regexec , .Fn regsub , and .Fn regerror were written at the University of Toronto and appeared in .Bx 4.3 tahoe . They are intended to be compatible with the Bell V8 .Xr regexp 3 , but are not derived from Bell code. .Sh BUGS Empty branches and empty regular expressions are not portable to V8. .Pp The restriction against applying `*' or `+' to a possibly-null operand is an artifact of the simplistic implementation. .Pp Does not support .Xr egrep Ns 's newline-separated branches; neither does the V8 .Xr regexp 3 , though. .Pp Due to emphasis on compactness and simplicity, it's not strikingly fast. It does give special attention to handling simple cases quickly. xless-1.7.orig/regexp/regsub.c100644 0 0 3747 5600151064 14472 0ustar rootroot/* * regsub * * Copyright (c) 1986 by University of Toronto. * Written by Henry Spencer. Not derived from licensed software. * * Permission is granted to anyone to use this software for any * purpose on any computer system, and to redistribute it freely, * subject to the following restrictions: * * 1. The author is not responsible for the consequences of use of * this software, no matter how awful, even if they arise * from defects in it. * * 2. The origin of this software must not be misrepresented, either * by explicit claim or by omission. * * 3. Altered versions must be plainly marked as such, and must not * be misrepresented as being the original software. */ #include #include #include #include "regmagic.h" #ifndef CHARBITS #define UCHARAT(p) ((int)*(unsigned char *)(p)) #else #define UCHARAT(p) ((int)*(p)&CHARBITS) #endif /* - regsub - perform substitutions after a regexp match */ void regsub(prog, source, dest) const regexp *prog; const char *source; char *dest; { register char *src; register char *dst; register char c; register int no; register int len; #ifndef AIXV3 extern char *strncpy(); #endif if (prog == NULL || source == NULL || dest == NULL) { regerror("NULL parm to regsub"); return; } if (UCHARAT(prog->program) != MAGIC) { regerror("damaged regexp fed to regsub"); return; } src = (char *)source; dst = dest; while ((c = *src++) != '\0') { if (c == '&') no = 0; else if (c == '\\' && '0' <= *src && *src <= '9') no = *src++ - '0'; else no = -1; if (no < 0) { /* Ordinary character. */ if (c == '\\' && (*src == '\\' || *src == '&')) c = *src++; *dst++ = c; } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) { len = prog->endp[no] - prog->startp[no]; (void) strncpy(dst, prog->startp[no], len); dst += len; if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */ regerror("damaged match string"); return; } } } *dst++ = '\0'; } xless-1.7.orig/regexp/regexp.h100444 0 0 1145 5572744700 14503 0ustar rootroot/* * Definitions etc. for regexp(3) routines. * * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], * not the System V one. */ #define NSUBEXP 10 typedef struct regexp { char *startp[NSUBEXP]; char *endp[NSUBEXP]; char regstart; /* Internal use only. */ char reganch; /* Internal use only. */ char *regmust; /* Internal use only. */ int regmlen; /* Internal use only. */ char program[1]; /* Unwarranted chumminess with compiler. */ } regexp; #ifndef __STDC__ #define const #endif extern regexp *regcomp(); extern int regexec(); extern void regsub(); extern void regerror(); xless-1.7.orig/regexp/regmagic.h100444 0 0 231 4620150477 14735 0ustar rootroot/* * The first byte of the regexp internal "program" is actually this magic * number; the start node begins in the second byte. */ #define MAGIC 0234 xless-1.7.orig/regexp/Imakefile100444 0 0 255 5572734054 14633 0ustar rootroot SRCS = regexp.c regsub.c regerror.c OBJS = regexp.o regsub.o regerror.o EXTRA_INCLUDES = -I. NormalLibraryObjectRule() NormalLibraryTarget(regexp,$(OBJS)) DependTarget() xless-1.7.orig/actions.c100444 0 0 4260 5573442361 13352 0ustar rootroot/* * Copyright (C) 1994 by Dave Glowacki * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * to rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * DAVE GLOWACKI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * $Header: /usr/sww/share/src/X11R6/local/applications/xless-1.5/RCS/actions.c,v 1.6 1994/06/02 20:45:12 dglo Exp $ */ #include #include #include #include "xless.h" static void QuitAction __P((Widget, XButtonEvent *, String *, Cardinal *)); static void HelpAction __P((Widget, XButtonEvent *, String *, Cardinal *)); XtActionsRec actions[] = { { "quit", (XtActionProc )QuitAction }, /* { "search", (XtActionProc )SearchAction }, */ /* { "search_next", (XtActionProc )SearchNextAction }, */ /* { "editor", (XtActionProc )EditorAction }, */ /* { "reload", (XtActionProc )ReloadAction }, */ /* { "change_file", (XtActionProc )ChangeFileAction }, */ /* { "new_window", (XtActionProc )NewWindowAction }, */ { "help", (XtActionProc )HelpAction }, }; Cardinal numactions = XtNumber(actions); static void QuitAction(w, e, p, n) Widget w; XButtonEvent *e; String *p; Cardinal *n; { QuitFunction(); } static void HelpAction(w, e, p, n) Widget w; XButtonEvent *e; String *p; Cardinal *n; { WindowInfo *wi; wi = findWindowInfo(w); PopupHelp(w, (XtPointer )wi, NULL); } xless-1.7.orig/callbacks.c100444 0 0 27675 5616064603 13665 0ustar rootroot/* * Copyright (C) 1994 by Dave Glowacki * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * to rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * DAVE GLOWACKI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * $Header: /usr/sww/share/src/X11R6/local/applications/xless-1.7/RCS/callbacks.c,v 1.37 1994/07/29 02:28:14 dglo Exp $ */ #include #include #include #include #include #include #include #include #include "regexp/regexp.h" #include "xless.h" extern char *getenv __P((const char *)); extern int system __P((const char *)); static void getReadOnlySource __P((Widget, const char *)); static int find __P((const char *, WindowInfo *, XawTextPosition)); static void doSearch __P((WindowInfo *)); static void popdownAndSearch __P((Widget, XtPointer, XtPointer)); static void popdownAndChange __P((Widget, XtPointer, XtPointer)); static void popdownAndCreate __P((Widget, XtPointer, XtPointer)); static void getReadOnlySource(w, string) Widget w; const char *string; { Widget source; /* free old source */ source = XawTextGetSource(w); XtDestroyWidget(source); /* Create a new source for the text widget, and put in the new string */ source = XtVaCreateWidget("readText", asciiSrcObjectClass, w, XtNeditType, XawtextRead, XtNstring, string, XtNuseStringInPlace, True, NULL); XawTextSetSource(w, source, (XawTextPosition) 0); } /* * Button callback functions. */ void Quit(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { QuitFunction(); } void Cancel(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { XtPopdown((Widget)closure); } void CallEditor(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { WindowInfo *wi = (WindowInfo *)closure; const char *editor; int cmdlen = 0; char *cmd; /* figure out which editor they want */ if ((editor = getenv("VISUAL")) == NULL && (editor = getenv("EDITOR")) == NULL) editor = (resources.editor ? resources.editor : DEFEDITOR); /* get a buffer long enough for the entire command */ if (!resources.editorDoesWindows) cmdlen = 9; /* "xterm -e " */ cmdlen += strlen(editor) + 1 + strlen(wi->file) + 2; cmd = (char *)XtMalloc((Cardinal )cmdlen); /* don't start from an xterm if the editor has its own window */ if (resources.editorDoesWindows) strcpy(cmd, editor); else { strcpy(cmd, "xterm -e "); strcat(cmd, editor); } strcat(cmd, " "); strcat(cmd, wi->file); strcat(cmd, "&"); system(cmd); XtFree(cmd); } void Reload(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { WindowInfo *wi = (WindowInfo *)closure; int fd; fd = open(wi->file, O_RDONLY); if (fd == -1) CouldntOpen(wi->base, wi->file); else { XtFree((char *)wi->memory); InitData(fd, wi); getReadOnlySource(wi->text, wi->memory); } } static int find(text, wi, offset) const char *text; WindowInfo *wi; XawTextPosition offset; { const char *special = "\\|*+?.^$[]()"; static Widget badPattern = NULL; char *str = wi->searchBuf; XawTextPosition beg, end; regexp *pat; char *s; Boolean insensitive, allocated; int len; unsigned slen, nSpecial, nAlpha; char *newstr; int rtnval; /* is this a case-insensitive search? */ insensitive = (wi->flag & XLessSearchInsensitive) == XLessSearchInsensitive; allocated = 0; /* if we need to escape special characters... */ if ((wi->flag & XLessSearchRegExpr) != XLessSearchRegExpr) { /* count the special characters */ nSpecial = nAlpha = 0; for (s = str; *s; s++) { if (strchr(special, *s) != NULL) nSpecial++; else if (insensitive && isalpha(*s)) nAlpha++; } /* if we need to escape something... */ if (nSpecial > 0 || (insensitive && nAlpha > 0)) { /* figure out how much space we'll need */ len = strlen(str); if (insensitive) slen = nAlpha * 4 + nSpecial * 2 + (len - (nSpecial + nAlpha)); else slen = len + nSpecial; /* get space for the new string */ newstr = (char *)XtMalloc(slen + 1); if (newstr == NULL) { fprintf(stderr, "Out of space in search routine!\n"); exit(1); } /* build the special string */ for (s = newstr; *str; str++) { if (strchr(special, *str) != NULL) { *s++ = '\\'; *s++ = *str; } else if (insensitive && isalpha(*str)) { *s++ = '['; *s++ = *str; if (isupper(*str)) *s++ = tolower(*str); else *s++ = toupper(*str); *s++ = ']'; } else *s++ = *str; } *s = 0; /* allocated string is the search pattern now */ allocated = 1; str = newstr; } } /* try to match the pattern */ rtnval = 0; pat = regcomp(str); if (pat == NULL) { if (!badPattern) badPattern = MessageBox(wi->base, "Bad pattern ...", "OK", 0, 0); if (badPattern) SetPopup(wi->base, badPattern); } else if (regexec(pat, text)) { beg = offset + (pat->startp[0] - text); end = beg + (pat->endp[0] - pat->startp[0]); XawTextSetInsertionPoint(wi->text, end); XawTextSetSelection(wi->text, beg, end); } else rtnval = -1; /* clean up allocated memory */ if (allocated) XtFree(str); if (pat) XtFree((char *)pat); return(rtnval); } static void doSearch(wi) WindowInfo *wi; { XawTextPosition offset; int len; const char *top; static Widget notFound = NULL; len = strlen(wi->searchBuf); offset = XawTextGetInsertionPoint(wi->text); top = wi->memory + offset; if (len <= 0 || find(top, wi, offset)) { if (!notFound) notFound = MessageBox(wi->base, "String not found ...", "OK", 0, 0); if (notFound) SetPopup(wi->base, notFound); } } void SearchNext(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { WindowInfo *wi = (WindowInfo *)closure; static Widget noString = NULL; if (wi->searchBuf == NULL) { if (!noString) noString = MessageBox(wi->base, "No search string specified ...", "OK", 0, 0); if (noString) SetPopup(wi->base, noString); } else doSearch(wi); } static void popdownAndSearch(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { WindowInfo *wi = (WindowInfo *)closure; XtPopdown((Widget)wi->searchPopup); doSearch(wi); } void Search(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { WindowInfo *wi = (WindowInfo *)closure; if (!wi->searchBuf) { wi->searchBuf = (char *)XtMalloc(XLESS_MAX_INPUT); wi->searchBuf[0] = 0; } if (!wi->searchPopup) wi->searchPopup = SearchBox(wi->base, popdownAndSearch, (XtPointer )wi, "Search for:", "Search", wi->searchBuf); /* popup search dialog box */ SetPopup(wi->base, wi->searchPopup); } static void popdownAndChange(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { WindowInfo *wi = (WindowInfo *)closure; int fd; const char *filename; XLessFlag flag = XLessClearFlag; XtPopdown((Widget)wi->changeFilePopup); /* make sure there's a filename there */ filename = wi->changeFileBuf; if (*filename == 0) return; #ifdef TILDE_EXPANSION /* see if we need to do tilde expansion */ if (filename && *filename == '~') { filename = TildeExpand(filename); if (*filename != '~') flag |= XLessFreeFilename; } #endif /* TILDE_EXPANSION */ fd = open(filename, O_RDONLY); if (fd == -1) CouldntOpen(wi->base, filename); else { /* read in new file */ XtFree((char *)wi->memory); InitData(fd, wi); if (wi->flag & XLessFreeFilename) { XtFree((char *)wi->file); wi->flag &= ~XLessFreeFilename; } getReadOnlySource(wi->text, wi->memory); wi->file = filename; wi->flag |= flag; /* sensitize buttons if previous file was STDIN */ if (wi->editorButton) { XtVaSetValues(wi->editorButton, XtNsensitive, True, NULL); wi->editorButton = 0; } if (wi->reloadButton) { XtVaSetValues(wi->reloadButton, XtNsensitive, True, NULL); wi->editorButton = 0; } /* set title & icon name */ SetXNames(wi->base, filename); } } void ChangeFile(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { WindowInfo *wi = (WindowInfo *)closure; if (!wi->changeFileBuf) { wi->changeFileBuf = (char *)XtMalloc(XLESS_MAX_INPUT); wi->changeFileBuf[0] = 0; } if (!wi->changeFilePopup) wi->changeFilePopup = DialogBox(wi->base, popdownAndChange, (XtPointer)wi, "Enter filename:", "Ok", wi->changeFileBuf); SetPopup(wi->base, wi->changeFilePopup); /* Change file dialog box */ } static void popdownAndCreate(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { WindowInfo *wi = (WindowInfo *)closure; XtPopdown((Widget)wi->newWindowPopup); CreateWindow(wi->base, wi->newWindowBuf); } void NewWindow(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { WindowInfo *wi = (WindowInfo *)closure; if (!wi->newWindowBuf) { wi->newWindowBuf = (char *)XtMalloc(XLESS_MAX_INPUT); wi->newWindowBuf[0] = 0; } if (!wi->newWindowPopup) wi->newWindowPopup = DialogBox(wi->base, popdownAndCreate, (XtPointer)wi, "Enter filename:", "Ok", wi->newWindowBuf); SetPopup(wi->base, wi->newWindowPopup); /* New window dialog box */ } void CloseWindow(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { WindowInfo *sd = (WindowInfo *)closure; DestroyWindowInfo(sd); } void Print(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { WindowInfo *wi = (WindowInfo *)closure; FILE *file; const char *printfile; char *cmd; #ifdef WIMPY_STDIO char *line, *l; #endif if (wi->file == NULL) { /* create a temporary file */ printfile = tmpnam(0); file = fopen(printfile, "w"); #ifdef WIMPY_STDIO /* write stdin (line by line) to temporary file */ line = l = wi->memory; while (line && *line) { if (l = strchr(line, '\n')) *l = 0; fprintf(file, "%s\n", line); if (l) *l = '\n'; line = l+1; } #else /* !WIMPY_STDIO */ /* write stdin (in one manly hunk) to temp file */ fputs(wi->memory, file); #endif /* WIMPY_STDIO */ fclose(file); } else printfile = wi->file; /* create the print command string */ cmd = (char *)XtMalloc((Cardinal )(strlen(resources.printCmd) + 1 + strlen(printfile) + 1)); strcpy(cmd, resources.printCmd); strcat(cmd, " "); strcat(cmd, printfile); system(cmd); XtFree(cmd); /* unlink the file if we created it */ if (wi->file == NULL) unlink(printfile); } void Background(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { static Widget forkError = NULL; WindowInfo *wi = (WindowInfo *)closure; switch (fork()) { case 0: break; case -1: if (!forkError) forkError = MessageBox(wi->base, "Error while backgrounding ...", "OK", 0, 0); if (forkError) SetPopup(wi->base, forkError); break; default: exit(0); } } xless-1.7.orig/functions.c100444 0 0 4512 5573442364 13725 0ustar rootroot/* * Copyright (C) 1994 by Dave Glowacki * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * to rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * DAVE GLOWACKI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * $Header: /usr/sww/share/src/X11R6/local/applications/xless-1.5/RCS/functions.c,v 1.11 1994/06/02 20:45:12 dglo Exp $ */ #include #include #include #include "xless.h" static void okQuitAll __P((Widget, XtPointer, XtPointer)); static void cancelQuitAll __P((Widget, XtPointer, XtPointer)); static int QuitAllPrompt __P((void)); static void okQuitAll(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { XtPopdown((Widget)closure); XtDestroyWidget((Widget)closure); DestroyAllWindows(); exit(0); } static void cancelQuitAll(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { XtPopdown((Widget)closure); } static int QuitAllPrompt() { Widget base; static Widget quitall = 0; /* make sure there's at least one window */ if (!windowlist) return(1); /* grab first base widget */ base = windowlist->base; /* popup warning box */ if (!quitall) quitall = MessageBox(base, "Quit ALL windows?", "Cancel", cancelQuitAll, "OK", okQuitAll, 0); SetPopup(base, quitall); return(0); } /* * clean up, exit application */ void QuitFunction() { if ((windowcount == 1) || QuitAllPrompt()) { DestroyAllWindows(); exit(0); } } xless-1.7.orig/help.c100444 0 0 10702 5616064553 12661 0ustar rootroot/* * Copyright (C) 1994 by Dave Glowacki * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * to rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * DAVE GLOWACKI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * $Header: /usr/sww/share/src/X11R6/local/applications/xless-1.7/RCS/help.c,v 1.23 1994/07/29 02:27:40 dglo Exp $ */ #include #include #include #include #include #include #include #include "xless.h" #include "XLessHlp.icn" static Widget createHelp __P((Widget)); static void PopdownHelp __P((Widget, XtPointer, XtPointer)); /* Function Name: CreateHelp. * Description: This function creates the help widget so that it will be * ready to be displayed. * Arguments: * Returns: the help widget */ static Widget createHelp(top) Widget top; { static const char *helpIconName = NULL; int fd; const char *helpPage; Widget base, pane, helpText, button; XtCallbackRec callback[2]; XtAccelerators accel; const String quitstr = "#override Q: set() notify() unset()\n"; /* try to open the help file */ fd = open(resources.helpFile, O_RDONLY); if (fd == -1) { CouldntOpen(top, resources.helpFile); return 0; } helpPage = InitData(fd, NULL); /* make sure the window title exists */ if (!helpIconName) { char *hin; hin = (char *)XtMalloc((Cardinal )(strlen(progname) + 6)); strcpy(hin, progname); strcat(hin, ":help"); helpIconName = hin; } /* create a new application shell */ base = XtVaAppCreateShell("help", className, applicationShellWidgetClass, disp, XtNallowShellResize, TRUE, XtNiconName, helpIconName, XtNiconPixmap, XCreateBitmapFromData(disp, XRootWindow(disp, 0), XLessHelp_bits, XLessHelp_width, XLessHelp_height), NULL); pane = XtVaCreateManagedWidget("helpPane", panedWidgetClass, base, NULL); helpText = MakeText(pane, NULL, helpPage, 1); /* set up Done button callback array */ callback[0].callback = PopdownHelp; callback[0].closure = (XtPointer)base; callback[1].callback = NULL; callback[1].closure = (XtPointer)NULL; /* set up Done button accelerator */ accel = XtParseAcceleratorTable(quitstr); /* create Done button */ button = XtVaCreateManagedWidget("helpQuit", commandWidgetClass, pane, XtNaccelerators, accel, XtNcallback, callback, XtNfont, buttonFont, XtNlabel, "Done With Help", NULL); XtInstallAccelerators(helpText, button); XtRealizeWidget(base); return(base); } /* Function Name: PopdownHelp * Description: This function pops down the help widget. * Arguments: w - the widget we are calling back from. * number - (closure) the number to switch on. * junk - (call data) not used. * Returns: none. */ /* ARGSUSED */ static void PopdownHelp(w, helpWidget, junk) Widget w; XtPointer helpWidget, junk; { XtPopdown((Widget )helpWidget); } /* Function Name: PopupHelp * Description: This function pops up the help widget, unless no * help could be found. * Arguments: w - the widget we are calling back from. * number - (closure) the number to switch on. * junk - (call data) not used. * Returns: none. */ /* ARGSUSED */ void PopupHelp(w, closure, callData) Widget w; XtPointer closure, callData; { WindowInfo *wi = (WindowInfo *)closure; static Widget helpWidget = 0; if (!helpWidget) helpWidget = createHelp(wi ? wi->base : w); if (helpWidget) XtPopup(helpWidget, XtGrabNone); } xless-1.7.orig/init.c100444 0 0 45775 5616071273 12713 0ustar rootroot/* * Copyright (C) 1994 by Dave Glowacki * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * to rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * DAVE GLOWACKI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * $Header: /usr/sww/share/src/X11R6/local/applications/xless-1.7/RCS/init.c,v 1.45 1994/07/29 03:07:33 dglo Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "xless.h" #define FontWidth(fnt) ((fnt)->max_bounds.width) #define FontHeight(fnt) ((fnt)->ascent + (fnt)->descent) static void fixNewText __P((char *, unsigned *, unsigned *, unsigned *)); static void restartNewInputHandler __P((XtPointer, XtIntervalId *)); static void handleNewInput __P((XtPointer, int *, XtInputId *)); static Widget makeButton __P((Widget, int, unsigned, Widget, XtCallbackProc, WindowInfo *, String, const char *)); static void ParseGeometryRsrc __P((void)); #define DEFAULT_WIDTH 80 #define DEFAULT_HEIGHT 24 static int geomParsed = 0; static int geomMask, geomX, geomY; static unsigned int geomWidth, geomHeight; static char *geomPosition = NULL; static void fixNewText(text, lp, wp, hp) char *text; unsigned *lp, *wp, *hp; { char *tmp; int i, w; /* lose all underlined and bold characters in the file */ i = w = 0; tmp = text; while (i < *lp) { if ((i+1 < *lp) && (*(text + i) == '_') && (*(text + i + 1) == '\b')) { i += 2; } else if ((i+2 < *lp) && (*(text + i) == *(text + i + 2)) && (*(text + i + 1) == '\b')) { i += 2; } else { *tmp = *(text + i++); if (*tmp == '\n') { if (w > *wp) *wp = w; w = 0; (*hp)++; } else if (*tmp == '\t') { w += 8 - (w % 8); } else w++; tmp++; } } *tmp++ = 0; *lp = (tmp - text); } static void restartNewInputHandler(closure, ignored) XtPointer closure; XtIntervalId *ignored; { WindowInfo *wi = (WindowInfo *)closure; wi->inputInfo->id = XtAppAddInput(context, wi->inputInfo->fd, (XtPointer )XtInputReadMask, handleNewInput, (XtPointer )wi); } static void handleNewInput(closure, source, id) XtPointer closure; int *source; XtInputId *id; { WindowInfo *wi = (WindowInfo *)closure; char buffer[BUFSIZ]; unsigned nbytes, lastchar; Cardinal needed; char *bottom; XawTextPosition pos; if ((nbytes = read(*source, buffer, (size_t )BUFSIZ)) == -1) { XtAppError(context, "handleNewMessage: read failed"); return; } if (nbytes > 0) { needed = wi->used + nbytes + (wi->flag & XLessAddedNewline ? 0 : 1); if (needed > wi->allocated) { wi->memory = XtRealloc((char *)wi->memory, needed); wi->allocated = needed; } lastchar = wi->used - (wi->flag & XLessAddedNewline ? 2 : 1); bottom = (char *)&(wi->memory[lastchar]); strncpy(bottom, buffer, (size_t )nbytes); wi->flag = (wi->flag & ~(unsigned )XLessAddedNewline); if (bottom[nbytes-1] != '\n') { wi->flag |= XLessAddedNewline; bottom[nbytes++] = '\n'; } bottom[nbytes] = 0; fixNewText(bottom, &nbytes, &(wi->dataWidth), &(wi->dataHeight)); wi->used = lastchar + nbytes; pos = XawTextGetInsertionPoint(wi->text); XtVaSetValues(wi->text, XtNstring, wi->memory, NULL); XawTextSetInsertionPoint(wi->text, (pos != lastchar ? pos : wi->used - (wi->flag & XLessAddedNewline ? 2 : 1))); } else { /* no input was waiting for us */ if (wi->inputInfo->falseAlarm++ >= 3) { /* bump up the wait interval */ wi->inputInfo->interval <<= 1; wi->inputInfo->falseAlarm = 0; } /* turn off input source... */ XtRemoveInput(wi->inputInfo->id); /* ...but set alarm to turn it back on after the appropriate interval */ XtAppAddTimeOut(context, wi->inputInfo->interval, restartNewInputHandler, (XtPointer )wi); } } static char * readFile(fd, wi, szp) int fd; WindowInfo *wi; Cardinal *szp; { struct stat fileinfo; /* file information from fstat */ char *data; XtInputId id; /* get size of file */ if (fstat(fd, &fileinfo)) { fprintf(stderr, "%s: can't get file size.\n", progname); exit(1); } /* leave space for the NULL (and possibly a final NEWLINE) */ data = (char *)XtMalloc((Cardinal )(fileinfo.st_size + 2)); /* read entire file */ read(fd, data, (size_t )fileinfo.st_size); if (resources.monitorFile && wi) { id = XtAppAddInput(context, fd, (XtPointer )XtInputReadMask, handleNewInput, (XtPointer )wi); if (wi) { wi->inputInfo = (InputInfo *)XtMalloc((Cardinal )sizeof(InputInfo)); wi->inputInfo->fd = fd; wi->inputInfo->id = id; wi->inputInfo->interval = 1000; wi->inputInfo->falseAlarm = 0; } } else { close(fd); /* make sure file ends with a NEWLINE */ if (*(data + fileinfo.st_size - 1) != '\n') { *(data + fileinfo.st_size) = '\n'; fileinfo.st_size++; if (wi) wi->flag |= XLessAddedNewline; } } *szp = fileinfo.st_size; return(data); } static char * readStdIn(fd, wi, szp) int fd; WindowInfo *wi; Cardinal *szp; { XtInputId id; char *data, *where; int size, sz, newsz; if (resources.monitorFile && wi) { /* only allocate a single byte, read everything dynamically */ data = (char *)XtMalloc(2); size = 1; *data = '\n'; if (wi) { wi->flag |= XLessAddedNewline; id = XtAppAddInput(context, 0, (XtPointer )XtInputReadMask, handleNewInput, (XtPointer )wi); wi->inputInfo = (InputInfo *)XtMalloc((Cardinal )sizeof(InputInfo)); wi->inputInfo->fd = 0; wi->inputInfo->id = id; wi->inputInfo->interval = 1000; wi->inputInfo->falseAlarm = 0; } } else { /* read STDIN a chunk at a time */ data = (char *)XtMalloc(XLESS_MEMORY_CHUNK); size = 0; where = data; while ((sz = read(fd, where, (size_t )XLESS_MEMORY_CHUNK)) != 0) { size += sz; newsz = size + XLESS_MEMORY_CHUNK; data = (char *)XtRealloc(data, (unsigned)newsz); where = data + size; } /* see if file ends with a NEWLINE */ if (*(data + size - 1) != '\n') size++; /* allocate final chunk of memory */ newsz = size + 1; data = (char *)XtRealloc(data, (unsigned)newsz); /* make sure file ends with a NEWLINE */ if (*(data + size - 1) != '\n') *(data + size - 1) = '\n'; } *szp = size; return(data); } const char * InitData(fd, wi) int fd; WindowInfo *wi; { char *data; /* pointer to the data stored in dynamic memory */ unsigned width, height, length; Cardinal size; /* * Get file size and allocate a chunk of memory for the file to be * copied into. */ if (fd != 0) data = readFile(fd, wi, &size); else data = readStdIn(fd, wi, &size); /* NUL-terminate file string */ *(data + size) = '\0'; width = height = 0; length = size; fixNewText((char *)data, &length, &width, &height); if (wi) { wi->memory = data; wi->allocated = size + 1; wi->used = length; wi->dataWidth = width; wi->dataHeight = height; } return(data); } static Widget makeButton(parent, sensitive, vertdist, prevwidg, procptr, wininfo, accelstr, label) Widget parent; int sensitive; unsigned vertdist; Widget prevwidg; XtCallbackProc procptr; WindowInfo *wininfo; String accelstr; const char *label; { XtAccelerators accel; XtCallbackRec callback[2]; Widget w; accel = XtParseAcceleratorTable(accelstr); callback[0].callback = procptr; callback[0].closure = (XtPointer )wininfo; callback[1].callback = (XtCallbackProc) NULL; callback[1].closure = (XtPointer) NULL; w = XtVaCreateManagedWidget(label, commandWidgetClass, parent, XtNaccelerators, accel, XtNbottom, XtChainTop, XtNcallback, callback, XtNcursor, stdcur, XtNfont, buttonFont, XtNfromVert, prevwidg, XtNfromHoriz, NULL, XtNhorizDistance, 4, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNsensitive, (sensitive ? False : True), XtNtop, XtChainTop, XtNvertDistance, vertdist, XtNwidth, XLESS_BUTTON_WIDTH, NULL); XtInstallAccelerators(wininfo->text, w); return(w); } /* * Function Name: MakeToolbox * Description: This function create all the widgets necessary * to build the toolbox. * Arguments: parent - the parent widget * cd - pointer to the data structure containing * the application data. * notmain - TRUE if this is not the main window * new_wdg - the shell widget that is the new window * filename - the name of the file displayed in the window * Returns: None. */ Widget MakeToolbox(parent, wi, filename) Widget parent; WindowInfo *wi; const char *filename; { Widget box, button; const String AccSearch = "#override MetaS: set() notify() unset()\n"; const String AccNext = "#override MetaN: set() notify() unset()\n"; const String AccReload = "#override MetaR: set() notify() unset()\n"; const String AccEdit = "#override MetaE: set() notify() unset()\n"; const String AccChange = "#override MetaC: set() notify() unset()\n"; const String AccWind = "#override MetaW: set() notify() unset()\n"; const String AccPrint = "#override MetaP: set() notify() unset()\n"; const String AccHelp = "#override ?: set() notify() unset()\n"; const String AccClose = "#override Q: set() notify() unset()\n"; const String AccBackgnd = "#override Meta&: set() notify() unset()\n"; const String AccQuit = "#override MetaQ: set() notify() unset()\n"; /* create the ButtonBox which contains the toolbox */ box = XtVaCreateManagedWidget("toolbox", boxWidgetClass, parent, XtNallowResize, True, XtNbottom, XtChainTop, XtNfromHoriz, wi->text, XtNhorizDistance, 1, XtNleft, XtChainRight, XtNorientation, XtorientVertical, XtNright, XtChainRight, XtNshowGrip, False, XtNskipAdjust, True, XtNtop, XtChainTop, NULL); button = (Widget )NULL; button = makeButton(box, False, 1, button, PopupHelp, wi, AccHelp, "Help"); button = makeButton(box, False, 1, button, Search, wi, AccSearch, "Search"); button = makeButton(box, False, 1, button, SearchNext, wi, AccNext, "Search Next"); button = makeButton(box, (filename == NULL ? True : False), 1, button, CallEditor, wi, AccEdit, "Editor"); if (filename == NULL) wi->editorButton = button; else wi->editorButton = 0; button = makeButton(box, ((filename == NULL || wi->inputInfo != NULL) ? True : False), 1, button, Reload, wi, AccReload, "Reload"); if (filename == NULL) wi->reloadButton = button; else wi->reloadButton = 0; button = makeButton(box, False, 1, button, ChangeFile, wi, AccChange, "Change file"); button = makeButton(box, False, 1, button, NewWindow, wi, AccWind, "New window"); button = makeButton(box, False, 1, button, Print, wi, AccPrint, "Print"); button = makeButton(box, False, 1, button, Background, wi, AccBackgnd, "Background"); button = makeButton(box, False, 1, button, CloseWindow, wi, AccClose, "Close window"); if (resources.quitButton) button = makeButton(box, False, 1, button, Quit, wi, AccQuit, "Quit"); return(box); } static void ParseGeometryRsrc() { /* get geometry from resource */ if (resources.geometry) { geomMask = XParseGeometry(resources.geometry, &geomX, &geomY, &geomWidth, &geomHeight); /* supply width & height if unspecified */ if ((geomMask & WidthValue) == 0 || (geomMask & HeightValue) == 0) { if (((geomMask & WidthValue) && geomWidth <= 0) || ((geomMask & HeightValue) && geomHeight <= 0)) fprintf(stderr, "Bad WIDTHxHEIGHT in geometry \"%s\"!\n", resources.geometry); geomWidth = DEFAULT_WIDTH; geomHeight = DEFAULT_HEIGHT; } } else { geomWidth = DEFAULT_WIDTH; geomHeight = DEFAULT_HEIGHT; } /* remember that we've been here */ geomParsed = 1; } const char * GetGeometryPosition() { if (!geomParsed) ParseGeometryRsrc(); if (!geomPosition && (geomMask & XValue) && (geomMask & YValue)) { geomPosition = XtMalloc(32); sprintf(geomPosition, "%+d%+d", geomX, geomY); } return(geomPosition); } /* * Function Name: MakeText * Description: This function creates the text widget necessary * to display the data. * Arguments: parent - the parent widget * wi - pointer to window information * data - pointer to data in memory. * ignoreGeom - TRUE if we should ignore supplied geometry * Returns: tmp - the text widget so created. */ Widget MakeText(parent, wi, data, ignoreGeom) Widget parent; WindowInfo *wi; const char *data; int ignoreGeom; { int windowWidth, windowHeight; int charWidth, charHeight; Widget txt; /* make sure we have default width and height */ if (!geomParsed) ParseGeometryRsrc(); /* set window width & height (expressed in characters) */ windowWidth = (ignoreGeom ? DEFAULT_WIDTH : geomWidth); windowHeight = (ignoreGeom ? DEFAULT_HEIGHT : geomHeight); /* get width/height of a text window character */ charWidth = FontWidth(textFont); charHeight = FontHeight(textFont); /* if actual text is smaller, use it instead */ if (wi && (wi->inputInfo == NULL) && resources.sizeToFit && (resources.geometry == NULL)) { if (windowWidth > wi->dataWidth) windowWidth = wi->dataWidth + 1; if (windowHeight > wi->dataHeight) windowHeight = wi->dataHeight; } /* convert width/height of text window to pixel values */ windowWidth *= charWidth; windowHeight *= charHeight; #ifdef DUMP_TEXTFONT_INFO printf("\nTextFont info:\n"); printf("\tfid=%ld, direction=%d\n", textFont->fid, textFont->direction); printf("\tmin_char_or_byte2=%d, max_char_or_byte2=%d\n", textFont->min_char_or_byte2, textFont->max_char_or_byte2); printf("\tmin_byte1=%d, max_byte1=%d\n", textFont->min_byte1, textFont->max_byte1); printf("\tall_chars_exist=%s, default_char=%d, n_properties=%d\n", (textFont->all_chars_exist ? "TRUE" : "FALSE"), textFont->default_char, textFont->n_properties); printf("\tmin_bounds: lbearing=%d, rbearing=%d, width=%d,\n", textFont->min_bounds.lbearing, textFont->min_bounds.rbearing, textFont->min_bounds.width); printf("\t\tascent=%d, descent=%d\n", textFont->min_bounds.ascent, textFont->min_bounds.descent); printf("\tmax_bounds: lbearing=%d, rbearing=%d, width=%d,\n", textFont->max_bounds.lbearing, textFont->max_bounds.rbearing, textFont->max_bounds.width); printf("\t\tascent=%d, descent=%d\n", textFont->max_bounds.ascent, textFont->max_bounds.descent); printf("\tascent=%d, descent=%d\n", textFont->ascent, textFont->descent); printf("TextWindow: char=(%d,%d), lines=(%d,%d), txtwin=(%d,%d)\n", charWidth, charHeight, (wi ? wi->dataWidth : -1), (wi? wi->dataHeight : -1), windowWidth, windowHeight); #endif /* DUMP_TEXTFONT_INFO */ txt = XtVaCreateManagedWidget("text", asciiTextWidgetClass, parent, XtNallowResize, True, XtNbottom, XtChainBottom, XtNdisplayNonprinting, False, XtNeditType, XawtextRead, XtNfont, textFont, XtNfromHoriz, NULL, XtNheight, windowHeight, XtNhorizDistance, 1, XtNleft, XtChainLeft, XtNright, XtChainRight, XtNskipAdjust, False, XtNscrollVertical, XawtextScrollWhenNeeded, XtNscrollHorizontal, XawtextScrollWhenNeeded, XtNshowGrip, False, XtNstring, data, XtNtop, XtChainTop, XtNuseStringInPlace, True, XtNwidth, windowWidth, NULL); return (txt); } void SetXNames(top, filename) Widget top; const char *filename; { static char *namePrefix; static int namelen = 0; static char *namestr = 0; const char *cp; int prefixlen, newlen; /* don't do this if user has already named the window */ if (resources.name && resources.title) return; /* make sure there's a filename string */ if (!filename || *filename == 0) return; /* if there's no namePrefix, set one up */ if (!namePrefix) { namePrefix = XtMalloc((Cardinal )(strlen(progname) + 2)); strcpy(namePrefix, progname); strcat(namePrefix, ":"); } /* figure out how long the prefix is */ if (namePrefix && *namePrefix) prefixlen = strlen(namePrefix); else prefixlen = 0; /* remove path junk if user doesn't want it */ if (resources.removePath) { cp = strrchr(filename, '/'); if (cp) filename = cp + 1; } /* make sure name buffer is large enough */ newlen = prefixlen + strlen(filename) + 1; if (newlen > namelen) { if (namestr) XtFree(namestr); namestr = (char *)XtMalloc((Cardinal )newlen); namelen = newlen; } /* create title/icon name string */ strcpy(namestr, namePrefix); strcat(namestr, filename); /* set window's icon and title names to the file name */ XtVaSetValues(top, XtNiconName, (resources.name ? resources.name : namestr), XtNtitle, (resources.title ? resources.title : namestr), NULL); } void SetWMHints(wi) WindowInfo *wi; { Dimension txtWidth, txtHeight; Dimension winWidth, winHeight; Dimension baseWidth, baseHeight; Dimension tbxWidth, tbxHeight; int charWidth, charHeight; /* get width/height of entire window */ XtVaGetValues(wi->base, XtNheight, &winHeight, XtNwidth, &winWidth, NULL); /* get width/height of text window */ XtVaGetValues(wi->text, XtNheight, &txtHeight, XtNwidth, &txtWidth, NULL); /* get size of tool box */ XtVaGetValues(wi->toolbox, XtNheight, &tbxHeight, XtNwidth, &tbxWidth, NULL); /* figure out base width/height */ baseWidth = winWidth - txtWidth; baseHeight = (tbxHeight > txtHeight ? tbxHeight : txtHeight); /* get width/height of a text window character */ charWidth = FontWidth(textFont); charHeight = FontHeight(textFont); /* set base & increment size */ XtVaSetValues(wi->base, XtNbaseWidth, baseWidth, XtNbaseHeight, charHeight, XtNheightInc, charHeight, XtNwidthInc, charWidth, NULL); /* set minimum window size */ XtVaSetValues(wi->base, XtNminHeight, tbxHeight, XtNminWidth, tbxWidth + charWidth + charWidth, NULL); } xless-1.7.orig/main.c100444 0 0 23627 5616070013 12653 0ustar rootroot/* * Copyright (C) 1994 by Dave Glowacki * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * to rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * DAVE GLOWACKI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * $Header: /usr/sww/share/src/X11R6/local/applications/xless-1.7/RCS/main.c,v 1.36 1994/07/29 02:55:50 dglo Exp $ */ #include #include #include #include #include #include #include #include "xless.h" #include "version.h" #include "XLessTop.icn" #define XtRSearchType "SearchType" XtAppContext context; Widget toplevel; Display *disp; const char *className; const char *progname; XLessResources resources; static XtResource privResources[] = { {XtNgeometry, XtCGeometry, XtRString, sizeof(String), XtOffset(XLessResources *, geometry), XtRString, NULL}, {XtNname, "Name", XtRString, sizeof(String), XtOffset(XLessResources *, name), XtRString, NULL}, {XtNtitle, XtCTitle, XtRString, sizeof(String), XtOffset(XLessResources *, title), XtRString, NULL}, {"helpFile", XtCFile, XtRString, sizeof(String), XtOffset(XLessResources *, helpFile), XtRString, HELPFILE}, {"standardCur", XtCCursor, XtRCursor, sizeof(Cursor), XtOffset(XLessResources *, cursors.top), XtRString, STANDARDCUR}, {"dialogCur", XtCCursor, XtRCursor, sizeof(Cursor), XtOffset(XLessResources *, cursors.dialog), XtRString, STANDARDCUR}, {"standardFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *), XtOffset(XLessResources *, fonts.standard), XtRString, STANDARDFONT}, {"textFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *), XtOffset(XLessResources *, fonts.text), XtRString, TEXTFONT}, {"labelFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *), XtOffset(XLessResources *, fonts.label), XtRString, LABELFONT}, {"buttonFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *), XtOffset(XLessResources *, fonts.button), XtRString, BUTTONFONT}, {"editor", "Editor", XtRString, sizeof(String), XtOffset(XLessResources *, editor), XtRString, DEFEDITOR}, {"editorDoesWindows", "EditorDoesWindows", XtRBoolean, sizeof(Boolean), XtOffset(XLessResources *, editorDoesWindows), XtRString, "False"}, {"printCmd", "PrintCommand", XtRString, sizeof(String), XtOffset(XLessResources *, oldPrintCmd), XtRString, NULL}, {"printCommand", "PrintCommand", XtRString, sizeof(String), XtOffset(XLessResources *, printCmd), XtRString, PRINTCMD}, {"maxWindows", "MaxWindows", XtRInt, sizeof(int), XtOffset(XLessResources *, maxWindows), XtRString, "0"}, {"quitButton", "QuitButton", XtRBoolean, sizeof(Boolean), XtOffset(XLessResources *, quitButton), XtRString, "False"}, {"sizeToFit", "SizeToFit", XtRBoolean, sizeof(Boolean), XtOffset(XLessResources *, sizeToFit), XtRString, "True"}, {"removePath", "RemovePath", XtRBoolean, sizeof(Boolean), XtOffset(XLessResources *, removePath), XtRString, "True"}, {"helpMessage", "HelpMessage", XtRBoolean, sizeof(Boolean), XtOffset(XLessResources *, helpMessage), XtRString, "False"}, {"defaultSearchType", "SearchType", XtRSearchType, sizeof(unsigned), XtOffset(XLessResources *, defaultSearchType), XtRString, "ExactMatch"}, {"monitorFile", "MonitorFile", XtRBoolean, sizeof(Boolean), XtOffset(XLessResources *, monitorFile), XtRString, "False"}, {"printVersion", "PrintVersion", XtRBoolean, sizeof(Boolean), XtOffset(XLessResources *, printVersion), XtRString, "False"}, }; static XrmOptionDescRec options[] = { {"-f", "*monitorFile", XrmoptionNoArg, (XtPointer )"True"}, {"-follow", "*monitorFile", XrmoptionNoArg, (XtPointer )"True"}, {"-fn", "*textFont", XrmoptionSepArg, (XtPointer )NULL}, {"-font", "*textFont", XrmoptionSepArg, (XtPointer )NULL}, {"-help", "*helpMessage", XrmoptionNoArg, (XtPointer )"True"}, {"-version", "*printVersion", XrmoptionNoArg, (XtPointer )"True"}, }; static Boolean cvtStringToSearchType __P((Display *, XrmValue *, Cardinal *, XrmValue *, XrmValue *, XtPointer *)); static void cleanup __P((void)); static void argPrint __P((const char *)); #define done(type, value) \ { \ if (toVal->addr != NULL) { \ if (toVal->size < sizeof(type)) { \ toVal->size = sizeof(type); \ return False; \ } \ *(type *)(toVal->addr) = (value); \ } else { \ static type newValue; \ \ newValue = (value); \ toVal->addr = (XtPointer )&newValue; \ } \ toVal->size = sizeof(type); \ return True; \ } static Boolean cvtStringToSearchType(display, args, numArgs, fromVal, toVal, destructorData) Display *display; XrmValue *args; Cardinal *numArgs; XrmValue *fromVal; XrmValue *toVal; XtPointer *destructorData; { static int initialized = 0; static XrmQuark QExactMatch, QCaseInsensitive, QRegularExpression; char *tmp; XrmQuark q; if (!initialized) { QExactMatch = XrmStringToQuark("exactmatch"); QCaseInsensitive = XrmStringToQuark("caseinsensitive"); QRegularExpression = XrmStringToQuark("regularexpression"); initialized = 1; } if (*numArgs != 0) XtWarning("String to SearchType conversion needs no extra arguments"); /* get quark for string */ tmp = XtMalloc((Cardinal )(strlen((char *)fromVal->addr) + 1)); XmuCopyISOLatin1Lowered(tmp, (char *)fromVal->addr); q = XrmStringToQuark(tmp); XtFree(tmp); if (q == QExactMatch) done(unsigned, XLessClearFlag); if (q == QCaseInsensitive) done(unsigned, XLessSearchInsensitive); if (q == QRegularExpression) done(unsigned, XLessSearchRegExpr); XtDisplayStringConversionWarning(display, fromVal->addr, "XtRSearchType"); return False; } static void cleanup() { XtDestroyWidget(toplevel); XtDestroyApplicationContext(context); } static void argPrint(str) const char *str; { static int lineLen = 0; static int current = 0; int len; /* find line length */ if (lineLen == 0) { lineLen = 80; current = lineLen; } len = strlen(str); current -= len; if (current > 0) { fputs(str, stderr); } else { fprintf(stderr, "\n\t%s", str); current = lineLen - (8 + len); } } void main(argc, argv) int argc; char *argv[]; { int i, attempted; #ifdef _DEBUG_MALLOC_INC { union dbmalloptarg moa; moa.i = 0; dbmallopt(MALLOC_CKCHAIN, &moa); } #endif /* save program name */ if ((progname = strrchr(argv[0], '/'))) progname++; else progname = argv[0]; toplevel = XtVaAppInitialize(&context, XLESS_CLASS, options, XtNumber(options), &argc, argv, NULL, NULL); XtAppSetTypeConverter(context, XtRString, XtRSearchType, cvtStringToSearchType, (XtConvertArgList )NULL, 0, XtCacheAll, NULL); XtGetApplicationResources(toplevel, (XtPointer )&resources, privResources, XtNumber(privResources), NULL, (Cardinal) 0); /* print our version number if user wants it */ if (resources.printVersion) printf("XLess version %s\n", VERSION); /* complain about old printCmd resource usage */ if (resources.oldPrintCmd != NULL) { if (strcmp(resources.printCmd, PRINTCMD) != 0) fprintf(stderr, "%s: Both 'printCommand' and 'printCmd' specified!\n", progname); else { fprintf(stderr, "%s: Please use the 'printCommand' resource", progname); fprintf(stderr, " instead of 'printCmd'\n"); resources.printCmd = resources.oldPrintCmd; } } /* save class name */ className = XLESS_CLASS; XtAppAddActions(context, actions, numactions); disp = XtDisplay(toplevel); XtVaSetValues(toplevel, XtNiconPixmap, XCreateBitmapFromData(disp, XRootWindow(disp, 0), XLessTop_bits, XLessTop_width, XLessTop_height), NULL); CheckFonts(); attempted = 0; for (i = 1; resources.helpMessage || i < argc; i++) { /* whine if there's still an argument */ if (resources.helpMessage || *argv[i] == '-') { argPrint("Usage: "); argPrint(progname); argPrint(" [-f]"); argPrint(" [-follow]"); argPrint(" [-fn textFont]"); argPrint(" [-font textFont]"); argPrint(" [-help]"); argPrint(" [-version]"); argPrint(" [file ...]"); argPrint("\n"); argPrint("\t("); argPrint(progname); argPrint(" also takes input"); argPrint(" from stdin)\n"); cleanup(); exit(0); } CreateWindow(toplevel, argv[i]); attempted++; } /* die if everything failed */ if (attempted > 0 && windowcount == 0) { fprintf(stderr, "%s: no windows found\n", progname); cleanup(); exit(1); } /* if we haven't opened a window yet... */ if (windowcount == 0) { /* * Not really necessary to call this an error, * but if the control terminal (for commands) * and the input file (for data) are the same, * we get weird results at best. */ if (isatty(fileno(stdin))) { fprintf(stderr, "%s: can't take input from terminal\n", progname); cleanup(); exit(1); } /* bring up controlling window using stdin as input */ CreateWindow(toplevel, NULL); } XtAppMainLoop(context); } xless-1.7.orig/xless.h100444 0 0 17452 5616067751 13110 0ustar rootroot/* * Copyright (C) 1994 by Dave Glowacki * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * to rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * DAVE GLOWACKI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * $Header: /usr/sww/share/src/X11R6/local/applications/xless-1.7/RCS/xless.h,v 1.53 1994/07/29 02:55:34 dglo Exp $ * */ #ifndef XLESS_H #define XLESS_H /* Useful defines */ #define XLESS_MEMORY_CHUNK 512000 #define XLESS_BUTTON_WIDTH 100 #define XLESS_DIALOG_WIDTH 350 #define XLESS_DIALOG_HEIGHT 150 #define XLESS_INPUT_WIDTH 200 #define XLESS_MAX_INPUT 256 /* handle differences between K&R and ANSI C */ #if __STDC__ #define __P(a) a #else #define __P(a) () #define const #endif /* * The default editor; make sure the file exists. * (Used if the environment variable EDITOR is not set) */ #ifndef DEFEDITOR #define DEFEDITOR "/usr/ucb/vi" #endif /* * This is the default helpfile and is site specific. * If you're not using 'imake', make sure you change this. */ #ifndef HELPFILE #define HELPFILE "/usr/lib/X11/xless.help" #endif /* * This is the default print command and is OS specific. * It should probably be "lpr" for BSD, "lp" for SysV */ #ifndef PRINTCMD #define PRINTCMD "/usr/ucb/lpr" #endif /* * Application class. You shouldn't change this. */ #ifndef XLESS_CLASS #define XLESS_CLASS "XLess" #endif /* XLESS_CLASS */ /* Default fonts. */ #define STANDARDCUR "left_ptr" #define STANDARDFONT "fixed" #define TEXTFONT "-adobe-courier-medium-r-normal--12-120-75-75-m-*-iso8859-1" #define LABELFONT "-adobe-times-medium-r-normal--12-120-75-75-p-*-iso8859-1" #define BUTTONFONT "-adobe-new century schoolbook-medium-r-normal--12-120-75-75-p-*-iso8859-1" /* Typedefs */ /* * Values for WindowInfo flag */ typedef enum _XLessFlagBits { XLessClearFlag = 0x0000, /* turn off all bits */ XLessFreeFilename = 0x0001, /* filename uses malloc'd memory */ XLessAddedNewline = 0x0002, /* added newline to end of text */ XLessSearchInsensitive = 0x0100, /* case-insensitive search */ XLessSearchRegExpr = 0x0200 /* regular-expression search */ } XLessFlag; /* * This structure holds info needed to stop and start input */ typedef struct _InputInfo { int fd; XtInputId id; int falseAlarm; unsigned long interval; } InputInfo; /* * This structure holds everything xless needs to know about * each of its windows. */ typedef struct _WindowInfo { /* main window widgets */ Widget base; Widget text; Widget toolbox; Widget editorButton; Widget reloadButton; /* popup window widgets and buffers */ Widget searchPopup, newWindowPopup, changeFilePopup; char *searchBuf, *newWindowBuf, *changeFileBuf; /* actual text and associated statistics */ const char *memory; Cardinal allocated, used; /* file name (if any) */ const char *file; /* miscellaneous flag values */ XLessFlag flag; /* height (in lines), width (in chars) */ unsigned dataHeight, dataWidth; /* info needed to manage dynamic files */ InputInfo *inputInfo; /* next in the series (collect 'em all!) */ struct _WindowInfo *next; } WindowInfo; typedef struct _XLessFonts { XFontStruct *standard, /* The font used if no fonts specied */ *text, /* Font used for XLess text */ *label, /* Font used for labels in dialog boxes */ *button; /* Font used for commandbuttons */ } XLessFonts; typedef struct _XLessCursors { Cursor top, /* The top cursor, default for XLess */ dialog; /* Cursor for dialog boxes */ } XLessCursors; /* Resource manager sets these */ typedef struct _XLessResources { String geometry; /* width/height of text window */ String name; /* instance name */ String title; /* title name */ XLessFonts fonts; /* The fonts used for XLess */ XLessCursors cursors; /* The cursors used for XLess */ String helpFile; /* The help file name */ Boolean editorDoesWindows; /* does editor come up in a window? */ String editor; /* default editor */ String printCmd; /* command used to print file */ int maxWindows; /* maximum number of open windows */ Boolean quitButton; /* does user want a QUIT button? */ Boolean autoName; /* should we automatically name the window? */ Boolean removePath; /* does user want path junk removed? */ Boolean sizeToFit; /* should window be as small as possible? */ Boolean helpMessage; /* should we just print a help msg and exit? */ unsigned defaultSearchType; /* flag used to set default search type */ Boolean monitorFile; /* should we keep checking for input? */ Boolean printVersion; /* should we keep print our version number? */ String oldPrintCmd; /* catch old resource name usage */ } XLessResources; /* prototypes from help.c */ void PopupHelp __P((Widget, XtPointer, XtPointer)); /* prototypes from init.c */ const char *InitData __P((int, WindowInfo *)); Widget MakeToolbox __P((Widget, WindowInfo *, const char *)); const char *GetGeometryPosition __P((void)); Widget MakeText __P((Widget, WindowInfo *, const char *, int)); void SetXNames __P((Widget, const char *)); void SetWMHints __P((WindowInfo *)); /* prototypes from popup.c */ Widget DialogBox __P((Widget, XtCallbackProc, XtPointer, const char *, const char *, char *)); Widget SearchBox __P((Widget, XtCallbackProc, WindowInfo *, const char *, const char *, char *)); Widget MessageBox __P((Widget, const char *, ...)); WindowInfo *MakeDialog __P((Widget)); /* prototypes from util.c */ void SetPopup __P((Widget, Widget)); void CheckFonts __P((void)); void CouldntOpen __P((Widget, const char *)); const char *TildeExpand __P((const char *)); extern XFontStruct *buttonFont; extern XFontStruct *labelFont; extern XFontStruct *textFont; extern Cursor stdcur; extern Cursor dialogcur; /* prototypes from callbacks.c */ void Quit __P((Widget, XtPointer, XtPointer)); void SearchNext __P((Widget, XtPointer, XtPointer)); void Cancel __P((Widget, XtPointer, XtPointer)); void CallEditor __P((Widget, XtPointer, XtPointer)); void Reload __P((Widget, XtPointer, XtPointer)); void Search __P((Widget, XtPointer, XtPointer)); void ChangeFile __P((Widget, XtPointer, XtPointer)); void NewWindow __P((Widget, XtPointer, XtPointer)); void CloseWindow __P((Widget, XtPointer, XtPointer)); void Print __P((Widget, XtPointer, XtPointer)); void Background __P((Widget, XtPointer, XtPointer)); /* prototypes from functions.c */ void QuitFunction __P((void)); /* prototypes from main.c */ void main __P((int, char *[])); extern XtAppContext context; extern Widget toplevel; extern Display *disp; extern XLessResources resources; extern const char *progname; extern const char *className; /* prototypes from window.c */ WindowInfo *createWindowInfo __P((void)); WindowInfo *findWindowInfo __P((Widget)); int CreateWindow __P((Widget, const char *)); void DestroyWindowInfo __P((WindowInfo *)); void DestroyAllWindows __P((void)); extern WindowInfo *windowlist; extern int windowcount; /* prototypes from actions.c */ extern XtActionsRec actions[]; extern Cardinal numactions; #endif /* XLESS_H */ xless-1.7.orig/popup.c100444 0 0 27025 5575717263 13111 0ustar rootroot/* * Copyright (C) 1994 by Dave Glowacki * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * to rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * DAVE GLOWACKI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * $Header: /usr/sww/share/src/X11R6/local/applications/xless-1.7/RCS/popup.c,v 1.29 1994/06/09 22:59:12 dglo Exp $ */ #include #include #include #include #include #include #include #include #include #include #include "xless.h" #define SEARCH_BITS ((unsigned )(XLessSearchInsensitive|XLessSearchRegExpr)) /* stole this chunk from xdm/dm.c */ #if defined(USE_PROTOTYPES) || defined(__STDC__) #include #define Va_start(a,b) va_start(a,b) #else #include #define Va_start(a,b) va_start(a) #endif static void toggleSearchType __P((Widget, XtPointer, XtPointer)); static void popdownBox __P((Widget, XtPointer, XtPointer)); Widget DialogBox(top, confFunc, confData, label, btnLabel, selection) Widget top; XtCallbackProc confFunc; XtPointer confData; const char *label; const char *btnLabel; char *selection; { static XtActionsRec dbactions[2]; static String myreturn = "#override Return: set() notify() unset()\n"; XtAccelerators accel; static String mytranslations = "#override\n\ CtrlS: no-op(RingBell)\n\ CtrlR: no-op(RingBell)\n"; XtTranslations xlate; static int init = 0; Widget popup, form, lbl, input, confirm, cancel; XtCallbackRec callback[2]; dbactions[0].string = "Nothing"; dbactions[0].proc = (XtActionProc)NULL; if (!init) { XtAddActions(dbactions, XtNumber(dbactions)); init = 1; } callback[1].callback = NULL; callback[1].closure = (XtPointer)NULL; popup = XtVaCreatePopupShell("popup", transientShellWidgetClass, top, XtNallowShellResize, True, NULL); form = XtVaCreateManagedWidget("form", formWidgetClass, popup, NULL); lbl = XtVaCreateManagedWidget(label, labelWidgetClass, form, XtNborderWidth, 0, XtNfont, labelFont, XtNjustify, XtJustifyLeft, XtNlabel, label, XtNleft, XtChainLeft, XtNright, XtChainLeft, NULL); xlate = XtParseTranslationTable(mytranslations); input = XtVaCreateManagedWidget("input", asciiTextWidgetClass, form, XtNeditType, XawtextEdit, XtNfont, textFont, XtNfromHoriz, NULL, XtNfromVert, lbl, XtNleft, XtChainLeft, XtNlength, XLESS_MAX_INPUT, XtNresizable, True, XtNright, XtChainRight, XtNstring, selection, #ifdef X11R4 XtNtextOptions, resizeWidth, #endif XtNtranslations, xlate, XtNuseStringInPlace, True, XtNvertDistance, 0, XtNwidth, XLESS_INPUT_WIDTH, NULL); XtSetKeyboardFocus(form, input); accel = XtParseAcceleratorTable(myreturn); callback[0].callback = confFunc; callback[0].closure = confData; confirm = XtVaCreateManagedWidget(btnLabel, commandWidgetClass, form, XtNaccelerators, accel, XtNcallback, callback, XtNcursor, dialogcur, XtNfont, buttonFont, XtNfromVert, input, XtNfromHoriz, NULL, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNvertDistance, 5, XtNwidth, XLESS_BUTTON_WIDTH, NULL); callback[0].callback = Cancel; callback[0].closure = (XtPointer)popup; cancel = XtVaCreateManagedWidget("Cancel", commandWidgetClass, form, XtNcallback, callback, XtNcursor, dialogcur, XtNfont, buttonFont, XtNfromVert, input, XtNfromHoriz, confirm, XtNhorizDistance, 2, XtNleft, XtChainRight, XtNright, XtChainRight, XtNvertDistance, 5, XtNwidth, XLESS_BUTTON_WIDTH, NULL); XtInstallAccelerators(input, confirm); return(popup); } static void toggleSearchType(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { WindowInfo *wi = (WindowInfo *)closure; int searchType = wi->flag & SEARCH_BITS; if (!searchType) wi->flag |= XLessSearchInsensitive; else if (searchType && ((searchType & XLessSearchInsensitive) == searchType)) wi->flag = (wi->flag & ~SEARCH_BITS) | XLessSearchRegExpr; else if (searchType && ((searchType & XLessSearchRegExpr) == searchType)) wi->flag &= ~SEARCH_BITS; else wi->flag = (wi->flag & ~SEARCH_BITS) | XLessSearchInsensitive; XtVaSetValues(widget, XtNlabel, (wi->flag & XLessSearchInsensitive ? " Case Insensitive " : (wi->flag & XLessSearchRegExpr ? "Regular Expression" : " Exact Match ")), NULL); } Widget SearchBox(top, srchFunc, wi, label, btnLabel, selection) Widget top; XtCallbackProc srchFunc; WindowInfo *wi; const char *label; const char *btnLabel; char *selection; { static XtActionsRec dbactions[2]; static String myreturn = "#override Return: set() notify() unset()\n"; XtAccelerators accel; static String mytranslations = "#override\n\ CtrlS: no-op(RingBell)\n\ CtrlR: no-op(RingBell)\n"; XtTranslations xlate; static int init = 0; Widget popup, form, lbl, input, searchType, search, cancel; const char *searchLabel; XtCallbackRec callback[2]; dbactions[0].string = "Nothing"; dbactions[0].proc = (XtActionProc)NULL; if (!init) { XtAddActions(dbactions, XtNumber(dbactions)); init = 1; } callback[1].callback = NULL; callback[1].closure = (XtPointer)NULL; popup = XtVaCreatePopupShell("popup", transientShellWidgetClass, top, XtNallowShellResize, True, NULL); form = XtVaCreateManagedWidget("form", formWidgetClass, popup, NULL); lbl = XtVaCreateManagedWidget(label, labelWidgetClass, form, XtNborderWidth, 0, XtNfont, labelFont, XtNjustify, XtJustifyLeft, XtNlabel, label, XtNleft, XtChainLeft, XtNright, XtChainLeft, NULL); xlate = XtParseTranslationTable(mytranslations); input = XtVaCreateManagedWidget("input", asciiTextWidgetClass, form, XtNeditType, XawtextEdit, XtNfont, textFont, XtNfromHoriz, NULL, XtNfromVert, lbl, XtNleft, XtChainLeft, XtNlength, XLESS_MAX_INPUT, XtNresizable, True, XtNright, XtChainRight, XtNstring, selection, #ifdef X11R4 XtNtextOptions, resizeWidth, #endif XtNtranslations, xlate, XtNuseStringInPlace, True, XtNvertDistance, 0, XtNwidth, XLESS_INPUT_WIDTH, NULL); XtSetKeyboardFocus(form, input); wi->flag &= ~SEARCH_BITS; if (resources.defaultSearchType == XLessSearchInsensitive) { searchLabel = " Case Insensitive "; wi->flag |= XLessSearchInsensitive; } else if (resources.defaultSearchType == XLessSearchRegExpr) { searchLabel = " Regular Expression "; wi->flag |= XLessSearchRegExpr; } else { searchLabel = " Exact Match "; } callback[0].callback = toggleSearchType; callback[0].closure = (XtPointer )wi; searchType = XtVaCreateManagedWidget("searchType", commandWidgetClass, form, XtNcallback, callback, XtNfont, buttonFont, XtNfromVert, input, XtNfromHoriz, NULL, XtNlabel, searchLabel, XtNleft, XtChainLeft, XtNright, XtChainRight, NULL); accel = XtParseAcceleratorTable(myreturn); callback[0].callback = srchFunc; callback[0].closure = (XtPointer )wi; search = XtVaCreateManagedWidget(btnLabel, commandWidgetClass, form, XtNaccelerators, accel, XtNcallback, callback, XtNcursor, dialogcur, XtNfont, buttonFont, XtNfromVert, searchType, XtNfromHoriz, NULL, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNvertDistance, 5, XtNwidth, XLESS_BUTTON_WIDTH, NULL); callback[0].callback = Cancel; callback[0].closure = (XtPointer)popup; cancel = XtVaCreateManagedWidget("Cancel", commandWidgetClass, form, XtNcallback, callback, XtNcursor, dialogcur, XtNfont, buttonFont, XtNfromVert, searchType, XtNfromHoriz, search, XtNhorizDistance, 2, XtNleft, XtChainRight, XtNright, XtChainRight, XtNvertDistance, 5, XtNwidth, XLESS_BUTTON_WIDTH, NULL); XtInstallAccelerators(input, search); return(popup); } static void popdownBox(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { XtPopdown((Widget)closure); } /* * Function Name: MessageBox * Description: This function creates the message dialog box. * Arguments: top widget to use as message box parent * msg message to display * btnlabel label on next button * btnproc callback executed when next button is pressed * Returns: widget id of the message box. */ Widget #if defined(USE_PROTOTYPES) || defined(__STDC__) MessageBox(Widget top, const char *msg, ...) #else MessageBox(top, msg, va_alist) Widget top; const char *msg; va_dcl #endif { Widget msgPop, form, msgLabel, button; XtCallbackRec callback[2]; static String myreturn = "#override Return: set() notify() unset()\n"; XtAccelerators accel; const char *btntext; XtCallbackProc btnproc; va_list vap; /* can't popup a messagebox if widgets haven't been realized yet... */ if (!XtIsRealized(top)) { XtAppWarning(context, msg); return 0; } callback[1].callback = (XtCallbackProc) NULL; callback[1].closure = (XtPointer) NULL; msgPop = XtVaCreatePopupShell("msgPop", transientShellWidgetClass, top, XtNallowShellResize, True, NULL); form = XtVaCreateManagedWidget("form", formWidgetClass, msgPop, XtNallowShellResize, True, NULL); msgLabel = XtVaCreateManagedWidget("message", labelWidgetClass, form, XtNallowShellResize, True, XtNborderWidth, 0, XtNfont, labelFont, XtNjustify, XtJustifyLeft, XtNlabel, msg, NULL); Va_start(vap, msg); btntext = (const char *)va_arg(vap, const char *); accel = XtParseAcceleratorTable(myreturn); button = 0; while (btntext) { btnproc = (XtCallbackProc )va_arg(vap, XtCallbackProc); if (btnproc) callback[0].callback = btnproc; else callback[0].callback = popdownBox; callback[0].closure = (XtPointer)msgPop; button = XtVaCreateManagedWidget(btntext, commandWidgetClass, form, XtNaccelerators, accel, XtNcallback, callback, XtNcursor, dialogcur, XtNfont, buttonFont, XtNfromVert, msgLabel, XtNfromHoriz, button, XtNleft, XtChainRight, XtNright, XtChainRight, XtNvertDistance, 1, XtNwidth, XLESS_BUTTON_WIDTH, NULL); XtInstallAccelerators(form, button); btntext = (const char *)va_arg(vap, const char *); } return(msgPop); } xless-1.7.orig/util.c100444 0 0 12205 5600151523 12671 0ustar rootroot/* * Copyright (C) 1994 by Dave Glowacki * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * to rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * DAVE GLOWACKI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * $Header: /usr/sww/share/src/X11R6/local/applications/xless-1.7/RCS/util.c,v 1.22 1994/06/16 22:33:46 dglo Exp $ */ #include #include #include #include #include #include #include "xless.h" XFontStruct *buttonFont; XFontStruct *labelFont; XFontStruct *textFont; Cursor stdcur; Cursor dialogcur; static void popdownCouldntOpen __P((Widget, XtPointer, XtPointer)); static struct opendata { Widget errbox; char *errmsg; } data; /* * Function name: SetPopup * Description: This function pops up the specified dialog box. * Arguments: top - where to pop up this dialog box * wdg - the widget to be popped up. * Returns: None. */ void SetPopup(top, wdg) Widget top, wdg; { Position x=0, y=0; Window rwin; Window chwin; int rx, ry, wx, wy; Dimension wd = 0; Dimension he = 0; unsigned int mask; /* Make the popup shell "wdg" come up at the current pointer position */ XQueryPointer(XtDisplay(top), XtWindow(top), &rwin, &chwin, &rx, &ry, &wx, &wy, &mask); XtVaGetValues(wdg, XtNheight, &he, XtNwidth, &wd, NULL); if (wd == 0) wd = XLESS_DIALOG_WIDTH; if (he == 0) he = XLESS_DIALOG_HEIGHT; x = rx - wd/2; y = ry - he/2; XtVaSetValues(wdg, XtNx, x, XtNy, y, NULL); /* Popup the widget */ XtPopup(wdg, XtGrabExclusive); } /* * Function name: CheckFonts * Description: This function checks the resource DB for the * user specified fonts. * Arguments: None. * Returns: None. */ void CheckFonts() { if (!(buttonFont = resources.fonts.button)) buttonFont = resources.fonts.standard; if (!(labelFont = resources.fonts.label)) labelFont = resources.fonts.standard; if (!(textFont = resources.fonts.text)) textFont = resources.fonts.standard; dialogcur = resources.cursors.dialog; stdcur = resources.cursors.dialog; if (!buttonFont || !labelFont || !textFont) { fprintf(stderr, "%s: unable to open any of the specified fonts\n", progname); exit(1); } } static void popdownCouldntOpen(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { XtPopdown(data.errbox); XtDestroyWidget(data.errbox); XtFree(data.errmsg); } /* * Function name: CouldntOpen * Description: This function pops up the "Couldn't open" dialog box. * Arguments: wdg - the widget to be popped up on. * Returns: None. */ void CouldntOpen(top, filename) Widget top; const char *filename; { const char *msgpart = "Couldn't open file: "; data.errmsg = (char *)XtMalloc((Cardinal )(strlen(msgpart) + strlen(filename) + 1)); strcpy(data.errmsg, msgpart); strcat(data.errmsg, filename); data.errbox = MessageBox(top, data.errmsg, "OK", popdownCouldntOpen, 0); if (data.errbox) SetPopup(top, data.errbox); } #ifdef TILDE_EXPANSION #include #define USERNAMELEN 9 const char * TildeExpand(filename) const char *filename; { struct passwd *pw; char username[USERNAMELEN], *bptr = username; const char *end; int len; /* find end of tilde'd name */ end = strchr(filename, '/'); if (!end) end = filename + strlen(filename); /* if it's just '~/...' or '~' */ if (end == filename + 1) { /* look up this UID in passwd file */ pw = getpwuid(getuid()); } else { /* allocate a buffer if static one is too small */ len = end - filename; if (len > USERNAMELEN) bptr = (char *)XtMalloc((Cardinal )len); /* copy name into buffer */ len--; strncpy(bptr, filename + 1, (size_t )len); bptr[len] = 0; /* look up this user in passwd file */ pw = getpwnam(bptr); /* free allocated memory */ if (bptr != username) XtFree(bptr); } /* if we found a passwd entry... */ if (pw) { /* get enough memory for expanded string */ bptr = (char *)XtMalloc((Cardinal )(strlen(pw->pw_dir) + strlen(end) + 1)); /* create new string */ if (bptr) { strcpy(bptr, pw->pw_dir); strcat(bptr, end); filename = bptr; } } /* return final string */ return(filename); } #endif /* TILDE_EXPANSION */ xless-1.7.orig/version.h100664 0 0 26 5575236456 13354 0ustar rootroot#define VERSION "1.7" xless-1.7.orig/xless.help100444 0 0 6411 5616064361 13554 0ustar rootrootThis is XLess version 1.7, a file browsing tool for the X Window System CREDITS: By Dave Glowacki - UCB Software Warehouse Originally By Carlo Lisa - MIT Project Athena. Based Upon Xmore for X11R2 by Chris Peterson - MIT Project Athena. The regular expression library in the 'regexp' subdirectory was written by Henry Spencer and is Copyright (c) 1986 by University of Toronto LEGAL STUFF: Copyright (C) 1994 by Dave Glowacki Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation to rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DAVE GLOWACKI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. FEATURES: Display either the file(s) specified on the command line or input from standard input, supplied by a pipe. File/pipe may be optionally monitored so that the display is continuously updated as new text is added. Display new files in the current window or by creating a new window. Reload or print the displayed file. Search the displayed file using either exact, case-insensitive, or regular expression patterns. Edit the displayed file with your favorite editor (as specified in the VISUAL or EDITOR environment variable) SUMMARY OF ACTIONS: In Text: Ctrlv OR SPACE OR f Scroll forward one full window Metav OR Ctrlb OR b Scroll back one full window k OR y Scroll down one line RETURN OR j OR e Scroll up one line Metas Bring up Search dialog box (like pressing Search button) Metan Search for next occurence of pattern (like pressing Search Next button) Metar Reload current file (like pressing Reload button) Metae Edit current file (like pressing Editor button) Metac Change to a different file (like pressing Change File button) Metaw Open a file in a new window (like pressing New Window button) Metap Print current file (like pressing Print button) ? Read this help message (like pressing Help button) Metaq Close all windows CLICK LEFT: Position cursor. CLICK RIGHT: Copy text, from cursor position to actual mouse position, into Cut & Paste buffer. In scrollbars: CLICK LEFT: Move Down - more of pointer is near bottom of window. CLICK MIDDLE: Move top of page to current mouse position. CLICK RIGHT: Move Up - more of pointer is near bottom of window. xless-1.7.orig/window.c100444 0 0 16256 5616065427 13253 0ustar rootroot/* * Copyright (C) 1994 by Dave Glowacki * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * to rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * DAVE GLOWACKI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * $Header: /usr/sww/share/src/X11R6/local/applications/xless-1.7/RCS/window.c,v 1.24 1994/07/29 02:34:16 dglo Exp $ */ #include #include #include #include #include #include #include #include #include "xless.h" #include "XLessWin.icn" /* list of all xless windows */ WindowInfo *windowlist = 0; int windowcount = 0; /* flag for "too many windows" popup */ static int tooManyFlag = 0; static void popdownTooMany __P((Widget, XtPointer, XtPointer)); WindowInfo * createWindowInfo() { WindowInfo *wi; wi = (WindowInfo *)XtMalloc((Cardinal )sizeof(WindowInfo)); wi->base = wi->text = wi->toolbox = NULL; wi->searchPopup = wi->newWindowPopup = wi->changeFilePopup = NULL; wi->editorButton = wi->reloadButton = NULL; wi->memory = NULL; wi->allocated = 0; wi->used = 0; wi->file = NULL; wi->flag = XLessClearFlag; wi->dataHeight = wi->dataWidth = 0; wi->searchBuf = wi->newWindowBuf = wi->changeFileBuf = NULL; wi->inputInfo = NULL; return(wi); } WindowInfo * findWindowInfo(w) Widget w; { WindowInfo *wi = windowlist; while (w) { /* if this is the shell widget... */ if (XtClass(w) == applicationShellWidgetClass) { /* find this window in the list */ while (wi && (wi->base != w)) wi = wi->next; return(wi); } /* see if parent is the shell widget */ w = XtParent(w); } /* couldn't find a window associated with this widget */ return(0); } static void popdownTooMany(widget, closure, callData) Widget widget; XtPointer closure; XtPointer callData; { XtPopdown((Widget)closure); tooManyFlag = 0; } int CreateWindow(top, filename) Widget top; const char *filename; { int fd; const char *shellName; const char *geom; Widget base, mainFrame; WindowInfo *wi; XLessFlag flag = XLessClearFlag; const char *fixedName; static Widget badFileMsg = 0; /* make sure we haven't created *too* many windows */ if (resources.maxWindows && (windowcount >= resources.maxWindows)) { static Widget tooManyMsg = 0; char message[64]; if (!tooManyFlag) { tooManyFlag = 1; sprintf(message, "Can't have more than %d windows!", resources.maxWindows); if (!tooManyMsg) tooManyMsg = MessageBox(top, message, "OK", popdownTooMany, 0); if (tooManyMsg) SetPopup(top, tooManyMsg); } return 1; } /* get a filehandle (or exit) */ if (filename) { #ifdef TILDE_EXPANSION /* see if we need to do tilde expansion */ if (filename && *filename == '~') { filename = TildeExpand(filename); if (*filename != '~') flag |= XLessFreeFilename; } #endif /* TILDE_EXPANSION */ /* try to open the file */ fd = open(filename, O_RDONLY); if (fd == -1) { CouldntOpen(top, filename); return 2; } fixedName = filename; } else if (windowcount == 0) { /* first file can come from stdin */ fixedName = "stdin"; fd = 0; } else { /* don't let 'em get away with this!!! */ if (!badFileMsg) badFileMsg = MessageBox(top, "Please specify a file name!", "OK", 0, 0); if (badFileMsg) SetPopup(top, badFileMsg); return 3; } /* keep track of the new window */ wi = createWindowInfo(); wi->file = fixedName; wi->flag = flag; /* read the file into memory */ InitData(fd, wi); /* figure out what to call the shell */ if (resources.name != NULL) shellName = resources.name; else shellName = progname; /* create a new application shell */ geom = GetGeometryPosition(); base = XtVaAppCreateShell(shellName, className, applicationShellWidgetClass, disp, XtNallowShellResize, TRUE, XtNgeometry, geom, XtNiconPixmap, XCreateBitmapFromData(disp, XRootWindow(disp,0), XLessWin_bits, XLessWin_width, XLessWin_height), NULL); /* set icon & title name for new window */ SetXNames(base, fixedName); /* create the container for the subwindows */ #ifdef FRAME_IS_FORM mainFrame = XtVaCreateManagedWidget("frame", formWidgetClass, base, NULL); #else mainFrame = XtVaCreateManagedWidget("frame", panedWidgetClass, base, XtNorientation, XtorientHorizontal, NULL); #endif /* build widgets for new window */ wi->base = base; wi->text = MakeText(mainFrame, wi, wi->memory, 0); wi->toolbox = MakeToolbox(mainFrame, wi, filename); /* make sure text window gets all keystrokes */ XtSetKeyboardFocus(mainFrame, wi->text); /* no dialog boxes yet */ wi->searchPopup = 0; wi->newWindowPopup = 0; wi->changeFilePopup = 0; /* display the window */ XtPopup(base, XtGrabNone); /* add this window to the list */ wi->next = windowlist; windowlist = wi; windowcount++; SetWMHints(wi); return 0; } void DestroyWindowInfo(wi) WindowInfo *wi; { WindowInfo *prev; /* free all window-related widgets */ XtDestroyWidget(wi->base); /* free all existing dialog boxes */ if (wi->searchPopup) XtDestroyWidget(wi->searchPopup); if (wi->newWindowPopup) XtDestroyWidget(wi->newWindowPopup); if (wi->changeFilePopup) XtDestroyWidget(wi->changeFilePopup); /* free all existing dialog box buffers */ if (wi->searchBuf) XtFree(wi->searchBuf); if (wi->newWindowBuf) XtFree(wi->newWindowBuf); if (wi->changeFileBuf) XtFree(wi->changeFileBuf); /* free text memory */ XtFree((char *)wi->memory); /* free filename string if it was malloc'd */ if (wi->flag & XLessFreeFilename) XtFree((char *)wi->file); /* free any input info */ if (wi->inputInfo) XtFree((char *)wi->inputInfo); /* remove from windowlist chain */ if (windowlist == wi) windowlist = wi->next; else { prev = windowlist; while (prev && (prev->next != wi)) prev = prev->next; if (prev) prev->next = wi->next; } /* one less window to worry about... */ XtFree((char *)wi); windowcount--; /* nothing else to do if we've closed all the windows */ if (windowcount == 0) { exit(0); } } void DestroyAllWindows() { while (windowlist) DestroyWindowInfo(windowlist); } xless-1.7.orig/widgdump.c100444 0 0 756 5270662530 13514 0ustar rootroot#include #include #include #include extern Widget toplevel; void widgdump(w) Widget w; { WidgetClass wclass; char *name; while (w) { wclass = XtClass(w); printf("Widget \"%s\" is class \"%s\"\n", XtName(w), wclass->core_class.class_name); if (wclass == applicationShellWidgetClass) { if (w == toplevel) printf("^^^^TOP^^^^\n"); else printf("^^WINDOW^^^\n"); } w = XtParent(w); } } xless-1.7.orig/TODO100664 0 0 1475 5616056006 12242 0ustar rootrootCheck out RichText widget, see if it's usable. Clean up help file. Add a "Save" command to save STDIN. Add actions for all buttons Document actions Handle appropriate 'less' options & keys Use selection as pattern if [Search Next] is pressed and searchBuf is NULL (suggested by Mark Phillips ) Allow for numbered lines (suggested by "John A. Murphy" ) Add a status line like that in 'less': "Lines 8-30 of 71 Byte 635 of 1818 34%" (suggested by "John A. Murphy" ) Allow text in dialog boxes to scroll (suggested by Michael Short ) xless-1.7.orig/XLessHlp.icn100444 0 0 2171 5242533363 13736 0ustar rootroot#define XLessHelp_width 30 #define XLessHelp_height 40 #define XLessHelp_x_hot -1 #define XLessHelp_y_hot -1 static char XLessHelp_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x0e, 0x30, 0x00, 0x00, 0x1c, 0x18, 0x00, 0x00, 0x38, 0x0c, 0x01, 0x00, 0x70, 0x06, 0x01, 0x00, 0x60, 0x03, 0x19, 0x11, 0xb0, 0x03, 0xa5, 0x2a, 0x18, 0x07, 0xa5, 0x08, 0x0c, 0x0e, 0x1d, 0x11, 0x06, 0x1c, 0x05, 0x22, 0x03, 0x38, 0x85, 0x2a, 0x01, 0x70, 0x39, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1c, 0xfe, 0xff, 0x1f, 0xbe, 0x01, 0x00, 0x28, 0x88, 0xf8, 0x7f, 0x0c, 0xc8, 0x00, 0x00, 0x04, 0x60, 0xfe, 0x1f, 0x06, 0x20, 0x00, 0x00, 0x03, 0x30, 0xff, 0x0f, 0x01, 0x18, 0x00, 0x80, 0x08, 0xc8, 0xff, 0x47, 0x08, 0x0c, 0x00, 0x60, 0x3e, 0x04, 0x00, 0x20, 0x1c, 0x0c, 0x00, 0x60, 0x08, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3e, 0x83, 0x07, 0x66, 0x06, 0x83, 0x0d, 0x66, 0x06, 0x83, 0x0d, 0x7e, 0x1e, 0x83, 0x07, 0x66, 0x06, 0x83, 0x01, 0x66, 0x06, 0x83, 0x01, 0x66, 0x3e, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; xless-1.7.orig/Imakefile100444 0 0 2023 5573464646 13364 0ustar rootroot/* * Possible additions to DEFINES (with their hardcoded defaults) * * -DDEFEDITOR=\"/usr/ucb/vi\" - path to default editor * -DPRINTCMD=\"/usr/ucb/lpr\" - path to send file to printer * -DTILDE_EXPANSION - perform ~ expansion on filenames */ DEFINES = -DHELPFILE=\"${LIBDIR}/xless.help\" -DTILDE_EXPANSION SRCS = help.c init.c popup.c util.c callbacks.c window.c main.c \ actions.c functions.c OBJS = help.o init.o popup.o util.o callbacks.o window.o main.o \ actions.o functions.o INCLUDES = -Iregexp LOCAL_LIBRARIES = -Lregexp -lregexp XawClientLibs DEPLIBS = ./regexp/libregexp.a XawClientDepLibs SUBDIRS = regexp #define IHaveSubdirs 1 #ifndef PassCDebugFlags #define PassCDebugFlags #endif MakeSubdirs($(SUBDIRS)) ComplexProgramTarget(xless) InstallNonExec(xless.help, $(LIBDIR)) InstallAppDefaults(XLess) #if ProjectX >= 5 /* * Only users of X11R5 (and beyond) can automatically use the color defaults */ InstallAppDefaultsLong(XLess-co,XLess-color) #endif