~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to grep.py

  • Committer: Parth Malwankar
  • Date: 2010-03-29 09:58:31 UTC
  • mto: (0.44.2 grep) (6531.3.1 merge-grep)
  • mto: This revision was merged to the branch mainline in revision 6555.
  • Revision ID: parth.malwankar@gmail.com-20100329095831-fwx6wney2agc4xj4
initial implementation of -L/--files-without-matches. no tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
128
128
def versioned_grep(revision, pattern, compiled_pattern, path_list, recursive,
129
129
        line_number, from_root, eol_marker, print_revno, levels,
130
130
        include, exclude, verbose, fixed_string, ignore_case, files_with_matches,
131
 
        outf):
 
131
        files_without_matches, outf):
132
132
 
133
133
    wt, relpath = WorkingTree.open_containing('.')
134
134
    wt.lock_read()
199
199
                        line_number, pattern, compiled_pattern,
200
200
                        from_root, eol_marker, revno, print_revno,
201
201
                        include, exclude, verbose, fixed_string,
202
 
                        ignore_case, files_with_matches,
 
202
                        ignore_case, files_with_matches, files_without_matches,
203
203
                        outf, path_prefix, res_cache)
204
204
                else:
205
205
                    versioned_file_grep(tree, id, '.', path,
206
206
                        pattern, compiled_pattern, eol_marker, line_number,
207
207
                        revno, print_revno, include, exclude, verbose,
208
208
                        fixed_string, ignore_case, files_with_matches,
209
 
                        outf)
 
209
                        files_without_matches, outf)
210
210
    finally:
211
211
        wt.unlock()
212
212
 
213
213
 
214
214
def workingtree_grep(pattern, compiled_pattern, path_list, recursive,
215
215
        line_number, from_root, eol_marker, include, exclude, verbose,
216
 
        fixed_string, ignore_case, files_with_matches, outf):
 
216
        fixed_string, ignore_case, files_with_matches, files_without_matches,
 
217
        outf):
217
218
    revno = print_revno = None # for working tree set revno to None
218
219
 
219
220
    tree, branch, relpath = \
226
227
                dir_grep(tree, path, relpath, recursive, line_number,
227
228
                    pattern, compiled_pattern, from_root, eol_marker, revno,
228
229
                    print_revno, include, exclude, verbose, fixed_string,
229
 
                    ignore_case, files_with_matches, outf, path_prefix)
 
230
                    ignore_case, files_with_matches, files_without_matches,
 
231
                    outf, path_prefix)
230
232
            else:
231
233
                _file_grep(open(path).read(), '.', path, pattern,
232
234
                    compiled_pattern, eol_marker, line_number, revno,
233
235
                    print_revno, include, exclude, verbose,
234
 
                    fixed_string, ignore_case, files_with_matches, outf)
 
236
                    fixed_string, ignore_case, files_with_matches,
 
237
                    files_without_matches, outf)
235
238
    finally:
236
239
        tree.unlock()
237
240
 
247
250
def dir_grep(tree, path, relpath, recursive, line_number, pattern,
248
251
        compiled_pattern, from_root, eol_marker, revno, print_revno,
249
252
        include, exclude, verbose, fixed_string, ignore_case,
250
 
        files_with_matches, outf, path_prefix, res_cache={}):
 
253
        files_with_matches, files_without_matches, outf,
 
254
        path_prefix, res_cache={}):
251
255
    _revno_pattern = re.compile("\~[0-9.]+:")
252
256
    _revno_pattern_list_only = re.compile("\~[0-9.]+")
253
257
    dir_res = {}
304
308
                    from_dir = '.'
305
309
 
306
310
                path_for_file = osutils.pathjoin(tree.basedir, from_dir, fp)
307
 
                if not files_with_matches:
308
 
                    file_text = codecs.open(path_for_file, 'r').read()
309
 
                    _file_grep(file_text, rpath, fp,
310
 
                        pattern, compiled_pattern, eol_marker, line_number, revno,
311
 
                        print_revno, include, exclude, verbose, fixed_string,
312
 
                        ignore_case, files_with_matches, outf, path_prefix)
313
 
                else:
 
311
                if files_with_matches or files_without_matches:
314
312
                    # Optimize for wtree list-only as we don't need to read the
315
313
                    # entire file
316
314
                    file = codecs.open(path_for_file, 'r', buffering=4096)
317
315
                    _file_grep_list_only_wtree(file, rpath, fp,
318
316
                        pattern, compiled_pattern, eol_marker, line_number, revno,
319
317
                        print_revno, include, exclude, verbose, fixed_string,
320
 
                        ignore_case, files_with_matches, outf, path_prefix)
 
318
                        ignore_case, files_with_matches, files_without_matches,
 
319
                        outf, path_prefix)
 
320
                else:
 
321
                    file_text = codecs.open(path_for_file, 'r').read()
 
322
                    _file_grep(file_text, rpath, fp,
 
323
                        pattern, compiled_pattern, eol_marker, line_number, revno,
 
324
                        print_revno, include, exclude, verbose, fixed_string,
 
325
                        ignore_case, files_with_matches, files_without_matches,
 
326
                        outf, path_prefix)
321
327
 
322
328
    if revno != None: # grep versioned files
323
329
        for (path, fid), chunks in tree.iter_files_bytes(to_grep):
325
331
            res = _file_grep(chunks[0], rpath, path, pattern,
326
332
                compiled_pattern, eol_marker, line_number, revno,
327
333
                print_revno, include, exclude, verbose, fixed_string,
328
 
                ignore_case, files_with_matches, outf, path_prefix)
 
334
                ignore_case, files_with_matches, files_without_matches,
 
335
                outf, path_prefix)
329
336
            file_rev = tree.inventory[fid].revision
330
337
            dir_res[file_rev] = res
331
338
    return dir_res
349
356
def versioned_file_grep(tree, id, relpath, path, pattern, patternc,
350
357
        eol_marker, line_number, revno, print_revno, include, exclude,
351
358
        verbose, fixed_string, ignore_case, files_with_matches,
352
 
        outf, path_prefix = None):
 
359
        files_without_matches, outf, path_prefix = None):
353
360
    """Create a file object for the specified id and pass it on to _file_grep.
354
361
    """
355
362
 
357
364
    file_text = tree.get_file_text(id)
358
365
    _file_grep(file_text, relpath, path, pattern, patternc, eol_marker,
359
366
        line_number, revno, print_revno, include, exclude, verbose,
360
 
        fixed_string, ignore_case, files_with_matches, outf, path_prefix)
 
367
        fixed_string, ignore_case, files_with_matches, files_without_matches,
 
368
        outf, path_prefix)
361
369
 
362
370
 
363
371
def _path_in_glob_list(path, glob_list):
371
379
 
372
380
def _file_grep_list_only_wtree(file, relpath, path, pattern, patternc,
373
381
        eol_marker, line_number, revno, print_revno, include, exclude,
374
 
        verbose, fixed_string, ignore_case, files_with_matches, outf,
375
 
        path_prefix=None):
 
382
        verbose, fixed_string, ignore_case, files_with_matches,
 
383
        files_without_matches, outf, path_prefix=None):
376
384
 
377
385
    # test and skip binary files
378
386
    if '\x00' in file.read(1024):
400
408
                if pattern in line:
401
409
                    found = True
402
410
                    break
403
 
    else:   # not fixed_string
 
411
    else: # not fixed_string
404
412
 
405
413
        for line in file:
406
414
            if patternc.search(line):
407
415
                found = True
408
416
                break
409
417
 
410
 
    if found:
 
418
    if (files_with_matches and found) or (files_without_matches and not found):
411
419
        if path_prefix and path_prefix != '.':
412
420
            # user has passed a dir arg, show that as result prefix
413
421
            path = osutils.pathjoin(path_prefix, path)
415
423
        s = path + eol_marker
416
424
        outf.write(s)
417
425
 
 
426
 
418
427
def _file_grep(file_text, relpath, path, pattern, patternc, eol_marker,
419
428
        line_number, revno, print_revno, include, exclude, verbose,
420
 
        fixed_string, ignore_case, files_with_matches, outf, path_prefix=None):
 
429
        fixed_string, ignore_case, files_with_matches, files_without_matches,
 
430
        outf, path_prefix=None):
421
431
    res = []
422
432
    res_append = res.append
423
433
    outf_write = outf.write
445
455
    # of the core loop. hence, the core loop is somewhat duplicated
446
456
    # for various combinations of formatting options.
447
457
 
448
 
    if files_with_matches:
 
458
    if files_with_matches or files_without_matches:
449
459
        # While printing files with matches we only have two case
450
460
        # print file name or print file name with revno.
 
461
        found = False
451
462
        if print_revno:
452
463
            pfmt = "~%s".encode(_te, 'replace')
453
464
            if fixed_string:
456
467
                        line = line.lower()
457
468
                    if pattern in line:
458
469
                        s = path + (pfmt % (revno,)) + eol_marker
459
 
                        res_append(s)
460
 
                        outf_write(s)
 
470
                        found = True
461
471
                        break
462
472
            else:
463
473
                for line in file_text.splitlines():
464
474
                    if patternc.search(line):
465
475
                        s = path + (pfmt % (revno,)) + eol_marker
466
 
                        res_append(s)
467
 
                        outf_write(s)
 
476
                        found = True
468
477
                        break
469
478
        else:
470
479
            if fixed_string:
473
482
                        line = line.lower()
474
483
                    if pattern in line:
475
484
                        s = path + eol_marker
476
 
                        res_append(s)
477
 
                        outf_write(s)
 
485
                        found = True
478
486
                        break
479
487
            else:
480
488
                for line in file_text.splitlines():
481
489
                    if patternc.search(line):
482
490
                        s = path + eol_marker
483
 
                        res_append(s)
484
 
                        outf_write(s)
 
491
                        found = True
485
492
                        break
 
493
        if (files_with_matches and found) or \
 
494
                (files_without_matches and not found):
 
495
            res_append(s)
 
496
            outf_write(s)
486
497
        return res # return from files_with_matches
487
498
 
488
499