xref: /netbsd-src/external/bsd/openldap/dist/contrib/slapd-tools/wrap_slap_ops (revision e670fd5c413e99c2f6a37901bb21c537fcd322d2)
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