csh and tcsh work

Sources of csh/sh.set.c

csh と tcsh のソース

Bill Joy

First published: October, 1978.

Copyright © 1979 Regents of the University of California.

  1. 1
    /* Copyright (c) 1979 Regents of the University of California */
  2. 2
    #include "sh.h"
  3. 3
  4. 4
    /*
  5. 5
     * C Shell
  6. 6
     */
  7. 7
  8. 8
    doset(v)
  9. 9
    	register char **v;
  10. 10
    {
  11. 11
    	register char *p;
  12. 12
    	char *vp, op;
  13. 13
    	bool hadsub;
  14. 14
    	int subscr;
  15. 15
  16. 16
    	v++;
  17. 17
    	p = *v++;
  18. 18
    	if (p == 0) {
  19. 19
    		prvars();
  20. 20
    		return;
  21. 21
    	}
  22. 22
    	do {
  23. 23
    		hadsub = 0;
  24. 24
    		for (vp = p; letter(*p); p++)
  25. 25
    			continue;
  26. 26
    		if (vp == p)
  27. 27
    			goto setsyn;
  28. 28
    		if (*p == '[') {
  29. 29
    			hadsub++;
  30. 30
    			p = getinx(p, &subscr);
  31. 31
    		}
  32. 32
    		if (op = *p) {
  33. 33
    			*p++ = 0;
  34. 34
    			if (*p == 0 && *v && **v == '(')
  35. 35
    				p = *v++;
  36. 36
    		} else if (*v && eq(*v, "=")) {
  37. 37
    			op = '=', v++;
  38. 38
    			if (*v)
  39. 39
    				p = *v++;
  40. 40
    		}
  41. 41
    		if (op && op != '=')
  42. 42
    setsyn:
  43. 43
    			bferr("Syntax error");
  44. 44
    		if (eq(p, "(")) {
  45. 45
    			register char **e = v;
  46. 46
  47. 47
    			if (hadsub)
  48. 48
    				goto setsyn;
  49. 49
    			for (;;) {
  50. 50
    				if (!*e)
  51. 51
    					bferr("Missing )");
  52. 52
    				if (**e == ')')
  53. 53
    					break;
  54. 54
    				e++;
  55. 55
    			}
  56. 56
    			p = *e, *e = 0, set1(vp, saveblk(v), &shvhed), *e = p;
  57. 57
    			v = e + 1;
  58. 58
    		} else if (hadsub)
  59. 59
    			asx(vp, subscr, savestr(p));
  60. 60
    		else
  61. 61
    			set(vp, savestr(p));
  62. 62
    	} while (p = *v++);
  63. 63
    }
  64. 64
  65. 65
    char *
  66. 66
    getinx(cp, ip)
  67. 67
    	register char *cp;
  68. 68
    	register int *ip;
  69. 69
    {
  70. 70
  71. 71
    	*ip = 0;
  72. 72
    	*cp++ = 0;
  73. 73
    	while (*cp && digit(*cp))
  74. 74
    		*ip = *ip * 10 + *cp++ - '0';
  75. 75
    	if (*cp++ != ']')
  76. 76
    		bferr("Subscript error");
  77. 77
    	return (cp);
  78. 78
    }
  79. 79
  80. 80
    asx(vp, subscr, p)
  81. 81
    	char *vp;
  82. 82
    	int subscr;
  83. 83
    	char *p;
  84. 84
    {
  85. 85
    	register struct varent *v = getvx(vp, subscr);
  86. 86
  87. 87
    	xfree(v->vec[subscr - 1]);
  88. 88
    	v->vec[subscr - 1] = globone(p);
  89. 89
    }
  90. 90
  91. 91
    struct varent *
  92. 92
    getvx(vp, subscr)
  93. 93
    {
  94. 94
    	register struct varent *v = adrof(vp);
  95. 95
  96. 96
    	if (v == 0)
  97. 97
    		udvar(vp);
  98. 98
    	if (subscr < 1 || subscr > blklen(v->vec))
  99. 99
    		bferr("Subscript out of range");
  100. 100
    	return (v);
  101. 101
    }
  102. 102
  103. 103
    char	plusplus[2] = { '1', 0 };
  104. 104
  105. 105
  106. 106
    dolet(v)
  107. 107
    	char **v;
  108. 108
    {
  109. 109
    	register char *p;
  110. 110
    	char *vp, c, op;
  111. 111
    	bool hadsub;
  112. 112
    	int subscr;
  113. 113
  114. 114
    	v++;
  115. 115
    	p = *v++;
  116. 116
    	if (p == 0) {
  117. 117
    		prvars();
  118. 118
    		return;
  119. 119
    	}
  120. 120
    	do {
  121. 121
    		hadsub = 0;
  122. 122
    		for (vp = p; letter(*p); p++)
  123. 123
    			continue;
  124. 124
    		if (vp == p)
  125. 125
    			goto letsyn;
  126. 126
    		if (*p == '[') {
  127. 127
    			hadsub++;
  128. 128
    			p = getinx(p, &subscr);
  129. 129
    		}
  130. 130
    		if (*p == 0 && *v)
  131. 131
    			p = *v++;
  132. 132
    		if (op = *p)
  133. 133
    			*p++ = 0;
  134. 134
    		else
  135. 135
    			goto letsyn;
  136. 136
    		vp = savestr(vp);
  137. 137
    		if (op == '=') {
  138. 138
    			c = '=';
  139. 139
    			p = xset(p, &v);
  140. 140
    		} else {
  141. 141
    			c = *p++;
  142. 142
    			if (any(c, "+-")) {
  143. 143
    				if (c != op || *p)
  144. 144
    					goto letsyn;
  145. 145
    				p = plusplus;
  146. 146
    			} else {
  147. 147
    				if (any(op, "<>")) {
  148. 148
    					if (c != op)
  149. 149
    						goto letsyn;
  150. 150
    					c = *p++;
  151. 151
    letsyn:
  152. 152
    					bferr("Syntax error");
  153. 153
    				}
  154. 154
    				if (c != '=')
  155. 155
    					goto letsyn;
  156. 156
    				p = xset(p, &v);
  157. 157
    			}
  158. 158
    		}
  159. 159
    		if (op == '=')
  160. 160
    			if (hadsub)
  161. 161
    				asx(vp, subscr, p);
  162. 162
    			else
  163. 163
    				set(vp, p);
  164. 164
    		else
  165. 165
    			if (hadsub)
  166. 166
    #ifndef V6
  167. 167
    				/* avoid bug in vax CC */
  168. 168
    				{
  169. 169
    					struct varent *gv = getvx(vp, subscr);
  170. 170
  171. 171
    					asx(vp, subscr, operate(op, gv->vec[subscr - 1], p));
  172. 172
    				}
  173. 173
    #else
  174. 174
    				asx(vp, subscr, operate(op, getvx(vp, subscr)->vec[subscr - 1], p));
  175. 175
    #endif
  176. 176
    			else
  177. 177
    				set(vp, operate(op, value(vp), p));
  178. 178
    		xfree(vp);
  179. 179
    		if (c != '=')
  180. 180
    			xfree(p);
  181. 181
    	} while (p = *v++);
  182. 182
    }
  183. 183
  184. 184
    char *
  185. 185
    xset(cp, vp)
  186. 186
    	char *cp, ***vp;
  187. 187
    {
  188. 188
    	register char *dp;
  189. 189
  190. 190
    	if (*cp) {
  191. 191
    		dp = savestr(cp);
  192. 192
    		--(*vp);
  193. 193
    		xfree(**vp);
  194. 194
    		**vp = dp;
  195. 195
    	}
  196. 196
    	return (putn(exp(vp)));
  197. 197
    }
  198. 198
  199. 199
    char *
  200. 200
    operate(op, vp, p)
  201. 201
    	char op, *vp, *p;
  202. 202
    {
  203. 203
    	char opr[2];
  204. 204
    	char *vec[5];
  205. 205
    	register char **v = vec;
  206. 206
    	char **vecp = v;
  207. 207
    	register int i;
  208. 208
  209. 209
    	if (op != '=') {
  210. 210
    		if (*vp)
  211. 211
    			*v++ = vp;
  212. 212
    		opr[0] = op;
  213. 213
    		opr[1] = 0;
  214. 214
    		*v++ = opr;
  215. 215
    		if (op == '<' || op == '>')
  216. 216
    			*v++ = opr;
  217. 217
    	}
  218. 218
    	*v++ = p;
  219. 219
    	*v++ = 0;
  220. 220
    	i = exp(&vecp);
  221. 221
    	if (*vecp)
  222. 222
    		bferr("Expression syntax");
  223. 223
    	return (putn(i));
  224. 224
    }
  225. 225
  226. 226
    onlyread(cp)
  227. 227
    	char *cp;
  228. 228
    {
  229. 229
    	extern char end[];
  230. 230
  231. 231
    	return (cp < end);
  232. 232
    }
  233. 233
  234. 234
    xfree(cp)
  235. 235
    	char *cp;
  236. 236
    {
  237. 237
    	extern char end[];
  238. 238
  239. 239
    	if (cp >= end && cp < (char *) &cp)
  240. 240
    		cfree(cp);
  241. 241
    }
  242. 242
  243. 243
    char *
  244. 244
    savestr(s)
  245. 245
    	register char *s;
  246. 246
    {
  247. 247
  248. 248
    	if (s == 0)
  249. 249
    		s = "";
  250. 250
    	return (strcpy(calloc(1, strlen(s) + 1), s));
  251. 251
    }
  252. 252
  253. 253
    static	char *putp;
  254. 254
  255. 255
    char *
  256. 256
    putn(n)
  257. 257
    	register int n;
  258. 258
    {
  259. 259
    	static char number[15];
  260. 260
  261. 261
    	putp = number;
  262. 262
    	if (n < 0) {
  263. 263
    		n = -n;
  264. 264
    		*putp++ = '-';
  265. 265
    	}
  266. 266
    	if (sizeof (int) == 2 && n == -32768) {
  267. 267
    		*putp++ = '3';
  268. 268
    		n = 2768;
  269. 269
    #ifdef pdp11
  270. 270
    	}
  271. 271
    #else
  272. 272
    	} else if (sizeof (int) == 4 && n == -2147483648) {
  273. 273
    		*putp++ = '2';
  274. 274
    		n = 147483648;
  275. 275
    	}
  276. 276
    #endif
  277. 277
    	putn1(n);
  278. 278
    	*putp = 0;
  279. 279
    	return (savestr(number));
  280. 280
    }
  281. 281
  282. 282
    putn1(n)
  283. 283
    	register int n;
  284. 284
    {
  285. 285
    	if (n > 9)
  286. 286
    		putn1(n / 10);
  287. 287
    	*putp++ = n % 10 + '0';
  288. 288
    }
  289. 289
  290. 290
    getn(cp)
  291. 291
    	register char *cp;
  292. 292
    {
  293. 293
    	register int n;
  294. 294
    	int sign;
  295. 295
  296. 296
    	sign = 0;
  297. 297
    	if (cp[0] == '+' && cp[1])
  298. 298
    		cp++;
  299. 299
    	if (*cp == '-') {
  300. 300
    		sign++;
  301. 301
    		cp++;
  302. 302
    		if (!digit(*cp))
  303. 303
    			goto badnum;
  304. 304
    	}
  305. 305
    	n = 0;
  306. 306
    	while (digit(*cp))
  307. 307
    		n = n * 10 + *cp++ - '0';
  308. 308
    	if (*cp)
  309. 309
    		goto badnum;
  310. 310
    	return (sign ? -n : n);
  311. 311
    badnum:
  312. 312
    	bferr("Badly formed number");
  313. 313
    	return (0);
  314. 314
    }
  315. 315
  316. 316
    char *
  317. 317
    value(var)
  318. 318
    	char *var;
  319. 319
    {
  320. 320
  321. 321
    	return (value1(var, &shvhed));
  322. 322
    }
  323. 323
  324. 324
    char *
  325. 325
    value1(var, head)
  326. 326
    	char *var;
  327. 327
    	struct varent *head;
  328. 328
    {
  329. 329
    	register struct varent *vp;
  330. 330
  331. 331
    	vp = adrof1(var, head);
  332. 332
    	return (vp == 0 || vp->vec[0] == 0 ? "" : vp->vec[0]);
  333. 333
    }
  334. 334
  335. 335
    static	struct varent *shprev;
  336. 336
  337. 337
    struct varent *
  338. 338
    adrof(var)
  339. 339
    	char *var;
  340. 340
    {
  341. 341
  342. 342
    	return (adrof1(var, &shvhed));
  343. 343
    }
  344. 344
  345. 345
    struct varent *
  346. 346
    madrof(pat, head)
  347. 347
    	char *pat;
  348. 348
    	struct varent *head;
  349. 349
    {
  350. 350
    	register struct varent *vp;
  351. 351
  352. 352
    	shprev = head;
  353. 353
    	for (vp = shprev->link; vp != 0; vp = vp->link) {
  354. 354
    		if (Gmatch(vp->name, pat))
  355. 355
    			return (vp);
  356. 356
    		shprev = vp;
  357. 357
    	}
  358. 358
    	return (0);
  359. 359
    }
  360. 360
  361. 361
    struct varent *
  362. 362
    adrof1(var, head)
  363. 363
    	char *var;
  364. 364
    	struct varent *head;
  365. 365
    {
  366. 366
    	register struct varent *vp;
  367. 367
    	int cmp;
  368. 368
  369. 369
    	shprev = head;
  370. 370
    	for (vp = shprev->link; vp != 0; vp = vp->link) {
  371. 371
    		cmp = strcmp(vp->name, var);
  372. 372
    		if (cmp == 0)
  373. 373
    			return (vp);
  374. 374
    		else if (cmp > 0)
  375. 375
    			return (0);
  376. 376
    		shprev = vp;
  377. 377
    	}
  378. 378
    	return (0);
  379. 379
    }
  380. 380
  381. 381
    /*
  382. 382
     * The caller is responsible for putting value in a safe place
  383. 383
     */
  384. 384
    set(var, value)
  385. 385
    	char *var, *value;
  386. 386
    {
  387. 387
    	register char **vec = (char **) calloc(2, sizeof (char **));
  388. 388
  389. 389
    	vec[0] = onlyread(value) ? savestr(value) : value;
  390. 390
    	set1(var, vec, &shvhed);
  391. 391
    }
  392. 392
  393. 393
    set1(var, vec, head)
  394. 394
    	char *var, **vec;
  395. 395
    	struct varent *head;
  396. 396
    {
  397. 397
  398. 398
    	register char **oldv = vec;
  399. 399
  400. 400
    	gflag = 0; rscan(oldv, tglob);
  401. 401
    	if (gflag) {
  402. 402
    		vec = glob(oldv);
  403. 403
    		if (vec == 0) {
  404. 404
    			bferr("No match");
  405. 405
    			blkfree(oldv);
  406. 406
    			return;
  407. 407
    		}
  408. 408
    		blkfree(oldv);
  409. 409
    		gargv = 0;
  410. 410
    	}
  411. 411
    	setq(var, vec, head);
  412. 412
    }
  413. 413
  414. 414
    setq(var, vec, head)
  415. 415
    	char *var, **vec;
  416. 416
    	struct varent *head;
  417. 417
    {
  418. 418
    	register struct varent *vp;
  419. 419
  420. 420
    	vp = adrof1(var, head);
  421. 421
    	if (vp == 0) {
  422. 422
    		vp = (struct varent *) calloc(1, sizeof *vp);
  423. 423
    		vp->name = savestr(var);
  424. 424
    		vp->link = shprev->link;
  425. 425
    		shprev->link = vp;
  426. 426
    	}
  427. 427
    	if (vp->vec)
  428. 428
    		blkfree(vp->vec);
  429. 429
    	scan(vec, trim);
  430. 430
    	vp->vec = vec;
  431. 431
    }
  432. 432
  433. 433
    unset(v)
  434. 434
    	register char *v[];
  435. 435
    {
  436. 436
  437. 437
    	unset1(v, &shvhed);
  438. 438
    }
  439. 439
  440. 440
    unset1(v, head)
  441. 441
    	register char *v[];
  442. 442
    	struct varent *head;
  443. 443
    {
  444. 444
    	register char *var;
  445. 445
    	register struct varent *vp;
  446. 446
    	register int cnt;
  447. 447
  448. 448
    	v++;
  449. 449
    	while (var = *v++) {
  450. 450
    		cnt = 0;
  451. 451
    		while (vp = madrof(var, head))
  452. 452
    			unsetv1(vp->name, head), cnt++;
  453. 453
    /*
  454. 454
    		if (cnt == 0)
  455. 455
    			setname(var), bferr("No match");
  456. 456
    */
  457. 457
    	}
  458. 458
    }
  459. 459
  460. 460
    unsetv(var)
  461. 461
    	char *var;
  462. 462
    {
  463. 463
  464. 464
    	unsetv1(var, &shvhed);
  465. 465
    }
  466. 466
  467. 467
    unsetv1(var, head)
  468. 468
    	char *var;
  469. 469
    	struct varent *head;
  470. 470
    {
  471. 471
    	register struct varent *vp;
  472. 472
  473. 473
    	vp = adrof1(var, head);
  474. 474
    	if (vp == 0)
  475. 475
    		udvar(var);
  476. 476
    	vp = shprev->link;
  477. 477
    	shprev->link = vp->link;
  478. 478
    	blkfree(vp->vec);
  479. 479
    	xfree(vp->name);
  480. 480
    	xfree(vp);
  481. 481
    }
  482. 482
  483. 483
    setNS(cp)
  484. 484
    	char *cp;
  485. 485
    {
  486. 486
  487. 487
    	set(cp, "");
  488. 488
    }
  489. 489
  490. 490
    shift(v)
  491. 491
    	register char **v;
  492. 492
    {
  493. 493
    	register struct varent *argv;
  494. 494
    	register char *name;
  495. 495
  496. 496
    	v++;
  497. 497
    	name = *v;
  498. 498
    	if (name == 0)
  499. 499
    		name = "argv";
  500. 500
    	else
  501. 501
    		strip(name);
  502. 502
    	argv = adrof(name);
  503. 503
    	if (argv == 0)
  504. 504
    		udvar(name);
  505. 505
    	if (argv->vec[0] == 0)
  506. 506
    		bferr("No more words");
  507. 507
    	lshift(argv->vec, 1);
  508. 508
    }
  509. 509
  510. 510
    deletev(cp)
  511. 511
    	register char *cp;
  512. 512
    {
  513. 513
  514. 514
    	if (adrof(cp))
  515. 515
    		unsetv(cp);
  516. 516
    }

To the top of this page