Hex Artifact Content
Not logged in

Artifact 97098936a5608049ec59baef7de7525ce18d4f82:

File src/tokenize_path.c part of check-in [58ee4e6e16] - added missing #include by stephan on 2008-02-07 05:31:57.

0000: 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67  #include <string
0010: 2e 68 3e 0d 0a 23 69 6e 63 6c 75 64 65 20 3c 73  .h>..#include <s
0020: 74 64 6c 69 62 2e 68 3e 0d 0a 23 69 6e 63 6c 75  tdlib.h>..#inclu
0030: 64 65 20 22 74 6f 6b 65 6e 69 7a 65 5f 70 61 74  de "tokenize_pat
0040: 68 2e 68 22 0d 0a 0d 0a 2f 2a 2a 0d 0a 74 6f 6b  h.h"..../**..tok
0050: 65 6e 69 7a 65 5f 70 61 74 68 5f 66 72 65 65 28  enize_path_free(
0060: 29 20 69 73 20 74 68 65 20 6f 6e 6c 79 20 70 75  ) is the only pu
0070: 62 6c 69 63 61 6c 6c 79 2d 64 65 66 69 6e 65 64  blically-defined
0080: 20 77 61 79 20 74 6f 20 64 65 61 6c 6c 6f 63 61   way to dealloca
0090: 74 65 0d 0a 61 20 73 74 72 69 6e 67 20 61 72 72  te..a string arr
00a0: 61 79 20 63 72 65 61 74 65 64 20 62 79 20 74 6f  ay created by to
00b0: 6b 65 6e 69 7a 65 5f 70 61 74 68 28 29 2e 20 20  kenize_path().  
00c0: 49 74 20 6d 75 73 74 20 62 65 20 63 61 6c 6c 65  It must be calle
00d0: 64 20 65 78 61 63 74 6c 79 0d 0a 6f 6e 63 65 20  d exactly..once 
00e0: 66 6f 72 20 65 61 63 68 20 72 65 74 75 72 6e 20  for each return 
00f0: 76 61 6c 75 65 20 66 72 6f 6d 20 74 6f 6b 65 6e  value from token
0100: 69 7a 65 5f 70 61 74 68 28 29 2e 20 46 61 69 6c  ize_path(). Fail
0110: 69 6e 67 20 74 6f 20 63 61 6c 6c 20 69 74 0d 0a  ing to call it..
0120: 77 69 6c 6c 20 72 65 73 75 6c 74 20 69 6e 20 61  will result in a
0130: 20 6d 65 6d 6f 72 79 20 6c 65 61 6b 2e 0d 0a 0d   memory leak....
0140: 0a 49 66 20 28 21 70 29 20 74 68 65 6e 20 74 68  .If (!p) then th
0150: 69 73 20 66 75 6e 63 74 69 6f 6e 20 64 6f 65 73  is function does
0160: 20 6e 6f 74 68 69 6e 67 2e 20 20 50 61 73 73 69   nothing.  Passi
0170: 6e 67 20 61 20 70 6f 69 6e 74 65 72 20 77 68 69  ng a pointer whi
0180: 63 68 20 77 61 73 0d 0a 6e 6f 74 20 72 65 74 75  ch was..not retu
0190: 72 6e 65 64 20 66 72 6f 6d 20 74 6f 6b 65 6e 69  rned from tokeni
01a0: 7a 65 5f 70 61 74 68 28 29 20 77 69 6c 6c 20 72  ze_path() will r
01b0: 65 73 75 6c 74 20 69 6e 20 75 6e 64 65 66 69 6e  esult in undefin
01c0: 65 64 20 62 65 68 61 76 69 6f 75 72 2e 0d 0a 0d  ed behaviour....
01d0: 0a 41 66 74 65 72 20 63 61 6c 6c 69 6e 67 20 74  .After calling t
01e0: 68 69 73 2c 20 70 27 73 20 63 6f 6e 74 65 6e 74  his, p's content
01f0: 73 20 61 72 65 20 69 6e 76 61 6c 69 64 2e 0d 0a  s are invalid...
0200: 0d 0a 2a 2f 0d 0a 76 6f 69 64 20 74 6f 6b 65 6e  ..*/..void token
0210: 69 7a 65 5f 70 61 74 68 5f 66 72 65 65 28 20 63  ize_path_free( c
0220: 68 61 72 20 2a 2a 20 70 20 29 0d 0a 7b 0d 0a 20  har ** p )..{.. 
0230: 20 69 66 28 20 70 20 29 0d 0a 20 20 7b 20 0d 0a   if( p )..  { ..
0240: 20 20 20 20 2f 2a 20 46 72 65 65 20 74 68 65 20      /* Free the 
0250: 74 6f 6b 65 6e 69 7a 65 64 20 73 74 72 69 6e 67  tokenized string
0260: 73 20 28 61 20 73 69 6e 67 6c 65 20 73 74 72 69  s (a single stri
0270: 6e 67 2c 20 61 63 74 75 61 6c 6c 79 29 3a 20 2a  ng, actually): *
0280: 2f 0d 0a 20 20 20 20 66 72 65 65 28 20 2a 28 70  /..    free( *(p
0290: 2d 31 29 20 29 3b 0d 0a 20 20 20 20 2f 2a 20 46  -1) );..    /* F
02a0: 72 65 65 20 70 20 66 72 6f 6d 20 69 74 73 20 52  ree p from its R
02b0: 45 41 4c 20 73 74 61 72 74 69 6e 67 20 70 6f 69  EAL starting poi
02c0: 6e 74 2e 20 2a 2f 0d 0a 20 20 20 20 66 72 65 65  nt. */..    free
02d0: 28 20 70 2d 31 20 29 3b 0d 0a 20 20 7d 0d 0a 7d  ( p-1 );..  }..}
02e0: 0d 0a 0d 0a 2f 2a 2a 0d 0a 74 6f 6b 65 6e 69 7a  ..../**..tokeniz
02f0: 65 5f 70 61 74 68 5f 69 73 5f 73 65 70 61 72 61  e_path_is_separa
0300: 74 6f 72 28 29 20 69 73 20 74 68 65 20 64 65 66  tor() is the def
0310: 61 75 6c 74 20 70 72 65 64 69 63 61 74 65 20 66  ault predicate f
0320: 75 6e 63 74 69 6f 6e 20 66 6f 72 0d 0a 74 6f 6b  unction for..tok
0330: 65 6e 69 7a 65 5f 70 61 74 68 28 29 2e 20 49 74  enize_path(). It
0340: 20 72 65 74 75 72 6e 73 20 31 20 69 66 20 28 63   returns 1 if (c
0350: 20 3d 3d 20 27 2f 27 29 2c 20 65 6c 73 65 20 69   == '/'), else i
0360: 74 20 72 65 74 75 72 6e 73 20 30 2e 0d 0a 0d 0a  t returns 0.....
0370: 2a 2f 0d 0a 69 6e 74 20 74 6f 6b 65 6e 69 7a 65  */..int tokenize
0380: 5f 70 61 74 68 5f 69 73 5f 73 65 70 61 72 61 74  _path_is_separat
0390: 6f 72 28 20 69 6e 74 20 63 20 29 0d 0a 7b 0d 0a  or( int c )..{..
03a0: 20 20 72 65 74 75 72 6e 20 28 63 20 3d 3d 20 27    return (c == '
03b0: 2f 27 29 3b 0d 0a 7d 0d 0a 2f 2a 2a 0d 0a 20 20  /');..}../**..  
03c0: 20 74 6f 6b 65 6e 69 7a 65 5f 70 61 74 68 28 29   tokenize_path()
03d0: 20 74 61 6b 65 73 20 61 20 73 74 72 69 6e 67 2c   takes a string,
03e0: 20 61 73 73 75 6d 65 64 20 74 6f 20 62 65 20 61   assumed to be a
03f0: 20 64 65 6c 69 6d 69 74 65 64 0d 0a 20 20 20 6e   delimited..   n
0400: 75 6c 6c 2d 74 65 72 6d 69 6e 61 74 65 64 20 70  ull-terminated p
0410: 61 74 68 2d 73 74 79 6c 65 20 73 74 72 69 6e 67  ath-style string
0420: 20 28 6c 69 6b 65 20 61 20 70 61 74 68 20 74 6f   (like a path to
0430: 20 61 20 66 69 6c 65 29 2c 20 61 6e 64 0d 0a 20   a file), and.. 
0440: 20 20 74 6f 6b 65 6e 69 7a 65 73 20 69 74 20 69    tokenizes it i
0450: 6e 74 6f 20 69 74 73 20 63 6f 6d 70 6f 6e 65 6e  nto its componen
0460: 74 20 70 61 72 74 73 2e 20 54 68 65 20 27 6f 75  t parts. The 'ou
0470: 74 27 20 70 61 72 61 6d 65 74 65 72 20 28 69 66  t' parameter (if
0480: 20 6e 6f 74 0d 0a 20 20 20 6e 75 6c 6c 29 20 69   not..   null) i
0490: 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e 75 6d  s set to the num
04a0: 62 65 72 20 6f 66 20 74 6f 6b 65 6e 69 7a 65 64  ber of tokenized
04b0: 20 69 74 65 6d 73 20 28 6d 61 79 20 62 65 20 30   items (may be 0
04c0: 29 2e 0d 0a 0d 0a 20 20 20 54 68 65 20 74 68 69  ).....   The thi
04d0: 72 64 20 61 72 67 75 6d 65 6e 74 20 69 73 20 61  rd argument is a
04e0: 20 75 6e 61 72 79 20 70 72 65 64 69 63 61 74 65   unary predicate
04f0: 20 66 75 6e 63 74 69 6f 6e 20 77 68 69 63 68 20   function which 
0500: 74 61 6b 65 73 0d 0a 20 20 20 61 20 73 69 6e 67  takes..   a sing
0510: 6c 65 20 63 68 61 72 61 63 74 65 72 20 61 6e 64  le character and
0520: 20 72 65 74 75 72 6e 73 20 74 72 75 65 20 6f 6e   returns true on
0530: 6c 79 20 69 66 20 74 68 61 74 20 63 68 61 72 61  ly if that chara
0540: 63 74 65 72 0d 0a 20 20 20 69 73 20 61 20 22 73  cter..   is a "s
0550: 65 70 61 72 61 74 6f 72 20 63 68 61 72 61 63 74  eparator charact
0560: 65 72 22 2e 20 49 66 20 74 68 65 20 33 72 64 20  er". If the 3rd 
0570: 61 72 67 75 6d 65 6e 74 20 69 73 20 30 20 74 68  argument is 0 th
0580: 65 6e 0d 0a 20 20 20 74 6f 6b 65 6e 69 7a 65 5f  en..   tokenize_
0590: 70 61 74 68 5f 69 73 5f 73 65 70 61 72 61 74 6f  path_is_separato
05a0: 72 28 29 20 69 73 20 75 73 65 64 2e 0d 0a 0d 0a  r() is used.....
05b0: 20 20 20 54 68 65 20 66 75 6e 63 74 69 6f 6e 20     The function 
05c0: 72 65 74 75 72 6e 73 20 61 20 6c 69 73 74 20 6f  returns a list o
05d0: 66 20 73 74 72 69 6e 67 73 20 28 6f 72 20 30 29  f strings (or 0)
05e0: 20 77 68 69 63 68 20 6d 75 73 74 20 62 65 20 66   which must be f
05f0: 72 65 65 64 0d 0a 20 20 20 76 69 61 20 74 6f 6b  reed..   via tok
0600: 65 6e 69 7a 65 5f 70 61 74 68 5f 66 72 65 65 28  enize_path_free(
0610: 29 20 62 65 63 61 75 73 65 20 74 68 65 20 69 6e  ) because the in
0620: 74 65 72 6e 61 6c 20 61 6c 6c 6f 63 61 74 69 6f  ternal allocatio
0630: 6e 20 6f 66 20 74 68 65 0d 0a 20 20 20 72 65 74  n of the..   ret
0640: 75 72 6e 20 72 65 73 75 6c 74 20 69 73 20 61 20  urn result is a 
0650: 62 69 74 20 74 72 69 63 6b 79 20 28 74 6f 20 6d  bit tricky (to m
0660: 69 6e 69 6d 69 7a 65 20 6f 6e 20 61 6c 6c 6f 63  inimize on alloc
0670: 61 74 69 6f 6e 73 29 2e 20 20 44 4f 20 4e 4f 54  ations).  DO NOT
0680: 0d 0a 20 20 20 70 61 73 73 20 74 68 65 20 72 65  ..   pass the re
0690: 74 75 72 6e 20 72 65 73 75 6c 74 20 74 6f 20 66  turn result to f
06a0: 72 65 65 28 29 2c 20 61 73 20 74 68 61 74 20 77  ree(), as that w
06b0: 69 6c 6c 20 63 61 75 73 65 20 75 6e 64 65 66 69  ill cause undefi
06c0: 6e 65 64 0d 0a 20 20 20 62 65 68 61 76 69 6f 75  ned..   behaviou
06d0: 72 2e 20 42 65 63 61 75 73 65 20 74 68 65 20 72  r. Because the r
06e0: 65 74 75 72 6e 65 64 20 61 72 72 61 79 20 69 73  eturned array is
06f0: 20 6e 75 6c 6c 2d 74 65 72 6d 69 6e 61 74 65 64   null-terminated
0700: 2c 20 74 68 65 20 73 65 63 6f 6e 64 0d 0a 20 20  , the second..  
0710: 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 6e 6f   parameter is no
0720: 72 6d 61 6c 6c 79 20 6e 6f 74 20 6e 65 65 64 65  rmally not neede
0730: 64 20 62 65 63 61 75 73 65 20 74 68 65 20 61 72  d because the ar
0740: 72 61 79 20 63 61 6e 20 73 61 66 65 6c 79 0d 0a  ray can safely..
0750: 20 20 20 62 65 20 6c 6f 6f 70 65 64 20 6f 76 65     be looped ove
0760: 72 20 77 69 74 68 6f 75 74 20 6b 6e 6f 77 69 6e  r without knowin
0770: 67 20 69 74 73 20 6c 65 6e 67 74 68 20 69 6e 20  g its length in 
0780: 61 64 76 61 6e 63 65 2e 20 4e 6f 6e 65 74 68 65  advance. Nonethe
0790: 6c 65 73 73 2c 0d 0a 20 20 20 68 61 76 69 6e 67  less,..   having
07a0: 20 74 68 65 20 63 6f 75 6e 74 20 62 65 66 6f 72   the count befor
07b0: 65 20 6c 6f 6f 70 69 6e 67 20 6d 61 79 20 62 65  e looping may be
07c0: 20 75 73 65 66 75 6c 20 66 6f 72 20 73 6f 6d 65   useful for some
07d0: 20 63 61 73 65 73 2e 0d 0a 0d 0a 48 6f 77 65 76   cases.....Howev
07e0: 65 72 2c 0d 0a 20 20 20 74 68 65 20 72 65 74 75  er,..   the retu
07f0: 72 6e 65 64 20 61 72 72 61 79 0d 0a 0d 0a 20 20  rned array....  
0800: 20 54 68 65 20 72 65 74 75 72 6e 65 64 20 73 74   The returned st
0810: 72 69 6e 67 20 61 72 72 61 79 20 69 73 20 61 6c  ring array is al
0820: 77 61 79 73 20 6e 75 6c 6c 2d 74 65 72 6d 69 6e  ways null-termin
0830: 61 74 65 64 2c 20 74 6f 20 73 69 6d 70 6c 69 66  ated, to simplif
0840: 79 0d 0a 20 20 20 6c 6f 6f 70 69 6e 67 20 6f 76  y..   looping ov
0850: 65 72 20 69 74 2e 20 54 68 65 20 66 75 6e 63 74  er it. The funct
0860: 69 6f 6e 20 72 65 74 75 72 6e 73 20 6e 75 6c 6c  ion returns null
0870: 20 69 66 20 74 68 65 20 69 6e 70 75 74 20 73 74   if the input st
0880: 72 69 6e 67 20 69 73 0d 0a 20 20 20 6e 75 6c 6c  ring is..   null
0890: 2c 20 65 6d 70 74 79 2c 20 6f 72 20 63 6f 6e 74  , empty, or cont
08a0: 61 69 6e 73 20 6f 6e 6c 79 20 73 65 70 61 72 61  ains only separa
08b0: 74 6f 72 20 63 68 61 72 61 63 74 65 72 73 2e 0d  tor characters..
08c0: 0a 0d 0a 20 20 20 54 6f 6b 65 6e 69 7a 69 6e 67  ...   Tokenizing
08d0: 20 62 65 68 61 76 69 6f 75 72 3a 0d 0a 0d 0a 20   behaviour:.... 
08e0: 20 20 2d 20 49 74 20 61 73 73 75 6d 65 73 20 74    - It assumes t
08f0: 68 61 74 20 41 4c 4c 20 6e 6f 6e 2d 73 65 70 61  hat ALL non-sepa
0900: 72 61 74 6f 72 20 63 68 61 72 73 20 61 72 65 20  rator chars are 
0910: 65 6e 74 72 79 20 6e 61 6d 65 73 2e 0d 0a 0d 0a  entry names.....
0920: 20 20 20 2d 20 49 74 20 74 72 65 61 74 73 20 72     - It treats r
0930: 75 6e 73 20 6f 66 20 6d 75 6c 74 69 70 6c 65 20  uns of multiple 
0940: 73 65 70 61 72 61 74 6f 72 73 20 63 68 61 72 73  separators chars
0950: 20 61 73 20 61 20 73 69 6e 67 6c 65 0d 0a 20 20   as a single..  
0960: 20 73 65 70 61 72 61 74 6f 72 2c 20 4e 4f 54 20   separator, NOT 
0970: 61 73 20 61 20 73 65 72 69 65 73 20 6f 66 20 65  as a series of e
0980: 6d 70 74 79 20 74 6f 6b 65 6e 73 2e 0d 0a 0d 0a  mpty tokens.....
0990: 20 20 20 2d 20 49 74 20 68 61 73 20 6e 6f 20 6b     - It has no k
09a0: 6e 6f 77 6c 65 64 67 65 20 6f 66 20 72 65 6c 61  nowledge of rela
09b0: 74 69 76 65 20 6f 72 20 61 62 73 6f 6c 75 74 65  tive or absolute
09c0: 20 70 61 74 68 73 2c 20 73 6f 0d 0a 20 20 20 22   paths, so..   "
09d0: 2e 22 20 61 6e 64 20 22 2e 2e 22 20 61 72 65 20  ." and ".." are 
09e0: 63 6f 6e 73 69 64 65 72 65 64 20 74 6f 20 62 65  considered to be
09f0: 20 6e 6f 72 6d 61 6c 20 65 6e 74 72 69 65 73 2e   normal entries.
0a00: 0d 0a 0d 0a 20 20 20 2d 20 54 68 65 20 72 65 74  ....   - The ret
0a10: 75 72 6e 65 64 20 73 74 72 69 6e 67 73 20 61 72  urned strings ar
0a20: 65 20 6e 6f 6e 2d 63 6f 6e 73 74 2c 20 62 75 74  e non-const, but
0a30: 20 74 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74   the caller must
0a40: 20 6e 6f 74 0d 0a 20 20 20 63 68 61 6e 67 65 20   not..   change 
0a50: 74 68 65 69 72 20 73 69 7a 65 73 20 6f 72 20 72  their sizes or r
0a60: 65 61 6c 6c 6f 63 61 74 65 20 74 68 65 6d 20 61  eallocate them a
0a70: 74 20 64 69 66 66 65 72 65 6e 74 20 6d 65 6d 6f  t different memo
0a80: 72 79 0d 0a 20 20 20 61 64 64 72 65 73 73 65 73  ry..   addresses
0a90: 2e 20 54 68 65 20 6f 6e 6c 79 20 6c 65 67 61 6c  . The only legal
0aa0: 20 77 61 79 20 74 6f 20 64 65 61 6c 6c 6f 63 61   way to dealloca
0ab0: 74 65 20 74 68 65 6d 20 69 73 20 77 69 74 68 0d  te them is with.
0ac0: 0a 20 20 20 74 6f 6b 65 6e 69 7a 65 5f 70 61 74  .   tokenize_pat
0ad0: 68 5f 66 72 65 65 28 29 2e 20 43 68 61 6e 67 69  h_free(). Changi
0ae0: 6e 67 20 74 68 65 20 73 74 72 69 6e 67 20 63 6f  ng the string co
0af0: 6e 74 65 6e 74 20 49 53 20 69 73 20 6c 65 67 61  ntent IS is lega
0b00: 6c 2e 0d 0a 0d 0a 20 20 20 65 2e 67 2e 3a 0d 0a  l.....   e.g.:..
0b10: 0d 0a 20 20 20 22 2f 70 61 74 68 2f 74 6f 2f 6e  ..   "/path/to/n
0b20: 6f 77 68 65 72 65 22 20 61 6e 64 20 22 70 61 74  owhere" and "pat
0b30: 68 2f 74 6f 2f 2f 2f 6e 6f 77 68 65 72 65 2f 22  h/to///nowhere/"
0b40: 20 62 6f 74 68 20 70 61 72 73 65 20 74 6f 3a 0d   both parse to:.
0b50: 0a 0d 0a 20 20 20 50 61 72 73 65 73 20 74 6f 3a  ...   Parses to:
0b60: 20 7b 20 22 70 61 74 68 22 2c 20 22 74 6f 22 2c   { "path", "to",
0b70: 20 22 6e 6f 77 68 65 72 65 22 20 7d 0d 0a 0d 0a   "nowhere" }....
0b80: 20 20 20 22 2f 2e 2f 2e 2e 2f 22 0d 0a 0d 0a 20     "/./../".... 
0b90: 20 20 50 61 72 73 65 73 20 74 6f 3a 20 7b 20 22    Parses to: { "
0ba0: 2e 22 2c 20 22 2e 2e 22 20 7d 0d 0a 0d 0a 20 20  .", ".." }....  
0bb0: 20 22 68 74 74 70 3a 2f 2f 66 6f 6f 2e 63 6f 6d   "http://foo.com
0bc0: 2f 62 61 72 22 0d 0a 0d 0a 20 20 20 50 61 72 73  /bar"....   Pars
0bd0: 65 73 20 74 6f 3a 20 7b 20 22 68 74 74 70 3a 22  es to: { "http:"
0be0: 2c 20 22 66 6f 6f 2e 63 6f 6d 22 2c 20 22 62 61  , "foo.com", "ba
0bf0: 72 22 20 7d 0d 0a 0d 0a 20 20 20 28 4e 6f 74 65  r" }....   (Note
0c00: 20 74 68 61 74 20 74 68 6f 73 65 20 61 72 72 61   that those arra
0c10: 79 73 20 61 6c 6c 20 68 61 76 65 20 61 6e 20 69  ys all have an i
0c20: 6d 70 6c 69 63 69 74 20 4e 55 4c 4c 20 65 6e 74  mplicit NULL ent
0c30: 72 79 20 61 73 20 74 68 65 69 72 0d 0a 20 20 20  ry as their..   
0c40: 6c 61 73 74 20 65 6c 65 6d 65 6e 74 2e 20 29 0d  last element. ).
0c50: 0a 0d 0a 0d 0a 2a 2f 0d 0a 63 68 61 72 20 2a 2a  .....*/..char **
0c60: 20 74 6f 6b 65 6e 69 7a 65 5f 70 61 74 68 28 20   tokenize_path( 
0c70: 63 68 61 72 20 63 6f 6e 73 74 20 2a 20 69 6e 2c  char const * in,
0c80: 0d 0a 09 09 20 20 20 20 20 20 20 69 6e 74 20 2a  ....       int *
0c90: 20 6f 75 74 2c 0d 0a 09 09 20 20 20 20 20 20 20   out,....       
0ca0: 69 6e 74 20 28 2a 70 72 65 64 69 63 61 74 65 29  int (*predicate)
0cb0: 28 20 69 6e 74 20 29 0d 0a 09 09 20 20 20 20 20  ( int )....     
0cc0: 20 20 29 0d 0a 7b 20 2f 2a 20 41 75 74 68 6f 72    )..{ /* Author
0cd0: 3a 20 73 67 62 65 61 6c 40 67 6f 6f 67 6c 65 6d  : sgbeal@googlem
0ce0: 61 69 6c 2e 63 6f 6d 2e 20 4c 69 63 65 6e 73 65  ail.com. License
0cf0: 3a 20 50 75 62 6c 69 63 20 44 6f 6d 61 69 6e 2e  : Public Domain.
0d00: 20 2a 2f 0d 0a 20 20 69 6e 74 20 69 67 6e 6f 72   */..  int ignor
0d10: 65 64 3b 0d 0a 20 20 69 66 28 20 21 20 6f 75 74  ed;..  if( ! out
0d20: 20 29 20 6f 75 74 20 3d 20 26 69 67 6e 6f 72 65   ) out = &ignore
0d30: 64 3b 0d 0a 20 20 2a 6f 75 74 20 3d 20 30 3b 0d  d;..  *out = 0;.
0d40: 0a 20 20 74 79 70 65 64 65 66 20 69 6e 74 20 28  .  typedef int (
0d50: 2a 73 65 70 5f 66 29 28 20 69 6e 74 20 29 3b 0d  *sep_f)( int );.
0d60: 0a 20 20 73 65 70 5f 66 20 69 73 5f 73 65 70 20  .  sep_f is_sep 
0d70: 3d 20 28 70 72 65 64 69 63 61 74 65 20 3f 20 70  = (predicate ? p
0d80: 72 65 64 69 63 61 74 65 20 3a 20 74 6f 6b 65 6e  redicate : token
0d90: 69 7a 65 5f 70 61 74 68 5f 69 73 5f 73 65 70 61  ize_path_is_sepa
0da0: 72 61 74 6f 72 29 3b 0d 0a 20 20 69 6e 74 20 69  rator);..  int i
0db0: 6e 6c 65 6e 20 3d 20 73 74 72 6c 65 6e 28 69 6e  nlen = strlen(in
0dc0: 29 3b 0d 0a 20 20 69 66 28 20 28 21 20 69 6e 29  );..  if( (! in)
0dd0: 20 7c 7c 20 28 30 3d 3d 69 6e 6c 65 6e 29 20 29   || (0==inlen) )
0de0: 20 72 65 74 75 72 6e 20 30 3b 0d 0a 20 20 63 68   return 0;..  ch
0df0: 61 72 20 2a 20 63 70 20 3d 20 6d 61 6c 6c 6f 63  ar * cp = malloc
0e00: 28 20 69 6e 6c 65 6e 20 2b 20 31 20 29 3b 0d 0a  ( inlen + 1 );..
0e10: 20 20 2f 2a 2a 0d 0a 20 20 20 20 20 57 65 20 6d    /**..     We m
0e20: 61 6b 65 20 61 20 63 6f 70 79 20 62 65 63 61 75  ake a copy becau
0e30: 73 65 3a 0d 0a 20 20 20 20 20 20 0d 0a 20 20 20  se:..      ..   
0e40: 20 20 4f 75 72 20 61 6c 67 6f 72 69 74 68 6d 20    Our algorithm 
0e50: 69 73 20 74 6f 20 72 65 70 6c 61 63 65 20 73 65  is to replace se
0e60: 70 61 72 61 74 6f 72 73 20 77 69 74 68 20 30 20  parators with 0 
0e70: 69 6e 20 6f 75 72 20 63 6f 70 79 2c 20 61 6e 64  in our copy, and
0e80: 0d 0a 20 20 20 20 20 75 73 65 20 74 68 61 74 20  ..     use that 
0e90: 63 6f 70 79 20 61 73 20 6f 75 72 20 72 65 74 75  copy as our retu
0ea0: 72 6e 20 76 61 6c 75 65 2e 20 54 68 69 73 20 61  rn value. This a
0eb0: 6c 6c 6f 77 73 20 75 73 20 74 6f 20 61 76 6f 69  llows us to avoi
0ec0: 64 0d 0a 20 20 20 20 20 61 6c 6c 6f 63 61 74 69  d..     allocati
0ed0: 6e 67 20 61 20 6e 65 77 20 73 74 72 69 6e 67 20  ng a new string 
0ee0: 66 6f 72 20 65 61 63 68 20 72 65 74 75 72 6e 65  for each returne
0ef0: 64 20 72 65 73 75 6c 74 2e 0d 0a 20 20 2a 2f 0d  d result...  */.
0f00: 0a 20 20 73 74 72 63 70 79 28 20 63 70 2c 20 69  .  strcpy( cp, i
0f10: 6e 20 29 3b 0d 0a 20 20 2f 2a 2a 0d 0a 20 20 20  n );..  /**..   
0f20: 20 20 62 75 66 66 73 69 7a 65 20 3d 20 74 68 65    buffsize = the
0f30: 20 6c 61 72 67 65 73 74 20 70 6f 73 73 69 62 6c   largest possibl
0f40: 65 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 74 75  e number of retu
0f50: 72 6e 20 72 65 73 75 6c 74 20 77 65 20 63 61 6e  rn result we can
0f60: 0d 0a 20 20 20 20 20 68 61 76 65 2c 20 70 6c 75  ..     have, plu
0f70: 73 20 31 20 28 74 6f 20 61 6c 6c 6f 77 20 66 6f  s 1 (to allow fo
0f80: 72 20 74 72 75 6e 63 61 74 65 64 20 64 69 76 69  r truncated divi
0f90: 73 69 6f 6e 29 2e 20 54 68 65 20 6d 61 78 69 6d  sion). The maxim
0fa0: 75 6d 20 73 69 7a 65 0d 0a 20 20 20 20 20 69 73  um size..     is
0fb0: 20 64 65 74 65 72 6d 69 6e 65 64 20 62 61 73 65   determined base
0fc0: 64 20 6f 6e 20 77 6f 72 73 74 2d 63 61 73 65 20  d on worst-case 
0fd0: 73 63 65 6e 61 72 69 6f 3a 20 61 20 6c 69 73 74  scenario: a list
0fe0: 20 6f 66 20 73 69 6e 67 6c 65 0d 0a 20 20 20 20   of single..    
0ff0: 20 63 68 61 72 61 63 74 65 72 73 2c 20 65 61 63   characters, eac
1000: 68 20 73 65 70 61 72 61 74 65 64 20 62 79 20 6f  h separated by o
1010: 6e 65 20 73 65 70 61 72 61 74 6f 72 73 2c 20 65  ne separators, e
1020: 2e 67 2e 20 20 22 2f 31 2f 31 2f 31 2f 31 2f 31  .g.  "/1/1/1/1/1
1030: 22 0d 0a 20 20 2a 2f 0d 0a 20 20 63 6f 6e 73 74  "..  */..  const
1040: 20 69 6e 74 20 62 75 66 66 73 69 7a 65 20 3d 20   int buffsize = 
1050: 69 6e 6c 65 6e 20 2f 20 32 20 2b 20 31 3b 0d 0a  inlen / 2 + 1;..
1060: 20 20 2f 2a 20 27 73 74 61 72 74 73 27 20 73 74    /* 'starts' st
1070: 6f 72 65 73 20 74 68 65 20 73 74 61 72 74 69 6e  ores the startin
1080: 67 20 70 6f 69 6e 74 20 6f 66 20 65 61 63 68 20  g point of each 
1090: 70 61 74 68 20 63 6f 6d 70 6f 6e 65 6e 74 0d 0a  path component..
10a0: 20 20 20 20 20 73 75 62 73 74 72 69 6e 67 20 6f       substring o
10b0: 66 20 27 63 70 27 2e 20 57 68 65 6e 20 77 65 20  f 'cp'. When we 
10c0: 73 6c 69 63 65 20 75 70 20 27 63 70 27 20 62 65  slice up 'cp' be
10d0: 6c 6f 77 2c 20 73 74 61 72 74 73 5b 78 5d 0d 0a  low, starts[x]..
10e0: 20 20 20 20 20 77 69 6c 6c 20 62 65 20 73 65 74       will be set
10f0: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 20 70   to point to a p
1100: 61 72 74 69 63 75 6c 61 72 20 70 6f 73 69 74 69  articular positi
1110: 6f 6e 20 77 69 74 68 69 6e 20 27 63 70 27 2e 0d  on within 'cp'..
1120: 0a 20 20 20 20 20 54 68 61 74 20 61 6c 6c 6f 77  .     That allow
1130: 73 20 75 73 20 74 6f 20 61 76 6f 69 64 20 61 6c  s us to avoid al
1140: 6c 6f 63 61 74 69 6e 67 2f 63 6f 70 79 69 6e 67  locating/copying
1150: 20 65 61 63 68 20 65 6c 65 6d 65 6e 74 0d 0a 20   each element.. 
1160: 20 20 20 20 73 65 70 61 72 61 74 65 6c 79 2e 0d      separately..
1170: 0a 20 20 2a 2f 0d 0a 20 20 63 68 61 72 20 2a 20  .  */..  char * 
1180: 73 74 61 72 74 73 5b 62 75 66 66 73 69 7a 65 5d  starts[buffsize]
1190: 3b 0d 0a 20 20 69 6e 74 20 69 20 3d 20 30 3b 0d  ;..  int i = 0;.
11a0: 0a 20 20 66 6f 72 28 20 69 20 3d 20 30 3b 20 69  .  for( i = 0; i
11b0: 20 3c 20 62 75 66 66 73 69 7a 65 3b 20 2b 2b 69   < buffsize; ++i
11c0: 20 29 20 73 74 61 72 74 73 5b 69 5d 20 3d 20 30   ) starts[i] = 0
11d0: 3b 0d 0a 0d 0a 20 20 63 68 61 72 20 2a 20 63 75  ;....  char * cu
11e0: 72 73 20 3d 20 63 70 3b 0d 0a 20 20 66 6f 72 28  rs = cp;..  for(
11f0: 20 63 75 72 73 20 3d 20 63 70 3b 20 69 73 5f 73   curs = cp; is_s
1200: 65 70 28 2a 63 75 72 73 29 3b 20 2b 2b 63 75 72  ep(*curs); ++cur
1210: 73 20 29 3b 0d 0a 20 20 2f 2a 20 5e 5e 5e 20 57  s );..  /* ^^^ W
1220: 65 20 73 6b 69 70 20 6c 65 61 64 69 6e 67 20 73  e skip leading s
1230: 65 70 61 72 61 74 6f 72 73 20 73 6f 20 77 65 20  eparators so we 
1240: 63 61 6e 20 65 61 73 69 6c 79 0d 0a 20 20 20 20  can easily..    
1250: 20 6d 61 72 6b 20 77 68 65 72 65 20 74 68 65 20   mark where the 
1260: 66 69 72 73 74 20 65 6e 74 72 79 20 73 74 72 69  first entry stri
1270: 6e 67 20 61 63 74 75 61 6c 6c 79 20 62 65 67 69  ng actually begi
1280: 6e 73 2e 0d 0a 20 20 2a 2f 0d 0a 20 20 69 66 28  ns...  */..  if(
1290: 20 27 5c 30 27 20 3d 3d 20 63 75 72 73 20 29 0d   '\0' == curs ).
12a0: 0a 20 20 7b 0d 0a 20 20 20 20 66 72 65 65 28 20  .  {..    free( 
12b0: 63 70 20 29 3b 0d 0a 20 20 20 20 72 65 74 75 72  cp );..    retur
12c0: 6e 20 30 3b 0d 0a 20 20 7d 0d 0a 20 20 63 68 61  n 0;..  }..  cha
12d0: 72 20 2a 20 6d 61 72 6b 20 3d 20 63 75 72 73 3b  r * mark = curs;
12e0: 20 2f 2a 20 70 6c 61 63 65 68 6f 6c 64 65 72 20   /* placeholder 
12f0: 66 6f 72 20 68 6f 6c 64 69 6e 67 20 74 68 65 20  for holding the 
1300: 68 65 61 64 20 61 64 64 72 20 6f 66 20 73 74 72  head addr of str
1310: 69 6e 67 73 2e 20 2a 2f 0d 0a 20 20 69 6e 74 20  ings. */..  int 
1320: 63 6f 75 6e 74 20 3d 20 30 3b 20 2f 2a 20 74 6f  count = 0; /* to
1330: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 65 6c  tal number of el
1340: 65 6d 65 6e 74 73 20 77 65 20 65 6e 64 20 75 70  ements we end up
1350: 20 74 6f 6b 65 6e 69 7a 69 6e 67 2e 20 2a 2f 0d   tokenizing. */.
1360: 0a 20 20 69 6e 74 20 73 74 61 72 74 65 64 20 3d  .  int started =
1370: 20 30 3b 20 2f 2a 20 74 6f 67 67 6c 65 64 20 77   0; /* toggled w
1380: 68 65 6e 20 77 65 20 65 6e 74 65 72 20 61 20 6e  hen we enter a n
1390: 65 77 20 70 61 74 68 20 65 6c 65 6d 65 6e 74 2e  ew path element.
13a0: 20 2a 2f 0d 0a 20 20 66 6f 72 28 20 3b 20 2a 63   */..  for( ; *c
13b0: 75 72 73 20 21 3d 20 27 5c 30 27 3b 20 2b 2b 63  urs != '\0'; ++c
13c0: 75 72 73 20 29 0d 0a 20 20 7b 0d 0a 20 20 20 20  urs )..  {..    
13d0: 2f 2a 2a 20 52 65 70 6c 61 63 65 20 27 2f 27 20  /** Replace '/' 
13e0: 77 69 74 68 20 27 5c 30 27 2e 2e 2e 20 2a 2f 0d  with '\0'... */.
13f0: 0a 20 20 20 20 69 66 28 20 69 73 5f 73 65 70 28  .    if( is_sep(
1400: 2a 63 75 72 73 29 20 29 0d 0a 20 20 20 20 7b 0d  *curs) )..    {.
1410: 0a 20 20 20 20 20 20 2a 63 75 72 73 20 3d 20 27  .      *curs = '
1420: 5c 30 27 3b 0d 0a 20 20 20 20 20 20 6d 61 72 6b  \0';..      mark
1430: 20 3d 20 63 75 72 73 2b 31 3b 0d 0a 20 20 20 20   = curs+1;..    
1440: 20 20 73 74 61 72 74 65 64 20 3d 20 30 3b 0d 0a    started = 0;..
1450: 20 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0d        continue;.
1460: 0a 20 20 20 20 7d 0d 0a 20 20 20 20 69 66 28 20  .    }..    if( 
1470: 21 20 73 74 61 72 74 65 64 20 29 0d 0a 20 20 20  ! started )..   
1480: 20 7b 20 2f 2a 2a 20 53 74 61 72 74 20 61 20 6e   { /** Start a n
1490: 65 77 20 70 61 74 68 20 65 6c 65 6d 65 6e 74 2e  ew path element.
14a0: 2e 2e 20 2a 2f 0d 0a 20 20 20 20 20 20 73 74 61  .. */..      sta
14b0: 72 74 73 5b 63 6f 75 6e 74 5d 20 3d 20 6d 61 72  rts[count] = mar
14c0: 6b 3b 0d 0a 20 20 20 20 20 20 73 74 61 72 74 65  k;..      starte
14d0: 64 20 3d 20 31 3b 0d 0a 20 20 20 20 20 20 2b 2b  d = 1;..      ++
14e0: 63 6f 75 6e 74 3b 0d 0a 20 20 20 20 7d 0d 0a 20  count;..    }.. 
14f0: 20 7d 0d 0a 20 20 69 66 28 20 21 20 73 74 61 72   }..  if( ! star
1500: 74 73 5b 30 5d 20 29 0d 0a 20 20 7b 0d 0a 20 20  ts[0] )..  {..  
1510: 20 20 66 72 65 65 28 20 63 70 20 29 3b 0d 0a 20    free( cp );.. 
1520: 20 20 20 72 65 74 75 72 6e 20 30 3b 0d 0a 20 20     return 0;..  
1530: 7d 0d 0a 20 20 63 70 5b 69 6e 6c 65 6e 5d 20 3d  }..  cp[inlen] =
1540: 20 27 5c 30 27 3b 0d 0a 20 20 63 68 61 72 20 2a   '\0';..  char *
1550: 2a 20 72 65 74 20 3d 20 63 61 6c 6c 6f 63 28 20  * ret = calloc( 
1560: 63 6f 75 6e 74 20 2b 20 32 2c 20 73 69 7a 65 6f  count + 2, sizeo
1570: 66 28 63 68 61 72 2a 29 20 29 3b 0d 0a 20 20 2f  f(char*) );..  /
1580: 2a 20 57 65 20 6f 76 65 72 2d 61 6c 6c 6f 63 61  * We over-alloca
1590: 74 65 20 62 79 20 32 20 65 6e 74 72 69 65 73 2e  te by 2 entries.
15a0: 20 54 68 65 20 66 69 72 73 74 20 6f 6e 65 20 68   The first one h
15b0: 6f 6c 64 73 20 74 68 65 20 61 64 64 72 65 73 73  olds the address
15c0: 20 6f 66 0d 0a 20 20 20 27 63 70 27 20 61 6e 64   of..   'cp' and
15d0: 20 74 68 65 20 6c 61 73 74 20 6f 6e 65 20 69 73   the last one is
15e0: 20 73 65 74 20 74 6f 20 30 20 74 6f 20 73 69 6d   set to 0 to sim
15f0: 70 6c 69 66 79 20 6c 6f 6f 70 69 6e 67 20 6f 76  plify looping ov
1600: 65 72 20 74 68 65 0d 0a 20 20 20 61 72 72 61 79  er the..   array
1610: 2e 20 2a 2f 0d 0a 20 20 2a 6f 75 74 20 3d 20 63  . */..  *out = c
1620: 6f 75 6e 74 3b 0d 0a 20 20 72 65 74 5b 30 5d 20  ount;..  ret[0] 
1630: 3d 20 63 70 3b 0d 0a 20 20 2b 2b 72 65 74 3b 0d  = cp;..  ++ret;.
1640: 0a 20 20 2f 2a 2a 0d 0a 20 20 20 20 20 57 65 27  .  /**..     We'
1650: 72 65 20 67 6f 69 6e 67 20 74 6f 20 68 69 64 65  re going to hide
1660: 20 74 68 61 74 20 5b 30 5d 20 65 6e 74 72 79 20   that [0] entry 
1670: 66 72 6f 6d 20 74 68 65 20 63 61 6c 6c 65 72 2e  from the caller.
1680: 20 49 6e 73 74 65 61 64 2c 20 77 65 0d 0a 20 20   Instead, we..  
1690: 20 20 20 75 73 65 20 74 68 61 74 20 74 6f 20 68     use that to h
16a0: 6f 6c 64 20 74 68 65 20 61 64 64 72 65 73 73 20  old the address 
16b0: 6f 66 20 27 63 70 27 2e 20 49 6e 20 74 6f 6b 65  of 'cp'. In toke
16c0: 6e 69 7a 65 5f 70 61 74 68 5f 66 72 65 65 28 29  nize_path_free()
16d0: 0d 0a 20 20 20 20 20 77 65 20 72 65 6c 65 61 73  ..     we releas
16e0: 65 20 62 6f 74 68 20 74 68 61 74 20 73 74 72 69  e both that stri
16f0: 6e 67 20 61 6e 64 20 28 72 65 74 2d 31 29 2e 0d  ng and (ret-1)..
1700: 0a 20 20 2a 2f 0d 0a 20 20 66 6f 72 28 20 69 20  .  */..  for( i 
1710: 3d 20 30 3b 20 69 20 3c 20 63 6f 75 6e 74 3b 20  = 0; i < count; 
1720: 2b 2b 69 20 29 0d 0a 20 20 7b 0d 0a 20 20 20 20  ++i )..  {..    
1730: 72 65 74 5b 69 5d 20 3d 20 73 74 61 72 74 73 5b  ret[i] = starts[
1740: 69 5d 3b 0d 0a 20 20 7d 0d 0a 20 20 72 65 74 5b  i];..  }..  ret[
1750: 63 6f 75 6e 74 5d 20 3d 20 30 3b 0d 0a 20 20 72  count] = 0;..  r
1760: 65 74 75 72 6e 20 72 65 74 3b 0d 0a 7d 0d 0a 0d  eturn ret;..}...
1770: 0a 65 78 74 65 72 6e 20 76 6f 69 64 20 63 67 69  .extern void cgi
1780: 5f 70 72 69 6e 74 66 28 63 6f 6e 73 74 20 63 68  _printf(const ch
1790: 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 2e 2e 2e 29  ar *zFormat,...)
17a0: 3b 0d 0a 2f 2a 2a 0d 0a 72 65 6e 64 65 72 5f 6c  ;../**..render_l
17b0: 69 6e 6b 65 64 5f 70 61 74 68 28 29 20 74 61 6b  inked_path() tak
17c0: 65 73 20 61 20 72 6f 6f 74 20 70 61 74 68 20 61  es a root path a
17d0: 6e 64 20 61 20 2f 75 6e 69 78 2f 73 74 79 6c 65  nd a /unix/style
17e0: 2f 70 61 74 68 20 61 6e 64 0d 0a 72 65 6e 64 65  /path and..rende
17f0: 72 73 20 28 75 73 69 6e 67 20 63 67 69 5f 70 72  rs (using cgi_pr
1800: 69 6e 74 66 28 29 29 20 61 20 63 6c 69 63 6b 61  intf()) a clicka
1810: 62 6c 65 20 6c 69 73 74 20 6f 66 20 74 68 65 20  ble list of the 
1820: 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65 0d 0a  entries in the..
1830: 70 61 74 68 2e 20 49 66 20 70 61 74 68 20 69 73  path. If path is
1840: 20 6e 75 6c 6c 20 69 74 20 64 6f 65 73 20 6e 6f   null it does no
1850: 74 68 69 6e 67 2e 20 49 66 20 72 6f 6f 74 20 69  thing. If root i
1860: 73 20 6e 75 6c 6c 20 69 74 20 69 73 20 74 72 65  s null it is tre
1870: 61 74 65 64 0d 0a 61 73 20 61 6e 20 65 6d 70 74  ated..as an empt
1880: 79 20 73 74 72 69 6e 67 2e 0d 0a 0d 0a 45 78 61  y string.....Exa
1890: 6d 70 6c 65 3a 0d 0a 0d 0a 72 65 6e 64 65 72 5f  mple:....render_
18a0: 6c 69 6e 6b 65 64 5f 70 61 74 68 28 20 22 2f 41  linked_path( "/A
18b0: 41 41 22 2c 20 22 62 2f 63 2f 64 22 20 29 3b 0d  AA", "b/c/d" );.
18c0: 0a 0d 0a 49 74 20 77 6f 75 6c 64 20 72 65 6e 64  ...It would rend
18d0: 65 72 20 61 20 6c 69 73 74 20 73 69 6d 69 6c 61  er a list simila
18e0: 72 20 74 6f 20 74 68 65 20 66 6f 6c 6c 6f 77 69  r to the followi
18f0: 6e 67 2c 0d 0a 62 75 74 20 74 68 69 6e 6b 20 6f  ng,..but think o
1900: 66 20 74 68 65 20 74 65 78 74 20 69 6e 20 5b 62  f the text in [b
1910: 72 61 63 6b 65 74 73 5d 20 61 73 20 68 79 70 65  rackets] as hype
1920: 72 6c 69 6e 6b 65 64 3a 0d 0a 0d 0a 20 20 5b 62  rlinked:....  [b
1930: 5d 2f 5b 63 5d 2f 5b 64 5d 0d 0a 0d 0a 20 20 45  ]/[c]/[d]....  E
1940: 61 63 68 20 65 6c 65 6d 65 6e 74 20 69 73 20 6c  ach element is l
1950: 69 6e 6b 65 64 20 74 6f 20 61 20 70 61 74 68 20  inked to a path 
1960: 6c 69 6b 65 20 73 6f 3a 0d 0a 0d 0a 20 20 62 3a  like so:....  b:
1970: 20 72 6f 6f 74 2f 62 0d 0a 20 20 63 3a 20 72 6f   root/b..  c: ro
1980: 6f 74 2f 62 2f 63 0d 0a 20 20 64 3a 20 72 6f 6f  ot/b/c..  d: roo
1990: 74 2f 62 2f 63 2f 64 0d 0a 0d 0a 49 66 20 72 6f  t/b/c/d....If ro
19a0: 6f 74 20 69 73 20 6e 75 6c 6c 20 74 68 65 6e 20  ot is null then 
19b0: 74 68 65 20 27 72 6f 6f 74 2f 27 20 70 61 72 74  the 'root/' part
19c0: 20 69 73 20 6e 6f 74 20 61 70 70 6c 69 65 64 2e   is not applied.
19d0: 0d 0a 0d 0a 2a 2f 0d 0a 76 6f 69 64 20 72 65 6e  ....*/..void ren
19e0: 64 65 72 5f 6c 69 6e 6b 65 64 5f 70 61 74 68 28  der_linked_path(
19f0: 20 63 68 61 72 20 63 6f 6e 73 74 20 2a 20 72 6f   char const * ro
1a00: 6f 74 2c 0d 0a 20 20 20 20 20 20 20 20 20 20 20  ot,..           
1a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63 68                ch
1a20: 61 72 20 63 6f 6e 73 74 20 2a 20 70 61 74 68 20  ar const * path 
1a30: 29 0d 0a 7b 0d 0a 20 20 69 6e 74 20 63 6f 75 6e  )..{..  int coun
1a40: 74 20 3d 20 30 3b 0d 0a 20 20 63 68 61 72 20 2a  t = 0;..  char *
1a50: 2a 20 74 6f 6b 73 20 3d 20 74 6f 6b 65 6e 69 7a  * toks = tokeniz
1a60: 65 5f 70 61 74 68 28 20 70 61 74 68 2c 20 26 63  e_path( path, &c
1a70: 6f 75 6e 74 2c 20 30 20 29 3b 0d 0a 20 20 69 66  ount, 0 );..  if
1a80: 28 20 21 20 74 6f 6b 73 20 29 20 72 65 74 75 72  ( ! toks ) retur
1a90: 6e 3b 0d 0a 20 20 63 68 61 72 20 63 6f 6e 73 74  n;..  char const
1aa0: 20 2a 20 74 20 3d 20 30 3b 0d 0a 20 20 69 6e 74   * t = 0;..  int
1ab0: 20 70 6f 73 20 3d 20 30 3b 0d 0a 20 20 66 6f 72   pos = 0;..  for
1ac0: 28 20 74 20 3d 20 74 6f 6b 73 5b 70 6f 73 5d 3b  ( t = toks[pos];
1ad0: 20 74 3b 20 74 20 3d 20 74 6f 6b 73 5b 2b 2b 70   t; t = toks[++p
1ae0: 6f 73 5d 20 29 0d 0a 20 20 7b 0d 0a 20 20 20 20  os] )..  {..    
1af0: 63 67 69 5f 70 72 69 6e 74 66 28 20 22 3c 61 20  cgi_printf( "<a 
1b00: 68 72 65 66 3d 27 22 20 29 3b 0d 0a 20 20 20 20  href='" );..    
1b10: 69 66 28 20 72 6f 6f 74 20 29 0d 0a 20 20 20 20  if( root )..    
1b20: 7b 0d 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69  {..      cgi_pri
1b30: 6e 74 66 28 20 22 25 73 2f 22 2c 20 72 6f 6f 74  ntf( "%s/", root
1b40: 20 29 3b 0d 0a 20 20 20 20 7d 0d 0a 20 20 20 20   );..    }..    
1b50: 69 6e 74 20 62 70 6f 73 20 3d 20 30 3b 0d 0a 20  int bpos = 0;.. 
1b60: 20 20 20 66 6f 72 28 20 3b 20 62 70 6f 73 20 3c     for( ; bpos <
1b70: 20 70 6f 73 3b 20 2b 2b 62 70 6f 73 20 29 0d 0a   pos; ++bpos )..
1b80: 20 20 20 20 7b 0d 0a 20 20 20 20 20 20 63 67 69      {..      cgi
1b90: 5f 70 72 69 6e 74 66 28 22 25 73 2f 22 2c 20 74  _printf("%s/", t
1ba0: 6f 6b 73 5b 62 70 6f 73 5d 20 29 3b 0d 0a 20 20  oks[bpos] );..  
1bb0: 20 20 7d 0d 0a 20 20 20 20 63 67 69 5f 70 72 69    }..    cgi_pri
1bc0: 6e 74 66 28 22 25 73 27 3e 25 73 3c 2f 61 3e 22  ntf("%s'>%s</a>"
1bd0: 2c 20 74 2c 20 74 20 29 3b 0d 0a 20 20 20 20 69  , t, t );..    i
1be0: 66 28 20 70 6f 73 20 21 3d 20 28 63 6f 75 6e 74  f( pos != (count
1bf0: 2d 31 29 20 29 0d 0a 20 20 20 20 7b 0d 0a 20 20  -1) )..    {..  
1c00: 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22      cgi_printf("
1c10: 2f 22 29 3b 0d 0a 20 20 20 20 7d 0d 0a 20 20 7d  /");..    }..  }
1c20: 0d 0a 20 20 74 6f 6b 65 6e 69 7a 65 5f 70 61 74  ..  tokenize_pat
1c30: 68 5f 66 72 65 65 28 20 74 6f 6b 73 20 29 3b 0d  h_free( toks );.
1c40: 0a 7d 0d 0a 0d 0a 23 69 66 20 30 20 2f 2a 20 73  .}....#if 0 /* s
1c50: 65 74 20 74 6f 20 31 20 74 6f 20 63 6f 6d 70 69  et to 1 to compi
1c60: 6c 65 20 61 20 74 65 73 74 20 61 70 70 2e 20 2a  le a test app. *
1c70: 2f 20 0d 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  / ..#include <st
1c80: 64 69 6f 2e 68 3e 0d 0a 0d 0a 73 74 61 74 69 63  dio.h>....static
1c90: 20 69 6e 74 20 73 65 70 5f 63 68 61 72 20 3d 20   int sep_char = 
1ca0: 27 3f 27 3b 0d 0a 73 74 61 74 69 63 20 69 6e 74  '?';..static int
1cb0: 20 69 73 5f 73 65 70 5f 63 68 61 72 28 20 69 6e   is_sep_char( in
1cc0: 74 20 63 20 29 0d 0a 7b 0d 0a 20 20 72 65 74 75  t c )..{..  retu
1cd0: 72 6e 20 63 20 3d 3d 20 73 65 70 5f 63 68 61 72  rn c == sep_char
1ce0: 3b 0d 0a 7d 0d 0a 69 6e 74 20 6d 61 69 6e 28 20  ;..}..int main( 
1cf0: 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a  int argc, char *
1d00: 2a 20 61 72 67 76 20 29 0d 0a 7b 0d 0a 0d 0a 20  * argv )..{.... 
1d10: 20 69 6e 74 20 63 6f 75 6e 74 20 3d 20 30 3b 0d   int count = 0;.
1d20: 0a 20 20 73 65 70 5f 63 68 61 72 20 3d 20 28 20  .  sep_char = ( 
1d30: 28 61 72 67 63 3e 32 29 20 3f 20 28 61 72 67 76  (argc>2) ? (argv
1d40: 5b 32 5d 29 5b 30 5d 20 3a 20 27 2f 27 29 3b 0d  [2])[0] : '/');.
1d50: 0a 20 20 70 72 69 6e 74 66 28 20 22 73 65 70 5f  .  printf( "sep_
1d60: 63 68 61 72 3d 3d 25 63 5c 6e 22 2c 73 65 70 5f  char==%c\n",sep_
1d70: 63 68 61 72 29 3b 0d 0a 20 20 63 68 61 72 20 2a  char);..  char *
1d80: 2a 20 6c 20 3d 20 74 6f 6b 65 6e 69 7a 65 5f 70  * l = tokenize_p
1d90: 61 74 68 28 20 61 72 67 63 3d 3d 31 20 3f 20 30  ath( argc==1 ? 0
1da0: 20 3a 20 61 72 67 76 5b 31 5d 2c 0d 0a 20 20 20   : argv[1],..   
1db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1dc0: 20 20 20 20 20 20 20 20 20 20 26 63 6f 75 6e 74            &count
1dd0: 2c 0d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ,..             
1de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1df0: 69 73 5f 73 65 70 5f 63 68 61 72 20 29 3b 0d 0a  is_sep_char );..
1e00: 20 20 70 72 69 6e 74 66 28 20 22 70 61 72 73 65    printf( "parse
1e10: 64 20 70 61 74 68 3a 20 63 6f 75 6e 74 3d 25 64  d path: count=%d
1e20: 5c 6e 22 2c 20 63 6f 75 6e 74 20 29 3b 0d 0a 20  \n", count );.. 
1e30: 20 69 66 28 20 21 20 63 6f 75 6e 74 20 29 0d 0a   if( ! count )..
1e40: 20 20 7b 0d 0a 20 20 20 20 70 72 69 6e 74 66 28    {..    printf(
1e50: 22 65 72 72 6f 72 3a 20 70 61 74 68 20 64 69 64  "error: path did
1e60: 6e 27 74 20 70 61 72 73 65 20 3a 28 5c 6e 22 29  n't parse :(\n")
1e70: 3b 0d 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b  ;..    return 1;
1e80: 0d 0a 20 20 7d 0d 0a 20 20 63 68 61 72 20 2a 20  ..  }..  char * 
1e90: 78 3b 0d 0a 20 20 69 6e 74 20 69 20 3d 20 30 3b  x;..  int i = 0;
1ea0: 0d 0a 20 20 66 6f 72 28 20 78 20 3d 20 6c 5b 30  ..  for( x = l[0
1eb0: 5d 3b 20 78 3b 20 78 20 3d 20 6c 5b 2b 2b 69 5d  ]; x; x = l[++i]
1ec0: 20 29 0d 0a 20 20 7b 0d 0a 20 20 20 20 70 72 69   )..  {..    pri
1ed0: 6e 74 66 28 20 22 5c 74 25 73 5c 6e 22 2c 20 78  ntf( "\t%s\n", x
1ee0: 20 29 3b 0d 0a 20 20 7d 0d 0a 20 20 74 6f 6b 65   );..  }..  toke
1ef0: 6e 69 7a 65 5f 70 61 74 68 5f 66 72 65 65 28 20  nize_path_free( 
1f00: 6c 20 29 3b 0d 0a 20 20 70 72 69 6e 74 66 28 20  l );..  printf( 
1f10: 22 42 79 65 21 5c 6e 22 29 3b 0d 0a 20 20 72 65  "Bye!\n");..  re
1f20: 74 75 72 6e 20 30 3b 0d 0a 7d 0d 0a 23 65 6e 64  turn 0;..}..#end
1f30: 69 66 0d 0a                                      if..