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