Compare commits
No commits in common. "main" and "v0.6.0" have entirely different histories.
21
.github/workflows/c-cpp.yml
vendored
21
.github/workflows/c-cpp.yml
vendored
@ -1,21 +0,0 @@
|
|||||||
name: Build
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "main" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "main" ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: prep
|
|
||||||
run: make prep
|
|
||||||
- name: make
|
|
||||||
run: make
|
|
||||||
- name: test
|
|
||||||
run: ./build/lat -V
|
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -130,3 +130,4 @@ $RECYCLE.BIN/
|
|||||||
*.lnk
|
*.lnk
|
||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/c,macos,windows,linux,c
|
# End of https://www.toptal.com/developers/gitignore/api/c,macos,windows,linux,c
|
||||||
|
|
||||||
|
23
LICENSE
23
LICENSE
@ -1,23 +0,0 @@
|
|||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
7
Makefile
7
Makefile
@ -6,11 +6,7 @@ ODIR:=obj
|
|||||||
BINDIR:=build
|
BINDIR:=build
|
||||||
|
|
||||||
CC:=cc
|
CC:=cc
|
||||||
# OMG SO FAST (see https://www.shlomifish.org/humour/by-others/funroll-loops/Gentoo-is-Rice.html)
|
CFLAGS:=-I$(IDIR) -Wall -Wextra -pedantic -Ofast
|
||||||
# CFLAGS:=-I$(IDIR) -Wall -Wextra -pedantic -Ofast -faggressive-loop-optimizations -funroll-all-loops -march=native
|
|
||||||
# For a stable experience
|
|
||||||
CFLAGS:=-I$(IDIR) -Wall -Wextra -pedantic -O2 -march=native
|
|
||||||
|
|
||||||
LIB:=
|
LIB:=
|
||||||
|
|
||||||
DEPS:=$($(IDIR)/%.h)
|
DEPS:=$($(IDIR)/%.h)
|
||||||
@ -34,6 +30,7 @@ prep:
|
|||||||
-@mkdir -p $(IDIR)
|
-@mkdir -p $(IDIR)
|
||||||
-@mkdir -p $(ODIR)
|
-@mkdir -p $(ODIR)
|
||||||
-@mkdir -p $(BINDIR)
|
-@mkdir -p $(BINDIR)
|
||||||
|
@echo $(BINDIR)/ >> .gitignore
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
47
README.md
47
README.md
@ -1,47 +0,0 @@
|
|||||||
# lat
|
|
||||||
> lat | lazy cat - a cat clone with some quality-of-life embellishments
|
|
||||||
|
|
||||||
## About
|
|
||||||
|
|
||||||
`lat` is a solution to a problem that doesn't exist. It's the awkward middle child in-between `cat` and `bat`. It was created because the author didn't want to have to configure `bat` just to get decent file printing, but wanted a little more control than `cat` offered.
|
|
||||||
|
|
||||||
`lat` does not expect to be used. `lat` expects to be forgotten and shunted into a corner because it does not belong in the slightest.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
`lat` is not yet at a stable version (`v1.0.0`), so it is not on any package managers.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/secondary-smiles/lat.git
|
|
||||||
|
|
||||||
cd lat
|
|
||||||
|
|
||||||
make
|
|
||||||
|
|
||||||
./build/lat -V
|
|
||||||
|
|
||||||
# now add lat to your $PATH/do whatever you want with the binary
|
|
||||||
```
|
|
||||||
|
|
||||||
## Helptext
|
|
||||||
> `lat -h`
|
|
||||||
|
|
||||||
```text
|
|
||||||
lat | lazy cat - a cat clone with some quality-of-life embellishments
|
|
||||||
|
|
||||||
usage: lat [-cltbrpneVh] [file...]
|
|
||||||
|
|
||||||
options:
|
|
||||||
-c toggle color
|
|
||||||
-l toggle line numbers
|
|
||||||
-t toggle file info headers
|
|
||||||
-b set binary mode, -b forces binary and -bb forces NOT binary
|
|
||||||
-r print everything (headers, line numbers, etc.) to stdout (or equivalent)
|
|
||||||
-p print file with the pager (uses less)
|
|
||||||
-n <name> manually set the name of the file shown in the title
|
|
||||||
-e <program> link extension to lat
|
|
||||||
-V show program version
|
|
||||||
-h display this help text
|
|
||||||
|
|
||||||
environment:
|
|
||||||
NO_COLOR, see https://no-color.org/
|
|
||||||
```
|
|
@ -2,19 +2,11 @@
|
|||||||
#define ARG_H
|
#define ARG_H
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define LAT_VERSION "0.13.0"
|
#define LAT_VERSION "0.4.0"
|
||||||
|
|
||||||
struct config {
|
struct config {
|
||||||
bool isstdin;
|
|
||||||
bool process;
|
|
||||||
bool color;
|
bool color;
|
||||||
bool lines;
|
bool lines;
|
||||||
bool headers;
|
|
||||||
int force_binary;
|
|
||||||
bool literal;
|
|
||||||
bool pager;
|
|
||||||
char *name;
|
|
||||||
char *extension;
|
|
||||||
bool has_read_stdin;
|
bool has_read_stdin;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
#ifndef FILE_H
|
#ifndef FILE_H
|
||||||
#define FILE_H
|
#define FILE_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
struct filedata {
|
||||||
|
int lc;
|
||||||
|
size_t len;
|
||||||
|
int binary;
|
||||||
|
char *buf;
|
||||||
|
};
|
||||||
|
|
||||||
struct filedata readfile(FILE *fp, bool isstdin);
|
struct filedata readfile(FILE *fp);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
#ifndef PROCESS_H
|
|
||||||
#define PROCESS_H
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
void loadlines(struct filedata *f);
|
|
||||||
|
|
||||||
char *linepad(int lc, int total);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,22 +0,0 @@
|
|||||||
#ifndef TYPES_H
|
|
||||||
#define TYPES_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
struct line {
|
|
||||||
size_t len;
|
|
||||||
char *buf;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct filedata {
|
|
||||||
int lc;
|
|
||||||
bool binary;
|
|
||||||
|
|
||||||
size_t buflen;
|
|
||||||
|
|
||||||
char *buf;
|
|
||||||
struct line *lines;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,54 +0,0 @@
|
|||||||
Require lat
|
|
||||||
Output social/render/binary.gif
|
|
||||||
|
|
||||||
Set Theme "Gruvbox Dark"
|
|
||||||
Set WindowBar Rings
|
|
||||||
Set BorderRadius 10
|
|
||||||
Set Margin 10
|
|
||||||
|
|
||||||
Set FontSize 32
|
|
||||||
Set Width 2400
|
|
||||||
Set Height 1200
|
|
||||||
Set TypingSpeed 0.2
|
|
||||||
|
|
||||||
Type "lat src/main.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
||||||
|
|
||||||
Type "clear"
|
|
||||||
Sleep 1s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 2s
|
|
||||||
|
|
||||||
Type "lat -b src/main.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
||||||
|
|
||||||
Type "clear"
|
|
||||||
Sleep 1s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 2s
|
|
||||||
|
|
||||||
Type "lat ./build/lat"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
||||||
|
|
||||||
Type "clear"
|
|
||||||
Sleep 1s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 2s
|
|
||||||
|
|
||||||
Type "lat -bb ./build/lat"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
@ -1,31 +0,0 @@
|
|||||||
Require lat
|
|
||||||
Output social/render/color.gif
|
|
||||||
|
|
||||||
Set Theme "Gruvbox Dark"
|
|
||||||
Set WindowBar Rings
|
|
||||||
Set BorderRadius 10
|
|
||||||
Set Margin 10
|
|
||||||
|
|
||||||
Set FontSize 32
|
|
||||||
Set Width 2400
|
|
||||||
Set Height 1200
|
|
||||||
Set TypingSpeed 0.2
|
|
||||||
|
|
||||||
Type "lat src/main.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
||||||
|
|
||||||
Type "clear"
|
|
||||||
Sleep 1s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 2s
|
|
||||||
|
|
||||||
Type "lat -c src/main.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
|||||||
Require lat
|
|
||||||
Output social/render/fzf_embed.gif
|
|
||||||
|
|
||||||
Set Theme "Gruvbox Dark"
|
|
||||||
Set WindowBar Rings
|
|
||||||
Set BorderRadius 10
|
|
||||||
Set Margin 10
|
|
||||||
|
|
||||||
Set FontSize 32
|
|
||||||
Set Width 2400
|
|
||||||
Set Height 1200
|
|
||||||
Set TypingSpeed 0.2
|
|
||||||
|
|
||||||
Type "fzf --preview 'lat -r {}'"
|
|
||||||
Sleep 1s
|
|
||||||
|
|
||||||
Enter
|
|
||||||
Sleep 2s
|
|
||||||
|
|
||||||
Type "main.c"
|
|
||||||
Sleep 2s
|
|
||||||
Backspace 7
|
|
||||||
Sleep 1s
|
|
||||||
|
|
||||||
Type "types.h"
|
|
||||||
Sleep 1s
|
|
||||||
Backspace 8
|
|
||||||
Sleep 2s
|
|
||||||
|
|
||||||
Type "file.c"
|
|
||||||
Sleep 3s
|
|
||||||
Backspace 7
|
|
||||||
Sleep 2s
|
|
||||||
|
|
||||||
Up@3s 15
|
|
||||||
|
|
||||||
Sleep 3s
|
|
||||||
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 2s
|
|
@ -1,32 +0,0 @@
|
|||||||
Require lat
|
|
||||||
Output social/render/headers.gif
|
|
||||||
|
|
||||||
Set Theme "Gruvbox Dark"
|
|
||||||
Set WindowBar Rings
|
|
||||||
Set BorderRadius 10
|
|
||||||
Set Margin 10
|
|
||||||
|
|
||||||
Set FontSize 32
|
|
||||||
Set Width 2400
|
|
||||||
Set Height 1200
|
|
||||||
Set TypingSpeed 0.2
|
|
||||||
|
|
||||||
Type "lat src/main.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
||||||
|
|
||||||
Type "clear"
|
|
||||||
Sleep 1s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 2s
|
|
||||||
|
|
||||||
Type "lat -t src/main.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
||||||
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
|||||||
Require lat
|
|
||||||
Output social/render/lat_demo.gif
|
|
||||||
|
|
||||||
Set Theme "Gruvbox Dark"
|
|
||||||
Set WindowBar Rings
|
|
||||||
Set BorderRadius 10
|
|
||||||
Set Margin 10
|
|
||||||
|
|
||||||
Set FontSize 32
|
|
||||||
Set Width 2400
|
|
||||||
Set Height 2000
|
|
||||||
Set TypingSpeed 0.2
|
|
||||||
|
|
||||||
Type "lat Makefile"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 4s
|
|
||||||
|
|
||||||
Type "lat -h"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 4s
|
|
@ -1,30 +0,0 @@
|
|||||||
Require lat
|
|
||||||
Output social/render/line_numbers.gif
|
|
||||||
|
|
||||||
Set Theme "Gruvbox Dark"
|
|
||||||
Set WindowBar Rings
|
|
||||||
Set BorderRadius 10
|
|
||||||
Set Margin 10
|
|
||||||
|
|
||||||
Set FontSize 32
|
|
||||||
Set Width 2400
|
|
||||||
Set Height 1200
|
|
||||||
Set TypingSpeed 0.2
|
|
||||||
|
|
||||||
Type "lat src/main.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 4s
|
|
||||||
|
|
||||||
Type "clear"
|
|
||||||
Sleep 1s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 2s
|
|
||||||
|
|
||||||
Type "lat -n src/main.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 4s
|
|
@ -1,46 +0,0 @@
|
|||||||
Require lat
|
|
||||||
Output social/render/literal.gif
|
|
||||||
|
|
||||||
Set Theme "Gruvbox Dark"
|
|
||||||
Set WindowBar Rings
|
|
||||||
Set BorderRadius 10
|
|
||||||
Set Margin 10
|
|
||||||
|
|
||||||
Set FontSize 32
|
|
||||||
Set Width 2400
|
|
||||||
Set Height 1200
|
|
||||||
Set TypingSpeed 0.2
|
|
||||||
|
|
||||||
Type "lat src/main.c > example.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
||||||
|
|
||||||
Type "cat example.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
||||||
|
|
||||||
Type "clear"
|
|
||||||
Sleep 1s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 2s
|
|
||||||
|
|
||||||
Type "lat -r src/main.c > example.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 3s
|
|
||||||
|
|
||||||
Type "cat example.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
||||||
|
|
||||||
Hide
|
|
||||||
Type "rm example.c"
|
|
||||||
Enter
|
|
@ -1,37 +0,0 @@
|
|||||||
Require lat
|
|
||||||
Output social/render/name.gif
|
|
||||||
|
|
||||||
Set Theme "Gruvbox Dark"
|
|
||||||
Set WindowBar Rings
|
|
||||||
Set BorderRadius 10
|
|
||||||
Set Margin 10
|
|
||||||
|
|
||||||
Set FontSize 32
|
|
||||||
Set Width 2400
|
|
||||||
Set Height 1200
|
|
||||||
Set TypingSpeed 0.2
|
|
||||||
|
|
||||||
Type "lat"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Type "hello, world!"
|
|
||||||
Enter
|
|
||||||
Sleep 3s
|
|
||||||
|
|
||||||
Ctrl+d
|
|
||||||
|
|
||||||
Sleep 3s
|
|
||||||
|
|
||||||
Type "lat -n "custom name" src/main.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Type "hello, world!"
|
|
||||||
Enter
|
|
||||||
Sleep 3s
|
|
||||||
|
|
||||||
Ctrl+d
|
|
||||||
|
|
||||||
Sleep 4s
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
|||||||
Require lat
|
|
||||||
Output social/render/pager.gif
|
|
||||||
|
|
||||||
Set Theme "Gruvbox Dark"
|
|
||||||
Set WindowBar Rings
|
|
||||||
Set BorderRadius 10
|
|
||||||
Set Margin 10
|
|
||||||
|
|
||||||
Set FontSize 32
|
|
||||||
Set Width 2400
|
|
||||||
Set Height 1200
|
|
||||||
Set TypingSpeed 0.2
|
|
||||||
|
|
||||||
Type "lat src/main.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
||||||
|
|
||||||
Type "clear"
|
|
||||||
Sleep 1s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 2s
|
|
||||||
|
|
||||||
Type "lat -p src/main.c"
|
|
||||||
Sleep 2s
|
|
||||||
Enter
|
|
||||||
|
|
||||||
Sleep 5s
|
|
||||||
|
|
||||||
Down 100
|
|
||||||
|
|
||||||
Sleep 3s
|
|
||||||
|
|
||||||
Type "q"
|
|
||||||
Sleep 4s
|
|
||||||
|
|
||||||
|
|
||||||
|
|
148
src/lib/arg.c
148
src/lib/arg.c
@ -1,93 +1,109 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdnoreturn.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "arg.h"
|
#include "arg.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define LAT_SHORT_ARGS "cltbrpn:e:Vh"
|
#define LAT_USAGE "usage: lat [cnVh] [files..]"
|
||||||
#define LAT_USAGE "usage: lat [-cltbrpneVh] [file...]"
|
|
||||||
|
|
||||||
struct config conf;
|
|
||||||
|
|
||||||
void help(void) {
|
void help(void) {
|
||||||
printf("lat | lazy cat - a cat clone with some quality-of-life "
|
printf("%s\n", LAT_USAGE);
|
||||||
"embellishments\n\n");
|
|
||||||
|
|
||||||
printf("%s\n\n", LAT_USAGE);
|
|
||||||
printf("options:\n"
|
printf("options:\n"
|
||||||
"\t-c toggle color\n"
|
"\t-c, --color\t toggle whether to print color or not\n"
|
||||||
"\t-l toggle line numbers\n"
|
"\t-n, --lines\t toggle whether to print line numbers or not\n"
|
||||||
"\t-t toggle file info headers\n"
|
"\t-V, --version\t show program version\n"
|
||||||
"\t-b set binary mode, -b forces binary and -bb forces NOT "
|
"\t-h, --help\t display this help text\n");
|
||||||
"binary\n"
|
|
||||||
"\t-r print everything (headers, line numbers, etc.) to "
|
|
||||||
"stdout (or equivalent)\n"
|
|
||||||
"\t-p disable or enable pager (uses less)\n"
|
|
||||||
"\t-n <name> manually set the name of the file shown in the title\n"
|
|
||||||
// "\t-e <program> NONFUNCTIONAL (will be added soon) link extension
|
|
||||||
// to lat\n"
|
|
||||||
"\t-V show program version\n"
|
|
||||||
"\t-h display this help text\n\n");
|
|
||||||
printf("environment:\n"
|
|
||||||
"\tNO_COLOR, see https://no-color.org/\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void version(void) {
|
void version(void) {
|
||||||
printf("lat - v%s built %s at %s\n", LAT_VERSION, __DATE__, __TIME__);
|
printf("lat - v%s | %s:%s\n", LAT_VERSION, __DATE__, __TIME__);
|
||||||
}
|
}
|
||||||
|
|
||||||
noreturn void argerr(void) {
|
struct config conf;
|
||||||
printf("\n%s\n", LAT_USAGE);
|
void argerr(char *r, char *arg) {
|
||||||
printf("run '-h' for more information\n");
|
printf("lat: %s '%s'\n", r, arg);
|
||||||
|
printf("%s\n", LAT_USAGE);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int parseargs(int argc, char *argv[]) {
|
void parselongarg(char *arg) {
|
||||||
char opt;
|
if (strcmp(arg, "--color") == 0) {
|
||||||
while ((opt = getopt(argc, argv, LAT_SHORT_ARGS)) != -1) {
|
conf.color = !conf.color;
|
||||||
switch (opt) {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(arg, "--lines") == 0) {
|
||||||
|
conf.lines = !conf.lines;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(arg, "--help") == 0) {
|
||||||
|
help();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(arg, "--version") == 0) {
|
||||||
|
version();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
argerr("unrecognized arg", arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseshortarg(char *arg) {
|
||||||
|
size_t i = 1;
|
||||||
|
while (arg[i] != '\0') {
|
||||||
|
char c = arg[i];
|
||||||
|
switch (c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
conf.color = !conf.color;
|
conf.color = !conf.color;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
|
||||||
conf.lines = !conf.lines;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
conf.headers = !conf.headers;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
if (conf.force_binary < 0)
|
|
||||||
conf.force_binary = 1;
|
|
||||||
else
|
|
||||||
conf.force_binary = !conf.force_binary;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
conf.literal = !conf.literal;
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
conf.pager = !conf.pager;
|
|
||||||
break;
|
|
||||||
case 'n':
|
case 'n':
|
||||||
conf.name = optarg;
|
conf.lines = !conf.lines;
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
conf.extension = optarg;
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
version();
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
help();
|
help();
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
break;
|
break;
|
||||||
default:
|
case 'V':
|
||||||
argerr();
|
version();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
char *str = malloc(2);
|
||||||
|
str[0] = c;
|
||||||
|
str[1] = '\0';
|
||||||
|
argerr("unrecognized flag", str);
|
||||||
|
free(str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return optind;
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int parseargs(int argc, char *argv[]) {
|
||||||
|
int i;
|
||||||
|
for (i = 1; i < argc; i++) { // offset for argv[0]
|
||||||
|
char *arg = argv[i];
|
||||||
|
|
||||||
|
if (*arg == '-') {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg[0] == '-') {
|
||||||
|
if (arg[1] == '-') {
|
||||||
|
parselongarg(arg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseshortarg(arg);
|
||||||
|
} else {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -2,84 +2,55 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "types.h"
|
#include "file.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "arg.h"
|
|
||||||
|
|
||||||
bool isbinary(struct filedata *f) {
|
|
||||||
|
|
||||||
// guess if printable
|
|
||||||
// from https://github.com/sharkdp/content_inspector/blob/master/src/lib.rs
|
|
||||||
int testlen = f->buflen >= 64 ? 64 : f->buflen;
|
|
||||||
char *testbuf[testlen];
|
|
||||||
memcpy(testbuf, f->buf, testlen);
|
|
||||||
|
|
||||||
char *result = memchr(testbuf, 0x00, testlen);
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct filedata readfile(FILE *fp) {
|
struct filedata readfile(FILE *fp) {
|
||||||
struct filedata f;
|
struct filedata f;
|
||||||
|
|
||||||
f.lc = 0;
|
f.lc = 0;
|
||||||
f.buflen = 0;
|
f.len = 0;
|
||||||
f.binary = 0;
|
f.binary = 0;
|
||||||
|
|
||||||
f.buf = NULL;
|
size_t bufsize = 4;
|
||||||
f.lines = NULL;
|
|
||||||
|
|
||||||
if (conf.isstdin) {
|
|
||||||
size_t bufsize = 1024;
|
|
||||||
f.buf = malloc(bufsize);
|
f.buf = malloc(bufsize);
|
||||||
if (f.buf == NULL)
|
if (f.buf == NULL)
|
||||||
die("malloc");
|
die("malloc");
|
||||||
|
|
||||||
char c;
|
char c;
|
||||||
while (fread(&c, 1, 1, fp) > 0) {
|
while (fread(&c, sizeof(char), 1, fp) > 0) {
|
||||||
if (f.buflen == bufsize - 1) {
|
if (f.len == bufsize - 1) {
|
||||||
bufsize *= 2;
|
bufsize *= 2;
|
||||||
|
|
||||||
char *new_buf = realloc(f.buf, bufsize);
|
char *new_buf = realloc(f.buf, bufsize);
|
||||||
if (new_buf == NULL)
|
if (f.buf == NULL) {
|
||||||
|
free(f.buf);
|
||||||
die("realloc");
|
die("realloc");
|
||||||
|
}
|
||||||
|
|
||||||
f.buf = new_buf;
|
f.buf = new_buf;
|
||||||
}
|
}
|
||||||
f.buf[f.buflen++] = c;
|
|
||||||
|
if (c == '\n') {
|
||||||
|
f.lc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f.buflen < bufsize - 1) {
|
f.buf[f.len++] = c;
|
||||||
char *new_buf = realloc(f.buf, f.buflen + 1);
|
|
||||||
if (new_buf == NULL)
|
|
||||||
die("realloc");
|
|
||||||
|
|
||||||
f.buf = new_buf;
|
|
||||||
}
|
}
|
||||||
f.buf[f.buflen] = '\0';
|
|
||||||
|
|
||||||
f.binary = isbinary(&f);
|
// guess if printable
|
||||||
|
// from https://github.com/sharkdp/content_inspector/blob/master/src/lib.rs
|
||||||
return f;
|
int testlen = f.len >= 64 ? 64 : f.len;
|
||||||
}
|
char *testbuf[testlen];
|
||||||
|
memcpy(testbuf, f.buf, testlen);
|
||||||
// expects to be at beginning of file
|
|
||||||
fseek(fp, 0, SEEK_END);
|
char *result = memchr(testbuf, 0x00, testlen);
|
||||||
f.buflen = ftell(fp);
|
|
||||||
fseek(fp, 0, SEEK_SET);
|
if (result) {
|
||||||
|
f.binary = 1;
|
||||||
f.buf = malloc(f.buflen);
|
} else {
|
||||||
if (f.buf == NULL)
|
f.binary = 0;
|
||||||
die("malloc");
|
}
|
||||||
|
|
||||||
if (fread(f.buf, f.buflen, 1, fp) < 0) {
|
|
||||||
die("fread");
|
|
||||||
}
|
|
||||||
|
|
||||||
f.binary = isbinary(&f);
|
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
void appendline(struct filedata *f, char *data, size_t len) {
|
|
||||||
f->lines = realloc(f->lines, sizeof(struct line) * (f->lc + 1));
|
|
||||||
if (f->lines == NULL)
|
|
||||||
die("realloc");
|
|
||||||
|
|
||||||
size_t loc = f->lc;
|
|
||||||
|
|
||||||
f->lines[loc].len = len;
|
|
||||||
f->lines[loc].buf = malloc(len + 1);
|
|
||||||
memcpy(f->lines[loc].buf, data, len);
|
|
||||||
f->lines[loc].buf[len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadlines(struct filedata *f) {
|
|
||||||
f->lc = 0;
|
|
||||||
|
|
||||||
size_t offset = 0;
|
|
||||||
size_t linelen = 1024;
|
|
||||||
char *line = malloc(linelen);
|
|
||||||
if (line == NULL)
|
|
||||||
die("malloc");
|
|
||||||
|
|
||||||
for (size_t i = 0; i < f->buflen; i++) {
|
|
||||||
char c = f->buf[i];
|
|
||||||
if (c == '\n') {
|
|
||||||
if (offset >= 1 && offset < linelen) { // shrink to fit
|
|
||||||
char *new_line = realloc(line, offset);
|
|
||||||
if (new_line == NULL)
|
|
||||||
die("realloc");
|
|
||||||
|
|
||||||
line = new_line;
|
|
||||||
}
|
|
||||||
|
|
||||||
appendline(f, line, offset);
|
|
||||||
f->lc++;
|
|
||||||
|
|
||||||
free(line);
|
|
||||||
offset = 0;
|
|
||||||
line = malloc(linelen);
|
|
||||||
if (line == NULL)
|
|
||||||
die("malloc");
|
|
||||||
} else {
|
|
||||||
if (offset == linelen) {
|
|
||||||
linelen *= 2;
|
|
||||||
|
|
||||||
char *new_line = realloc(line, linelen);
|
|
||||||
if (new_line == NULL)
|
|
||||||
die("realloc");
|
|
||||||
|
|
||||||
line = new_line;
|
|
||||||
}
|
|
||||||
|
|
||||||
line[offset++] = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// capture last line
|
|
||||||
if (offset >= 1 && offset < linelen) { // shrink
|
|
||||||
char *new_line = realloc(line, offset);
|
|
||||||
if (new_line == NULL)
|
|
||||||
die("realloc");
|
|
||||||
line = new_line;
|
|
||||||
}
|
|
||||||
|
|
||||||
appendline(f, line, offset);
|
|
||||||
f->lc++;
|
|
||||||
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *linepad(int lc, int total) {
|
|
||||||
int padlen = intlen(total) - intlen(lc);
|
|
||||||
char *padding = malloc(padlen + 1);
|
|
||||||
if (padding == NULL)
|
|
||||||
die("malloc");
|
|
||||||
|
|
||||||
if (padlen)
|
|
||||||
memset(padding, ' ', padlen);
|
|
||||||
padding[padlen] = '\0';
|
|
||||||
|
|
||||||
return padding;
|
|
||||||
}
|
|
@ -1,8 +1,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdnoreturn.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
noreturn void die(const char *message) {
|
void die(const char *message) {
|
||||||
perror(message);
|
perror(message);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
183
src/main.c
183
src/main.c
@ -1,12 +1,11 @@
|
|||||||
|
#include <libgen.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/ioctl.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "arg.h"
|
#include "arg.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "process.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#define INVERT_T "\x1b[7m"
|
#define INVERT_T "\x1b[7m"
|
||||||
@ -14,142 +13,65 @@
|
|||||||
#define GREY "\x1b[90m"
|
#define GREY "\x1b[90m"
|
||||||
#define RESET "\x1b[0m"
|
#define RESET "\x1b[0m"
|
||||||
|
|
||||||
FILE *st;
|
|
||||||
FILE *err;
|
|
||||||
|
|
||||||
struct colors {
|
|
||||||
char *invert_t;
|
|
||||||
char *grey;
|
|
||||||
char *reset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct colors c;
|
|
||||||
|
|
||||||
void initcolor(void) {
|
|
||||||
c.invert_t = conf.color ? INVERT_T : "";
|
|
||||||
c.grey = conf.color ? GREY : "";
|
|
||||||
c.reset = conf.color ? RESET : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void printheadertop(char *filename, bool binary) {
|
|
||||||
char *name = conf.name == NULL ? filename : conf.name;
|
|
||||||
char *addon = binary ? "<binary>" : "";
|
|
||||||
if (conf.isstdin && !conf.pager)
|
|
||||||
fprintf(err, "\x1b[2K\r%s%s%s%s\n", c.invert_t, name, addon, c.reset);
|
|
||||||
else
|
|
||||||
fprintf(err, "%s%s%s%s\n", c.invert_t, name, addon, c.reset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printheaderbottom(size_t buflen) {
|
|
||||||
float rounded;
|
|
||||||
char *format = formatbytes(buflen, &rounded);
|
|
||||||
|
|
||||||
fprintf(err, "%s%.2f %s%s\n", c.invert_t, rounded, format, c.reset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void run(FILE *fp, char *filename, bool tty) {
|
void run(FILE *fp, char *filename, bool tty) {
|
||||||
initcolor();
|
const char *invert_t = conf.color ? INVERT_T : "";
|
||||||
|
const char *uinvert_t = conf.color ? UINVERT_T : "";
|
||||||
|
const char *grey = conf.color ? GREY : "";
|
||||||
|
const char *reset = conf.color ? RESET : "";
|
||||||
|
|
||||||
struct filedata f;
|
struct filedata f;
|
||||||
f = readfile(fp, conf.isstdin);
|
f = readfile(fp);
|
||||||
|
|
||||||
// any/all processing to be done
|
if (tty) {
|
||||||
// TODO: maybe multithread?
|
char *addon = f.binary ? "<binary>" : "";
|
||||||
conf.process = (tty && !f.binary);
|
fprintf(stderr, "\r\x1b[2K%s%s%s%s\r\n", invert_t, basename(filename),
|
||||||
if (conf.process) { // file display processing
|
addon, uinvert_t);
|
||||||
loadlines(&f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf.extension != NULL) {
|
int lcpad = intlen(f.lc);
|
||||||
// TODO
|
|
||||||
|
f.lc = 0;
|
||||||
|
char pc = '\0';
|
||||||
|
char c;
|
||||||
|
for (size_t i = 0; i < f.len; i++) {
|
||||||
|
c = f.buf[i];
|
||||||
|
|
||||||
|
if ((conf.lines && tty && !f.binary) && (pc == '\n' || i == 0)) {
|
||||||
|
f.lc++;
|
||||||
|
|
||||||
|
int padlen = lcpad - intlen(f.lc);
|
||||||
|
char padding[padlen];
|
||||||
|
|
||||||
|
if (padlen)
|
||||||
|
memset(padding, ' ', padlen);
|
||||||
|
|
||||||
|
fprintf(stderr, "\r%s%s%d:%s ", grey, padlen > 0 ? padding : "", f.lc,
|
||||||
|
reset); // padlen < 1 causes undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
struct winsize w;
|
pc = c;
|
||||||
|
printf("%c", c);
|
||||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1 || w.ws_col != 0) {
|
|
||||||
if (w.ws_row <= f.lc + 5) {
|
|
||||||
conf.pager = !conf.pager;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf.pager) {
|
fflush(stdout); // prevent timing inconsistencies between stdout and stderr
|
||||||
st = popen("less", "w");
|
|
||||||
err = st;
|
|
||||||
|
|
||||||
if (st == NULL)
|
if (tty) {
|
||||||
die("popen 'less'");
|
float rounded;
|
||||||
}
|
char *format = formatbytes(f.len, &rounded);
|
||||||
|
|
||||||
if (conf.literal) {
|
char *cnewline = c == '\n' ? "" : "\n";
|
||||||
err = st;
|
fprintf(stderr, "\r%s%s%.2f %s%s\r\n", cnewline, invert_t, rounded, format,
|
||||||
}
|
uinvert_t);
|
||||||
|
|
||||||
if (conf.force_binary > 0) {
|
|
||||||
f.binary = true;
|
|
||||||
} else if (conf.force_binary == 0) {
|
|
||||||
f.binary = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conf.headers) {
|
|
||||||
printheadertop(filename, f.binary);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conf.process) {
|
|
||||||
int linecount = 1;
|
|
||||||
for (int i = 0; i < f.lc; i++) {
|
|
||||||
if (conf.lines) {
|
|
||||||
{ // line numbers
|
|
||||||
char *padding = linepad(linecount, f.lc);
|
|
||||||
fprintf(err, "%s%s%d│%s ", c.grey, padding, i + 1, c.reset);
|
|
||||||
free(padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
fwrite(f.lines[i].buf, 1, f.lines[i].len, st);
|
|
||||||
fprintf(st, "\n");
|
|
||||||
linecount++;
|
|
||||||
} else {
|
|
||||||
fprintf(st, "%s\n", f.lines[i].buf);
|
|
||||||
}
|
|
||||||
free(f.lines[i].buf);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fwrite(f.buf, 1, f.buflen, st);
|
|
||||||
fflush(st);
|
|
||||||
if (tty)
|
|
||||||
fwrite("\n", 1, 1, err);
|
|
||||||
}
|
|
||||||
free(f.buf);
|
|
||||||
free(f.lines);
|
|
||||||
|
|
||||||
fflush(st); // prevent timing inconsistencies between st and err
|
|
||||||
fflush(err);
|
|
||||||
|
|
||||||
if (conf.headers) {
|
|
||||||
printheaderbottom(f.buflen);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conf.pager) {
|
|
||||||
pclose(st); // err is already the same as st
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initconf(void) {
|
void initconf(void) {
|
||||||
conf.force_binary = -1;
|
|
||||||
conf.isstdin = false;
|
|
||||||
conf.has_read_stdin = false;
|
|
||||||
conf.pager = false;
|
|
||||||
conf.literal = false;
|
|
||||||
|
|
||||||
conf.process = true;
|
|
||||||
conf.headers = true;
|
|
||||||
conf.color = true;
|
conf.color = true;
|
||||||
conf.lines = true;
|
conf.lines = true;
|
||||||
|
conf.has_read_stdin = false;
|
||||||
conf.name = NULL;
|
|
||||||
conf.extension = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearstdin(void) {
|
void clearstdin() {
|
||||||
// from
|
// from
|
||||||
// https://stackoverflow.com/questions/7898215/how-to-clear-input-buffer-in-c
|
// https://stackoverflow.com/questions/7898215/how-to-clear-input-buffer-in-c
|
||||||
fseek(stdin, 0, SEEK_END);
|
fseek(stdin, 0, SEEK_END);
|
||||||
@ -158,9 +80,6 @@ void clearstdin(void) {
|
|||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
initconf();
|
initconf();
|
||||||
|
|
||||||
st = stdout;
|
|
||||||
err = stderr;
|
|
||||||
|
|
||||||
// init no_color first so that args take priority
|
// init no_color first so that args take priority
|
||||||
char *no_color = getenv("NO_COLOR");
|
char *no_color = getenv("NO_COLOR");
|
||||||
|
|
||||||
@ -169,46 +88,32 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool tty = isatty(STDOUT_FILENO);
|
bool tty = isatty(STDOUT_FILENO);
|
||||||
|
|
||||||
int offset = parseargs(argc, argv);
|
|
||||||
|
|
||||||
conf.headers = conf.headers && tty;
|
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
int offset = parseargs(argc, argv);
|
||||||
tty = tty || conf.literal;
|
|
||||||
|
|
||||||
for (int i = offset; i < argc; i++) {
|
for (int i = offset; i < argc; i++) {
|
||||||
if (*argv[i] == '-') {
|
if (*argv[i] == '-') {
|
||||||
if (conf.has_read_stdin)
|
if (conf.has_read_stdin)
|
||||||
clearstdin();
|
clearstdin();
|
||||||
conf.has_read_stdin = true;
|
conf.has_read_stdin = true;
|
||||||
conf.isstdin = true;
|
|
||||||
run(stdin, "stdin", tty);
|
run(stdin, "stdin", tty);
|
||||||
if (tty && (i + 1 != argc)) {
|
|
||||||
fprintf(err, "\n"); // separate concurrent files in tty
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
conf.isstdin = false;
|
|
||||||
FILE *fp = fopen(argv[i], "rb");
|
FILE *fp = fopen(argv[i], "rb");
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
die(argv[i]);
|
die(argv[i]);
|
||||||
run(fp, argv[i], tty);
|
run(fp, argv[i], tty);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
if (tty && (i + 1 != argc)) {
|
if (tty && (i + 1 != argc)) {
|
||||||
fprintf(err, "\n"); // separate concurrent files in tty
|
fprintf(stderr, "\r\n"); // separate concurrent files in tty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == argc) {
|
if (offset == argc) {
|
||||||
conf.isstdin = true;
|
|
||||||
run(stdin, "stdin", tty);
|
run(stdin, "stdin", tty);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
conf.isstdin = true;
|
|
||||||
run(stdin, "stdin", tty); // for piped-input or repl-like behavior
|
run(stdin, "stdin", tty); // for piped-input or repl-like behavior
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user