Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/pakPublic

Commitab497a7

Browse files
committed
Update embedded pkgcache
1 parent72ab88b commitab497a7

File tree

4 files changed

+127
-18
lines changed

4 files changed

+127
-18
lines changed

‎src/library/pkgcache/DESCRIPTION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Language: en-US
2727
Roxygen: list(markdown = TRUE, r6 = FALSE)
2828
RoxygenNote: 7.3.2.9000
2929
NeedsCompilation: yes
30-
Packaged: 2025-06-0409:25:33 UTC; gaborcsardi
30+
Packaged: 2025-11-0411:20:14 UTC; gaborcsardi
3131
Author: Gábor Csárdi [aut, cre],
3232
Posit Software, PBC [cph, fnd] (ROR: <https://ror.org/03wc8by49>)
3333
Maintainer: Gábor Csárdi <csardi.gabor@gmail.com>

‎src/library/pkgcache/NEWS.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
#pkgcache (development version)
22

3+
* pkgcache now supports comments in`DESCRIPTION` and`PACKAGES` files.
4+
Current R-devel supports this since
5+
https://github.com/wch/r-source/commit/92d9660517ceae66d422a510dc58e0840d55cdfc.
6+
Comments are lines that start with a hash (`#`), without leading
7+
whitespace. Comments within values are also supported (#130).
8+
39
#pkgcache 2.2.4
410

511
*`parse_packages()` now parses files ending with an extra newline

‎src/library/pkgcache/R/compat-vctrs.R‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# nocov start
2+
13
compat_vctrs<- local({
24
# Modified from https://github.com/r-lib/rlang/blob/master/R/compat-vctrs.R
35

‎src/library/pkgcache/src/lib.c‎

Lines changed: 118 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,30 @@ SEXP pkgcache_read_raw(SEXP paths) {
160160
returnresult;
161161
}
162162

163+
// `vlsize` is the total size of the value, without the trailing NL
164+
// `comment_size` is the total size of comment lines, including trailing NL
165+
staticSEXPcreate_value(char*vl,intvlsize,intcomment_size) {
166+
SEXPval=Rf_mkCharLenCE(vl,vlsize-comment_size,CE_BYTES);
167+
if (comment_size==0)returnval;
168+
169+
char*src=vl,*tgt= (char*)CHAR(val),*end=tgt+vlsize-comment_size;
170+
171+
// the value cannot start with a comment, comments begin at column zero
172+
while (tgt<end) {
173+
if (*src=='\n'&&*(src+1)=='#') {
174+
src++;
175+
while (*src!='\n')src++;
176+
// do not skip the last newline, we'll copy this over in the next
177+
// iteration, if any, if the next line is not a comment
178+
}else {
179+
*tgt=*src;
180+
tgt++;
181+
src++;
182+
}
183+
}
184+
returnval;
185+
}
186+
163187
/* --------------------------------------------------------------------- */
164188

165189
#defineS_BG 0/* beginning of the file */
@@ -175,6 +199,8 @@ SEXP pkgcache_parse_description_raw(SEXP raw) {
175199
char*kw=NULL,*vl=NULL;
176200
intkwsize=0,vlsize=0;
177201
intlinum=1;
202+
intcomment_size=0;
203+
inttail_comment=0;
178204

179205
SEXPresult=PROTECT(allocVector(STRSXP,200));
180206
SEXPnames=PROTECT(allocVector(STRSXP,200));
@@ -185,6 +211,16 @@ SEXP pkgcache_parse_description_raw(SEXP raw) {
185211

186212
/* -- at the begining ---------------------------------------------- */
187213
caseS_BG:
214+
/* skip comments and whitespace */
215+
while (*p=='#'||isspace(*p)) {
216+
if (*p=='\n')linum++;
217+
if (*p=='#') {
218+
while (*p!='\n'&&*p!='\0')p++;
219+
linum++;
220+
}
221+
if (*p!='\0')p++;
222+
}
223+
188224
if (*p==':'||*p=='\r'||*p=='\n'||*p==' '||*p=='\t') {
189225
R_THROW_ERROR(
190226
"Invalid DESCRIPTION file, must start with an "
@@ -223,6 +259,7 @@ SEXP pkgcache_parse_description_raw(SEXP raw) {
223259

224260
/* --- within a value ---------------------------------------------- */
225261
caseS_VL:
262+
tail_comment=0;
226263
/* newline might be the end of the value, if no continuation. */
227264
if (*p=='\n') {
228265
state=S_NL;
@@ -237,15 +274,27 @@ SEXP pkgcache_parse_description_raw(SEXP raw) {
237274

238275
/* -- right after a newline ---------------------------------------- */
239276
caseS_NL:
277+
/* comment line? */
278+
if (*p=='#') {
279+
tail_comment=1;
280+
char*cs=p;
281+
while (*p!='\n'&&*p!='\0')p++;
282+
// vlsize does not include trailing newlines
283+
vlsize=p-vl;
284+
if (*p!='\0')p++;
285+
// comment_size does include trailing newlines
286+
comment_size+= (p-cs);
287+
240288
/* maybe a continuation line */
241-
if (*p==' '||*p=='\t') {
289+
}elseif (*p==' '||*p=='\t') {
242290
state=S_WS;
243291
p++;
244292

245293
/* othewise we can save the field, and start parsing the next one */
246294
}else {
247-
SET_STRING_ELT(result,ridx,Rf_mkCharLenCE(vl,vlsize,CE_BYTES));
295+
SET_STRING_ELT(result,ridx,create_value(vl,vlsize,comment_size));
248296
SET_STRING_ELT(names,ridx,Rf_mkCharLenCE(kw,kwsize,CE_NATIVE));
297+
comment_size=0;
249298
ridx++;
250299
kw=p;
251300
state=S_KW;
@@ -277,10 +326,11 @@ SEXP pkgcache_parse_description_raw(SEXP raw) {
277326
if (state==S_KW) {
278327
R_THROW_ERROR("DESCRIPTION file ended while parsing a key");
279328
}elseif (state!=S_BG) {
280-
/* Strip the trailing newline(s) */
281-
while (p-1>start&&*(p-1)=='\n')p--;
329+
if (tail_comment)p--;
330+
/* Strip the trailing newline(s), need to ignore the last comment(s) */
331+
while (p-1>start&&*(p-1)=='\n')p--;
282332
vlsize=p-vl;
283-
SET_STRING_ELT(result,ridx,Rf_mkCharLenCE(vl,vlsize,CE_BYTES));
333+
SET_STRING_ELT(result,ridx,create_value(vl,vlsize,comment_size));
284334
SET_STRING_ELT(names,ridx,Rf_mkCharLenCE(kw,kwsize,CE_NATIVE));
285335
ridx++;
286336
}
@@ -321,14 +371,19 @@ SEXP pkgcache_parse_packages_raw(SEXP raw) {
321371
chartail=p[len-1];
322372
p[len-1]='\0';
323373

324-
/* Skip whitespace first, check for empty file */
374+
/* Skip comments and whitespace */
375+
while (*p=='#'||isspace(*p)) {
376+
if (*p=='#')while (*p!='\n'&&*p!='\0')p++;
377+
if (*p!='\0')p++;
378+
}
379+
constchar*begin=p;
325380

326-
while (*p=='\n'||*p=='\r')p++;
381+
/* Check for empty file.*/
327382
if (*p=='\0')returnR_NilValue;
328383

329-
/* This is faster than manual search, because strchr is optimized.
330-
It is also faster than strstr, for this special case of a two
331-
character pattern. */
384+
/*Count the number of packages.This is faster than manual search,
385+
because strchr is optimized.It is also faster than strstr, for this
386+
special case of a twocharacter pattern. */
332387

333388
for (;;) {
334389
p=strchr(p,'\n');
@@ -348,6 +403,8 @@ SEXP pkgcache_parse_packages_raw(SEXP raw) {
348403
char*kw=NULL,*vl=NULL;
349404
intkwsize=0,vlsize=0;
350405
intlinum=1;
406+
intcomment_size=0;
407+
inttail_comment=0;
351408
intmax_cols=1000;
352409

353410
SEXPnms=PROTECT(allocVector(STRSXP,max_cols));
@@ -357,7 +414,7 @@ SEXP pkgcache_parse_packages_raw(SEXP raw) {
357414
hash_create(&table,nms,cols,tab,max_cols,npkgs);
358415
intnpkg=0;
359416

360-
p= (char*)RAW(raw);
417+
p= (char*)begin;
361418
while (*p!='\0') {
362419
switch (state) {
363420

@@ -402,6 +459,7 @@ SEXP pkgcache_parse_packages_raw(SEXP raw) {
402459

403460
/* --- within a value ---------------------------------------------- */
404461
caseS_VL:
462+
tail_comment=0;
405463
/* newline might be the end of the value, if no continuation. */
406464
if (*p=='\n') {
407465
state=S_NL;
@@ -416,16 +474,27 @@ SEXP pkgcache_parse_packages_raw(SEXP raw) {
416474

417475
/* -- right after a newline ---------------------------------------- */
418476
caseS_NL:
477+
/* comment line, ignore */
478+
if (*p=='#') {
479+
tail_comment=1;
480+
char*cs=p;
481+
while (*p!='\n'&&*p!='\0')p++;
482+
// vlsize does not include trailing newlines
483+
vlsize=p-vl;
484+
if (*p!='\0')p++;
485+
// comment_size does include trailing newlines
486+
comment_size+= (p-cs);
419487

420488
/* maybe a continuation line */
421-
if (*p==' '||*p=='\t') {
489+
}elseif (*p==' '||*p=='\t') {
422490
state=S_WS;
423491
p++;
424492

425493
/* end of field */
426494
}else {
427495
/* Save field */
428-
SEXPval=PROTECT(mkCharLenCE(vl,vlsize,CE_BYTES));
496+
SEXPval=PROTECT(create_value(vl,vlsize,comment_size));
497+
comment_size=0;
429498
hash_update(&table,kw,kwsize,npkg,val,/* err */1);
430499
UNPROTECT(1);
431500

@@ -484,6 +553,8 @@ SEXP pkgcache_parse_packages_raw(SEXP raw) {
484553
vlsize=p-vl;
485554
p= (char*)RAW(raw);
486555
p[len-1]=tail;
556+
/* if ended with a comment, then need to drop last \n */
557+
if (tail_comment)tail='\n';
487558
if (state==S_VL&&tail!='\n')vlsize++;
488559
/* if the tail is a \n, we don't need that. We also drop \r, which
489560
is possibly not correct, but in practice better */
@@ -493,7 +564,7 @@ SEXP pkgcache_parse_packages_raw(SEXP raw) {
493564
R_THROW_ERROR("PACKAGES file ended while parsing a key");
494565
}elseif (state!=S_BG) {
495566
/* Save field */
496-
SEXPval=PROTECT(mkCharLenCE(vl,vlsize,CE_BYTES));
567+
SEXPval=PROTECT(create_value(vl,vlsize,comment_size));
497568
hash_update(&table,kw,kwsize,npkg,val,/* err= */1);
498569
UNPROTECT(1);
499570
}
@@ -543,6 +614,8 @@ SEXP pkgcache_parse_descriptions(SEXP paths, SEXP lowercase) {
543614
kwsize=0;
544615
vlsize=0;
545616
linum=1;
617+
intcomment_size=0;
618+
inttail_comment=0;
546619

547620
intlen=LENGTH(raw);
548621
char*p= (char*)RAW(raw);
@@ -553,6 +626,16 @@ SEXP pkgcache_parse_descriptions(SEXP paths, SEXP lowercase) {
553626
switch(state) {
554627
/* -- at the begining -------------------------------------------- */
555628
caseS_BG:
629+
/* skip comments and whitespace */
630+
while (*p=='#'||isspace(*p)) {
631+
if (*p=='\n')linum++;
632+
if (*p=='#') {
633+
while (*p!='\n'&&*p!='\0')p++;
634+
linum++;
635+
}
636+
if (*p!='\0')p++;
637+
}
638+
556639
if (*p==':'||*p=='\r'||*p=='\n'||*p==' '||*p=='\t') {
557640
SET_STRING_ELT(
558641
errors,
@@ -606,6 +689,7 @@ SEXP pkgcache_parse_descriptions(SEXP paths, SEXP lowercase) {
606689

607690
/* --- within a value -------------------------------------------- */
608691
caseS_VL:
692+
tail_comment=0;
609693
if (*p=='\n') {
610694
state=S_NL;
611695
vlsize=p-vl;
@@ -620,14 +704,26 @@ SEXP pkgcache_parse_descriptions(SEXP paths, SEXP lowercase) {
620704

621705
/* -- right after a newline -------------------------------------- */
622706
caseS_NL:
707+
/* comment line? */
708+
if (*p=='#') {
709+
tail_comment=1;
710+
char*cs=p;
711+
while (*p!='\n'&&*p!='\0')p++;
712+
// vlsize does not include trailing newlines
713+
vlsize=p-vl;
714+
if (*p!='\0')p++;
715+
// comment_size does include trailing newlines
716+
comment_size+= (p-cs);
717+
623718
/* maybe a continuation line */
624-
if (*p==' '||*p=='\t') {
719+
}elseif (*p==' '||*p=='\t') {
625720
state=S_WS;
626721
p++;
627722

628723
/* othewise we can save the field, and start parsing the next one */
629724
}else {
630-
SEXPval=PROTECT(mkCharLenCE(vl,vlsize,CE_BYTES));
725+
SEXPval=PROTECT(create_value(vl,vlsize,comment_size));
726+
comment_size=0;
631727
hash_update(&table,kw,kwsize,npkg,val,1);
632728
UNPROTECT(1);
633729

@@ -663,7 +759,12 @@ SEXP pkgcache_parse_descriptions(SEXP paths, SEXP lowercase) {
663759
vlsize=p-vl;
664760
p= (char*)RAW(raw);
665761
p[len-1]=tail;
762+
/* if ended with a comment, then need to drop last \n */
763+
if (tail_comment)tail='\n';
666764
if (state==S_VL&&tail!='\n')vlsize++;
765+
/* if the tail is a \n, we don't need that. We also drop \r, which
766+
is possibly not correct, but in practice better */
767+
if (state==S_NL&& (tail=='\n'||tail=='\r'))vlsize--;
667768

668769
if (state==S_KW) {
669770
SET_STRING_ELT(
@@ -679,7 +780,7 @@ SEXP pkgcache_parse_descriptions(SEXP paths, SEXP lowercase) {
679780

680781
}else {
681782
/* Save field */
682-
SEXPval=PROTECT(mkCharLenCE(vl,vlsize,CE_BYTES));
783+
SEXPval=PROTECT(create_value(vl,vlsize,comment_size));
683784
hash_update(&table,kw,kwsize,npkg,val,/* err = */1);
684785
UNPROTECT(1);
685786
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp