pg(1): import from trinity/src

This commit is contained in:
dtb 2024-04-21 06:21:15 -06:00
parent 8d9ac33566
commit e26d8e0e1b
Signed by: trinity
GPG Key ID: 31FF85CCB6DC7641
3 changed files with 86 additions and 2 deletions

View File

@ -102,11 +102,15 @@ mm: build/bin/mm
build/bin/mm: src/mm.c build
$(CC) $(CFLAGS) -o $@ src/mm.c
.PHONY: npc
npc: build/bin/npc
build/bin/npc: src/npc.c build
$(CC) $(CFLAGAS) -o $@ src/npc.c
$(CC) $(CFLAGS) -o $@ src/npc.c
.PHONY: pg
pg: build/bin/pg
build/bin/pg: src/pg.c build
$(CC) $(CFLAGS) -o $@ src/pg.c
.PHONY: rpn
rpn: build/bin/rpn

24
docs/pg.1 Normal file
View File

@ -0,0 +1,24 @@
.TH P 1
.SH NAME
pg \(en paginate
.SH DESCRIPTION
Pg prints standard input to standard output, pausing every 22 lines and waiting
for a line feed from the tty before continuing.
.SH DIAGNOSTICS
Pg returns an unsuccessful exit code if the tty couldn't be opened or if pg was
invoked incorrectly (with any arguments).
.SH RATIONALE
Plan 9 from Bell Labs had p(1), a similar "cooked"-mode paginator (as opposed
to "raw" mode, which a vast majority of paginators use).
.SH SEE ALSO
more(1)

56
src/pg.c Normal file
View File

@ -0,0 +1,56 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if !defined EX_USAGE || !defined EX_SOFTWARE
# include <sysexits.h>
#endif
/* Done while looking at plan9ports' src/cmd/p.c.
* Taken from plan9 are the interface (minus p(1)'s shell escaping and the
* ability to page multiple files) and the practice of reading /dev/tty to get
* keyboard input without going through stdin. Also, a newline is now printed
* before querying the keyboard. */
static size_t l = 22; /* plan9 default */
static char *program_name = "p";
static int print_lines(FILE *f, size_t l){
int c;
while((c = getc(f)) != EOF)
if((c = putc(c, stdout)) == EOF || (l -= (c == '\n')) == 0)
break;
return c;
}
int main(int argc, char *argv[]){
unsigned char cmd[99+1];
char *p;
FILE *t;
if(argc == 0)
argv = &program_name;
if(argc > 1){
fprintf(stderr, "Usage: %s\n", argv[0]);
return EX_USAGE;
}
if((t = fopen("/dev/tty", "rb")) == NULL){
fprintf(stderr, "%s: Could not open /dev/tty\n", argv[0]);
return EX_SOFTWARE;
}
while(print_lines(stdin, l) != EOF){
fgets(cmd, (sizeof cmd) / (sizeof *cmd), t);
for(p = cmd; *p != '\0' && strchr(" \t", *p) != NULL; ++p);
if(feof(t) || (*p | 32) == 'q')
break;
}
exit: fclose(t);
return 0;
}