Pm/Bc_misc.pm
1453 lines of code
1
package Bc_misc;
2
3
#/
4
# a module for miscellaneous subroutines
5
#  
6
# <table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td align=center><table class=error cellpadding=0 cellspacing=0><tr><td align=center>This is base code<hr style='background-image: none; background-color: #FF0000; width: 50%;'></td></tr><tr><td align=center><b>do not</b> include any use statements like<br><i>use Pm::Bc_chef</i></td></tr></table></td></tr></table>
7
#/
8
9
#CHLOG
10
# CHANGE LOG
11
# ==========
12
#   - May 12, 2021
13
#      - Added change log
14
#      - Tweaked a few subroutine descriptions
15
#CHLOG
16
17
use strict;
18
use warnings;
19
use CGI::Carp qw(fatalsToBrowser);
20
use Exporter;
21
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
22
use CGI;
23
use URI::Escape;
24
use HTML::Clean;
25
use HTML::Restrict;
26
use File::Basename;
27
28
$VERSION     = 1.00;
29
@ISA         = qw(Exporter);
30
@EXPORT = qw(
31
             get_param
32
             referrer
33
             add_param
34
             shorten_str
35
             spaces
36
37
             $COOL_DOT
38
             $cgi
39
            );
40
@EXPORT_OK   = qw(
41
                  _tests
42
43
                  a_number
44
                  a_or_an
45
                  add_numeric_suffix
46
                  add_param
47
                  add_zeros
48
49
                  byte_count
50
51
                  clear_spaces
52
                  commafied
53
54
                  fixthe
55
56
                  get_param
57
                  get_param_unfiltered
58
                  get_params
59
                  get_params_asArray
60
                  get_params_asHash
61
                  get_salt
62
63
                  hexDigit2Dec
64
65
                  isa_ArrayRef
66
                  isa_HashRef
67
68
                  minify_js
69
                  modulo
70
71
                  new_id
72
73
                  pluralize
74
                  pluralizable
75
76
                  random_numbers
77
                  redact
78
                  referrer
79
                  remove_param
80
81
                  shorten_str
82
                  spaces
83
84
                  to_hash
85
86
                  sanitize
87
88
                  valid_hex
89
90
                  word_as_possessive
91
92
                  $COOL_DOT
93
                  $cgi
94
                 );
95
96
97
########################
98
our $COOL_DOT = "•";
99
our $cgi = new CGI;
100
########################
101
102
########################
103
104
my $DEBUG_SPACES = 0;
105
106
########################
107
sub get_salt() {
108
  #*
109
  # generates a string of two random characters for use in encrypting pwords
110
  #*
111
  #@_; # (no parameters)
112
  my $rv = join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64];
113
114
  return $rv; # a scalar
115
  #usage: my $salt = get_salt(); # can return stuff like "9." as the "salt"
116
}
117
118
########################
119
sub a_or_an($) {
120
  #*
121
  # prepends "an" or "a" (and a space) to a word
122
  # this function does not look at digits (like 18 or 80)
123
  #*
124
  my ($word) = @_; # the word
125
  my $an = "a";
126
  if ($word =~ /^[aeiouh]/i) {
127
    if ($word !~ /heterosexual|^[1-7]|^9/i) {
128
      $an .= "n";
129
    }
130
  }
131
132
  return "$an $word"; # a scalar
133
  #usage: my $sentence = "I have " . a_or_an($word) . " for lunch!";
134
}
135
136
########################
137
sub add_numeric_suffix($) {
138
  #*
139
  # adds <b>st</b>, <b>nd</b>, <b>rd</b>, or <b>th</b> to a number
140
  #*
141
  my ($num) = @_; # the number to amend
142
143
  # first, let's remove all leading 0's.
144
  $num =~ s/^(0)*//;
145
  if ($num) {
146
    if ($num =~ /1[1|2|3]$/) { $num .= "th"; }
147
    elsif ($num =~ /1$/) { $num .= "st"; }
148
    elsif ($num =~ /2$/) { $num .= "nd"; }
149
    elsif ($num =~ /3$/) { $num .= "rd"; }
150
    else { $num .= "th"; }
151
  } else {
152
    $num = "0";
153
  }
154
155
  return $num; # scalar format of your number with a suffix (st, nd, rd, th)
156
  #usage: my $num = add_numeric_suffix(18);
157
}
158
159
##############################
160
sub add_zeros($) {
161
  #*
162
  # to insert a leading zero before any number that is 0 through 9
163
  #*
164
  my ($num) = @_; # the number to modify
165
  $num =~ s/^(0)*//; # remove any leading zeros
166
  if ($num < 10 and $num >= 0) { $num = "0$num"; }
167
  if ($num eq "0") { $num = "00"; }
168
169
  return $num; # a scalar
170
  #usage: my $modded_num = add_zeros($sum_num);
171
}
172
173
########################
174
sub commafied($) {
175
  #*
176
  # to insert commas before every 3rd number (from the right)
177
  # positive or negative numbers
178
  #*
179
  my ($num) = @_; # the number to insert commas into!
180
181
  my $negative = 0;
182
  if ($num =~ /^-/) {
183
    $negative = 1;
184
    $num =~ s/^-//;
185
  }
186
  $num =~ s/^(0)*//; # strip LEADING zeros from given number!
187
  $num =~ s/0/-/g; # convert zeros to dashes because reverse and/or split like to ignore zeros!
188
189
  if ($num) {
190
    my @digits = reverse split("", $num);
191
    $num = "";
192
193
    for (my $i = 0; $i < @digits; $i += 3) {
194
      $num .= $digits[$i];
195
      if ($digits[$i+1]) { $num .= $digits[$i+1]; }
196
      if ($digits[$i+2]) { $num .= $digits[$i+2]; }
197
      if ($i < (@digits - 3)) { $num .= ","; }
198
      if ($i >= @digits) { last; }
199
    }
200
201
    #$num =~ s/,$//;
202
    $num = join("", reverse split("", $num));
203
    $num =~ s/-/0/g;
204
  }
205
206
  if ($negative) { $num = "-" . $num; }
207
208
  return $num; # a number with commas added
209
  #usage: my $prettyNum = commafied(1234567890);
210
}
211
212
########################
213
sub get_param($;$$) {
214
  #*
215
  # gets the value of a given URL parameter name
216
  #*
217
  my ($p, $escape, $noSanitize) = @_; # the URL parameter to retrieve && "uri_escape" the value && unsanitized data
218
  my $rv = "";
219
220
  if ($noSanitize)
221
    { $rv = scalar $cgi->param($p); } else
222
    { $rv = sanitize(scalar $cgi->param($p)); }
223
224
  if (not $rv) {
225
    foreach my $arg (@ARGV) {
226
      if ($arg =~ s/$p\=//) { $rv = $arg; last; }
227
    }
228
  }
229
230
  if ($rv and $escape) { $rv = uri_escape($rv); }
231
  $rv =~ s/\r//g; # remove annoying \r from $rv
232
233
  return $rv; # a scalar
234
  #usage: my $page = get_param($QUERY_PAGE, 1);
235
}
236
237
########################
238
sub modulo($$) {
239
  #*
240
  # calculate the remainder and the quotient of a given number
241
  # returns an array where element 0 is the remainder and element 1 is the quotient
242
  #*
243
  my ($number, $divisor) = @_; # the number && and what to divide the number by
244
245
  my $remainder = $number % $divisor;
246
  my $quotient = ($number - $remainder) / $divisor;
247
248
  my @modulos = ($remainder, $quotient);
249
  return @modulos; # an array containing the remainder and the quotient, respectively.
250
  #usage: my @remquo = modulo(1234567890, 123);
251
}
252
253
##############################
254
sub new_id(;$$$$) {
255
  #*
256
  # to randomly generate a multi-digit, hexidecimal "number"
257
  # specify how many digits the number should have in $numDigits
258
  # $numDigits defaults to 10 when absent or if it's < 4
259
  # $numDigits capped at 4096
260
  # $addSymbols and $wholeAlphabet effectively override hexidecimal
261
  # output
262
  #*
263
  my ($numDigits, $addSymbols, $caseSensitive, $wholeAlphabet) = @_; # number of digits to return (optional, default = 10) && add symbols to the id (optional, default = 0) && case sensitive (optional, default = 0) && use whole alphabet (optional, default = 0)
264
  if (not $numDigits or $numDigits < 4) { $numDigits = 10; }
265
  if ($numDigits > 4096) { $numDigits = 4096; }
266
  my @set = ('0' ..'9', 'A' .. 'F');
267
  if ($wholeAlphabet) { push @set, ('G' .. 'Z'); }
268
  if ($caseSensitive) {
269
     push @set, ('a' .. 'f');
270
     if ($wholeAlphabet) { push @set, ('g' .. 'z'); }
271
  }
272
  if ($addSymbols) { push @set, ('!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '=', '_', '+', '~', '`', ',', '<', '.', '>', '/', '?', '[', '{', ']', '}', ';', ':', '\'', '"', '\\', '|'); }
273
  my $uid = join '' => map $set[rand @set], 1 .. $numDigits;
274
275
  return $uid; # a scalar
276
  #usage: my $id = new_id(64);
277
}
278
279
########################
280
sub pluralizable($) {
281
  #*
282
  # to pluralize any given word
283
  # this will not account for ALL words!
284
  # but, it will try.<br>
285
286
  # this function is not exactly meant to be used
287
  # standalone.  it's intended for use within the
288
  # <a href="#pluralize">pluralize(...)</a> subroutine. nor is it a
289
  # spell-checker!<br>
290
291
  # this function MAY return words in all lower case
292
  # under some circumstances (like if the word is
293
  # "Child").<br>
294
295
  # pluralizable will simply pluralize a word.  the
296
  # name of this function should be changed to
297
  # <i>plural_of</i>.<br>
298
299
  # consonant y to ies
300
  # sis to ses
301
  # f to ves
302
  # us to i
303
  #*
304
  my ($word) = @_; # the word to examine
305
  my $rv = 0; # assume it can't be, because MOST words can be.
306
307
  # some words have special (??) plural versions
308
  # when adding to this list, ensure all is lower-case!
309
  my %specials = (
310
                   you => "you",
311
                   goose => "geese",
312
                   moose => "moose",
313
                   mouse => "mice",
314
                   joey => "joeys",
315
                   man => "men",
316
                   woman => "women",
317
                   child => "children",
318
                   tooth => "teeth",
319
                   foot => "feet",
320
                   person => "people",
321
                   sheep => "sheep",
322
                   fish => "fish",
323
                   deer => "deer",
324
                   species => "species",
325
                   aircraft => "aircraft",
326
                   phenomenon => "phenomena",
327
                   criterion => "criteria",
328
                   datum => "data",
329
                   cod => "cod",
330
                   salmon => "salmon",
331
                   cattle => "cattle",
332
                   scissors => "scissors",
333
                   trousers => "trousers",
334
                   pants => "pants",
335
                   jeans => "jeans",
336
337
                   roof => "roofs",
338
                   proof => "proofs",
339
                   chief => "chiefs",
340
341
                   stomach => "stomachs",
342
343
                   hero => "heroes",
344
                   potato => "potatoes",
345
                   tomato => "tomatoes",
346
                   volcano => "volcanoes",
347
348
                   is => "are",
349
                 );
350
351
  # first, check if $word isn't a special word
352
  if ($specials{lc($word)}) { $rv = $specials{lc($word)}; }
353
354
  # if $word was NOT a special word, then $rv will still be 0
355
  if (not $rv) {
356
    $rv = $word;
357
358
    if ($rv =~ /([a|e|i|o|u|h])y$/i) { $rv .= "s"; }
359
    elsif ($rv =~ /(?![a|e|i|o|u]y)y$/i) { $rv =~ s/y$/ies/i; }
360
    elsif ($rv =~ /sis$/i) { $rv =~ s/sis$/ses/i; }
361
    elsif ($rv =~ /ch$|s$|sh$|x$|z$/i) { $rv .= "es"; }
362
    elsif ($rv =~ /f$|fe$/i) { $rv =~ s/f$|fe$/ves/i; }
363
    else {
364
      $rv .= "s";
365
    }
366
  }
367
368
  return $rv; # the plural of $word
369
  #usage: print "i have 10 " . pluralizable("buddy") . "!<br>\n";
370
}
371
372
########################
373
sub pluralize($$) {
374
  #*
375
  # will pluralize a word if $num ne 1
376
  #*
377
  my ($word, $num) = @_; # the word to pluralize & a number
378
379
  # okay, the following line is for if the word ends in a consenant other than y (like library), or us (like octopus)
380
  # there ARE rules to this shit.  i'll weed them out as i go
381
382
  if ($num ne 1) {
383
    $word = pluralizable($word);
384
  }
385
386
  return $word; # your word, pluralized (perhaps)
387
  #usage: print "you have $numBuds " . pluralize("Buddy", $numBuds) . "!<br>\n";
388
}
389
390
##############################
391
sub random_numbers() {
392
  #*
393
  # to generate a random number from
394
  # 0 to 9,223,372,036,854,775,807
395
  #*
396
  #@_; # (no parameters)
397
398
  return int(rand(9223372036854775807)); # a number
399
  #usage: my $code = random_numbers();
400
}
401
402
##############################
403
sub redact($;$) {
404
  #*
405
  # to convert every character in a given string to a given
406
  # character (default is 0x25CF - a solid round dot)
407
  #
408
  # if $char eq "strike", then str gets wrapped in a
409
  #   strikethrough HTML tag, and no char replacement
410
  #   occurs.
411
  #
412
  # if $char =~ s/^CSIS,//, then
413
  #   a background and foreground colour of black, and the text
414
  #   is converted to whatever char follows "CSIS," (eg: CSIS,x)
415
  #   this character can be a space, or omitted altogether!
416
  #   the string will be shortened to 3 characters
417
  #*
418
  my ($str, $char) = @_; # the string to convert && replacement character (optional, default = 0x25CF)
419
  if (not $char) { $char = chr(0x25CF); }
420
  $str =~ s/(\n)*$//; # remove trailing new lines
421
422
  if ($char eq "strike") {
423
    $str = "<strike>$str</strike>";
424
  } elsif ($char =~ s/^CSIS,//) {
425
    if (not $char) { $char = chr(0x25CF); }
426
    # and because this is an official redaction, let's
427
    # "shorten" the string to just 3 characters!
428
    $str = shorten_str($str, 3);
429
    $str =~ s/./$char/g;
430
    if ($char eq " ") { $str =~ s/ / /g; }
431
    $str = "<font style=\"color: black !important; background-color: black !important;\">$str</font>";
432
  } else {
433
    $str =~ s/./$char/g;
434
  }
435
436
  return $str; # a scalar
437
  #usage: my $pw = redact(get_user_pw($uid), '-');
438
}
439
440
########################
441
sub shorten_str($$;$) {
442
  #*
443
  # shortens $str to $len if the length of $str > $len
444
  # optionally append an ellipsis to $str if it does get shortened
445
  # the ellipsis effectively shortens $len by 3
446
  #*
447
  my ($str, $len, $no_ellipsis) = @_; # the string to shorten && the length you want the string to be && append an ellipsis (...) or not (optional; default=0 meaning ellipsis will be added)
448
  my $rv = $str;
449
450
  # now, do we NEED to shorten $str?
451
  if (length($str) > $len) {
452
    if ($no_ellipsis) {
453
      # do NOT append "..." to $rv
454
      $rv = substr($str, 0, $len);
455
    } else {
456
      # appened "..." to $str
457
      if (length($str) > $len-3) {
458
        $rv = substr($str, 0, $len-3) . "...";
459
      }
460
    }
461
  }
462
463
  return $rv; # $str possibly shortened, with or without "..." appended
464
  #usage: my $shortened = shorten_str($str, 10);
465
}
466
467
########################
468
sub word_as_possessive($) {
469
  #*
470
  # appends ' or 's to a given $word
471
  #*
472
  my ($word) = @_; # the word to possess!
473
  if ($word =~ /s$/) {
474
    # the word ends with s
475
    $word .= "'";
476
  } else {
477
    # the word ends with something other than s
478
    $word .= "'s";
479
  }
480
481
  return $word; # the word with <b>'</b> or <b>'s</b> appended
482
  #usage: my $linkText = word_as_possessive('James') . " Profile";
483
}
484
485
########################
486
sub get_params_asHash(;$) {
487
  #*
488
  # to get the URL parameters, and package
489
  # them into a tidy hash data structure.<br>
490
491
  # where each key = param name
492
  # and value in key = param value
493
  # eg: <i>my %p = get_params_asHash();
494
  #     my $tab = $p{'tab'};</i>
495
  #*
496
  my ($separator) = @_; # separator (optional, default = &)
497
  if (not $separator) { $separator = "&"; }
498
499
  # build the hash
500
  my %hash = map { split(m'='x, $_, 2) }
501
             grep { m'='x }
502
             split(m'&'x, get_params());
503
504
  return %hash; # a hash of URL parameters
505
  #usage: my %url_params = get_params_asHash();
506
}
507
508
########################
509
sub get_params_asArray(;$) {
510
  #*
511
  # to get the URL parameters, and package
512
  # them into a cute little list of URL
513
  # parameter pairings where each element is
514
  # <i>name=value</i>
515
  #*
516
  my ($separator) = @_; # separator (optional, default = &)
517
  if (not $separator) { $separator = "&"; }
518
519
  # build the array
520
  return split('\&', get_params()); # an array
521
  #usage: my @url_params = get_params_asArray();
522
}
523
524
########################
525
sub get_params(;$) {
526
  #*
527
  # to get the URL parameters, and package
528
  # them into a handy little scalar.  each param
529
  # is separated by an "&"<br>
530
531
  # there are other functions to retrieve this
532
  # same data as a hash or an array of parameters<br>
533
534
  # URL parameters are received already escaped
535
  # for us by the client and is not directly
536
  # altered in this subroutine.
537
  #*
538
  my ($separator) = @_; # separator (optional, default = &)
539
  if (not $separator) { $separator = "&"; }
540
541
  # build the scalar
542
  my $cgi = CGI->new();
543
  my $params = join($separator, map { $_ . '=' . $cgi->param($_) } $cgi->param());
544
545
  return $params; # a scalar
546
  #usage: my $url_params = get_params();
547
}
548
549
########################
550
sub referrer() {
551
  #*
552
  # to get the referring URL
553
  # if the referring URL is empty, then <b>/</b> will
554
  # be returned
555
  #*
556
  #@_; # (no parameters)
557
  my $rv = $ENV{HTTP_REFERER};
558
  if (not $rv) { $rv = "/"; }
559
560
  return $rv; # a scalar
561
  #usage: print referrer();
562
}
563
564
########################
565
sub isHashRef($) {
566
  #*
567
  # to determine if a scalar is a hash reference, or not
568
  #*
569
  my ($candidate) = @_; # candidate reference
570
  my $rv = 0;
571
572
  if (ref $candidate eq "HASH") { $rv = 1; }
573
574
  return $rv; # 1 when it's a reference or 0 if not
575
  #usage: if (isHashRef($ref)) { print "it's a hash reference alright"; }
576
}
577
578
########################
579
sub isArrayRef($) {
580
  #*
581
  # to determine if a scalar is an array reference, or not
582
  #*
583
  my ($candidate) = @_; # candidate reference
584
  my $rv = 0;
585
586
  if (ref $candidate eq "ARRAY") { $rv = 1; }
587
588
  return $rv; # 1 when it's a reference or 0 if not
589
  #usage: if (isArrayRef($ref)) { print "it's an array reference alright"; }
590
}
591
592
########################
593
sub sanitize($) {
594
  #*
595
  # to remove only the HTML from a string
596
  # that is to say, <script> tags will be removed,
597
  # but whatever is between <script> and </script>
598
  # will not be removed.
599
  #*
600
  my ($s) = @_; # a string of text
601
  my $rv = 0;
602
603
  if ($s) {
604
    my $nohtml = HTML::Restrict->new();
605
    my $processed = $nohtml->process($s);
606
    if ($processed ne $s) { $rv = $processed; } else { $rv = $s; }
607
  }
608
609
  return $rv; # $s with HTML tags removed.
610
  #usage: my $sanitized = sanitize($input);
611
}
612
613
########################
614
sub valid_hex($) {
615
  #*
616
  # determines if an ID contains only characters used in base 15 (hex)
617
  # that is: 0-9 and A-F
618
  #*
619
  my ($s) = @_; # a string
620
  my $rv = 1;
621
622
  if ($s) {
623
    # let's do this like we do the email address check
624
    # remove valid chars, if the length of the ID is not 0
625
    # then the ID is not valid
626
    $s =~ s/[0-9]//g;
627
    $s =~ s/[a-f]//ig;
628
    if (length $s ne 0) { $rv = 0; }
629
  } else {
630
    $rv = 0;
631
  }
632
633
  return $rv; # 1 if valid, or 0 if not
634
  #usage: if (valid_id($hexNum)) { print "valid hexidecimal number"; }
635
}
636
637
########################
638
sub clear_spaces($) {
639
  #*
640
  # removes all sequences of two or more leading spaces
641
  # and every line with only \n from a given string
642
  #*
643
  my ($s) = @_; # the string to condense
644
645
  my @spaces = split("\n", $s);
646
  $s = "";
647
  foreach my $space (@spaces) {
648
    $space =~ s/^( )*//;
649
    $s .= $space . "\n";
650
  }
651
652
  return $s; # a scalar
653
  #usage: $output = clear_spaces($output);
654
}
655
656
########################
657
sub minify_js($) {
658
  #*
659
  # goal is to remove all unnecessary stuff from js code
660
  # for now, just converts all \n\n to \n
661
  #*
662
  my ($s) = @_; # the string to condense
663
  $s =~ s/\n\n/\n/g;
664
  #$s =~ s/\n/ /g; # this breaks javascript??  why?
665
666
  return $s; # a scalar with all \n's removed.
667
  #usage: $output = minify_js($output);
668
}
669
670
########################
671
sub minify_html($) {
672
  #*
673
  # goal is to remove all html from a string
674
  # for now, just returns what was passed in
675
  #*
676
  my ($s) = @_; # the string to condense
677
678
  return $s; # a scalar with all \n's removed.
679
  #usage: $output = minify_js($output);
680
}
681
682
########################
683
sub hexDigit2Dec($) {
684
  #*
685
  # converts a SINGLE hexidecimal digit to decimal
686
  # eg: <i>C --> 12</i>
687
  #*
688
  my ($digit) = @_; # the digit to convert
689
  $digit = uc($digit);
690
  if ($digit eq "A") { $digit = 10; }
691
  elsif ($digit eq "B") { $digit = 11; }
692
  elsif ($digit eq "C") { $digit = 12; }
693
  elsif ($digit eq "D") { $digit = 13; }
694
  elsif ($digit eq "E") { $digit = 14; }
695
  elsif ($digit eq "F") { $digit = 15; }
696
  elsif ($digit eq "1" or $digit eq 1) { $digit = 1; }
697
  elsif ($digit eq "2" or $digit eq 2) { $digit = 2; }
698
  elsif ($digit eq "3" or $digit eq 3) { $digit = 3; }
699
  elsif ($digit eq "4" or $digit eq 4) { $digit = 4; }
700
  elsif ($digit eq "5" or $digit eq 5) { $digit = 5; }
701
  elsif ($digit eq "6" or $digit eq 6) { $digit = 6; }
702
  elsif ($digit eq "7" or $digit eq 7) { $digit = 7; }
703
  elsif ($digit eq "8" or $digit eq 8) { $digit = 8; }
704
  elsif ($digit eq "9" or $digit eq 9) { $digit = 9; }
705
  else { $digit = 0; } # anything else will be seen as a zero
706
707
  return $digit; # hexidecimal digit converted to decimal
708
  #usage: $output = hexDigit2Dec("c");
709
}
710
711
########################
712
sub a_number($) {
713
  #*
714
  # is it a number, or not?
715
  #*
716
  my ($scalar) = @_; # the "number" to examine
717
  my $it = $scalar;
718
719
  if ($scalar) {
720
    $it =~ s/^-//;
721
722
    if ($it) {
723
      $it =~ s/[0-9]//g; # remove all digits.
724
      # if there's nothing left, it was a number
725
      if (not $it) { $it = 1; } else { $it = 0; }
726
    }
727
  } else {
728
    $it = 1;
729
  }
730
731
  return $it; # 1 when $scalar is a number, otherwise 0
732
  #usage: if (a_number('abc123')) { ... }
733
}
734
735
########################
736
sub remove_param($$) {
737
  #*
738
  # removes a parameter from a given url, if it exists
739
  # and returns the results. given url is not affected
740
  # !this is not likely bullet-proof!
741
  #*
742
  my ($p, $u) = @_; # the parameter to remove (eg: "t") && the uri to remove $p from
743
  $p =~ s/\=(.)*//; # just in case (but, a year or more later, i don't know why!)
744
  my $rv;
745
746
  my $DEBUG_REMOVE_PARAM = 0;
747
748
  # beware.  we could get just the params, or just a hash tag, or
749
  # params and a hash tag, or
750
  # a fully qualified url with or without params and/or hashtags!
751
  # so how does one split a URL into it's three major components??
752
753
  # 1 - https://www.google.ca/damn.html?bob=uncle#photos: hash is right. params contains hash.  fn is right
754
  # 2 - https://www.google.ca/damn.html?bob=uncle:        hash eq $u. params is right. fn is right.
755
  # 3 - https://www.google.ca/damn.html:                  hash, params, and fn are equal
756
  # 4 - https://www.google.ca/damn.html#photos:           hash is right. params and fn are equal and contain the hash tag
757
  # 5 - ?bob=uncle#photos:        hash is right, params contains hash, fn is empty
758
  # 6 - bob=uncle#photos          hash is right, params eq $u, fn eq $u
759
  # 7 - ?bob=uncle                hash eq $u, params is right, fn is empty
760
  # 8 - #photos                   hash is right, params eq $u, fn eq $u
761
  # 9 - bob=uncle                 hash eq $u, params eq $u, fn eq $u
762
  # 10 - photos                   hash eq $u, params eq $u, fn eq $u
763
764
  # did i get'm all?
765
  # watch this, with my luck, this site will hit one i missed!
766
767
  # so now how do we program the above???
768
769
  my $fn = $u;
770
  my $params = $u;
771
  my $hash = $u;
772
773
  $fn =~ s/\?.*//;
774
  $params =~ s/.*\?//;
775
  $hash =~ s/.*\#//;
776
777
  my $rebuild = 0;
778
  # where 0 = don't rebuild params
779
  # 1 = rebuild params
780
781
  if ($hash !~ /#/ and $params =~ /#/ and $fn !~ /#/ and $fn !~ /\?/) {
782
    # 1
783
    $rebuild = 1;
784
    $rv = 1;
785
  } elsif ($hash eq $u and $params !~ /#/ and $fn !~ /#/ and $fn !~ /\?/) {
786
    # 2
787
    $rebuild = 1;
788
    $rv = 2;
789
  } elsif ($hash eq $params and $hash eq $fn) {
790
    # 3
791
    $rv = $u;
792
  } elsif ($hash and $params eq $fn and $params =~ /#/ and $fn =~ /#/) {
793
    # 4
794
    $rebuild = 1;
795
    $rv = 4;
796
  } elsif ($hash and $params =~ /#/ and not $fn) {
797
    # 5
798
    $rebuild = 1;
799
    $rv = 5;
800
  } elsif ($hash and $params eq $u and $fn eq $u) {
801
    # 6
802
    $rebuild = 1;
803
    $rv = 6;
804
  } elsif ($hash eq $u and $params and not $fn) {
805
    # 7
806
    $rebuild = 1;
807
    $rv = 7;
808
  } elsif ($hash and $params eq $u and $fn eq $u) {
809
    # 8
810
    $rv = $u;
811
  } elsif ($hash eq $u and $params eq $u and $fn eq $u) {
812
    # 9
813
    $rebuild = 1;
814
    $rv = 9;
815
  } else {
816
    # 10, and the others i likely missed at 525am!
817
    $rv = $u;
818
  }
819
820
  if ($rebuild) {
821
    $params =~ s/\#.*//;
822
    my @params = split(/&/, $params);
823
    my @new;
824
    foreach my $param (@params) {
825
      my ($n, $v) = split(/=/, $param);
826
      if ($n ne $p) {
827
        push @new, $param;
828
      }
829
    }
830
831
    if ($fn ne $params) {
832
      if ($fn) {
833
        if ($u =~ /\?/) { $rv = $fn . "?"; } else { $rv = ""; }
834
      } else {
835
        $rv = "?";
836
      }
837
      $rv .= join("&", @new);
838
      if ($hash and $hash ne $u) { $rv .= "#" . $hash; }
839
    } else {
840
      $rv = join("&", @new);
841
      if ($hash and $hash ne $u) { $rv .= "#" . $hash; }
842
    }
843
  }
844
845
  if ($DEBUG_REMOVE_PARAM) {
846
    my $newurl = $rv;
847
    $rv .= "<br>\n";
848
    $rv .= "orig url: $u<br>\n";
849
    $rv .= "new url: $newurl<br>\n";
850
  }
851
852
  return $rv; # the URL with the parameter and associated value removed (if it existed)
853
  #usage: my $r = remove_param("t", referrer());
854
}
855
856
########################
857
sub add_param($$$) {
858
  #*
859
  # adds a parameter to a given url
860
  # if the parameter already exists, it gets overwritten
861
  # !this is not likely bullet-proof!
862
  #*
863
  my ($param, $value, $url) = @_; # the parameter to add (eg: "t") && the value of the param && the URL to add $param to
864
865
  $param =~ s/\=(.)*//; # just in case
866
  my $rv = $url;
867
868
  if ($param and $value and $url) {
869
    $url = remove_param($param, $url);
870
    if ($url =~ /\?/) {
871
      my ($url, $params) = split(/\?/, $url);
872
      if ($params) {
873
        $rv = $url . "?$params&$param=$value";
874
      } else {
875
        $rv = $url . "?$param=$value";
876
      }
877
    } else {
878
      $rv = $url . "?$param=$value";
879
    }
880
  }
881
882
  return $rv; # modified url
883
  #usage: my $r = add_param("t", "eyes", referrer());
884
}
885
886
########################
887
sub spaces($) {
888
  #*
889
  # replaces each char in a scalar with a space
890
  #*
891
  my ($s) = @_; # the string to convert
892
  my $rv = $s =~ s/./ /g;
893
894
  return $rv; # a scalar
895
  #usage: my $s = spaces("llama's eat volleyballs");
896
}
897
898
########################
899
sub lc_littlewords($) {
900
  #*
901
  # lowercases all small words
902
  # ("such", "as", "an", "and", "the", "a")
903
  #*
904
  my ($s) = @_; # the string to convert
905
  my $rv = $s;
906
907
  my @allowed = ();
908
  push @allowed, "AD";
909
  push @allowed, "AI";
910
  push @allowed, "ARQ";
911
  push @allowed, "AXL";
912
  push @allowed, "BC";
913
  push @allowed, "CD";
914
  push @allowed, "ET";
915
  push @allowed, "II";
916
  push @allowed, "III";
917
  push @allowed, "IV";
918
  push @allowed, "VI";
919
  push @allowed, "VII";
920
  push @allowed, "VIII";
921
  push @allowed, "IX";
922
  push @allowed, "XI";
923
  push @allowed, "XII";
924
  push @allowed, "XIII";
925
  push @allowed, "XIV";
926
  push @allowed, "XV";
927
  push @allowed, "LA";
928
  push @allowed, "RV";
929
  push @allowed, "USS";
930
931
  my @littlewords = ();
932
  push @littlewords, "a";
933
  push @littlewords, "am";
934
  push @littlewords, "an";
935
  push @littlewords, "and";
936
  push @littlewords, "are";
937
  push @littlewords, "as";
938
  push @littlewords, "at";
939
  push @littlewords, "be";
940
  push @littlewords, "but";
941
  push @littlewords, "by";
942
  push @littlewords, "can";
943
  push @littlewords, "do";
944
  push @littlewords, "for";
945
  push @littlewords, "from";
946
  push @littlewords, "in";
947
  push @littlewords, "is";
948
  push @littlewords, "if";
949
  push @littlewords, "it";
950
  push @littlewords, "it's";
951
  push @littlewords, "my";
952
  push @littlewords, "nor";
953
  push @littlewords, "not";
954
  push @littlewords, "of";
955
  push @littlewords, "on";
956
  push @littlewords, "or";
957
  push @littlewords, "our";
958
  push @littlewords, "so";
959
  push @littlewords, "that";
960
  push @littlewords, "the";
961
  push @littlewords, "to";
962
  push @littlewords, "what";
963
  push @littlewords, "with";
964
  push @littlewords, "yet";
965
  push @littlewords, "you";
966
967
  foreach my $word (@littlewords) {
968
    $rv =~ s/( $word )/lc($1)/egi;
969
    $rv =~ s/( $word)$/lc($1)/egi;
970
  }
971
972
  # and, uppercase certain 'words'
973
  foreach my $okword (@allowed) {
974
    $rv =~ s/( $okword )/uc($1)/egi;
975
    $rv =~ s/( $okword)$/uc($1)/egi;
976
    $rv =~ s/^($okword )/uc($1)/egi;
977
    $rv =~ s/^($okword)$/uc($1)/egi;
978
    $rv =~ s/( $okword,)/uc($1)/egi;
979
  }
980
981
  # next, sometimes, we see multiple spaces, convert them to single space
982
  $rv =~ s/ {2,}/ /g;
983
984
  # finally?  now we have special cases.  like "'Twas", and "vs"
985
  my @specials = (); # one-offs
986
  push @specials, "'Twas";
987
  push @specials, "vs";
988
989
  foreach my $special (@specials) {
990
    if ($rv =~ /$special/i) {
991
      if ($special =~ /^S\[/) {
992
        $rv =~ s/($special)/uc $1/eig;
993
      } else {
994
        $rv =~ s/($special)/$special/ig;
995
      }
996
    }
997
  }
998
999
  # and now, remove extraneous spaces
1000
  $rv =~ s/ ,/,/g; # space before comma
1001
  $rv =~ s/  / /g; # double spaces
1002
  $rv =~ s/^ +//; # leading spaces
1003
  $rv =~ s/ +$//; # trailing spaces
1004
1005
  return $rv; # a scalar
1006
  #usage: my $s = lc_littlewords("The Quick Brown Fox Jumped Over The Lazy Dog");
1007
}
1008
1009
########################
1010
sub fixthe($) {
1011
  #*
1012
  # reorganizes filename wording and casing
1013
  # moves "The" from the start of a string, adds it
1014
  # to the end of a line, preceded with a comma
1015
  # this will also change "the", "is", "by" and
1016
  # so-on anywhere else in the string to lowercase
1017
  # this will also change casing, if required, of
1018
  # Mr. and Mrs. and Dr. and so on, and retain the .
1019
  #*
1020
  my ($s) = @_; # the string to convert (avoid including a path - just a filename, please)
1021
  my $rv = "";
1022
  my $preserver = "";
1023
  if ($s =~ /^0 - /) {
1024
    # this is a folder, not a file!
1025
    $s =~ s/^0 - //;
1026
    $preserver = "0 - ";
1027
  }
1028
1029
  # second, lowercase everything
1030
  $s = lc $s;
1031
  # then uppercase only the first letter of all words
1032
  $s = join " ", map {ucfirst} split " ", $s;
1033
1034
  # okay, let's try removing brackets now...cuz it ain't workin anywhere!
1035
  $s =~ s/\(//g;
1036
  $s =~ s/\)//g;
1037
1038
  my $frontend = $s;
1039
  my $middle = $s;
1040
  my $backend = $s;
1041
  my $ext = $s;
1042
  $ext =~ s/.+\///;
1043
  if ($ext eq $s) {
1044
    $ext =~ s/.+\.//;
1045
    if ($ext eq $s) { $ext = ""; }
1046
  }
1047
1048
  $backend =~ s/\.\Q$ext//;
1049
  $backend =~ s/.* - //;
1050
  $frontend =~ s/ - .*/ - /;
1051
1052
  $middle =~ s/$frontend//;
1053
  $middle =~ s/ - \Q$backend//;
1054
1055
  if (not $middle) {
1056
    $middle = $frontend;
1057
    $frontend = "";
1058
    $backend = "";
1059
  }
1060
  $middle =~ s/\.\Q$ext//;
1061
  if ($middle eq $backend) { $middle = $frontend; $frontend = ""; }
1062
1063
  $frontend =~ s/ - //;
1064
  $middle =~ s/ - //;
1065
  $backend =~ s/ - //;
1066
1067
  if ($middle eq $backend) {
1068
    $backend = "";
1069
  } else {
1070
    if ($frontend !~ /^[0-9][0-9]/ and $frontend) {
1071
      $backend = $middle;
1072
      $middle = $frontend;
1073
      $frontend = "";
1074
      $middle =~ s/ - //;
1075
    }
1076
  }
1077
1078
  my $BUGIT = 0;
1079
  if ($BUGIT) {
1080
    my $temp = "$frontend<br>\n";
1081
    $temp .= "$middle<br>\n";
1082
    $temp .= "$backend<br>\n";
1083
    $temp .= "$ext<br>\n";
1084
1085
    return $temp; # a scalar, with debug info when debugger is on
1086
  }
1087
1088
  # now, lowercase the words that shouldn't be uppercased
1089
  $frontend = lc_littlewords($frontend);
1090
  $middle = lc_littlewords($middle);
1091
  $backend = lc_littlewords($backend);
1092
1093
  if ($middle =~ /^the /i) {
1094
    $middle =~ s/^the //i;
1095
    $middle .= ", The";
1096
  }
1097
1098
  $middle =~ s/, the$/, The/;
1099
1100
  # now, ensure each part does not begin or end with a space!
1101
  $frontend =~ s/^ +//; $frontend =~ s/ +$//;
1102
  $middle =~ s/^ +//; $middle =~ s/ +$//;
1103
  $backend =~ s/^ +//; $backend =~ s/ +$//;
1104
  $ext =~ s/^ +//; $ext =~ s/ +$//;
1105
  $ext = lc($ext);
1106
  $backend =~ s/, the$/, The/i;
1107
1108
  $rv = $frontend;
1109
  if ($frontend) {
1110
    $rv .= " - ";
1111
  }
1112
  $rv .= $middle;
1113
  if ($middle and $backend) {
1114
    $rv .= " - " . $backend;
1115
    if ($ext) { $rv .= "." . $ext; }
1116
  }
1117
1118
  if (not $frontend and not $backend and $ext) {
1119
    $rv .= "." . $ext;
1120
  } else {
1121
    if ($ext and $rv !~ /\.\Q$ext$/i and $rv !~ /\Q$s/i) {
1122
      $rv .= $middle . $backend . "." . $ext;
1123
    }
1124
  }
1125
1126
  # now, ensure mr, mrs, dr, etc are correctly formatted
1127
  # there really ought to be a list for these to loop through
1128
  $rv =~ s/^Mr /Mr. /ig;
1129
  $rv =~ s/^Mrs /Mrs. /ig;
1130
  $rv =~ s/^Ms /Ms. /ig;
1131
  $rv =~ s/^Mt /Mt. /ig;
1132
  $rv =~ s/^Dr /Dr. /ig;
1133
  $rv =~ s/ Mr / Mr. /ig;
1134
  $rv =~ s/ Mrs / Mrs. /ig;
1135
  $rv =~ s/ Ms / Ms. /ig;
1136
  $rv =~ s/ Mt / Mt. /ig;
1137
  $rv =~ s/ Dr / Dr. /ig;
1138
  $rv =~ s/ This\./ This\./ig;
1139
  $rv =~ s/ That\./ That\./ig;
1140
  $rv =~ s/ This$/ This/ig;
1141
  $rv =~ s/ That$/ That/ig;
1142
1143
  # good god, and now, words like "O'Toole" and "McMasters" and "MacDonald"?
1144
  # this would be ideal if each case were in a list.  but, that breaks somehow.
1145
  # try adding one of the below to @specials, for instance, and you shall see
1146
  # dots and brackets are taken literally, not sure why, either.
1147
  $rv =~ s/ o'(.)/" O'" . uc $1/ieg;
1148
  $rv =~ s/ mc(.)/"Mc" . uc $1/ieg;
1149
  $rv =~ s/ mac(.)/"Mac" . uc $1/ieg;
1150
  $rv =~ s/^o'(.)/"O'" . uc $1/ieg;
1151
  $rv =~ s/^mc(.)/"Mc" . uc $1/ieg;
1152
  $rv =~ s/^mac(.)/"Mac" . uc $1/ieg;
1153
1154
  # same with these...
1155
  $rv =~ s/(S[0-9][0-9])/uc $1/ieg;
1156
  $rv =~ s/(E[0-9][0-9])/uc $1/ieg;
1157
1158
  # okay, and now shit like " -," or "(.)-," gets converted to ","
1159
  # and filenames ending with " -" or " - " or "- ";
1160
  {
1161
    my $fn = $rv;
1162
    # remove the extension
1163
    $fn =~ s/\..*$//i;
1164
    my $ext = $rv;
1165
    $ext =~ s/\Q$fn//;
1166
    $ext =~ s/\.//g;
1167
    # now search and destroy the intruders!
1168
    $fn =~ s/ -,/,/g;
1169
    $fn =~ s/(.)-,/$1,/g;
1170
1171
    $fn =~ s/- $//g;
1172
    $fn =~ s/ -$//g;
1173
    $fn =~ s/ - $//g;
1174
1175
    if ($ext) { $fn .= "." . $ext; }
1176
    $rv = $fn;
1177
  }
1178
1179
  # next, search for "years", and insert a "- " before it
1180
  if ($rv =~ /[0-9][0-9][0-9][0-9]/) {
1181
    if ($rv !~ / - ([0-9][0-9][0-9][0-9])/) {
1182
      $rv =~ s/([0-9][0-9][0-9][0-9])/- $1/;
1183
    }
1184
  }
1185
1186
  # now, move year to end of line, if required
1187
  $rv =~ s/ - ([0-9][0-9][0-9][0-9]), The/, The - $1/;
1188
1189
  if ($preserver) { $rv = $preserver . $rv; }
1190
1191
  return $rv; # a scalar
1192
  #usage: my $s = fixthe("The Conjuring"); # returns "Conjuring, The"
1193
}
1194
1195
########################
1196
sub inArray($$;$$$) {
1197
  #*
1198
  # is value (exact match) in a given array
1199
  #*
1200
  my ($arrayRef, $value, $toEOL, $like, $exclude) = @_; # an array reference && a search term && match to end of line? && toggle eq/=~ && exclude value
1201
  my $rv = 0;
1202
1203
  if (ref $arrayRef eq "ARRAY") {
1204
    my $i = 1;
1205
    foreach my $v (@$arrayRef) {
1206
      my $skipThis = 0;
1207
      if ($exclude eq $v) { $skipThis = 1; }
1208
1209
      if (not $skipThis) {
1210
        if ($like) {
1211
          if ($toEOL) {
1212
            if ($v =~ /$value$/) {
1213
              $rv = $i;
1214
              last;
1215
            }
1216
          }
1217
          else {
1218
            if ($v =~ /$value/) {
1219
              $rv = $i;
1220
              last;
1221
            }
1222
          }
1223
1224
        }
1225
        else {
1226
          if ($v eq $value) {
1227
            $rv = $i;
1228
            last;
1229
          }
1230
1231
        }
1232
      }
1233
1234
      $i++;
1235
    }
1236
  }
1237
1238
  return $rv; # an array index, or -1 when not found
1239
  #usage: my $s = inArray($arrayRef, "Farm");
1240
}
1241
1242
########################
1243
sub byte_count($);
1244
sub byte_count($) {
1245
  #*
1246
  # to count the total bytes used in a data structure
1247
  #*
1248
  my ($scalar) = @_; # a scalar (generally a reference)
1249
  my $rv = 0;
1250
1251
  if (ref $scalar eq "ARRAY") {
1252
    foreach my $e (@$scalar) {
1253
      $rv += byte_count($e);
1254
    }
1255
  } elsif (ref $scalar eq "HASH") {
1256
    foreach my $key (keys %$scalar) {
1257
      $rv += byte_count($scalar->{$key});
1258
    }
1259
  } elsif (ref $scalar eq "SCALAR") {
1260
    $rv += length $$scalar;
1261
  } else {
1262
    $rv += length $scalar;
1263
  }
1264
1265
  return $rv; # a scalar
1266
  #usage: my $count = byteCount($scalar);
1267
}
1268
1269
########################
1270
########################
1271
########################
1272
########################
1273
########################
1274
########################
1275
########################
1276
########################
1277
########################
1278
########################
1279
########################
1280
########################
1281
########################
1282
########################
1283
########################
1284
########################
1285
########################
1286
########################
1287
########################
1288
########################
1289
########################
1290
1291
########################
1292
sub _tests(;$) {
1293
  #*
1294
  # to test all <i>Pm::Bc_dir</i> functions
1295
  #*
1296
  my ($extended) = @_; # show extended data (optional)
1297
  my $rv = 0;
1298
  my $test = 0;
1299
  my $test2 = 0;
1300
  my $test3 = 0;
1301
  my $test4 = 0;
1302
  my @test = ();
1303
  my @test1 = ();
1304
  my @test2 = ();
1305
  my @test3 = ();
1306
  my %test = {};
1307
1308
  if ($Bc_sql::DB) {
1309
    $test = "octopus";
1310
    $rv = Html::display_debug_one("a_or_an(\"$test\")", a_or_an($test));
1311
    $test = 1;
1312
    $rv .= Html::display_debug_one("add_numeric_suffix($test)", add_numeric_suffix($test));
1313
    $test = "01";
1314
    $rv .= Html::display_debug_one("add_zeros($test)", add_zeros($test));
1315
    $test = -1234567890;
1316
    $rv .= Html::display_debug_one("commafied(\"$test\")", commafied("$test"));
1317
    $test = 1;
1318
    $rv .= Html::display_debug_one("commafied(\"$test\")", commafied("$test"));
1319
    $test = 10;
1320
    $rv .= Html::display_debug_one("commafied(\"$test\")", commafied("$test"));
1321
    $test = 100;
1322
    $rv .= Html::display_debug_one("commafied(\"$test\")", commafied("$test"));
1323
    $test = 1000;
1324
    $rv .= Html::display_debug_one("commafied(\"$test\")", commafied("$test"));
1325
    $test = 10000;
1326
    $rv .= Html::display_debug_one("commafied(\"$test\")", commafied("$test"));
1327
    $test = 100000;
1328
    $rv .= Html::display_debug_one("commafied(\"$test\")", commafied("$test"));
1329
    $test = 1000000;
1330
    $rv .= Html::display_debug_one("commafied(\"$test\")", commafied("$test"));
1331
    $test = 10000000;
1332
    $rv .= Html::display_debug_one("commafied(\"$test\")", commafied("$test"));
1333
    $test = 1000000000000000000;
1334
    $rv .= Html::display_debug_one("commafied(\"$test\")", commafied("$test"));
1335
    $test = 1234567890;
1336
    $rv .= Html::display_debug_one("commafied(\"$test\")", commafied("$test"));
1337
1338
    $test = Bc_sql::get_constant("QUERY_DEBUG_PAGE");
1339
    $rv .= Html::display_debug_one("get_param(\"$test\")", get_param($test));
1340
1341
    $test = Bc_misc::get_params();
1342
    $rv .= Html::display_debug_one("get_params()", $test);
1343
1344
    @test = Bc_misc::get_params_asArray();
1345
    $rv .= Html::display_debug_many("get_params_asArray()", \@test, ", ");
1346
1347
    @test = ();
1348
    %test = Bc_misc::get_params_asHash();
1349
1350
    push @test, \%test;
1351
    $rv .= Html::display_debug_large("get_params_asHash()", \@test);
1352
1353
    $test = 4999;
1354
    $test2 = 100;
1355
    @test = Bc_misc::modulo($test, $test2);
1356
    $rv .= Html::display_debug_many("modulo($test, $test2)", \@test);
1357
1358
    $test2 = 24;
1359
    $test3 = new_id($test2);
1360
    $rv .= Html::display_debug_one("new_id($test2)", $test3);
1361
1362
    $test = "child";
1363
    $rv .= Html::display_debug_one("pluralizable(\"$test\")", pluralizable($test));
1364
1365
    $rv .= Html::display_debug_one("pluralize(\"$test\", $test2)", pluralize($test, $test2));
1366
1367
    $test2 = '';
1368
    $rv .= Html::display_debug_one("redact(\"$test\", \"$test2\")", redact($test, $test2));
1369
1370
    $test = 15;
1371
    $rv .= Html::display_debug_one("shorten_str('$test3', $test)", shorten_str($test3, $test));
1372
1373
    $rv .= Html::display_debug_one("shorten_str('$test3', $test, 1)", shorten_str($test3, $test, 1));
1374
1375
    $test = "octopus";
1376
    $rv .= Html::display_debug_one("word_as_possessive(\"$test\")", word_as_possessive($test));
1377
1378
    $test = "bob";
1379
    #$test2 = "https://www.google.ca/test.html?bob=uncle&betty=aunt#photos";
1380
    #$test2 = "https://www.google.ca/test.html?bob=uncle&betty=aunt";
1381
    #$test2 = "https://www.google.ca/test.html#photos";
1382
    #$test2 = "https://www.google.ca/test.html";
1383
    $test2 = "?bob=uncle&betty=aunt#photos";
1384
    #$test2 = "bob=uncle&betty=aunt#photos";
1385
    #$test2 = "photos";
1386
    #$test2 = "bob=uncle&betty=aunt#photos";
1387
    #$test2 = "#photos";
1388
    $test3 = remove_param($test, $test2);
1389
    $rv .= Html::display_debug_one("remove_param(\"$test\", \"$test2\")", $test3);
1390
1391
    $test = "t";
1392
    $test2 = "len";
1393
    $test3 = "https://night-stand.ca/?test1=1&test2=2&t=bu";
1394
    $test4 = add_param($test, $test2, $test3);
1395
    $rv .= Html::display_debug_one("add_param(\"$test\", \"$test2\", \"$test3\")", $test4);
1396
1397
    $test = "test1";
1398
    $test2 = "lovin' it!";
1399
    $test3 = "https://night-stand.ca/?test1=1&test2=2&t=bu";
1400
    $test4 = add_param($test, $test2, $test3);
1401
    $rv .= Html::display_debug_one("add_param(\"$test\", \"$test2\", \"$test3\")", $test4);
1402
1403
    $test = referrer();
1404
    $rv .= Html::display_debug_one("referrer()", $test);
1405
1406
    $test = "98 - The Exciting adventures OF THE batman - Part MCXIX.mp4";
1407
    $test2 = fixthe($test);
1408
    $rv .= Html::display_debug_one("fixthe(\"$test\")", $test2);
1409
1410
    $test = "The Exciting adventures OF THE batman - Part MCXIX.mp4";
1411
    $test2 = fixthe($test);
1412
    $rv .= Html::display_debug_one("fixthe(\"$test\")", $test2);
1413
1414
    $test = "The Exciting adventures OF THE batman.mp4";
1415
    $test2 = fixthe($test);
1416
    $rv .= Html::display_debug_one("fixthe(\"$test\")", $test2);
1417
1418
    $test = "The People Vs Larry Flynt.avi";
1419
    $test2 = fixthe($test);
1420
    $rv .= Html::display_debug_one("fixthe(\"$test\")", $test2);
1421
1422
    $test2 = "Supplies";
1423
    $test = a_number($test2);
1424
    $rv .= Html::display_debug_one("a_number(\"$test2\")", $test);
1425
1426
    $test2 = "0";
1427
    $test = a_number($test2);
1428
    $rv .= Html::display_debug_one("a_number(\"$test2\")", $test);
1429
1430
    Bc_sql::sql_disconnect();
1431
1432
    @test = ("Subdesc,read_text_asArray", "Bc_dir,read_text_asArray");
1433
    $test = "read_text_asArray";
1434
    $test2 = inArray(\@test, $test, 1, 1);
1435
    $rv .= Html::display_debug_one("inArray(\\\@test, \"$test\", 1, 1)", $test2);
1436
1437
    @test = ("123", "abc");
1438
    @test2 = ("456", "efg");
1439
    @test3 = (@test1, @test2);
1440
    $test = byte_count(\@test3);
1441
    $rv .= Html::display_debug_one("byte_count(\\\@test3)", $test);
1442
1443
  # end if ($DB)
1444
  } else {
1445
    $rv .= "DB connection error!<br>\n";
1446
  # end else of if ($DB)
1447
  }
1448
1449
  return $rv; # 0 on failure, or a scalar
1450
  #usage: my $tests = _tests();
1451
}
1452
1453
1;