@@ -295,42 +295,75 @@ void write_name_quotedpfx(const char *pfx, size_t pfxlen,
295
295
fputc (terminator , fp );
296
296
}
297
297
298
- /* quote path as relative to the given prefix */
299
- char * quote_path_relative (const char * in , int len ,
300
- struct strbuf * out , const char * prefix )
298
+ static const char * path_relative (const char * in , int len ,
299
+ struct strbuf * sb , const char * prefix ,
300
+ int prefix_len );
301
+
302
+ void write_name_quoted_relative (const char * name , size_t len ,
303
+ const char * prefix , size_t prefix_len ,
304
+ FILE * fp , int terminator )
301
305
{
302
- int needquote ;
306
+ struct strbuf sb = STRBUF_INIT ;
307
+
308
+ name = path_relative (name , len , & sb , prefix , prefix_len );
309
+ write_name_quoted (name , fp , terminator );
310
+
311
+ strbuf_release (& sb );
312
+ }
313
+
314
+ /*
315
+ * Give path as relative to prefix.
316
+ *
317
+ * The strbuf may or may not be used, so do not assume it contains the
318
+ * returned path.
319
+ */
320
+ static const char * path_relative (const char * in , int len ,
321
+ struct strbuf * sb , const char * prefix ,
322
+ int prefix_len )
323
+ {
324
+ int off , i ;
303
325
304
326
if (len < 0 )
305
327
len = strlen (in );
328
+ if (prefix && prefix_len < 0 )
329
+ prefix_len = strlen (prefix );
330
+
331
+ off = 0 ;
332
+ i = 0 ;
333
+ while (i < prefix_len && i < len && prefix [i ] == in [i ]) {
334
+ if (prefix [i ] == '/' )
335
+ off = i + 1 ;
336
+ i ++ ;
337
+ }
338
+ in += off ;
339
+ len -= off ;
340
+
341
+ if (i >= prefix_len )
342
+ return in ;
306
343
307
- /* "../" prefix itself does not need quoting, but "in" might. */
308
- needquote = next_quote_pos (in , len ) < len ;
309
- strbuf_setlen (out , 0 );
310
- strbuf_grow (out , len );
311
-
312
- if (needquote )
313
- strbuf_addch (out , '"' );
314
- if (prefix ) {
315
- int off = 0 ;
316
- while (prefix [off ] && off < len && prefix [off ] == in [off ])
317
- if (prefix [off ] == '/' ) {
318
- prefix += off + 1 ;
319
- in += off + 1 ;
320
- len -= off + 1 ;
321
- off = 0 ;
322
- } else
323
- off ++ ;
324
-
325
- for (; * prefix ; prefix ++ )
326
- if (* prefix == '/' )
327
- strbuf_addstr (out , "../" );
344
+ strbuf_reset (sb );
345
+ strbuf_grow (sb , len );
346
+
347
+ while (i < prefix_len ) {
348
+ if (prefix [i ] == '/' )
349
+ strbuf_addstr (sb , "../" );
350
+ i ++ ;
328
351
}
352
+ strbuf_add (sb , in , len );
353
+
354
+ return sb -> buf ;
355
+ }
329
356
330
- quote_c_style_counted (in , len , out , NULL , 1 );
357
+ /* quote path as relative to the given prefix */
358
+ char * quote_path_relative (const char * in , int len ,
359
+ struct strbuf * out , const char * prefix )
360
+ {
361
+ struct strbuf sb = STRBUF_INIT ;
362
+ const char * rel = path_relative (in , len , & sb , prefix , -1 );
363
+ strbuf_reset (out );
364
+ quote_c_style_counted (rel , strlen (rel ), out , NULL , 0 );
365
+ strbuf_release (& sb );
331
366
332
- if (needquote )
333
- strbuf_addch (out , '"' );
334
367
if (!out -> len )
335
368
strbuf_addstr (out , "./" );
336
369
0 commit comments