linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
/*
|
|
|
|
* Copyright 2016-present Facebook. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* linelogcli.c: a simple CLI tool manipulating a linelog file
|
|
|
|
*
|
|
|
|
* This software may be used and distributed according to the terms of the
|
|
|
|
* GNU General Public License version 2 or any later version.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* this tool is mainly for testing and debugging purpose. it does not have
|
|
|
|
proper error handling and is not very user-friendly. */
|
|
|
|
|
|
|
|
#ifndef _XOPEN_SOURCE
|
|
|
|
#define _XOPEN_SOURCE 500 /* ftruncate */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "linelog.c" /* unusual but we want to access some private structs */
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#define ensure(expr) if (!(expr)) { \
|
|
|
|
fprintf(stderr, "unexpected: %s\n at line %d\n errno = %d %s", \
|
|
|
|
#expr, __LINE__, errno, strerror(errno)); \
|
|
|
|
closefile(); exit(-1); }
|
|
|
|
|
2016-07-30 14:59:48 +03:00
|
|
|
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
|
|
|
const size_t UNIT_SIZE = 1;
|
|
|
|
#else
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
const size_t UNIT_SIZE = 0x1000; /* 4KB, used when resizing the file */
|
2016-07-30 14:59:48 +03:00
|
|
|
#endif
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
|
|
|
|
static linelog_buf buf;
|
|
|
|
static linelog_annotateresult ar;
|
|
|
|
static int fd = -1;
|
|
|
|
static size_t maplen;
|
|
|
|
static const char *filename;
|
|
|
|
|
|
|
|
static const char helptext[] =
|
2016-07-30 14:59:48 +03:00
|
|
|
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
|
|
|
"(built for fuzz testing)\n"
|
|
|
|
#endif
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
"usage: linelogcli FILE CMDLIST\n"
|
|
|
|
"where CMDLIST := CMD | CMDLIST CMD\n"
|
linelogcli: add new command `getalllines`
Summary:
Since linelog has the new `getalllines` API, add a corresponding command
to support it.
Test Plan:
```
$ make && ./linelogcli /tmp/lll init annotate 0 replacelines 1 0:0 0:3 \
replacelines 2 1:2 1:3 getalllines 0:0
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:3
replacelines: rev 2, lines 1:2 -> 1:3
getalllines: 5 lines
0: rev 1, line 0, offset 3
1: rev 2, line 1, offset 8
2: rev 2, line 2, offset 9
3: rev 1, line 1, offset 11
4: rev 1, line 2, offset 5
```
Reviewers: #mercurial, simonfar, ttung
Reviewed By: simonfar
Subscribers: mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3716453
Signature: t1:3716453:1471265279:a8f625660ef47ca341ca8f5c4c7370b56277cef8
2016-08-15 14:47:14 +03:00
|
|
|
" CMD := init | info | dump | ANNOTATECMD | REPLACELINESCMD | "
|
|
|
|
"GETALLLINESCMD\n"
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
" ANNOTATECMD := annotate REV | annotate -\n"
|
linelogcli: add new command `getalllines`
Summary:
Since linelog has the new `getalllines` API, add a corresponding command
to support it.
Test Plan:
```
$ make && ./linelogcli /tmp/lll init annotate 0 replacelines 1 0:0 0:3 \
replacelines 2 1:2 1:3 getalllines 0:0
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:3
replacelines: rev 2, lines 1:2 -> 1:3
getalllines: 5 lines
0: rev 1, line 0, offset 3
1: rev 2, line 1, offset 8
2: rev 2, line 2, offset 9
3: rev 1, line 1, offset 11
4: rev 1, line 2, offset 5
```
Reviewers: #mercurial, simonfar, ttung
Reviewed By: simonfar
Subscribers: mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3716453
Signature: t1:3716453:1471265279:a8f625660ef47ca341ca8f5c4c7370b56277cef8
2016-08-15 14:47:14 +03:00
|
|
|
" REPLACELINESCMD := replacelines rev a1:a2 b1:b2\n"
|
|
|
|
" GETALLLINESCMD := getalllines offset1:offset2\n";
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
|
|
|
|
static void closefile(void) {
|
|
|
|
if (buf.data) {
|
|
|
|
ensure(msync(buf.data, buf.size, MS_ASYNC) == 0);
|
|
|
|
ensure(munmap(buf.data, maplen) == 0);
|
|
|
|
buf.data = NULL;
|
|
|
|
buf.size = 0;
|
|
|
|
}
|
|
|
|
if (fd != -1) {
|
|
|
|
ensure(close(fd) == 0);
|
|
|
|
fd = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void openfile(void) {
|
|
|
|
closefile();
|
|
|
|
ensure((fd = open(filename, O_RDWR | O_CREAT, 0644)) != -1);
|
|
|
|
|
|
|
|
struct stat st;
|
|
|
|
ensure(fstat(fd, &st) == 0);
|
|
|
|
|
|
|
|
maplen = (st.st_size == 0 ? 1 : (size_t)st.st_size);
|
|
|
|
void *p = mmap(NULL, maplen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
|
|
ensure(p != MAP_FAILED);
|
|
|
|
|
|
|
|
buf.data = p;
|
|
|
|
buf.size = (size_t)st.st_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void resizefile(size_t size) {
|
|
|
|
closefile();
|
|
|
|
ensure((fd = open(filename, O_RDWR | O_CREAT, 0644)) != -1);
|
|
|
|
ensure(ftruncate(fd, (off_t)size) == 0);
|
|
|
|
openfile();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* handle LINELOG_RESULT_ENEEDRESIZE automatically */
|
|
|
|
#define eval(result, expr) while (1) { \
|
|
|
|
result = (expr); \
|
|
|
|
if (result != LINELOG_RESULT_ENEEDRESIZE) \
|
|
|
|
break; \
|
|
|
|
resizefile((buf.neededsize / UNIT_SIZE + 1) * UNIT_SIZE); }
|
|
|
|
|
|
|
|
int cmdinit(const char *args[]) {
|
|
|
|
(void)args;
|
|
|
|
linelog_result r;
|
|
|
|
eval(r, linelog_clear(&buf));
|
|
|
|
if (r == LINELOG_RESULT_OK)
|
|
|
|
printf("init: okay\n");
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmdinfo(const char *args[]) {
|
|
|
|
(void)args;
|
|
|
|
size_t size = linelog_getactualsize(&buf);
|
|
|
|
linelog_revnum rev = linelog_getmaxrev(&buf);
|
|
|
|
printf("info: maxrev = %u, size = %lu\n",
|
|
|
|
(unsigned)rev, (unsigned long)size);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmdannotate(const char *args[]) {
|
|
|
|
linelog_result r = LINELOG_RESULT_OK;
|
|
|
|
unsigned rev = 0;
|
|
|
|
if (sscanf(args[0], "%u", &rev) == 1) {
|
|
|
|
printf("annotate: run annotate for rev %u\n", rev);
|
|
|
|
eval(r, linelog_annotate(&buf, &ar, (linelog_revnum)rev));
|
|
|
|
}
|
|
|
|
if (r == LINELOG_RESULT_OK) {
|
|
|
|
printf("annotate: %u lines, endoffset %u\n",
|
|
|
|
ar.linecount, ar.lines[ar.linecount].offset);
|
|
|
|
for (uint32_t i = 0; i < ar.linecount; ++i) {
|
|
|
|
linelog_lineinfo l = ar.lines[i];
|
|
|
|
printf(" %u: rev %u, line %u, offset %u\n",
|
|
|
|
i, l.rev, l.linenum, l.offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2016-07-30 14:59:48 +03:00
|
|
|
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
|
|
|
static void doublecheckannotateresult(linelog_revnum rev) {
|
|
|
|
/* backup current ar for later comparison */
|
|
|
|
linelog_annotateresult ar2 = ar;
|
|
|
|
size_t arsize = (ar.linecount + 1) * sizeof(linelog_lineinfo);
|
|
|
|
ar2.lines = malloc(arsize);
|
|
|
|
ar2.maxlinecount = ar2.linecount + 1;
|
|
|
|
ensure(ar2.lines != NULL);
|
|
|
|
memcpy(ar2.lines, ar.lines, arsize);
|
|
|
|
linelog_result r;
|
|
|
|
eval(r, linelog_annotate(&buf, &ar2, rev));
|
|
|
|
if (r != LINELOG_RESULT_OK || (ar.linecount == ar2.linecount &&
|
|
|
|
memcmp(ar2.lines, ar.lines, arsize) == 0)) {
|
|
|
|
free(ar2.lines);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
fprintf(stderr, "unexpected: annotate results mismatch\n");
|
|
|
|
int cmddump(const char *args[]);
|
|
|
|
cmddump(NULL);
|
|
|
|
|
|
|
|
linelog_linenum maxlc = ar.linecount > ar2.linecount
|
|
|
|
? ar.linecount : ar2.linecount;
|
|
|
|
fprintf(stderr, "ar %d lines | ar2 %d lines\n",
|
|
|
|
ar.linecount, ar2.linecount);
|
|
|
|
for (uint32_t i = 0; i <= maxlc; ++i) {
|
|
|
|
linelog_lineinfo l[2];
|
|
|
|
memset(l, -1, sizeof(l));
|
|
|
|
if (i <= ar.linecount)
|
|
|
|
l[0] = ar.lines[i];
|
|
|
|
if (i <= ar2.linecount)
|
|
|
|
l[1] = ar2.lines[i];
|
|
|
|
char ch = memcmp(l, l + 1, sizeof(l[0])) ? '!' : '=';
|
|
|
|
fprintf(stderr, "%c %u: %u %u %u | %u %u %u\n",
|
|
|
|
ch, i,
|
|
|
|
l[0].rev, l[0].linenum, l[0].offset,
|
|
|
|
l[1].rev, l[1].linenum, l[1].offset);
|
|
|
|
}
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
int cmdreplacelines(const char *args[]) {
|
|
|
|
linelog_result r;
|
|
|
|
unsigned rev = 0, b1 = 0, b2 = 0;
|
|
|
|
int a1 = 0, a2 = 0;
|
|
|
|
sscanf(args[0], "%u", &rev);
|
|
|
|
sscanf(args[1], "%d:%d", &a1, &a2);
|
|
|
|
sscanf(args[2], "%u:%u", &b1, &b2);
|
|
|
|
/* for negative number of a1, a2. use linecount automatically */
|
|
|
|
if (a1 < 0)
|
|
|
|
a1 = (int)ar.linecount + 1 + a1;
|
|
|
|
if (a2 < 0)
|
|
|
|
a2 = (int)ar.linecount + 1 + a2;
|
2016-07-30 14:59:48 +03:00
|
|
|
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
|
|
|
/* make sure we use clean, up-to-date annotate result. this changes
|
|
|
|
behavior a bit but reduces noise from fuzz testing */
|
|
|
|
eval(r, linelog_annotate(&buf, &ar, rev));
|
|
|
|
if (r != LINELOG_RESULT_OK)
|
|
|
|
return r;
|
|
|
|
#endif
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
eval(r, linelog_replacelines(&buf, &ar, rev,
|
|
|
|
(uint32_t)a1, (uint32_t)a2, b1, b2));
|
|
|
|
if (r == LINELOG_RESULT_OK) {
|
|
|
|
printf("replacelines: rev %u, lines %u:%u -> %u:%u\n",
|
|
|
|
rev, a1, a2, b1, b2);
|
2016-07-30 14:59:48 +03:00
|
|
|
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
|
|
|
/* annotateresult updated by linelog_replacelines should be
|
|
|
|
the same with running linelog_annotate directly */
|
|
|
|
doublecheckannotateresult(rev);
|
|
|
|
#endif
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmddump(const char *args[]) {
|
|
|
|
(void)args;
|
|
|
|
size_t size = linelog_getactualsize(&buf) / INST_SIZE;
|
|
|
|
printf("dump:\n");
|
|
|
|
for (size_t offset = 1; offset < size; ++offset) {
|
|
|
|
linelog_inst i;
|
|
|
|
memset(&i, 0, sizeof(i));
|
|
|
|
readinst(&buf, &i, offset);
|
|
|
|
/* opcode */
|
|
|
|
const char *opname = "?";
|
|
|
|
if (i.opcode == JGE) {
|
|
|
|
if (i.rev == 0) {
|
|
|
|
if (i.offset == 0) /* JGE 0 0 => END */
|
|
|
|
opname = "END";
|
|
|
|
else /* JGE 0 => J */
|
|
|
|
opname = "J";
|
|
|
|
} else {
|
|
|
|
opname = "JGE";
|
|
|
|
}
|
|
|
|
} else if (i.opcode == JL) {
|
|
|
|
opname = "JL";
|
|
|
|
} else if (i.opcode == LINE) {
|
|
|
|
opname = "LINE";
|
|
|
|
}
|
|
|
|
printf(" %6u: %-4s ", (unsigned)offset, opname);
|
|
|
|
/* operand 1 */
|
2016-08-11 00:02:24 +03:00
|
|
|
if (i.rev) {
|
|
|
|
printf("%5u ", (unsigned)i.rev);
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
} else {
|
|
|
|
printf(" ");
|
|
|
|
}
|
|
|
|
/* operand 2 */
|
|
|
|
if (opname[0] == 'E') { /* END */
|
|
|
|
printf("\n");
|
|
|
|
} else {
|
2016-08-11 00:02:24 +03:00
|
|
|
printf("%u\n", (unsigned)i.offset);
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return LINELOG_RESULT_OK;
|
|
|
|
}
|
|
|
|
|
linelogcli: add new command `getalllines`
Summary:
Since linelog has the new `getalllines` API, add a corresponding command
to support it.
Test Plan:
```
$ make && ./linelogcli /tmp/lll init annotate 0 replacelines 1 0:0 0:3 \
replacelines 2 1:2 1:3 getalllines 0:0
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:3
replacelines: rev 2, lines 1:2 -> 1:3
getalllines: 5 lines
0: rev 1, line 0, offset 3
1: rev 2, line 1, offset 8
2: rev 2, line 2, offset 9
3: rev 1, line 1, offset 11
4: rev 1, line 2, offset 5
```
Reviewers: #mercurial, simonfar, ttung
Reviewed By: simonfar
Subscribers: mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3716453
Signature: t1:3716453:1471265279:a8f625660ef47ca341ca8f5c4c7370b56277cef8
2016-08-15 14:47:14 +03:00
|
|
|
int cmdgetalllines(const char *args[]) {
|
|
|
|
unsigned offset1 = 0, offset2 = 0;
|
|
|
|
sscanf(args[0], "%u:%u", &offset1, &offset2);
|
|
|
|
|
|
|
|
linelog_result r;
|
|
|
|
linelog_annotateresult ar;
|
|
|
|
memset(&ar, 0, sizeof(ar));
|
|
|
|
eval(r, linelog_getalllines(&buf, &ar, offset1, offset2));
|
|
|
|
if (r == LINELOG_RESULT_OK) {
|
|
|
|
printf("getalllines: %u lines\n", ar.linecount);
|
|
|
|
for (uint32_t i = 0; i < ar.linecount; ++i) {
|
|
|
|
linelog_lineinfo l = ar.lines[i];
|
|
|
|
printf(" %u: rev %u, line %u, offset %u\n",
|
|
|
|
i, l.rev, l.linenum, l.offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
linelog_annotateresult_clear(&ar);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
typedef int cmdfunc(const char *args[]);
|
|
|
|
typedef struct {
|
|
|
|
const char *name;
|
linelogcli: add new command `getalllines`
Summary:
Since linelog has the new `getalllines` API, add a corresponding command
to support it.
Test Plan:
```
$ make && ./linelogcli /tmp/lll init annotate 0 replacelines 1 0:0 0:3 \
replacelines 2 1:2 1:3 getalllines 0:0
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:3
replacelines: rev 2, lines 1:2 -> 1:3
getalllines: 5 lines
0: rev 1, line 0, offset 3
1: rev 2, line 1, offset 8
2: rev 2, line 2, offset 9
3: rev 1, line 1, offset 11
4: rev 1, line 2, offset 5
```
Reviewers: #mercurial, simonfar, ttung
Reviewed By: simonfar
Subscribers: mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3716453
Signature: t1:3716453:1471265279:a8f625660ef47ca341ca8f5c4c7370b56277cef8
2016-08-15 14:47:14 +03:00
|
|
|
const char shortname;
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
int argcount;
|
|
|
|
cmdfunc *func;
|
|
|
|
} cmdentry;
|
|
|
|
|
|
|
|
static cmdentry cmdtable[] = {
|
linelogcli: add new command `getalllines`
Summary:
Since linelog has the new `getalllines` API, add a corresponding command
to support it.
Test Plan:
```
$ make && ./linelogcli /tmp/lll init annotate 0 replacelines 1 0:0 0:3 \
replacelines 2 1:2 1:3 getalllines 0:0
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:3
replacelines: rev 2, lines 1:2 -> 1:3
getalllines: 5 lines
0: rev 1, line 0, offset 3
1: rev 2, line 1, offset 8
2: rev 2, line 2, offset 9
3: rev 1, line 1, offset 11
4: rev 1, line 2, offset 5
```
Reviewers: #mercurial, simonfar, ttung
Reviewed By: simonfar
Subscribers: mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3716453
Signature: t1:3716453:1471265279:a8f625660ef47ca341ca8f5c4c7370b56277cef8
2016-08-15 14:47:14 +03:00
|
|
|
{ "init", 'i', 0, cmdinit },
|
|
|
|
{ "info", 'f', 0, cmdinfo },
|
|
|
|
{ "annotate", 'a', 1, cmdannotate },
|
|
|
|
{ "replacelines", 'r', 3, cmdreplacelines },
|
|
|
|
{ "dump", 'd', 0, cmddump },
|
|
|
|
{ "getalllines", 'l', 1, cmdgetalllines },
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
const cmdentry *findcmd(const char *name) {
|
linelogcli: add new command `getalllines`
Summary:
Since linelog has the new `getalllines` API, add a corresponding command
to support it.
Test Plan:
```
$ make && ./linelogcli /tmp/lll init annotate 0 replacelines 1 0:0 0:3 \
replacelines 2 1:2 1:3 getalllines 0:0
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:3
replacelines: rev 2, lines 1:2 -> 1:3
getalllines: 5 lines
0: rev 1, line 0, offset 3
1: rev 2, line 1, offset 8
2: rev 2, line 2, offset 9
3: rev 1, line 1, offset 11
4: rev 1, line 2, offset 5
```
Reviewers: #mercurial, simonfar, ttung
Reviewed By: simonfar
Subscribers: mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3716453
Signature: t1:3716453:1471265279:a8f625660ef47ca341ca8f5c4c7370b56277cef8
2016-08-15 14:47:14 +03:00
|
|
|
size_t len = strlen(name);
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
for (size_t i = 0; i < sizeof(cmdtable) / sizeof(cmdtable[0]); ++i) {
|
linelogcli: add new command `getalllines`
Summary:
Since linelog has the new `getalllines` API, add a corresponding command
to support it.
Test Plan:
```
$ make && ./linelogcli /tmp/lll init annotate 0 replacelines 1 0:0 0:3 \
replacelines 2 1:2 1:3 getalllines 0:0
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:3
replacelines: rev 2, lines 1:2 -> 1:3
getalllines: 5 lines
0: rev 1, line 0, offset 3
1: rev 2, line 1, offset 8
2: rev 2, line 2, offset 9
3: rev 1, line 1, offset 11
4: rev 1, line 2, offset 5
```
Reviewers: #mercurial, simonfar, ttung
Reviewed By: simonfar
Subscribers: mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3716453
Signature: t1:3716453:1471265279:a8f625660ef47ca341ca8f5c4c7370b56277cef8
2016-08-15 14:47:14 +03:00
|
|
|
if (len == 1 ? name[0] == cmdtable[i].shortname
|
|
|
|
: strcmp(name, cmdtable[i].name) == 0)
|
linelogcli: a simple CLI tool for linelog
Summary:
The `linelogcli` tool exposes linelog APIs to command line:
- `linelogcli file init`: create a linelog file
- `linelogcli file annotate rev`: run annotate
- `linelogcli file replacelines rev a1:a2 b1:b2`: replace lines
- `linelogcli file info`: show maxrev and buffer size
- `linelogcli file dump`: dump human-readable instructions
It's designed for (fuzz) testing, memory leak checking. It's also
a basic tool for developers to investigate a linelog file.
It's not designed for end users and we will have a separate Python wrapper
implemented in Cython for mercurial integration. Therefore reviewers are
recommended to be less strict for this implementation.
Test Plan:
`make` and test some basic operations:
```
$ ./linelogcli /tmp/foo init annotate 0 replacelines 1 0:0 0:4 annotate - replacelines 2 1:2 10:13 annotate - replacelines 3 2:6 20:22 annotate - replacelines 4 0:4 30:31 annotate - annotate 2 info dump
init: okay
annotate: run annotate for rev 0
annotate: 0 lines, endoffset 1
replacelines: rev 1, lines 0:0 -> 0:4
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 1, ln 1, offset 4
2: rev 1, ln 2, offset 5
3: rev 1, ln 3, offset 6
replacelines: rev 2, lines 1:2 -> 10:13
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 10
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
replacelines: rev 3, lines 2:6 -> 20:22
annotate: 4 lines, endoffset 7
0: rev 1, ln 0, offset 3
1: rev 2, ln 10, offset 9
2: rev 3, ln 20, offset 16
3: rev 3, ln 21, offset 17
replacelines: rev 4, lines 0:4 -> 30:31
annotate: 1 lines, endoffset 7
0: rev 4, ln 30, offset 22
annotate: run annotate for rev 2
annotate: 6 lines, endoffset 7
0: rev 1, ln 0, offset 24
1: rev 2, ln 10, offset 9
2: rev 2, ln 11, offset 19
3: rev 2, ln 12, offset 11
4: rev 1, ln 2, offset 5
5: rev 1, ln 3, offset 6
info: maxrev = 4, size = 208
dump:
1: J 2
2: JL 1 7
3: J 21
4: J 8
5: LINE 1 2
6: LINE 1 3
7: END
8: JL 2 12
9: LINE 2 10
10: J 15
11: LINE 2 12
12: JGE 2 5
13: LINE 1 1
14: J 5
15: JL 3 18
16: LINE 3 20
17: LINE 3 21
18: JGE 3 7
19: LINE 2 11
20: J 11
21: JL 4 23
22: LINE 4 30
23: JGE 4 7
24: LINE 1 0
25: J 4
```
Also run with `valgrind --tool=memcheck --leak-check=yes` to make sure there is no memory leak.
Reviewers: #mercurial, simonfar
Reviewed By: simonfar
Subscribers: simonfar, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3645102
Signature: t1:3645102:1470335856:860a7dbb1781f6fe1e11e235ad163e2fbb6d45b2
2016-07-30 14:59:17 +03:00
|
|
|
return &cmdtable[i];
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *translateerror(linelog_result result) {
|
|
|
|
switch (result) {
|
|
|
|
case LINELOG_RESULT_ENOMEM:
|
|
|
|
return "NOMEM";
|
|
|
|
case LINELOG_RESULT_EILLDATA:
|
|
|
|
return "ILLDATA";
|
|
|
|
case LINELOG_RESULT_EOVERFLOW:
|
|
|
|
return "OVERFLOW";
|
|
|
|
}
|
|
|
|
return "(unknown)";
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char const *argv[]) {
|
|
|
|
if (argc < 3) {
|
|
|
|
puts(helptext);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
filename = argv[1];
|
|
|
|
openfile();
|
|
|
|
linelog_annotateresult_clear(&ar);
|
|
|
|
|
|
|
|
for (int i = 2; i < argc; i++) {
|
|
|
|
const cmdentry *cmd = findcmd(argv[i]);
|
|
|
|
if (!cmd) {
|
|
|
|
fprintf(stderr, "%s: unknown command\n", argv[i]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (argc - i - 1 < cmd->argcount) {
|
|
|
|
fprintf(stderr, "%s: missing argument\n", argv[i++]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
linelog_result r = cmd->func(argv + i + 1);
|
|
|
|
if (r != LINELOG_RESULT_OK)
|
|
|
|
fprintf(stderr, "%s: error %d (%s)\n",
|
|
|
|
cmd->name, (int)r, translateerror(r));
|
|
|
|
i += cmd->argcount;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* truncate the file to actual used size */
|
|
|
|
size_t size = linelog_getactualsize(&buf);
|
|
|
|
if (size && size != buf.size)
|
|
|
|
resizefile(size);
|
|
|
|
|
|
|
|
closefile();
|
|
|
|
linelog_annotateresult_clear(&ar);
|
|
|
|
return 0;
|
|
|
|
}
|