1# 2# Copyright © 2000 Vita Nuova (Holdings) Limited. All rights reserved. 3# 4 5implement Mkproto; 6 7# make a proto description of the directory or file 8 9include "sys.m"; 10 sys: Sys; 11 12include "draw.m"; 13 14include "readdir.m"; 15 readdir: Readdir; 16 17include "bufio.m"; 18 bufio: Bufio; 19 Iobuf: import bufio; 20 21Mkproto: module 22{ 23 init: fn(ctxt: ref Draw->Context, argv: list of string); 24}; 25 26usage() 27{ 28 sys->fprint(sys->fildes(2), "Usage: mkproto [ file|directory ... ]\n"); 29 raise "fail:usage"; 30} 31 32not: list of string; 33bout: ref Iobuf; 34 35init(nil: ref Draw->Context, argv: list of string) 36{ 37 sys = load Sys Sys->PATH; 38 readdir = load Readdir Readdir->PATH; 39 bufio = load Bufio Bufio->PATH; 40 41 bout = bufio->fopen(sys->fildes(1), Bufio->OWRITE); 42 argv = tl argv; 43 while (argv != nil && hd argv != nil && (hd argv)[0] == '-') { 44 not = (hd argv)[1:] :: not; 45 argv = tl argv; 46 } 47 if (argv == nil) 48 visit(".", nil, -1); 49 else if (tl argv == nil) 50 visit(hd argv, nil, -1); 51 else { 52 for ( ; argv != nil; argv = tl argv) 53 visit(hd argv, hd argv, 0); 54 } 55 bout.flush(); 56} 57 58warn(s: string) 59{ 60 sys->fprint(sys->fildes(2), "mkproto: %s\n", s); 61} 62 63visit(fulln: string, reln: string, depth: int) 64{ 65 if (depth == 0) { 66 for (n := not; n != nil; n = tl n) { 67 if (hd n == reln) { 68 # sys->fprint(stderr, "skipping %s\n", reln); 69 return; 70 } 71 } 72 # sys->fprint(stderr, "doing %s\n", reln); 73 } 74 (ok, d) := sys->stat(fulln); 75 if(ok < 0){ 76 warn(sys->sprint("cannot stat %s: %r", fulln)); 77 return; 78 } 79 if (depth >= 0) 80 visitf(fulln, reln, d, depth); 81 if (d.mode & Sys->DMDIR) 82 visitd(fulln, reln, d, depth); 83} 84 85visitd(fulln: string, nil: string, nil: Sys->Dir, depth: int) 86{ 87 (dir, n) := readdir->init(fulln, Readdir->NAME|Readdir->COMPACT); 88 for (i := 0; i < n; i++) { 89 path := "/"+dir[i].name; 90 visit(fulln+path, dir[i].name, depth+1); 91 } 92} 93 94visitf(nil: string, reln: string, nil: Sys->Dir, depth: int) 95{ 96 for (i := 0; i < depth; i++) 97 bout.putc('\t'); 98 bout.puts(sys->sprint("%q\n", reln)); 99} 100