|
|
1.1 ! root 1: /* ! 2: * req2.c ! 3: * Nroff/Troff. ! 4: * Requests (n-z). ! 5: */ ! 6: ! 7: #include <ctype.h> ! 8: #include "roff.h" ! 9: ! 10: #define A_BEL 0x07 /* Bell */ ! 11: #define A_DEL 0x7F /* Delete */ ! 12: ! 13: /* ! 14: * Turn adjust mode off. ! 15: */ ! 16: req_na() ! 17: { ! 18: adm = 0; ! 19: } ! 20: ! 21: /* ! 22: * Overstrike bold off. ! 23: * !V7. ! 24: */ ! 25: req_nb() ! 26: { ! 27: enb = 0; ! 28: } ! 29: ! 30: /* ! 31: * Need. ! 32: */ ! 33: req_ne(argc, argv) int argc; char *argv[]; ! 34: { ! 35: register int need, ! 36: have; ! 37: ! 38: need = number(argv[1], SMVLSP, SDVLSP, 0, 1, unit(SMVLSP, SDVLSP)); ! 39: if (cdivp->d_ctpp) { ! 40: have = cdivp->d_ctpp->t_apos; ! 41: if (have > pgl) ! 42: have = pgl; ! 43: } else ! 44: have = pgl; ! 45: have -= cdivp->d_rpos; ! 46: if (have >= need || nsm != 0) ! 47: return; ! 48: setbreak(); ! 49: sspace(have); ! 50: } ! 51: ! 52: /* ! 53: * Go into no fill mode. ! 54: */ ! 55: req_nf() ! 56: { ! 57: setbreak(); ! 58: fill = 0; ! 59: } ! 60: ! 61: /* ! 62: * Turn off hyphenation. ! 63: */ ! 64: req_nh() ! 65: { ! 66: hyp = 0; /* turn the durn thing off */ ! 67: } ! 68: ! 69: /* ! 70: * Set number mode. (.nm) $$TO_DO$$ ! 71: */ ! 72: req_nm(argc, argv) int argc; char *argv[]; ! 73: { ! 74: #if 1 ! 75: printu(".nm"); ! 76: #else ! 77: long smdigw, sddigw; ! 78: ! 79: smdigw = width('0') * swddiv; ! 80: sddigw = swddiv; ! 81: if ((lnn=number(argv[1], SMUNIT, SDUNIT, lnn, 0, 0)) <= 0) { ! 82: lnn = 0; ! 83: return; ! 84: } ! 85: if (argv[2][0] != '\0') ! 86: lnm = number(argv[2], SMUNIT, SDUNIT, 0, 0, 1); ! 87: if (argv[3][0] != '\0') ! 88: lns = number(argv[3], smdigw, sddigw, 0, 0, unit(smdigw, sddigw)); ! 89: if (argv[4][0] != '\0') ! 90: lni = number(argv[4], smdigw, sddigw, 0, 0, unit(smdigw, sddigw); ! 91: #endif ! 92: } ! 93: ! 94: /* ! 95: * Turn off line number mode for n lines. (.nn) $$TO_DO$$ ! 96: */ ! 97: req_nn(argc, argv) int argc; char *argv[]; ! 98: { ! 99: #if 1 ! 100: printu(".nn"); ! 101: #else ! 102: register int n; ! 103: ! 104: lnc = number(argv[1], SMUNIT, SDUNIT, 0, 0, 1); ! 105: #endif ! 106: } ! 107: ! 108: /* ! 109: * Define a number register. ! 110: */ ! 111: req_nr(argc, argv) int argc; char *argv[]; ! 112: { ! 113: register REG *rp; ! 114: char name[2]; ! 115: ! 116: argname(argv[1], name); ! 117: #if 0 ! 118: rp = getnreg(name, RNUMR); /* too many paramters! */ ! 119: #else ! 120: rp = getnreg(name); ! 121: #endif ! 122: rp->n_reg.r_nval = number(argv[2], SMUNIT, SDUNIT, rp->n_reg.r_nval, 0, 0); ! 123: if (argc >= 4) ! 124: rp->n_reg.r_incr = numb(argv[3], SMUNIT, SDUNIT); ! 125: if (rp == nrpnreg) ! 126: npn = pno + 1; ! 127: } ! 128: ! 129: /* ! 130: * Turn no-space mode on. ! 131: */ ! 132: req_ns() ! 133: { ! 134: nsm = 1; ! 135: } ! 136: ! 137: /* ! 138: * End input from current file and switch to given file. ! 139: */ ! 140: req_nx(argc, argv) int argc; char *argv[]; ! 141: { ! 142: register FILE *fp; ! 143: register STR *sp; ! 144: ! 145: sp = strp; ! 146: do { ! 147: if (sp == NULL) { ! 148: printe("cannot find current file"); ! 149: return; ! 150: } ! 151: } while (sp->x2.s_type != SFILE); ! 152: if ((fp = fopen(argv[1], "r")) == NULL) { ! 153: printe("cannot open %s", argv[1]); ! 154: return; ! 155: } ! 156: fclose(sp->x2.s_fp); ! 157: sp->x2.s_fp = fp; ! 158: nfree(sp->x2.s_fname); ! 159: sp->x2.s_fname = duplstr(argv[1]); ! 160: sp->x2.s_clnc = 1; ! 161: sp->x2.s_nlnc = 1; ! 162: } ! 163: ! 164: /* ! 165: * Output saved space. ! 166: */ ! 167: req_os() ! 168: { ! 169: sspace(svs); ! 170: } ! 171: ! 172: /* ! 173: * Set page number character in title. ! 174: */ ! 175: req_pc(argc, argv) int argc; char *argv[]; ! 176: { ! 177: tpc = argv[1][0]; ! 178: } ! 179: ! 180: /* ! 181: * Pipe nroff output. (.pi) $$TO_DO$$ ! 182: */ ! 183: req_pi(argc, argv) int argc; char *argv[]; ! 184: { ! 185: printu(".pi"); ! 186: } ! 187: ! 188: /* ! 189: * Set page length. ! 190: */ ! 191: req_pl(argc, argv) int argc; char *argv[]; ! 192: { ! 193: pgl = number(argv[1], SMVLSP, SDVLSP, pgl, 0, unit(11*SMINCH, SDINCH)); ! 194: if (pgl == 0) ! 195: pgl = unit(SMVLSP, SDVLSP); ! 196: } ! 197: ! 198: /* ! 199: * Print sizes of macros. ! 200: */ ! 201: req_pm(argc, argv) int argc; char *argv[]; ! 202: { ! 203: register REG **rpp, ! 204: *rp; ! 205: unsigned rnum, /* number of registers */ ! 206: mnum, /* number of macros */ ! 207: csize; /* total space */ ! 208: int vflag; ! 209: ! 210: vflag = (argv[1][0] == '\0'); ! 211: if (vflag) ! 212: fprintf(stderr, "Macro and register sizes:\n"); ! 213: else ! 214: fprintf(stderr, "Macro and register size: "); ! 215: rnum = mnum = 0; ! 216: csize = 0; ! 217: for (rpp = ®t[0]; rpp < ®t[RHTSIZE]; rpp++) { ! 218: for (rp = *rpp; rp; rp = rp->t_reg.r_next) ! 219: switch (rp->t_reg.r_type) { ! 220: case RNUMR: ! 221: ++rnum; ! 222: if (vflag) ! 223: printnr(rp); ! 224: csize += sizeof(*rp); ! 225: break; ! 226: case RTEXT: ! 227: ++mnum; ! 228: csize += sizeof(*rp) - sizeof(rp->t_reg.r_macd); ! 229: csize += printm(rp, vflag); ! 230: break; ! 231: default: ! 232: panic("unknown macro/register type %d", ! 233: rp->t_reg.r_type); ! 234: } ! 235: } ! 236: fprintf(stderr, "%u registers, %u macros, %u bytes\n", ! 237: rnum, mnum, csize); ! 238: } ! 239: ! 240: /* ! 241: * Printnr prints out the size and name of a number register. ! 242: */ ! 243: printnr(rp) ! 244: register REG *rp; ! 245: { ! 246: fprintf(stderr, "Register %.2s %u bytes\n", rp->t_reg.r_name, ! 247: sizeof(*rp)); ! 248: } ! 249: ! 250: /* ! 251: * Printm returns the size of a macro and prints out its name if vflag. ! 252: */ ! 253: printm(rp, vflag) ! 254: register REG *rp; ! 255: int vflag; ! 256: { ! 257: register MAC *mp; ! 258: unsigned size; ! 259: int type; ! 260: static char *tn[] = { "Macro/String", "Diversion" }; ! 261: ! 262: size = 0; ! 263: mp = &rp->t_reg.r_macd; ! 264: type = mp->t_div.m_type; ! 265: if (type != MTEXT && type != MDIVN) ! 266: return (size); ! 267: fprintf(stderr, "%s %.2s", tn[type], rp->t_reg.r_name); ! 268: for (;;) { ! 269: size += sizeof(*mp); ! 270: mp = mp->t_div.m_next; ! 271: if (mp == NULL) ! 272: break; ! 273: if (mp->t_div.m_type != type) ! 274: fprintf(stderr, " (changed to %s)", ! 275: tn[mp->t_div.m_type]); ! 276: } ! 277: if (vflag) ! 278: fprintf(stderr, " uses %u bytes\n", size); ! 279: return (size); ! 280: } ! 281: ! 282: ! 283: /* ! 284: * Set page number. ! 285: */ ! 286: req_pn(argc, argv) int argc; char *argv[]; ! 287: { ! 288: if (argc >= 2) { ! 289: pno = number(argv[1], SMUNIT, SDUNIT, pno, 0, pno); ! 290: npn = pno + 1; ! 291: } ! 292: } ! 293: ! 294: /* ! 295: * Set page offset. ! 296: */ ! 297: req_po(argc, argv) int argc; char *argv[]; ! 298: { ! 299: setval(&pof, &oldpof, argv[1], SMEMSP, SDEMSP); ! 300: } ! 301: ! 302: /* ! 303: * Set pointsize. ! 304: */ ! 305: req_ps(argc, argv) int argc; char *argv[]; ! 306: { ! 307: register int n; ! 308: ! 309: n = number(argv[1], SMPOIN, SDPOIN, psz, 0, oldpsz); ! 310: newpsze(n); ! 311: } ! 312: ! 313: /* ! 314: * Copy a file verbatim to output. ! 315: * !V7. ! 316: */ ! 317: req_rb(argc, argv) int argc; char *argv[]; ! 318: { ! 319: setbreak(); ! 320: if (argc < 2) ! 321: printe(".rb: no file specified"); ! 322: else if (copy_file(argv[1]) == 0) ! 323: printe(".rb: cannot open file %s", argv[1]); ! 324: } ! 325: ! 326: /* ! 327: * Read an insertion from the standard input. ! 328: */ ! 329: req_rd(argc, argv) int argc; char *argv[]; ! 330: { ! 331: if (argc >= 2) ! 332: fprintf(stderr, "%s", argv[1]); ! 333: else ! 334: putc(A_BEL, stderr); ! 335: allstr(SSINP); ! 336: } ! 337: ! 338: /* ! 339: * Assign a named font to another name. ! 340: * !V7. ! 341: */ ! 342: req_rf(argc, argv) int argc; char *argv[]; ! 343: { ! 344: register int n; ! 345: ! 346: if (argc < 2) { ! 347: printe(".rf: requires name and new name"); ! 348: return; ! 349: } ! 350: if ((n = font_number(argv[1], ".rf: ")) >= 0) ! 351: assign_font(argv[2], n); ! 352: } ! 353: ! 354: /* ! 355: * Remove text register or request. ! 356: */ ! 357: req_rm(argc, argv) int argc; char *argv[]; ! 358: { ! 359: char name[2]; ! 360: register int i; ! 361: ! 362: for (i=1; i<argc; i++) { ! 363: argname(argv[i], name); ! 364: if (reltreg(name)) ! 365: continue; ! 366: printe("cannot remove %s", argv[i]); ! 367: } ! 368: } ! 369: ! 370: /* ! 371: * Rename the given request or macro. ! 372: * Lookup is hashed, so just changing the name field does not work. ! 373: */ ! 374: req_rn(argc, argv) int argc; char *argv[]; ! 375: { ! 376: register REG *orp, *nrp; ! 377: char oname[2], nname[2]; ! 378: ! 379: argname(argv[1], oname); ! 380: if ((orp = findreg(oname, RTEXT)) == NULL) { ! 381: printe("cannot find request %s", argv[1]); ! 382: return; ! 383: } ! 384: argname(argv[2], nname); ! 385: if ((nrp = makereg(nname, RTEXT)) == NULL) { ! 386: printe("cannot make request %s", argv[2]); ! 387: return; ! 388: } ! 389: nrp->t_reg.r_maxh = orp->t_reg.r_maxh; ! 390: nrp->t_reg.r_maxw = orp->t_reg.r_maxw; ! 391: nrp->t_reg.r_macd = orp->t_reg.r_macd; ! 392: reltreg(oname); ! 393: } ! 394: ! 395: /* ! 396: * Restore the cursor position, just in case it got garbaged. ! 397: * !V7. ! 398: */ ! 399: req_rp() ! 400: { ! 401: addidir(DFPOS, 0); ! 402: } ! 403: ! 404: /* ! 405: * Remove number register. ! 406: */ ! 407: req_rr(argc, argv) int argc; char *argv[]; ! 408: { ! 409: char name[2]; ! 410: register int i; ! 411: ! 412: for (i=1; i<argc; i++) { ! 413: argname(argv[i], name); ! 414: if (relnreg(name)) ! 415: continue; ! 416: printe("cannot remove %s", argv[i]); ! 417: } ! 418: } ! 419: ! 420: /* ! 421: * Turn no space mode off. ! 422: */ ! 423: req_rs() ! 424: { ! 425: nsm = 0; ! 426: } ! 427: ! 428: /* ! 429: * Return to marked vertical position. ! 430: */ ! 431: req_rt(argc, argv) int argc; char *argv[]; ! 432: { ! 433: register int n; ! 434: ! 435: if (argc == 1) ! 436: n = cdivp->d_mk; ! 437: else ! 438: n = numb(argv[1], SMVLSP, SDVLSP); ! 439: if (n >= cdivp->d_rpos) ! 440: return; ! 441: sspace(n - cdivp->d_rpos); ! 442: } ! 443: ! 444: /* ! 445: * Stack input and redirect from given file. ! 446: */ ! 447: req_so(argc, argv) int argc; char *argv[]; ! 448: { ! 449: adsfile(argv[1]); ! 450: } ! 451: ! 452: /* ! 453: * Space vertically. ! 454: */ ! 455: req_sp(argc, argv) int argc; char *argv[]; ! 456: { ! 457: if (nsm != 0) ! 458: return; ! 459: setbreak(); ! 460: sspace(number(argv[1], SMVLSP, SDVLSP, 0, 1, unit(SMVLSP, SDVLSP))); ! 461: } ! 462: ! 463: /* ! 464: * Set space character size. ! 465: */ ! 466: req_ss(argc, argv) int argc; char *argv[]; ! 467: { ! 468: ssz = sszmul = number(argv[1], SMEMSP, ! 469: (ntroff == NROFF) ? SDEMSP : 36 * SDEMSP, ! 470: ssz, 0, ssz); ! 471: sszdiv = psz; ! 472: } ! 473: ! 474: /* ! 475: * Save vertical distance. ! 476: */ ! 477: req_sv(argc, argv) int argc; char *argv[]; ! 478: { ! 479: register int n; ! 480: ! 481: n = number(argv[1], SMVLSP, SDVLSP, 0, 0, unit(SMVLSP, SDVLSP)); ! 482: if (mdivp->d_rpos+n > mdivp->d_ctpp->t_rpos) ! 483: svs = n; ! 484: else ! 485: sspace(n); ! 486: } ! 487: ! 488: /* ! 489: * Set tab stops. ! 490: */ ! 491: req_ta(argc, argv) int argc; char *argv[]; ! 492: { ! 493: register TAB *tp; ! 494: register int i; ! 495: register char *p; ! 496: int prevpos = 0; ! 497: ! 498: tp = &tab[1]; ! 499: for (i=1; i<argc; i++) { ! 500: if (i > TABSIZE-2) { ! 501: printe("too many tab stops"); ! 502: break; ! 503: } ! 504: p = argv[i]; ! 505: if (*p == '\0') { ! 506: printe("bad tab stop"); ! 507: break; ! 508: } ! 509: while (*p) ! 510: p++; ! 511: tp->t_jus = LJUS; ! 512: switch (*--p) { ! 513: case 'L': ! 514: tp->t_jus = LJUS; ! 515: *p = '\0'; ! 516: break; ! 517: case 'C': ! 518: tp->t_jus = CJUS; ! 519: *p = '\0'; ! 520: break; ! 521: case 'R': ! 522: tp->t_jus = RJUS; ! 523: *p = '\0'; ! 524: break; ! 525: } ! 526: tp->t_pos = number(argv[i], SMEMSP, SDEMSP, prevpos, 0, 0); ! 527: if (tp->t_pos < prevpos) { ! 528: printe("bad tab stop"); ! 529: break; ! 530: } ! 531: prevpos = tp->t_pos; ! 532: tp++; ! 533: } ! 534: tp->t_jus = '\0'; ! 535: } ! 536: ! 537: /* ! 538: * Set tab character. ! 539: */ ! 540: req_tc(argc, argv) int argc; char *argv[]; ! 541: { ! 542: register int n; ! 543: ! 544: if (argc < 1) { ! 545: tbc = '\0'; ! 546: return; ! 547: } ! 548: tbc = argv[1][0]; ! 549: tfn = curfont; ! 550: if (argc > 2) ! 551: tbs = number(argv[2], SMEMSP, SDEMSP, tbs, 0, tbs); ! 552: if (argc > 3 && (n = font_number(argv[3], ".tc: ")) >= 0) ! 553: tfn = n; ! 554: } ! 555: ! 556: /* ! 557: * Temporary indent. ! 558: */ ! 559: req_ti(argc, argv) int argc; char *argv[]; ! 560: { ! 561: setbreak(); ! 562: tin = number(argv[1], SMEMSP, SDEMSP, ind, 0, 0); ! 563: tif = 1; ! 564: } ! 565: ! 566: /* ! 567: * Three part title. ! 568: */ ! 569: req_tl(argc, argv) int argc; char *argv[]; ! 570: { ! 571: CODE *cp; ! 572: int i; ! 573: register int n; ! 574: char charbuf[CBFSIZE], endc, c; ! 575: register char *bp, *lp; ! 576: ! 577: envsave(ENVTITLE); ! 578: setline(); ! 579: ind = 0; ! 580: lln = tln; ! 581: fill = 0; ! 582: setfont("R", 1); ! 583: bp = nextarg(miscbuf, NULL, 0); ! 584: if ((endc = *bp) != '\0') ! 585: bp++; ! 586: for (i=0; i<3; i++) { ! 587: lp = charbuf; ! 588: for (;;) { ! 589: if (*bp == '\0') ! 590: break; ! 591: if ((c = *bp++) == endc) ! 592: break; ! 593: if (c == tpc) { ! 594: char digits[5]; ! 595: register char *dp = &digits[0]; ! 596: register int pn = pno; ! 597: ! 598: for(; pn > 0; pn /= 10) ! 599: *dp++ = pn%10 + '0'; ! 600: while (--dp > &digits[0]) ! 601: *lp++ = *dp; ! 602: c = *dp; ! 603: } ! 604: if (lp >= &charbuf[CBFSIZE-2]) { ! 605: printe("section %d of title too large", i+1); ! 606: break; ! 607: } ! 608: *lp++ = c; ! 609: } ! 610: if (lp != charbuf) { ! 611: *lp = '\0'; ! 612: adscore(charbuf); ! 613: strp->x1.s_eoff = 1; ! 614: process(); ! 615: wordbreak(DHMOV); ! 616: } ! 617: switch (i) { ! 618: case 0: ! 619: n = llinsiz; ! 620: cp = llinptr; ! 621: break; ! 622: case 1: ! 623: n = (lln - llinsiz - n)/2; ! 624: nlinsiz = llinsiz += cp->l_arg.c_iarg = n; ! 625: cp = llinptr; ! 626: break; ! 627: case 2: ! 628: n = lln - llinsiz; ! 629: cp->l_arg.c_iarg += n; ! 630: llinsiz += n; ! 631: break; ! 632: } ! 633: } ! 634: linebreak(1); ! 635: envload(ENVTITLE); ! 636: } ! 637: ! 638: /* ! 639: * Print a message on the terminal. ! 640: */ ! 641: req_tm(argc, argv) int argc; char *argv[]; ! 642: { ! 643: fprintf(stderr, "%s\n", nextarg(miscbuf, NULL, 0)); ! 644: } ! 645: ! 646: /* ! 647: * Translate on output. ! 648: */ ! 649: req_tr(argc, argv) int argc; char *argv[]; ! 650: { ! 651: register char c1, c2, *p; ! 652: ! 653: p = argv[1]; ! 654: while (c1 = *p++) { ! 655: if ((c2 = *p++) == '\0') { ! 656: --p; ! 657: c2 = ' '; ! 658: } ! 659: if (!isascii(c1) || !isascii(c2)) /* Remove this! */ ! 660: continue; /* $$TO_DO$$ */ ! 661: if (c2 == ' ') ! 662: c2 = A_DEL; /* Or some other value? */ ! 663: trantab[c1] = c2; ! 664: } ! 665: } ! 666: ! 667: /* ! 668: * Set underline font. ! 669: */ ! 670: req_uf(argc, argv) int argc; char *argv[]; ! 671: { ! 672: register int n; ! 673: char *name; ! 674: ! 675: name = (argc < 1) ? "I" : argv[1]; ! 676: if ((n = font_number(name, ".uf: ")) >= 0) ! 677: ufn = n; ! 678: } ! 679: ! 680: /* ! 681: * Underline. ! 682: */ ! 683: req_ul(argc, argv) int argc; char *argv[]; ! 684: { ! 685: register int n; ! 686: ! 687: n = number(argv[1], SMUNIT, SDUNIT, 0, 0, 1); ! 688: if (n != 0) { ! 689: ufp = curfont; /* save current font */ ! 690: setfontnum(ufn, 0); /* set underline font */ ! 691: } else if (ulc != 0) ! 692: setfontnum(ufp, 1); /* restore previous font */ ! 693: ulc = n; /* set underline count */ ! 694: } ! 695: ! 696: /* ! 697: * Set vertical base line spacing. ! 698: */ ! 699: req_vs(argc, argv) int argc; char *argv[]; ! 700: { ! 701: setval(&vls, &oldvls, argv[1], SMPOIN, SDPOIN); ! 702: } ! 703: ! 704: /* ! 705: * Set a trap. ! 706: */ ! 707: req_wh(argc, argv) int argc; char *argv[]; ! 708: { ! 709: register TPL **tpp, *tp; ! 710: TPL *in; ! 711: register DIV *dp; ! 712: int rpos, apos; ! 713: ! 714: rpos = numb(argv[1], SMVLSP, SDVLSP); ! 715: apos = rpos>=0 ? rpos : pgl+rpos; ! 716: dp = mdivp; ! 717: for (tpp = &dp->d_stpl; tp = *tpp; tpp = &tp->t_next) { ! 718: if (apos == tp->t_apos) { ! 719: if (dp->d_trap == tp) ! 720: dp->d_trap = tp->t_next; ! 721: if (dp->d_ctpp == tp) ! 722: dp->d_ctpp = tp->t_next; ! 723: *tpp = tp->t_next; ! 724: nfree(tp); ! 725: if (argc < 3) /* .wh NN xx !replaces all at NN */ ! 726: break; /* .wh NN !only removes 1st */ ! 727: } else if (apos < tp->t_apos) ! 728: break; ! 729: } ! 730: if (argc >= 3) { ! 731: tp = (TPL *)nalloc(sizeof (TPL)); ! 732: tp->t_rpos = rpos; ! 733: tp->t_apos = apos; ! 734: argname(argv[2], tp->t_name); ! 735: ! 736: if ((dp->d_stpl == NULL) || (dp->d_stpl->t_apos > apos)) { ! 737: tp->t_next = dp->d_stpl; ! 738: dp->d_stpl = tp; ! 739: } ! 740: else { in = dp->d_stpl; ! 741: while (in->t_next) ! 742: if (in->t_next->t_apos > apos) ! 743: break; ! 744: else ! 745: in = in->t_next; ! 746: tp->t_next = in->t_next; ! 747: in->t_next = tp; ! 748: } ! 749: ! 750: if (dp->d_trap==tp->t_next && apos>=0) ! 751: dp->d_trap = tp; ! 752: if (dp->d_ctpp==tp->t_next && apos>=dp->d_rpos) ! 753: dp->d_ctpp = tp; ! 754: } ! 755: } ! 756: ! 757: /* end of req2.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.