Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Pull the latest changes from trunk into windows-i18n. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | windows-i18n |
Files: | files | file ages | folders |
SHA1: |
f25b6c00c8c77799a687a9953034f1ff |
User & Date: | drh 2011-05-12 12:14:07.197 |
Context
2011-05-13
| ||
14:20 | Pull the latest changes in trunk over into the windows-i18n branch. ... (check-in: 70743eba user: drh tags: windows-i18n) | |
2011-05-12
| ||
12:14 | Pull the latest changes from trunk into windows-i18n. ... (check-in: f25b6c00 user: drh tags: windows-i18n) | |
12:13 | Back out the [ab934c6b09fd1d5] change. Do not change the console output mode using SetConsoleOutputCP(). Go back to converting UTF8 into MBCS upon output. ... (check-in: b33032ae user: drh tags: windows-i18n) | |
12:02 | Change fossil_malloc() so that it does not report "out of memory" when allocating zero bytes. ... (check-in: 6b382b08 user: drh tags: trunk) | |
Changes
Changes to src/descendants.c.
︙ | ︙ | |||
157 158 159 160 161 162 163 164 165 166 167 | /* ** Load the record ID rid and up to N-1 closest ancestors into ** the "ok" table. */ void compute_ancestors(int rid, int N){ Bag seen; PQueue queue; bag_init(&seen); pqueue_init(&queue); bag_insert(&seen, rid); pqueue_insert(&queue, rid, 0.0, 0); | > > < < | | | | | > > > > > | > > > > > > > > | > | < | > > | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | /* ** Load the record ID rid and up to N-1 closest ancestors into ** the "ok" table. */ void compute_ancestors(int rid, int N){ Bag seen; PQueue queue; Stmt ins; Stmt q; bag_init(&seen); pqueue_init(&queue); bag_insert(&seen, rid); pqueue_insert(&queue, rid, 0.0, 0); db_prepare(&ins, "INSERT OR IGNORE INTO ok VALUES(:rid)"); db_prepare(&q, "SELECT a.pid, b.mtime FROM plink a LEFT JOIN plink b ON b.cid=a.pid" " WHERE a.cid=:rid" ); while( (N--)>0 && (rid = pqueue_extract(&queue, 0))!=0 ){ db_bind_int(&ins, ":rid", rid); db_step(&ins); db_reset(&ins); db_bind_int(&q, ":rid", rid); while( db_step(&q)==SQLITE_ROW ){ int pid = db_column_int(&q, 0); double mtime = db_column_double(&q, 1); if( bag_insert(&seen, pid) ){ pqueue_insert(&queue, pid, -mtime, 0); } } db_reset(&q); } bag_clear(&seen); pqueue_clear(&queue); db_finalize(&ins); db_finalize(&q); } /* ** Load the record ID rid and up to N-1 closest descendants into ** the "ok" table. */ void compute_descendants(int rid, int N){ Bag seen; PQueue queue; Stmt ins; Stmt q; bag_init(&seen); pqueue_init(&queue); bag_insert(&seen, rid); pqueue_insert(&queue, rid, 0.0, 0); db_prepare(&ins, "INSERT OR IGNORE INTO ok VALUES(:rid)"); db_prepare(&q, "SELECT cid, mtime FROM plink WHERE pid=:rid"); while( (N--)>0 && (rid = pqueue_extract(&queue, 0))!=0 ){ db_bind_int(&ins, ":rid", rid); db_step(&ins); db_reset(&ins); db_bind_int(&q, ":rid", rid); while( db_step(&q)==SQLITE_ROW ){ int pid = db_column_int(&q, 0); double mtime = db_column_double(&q, 1); if( bag_insert(&seen, pid) ){ pqueue_insert(&queue, pid, mtime, 0); } } db_reset(&q); } bag_clear(&seen); pqueue_clear(&queue); db_finalize(&ins); db_finalize(&q); } /* ** COMMAND: descendants ** ** Usage: %fossil descendants ?BASELINE-ID? ** |
︙ | ︙ |
Changes to src/diff.c.
︙ | ︙ | |||
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 | for(i=0; i<x.nOrig; i++){ const char *zSrc = x.aOrig[i].zSrc; if( zSrc==0 ) zSrc = g.argv[g.argc-1]; fossil_print("%10s: %.*s\n", zSrc, x.aOrig[i].n, x.aOrig[i].z); } } /* ** Compute a complete annotation on a file. The file is identified ** by its filename number (filename.fnid) and the baseline in which ** it was checked in (mlink.mid). */ static void annotate_file( Annotator *p, /* The annotator */ int fnid, /* The name of the file to be annotated */ int mid, /* The specific version of the file for this step */ int webLabel, /* Use web-style annotations if true */ | > > > | > | > > | < > | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 | for(i=0; i<x.nOrig; i++){ const char *zSrc = x.aOrig[i].zSrc; if( zSrc==0 ) zSrc = g.argv[g.argc-1]; fossil_print("%10s: %.*s\n", zSrc, x.aOrig[i].n, x.aOrig[i].z); } } /* Annotation flags */ #define ANN_FILE_VERS 0x001 /* Show file version rather than commit version */ /* ** Compute a complete annotation on a file. The file is identified ** by its filename number (filename.fnid) and the baseline in which ** it was checked in (mlink.mid). */ static void annotate_file( Annotator *p, /* The annotator */ int fnid, /* The name of the file to be annotated */ int mid, /* The specific version of the file for this step */ int webLabel, /* Use web-style annotations if true */ int iLimit, /* Limit the number of levels if greater than zero */ int annFlags /* Flags to alter the annotation */ ){ Blob toAnnotate; /* Text of the final version of the file */ Blob step; /* Text of previous revision */ int rid; /* Artifact ID of the file being annotated */ char *zLabel; /* Label to apply to a line */ Stmt q; /* Query returning all ancestor versions */ /* Initialize the annotation */ rid = db_int(0, "SELECT fid FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid); if( rid==0 ){ fossil_panic("file #%d is unchanged in manifest #%d", fnid, mid); } if( !content_get(rid, &toAnnotate) ){ fossil_panic("unable to retrieve content of artifact #%d", rid); } db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)"); compute_ancestors(mid, 1000000000); annotation_start(p, &toAnnotate); db_prepare(&q, "SELECT mlink.fid," " (SELECT uuid FROM blob WHERE rid=mlink.%s)," " date(event.mtime), " " coalesce(event.euser,event.user) " " FROM mlink, event" " WHERE mlink.fnid=%d" " AND mlink.mid IN ok" " AND event.objid=mlink.mid" " ORDER BY event.mtime DESC" " LIMIT %d", (annFlags & ANN_FILE_VERS)!=0 ? "fid" : "mid", fnid, iLimit>0 ? iLimit : 10000000 ); while( db_step(&q)==SQLITE_ROW ){ int pid = db_column_int(&q, 0); const char *zUuid = db_column_text(&q, 1); const char *zDate = db_column_text(&q, 2); |
︙ | ︙ | |||
824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 | ** filename=FILENAME The filename. */ void annotation_page(void){ int mid; int fnid; int i; int iLimit; Annotator ann; login_check_credentials(); if( !g.okRead ){ login_needed(); return; } mid = name_to_rid(PD("checkin","0")); fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename")); if( mid==0 || fnid==0 ){ fossil_redirect_home(); } iLimit = atoi(PD("limit","-1")); if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ fossil_redirect_home(); } style_header("File Annotation"); | > > | | 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 | ** filename=FILENAME The filename. */ void annotation_page(void){ int mid; int fnid; int i; int iLimit; int annFlags = 0; Annotator ann; login_check_credentials(); if( !g.okRead ){ login_needed(); return; } mid = name_to_rid(PD("checkin","0")); fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename")); if( mid==0 || fnid==0 ){ fossil_redirect_home(); } iLimit = atoi(PD("limit","-1")); if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ fossil_redirect_home(); } style_header("File Annotation"); if( P("filevers") ) annFlags |= ANN_FILE_VERS; annotate_file(&ann, fnid, mid, g.okHistory, iLimit, annFlags); if( P("log") ){ int i; @ <h2>Versions analyzed:</h2> @ <ol> for(i=0; i<ann.nVers; i++){ @ <li><tt>%s(ann.azVers[i])</tt></li> } |
︙ | ︙ | |||
868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 | ** ** Output the text of a file with markings to show when each line of ** the file was last modified. ** ** Options: ** --limit N Only look backwards in time by N versions ** --log List all versions analyzed */ void annotate_cmd(void){ int fnid; /* Filename ID */ int fid; /* File instance ID */ int mid; /* Manifest where file was checked in */ Blob treename; /* FILENAME translated to canonical form */ char *zFilename; /* Cannonical filename */ Annotator ann; /* The annotation of the file */ int i; /* Loop counter */ const char *zLimit; /* The value to the --limit option */ int iLimit; /* How far back in time to look */ int showLog; /* True to show the log */ zLimit = find_option("limit",0,1); if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; iLimit = atoi(zLimit); showLog = find_option("log",0,0)!=0; db_must_be_within_tree(); if (g.argc<3) { usage("FILENAME"); } file_tree_name(g.argv[2], &treename, 1); zFilename = blob_str(&treename); fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); if( fnid==0 ){ fossil_fatal("no such file: %s", zFilename); } fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename); if( fid==0 ){ fossil_fatal("not part of current checkout: %s", zFilename); } mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid); if( mid==0 ){ fossil_panic("unable to find manifest"); } | > > > > > | | 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 | ** ** Output the text of a file with markings to show when each line of ** the file was last modified. ** ** Options: ** --limit N Only look backwards in time by N versions ** --log List all versions analyzed ** --filevers Show file version numbers rather than check-in versions */ void annotate_cmd(void){ int fnid; /* Filename ID */ int fid; /* File instance ID */ int mid; /* Manifest where file was checked in */ Blob treename; /* FILENAME translated to canonical form */ char *zFilename; /* Cannonical filename */ Annotator ann; /* The annotation of the file */ int i; /* Loop counter */ const char *zLimit; /* The value to the --limit option */ int iLimit; /* How far back in time to look */ int showLog; /* True to show the log */ int fileVers; /* Show file version instead of check-in versions */ int annFlags = 0; /* Flags to control annotation properties */ zLimit = find_option("limit",0,1); if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; iLimit = atoi(zLimit); showLog = find_option("log",0,0)!=0; fileVers = find_option("filevers",0,0)!=0; db_must_be_within_tree(); if (g.argc<3) { usage("FILENAME"); } file_tree_name(g.argv[2], &treename, 1); zFilename = blob_str(&treename); fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); if( fnid==0 ){ fossil_fatal("no such file: %s", zFilename); } fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename); if( fid==0 ){ fossil_fatal("not part of current checkout: %s", zFilename); } mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid); if( mid==0 ){ fossil_panic("unable to find manifest"); } if( fileVers ) annFlags |= ANN_FILE_VERS; annotate_file(&ann, fnid, mid, 0, iLimit, annFlags); if( showLog ){ for(i=0; i<ann.nVers; i++){ printf("version %3d: %s\n", i+1, ann.azVers[i]); } printf("---------------------------------------------------\n"); } for(i=0; i<ann.nOrig; i++){ fossil_print("%s: %.*s\n", ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z); } } |
Changes to src/finfo.c.
︙ | ︙ | |||
184 185 186 187 188 189 190 | } /* ** WEBPAGE: finfo ** URL: /finfo?name=FILENAME ** | | > > > > > > > > > > | > | < > > > > > > > > > > > > | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | } /* ** WEBPAGE: finfo ** URL: /finfo?name=FILENAME ** ** Show the change history for a single file. ** ** Additional query parameters: ** ** a=DATE Only show changes after DATE ** b=DATE Only show changes before DATE ** n=NUM Show the first NUM changes only */ void finfo_page(void){ Stmt q; const char *zFilename; char zPrevDate[20]; const char *zA; const char *zB; int n; Blob title; Blob sql; GraphContext *pGraph; login_check_credentials(); if( !g.okRead ){ login_needed(); return; } style_header("File History"); login_anonymous_available(); zPrevDate[0] = 0; zFilename = PD("name",""); blob_zero(&sql); blob_appendf(&sql, "SELECT" " datetime(event.mtime,'localtime')," /* Date of change */ " coalesce(event.ecomment, event.comment)," /* Check-in comment */ " coalesce(event.euser, event.user)," /* User who made chng */ " mlink.pid," /* Parent rid */ " mlink.fid," /* File rid */ " (SELECT uuid FROM blob WHERE rid=mlink.pid)," /* Parent file uuid */ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */ " (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */ " event.bgcolor," /* Background color */ " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0" " AND tagxref.rid=mlink.mid)" /* Tags */ " FROM mlink, event" " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)" " AND event.objid=mlink.mid", TAG_BRANCH, zFilename ); if( (zA = P("a"))!=0 ){ blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA); } if( (zB = P("b"))!=0 ){ blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zB); } blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/"); if( (n = atoi(PD("n","0")))>0 ){ blob_appendf(&sql, " LIMIT %d", n); } db_prepare(&q, blob_str(&sql)); blob_reset(&sql); blob_zero(&title); blob_appendf(&title, "History of "); hyperlinked_path(zFilename, &title, 0); @ <h2>%b(&title)</h2> blob_reset(&title); pGraph = graph_init(); @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div> |
︙ | ︙ | |||
244 245 246 247 248 249 250 | const char *zBgClr = db_column_text(&q, 8); const char *zBr = db_column_text(&q, 9); int gidx; char zTime[10]; char zShort[20]; char zShortCkin[20]; if( zBr==0 ) zBr = "trunk"; | | | 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | const char *zBgClr = db_column_text(&q, 8); const char *zBr = db_column_text(&q, 9); int gidx; char zTime[10]; char zShort[20]; char zShortCkin[20]; if( zBr==0 ) zBr = "trunk"; gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr, 0); if( memcmp(zDate, zPrevDate, 10) ){ sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); @ <tr><td> @ <div class="divider">%s(zPrevDate)</div> @ </td></tr> } memcpy(zTime, &zDate[11], 5); |
︙ | ︙ | |||
289 290 291 292 293 294 295 | @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&filename=%h(z)"> @ [annotate]</a> } @ </td></tr> } db_finalize(&q); if( pGraph ){ | | > | | | 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&filename=%h(z)"> @ [annotate]</a> } @ </td></tr> } db_finalize(&q); if( pGraph ){ graph_finish(pGraph, 0); if( pGraph->nErr ){ graph_free(pGraph); pGraph = 0; }else{ @ <tr><td></td><td> @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div> @ </td></tr> } } @ </table> timeline_output_graph_javascript(pGraph, 0); style_footer(); } |
Changes to src/graph.c.
︙ | ︙ | |||
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | pLoop->railInUse |= mask; } } } pChild->mergeIn[pParent->mergeOut/4] = (pParent->mergeOut&3)+1; } /* ** Compute the complete graph */ void graph_finish(GraphContext *p, int omitDescenders){ GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent; int i; u32 mask; u32 inUse; | > > > > > > > > > > > > > > > | | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | pLoop->railInUse |= mask; } } } pChild->mergeIn[pParent->mergeOut/4] = (pParent->mergeOut&3)+1; } /* ** Compute the maximum rail number. */ static void find_max_rail(GraphContext *p){ GraphRow *pRow; p->mxRail = 0; for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ if( pRow->iRail>p->mxRail ) p->mxRail = pRow->iRail; if( pRow->mergeOut/4>p->mxRail ) p->mxRail = pRow->mergeOut/4; while( p->mxRail<GR_MAX_RAIL && pRow->mergeDown>((1<<(p->mxRail+1))-1) ){ p->mxRail++; } } } /* ** Compute the complete graph */ void graph_finish(GraphContext *p, int omitDescenders){ GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent; int i; u32 mask; u32 inUse; int hasDup = 0; /* True if one or more isDup entries */ const char *zTrunk; if( p==0 || p->pFirst==0 || p->nErr ) return; p->nErr = 1; /* Assume an error until proven otherwise */ /* Initialize all rows */ p->nHash = p->nRow*2 + 1; |
︙ | ︙ | |||
388 389 390 391 392 393 394 395 396 397 398 399 400 401 | ** each to a rail and draw descenders to the bottom of the screen. ** ** Strive to put the "trunk" branch on far left. */ zTrunk = persistBranchName(p, "trunk"); for(i=0; i<2; i++){ for(pRow=p->pLast; pRow; pRow=pRow->pPrev){ if( i==0 ){ if( pRow->zBranch!=zTrunk ) continue; }else { if( pRow->iRail>=0 ) continue; } if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){ if( omitDescenders ){ | > | 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | ** each to a rail and draw descenders to the bottom of the screen. ** ** Strive to put the "trunk" branch on far left. */ zTrunk = persistBranchName(p, "trunk"); for(i=0; i<2; i++){ for(pRow=p->pLast; pRow; pRow=pRow->pPrev){ if( pRow->isDup ) continue; if( i==0 ){ if( pRow->zBranch!=zTrunk ) continue; }else { if( pRow->iRail>=0 ) continue; } if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){ if( omitDescenders ){ |
︙ | ︙ | |||
433 434 435 436 437 438 439 | pLoop->railInUse |= mask; } } } continue; } if( pRow->isDup ){ | < < < | | 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 | pLoop->railInUse |= mask; } } } continue; } if( pRow->isDup ){ continue; }else{ assert( pRow->nParent>0 ); parentRid = pRow->aParent[0]; pParent = hashFind(p, parentRid); if( pParent==0 ){ pRow->iRail = ++p->mxRail; if( p->mxRail>=GR_MAX_RAIL ) return; |
︙ | ︙ | |||
513 514 515 516 517 518 519 520 521 522 523 524 525 | } } /* ** Insert merge rails from primaries to duplicates. */ if( hasDup ){ for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ if( !pRow->isDup ) continue; pDesc = hashFind(p, pRow->rid); assert( pDesc!=0 && pDesc!=pRow ); createMergeRiser(p, pDesc, pRow); } | > > > > > > > > > > > > > > | < < < < < | < < | 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | } } /* ** Insert merge rails from primaries to duplicates. */ if( hasDup ){ int dupRail; int mxRail; find_max_rail(p); mxRail = p->mxRail; dupRail = mxRail+1; if( p->mxRail>=GR_MAX_RAIL ) return; for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ if( !pRow->isDup ) continue; pRow->iRail = dupRail; pDesc = hashFind(p, pRow->rid); assert( pDesc!=0 && pDesc!=pRow ); createMergeRiser(p, pDesc, pRow); if( pDesc->mergeOut/4>mxRail ) mxRail = pDesc->mergeOut/4; } if( dupRail<=mxRail ){ dupRail = mxRail+1; for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ if( pRow->isDup ) pRow->iRail = dupRail; } } if( mxRail>=GR_MAX_RAIL ) return; } /* ** Find the maximum rail number. */ find_max_rail(p); p->nErr = 0; } |
Changes to src/main.c.
︙ | ︙ | |||
405 406 407 408 409 410 411 | } } /* ** Malloc and free routines that cannot fail */ void *fossil_malloc(size_t n){ | | | 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 | } } /* ** Malloc and free routines that cannot fail */ void *fossil_malloc(size_t n){ void *p = malloc(n==0 ? 1 : n); if( p==0 ) fossil_panic("out of memory"); return p; } void fossil_free(void *p){ free(p); } void *fossil_realloc(void *p, size_t n){ |
︙ | ︙ |