wrap_slap_ops revision 1.1.1.1
1#!/usr/bin/perl -wn0777 2# wrap_slap_ops - Help update code to use SLAP_OP() & co. 3# 4# This work is part of OpenLDAP Software <http://www.openldap.org/>. 5# 6# Copyright 2011-2021 The OpenLDAP Foundation. 7# Portions Copyright 2011-2013 Hallvard B. Furuseth. 8# All rights reserved. 9# 10# Redistribution and use in source and binary forms, with or without 11# modification, are permitted only as authorized by the OpenLDAP 12# Public License. 13# 14# A copy of this license is available in the file LICENSE in the 15# top-level directory of the distribution or, alternatively, at 16# <http://www.OpenLDAP.org/license.html>. 17 18use strict; 19 20sub usage() { 21 warn "Usage: $0 {-l | -u | -U<num>} {file | dir}... 22 23Update slapd source code to wrap LDAP operation calls in the debug 24macros SLAP_OP() & co. They compile like the old code by default. 25Define USE_RS_ASSERT to enable asserts which verify the SlapReply. 26See servers/slapd/result.c. 27 28Options: 29 -u, -U<n> Output unidiffs with n lines of context (-u = default for diff). 30 -l List files which would change. Show remaining cases on stderr.\n"; 31 exit(1); 32} 33 34#### File/option handling. Skips symlinks, handles filenames =~ /\.[ch]+p*$/i. 35 36sub ls_R { 37 map { -l $_ ? () : -d _ ? ls_R(<$_/*>) : /\.[ch]+p*$/i ? $_ : () } @_; 38} 39 40use constant Mode => shift(@ARGV) || ""; 41use vars qw($ccnt $rcnt); 42INIT { 43 usage() unless Mode =~ /^-(l|[uU]\d*)$/ && ($ARGV[0]||"") =~ /^[^\-]/; 44 exit(0) unless @ARGV = ls_R(@ARGV); # Expand ARGV, exit if no files 45 $| = 1; 46 $ccnt = $rcnt = 0; 47} 48 49sub file_result( $$ ) { 50 my($contents, $changed) = @_; 51 $ccnt++ if $changed; 52 $rcnt += scalar( my @rest = remaining($contents) ); 53 if (Mode eq "-l") { 54 print "$ARGV\n" if $changed; 55 print STDERR "$ARGV:\t$_\n" foreach @rest; 56 } elsif ($changed) { 57 (my $file = "$ARGV") =~ s%^-%./-%; 58 print "Index: $file\n"; 59 (open(D, "|-", "diff", Mode, $file, "-") 60 && (print D $contents) 61 && (close(D) || $! == 0)) or die "$0: diff failed: $!\n"; 62 } 63} 64 65END { 66 print STDERR <<EOMSG if defined $ccnt; 67$ccnt files to change. $rcnt suspicious lines remain. (Expect three in slapd). 68EOMSG 69} 70 71#### Edit the contents of a file 72 73use vars qw($obj_re %addr %func2op $func_re $todo_re); 74INIT { 75 $obj_re = qr/(?:\w+ (?:\s* (?:->|\.) \s* \w+)*?)/x; 76 %addr = ("." => "&", "->" => ""); # x.y => (&x)->y, x->y => x->y 77 %func2op = map { /(\w+) \s+ (?= .*?=>\s* (\w+))/gx } <DATA>; 78 $func_re = '\b(?=b[ei]_)(?:' . join("|", keys %func2op) . ')\b'; 79 my %both = (%func2op, reverse %func2op); 80 $todo_re = '\b(?=[bo][eip]_)(?:' . join("|", keys %both) . ')\b'; 81} 82next if !/$todo_re/; 83my $orig = "$_"; 84 85# x->func(op, rs) ==> slap_bi_op( x, <enum op_func>, op, rs) 86# x. func(op, rs) ==> slap_bi_op(&x, <enum op_func>, op, rs) 87s%( # 1: entire match: "<delim><function>(" 88 ((?: [\)!=\;{}\\] | \*/ | \b if\s*\( | \b return \b ) \s*) # 2: delim 89 (\(\s* (?:\* \s*)?)? # 3: optional "(*" or "(" in (*f)() 90 ($obj_re) \s* (->|\.) \s* # 4: object, 5: "->" or "." 91 (?=(b[ie]_))($func_re) \s* # 6: "bi_" or "be_", 7: function 92 (\)\s*)? # 8: optional ")" in (*f), 93 (\(\s*) # 9: "(" + whitespace 94)% (!$3) == (!$8) ? "$2slap_$6op$9$addr{$5}$4, $func2op{$7}, " : $1 %egox; 95 96# (&x->bi_op_bind)[which](op, rs) ==> slap_bi_op(x, which, op, rs) 97# (&x->be_bind)[which](op, rs) ==> slap_be_op(x, which, op, rs) 98s/\(&(\w+(?:(?:->|\.)\w+)*)->b(?=([ei]))(?:e|i_op)_bind\)\[\s* (\w+) \s*\] \((\s*) ([^()]*)\) 99 /slap_b$2_op($4$1, $3, $5)/gox; 100 101# slap_bi_op(x->bd_info, which, op, rs) ==> slap_be_op( x, which, op, rs) 102# slap_bi_op(x. bd_info, which, op, rs) ==> slap_be_op(&x, which, op, rs) 103s/\b slap_bi_op (\(\s*) ($obj_re) \s* (->|\.) \s* bd_info \s*, 104 /slap_be_op$1$addr{$3}$2,/gox; 105 106# slap_be_op(op->o_bd, which, &op, rs) ==> SLAP_OP(which, op, rs) 107# slap_be_op(op. o_bd, which, &op, rs) ==> SLAP_OP(which, &op, rs) 108s/\b(slap_be_op (\(\s*) ($obj_re) \s*(->|\.)\s* o_bd, \s (\w+, \s (&?)\3,)) 109 / $addr{$4} eq $6 ? "SLAP_OP$2$5" : die "$ARGV: Bad syntax: $1\n" /egox; 110 111my $changed = $_ ne $orig; 112 113# When changing a file, do some whitespace cleanup too 114if ($changed) { 115 s/\b ((SLAP_OP|slap_b[ei](func)?_op) \b .*?) [\ \t]+$ /$1/gmx; 116 s/\A\s*\n//; 117 s/\s*\z/\n/; 118} 119 120file_result($_, $changed); 121 122#### 123 124# Return remaining lines that contain operation method names 125sub remaining { 126 my($contents) = @_; 127 return $contents !~ /$func_re/o ? () : grep { 128 !/^\# [ \t]* define \s+ ($func_re|slap_bi_op\b) /x && 129 # Skip "if ( (&bi->bi_op_bind)[ which ] )" and variants 130 !/^(\} \s* else \s*)? if \s* \( \s* 131 \(& (\w+ | \(\s*\w+\s*=\s*$obj_re\s*\)) -> bi_op_bind\) 132 \s* \[ \s* \w+ \s* \] 133 \s* [&|\)]/ox; 134 } $contents =~ m% ^[\ \t]* (?=\S) ( 135 # The line contains a member opfunction 136 .*? (?:->|\.) \s* $func_re 137 138 # Skip if the member function is assigned, compared, 139 # 'and/or'ed, followed by a word (this is a comment), or by 140 # ') {' or ') word' (function is the boolean in an if/while). 141 (?! \s* (?: [!=&|\w] | \)\s*[\{\w] )) 142 143 .*? 144 ) \s*?$ %gmox; 145} 146 147# %func2op: Member functions => slap_operation_t 148__DATA__ 149be_bind bi_op_bind => op_bind 150be_unbind bi_op_unbind => op_unbind 151be_search bi_op_search => op_search 152be_compare bi_op_compare => op_compare 153be_modify bi_op_modify => op_modify 154be_modrdn bi_op_modrdn => op_modrdn 155be_add bi_op_add => op_add 156be_delete bi_op_delete => op_delete 157be_abandon bi_op_abandon => op_abandon 158be_extended bi_extended => op_extended 159be_cancel bi_op_cancel => op_cancel 160be_operational bi_operational => op_aux_operational 161be_chk_referrals bi_chk_referrals => op_aux_chk_referrals 162be_chk_controls bi_chk_controls => op_aux_chk_controls 163