Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
bugzilla
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
bugzilla
Commits
8fdb0d36
Commit
8fdb0d36
authored
Jan 28, 2000
by
terry%mozilla.org
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Massive stomp on the query page and buglist page. Added the ability
to use the "boolean charts" to do very powerful queries.
parent
b23cb23b
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
768 additions
and
374 deletions
+768
-374
CGI.pl
CGI.pl
+18
-12
booleanchart.html
booleanchart.html
+79
-0
buglist.cgi
buglist.cgi
+567
-361
checksetup.pl
checksetup.pl
+5
-0
query.cgi
query.cgi
+99
-1
No files found.
CGI.pl
View file @
8fdb0d36
...
...
@@ -78,10 +78,10 @@ sub url_quote {
}
sub
P
rocessFormFields
{
my
(
$buffer
)
=
(
@_
);
undef
%
::
FORM
;
undef
%
::
MFORM
;
sub
P
arseUrlString
{
my
(
$buffer
,
$f
,
$m
)
=
(
@_
);
undef
%
$f
;
undef
%
$m
;
my
%
isnull
;
my
$remaining
=
$buffer
;
...
...
@@ -105,13 +105,13 @@ sub ProcessFormFields {
$value
=
""
;
}
if
(
$value
ne
""
)
{
if
(
defined
$
::FORM
{
$name
})
{
$
::FORM
{
$name
}
.=
$value
;
my
$ref
=
$
::MFORM
{
$name
};
if
(
defined
$
f
->
{
$name
})
{
$
f
->
{
$name
}
.=
$value
;
my
$ref
=
$
m
->
{
$name
};
push
@$ref
,
$value
;
}
else
{
$
::FORM
{
$name
}
=
$value
;
$
::MFORM
{
$name
}
=
[
$value
];
$
f
->
{
$name
}
=
$value
;
$
m
->
{
$name
}
=
[
$value
];
}
}
else
{
$isnull
{
$name
}
=
1
;
...
...
@@ -119,15 +119,21 @@ sub ProcessFormFields {
}
if
(
defined
%
isnull
)
{
foreach
my
$name
(
keys
(
%
isnull
))
{
if
(
!
defined
$
::FORM
{
$name
})
{
$
::FORM
{
$name
}
=
""
;
$
::MFORM
{
$name
}
=
[]
;
if
(
!
defined
$
f
->
{
$name
})
{
$
f
->
{
$name
}
=
""
;
$
m
->
{
$name
}
=
[]
;
}
}
}
}
sub
ProcessFormFields
{
my
(
$buffer
)
=
(
@_
);
return
ParseUrlString
(
$buffer
,
\%::
FORM
,
\%::
MFORM
);
}
sub
ProcessMultipartFormFields
{
my
(
$boundary
)
=
(
@_
);
$boundary
=~
s/^-*//
;
...
...
booleanchart.html
0 → 100644
View file @
8fdb0d36
<html>
<head>
<title>
The "boolean chart" section of the query page
</title>
</head>
<body>
<h1>
The "boolean chart" section of the query page
</h1>
("Boolean chart" is a terrible term; anyone got a better one I can use
instead?)
<p>
The Bugzilla query page is designed to be reasonably easy to use.
But, with such ease of use always comes some lack of power. The
"boolean chart" section is designed to let you do very powerful
queries, but it's not the easiest thing to learn (or explain).
<p>
So.
<p>
The boolean chart starts with a single "term". A term is a
combination of two pulldown menus and a text field.
You choose items from the menus, specifying "what kind of thing
am I searching for" and "what kind of matching do I want", and type in
a value on the text field, specifying "what should it match".
<p>
The real fun starts when you click on the "Or" or "And" buttons. If
you bonk on the "Or" button, then you get a second term to the right
of the first one. You can then configure that term, and the result of
the query will be anything that matches either of the terms.
<p>
Or, you can bonk the "And" button, and get a new term below the
original one, and now the result of the query will be anything that
matches both of the terms.
<p>
And you can keep clicking "And" and "Or", and get a page with tons of
terms. "Or" has higher precedence than "And". (In other words, you
can think of each line of "Or" stuff as having parenthesis around it.)
<p>
The most subtle thing is this "Add another boolean chart" button.
This is almost the same thing as the "And" button. The difference is
if you use one of the fields where several items can be associated
with a single bug. This includes "Comments", "CC", and all the
"changed [something]" entries. Now, if you have multiple terms that
all talk about one of these fields, it's ambiguous whether they are
allowed to be talking about different instances of that field. So,
to let you have it both ways, they always mean the same instance,
unless the terms appear on different charts.
<p>
For example: if you search for "priority changed to P5" and
"priority changed by person@addr", it will only find bugs where the
given person at some time changed the priority to P5. However, if
what you really want is to find all bugs where the milestone was
changed at some time by the person, and someone (possibly someone
else) at some time changed the milestone to P5, then you would put
the two terms in two different charts.
<p>
Clear as mud? Please, I beg you, rewrite this document to make
everything crystal clear, and send the improved version to
<a
href=
"terry@mozilla.org"
>
Terry
</a>
.
<hr>
<!-- hhmts start -->
Last modified: Thu Jan 27 16:56:11 2000
<!-- hhmts end -->
</body>
</html>
buglist.cgi
View file @
8fdb0d36
...
...
@@ -46,17 +46,565 @@ sub sillyness {
$zz
=
@::versions
;
};
my
$serverpush
=
0
;
ConnectToDatabase
();
# print "Content-type: text/plain\n\n"; # Handy for debugging.
# $::FORM{'debug'} = 1;
if
(
grep
(
/^cmd-/
,
keys
(
%::
FORM
)))
{
my
$url
=
"query.cgi#chart?$::buffer"
;
print
qq{Refresh: 0; URL=$url
Content-type: text/html
<A HREF="$url">Adding field to query page...</A>
}
;
exit
();
}
if
(
!
defined
$::FORM
{
'cmdtype'
})
{
# This can happen if there's an old bookmark to a query...
$::FORM
{
'cmdtype'
}
=
'doit'
;
}
sub
SqlifyDate
{
my
(
$str
)
=
(
@_
);
if
(
!
defined
$str
)
{
$str
=
""
;
}
my
$date
=
str2time
(
$str
);
if
(
!
defined
$date
)
{
print
"\n\n<P>The string '<tt>$str</tt>' is not a legal date.\n"
;
print
"<P>Please click the <B>Back</B> button and try again.\n"
;
PutFooter
();
exit
;
}
return
time2str
(
"%Y/%m/%d %H:%M:%S"
,
$date
);
}
sub
GetByWordList
{
my
(
$field
,
$strs
)
=
(
@_
);
my
@list
;
foreach
my
$w
(
split
(
/[\s,]+/
,
$strs
))
{
my
$word
=
$w
;
if
(
$word
ne
""
)
{
$word
=~
tr
/A-Z/
a
-
z
/
;
$word
=
SqlQuote
(
quotemeta
(
$word
));
$word
=~
s/^'//
;
$word
=~
s/'$//
;
$word
=
'(^|[^a-z0-9])'
.
$word
.
'($|[^a-z0-9])'
;
push
(
@list
,
"lower($field) regexp '$word'"
);
}
}
return
\
@list
;
}
sub
Error
{
my
(
$str
)
=
(
@_
);
if
(
!
$serverpush
)
{
print
"Content-type: text/html\n\n"
;
}
print
$str
;
print
"\n<P>Please press <B>Back</B> and try again.\n"
;
PutFooter
();
exit
();
}
sub
GenerateSQL
{
my
$debug
=
0
;
my
(
$fieldsref
,
$supptablesref
,
$wherepartref
,
$urlstr
)
=
(
@_
);
my
@fields
;
my
@supptables
;
my
@wherepart
;
@fields
=
@$fieldsref
if
$fieldsref
;
@supptables
=
@$supptablesref
if
$supptablesref
;
@wherepart
=
@$wherepartref
if
$wherepartref
;
my
%
F
;
my
%
M
;
ParseUrlString
(
$urlstr
,
\%
F
,
\%
M
);
my
@specialchart
;
my
@andlist
;
# First, deal with all the old hard-coded non-chart-based poop.
unshift
(
@supptables
,
(
"profiles map_assigned_to"
,
"profiles map_reporter"
,
"LEFT JOIN profiles map_qa_contact ON bugs.qa_contact = map_qa_contact.userid"
));
unshift
(
@wherepart
,
(
"bugs.assigned_to = map_assigned_to.userid"
,
"bugs.reporter = map_reporter.userid"
,
"bugs.groupset & $::usergroupset = bugs.groupset"
));
my
$minvotes
;
if
(
defined
$F
{
'votes'
})
{
my
$c
=
trim
(
$F
{
'votes'
});
if
(
$c
ne
""
)
{
if
(
$c
!~
/^[0-9]*$/
)
{
return
Error
(
"The 'At least ___ votes' field must be a\n"
.
"simple number. You entered \"$c\", which\n"
.
"doesn't cut it."
);
}
push
(
@specialchart
,
[
"votes"
,
"greaterthan"
,
$c
-
1
]);
}
}
if
(
$M
{
'bug_id'
})
{
my
$type
=
"anyexact"
;
if
(
$F
{
'bugidtype'
}
&&
$F
{
'bugidtype'
}
eq
'exclude'
)
{
$type
=
"noexact"
;
}
push
(
@specialchart
,
[
"bug_id"
,
$type
,
join
(
','
,
@
{
$M
{
'bug_id'
}})]);
}
if
(
defined
$F
{
'sql'
})
{
push
(
@wherepart
,
"( $F{'sql'} )"
);
}
my
@legal_fields
=
(
"product"
,
"version"
,
"rep_platform"
,
"op_sys"
,
"bug_status"
,
"resolution"
,
"priority"
,
"bug_severity"
,
"assigned_to"
,
"reporter"
,
"component"
,
"target_milestone"
,
"groupset"
);
foreach
my
$field
(
keys
%
F
)
{
if
(
lsearch
(
\
@legal_fields
,
$field
)
!=
-
1
)
{
push
(
@specialchart
,
[
$field
,
"anyexact"
,
join
(
','
,
@
{
$M
{
$field
}})]);
}
}
if
(
$F
{
'keywords'
})
{
my
$t
=
$F
{
'keywords_type'
};
if
(
!
$t
||
$t
eq
"or"
)
{
$t
=
"anywords"
;
}
push
(
@specialchart
,
[
"keywords"
,
$t
,
$F
{
'keywords'
}]);
}
foreach
my
$id
(
"1"
,
"2"
)
{
if
(
!
defined
(
$F
{
"email$id"
}))
{
next
;
}
my
$email
=
trim
(
$F
{
"email$id"
});
if
(
$email
eq
""
)
{
next
;
}
my
$type
=
$F
{
"emailtype$id"
};
if
(
$type
eq
"exact"
)
{
$type
=
"anyexact"
;
foreach
my
$name
(
split
(
','
,
$email
))
{
$name
=
trim
(
$name
);
if
(
$name
)
{
DBNameToIdAndCheck
(
$name
);
}
}
}
my
@clist
;
foreach
my
$field
(
"assigned_to"
,
"reporter"
,
"cc"
,
"qa_contact"
)
{
if
(
$F
{
"email$field$id"
})
{
push
(
@clist
,
$field
,
$type
,
$email
);
}
}
if
(
$F
{
"emaillongdesc$id"
})
{
my
$table
=
"longdescs_"
;
push
(
@supptables
,
"longdescs $table"
);
push
(
@wherepart
,
"$table.bug_id = bugs.bug_id"
);
my
$ptable
=
"longdescnames_"
;
push
(
@supptables
,
"LEFT JOIN profiles $ptable ON $table.who = $ptable.userid"
);
push
(
@clist
,
"$ptable.login_name"
,
$type
,
$email
);
}
if
(
@clist
)
{
push
(
@specialchart
,
\
@clist
);
}
else
{
return
Error
(
"You must specify one or more fields in which to\n"
.
"search for <tt>$email</tt>.\n"
);
}
}
if
(
defined
$F
{
'changedin'
})
{
my
$c
=
trim
(
$F
{
'changedin'
});
if
(
$c
ne
""
)
{
if
(
$c
!~
/^[0-9]*$/
)
{
return
Error
(
"The 'changed in last ___ days' field must be\n"
.
"a simple number. You entered \"$c\", which\n"
.
"doesn't cut it."
);
}
push
(
@specialchart
,
[
"changedin"
,
"lessthan"
,
$c
+
1
]);
}
}
my
$ref
=
$M
{
'chfield'
};
if
(
defined
$ref
)
{
my
$which
=
lsearch
(
$ref
,
"[Bug creation]"
);
if
(
$which
>=
0
)
{
splice
(
@$ref
,
$which
,
1
);
push
(
@specialchart
,
[
"creation_ts"
,
"greaterthan"
,
SqlifyDate
(
$F
{
'chfieldfrom'
})]);
my
$to
=
$F
{
'chfieldto'
};
if
(
defined
$to
)
{
$to
=
trim
(
$to
);
if
(
$to
ne
""
&&
$to
!~
/^now$/i
)
{
push
(
@specialchart
,
[
"creation_ts"
,
"lessthan"
,
SqlifyDate
(
$to
)]);
}
}
}
}
if
(
defined
$ref
&&
0
<
@$ref
)
{
push
(
@supptables
,
"bugs_activity actcheck"
);
my
@list
;
foreach
my
$f
(
@$ref
)
{
push
(
@list
,
"\nactcheck.fieldid = "
.
GetFieldID
(
$f
));
}
push
(
@wherepart
,
"actcheck.bug_id = bugs.bug_id"
);
push
(
@wherepart
,
"("
.
join
(
' OR '
,
@list
)
.
")"
);
push
(
@wherepart
,
"actcheck.bug_when >= "
.
SqlQuote
(
SqlifyDate
(
$F
{
'chfieldfrom'
})));
my
$to
=
$F
{
'chfieldto'
};
if
(
defined
$to
)
{
$to
=
trim
(
$to
);
if
(
$to
ne
""
&&
$to
!~
/^now$/i
)
{
push
(
@wherepart
,
"actcheck.bug_when <= "
.
SqlQuote
(
SqlifyDate
(
$to
)));
}
}
my
$value
=
$F
{
'chfieldvalue'
};
if
(
defined
$value
)
{
$value
=
trim
(
$value
);
if
(
$value
ne
""
)
{
push
(
@wherepart
,
"actcheck.newvalue = "
.
SqlQuote
(
$value
))
}
}
}
foreach
my
$f
(
"short_desc"
,
"long_desc"
,
"bug_file_loc"
,
"status_whiteboard"
)
{
if
(
defined
$F
{
$f
})
{
my
$s
=
trim
(
$F
{
$f
});
if
(
$s
ne
""
)
{
my
$n
=
$f
;
my
$q
=
SqlQuote
(
$s
);
my
$type
=
$F
{
$f
.
"_type"
};
push
(
@specialchart
,
[
$f
,
$type
,
$s
]);
}
}
}
my
$chartid
;
my
$f
;
my
$t
;
my
$q
;
my
$v
;
my
$term
;
my
%
funcsbykey
;
my
@funcdefs
=
(
"^(assigned_to|reporter),"
=>
sub
{
push
(
@supptables
,
"profiles map_$f"
);
push
(
@wherepart
,
"bugs.$f = map_$f.userid"
);
$f
=
"map_$f.login_name"
;
},
"^qa_contact,"
=>
sub
{
push
(
@supptables
,
"LEFT JOIN profiles map_qa_contact ON bugs.qa_contact = map_qa_contact.userid"
);
$f
=
"map_$f.login_name"
;
},
"^cc,"
=>
sub
{
push
(
@supptables
,
(
"LEFT JOIN cc cc_$chartid ON bugs.bug_id = cc_$chartid.bug_id LEFT JOIN profiles map_cc_$chartid ON cc_$chartid.who = map_cc_$chartid.userid"
));
$f
=
"map_cc_$chartid.login_name"
;
},
"^long_?desc,changedby"
=>
sub
{
my
$table
=
"longdescs_$chartid"
;
push
(
@supptables
,
"longdescs $table"
);
push
(
@wherepart
,
"$table.bug_id = bugs.bug_id"
);
my
$id
=
DBNameToIdAndCheck
(
$v
);
$term
=
"$table.who = $id"
;
},
"^long_?desc,changedbefore"
=>
sub
{
my
$table
=
"longdescs_$chartid"
;
push
(
@supptables
,
"longdescs $table"
);
push
(
@wherepart
,
"$table.bug_id = bugs.bug_id"
);
$term
=
"$table.who < "
.
SqlQuote
(
SqlifyDate
(
$v
));
},
"^long_?desc,changedafter"
=>
sub
{
my
$table
=
"longdescs_$chartid"
;
push
(
@supptables
,
"longdescs $table"
);
push
(
@wherepart
,
"$table.bug_id = bugs.bug_id"
);
$term
=
"$table.who > "
.
SqlQuote
(
SqlifyDate
(
$v
));
},
"^long_?desc,"
=>
sub
{
my
$table
=
"longdescs_$chartid"
;
push
(
@supptables
,
"longdescs $table"
);
push
(
@wherepart
,
"$table.bug_id = bugs.bug_id"
);
$f
=
"$table.thetext"
;
},
"^changedin,"
=>
sub
{
$f
=
"(to_days(now()) - to_days(bugs.delta_ts))"
;
},
"^keywords,"
=>
sub
{
GetVersionTable
();
my
@list
;
my
$table
=
"keywords_$chartid"
;
foreach
my
$value
(
split
(
/[\s,]+/
,
$v
))
{
if
(
$value
eq
''
)
{
next
;
}
my
$id
=
$::keywordsbyname
{
$value
};
if
(
$id
)
{
push
(
@list
,
"$table.keywordid = $id"
);
}
else
{
return
Error
(
"Unknown keyword named <code>$v</code>.\n"
.
"<P>The legal keyword names are\n"
.
"<A HREF=describekeywords.cgi>"
.
"listed here</A>.\n"
);
}
}
my
$haveawordterm
;
if
(
@list
)
{
$haveawordterm
=
"("
.
join
(
' OR '
,
@list
)
.
")"
;
if
(
$t
eq
"anywords"
)
{
$term
=
$haveawordterm
;
}
elsif
(
$t
eq
"allwords"
)
{
$ref
=
$funcsbykey
{
",$t"
};
&
$ref
;
if
(
$term
&&
$haveawordterm
)
{
$term
=
"(($term) AND $haveawordterm)"
;
}
}
}
if
(
$term
)
{
push
(
@supptables
,
"keywords $table"
);
push
(
@wherepart
,
"$table.bug_id = bugs.bug_id"
);
}
},
",equals"
=>
sub
{
$term
=
"$f = $q"
;
},
",notequals"
=>
sub
{
$term
=
"$f != $q"
;
},
",casesubstring"
=>
sub
{
$term
=
"INSTR($f, $q)"
;
},
",(substring|substr)"
=>
sub
{
$term
=
"INSTR(LOWER($f), "
.
lc
(
$q
)
.
")"
;
},
",notsubstring"
=>
sub
{
$term
=
"INSTR(LOWER($f), "
.
lc
(
$q
)
.
") = 0"
;
},
",regexp"
=>
sub
{
$term
=
"LOWER($f) REGEXP $q"
;
},
",notregexp"
=>
sub
{
$term
=
"LOWER($f) NOT REGEXP $q"
;
},
",lessthan"
=>
sub
{
$term
=
"$f < $q"
;
},
",greaterthan"
=>
sub
{
$term
=
"$f > $q"
;
},
",anyexact"
=>
sub
{
my
@list
;
foreach
my
$w
(
split
(
/,/
,
$v
))
{
if
(
$w
eq
"---"
)
{
$w
=
""
;
}
push
(
@list
,
"$f = "
.
SqlQuote
(
$w
));
}
$term
=
join
(
" OR "
,
@list
);
},
",anywords"
=>
sub
{
$term
=
join
(
" OR "
,
@
{
GetByWordList
(
$f
,
$v
)});
},
",allwords"
=>
sub
{
$term
=
join
(
" AND "
,
@
{
GetByWordList
(
$f
,
$v
)});
},
",nowords"
=>
sub
{
my
@list
=
@
{
GetByWordList
(
$f
,
$v
)};
if
(
@list
)
{
$term
=
"NOT ("
.
join
(
" OR "
,
@list
)
.
")"
;
}
},
",changedbefore"
=>
sub
{
my
$table
=
"act_$chartid"
;
my
$ftable
=
"fielddefs_$chartid"
;
push
(
@supptables
,
"bugs_activity $table"
);
push
(
@supptables
,
"fielddefs $ftable"
);
push
(
@wherepart
,
"$table.bug_id = bugs.bug_id"
);
push
(
@wherepart
,
"$table.fieldid = $ftable.fieldid"
);
$term
=
"($ftable.name = '$f' AND $table.bug_when < $q)"
;
},
",changedafter"
=>
sub
{
my
$table
=
"act_$chartid"
;
my
$ftable
=
"fielddefs_$chartid"
;
push
(
@supptables
,
"bugs_activity $table"
);
push
(
@supptables
,
"fielddefs $ftable"
);
push
(
@wherepart
,
"$table.bug_id = bugs.bug_id"
);
push
(
@wherepart
,
"$table.fieldid = $ftable.fieldid"
);
$term
=
"($ftable.name = '$f' AND $table.bug_when > $q)"
;
},
",changedto"
=>
sub
{
my
$table
=
"act_$chartid"
;
my
$ftable
=
"fielddefs_$chartid"
;
push
(
@supptables
,
"bugs_activity $table"
);
push
(
@supptables
,
"fielddefs $ftable"
);
push
(
@wherepart
,
"$table.bug_id = bugs.bug_id"
);
push
(
@wherepart
,
"$table.fieldid = $ftable.fieldid"
);
$term
=
"($ftable.name = '$f' AND $table.newvalue = $q)"
;
},
",changedby"
=>
sub
{
my
$table
=
"act_$chartid"
;
my
$ftable
=
"fielddefs_$chartid"
;
push
(
@supptables
,
"bugs_activity $table"
);
push
(
@supptables
,
"fielddefs $ftable"
);
push
(
@wherepart
,
"$table.bug_id = bugs.bug_id"
);
push
(
@wherepart
,
"$table.fieldid = $ftable.fieldid"
);
my
$id
=
DBNameToIdAndCheck
(
$v
);
$term
=
"($ftable.name = '$f' AND $table.who = $id)"
;
},
);
my
@funcnames
;
while
(
@funcdefs
)
{
my
$key
=
shift
(
@funcdefs
);
my
$value
=
shift
(
@funcdefs
);
if
(
$key
=~
/^[^,]*$/
)
{
die
"All defs in %funcs must have a comma in their name: $key"
;
}
if
(
exists
$funcsbykey
{
$key
})
{
die
"Duplicate key in %funcs: $key"
;
}
$funcsbykey
{
$key
}
=
$value
;
push
(
@funcnames
,
$key
);
}
my
$chart
=
-
1
;
my
$row
=
0
;
foreach
my
$ref
(
@specialchart
)
{
my
$col
=
0
;
while
(
@$ref
)
{
$F
{
"field$chart-$row-$col"
}
=
shift
(
@$ref
);
$F
{
"type$chart-$row-$col"
}
=
shift
(
@$ref
);
$F
{
"value$chart-$row-$col"
}
=
shift
(
@$ref
);
if
(
$debug
)
{
print
qq{<P>$F{"field$chart-$row-$col"} | $F{"type$chart-$row-$col"} | $F{"value$chart-$row-$col"}*\n}
;
}
$col
++
;
}
$row
++
;
}
for
(
$chart
=-
1
;
$chart
<
0
||
exists
$F
{
"field$chart-0-0"
}
;
$chart
++
)
{
$chartid
=
$chart
>=
0
?
$chart
:
""
;
for
(
my
$row
=
0
;
exists
$F
{
"field$chart-$row-0"
}
;
$row
++
)
{
my
@orlist
;
for
(
my
$col
=
0
;
exists
$F
{
"field$chart-$row-$col"
}
;
$col
++
)
{
$f
=
$F
{
"field$chart-$row-$col"
}
||
"noop"
;
$t
=
$F
{
"type$chart-$row-$col"
}
||
"noop"
;
$v
=
$F
{
"value$chart-$row-$col"
};
$v
=
""
if
!
defined
$v
;
$v
=
trim
(
$v
);
if
(
$f
eq
"noop"
||
$t
eq
"noop"
||
$v
eq
""
)
{
next
;
}
$q
=
SqlQuote
(
$v
);
my
$func
;
$term
=
undef
;
foreach
my
$key
(
@funcnames
)
{
if
(
"$f,$t"
=~
m/$key/
)
{
my
$ref
=
$funcsbykey
{
$key
};
if
(
$debug
)
{
print
"<P>$key ($f , $t ) => "
;
}
&
$ref
;
if
(
$debug
)
{
print
"$f , $t , $term"
;
}
if
(
$term
)
{
last
;
}
}
}
if
(
$term
)
{
push
(
@orlist
,
$term
);
}
else
{
my
$errstr
=
"Can't seem to handle "
.
qq{'<code>$F{"field$chart-$row-$col"}</code>' and }
.
qq{'<code>$F{"type$chart-$row-$col"}</code>' }
.
"together"
;
die
"Internal error: $errstr"
if
$chart
<
0
;
return
Error
(
$errstr
);
}
}
if
(
@orlist
)
{
push
(
@andlist
,
"("
.
join
(
" OR "
,
@orlist
)
.
")"
);
}
}
}
my
%
suppseen
=
(
"bugs"
=>
1
);
my
$suppstring
=
"bugs"
;
foreach
my
$str
(
@supptables
)
{
if
(
!
$suppseen
{
$str
})
{
if
(
$str
!~
/^LEFT JOIN/i
)
{
$suppstring
.=
","
;
}
$suppstring
.=
" $str"
;
$suppseen
{
$str
}
=
1
;
}
}
my
$query
=
(
"SELECT "
.
join
(
', '
,
@fields
)
.
" FROM $suppstring"
.
" WHERE "
.
join
(
' AND '
,
(
@wherepart
,
@andlist
))
.
" GROUP BY bugs.bug_id"
);
if
(
$debug
)
{
print
"<P><CODE>"
.
value_quote
(
$query
)
.
"</CODE><P>\n"
;
exit
();
}
return
$query
;
}
sub
LookupNamedQuery
{
my
(
$name
)
=
(
@_
);
confirm_login
();
...
...
@@ -164,7 +712,6 @@ OK, you have a new query named <code>$name</code>
}
my
$serverpush
=
0
;
if
(
$ENV
{
'HTTP_USER_AGENT'
}
=~
/Mozilla.[3-9]/
&&
$ENV
{
'HTTP_USER_AGENT'
}
!~
/[Cc]ompatible/
)
{
# Search for real Netscape 3 and up. http://www.browsercaps.org used as source of
# browsers compatbile with server-push. It's a Netscape hack, incompatbile
...
...
@@ -205,9 +752,11 @@ DefCol("severity", "substring(bugs.bug_severity, 1, 3)", "Sev",
DefCol
(
"priority"
,
"substring(bugs.priority, 1, 3)"
,
"Pri"
,
"bugs.priority"
);
DefCol
(
"platform"
,
"substring(bugs.rep_platform, 1, 3)"
,
"Plt"
,
"bugs.rep_platform"
);
DefCol
(
"owner"
,
"assign.login_name"
,
"Owner"
,
"assign.login_name"
);
DefCol
(
"reporter"
,
"report.login_name"
,
"Reporter"
,
"report.login_name"
);
DefCol
(
"qa_contact"
,
"qacont.login_name"
,
"QAContact"
,
"qacont.login_name"
);
DefCol
(
"owner"
,
"map_assigned_to.login_name"
,
"Owner"
,
"map_assigned_to.login_name"
);
DefCol
(
"reporter"
,
"map_reporter.login_name"
,
"Reporter"
,
"map_reporter.login_name"
);
DefCol
(
"qa_contact"
,
"map_qa_contact.login_name"
,
"QAContact"
,
"map_qa_contact.login_name"
);
DefCol
(
"status"
,
"substring(bugs.bug_status,1,4)"
,
"State"
,
"bugs.bug_status"
);
DefCol
(
"resolution"
,
"substring(bugs.resolution,1,4)"
,
"Result"
,
"bugs.resolution"
);
...
...
@@ -233,16 +782,7 @@ if (defined $::COOKIE{'COLUMNLIST'}) {
my
$minvotes
;
if
(
defined
$::FORM
{
'votes'
})
{
my
$c
=
trim
(
$::FORM
{
'votes'
});
if
(
$c
ne
""
)
{
if
(
$c
!~
/^[0-9]*$/
)
{
print
"\n\n<P>The 'At least ___ votes' field must be a simple "
;
print
"number. You entered \"$c\", which doesn't cut it."
;
print
"<P>Please click the <B>Back</B> button and try again.\n"
;
PutFooter
();
exit
;
}
$minvotes
=
$c
;
if
(
trim
(
$::FORM
{
'votes'
})
ne
""
)
{
if
(
!
(
grep
{
/^votes$/
}
@collist
))
{
push
(
@collist
,
'votes'
);
}
...
...
@@ -259,36 +799,20 @@ if ($dotweak) {
}
my
$query
=
"select bugs.bug_id, bugs.groupset"
;
my
@fields
=
(
"bugs.bug_id"
,
"bugs.groupset"
)
;
foreach
my
$c
(
@collist
)
{
if
(
exists
$::needquote
{
$c
})
{
$query
.=
",
\t$::key{$c}"
;
push
(
@fields
,
"$::key{$c}"
);
}
}
if
(
$dotweak
)
{
$query
.=
",
bugs.product,
bugs.bug_status"
;
push
(
@fields
,
"bugs.product"
,
"bugs.bug_status"
);
}
$query
.=
"
from bugs,
profiles assign,
profiles report
left join profiles qacont on bugs.qa_contact = qacont.userid,
versions projector
where bugs.assigned_to = assign.userid
and bugs.reporter = report.userid
and bugs.product = projector.program
and bugs.version = projector.value
and bugs.groupset & $::usergroupset = bugs.groupset
"
;
if
(
$::FORM
{
'regetlastlist'
})
{
if
(
!
$::COOKIE
{
'BUGLIST'
})
{
...
...
@@ -309,332 +833,11 @@ query. You will have to start over at the <A HREF="query.cgi">query page</A>.
url_quote
(
$::FORM
{
'order'
});
}
if
((
defined
$::FORM
{
'emailcc1'
}
&&
$::FORM
{
'emailcc1'
})
||
(
defined
$::FORM
{
'emailcc2'
}
&&
$::FORM
{
'emailcc2'
}))
{
# We need to poke into the CC table. Do weird SQL left join stuff so that
# we can look in the CC table, but won't reject any bugs that don't have
# any CC fields.
$query
=~
s/bugs,/bugs left join cc on bugs.bug_id = cc.bug_id left join profiles ccname on cc.who = ccname.userid,/
;
}
my
$needlongdescs
=
0
;
# Whether we need to patch in the longdescs
# table.
if
(
$::MFORM
{
'bug_id'
})
{
my
@list
=
grep
(
!
/^$/
,
split
(
/[^0-9]+/
,
join
(
','
,
@
{
$::MFORM
{
'bug_id'
}})));
if
(
@list
)
{
my
$verb
=
"IN"
;
if
(
$::FORM
{
'bugidtype'
}
&&
$::FORM
{
'bugidtype'
}
eq
'exclude'
)
{
$verb
=
"NOT IN"
;
}
$query
.=
" AND bugs.bug_id $verb ("
.
join
(
','
,
@list
)
.
") "
;
}
}
if
(
defined
$::FORM
{
'sql'
})
{
$query
.=
"and (\n$::FORM{'sql'}\n)"
}
else
{
my
@legal_fields
=
(
"product"
,
"version"
,
"rep_platform"
,
"op_sys"
,
"bug_status"
,
"resolution"
,
"priority"
,
"bug_severity"
,
"assigned_to"
,
"reporter"
,
"component"
,
"target_milestone"
,
"groupset"
);
foreach
my
$field
(
keys
%::
FORM
)
{
my
$or
=
""
;
if
(
lsearch
(
\
@legal_fields
,
$field
)
!=
-
1
&&
$::FORM
{
$field
}
ne
""
)
{
$query
.=
"\tand (\n"
;
if
(
$field
eq
"assigned_to"
||
$field
eq
"reporter"
)
{
foreach
my
$p
(
split
(
/,/
,
$::FORM
{
$field
}))
{
my
$whoid
=
DBNameToIdAndCheck
(
$p
);
$query
.=
"\t\t${or}bugs.$field = $whoid\n"
;
$or
=
"or "
;
}
}
else
{
my
$ref
=
$::MFORM
{
$field
};
foreach
my
$v
(
@$ref
)
{
if
(
$v
eq
"(empty)"
)
{
$query
.=
"\t\t${or}bugs.$field is null\n"
;
}
else
{
if
(
$v
eq
"---"
)
{
$query
.=
"\t\t${or}bugs.$field = ''\n"
;
}
else
{
$query
.=
"\t\t${or}bugs.$field = "
.
SqlQuote
(
$v
)
.
"\n"
;
}
}
$or
=
"or "
;
}
}
$query
.=
"\t)\n"
;
}
}
}
if
(
$::FORM
{
'keywords'
})
{
GetVersionTable
();
my
@list
;
foreach
my
$v
(
split
(
/[\s,]+/
,
$::FORM
{
'keywords'
}))
{
if
(
$v
eq
''
)
{
next
;
}
my
$id
=
$::keywordsbyname
{
$v
};
if
(
$id
)
{
push
(
@list
,
"keywords.keywordid = $id"
);
}
else
{
print
"Unknown keyword named <code>$v</code>.\n"
;
print
"<P>The legal keyword names are <A HREF=describekeywords.cgi>"
;
print
"listed here</A>.\n"
;
print
"<P>Please click the <B>Back</B> button and try again.\n"
;
PutFooter
();
exit
;
}
}
if
(
@list
)
{
$query
=~
s/where/, keywords where/
;
my
$type
=
$::FORM
{
'keywords_type'
};
my
$notopt
=
""
;
if
(
$type
eq
"nowords"
)
{
# Ought to take advantage of keyword table somehow! ###
my
$extra
=
GetByWordList
(
"bugs.keywords"
,
$::FORM
{
'keywords'
},
"or"
);
$extra
=~
s/AND/AND NOT/i
;
$query
.=
$extra
;
}
else
{
$query
.=
"and keywords.bug_id = bugs.bug_id and $notopt ("
.
join
(
" or "
,
@list
)
.
")\n"
;
if
(
$type
eq
"allwords"
)
{
# This needs to be tuned to take better advantage of the
# keyword table!
$query
.=
GetByWordList
(
"bugs.keywords"
,
$::FORM
{
'keywords'
},
"and"
);
}
}
}
}
foreach
my
$id
(
"1"
,
"2"
)
{
if
(
!
defined
(
$::FORM
{
"email$id"
}))
{
next
;
}
my
$email
=
trim
(
$::FORM
{
"email$id"
});
if
(
$email
eq
""
)
{
next
;
}
my
$qemail
=
SqlQuote
(
$email
);
my
$type
=
$::FORM
{
"emailtype$id"
};
my
$emailid
;
if
(
$type
eq
"exact"
)
{
$emailid
=
DBNameToIdAndCheck
(
$email
);
}
my
$foundone
=
0
;
my
$lead
=
"and (\n"
;
foreach
my
$field
(
"assigned_to"
,
"reporter"
,
"cc"
,
"qa_contact"
,
"longdesc"
)
{
my
$doit
=
$::FORM
{
"email$field$id"
};
if
(
!
$doit
)
{
next
;
}
$foundone
=
1
;
my
$table
;
if
(
$field
eq
"assigned_to"
)
{
$table
=
"assign"
;
}
elsif
(
$field
eq
"reporter"
)
{
$table
=
"report"
;
}
elsif
(
$field
eq
"qa_contact"
)
{
$table
=
"qacont"
;
}
elsif
(
$field
eq
"longdesc"
)
{
$table
=
"longdescname"
;
$needlongdescs
=
1
;
}
else
{
$table
=
"ccname"
;
}
if
(
$type
eq
"exact"
)
{
if
(
$field
eq
"cc"
)
{
$query
.=
"\t$lead cc.who = $emailid\n"
;
}
elsif
(
$field
eq
"longdesc"
)
{
$query
.=
"\t$lead longdescs.who = $emailid\n"
;
}
else
{
$query
.=
"\t$lead $field = $emailid\n"
;
}
}
elsif
(
$type
eq
"regexp"
)
{
$query
.=
"\t$lead $table.login_name regexp $qemail\n"
;
}
elsif
(
$type
eq
"notregexp"
)
{
$query
.=
"\t$lead $table.login_name not regexp $qemail\n"
;
}
else
{
$query
.=
"\t$lead instr($table.login_name, $qemail)\n"
;
}
$lead
=
" or "
;
}
if
(
!
$foundone
)
{
print
"\n\n<P>You must specify one or more fields in which to search for <tt>$email</tt>.\n"
;
print
"<P>Please click the <B>Back</B> button and try again.\n"
;
PutFooter
();
exit
;
}
if
(
$lead
eq
" or "
)
{
$query
.=
")\n"
;
}
}
if
(
defined
$::FORM
{
'changedin'
})
{
my
$c
=
trim
(
$::FORM
{
'changedin'
});
if
(
$c
ne
""
)
{
if
(
$c
!~
/^[0-9]*$/
)
{
print
"\n\n<P>The 'changed in last ___ days' field must be a simple "
;
print
"number. You entered \"$c\", which doesn't cut it."
;
print
"<P>Please click the <B>Back</B> button and try again.\n"
;
PutFooter
();
exit
;
}
$query
.=
"and to_days(now()) - to_days(bugs.delta_ts) <= $c "
;
}
}
if
(
defined
$minvotes
)
{
$query
.=
"and votes >= $minvotes "
;
}
my
$ref
=
$::MFORM
{
'chfield'
};
sub
SqlifyDate
{
my
(
$str
)
=
(
@_
);
if
(
!
defined
$str
)
{
$str
=
""
;
}
my
$date
=
str2time
(
$str
);
if
(
!
defined
$date
)
{
print
"\n\n<P>The string '<tt>$str</tt>' is not a legal date.\n"
;
print
"<P>Please click the <B>Back</B> button and try again.\n"
;
PutFooter
();
exit
;
}
return
time2str
(
"'%Y/%m/%d %H:%M:%S'"
,
$date
);
}
if
(
defined
$ref
)
{
my
$which
=
lsearch
(
$ref
,
"[Bug creation]"
);
if
(
$which
>=
0
)
{
splice
(
@$ref
,
$which
,
1
);
$query
.=
"and bugs.creation_ts >= "
.
SqlifyDate
(
$::FORM
{
'chfieldfrom'
})
.
"\n"
;
my
$to
=
$::FORM
{
'chfieldto'
};
if
(
defined
$to
)
{
$to
=
trim
(
$to
);
if
(
$to
ne
""
&&
$to
!~
/^now$/i
)
{
$query
.=
"and bugs.creation_ts <= "
.
SqlifyDate
(
$to
)
.
"\n"
;
}
}
}
}
my
$query
=
GenerateSQL
(
\
@fields
,
undef
,
undef
,
$::buffer
);
if
(
defined
$ref
&&
0
<
@$ref
)
{
# Do surgery on the query to tell it to patch in the bugs_activity
# table.
$query
=~
s/where/, bugs_activity where/
;
my
@list
;
foreach
my
$f
(
@$ref
)
{
push
(
@list
,
"\nbugs_activity.fieldid = "
.
GetFieldID
(
$f
));
}
$query
.=
"and bugs_activity.bug_id = bugs.bug_id and ("
.
join
(
' or '
,
@list
)
.
") "
;
$query
.=
"and bugs_activity.bug_when >= "
.
SqlifyDate
(
$::FORM
{
'chfieldfrom'
})
.
"\n"
;
my
$to
=
$::FORM
{
'chfieldto'
};
if
(
defined
$to
)
{
$to
=
trim
(
$to
);
if
(
$to
ne
""
&&
$to
!~
/^now$/i
)
{
$query
.=
"and bugs_activity.bug_when <= "
.
SqlifyDate
(
$to
)
.
"\n"
;
}
}
my
$value
=
$::FORM
{
'chfieldvalue'
};
if
(
defined
$value
)
{
$value
=
trim
(
$value
);
if
(
$value
ne
""
)
{
$query
.=
"and bugs_activity.newvalue = "
.
SqlQuote
(
$value
)
.
"\n"
;
}
}
}
sub
GetByWordList
{
my
(
$field
,
$strs
,
$verb
)
=
(
@_
);
my
@list
;
foreach
my
$w
(
split
(
/[\s,]+/
,
$strs
))
{
my
$word
=
$w
;
if
(
$word
ne
""
)
{
$word
=~
tr
/A-Z/
a
-
z
/
;
$word
=
SqlQuote
(
quotemeta
(
$word
));
$word
=~
s/^'//
;
$word
=~
s/'$//
;
$word
=
'(^|[^a-z0-9])'
.
$word
.
'($|[^a-z0-9])'
;
push
(
@list
,
"lower($field) regexp '$word'"
);
}
}
if
(
0
==
@list
)
{
return
""
;
}
return
"and ("
.
join
(
" $verb "
,
@list
)
.
")\n"
;
}
foreach
my
$f
(
"short_desc"
,
"long_desc"
,
"bug_file_loc"
,
"status_whiteboard"
)
{
if
(
defined
$::FORM
{
$f
})
{
my
$s
=
trim
(
$::FORM
{
$f
});
if
(
$s
ne
""
)
{
my
$n
=
$f
;
my
$q
=
SqlQuote
(
$s
);
my
$type
=
$::FORM
{
$f
.
"_type"
};
if
(
$f
eq
"long_desc"
)
{
$needlongdescs
=
1
;
# Patch in the longdescs table.
$query
.=
"and longdescs.bug_id = bugs.bug_id\n"
;
$n
=
"longdescs.thetext"
;
}
if
(
$type
eq
"regexp"
)
{
$query
.=
"and $n regexp $q\n"
;
}
elsif
(
$type
eq
"notregexp"
)
{
$query
.=
"and $n not regexp $q\n"
;
}
elsif
(
$type
eq
"casesubstring"
)
{
$query
.=
"and instr($n, $q)\n"
;
}
elsif
(
$type
eq
"allwords"
)
{
$query
.=
GetByWordList
(
$n
,
$s
,
"and"
);
}
elsif
(
$type
eq
"anywords"
)
{
$query
.=
GetByWordList
(
$n
,
$s
,
"or"
);
}
else
{
$query
.=
"and instr(lower($n), lower($q))\n"
;
}
}
}
}
if
(
$needlongdescs
)
{
$query
=~
s/where/, longdescs left join profiles longdescname on longdescs.who = longdescname.userid where/
;
$query
.=
" AND longdescs.bug_id = bugs.bug_id "
;
}
$query
.=
"group by bugs.bug_id\n"
;
if
(
$::COOKIE
{
'LASTORDER'
})
{
if
((
!
$::FORM
{
'order'
})
||
$::FORM
{
'order'
}
=~
/^reuse/i
)
{
...
...
@@ -644,9 +847,12 @@ if ($::COOKIE{'LASTORDER'}) {
if
(
defined
$::FORM
{
'order'
}
&&
$::FORM
{
'order'
}
ne
""
)
{
$query
.=
"
order by
"
;
$query
.=
"
ORDER BY
"
;
$::FORM
{
'order'
}
=~
s/votesum/bugs.votes/
;
# Silly backwards compatability
# hack.
$::FORM
{
'order'
}
=~
s/assign\.login_name/map_assigned_to.login_name/g
;
# Another backwards compatability hack.
ORDER:
for
(
$::FORM
{
'order'
})
{
/\./
&&
do
{
# This (hopefully) already has fieldnames in it, so we're done.
...
...
@@ -661,18 +867,18 @@ if (defined $::FORM{'order'} && $::FORM{'order'} ne "") {
last
ORDER
;
};
/Assign/
&&
do
{
$::FORM
{
'order'
}
=
"
assign
.login_name, bugs.bug_status, priority, bugs.bug_id"
;
$::FORM
{
'order'
}
=
"
map_assigned_to
.login_name, bugs.bug_status, priority, bugs.bug_id"
;
last
ORDER
;
};
# DEFAULT
$::FORM
{
'order'
}
=
"bugs.bug_status, bugs.priority,
assign
.login_name, bugs.bug_id"
;
$::FORM
{
'order'
}
=
"bugs.bug_status, bugs.priority,
map_assigned_to
.login_name, bugs.bug_id"
;
}
$query
.=
$::FORM
{
'order'
};
}
if
(
$::FORM
{
'debug'
}
&&
$serverpush
)
{
print
"<P
RE>$query</PRE
>\n"
;
print
"<P
><CODE>"
.
value_quote
(
$query
)
.
"</CODE><P
>\n"
;
}
...
...
@@ -866,7 +1072,7 @@ print "
<B>"
.
time2str
(
"%a %b %e %T %Z %Y"
,
time
())
.
"</B>"
;
if
(
defined
$::FORM
{
'debug'
})
{
print
"<P
RE>$query</PRE
>\n"
;
print
"<P
><CODE>"
.
value_quote
(
$query
)
.
"</CODE><P
>\n"
;
}
if
(
$toolong
)
{
...
...
checksetup.pl
View file @
8fdb0d36
...
...
@@ -882,19 +882,24 @@ AddFDef("short_desc", "Summary", 1);
AddFDef
(
"product"
,
"Product"
,
1
);
AddFDef
(
"version"
,
"Version"
,
1
);
AddFDef
(
"rep_platform"
,
"Platform"
,
1
);
AddFDef
(
"bug_file_loc"
,
"URL"
,
1
);
AddFDef
(
"op_sys"
,
"OS/Version"
,
1
);
AddFDef
(
"bug_status"
,
"Status"
,
1
);
AddFDef
(
"status_whiteboard"
,
"Status Whiteboard"
,
1
);
AddFDef
(
"keywords"
,
"Keywords"
,
1
);
AddFDef
(
"resolution"
,
"Resolution"
,
1
);
AddFDef
(
"bug_severity"
,
"Severity"
,
1
);
AddFDef
(
"priority"
,
"Priority"
,
1
);
AddFDef
(
"component"
,
"Component"
,
1
);
AddFDef
(
"assigned_to"
,
"AssignedTo"
,
1
);
AddFDef
(
"reporter"
,
"ReportedBy"
,
1
);
AddFDef
(
"votes"
,
"Votes"
,
0
);
AddFDef
(
"qa_contact"
,
"QAContact"
,
0
);
AddFDef
(
"cc"
,
"CC"
,
0
);
AddFDef
(
"dependson"
,
"BugsThisDependsOn"
,
0
);
AddFDef
(
"blocked"
,
"OtherBugsDependingOnThis"
,
0
);
AddFDef
(
"target_milestone"
,
"Target Milestone"
,
0
);
AddFDef
(
"longdesc"
,
"Comment"
,
0
);
...
...
query.cgi
View file @
8fdb0d36
...
...
@@ -468,7 +468,7 @@ print "
</td>
<td align=left valign=top>
@{[make_selection_widget(\"platform\",\@::legal_platform,$default{'platform'}, $type{'platform'}, 1)]}
@{[make_selection_widget(\"
rep_
platform\",\@::legal_platform,$default{'platform'}, $type{'platform'}, 1)]}
</td>
<td align=left valign=top>
...
...
@@ -663,6 +663,104 @@ print "
<p>
"
;
my
@fields
;
push
(
@fields
,
[
"noop"
,
"---"
]);
SendSQL
(
"SELECT name, description FROM fielddefs ORDER BY sortkey"
);
while
(
MoreSQLData
())
{
my
(
$name
,
$description
)
=
(
FetchSQLData
());
push
(
@fields
,
[
$name
,
$description
]);
}
my
@types
=
(
[
"noop"
,
"---"
],
[
"equals"
,
"equal to"
],
[
"notequals"
,
"not equal to"
],
[
"casesubstring"
,
"contains (case-sensitive) substring"
],
[
"substring"
,
"contains (case-insensitive) substring"
],
[
"notsubstring"
,
"does not contain (case-insensitive) substring"
],
[
"regexp"
,
"contains regexp"
],
[
"notregexp"
,
"does not contain regexp"
],
[
"lessthan"
,
"less than"
],
[
"greaterthan"
,
"greater than"
],
[
"anywords"
,
"any words"
],
[
"allwords"
,
"all words"
],
[
"nowords"
,
"none of the words"
],
[
"changedbefore"
,
"changed before"
],
[
"changedafter"
,
"changed after"
],
[
"changedto"
,
"changed to"
],
[
"changedby"
,
"changed by"
],
);
foreach
my
$cmd
(
grep
(
/^cmd-/
,
keys
(
%::
FORM
)))
{
if
(
$cmd
=~
/^cmd-add(\d+)-(\d+)-(\d+)$/
)
{
$::FORM
{
"field$1-$2-$3"
}
=
"xyzzy"
;
}
}
# foreach my $i (sort(keys(%::FORM))) {
# print "$i : " . value_quote($::FORM{$i}) . "<BR>\n";
# }
if
(
!
exists
$::FORM
{
'field0-0-0'
})
{
$::FORM
{
'field0-0-0'
}
=
"xyzzy"
;
}
print
qq{<A NAME="chart"> </A>\n}
;
my
$chart
;
for
(
$chart
=
0
;
exists
$::FORM
{
"field$chart-0-0"
}
;
$chart
++
)
{
my
@rows
;
my
$row
;
for
(
$row
=
0
;
exists
$::FORM
{
"field$chart-$row-0"
}
;
$row
++
)
{
my
@cols
;
my
$col
;
for
(
$col
=
0
;
exists
$::FORM
{
"field$chart-$row-$col"
}
;
$col
++
)
{
my
$key
=
"$chart-$row-$col"
;
my
$deffield
=
$::FORM
{
"field$key"
}
||
""
;
my
$deftype
=
$::FORM
{
"type$key"
}
||
""
;
my
$defvalue
=
value_quote
(
$::FORM
{
"value$key"
}
||
""
);
my
$line
=
""
;
$line
.=
"<TD>"
;
$line
.=
BuildPulldown
(
"field$key"
,
\
@fields
,
$deffield
);
$line
.=
BuildPulldown
(
"type$key"
,
\
@types
,
$deftype
);
$line
.=
qq{<INPUT NAME="value$key" VALUE="$defvalue">}
;
$line
.=
"</TD>\n"
;
push
(
@cols
,
$line
);
}
push
(
@rows
,
"<TR>"
.
join
(
qq{<TD ALIGN="center"> or </TD>\n}
,
@cols
)
.
qq{<TD><INPUT TYPE="submit" VALUE="Or" NAME="cmd-add$chart-$row-$col"></TD></TR>}
);
}
print
qq{
<HR>
<TABLE>
}
;
print
join
(
'<TR><TD>And</TD></TR>'
,
@rows
);
print
qq{
<TR><TD><INPUT TYPE="submit" VALUE="And" NAME="cmd-add$chart-$row-0">
}
;
my
$n
=
$chart
+
1
;
if
(
!
exists
$::FORM
{
"field$n-0-0"
})
{
print
qq{
<INPUT TYPE="submit" VALUE="Add another boolean chart" NAME="cmd-add$n-0-0">
<NOBR><A HREF="booleanchart.html">What is this stuff?</A></NOBR>
}
;
}
print
qq{
</TD>
</TR>
</TABLE>
}
;
}
print
qq{<HR>}
;
if
(
!
$userid
)
{
print
qq{<INPUT TYPE="hidden" NAME="cmdtype" VALUE="doit">}
;
}
else
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment